diff --git a/.env.default b/.env.default index 3219ce1..1c40be4 100644 --- a/.env.default +++ b/.env.default @@ -1,4 +1,71 @@ +# +# Site configuration +# + +DTP_SITE_NAME= +DTP_SITE_DESCRIPTION= +DTP_SITE_DOMAIN=localhost +DTP_SITE_DOMAIN_KEY= +DTP_SITE_COMPANY=Digital Telepresence, LLC +DTP_PASSWORD_SALT= + +# +# Mailgun Configuration +# + +DTP_MAILGUN_ENABLED=disabled +MAILGUN_API_KEY= +MAILGUN_DOMAIN= + +# +# MongoDB configuration +# + +MONGODB_HOST=localhost:27017 +MONGODB_DATABASE=dtp-sites + +# # Redis configuration -REDIS_HOST= -REDIS_PORT= -REDIS_PASSWORD= \ No newline at end of file +# + +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_PASSWORD= + +# +# MinIO configuration +# + +MINIO_ENDPOINT=localhost +MINIO_PORT=9000 +MINIO_USE_SSL=disabled +MINIO_ACCESS_KEY=dtp-sites +MINIO_SECRET_KEY= +MINIO_IMAGE_BUCKET=site-images +MINIO_VIDEO_BUCKET=site-videos + +# +# ExpressJS/HTTP configuration +# + +HTTP_BIND_ADDRESS=127.0.0.1 +HTTP_BIND_PORT=3000 +HTTP_SESSION_SECRET= + +# +# Log configuration +# + +DTP_LOG_CONSOLE=enabled +DTP_LOG_MONGODB=enabled +DTP_LOG_FILE=enabled + +DTP_LOG_FILE_PATH=/tmp/dtp-sites/logs +DTP_LOG_FILE_NAME_APP=justjoeradio-app.log +DTP_LOG_FILE_NAME_HTTP=justjoeradio-access.log + +DTP_LOG_DEBUG=enabled +DTP_LOG_INFO=enabled +DTP_LOG_WARN=enabled + +DTP_LOG_HTTP_FORMAT=combined \ No newline at end of file diff --git a/.gitignore b/.gitignore index d09104f..9e9b214 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .env -node_modules \ No newline at end of file +node_modules +dist diff --git a/LICENSE b/LICENSE index fdbc477..5c06269 100644 --- a/LICENSE +++ b/LICENSE @@ -1,49 +1,13 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ +Copyright 2021 Digital Telepresence, LLC -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at -1. Definitions. +http://www.apache.org/licenses/LICENSE-2.0 -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and -You must cause any modified files to carry prominent notices stating that You changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. - -You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. \ No newline at end of file +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md index 190457f..a6e0aad 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,90 @@ # Digital Telepresence Sites -A content management system based on the Digital Telepresence Platform. \ No newline at end of file + +A content management and web hosting system based on the Digital Telepresence Platform. + +## Requirements + +The only qualified operated system for hosting a DTP Sites suite is [Ubuntu 20.04 LTS](https://releases.ubuntu.com/20.04/). It is acceptable to run it in a virtual machine for development and testing, but it should be run as close to bare metal as can be had for production environments. + +You will need MongoDB and MinIO installed and running before you can start DTP Sites web services. + +1. [Install MongoDB](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/) +2. [Install MinIO](https://docs.min.io/docs/minio-quickstart-guide.html) + +Install redis: +```sh +sudo apt-get install redis +``` + +## Environment Configuration + +On a new host or host image, copy `.env.default` to `.env` and edit it as necessary. + +For password salt and service passwords, the `uuidgen` tool may be useful to help generate hard-to-guess passwords for use in a development environment. Something more sophisticated than a UUID should be used in production. + +Install application dependencies by running Yarn. You should do this on initial install and after every update or `git pull` as dependencies do change often, become upgraded to new versions, receive security fixes, etc. + +```sh +yarn +``` + +## Starting DTP Sites In Development Mode + +1. Make sure `NODE_ENV` is set to `local` +2. Run `./sites-start-local` in a VS Code terminal, then rename that terminal to `services`. +3. In a new VS Code terminal, run `gulp` and rename that terminal `gulp`. +4. Open https://localhost:3000 in your web browser. + +You can now make changes to program source code, and the environment will automatically respond, build, pack, and re-load things as needed depending on what you did and what's open/running. + +DTP Sites is a multi-tier web hosting engine built on: + +- [MongoDB](https://www.mongodb.com/) +- [Redis](https://redis.io/) +- [MinIO](https://min.io/) +- [Node.js](https://nodejs.org/en/) +- [ExpressJS](http://expressjs.com/) +- [UIkit](https://getuikit.com/) + +## Production Environment Information + +It's impossible to give 100% generic advice here, but it all depends on how large your audience is and how much they use your website. Larger, more active audiences will require a different kind of production server deployment than smaller and less active audiences. + +Generally, it's possible to stack all components on one host and operate a fast site for small-to-medium audiences. The size of the host may vary, but it's possible to keep the system stacked and handle quite a large audience. + +Beyond a point, you'll need to start isolating services away from each other. Storage will want it's own system(s), MongoDB will want it's own systems (plural), Redis will want it's own system(s), and the Node.js components can each start to want their own system(s). + +Once you start scaling horizontally, the host requirements change a little. You will need two networks and network interfaces per host. The production network to handle public requests; and a management network for handling IPC and data-sharing among the hosts themselves. + +- [MongoDB](https://docs.mongodb.com/launch-manage/) + +Some useful links for learning more about hosting MinIO: + +- [Quick Start](https://docs.min.io/docs/minio-quickstart-guide.html) +- [Configuration](https://docs.min.io/docs/minio-server-configuration-guide.html) + +- [Docker](https://docs.min.io/docs/minio-docker-quickstart-guide.html) +- [Distributed](https://docs.min.io/docs/distributed-minio-quickstart-guide.html) +- [Monitoring](https://docs.min.io/docs/minio-monitoring-guide.html) + +- [Security Overview](https://docs.min.io/docs/minio-security-overview.html) +- [TLS](https://docs.min.io/docs/how-to-secure-access-to-minio-server-with-tls.html) + + +Redis simply has many different documents to describe it's many different features and their requirements. I'd like to give you a summary page link, but it doesn't exist. This is that summary page. These are those links. + +- [Quick Start](https://redis.io/topics/quickstart) + +- [Access Control Lists](https://redis.io/topics/acl) +- [Administration](https://redis.io/topics/admin) +- [Configuration](https://redis.io/topics/config) +- [Encryption](https://redis.io/topics/encryption) +- [High Availability](https://redis.io/topics/sentinel) +- [Persistence](https://redis.io/topics/persistence) +- [Replication](https://redis.io/topics/replication) +- [Security](https://redis.io/topics/security) +- [Signals](https://redis.io/topics/signals) + +## Software License + +The Digital Telepresence Platform Sites engine is licensed under the [Apache 2.0](https://spdx.org/licenses/Apache-2.0.html) open source software license. See [LICENSE](LICENSE) for more information. \ No newline at end of file diff --git a/app/controllers/admin/domain.js b/app/controllers/admin/domain.js new file mode 100644 index 0000000..e11b165 --- /dev/null +++ b/app/controllers/admin/domain.js @@ -0,0 +1,91 @@ +// admin/domain.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const express = require('express'); + +const { /*SiteError,*/ SiteController } = require('../../../lib/site-lib'); + +class DomainController extends SiteController { + + constructor (dtp) { + super(dtp, 'admin:domain'); + } + + async start ( ) { + const router = express.Router(); + router.use(async (req, res, next) => { + res.locals.currentView = 'admin'; + res.locals.adminView = 'domain'; + return next(); + }); + + router.param('domainId', this.populateDomainId.bind(this)); + + router.post('/:domainId', this.postUpdateDomain.bind(this)); + router.post('/', this.postCreateDomain.bind(this)); + + router.get('/create', this.getCreateForm.bind(this)); + router.get('/:domainId', this.getDomainView.bind(this)); + + router.get('/', this.getHomeView.bind(this)); + + return router; + } + + async populateDomainId (req, res, next, domainId) { + const { domain: domainService } = this.dtp.services; + try { + res.locals.domain = await domainService.getById(domainId); + return next(); + } catch (error) { + return next(error); + } + } + + async postUpdateDomain (req, res, next) { + const { domain: domainService } = this.dtp.services; + try { + await domainService.update(res.locals.domain, req.body); + res.redirect('/admin/domain'); + } catch (error) { + return next(error); + } + } + + async postCreateDomain (req, res, next) { + const { domain: domainService } = this.dtp.services; + try { + res.locals.domain = await domainService.create(req.body); + res.redirect(`/admin/domain/${res.locals.domain._id}`); + } catch (error) { + return next(error); + } + } + + async getDomainView (req, res) { + res.render('admin/domain/form'); + } + + async getCreateForm (req, res) { + res.render('admin/domain/form'); + } + + async getHomeView (req, res, next) { + const { domain: domainService } = this.dtp.services; + try { + res.locals.pagination = this.getPaginationParameters(req, 10); + res.locals.domains = await domainService.getDomains(res.locals.pagination); + res.render('admin/domain/index'); + } catch (error) { + return next(error); + } + } +} + +module.exports = async (dtp) => { + let controller = new DomainController(dtp); + return controller; +}; diff --git a/app/controllers/admin/host.js b/app/controllers/admin/host.js new file mode 100644 index 0000000..b8ec0de --- /dev/null +++ b/app/controllers/admin/host.js @@ -0,0 +1,76 @@ +// admin/host.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'admin:host'; + +const express = require('express'); + +const mongoose = require('mongoose'); +const NetHost = mongoose.model('NetHost'); +const NetHostStats = mongoose.model('NetHostStats'); + +const { /*SiteError,*/ SiteController } = require('../../../lib/site-lib'); + +class HostController extends SiteController { + + constructor (dtp) { + super(dtp, DTP_COMPONENT_NAME); + } + + async start ( ) { + const router = express.Router(); + router.use(async (req, res, next) => { + res.locals.currentView = 'admin'; + res.locals.adminView = 'host'; + return next(); + }); + + router.param('hostId', this.populateHostId.bind(this)); + + router.get('/:hostId', this.getHostView.bind(this)); + + router.get('/', this.getHomeView.bind(this)); + + return router; + } + + async populateHostId (req, res, next, hostId) { + try { + res.locals.host = await NetHost.findOne({ _id: hostId }); + return next(); + } catch (error) { + return next(error); + } + } + + async getHostView (req, res, next) { + try { + res.locals.stats = await NetHostStats + .find({ host: res.locals.host._id }) + .sort({ created: -1 }) + .limit(30) + .lean(); + res.locals.stats = res.locals.stats.reverse(); + res.render('admin/host/view'); + } catch (error) { + return next(error); + } + } + + async getHomeView (req, res, next) { + try { + res.locals.hosts = await NetHost.find({ status: { $ne: 'inactive' } }); + res.render('admin/host/index'); + } catch (error) { + return next(error); + } + } +} + +module.exports = async (dtp) => { + let controller = new HostController(dtp); + return controller; +}; diff --git a/app/controllers/admin/job-queue.js b/app/controllers/admin/job-queue.js new file mode 100644 index 0000000..e4b5f79 --- /dev/null +++ b/app/controllers/admin/job-queue.js @@ -0,0 +1,77 @@ +// admin/domain.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'admin:domain'; +const express = require('express'); + +const { /*SiteError,*/ SiteController } = require('../../../lib/site-lib'); + +class JobQueueController extends SiteController { + + constructor (dtp) { + super(dtp, DTP_COMPONENT_NAME); + } + + async start ( ) { + const router = express.Router(); + router.use(async (req, res, next) => { + res.locals.currentView = 'admin'; + res.locals.adminView = 'job-queue'; + return next(); + }); + + router.param('jobQueueName', this.populateJobQueueName.bind(this)); + + router.get('/:jobQueueName', this.getJobQueueView.bind(this)); + router.get('/', this.getHomeView.bind(this)); + + return router; + } + + async populateJobQueueName (req, res, next, jobQueueName) { + const { jobQueue: jobQueueService } = this.dtp.services; + try { + res.locals.queueName = jobQueueName; + res.locals.queue = await jobQueueService.getJobQueue(jobQueueName); + return next(); + } catch (error) { + this.log.error('failed to populate job queue', { jobQueueName, error }); + return next(error); + } + } + + async getJobQueueView (req, res, next) { + try { + res.locals.jobCounts = await res.locals.queue.getJobCounts(); + res.locals.jobs = { + waiting: await res.locals.queue.getWaiting(0, 5), + active: await res.locals.queue.getActive(0, 5), + delayed: await res.locals.queue.getDelayed(0, 5), + failed: await res.locals.queue.getFailed(0, 5), + }; + res.render('admin/job-queue/queue-view'); + } catch (error) { + this.log.error('failed to populate job queue view', { error }); + return next(error); + } + } + + async getHomeView (req, res, next) { + const { jobQueue: jobQueueService } = this.dtp.services; + try { + res.locals.queues = await jobQueueService.discoverJobQueues('soapy:*:id'); + res.render('admin/job-queue/index'); + } catch (error) { + this.log.error('failed to populate job queues view', { error }); + return next(error); + } + } +} + +module.exports = async (dtp) => { + let controller = new JobQueueController(dtp); + return controller; +}; \ No newline at end of file diff --git a/app/controllers/admin/user.js b/app/controllers/admin/user.js new file mode 100644 index 0000000..01aac69 --- /dev/null +++ b/app/controllers/admin/user.js @@ -0,0 +1,75 @@ +// admin/user.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'admin:user'; + +const express = require('express'); + +const { /*SiteError,*/ SiteController } = require('../../../lib/site-lib'); + +class UserController extends SiteController { + + constructor (dtp) { + super(dtp, DTP_COMPONENT_NAME); + } + + async start ( ) { + const router = express.Router(); + router.use(async (req, res, next) => { + res.locals.currentView = 'admin'; + res.locals.adminView = 'user'; + return next(); + }); + + router.param('userId', this.populateUserId.bind(this)); + + router.post('/:userId', this.postUpdateUser.bind(this)); + router.get('/:userId', this.getUserView.bind(this)); + router.get('/', this.getHomeView.bind(this)); + + return router; + } + + async populateUserId (req, res, next, userId) { + const { user: userService } = this.dtp.services; + try { + res.locals.userAccount = await userService.getUserAccount(userId); + return next(); + } catch (error) { + return next(error); + } + } + + async postUpdateUser (req, res, next) { + const { user: userService } = this.dtp.services; + try { + await userService.update(res.locals.userAccount, req.body); + res.redirect('/admin/user'); + } catch (error) { + return next(error); + } + } + + async getUserView (req, res) { + res.render('admin/user/form'); + } + + async getHomeView (req, res, next) { + const { user: userService } = this.dtp.services; + try { + res.locals.pagination = this.getPaginationParameters(req, 10); + res.locals.userAccounts = await userService.getUserAccounts(res.locals.pagination); + res.render('admin/user/index'); + } catch (error) { + return next(error); + } + } +} + +module.exports = async (dtp) => { + let controller = new UserController(dtp); + return controller; +}; diff --git a/app/controllers/auth.js b/app/controllers/auth.js new file mode 100644 index 0000000..b33b311 --- /dev/null +++ b/app/controllers/auth.js @@ -0,0 +1,195 @@ +// auth.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'auth'; + +const express = require('express'); +const mongoose = require('mongoose'); +const multer = require('multer'); +const passport = require('passport'); +const uuidv4 = require('uuid').v4; + +const { SiteController, SiteError } = require('../../lib/site-lib'); + +const ConnectToken = mongoose.model('ConnectToken'); + +class AuthController extends SiteController { + + constructor (dtp) { + super(dtp, DTP_COMPONENT_NAME); + } + + async start ( ) { + const { limiter: limiterService } = this.dtp.services; + const upload = multer({ }); + + const router = express.Router(); + this.dtp.app.use('/auth', router); + + const authRequired = this.dtp.services.session.authCheckMiddleware({ requireLogin: true }); + + router.post('/otp/enable', + limiterService.create(limiterService.config.auth.postOtpEnable), + this.postOtpEnable.bind(this), + ); + router.post('/otp/auth', + limiterService.create(limiterService.config.auth.postOtpAuthenticate), + this.postOtpAuthenticate.bind(this), + ); + + router.post('/login', + limiterService.create(limiterService.config.auth.postLogin), + upload.none(), + this.postLogin.bind(this), + ); + + router.get('/api-token/personal', + authRequired, + limiterService.create(limiterService.config.auth.getPersonalApiToken), + this.getPersonalApiToken.bind(this), + ); + + router.get('/socket-token', + authRequired, + limiterService.create(limiterService.config.auth.getSocketToken), + this.getSocketToken.bind(this), + ); + + router.get('/logout', + authRequired, + limiterService.create(limiterService.config.auth.getLogout), + this.getLogout.bind(this), + ); + + return router; + } + + async postOtpEnable (req, res, next) { + const { otpAuth: otpAuthService } = this.dtp.services; + + const service = req.body['otp-service']; + const secret = req.body['otp-secret']; + const token = req.body['otp-token']; + const otpRedirectURL = req.body['otp-redirect'] || '/'; + + try { + this.log.info('enabling OTP protections', { service, secret, token }); + res.locals.otpAccount = await otpAuthService.createOtpAccount(req, service, secret, token); + res.locals.otpRedirectURL = otpRedirectURL; + res.render('otp/new-account'); + } catch (error) { + this.log.error('failed to enable OTP protections', { + service, error, + }); + return next(error); + } + } + + async postOtpAuthenticate (req, res, next) { + const { otpAuth: otpAuthService } = this.dtp.services; + + if (!req.user) { + return res.status(403).json({ + success: false, + message: 'Must be logged in', + }); + } + const service = req.body['otp-service']; + if (!service) { + return res.status(400).json({ + success: false, + message: 'Must specify OTP service name', + }); + } + const passcode = req.body['otp-passcode']; + if (!passcode || (typeof passcode !== 'string') || (passcode.length !== 6)) { + return res.status(400).json({ + success: false, + message: 'Must include a valid passcode', + }); + } + try { + await otpAuthService.startOtpSession(req, service, passcode); + return res.redirect(req.body['otp-redirect']); + } catch (error) { + this.log.error('failed to verify one-time password for 2FA', { + service, error, + }, req.user); + return next(error); + } + } + + async postLogin (req, res, next) { + passport.authenticate('dtp-local', (error, user/*, info*/) => { + if (error) { + req.session.loginResult = error.toString(); + return next(error); + } + if (!user) { + req.session.loginResult = 'Username or email address is unknown.'; + return res.redirect('/welcome/login'); + } + this.log.info('user logging in', { user: user.username }); + req.login(user, (error) => { + if (error) { + return next(error); + } + return res.redirect('/'); + }); + })(req, res, next); + } + + async getPersonalApiToken (req, res, next) { + try { + const { apiGuard: apiGuardService } = this.dtp.platform.services; + res.locals.apiToken = await apiGuardService.createApiToken(req.user, [ + 'account-read', + // additional scopes go here + ]); + res.render('api-token/view'); + } catch (error) { + this.log.error('failed to generate API token', { error }); + return next(error); + } + } + + async getSocketToken (req, res, next) { + try { + const token = await ConnectToken.create({ + created: new Date(), + user: req.user._id, + token: uuidv4(), + }); + res.status(200).json({ + success: true, + token: token.token + }); + } catch (error) { + this.log.error('failed to create Socket.io connect token', { error }); + return next(error); + } + } + + async getLogout (req, res, next) { + if (!req.user) { + return next(new SiteError(403, 'You are not signed in')); + } + + req.logout(); + req.session.destroy((err) => { + if (err) { + this.log.error('failed to destroy browser session', { err }); + return next(err); + } + res.redirect('/'); + }); + } +} + +module.exports = async (dtp) => { + let controller = new AuthController(dtp); + return controller; +}; \ No newline at end of file diff --git a/app/controllers/home.js b/app/controllers/home.js index 803bec3..1648e87 100644 --- a/app/controllers/home.js +++ b/app/controllers/home.js @@ -4,15 +4,47 @@ 'use strict'; -class HomeController { +const DTP_COMPONENT_NAME = 'home'; - constructor ( ) { +const express = require('express'); +const { SiteController } = require('../../lib/site-lib'); + +class HomeController extends SiteController { + + constructor (dtp) { + super(dtp, DTP_COMPONENT_NAME); + } + + async start ( ) { + const { dtp } = this; + const { limiter: limiterService } = dtp.services; + + const router = express.Router(); + dtp.app.use('/', router); + + router.use(async (req, res, next) => { + res.locals.currentView = 'home'; + return next(); + }); + + router.get('/', + limiterService.create(limiterService.config.home.getHome), + this.getHome.bind(this), + ); } - async getHome (req, res) { - res.send(`Hello, controller!`); + async getHome (req, res, next) { + try { + res.locals.pagination = this.getPaginationParameters(req, 20); + res.render('index'); + } catch (error) { + return next(error); + } } } -module.exports.HomeController = HomeController; \ No newline at end of file +module.exports = async (dtp) => { + let controller = new HomeController(dtp); + return controller; +}; diff --git a/app/controllers/image.js b/app/controllers/image.js new file mode 100644 index 0000000..0940e63 --- /dev/null +++ b/app/controllers/image.js @@ -0,0 +1,125 @@ +// page.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'image'; + +const fs = require('fs'); + +const express = require('express'); +const mongoose = require('mongoose'); +const multer = require('multer'); + +const { SiteController/*, SiteError*/ } = require('../../lib/site-lib'); + +class ImageController extends SiteController { + + constructor (dtp) { + super(dtp, DTP_COMPONENT_NAME); + + } + + async start ( ) { + const { dtp } = this; + const { limiter: limiterService } = dtp.services; + + const router = express.Router(); + dtp.app.use('/image', router); + + const imageUpload = multer({ + dest: '/tmp/dtp-sites/upload/image', + limits: { + fileSize: 1024 * 1000 * 5, + }, + }); + + router.use(async (req, res, next) => { + res.locals.currentView = 'image'; + return next(); + }); + + router.param('imageId', this.populateImage.bind(this)); + + router.post('/', + limiterService.create(limiterService.config.image.postCreateImage), + imageUpload.single('file'), + this.postCreateImage.bind(this), + ); + + router.get('/:imageId', + limiterService.create(limiterService.config.image.getImage), + this.getHostCacheImage.bind(this), + // this.getImage.bind(this), + ); + } + + async populateImage (req, res, next, imageId) { + try { + res.locals.imageId = mongoose.Types.ObjectId(imageId); + res.locals.image = await this.dtp.services.image.getImageById(res.locals.imageId); + return next(); + } catch (error) { + this.log.error('failed to populate image', { error }); + return next(error); + } + } + + async postCreateImage (req, res, next) { + const { image: imageService } = this.dtp.services; + try { + res.locals.image = await imageService.create(req.user, req.body, req.file); + res.status(200).json({ + success: true, + imageId: res.locals.image._id.toString(), + }); + } catch (error) { + this.log.error('failed to create image', { error }); + return next(error); + } + } + + async getHostCacheImage (req, res) { + const { hostCache: hostCacheService } = this.dtp.services; + const { image } = res.locals; + try { + const fileInfo = await hostCacheService.getFile(image.file.bucket, image.file.key); + const stream = fs.createReadStream(fileInfo.file.path); + res.header('Content-Type', image.type); + res.header('Content-Length', fileInfo.file.stats.size); + res.status(200); + stream.pipe(res); + } catch (error) { + this.log.error('failed to fetch image', { image, error }); + return res.status(error.statusCode || 500).json({ + success: false, + message: error.message, + }); + } + } + + async getImage (req, res) { + const { minio: minioService } = this.dtp.services; + try { + const stream = await minioService.openDownloadStream({ + bucket: res.locals.image.file.bucket, + key: res.locals.image.file.key + }); + res.header('Content-Type', res.locals.image.type); + res.header('Content-Length', res.locals.image.size); + res.status(200); + stream.pipe(res); + } catch (error) { + return res.status(error.statusCode || 500).json({ + success: false, + message: error.message, + }); + } + } +} + +module.exports = async (dtp) => { + let controller = new ImageController(dtp); + return controller; +}; \ No newline at end of file diff --git a/app/controllers/manifest.js b/app/controllers/manifest.js new file mode 100644 index 0000000..2468a1f --- /dev/null +++ b/app/controllers/manifest.js @@ -0,0 +1,71 @@ +// manifest.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'manifest'; + +const express = require('express'); + +const { SiteController } = require('../../lib/site-lib'); + +class ManifestController extends SiteController { + + constructor (dtp) { + super(dtp, DTP_COMPONENT_NAME); + } + + async start ( ) { + const { dtp } = this; + const { limiter: limiterService } = dtp.services; + + const router = express.Router(); + dtp.app.use('/manifest.json', router); + + router.use(async (req, res, next) => { + res.locals.currentView = DTP_COMPONENT_NAME; + return next(); + }); + + router.get('/', + limiterService.create(limiterService.config.manifest.getManifest), + this.getManifest.bind(this), + ); + } + + async getManifest (req, res, next) { + const DEFAULT_THEME_COLOR = '#4a4a4a'; + const DEFAULT_BACKGROUND_COLOR = '#1a1a1a'; + try { + const manifest = { + theme_color: DEFAULT_THEME_COLOR, + background_color: DEFAULT_BACKGROUND_COLOR, + display: 'fullscreen', + scope: '/', + start_url: '/', + name: this.dtp.config.site.name, + short_name: this.dtp.config.site.name, + description: this.dtp.config.site.description, + icons: [ ], + }; + + [512, 384, 256, 192, 144, 96, 72, 48, 32, 16].forEach((size) => { + manifest.icons.push({ + src: `/img/icon/${this.dtp.config.site.domainKey}/icon-${size}x${size}.png`, + sizes: `${size}x${size}`, + type: 'image/png' + }); + }); + + res.status(200).json(manifest); + } catch (error) { + return next(error); + } + } +} + +module.exports = async (dtp) => { + let controller = new ManifestController(dtp); + return controller; +}; diff --git a/app/controllers/user.js b/app/controllers/user.js new file mode 100644 index 0000000..abeca5e --- /dev/null +++ b/app/controllers/user.js @@ -0,0 +1,162 @@ +// user.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'user'; + +const express = require('express'); +const mongoose = require('mongoose'); +const multer = require('multer'); + +const { SiteController, SiteError } = require('../../lib/site-lib'); + +class UserController extends SiteController { + + constructor (dtp) { + super(dtp, DTP_COMPONENT_NAME); + } + + async start ( ) { + const { dtp } = this; + const { limiter: limiterService, otpAuth: otpAuthService } = dtp.services; + + const upload = multer({ dest: "/tmp" }); + const router = express.Router(); + dtp.app.use('/user', router); + + const otpMiddleware = otpAuthService.middleware('Account', { + adminRequired: false, + otpRequired: false, + otpRedirectURL: async (req) => { return `/user/${req.user._id}`; }, + }); + + router.use( + async (req, res, next) => { + try { + res.locals.currentView = 'user'; + res.locals.pageTitle = 'Manage your user account.'; + return next(); + } catch (error) { + return next(error); + } + }, + ); + + async function checkProfileOwner (req, res, next) { + if (!req.user || !req.user._id.equals(res.locals.userProfile._id)) { + return next(new SiteError(403, 'This is not your user account or profile')); + } + return next(); + } + + router.param('userId', this.populateUser.bind(this)); + + router.post('/:userId/settings', + limiterService.create(limiterService.config.user.postUpdateSettings), + upload.none(), + this.postUpdateSettings.bind(this), + ); + + router.post('/', + limiterService.create(limiterService.config.user.postCreate), + this.postCreateUser.bind(this), + ); + + router.get('/:userId/settings', + limiterService.create(limiterService.config.user.getSettings), + otpMiddleware, + checkProfileOwner, + this.getUserSettingsView.bind(this), + ); + router.get('/:userId', + limiterService.create(limiterService.config.user.getUserProfile), + otpMiddleware, + checkProfileOwner, + this.getUserView.bind(this), + ); + } + + async populateUser (req, res, next, userId) { + const { user: userService } = this.dtp.services; + try { + userId = mongoose.Types.ObjectId(userId); + } catch (error) { + return next(new SiteError(406, 'Invalid User')); + } + try { + if (!req.user._id.equals(userId)) { + return next(new Error('Invalid account ID')); + } + res.locals.userProfile = await userService.getUserAccount(userId); + return next(); + } catch (error) { + this.log.error('failed to populate userId', { userId, error }); + return next(error); + } + } + + async postCreateUser (req, res, next) { + const { user: userService } = this.dtp.services; + try { + res.locals.user = await userService.create(req.body); + req.login(res.locals.user, (error) => { + if (error) { + return next(error); + } + res.redirect(`/user/${res.locals.user._id}`); + }); + } catch (error) { + this.log.error('failed to create new user', { error }); + return next(error); + } + } + + async postUpdateSettings (req, res) { + const { user: userService, displayEngine: displayEngineService } = this.dtp.services; + try { + const displayList = displayEngineService.createDisplayList('app-settings'); + + await userService.updateSettings(req.user, req.body); + + displayList.showNotification( + 'Member account settings updated successfully.', + 'success', + 'bottom-center', + 6000, + ); + res.status(200).json({ success: true, displayList }); + } catch (error) { + this.log.error('failed to update account settings', { error }); + return res.status(error.statusCode || 500).json({ + success: false, + message: error.message, + }); + } + } + + async getUserSettingsView (req, res, next) { + try { + res.locals.startTab = req.query.st || 'watch'; + res.render('user/settings'); + } catch (error) { + this.log.error('failed to produce user settings view', { error }); + return next(error); + } + } + + async getUserView (req, res, next) { + try { + res.render('user/profile'); + } catch (error) { + this.log.error('failed to produce user profile view', { error }); + return next(error); + } + } +} + +module.exports = async (dtp) => { + let controller = new UserController(dtp); + return controller; +}; diff --git a/app/controllers/welcome.js b/app/controllers/welcome.js new file mode 100644 index 0000000..19dedc1 --- /dev/null +++ b/app/controllers/welcome.js @@ -0,0 +1,54 @@ +// welcome.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'welcome'; + +const express = require('express'); + +const { SiteController/*, SiteError */ } = require('../../lib/site-lib'); + +class WelcomeController extends SiteController { + + constructor (dtp) { + super(dtp, DTP_COMPONENT_NAME); + } + + async start ( ) { + const { limiter: limiterService } = this.dtp.services; + const welcomeLimiter = limiterService.create(limiterService.config.welcome); + + const router = express.Router(); + this.dtp.app.use('/welcome', welcomeLimiter, router); + + router.get('/signup', this.getSignupView.bind(this)); + router.get('/login', this.getLoginView.bind(this)); + router.get('/', this.getHomeView.bind(this)); + + return router; + } + + async getSignupView (req, res) { + res.render('welcome/signup'); + } + + async getLoginView (req, res) { + res.locals.loginResult = req.session.loginResult; + res.render('welcome/login'); + } + + async getHomeView (req, res, next) { + try { + res.render('welcome/index'); + } catch (error) { + return next(error); + } + } +} + +module.exports = async (dtp) => { + let controller = new WelcomeController(dtp); + return controller; +}; \ No newline at end of file diff --git a/app/models/article.js b/app/models/article.js new file mode 100644 index 0000000..2fff4ff --- /dev/null +++ b/app/models/article.js @@ -0,0 +1,29 @@ +// article.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const ArticleSchema = new Schema({ + domain: { type: Schema.ObjectId, required: true, index: 1, ref: 'Domain' }, + channel: { type: Schema.ObjectId, required: true, index: 1, ref: 'Channel' }, + created: { type: Date, default: Date.now, required: true, index: -1 }, + author: { type: Schema.ObjectId, required: true, index: 1, ref: 'User' }, + image: { type: Schema.ObjectId, required: true, ref: 'Image' }, + title: { type: String, required: true }, + summary: { type: String }, + content: { type: String }, +}); + +ArticleSchema.index({ + domain: 1, + channel: 1, +}, { + name: 'article_domain_channel_idx', +}); + +module.exports = mongoose.model('Article', ArticleSchema); \ No newline at end of file diff --git a/app/models/category.js b/app/models/category.js new file mode 100644 index 0000000..d353835 --- /dev/null +++ b/app/models/category.js @@ -0,0 +1,34 @@ +// category.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const CategorySchema = new Schema({ + domain: { type: Schema.ObjectId, required: true, index: 1, ref: 'Domain' }, + name: { type: String }, + slug: { type: String, lowercase: true, required: true, index: 1 }, + description: { type: String }, + images: { + header: { type: Schema.ObjectId }, + icon: { type: Schema.ObjectId }, + }, + stats: { + liveChannelCount: { type: Number, default: 0, required: true }, + currentViewerCount: { type: Number, default: 0, required: true }, + }, +}); + +CategorySchema.index({ + domain: 1, + slug: 1, +}, { + unique: true, + name: 'domain_category_unique', +}); + +module.exports = mongoose.model('Category', CategorySchema); \ No newline at end of file diff --git a/app/models/chat-message.js b/app/models/chat-message.js new file mode 100644 index 0000000..ea36029 --- /dev/null +++ b/app/models/chat-message.js @@ -0,0 +1,21 @@ +// chat-message.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const ChatMessageSchema = new Schema({ + created: { type: Date, default: Date.now, required: true, index: -1, expires: '10d' }, + domain: { type: Schema.ObjectId, required: true, index: 1, ref: 'Domain' }, + channel: { type: Schema.ObjectId, required: true, index: 1, ref: 'Channel' }, + episode: { type: Schema.ObjectId, index: 1, ref: 'Episode' }, + author: { type: Schema.ObjectId, required: true, index: 1, ref: 'User' }, + content: { type: String }, + stickers: { type: [String] }, +}); + +module.exports = mongoose.model('ChatMessage', ChatMessageSchema); \ No newline at end of file diff --git a/app/models/connect-token.js b/app/models/connect-token.js new file mode 100644 index 0000000..12096cd --- /dev/null +++ b/app/models/connect-token.js @@ -0,0 +1,18 @@ +// connect-token.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const ConnectTokenSchema = new Schema({ + created: { type: Date, default: Date.now, required: true, index: -1, expires: '1m' }, + user: { type: Schema.ObjectId, required: true, index: true, ref: 'User' }, + token: { type: String, required: true }, + claimed: { type: Date }, +}); + +module.exports = mongoose.model('ConnectToken', ConnectTokenSchema); \ No newline at end of file diff --git a/app/models/csrf-token.js b/app/models/csrf-token.js new file mode 100644 index 0000000..6969ab3 --- /dev/null +++ b/app/models/csrf-token.js @@ -0,0 +1,20 @@ +// csrf-token.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const CsrfTokenSchema = new Schema({ + created: { type: Date, required: true, default: Date.now, index: -1, expires: '7d' }, + expires: { type: Date, required: true, default: Date.now, index: -1 }, + claimed: { type: Date }, + token: { type: String, index: 1 }, + user: { type: Schema.ObjectId, ref: 'User' }, + ip: { type: String, required: true }, +}); + +module.exports = mongoose.model('CsrfToken', CsrfTokenSchema); \ No newline at end of file diff --git a/app/models/domain.js b/app/models/domain.js new file mode 100644 index 0000000..000427b --- /dev/null +++ b/app/models/domain.js @@ -0,0 +1,21 @@ +// domain.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const DomainSchema = new Schema({ + created: { type: Date, default: Date.now, required: true, index: -1 }, + name: { type: String, required: true, lowercase: true, index: 1 }, + stats: { + channelCount: { type: Number, default: 0, required: true }, + streamCount: { type: Number, default: 0, required: true }, + viewerCount: { type: Number, default: 0, required: true }, + }, +}); + +module.exports = mongoose.model('Domain', DomainSchema); \ No newline at end of file diff --git a/app/models/email-blacklist.js b/app/models/email-blacklist.js new file mode 100644 index 0000000..c579560 --- /dev/null +++ b/app/models/email-blacklist.js @@ -0,0 +1,34 @@ +// email-blacklist.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const EmailBlacklistSchema = new Schema({ + created: { type: Date, required: true, default: Date.now, index: -1, expires: '30d' }, + email: { + type: String, + required: true, + lowercase: true, + maxlength: 255, + unique: true, + }, + flags: { + isVerified: { type: Boolean, default: false, required: true }, + }, +}); + +EmailBlacklistSchema.index({ + email: 1, + 'flags.isVerified': true, +}, { + partialFilterExpression: { + 'flags.isVerified': true, + }, +}); + +module.exports = mongoose.model('EmailBlacklist', EmailBlacklistSchema); \ No newline at end of file diff --git a/app/models/image.js b/app/models/image.js new file mode 100644 index 0000000..4ffe590 --- /dev/null +++ b/app/models/image.js @@ -0,0 +1,35 @@ +// image.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const ImageSchema = new Schema({ + created: { type: Date, default: Date.now, required: true, index: -1 }, + owner: { type: Schema.ObjectId, required: true, index: 1, ref: 'User' }, + type: { type: String, required: true }, + size: { type: Number, required: true }, + file: { + bucket: { type: String, required: true }, + key: { type: String, required: true }, + etag: { type: String, required: true, index: true }, + }, + metadata: { + format: { type: String }, + size: { type: Number }, + width: { type: Number }, + height: { type: Number }, + space: { type: String }, + channels: { type: Number }, + depth: { type: String }, + density: { type: Number }, + hasAlpha: { type: Boolean }, + orientation: { type: Number }, + }, +}); + +module.exports = mongoose.model('Image', ImageSchema); \ No newline at end of file diff --git a/app/models/log.js b/app/models/log.js new file mode 100644 index 0000000..574e5ae --- /dev/null +++ b/app/models/log.js @@ -0,0 +1,29 @@ +// log.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const LOG_LEVEL_LIST = [ + 'debug', + 'info', + 'warn', + 'alert', + 'error', + 'crit', + 'fatal', +]; + +const LogSchema = new Schema({ + created: { type: Date, default: Date.now, required: true, index: -1, expires: '7d' }, + componentName: { type: String, required: true }, + level: { type: String, enum: LOG_LEVEL_LIST, required: true, index: true }, + message: { type: String }, + metadata: { type: Schema.Types.Mixed }, +}); + +module.exports = mongoose.model('Log', LogSchema); \ No newline at end of file diff --git a/app/models/net-host-stats.js b/app/models/net-host-stats.js new file mode 100644 index 0000000..fb295f8 --- /dev/null +++ b/app/models/net-host-stats.js @@ -0,0 +1,75 @@ +// net-host-stats.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const CpuInfoSchema = new Schema({ + user: { type: Number }, + nice: { type: Number }, + sys: { type: Number }, + idle: { type: Number }, + irq: { type: Number }, +}); + +const MemoryInfoSchema = new Schema({ + total: { type: Number }, + free: { type: Number }, + used: { type: Number }, + active: { type: Number }, + available: { type: Number }, + buffers: { type: Number }, + cached: { type: Number }, + slab: { type: Number }, + buffcache: { type: Number }, + swaptotal: { type: Number }, + swapused: { type: Number }, + swapfree: { type: Number }, +}); + +const CacheStatsSchema = new Schema({ + itemCount: { type: Number, required: true }, + dataSize: { type: Number, required: true }, + expireCount: { type: Number, required: true }, + expireDataSize: { type: Number, required: true }, + hitCount: { type: Number, required: true }, + hitDataSize: { type: Number, required: true }, + missCount: { type: Number, required: true }, + missDataSize: { type: Number, required: true }, +}); + +const DiskUsageSchema = new Schema({ + total: { type: Number }, + used: { type: Number }, + available: { type: Number }, + pctUsed: { type: Number }, +}); + +const NetworkInterfaceStatsSchema = new Schema({ + iface: { type: String, required: true }, + rxPerSecond: { type: Number }, + rxDropped: { type: Number }, + rxErrors: { type: Number }, + txPerSecond: { type: Number }, + txDropped: { type: Number }, + txErrors: { type: Number }, +}); + +const NetHostStatsSchema = new Schema({ + created: { type: Date, default: Date.now, required: true, index: 1, expires: '7d' }, + host: { type: Schema.ObjectId, required: true, index: 1, ref: 'NetHost' }, + load: { type: [Number], required: true }, + cpus: { type: [CpuInfoSchema], required: true }, + memory: { type: MemoryInfoSchema, required: true }, + cache: { type: CacheStatsSchema, required: true }, + disk: { + cache: { type: DiskUsageSchema, required: true }, + }, + network: { type: [NetworkInterfaceStatsSchema], required: true }, +}); + +module.exports = mongoose.model('NetHostStats', NetHostStatsSchema); \ No newline at end of file diff --git a/app/models/net-host.js b/app/models/net-host.js new file mode 100644 index 0000000..5114493 --- /dev/null +++ b/app/models/net-host.js @@ -0,0 +1,45 @@ +// net-host.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const CpuInfoSchema = new Schema({ + model: { type: String }, + speed: { type: Number }, +}); + +const NetworkInterfaceSchema = new Schema({ + iface: { type: String, required: true }, + speed: { type: Number }, + mac: { type: String }, + ip4: { type: String }, + ip4subnet: { type: String }, + ip6: { type: String }, + ip6subnet: { type: String }, + flags: { + internal: { type: Boolean }, + virtual: { type: Boolean }, + }, +}); + +const NetHostSchema = new Schema({ + created: { type: Date, default: Date.now, required: true, index: 1 }, + updated: { type: Date }, + status: { type: String, enum: ['starting', 'active', 'shutdown', 'inactive', 'crashed'], required: true, index: 1 }, + hostname: { type: String, required: true, index: 1 }, + arch: { type: String, required: true }, + cpus: { type: [CpuInfoSchema], required: true }, + totalmem: { type: Number, required: true }, + freemem: { type: Number, required: true }, + platform: { type: String, required: true }, + release: { type: String, required: true }, + version: { type: String, required: true }, + network: { type: [NetworkInterfaceSchema] }, +}); + +module.exports = mongoose.model('NetHost', NetHostSchema); \ No newline at end of file diff --git a/app/models/otp-account.js b/app/models/otp-account.js new file mode 100644 index 0000000..44e35e0 --- /dev/null +++ b/app/models/otp-account.js @@ -0,0 +1,38 @@ +// otp-account.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +var OtpBackupTokenSchema = new Schema({ + token: { type: String, required: true }, + claimed: { type: Date }, +}); + +const OtpAccountSchema = new Schema({ + created: { type: Date, default: Date.now, required: true, index: -1 }, + domain: { type: Schema.ObjectId, required: true, index: true, ref: 'Domain' }, + user: { type: Schema.ObjectId, required: true, index: true, ref: 'User' }, + service: { type: String, required: true }, + secret: { type: String, required: true, select: false }, + algorithm: { type: String, required: true }, + step: { type: Number, default: 30, required: true, min: 15 }, + digits: { type: Number, default: 6, required: true, min: 6 }, + backupTokens: { type: [OtpBackupTokenSchema], select: false }, + lastVerification: { type: Date }, + lastVerificationIp: { type: String }, +}); + +OtpAccountSchema.index({ + domain: 1, + user: 1, + service: 1, +}, { + unique: true, + name: 'otp_user_svc_uniq_idx', +}); + +module.exports = mongoose.model('OtpAccount', OtpAccountSchema); \ No newline at end of file diff --git a/app/models/user.js b/app/models/user.js new file mode 100644 index 0000000..ae9933c --- /dev/null +++ b/app/models/user.js @@ -0,0 +1,37 @@ +// user.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); + +const Schema = mongoose.Schema; + +const UserFlagsSchema = new Schema({ + isAdmin: { type: Boolean, default: false, required: true }, + isModerator: { type: Boolean, default: false, required: true }, +}); + +const UserPermissionsSchema = new Schema({ + canLogin: { type: Boolean, default: true, required: true }, + canChat: { type: Boolean, default: true, required: true }, +}); + +const UserSchema = new Schema({ + created: { type: Date, default: Date.now, required: true, index: -1 }, + email: { type: String, required: true, lowercase: true, unique: true }, + username: { type: String, required: true }, + username_lc: { type: String, required: true, lowercase: true, unique: true, index: 1 }, + passwordSalt: { type: String, required: true }, + password: { type: String, required: true }, + displayName: { type: String }, + picture: { + large: { type: Schema.ObjectId, ref: 'Image' }, + small: { type: Schema.ObjectId, ref: 'Image' }, + }, + flags: { type: UserFlagsSchema, select: false }, + permissions: { type: UserPermissionsSchema, select: false }, +}); + +module.exports = mongoose.model('User', UserSchema); \ No newline at end of file diff --git a/app/services/article.js b/app/services/article.js new file mode 100644 index 0000000..a3135b4 --- /dev/null +++ b/app/services/article.js @@ -0,0 +1,66 @@ +// article.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const fs = require('fs'); + +const { SiteService } = require('../../lib/site-lib'); + +const mongoose = require('mongoose'); +const Article = mongoose.model('Article'); + +const marked = require('marked'); + +class ArticleService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + + this.populateArticle = [ + { + path: 'channel', + select: 'slug name images.icon status stats links', + }, + { + path: 'author', + select: '_id username username_lc displayName picture', + }, + ]; + } + + async start ( ) { + this.markedRenderer = new marked.Renderer(); + } + + async getById (articleId) { + const article = await Article + .findById(articleId) + .populate(this.populateArticle) + .lean(); + return article; + } + + async getForChannel (channel, pagination) { + const articles = await Article + .find({ channel: channel._id }) + .sort({ created: -1 }) + .skip(pagination.skip) + .limit(pagination.cpp) + .populate(this.populateArticle) + .lean(); + return articles; + } + + async renderMarkdown (documentFile) { + const markdown = await fs.promises.readFile(documentFile, 'utf8'); + return marked(markdown, { renderer: this.markedRenderer }); + } +} + +module.exports = { + slug: 'article', + name: 'article', + create: (dtp) => { return new ArticleService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/cache.js b/app/services/cache.js new file mode 100644 index 0000000..8e22986 --- /dev/null +++ b/app/services/cache.js @@ -0,0 +1,63 @@ +// cache.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const { SiteService } = require('../../lib/site-lib'); + +class CacheService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + } + + async set (name, value) { + return this.dtp.redis.set(name, value); + } + + async setEx (name, seconds, value) { + return this.dtp.redis.setex(name, seconds, value); + } + + async get (name) { + return this.dtp.redis.get(name); + } + + async setObject (name, value) { + return this.dtp.redis.set(name, JSON.stringify(value)); + } + + async setObjectEx (name, seconds, value) { + return this.dtp.redis.setex(name, seconds, JSON.stringify(value)); + } + + async getObject (name) { + const value = await this.dtp.redis.get(name); + if (!value) { + return; // undefined + } + return JSON.parse(value); + } + + async del (name) { + return this.dtp.redis.del(name); + } + + getKeys (pattern) { + return new Promise((resolve, reject) => { + return this.dtp.redis.keys(pattern, (err, response) => { + if (err) { + return reject(err); + } + return resolve(response); + }); + }); + } +} + +module.exports = { + slug: 'cache', + name: 'cache', + create: (dtp) => { return new CacheService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/crypto.js b/app/services/crypto.js new file mode 100644 index 0000000..dc89f9e --- /dev/null +++ b/app/services/crypto.js @@ -0,0 +1,64 @@ +// crypto.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const crypto = require('crypto'); + +const { SiteService } = require('../../lib/site-lib'); + +class CryptoService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + } + + maskPassword (passwordSalt, password) { + const hash = crypto.createHash('sha256'); + + hash.update(process.env.DTP_PASSWORD_SALT); + hash.update(passwordSalt); + hash.update(password); + + return hash.digest('hex'); + } + + createHash (content, algorithm = 'sha256') { + const hash = crypto.createHash(algorithm); + hash.update(content); + return hash.digest('hex'); + } + + hash32 (text) { + var hash = 0, i, chr; + if (text.length === 0) { + return hash; + } + for (i = text.length - 1; i >= 0; --i) { + chr = text.charCodeAt(i); + // jshint ignore:start + hash = ((hash << 5) - hash) + chr; + hash |= 0; + // jshint ignore:end + } + hash = hash.toString(16); + if (hash[0] === '-') { + hash = hash.slice(1); + } + return hash; + } + + createProof (secret, challenge) { + let hash = crypto.createHash('sha256'); + hash.update(secret); + hash.update(challenge); + return hash.digest('hex'); + } +} + +module.exports = { + slug: 'crypto', + name: 'crypto', + create: (dtp) => { return new CryptoService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/csrf-token.js b/app/services/csrf-token.js new file mode 100644 index 0000000..273d513 --- /dev/null +++ b/app/services/csrf-token.js @@ -0,0 +1,79 @@ +// csrf-token.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const moment = require('moment'); +const mongoose = require('mongoose'); +const uuidv4 = require('uuid').v4; + +const CsrfToken = mongoose.model('CsrfToken'); +const { SiteService } = require('../../lib/site-lib'); + +class CsrfTokenService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + } + + middleware (options) { + return async (req, res, next) => { + const requestToken = req.body[`csrf-token-${options.name}`]; + if (!requestToken) { + return next(new Error('Must include valid CSRF token')); + } + + const token = await CsrfToken.findOne({ token: requestToken }); + if (!token) { + return next(new Error('CSRF request token is invalid')); + } + if (token.ip !== req.ip) { + return next(new Error('CSRF request token client mismatch')); + } + + if (token.user) { + if (!req.user) { + return next(new Error('Must be logged in')); + } + if (!token.user.equals(req.user._id)) { + return next(new Error('CSRF request token user mismatch')); + } + } + + this.log.info('claiming CSRF token', { + requestToken, + ip: req.ip, + }); + await CsrfToken.updateOne( + { _id: token._id }, + { $set: { claimed: new Date() } }, + ); + + return next(); + }; + } + + async create (req, options) { + options = Object.assign({ + expiresMinutes: 30, + }, options); + const now = new Date(); + let csrfToken = await CsrfToken.create({ + created: now, + expires: moment(now).add(options.expiresMinutes, 'minute').toDate(), + user: req.user ? req.user._id : null, + ip: req.ip, + token: uuidv4(), + }); + csrfToken = csrfToken.toObject(); + csrfToken.name = `csrf-token-${options.name}`; + return csrfToken; + } +} + +module.exports = { + slug: 'csrf-token', + name: 'csrfToken', + create: (dtp) => { return new CsrfTokenService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/display-engine.js b/app/services/display-engine.js new file mode 100644 index 0000000..3e3b971 --- /dev/null +++ b/app/services/display-engine.js @@ -0,0 +1,125 @@ +// display-engine.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const path = require('path'); + +const pug = require('pug'); +const uuidv4 = require('uuid').v4; + +const { SiteService, SiteError } = require('../../lib/site-lib'); + +class DisplayList { + + constructor (service, name) { + this.name = name; + this.id = uuidv4(); + this.commands = [ ]; + } + + showNotification (message, status, pos, timeout) { + this.commands.push({ + action: 'showNotification', + params: { message, status, pos, timeout }, + }); + } + + addElement (selector, where, html) { + this.commands.push({ + selector, action: 'addElement', + params: { where, html }, + }); + } + + setTextContent (selector, text) { + this.commands.push({ + selector, action: 'setTextContent', + params: { text }, + }); + } + + replaceElement (selector, html) { + this.commands.push({ + selector, action: 'replaceElement', + params: { html }, + }); + } + + removeElement (selector) { + this.commands.push({ + selector, action: 'removeElement', + params: { }, + }); + } + + setAttribute (selector, name, value) { + this.commands.push({ + selector, action: 'setAttribute', + params: { name, value }, + }); + } + + removeAttribute (selector, name) { + this.commands.push({ + selector, action: 'removeAttribute', + params: { name }, + }); + } + + addClass (selector, add) { + this.commands.push({ + selector, action: 'addClass', + params: { add }, + }); + } + + removeClass (selector, remove) { + this.commands.push({ + selector, action: 'removeClass', + params: { remove }, + }); + } + + replaceClass (selector, remove, add) { + this.commands.push({ + selector, action: 'replaceClass', + params: { remove, add }, + }); + } +} + +class DisplayEngineService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + this.templates = { }; + } + + async start ( ) { } + + async stop ( ) { } + + loadTemplate (name, pugScript) { + const scriptFile = path.join(this.dtp.config.root, 'app', 'views', pugScript); + this.templates[name] = pug.compileFile(scriptFile); + } + + executeTemplate (name, data) { + if (!this.templates[name]) { + this.log.error('view engine template undefined', { name }); + throw new SiteError(500, 'Unknown display engine template'); + } + data = Object.assign(this.dtp.app.locals, data); + return this.templates[name](data); + } + + createDisplayList (name = 'default') { return new DisplayList(this, name); } +} + +module.exports = { + slug: 'display-engine', + name: 'displayEngine', + create: (dtp) => { return new DisplayEngineService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/domain.js b/app/services/domain.js new file mode 100644 index 0000000..af9c48a --- /dev/null +++ b/app/services/domain.js @@ -0,0 +1,72 @@ +// domain.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const striptags = require('striptags'); + +const mongoose = require('mongoose'); +const Domain = mongoose.model('Domain'); + +const { SiteService, SiteError } = require('../../lib/site-lib'); + +class DomainService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + } + + async create (domainDefinition) { + const NOW = new Date(); + const domain = new Domain(); + domain.created = NOW; + domain.name = striptags(domainDefinition.name.trim().toLowerCase()); + await domain.save(); + return domain.toObject(); + } + + async update (domain, domainDefinition) { + await Domain.updateOne( + { _id: domain._id }, + { + $set: { + name: striptags(domainDefinition.name.trim().toLowerCase()), + }, + }, + ); + } + + async getSiteDomain ( ) { + return this.getByName(process.env.DTP_SITE_DOMAIN_KEY); + } + + async getById (domainId) { + const domain = await Domain.findById(domainId).lean(); + return domain; + } + + async getByName (domainName) { + const domain = await Domain.findOne({ name: domainName.toLowerCase().trim() }).lean(); + if (!domain) { + throw new SiteError(404, 'Domain does not exist'); + } + return domain; + } + + async getDomains (pagination) { + const domains = await Domain + .find() + .sort({ name: 1 }) + .skip(pagination.skip) + .limit(pagination.cpp) + .lean(); + return domains; + } +} + +module.exports = { + slug: 'domain', + name: 'domain', + create: (dtp) => { return new DomainService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/email.js b/app/services/email.js new file mode 100644 index 0000000..eb4742e --- /dev/null +++ b/app/services/email.js @@ -0,0 +1,103 @@ +// email.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const path = require('path'); +const pug = require('pug'); + +const mailgun = require('mailgun-js'); + +const mongoose = require('mongoose'); +const EmailBlacklist = mongoose.model('EmailBlacklist'); + +const disposableEmailDomains = require('disposable-email-provider-domains'); +const emailValidator = require('email-validator'); +const emailDomainCheck = require('email-domain-check'); + +const { SiteService } = require('../../lib/site-lib'); + +class EmailService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + } + + async start ( ) { + await super.start(); + + if (process.env.DTP_MAILGUN_ENABLED === 'enabled') { + this.mg = mailgun({ + apiKey: process.env.MAILGUN_API_KEY, + domain: process.env.MAILGUN_DOMAIN, + }); + } + + this.templates = { + html: { + welcome: pug.compileFile(path.join(this.dtp.config.root, 'app', 'templates', 'html', 'welcome.pug')), + }, + text: { + welcome: pug.compileFile(path.join(this.dtp.config.root, 'app', 'templates', 'text', 'welcome.pug')), + }, + }; + } + + async send (message) { + return new Promise((resolve, reject) => { + this.log.info('sending email', { to: message.to, subject: message.subject }); + this.mg.messages().send(message, async (error, body) => { + if (error) { + return reject(error); + } + resolve(body); + }); + }); + } + + async checkEmailAddress (emailAddress) { + this.log.debug('validating email address', { emailAddress }); + if (!emailValidator.validate(emailAddress)) { + throw new Error('Email address is invalid'); + } + + const domainCheck = await emailDomainCheck(emailAddress); + this.log.debug('email domain check', { domainCheck }); + if (!domainCheck) { + throw new Error('Email address is invalid'); + } + + await this.isEmailBlacklisted(emailAddress); + } + + async isEmailBlacklisted (emailAddress) { + emailAddress = emailAddress.toLowerCase().trim(); + + const domain = emailAddress.split('@')[1]; + this.log.debug('checking email domain for blacklist', { domain }); + if (disposableEmailDomains.domains.includes(domain)) { + this.log.alert('blacklisted email domain blocked', { emailAddress, domain }); + throw new Error('Invalid email address'); + } + + const blacklistRecord = await EmailBlacklist.findOne({ email: emailAddress }); + if (blacklistRecord) { + throw new Error('Email address has requested to not receive emails', { blacklistRecord }); + } + + return false; + } + + async renderTemplate (templateId, templateType, message) { + return this.templates[templateType][templateId](message); + } +} + +module.exports = { + slug: 'email', + name: 'email', + create: (dtp) => { + return new EmailService(dtp); + }, +}; \ No newline at end of file diff --git a/app/services/host-cache.js b/app/services/host-cache.js new file mode 100644 index 0000000..b4143e5 --- /dev/null +++ b/app/services/host-cache.js @@ -0,0 +1,100 @@ +// host-cache.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const dgram = require('dgram'); +const uuidv4 = require('uuid').v4; + +const { SiteService, SiteError } = require('../../lib/site-lib'); + +class HostCacheService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + this.transactions = { }; + } + + async start ( ) { + await super.start(); + + this.log.info('creating UDP host-cache socket'); + this.hostCache = dgram.createSocket('udp4', this.onMessage.bind(this)); + this.hostCache.on('error', this.onError.bind(this)); + + this.log.info('connecting UDP host-cache socket'); + this.hostCache.bind(0, '127.0.0.1'); + this.hostCache.connect(8000, '127.0.0.1'); + } + + async stop ( ) { + if (this.hostCache) { + this.log.info('disconnecting UDP host-cache socket'); + this.hostCache.disconnect(); + delete this.hostCache; + } + } + + async getFile (bucket, key) { + return new Promise((resolve, reject) => { + const transaction = { tid: uuidv4(), bucket, key, resolve, reject }; + this.transactions[transaction.tid] = transaction; + const message = JSON.stringify({ + tid: transaction.tid, + cmd: 'getFile', + params: { bucket, key }, + }); + this.hostCache.send(message); + }); + } + + async onMessage (message, rinfo) { + message = message.toString('utf8'); + message = JSON.parse(message); + switch (message.res.cmd) { + case 'getFile': + return this.onGetFile(message, rinfo); + } + } + + async onGetFile (message) { + const transaction = this.transactions[message.tid]; + if (!transaction) { + this.log.error('getFile response received with no matching transaction', { tid: message.tid }); + return; + } + if (!message.res.success) { + transaction.reject(new SiteError(message.res.statusCode, message.res.message)); + delete this.transactions[message.tid]; + return; + } + transaction.resolve({ + success: message.res.success, + message: message.res.message, + file: message.res.file, + flags: message.flags, + duration: message.duration, + }); + delete this.transactions[message.tid]; + } + + async onError (error) { + this.log.error('onError', { error }); + if ((error.errno !== -111) || (error.code !== 'ECONNREFUSED')) { + return; + } + const keys = Object.keys(this.transactions); + keys.forEach((key) => { + const transaction = this.transactions[key]; + transaction.reject(error); + delete this.transactions[key]; + }); + } +} + +module.exports = { + slug: 'host-cache', + name: 'hostCache', + create: (dtp) => { return new HostCacheService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/image.js b/app/services/image.js new file mode 100644 index 0000000..f1c1423 --- /dev/null +++ b/app/services/image.js @@ -0,0 +1,225 @@ +// minio.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const path = require('path'); +const fs = require('fs'); + +const mongoose = require('mongoose'); +const SiteImage = mongoose.model('Image'); + +const sharp = require('sharp'); + +const { SiteService, SiteAsync } = require('../../lib/site-lib'); + +class ImageService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + this.populateImage = [ + { + path: 'owner', + select: '_id username username_lc displayName picture' + }, + ]; + } + + async start ( ) { + await super.start(); + await fs.promises.mkdir(process.env.DTP_IMAGE_WORK_PATH, { recursive: true }); + } + + async create (owner, imageDefinition, file) { + const NOW = new Date(); + const { minio: minioService } = this.dtp.services; + + this.log.debug('processing uploaded image', { imageDefinition, file }); + + const sharpImage = await sharp(file.path); + const metadata = await sharpImage.metadata(); + + // create an Image model instance, but leave it here in application memory. + // we don't persist it to the db until MinIO accepts the binary data. + const image = new SiteImage(); + image.created = NOW; + image.owner = owner._id; + image.type = file.mimetype; + image.size = file.size; + image.file.bucket = process.env.MINIO_IMAGE_BUCKET; + image.metadata = this.makeImageMetadata(metadata); + + const imageId = image._id.toString(); + const ownerId = owner._id.toString(); + const fileKey = `/${ownerId.slice(0, 3)}/${ownerId}/${imageId.slice(0, 3)}/${imageId}`; + image.file.key = fileKey; + + // upload the image file to MinIO + const response = await minioService.uploadFile({ + bucket: image.file.bucket, + key: image.file.key, + filePath: file.path, + metadata: { + 'Content-Type': file.mimetype, + 'Content-Length': file.size, + }, + }); + + // store the eTag from MinIO in the Image model + image.file.etag = response.etag; + + // save the Image model to the db + await image.save(); + + this.log.info('processed uploaded image', { ownerId, imageId, fileKey }); + return image.toObject(); + } + + async getImageById (imageId) { + const image = await SiteImage + .findById(imageId) + .populate(this.populateImage); + return image; + } + + async getRecentImagesForOwner (owner) { + const images = await SiteImage + .find({ owner: owner._id }) + .sort({ created: -1 }) + .limit(10) + .populate(this.populateImage) + .lean(); + return images; + } + + async deleteImage (image) { + const { minio: minioService } = this.dtp.services; + + this.log.debug('removing image from storage', { bucket: image.file.bucket, key: image.file.key }); + await minioService.removeObject(image.file.bucket, image.file.key); + + this.log.debug('removing image from MongoDB', { _id: image._id }); + await SiteImage.deleteOne({ _id: image._id }); + } + + async processImageFile (owner, file, outputs, options) { + this.log.debug('processing image file', { owner, file, outputs }); + const sharpImage = sharp(file.path); + return this.processImage(owner, sharpImage, outputs, options); + } + + async processImage (owner, sharpImage, outputs, options) { + const NOW = new Date(); + const service = this; + const { minio: minioService } = this.dtp.services; + + options = Object.assign({ + removeWorkFiles: true, + }, options); + + const imageWorkPath = process.env.DTP_IMAGE_WORK_PATH || '/tmp'; + const metadata = await sharpImage.metadata(); + + async function processOutputImage (output) { + const outputMetadata = service.makeImageMetadata(metadata); + outputMetadata.width = output.width; + outputMetadata.height = output.height; + + service.log.debug('processing image', { output, outputMetadata }); + + const image = new SiteImage(); + image.created = NOW; + image.owner = owner._id; + image.type = `image/${output.format}`; + image.metadata = outputMetadata; + + try { + let chain = sharpImage.clone().resize({ width: output.width, height: output.height }); + chain = chain[output.format](output.formatParameters); + + output.filePath = path.join(imageWorkPath, `${image._id}.${output.width}x${output.height}.${output.format}`); + output.mimetype = `image/${output.format}`; + await chain.toFile(output.filePath); + output.stat = await fs.promises.stat(output.filePath); + } catch (error) { + service.log.error('failed to process output image', { output, error }); + throw error; + } + + try { + const imageId = image._id.toString(); + const ownerId = owner._id.toString(); + const fileKey = `/${ownerId.slice(0, 3)}/${ownerId}/images/${imageId.slice(0, 3)}/${imageId}.${output.format}`; + + image.file.bucket = process.env.MINIO_IMAGE_BUCKET; + image.file.key = fileKey; + image.size = output.stat.size; + + // upload the image file to MinIO + const response = await minioService.uploadFile({ + bucket: image.file.bucket, + key: image.file.key, + filePath: output.filePath, + metadata: { + 'Content-Type': output.mimetype, + 'Content-Length': output.stat.size, + }, + }); + + // store the eTag from MinIO in the Image model + image.file.etag = response.etag; + + // save the Image model to the db + await image.save(); + + service.log.info('processed uploaded image', { ownerId, imageId, fileKey }); + + if (options.removeWorkFiles) { + service.log.debug('removing work file', { path: output.filePath }); + await fs.promises.unlink(output.filePath); + delete output.filePath; + } + + output.image = { + _id: image._id, + bucket: image.file.bucket, + key: image.file.key, + }; + } catch (error) { + service.log.error('failed to persist output image', { output, error }); + if (options.removeWorkFiles) { + service.log.debug('removing work file', { path: output.filePath }); + await SiteAsync.each(outputs, async (output) => { + await fs.promises.unlink(output.filePath); + delete output.filePath; + }, 4); + } + throw error; + } + } + + await SiteAsync.each(outputs, processOutputImage, 4); + } + + makeImageMetadata (metadata) { + return { + format: metadata.format, + size: metadata.size, + width: metadata.width, + height: metadata.height, + space: metadata.space, + channels: metadata.channels, + depth: metadata.depth, + density: metadata.density, + hasAlpha: metadata.hasAlpha, + orientation: metadata.orientation, + }; + } +} + +module.exports = { + slug: 'image', + name: 'image', + create: (dtp) => { return new ImageService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/job-queue.js b/app/services/job-queue.js new file mode 100644 index 0000000..3f93f6d --- /dev/null +++ b/app/services/job-queue.js @@ -0,0 +1,73 @@ +// job-queue.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const BullQueue = require('bull'); + +const { /*SiteError,*/ SiteService } = require('../../lib/site-lib'); + +class JobQueueService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + this.queues = { }; + } + + async start ( ) { } + + async stop ( ) { } + + getJobQueue (name, defaultJobOptions) { + /* + * If we have a named queue, return it. + */ + let queue = this.queues[name]; + if (queue) { + return queue; + } + + /* + * Create a new named queue + */ + defaultJobOptions = Object.assign({ + priority: 10, + delay: 0, + attempts: 1, + removeOnComplete: true, + removeOnFail: false, + }, defaultJobOptions); + + queue = new BullQueue(name, { + prefix: process.env.DTP_BULL_PREFIX || 'dtp', + redis: { + host: process.env.REDIS_HOST, + port: parseInt(process.env.REDIS_PORT || '6379', 10), + password: process.env.REDIS_PASSWORD, + keyPrefix: process.env.REDIS_KEY_PREFIX, + lazyConnect: true, + }, + defaultJobOptions, + }); + queue.setMaxListeners(64); + this.queues[name] = queue; + + return queue; + } + + async discoverJobQueues (pattern) { + const { cache: cacheService } = this.dtp.services; + let bullQueues = await cacheService.getKeys(pattern); + return bullQueues + .map((queue) => queue.split(':')[1]) + .sort() + ; + } +} + +module.exports = { + slug: 'job-queue', + name: 'jobQueue', + create: (dtp) => { return new JobQueueService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/limiter.js b/app/services/limiter.js new file mode 100644 index 0000000..b06d05c --- /dev/null +++ b/app/services/limiter.js @@ -0,0 +1,61 @@ +// limiter.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const path = require('path'); +const expressLimiter = require('express-limiter'); + +const { SiteService, SiteError } = require('../../lib/site-lib'); + +class LimiterService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + this.config = require(path.resolve(dtp.config.root, 'config', 'limiter.js')); + + this.limiter = expressLimiter(this.dtp.app, this.dtp.redis); + + this.handlers = { + lookup: this.limiterLookup.bind(this), + whitelist: this.limiterWhitelist.bind(this), + }; + } + + create (config) { + const options = { + total: config.total, + expire: config.expire, + lookup: this.handlers.lookup, + whitelist: this.handlers.whitelist, + onRateLimited: async (req, res, next) => { + this.emit('limiter:block', req); + next(new SiteError(config.status || 429, config.message || 'Rate limit exceeded')); + }, + }; + const middleware = this.limiter(options); + return async (req, res, next) => { + return middleware(req, res, next); + }; + } + + limiterLookup (req, res, options, next) { + if (req.user) { + options.lookup = 'user._id'; // req.user._id, populated by PassportJS session + } else { + options.lookup = 'ip'; // req.ip, populated by ExpressJS with trust_proxy=1 + } + return next(); + } + + limiterWhitelist (req) { + return req.user && req.user.flags.isAdmin; + } +} + +module.exports = { + slug: 'limiter', + name: 'limiter', + create: (dtp) => { return new LimiterService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/media.js b/app/services/media.js new file mode 100644 index 0000000..4d2b72a --- /dev/null +++ b/app/services/media.js @@ -0,0 +1,100 @@ +// article.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const util = require('util'); +const execFile = util.promisify(require('child_process').execFile); + +const { SiteService } = require('../../lib/site-lib'); + +class MediaService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + } + + async ffmpeg (ffmpegArgs) { + try { + await execFile(process.env.DTP_FFMPEG_PATH, ffmpegArgs, { + cwd: this.dtp.config.root, + encoding: 'utf8', + }); + } catch (error) { + this.log.error('failed to execute ffprobe', { ffmpegArgs, error }); + throw error; + } + } + + async ffprobe (input, options) { + options = Object.assign({ + streams: true, + format: true, + error: true, + }, options); + const ffprobeOpts = ['-print_format', 'json']; + if (options.streams) { + ffprobeOpts.push('-show_streams'); + } + if (options.format) { + ffprobeOpts.push('-show_format'); + } + if (options.error) { + ffprobeOpts.push('-show_error'); + } + ffprobeOpts.push(input); + + try { + const { stdout } = await execFile(process.env.DTP_FFPROBE_PATH, ffprobeOpts, { + cwd: this.dtp.config.root, + encoding: 'utf8', + }); + const probe = JSON.parse(stdout); + + if (probe.format && probe.format.tags) { + let keys = Object.keys(probe.format.tags); + keys.forEach((key) => { + probe.format.tags[key.replace(/\./g, '_')] = probe.format.tags[key]; + delete probe.format.tags[key]; + }); + } + + probe.duration = probe.format.duration; + probe.width = probe.format.width; + + if (Array.isArray(probe.streams) && probe.streams.length) { + const stream = probe.streams + .find((stream) => stream.codec_type === 'video') || probe.streams[0]; + + if (stream.duration) { + probe.duration = parseFloat(stream.duration); + } else { + probe.duration = parseFloat(probe.format.duration); + } + probe.width = stream.width; + probe.height = stream.height; + + const fpsFraction = stream.avg_frame_rate.split('/').map((value) => parseInt(value, 10)); + if (Array.isArray(fpsFraction) && fpsFraction[1] !== 0) { + probe.fps = fpsFraction[0] / fpsFraction[1]; + } + } else { + probe.duration = undefined; + probe.width = undefined; + probe.height = undefined; + } + + return probe; + } catch (error) { + this.log.error('failed to execute ffprobe', { input, error }); + throw error; + } + } +} + +module.exports = { + slug: 'media', + name: 'media', + create: (dtp) => { return new MediaService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/minio.js b/app/services/minio.js new file mode 100644 index 0000000..b523c5d --- /dev/null +++ b/app/services/minio.js @@ -0,0 +1,76 @@ +// minio.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const Minio = require('minio'); + +const { SiteService } = require('../../lib/site-lib'); + +class MinioService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + } + + async start ( ) { + await super.start(); + + this.minio = new Minio.Client({ + endPoint: process.env.MINIO_ENDPOINT, + port: parseInt(process.env.MINIO_PORT, 10), + useSSL: (process.env.MINIO_USE_SSL === 'enabled'), + accessKey: process.env.MINIO_ACCESS_KEY, + secretKey: process.env.MINIO_SECRET_KEY, + }); + } + + async stop ( ) { + this.log.info(`stopping ${module.exports.name} service`); + } + + async uploadFile (fileInfo) { + try { + const result = await this.minio.fPutObject( + fileInfo.bucket, + fileInfo.key, + fileInfo.filePath, + fileInfo.metadata + ); + return result; + } catch (error) { + this.log.error('failed to upload file to MinIO', { fileInfo, error }); + throw error; + } + } + + async downloadFile (fileInfo) { + await this.minio.fGetObject(fileInfo.bucket, fileInfo.key, fileInfo.filePath); + } + + async openDownloadStream (fi) { + if (fi.range) { + const length = fi.range.end - fi.range.start + 1; + const stream = await this.minio.getPartialObject(fi.bucket, fi.key, fi.range.start, length); + return stream; + } + const stream = await this.minio.getObject(fi.bucket, fi.key); + return stream; + } + + async removeObject (bucket, key) { + try { + await this.minio.removeObject(bucket, key); + } catch (error) { + this.log.error('failed to remove object', { bucket, key, error }); + throw error; + } + } +} + +module.exports = { + slug: 'minio', + name: 'minio', + create: (dtp) => { return new MinioService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/otp-auth.js b/app/services/otp-auth.js new file mode 100644 index 0000000..ad41b65 --- /dev/null +++ b/app/services/otp-auth.js @@ -0,0 +1,224 @@ +// otp-auth.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +// const striptags = require('striptags'); + +const mongoose = require('mongoose'); +const OtpAccount = mongoose.model('OtpAccount'); + +const ONE_HOUR = 1000 * 60 * 60; +const OTP_SESSION_DURATION = (process.env.NODE_ENV === 'local') ? (ONE_HOUR * 24) : (ONE_HOUR * 2); + +const { authenticator } = require('otplib'); +const uuidv4 = require('uuid').v4; + +const { SiteService, SiteError } = require('../../lib/site-lib'); + +class DomainService extends SiteService { + + constructor (dtp) { + super(dtp, module.exports); + } + + async start ( ) { + const { domain: domainService } = this.dtp.services; + this.siteDomain = await domainService.getSiteDomain(); + + authenticator.options = { + algorithm: 'sha1', + step: 30, + digits: 6, + }; + } + + middleware (serviceName, options) { + options = Object.assign({ + otpRequired: false, + otpRedirectURL: '/', + adminRequired: false, + }, options); + return async (req, res, next) => { + res.locals.otp = { }; // will decorate view model with OTP information + if (!req.session) { + return next(new SiteError(403, 'Request session is invalid')); + } + if (!req.user) { + return next(new SiteError(403, 'Must be logged in')); + } + if (options.adminRequired && !req.user.flags.isAdmin) { + return next(new SiteError(403, 'Admin privileges are required')); + } + + req.session.otp = req.session.otp || { }; + if (await this.checkOtpSession(req, serviceName)) { + return next(); // user is OTP-authenticated on this service + } + + res.locals.otpOptions = authenticator.options; + res.locals.otpServiceName = serviceName; + res.locals.otpAlgorithm = authenticator.options.algorithm.toUpperCase(); + res.locals.otpDigits = authenticator.options.digits; + res.locals.otpPeriod = authenticator.options.step; + + if (typeof options.otpRedirectURL === 'function') { + // allows redirect to things like /user/:userId using current session's user + res.locals.otpRedirectURL = await options.otpRedirectURL(req, res); + } else { + res.locals.otpRedirectURL = options.otpRedirectURL; + } + + res.locals.otpAccount = await OtpAccount + .findOne({ + domain: this.siteDomain._id, + user: req.user._id, + service: serviceName, + }); + if (!res.locals.otpAccount && !options.otpRequired) { + return next(); // route not guarded (am I a joke to you?) + } + + if (!res.locals.otpAccount) { + res.locals.otpTempSecret = authenticator.generateSecret(); + res.locals.otpKeyURI = authenticator.keyuri( + req.user.username.trim(), + `${this.dtp.config.site.name}: ${serviceName}`, + res.locals.otpTempSecret, + ); + req.session.otp[serviceName] = req.session.otp[serviceName] || { }; + req.session.otp[serviceName].secret = res.locals.otpTempSecret; + req.session.otp[serviceName].redirectURL = res.locals.otpRedirectURL; + return res.render('otp/welcome'); + } + + res.locals.otpSession = req.session.otp[serviceName]; + + this.log.debug('request on OTP-required route with no authentication', { + service: serviceName, + ip: req.ip, + session: res.locals.otpSession, + }, req.user); + + req.session.otp[serviceName] = req.session.otp[serviceName] || { }; + req.session.otp[serviceName].redirectURL = res.locals.otpRedirectURL; + await this.saveSession(req); + + if (!res.locals.otpSession || !res.locals.otpSession.isAuthenticated) { + return res.render('otp/authenticate'); + } + + return next(); + }; + } + + async createOtpAccount (req, service, secret, passcode) { + const NOW = new Date(); + const { crypto: cryptoService } = this.dtp.services; + try { + this.log.info('verifying user passcode', { + user: req.user._id, + username: req.user.username, + service, secret, passcode, + }, req.user); + if (authenticator.check(passcode, secret)) { + throw new SiteError(403, 'Invalid passcode'); + } + + const backupTokens = [ ]; + for (let i = 0; i < 10; ++i) { + backupTokens.push({ + token: cryptoService.createHash(secret + uuidv4()), + }); + } + + const now = new Date(); + const account = await OtpAccount.create({ + created: NOW, + domain: this.siteDomain._id, + user: req.user._id, + service, + secret, + algorithm: authenticator.options.algorithm, + step: authenticator.options.step, + digits: authenticator.options.digits, + backupTokens, + lastVerification: now, + lastVerificationIp: req.ip, + }); + + return account; + } catch (error) { + this.log.error('failed to create OTP account', { + service, secret, passcode, error, + }, req.user); + throw error; + } + } + + async startOtpSession (req, serviceName, passcode) { + if (!passcode || (typeof passcode !== 'string')) { + throw new SiteError(403, 'Invalid passcode'); + } + try { + const account = await OtpAccount + .findOne({ user: req.user._id, service: serviceName }) + .select('+secret') + .lean(); + if (!account) { + throw new SiteError(400, 'Two-Factor Authentication not enabled'); + } + + const now = new Date(); + if (!authenticator.check(passcode, account.secret)) { + throw new SiteError(403, 'Invalid passcode'); + } + + req.session.otp = req.session.otp || { }; + req.session.otp[serviceName] = req.session.otp[serviceName] || { }; + req.session.otp[serviceName].isAuthenticated = true; + req.session.otp[serviceName].expiresAt = now.valueOf() + OTP_SESSION_DURATION; + await this.saveSession(req); + } catch (error) { + this.log.error('failed to start OTP session', { + serviceName, passcode, error, + }); + throw error; + } + } + + async checkOtpSession (req, serviceName) { + if (!req.session || !req.session.otp) { + return false; + } + + const session = req.session.otp[serviceName]; + if (!session) { + return false; + } + + if (!session.isAuthenticated) { + return false; + } + + const NOW = Date.now(); + if (NOW >= session.expiresAt) { + session.isAuthenticated = false; + delete session.expiresAt; + await this.saveSession(req); + return false; + } + + session.expiresAt = NOW + OTP_SESSION_DURATION; + await this.saveSession(req); + + return true; + } +} + +module.exports = { + slug: 'otp-auth', + name: 'otpAuth', + create: (dtp) => { return new DomainService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/session.js b/app/services/session.js new file mode 100644 index 0000000..7c6f226 --- /dev/null +++ b/app/services/session.js @@ -0,0 +1,83 @@ +// session.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const util = require('util'); + +const passport = require('passport'); + +const { SiteError, SiteLog } = require('../../lib/site-lib'); + +class SessionService { + + constructor (dtp) { + this.dtp = dtp; + this.log = new SiteLog(dtp, `svc:${module.exports.slug}`); + } + + async start ( ) { + this.log.info(`starting ${module.exports.name} service`); + passport.serializeUser(this.serializeUser.bind(this)); + passport.deserializeUser(this.deserializeUser.bind(this)); + } + + async stop ( ) { + this.log.info(`stopping ${module.exports.name} service`); + } + + middleware ( ) { + return async (req, res, next) => { + res.locals.user = req.user; + res.locals.query = req.query; + + if (req.user) { + if (req.user.flags.isAdmin) { + res.locals.config = this.dtp.config; + res.locals.session = req.session; + res.locals.util = util; + } + } + + return next(); + }; + } + + authCheckMiddleware (options) { + options = Object.assign({ + requireLogin: true, + requireAdmin: false, + }, options); + return async (req, res, next) => { + if (options.requireLogin && !req.user) { + return next(new SiteError(403, 'Must sign in to proceed')); + } + if (options.requireAdmin && (!req.user || !req.user.flags.isAdmin)) { + return next(new SiteError(403, 'Administrator privileges are required')); + } + return next(); + }; + } + + async serializeUser (user, done) { + return done(null, user._id); + } + + async deserializeUser (userId, done) { + const { user: userService } = this.dtp.services; + try { + const user = await userService.getUserAccount(userId); + return done(null, user); + } catch (error) { + this.log.error('failed to deserialize user from session', { error }); + return done(null, null); + } + } +} + +module.exports = { + slug: 'session', + name: 'session', + create: (dtp) => { return new SessionService(dtp); }, +}; \ No newline at end of file diff --git a/app/services/sms.js b/app/services/sms.js new file mode 100644 index 0000000..a4d3bb2 --- /dev/null +++ b/app/services/sms.js @@ -0,0 +1,55 @@ +// sms.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +// const mongoose = require('mongoose'); + +const libphonenumber = require('libphonenumber-js'); + +const { SiteLog } = require('../../lib/site-lib'); + +class SmsService { + + constructor (dtp) { + this.dtp = dtp; + this.log = new SiteLog(dtp, `svc:${module.exports.slug}`); + } + + async start ( ) { + this.log.info(`starting ${module.exports.name} service`); + } + + async stop ( ) { + this.log.info(`stopping ${module.exports.name} service`); + } + + async send (message) { + this.log.info('sending SMS', message); + } + + /** + * + * @param {*} phoneNumber + * @returns + */ + async checkPhoneNumber (phoneNumber) { + const { parsePhoneNumber } = libphonenumber; + + const phoneCheck = parsePhoneNumber(phoneNumber, 'US'); + if (!phoneCheck.isValid() || !phoneCheck.number) { + throw new Error('Invalid phone number'); + } + + return phoneCheck; // in case caller wants full data + } +} + +module.exports = { + slug: 'sms', + name: 'sms', + create: (dtp) => { + return new SmsService(dtp); + }, +}; \ No newline at end of file diff --git a/app/services/user.js b/app/services/user.js new file mode 100644 index 0000000..b4af09a --- /dev/null +++ b/app/services/user.js @@ -0,0 +1,385 @@ +// user.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const mongoose = require('mongoose'); +const User = mongoose.model('User'); + +const passport = require('passport'); +const PassportLocal = require('passport-local'); + +const striptags = require('striptags'); +const uuidv4 = require('uuid').v4; + +const { SiteError, SiteLog } = require('../../lib/site-lib'); + +class UserService { + + constructor (dtp) { + this.dtp = dtp; + this.log = new SiteLog(dtp, `svc:${module.exports.slug}`); + } + + async start ( ) { + this.log.info(`starting ${module.exports.name} service`); + this.registerPassportLocal(); + if (process.env.DTP_ADMIN === 'enabled') { + this.registerPassportAdmin(); + } + } + + async stop ( ) { + this.log.info(`stopping ${module.exports.name} service`); + } + + async create (userDefinition) { + const NOW = new Date(); + const { + crypto: cryptoService, + email: mailService, + } = this.dtp.services; + + try { + userDefinition.email = userDefinition.email.trim().toLowerCase(); + + // strip characters we don't want to allow in username + userDefinition.username = userDefinition.username.trim().replace(/[^A-Za-z0-9\-_]/gi, ''); + const username_lc = userDefinition.username.toLowerCase(); + + // test the email address for validity, blacklisting, etc. + await mailService.checkEmailAddress(userDefinition.email); + + // test if we already have a user with this email address + let user = await User.findOne({ 'email': userDefinition.email.toLowerCase().trim() }).lean(); + if (user) { + throw new SiteError(400, `An account with email address ${userDefinition.email} already exists.`); + } + + // test if we already have a user with this username + user = await User.findOne({ username_lc }).lean(); + if (user) { + throw new SiteError(400, `An account with username ${userDefinition.username} already exists.`); + } + + const passwordSalt = uuidv4(); + const maskedPassword = cryptoService.maskPassword(passwordSalt, userDefinition.password); + + user = new User(); + user.created = NOW; + + user.email = userDefinition.email; + user.username = userDefinition.username; + user.username_lc = username_lc; + + user.passwordSalt = passwordSalt; + user.password = maskedPassword; + + user.flags = { + isAdmin: false, + isModerator: false, + }; + + user.permissions = { + canLogin: true, + canChat: true, + }; + + this.log.info('creating new user account', { email: userDefinition.email }); + await user.save(); + + return user.toObject(); + } catch (error) { + this.log.error('failed to create user', { error }); + throw error; + } + } + + async update (user, userDefinition) { + // strip characters we don't want to allow in username + userDefinition.username = striptags(userDefinition.username.trim().replace(/[^A-Za-z0-9\-_]/gi, '')); + const username_lc = userDefinition.username.toLowerCase(); + + userDefinition.displayName = striptags(userDefinition.displayName.trim()); + + this.log.info('updating user', { userDefinition }); + await User.updateOne( + { _id: user._id }, + { + $set: { + username: userDefinition.username, + username_lc, + displayName: userDefinition.displayName, + 'flags.isAdmin': userDefinition.isAdmin === 'on', + 'flags.isModerator': userDefinition.isModerator === 'on', + 'permissions.canLogin': userDefinition.canLogin === 'on', + 'permissions.canChat': userDefinition.canChat === 'on', + }, + }, + ); + } + + async updateSettings (user, userDefinition) { + // strip characters we don't want to allow in username + userDefinition.username = striptags(userDefinition.username.trim().replace(/[^A-Za-z0-9\-_]/gi, '')); + const username_lc = userDefinition.username.toLowerCase(); + + userDefinition.displayName = striptags(userDefinition.displayName.trim()); + + this.log.info('updating user settings', { userDefinition }); + await User.updateOne( + { _id: user._id }, + { + $set: { + username: userDefinition.username, + username_lc, + displayName: userDefinition.displayName, + }, + }, + ); + } + + async authenticate (account, options) { + const { crypto } = this.dtp.services; + + options = Object.assign({ + adminRequired: false, + }, options); + + const accountEmail = account.username.trim().toLowerCase(); + const accountUsername = await this.filterUsername(accountEmail); + + this.log.debug('locating user record', { accountEmail, accountUsername }); + const user = await User + .findOne({ + $or: [ + { email: accountEmail }, + { username_lc: accountUsername }, + ] + }) + .select('+passwordSalt +password +flags') + .lean(); + if (!user) { + throw new SiteError(404, 'Member account not found'); + } + + const maskedPassword = crypto.maskPassword( + user.passwordSalt, + account.password, + ); + if (maskedPassword !== user.password) { + throw new SiteError(403, 'Account credentials do not match'); + } + + // remove these critical fields from the user object + delete user.passwordSalt; + delete user.password; + + if (options.adminRequired && !user.flags.isAdmin) { + throw new SiteError(403, 'Admin privileges required'); + } + + this.log.debug('user authenticated', { user }); + + return user; + } + + registerPassportLocal ( ) { + const options = { + usernameField: 'username', + passwordField: 'password', + session: true, + }; + passport.use('dtp-local', new PassportLocal(options, this.handleLocalLogin.bind(this))); + } + + async handleLocalLogin (username, password, done) { + const now = new Date(); + this.log.info('handleLocalLogin', { username, password }); + try { + const user = await this.authenticate({ username, password }, { adminRequired: false }); + await this.startUserSession(user, now); + done(null, this.filterUserObject(user)); + } catch (error) { + this.log.error('failed to process local user login', { error }); + done(error); + } + } + + registerPassportAdmin ( ) { + const options = { + usernameField: 'username', + passwordField: 'password', + session: true, + }; + this.log.info('registering PassportJS admin strategy', { options }); + passport.use('dtp-admin', new PassportLocal(options, this.handleAdminLogin.bind(this))); + } + + async handleAdminLogin (email, password, done) { + const now = new Date(); + try { + const user = await this.authenticate({ email, password }, { adminRequired: true }); + await this.startUserSession(user, now); + done(null, this.filterUserObject(user)); + } catch (error) { + this.log.error('failed to process admin user login', { error }); + done(error); + } + } + + async startUserSession (user, now) { + await User.updateOne( + { _id: user._id }, + { + $set: { 'stats.lastLogin': now }, + $inc: { 'stats.loginCount': 1 }, + }, + ); + } + + filterUserObject (user) { + return { + _id: user._id, + email: user.email, + created: user.created, + flags: user.flags, + permissions: user.permissions, + }; + } + + async getUserAccount (userId) { + const user = await User + .findById(userId) + .select('+email +flags +permissions') + .lean() + ; + if (!user) { + throw new SiteError(404, 'Member account not found'); + } + return user; + } + + async getUserAccounts (pagination) { + const users = await User + .find() + .sort({ username_lc: 1 }) + .select('+email +flags +permissions') + .skip(pagination.skip) + .limit(pagination.cpp) + .lean() + ; + return users; + } + + async getUserProfile (userId) { + let user; + try { + userId = mongoose.Types.ObjectId(userId); // will throw if invalid format + user = User.findById(userId); + } catch (error) { + user = User.findOne({ username: userId }); + } + user = await user.select('+email +flags +settings').lean(); + return user; + } + + async setUserSettings (user, settings) { + const { + crypto: cryptoService, + mail: mailService, + phone: phoneService, + } = this.dtp.platform.services; + + const update = { $set: { } }; + const actions = [ ]; + + if (settings.name && (settings.name !== user.name)) { + update.name = striptags(settings.name.trim()); + update.name_lc = update.name.toLowerCase(); + actions.push('Display name updated'); + } + + if (settings.username && (settings.username !== user.username)) { + update.username = this.filterUsername(settings.username); + const isReserved = await this.isUsernameReserved(update.username); + if (!isReserved) { + throw new SiteError(403, 'The username you entered is taken'); + } + } + + if (settings.email && (settings.email !== user.email)) { + settings.email = settings.email.toLowerCase().trim(); + await mailService.checkEmailAddress(settings.email); + update.$set['flags.isEmailVerified'] = false; + update.$set.email = settings.email; + actions.push('Email address updated and verification email sent. Please check your inbox and follow the instructions included to complete the change of your email address.'); + } + + /* + * User is changing the phone number stored on the account. + * "There's a lot to unpack here" + */ + if (settings.phone) { + // update the phone number (there's a lot going on here) + try { + update.$set.phone = await phoneService.processPhoneNumberInput(settings.phone); + } catch (error) { + throw error; + } + + // un-verify the account's phone number + update.$set['flags.isPhoneVerified'] = false; + + actions.push('Phone number updated and verification message sent. Please follow the instructions in the text message to complete the change of your mobile phone number.'); + } + + if (settings.password) { + if (settings.password !== settings.passwordv) { + throw new SiteError(400, 'Password and password verification do not match.'); + } + update.$set.passwordSalt = uuidv4(); + update.$set.password = cryptoService.maskPassword(update.$set.passwordSalt, settings.password); + actions.push('Password changed successfully.'); + } + + if (settings.theme) { + update.$set['settings.theme'] = striptags(settings.theme.trim()); + } + if (settings.language) { + update.$set['settings.language'] = mongoose.Types.ObjectId(settings.language); + actions.push('Interface language changed.'); + } + + await User.updateOne({ _id: user._id }, update); + + return actions; + } + + async filterUsername (username) { + return striptags(username.trim().toLowerCase()).replace(/\W/g, ''); + } + + async isUsernameReserved (username) { + const reservedNames = ['digitaltelepresence', 'dtp', 'rob', 'amy', 'zack']; + if (reservedNames.includes(username)) { + this.log.alert('prohibiting use of reserved username', { username }); + return true; + } + + const user = await User.findOne({ username: username}).select('username').lean(); + if (user) { + this.log.alert('username is already registered', { username }); + return true; + } + + return false; + } +} + +module.exports = { + slug: 'user', + name: 'user', + create: (dtp) => { return new UserService(dtp); }, +}; \ No newline at end of file diff --git a/app/templates/common/html/footer.pug b/app/templates/common/html/footer.pug new file mode 100644 index 0000000..8f74b15 --- /dev/null +++ b/app/templates/common/html/footer.pug @@ -0,0 +1,10 @@ +.common-footer + + p This email was sent to #{user.email} because you selected to receive emails from LocalRedAction.com. You can #[a(href=`https://localredaction.com/opt-out/${voter._id}/email`) opt out] at any time to stop receiving these emails. + + p You can request to stop receiving these emails in writing at: + address + div Local Red Action + div P.O. Box ######## + div McKees Rocks, PA 15136 + div USA \ No newline at end of file diff --git a/app/templates/common/html/header.pug b/app/templates/common/html/header.pug new file mode 100644 index 0000000..abd3ff7 --- /dev/null +++ b/app/templates/common/html/header.pug @@ -0,0 +1 @@ +.greeting Dear #{voter.name}, \ No newline at end of file diff --git a/app/templates/common/text/footer.pug b/app/templates/common/text/footer.pug new file mode 100644 index 0000000..a9e38f6 --- /dev/null +++ b/app/templates/common/text/footer.pug @@ -0,0 +1,9 @@ +| - - - +| This email was sent to #{user.email} because you selected to receive emails from LocalRedAction.com. Visit #{`https://localredaction.com/opt-out/${voter._id}/email`} to opt out and stop receiving these emails. +| +| You can request to stop receiving these emails in writing at: +| +| Local Red Action +| P.O. Box ######## +| McKees Rocks, PA 15136 +| USA \ No newline at end of file diff --git a/app/templates/common/text/header.pug b/app/templates/common/text/header.pug new file mode 100644 index 0000000..e0c2dc5 --- /dev/null +++ b/app/templates/common/text/header.pug @@ -0,0 +1 @@ +| Dear #{voter.name}, \ No newline at end of file diff --git a/app/templates/html/welcome.pug b/app/templates/html/welcome.pug new file mode 100644 index 0000000..ff8449d --- /dev/null +++ b/app/templates/html/welcome.pug @@ -0,0 +1,27 @@ +doctype html +html(lang='en') + head + meta(charset='UTF-8') + meta(name='viewport', content='width=device-width, initial-scale=1.0') + meta(name='description', content= pageDescription || siteDescription) + + title= pageTitle ? `${pageTitle} | ${site.name}` : site.name + + style(type="text/css"). + html, body { + margin: 0; + padding: 0; + } + .greeting { font-size: 1.5em; margin-bottom: 16px; } + .message {} + + body + + include ../common/html/header + + .message + p Welcome to #{service.name}! Please visit #[a(href=`https://localredaction.com/verify?t=${emailVerifyToken}`)= `https://localredaction.com/verify?t=${emailVerifyToken}`] to verify your email address. + + p Thank you for supporting your local Republican committee and candidates! + + include ../common/html/footer \ No newline at end of file diff --git a/app/templates/text/welcome.pug b/app/templates/text/welcome.pug new file mode 100644 index 0000000..678390a --- /dev/null +++ b/app/templates/text/welcome.pug @@ -0,0 +1,7 @@ +include ../common/text/header +| +| Welcome to #{service.name}! Please visit #[a(href=`https://localredaction.com/verify?t=${emailVerifyToken}`)= `https://localredaction.com/verify?t=${emailVerifyToken}`] to verify your email address. +| +| Thank you for supporting your local Republican committee and candidates! +| +include ../common/text/footer \ No newline at end of file diff --git a/app/views/admin/category/editor.pug b/app/views/admin/category/editor.pug new file mode 100644 index 0000000..ad57d93 --- /dev/null +++ b/app/views/admin/category/editor.pug @@ -0,0 +1,17 @@ +extends ../layouts/main +block content + + - var formAction = category ? `/admin/category/${category._id}` : '/admin/category'; + + pre= JSON.stringify(category, null, 2) + + form(method="POST", action= formAction).uk-form + .uk-margin + label(for="name").uk-form-label Category Name + input(id="name", name="name", type="text", placeholder="Enter category name", value= category ? category.name : undefined).uk-input + + .uk-margin + label(for="description").uk-form-label Description + textarea(id="description", name="description", rows="3", placeholder="Enter category description").uk-textarea= category ? category.description : undefined + + button(type="submit").uk-button.uk-button-primary= category ? 'Update Category' : 'Create Category' \ No newline at end of file diff --git a/app/views/admin/category/index.pug b/app/views/admin/category/index.pug new file mode 100644 index 0000000..d8e68e4 --- /dev/null +++ b/app/views/admin/category/index.pug @@ -0,0 +1,21 @@ +extends ../layouts/main +block content + + .uk-margin + div(uk-grid).uk-flex-middle + .uk-width-expand + h2 Category Manager + .uk-width-auto + a(href="/admin/category/create").uk-button.uk-button-primary + span + i.fas.fa-plus + span.uk-margin-small-left Add category + + .uk-margin + if Array.isArray(categories) && (categories.length > 0) + uk.uk-list + each category in categories + li + a(href=`/admin/category/${category._id}`)= category.name + else + h4 There are no categories. \ No newline at end of file diff --git a/app/views/admin/channel-application/index.pug b/app/views/admin/channel-application/index.pug new file mode 100644 index 0000000..32df09c --- /dev/null +++ b/app/views/admin/channel-application/index.pug @@ -0,0 +1,26 @@ +extends ../layouts/main +block content + + table.uk-table + thead + th Channel Name + th Domain + th Created + th Member + th Audience + th Status + tbody + each application in applications + tr + td + a(href=`/admin/channel-application/${application._id}`)= application.name + td= application.domain ? application.domain.name : 'N/A' + td= moment(application.created).fromNow() + td + a(href=`/admin/member/${application.owner._id}`)= application.owner.username + td= numeral(application.interview.audienceSize).format('0,0') + td(class={ + 'uk-text-primary': ['new','review'].includes(application.status), + 'uk-text-success': (application.status === 'approved'), + 'uk-text-danger': (application.status === 'rejected'), + })= application.status \ No newline at end of file diff --git a/app/views/admin/channel-application/view.pug b/app/views/admin/channel-application/view.pug new file mode 100644 index 0000000..dfff3f6 --- /dev/null +++ b/app/views/admin/channel-application/view.pug @@ -0,0 +1,79 @@ +extends ../layouts/main +block content + + .uk-card.uk-card-secondary.uk-card-body.uk-margin + fieldset.uk-fieldset + legend.sr-only Channel Information + div(uk-grid) + .uk-width-expand + .uk-margin + label.uk-form-label Channel Name: + .uk-text-large.uk-text-bold= application.name + .uk-width-auto + .uk-margin + label.uk-form-label Owner: + div + a(href=`mailto:${application.owner.email}?subject=${encodeURIComponent(site.name)}${encodeURIComponent(': ')}${encodeURIComponent(application.name)}`)= application.owner.displayName || application.owner.email + .uk-width-auto + .uk-margin + label.uk-form-label Phone: + div + a(href=`tel:${application.contact.phone.number}`)= application.contact.phone.number + .uk-width-auto + .uk-margin + label.uk-form-label Submitted: + div= moment(application.created).fromNow() + + .uk-margin + label.uk-form-label Description + div!= marked(application.description) + + div(uk-grid) + .uk-width-auto + .uk-margin + label.uk-form-label Category + div= application.category.name + .uk-width-auto + .uk-margin + label.uk-form-label Short Name + div= application.slug + .uk-width-auto + .uk-margin + label.uk-form-label Search Tags + div= application.tags ? application.tags.join(',') : 'N/A' + + .uk-card.uk-card-secondary.uk-card-body.uk-margin + fieldset.uk-fieldset + legend.uk-legend Interview + + div(uk-grid) + div(class="uk-width-1-1 uk-width-auto@m") + .uk-margin + label.uk-form-label Audience Size + div= application.interview.audienceSize + div(class="uk-width-1-1 uk-width-auto@m") + .uk-margin + label.uk-form-label Demo URL + div + a(href= application.interview.demoUrl)= application.interview.demoUrl + + .uk-margin + label.uk-form-label History + div!= marked(application.interview.history) + + .uk-card.uk-card-secondary.uk-card-body.uk-margin + form(method="POST", action=`/admin/channel-application/${application._id}`).uk-form + .uk-margin + label(for="rejected-reason").uk-form-label Rejection explanation + textarea(id="rejected-reason", name="rejectedReason", rows="4", placeholder= "Enter reason for rejecting").uk-textarea + div(uk-grid) + .uk-width-auto + button(type="submit", name="action", value="approve").uk-button.uk-button-primary + span + i.fas.fa-check + span.uk-text-bold.uk-margin-small-left Approve + .uk-width-auto + button(type="submit", name="action", value="reject").uk-button.uk-button-danger + span + i.fas.fa-times + span.uk-text-bold.uk-margin-small-left Reject \ No newline at end of file diff --git a/app/views/admin/channel/index.pug b/app/views/admin/channel/index.pug new file mode 100644 index 0000000..108b5e5 --- /dev/null +++ b/app/views/admin/channel/index.pug @@ -0,0 +1,28 @@ +extends ../layouts/main +block content + + .uk-overflow-auto + table.uk-table.uk-table-small.uk-table-divider + thead + th Channel + th Owner + th Category + th Status + th Created + tbody + each channel in channels + tr + td + a(href=`/admin/channel/${channel._id}`)= channel.name + + td + a(href=`/admin/user/${channel.owner._id}`)= channel.owner.username + + td= channel.category.name + + td(class={ + 'uk-text-success': (channel.status === 'live'), + 'uk-text-default': (channel.status === 'offline'), + })= channel.status + + td= moment(channel.created).format('MMM DD, YYYY') \ No newline at end of file diff --git a/app/views/admin/components/menu.pug b/app/views/admin/components/menu.pug new file mode 100644 index 0000000..d31938e --- /dev/null +++ b/app/views/admin/components/menu.pug @@ -0,0 +1,73 @@ +ul.uk-nav.uk-nav-default + li.uk-nav-header Admin Menu + + li(class={ 'uk-active': (adminView === 'home') }) + a(href="/admin") + span.nav-item-icon + i.fas.fa-home + span.uk-margin-small-left Home + + li.uk-nav-divider + + li(class={ 'uk-active': (adminView === 'domain') }) + a(href="/admin/domain") + span.nav-item-icon + i.fas.fa-globe-americas + span.uk-margin-small-left Domains + li(class={ 'uk-active': (adminView === 'host') }) + a(href="/admin/host") + span.nav-item-icon + i.fas.fa-tachometer-alt + span.uk-margin-small-left Platform + li(class={ 'uk-active': (adminView === 'job-queue') }) + a(href="/admin/job-queue") + span.nav-item-icon + i.fas.fa-microchip + span.uk-margin-small-left Jobs + + li.uk-nav-divider + + li(class={ 'uk-active': (adminView === 'channel-application') }) + a(href="/admin/channel-application") + span.nav-item-icon + i.fas.fa-user-tie + span.uk-margin-small-left Channel Applications + + li(class={ 'uk-active': (adminView === 'channel') }) + a(href="/admin/channel") + span.nav-item-icon + i.fas.fa-broadcast-tower + span.uk-margin-small-left Channels + + li(class={ 'uk-active': (adminView === 'user') }) + a(href="/admin/user") + span.nav-item-icon + i.fas.fa-user + span.uk-margin-small-left Users + + li.uk-nav-divider + + li(class={ 'uk-active': (adminView === 'stream') }) + a(href="/admin/stream") + span.nav-item-icon + i.fas.fa-tv + span.uk-margin-small-left Live Streams + + li(class={ 'uk-active': (adminView === 'replay') }) + a(href="/admin/replay") + span.nav-item-icon + i.fas.fa-hdd + span.uk-margin-small-left Replay DVR + + li.uk-nav-divider + + li(class={ 'uk-active': (adminView === 'category') }) + a(href="/admin/category") + span.nav-item-icon + i.fas.fa-box + span.uk-margin-small-left Categories + li(class={ 'uk-active': (adminView === 'survey') }) + a(href="/admin/survey") + span.nav-item-icon + i.fas.fa-poll-h + span.uk-margin-small-left Surveys \ No newline at end of file diff --git a/app/views/admin/domain/form.pug b/app/views/admin/domain/form.pug new file mode 100644 index 0000000..8c7a291 --- /dev/null +++ b/app/views/admin/domain/form.pug @@ -0,0 +1,13 @@ +extends ../layouts/main +block content + + - var formAction = domain ? `/admin/domain/${domain._id}` : "/admin/domain"; + + h2 Domain Manager + + form(method="POST", action= formAction).uk-form + .uk-margin + label(for="name").uk-form-label Name + input(id="name", name="name", type="text", placeholder= "Enter domain name", value= domain ? domain.name : undefined).uk-input + .uk-margin + button(type="submit").uk-button.uk-button-primary= domain ? 'Update domain' : 'Create domain' \ No newline at end of file diff --git a/app/views/admin/domain/index.pug b/app/views/admin/domain/index.pug new file mode 100644 index 0000000..f450b14 --- /dev/null +++ b/app/views/admin/domain/index.pug @@ -0,0 +1,18 @@ +extends ../layouts/main +block content + + .uk-margin + div(uk-grid).uk-flex-middle + .uk-width-expand + h2 Domain Manager + .uk-width-auto + a(href="/admin/domain/create").uk-button.uk-button-primary + span + i.fas.fa-plus + span.uk-margin-small-left Add domain + + .uk-margin + uk.uk-list + each domain in domains + li + a(href=`/admin/domain/${domain._id}`)= domain.name \ No newline at end of file diff --git a/app/views/admin/host/index.pug b/app/views/admin/host/index.pug new file mode 100644 index 0000000..65eb9a3 --- /dev/null +++ b/app/views/admin/host/index.pug @@ -0,0 +1,23 @@ +extends ../layouts/main +block content + + table.uk-table.uk-table-small.uk-table-divider + thead + th Host + th Status + th Memory + th Platform + th Arch + th Created + th Updated + tbody + each host in hosts + tr + td + a(href=`/admin/host/${host._id}`)= host.hostname + td= host.status + td= numeral((host.totalmem - host.freemem) / host.totalmem).format('0.00%') + td= host.platform + td= host.arch + td= moment(host.created).fromNow() + td= host.updated ? moment(host.updated).fromNow() : 'N/A' \ No newline at end of file diff --git a/app/views/admin/host/view.pug b/app/views/admin/host/view.pug new file mode 100644 index 0000000..146e84d --- /dev/null +++ b/app/views/admin/host/view.pug @@ -0,0 +1,140 @@ +extends ../layouts/main +block content + + - var latestReport = stats[stats.length - 1]; + + mixin renderCpuStatsGraph (cpu) + - var totalTime = cpu.user + cpu.nice + cpu.sys + cpu.idle + cpu.irq + .no-select + canvas(width="320", height="100", class= { + 'cpu-overload': ((cpu.idle / totalTime) < 0.1), + }).dtp-cpu-graph + .dtp-stats-bar + .dtp-cpu-stat-bar.dtp-cpu-user(style=`width: ${(cpu.user / totalTime) * 100}%;`)= numeral(cpu.user / totalTime).format('0%') + .dtp-cpu-stat-bar.dtp-cpu-nice(style=`width: ${(cpu.nice / totalTime) * 100}%;`)= numeral(cpu.nice / totalTime).format('0%') + .dtp-cpu-stat-bar.dtp-cpu-sys(style=`width: ${(cpu.sys / totalTime) * 100}%;`)= numeral(cpu.sys / totalTime).format('0%') + .dtp-cpu-stat-bar.dtp-cpu-irq(style=`width: ${(cpu.irq / totalTime) * 100}%;`)= numeral(cpu.irq / totalTime).format('0%') + .dtp-cpu-stat-bar.dtp-cpu-idle(style=`width: ${(cpu.idle / totalTime) * 100}%;`)= numeral(cpu.idle / totalTime).format('0%') + + mixin renderStatCell (label, value) + .dtp-stat-cell.uk-width-auto + .uk-text-bold= value + .uk-text-small= label + + .uk-margin + .uk-overflow-auto + table.uk-table.uk-table-small.uk-table-divider + thead + th Host + th Status + th Memory + th Disk + th Platform + th Arch + th Created + th Updated + tbody + tr + td + a(href=`/admin/host/${host._id}`)= host.hostname + td= host.status + td= numeral((host.totalmem - host.freemem) / host.totalmem).format('0.00%') + td= numeral(latestReport.disk.cache.pctUsed / 100.0).format('0.00%') + td= host.platform + td= host.arch + td= moment(host.created).fromNow() + td= host.updated ? moment(host.updated).fromNow() : 'N/A' + + .dtp-dashboard-cluster.uk-margin + fieldset + legend [Processor] + div(uk-grid).uk-grid-small.uk-flex-between + each cpu in latestReport.cpus + div(class="uk-width-1-1 uk-width-auto@m") + +renderCpuStatsGraph(cpu) + + .dtp-dashboard-cluster.uk-margin + div(uk-grid).uk-flex-between + div(class="uk-width-1-1 uk-width-auto@m") + fieldset + legend [Core Memory] + .dtp-stats-bar + .dtp-mem-stat-bar.dtp-mem-used(style=`width: ${(latestReport.memory.active / latestReport.memory.total) * 100}%;`)= numeral(latestReport.memory.active / latestReport.memory.total).format('0%') + .dtp-mem-stat-bar.dtp-mem-available(style=`width: ${(latestReport.memory.available / latestReport.memory.total) * 100}%;`)= numeral(latestReport.memory.available / latestReport.memory.total).format('0%') + .uk-margin-small-top + div(uk-grid) + +renderStatCell('total', numeral(latestReport.memory.total).format('0,0.0 b')) + +renderStatCell('avail.', numeral(latestReport.memory.available).format('0,0.0 b')) + +renderStatCell('active', numeral(latestReport.memory.active).format('0,0.0 b')) + +renderStatCell('used', numeral(latestReport.memory.used).format('0,0.0 b')) + +renderStatCell('free', numeral(latestReport.memory.free).format('0,0.0 b')) + + div(class="uk-width-1-1 uk-width-auto@m") + fieldset + legend [Buffers] + .dtp-stats-bar + .dtp-mem-stat-bar.dtp-mem-cached(style=`width: ${(latestReport.memory.cached / latestReport.memory.buffcache) * 100}%;`)= numeral(latestReport.memory.cached / latestReport.memory.buffcache).format('0%') + .dtp-mem-stat-bar.dtp-mem-buffers(style=`width: ${(latestReport.memory.buffers / latestReport.memory.buffcache) * 100}%;`)= numeral(latestReport.memory.buffers / latestReport.memory.buffcache).format('0%') + .dtp-mem-stat-bar.dtp-mem-slab(style=`width: ${(latestReport.memory.slab / latestReport.memory.buffcache) * 100}%;`)= numeral(latestReport.memory.slab / latestReport.memory.buffcache).format('0%') + .uk-margin-small-top + div(uk-grid) + +renderStatCell('buffers', numeral(latestReport.memory.buffers).format('0,0.0 b')) + +renderStatCell('cached', numeral(latestReport.memory.cached).format('0,0.0 b')) + +renderStatCell('slab', numeral(latestReport.memory.slab).format('0,0.0 b')) + +renderStatCell('buffcache', numeral(latestReport.memory.buffcache).format('0,0.0 b')) + + div(class="uk-width-1-1 uk-width-auto@m") + fieldset + legend [Swap] + .dtp-stats-bar + .dtp-mem-stat-bar.dtp-mem-used(style=`width: ${(latestReport.memory.swapused / latestReport.memory.swaptotal) * 100}%;`)= numeral(latestReport.memory.swapused / latestReport.memory.swaptotal).format('0%') + .dtp-mem-stat-bar.dtp-mem-available(style=`width: ${(latestReport.memory.swapfree / latestReport.memory.swaptotal) * 100}%;`)= numeral(latestReport.memory.swapfree / latestReport.memory.swaptotal).format('0%') + .uk-margin-small-top + div(uk-grid) + +renderStatCell('used', numeral(latestReport.memory.swapused).format('0,0.0 b')) + +renderStatCell('free', numeral(latestReport.memory.swapfree).format('0,0.0 b')) + +renderStatCell('total', numeral(latestReport.memory.swaptotal).format('0,0.0 b')) + div(class="uk-width-1-1 uk-width-auto@m") + fieldset + legend [Load Avg] + div(uk-grid) + +renderStatCell('1 min', latestReport.load[0]) + +renderStatCell('5 min', latestReport.load[1]) + +renderStatCell('15 min', latestReport.load[2]) + + + .dtp-dashboard-cluster.uk-margin + fieldset + legend [Host Cache] + div(uk-grid).uk-flex-between + +renderStatCell('objects', numeral(latestReport.cache.itemCount).format('0,0')) + +renderStatCell('data size', numeral(latestReport.cache.dataSize).format('0,0.00b')) + +renderStatCell('expire count', numeral(latestReport.cache.expireCount).format('0,0')) + +renderStatCell('expire size', numeral(latestReport.cache.expireDataSize).format('0,0.00b')) + +renderStatCell('hits', numeral(latestReport.cache.hitCount).format('0,0')) + +renderStatCell('hit size', numeral(latestReport.cache.hitDataSize).format('0,0.00b')) + +renderStatCell('misses', numeral(latestReport.cache.missCount).format('0,0')) + +renderStatCell('miss size', numeral(latestReport.cache.missDataSize).format('0,0.00b')) + + .dtp-dashboard-cluster.uk-margin + div(uk-grid).uk-grid-small + each iface in latestReport.network + div(class="uk-width-1-1 uk-width-auto@m") + fieldset + legend= `[${iface.iface}]` + canvas(data-iface= iface.iface, width="300", height="100").dtp-iface-graph + +block viewjs + + script(src="/chart.js/chart.min.js") + + script. + const dtp = window.dtp = window.dtp || { }; + + dtp.hostStats = !{JSON.stringify(stats)}; + + window.addEventListener('dtp-load-admin', ( ) => { + dtp.adminApp.prepareGraphData(); + dtp.adminApp.renderCpuGraphs(); + dtp.adminApp.renderNetworkGraphs(); + }); \ No newline at end of file diff --git a/app/views/admin/index.pug b/app/views/admin/index.pug new file mode 100644 index 0000000..904dbc9 --- /dev/null +++ b/app/views/admin/index.pug @@ -0,0 +1,12 @@ +extends layouts/main +block content + + div(uk-grid).uk-grid-small.uk-flex-between.uk-flex-middle + .uk-width-auto + +renderCell('Members', formatCount(stats.memberCount)) + .uk-width-auto + +renderCell('Channels', formatCount(stats.channelCount)) + .uk-width-auto + +renderCell('Streams', formatCount(stats.streamCount)) + .uk-width-auto + +renderCell('Viewers', formatCount(stats.viewerCount)) diff --git a/app/views/admin/job-queue/index.pug b/app/views/admin/job-queue/index.pug new file mode 100644 index 0000000..7b8e184 --- /dev/null +++ b/app/views/admin/job-queue/index.pug @@ -0,0 +1,7 @@ +extends ../layouts/main +block content + + ul.uk-list + each queueName in queues + li + a(href=`/admin/job-queue/${queueName}`)= queueName \ No newline at end of file diff --git a/app/views/admin/job-queue/queue-view.pug b/app/views/admin/job-queue/queue-view.pug new file mode 100644 index 0000000..1fd3595 --- /dev/null +++ b/app/views/admin/job-queue/queue-view.pug @@ -0,0 +1,62 @@ +extends ../layouts/main +block content + + mixin renderJobList (jobList) + if !Array.isArray(jobList) || (jobList.length === 0) + div No jobs + else + table.uk-table.uk-table-small + thead + th ID + th Name + th Attempts + th Progress + tbody + each job in jobList + tr + td= job.id + td + a(href=`/admin/job-queue/${queue.name}/${job.id}`)= job.name + td= job.attemptsMade + td #{job.progress()}% + + .uk-margin + h1 Job Queue: #{queueName} + div(uk-grid).uk-flex-between + - var pendingJobCount = jobCounts.waiting + jobCounts.delayed + jobCounts.paused + jobCounts.active + .uk-width-auto Total#[br]#{numeral(pendingJobCount).format('0,0')} + .uk-width-auto Waiting#[br]#{numeral(jobCounts.waiting).format('0,0')} + .uk-width-auto Delayed#[br]#{numeral(jobCounts.delayed).format('0,0')} + .uk-width-auto Paused#[br]#{numeral(jobCounts.paused).format('0,0')} + .uk-width-auto Active#[br]#{numeral(jobCounts.active).format('0,0')} + .uk-width-auto Completed#[br]#{numeral(jobCounts.completed).format('0,0')} + .uk-width-auto Failed#[br]#{numeral(jobCounts.failed).format('0,0')} + + div(uk-grid) + div(class="uk-width-1-1 uk-width-1-2@l") + .uk-card.uk-card-default.uk-card-small + .uk-card-header + h3.uk-card-title Active + .uk-card-body + +renderJobList(jobs.active) + + div(class="uk-width-1-1 uk-width-1-2@l") + .uk-card.uk-card-default.uk-card-small + .uk-card-header + h3.uk-card-title Waiting + .uk-card-body + +renderJobList(jobs.waiting) + + div(class="uk-width-1-1 uk-width-1-2@l") + .uk-card.uk-card-default.uk-card-small + .uk-card-header + h3.uk-card-title Delayed + .uk-card-body + +renderJobList(jobs.delayed) + + div(class="uk-width-1-1 uk-width-1-2@l") + .uk-card.uk-card-default.uk-card-small + .uk-card-header + h3.uk-card-title Failed + .uk-card-body + +renderJobList(jobs.failed) \ No newline at end of file diff --git a/app/views/admin/layouts/main.pug b/app/views/admin/layouts/main.pug new file mode 100644 index 0000000..74b356b --- /dev/null +++ b/app/views/admin/layouts/main.pug @@ -0,0 +1,19 @@ +extends ../../layouts/main +block content-container + + block page-header + section.uk-section.uk-section-header.uk-section-xsmall + .uk-container + h1.uk-text-center DTP Sites Engine + + block admin-layout + + section.uk-section.uk-section-default.uk-section-small + .uk-container.uk-container-expand + div(uk-grid) + div(class="uk-width-1-1 uk-flex-last uk-width-auto@m uk-flex-first@m") + .uk-card.uk-card-secondary.uk-card-body.uk-border-rounded + include ../components/menu + + div(class="uk-width-1-1 uk-flex-first uk-width-expand@m").uk-width-expand + block content \ No newline at end of file diff --git a/app/views/admin/user/form.pug b/app/views/admin/user/form.pug new file mode 100644 index 0000000..d45a495 --- /dev/null +++ b/app/views/admin/user/form.pug @@ -0,0 +1,37 @@ +extends ../layouts/main +block content + + .uk-margin + .uk-text-large= userAccount.displayName || userAccount.email + div= userAccount.username + + form(method="POST", action=`/admin/user/${userAccount._id}`).uk-form + input(type="hidden", name="username", value= userAccount.username) + input(type="hidden", name="displayName", value= userAccount.displayName) + .uk-margin + div(uk-grid) + div(class="uk-width-1-1 uk-width-1-2@m") + fieldset + legend Flags + .uk-margin + div(uk-grid).uk-grid-small + label + input(id="is-admin", name="isAdmin", type="checkbox", checked= userAccount.flags.isAdmin) + | Admin + label + input(id="is-moderator", name="isModerator", type="checkbox", checked= userAccount.flags.isModerator) + | Moderator + + div(class="uk-width-1-1 uk-width-1-2@m") + fieldset + legend Permissions + .uk-margin + div(uk-grid).uk-grid-small + label + input(id="can-login", name="canLogin", type="checkbox", checked= userAccount.permissions.canLogin) + | Can Login + label + input(id="can-chat", name="canChat", type="checkbox", checked= userAccount.permissions.canChat) + | Can Chat + + button(type="submit").uk-button.uk-button-primary Update User \ No newline at end of file diff --git a/app/views/admin/user/index.pug b/app/views/admin/user/index.pug new file mode 100644 index 0000000..ff74877 --- /dev/null +++ b/app/views/admin/user/index.pug @@ -0,0 +1,22 @@ +extends ../layouts/main +block content + + .uk-overflow-auto + table.uk-table.uk-table-divider.uk-table-hover.uk-table-small.uk-table-justify + thead + th Username + th Display Name + th Created + th User ID + tbody + each userAccount in userAccounts + tr + td + a(href=`/admin/user/${userAccount._id}`)= userAccount.username + td + if userAccount.displayName + a(href=`/admin/user/${userAccount._id}`)= userAccount.displayName + else + .uk-text-muted N/A + td= moment(userAccount.created).format('YYYY-MM-DD hh:mm a') + td= userAccount._id \ No newline at end of file diff --git a/app/views/article/components/article.pug b/app/views/article/components/article.pug new file mode 100644 index 0000000..b2b287a --- /dev/null +++ b/app/views/article/components/article.pug @@ -0,0 +1,10 @@ +mixin renderArticle (article) + article.uk-article + if article.image + img(src="/img/payment/payment-option.jpg").responsive + h1.uk-article-title= article.title + if article.meta + p.uk-article-meta= article.meta + if article.lead + p.-uk-text-lead= article.lead + div!= article.content \ No newline at end of file diff --git a/app/views/article/view.pug b/app/views/article/view.pug new file mode 100644 index 0000000..7b80f77 --- /dev/null +++ b/app/views/article/view.pug @@ -0,0 +1,8 @@ +extends ../layouts/main +block content + + include components/article + + section.uk-section.uk-section-default + .uk-container + +renderArticle(article) \ No newline at end of file diff --git a/app/views/category/components/list-item.pug b/app/views/category/components/list-item.pug new file mode 100644 index 0000000..41f5f55 --- /dev/null +++ b/app/views/category/components/list-item.pug @@ -0,0 +1,6 @@ +mixin renderCategoryListItem (category) + a(href=`/category/${category.slug}`).uk-display-block.uk-link-reset + img(src='/img/default-poster.jpg').uk-display-block.uk-margin-small.responsive.uk-border-rounded + .uk-link-reset.uk-text-bold= category.name + .uk-ling-reset.uk-text-muted #{numeral(category.stats.liveChannelCount).format("0,0")} live channels + .uk-ling-reset.uk-text-muted #{numeral(category.stats.currentViewerCount).format("0,0.0a")} viewers \ No newline at end of file diff --git a/app/views/category/home.pug b/app/views/category/home.pug new file mode 100644 index 0000000..da7cb09 --- /dev/null +++ b/app/views/category/home.pug @@ -0,0 +1,17 @@ +extends ../layouts/main +block content + + include components/list-item + + section.uk-section.uk-section-default.uk-section-small + .uk-container.uk-container-expand + + if Array.isArray(categories) && (categories.length > 0) + div(uk-grid).uk-flex-center.uk-grid-small + each category in categories + .uk-width-auto + .uk-width-medium + .uk-margin + +renderCategoryListItem(category) + else + h4.uk-text-center There are no categories or the system is down for maintenance. \ No newline at end of file diff --git a/app/views/category/view.pug b/app/views/category/view.pug new file mode 100644 index 0000000..7cd7b4d --- /dev/null +++ b/app/views/category/view.pug @@ -0,0 +1,32 @@ +extends ../layouts/main +block content + + include ../channel/components/list-item + + section(style="font: Verdana;").uk-section.uk-section-muted.uk-section-small + .uk-container + div(uk-grid).uk-grid-small + .uk-width-auto + img(src="/img/default-poster.jpg").uk-width-small + .uk-width-expand + h1.uk-margin-remove.uk-padding-remove= category.name + div= category.description + div(uk-grid).uk-grid-small + .uk-width-auto #{category.stats.streamCount} live shows. + .uk-width-auto #{category.stats.viewerCount} total viewers. + + section.uk-section.uk-section-default + .uk-container + if Array.isArray(channels) && (channels.length > 0) + div(uk-grid).uk-flex-center.uk-grid-small + each channel in channels + div(class="uk-width-1-1 uk-width-1-2@s uk-width-1-3@m uk-width-1-4@l") + +renderChannelListItem(channel) + else + .uk-text-lead No channels in this category, check back later. + include ../components/back-button + + + //- pre= JSON.stringify(category, null, 2) + pre= JSON.stringify(category, null, 2) + pre= JSON.stringify(channels, null, 2) diff --git a/app/views/components/back-button.pug b/app/views/components/back-button.pug new file mode 100644 index 0000000..e3f50e9 --- /dev/null +++ b/app/views/components/back-button.pug @@ -0,0 +1,4 @@ +button(type="button", onclick= "return window.history.back();").uk-button.dtp-button-primary + span + i.fas.fa-chevron-left + span.uk-margin-small-left Back diff --git a/app/views/components/crypto-symbol-summary.pug b/app/views/components/crypto-symbol-summary.pug new file mode 100644 index 0000000..c9c9f68 --- /dev/null +++ b/app/views/components/crypto-symbol-summary.pug @@ -0,0 +1,15 @@ +mixin renderCryptoSymbolSummary (currency) + div(uk-grid).uk-grid-small.uk-flex-middle + .uk-width-auto + img(src=`/img/payment/${currency.sourceSymbol.toLowerCase()}.svg`, width="40", height="40") + .uk-width-expand + div + span.uk-text-bold= currency.sourceSymbol + span.uk-margin-small-left= numeral(currency.last).format('$0,0.00') + span.uk-margin-small-left.uk-text-small(class={ + 'uk-text-success': (currency.changes.price.day > 0), + 'uk-text-danger': (currency.changes.price.day < 0), + })= numeral(currency.changes.price.day).format('$0,0.00') + .uk-text-small + span bid: #{numeral(currency.bid).format('$0,0.00')} + span.uk-margin-small-left ask: #{numeral(currency.ask).format('$0,0.00')} diff --git a/app/views/components/csrf-token-input.pug b/app/views/components/csrf-token-input.pug new file mode 100644 index 0000000..ee20043 --- /dev/null +++ b/app/views/components/csrf-token-input.pug @@ -0,0 +1,2 @@ +mixin renderCsrfTokenInput (csrfToken) + input(type="hidden", name= csrfToken.name, value= csrfToken.token) \ No newline at end of file diff --git a/app/views/components/file-upload-image.pug b/app/views/components/file-upload-image.pug new file mode 100644 index 0000000..762992b --- /dev/null +++ b/app/views/components/file-upload-image.pug @@ -0,0 +1,60 @@ +mixin renderFileUploadImage (actionUrl, containerId, imageId, imageClass, defaultImage, currentImage, cropperOptions) + div(id= containerId).dtp-file-upload + form(method="POST", action= actionUrl, enctype="multipart/form-data", onsubmit= "return dtp.app.submitForm(event);").uk-form + .uk-margin + .uk-card.uk-card-default.uk-card-small + .uk-card-body + div(uk-grid).uk-flex-middle.uk-flex-center + div(class="uk-width-1-1 uk-width-auto@m") + .upload-image-container.size-512 + if !!currentImage + img(id= imageId, data-cropper-options= cropperOptions, src= `/image/${currentImage._id}`, class= imageClass).sb-large + else + img(id= imageId, data-cropper-options= cropperOptions, src= defaultImage, class= imageClass).sb-large + + div(class="uk-width-1-1 uk-width-auto@m") + .uk-text-small.uk-margin(hidden= !!currentImage) + if !currentImage + #file-select + .uk-margin(class="uk-text-center uk-text-left@m") + span.uk-text-middle Select an image + div(uk-form-custom).uk-margin-small-left + input( + type="file", + name="imageFile", + formenctype="multipart/form-data", + accept=".jpg,.png,image/jpeg,image/png", + data-file-select-container= containerId, + data-file-select="test-image-upload", + data-file-size-element= "file-size", + data-file-max-size= 15 * 1024000, + data-image-id= imageId, + data-image-w= 512, + data-image-h= 512, + onchange="return dtp.app.selectImageFile(event);", + ) + button(type="button", tabindex="-1").uk-button.dtp-button-default Select + + #file-info(class="uk-text-center uk-text-left@m", hidden) + #file-name.uk-text-bold + if currentImage + div resolution: #[span#image-resolution-w= numeral(currentImage.metadata.width).format('0,0')]x#[span#image-resolution-h= numeral(currentImage.metadata.height).format('0,0')] + div size: #[span#file-size= numeral(currentImage.metadata.size).format('0,0.00b')] + div last modified: #[span#file-modified= moment(currentImage.created).format('MMM DD, YYYY')] + else + div resolution: #[span#image-resolution-w 512]x#[span#image-resolution-h 512] + div size: #[span#file-size N/A] + div last modified: #[span#file-modified N/A] + + .uk-card-footer + div(class="uk-flex-center", uk-grid) + #remove-btn(hidden= !currentImage).uk-width-auto + button( + type= "button", + onclick= "return dtp.app.removeImageFile(event);", + ).uk-button.uk-button-danger Remove + + #file-save-btn(hidden).uk-width-auto + button( + type="submit", + ).uk-button.uk-button-primary Save \ No newline at end of file diff --git a/app/views/components/gab-share-button.pug b/app/views/components/gab-share-button.pug new file mode 100644 index 0000000..fdbf624 --- /dev/null +++ b/app/views/components/gab-share-button.pug @@ -0,0 +1,9 @@ +mixin renderGabShareButton (shareUrl, shareMsg) + a(href=`https://gab.com/compose?url=${shareUrl}&text=${shareMsg}`, target="_frenshare").fren-button + span(style="color: white;") + + + + + + span(class="uk-visible@s") Share #[span(class="uk-visible@l") to Gab] \ No newline at end of file diff --git a/app/views/components/home-menu-button.pug b/app/views/components/home-menu-button.pug new file mode 100644 index 0000000..71c8db6 --- /dev/null +++ b/app/views/components/home-menu-button.pug @@ -0,0 +1,6 @@ +mixin renderHomeMenuButton (buttonClass, className, label, url) + a(href= url).uk-button.uk-button-text.uk-display-block + .home-menu-button(class= buttonClass) + .button-icon + i(class= className) + .button-label!= label \ No newline at end of file diff --git a/app/views/components/item-metabar.pug b/app/views/components/item-metabar.pug new file mode 100644 index 0000000..e42806a --- /dev/null +++ b/app/views/components/item-metabar.pug @@ -0,0 +1,84 @@ +mixin renderItemMetabar (dictionaryItem, itemType, options) + - + options = Object.assign({ hideActions: false }, options); + const decoratedItem = dictionaryItems.find((item) => item._id.equals(dictionaryItem._id)); + if (decoratedItem) { + dictionaryItem = decoratedItem; // override it + } + var submitterName = (dictionaryItem.submitter.name && (dictionaryItem.submitter.name.length > 0)) ? dictionaryItem.submitter.name : '[Submitter Name Is Empty]'; + var reportUrl = user ? `/content-report/${itemType}/${dictionaryItem._id}/submit` : '/welcome?src=report'; + + .frenspeak-metabar(data-item-type= itemType, data-item-id= dictionaryItem._id) + .metabar-submitter.uk-text-muted.uk-text-small(title="Submitted by") + div(uk-grid).uk-grid-collapse + .uk-width-auto + span(style="margin-right: 4px;") #{itemType} submitted by: + .uk-width-expand + a(href=`/user/${dictionaryItem.submitter._id}`).uk-text-truncate= submitterName + + if !options.hideActions + div(uk-grid).uk-grid-collapse.uk-flex-bottom + .uk-width-expand + if user + button.metabar-button( + type="button", + title="Upvotes", + data-item-type= itemType, + data-item-id= dictionaryItem._id, + data-vote= "up", + onclick=`return window.dtp.app.processVote(event);`, + ) + span(class={ 'uk-text-success': dictionaryItem.myVote && (dictionaryItem.myVote.vote === 'up') }).metabutton-icon.upvote-icon + i.fas.fa-thumbs-up + span.upvote-label.icon-label= numeral(dictionaryItem.stats.upVoteCount).format('0,0a') + + button.metabar-button( + type="button", + title="Downvotes", + data-item-type= itemType, + data-item-id= dictionaryItem._id, + data-vote= "down", + onclick=`return window.dtp.app.processVote(event);`, + ) + span(class={ 'uk-text-danger': dictionaryItem.myVote && (dictionaryItem.myVote.vote === 'down' ) }).metabutton-icon.downvote-icon + i.fas.fa-thumbs-down + span.downvote-label.icon-label= numeral(dictionaryItem.stats.downVoteCount).format('0,0a') + + button.metabar-button( + type="button", + title="ReeeVotes", + data-item-type= itemType, + data-item-id= dictionaryItem._id, + data-vote= "reee", + onclick=`return window.dtp.app.processVote(event);`, + ) + span(class={ 'uk-text-warning': dictionaryItem.myVote && (dictionaryItem.myVote.vote === 'reee') }).metabutton-icon.reeevote-icon + i.fas.fa-biohazard + span.reeevote-label.icon-label= numeral(dictionaryItem.stats.reeeVoteCount).format('0,0a') + else + a(href="/welcome?src=voting", title="Upvotes").metabar-button.uk-link-text + span(class={ 'uk-text-success': dictionaryItem.myVote && (dictionaryItem.myVote.vote === 'up') }).metabutton-icon.upvote-icon + i.fas.fa-thumbs-up + span.upvote-label.icon-label= numeral(dictionaryItem.stats.upVoteCount).format('0,0a') + + a(href="/welcome?src=voting", title="Downvotes").metabar-button.uk-link-text + span(class={ 'uk-text-danger': dictionaryItem.myVote && (dictionaryItem.myVote.vote === 'down' ) }).metabutton-icon.downvote-icon + i.fas.fa-thumbs-down + span.downvote-label.icon-label= numeral(dictionaryItem.stats.downVoteCount).format('0,0a') + + a(href="/welcome?src=voting", title="ReeeVotes").metabar-button.uk-link-text + span(class={ 'uk-text-warning': dictionaryItem.myVote && (dictionaryItem.myVote.vote === 'reee') }).metabutton-icon.reeevote-icon + i.fas.fa-biohazard + span.reeevote-label.icon-label= numeral(dictionaryItem.stats.reeeVoteCount).format('0,0a') + + button(type="button").metabar-button + span.metabutton-icon + i.fas.fa-ellipsis-h + + div(uk-dropdown={ mode: 'click' }) + ul.uk-nav.uk-dropdown-nav + li + a(href= reportUrl) Report #{itemType} + + .uk-width-auto + .uk-text-meta(title="Date submitted")= moment(dictionaryItem.created).format('MMM DD, YYYY') \ No newline at end of file diff --git a/app/views/components/library.pug b/app/views/components/library.pug new file mode 100644 index 0000000..0bbf826 --- /dev/null +++ b/app/views/components/library.pug @@ -0,0 +1,12 @@ +//- common routines for all views everywhere + +- + function formatCount(value) { + value = value || 0; + return (value < 1000) ? numeral(value).format('0,0') : numeral(value).format('0,0.0a'); + } + +mixin renderCell (label, value, className) + div(style="padding: 10px 20px;", title=`${label}: ${numeral(value).format('0,0')}`).uk-card.uk-card-default.uk-card-body.no-select + .uk-text-muted= label + div(class=className)= value \ No newline at end of file diff --git a/app/views/components/missing-profile-icon.pug b/app/views/components/missing-profile-icon.pug new file mode 100644 index 0000000..ae6e7af --- /dev/null +++ b/app/views/components/missing-profile-icon.pug @@ -0,0 +1,13 @@ +svg( + version="1.1", xmlns="http://www.w3.org/2000/svg", xmlns:xlink="http://www.w3.org/1999/xlink", + width="32", height="32", + viewBox="0 0 600 600", +).profile-navbar + defs + clipPath(id="circular-border") + circle(cx="300", cy="300", r="280") + clipPath(id="avoid-antialiasing-bugs") + rect(width="100%", height="498") + circle(cx="300", cy="300", r="280", fill="black", clip-path="url(#avoid-antialiasing-bugs)") + circle(cx="300", cy="230", r="115") + circle(cx="300", cy="550", r="205", clip-path="url(#circular-border)") \ No newline at end of file diff --git a/app/views/components/navbar.pug b/app/views/components/navbar.pug new file mode 100644 index 0000000..bf69944 --- /dev/null +++ b/app/views/components/navbar.pug @@ -0,0 +1,79 @@ +.uk-navbar-container.uk-padding-remove.uk-position-fixed.uk-position-top + nav(uk-navbar) + .uk-navbar-left + .uk-navbar-item + button(type="button", uk-toggle="target: #dtp-offcanvas").uk-button.uk-button-link.uk-padding-small + i.fas.fa-chevron-right + + .uk-navbar-center + a(href="/").uk-navbar-item.uk-logo + img(src=`/img/icon/${site.domainKey}/icon-48x48.png`) + + .uk-navbar-right + .uk-navbar-item + if user + div.no-select + if user.picture_url + img( + src= user.picture_url || '/img/default-member.png', + title="Member Menu", + ).profile-navbar + else + include missing-profile-icon + div(uk-dropdown={ mode: 'click' }).uk-navbar-dropdown + ul.uk-nav.uk-navbar-dropdown-nav(style="z-index: 1024;") + li.uk-nav-heading.uk-text-center= user.displayName || user.username + li.uk-nav-divider + if (user.channel) + li + a(href=`/channel/${user.channel.slug}`) + span.nav-item-icon + i.fas.fa-broadcast-tower + span(style="max-width: 120px;").uk-text-truncate= user.channel.name + if (user.channel.liveEpisode) + li + a(href=`/channel/${user.channel.slug}/broadcaster`) + span.nav-item-icon + i.fas.fa-box-open + span Broadcaster + li + a(href='/dashboard') + span.nav-item-icon + i.fas.fa-tachometer-alt + span Dashboard + + li.uk-nav-divider + + li + a(href=`/user/${user._id}`) + span.nav-item-icon + i.fas.fa-user + span Profile + li + a(href=`/user/${user._id}/settings`) + span.nav-item-icon + i.fas.fa-cog + span Settings + + if user.flags && user.flags.isAdmin + li.uk-nav-divider + li + a(href='/admin') + span.nav-item-icon + i.fas.fa-user-lock + span Admin + + li.uk-nav-divider + + li + a(href='/auth/logout') + span.nav-item-icon + i.fas.fa-sign-out-alt + span Logout + else + ul.uk-navbar-nav + li + a(href='/welcome').uk-button.uk-button-link + span.nav-item-icon + i.fas.fa-sign-in-alt + span(class="uk-visible@m").uk-margin-small-left GET STARTED! \ No newline at end of file diff --git a/app/views/components/off-canvas.pug b/app/views/components/off-canvas.pug new file mode 100644 index 0000000..f668f95 --- /dev/null +++ b/app/views/components/off-canvas.pug @@ -0,0 +1,72 @@ +#dtp-offcanvas(uk-offcanvas="mode: slide; overlay: true; bg-close: true;") + .uk-offcanvas-bar + .uk-margin + a(href="/", style="color: white;").uk-display-block + .uk-text-large= site.name + .uk-text-small.uk-text-muted= site.description + + ul.uk-nav.uk-nav-default.dtp-app-menu + li(class={ "uk-active": (currentView === 'home') }) + a(href='/').uk-display-block + div(uk-grid).uk-grid-collapse + .uk-width-auto + .app-menu-icon + i(class=`fas fa-home`) + .uk-width-expand Home + + if user + li.uk-nav-header Member Menu + + li(class={ "uk-active": (currentView === 'user-settings') }) + a(href=`/user/${user._id}`).uk-display-block + div(uk-grid).uk-grid-collapse + .uk-width-auto + .app-menu-icon + i.fas.fa-user + .uk-width-expand Profile + + li(class={ "uk-active": (currentView === 'user-settings') }) + a(href=`/user/${user._id}/settings`).uk-display-block + div(uk-grid).uk-grid-collapse + .uk-width-auto + .app-menu-icon + i.fas.fa-cog + .uk-width-expand Settings + + if user.permissions.isAdmin + a(href="/admin").uk-display-block + li(class={ "uk-active": currentView === 'admin' }) + div(uk-grid).uk-grid-collapse + .uk-width-auto + .app-menu-icon + i.fas.fa-user-shield + .uk-width-expand Admin + + li + a(href="/auth/logout").uk-display-block + div(uk-grid).uk-grid-collapse + .uk-width-auto + .app-menu-icon + i.fas.fa-sign-out-alt + .uk-width-expand Logout + + li.uk-nav-header Legal + + li + a(href="/policy/terms-of-service").uk-display-block + div(uk-grid).uk-grid-collapse + .uk-width-auto + .app-menu-icon + i.fas.fa-balance-scale + .uk-width-expand Terms of Service + li + a(href="/policy/privacy").uk-display-block + div(uk-grid).uk-grid-collapse + .uk-width-auto + .app-menu-icon + i.fas.fa-balance-scale + .uk-width-expand Privacy Policy + + .uk-text-small.uk-text-muted.uk-margin-medium + div © #{moment().format('YYYY')} #{site.company} + div Made In USA 🇺🇸 \ No newline at end of file diff --git a/app/views/components/page-footer.pug b/app/views/components/page-footer.pug new file mode 100644 index 0000000..2d43984 --- /dev/null +++ b/app/views/components/page-footer.pug @@ -0,0 +1,4 @@ +section.uk-section.uk-section-muted.uk-section-small + .uk-container.uk-text-small.uk-text-muted + div(class="uk-text-center uk-text-left@m") + div Copyright © 2021 #[+renderSiteLink()] \ No newline at end of file diff --git a/app/views/components/page-header.pug b/app/views/components/page-header.pug new file mode 100644 index 0000000..7aa1ab6 --- /dev/null +++ b/app/views/components/page-header.pug @@ -0,0 +1,13 @@ +section.uk-section.uk-section-header.uk-section-xsmall.header-section + .uk-container + div(uk-grid).uk-grid-small.uk-flex-middle + div(class="uk-hidden@m").uk-width-1-1 + h1.uk-text-center + a(href='/').uk-link-reset= pageCommitteeName || 'Local Red Action' + div(class="uk-visible@m").uk-width-auto + a(href="/").uk-link-reset + img(src= pageLogoURL || "/img/lra-logo.png", alt="Robinson Township Republicans").committee-logo + div(class="uk-width-1-1 uk-text-center uk-width-expand@m uk-text-left@m") + h1(class="uk-visible@m").uk-margin-small + a(href="/").uk-link-reset= pageCommitteeName || 'Local Red Action' + .uk-text-large= pageTitle || 'Local leadership to preserve our communities' \ No newline at end of file diff --git a/app/views/components/pagination-bar.pug b/app/views/components/pagination-bar.pug new file mode 100644 index 0000000..20817a2 --- /dev/null +++ b/app/views/components/pagination-bar.pug @@ -0,0 +1,27 @@ +mixin renderPaginationBar (baseUrl, totalItemCount, urlParameters = '') + - + var startPage = pagination.p - 2; + if (startPage < 1) { + startPage = 1; + } + var endPage = startPage + 4; + var lastPage = Math.floor(totalItemCount / pagination.cpp); + if ((totalItemCount % pagination.cpp) !== 0) { + ++lastPage; + } + if (endPage > lastPage) { + endPage = lastPage; + } + + ul(aria-label="Page navigation").uk-pagination.uk-flex-center + li(class= pagination.p === 1 ? 'uk-disabled' : undefined) + a(href=`${baseUrl}?p=${pagination.p - 1}${urlParameters}`) + span(uk-pagination-previous).uk-margin-small-right + span prev + while startPage <= endPage + li(class= startPage === pagination.p ? 'active' : undefined) + a(href=`${baseUrl}?p=${startPage}${urlParameters}`)= startPage++ + li(class= pagination.p === lastPage ? 'disabled' : undefined) + a(href=`${baseUrl}?p=${pagination.p + 1}${urlParameters}`) + span next + span(uk-pagination-next).uk-margin-small-left \ No newline at end of file diff --git a/app/views/components/pwa-support.pug b/app/views/components/pwa-support.pug new file mode 100644 index 0000000..970a710 --- /dev/null +++ b/app/views/components/pwa-support.pug @@ -0,0 +1,20 @@ +link(rel="apple-touch-icon" sizes="57x57" href=`/img/icon/${site.domainKey}/icon-57x57.png?v=${pkg.version}`) +link(rel="apple-touch-icon" sizes="60x60" href=`/img/icon/${site.domainKey}/icon-60x60.png?v=${pkg.version}`) +link(rel="apple-touch-icon" sizes="72x72" href=`/img/icon/${site.domainKey}/icon-72x72.png?v=${pkg.version}`) +link(rel="apple-touch-icon" sizes="76x76" href=`/img/icon/${site.domainKey}/icon-76x76.png?v=${pkg.version}`) +link(rel="apple-touch-icon" sizes="114x114" href=`/img/icon/${site.domainKey}/icon-114x114.png?v=${pkg.version}`) +link(rel="apple-touch-icon" sizes="120x120" href=`/img/icon/${site.domainKey}/icon-120x120.png?v=${pkg.version}`) +link(rel="apple-touch-icon" sizes="144x144" href=`/img/icon/${site.domainKey}/icon-144x144.png?v=${pkg.version}`) +link(rel="apple-touch-icon" sizes="152x152" href=`/img/icon/${site.domainKey}/icon-152x152.png?v=${pkg.version}`) +link(rel="apple-touch-icon" sizes="180x180" href=`/img/icon/${site.domainKey}/icon-180x180.png?v=${pkg.version}`) +link(rel="icon" type="image/png" sizes="32x32" href=`/img/icon/${site.domainKey}/icon-32x32.png?v=${pkg.version}`) +link(rel="icon" type="image/png" sizes="96x96" href=`/img/icon/${site.domainKey}/icon-96x96.png?v=${pkg.version}`) +link(rel="icon" type="image/png" sizes="16x16" href=`/img/icon/${site.domainKey}/icon-16x16.png?v=${pkg.version}`) +link(rel="icon" type="image/png" sizes="512x512" href=`/img/icon/${site.domainKey}/icon-512x512.png?v=${pkg.version}`) +link(rel="icon" type="image/png" sizes="384x384" href=`/img/icon/${site.domainKey}/icon-384x384.png?v=${pkg.version}`) +link(rel="icon" type="image/png" sizes="256x256" href=`/img/icon/${site.domainKey}/icon-512x512.png?v=${pkg.version}`) +link(rel="icon" type="image/png" sizes="192x192" href=`/img/icon/${site.domainKey}/icon-192x192.png?v=${pkg.version}`) +link(rel="manifest" href=`/manifest.json?v=${pkg.version}`) +meta(name="msapplication-TileColor" content="#f1c52f") +meta(name="msapplication-TileImage" content=`/img/icon/ms-icon-144x144.png?v=${pkg.version}`) +meta(name="theme-color" content="#f1c52f") \ No newline at end of file diff --git a/app/views/components/site-link.pug b/app/views/components/site-link.pug new file mode 100644 index 0000000..0abb06c --- /dev/null +++ b/app/views/components/site-link.pug @@ -0,0 +1,3 @@ +mixin renderSiteLink ( ) + a(href="/").uk-link-reset + span.brand-emphasis #{site.name} \ No newline at end of file diff --git a/app/views/components/social-card/facebook.pug b/app/views/components/social-card/facebook.pug new file mode 100644 index 0000000..d017243 --- /dev/null +++ b/app/views/components/social-card/facebook.pug @@ -0,0 +1,8 @@ +block facebook-card + meta(property='og:site_name', content= site.name) + meta(property='og:type', content='website') + meta(property='og:image', content= `https://${site.domain}/img/social-cards/${site.domain}.png?v=${pkg.version}`) + meta(property='og:url', content= `https://${site.domain}${dtp.request.url}`) + meta(property='og:title', content= `${site.name} | ${site.description}`) + meta(property='og:description', content= site.description) + meta(property='og:image:alt', content= `${site.name} | ${site.description}`) \ No newline at end of file diff --git a/app/views/components/social-card/twitter.pug b/app/views/components/social-card/twitter.pug new file mode 100644 index 0000000..796bea8 --- /dev/null +++ b/app/views/components/social-card/twitter.pug @@ -0,0 +1,5 @@ +block twitter-card + meta(name='twitter:card', content='summary_large_image') + meta(name='twitter:image' content= `https://${site.domain}/img/social-cards/${site.domain}.png?v=${pkg.version}`) + meta(name='twitter:title', content= `${site.name} | ${site.description}`) + meta(name='twitter:description', content= site.description) \ No newline at end of file diff --git a/app/views/components/term-list-tile.pug b/app/views/components/term-list-tile.pug new file mode 100644 index 0000000..0daec39 --- /dev/null +++ b/app/views/components/term-list-tile.pug @@ -0,0 +1,6 @@ +include term-list +mixin renderTermListTile (termList, tileTitle) + section.uk-section.uk-section-muted.uk-section-xsmall + .uk-container.uk-container-expand + h4.uk-heading.uk-text-center= tileTitle + +renderTermList(termList) \ No newline at end of file diff --git a/app/views/components/term-list.pug b/app/views/components/term-list.pug new file mode 100644 index 0000000..7d9405d --- /dev/null +++ b/app/views/components/term-list.pug @@ -0,0 +1,14 @@ +include item-metabar +mixin renderTermList (terms) + - var submitUrl = user ? '/term/submit' : '/welcome?src=submit'; + if Array.isArray(terms) && (terms.length > 0) + ul.uk-list.uk-list-divider + each term in terms + li(data-term-id= term._id) + a(href=`/term/${term._id}`).uk-display-block.uk-link-reset.uk-margin-small + h4.uk-heading.uk-margin-remove= term.term + if term.definition && term.definition.content + .markdown-block!= anchorme(marked(term.definition.content)) + +renderItemMetabar(term, 'term') + else + .uk-text-muted There are no terms at this time. #[a(href=submitUrl) Submit one] now to get started! \ No newline at end of file diff --git a/app/views/components/view-title.pug b/app/views/components/view-title.pug new file mode 100644 index 0000000..17250be --- /dev/null +++ b/app/views/components/view-title.pug @@ -0,0 +1,27 @@ +mixin renderViewTitle (title, options) + .uk-navbar-container.uk-padding-remove.uk-position-fixed.uk-position-top + nav(uk-navbar) + .uk-navbar-left + .uk-navbar-item + div(uk-grid).uk-grid-small.uk-flex-middle + .uk-width-expand + .uk-text-large.uk-margin-remove.no-select + if options && options.iconClass + span.uk-margin-small-right + i(class= options.iconClass) + span= title + .uk-navbar-right + if options && options.href && options.prompt + .uk-navbar-item + a(href= options.href).uk-button.dtp-button-navbar.uk-button-small.uk-border-rounded + span + i.fas.fa-plus + span(class="uk-visible@s").uk-margin-small-left= options.prompt + if options && options.includeBackButton + .uk-navbar-item + button(type="button", onclick="window.history.back();").uk-button.dtp-button-navbar.uk-button-small.uk-border-rounded + span + i.fas.fa-chevron-left + span(class="uk-visible@s").uk-margin-small-left Back + //- section(uk-sticky).uk-section.uk-section-secondary.uk-section-xsmall + //- .uk-container.uk-container-expand diff --git a/app/views/error.pug b/app/views/error.pug new file mode 100644 index 0000000..077adc4 --- /dev/null +++ b/app/views/error.pug @@ -0,0 +1,17 @@ +extends layouts/main +block content + + section.uk-section.uk-section-default.uk-section-xsmall + .uk-container + .uk-text-large= message + //- if error.stack + //- pre= error.stack + if error && error.status + div.uk-text-small.uk-text-muted status:#{error.status} + + section.uk-section.uk-section-primary.uk-section-xsmall + .uk-container + a(href="/").uk-button.uk-button-default.uk-border-rounded + span.uk-margin-small-right + i.fas.fa-home + span Home \ No newline at end of file diff --git a/app/views/home/logged-in.member.pug b/app/views/home/logged-in.member.pug new file mode 100644 index 0000000..c580e1c --- /dev/null +++ b/app/views/home/logged-in.member.pug @@ -0,0 +1,13 @@ +section.uk-section.uk-section-default + .uk-container + + h1(class="uk-text-center uk-text-left@m") #[small Welcome to]#[br]#[+renderSiteLink()] + + p Please create a #[a(href='/voter/signup') Voter Profile] to start supporting committees and candidates. As you do, this home page will become your Voter Dashboard with all the latest updates from the committees and candidates you are supporting. + + div(class="uk-flex uk-flex-center uk-flex-left@m") + .uk-width-auto + a(href="/voter/signup").uk-button.uk-button-primary + span + i.fas.fa-user + span.uk-margin-small-left.uk-text-bold Create Voter Profile \ No newline at end of file diff --git a/app/views/home/logged-in.voter.pug b/app/views/home/logged-in.voter.pug new file mode 100644 index 0000000..75a9661 --- /dev/null +++ b/app/views/home/logged-in.voter.pug @@ -0,0 +1,72 @@ +include ../committee/components/post +include ../committee/components/article-summary + +section.uk-section.uk-section-default + .uk-container + + div(uk-grid) + + div(class="uk-width-1-3 uk-visible@m uk-width-1-4@l") + ul(class="uk-visible@m").uk-nav.uk-nav-default.uk-nav-divider + li.uk-nav-header Site Navigation + li(class={ 'uk-active': (currentView === 'home')}) + a(href="/") + span.nav-item-icon + i.fas.fa-home + span.uk-margin-small-left Home + li + a(href=`/user/${user._id}`) + span.nav-item-icon + i.fas.fa-user + span.uk-margin-small-left Profile + if committee + li.uk-nav-header Committee Links + li(class={ 'uk-active': (currentView === 'committee') }) + a(href=`/committee/${committee.slug}`) + span.nav-item-icon + i.fas.fa-home + span.uk-margin-small-left= committee.name + a(href=`/committee/${committee.slug}/dashboard`) + span.nav-item-icon + i.fas.fa-tachometer-alt + span.uk-margin-small-left Dashboard + + if voter + li.uk-nav-header Voter Links + li + a(href="/voter") + span.nav-item-icon + i.fas.fa-tachometer-alt + span.uk-margin-small-left Voter Dashboard + + div(class="uk-width-1-1 uk-width-expand@m") + ul.uk-list + each feedItem in siteFeed + li + case feedItem.itemType + when 'Article' + +renderCommitteeArticleSummary(feedItem.item) + when 'Post' + +renderCommitteePost(feedItem.item) + + div(class="uk-width-1-3 uk-visible@m uk-width-1-4@l") + ul.uk-list + li + .uk-card.uk-card-secondary.uk-card-body.uk-border-rounded + h3.uk-card-title Featured Candidates + p This will be a list of candidates running for office who are growing their support base in your area. + + li + .uk-card.uk-card-secondary.uk-card-body.uk-border-rounded + h3.uk-card-title Committee Spotlight + p This will be a list of committees who are growing their support base in your area. + + li + .uk-card.uk-card-secondary.uk-card-body.uk-border-rounded + h3.uk-card-title Recent Wins + p This will highlight posts tagged as wins + + li + .uk-card.uk-card-secondary.uk-card-body.uk-border-rounded + h3.uk-card-title Recent Lessons + p This will highlight posts tagged as lessons learned. \ No newline at end of file diff --git a/app/views/home/logged-out.pug b/app/views/home/logged-out.pug new file mode 100644 index 0000000..05df898 --- /dev/null +++ b/app/views/home/logged-out.pug @@ -0,0 +1,20 @@ +section.uk-section.uk-section-default + .uk-container + .uk-text-lead Welcome to #[+renderSiteLink()] + p We are a new organization that exists to empower small and grassroots conservative Republican Political Action Committees with the resources more commonly reserved for larger organizations. + +section.uk-section.uk-section-primary.uk-section-xsmall + .uk-container + div(uk-grid).uk-grid-small.uk-flex-around + .uk-width-auto + .uk-margin + a(href="/welcome/signup").uk-button.uk-button-primary + span + i.fas.fa-user-plus + span.uk-margin-small-left JOIN NOW + .uk-width-auto + .uk-margin + a(href="/welcome/login").uk-button.uk-button-secondary + span + i.fas.fa-sign-in-alt + span.uk-margin-small-left SIGN IN diff --git a/app/views/index.pug b/app/views/index.pug new file mode 100644 index 0000000..cd5cbca --- /dev/null +++ b/app/views/index.pug @@ -0,0 +1,16 @@ +extends layouts/main +block content + + section.uk-section.uk-section-default.uk-padding-remove + .uk-container + div(style="position: relative; overflow: hidden; width: 100%; padding-top: 56.25%") + iframe( + src="https://tv.gab.com/channel/mrjoeprich/embed/what-is-just-joe-radio-61ad9b2165a83d20e95a465d", + width="960", + height="540", + style="position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%;", + ) + + section.uk-section.uk-section-secondary + .uk-container + .uk-text-lead.uk-text-center Welcome to the new online home of #{site.name}! We just getting started. Hang tight! \ No newline at end of file diff --git a/app/views/layouts/main.pug b/app/views/layouts/main.pug new file mode 100644 index 0000000..d87dac9 --- /dev/null +++ b/app/views/layouts/main.pug @@ -0,0 +1,111 @@ +include ../components/library +doctype html +html(lang='en') + head + meta(charset='UTF-8') + meta(name='viewport', content='width=device-width, initial-scale=1.0') + meta(name='description', content= pageDescription || siteDescription) + + title= pageTitle ? `${pageTitle} | ${site.name}` : site.name + + meta(name="robots", content= "index,follow") + meta(name="googlebot", conten= "index,follow") + meta(content="#4a4a4a" name="theme-color") + meta(content="black-translucent" name="apple-mobile-web-app-status-bar-style") + + block css + + link(rel='stylesheet', href=`/fontawesome/css/all.min.css?v=${pkg.version}`) + + block vendorcss + + link(rel='stylesheet', href=`/dist/css/style.css?v=${pkg.version}`) + + block js + script(src=`/uikit/js/uikit.min.js?v=${pkg.version}`) + script(src=`/uikit/js/uikit-icons.min.js?v=${pkg.version}`) + script(src=`/fontawesome/js/fontawesome.min.js?v=${pkg.version}`) + + block pwa-support + include ../components/pwa-support + + block social-card + include ../components/social-card/twitter + include ../components/social-card/facebook + + block view-header + + script. + + function onImageLoadError (event) { + const imageType = event.currentTarget.getAttribute('data-image-type') || 'thumb'; + console.error('image error', imageType, event); + switch (imageType) { + case 'profile': + event.currentTarget.setAttribute('src', '/img/default-member.png'); + break; + case 'thumb': + event.currentTarget.setAttribute('src', '/img/default-poster.jpg'); + break; + } + } + + body.dtp(class= 'dtp-dark', data-dtp-env= process.env.NODE_ENV, data-dtp-domain= site.domainKey, data-current-view= currentView) + + include ../components/site-link + + block view-globals + + block content-container + block content + //- block page-footer + //- include ../components/page-footer + + block dtp-navbar + include ../components/navbar + + block view-title + + block dtp-off-canvas + include ../components/off-canvas + + block clientjs + if user + - + var safeUser = { + _id: user._id, + created: user.created, + username: user.username, + username_lc: user.username_lc, + displayName: user.displayName, + }; + + script(src=`/moment/moment.min.js?v=${pkg.version}`) + script(src=`/numeral/numeral.min.js?v=${pkg.version}`) + script(src=`/socket.io/socket.io.js?v=${pkg.version}`) + + block vendorjs + + script. + window.dtp = window.dtp || { }; + + if user + script. + window.dtp.user = !{JSON.stringify(safeUser, null, 2)} + + if channel + script. + dtp.channel = !{JSON.stringify(channel || null)}; + + if DTP_SCRIPT_DEBUG + script(src=`/dist/js/dtpsites-app.js?v=${pkg.version}`, type="module") + else + script(src=`/dist/js/dtpsites-app.min.js?v=${pkg.version}`, type="module") + + if user && user.flags.isAdmin + if DTP_SCRIPT_DEBUG + script(src=`/dist/js/dtpsites-admin.js?v=${pkg.version}`, type="module") + else + script(src=`/dist/js/dtpsites-admin.min.js?v=${pkg.version}`, type="module") + + block viewjs \ No newline at end of file diff --git a/app/views/otp/authenticate.pug b/app/views/otp/authenticate.pug new file mode 100644 index 0000000..ff066a8 --- /dev/null +++ b/app/views/otp/authenticate.pug @@ -0,0 +1,27 @@ +extends ../layouts/main +block content + + section.uk-section.uk-section-primary.uk-section-xsmall + .uk-container.uk-text-center + h1 #{site.name} #{otpServiceName} Passcode Required + .uk-text-large A one-time passcode is required to access #{site.name} #{otpServiceName} on this server + + section.uk-section.uk-section-default.uk-section-xsmall + .uk-container + form(method="POST", action="/auth/otp/auth") + input(type="hidden", name="otp-service", value= otpServiceName) + input(type="hidden", name="otp-redirect", value= otpRedirectURL) + .uk-width-1-2.uk-margin-auto + .uk-margin.uk-text-center + label(for="otp-passcode").uk-form-label Enter passcode: + input( + id="otp-passcode", + name="otp-passcode", + type="text", + placeholder="######", + autocomplete="off", + ).uk-input.uk-form-large.uk-text-center + .uk-text-muted.uk-text-small Please enter a passcode from your authenticator app for #{site.name} #{otpServiceName}:#{user.username} + + .uk-margin.uk-text-center + button(type="submit").uk-button.uk-button-primary.uk-border-pill Login \ No newline at end of file diff --git a/app/views/otp/new-account.pug b/app/views/otp/new-account.pug new file mode 100644 index 0000000..4f089c4 --- /dev/null +++ b/app/views/otp/new-account.pug @@ -0,0 +1,11 @@ +extends ../layouts/main +block content + + section.uk-section.uk-section-primary.uk-section-xsmall + .uk-container + h1 2FA Setup Successful + + section.uk-section.uk-section-default.uk-section-xsmall + .uk-container + p Your account is now enabled with access to #{site.name} #{otpServiceName}. + a(href= otpRedirectURL, title="Continue").uk-button.uk-button-primary.uk-border-pill Continue \ No newline at end of file diff --git a/app/views/otp/welcome.pug b/app/views/otp/welcome.pug new file mode 100644 index 0000000..1ec18be --- /dev/null +++ b/app/views/otp/welcome.pug @@ -0,0 +1,61 @@ +extends ../layouts/main +block content + + section.uk-section.uk-section-primary.uk-section-xsmall + .uk-container + h1 #{site.name} #{otpServiceName} 2FA Setup + div(class="uk-text-large uk-visible@m") Two-factor authentication is required to access #{site.name} #{otpServiceName}. + + section.uk-section.uk-section-default.uk-section-xsmall + .uk-container + form(method="POST", action="/auth/otp/enable") + input(type="hidden", name="otp-secret", value= otpTempSecret) + input(type="hidden", name="otp-service", value= otpServiceName) + input(type="hidden", name="otp-redirect", value= otpRedirectURL) + div(uk-grid) + + div(class="uk-width-1-1 uk-width-auto@s uk-text-center") + .uk-margin + canvas(id="otp-qrcode", width="480", height="480") + .uk-margin + a(href=otpKeyURI, title="Add to Authenticator App").uk-button.uk-button-default.uk-border-pill Add to authenticator + + div(class="uk-width-1-1 uk-width-expand@s uk-text-center uk-text-left@m") + .uk-margin + p You can scan this QR code using an authenticator app such as #[a(href="https://freeotp.github.io/") FreeOTP], or select "Add to authenticator" if you are using the device with your authenticator app installed. + + p Your authenticator will begin displaying #{otpOptions.digits}-digit authentication codes. Enter one below to enable Two-Factor Authentication (2FA) for #{site.name} #{otpServiceName} (as #{user.username}). + + .uk-text-center + .uk-margin + label(for="otp-passcode").uk-form-label Enter passcode: + br + input( + id="otp-passcode", + name="otp-passcode", + type="text", + placeholder="######", + autocomplete="off", + ).uk-input.uk-form-large.uk-text-center.uk-width-1-2 + + .uk-margin + button(type="submit").uk-button.uk-button-primary.uk-border-pill Enable 2FA + + div(class="uk-width-1-1 uk-text-center uk-text-left@m", hidden) + .uk-margin + p Or, if your authenticator doesn't support scanning QR codes, you can enter the OTP configuration information shown here to begin displaying codes: + pre( + style="display: inline-block; border: solid 1px #888888; padding: 8px;" + ).uk-border.uk-text-left.uk-margin-remove. + Secret: #{otpTempSecret} + Algorithm: #{otpOptions.algorithm.toUpperCase()} + Step/Period: #{otpOptions.step} + Digits: #{otpOptions.digits} + +block viewjs + script. + window.dtp.keyURI = !{JSON.stringify(otpKeyURI)}; + window.addEventListener('dtp-load', async ( ) => { + const canvas = document.getElementById('otp-qrcode'); + dtp.app.generateOtpQR(canvas, window.dtp.keyURI); + }); \ No newline at end of file diff --git a/app/views/page/index.pug b/app/views/page/index.pug new file mode 100644 index 0000000..cfeb936 --- /dev/null +++ b/app/views/page/index.pug @@ -0,0 +1,12 @@ +extends ../layouts/main +block content + + include ../components/page-header + + section.uk-section.uk-section-default.uk-section-xsmall + .uk-container + h1 Pages + ul.uk-list + each page of pages + li + h1= page.title \ No newline at end of file diff --git a/app/views/page/view.pug b/app/views/page/view.pug new file mode 100644 index 0000000..fb11ee9 --- /dev/null +++ b/app/views/page/view.pug @@ -0,0 +1,9 @@ +extends ../layouts/main +block content + + include ../components/page-header + + section.uk-section.uk-section-default + .container + h1= page.title + article= page.content \ No newline at end of file diff --git a/app/views/user/profile.pug b/app/views/user/profile.pug new file mode 100644 index 0000000..c60bebf --- /dev/null +++ b/app/views/user/profile.pug @@ -0,0 +1,9 @@ +extends ../layouts/main +block content + + section.uk-section.uk-section-default + .uk-container + h1= user.displayName || user.username || user.email + p Viewers do not have public profiles on #[+renderSiteLink()]. You must be logged in to view your profile. Only you can view your profile. + + p Your profile is where you manage your channel subscriptions, edit account settings, configure your chat defaults, and otherwise manage how you use #[+renderSiteLink()]. \ No newline at end of file diff --git a/app/views/user/settings.pug b/app/views/user/settings.pug new file mode 100644 index 0000000..a6ff2fc --- /dev/null +++ b/app/views/user/settings.pug @@ -0,0 +1,31 @@ +extends ../layouts/main +block vendorcss + link(rel='stylesheet', href=`/cropperjs/cropper.min.css?v=${pkg.version}`) +block vendorjs + script(src=`/cropperjs/cropper.min.js?v=${pkg.version}`) +block content + + include ../components/file-upload-image + + section.uk-section.uk-section-default + .uk-container + h1 Settings + + div(uk-grid) + div(class="uk-width-1-1 uk-width-1-3@m") + - + var currentImage = null; + if (user.picture && user.picture.large) { + currentImage = user.picture.large; + } + +renderFileUploadImage(`/user/${user._id}/profile-photo`, 'test-image-upload', 'profile-picture-file', 'site-profile-picture', `/img/default-member.png`, currentImage) + div(class="uk-width-1-1 uk-width-expand@m") + form(method="POST", action=`/user/${user._id}/settings`, onsubmit="return dtp.app.submitForm(event, 'user account update');").uk-form + .uk-margin + label(for="username").uk-form-label Username + input(id="username", name="username", type="text", placeholder="Enter username", value= user.username).uk-input + .uk-margin + label(for="display-name").uk-form-label Display Name + input(id="display-name", name="displayName", type="text", placeholder="Enter display name", value= user.displayName).uk-input + .uk-margin + button(type="submit").uk-button.dtp-button-primary Update account settings \ No newline at end of file diff --git a/app/views/welcome/index.pug b/app/views/welcome/index.pug new file mode 100644 index 0000000..4b7af06 --- /dev/null +++ b/app/views/welcome/index.pug @@ -0,0 +1,14 @@ +extends ../layouts/main +block content + + section.uk-section.uk-section-secondary + .uk-container.uk-text-center + h1 Welcome to #{site.name} + .uk-text-lead= site.description + + .uk-margin-medium-top + div(uk-grid).uk-flex-center + .uk-width-auto + a(href="/welcome/signup").uk-button.dtp-button-primary Create Account + .uk-width-auto + a(href="/welcome/login").uk-button.dtp-button-secondary Sign In \ No newline at end of file diff --git a/app/views/welcome/login.pug b/app/views/welcome/login.pug new file mode 100644 index 0000000..39eaec0 --- /dev/null +++ b/app/views/welcome/login.pug @@ -0,0 +1,24 @@ +extends ../layouts/main +block content + + form(method="POST", action="/auth/login").uk-form + section.uk-section.uk-section-default + .uk-container + fieldset.uk-fieldset + legend(class="uk-text-center uk-text-left@m").uk-legend Member Login + if loginResult + div(uk-alert).uk-alert.uk-alert-danger= loginResult + .uk-margin + label(for="username", class="uk-visible@m").uk-form-label Username or email address + input(id="username", name="username", type="text", placeholder="Enter username or email address").uk-input + + .uk-margin + label(for="password", class="uk-visible@m").uk-form-label Password + input(id="password", name="password", type="password", placeholder="Enter password").uk-input + .uk-text-muted.uk-text-small.uk-margin-small-top Remember that password we said you shouldn't forget? Type that here. + + section.uk-section.uk-section-secondary.uk-section-xsmall + .uk-container + .uk-margin + .uk-flex.uk-flex-center + button(type="submit").uk-button.dtp-button-primary Login \ No newline at end of file diff --git a/app/views/welcome/signup.pug b/app/views/welcome/signup.pug new file mode 100644 index 0000000..92a74a7 --- /dev/null +++ b/app/views/welcome/signup.pug @@ -0,0 +1,44 @@ +extends ../layouts/main +block content + + form(method="POST", action="/user").uk-form + section.uk-section.uk-section-muted.uk-section + .uk-container.uk-container-small + p You are creating a new member account on #[+renderSiteLink()]. If you have an account, please #[a(href="/welcome/login") log in here]. + + .uk-margin + label(for="email").uk-form-label Email + input(id="email", name="email", type="email", autocomplete="off", placeholder="Enter your email address").uk-input + .uk-text-small.uk-text-muted.uk-margin-small-top(class="uk-visible@m") I'm throwing your email address away after the demo, and I'm not verifying it. You won't receive email. + + .uk-margin + label(for="username").uk-form-label Username + input(id="username", name="username", type="text", autocomplete="off", placeholder="Enter a username").uk-input + .uk-text-small.uk-text-muted.uk-margin-small-top(class="uk-visible@m") 40 characters max. No spaces. A-Z, a-z, 0-9, - (dash) and _ (underscore). + + .uk-margin + label(for="display-name").uk-form-label Display Name + input(id="display-name", name="displayName", type="text", autocomplete="off", placeholder="Enter a display name").uk-input + .uk-text-small.uk-text-muted.uk-margin-small-top(class="uk-visible@m") 40 characters max, and can include most printable characters including emojis, spaces, whatever you're into within reason. + + .uk-margin + div(uk-grid) + .uk-width-1-2 + .uk-margin + label(for="password").uk-form-label Password + input(id="password", name="password", type="password", placeholder="Enter password").uk-input + .uk-text-small.uk-text-muted.uk-margin-small-top(class="uk-visible@m") Don't forget your password. There is no reset (yet). + + .uk-width-1-2 + .uk-margin + label(for="passwordv").uk-form-label Verify password + input(id="passwordv", name="passwordv", type="password", placeholder="Verify password").uk-input + .uk-text-small.uk-text-muted.uk-margin-small-top(class="uk-visible@m") Please enter your password again to prove you're not an idiot. + + section.uk-section.uk-section-secondary.uk-section + .uk-container.uk-container-small + .uk-margin-large + .uk-text-center + .uk-margin-small + button(type="submit").uk-button.uk-button-primary Create Account + .uk-text-center.uk-text-small.uk-text-muted You aren't going to be asked for money and I'm not going to bug you. This is only a technology demo. \ No newline at end of file diff --git a/client/img/altmedia.png b/client/img/altmedia.png new file mode 100644 index 0000000..b00f2f5 Binary files /dev/null and b/client/img/altmedia.png differ diff --git a/client/img/default-member.png b/client/img/default-member.png new file mode 100644 index 0000000..afeaaa0 Binary files /dev/null and b/client/img/default-member.png differ diff --git a/client/img/default-poster.jpg b/client/img/default-poster.jpg new file mode 100644 index 0000000..919d8ab Binary files /dev/null and b/client/img/default-poster.jpg differ diff --git a/client/img/donate-qr-init.png b/client/img/donate-qr-init.png new file mode 100644 index 0000000..4ec7b4b Binary files /dev/null and b/client/img/donate-qr-init.png differ diff --git a/client/img/gab-g.svg b/client/img/gab-g.svg new file mode 100644 index 0000000..4acec36 --- /dev/null +++ b/client/img/gab-g.svg @@ -0,0 +1,63 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/client/img/header-sample.png b/client/img/header-sample.png new file mode 100644 index 0000000..abec896 Binary files /dev/null and b/client/img/header-sample.png differ diff --git a/client/img/icon/altmedia.tv.png b/client/img/icon/altmedia.tv.png new file mode 100644 index 0000000..cc432a9 Binary files /dev/null and b/client/img/icon/altmedia.tv.png differ diff --git a/client/img/icon/altmedia.tv/home.png b/client/img/icon/altmedia.tv/home.png new file mode 100644 index 0000000..4ae4e23 Binary files /dev/null and b/client/img/icon/altmedia.tv/home.png differ diff --git a/client/img/icon/altmedia.tv/icon-114x114.png b/client/img/icon/altmedia.tv/icon-114x114.png new file mode 100644 index 0000000..db26bde Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-114x114.png differ diff --git a/client/img/icon/altmedia.tv/icon-120x120.png b/client/img/icon/altmedia.tv/icon-120x120.png new file mode 100644 index 0000000..fab6d18 Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-120x120.png differ diff --git a/client/img/icon/altmedia.tv/icon-144x144.png b/client/img/icon/altmedia.tv/icon-144x144.png new file mode 100644 index 0000000..3b01b10 Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-144x144.png differ diff --git a/client/img/icon/altmedia.tv/icon-150x150.png b/client/img/icon/altmedia.tv/icon-150x150.png new file mode 100644 index 0000000..4805997 Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-150x150.png differ diff --git a/client/img/icon/altmedia.tv/icon-152x152.png b/client/img/icon/altmedia.tv/icon-152x152.png new file mode 100644 index 0000000..eed519d Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-152x152.png differ diff --git a/client/img/icon/altmedia.tv/icon-16x16.png b/client/img/icon/altmedia.tv/icon-16x16.png new file mode 100644 index 0000000..51424ae Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-16x16.png differ diff --git a/client/img/icon/altmedia.tv/icon-180x180.png b/client/img/icon/altmedia.tv/icon-180x180.png new file mode 100644 index 0000000..cb0980f Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-180x180.png differ diff --git a/client/img/icon/altmedia.tv/icon-192x192.png b/client/img/icon/altmedia.tv/icon-192x192.png new file mode 100644 index 0000000..281aadc Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-192x192.png differ diff --git a/client/img/icon/altmedia.tv/icon-256x256.png b/client/img/icon/altmedia.tv/icon-256x256.png new file mode 100644 index 0000000..23a8c6d Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-256x256.png differ diff --git a/client/img/icon/altmedia.tv/icon-310x310.png b/client/img/icon/altmedia.tv/icon-310x310.png new file mode 100644 index 0000000..81d8ffc Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-310x310.png differ diff --git a/client/img/icon/altmedia.tv/icon-32x32.png b/client/img/icon/altmedia.tv/icon-32x32.png new file mode 100644 index 0000000..4dc093d Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-32x32.png differ diff --git a/client/img/icon/altmedia.tv/icon-36x36.png b/client/img/icon/altmedia.tv/icon-36x36.png new file mode 100644 index 0000000..d46e47e Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-36x36.png differ diff --git a/client/img/icon/altmedia.tv/icon-384x384.png b/client/img/icon/altmedia.tv/icon-384x384.png new file mode 100644 index 0000000..0993c6b Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-384x384.png differ diff --git a/client/img/icon/altmedia.tv/icon-48x48.png b/client/img/icon/altmedia.tv/icon-48x48.png new file mode 100644 index 0000000..f5d12ca Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-48x48.png differ diff --git a/client/img/icon/altmedia.tv/icon-512x512.png b/client/img/icon/altmedia.tv/icon-512x512.png new file mode 100644 index 0000000..cbe89f6 Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-512x512.png differ diff --git a/client/img/icon/altmedia.tv/icon-57x57.png b/client/img/icon/altmedia.tv/icon-57x57.png new file mode 100644 index 0000000..3188e4d Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-57x57.png differ diff --git a/client/img/icon/altmedia.tv/icon-60x60.png b/client/img/icon/altmedia.tv/icon-60x60.png new file mode 100644 index 0000000..25c55af Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-60x60.png differ diff --git a/client/img/icon/altmedia.tv/icon-70x70.png b/client/img/icon/altmedia.tv/icon-70x70.png new file mode 100644 index 0000000..0e2dab4 Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-70x70.png differ diff --git a/client/img/icon/altmedia.tv/icon-72x72.png b/client/img/icon/altmedia.tv/icon-72x72.png new file mode 100644 index 0000000..7906d49 Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-72x72.png differ diff --git a/client/img/icon/altmedia.tv/icon-76x76.png b/client/img/icon/altmedia.tv/icon-76x76.png new file mode 100644 index 0000000..a699425 Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-76x76.png differ diff --git a/client/img/icon/altmedia.tv/icon-96x96.png b/client/img/icon/altmedia.tv/icon-96x96.png new file mode 100644 index 0000000..0f500d1 Binary files /dev/null and b/client/img/icon/altmedia.tv/icon-96x96.png differ diff --git a/client/img/icon/freetopray.tv.png b/client/img/icon/freetopray.tv.png new file mode 100644 index 0000000..73bcfdd Binary files /dev/null and b/client/img/icon/freetopray.tv.png differ diff --git a/client/img/icon/freetopray.tv/home.png b/client/img/icon/freetopray.tv/home.png new file mode 100644 index 0000000..acbeaaf Binary files /dev/null and b/client/img/icon/freetopray.tv/home.png differ diff --git a/client/img/icon/freetopray.tv/icon-114x114.png b/client/img/icon/freetopray.tv/icon-114x114.png new file mode 100644 index 0000000..12a51a1 Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-114x114.png differ diff --git a/client/img/icon/freetopray.tv/icon-120x120.png b/client/img/icon/freetopray.tv/icon-120x120.png new file mode 100644 index 0000000..52f875d Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-120x120.png differ diff --git a/client/img/icon/freetopray.tv/icon-144x144.png b/client/img/icon/freetopray.tv/icon-144x144.png new file mode 100644 index 0000000..6bd0d9b Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-144x144.png differ diff --git a/client/img/icon/freetopray.tv/icon-150x150.png b/client/img/icon/freetopray.tv/icon-150x150.png new file mode 100644 index 0000000..51db00b Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-150x150.png differ diff --git a/client/img/icon/freetopray.tv/icon-152x152.png b/client/img/icon/freetopray.tv/icon-152x152.png new file mode 100644 index 0000000..c675c39 Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-152x152.png differ diff --git a/client/img/icon/freetopray.tv/icon-16x16.png b/client/img/icon/freetopray.tv/icon-16x16.png new file mode 100644 index 0000000..fd4aa21 Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-16x16.png differ diff --git a/client/img/icon/freetopray.tv/icon-180x180.png b/client/img/icon/freetopray.tv/icon-180x180.png new file mode 100644 index 0000000..6a05e7d Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-180x180.png differ diff --git a/client/img/icon/freetopray.tv/icon-192x192.png b/client/img/icon/freetopray.tv/icon-192x192.png new file mode 100644 index 0000000..a9999d0 Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-192x192.png differ diff --git a/client/img/icon/freetopray.tv/icon-256x256.png b/client/img/icon/freetopray.tv/icon-256x256.png new file mode 100644 index 0000000..6dc4bc8 Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-256x256.png differ diff --git a/client/img/icon/freetopray.tv/icon-310x310.png b/client/img/icon/freetopray.tv/icon-310x310.png new file mode 100644 index 0000000..5fcc285 Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-310x310.png differ diff --git a/client/img/icon/freetopray.tv/icon-32x32.png b/client/img/icon/freetopray.tv/icon-32x32.png new file mode 100644 index 0000000..acbeaaf Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-32x32.png differ diff --git a/client/img/icon/freetopray.tv/icon-36x36.png b/client/img/icon/freetopray.tv/icon-36x36.png new file mode 100644 index 0000000..7b370da Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-36x36.png differ diff --git a/client/img/icon/freetopray.tv/icon-384x384.png b/client/img/icon/freetopray.tv/icon-384x384.png new file mode 100644 index 0000000..98dd3d8 Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-384x384.png differ diff --git a/client/img/icon/freetopray.tv/icon-48x48.png b/client/img/icon/freetopray.tv/icon-48x48.png new file mode 100644 index 0000000..ca4312f Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-48x48.png differ diff --git a/client/img/icon/freetopray.tv/icon-512x512.png b/client/img/icon/freetopray.tv/icon-512x512.png new file mode 100644 index 0000000..6513291 Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-512x512.png differ diff --git a/client/img/icon/freetopray.tv/icon-57x57.png b/client/img/icon/freetopray.tv/icon-57x57.png new file mode 100644 index 0000000..d2bfaca Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-57x57.png differ diff --git a/client/img/icon/freetopray.tv/icon-60x60.png b/client/img/icon/freetopray.tv/icon-60x60.png new file mode 100644 index 0000000..96a2da0 Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-60x60.png differ diff --git a/client/img/icon/freetopray.tv/icon-70x70.png b/client/img/icon/freetopray.tv/icon-70x70.png new file mode 100644 index 0000000..736361e Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-70x70.png differ diff --git a/client/img/icon/freetopray.tv/icon-72x72.png b/client/img/icon/freetopray.tv/icon-72x72.png new file mode 100644 index 0000000..d7605e7 Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-72x72.png differ diff --git a/client/img/icon/freetopray.tv/icon-76x76.png b/client/img/icon/freetopray.tv/icon-76x76.png new file mode 100644 index 0000000..4721c1c Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-76x76.png differ diff --git a/client/img/icon/freetopray.tv/icon-96x96.png b/client/img/icon/freetopray.tv/icon-96x96.png new file mode 100644 index 0000000..393ecc3 Binary files /dev/null and b/client/img/icon/freetopray.tv/icon-96x96.png differ diff --git a/client/img/icon/justjoeradio.com.png b/client/img/icon/justjoeradio.com.png new file mode 100644 index 0000000..3417174 Binary files /dev/null and b/client/img/icon/justjoeradio.com.png differ diff --git a/client/img/icon/justjoeradio.com/icon-114x114.png b/client/img/icon/justjoeradio.com/icon-114x114.png new file mode 100644 index 0000000..cdff427 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-114x114.png differ diff --git a/client/img/icon/justjoeradio.com/icon-120x120.png b/client/img/icon/justjoeradio.com/icon-120x120.png new file mode 100644 index 0000000..8522d1f Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-120x120.png differ diff --git a/client/img/icon/justjoeradio.com/icon-144x144.png b/client/img/icon/justjoeradio.com/icon-144x144.png new file mode 100644 index 0000000..637e04e Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-144x144.png differ diff --git a/client/img/icon/justjoeradio.com/icon-150x150.png b/client/img/icon/justjoeradio.com/icon-150x150.png new file mode 100644 index 0000000..99635d2 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-150x150.png differ diff --git a/client/img/icon/justjoeradio.com/icon-152x152.png b/client/img/icon/justjoeradio.com/icon-152x152.png new file mode 100644 index 0000000..5b80938 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-152x152.png differ diff --git a/client/img/icon/justjoeradio.com/icon-16x16.png b/client/img/icon/justjoeradio.com/icon-16x16.png new file mode 100644 index 0000000..4cd8efc Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-16x16.png differ diff --git a/client/img/icon/justjoeradio.com/icon-180x180.png b/client/img/icon/justjoeradio.com/icon-180x180.png new file mode 100644 index 0000000..7acf658 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-180x180.png differ diff --git a/client/img/icon/justjoeradio.com/icon-192x192.png b/client/img/icon/justjoeradio.com/icon-192x192.png new file mode 100644 index 0000000..4ff9d8e Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-192x192.png differ diff --git a/client/img/icon/justjoeradio.com/icon-256x256.png b/client/img/icon/justjoeradio.com/icon-256x256.png new file mode 100644 index 0000000..f8d2d7f Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-256x256.png differ diff --git a/client/img/icon/justjoeradio.com/icon-310x310.png b/client/img/icon/justjoeradio.com/icon-310x310.png new file mode 100644 index 0000000..b049ab6 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-310x310.png differ diff --git a/client/img/icon/justjoeradio.com/icon-32x32.png b/client/img/icon/justjoeradio.com/icon-32x32.png new file mode 100644 index 0000000..0cddef8 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-32x32.png differ diff --git a/client/img/icon/justjoeradio.com/icon-36x36.png b/client/img/icon/justjoeradio.com/icon-36x36.png new file mode 100644 index 0000000..ce2df49 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-36x36.png differ diff --git a/client/img/icon/justjoeradio.com/icon-384x384.png b/client/img/icon/justjoeradio.com/icon-384x384.png new file mode 100644 index 0000000..b812a38 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-384x384.png differ diff --git a/client/img/icon/justjoeradio.com/icon-48x48.png b/client/img/icon/justjoeradio.com/icon-48x48.png new file mode 100644 index 0000000..b1eda57 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-48x48.png differ diff --git a/client/img/icon/justjoeradio.com/icon-512x512.png b/client/img/icon/justjoeradio.com/icon-512x512.png new file mode 100644 index 0000000..b61ab22 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-512x512.png differ diff --git a/client/img/icon/justjoeradio.com/icon-57x57.png b/client/img/icon/justjoeradio.com/icon-57x57.png new file mode 100644 index 0000000..3df418c Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-57x57.png differ diff --git a/client/img/icon/justjoeradio.com/icon-60x60.png b/client/img/icon/justjoeradio.com/icon-60x60.png new file mode 100644 index 0000000..8df806d Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-60x60.png differ diff --git a/client/img/icon/justjoeradio.com/icon-70x70.png b/client/img/icon/justjoeradio.com/icon-70x70.png new file mode 100644 index 0000000..09aede8 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-70x70.png differ diff --git a/client/img/icon/justjoeradio.com/icon-72x72.png b/client/img/icon/justjoeradio.com/icon-72x72.png new file mode 100644 index 0000000..a8c29bf Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-72x72.png differ diff --git a/client/img/icon/justjoeradio.com/icon-76x76.png b/client/img/icon/justjoeradio.com/icon-76x76.png new file mode 100644 index 0000000..33d87be Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-76x76.png differ diff --git a/client/img/icon/justjoeradio.com/icon-96x96.png b/client/img/icon/justjoeradio.com/icon-96x96.png new file mode 100644 index 0000000..939a540 Binary files /dev/null and b/client/img/icon/justjoeradio.com/icon-96x96.png differ diff --git a/client/img/icon/shing.tv.png b/client/img/icon/shing.tv.png new file mode 100644 index 0000000..276118e Binary files /dev/null and b/client/img/icon/shing.tv.png differ diff --git a/client/img/icon/shing.tv/home.png b/client/img/icon/shing.tv/home.png new file mode 100644 index 0000000..3ae787c Binary files /dev/null and b/client/img/icon/shing.tv/home.png differ diff --git a/client/img/icon/shing.tv/icon-114x114.png b/client/img/icon/shing.tv/icon-114x114.png new file mode 100644 index 0000000..4483058 Binary files /dev/null and b/client/img/icon/shing.tv/icon-114x114.png differ diff --git a/client/img/icon/shing.tv/icon-120x120.png b/client/img/icon/shing.tv/icon-120x120.png new file mode 100644 index 0000000..5560dfa Binary files /dev/null and b/client/img/icon/shing.tv/icon-120x120.png differ diff --git a/client/img/icon/shing.tv/icon-144x144.png b/client/img/icon/shing.tv/icon-144x144.png new file mode 100644 index 0000000..efd3cd1 Binary files /dev/null and b/client/img/icon/shing.tv/icon-144x144.png differ diff --git a/client/img/icon/shing.tv/icon-150x150.png b/client/img/icon/shing.tv/icon-150x150.png new file mode 100644 index 0000000..26c9daa Binary files /dev/null and b/client/img/icon/shing.tv/icon-150x150.png differ diff --git a/client/img/icon/shing.tv/icon-152x152.png b/client/img/icon/shing.tv/icon-152x152.png new file mode 100644 index 0000000..1cda25d Binary files /dev/null and b/client/img/icon/shing.tv/icon-152x152.png differ diff --git a/client/img/icon/shing.tv/icon-16x16.png b/client/img/icon/shing.tv/icon-16x16.png new file mode 100644 index 0000000..a203f83 Binary files /dev/null and b/client/img/icon/shing.tv/icon-16x16.png differ diff --git a/client/img/icon/shing.tv/icon-180x180.png b/client/img/icon/shing.tv/icon-180x180.png new file mode 100644 index 0000000..b7a7625 Binary files /dev/null and b/client/img/icon/shing.tv/icon-180x180.png differ diff --git a/client/img/icon/shing.tv/icon-192x192.png b/client/img/icon/shing.tv/icon-192x192.png new file mode 100644 index 0000000..8b5da07 Binary files /dev/null and b/client/img/icon/shing.tv/icon-192x192.png differ diff --git a/client/img/icon/shing.tv/icon-256x256.png b/client/img/icon/shing.tv/icon-256x256.png new file mode 100644 index 0000000..7d05b59 Binary files /dev/null and b/client/img/icon/shing.tv/icon-256x256.png differ diff --git a/client/img/icon/shing.tv/icon-310x310.png b/client/img/icon/shing.tv/icon-310x310.png new file mode 100644 index 0000000..159493f Binary files /dev/null and b/client/img/icon/shing.tv/icon-310x310.png differ diff --git a/client/img/icon/shing.tv/icon-32x32.png b/client/img/icon/shing.tv/icon-32x32.png new file mode 100644 index 0000000..6ffb901 Binary files /dev/null and b/client/img/icon/shing.tv/icon-32x32.png differ diff --git a/client/img/icon/shing.tv/icon-36x36.png b/client/img/icon/shing.tv/icon-36x36.png new file mode 100644 index 0000000..a7d325b Binary files /dev/null and b/client/img/icon/shing.tv/icon-36x36.png differ diff --git a/client/img/icon/shing.tv/icon-384x384.png b/client/img/icon/shing.tv/icon-384x384.png new file mode 100644 index 0000000..72bd6a8 Binary files /dev/null and b/client/img/icon/shing.tv/icon-384x384.png differ diff --git a/client/img/icon/shing.tv/icon-48x48.png b/client/img/icon/shing.tv/icon-48x48.png new file mode 100644 index 0000000..60ebd52 Binary files /dev/null and b/client/img/icon/shing.tv/icon-48x48.png differ diff --git a/client/img/icon/shing.tv/icon-512x512.png b/client/img/icon/shing.tv/icon-512x512.png new file mode 100644 index 0000000..087f5fa Binary files /dev/null and b/client/img/icon/shing.tv/icon-512x512.png differ diff --git a/client/img/icon/shing.tv/icon-57x57.png b/client/img/icon/shing.tv/icon-57x57.png new file mode 100644 index 0000000..f8134a4 Binary files /dev/null and b/client/img/icon/shing.tv/icon-57x57.png differ diff --git a/client/img/icon/shing.tv/icon-60x60.png b/client/img/icon/shing.tv/icon-60x60.png new file mode 100644 index 0000000..965a22f Binary files /dev/null and b/client/img/icon/shing.tv/icon-60x60.png differ diff --git a/client/img/icon/shing.tv/icon-70x70.png b/client/img/icon/shing.tv/icon-70x70.png new file mode 100644 index 0000000..a6432dc Binary files /dev/null and b/client/img/icon/shing.tv/icon-70x70.png differ diff --git a/client/img/icon/shing.tv/icon-72x72.png b/client/img/icon/shing.tv/icon-72x72.png new file mode 100644 index 0000000..9a59fff Binary files /dev/null and b/client/img/icon/shing.tv/icon-72x72.png differ diff --git a/client/img/icon/shing.tv/icon-76x76.png b/client/img/icon/shing.tv/icon-76x76.png new file mode 100644 index 0000000..db9c6b1 Binary files /dev/null and b/client/img/icon/shing.tv/icon-76x76.png differ diff --git a/client/img/icon/shing.tv/icon-96x96.png b/client/img/icon/shing.tv/icon-96x96.png new file mode 100644 index 0000000..d7a5b62 Binary files /dev/null and b/client/img/icon/shing.tv/icon-96x96.png differ diff --git a/client/img/logo.png b/client/img/logo.png new file mode 100644 index 0000000..aee9756 Binary files /dev/null and b/client/img/logo.png differ diff --git a/client/img/lra-logo.png b/client/img/lra-logo.png new file mode 100644 index 0000000..b87a4dd Binary files /dev/null and b/client/img/lra-logo.png differ diff --git a/client/img/payment/btc.svg b/client/img/payment/btc.svg new file mode 100644 index 0000000..0f5269f --- /dev/null +++ b/client/img/payment/btc.svg @@ -0,0 +1,62 @@ + + + +image/svg+xml + + + + + + + + \ No newline at end of file diff --git a/client/img/payment/eth.svg b/client/img/payment/eth.svg new file mode 100644 index 0000000..42c41e1 --- /dev/null +++ b/client/img/payment/eth.svg @@ -0,0 +1,80 @@ + + + +image/svg+xml + + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/img/payment/give-send-go.png b/client/img/payment/give-send-go.png new file mode 100644 index 0000000..7846f14 Binary files /dev/null and b/client/img/payment/give-send-go.png differ diff --git a/client/img/payment/ltc.svg b/client/img/payment/ltc.svg new file mode 100644 index 0000000..a28cb94 --- /dev/null +++ b/client/img/payment/ltc.svg @@ -0,0 +1,64 @@ + + + + + + image/svg+xml + + + + + + + litecoin-ltc-logo + + + diff --git a/client/img/payment/payment-option.jpg b/client/img/payment/payment-option.jpg new file mode 100644 index 0000000..b7dcd46 Binary files /dev/null and b/client/img/payment/payment-option.jpg differ diff --git a/client/img/social-cards/altmedia.tv.png b/client/img/social-cards/altmedia.tv.png new file mode 100644 index 0000000..a08e64d Binary files /dev/null and b/client/img/social-cards/altmedia.tv.png differ diff --git a/client/img/social-cards/shing.tv.png b/client/img/social-cards/shing.tv.png new file mode 100644 index 0000000..0f8c6f0 Binary files /dev/null and b/client/img/social-cards/shing.tv.png differ diff --git a/client/js/index-admin.js b/client/js/index-admin.js new file mode 100644 index 0000000..fe110ed --- /dev/null +++ b/client/js/index-admin.js @@ -0,0 +1,23 @@ +// index-admin.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'SiteAdmin'; + +const dtp = window.dtp = window.dtp || { }; +dtp.admin = dtp.admin || { }; + +import DtpSiteAdminHostStatsApp from './site-admin-host-stats-app.js'; +import DtpWebLog from 'dtp/dtp-log.js'; + +window.addEventListener('load', async ( ) => { + // application console log + dtp.admin.log = new DtpWebLog(DTP_COMPONENT_NAME); + + dtp.adminApp = new DtpSiteAdminHostStatsApp(dtp.user); + + dtp.admin.log.debug('load', 'dispatching load event'); + window.dispatchEvent(new Event('dtp-load-admin')); +}); \ No newline at end of file diff --git a/client/js/index.js b/client/js/index.js new file mode 100644 index 0000000..e990812 --- /dev/null +++ b/client/js/index.js @@ -0,0 +1,46 @@ +// index.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'Site'; + +const dtp = window. dtp = window.dtp || { }; + +import DtpSiteApp from './site-app.js'; +import DtpWebLog from 'dtp/dtp-log.js'; +import UIkit from 'uikit'; + +window.addEventListener('load', async ( ) => { + // application console log + dtp.log = new DtpWebLog(DTP_COMPONENT_NAME); + + // service worker + if ('serviceWorker' in navigator) { + try { + dtp.registration = await navigator.serviceWorker.register('/dist/js/service_worker.min.js'); + dtp.log.info('load', 'service worker startup complete', { scope: dtp.registration.scope }); + } catch (error) { + console.log('service worker startup failed', { error }); + UIkit.modal.alert(`Service worker startup failed: ${error.message}`); + } + } + + dtp.app = new DtpSiteApp(dtp.user); + if (dtp.user && dtp.user._id) { + await dtp.app.connect(); + } + + dtp.log.debug('load', 'dispatching load event'); + window.dispatchEvent(new Event('dtp-load')); +}); + +document.addEventListener('socketConnected', async ( ) => { + if (dtp.channel) { + dtp.app.socket.joinChannel(dtp.channel._id); + if (dtp.user && (dtp.user._id === dtp.channel.owner._id)) { + dtp.app.socket.joinChannel(`broadcast:${dtp.channel._id}`); + } + } +}); \ No newline at end of file diff --git a/client/js/site-admin-host-stats-app.js b/client/js/site-admin-host-stats-app.js new file mode 100644 index 0000000..2a2e9d8 --- /dev/null +++ b/client/js/site-admin-host-stats-app.js @@ -0,0 +1,205 @@ +// dtp-site-app.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'SiteAdminApp'; +const dtp = window.dtp = window.dtp || { }; + +const GRID_COLOR = '#a0a0a0'; +const GRID_TICK_COLOR = '#707070'; + +const AXIS_TICK_COLOR = '#c0c0c0'; + +const CHART_LINE_USER = 'rgb(0, 192, 0)'; +const CHART_LINE_NICE = 'rgb(160, 160, 160)'; +const CHART_LINE_SYSTEM = 'rgb(192, 192, 0)'; +const CHART_LINE_IRQ = 'rgb(0, 0, 192)'; + +const CHART_LINE_TX_SEC = 'rgb(240, 185, 6)'; +const CHART_LINE_RX_SEC = 'rgb(6, 154, 240)'; + +import DtpApp from 'dtp/dtp-app.js'; +import numeral from 'numeral'; +// import UIkit from 'uikit'; + +export default class DtpSiteAdminHostStatsApp extends DtpApp { + + constructor (user) { + super(DTP_COMPONENT_NAME, user); + this.log.debug('constructor', 'app instance created'); + } + + prepareGraphData ( ) { + this.charts = { cpus: [ ], interfaces: [ ] }; + + this.coreGraphs = document.querySelectorAll('.dtp-cpu-graph'); + this.coreCount = dtp.hostStats[0].cpus.length; + this.cores = [ ]; + for (let idx = 0; idx < this.coreCount; ++idx) { + this.cores.push([ ]); + } + + this.ifaceGraphs = document.querySelectorAll('.dtp-iface-graph'); + this.ifaceCount = this.ifaceGraphs.length; + this.ifaces = { }; + dtp.hostStats[0].network.forEach((iface) => { + this.ifaces[iface.iface] = [ ]; + }); + + dtp.hostStats.forEach((stats) => { + for (let idx = 0; idx < this.coreCount; ++idx) { + const stat = stats.cpus[idx]; + stat.totalTime = stat.user + stat.nice + stat.sys + stat.idle + stat.irq; + this.cores[idx].push({ + created: stats.created, + ...stats.cpus[idx], + }); + } + + stats.network.forEach((iface) => { + iface.created = stats.created; + this.ifaces[iface.iface].push(iface); + }); + }); + } + + renderCpuGraphs ( ) { + for (let idx = 0; idx < this.coreCount; ++idx) { + const ctx = this.coreGraphs[idx].getContext('2d'); + const datasets = [ + { + label: 'user', + data: this.cores[idx].map((sample) => ((sample.user / sample.totalTime) * 100.0)), + borderColor: CHART_LINE_USER, + tension: 0.5, + }, + { + label: 'nice', + data: this.cores[idx].map((sample) => ((sample.nice / sample.totalTime) * 100.0)), + borderColor: CHART_LINE_NICE, + tension: 0.5, + }, + { + label: 'sys', + data: this.cores[idx].map((sample) => ((sample.sys / sample.totalTime) * 100.0)), + borderColor: CHART_LINE_SYSTEM, + tension: 0.5, + }, + { + label: 'irq', + data: this.cores[idx].map((sample) => ((sample.irq / sample.totalTime) * 100.0)), + borderColor: CHART_LINE_IRQ, + tension: 0.5, + }, + ]; + + const chart = new Chart(ctx, { + type: 'line', + data: { + labels: this.cores[idx].map((sample) => sample.created), + datasets, + }, + options: { + scales: { + yAxis: { + display: true, + max: 100.0, + ticks: { + color: AXIS_TICK_COLOR, + }, + grid: { + color: GRID_COLOR, + tickColor: GRID_TICK_COLOR, + }, + }, + xAxis: { + display: false, + }, + }, + plugins: { + title: { display: false }, + subtitle: { display: false }, + legend: { + display: true, + position: 'bottom', + }, + }, + }, + }); + this.charts.cpus.push(chart); + } + } + + renderNetworkGraphs ( ) { + const ifNames = Object.keys(this.ifaces); + + ifNames.forEach((ifName) => { + const iface = this.ifaces[ifName]; + const canvas = document.querySelector(`.dtp-iface-graph[data-iface="${ifName}"]`); + if (!canvas) { + return; + } + const ctx = canvas.getContext('2d'); + + const datasets = [ + { + label: 'TX/sec', + data: iface.map((sample) => sample.txPerSecond), + borderColor: CHART_LINE_TX_SEC, + tension: 0.5, + }, + { + label: 'RX/sec', + data: iface.map((sample) => sample.rxPerSecond), + borderColor: CHART_LINE_RX_SEC, + tension: 0.5, + }, + ]; + + const chart = new Chart(ctx, { + type: 'line', + data: { + labels: iface.map((sample) => sample.created), + datasets, + }, + options: { + scales: { + yAxis: { + display: true, + ticks: { + color: AXIS_TICK_COLOR, + callback: (value) => { + let label = 'Mbps'; + let megabits = value * (8 / 1024.0 / 1000.0); + if (megabits > 1000) { + label = 'Gbps'; + megabits /= 1000.0; + } + return `${numeral(megabits).format('0,0.00')} ${label}`; + }, + }, + grid: { + color: GRID_COLOR, + tickColor: GRID_TICK_COLOR, + }, + }, + xAxis: { display: false }, + }, + plugins: { + title: { display: false }, + subtitle: { display: false }, + legend: { + display: true, + position: 'bottom', + }, + }, + }, + }); + this.charts.interfaces.push(chart); + }); + } +} + +dtp.DtpSiteAdminHostStatsApp = DtpSiteAdminHostStatsApp; \ No newline at end of file diff --git a/client/js/site-app.js b/client/js/site-app.js new file mode 100644 index 0000000..d9b43c8 --- /dev/null +++ b/client/js/site-app.js @@ -0,0 +1,456 @@ +// site-app.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const DTP_COMPONENT_NAME = 'SiteApp'; +const dtp = window.dtp = window.dtp || { }; + +import DtpApp from 'dtp/dtp-app.js'; + +import UIkit from 'uikit'; +import QRCode from 'qrcode'; +import Cropper from 'cropperjs'; + +export default class DtpSiteApp extends DtpApp { + + constructor (user) { + super(DTP_COMPONENT_NAME, user); + this.log.debug('constructor', 'app instance created'); + + this.chat = { + form: document.querySelector('#chat-input-form'), + messageList: document.querySelector('#chat-message-list'), + messages: [ ], + messageMenu: document.querySelector('.chat-message-menu'), + input: document.querySelector('#chat-input-text'), + isAtBottom: true, + }; + if (this.chat.messageList) { + this.chat.messageList.addEventListener('scroll', this.onChatMessageListScroll.bind(this)); + } + if (this.chat.input) { + this.chat.input.addEventListener('keydown', this.onChatInputKeyDown.bind(this)); + } + } + + async connect ( ) { + // can't use "super" because Webpack + this.log.info('connect', 'connecting WebSocket layer'); + await DtpApp.prototype.connect.call(this, { withRetry: true, withError: false }); + if (this.user) { + const { socket } = this.socket; + socket.on('user-chat', this.onUserChat.bind(this)); + } + } + + async onChatInputKeyDown (event) { + this.log.info('onChatInputKeyDown', 'chat input received', { event }); + if (event.key === 'Enter' && !event.shiftKey) { + return this.sendUserChat(event); + } + } + + async sendUserChat (event) { + event.preventDefault(); + + if (!dtp.channel || !dtp.channel._id) { + UIkit.modal.alert('There is a problem with Chat. Please refresh the page.'); + return; + } + + const channelId = dtp.channel._id; + this.log.info('chat form', channelId); + + const content = this.chat.input.value; + this.chat.input.value = ''; + + if (content.length === 0) { + return true; + } + + this.log.info('sendUserChat', 'sending chat message', { channel: this.user._id, content }); + this.socket.sendUserChat(channelId, content); + + // set focus back to chat input + this.chat.input.focus(); + + return true; + } + + async onUserChat (message) { + this.log.info('onUserChat', 'message received', { user: message.user, content: message.content }); + + const chatMessage = document.createElement('div'); + chatMessage.classList.add('uk-margin-small'); + chatMessage.classList.add('chat-message'); + + const chatUser = document.createElement('div'); + chatUser.classList.add('uk-text-small'); + chatUser.classList.add('chat-username'); + chatUser.textContent = message.user.username; + chatMessage.appendChild(chatUser); + + const chatContent = document.createElement('div'); + chatContent.classList.add('chat-content'); + chatContent.innerHTML = message.content; + chatMessage.appendChild(chatContent); + + if (Array.isArray(message.stickers) && message.stickers.length) { + message.stickers.forEach((sticker) => { + const chatContent = document.createElement('div'); + chatContent.classList.add('chat-sticker'); + chatContent.innerHTML = ``; + chatMessage.appendChild(chatContent); + }); + } + + this.chat.messageList.appendChild(chatMessage); + this.chat.messages.push(chatMessage); + + while (this.chat.messages.length > 50) { + const message = this.chat.messages.shift(); + this.chat.messageList.removeChild(message); + } + if (this.chat.isAtBottom) { + this.chat.messageList.scrollTo(0, this.chat.messageList.scrollHeight); + } + } + + async onChatMessageListScroll (/* event */) { + const prevBottom = this.chat.isAtBottom; + const scrollPos = this.chat.messageList.scrollTop + this.chat.messageList.clientHeight; + + this.chat.isAtBottom = scrollPos >= this.chat.messageList.scrollHeight; + if (this.chat.isAtBottom !== prevBottom) { + this.log.info('onChatMessageListScroll', 'at-bottom status change', { atBottom: this.chat.isAtBottom }); + if (this.chat.isAtBottom) { + this.chat.messageMenu.classList.remove('chat-menu-visible'); + } else { + this.chat.messageMenu.classList.add('chat-menu-visible'); + } + } + } + + async resumeChatScroll ( ) { + this.chat.messageList.scrollTop = this.chat.messageList.scrollHeight; + } + + async submitForm (event, userAction) { + event.preventDefault(); + event.stopPropagation(); + + try { + const formElement = event.currentTarget || event.target; + const form = new FormData(formElement); + + this.log.info('submitForm', userAction, { event, action: formElement.action }); + const response = await fetch(formElement.action, { + method: formElement.method, + body: form, + }); + + if (!response.ok) { + throw new Error('Server error'); + } + + await this.processResponse(response); + } catch (error) { + UIkit.modal.alert(`Failed to ${userAction}: ${error.message}`); + } + + return; + } + + async selectImageFile (event) { + event.preventDefault(); + + const imageId = event.target.getAttribute('data-image-id'); + + //z read the cropper options from the element on the page + const cropperOptions = event.target.getAttribute('data-cropper-options'); + this.log.debug('selectImageFile', 'cropper options', { cropperOptions }); //z remove when done + + const fileSelectContainerId = event.target.getAttribute('data-file-select-container'); + if (!fileSelectContainerId) { + UIkit.modal.alert('Missing file select container element ID information'); + return; + } + + const fileSelectContainer = document.getElementById(fileSelectContainerId); + if (!fileSelectContainer) { + UIkit.modal.alert('Missing file select element'); + return; + } + + const fileSelect = fileSelectContainer.querySelector('input[type="file"]'); + if (!fileSelect.files || (fileSelect.files.length === 0)) { + return; + } + + const selectedFile = fileSelect.files[0]; + if (!selectedFile) { + return; + } + + this.log.debug('selectImageFile', 'thumbnail file select', { event, selectedFile }); + + const filter = /^(image\/jpg|image\/jpeg|image\/png)$/i; + if (!filter.test(selectedFile.type)) { + UIkit.modal.alert(`Unsupported image file type selected: ${selectedFile.type}`); + return; + } + + const fileSizeId = event.target.getAttribute('data-file-size-element'); + const FILE_MAX_SIZE = parseInt(fileSelect.getAttribute('data-file-max-size'), 10); + const fileSize = document.getElementById(fileSizeId); + fileSize.textContent = numeral(selectedFile.size).format('0,0.0b'); + if (selectedFile.size > (FILE_MAX_SIZE)) { + UIkit.modal.alert(`File is too large: ${fileSize.textContent}. Custom thumbnail images may be up to ${numeral(FILE_MAX_SIZE).format('0,0.00b')} in size.`); + return; + } + + // const IMAGE_WIDTH = parseInt(event.target.getAttribute('data-image-w')); + // const IMAGE_HEIGHT = parseInt(event.target.getAttribute('data-image-h')); + + const reader = new FileReader(); + reader.onload = (e) => { + const img = document.getElementById(imageId); + img.onload = (e) => { + console.log('image loaded', e, img.naturalWidth, img.naturalHeight); + // if (img.naturalWidth !== IMAGE_WIDTH || img.naturalHeight !== IMAGE_HEIGHT) { + // UIkit.modal.alert(`This image must be ${IMAGE_WIDTH}x${IMAGE_HEIGHT}`); + // img.setAttribute('hidden', ''); + // img.src = ''; + // return; + // } + + fileSelectContainer.querySelector('#file-name').textContent = selectedFile.name; + fileSelectContainer.querySelector('#file-modified').textContent = moment(selectedFile.lastModifiedDate).fromNow(); + fileSelectContainer.querySelector('#image-resolution-w').textContent = img.naturalWidth.toString(); + fileSelectContainer.querySelector('#image-resolution-h').textContent = img.naturalHeight.toString(); + + fileSelectContainer.querySelector('#file-select').setAttribute('hidden', true); + fileSelectContainer.querySelector('#file-info').removeAttribute('hidden'); + + fileSelectContainer.querySelector('#file-save-btn').removeAttribute('hidden'); + }; + + // set the image as the "src" of the in the DOM. + img.src = e.target.result; + + //z create cropper and set options here + this.createImageCropper(img); + }; + + // read in the file, which will trigger everything else in the event handler above. + reader.readAsDataURL(selectedFile); + } + + async createImageCropper (img) { + this.log.info("createImageCropper", "Creating image cropper", { img }); + this.cropper = new Cropper(img, { + aspectRatio: 1, + dragMode: 'move', + autoCropArea: 0.85, + restore: false, + guides: false, + center: false, + highlight: false, + cropBoxMovable: false, + cropBoxResizable: false, + toggleDragModeOnDblclick: false, + modal: true, + }); + } + + async attachTinyMCE (editor) { + editor.on('KeyDown', async (e) => { + if (dtp.autosaveTimeout) { + window.clearTimeout(dtp.autosaveTimeout); + delete dtp.autosaveTimeout; + } + dtp.autosaveTimeout = window.setTimeout(async ( ) => { + console.log('document autosave'); + }, 1000); + if ((e.keyCode === 8 || e.keyCode === 46) && editor.selection) { + var selectedNode = editor.selection.getNode(); + if (selectedNode && selectedNode.nodeName === 'IMG') { + console.log('removing image', selectedNode); + await dtp.app.deleteImage(selectedNode.src.slice(-24)); + } + } + }); + } + + async deleteImage (imageId) { + try { + throw new Error(`would want to delete /image/${imageId}`); + } catch (error) { + UIkit.modal.alert(error.message); + } + } + + async openPaymentModal ( ) { + await UIkit.modal('#donate-modal').show(); + await UIkit.slider('#payment-slider').show(0); + } + + async generateQRCode (event) { + const selectorQR = event.target.getAttribute('data-selector-qr'); + const selectorPrompt = event.target.getAttribute('data-selector-prompt'); + + const targetAmount = event.target.getAttribute('data-amount'); + const amountLabel = numeral(targetAmount).format('$0,0.00'); + const currencyAmountLabel = numeral(targetAmount * this.exchangeRates[this.paymentCurrency].conversionRateUSD).format('0,0.0000000000000000'); + const prompt = `Donate ${amountLabel} using ${this.paymentCurrencyLabel}.`; + + event.preventDefault(); + + let targetUrl; + switch (this.paymentCurrency) { + case 'BTC': + targetUrl = `bitcoin:${dtp.channel.wallet.btc}?amount=${targetAmount}&message=Donation to ${dtp.channel.name}`; + break; + case 'ETH': + targetUrl = `ethereum:${dtp.channel.wallet.eth}?amount=${targetAmount}`; + break; + case 'LTC': + targetUrl = `litecoin:${dtp.channel.wallet.ltc}?amount=${targetAmount}&message=Donation to ${dtp.channel.name}`; + break; + } + + try { + let elements; + + const imageUrl = await QRCode.toDataURL(targetUrl); + + elements = document.querySelectorAll(selectorQR); + elements.forEach((element) => element.setAttribute('src', imageUrl)); + + elements = document.querySelectorAll(selectorPrompt); + elements.forEach((e) => e.textContent = prompt); + + elements = document.querySelectorAll('span.prompt-donate-amount'); + elements.forEach((element) => { + element.textContent = amountLabel; + }); + + elements = document.querySelectorAll('span.prompt-donate-amount-crypto'); + elements.forEach((element) => { + element.textContent = currencyAmountLabel; + }); + + elements = document.querySelectorAll('a.payment-target-link'); + elements.forEach((element) => { + element.setAttribute('href', targetUrl); + }); + + const e = document.getElementById('payment-link'); + e.setAttribute('href', targetUrl); + + UIkit.slider('#payment-slider').show(2); + } catch (error) { + this.log.error('failed to generate QR code to image', { error }); + UIkit.modal.alert(`Failed to generate QR code: ${error.message}`); + } + return true; + } + + async setPaymentCurrency (currency) { + this.paymentCurrency = currency; + this.log.info('setPaymentCurrency', 'payment currency', { currency: this.paymentCurrency }); + + await this.updateExchangeRates(); + switch (this.paymentCurrency) { + case 'BTC': + this.paymentCurrencyLabel = 'Bitcoin (BTC)'; + break; + case 'ETH': + this.paymentCurrencyLabel = 'Ethereum (ETH)'; + break; + case 'LTC': + this.paymentCurrencyLabel = 'Litecoin (LTC)'; + break; + } + + let elements = document.querySelectorAll('span.prompt-donate-currency'); + elements.forEach((element) => { + element.textContent = this.paymentCurrencyLabel; + }); + + UIkit.slider('#payment-slider').show(1); + } + + async updateExchangeRates ( ) { + const NOW = Date.now(); + try { + let exchangeRates; + if (!window.localStorage.exchangeRates) { + exchangeRates = await this.loadExchangeRates(); + this.log.info('updateExchangeRates', 'current exchange rates received and cached', { exchangeRates }); + window.localStorage.exchangesRates = JSON.stringify(exchangeRates); + } else { + exchangeRates = JSON.parse(window.localStorage.exchangeRates); + if (exchangeRates.timestamp < (NOW - 60000)) { + exchangeRates = await this.loadExchangeRates(); + this.log.info('updateExchangeRates', 'current exchange rates received and cached', { exchangeRates }); + window.localStorage.exchangesRates = JSON.stringify(exchangeRates); + } + } + this.exchangeRates = exchangeRates.symbols; + } catch (error) { + this.log.error('updateExchangeRates', 'failed to fetch currency exchange rates', { error }); + UIkit.modal.alert(`Failed to fetch current exchange rates: ${error.message}`); + } + } + + async loadExchangeRates ( ) { + this.log.info('loadExchangeRates', 'fetching current exchange rates'); + const response = await fetch('/crypto-exchange/current-rates'); + if (!response.ok) { + throw new Error('Server error'); + } + let exchangeRates = await response.json(); + if (!exchangeRates.success) { + throw new Error(exchangeRates.message); + } + exchangeRates.timestamp = Date.now(); + return exchangeRates; + } + + async generateOtpQR (canvas, keyURI) { + QRCode.toCanvas(canvas, keyURI); + } + + async removeImageFile (event) { + const imageType = (event.target || event.currentTarget).getAttribute('data-image-type'); + try { + this.log.info('removeImageFile', 'request to remove image', event); + + let response; + switch (imageType) { + case 'channel-app-icon': + const channelId = (event.target || event.currentTarget).getAttribute('data-channel-id'); + response = await fetch(`/channel/${channelId}/app-icon`, { + method: 'DELETE', + }); + break; + + default: + throw new Error('Invalid image type'); + } + + if (!response.ok) { + throw new Error('Server error'); + } + + await this.processResponse(response); + } catch (error) { + UIkit.modal.alert(`Failed to remove image: ${error.message}`); + } + } +} + +dtp.DtpSiteApp = DtpSiteApp; \ No newline at end of file diff --git a/client/less/site/app-menu.less b/client/less/site/app-menu.less new file mode 100644 index 0000000..a287e71 --- /dev/null +++ b/client/less/site/app-menu.less @@ -0,0 +1,5 @@ +.dtp-app-menu .app-menu-icon { + margin-right: 6px; + width: 24px; + text-align: center; +} \ No newline at end of file diff --git a/client/less/site/brand.less b/client/less/site/brand.less new file mode 100644 index 0000000..c9d4f55 --- /dev/null +++ b/client/less/site/brand.less @@ -0,0 +1,7 @@ +.brand-color { + color: @site-brand-color; +} + +.brand-emphasis { + font-weight: bold; +} \ No newline at end of file diff --git a/client/less/site/button.less b/client/less/site/button.less new file mode 100644 index 0000000..b2ec990 --- /dev/null +++ b/client/less/site/button.less @@ -0,0 +1,123 @@ +.share-button { + background: #00d178; + color: white; + font-weight: bold; + + &:hover { + color: white; + } +} + +button.dtp-payment-method { + background: none; + border: none; + outline: none; + cursor: pointer; + + color: #e8e8e8; + + font-size: 1.25em; + + img { + height: auto; + } +} + +button.dtp-payment-amount { + display: block; + width: 100%; + margin: 0; + padding: 15px 0; + + text-align: center; + font-size: 1.5em; + font-weight: bold; + cursor: pointer; + + background: none; + outline: none; + color: #e8e8e8; + + border: solid 3px #10b0e0; + border-radius: 8px; + + transition: background-color 0.2s; + + &:hover { + background: #10b0e0; + } +} + +button.uk-button.dtp-send-button { + padding-left: 12px; + padding-right: 12px; + background: #2a2a2a; + color: #c8c8c8; +} + +button.uk-button.dtp-button-subscribe { + background-color: rgb(75, 75, 75); + color: #c8c8c8; + + &[data-is-subscribed="true"] { + background-color: rgb(92, 31, 31); + &:hover { + background-color:rgb(145, 45, 45); + } + } +} + +a.uk-button.dtp-button-default, +button.uk-button.dtp-button-default { + background: none; + outline: none; + border: solid 2px rgb(75, 75, 75); + color: #c8c8c8; + + transition: background-color 0.2s; + + &:hover { + background-color: rgb(75, 75, 75); + } +} + +a.uk-button.dtp-button-primary, +button.uk-button.dtp-button-primary { + background: none; + outline: none; + border: solid 2px #1e87f0; + color: #c8c8c8; + + transition: background-color 0.2s; + + &:hover { + background-color: #1e87f0; + } +} + + + +a.uk-button.dtp-button-secondary, +button.uk-button.dtp-button-secondary { + background: none; + outline: none; + border: solid 2px rgb(75, 75, 75); + color: #c8c8c8; + + &:hover { + background-color: rgb(75, 75, 75); + } +} + +a.uk-button.dtp-button-danger, +button.uk-button.dtp-button-danger { + background: none; + outline: none; + border: solid 2px rgb(255, 0, 0); + color: #c8c8c8; + + &:hover { + background-color: rgb(255, 0, 0); + } +} + diff --git a/client/less/site/channel.less b/client/less/site/channel.less new file mode 100644 index 0000000..23abbab --- /dev/null +++ b/client/less/site/channel.less @@ -0,0 +1,66 @@ +.site-channel-tile { + width: 320px; +} + +.site-channel-list-item { + + .channel-image { + display: block; + position: relative; + + #channel-live-label { + display: none; + position: absolute; + left: 12px; + bottom: 0; + padding: 3px 8px; + line-height: 1; + margin: 0 auto; + background-color: rgba(8,190,8); + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border: solid 2px white; + border-bottom: none; + color: white; + text-align: center; + font-weight: bold; + } + } + + &[data-status="live"] { + .channel-image #channel-live-label { + display: block; + } + } +} + +.site-recommendation-list { + + .recommended-channel-name { + font-size: 14px; + line-height: 1; + color: #e8e8e8; + } + + .recommended-channel-episode-title { + font-size: 11px; + line-height: 1; + margin-top: 2px; + color: #686868; + } + + .recommended-channel-meta.no-select { + font-size: 11px; + line-height: 1; + margin-top: 2px; + + .channel-meta-icon { + color: #686868; + } + + .channel-meta-label { + margin-left: 4px; + color: #e8e8e8; + } + } +} \ No newline at end of file diff --git a/client/less/site/chat.less b/client/less/site/chat.less new file mode 100644 index 0000000..3b7df3e --- /dev/null +++ b/client/less/site/chat.less @@ -0,0 +1,24 @@ +.chat-message { + + .chat-username { + color: #c8c8c8; + margin-right: 4px; + font-weight: bold; + } + + .chat-content { + color: #a8a8a8; + em { color: inherit; } + strong { color: #c8c8c8; } + } + + .chat-sticker { + display: inline-block; + margin-right: 8px; + + video { + width: auto; + height: 100px; + } + } +} \ No newline at end of file diff --git a/client/less/site/dashboard.less b/client/less/site/dashboard.less new file mode 100644 index 0000000..dd75332 --- /dev/null +++ b/client/less/site/dashboard.less @@ -0,0 +1,81 @@ +.dtp-dashboard-cluster { + + fieldset { + border-color: #9e9e9e; + color: #c8c8c8; + + legend { + font-family: 'Courier New', Courier, monospace; + font-size: 11px; + color: #9e9e9e; + } + } + + .dtp-cpu-graph { + background: none; + + &.cpu-overload { + background: #4e0000; + } + } + + .dtp-stat-cell { + line-height: 1; + } + + .dtp-stats-bar { + width: 100%; + height: 16px; + margin: 0; + padding: 0; + + .dtp-cpu-stat-bar { + display: inline-block; + height: 16px; + text-align: center; + font-size: 10px; + overflow: hidden; + + &.dtp-cpu-user { + background-color: #008000; + } + &.dtp-cpu-nice { + background-color: #808080; + } + &.dtp-cpu-sys { + background-color: #808000; + } + &.dtp-cpu-idle { + background-color: #484848; + } + &.dtp-cpu-irq { + background-color: #800000; + } + } + + .dtp-mem-stat-bar { + display: inline-block; + height: 16px; + text-align: center; + font-size: 10px; + overflow: hidden; + + &.dtp-mem-used { + background-color: #008000; + } + &.dtp-mem-available { + background-color: #404040; + } + + &.dtp-mem-cached { + background-color: #008000; + } + &.dtp-mem-buffers { + background-color: #004000; + } + &.dtp-mem-slab { + background-color: #808000; + } + } + } +} \ No newline at end of file diff --git a/client/less/site/figure.less b/client/less/site/figure.less new file mode 100644 index 0000000..831fad8 --- /dev/null +++ b/client/less/site/figure.less @@ -0,0 +1,16 @@ +figure { + + &.align-center { + text-align: center; + } + + img { + display: inline-block; + border: solid 1px black; + border-radius: 4px; + } +} +figcaption { + opacity: 0.5; + font-size: 0.8em; +} \ No newline at end of file diff --git a/client/less/site/form.less b/client/less/site/form.less new file mode 100644 index 0000000..cc24936 --- /dev/null +++ b/client/less/site/form.less @@ -0,0 +1,28 @@ +.form-required { + color: red; +} + +.uk-input, .uk-textarea, .uk-select { + border-color: #4a4a4a; +} + +input[type="color"].dtp-colorpicker { + display: block; + outline: none; + border: none; + margin: 0; + padding: 0; + background: none; + width: 64px; + height: 32px; +} + +.upload-image-container { + display: block; + margin-left: auto; + margin-right: auto; + + &.size-512 { + max-width: 512px; + } +} \ No newline at end of file diff --git a/client/less/site/header-section.less b/client/less/site/header-section.less new file mode 100644 index 0000000..fe2ef77 --- /dev/null +++ b/client/less/site/header-section.less @@ -0,0 +1,24 @@ +.uk-section.uk-section-header { + background-color: @site-brand-color; + color: white; + + .profile-header-name { + font-size: 2.5em; + line-height: 1; + margin: 8px 0; + } + .profile-header-description { + font-size: 1.5em; + line-height: 1; + margin: 8px 0; + } +} + +.uk-section.uk-section-header h1, +.uk-section.uk-section-header h2, +.uk-section.uk-section-header h3, +.uk-section.uk-section-header h4, +.uk-section.uk-section-header h5, +.uk-section.uk-section-header h6 { + color: white; +} \ No newline at end of file diff --git a/client/less/site/image.less b/client/less/site/image.less new file mode 100644 index 0000000..4c811e9 --- /dev/null +++ b/client/less/site/image.less @@ -0,0 +1,72 @@ +img.responsive { + width: 100%; + height: auto; +} + +img.site-app-icon { + width: 256px; + height: 256px; + border-radius: 20px; +} + +img.site-app-icon { + display: block; + width: 100%; + height: auto; + margin-left: auto; + margin-right: auto; + border: solid 1px #4a4a4a; + background-color: #000000; +} + +img.site-profile-picture { + display: block; + width: 100%; + height: auto; + margin-left: auto; + margin-right: auto; + border-radius: 50%; + background-color: #8a8a8a; +} + +img.site-channel-icon { + display: block; + width: 100%; + height: auto; + margin-left: auto; + margin-right: auto; + border-radius: 8px; + background-color: #8a8a8a; +} + +img.site-app-icon, +img.site-channel-icon, +img.site-profile-picture { + &.sb-xxsmall { + max-width: 32px; + border-radius: 4px; + } + &.sb-xsmall { + max-width: 48px; + border-radius: 6px; + } + &.sb-list-item { + max-width: 48px; + border-radius: 6px; + } + &.sb-small { + max-width: 64px; + } + &.sb-medium { + max-width: 128px; + border-radius: 12px; + } + &.sb-large { + max-width: 256px; + border-radius: 16px; + } + &.sb-full { + max-width: 512px; + border-radius: 20px; + } +} \ No newline at end of file diff --git a/client/less/site/main.less b/client/less/site/main.less new file mode 100644 index 0000000..7e52312 --- /dev/null +++ b/client/less/site/main.less @@ -0,0 +1,21 @@ +html, body { + margin: 0; + padding: 0; + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"; +} + +body { + padding-top: @site-navbar-height; +} + +.no-select { + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; +} + +.uk-card-body { + p:last-child { + margin-bottom: 0; + } +} \ No newline at end of file diff --git a/client/less/site/nav.less b/client/less/site/nav.less new file mode 100644 index 0000000..2941df4 --- /dev/null +++ b/client/less/site/nav.less @@ -0,0 +1,5 @@ +.nav-item-icon { + display: inline-block; + width: 1.75em; + text-align: center; +} \ No newline at end of file diff --git a/client/less/site/site-home.less b/client/less/site/site-home.less new file mode 100644 index 0000000..e69de29 diff --git a/client/less/site/site.less b/client/less/site/site.less new file mode 100644 index 0000000..253ddab --- /dev/null +++ b/client/less/site/site.less @@ -0,0 +1,106 @@ +.site-player-view { + position: relative; + + #site-video-container { + align-self: auto; + + video { + width: 100%; + min-height: 540px; + max-height: 720px; + } + } + + #site-chat-container { + align-self: stretch; + + #chat-input-form { + textarea.uk-textarea { + padding: 2px 6px; + resize: none; + } + } + + #chat-message-list-wrapper { + position: relative; + flex: 1; + + #chat-message-list { + position: absolute; + top: 0; right: 0; bottom: 0; left: 0; + overflow: auto; + box-shadow: 0 0 8px rgba(0,0,0, 0.8) inset; + } + + .chat-message-menu { + position: absolute; + display: none; + right: 4px; bottom: 20px; left: 4px; + text-align: center; + + &.chat-menu-visible { + display: block; + } + + button.chat-scroll-return { + padding: 4px 8px; + background: transparent; + color: #c8c8c8; + border: solid 2px #c8c800; + border-radius: 8px; + outline: none; + + &:hover { + border-color: #ffff00; + color: white; + } + &:active { + border-color: transparent; + } + } + } + } + } +} + +/* + * Mobile view layout + */ +@media screen and (max-width: 959px) { + + body[data-current-view="channel-broadcast"] { + position: fixed; + top: 0; right: 0; bottom: 0; left: 0; + padding: 0; + margin: 0; + width: 100%; + height: 100%; + + .site-player-view { + position: absolute; + top: 64px; right: 0; bottom: 0; left: 0; + overflow: hidden; + + display: flex; + flex-direction: column; + flex-wrap: nowrap; + + #site-video-container { + flex: 0; + } + + #site-chat-container { + position: relative; + flex: 1; + + #chat-message-list { + flex: 1; + } + + #chat-input-form { + flex: 0; + } + } + } + } +} \ No newline at end of file diff --git a/client/less/site/uikit-theme.less b/client/less/site/uikit-theme.less new file mode 100644 index 0000000..25472f3 --- /dev/null +++ b/client/less/site/uikit-theme.less @@ -0,0 +1,89 @@ +// +// Colors +// + +@global-background: #000000; +@global-muted-background: #2a2a2a; +@global-primary-background: #1e87f0; +@global-secondary-background: #222; + +@global-success-background: #32d296; +@global-warning-background: #faa05a; +@global-danger-background: #f0506e; + +@global-color: #c8c8c8; +@global-emphasis-color: #ffffff; +@global-muted-color: #4a4a4a; + +@global-link-color: #e00000; +@global-link-hover-color: #ff0000; + +@global-border: #4a4a4a; +@global-inverse-color: #e8e8e8; + +// +// Inverse +// + +@inverse-global-color-mode: light; + +@inverse-global-color: fade(@global-inverse-color, 70%); +@inverse-global-emphasis-color: @global-inverse-color; +@inverse-global-muted-color: #a8a8a8; +@inverse-global-inverse-color: #1a1a1a; + +@inverse-global-primary-background: @global-inverse-color; +@inverse-global-muted-background: fade(@global-inverse-color, 10%); + +@inverse-global-border: fade(@global-inverse-color, 20%); + +// +// Button +// + +@button-default-color: #000000; +@button-primary-color: #000000; +@button-secondary-color: #000000; + +@button-text-color: #000000; +@button-text-hover-color: #000000; +@button-text-disabled-color: #000000; + +// +// Component: Navbar +// + +@navbar-background: #1a1a1a; +@navbar-nav-item-height: @site-navbar-height; + +// +// Off-Canvas +// + +@offcanvas-bar-background: #1a1a1a; + +// +// Navbar +// + +@navbar-dropdown-background: #2a2a2a; +@navbar-dropdown-border: #3a3a3a; + +.uk-navbar-dropdown { + border: solid 2px @navbar-dropdown-border; + border-radius: 4px; + + .uk-nav-divider { + border-color: @navbar-dropdown-border; + } +} + +// +// Form +// + +@internal-form-select-image: "../images/backgrounds/form-select.svg"; +@internal-form-datalist-image: "../images/backgrounds/form-datalist.svg"; +@internal-form-radio-image: "../images/backgrounds/form-radio.svg"; +@internal-form-checkbox-image: "../images/backgrounds/form-checkbox.svg"; +@internal-form-checkbox-indeterminate-image: "../images/backgrounds/form-checkbox-indeterminate.svg"; \ No newline at end of file diff --git a/client/less/site/variables.less b/client/less/site/variables.less new file mode 100644 index 0000000..36104fc --- /dev/null +++ b/client/less/site/variables.less @@ -0,0 +1,2 @@ +@site-brand-color: #d01a2a; +@site-navbar-height: 64px; \ No newline at end of file diff --git a/client/less/style.less b/client/less/style.less new file mode 100644 index 0000000..3a5c225 --- /dev/null +++ b/client/less/style.less @@ -0,0 +1,20 @@ +@import "site/variables.less"; + +@import "node_modules/uikit/src/less/uikit.theme.less"; +@import "site/uikit-theme.less"; + +@import "site/main.less"; +@import "site/image.less"; +@import "site/figure.less"; +@import "site/header-section.less"; +@import "site/brand.less"; +@import "site/app-menu.less"; +@import "site/nav.less"; + +@import "site/dashboard.less"; +@import "site/site.less"; +@import "site/site-home.less"; +@import "site/form.less"; +@import "site/button.less"; + +@import "site/chat.less"; \ No newline at end of file diff --git a/config/job-queues.js b/config/job-queues.js new file mode 100644 index 0000000..1f814ec --- /dev/null +++ b/config/job-queues.js @@ -0,0 +1,11 @@ +// job-queues.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +module.exports = { + // 'dvr-ingest': { + // attempts: 3, + // }, +}; \ No newline at end of file diff --git a/config/limiter.js b/config/limiter.js new file mode 100644 index 0000000..ef75e8d --- /dev/null +++ b/config/limiter.js @@ -0,0 +1,153 @@ +// limiter.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const ONE_SECOND = 1000; +const ONE_MINUTE = ONE_SECOND * 60; +// const ONE_HOUR = ONE_MINUTE * 60; + +module.exports = { + + /* + * AuthController + */ + auth: { + postOtpEnable: { + total: 5, + expire: ONE_MINUTE * 30, + message: 'You are enabling One-Time Passwords too quickly. Please try again later', + }, + postOtpAuthenticate: { + total: 5, + expire: ONE_MINUTE, + message: 'You are trying One-Time Passwords too quickly. Please try again later', + }, + postLogin: { + total: 10, + expire: ONE_MINUTE, + message: 'You are logging in too quickly', + }, + getPersonalApiToken: { + total: 20, + expire: ONE_MINUTE, + message: 'You are logging in too quickly', + }, + getSocketToken: { + total: 20, + expire: ONE_MINUTE, + message: 'You are logging in too quickly', + }, + getLogout: { + total: 10, + expire: ONE_MINUTE, + message: 'You are logging out too quickly', + }, + }, + + /* + * CryptoExchangeController + */ + cryptoExchange: { + getRateGraph: { + total: 10, + expire: ONE_MINUTE, + message: 'You are loading exchange rate graphs too quickly', + }, + getCurrentRates: { + total: 10, + expire: ONE_MINUTE, + message: 'You are loading cryptocurrency exchange rates too quickly', + }, + }, + + /* + * DashboardController + */ + dashboard: { + getEpisodeView: { + total: 15, + expire: ONE_MINUTE, + message: 'You are loading the dashboard episode view too quickly', + }, + getHome: { + total: 15, + expire: ONE_MINUTE, + message: 'You are loading the publisher dashboard too quickly', + }, + }, + + /* + * HomeController + */ + home: { + getHome: { + total: 20, + expire: ONE_MINUTE, + message: 'You are loading the home page too quickly', + } + }, + + /* + * ImageController + */ + image: { + postCreateImage: { + total: 5, + expire: ONE_MINUTE, + message: 'You are uploading images too quickly', + }, + getImage: { + // 50 per second on a 10-second scale + // it simply *is* a limit instead of not having one at all, + // and will help mitigate severe attacks + total: 500, + expire: ONE_SECOND * 10, + message: 'You are requesting images too quickly', + }, + }, + + /* + * ManifestController + */ + manifest: { + getManifest: { + total: 5, + expire: ONE_SECOND, + message: 'You are fetching application manifests too quickly', + } + }, + + /* + * UserController + */ + user: { + postCreate: { + total: 4, + expire: ONE_MINUTE, + message: 'You are creating accounts too quickly', + }, + postUpdateSettings: { + total: 4, + expire: ONE_MINUTE, + message: 'You are updating account settings too quickly', + }, + getSettings: { + total: 8, + expire: ONE_MINUTE, + message: 'You are requesting user settings too quickly', + }, + getUserProfile: { + total: 12, + expire: ONE_MINUTE, + message: 'You are requesting user profiles too quickly', + }, + }, + + welcome: { + total: 12, + expire: ONE_MINUTE, + message: 'You are loading these pages too quickly', + }, +}; \ No newline at end of file diff --git a/dtp-sites-cli.js b/dtp-sites-cli.js new file mode 100644 index 0000000..96ee273 --- /dev/null +++ b/dtp-sites-cli.js @@ -0,0 +1,161 @@ +// dtp-sites-cli.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +require('dotenv').config(); + +const path = require('path'); + +const mongoose = require('mongoose'); + +const { + SitePlatform, + SiteAsync, + SiteLog, +} = require(path.join(__dirname, 'lib', 'site-lib')); + +module.pkg = require(path.join(__dirname, 'package.json')); +module.config = { + componentName: 'sites-cli', + root: __dirname, + site: { + name: process.env.DTP_SITE_NAME, + description: process.env.DTP_SITE_DESCRIPTION, + domain: process.env.DTP_SITE_DOMAIN, + domainKey: process.env.DTP_SITE_DOMAIN_KEY, + company: process.env.DTP_SITE_COMPANY || 'Digital Telepresence, LLC', + }, +}; + +module.log = new SiteLog(module, module.config.componentName); + +module.createDomain = async (target) => { + const Domain = mongoose.model('Domain'); + try { + const domain = await Domain.create({ name: target }); + module.log.info('domain created', { domain }); + } catch (error) { + module.log.error('failed to create domain', { target, error }); + } +}; + +module.grantPermission = async (target, permission) => { + const User = mongoose.model('User'); + try { + const user = await User.findOne({ email: target }).select('+permissions +flags'); + switch (permission) { + case 'admin': + user.flags.isAdmin = true; + break; + case 'moderator': + user.flags.isModerator = true; + break; + case 'login': + user.permissions.canLogin = true; + break; + default: + throw new Error(`Invalid permission: ${permission}`); + } + await user.save(); + module.log.info('user updated', { user: user._id }); + } catch (error) { + module.log.error('failed to grant permission', { app: module.app, target, permission, error }); + } +}; + +module.revokePermission = async (target, permission) => { + const User = mongoose.model('User'); + try { + const user = await User.findOne({ email: target }).select('+permissions +flags'); + switch (permission) { + case 'admin': + user.flags.isAdmin = false; + break; + case 'moderator': + user.flags.isModerator = false; + break; + case 'login': + user.permissions.canLogin = false; + break; + default: + throw new Error(`Invalid permission: ${permission}`); + } + await user.save(); + module.log.info('user updated', { user: user._id }); + } catch (error) { + module.log.error('failed to revoke permission', { app: module.app, target, permission, error }); + } +}; + +module.dvrIngest = async (episodeId) => { + const jobQueue = module.services.jobQueue.getJobQueue('dvr-ingest', module.config.jobQueues['dvr-ingest']); + const job = await jobQueue.add({ episodeId }); + module.log.info('job created', { id: job.id }); +}; + +/* + * SERVER INIT + */ + +(async ( ) => { + + const argv = require('argv'); // https://www.npmjs.com/package/argv + argv.version(module.pkg.version); + argv.option([ + { + name: 'action', + short: 'a', + type: 'string', + description: 'The action to perform', + example: 'sites-cli --action=grant --permission=moderator email email ...', + }, + { + name: 'permission', + short: 'p', + type: 'string', + description: 'The permission(s) being added or removed', + example: 'sites-cli --action=grant --permission=admin email email ...' + }, + ]); + + try { + await SitePlatform.startPlatform(module); + } catch (error) { + module.log.error('failed to start DTP Sites platform', { error }); + return; + } + + try { + module.app = argv.run(); + + await SiteAsync.each(module.app.targets, async (target) => { + module.log.info('processing target', { target }); + switch (module.app.options.action) { + case 'create-domain': + await module.createDomain(target); + break; + + case 'grant': + await module.grantPermission(target, module.app.options.permission); + break; + + case 'revoke': + await module.revokePermission(target, module.app.options.permission); + break; + + case 'dvr-ingest': + await module.dvrIngest(target); + break; + + default: + throw new Error(`invalid action: ${module.app.options.action}`); + } + }); + process.exit(0); + } catch (error) { + module.log.error('failed to process target', { app: module.app, error }); + } + +})(); \ No newline at end of file diff --git a/dtp-sites.js b/dtp-sites.js index 64a2211..2deef8e 100644 --- a/dtp-sites.js +++ b/dtp-sites.js @@ -4,21 +4,65 @@ 'use strict'; +require('dotenv').config(); + const path = require('path'); -const express = require('express'); +const { SitePlatform, SiteLog } = require(path.join(__dirname, 'lib', 'site-lib')); + +module.pkg = require(path.join(__dirname, 'package.json')); +module.config = { + componentName: 'sites', + root: __dirname, + site: { + name: process.env.DTP_SITE_NAME, + description: process.env.DTP_SITE_DESCRIPTION, + domain: process.env.DTP_SITE_DOMAIN, + domainKey: process.env.DTP_SITE_DOMAIN_KEY, + company: process.env.DTP_SITE_COMPANY || 'Digital Telepresence, LLC', + }, + http: { + address: process.env.HTTP_BIND_ADDRESS, + port: parseInt(process.env.HTTP_BIND_PORT, 10), + }, +}; -const { HomeController } = require(path.join(__dirname, 'app', 'controllers', 'home.js')); +module.log = new SiteLog(module, module.config.componentName); (async ( ) => { + + process.on('unhandledRejection', (error, p) => { + module.log.error('Unhandled rejection', { + error: error, + promise: p, + stack: error.stack + }); + }); - module.app = express(); + process.on('warning', (error) => { + module.log.alert('warning', { error }); + }); - const home = new HomeController(); + process.once('SIGINT', async ( ) => { + module.log.info('SIGINT received'); + module.log.info('requesting shutdown...'); + const exitCode = await SitePlatform.shutdown(); + process.nextTick(( ) => { + process.exit(exitCode); + }); + }); + + process.once('SIGUSR2', async ( ) => { + await SitePlatform.shutdown(); + process.kill(process.pid, 'SIGUSR2'); + }); - module.app.get('/', home.getHome.bind(home)); + try { + await SitePlatform.startPlatform(module); + await SitePlatform.startWebServer(module); + } catch (error) { + module.log.error('failed to start DTP Sites web server', { error }); + process.exit(-1); + } - module.app.listen(3000, 'localhost', ( ) => { - console.log('App started'); - }); })(); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..c041b9d --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,313 @@ +// gulpfile.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const path = require('path'); + +const gulp = require('gulp'); +const nodemon = require('gulp-nodemon'); +const plumber = require('gulp-plumber'); +const less = require('gulp-less'); +const jshint = require('gulp-jshint'); + +const webpack = require('webpack-stream'); +const { GenerateSW } = require('workbox-webpack-plugin'); +const TerserPlugin = require('terser-webpack-plugin'); + +const browserSync = require('browser-sync').create(); + +function util_start_browsersync ( ) { + return new Promise((resolve, reject) => { + browserSync.init({ + proxy: { + target: 'http://localhost:3000', + ws: true, + }, + host: 'localhost', + open: 'local', + // https: { + // key: path.join(__dirname, 'ssl', 'dtp-sites.key'), + // cert: path.join(__dirname, 'ssl', 'dtp-sites.crt'), + // }, + port: 3333, + cors: true, + ui: { + port: 3400, + }, + notify: false, + ghostMode: { + clicks: false, + forms: false, + scroll: true, + }, + logLevel: 'info', + callbacks: { + ready: function (err, bs) { + if (err) { + console.log('BrowserSync start error', err); + return reject(err); + } + console.log('BrowserSync ready'); + return resolve(bs); + }, + }, + }); + }); +} + +function dtp_less ( ) { + return gulp + .src('./client/less/style.less') + .pipe(plumber()) + .pipe(less({ + math: 'always', + })) + .pipe(gulp.dest('./dist/css')) + .pipe(browserSync.stream()); +} + +function dtp_jshint_client ( ) { + var jsrc = 'client/js/**/*.js'; + return gulp + .src(jsrc) + .pipe(jshint()) + .pipe(jshint.reporter('dtp-jshint-reporter')) + .pipe(jshint.reporter('fail')) + .pipe(browserSync.stream()) + ; +} + +function dtp_jshint_lib ( ) { + var jsrc = 'lib/**/*.js'; + return gulp + .src(jsrc) + .pipe(jshint()) + .pipe(jshint.reporter('dtp-jshint-reporter')) + .pipe(jshint.reporter('fail')) + .pipe(browserSync.stream()) + ; +} + +function dtp_jshint_workers ( ) { + var jsrc = 'app/workers/**/*.js'; + return gulp + .src(jsrc) + .pipe(jshint()) + .pipe(jshint.reporter('dtp-jshint-reporter')) + ; +} + +function dtp_jshint_services ( ) { + var jsrc = 'app/services/**/*.js'; + return gulp + .src(jsrc) + .pipe(jshint()) + .pipe(jshint.reporter('dtp-jshint-reporter')) + ; +} + +function dtp_jshint_models ( ) { + var jsrc = 'app/models/**/*.js'; + return gulp + .src(jsrc) + .pipe(jshint()) + .pipe(jshint.reporter('dtp-jshint-reporter')) + .pipe(jshint.reporter('fail')) + .pipe(browserSync.stream()) + ; +} + +function dtp_jshint_controllers ( ) { + var jsrc = 'app/controllers/**/*.js'; + return gulp + .src(jsrc) + .pipe(jshint()) + .pipe(jshint.reporter('dtp-jshint-reporter')) + .pipe(jshint.reporter('fail')) + .pipe(browserSync.stream()) + ; +} + +/* + * Shared Webpack settings detween dev & prod + */ +const webpackDevtool = 'source-map'; +const webpackResolve = { + alias: { + dtp: path.resolve(__dirname, 'lib', 'client', 'js'), + }, + extensions: ['.js'], +}; +const webpackOutput = { + filename: 'dtpsites-[name].js', + path: path.resolve(__dirname, 'dist', 'js') +}; + +/* + * Webpack dev build + */ +function dtp_jsbuild_dev ( ) { + var jsrc = 'client/js/index.js'; + var jdst = 'dist/js'; + return gulp + .src(jsrc) + .pipe(webpack({ + mode: 'development', + devtool: webpackDevtool, + resolve: webpackResolve, + entry: { + "app": './client/js/index.js', + "admin": './client/js/index-admin.js', + }, + output: webpackOutput, + plugins: [ + new GenerateSW({ + swDest: 'service_worker.js', + }), + ], + performance: { + hints: false, + maxEntrypointSize: 512 * 1024, + maxAssetSize: 512 * 1024, + }, + })) + .on('error', function (err) { console.log(err.toString()); }) + .pipe(gulp.dest(jdst)) + ; +} + +/* + * Webpack prod build + */ +function dtp_jsbuild_prod ( ) { + var jsrc = 'client/js/index.js'; + var jdst = 'dist/js'; + return gulp + .src(jsrc) + .pipe(webpack({ + mode: 'production', + devtool: webpackDevtool, + resolve: webpackResolve, + entry: { + "app.min": './client/js/index.js', + "admin.min": './client/js/index-admin.js', + }, + optimization: { + minimize: true, + minimizer: [new TerserPlugin({ + extractComments: true, + })], + }, + output: webpackOutput, + plugins: [ + new GenerateSW({ + swDest: 'service_worker.min.js', + }), + ], + performance: { + hints: false, + maxEntrypointSize: 512 * 1024, + maxAssetSize: 512 * 1024, + }, + })) + .on('error', function (err) { console.log(err.toString()); }) + .pipe(gulp.dest(jdst)) + ; +} + +function dtp_watch_client (done) { + var files = [ + './client/less/**/*.less', + './client/less/dtp/*.less' + ]; + gulp.watch(files, dtp_less); + + var jsfiles = [ + path.join(__dirname, '..', 'dtp', 'dtp-lib', 'client', '**', '*.js'), + path.join(__dirname, 'client', 'js', '**', '*.js'), + ]; + gulp.watch(jsfiles, gulp.series( + dtp_jshint_client, // check syntax, etc. + gulp.parallel( + dtp_jsbuild_dev, // build dev webpack + dtp_jsbuild_prod, // build prod webpack + ), + function reload (done) { + browserSync.reload(); + return done(); + }, + )); + + var workerFiles = ['app/workers/*.js']; + gulp.watch(workerFiles, dtp_jshint_workers); + + var serviceFiles = ['app/services/**/*.js']; + gulp.watch(serviceFiles, dtp_jshint_services); + + done(); +} + +function dtp_develop (done) { + var isFirst = true; + nodemon({ + script: 'dtp-sites.js', + verbose: false, + watch: [ + './*.js', + './config/**/*.js', + 'lib/**/*.js', + 'app/**/*.js', + 'app/views/**/*.pug', + 'app/templates/**/*.pug', + 'app/services/**/*.js', + 'app/workers/**/*.js', + ], + ext: 'js pug', + stdout: false, + done: done + }) + .on('readable', function ( ) { + this.stdout.on('data', (chunk) => { + if (/sites platform online/.test(chunk)) { + if (isFirst) { + util_start_browsersync(); + isFirst = false; + } else { + browserSync.reload(); + } + } + }); + this.stdout.pipe(process.stdout); + this.stderr.pipe(process.stderr); + }); +} + +exports.less = dtp_less; + +exports.jshint = gulp.parallel( + dtp_jshint_models, + dtp_jshint_lib, + dtp_jshint_controllers, + dtp_jshint_client, + dtp_jshint_workers, + dtp_jshint_services, +); + +exports.build = gulp.parallel( + dtp_less, + dtp_jshint_models, + dtp_jshint_lib, + dtp_jshint_controllers, + dtp_jshint_client, + dtp_jshint_workers, + dtp_jshint_services, + dtp_jsbuild_dev, + dtp_jsbuild_prod, +); + +exports.default = gulp.series( + exports.build, + gulp.parallel(dtp_watch_client, dtp_develop) +); diff --git a/lib/client/js/dtp-app.js b/lib/client/js/dtp-app.js new file mode 100644 index 0000000..5835453 --- /dev/null +++ b/lib/client/js/dtp-app.js @@ -0,0 +1,112 @@ +// dtp-app.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +import DtpLog from './dtp-log'; +import DtpSocket from './dtp-socket'; +import DtpDisplayEngine from './dtp-display-engine'; + +export default class DtpApp { + + constructor (appName, user) { + this.user = user; + this.log = new DtpLog(appName); + + this.log.debug('constructor', 'creating DisplayEngine instance'); + this.displayEngine = new DtpDisplayEngine(); + } + + async connect (options) { + try { + this.log.debug('connect', 'creating WebSocket interface'); + this.socket = new DtpSocket(); + + this.log.debug('connect', 'connecting WebSocket platform'); + await this.socket.connect(options); + + this.log.info('connect', 'DTP framework online'); + } catch (error) { + this.log.error('connect', 'failed to connect', { error }); + UIkit.modal.alert(`Failed to connect to server: ${error.message}`); + } + } + + async processResponse (response) { + const json = await response.json(); + if (!json.success) { + this.log.error('processResponse', json.message); + throw new Error(json.message); + } + if (json.displayList) { + this.displayEngine.executeDisplayList(json.displayList); + } + } + + async validateTextElement (element, elementName, options) { + const DEFAULT_MAX_CHARS = 1000; + const DEFAULT_OPTIONS = { + maxLength: DEFAULT_MAX_CHARS, + minLength: 1, + warnLengths: [80, 150], + feedback: { + textEmpty: `The ${elementName} can't be empty`, + textTooShort: "Keep going...", + textValid: "You're off to a great start!", + textLengthWarn: [ + "This is getting a little crazy", + `Only ${Math.max(0, options.maxLength - element.value.length)} characters left`, + ], + textMaxLength: `The ${elementName} is as long as it can be.`, + textTooLong: `${elementName} is too long by ${element.value.length - options.maxLength} characters`, + } + }; + options = Object.assign(DEFAULT_OPTIONS, options); + + if (options.prompt) { + options.prompt.textContent = `${element.value.length} of ${options.maxLength} max`; + } + + let isValid = true; + + if (element.value.length === 0 || element.value.length > options.maxLength) { + element.classList.remove('uk-form-success'); + element.classList.remove('uk-form-warning'); + element.classList.add('uk-form-danger'); + isValid = false; + } else if (element.value.length > options.warnLengths[1]) { + element.classList.remove('uk-form-success'); + element.classList.remove('uk-form-danger'); + element.classList.add('uk-form-warning'); + } else { + element.classList.remove('uk-form-danger'); + element.classList.remove('uk-form-warning'); + element.classList.remove('uk-form-success'); + } + + if (element.value.length === 0) { + window.dtp.submit.prompt.textContent = options.feedback.textEmpty; + isValid = false; + } else if (options.minLength && (element.value.length < options.minLength)) { + window.dtp.submit.prompt.textContent = options.feedback.textTooShort; + isValid = false; + } else if (element.value.length < options.warnLengths[0]) { + window.dtp.submit.prompt.textContent = options.feedback.textValid; + } else if (element.value.length < options.warnLengths[1]) { + window.dtp.submit.prompt.textContent = options.feedback.textLengthWarn[0]; + } else if (element.value.length < options.maxLength) { + window.dtp.submit.prompt.textContent = options.feedback.textLengthWarn[1]; + window.dtp.submit.prompt.classList.add('uk-text-bold'); + } else if (element.value.length === options.maxLength) { + window.dtp.submit.prompt.textContent = options.feedback.textMaxLength; + window.dtp.submit.prompt.classList.add('uk-text-bold'); + } else { + window.dtp.submit.prompt.textContent = options.feedback.textTooLong; + window.dtp.submit.prompt.classList.add('uk-text-bold'); + isValid = false; + } + + return isValid; + } +} \ No newline at end of file diff --git a/lib/client/js/dtp-display-engine.js b/lib/client/js/dtp-display-engine.js new file mode 100644 index 0000000..cb58170 --- /dev/null +++ b/lib/client/js/dtp-display-engine.js @@ -0,0 +1,199 @@ +// dtp-display-engine.js +// Copyright (C) 2021 Digital Telepresence, Inc. +// License: Apache-2.0 + +'use strict'; + +import DtpLog from './dtp-log.js'; + +export default class DtpDisplayEngine { + + constructor ( ) { + this.processors = { }; + this.log = new DtpLog('DtpDisplayEngine'); + this.log.debug('constructor', 'DTP Display Engine instance created'); + } + + /** + * Register a named Display List processor plugin. This lets client objects + * define their own Display List processor classes and resiter them. Server + * code can then execute actions on named processors in the client. + * @param {*} name The name of the DL processor being registered. + * @param {*} processor The custom DL processor being registered. + */ + registerProcessor (name, processor) { + this.processors[name] = processor; + } + + /** + * Unregisters a named Display List processing plugin. + * @param {String} name The name of the DL processor to be unregistered. + */ + unregisterProcessor (name) { + if (!this.processors[name]) { + return; + } + delete this.processors[name]; + } + + /** + * Executes a Display List to implement view changes requested by the server. + * These can arrive from an HTTP request, via socket.io, or generated in code + * and passed in. + * @param {DtpDisplayList} displayList + */ + async executeDisplayList (displayList) { + try { + displayList.commands.forEach((command) => { + const processor = command.processor ? this.processors[command.processor] : this; + this.log.debug(command.action, 'action', command); + processor[command.action](displayList, command); + }); + } catch (error) { + this.log.error('executeDisplayList', 'failed to apply DisplayEngine updates', { error }); + UIkit.modal.alert(`Failed to apply updates: ${error.message}`); + } + } + + /* + * action: addElement + * selector: Specifies the container element to insertAdjacentHtml + * where: 'beforebegin', 'afterbegin', 'beforeend', 'afterend' + * html: the HTML content to insert at the container as specified + */ + async addElement (displayList, command) { + const container = document.querySelector(command.selector); + if (!container) { + console.debug('displayList.addElement has failed', { command }); + return; + } + container.insertAdjacentHtml(command.params.where, command.params.html); + } + + async setTextContent (displayList, command) { + const elements = document.querySelectorAll(command.selector); + if (!elements || (elements.length === 0)) { + this.log.error('setTextContent', 'failed to find target elements', { command }); + return; + } + elements.forEach((element) => { + element.textContent = command.params.text; + }); + } + + /* + * action: replaceElement + * selector: Specifies the element to be replaced + * html: replaces the whole specified element + */ + async replaceElement (displayList, command) { + const element = document.querySelector(command.selector); + if (!element) { + console.debug('displayList.replaceElement has failed to find requested element', { command }); + return; + } + element.outerHTML = command.params.html; + } + + /* + * action: removeElement + * selector: Specifies the element(s) to be removed + */ + async removeElement (displayList, command) { + const elements = document.querySelectorAll(command.selector); + if (!elements || !elements.length) { + console.debug('displayList.removeElement has failed', { command }); + return; + } + elements.forEach((element) => { + element.parentElement.removeChild(element); + }); + } + + /* + * action: setAttribute + * selector: Specifies the element(s) for which an attribute's value should be set + * name: the name of the attribute to be set + * value: the value to be set on the named attribute + */ + async setAttribute (displayList, command) { + const elements = document.querySelectorAll(command.selector); + if (!elements || !elements.length) { + console.debug('displayList.setAttribute has failed', { command }); + return; + } + elements.forEach((element) => { + element.setAttribute(command.params.name, command.params.value); + }); + } + + /* + * action: removeAttribute + * selector: specifies the element(s) from which an attribute is to be removed + * name: the name of the attribute to be removed + */ + async removeAttribute (displayList, command) { + const elements = document.querySelectorAll(command.selector); + if (!elements || !elements.length) { + console.debug('displayList.removeAttribute has failed', { command }); + return; + } + elements.forEach((element) => { + element.removeAttribute(command.params.name); + }); + } + + /* + * action: addClass + * selector: Specifies the element(s) for which style class(es) should be added + * name: the class name to add to the classList + */ + async addClass (displayList, command) { + const elements = document.querySelectorAll(command.selector); + if (!elements || !elements.length) { + console.debug('displayList.addClass has failed', { command }); + return; + } + elements.forEach((element) => { + element.classList.add(command.params.add); + }); + } + + /* + * action: removeClass + * selector: Specifies the element(s) for which style class(es) should be removed + * name: the class name to remove from the classList + */ + async removeClass (displayList, command) { + const elements = document.querySelectorAll(command.selector); + if (!elements || !elements.length) { + console.debug('displayList.removeClass has failed', { command }); + return; + } + elements.forEach((element) => { + element.classList.remove(command.params.remove); + }); + } + + /* + * action: replaceClass + * selector: Specifies the elements for which class replacement should occur + * remove: the class name to remove from the classList + * add: the class name to add to the classList + */ + async replaceClass (displayList, command) { + const elements = document.querySelectorAll(command.selector); + if (!elements || !elements.length) { + console.debug('displayList.replaceClass has failed', { command }); + return; + } + elements.forEach((element) => { + element.classList.remove(command.params.remove); + element.classList.add(command.params.add); + }); + } + + async showNotification (displayList, command) { + UIkit.notification(command.params); + } +} \ No newline at end of file diff --git a/lib/client/js/dtp-log.js b/lib/client/js/dtp-log.js new file mode 100644 index 0000000..8434b33 --- /dev/null +++ b/lib/client/js/dtp-log.js @@ -0,0 +1,127 @@ +// dtpweb-log.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +window.dtp = window.dtp || { }; + +export default class DtpWebLog { + + constructor (componentName, options) { + this.componentName = componentName; + this.options = Object.assign({ + color: { + debug: '#808080', + info: '#249324', + warn: '#AC7C37', + error: '#A74949', + }, + size: { + label: 120, + }, + }, options); + + this.css = { + debug: { + label: ` + display: inline-block; + background-color: ${this.options.color.debug}; + color: white; + width: ${this.options.size.label}px; + padding: 2px 4px; + border-radius: 4px; + `, + message: ` + color: ${this.options.color.debug}; + `, + }, + info: { + label: ` + background-color: ${this.options.color.info}; + color: white; + width: ${this.options.size.label}px; + padding: 2px 4px; + border-radius: 4px; + `, + message: ` + color: ${this.options.color.info}; + `, + }, + warn: { + label: ` + background-color: ${this.options.color.warn}; + color: white; + width: ${this.options.size.label}px; + padding: 2px 4px; + border-radius: 4px; + `, + message: ` + color: ${this.options.color.warn}; + `, + }, + error: { + label: ` + background-color: ${this.options.color.error}; + color: white; + width: ${this.options.size.label}px; + padding: 2px 4px; + border-radius: 4px; + `, + message: ` + color: ${this.options.color.error}; + `, + }, + }; + + const env = document.querySelector('body').getAttribute('data-dtp-env'); + if (env === 'local') { + this.enable(); + } + } + + enable (enabled = true) { + this.enabled = enabled; + } + + debug (event, msg, data) { + this.write('debug', this.css.debug, event, msg, data); + } + + log (event, msg, data) { this.info(event, msg, data); } + + info (event, msg, data) { + this.write('log', this.css.info, event, msg, data); + } + + warn (event, msg, data) { // alias for warning + this.warning(event, msg, data); + } + + warning (event, msg, data) { + this.write('warn', this.css.warn, event, msg, data); + } + + error (event, msg, data) { + this.write('error', this.css.error, event, msg, data); + if (data && data.error) { + console.error(data.error); + } + } + + write (method, css, event, msg, data) { + if (!this.enabled) { return; } + if (data) { + console[method]('%c%s%c: %s', + css.label, `${this.componentName}.${event}`, + css.message, msg, + data, + ); + } else { + console[method]('%c%s%c: %s', + css.label, `${this.componentName}.${event}`, + css.message, msg, + ); + } + } +} \ No newline at end of file diff --git a/lib/client/js/dtp-plugin.js b/lib/client/js/dtp-plugin.js new file mode 100644 index 0000000..474b65a --- /dev/null +++ b/lib/client/js/dtp-plugin.js @@ -0,0 +1,43 @@ +// dtp-plugin.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +/** + * I am just getting started roughing in the framework for DtpPlugin. + * DtpPlugin will be the base class for developers to use when creating a plugin + * intended to run within a DTP call. + * + * DtpApp will first create a data channel within the current call to implement + * the plugin's communications among call participants. DtpApp will then + * configure the view with a
and populate a plugin-safe object with + * information about the call participants. + * + * The plugin will be given these objects. It will instantiate itself into the + * parent
provided by DtpApp, wire up any event handlers it needs, etc. It + * can then immediately begin sending and receiving data among the call + * participants and indicate whatever is needed within the
provided. + * + * Some plugins may instantiate a within the
. Canvas2D, WebGL, + * Web Audio API, Gamepad API, and the rest of the web are available directly to + * DTP plugins. + */ + +'use strict'; + +const DTP_COMPONENT_NAME = 'dtp:plugin'; + +window.dtp = window.dtp || { }; + +import DtpLog from 'dtp/dtp-log.js'; + +export default class DtpPlugin { + + constructor (app, context, componentName) { + this.app = app; + this.context = context; + this.componentName = componentName; + this.log = new DtpLog(`${DTP_COMPONENT_NAME}:${componentName}`); + } +} + +window.dtp.DtpPlugin = DtpPlugin; \ No newline at end of file diff --git a/lib/client/js/dtp-socket.js b/lib/client/js/dtp-socket.js new file mode 100644 index 0000000..809252f --- /dev/null +++ b/lib/client/js/dtp-socket.js @@ -0,0 +1,138 @@ +// dtpweb-socket.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +window.dtp = window.dtp || { }; + +import DtpWebLog from './dtp-log.js'; + +export default class DtpWebSocket { + + constructor ( ) { + this.isConnected = false; + this.isAuthenticated = false; + this.joinedChannels = { }; + + this.log = new DtpWebLog('DtpWebSocket'); + } + + async connect (options) { + options = Object.assign({ + withRetry: true, + withError: false, + }, options); + try { + const response = await fetch('/auth/socket-token'); + if (!response.ok) { + this.retryConnect(); + throw new Error('socket failed to connect'); + } + + const json = await response.json(); + if (!json.success) { + this.retryConnect(); + throw new Error(`failed to connect: ${json.message}`); + } + + this.log.debug('connect', 'WebSocket connecting to Digital Telepresence Platform', json); + this.socket = io('/', { + transports: ['websocket'], + reconnection: false, + auth: { + token: json.token, + }, + }); + + this.socket.on('connect', this.onSocketConnect.bind(this)); + this.socket.on('authenticated', this.onSocketAuthenticated.bind(this)); + this.socket.on('join-result', this.onJoinResult.bind(this)); + this.socket.on('disconnect', this.onSocketDisconnect.bind(this)); + } catch (error) { + this.log.error('connect', 'failed to connect', { error }); + if (options.withRetry) { + this.retryConnect(); + } + if (options.withError) { + throw error; + } + } + } + + async onSocketConnect ( ) { + this.log.info('onSocketConnect', 'WebSocket connected'); + this.isConnected = true; + } + + async onSocketDisconnect (reason) { + this.isConnected = false; + this.socket.close(); + delete this.socket; + + if (!this.isAuthenticated) { + UIkit.modal.alert(`Failed to authenticate WebSocket session. Please log out, log back in, and try again.`); + return; + } + + const REASONS = { + 'io server disconnect': 'The server closed the connection', + 'io client disconnect': 'The client closed the connection', + 'ping timeout': 'The server is unreachable', + 'transport close': 'Connection was lost or network changed', + 'transport error': 'Server communication error, please try again.', + }; + + this.log.warn('onSocketDisconnect', 'WebSocket disconnected', { reason }); + UIkit.modal.alert(`Disconnected: ${REASONS[reason]}`); + + this.retryConnect(); + } + + retryConnect ( ) { + if (this.retryTimeout) { + return; // a retry is already in progress + } + this.retryTimeout = setTimeout(async ( ) => { + delete this.retryTimeout; + await this.connect(); + }, 2000); + } + + async onSocketAuthenticated (message) { + this.log.info('onSocketAuthenticated', message.message, { user: message.user }); + + this.isAuthenticated = true; + this.user = message.user; + + this.joinChannel(message.user._id, 'user'); + document.dispatchEvent(new Event('socketConnected')); + } + + async joinChannel (channelId, channelType) { + this.log.info('joinChannel', 'joining channel', { channelId, channelType }); + this.socket.emit('join', { channelId, channelType }); + } + + async isChannelJoined (channelId) { + return !!this.joinedChannels[channelId]; + } + + async onJoinResult (message) { + this.log.info('onJoinResult', 'channel joined', { message }); + this.joinedChannels[message.channelId] = message; + } + + async leaveChannel (channelId) { + this.log.info('leaveChannel', 'leaving channel', { channelId }); + this.socket.emit('leave', { channelId }); + if (this.joinedChannels[channelId]) { + delete this.joinedChannels[channelId]; + } + } + + async sendUserChat (channelId, content) { + this.log.info('sendUserChat', 'sending message to channel', { channelId, content }); + this.socket.emit('user-chat', { channelId, content }); + } +} \ No newline at end of file diff --git a/lib/site-async.js b/lib/site-async.js new file mode 100644 index 0000000..582e636 --- /dev/null +++ b/lib/site-async.js @@ -0,0 +1,41 @@ +// site-async.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +class SiteAsync { + + static each (sourceItems, callback, concurrent = 1) { + if (!Array.isArray(sourceItems)) { + throw new Error('each requires an array of objects to be processed'); + } + if (sourceItems.length === 0) { + return Promise.resolve(); + } + + var items = sourceItems.slice(); + var running = 0; + + return new Promise((resolve, reject) => { + function next ( ) { + let item = items.shift(); + if (!item) { + return; + } + ++running; + callback(item).then(next).catch(reject).finally(( ) => { + if (--running === 0) { + resolve(); + } + }); + } + while (concurrent && items.length) { + next(); + --concurrent; + } + }); + } +} + +module.exports.SiteAsync = SiteAsync; \ No newline at end of file diff --git a/lib/site-common.js b/lib/site-common.js new file mode 100644 index 0000000..1438cd4 --- /dev/null +++ b/lib/site-common.js @@ -0,0 +1,27 @@ +// site-common.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const Events = require('events'); +class SiteCommon extends Events { + + constructor (dtp) { + super(); + this.dtp = dtp; + } + + saveSession (req) { + return new Promise((resolve, reject) => { + req.session.save((err) => { + if (err) { + return reject(err); + } + resolve(); + }); + }); + } +} + +module.exports.SiteCommon = SiteCommon; \ No newline at end of file diff --git a/lib/site-controller.js b/lib/site-controller.js new file mode 100644 index 0000000..ce6a589 --- /dev/null +++ b/lib/site-controller.js @@ -0,0 +1,47 @@ +// site-controller.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const path = require('path'); + +const { SiteCommon } = require(path.join(__dirname, 'site-common')); +const { SiteLog } = require(path.join(__dirname, 'site-log')); + +class SiteController extends SiteCommon { + + constructor (dtp, name) { + super(dtp); + this.name = name; + this.log = new SiteLog(dtp, `ctrl:${name}`); + } + + async loadChild (filename) { + this.log.info('loading child controller', { script: filename }); + let child = await require(filename)(this.dtp); + return await child.start(); + } + + getPaginationParameters (req, maxPerPage) { + const pagination = { + p: parseInt(req.query.p || '1', 10), + cpp: parseInt(req.query.cpp || maxPerPage.toString(), 10), + }; + if (pagination.p < 1) { + pagination.p = 1; + } + if (pagination.cpp > maxPerPage) { + pagination.cpp = maxPerPage; + } + pagination.skip = (pagination.p - 1) * pagination.cpp; + return pagination; + } + + async createCsrfToken (req, name) { + const { csrfToken } = this.dtp.platform.services; + return csrfToken.create(req, { name }); + } +} + +module.exports.SiteController = SiteController; \ No newline at end of file diff --git a/lib/site-error.js b/lib/site-error.js new file mode 100644 index 0000000..6601839 --- /dev/null +++ b/lib/site-error.js @@ -0,0 +1,19 @@ +// site-error.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +class SiteError extends Error { + + constructor (statusCode, message) { + super(message); + this.name = 'SiteError'; + if (!this.code) { + this.code = statusCode; + } + this.statusCode = statusCode; + } +} + +module.exports.SiteError = SiteError; \ No newline at end of file diff --git a/lib/site-ioserver.js b/lib/site-ioserver.js new file mode 100644 index 0000000..1da8875 --- /dev/null +++ b/lib/site-ioserver.js @@ -0,0 +1,234 @@ +// site-ioserver.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const path = require('path'); + +const Redis = require('ioredis'); + +const mongoose = require('mongoose'); +const ConnectToken = mongoose.model('ConnectToken'); +const ChatMessage = mongoose.model('ChatMessage'); + +const striptags = require('striptags'); +const marked = require('marked'); + +const { SiteLog } = require(path.join(__dirname, 'site-log')); + +const Events = require('events'); +class SiteIoServer extends Events { + + constructor (dtp) { + super(); + this.dtp = dtp; + this.log = new SiteLog(dtp, 'ioserver'); + } + + async start (httpServer) { + const { domain: domainService } = this.dtp.services; + + const { Server } = require('socket.io'); + const { createAdapter } = require('@socket.io/redis-adapter'); + + this.domain = await domainService.getByName(process.env.DTP_SITE_DOMAIN_KEY); + if (!this.domain) { + throw new Error('Must define site domain in MongoDB before starting environment'); + } + + this.markedRenderer = new marked.Renderer(); + this.markedRenderer.link = (href, title, text) => { return text; }; + this.markedRenderer.image = (href, title, text) => { return text; }; + this.markedRenderer.image = (href, title, text) => { return text; }; + + const hljs = require('highlight.js'); + this.markedConfig = { + renderer: this.markedRenderer, + highlight: function(code, lang) { + const language = hljs.getLanguage(lang) ? lang : 'plaintext'; + return hljs.highlight(code, { language }).value; + }, + langPrefix: 'hljs language-', // highlight.js css expects a top-level 'hljs' class. + pedantic: false, + gfm: true, + breaks: false, + sanitize: false, + smartLists: true, + smartypants: false, + xhtml: false, + }; + + const transports = ['websocket'/*, 'polling'*/]; + + const pubClient = new Redis({ + host: process.env.REDIS_HOST, + port: process.env.REDIS_PORT, + password: process.env.REDIS_PASSWORD, + key: process.env.REDIS_PREFIX, + }); + pubClient.on('error', this.onRedisError.bind(this)); + + const subClient = pubClient.duplicate(); + subClient.on('error', this.onRedisError.bind(this)); + + const adapter = createAdapter(pubClient, subClient); + this.io = new Server(httpServer, { adapter, transports }); + + this.io.on('connection', this.onSocketConnect.bind(this)); + } + + async onRedisError (error) { + this.log.error('Redis error', { error }); + } + + async stop ( ) { + + } + + async onSocketConnect (socket) { + this.log.debug('socket connection', { sid: socket.id }); + const token = await ConnectToken.findOne({ token: socket.handshake.auth.token }).populate('user').lean(); + if (!token) { + this.log.alert('rejecting invalid socket token', { + sid: socket.sid, + handshake: socket.handshake, + }); + socket.close(); + return; + } + + if (token.claimed) { + this.log.alert('rejecting use of claimed connect token', { + sid: socket.id, + handshake: socket.handshake, + }); + socket.close(); + return; + } + + await ConnectToken.updateOne( + { _id: token._id }, + { $set: { claimed: new Date() } }, + ); + this.log.debug('token claimed', { + sid: socket.id, + token: socket.handshake.auth.token, + user: token.user._id, + }); + + const session = { + user: { + _id: token.user._id, + created: token.user.created, + username: token.user.username, + displayName: token.user.displayName, + }, + socket, + }; + + session.onSocketDisconnect = this.onSocketDisconnect.bind(this, session); + session.onJoinChannel = this.onJoinChannel.bind(this, session); + session.onLeaveChannel = this.onLeaveChannel.bind(this, session); + session.onUserChat = this.onUserChat.bind(this, session); + + socket.on('disconnect', session.onSocketDisconnect); + socket.on('join', session.onJoinChannel); + socket.on('leave', session.onLeaveChannel); + socket.on('user-chat', session.onUserChat); + + socket.emit('authenticated', { + message: 'token verified', + user: session.user, + }); + } + + async onSocketDisconnect (session, reason) { + this.log.debug('socket disconnect', { sid: session.socket.id, user: session.user._id, reason }); + session.socket.off('disconnect', session.onSocketDisconnect); + session.socket.off('join', session.onJoinChannel); + session.socket.off('leave', session.onLeaveChannel); + } + + async onJoinChannel (session, message) { + const { channelId } = message; + this.log.debug('socket joins channel', { sid: session.socket.id, user: session.user._id, channelId }); + session.socket.join(channelId); + session.socket.emit('join-result', { channelId }); + } + + async onLeaveChannel (session, message) { + const { channelId } = message; + this.log.debug('socket leaves channel', { sid: session.socket.id, user: session.user._id, channelId }); + session.socket.leave(channelId); + } + + async onUserChat (session, message) { + const { channel: channelService } = this.dtp.services; + const { channelId } = message; + + if (!message.content || (message.content.length === 0)) { + return; + } + + const channel = await channelService.getChannelById(channelId); + if (!channel) { + return; + } + + const stickers = this.findStickers(message.content); + stickers.forEach((sticker) => { + const re = new RegExp(`:${sticker}:`, 'gi'); + message.content = message.content.replace(re, '').trim(); + }); + + message.content = striptags(message.content); + + await ChatMessage.create({ + created: new Date(), + domain: this.domain._id, + channel: mongoose.Types.ObjectId(channelId), + episode: channel.liveEpisode, + author: session.user._id, + content: message.content, + stickers, + }); + + const renderedContent = marked(message.content, this.markedConfig); + + const payload = { + user: { + _id: session.user._id, + username: session.user.username, + }, + content: renderedContent, + stickers, + }; + + session.socket.to(channelId).emit('user-chat', payload); + session.socket.emit('user-chat', payload); + } + + findStickers (content) { + const tokens = content.split(' '); + const stickers = [ ]; + tokens.forEach((token) => { + if ((token[0] !== ':') || (token[token.length -1 ] !== ':')) { + return; + } + + token = token.slice(1, token.length - 1 ).toLowerCase(); + if (token.includes('/') || token.includes(':') || token.includes(' ')) { + return; // trimmed token includes invalid characters + } + + this.log.debug('found sticker request', { token }); + if (!stickers.includes(token)) { + stickers.push(striptags(token)); + } + }); + return stickers; + } +} + +module.exports.SiteIoServer = SiteIoServer; \ No newline at end of file diff --git a/lib/site-lib.js b/lib/site-lib.js new file mode 100644 index 0000000..54cda91 --- /dev/null +++ b/lib/site-lib.js @@ -0,0 +1,17 @@ +// site-lib.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const path = require('path'); + +module.exports = { + SiteCommon: require(path.join(__dirname, 'site-common')).SiteCommon, + SitePlatform: require(path.join(__dirname, 'site-platform')), + SiteAsync: require(path.join(__dirname, 'site-async')).SiteAsync, + SiteError: require(path.join(__dirname, 'site-error')).SiteError, + SiteLog: require(path.join(__dirname, 'site-log')).SiteLog, + SiteController: require(path.join(__dirname, 'site-controller')).SiteController, + SiteService: require(path.join(__dirname, 'site-service')).SiteService, +}; \ No newline at end of file diff --git a/lib/site-log.js b/lib/site-log.js new file mode 100644 index 0000000..8f6789d --- /dev/null +++ b/lib/site-log.js @@ -0,0 +1,96 @@ +// site-log.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const util = require('util'); +const moment = require('moment'); +const rfs = require('rotating-file-stream'); + +var LogModel, LogStream; + +if (process.env.DTP_LOG_FILE === 'enabled') { + LogStream = rfs.createStream(process.env.DTP_LOG_FILE_NAME_APP || 'site-app.log', { + path: process.env.DTP_LOG_FILE_PATH || '/tmp', + size: '10M', + interval: '1d', + compress: 'gzip', + }); +} + +class SiteLog { + + /** + * Sets the Mongoose model to be used for writing log entries to the database. + * This is managed like this so we don't have to connect to the database and + * load the db models *before* we can write log entries to the console. + * @param {Model} model the Mongoose model to be used for writing logs. + */ + static setModel (model) { LogModel = model; } + + constructor (dtp, componentName) { + this.dtp = dtp; + this.componentName = componentName; + } + + async debug (message, metadata) { + if (process.env.DTP_LOG_DEBUG !== 'enabled') { + return; + } + return this.writeLog('debug', message, metadata); + } + + async info (message, metadata) { + if (process.env.DTP_LOG_INFO !== 'enabled') { + return; + } + return this.writeLog('info', message, metadata); + } + + async warn (message, metadata) { + if (process.env.DTP_LOG_WARN !== 'enabled') { + return; + } + return this.writeLog('warn', message, metadata); + } + + async alert (message, metadata) { + return this.writeLog('alert', message, metadata); + } + + async error (message, metadata) { + return this.writeLog('error', message, metadata); + } + + async crit (message, metadata) { + return this.writeLog('crit', message, metadata); + } + + async fatal (message, metadata) { + this.writeLog('fatal', message, metadata); + } + + async writeLog (level, message, metadata) { + const NOW = new Date(); + const { componentName } = this; + if (process.env.DTP_LOG_CONSOLE === 'enabled') { + if (metadata) { + console.log(`${moment(NOW).format('YYYY-MM-DD HH:mm:ss.SSS')} ${componentName} ${level} ${message}`, util.inspect(metadata, false, Infinity, true)); + } else { + console.log(`${moment(NOW).format('YYYY-MM-DD HH:mm:ss.SSS')} ${componentName} ${level} ${message}`); + } + } + if (LogModel && (process.env.DTP_LOG_MONGODB === 'enabled')) { + await LogModel.create({ created: NOW, level, componentName, message, metadata }); + } + if (LogStream && (process.env.DTP_LOG_FILE === 'enabled')) { + const logEntry = { + t: NOW, c: componentName, l: level, m: message, d: metadata, + }; + LogStream.write(`${JSON.stringify(logEntry)}\n`); + } + } +} + +module.exports.SiteLog = SiteLog; \ No newline at end of file diff --git a/lib/site-platform.js b/lib/site-platform.js new file mode 100644 index 0000000..66d0994 --- /dev/null +++ b/lib/site-platform.js @@ -0,0 +1,317 @@ +// site-platform.js +// Copyright (C) 2021 Digital Telepresence, LLC. +// License: Apache-2.0 + +'use strict'; + +const path = require('path'); +const glob = require('glob'); + +const express = require('express'); +const cookieParser = require('cookie-parser'); +const session = require('express-session'); +const RedisSessionStore = require('connect-redis')(session); +const passport = require('passport'); + +const mongoose = require('mongoose'); +const Redis = require('ioredis'); +const ioEmitter = require('socket.io-emitter'); + +const morgan = require('morgan'); +const rfs = require('rotating-file-stream'); +const compress = require('compression'); +const methodOverride = require('method-override'); +const marked = require('marked'); + +const { SiteAsync } = require(path.join(__dirname, 'site-async')); +const { SiteLog } = require(path.join(__dirname, 'site-log')); + +module.connectDatabase = async (/*dtp*/) => { + try { + module.log.info('connecting to MongoDB database', { + pid: process.pid, + host: process.env.MONGODB_HOST, + database: process.env.MONGODB_DATABASE, + }); + const mongoConnectUri = `mongodb://${process.env.MONGODB_HOST}/${process.env.MONGODB_DATABASE}`; + module.db = await mongoose.connect(mongoConnectUri, { + socketTimeoutMS: 0, + keepAlive: true, + keepAliveInitialDelay: 300000, + dbName: process.env.MONGODB_DATABASE, + }); + module.log.info('connected to MongoDB'); + } catch (error) { + module.log.error('failed to connect to database', { error }); + throw error; + } +}; + + +module.loadModels = async (dtp) => { + dtp.models = module.models = [ ]; + const modelScripts = glob.sync(path.join(dtp.config.root, 'app', 'models', '*.js')); + modelScripts.forEach((modelScript) => { + const model = require(modelScript); + if (module.models[model.modelName]) { + module.log.error('model name collision', { name: model.modelName }); + process.exit(-1); + } + module.log.info('data model loaded', { + name: model.modelName, + collection: model.collection.collectionName, + }); + module.models[model.modelName] = model; + }); +}; + +module.connectRedis = async (dtp) => { + try { + const options = { + host: process.env.REDIS_HOST, + port: parseInt(process.env.REDIS_PORT || '6379', 10), + password: process.env.REDIS_PASSWORD, + keyPrefix: process.env.REDIS_KEY_PREFIX, + lazyConnect: true, + }; + module.log.info('connecting to Redis', { + host: options.host, + port: options.port, + prefix: options.keyPrefix, + }); + + module.redis = dtp.redis = new Redis(options); + module.redis.setMaxListeners(64); // prevents warnings/errors with Bull Queue + + await module.redis.connect(); + module.ioEmitter = dtp.ioEmitter = ioEmitter(module.redis); + + module.log.info('Redis connected'); + } catch (error) { + module.log.error('failed to connect to Redis', error); + throw error; + } +}; + +module.getRedisKeys = (pattern) => { + return new Promise((resolve, reject) => { + return module.redis.keys(pattern, (err, response) => { + if (err) { + return reject(err); + } + return resolve(response); + }); + }); +}; + +module.loadServices = async (dtp) => { + dtp.services = module.services = { }; + const scripts = glob.sync(path.join(dtp.config.root, 'app', 'services', '*.js')); + const inits = [ ]; + await SiteAsync.each(scripts, async (script) => { + module.log.info('service', { script }); + const service = await require(script); + module.services[service.name] = service.create(dtp); + module.services[service.name].__dtp_service_name = service.name; + inits.push(module.services[service.name]); + module.log.info('service loaded', { name: service.name }); + }); + await SiteAsync.each(inits, async (service) => { + await service.start(); + }); +}; + +module.loadControllers = async (dtp) => { + const scripts = glob.sync(path.join(dtp.config.root, 'app', 'controllers', '*.js')); + const inits = [ ]; + await SiteAsync.each(scripts, async (script) => { + module.log.info('controller', { script }); + const controller = await require(script)(dtp); + inits.push(controller); + }); + await SiteAsync.each(inits, async (controller) => { + await controller.start(); + }); +}; + +module.exports.startPlatform = async (dtp) => { + try { + + module.log = new SiteLog(module, dtp.config.componentName); + dtp.config.jobQueues = require(path.join(dtp.config.root, 'config', 'job-queues')); + + await module.connectDatabase(dtp); + await module.connectRedis(dtp); + + await module.loadModels(dtp); + SiteLog.setModel(mongoose.model('Log')); + + await module.loadServices(dtp); + } catch (error) { + module.log.error('failed to initialize the Digital Telepresence Platform', { error }); + return; + } +}; + +module.exports.startWebServer = async (dtp) => { + + dtp.app = module.app = express(); + + module.app.set('views', path.join(dtp.config.root, 'app', 'views')); + module.app.set('view engine', 'pug'); + module.app.set('x-powered-by', false); + + /* + * Expose useful modules and information + */ + module.app.locals.DTP_SCRIPT_DEBUG = (process.env.NODE_ENV === 'local'); + module.app.locals.site = dtp.config.site; + module.app.locals.pkg = require(path.join(dtp.config.root, 'package.json')); + module.app.locals.moment = require('moment'); + module.app.locals.numeral = require('numeral'); + module.app.locals.phoneNumberJS = require('libphonenumber-js'); + module.app.locals.anchorme = require('anchorme').default; + + /* + * Set up the protected markdown renderer that will refuse to process links and images + * for security reasons. + */ + var markedRenderer = new marked.Renderer(); + markedRenderer.link = (href, title, text) => { return text; }; + markedRenderer.image = (href, title, text) => { return text; }; + marked.setOptions({ renderer: markedRenderer }); + module.app.locals.marked = marked; + + /* + * HTTP request logging + */ + if (process.env.DTP_LOG_FILE === 'enabled') { + const httpLogStream = rfs.createStream(process.env.DTP_LOG_FILE_NAME_HTTP || 'dtp-sites-access.log', { + interval: '1d', + path: process.env.DTP_LOG_FILE_PATH || '/tmp', + compress: 'gzip', + }); + module.app.use(morgan(process.env.DTP_LOG_HTTP_FORMAT || 'combined', { stream: httpLogStream })); + } + + function cacheOneDay (req, res, next) { + res.set('Cache-Control', 's-maxage=86400'); + return next(); + } + + /* + * Static file services (project) + */ + module.app.use(express.static(path.join(dtp.config.root, 'client'))); + module.app.use('/dist', cacheOneDay, express.static(path.join(dtp.config.root, 'dist'))); + module.app.use('/img', cacheOneDay, express.static(path.join(dtp.config.root, 'client', 'img'))); + + /* + * Static file services (vendor) + */ + module.app.use('/uikit', cacheOneDay, express.static(path.join(dtp.config.root, 'node_modules', 'uikit', 'dist'))); + module.app.use('/chart.js', cacheOneDay, express.static(path.join(dtp.config.root, 'node_modules', 'chart.js', 'dist'))); + module.app.use('/cropperjs', cacheOneDay, express.static(path.join(dtp.config.root, 'node_modules', 'cropperjs', 'dist'))); + module.app.use('/fontawesome', cacheOneDay, express.static(path.join(dtp.config.root, 'node_modules', '@fortawesome', 'fontawesome-free'))); + module.app.use('/moment', cacheOneDay, express.static(path.join(dtp.config.root, 'node_modules', 'moment', 'min'))); + module.app.use('/mpegts', cacheOneDay, express.static(path.join(dtp.config.root, 'node_modules', 'mpegts.js', 'dist'))); + module.app.use('/numeral', cacheOneDay, express.static(path.join(dtp.config.root, 'node_modules', 'numeral', 'min'))); + module.app.use('/tinymce', cacheOneDay, express.static(path.join(dtp.config.root, 'node_modules', 'tinymce'))); + + /* + * ExpressJS middleware + */ + module.app.use(express.json({ })); + module.app.use(express.urlencoded({ extended: true })); + module.app.use(cookieParser()); + module.app.use(compress()); + module.app.use(methodOverride()); + + /* + * Express sessions + */ + module.log.info('initializing redis session store'); + var sessionStore = new RedisSessionStore({ client: module.redis }); + + const SESSION_DURATION = 1000 * 60 * 60 * 24 * 30; // 30 days + module.sessionConfig = { + name: `session.${process.env.DTP_SITE_DOMAIN_KEY}.${process.env.NODE_ENV}`, + secret: process.env.HTTP_SESSION_SECRET, + resave: true, + saveUninitialized: true, + cookie: { + domain: process.env.DTP_SITE_DOMAIN, + path: '/', + httpOnly: true, + secure: false, + sameSite: 'strict', + expires: SESSION_DURATION, + }, + store: null, + }; + module.sessionConfig.store = sessionStore; + if (process.env.NODE_ENV === 'production') { + module.app.set('trust proxy', 1); + // module.sessionConfig.cookie.secure = true; + } + module.app.use(session(module.sessionConfig)); + + /* + * PassportJS setup + */ + module.log.info('initializting PassportJS'); + module.app.use(passport.initialize()); + module.app.use(passport.session()); + + module.app.use(module.services.session.middleware()); + + /* + * Application logic middleware + */ + module.app.use(async (req, res, next) => { + res.locals.dtp = { + request: req, + }; + return next(); + }); + + /* + * System Init + */ + try { + await module.loadControllers(dtp); + } catch (error) { + module.log.error('failed to initialize application controller', { error }); + return; + } + + module.app.use(async (err, req, res, next) => { // jshint ignore:line + var errorCode = err.status || err.statusCode || err.code || 500; + module.log.error('HTTP error', { error: err }); + res.status(errorCode).render('error', { + message: err.message, + error: err, + title: 'error' + }); + }); + + module.log.info('creating HTTP server'); + module.http = require('http').createServer(module.app); + + module.log.info('creating Socket.io server'); + const { SiteIoServer } = require(path.join(__dirname, 'site-ioserver')); + module.io = new SiteIoServer(dtp); + await module.io.start(module.http); + + module.log.info('starting HTTP server', { + port: dtp.config.http.port, + bind: dtp.config.http.address, + }); + module.http.listen(dtp.config.http.port, dtp.config.http.address, ( ) => { + module.log.info(`${dtp.config.componentName} platform online`, { port: dtp.config.http.port }); + }); +}; + +module.exports.shutdown = async ( ) => { + module.log.info('platform shutting down'); +}; \ No newline at end of file diff --git a/lib/site-service.js b/lib/site-service.js new file mode 100644 index 0000000..024fd4b --- /dev/null +++ b/lib/site-service.js @@ -0,0 +1,30 @@ +// site-service.js +// Copyright (C) 2021 Digital Telepresence, LLC +// License: Apache-2.0 + +'use strict'; + +const path = require('path'); + +const { SiteCommon } = require(path.join(__dirname, 'site-common')); +const { SiteLog } = require(path.join(__dirname, 'site-log')); + +class SiteService extends SiteCommon { + + constructor (dtp, definition) { + super(dtp); + this.slug = definition.slug; + this.name = definition.name; + this.log = new SiteLog(dtp, `svc:${this.slug}`); + } + + async start ( ) { + this.log.info(`starting ${this.name} service`); + } + + async stop ( ) { + this.log.info(`stopping ${this.name} service`); + } +} + +module.exports.SiteService = SiteService; \ No newline at end of file diff --git a/package.json b/package.json index a9b1c1c..ae52409 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,80 @@ "dev": "nodemon dtp-sites.js" }, "dependencies": { + "@fortawesome/fontawesome-free": "^5.15.4", + "@socket.io/redis-adapter": "^7.1.0", + "anchorme": "^2.1.2", + "argv": "^0.0.2", + "bull": "^4.1.1", + "chart.js": "^3.6.2", + "compression": "^1.7.4", + "connect-redis": "^6.0.0", + "cookie-parser": "^1.4.6", + "cron": "^1.8.2", + "cropperjs": "^1.5.12", + "diskusage-ng": "^1.0.2", + "disposable-email-provider-domains": "^1.0.9", "dotenv": "^10.0.0", + "dtp-jshint-reporter": "^1.0.2", + "ein-validator": "^1.0.1", + "email-domain-check": "^1.1.4", + "email-validator": "^2.0.4", + "execa": "^6.0.0", "express": "^4.17.1", + "express-limiter": "^1.6.1", + "express-session": "^1.17.2", + "feed": "^4.2.2", + "geoip-lite": "^1.4.2", + "glob": "^7.2.0", + "highlight.js": "^11.3.1", + "html-filter": "^4.3.2", + "ioredis": "^4.28.2", + "jsdom": "^19.0.0", + "libphonenumber-js": "^1.9.44", + "mailgun-js": "^0.22.0", + "marked": "^4.0.6", + "method-override": "^3.0.0", + "minio": "^7.0.23", + "moment": "^2.29.1", "mongoose": "^6.0.14", - "pug": "^3.0.2" + "morgan": "^1.10.0", + "multer": "^1.4.3", + "node-fetch": "^3.1.0", + "numeral": "^2.0.6", + "otplib": "^12.0.1", + "passport": "^0.5.0", + "passport-local": "^1.0.0", + "pug": "^3.0.2", + "qrcode": "^1.5.0", + "rate-limiter-flexible": "^2.3.6", + "rotating-file-stream": "^3.0.2", + "serve-favicon": "^2.5.0", + "sharp": "^0.29.3", + "slug": "^5.1.0", + "socket.io": "^4.4.0", + "socket.io-emitter": "^3.2.0", + "striptags": "^3.2.0", + "systeminformation": "^5.9.16", + "tinymce": "^5.10.2", + "uikit": "^3.9.4", + "uniqid": "^5.4.0", + "uuid": "^8.3.2", + "zxcvbn": "^4.4.2" }, "devDependencies": { - "jshint": "^2.13.1" + "browser-sync": "^2.27.7", + "gulp": "^4.0.2", + "gulp-concat": "^2.6.1", + "gulp-jshint": "^2.1.0", + "gulp-less": "^5.0.0", + "gulp-nodemon": "^2.5.0", + "gulp-plumber": "^1.2.1", + "gulp-rename": "^2.0.0", + "gulp-uglify-es": "^3.0.0", + "jshint": "^2.13.1", + "terser-webpack-plugin": "^5.2.5", + "webpack": "^5.64.4", + "webpack-stream": "^7.0.0", + "workbox-webpack-plugin": "^6.4.2" } } diff --git a/release b/release new file mode 100755 index 0000000..c1ea781 --- /dev/null +++ b/release @@ -0,0 +1,18 @@ +#!/bin/bash + +if [ -z "$1" ] +then + echo "Must specify the release type: major, minor, patch" + exit; +fi + +yarn version --$1 + +git checkout develop +git push origin develop + +git checkout master +git pull . develop +git push origin master + +git checkout develop diff --git a/sites-start-local b/sites-start-local new file mode 100755 index 0000000..e7691da --- /dev/null +++ b/sites-start-local @@ -0,0 +1,11 @@ +#!/bin/bash + +MINIO_ROOT_USER="sites" +MINIO_ROOT_PASSWORD="1f1c7c9b-b833-4462-ae41-d56f52faa49c" +export MINIO_ROOT_USER MINIO_ROOT_PASSWORD + +forever start app/workers/host-services.js + +minio server ./data/minio --console-address ":9001" + +forever stop app/workers/host-services.js \ No newline at end of file diff --git a/ssl/mkcert b/ssl/mkcert new file mode 100755 index 0000000..dc60564 --- /dev/null +++ b/ssl/mkcert @@ -0,0 +1,7 @@ +#!/bin/bash + +openssl genrsa -out dtp-sites.key +openssl req -new -out dtp-sites.csr -key dtp-sites.key -config openssl.cnf +openssl x509 -req -days 3650 -in dtp-sites.csr -signkey dtp-sites.key -out dtp-sites.crt -extensions v3_req -extfile openssl.cnf + +rm dtp-sites.csr \ No newline at end of file diff --git a/ssl/openssl.cnf b/ssl/openssl.cnf new file mode 100644 index 0000000..756f0d2 --- /dev/null +++ b/ssl/openssl.cnf @@ -0,0 +1,25 @@ +[req] +distinguished_name = req_distinguished_name +req_extensions = v3_req + +[req_distinguished_name] +countryName = US +countryName_default = US +stateOrProvinceName = Pennsylvania +stateOrProvinceName_default = Pennsylvania +localityName = Pittsburgh +localityName_default = Pittsburgh +organizationalUnitName = Digital Telepresence, LLC +organizationalUnitName_default = Digital Telepresence, LLC +commonName = *.digitaltelepresence.com +commonName_max = 64 + +[ v3_req ] +# Extensions to add to a certificate request +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = *.digitaltelepresence.com +DNS.2 = localhost \ No newline at end of file diff --git a/update-deps b/update-deps new file mode 100755 index 0000000..14a290c --- /dev/null +++ b/update-deps @@ -0,0 +1,76 @@ +#!/bin/bash + +yarn \ + add @fortawesome/fontawesome-free \ + anchorme \ + argv \ + bull \ + chart.js \ + compression \ + connect-redis \ + cookie-parser \ + cron \ + cropperjs \ + diskusage-ng \ + disposable-email-provider-domains \ + dotenv \ + ein-validator \ + email-domain-check \ + email-validator \ + execa \ + express \ + express-limiter \ + express-session \ + feed \ + geoip-lite \ + glob \ + highlight.js \ + html-filter \ + ioredis \ + jsdom \ + libphonenumber-js \ + mailgun-js \ + marked \ + method-override \ + minio \ + moment \ + mongoose \ + morgan \ + multer \ + node-fetch \ + numeral \ + otplib \ + passport \ + passport-local \ + pug \ + qrcode \ + rate-limiter-flexible \ + rotating-file-stream \ + serve-favicon \ + sharp \ + slug \ + socket.io \ + socket.io-emitter \ + @socket.io/redis-adapter \ + striptags \ + systeminformation \ + tinymce \ + uikit \ + uniqid \ + uuid \ + zxcvbn + +yarn add -D \ + browser-sync \ + gulp \ + gulp-concat \ + gulp-jshint \ + gulp-less \ + gulp-nodemon \ + gulp-plumber \ + gulp-rename \ + gulp-uglify-es \ + terser-webpack-plugin \ + webpack \ + webpack-stream \ + workbox-webpack-plugin \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index b4d1fcd..5306c8a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,17 +2,882 @@ # yarn lockfile v1 +"@apideck/better-ajv-errors@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.1.tgz#a8d4ef3ce67c418b8b24f2b76b6bc84eb547baf7" + integrity sha512-6RMV31esAxqlDIvVCG/CJxY/s8dFNVOI5w8RWIfDMhjg/iwqnawko9tJXau/leqC4+T1Bu8et99QVWCwU5wk+g== + dependencies: + json-schema "^0.4.0" + jsonpointer "^5.0.0" + leven "^3.1.0" + +"@babel/code-frame@^7.10.4", "@babel/code-frame@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" + integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA== + dependencies: + "@babel/highlight" "^7.16.0" + +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.0", "@babel/compat-data@^7.16.4": + version "7.16.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" + integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== + +"@babel/core@^7.11.1": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.0.tgz#c4ff44046f5fe310525cc9eb4ef5147f0c5374d4" + integrity sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ== + dependencies: + "@babel/code-frame" "^7.16.0" + "@babel/generator" "^7.16.0" + "@babel/helper-compilation-targets" "^7.16.0" + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helpers" "^7.16.0" + "@babel/parser" "^7.16.0" + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.1.2" + semver "^6.3.0" + source-map "^0.5.0" + +"@babel/generator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2" + integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew== + dependencies: + "@babel/types" "^7.16.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz#9a1f0ebcda53d9a2d00108c4ceace6a5d5f1f08d" + integrity sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.0.tgz#f1a686b92da794020c26582eb852e9accd0d7882" + integrity sha512-9KuleLT0e77wFUku6TUkqZzCEymBdtuQQ27MhEKzf9UOOJu3cYj98kyaDAzxpC7lV6DGiZFuC8XqDsq8/Kl6aQ== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.0", "@babel/helper-compilation-targets@^7.16.3": + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.3.tgz#5b480cd13f68363df6ec4dc8ac8e2da11363cbf0" + integrity sha512-vKsoSQAyBmxS35JUOOt+07cLc6Nk/2ljLIHwmq2/NM6hdioUaqEXq/S+nXvbvXbZkNDlWOymPanJGOc4CBjSJA== + dependencies: + "@babel/compat-data" "^7.16.0" + "@babel/helper-validator-option" "^7.14.5" + browserslist "^4.17.5" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.0.tgz#090d4d166b342a03a9fec37ef4fd5aeb9c7c6a4b" + integrity sha512-XLwWvqEaq19zFlF5PTgOod4bUA+XbkR4WLQBct1bkzmxJGB0ZEJaoKF4c8cgH9oBtCDuYJ8BP5NB9uFiEgO5QA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-function-name" "^7.16.0" + "@babel/helper-member-expression-to-functions" "^7.16.0" + "@babel/helper-optimise-call-expression" "^7.16.0" + "@babel/helper-replace-supers" "^7.16.0" + "@babel/helper-split-export-declaration" "^7.16.0" + +"@babel/helper-create-regexp-features-plugin@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz#06b2348ce37fccc4f5e18dcd8d75053f2a7c44ff" + integrity sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + regexpu-core "^4.7.1" + +"@babel/helper-define-polyfill-provider@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.0.tgz#c5b10cf4b324ff840140bb07e05b8564af2ae971" + integrity sha512-7hfT8lUljl/tM3h+izTX/pO3W3frz2ok6Pk+gzys8iJqDfZrZy2pXjRTZAvG2YmfHun1X4q8/UZRLatMfqc5Tg== + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-explode-assignable-expression@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.0.tgz#753017337a15f46f9c09f674cff10cee9b9d7778" + integrity sha512-Hk2SLxC9ZbcOhLpg/yMznzJ11W++lg5GMbxt1ev6TXUiJB0N42KPC+7w8a+eWGuqDnUYuwStJoZHM7RgmIOaGQ== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-function-name@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481" + integrity sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog== + dependencies: + "@babel/helper-get-function-arity" "^7.16.0" + "@babel/template" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helper-get-function-arity@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa" + integrity sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-hoist-variables@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a" + integrity sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-member-expression-to-functions@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz#29287040efd197c77636ef75188e81da8bccd5a4" + integrity sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3" + integrity sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-module-transforms@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.0.tgz#1c82a8dd4cb34577502ebd2909699b194c3e9bb5" + integrity sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA== + dependencies: + "@babel/helper-module-imports" "^7.16.0" + "@babel/helper-replace-supers" "^7.16.0" + "@babel/helper-simple-access" "^7.16.0" + "@babel/helper-split-export-declaration" "^7.16.0" + "@babel/helper-validator-identifier" "^7.15.7" + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helper-optimise-call-expression@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338" + integrity sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" + integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== + +"@babel/helper-remap-async-to-generator@^7.16.0", "@babel/helper-remap-async-to-generator@^7.16.4": + version "7.16.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.4.tgz#5d7902f61349ff6b963e07f06a389ce139fbfe6e" + integrity sha512-vGERmmhR+s7eH5Y/cp8PCVzj4XEjerq8jooMfxFdA5xVtAk9Sh4AQsrWgiErUEBjtGrBtOFKDUcWQFW4/dFwMA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-wrap-function" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helper-replace-supers@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz#73055e8d3cf9bcba8ddb55cad93fedc860f68f17" + integrity sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.16.0" + "@babel/helper-optimise-call-expression" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helper-simple-access@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz#21d6a27620e383e37534cf6c10bba019a6f90517" + integrity sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" + integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-split-export-declaration@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438" + integrity sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw== + dependencies: + "@babel/types" "^7.16.0" + "@babel/helper-validator-identifier@^7.15.7": version "7.15.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== -"@babel/parser@^7.6.0", "@babel/parser@^7.9.6": +"@babel/helper-validator-option@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" + integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== + +"@babel/helper-wrap-function@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.0.tgz#b3cf318afce774dfe75b86767cd6d68f3482e57c" + integrity sha512-VVMGzYY3vkWgCJML+qVLvGIam902mJW0FvT7Avj1zEe0Gn7D93aWdLblYARTxEw+6DhZmtzhBM2zv0ekE5zg1g== + dependencies: + "@babel/helper-function-name" "^7.16.0" + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/helpers@^7.16.0": + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.3.tgz#27fc64f40b996e7074dc73128c3e5c3e7f55c43c" + integrity sha512-Xn8IhDlBPhvYTvgewPKawhADichOsbkZuzN7qz2BusOM0brChsyXMDJvldWaYMMUNiCQdQzNEioXTp3sC8Nt8w== + dependencies: + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.3" + "@babel/types" "^7.16.0" + +"@babel/highlight@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a" + integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g== + dependencies: + "@babel/helper-validator-identifier" "^7.15.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.16.0", "@babel/parser@^7.16.3", "@babel/parser@^7.6.0", "@babel/parser@^7.9.6": version "7.16.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.4.tgz#d5f92f57cf2c74ffe9b37981c0e72fee7311372e" integrity sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng== -"@babel/types@^7.6.1", "@babel/types@^7.9.6": +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.2": + version "7.16.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz#2977fca9b212db153c195674e57cfab807733183" + integrity sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.0.tgz#358972eaab006f5eb0826183b0c93cbcaf13e1e2" + integrity sha512-4tcFwwicpWTrpl9qjf7UsoosaArgImF85AxqCRZlgc3IQDvkUHjJpruXAL58Wmj+T6fypWTC/BakfEkwIL/pwA== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.0" + +"@babel/plugin-proposal-async-generator-functions@^7.16.4": + version "7.16.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.4.tgz#e606eb6015fec6fa5978c940f315eae4e300b081" + integrity sha512-/CUekqaAaZCQHleSK/9HajvcD/zdnJiKRiuUFq8ITE+0HsPzquf53cpFiqAwl/UfmJbR6n5uGPQSPdrmKOvHHg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-remap-async-to-generator" "^7.16.4" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-class-properties@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.0.tgz#c029618267ddebc7280fa286e0f8ca2a278a2d1a" + integrity sha512-mCF3HcuZSY9Fcx56Lbn+CGdT44ioBMMvjNVldpKtj8tpniETdLjnxdHI1+sDWXIM1nNt+EanJOZ3IG9lzVjs7A== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-proposal-class-static-block@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.0.tgz#5296942c564d8144c83eea347d0aa8a0b89170e7" + integrity sha512-mAy3sdcY9sKAkf3lQbDiv3olOfiLqI51c9DR9b19uMoR2Z6r5pmGl7dfNFqEvqOyqbf1ta4lknK4gc5PJn3mfA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-proposal-dynamic-import@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.0.tgz#783eca61d50526202f9b296095453977e88659f1" + integrity sha512-QGSA6ExWk95jFQgwz5GQ2Dr95cf7eI7TKutIXXTb7B1gCLTCz5hTjFTQGfLFBBiC5WSNi7udNwWsqbbMh1c4yQ== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-namespace-from@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.0.tgz#9c01dee40b9d6b847b656aaf4a3976a71740f222" + integrity sha512-CjI4nxM/D+5wCnhD11MHB1AwRSAYeDT+h8gCdcVJZ/OK7+wRzFsf7PFPWVpVpNRkHMmMkQWAHpTq+15IXQ1diA== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.0.tgz#cae35a95ed1d2a7fa29c4dc41540b84a72e9ab25" + integrity sha512-kouIPuiv8mSi5JkEhzApg5Gn6hFyKPnlkO0a9YSzqRurH8wYzSlf6RJdzluAsbqecdW5pBvDJDfyDIUR/vLxvg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.0.tgz#a711b8ceb3ffddd3ef88d3a49e86dbd3cc7db3fd" + integrity sha512-pbW0fE30sVTYXXm9lpVQQ/Vc+iTeQKiXlaNRZPPN2A2VdlWyAtsUrsQ3xydSlDW00TFMK7a8m3cDTkBF5WnV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.0.tgz#44e1cce08fe2427482cf446a91bb451528ed0596" + integrity sha512-3bnHA8CAFm7cG93v8loghDYyQ8r97Qydf63BeYiGgYbjKKB/XP53W15wfRC7dvKfoiJ34f6Rbyyx2btExc8XsQ== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.0.tgz#5d418e4fbbf8b9b7d03125d3a52730433a373734" + integrity sha512-FAhE2I6mjispy+vwwd6xWPyEx3NYFS13pikDBWUAFGZvq6POGs5eNchw8+1CYoEgBl9n11I3NkzD7ghn25PQ9Q== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.0.tgz#5fb32f6d924d6e6712810362a60e12a2609872e6" + integrity sha512-LU/+jp89efe5HuWJLmMmFG0+xbz+I2rSI7iLc1AlaeSMDMOGzWlc5yJrMN1d04osXN4sSfpo4O+azkBNBes0jg== + dependencies: + "@babel/compat-data" "^7.16.0" + "@babel/helper-compilation-targets" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.16.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.0.tgz#5910085811ab4c28b00d6ebffa4ab0274d1e5f16" + integrity sha512-kicDo0A/5J0nrsCPbn89mTG3Bm4XgYi0CZtvex9Oyw7gGZE3HXGD0zpQNH+mo+tEfbo8wbmMvJftOwpmPy7aVw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.0.tgz#56dbc3970825683608e9efb55ea82c2a2d6c8dc0" + integrity sha512-Y4rFpkZODfHrVo70Uaj6cC1JJOt3Pp0MdWSwIKtb8z1/lsjl9AmnB7ErRFV+QNGIfcY1Eruc2UMx5KaRnXjMyg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-private-methods@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.0.tgz#b4dafb9c717e4301c5776b30d080d6383c89aff6" + integrity sha512-IvHmcTHDFztQGnn6aWq4t12QaBXTKr1whF/dgp9kz84X6GUcwq9utj7z2wFCUfeOup/QKnOlt2k0zxkGFx9ubg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-proposal-private-property-in-object@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.0.tgz#69e935b2c5c79d2488112d886f0c4e2790fee76f" + integrity sha512-3jQUr/HBbMVZmi72LpjQwlZ55i1queL8KcDTQEkAHihttJnAPrcvG9ZNXIfsd2ugpizZo595egYV6xy+pv4Ofw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-create-class-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-proposal-unicode-property-regex@^7.16.0", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.0.tgz#890482dfc5ea378e42e19a71e709728cabf18612" + integrity sha512-ti7IdM54NXv29cA4+bNNKEMS4jLMCbJgl+Drv+FgYy0erJLAxNAIXcNjNjrRZEcWq0xJHsNVwQezskMFpF8N9g== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-arrow-functions@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.0.tgz#951706f8b449c834ed07bd474c0924c944b95a8e" + integrity sha512-vIFb5250Rbh7roWARvCLvIJ/PtAU5Lhv7BtZ1u24COwpI9Ypjsh+bZcKk6rlIyalK+r0jOc1XQ8I4ovNxNrWrA== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-async-to-generator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.0.tgz#df12637f9630ddfa0ef9d7a11bc414d629d38604" + integrity sha512-PbIr7G9kR8tdH6g8Wouir5uVjklETk91GMVSUq+VaOgiinbCkBP6Q7NN/suM/QutZkMJMvcyAriogcYAdhg8Gw== + dependencies: + "@babel/helper-module-imports" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-remap-async-to-generator" "^7.16.0" + +"@babel/plugin-transform-block-scoped-functions@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.0.tgz#c618763233ad02847805abcac4c345ce9de7145d" + integrity sha512-V14As3haUOP4ZWrLJ3VVx5rCnrYhMSHN/jX7z6FAt5hjRkLsb0snPCmJwSOML5oxkKO4FNoNv7V5hw/y2bjuvg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-block-scoping@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.0.tgz#bcf433fb482fe8c3d3b4e8a66b1c4a8e77d37c16" + integrity sha512-27n3l67/R3UrXfizlvHGuTwsRIFyce3D/6a37GRxn28iyTPvNXaW4XvznexRh1zUNLPjbLL22Id0XQElV94ruw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-classes@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.0.tgz#54cf5ff0b2242c6573d753cd4bfc7077a8b282f5" + integrity sha512-HUxMvy6GtAdd+GKBNYDWCIA776byUQH8zjnfjxwT1P1ARv/wFu8eBDpmXQcLS/IwRtrxIReGiplOwMeyO7nsDQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.0" + "@babel/helper-function-name" "^7.16.0" + "@babel/helper-optimise-call-expression" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-replace-supers" "^7.16.0" + "@babel/helper-split-export-declaration" "^7.16.0" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.0.tgz#e0c385507d21e1b0b076d66bed6d5231b85110b7" + integrity sha512-63l1dRXday6S8V3WFY5mXJwcRAnPYxvFfTlt67bwV1rTyVTM5zrp0DBBb13Kl7+ehkCVwIZPumPpFP/4u70+Tw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-destructuring@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.0.tgz#ad3d7e74584ad5ea4eadb1e6642146c590dee33c" + integrity sha512-Q7tBUwjxLTsHEoqktemHBMtb3NYwyJPTJdM+wDwb0g8PZ3kQUIzNvwD5lPaqW/p54TXBc/MXZu9Jr7tbUEUM8Q== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-dotall-regex@^7.16.0", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.0.tgz#50bab00c1084b6162d0a58a818031cf57798e06f" + integrity sha512-FXlDZfQeLILfJlC6I1qyEwcHK5UpRCFkaoVyA1nk9A1L1Yu583YO4un2KsLBsu3IJb4CUbctZks8tD9xPQubLw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-duplicate-keys@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.0.tgz#8bc2e21813e3e89e5e5bf3b60aa5fc458575a176" + integrity sha512-LIe2kcHKAZOJDNxujvmp6z3mfN6V9lJxubU4fJIGoQCkKe3Ec2OcbdlYP+vW++4MpxwG0d1wSDOJtQW5kLnkZQ== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-exponentiation-operator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.0.tgz#a180cd2881e3533cef9d3901e48dad0fbeff4be4" + integrity sha512-OwYEvzFI38hXklsrbNivzpO3fh87skzx8Pnqi4LoSYeav0xHlueSoCJrSgTPfnbyzopo5b3YVAJkFIcUpK2wsw== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-for-of@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.0.tgz#f7abaced155260e2461359bbc7c7248aca5e6bd2" + integrity sha512-5QKUw2kO+GVmKr2wMYSATCTTnHyscl6sxFRAY+rvN7h7WB0lcG0o4NoV6ZQU32OZGVsYUsfLGgPQpDFdkfjlJQ== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-function-name@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.0.tgz#02e3699c284c6262236599f751065c5d5f1f400e" + integrity sha512-lBzMle9jcOXtSOXUpc7tvvTpENu/NuekNJVova5lCCWCV9/U1ho2HH2y0p6mBg8fPm/syEAbfaaemYGOHCY3mg== + dependencies: + "@babel/helper-function-name" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.0.tgz#79711e670ffceb31bd298229d50f3621f7980cac" + integrity sha512-gQDlsSF1iv9RU04clgXqRjrPyyoJMTclFt3K1cjLmTKikc0s/6vE3hlDeEVC71wLTRu72Fq7650kABrdTc2wMQ== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-member-expression-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.0.tgz#5251b4cce01eaf8314403d21aedb269d79f5e64b" + integrity sha512-WRpw5HL4Jhnxw8QARzRvwojp9MIE7Tdk3ez6vRyUk1MwgjJN0aNpRoXainLR5SgxmoXx/vsXGZ6OthP6t/RbUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-modules-amd@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.0.tgz#09abd41e18dcf4fd479c598c1cef7bd39eb1337e" + integrity sha512-rWFhWbCJ9Wdmzln1NmSCqn7P0RAD+ogXG/bd9Kg5c7PKWkJtkiXmYsMBeXjDlzHpVTJ4I/hnjs45zX4dEv81xw== + dependencies: + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.0.tgz#add58e638c8ddc4875bd9a9ecb5c594613f6c922" + integrity sha512-Dzi+NWqyEotgzk/sb7kgQPJQf7AJkQBWsVp1N6JWc1lBVo0vkElUnGdr1PzUBmfsCCN5OOFya3RtpeHk15oLKQ== + dependencies: + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-simple-access" "^7.16.0" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.0.tgz#a92cf240afeb605f4ca16670453024425e421ea4" + integrity sha512-yuGBaHS3lF1m/5R+6fjIke64ii5luRUg97N2wr+z1sF0V+sNSXPxXDdEEL/iYLszsN5VKxVB1IPfEqhzVpiqvg== + dependencies: + "@babel/helper-hoist-variables" "^7.16.0" + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-identifier" "^7.15.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.0.tgz#195f26c2ad6d6a391b70880effce18ce625e06a7" + integrity sha512-nx4f6no57himWiHhxDM5pjwhae5vLpTK2zCnDH8+wNLJy0TVER/LJRHl2bkt6w9Aad2sPD5iNNoUpY3X9sTGDg== + dependencies: + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.0.tgz#d3db61cc5d5b97986559967cd5ea83e5c32096ca" + integrity sha512-LogN88uO+7EhxWc8WZuQ8vxdSyVGxhkh8WTC3tzlT8LccMuQdA81e9SGV6zY7kY2LjDhhDOFdQVxdGwPyBCnvg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.0" + +"@babel/plugin-transform-new-target@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.0.tgz#af823ab576f752215a49937779a41ca65825ab35" + integrity sha512-fhjrDEYv2DBsGN/P6rlqakwRwIp7rBGLPbrKxwh7oVt5NNkIhZVOY2GRV+ULLsQri1bDqwDWnU3vhlmx5B2aCw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-object-super@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.0.tgz#fb20d5806dc6491a06296ac14ea8e8d6fedda72b" + integrity sha512-fds+puedQHn4cPLshoHcR1DTMN0q1V9ou0mUjm8whx9pGcNvDrVVrgw+KJzzCaiTdaYhldtrUps8DWVMgrSEyg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-replace-supers" "^7.16.0" + +"@babel/plugin-transform-parameters@^7.16.0", "@babel/plugin-transform-parameters@^7.16.3": + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.3.tgz#fa9e4c874ee5223f891ee6fa8d737f4766d31d15" + integrity sha512-3MaDpJrOXT1MZ/WCmkOFo7EtmVVC8H4EUZVrHvFOsmwkk4lOjQj8rzv8JKUZV4YoQKeoIgk07GO+acPU9IMu/w== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.0.tgz#a95c552189a96a00059f6776dc4e00e3690c78d1" + integrity sha512-XLldD4V8+pOqX2hwfWhgwXzGdnDOThxaNTgqagOcpBgIxbUvpgU2FMvo5E1RyHbk756WYgdbS0T8y0Cj9FKkWQ== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-regenerator@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.0.tgz#eaee422c84b0232d03aea7db99c97deeaf6125a4" + integrity sha512-JAvGxgKuwS2PihiSFaDrp94XOzzTUeDeOQlcKzVAyaPap7BnZXK/lvMDiubkPTdotPKOIZq9xWXWnggUMYiExg== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.0.tgz#fff4b9dcb19e12619394bda172d14f2d04c0379c" + integrity sha512-Dgs8NNCehHSvXdhEhln8u/TtJxfVwGYCgP2OOr5Z3Ar+B+zXicEOKNTyc+eca2cuEOMtjW6m9P9ijOt8QdqWkg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-shorthand-properties@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.0.tgz#090372e3141f7cc324ed70b3daf5379df2fa384d" + integrity sha512-iVb1mTcD8fuhSv3k99+5tlXu5N0v8/DPm2mO3WACLG6al1CGZH7v09HJyUb1TtYl/Z+KrM6pHSIJdZxP5A+xow== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-spread@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.0.tgz#d21ca099bbd53ab307a8621e019a7bd0f40cdcfb" + integrity sha512-Ao4MSYRaLAQczZVp9/7E7QHsCuK92yHRrmVNRe/SlEJjhzivq0BSn8mEraimL8wizHZ3fuaHxKH0iwzI13GyGg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + +"@babel/plugin-transform-sticky-regex@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.0.tgz#c35ea31a02d86be485f6aa510184b677a91738fd" + integrity sha512-/ntT2NljR9foobKk4E/YyOSwcGUXtYWv5tinMK/3RkypyNBNdhHUaq6Orw5DWq9ZcNlS03BIlEALFeQgeVAo4Q== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-template-literals@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.0.tgz#a8eced3a8e7b8e2d40ec4ec4548a45912630d302" + integrity sha512-Rd4Ic89hA/f7xUSJQk5PnC+4so50vBoBfxjdQAdvngwidM8jYIBVxBZ/sARxD4e0yMXRbJVDrYf7dyRtIIKT6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-typeof-symbol@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.0.tgz#8b19a244c6f8c9d668dca6a6f754ad6ead1128f2" + integrity sha512-++V2L8Bdf4vcaHi2raILnptTBjGEFxn5315YU+e8+EqXIucA+q349qWngCLpUYqqv233suJ6NOienIVUpS9cqg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-unicode-escapes@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.0.tgz#1a354064b4c45663a32334f46fa0cf6100b5b1f3" + integrity sha512-VFi4dhgJM7Bpk8lRc5CMaRGlKZ29W9C3geZjt9beuzSUrlJxsNwX7ReLwaL6WEvsOf2EQkyIJEPtF8EXjB/g2A== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-unicode-regex@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.0.tgz#293b80950177c8c85aede87cef280259fb995402" + integrity sha512-jHLK4LxhHjvCeZDWyA9c+P9XH1sOxRd1RO9xMtDVRAOND/PczPqizEtVdx4TQF/wyPaewqpT+tgQFYMnN/P94A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.0" + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/preset-env@^7.11.0": + version "7.16.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.4.tgz#4f6ec33b2a3fe72d6bfdcdf3859500232563a2e3" + integrity sha512-v0QtNd81v/xKj4gNKeuAerQ/azeNn/G1B1qMLeXOcV8+4TWlD2j3NV1u8q29SDFBXx/NBq5kyEAO+0mpRgacjA== + dependencies: + "@babel/compat-data" "^7.16.4" + "@babel/helper-compilation-targets" "^7.16.3" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.2" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.0" + "@babel/plugin-proposal-async-generator-functions" "^7.16.4" + "@babel/plugin-proposal-class-properties" "^7.16.0" + "@babel/plugin-proposal-class-static-block" "^7.16.0" + "@babel/plugin-proposal-dynamic-import" "^7.16.0" + "@babel/plugin-proposal-export-namespace-from" "^7.16.0" + "@babel/plugin-proposal-json-strings" "^7.16.0" + "@babel/plugin-proposal-logical-assignment-operators" "^7.16.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.0" + "@babel/plugin-proposal-numeric-separator" "^7.16.0" + "@babel/plugin-proposal-object-rest-spread" "^7.16.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.0" + "@babel/plugin-proposal-private-methods" "^7.16.0" + "@babel/plugin-proposal-private-property-in-object" "^7.16.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.16.0" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.16.0" + "@babel/plugin-transform-async-to-generator" "^7.16.0" + "@babel/plugin-transform-block-scoped-functions" "^7.16.0" + "@babel/plugin-transform-block-scoping" "^7.16.0" + "@babel/plugin-transform-classes" "^7.16.0" + "@babel/plugin-transform-computed-properties" "^7.16.0" + "@babel/plugin-transform-destructuring" "^7.16.0" + "@babel/plugin-transform-dotall-regex" "^7.16.0" + "@babel/plugin-transform-duplicate-keys" "^7.16.0" + "@babel/plugin-transform-exponentiation-operator" "^7.16.0" + "@babel/plugin-transform-for-of" "^7.16.0" + "@babel/plugin-transform-function-name" "^7.16.0" + "@babel/plugin-transform-literals" "^7.16.0" + "@babel/plugin-transform-member-expression-literals" "^7.16.0" + "@babel/plugin-transform-modules-amd" "^7.16.0" + "@babel/plugin-transform-modules-commonjs" "^7.16.0" + "@babel/plugin-transform-modules-systemjs" "^7.16.0" + "@babel/plugin-transform-modules-umd" "^7.16.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.0" + "@babel/plugin-transform-new-target" "^7.16.0" + "@babel/plugin-transform-object-super" "^7.16.0" + "@babel/plugin-transform-parameters" "^7.16.3" + "@babel/plugin-transform-property-literals" "^7.16.0" + "@babel/plugin-transform-regenerator" "^7.16.0" + "@babel/plugin-transform-reserved-words" "^7.16.0" + "@babel/plugin-transform-shorthand-properties" "^7.16.0" + "@babel/plugin-transform-spread" "^7.16.0" + "@babel/plugin-transform-sticky-regex" "^7.16.0" + "@babel/plugin-transform-template-literals" "^7.16.0" + "@babel/plugin-transform-typeof-symbol" "^7.16.0" + "@babel/plugin-transform-unicode-escapes" "^7.16.0" + "@babel/plugin-transform-unicode-regex" "^7.16.0" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.16.0" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.4.0" + babel-plugin-polyfill-regenerator "^0.3.0" + core-js-compat "^3.19.1" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime@^7.11.2", "@babel/runtime@^7.8.4": + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" + integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6" + integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A== + dependencies: + "@babel/code-frame" "^7.16.0" + "@babel/parser" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.3": + version "7.16.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.3.tgz#f63e8a938cc1b780f66d9ed3c54f532ca2d14787" + integrity sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag== + dependencies: + "@babel/code-frame" "^7.16.0" + "@babel/generator" "^7.16.0" + "@babel/helper-function-name" "^7.16.0" + "@babel/helper-hoist-variables" "^7.16.0" + "@babel/helper-split-export-declaration" "^7.16.0" + "@babel/parser" "^7.16.3" + "@babel/types" "^7.16.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.16.0", "@babel/types@^7.4.4", "@babel/types@^7.6.1", "@babel/types@^7.9.6": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba" integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg== @@ -20,11 +885,186 @@ "@babel/helper-validator-identifier" "^7.15.7" to-fast-properties "^2.0.0" -"@types/node@*": +"@fortawesome/fontawesome-free@^5.15.4": + version "5.15.4" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" + integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== + +"@otplib/core@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@otplib/core/-/core-12.0.1.tgz#73720a8cedce211fe5b3f683cd5a9c098eaf0f8d" + integrity sha512-4sGntwbA/AC+SbPhbsziRiD+jNDdIzsZ3JUyfZwjtKyc/wufl1pnSIaG4Uqx8ymPagujub0o92kgBnB89cuAMA== + +"@otplib/plugin-crypto@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@otplib/plugin-crypto/-/plugin-crypto-12.0.1.tgz#2b42c624227f4f9303c1c041fca399eddcbae25e" + integrity sha512-qPuhN3QrT7ZZLcLCyKOSNhuijUi9G5guMRVrxq63r9YNOxxQjPm59gVxLM+7xGnHnM6cimY57tuKsjK7y9LM1g== + dependencies: + "@otplib/core" "^12.0.1" + +"@otplib/plugin-thirty-two@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@otplib/plugin-thirty-two/-/plugin-thirty-two-12.0.1.tgz#5cc9b56e6e89f2a1fe4a2b38900ca4e11c87aa9e" + integrity sha512-MtT+uqRso909UkbrrYpJ6XFjj9D+x2Py7KjTO9JDPhL0bJUYVu5kFP4TFZW4NFAywrAtFRxOVY261u0qwb93gA== + dependencies: + "@otplib/core" "^12.0.1" + thirty-two "^1.0.2" + +"@otplib/preset-default@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@otplib/preset-default/-/preset-default-12.0.1.tgz#cb596553c08251e71b187ada4a2246ad2a3165ba" + integrity sha512-xf1v9oOJRyXfluBhMdpOkr+bsE+Irt+0D5uHtvg6x1eosfmHCsCC6ej/m7FXiWqdo0+ZUI6xSKDhJwc8yfiOPQ== + dependencies: + "@otplib/core" "^12.0.1" + "@otplib/plugin-crypto" "^12.0.1" + "@otplib/plugin-thirty-two" "^12.0.1" + +"@otplib/preset-v11@^12.0.1": + version "12.0.1" + resolved "https://registry.yarnpkg.com/@otplib/preset-v11/-/preset-v11-12.0.1.tgz#4c7266712e7230500b421ba89252963c838fc96d" + integrity sha512-9hSetMI7ECqbFiKICrNa4w70deTUfArtwXykPUvSHWOdzOlfa9ajglu7mNCntlvxycTiOAXkQGwjQCzzDEMRMg== + dependencies: + "@otplib/core" "^12.0.1" + "@otplib/plugin-crypto" "^12.0.1" + "@otplib/plugin-thirty-two" "^12.0.1" + +"@rollup/plugin-babel@^5.2.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.0.tgz#9cb1c5146ddd6a4968ad96f209c50c62f92f9879" + integrity sha512-9uIC8HZOnVLrLHxayq/PTzw+uS25E14KPUBh5ktF+18Mjo5yK0ToMMx6epY0uEgkjwJw0aBW4x2horYXh8juWw== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@rollup/pluginutils" "^3.1.0" + +"@rollup/plugin-node-resolve@^11.2.1": + version "11.2.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60" + integrity sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + "@types/resolve" "1.17.1" + builtin-modules "^3.1.0" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.19.0" + +"@rollup/plugin-replace@^2.4.1": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz#a2d539314fbc77c244858faa523012825068510a" + integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg== + dependencies: + "@rollup/pluginutils" "^3.1.0" + magic-string "^0.25.7" + +"@rollup/pluginutils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" + integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== + dependencies: + "@types/estree" "0.0.39" + estree-walker "^1.0.1" + picomatch "^2.2.2" + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@socket.io/redis-adapter@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@socket.io/redis-adapter/-/redis-adapter-7.1.0.tgz#66f854da3cc47b80a9f5d287e93a58af16e5c3fb" + integrity sha512-vbsNJKUQgtVHcOqNL2ac8kSemTVNKHRzYPldqQJt0eFKvlAtAviuAMzBP0WmOp5OoRLQMjhVsVvgMzzMsVsK5g== + dependencies: + debug "~4.3.1" + notepack.io "~2.2.0" + socket.io-adapter "~2.3.0" + uid2 "0.0.3" + +"@surma/rollup-plugin-off-main-thread@^2.2.3": + version "2.2.3" + resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz#ee34985952ca21558ab0d952f00298ad2190c053" + integrity sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ== + dependencies: + ejs "^3.1.6" + json5 "^2.2.0" + magic-string "^0.25.0" + string.prototype.matchall "^4.0.6" + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + +"@types/component-emitter@^1.2.10": + version "1.2.11" + resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" + integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ== + +"@types/cookie@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" + integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== + +"@types/cors@^2.8.12": + version "2.8.12" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.12.tgz#6b2c510a7ad7039e98e7b8d3d6598f4359e5c080" + integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw== + +"@types/eslint-scope@^3.7.0": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e" + integrity sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.2.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.1.tgz#13f3d69bac93c2ae008019c28783868d0a1d6605" + integrity sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^0.0.50": + version "0.0.50" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" + integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== + +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/json-schema@*", "@types/json-schema@^7.0.8": + version "7.0.9" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== + +"@types/node@*", "@types/node@>=10.0.0": version "16.11.11" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.11.tgz#6ea7342dfb379ea1210835bada87b3c512120234" integrity sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw== +"@types/resolve@1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" + integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== + dependencies: + "@types/node" "*" + +"@types/trusted-types@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" + integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== + "@types/webidl-conversions@*": version "6.1.1" resolved "https://registry.yarnpkg.com/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz#e33bc8ea812a01f63f90481c666334844b12a09e" @@ -38,7 +1078,153 @@ "@types/node" "*" "@types/webidl-conversions" "*" -accepts@~1.3.7: +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +"@zxing/text-encoding@0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@zxing/text-encoding/-/text-encoding-0.9.0.tgz#fb50ffabc6c7c66a0c96b4c03e3d9be74864b70b" + integrity sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA== + +abab@^2.0.3, abab@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" + integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== @@ -46,25 +1232,434 @@ accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn-walk@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= +acorn@^8.4.1, acorn@^8.5.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" + integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== + +after@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" + integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= + +agent-base@4, agent-base@^4.2.0, agent-base@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== + dependencies: + es6-promisify "^5.0.0" + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agent-base@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.6.0: + version "8.8.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb" + integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +anchorme@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/anchorme/-/anchorme-2.1.2.tgz#4abc7e128a8a42d0036a61ebb9b18bbc032fa52a" + integrity sha512-2iPY3kxDDZvtRzauqKDb4v7a5sTF4GZ+esQTY8nGYvmhAtGTeFPMn4cRnvyWS1qmtPTP0Mv8hyLOp9l3ZzWMKg== + +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + +ansi-colors@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" + integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== + dependencies: + ansi-wrap "^0.1.0" + +ansi-cyan@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" + integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= + dependencies: + ansi-wrap "0.1.0" + +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= + dependencies: + ansi-wrap "0.1.0" + +ansi-red@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" + integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= + dependencies: + ansi-wrap "0.1.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-wrap@0.1.0, ansi-wrap@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +append-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" + integrity sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE= + dependencies: + buffer-equal "^1.0.0" + +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" + integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY= + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + +are-we-there-yet@~1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" + integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/argv/-/argv-0.0.2.tgz#ecbd16f8949b157183711b1bda334f37840185ab" + integrity sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas= + +arr-diff@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" + integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo= + dependencies: + arr-flatten "^1.0.1" + array-slice "^0.2.3" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-filter@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/arr-filter/-/arr-filter-1.1.2.tgz#43fdddd091e8ef11aa4c45d9cdc18e2dff1711ee" + integrity sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4= + dependencies: + make-iterator "^1.0.0" + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-map@^2.0.0, arr-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/arr-map/-/arr-map-2.0.2.tgz#3a77345ffc1cf35e2a91825601f9e58f2e24cac4" + integrity sha1-Onc0X/wc814qkYJWAfnljy4kysQ= + dependencies: + make-iterator "^1.0.0" + +arr-union@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" + integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0= + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-each@^1.0.0, array-each@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" + integrity sha1-p5SvDAWrF1KEbudTofIRoFugxE8= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-initial@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-initial/-/array-initial-1.1.0.tgz#2fa74b26739371c3947bd7a7adc73be334b3d795" + integrity sha1-L6dLJnOTccOUe9enrcc74zSz15U= + dependencies: + array-slice "^1.0.0" + is-number "^4.0.0" + +array-last@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/array-last/-/array-last-1.3.0.tgz#7aa77073fec565ddab2493f5f88185f404a9d336" + integrity sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg== + dependencies: + is-number "^4.0.0" + +array-slice@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" + integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= + +array-slice@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-1.1.0.tgz#e368ea15f89bc7069f7ffb89aec3a6c7d4ac22d4" + integrity sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w== + +array-sort@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a" + integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg== + dependencies: + default-compare "^1.0.0" + get-value "^2.0.6" + kind-of "^5.0.2" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arraybuffer.slice@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" + integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog== + +asap@^2.0.6, asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +assert-never@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe" + integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw== + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +ast-types@0.x.x: + version "0.14.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" + integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== + dependencies: + tslib "^2.0.1" + +async-done@^1.2.0, async-done@^1.2.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/async-done/-/async-done-1.3.2.tgz#5e15aa729962a4b07414f528a88cdf18e0b290a2" + integrity sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.2" + process-nextick-args "^2.0.0" + stream-exhaust "^1.0.1" + +async-each-series@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/async-each-series/-/async-each-series-0.1.1.tgz#7617c1917401fd8ca4a28aadce3dbae98afeb432" + integrity sha1-dhfBkXQB/Yykooqtzj266Yr+tDI= + +async-each@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +async-settle@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-settle/-/async-settle-1.0.0.tgz#1d0a914bb02575bec8a8f3a74e5080f72b2c0c6b" + integrity sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs= + dependencies: + async-done "^1.2.2" + +async@0.9.x: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= + +async@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +async@^2.1.1, async@^2.6.1: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + +async@^3.1.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.2.tgz#2eb7671034bb2194d45d30e31e24ec7e7f9670cd" + integrity sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +axios@0.21.4: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= +babel-plugin-polyfill-corejs2@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz#407082d0d355ba565af24126fb6cb8e9115251fd" + integrity sha512-wMDoBJ6uG4u4PNFh72Ty6t3EgfA91puCuAwKIazbQlci+ENb/UU9A3xG5lutjUIiXCIn1CY5L15r9LimiJyrSA== + dependencies: + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.3.0" + semver "^6.1.1" -assert-never@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe" - integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw== +babel-plugin-polyfill-corejs3@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.4.0.tgz#0b571f4cf3d67f911512f5c04842a7b8e8263087" + integrity sha512-YxFreYwUfglYKdLUGvIF2nJEsGwj+RhWSX/ije3D2vQPOXuyMLMtg/cCGMDpOA7Nd+MwlNdnGODbd2EwUZPlsw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.0" + core-js-compat "^3.18.0" + +babel-plugin-polyfill-regenerator@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz#9ebbcd7186e1a33e21c5e20cae4e7983949533be" + integrity sha512-dhAPTDLGoMW5/84wkgwiLRwMnio2i1fUe53EuvtKMv0pn2p3S8OCoV1xAzfJPl0KOX7IB89s2ib85vbYiea3jg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.0" babel-walk@3.0.0-canary-5: version "3.0.0-canary-5" @@ -73,16 +1668,114 @@ babel-walk@3.0.0-canary-5: dependencies: "@babel/types" "^7.9.6" +bach@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/bach/-/bach-1.2.0.tgz#4b3ce96bf27134f79a1b414a51c14e34c3bd9880" + integrity sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA= + dependencies: + arr-filter "^1.1.1" + arr-flatten "^1.0.1" + arr-map "^2.0.0" + array-each "^1.0.0" + array-initial "^1.0.0" + array-last "^1.1.1" + async-done "^1.2.2" + async-settle "^1.0.0" + now-and-later "^2.0.0" + +backo2@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-arraybuffer@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812" + integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI= + +base64-arraybuffer@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz#87bd13525626db4a9838e00a508c2b73efcf348c" + integrity sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA== + base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +base64id@2.0.0, base64id@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" + integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +basic-auth@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" + integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== + dependencies: + safe-buffer "5.1.2" + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= + +binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +blob@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" + integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== + +block-stream2@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/block-stream2/-/block-stream2-2.1.0.tgz#ac0c5ef4298b3857796e05be8ebed72196fa054b" + integrity sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg== + dependencies: + readable-stream "^3.4.0" + body-parser@1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" @@ -99,6 +1792,20 @@ body-parser@1.19.0: raw-body "2.4.0" type-is "~1.6.17" +boxen@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -107,6 +1814,113 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + +browser-sync-client@^2.27.7: + version "2.27.7" + resolved "https://registry.yarnpkg.com/browser-sync-client/-/browser-sync-client-2.27.7.tgz#e09dce1add876984cf8232de95d2332d29401a64" + integrity sha512-wKg9UP9a4sCIkBBAXUdbkdWFJzfSAQizGh+nC19W9y9zOo9s5jqeYRFUUbs7x5WKhjtspT+xetVp9AtBJ6BmWg== + dependencies: + etag "1.8.1" + fresh "0.5.2" + mitt "^1.1.3" + rxjs "^5.5.6" + +browser-sync-ui@^2.27.7: + version "2.27.7" + resolved "https://registry.yarnpkg.com/browser-sync-ui/-/browser-sync-ui-2.27.7.tgz#38cd65f7ba058544310591ad8ac2e7fdf29934f2" + integrity sha512-Bt4OQpx9p18OIzk0KKyu7jqlvmjacasUlk8ARY3uuIyiFWSBiRgr2i6XY8dEMF14DtbooaEBOpHEu9VCYvMcCw== + dependencies: + async-each-series "0.1.1" + connect-history-api-fallback "^1" + immutable "^3" + server-destroy "1.0.1" + socket.io-client "^2.4.0" + stream-throttle "^0.1.3" + +browser-sync@^2.27.7: + version "2.27.7" + resolved "https://registry.yarnpkg.com/browser-sync/-/browser-sync-2.27.7.tgz#65ec55d6c6e33283e505e06e5113bc32d9d0a8f0" + integrity sha512-9ElnnA/u+s2Jd+IgY+2SImB+sAEIteHsMG0NR96m7Ph/wztpvJCUpyC2on1KqmG9iAp941j+5jfmd34tEguGbg== + dependencies: + browser-sync-client "^2.27.7" + browser-sync-ui "^2.27.7" + bs-recipes "1.3.4" + bs-snippet-injector "^2.0.1" + chokidar "^3.5.1" + connect "3.6.6" + connect-history-api-fallback "^1" + dev-ip "^1.0.1" + easy-extender "^2.3.4" + eazy-logger "3.1.0" + etag "^1.8.1" + fresh "^0.5.2" + fs-extra "3.0.1" + http-proxy "^1.18.1" + immutable "^3" + localtunnel "^2.0.1" + micromatch "^4.0.2" + opn "5.3.0" + portscanner "2.1.1" + qs "6.2.3" + raw-body "^2.3.2" + resp-modifier "6.0.2" + rx "4.1.0" + send "0.16.2" + serve-index "1.9.1" + serve-static "1.13.2" + server-destroy "1.0.1" + socket.io "2.4.0" + ua-parser-js "1.0.2" + yargs "^15.4.1" + +browserslist@^4.14.5, browserslist@^4.17.5, browserslist@^4.18.1: + version "4.18.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.18.1.tgz#60d3920f25b6860eb917c6c7b185576f4d8b017f" + integrity sha512-8ScCzdpPwR2wQh8IT82CA2VgDwjHyqMovPBZSNH54+tm4Jk2pCuv90gmAdH6J84OCRWi0b4gMe6O6XPXuJnjgQ== + dependencies: + caniuse-lite "^1.0.30001280" + electron-to-chromium "^1.3.896" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +bs-recipes@1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/bs-recipes/-/bs-recipes-1.3.4.tgz#0d2d4d48a718c8c044769fdc4f89592dc8b69585" + integrity sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU= + +bs-snippet-injector@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz#61b5393f11f52559ed120693100343b6edb04dd5" + integrity sha1-YbU5PxH1JVntEgaTEANDtu2wTdU= + bson@^4.2.2, bson@^4.5.4: version "4.6.0" resolved "https://registry.yarnpkg.com/bson/-/bson-4.6.0.tgz#15c3b39ba3940c3d915a0c44d51459f4b4fbf1b2" @@ -114,7 +1928,22 @@ bson@^4.2.2, bson@^4.5.4: dependencies: buffer "^5.6.0" -buffer@^5.6.0: +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= + +buffer-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" + integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74= + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer@^5.5.0, buffer@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -122,12 +1951,77 @@ buffer@^5.6.0: base64-js "^1.3.1" ieee754 "^1.1.13" +builtin-modules@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" + integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== + +bull@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/bull/-/bull-4.1.1.tgz#57fa7f9caa9ed74cd3fddc2301559d35f616bcef" + integrity sha512-EDkS3+QZyzHjC2gPThAlEwklIJSt2520nT6drpGfs5UlmVZnkTuA1unawUNLWjfN2lnwOJmstZ0t3/Rg/cRe8Q== + dependencies: + cron-parser "^2.13.0" + debuglog "^1.0.0" + get-port "^5.1.1" + ioredis "^4.27.0" + lodash "^4.17.21" + p-timeout "^3.2.0" + semver "^7.3.2" + uuid "^8.3.0" + +busboy@^0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" + integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= + dependencies: + dicer "0.2.5" + readable-stream "1.1.x" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + bytes@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== -call-bind@^1.0.2: +bytes@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" + integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== @@ -135,6 +2029,54 @@ call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= + +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.1.tgz#250fd350cfd555d0d2160b1d51510eaf8326e86e" + integrity sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA== + +caniuse-lite@^1.0.30001280: + version "1.0.30001284" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001284.tgz#d3653929ded898cd0c1f09a56fd8ca6952df4fca" + integrity sha512-t28SKa7g6kiIQi6NHeOcKrOrGMzCRrXvlasPwWC26TH2QNdglgzQIRUuJ0cR3NeQPH+5jpuveeeSFDLm2zbkEw== + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0, chalk@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + character-parser@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0" @@ -142,6 +2084,75 @@ character-parser@^2.2.0: dependencies: is-regex "^1.0.3" +chart.js@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.6.2.tgz#47342c551f688ffdda2cd53b534cb7e461ecec33" + integrity sha512-Xz7f/fgtVltfQYWq0zL1Xbv7N2inpG+B54p3D5FSvpCdy3sM+oZhbqa42eNuYXltaVvajgX5UpKCU2GeeJIgxg== + +chokidar@^2.0.0: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + +chokidar@^3.5.1, chokidar@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + cli@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/cli/-/cli-1.0.1.tgz#22817534f24bfa4950c34d532d48ecbc621b8c14" @@ -150,11 +2161,257 @@ cli@~1.0.0: exit "0.1.2" glob "^7.1.1" +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +cluster-key-slot@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" + integrity sha512-2Nii8p3RwAPiFwsnZvukotvow2rIHM+yQ6ZcBXGHdniadkYGZYiGmkHJIbZPIV9nfv7m/U1IPMVVcAhoWFeklw== + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +collection-map@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-map/-/collection-map-1.0.0.tgz#aea0f06f8d26c780c2b75494385544b2255af18c" + integrity sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw= + dependencies: + arr-map "^2.0.2" + for-own "^1.0.0" + make-iterator "^1.0.0" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.0.tgz#63b6ebd1bec11999d1df3a79a7569451ac2be8aa" + integrity sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + +color@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/color/-/color-4.1.0.tgz#9502e6a2dcacb26adf4c60910a27628d010b3de3" + integrity sha512-o2rkkxyLGgYoeUy1OodXpbPAQNmlNBrirQ8ODO8QutzDiDMNdezSOZLNnusQ6pUpCQJUsaJIo9DZJKqa2HgH7A== + dependencies: + color-convert "^2.0.1" + color-string "^1.9.0" + +colors@^1.1.2, colors@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6, combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.2.0, commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +common-tags@^1.8.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== + +component-bind@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/component-bind/-/component-bind-1.0.0.tgz#00c608ab7dcd93897c0009651b1d3a8e1e73bbd1" + integrity sha1-AMYIq33Nk4l8AAllGx06jh5zu9E= + +component-emitter@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +component-emitter@^1.2.1, component-emitter@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +component-inherit@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/component-inherit/-/component-inherit-0.0.3.tgz#645fc4adf58b72b649d5cae65135619db26ff143" + integrity sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM= + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +concat-stream@^1.5.2, concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +concat-with-sourcemaps@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz#d4ea93f05ae25790951b99e7b3b09e3908a4082e" + integrity sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg== + dependencies: + source-map "^0.6.1" + +configstore@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" + integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== + dependencies: + dot-prop "^5.2.0" + graceful-fs "^4.1.2" + make-dir "^3.0.0" + unique-string "^2.0.0" + write-file-atomic "^3.0.0" + xdg-basedir "^4.0.0" + +connect-history-api-fallback@^1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" + integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== + +connect-redis@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/connect-redis/-/connect-redis-6.0.0.tgz#7e443fc7028eca43302bee59f51a315f65cd56b5" + integrity sha512-6eGEAAPHYvcfbRNCMmPzBIjrqRWLw7at9lCUH4G6NQ8gwWDJelaUmFNOqPIhehbw941euVmIuqWsaWiKXfb+5g== + +connect@3.6.6: + version "3.6.6" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" + integrity sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ= + dependencies: + debug "2.6.9" + finalhandler "1.1.0" + parseurl "~1.3.2" + utils-merge "1.0.1" + console-browserify@1.1.x: version "1.1.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" @@ -162,6 +2419,11 @@ console-browserify@1.1.x: dependencies: date-now "^0.1.4" +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + constantinople@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-4.0.1.tgz#0def113fa0e4dc8de83331a5cf79c8b325213151" @@ -182,6 +2444,21 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +convert-source-map@^1.5.0, convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + +cookie-parser@^1.4.6: + version "1.4.6" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.6.tgz#3ac3a7d35a7a03bbc7e365073a26074824214594" + integrity sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA== + dependencies: + cookie "0.4.1" + cookie-signature "1.0.6" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -192,30 +2469,296 @@ cookie@0.4.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== +cookie@0.4.1, cookie@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + +copy-anything@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.3.tgz#842407ba02466b0df844819bbe3baebbe5d45d87" + integrity sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ== + dependencies: + is-what "^3.12.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +copy-props@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/copy-props/-/copy-props-2.0.5.tgz#03cf9ae328d4ebb36f8f1d804448a6af9ee3f2d2" + integrity sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw== + dependencies: + each-props "^1.3.2" + is-plain-object "^5.0.0" + +core-js-compat@^3.18.0, core-js-compat@^3.19.1: + version "3.19.2" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.19.2.tgz#18066a3404a302433cb0aa8be82dd3d75c76e5c4" + integrity sha512-ObBY1W5vx/LFFMaL1P5Udo4Npib6fu+cMokeziWkA8Tns4FcDemKF5j9JvaI5JhdkW8EQJQGJN1EcrzmEwuAqQ== + dependencies: + browserslist "^4.18.1" + semver "7.0.0" + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cors@~2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cron-parser@^2.13.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/cron-parser/-/cron-parser-2.18.0.tgz#de1bb0ad528c815548371993f81a54e5a089edcf" + integrity sha512-s4odpheTyydAbTBQepsqd2rNWGa2iV3cyo8g7zbI2QQYGLVsfbhmwukayS1XHppe02Oy1fg7mg6xoaraVJeEcg== + dependencies: + is-nan "^1.3.0" + moment-timezone "^0.5.31" + +cron@^1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/cron/-/cron-1.8.2.tgz#4ac5e3c55ba8c163d84f3407bde94632da8370ce" + integrity sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg== + dependencies: + moment-timezone "^0.5.x" + +cropperjs@^1.5.12: + version "1.5.12" + resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-1.5.12.tgz#d9c0db2bfb8c0d769d51739e8f916bbc44e10f50" + integrity sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== + +cssom@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" + integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +data-uri-to-buffer@1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835" + integrity sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ== + +data-uri-to-buffer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b" + integrity sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA== + +data-urls@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.1.tgz#597fc2ae30f8bc4dbcf731fcd1b1954353afc6f8" + integrity sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^3.0.0" + whatwg-url "^10.0.0" + date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= -debug@2.6.9: +debug@2, debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@~2.6.4: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@4.x: +debug@3.1.0, debug@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@4, debug@4.x, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@~4.3.1, debug@~4.3.2: version "4.3.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" +debug@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +debug@^3.1.0, debug@^3.2.6, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@~4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +debuglog@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= + +decamelize@^1.1.1, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decimal.js@^10.3.1: + version "10.3.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" + integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +default-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f" + integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ== + dependencies: + kind-of "^5.0.2" + +default-resolution@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-resolution/-/default-resolution-2.0.0.tgz#bcb82baa72ad79b426a76732f1a81ad6df26d684" + integrity sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ= + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +degenerator@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" + integrity sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU= + dependencies: + ast-types "0.x.x" + escodegen "1.x.x" + esprima "3.x.x" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +denque@^1.1.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.1.tgz#07f670e29c9a78f8faecb2566a1e2c11929c5cbf" + integrity sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw== + denque@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/denque/-/denque-2.0.1.tgz#bcef4c1b80dc32efe97515744f21a4229ab8934a" @@ -226,11 +2769,67 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +detect-file@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" + integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= + +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +dev-ip@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dev-ip/-/dev-ip-1.0.1.tgz#a76a3ed1855be7a012bb8ac16cb80f3c00dc28f0" + integrity sha1-p2o+0YVb56ASu4rBbLgPPADcKPA= + +dicer@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" + integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= + dependencies: + readable-stream "1.1.x" + streamsearch "0.1.2" + +dijkstrajs@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.2.tgz#2e48c0d3b825462afe75ab4ad5e829c8ece36257" + integrity sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg== + +diskusage-ng@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/diskusage-ng/-/diskusage-ng-1.0.2.tgz#5ded0862ce3726ca2ddc2956a66b0673877cd3a1" + integrity sha512-IO+Dbvxf5kXGuOEAHFCSf/aW9z/E96OwUH1Szstf2Rjzy+AP6sr/Y5yQh70fdX8SEFKdkTMpVG+b5jR7Uw3Q1Q== + +disposable-email-provider-domains@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/disposable-email-provider-domains/-/disposable-email-provider-domains-1.0.9.tgz#0ac18ca5477a8d5e6f7f53c5862de8f0dcdee055" + integrity sha512-6/8yqrRlRSZvpfKoR11Sk+S3Vv65jR3AN7Q6F81xusnPRNQ4cna+dOv5ZdTYUOJky6dKY/43vTNK7V5M7q4f7Q== + +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + +dnscache@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/dnscache/-/dnscache-1.0.2.tgz#fd3c24d66c141625f594c77be7a8dafee2a66c8a" + integrity sha512-2FFKzmLGOnD+Y378bRKH+gTjRMuSpH7OKgPy31KjjfCoKZx7tU8Dmqfd/3fhG2d/4bppuN8/KtWMUZBAcUCRnQ== + dependencies: + asap "^2.0.6" + lodash.clone "^4.5.0" + doctypes@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9" @@ -254,6 +2853,13 @@ domelementtype@^2.0.1: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== +domexception@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" + integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== + dependencies: + webidl-conversions "^7.0.0" + domhandler@2.3: version "2.3.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738" @@ -269,21 +2875,195 @@ domutils@1.5: dom-serializer "0" domelementtype "1" +dot-prop@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== + dependencies: + is-obj "^2.0.0" + dotenv@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== +double-ended-queue@^2.1.0-0: + version "2.1.0-0" + resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" + integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw= + +dtp-jshint-reporter@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/dtp-jshint-reporter/-/dtp-jshint-reporter-1.0.2.tgz#34d11f78eac98027d13dd2a8641e0ec664ddd9ab" + integrity sha512-+tT86GZ5JH+GvxiSmYdVUTC8yZLktlI1e/YCmti35kLNz4KKO2qwU9Z/50LCwryJNkA8+LMPK2y/mOrX2uU/Fg== + dependencies: + chalk "^4.1.1" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +each-props@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/each-props/-/each-props-1.3.2.tgz#ea45a414d16dd5cfa419b1a81720d5ca06892333" + integrity sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA== + dependencies: + is-plain-object "^2.0.1" + object.defaults "^1.1.0" + +easy-extender@^2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/easy-extender/-/easy-extender-2.3.4.tgz#298789b64f9aaba62169c77a2b3b64b4c9589b8f" + integrity sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q== + dependencies: + lodash "^4.17.10" + +eazy-logger@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eazy-logger/-/eazy-logger-3.1.0.tgz#b169eb56df714608fa114f164c8a2956bec9f0f3" + integrity sha512-/snsn2JqBtUSSstEl4R0RKjkisGHAhvYj89i7r3ytNUKW12y178KDZwXLXIgwDqLW6E/VRMT9qfld7wvFae8bQ== + dependencies: + tfunk "^4.0.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -encodeurl@~1.0.2: +ein-validator@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ein-validator/-/ein-validator-1.0.1.tgz#c3098e31ba2e8a7fe4df8c691ed33ea7f6b56429" + integrity sha512-Qhf7R4YeKCt/06J0CmxzDvqyzpkQvcUls3uJAamh5jrLxv0ZNTCzuzVIU2rXDZk8LKwLXNRFsL4ScAvtdBZsKA== + +ejs@^3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.6.tgz#5bfd0a0689743bb5268b3550cceeebbc1702822a" + integrity sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw== + dependencies: + jake "^10.6.1" + +electron-to-chromium@^1.3.896: + version "1.4.11" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.11.tgz#303c9deebbe90c68bf5c2c81a88a3bf4522c8810" + integrity sha512-2OhsaYgsWGhWjx2et8kaUcdktPbBGjKM2X0BReUCKcSCPttEY+hz2zie820JLbttU8jwL92+JJysWwkut3wZgA== + +email-domain-check@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/email-domain-check/-/email-domain-check-1.1.4.tgz#b4001caaf7f7fa15fb8604dbb0739d2179578e8a" + integrity sha512-Yz+hjRaJqogl1j58UAJgrgxPnFd8R4kRW5JS145C4QZHVsSzJTSSSXW61GoqI9RbSRhDRB0vBS33fUyBki7AOw== + dependencies: + co "^4.6.0" + dnscache "^1.0.1" + +email-validator@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/email-validator/-/email-validator-2.0.4.tgz#b8dfaa5d0dae28f1b03c95881d904d4e40bfe7ed" + integrity sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encode-utf8@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" + integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== + +encodeurl@~1.0.1, encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +engine.io-client@~3.5.0: + version "3.5.2" + resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.5.2.tgz#0ef473621294004e9ceebe73cef0af9e36f2f5fa" + integrity sha512-QEqIp+gJ/kMHeUun7f5Vv3bteRHppHH/FMBQX/esFj/fuYfjyUKWGMo3VCvIP/V8bE9KcjHmRZrhIz2Z9oNsDA== + dependencies: + component-emitter "~1.3.0" + component-inherit "0.0.3" + debug "~3.1.0" + engine.io-parser "~2.2.0" + has-cors "1.1.0" + indexof "0.0.1" + parseqs "0.0.6" + parseuri "0.0.6" + ws "~7.4.2" + xmlhttprequest-ssl "~1.6.2" + yeast "0.1.2" + +engine.io-parser@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-2.2.1.tgz#57ce5611d9370ee94f99641b589f94c97e4f5da7" + integrity sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg== + dependencies: + after "0.8.2" + arraybuffer.slice "~0.0.7" + base64-arraybuffer "0.1.4" + blob "0.0.5" + has-binary2 "~1.0.2" + +engine.io-parser@~5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.2.tgz#69a2ec3ed431da021f0666712d07f106bcffa6ce" + integrity sha512-wuiO7qO/OEkPJSFueuATIXtrxF7/6GTbAO9QLv7nnbjwZ5tYhLm9zxvLwxstRs0dcT0KUlWTjtIOs1T86jt12g== + dependencies: + base64-arraybuffer "~1.0.1" + +engine.io@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-3.5.0.tgz#9d6b985c8a39b1fe87cd91eb014de0552259821b" + integrity sha512-21HlvPUKaitDGE4GXNtQ7PLP0Sz4aWLddMPw2VTyFz1FVZqu/kZsJUO8WNpKuE/OCL7nkfRaOui2ZCJloGznGA== + dependencies: + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + debug "~4.1.0" + engine.io-parser "~2.2.0" + ws "~7.4.2" + +engine.io@~6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/engine.io/-/engine.io-6.1.0.tgz#459eab0c3724899d7b63a20c3a6835cf92857939" + integrity sha512-ErhZOVu2xweCjEfYcTdkCnEYUiZgkAcBBAhW4jbIvNG8SLU3orAqoJCiytZjYF7eTpVmmCrLDjLIEaPlUAs1uw== + dependencies: + "@types/cookie" "^0.4.1" + "@types/cors" "^2.8.12" + "@types/node" ">=10.0.0" + accepts "~1.3.4" + base64id "2.0.0" + cookie "~0.4.1" + cors "~2.8.5" + debug "~4.3.1" + engine.io-parser "~5.0.0" + ws "~8.2.3" + +enhanced-resolve@^5.8.3: + version "5.8.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" + integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + entities@1.0: version "1.0.0" resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26" @@ -294,21 +3074,281 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== +errno@^0.1.1, errno@^0.1.3: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.18.5, es-abstract@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" + integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.1" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.1" + is-string "^1.0.7" + is-weakref "^1.0.1" + object-inspect "^1.11.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + string.prototype.trimend "^1.0.4" + string.prototype.trimstart "^1.0.4" + unbox-primitive "^1.0.1" + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50: + version "0.10.53" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-error@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + +es6-iterator@^2.0.1, es6-iterator@^2.0.3, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-promise@^4.0.3: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + +es6-weak-map@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-goat@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" + integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -etag@~1.8.1: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@1.x.x: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esprima@3.x.x: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + +esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1, estraverse@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +estree-walker@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" + integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@1.8.1, etag@^1.8.1, etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-6.0.0.tgz#598b46f09ae44f5d8097a30cfb1681d0f0371503" + integrity sha512-m4wU9j4Z9nXXoqT8RSfl28JSwmMNLFF69OON8H/lL3NeU0tNpGz313bcOfYoBBHokB0dC2tMl3VUcKgHELhL2Q== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^3.0.1" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.0.1" + onetime "^6.0.0" + signal-exit "^3.0.5" + strip-final-newline "^3.0.0" + exit@0.1.2, exit@0.1.x: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI= + dependencies: + homedir-polyfill "^1.0.1" + +express-limiter@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/express-limiter/-/express-limiter-1.6.1.tgz#70ede144f9e875e3c7e120644018a6f7784bda71" + integrity sha512-w/Xz/FIHuAOIVIUeHSe6g2rSYTqCSKA9WFLO2CxX15BzEAK+avp7HoYd7pu/M2tEp5E/to253+4x8vQ6WcTJkQ== + +express-session@^1.17.2: + version "1.17.2" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.2.tgz#397020374f9bf7997f891b85ea338767b30d0efd" + integrity sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ== + dependencies: + cookie "0.4.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~2.0.0" + on-headers "~1.0.2" + parseurl "~1.3.3" + safe-buffer "5.2.1" + uid-safe "~2.1.5" + express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -345,6 +3385,154 @@ express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" +ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + dependencies: + type "^2.5.0" + +extend-shallow@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" + integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE= + dependencies: + kind-of "^1.1.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@^3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fancy-log@^1.3.2, fancy-log@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz#e6a754cc8f15e58987aa9cbd27af66fd6f4e5af9" + integrity sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk= + +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fast-xml-parser@^3.17.5: + version "3.21.1" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.21.1.tgz#152a1d51d445380f7046b304672dd55d15c9e736" + integrity sha512-FTFVjYoBOZTJekiUsawGsSYV9QL0A+zDYCRj7y34IO6Jg+2IMYEtQa+bbictpdpV8dHxXywqU7C0gRDEOFtBFg== + dependencies: + strnum "^1.0.4" + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= + dependencies: + pend "~1.2.0" + +feed@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/feed/-/feed-4.2.2.tgz#865783ef6ed12579e2c44bbef3c9113bc4956a7e" + integrity sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ== + dependencies: + xml-js "^1.6.11" + +fetch-blob@^3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.1.3.tgz#a7dca4855e39d3e3c5a1da62d4ee335c37d26012" + integrity sha512-ax1Y5I9w+9+JiM+wdHkhBoxew+zG4AJ2SvAD1v1szpddUIiPERVGBxrMcB2ZqW0Y3PP8bOWYv2zqQq1Jp2kqUQ== + dependencies: + web-streams-polyfill "^3.0.3" + +file-uri-to-path@1, file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filelist@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.2.tgz#80202f21462d4d1c2e214119b1807c1bc0380e5b" + integrity sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ== + dependencies: + minimatch "^3.0.4" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + integrity sha1-zgtoVbRYU+eRsvzGgARtiCU91/U= + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + finalhandler@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" @@ -358,36 +3546,353 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +findup-sync@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc" + integrity sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw= + dependencies: + detect-file "^1.0.0" + is-glob "^3.1.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +findup-sync@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" + integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== + dependencies: + detect-file "^1.0.0" + is-glob "^4.0.0" + micromatch "^3.0.4" + resolve-dir "^1.0.1" + +fined@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" + integrity sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng== + dependencies: + expand-tilde "^2.0.2" + is-plain-object "^2.0.3" + object.defaults "^1.1.0" + object.pick "^1.2.0" + parse-filepath "^1.0.1" + +flagged-respawn@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41" + integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q== + +flush-write-stream@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +follow-redirects@^1.0.0, follow-redirects@^1.14.0: + version "1.14.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381" + integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA== + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= + dependencies: + for-in "^1.0.1" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + +form-data@^2.3.3: + version "2.5.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" + integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fresh@0.5.2: +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2, fresh@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +fs-extra@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" + integrity sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE= + dependencies: + graceful-fs "^4.1.2" + jsonfile "^3.0.0" + universalify "^0.1.0" + +fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-mkdirp-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz#0b7815fc3201c6a69e14db98ce098c16935259eb" + integrity sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes= + dependencies: + graceful-fs "^4.1.11" + through2 "^2.0.3" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +ftp@~0.3.10: + version "0.3.10" + resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" + integrity sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0= + dependencies: + readable-stream "1.1.x" + xregexp "2.0.0" + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -get-intrinsic@^1.0.2: - version "1.1.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" - integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +geoip-lite@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/geoip-lite/-/geoip-lite-1.4.2.tgz#f41dc50086cce3bc31a6d2d578cad1c37f9f17b3" + integrity sha512-1rUNqar68+ldSSlSMdpLZPAM+NRokIDzB2lpQFRHSOaDVqtmy25jTAWe0lM2GqWFeaA35RiLhF8GF0vvL+qOKA== + dependencies: + async "^2.1.1" + colors "^1.1.2" + iconv-lite "^0.4.13" + ip-address "^5.8.9" + lazy "^1.0.11" + rimraf "^2.5.2" + yauzl "^2.9.2" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-caller-file@^2.0.1, get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + +get-port@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" + integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== + +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +get-uri@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.4.tgz#d4937ab819e218d4cb5ae18e4f5962bef169cc6a" + integrity sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q== + dependencies: + data-uri-to-buffer "1" + debug "2" + extend "~3.0.2" + file-uri-to-path "1" + ftp "~0.3.10" + readable-stream "2" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.1" + is-glob "^4.0.1" -glob@^7.1.1: +glob-stream@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-6.1.0.tgz#7045c99413b3eb94888d83ab46d0b404cc7bdde4" + integrity sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ= + dependencies: + extend "^3.0.0" + glob "^7.1.1" + glob-parent "^3.1.0" + is-negated-glob "^1.0.0" + ordered-read-streams "^1.0.0" + pumpify "^1.3.5" + readable-stream "^2.1.5" + remove-trailing-separator "^1.0.1" + to-absolute-glob "^2.0.0" + unique-stream "^2.0.2" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob-watcher@^5.0.3: + version "5.0.5" + resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-5.0.5.tgz#aa6bce648332924d9a8489be41e3e5c52d4186dc" + integrity sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw== + dependencies: + anymatch "^2.0.0" + async-done "^1.2.0" + chokidar "^2.0.0" + is-negated-glob "^1.0.0" + just-debounce "^1.0.0" + normalize-path "^3.0.0" + object.defaults "^1.1.0" + +glob@^7.1.1, glob@^7.1.3, glob@^7.1.6, glob@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -399,6 +3904,209 @@ glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" +global-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== + dependencies: + ini "2.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg== + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4= + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +glogg@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.2.tgz#2d7dd702beda22eb3bffadf880696da6d846313f" + integrity sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA== + dependencies: + sparkles "^1.0.0" + +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: + version "4.2.8" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" + integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + +gulp-cli@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/gulp-cli/-/gulp-cli-2.3.0.tgz#ec0d380e29e52aa45e47977f0d32e18fd161122f" + integrity sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A== + dependencies: + ansi-colors "^1.0.1" + archy "^1.0.0" + array-sort "^1.0.0" + color-support "^1.1.3" + concat-stream "^1.6.0" + copy-props "^2.0.1" + fancy-log "^1.3.2" + gulplog "^1.0.0" + interpret "^1.4.0" + isobject "^3.0.1" + liftoff "^3.1.0" + matchdep "^2.0.0" + mute-stdout "^1.0.0" + pretty-hrtime "^1.0.0" + replace-homedir "^1.0.0" + semver-greatest-satisfied-range "^1.1.0" + v8flags "^3.2.0" + yargs "^7.1.0" + +gulp-concat@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/gulp-concat/-/gulp-concat-2.6.1.tgz#633d16c95d88504628ad02665663cee5a4793353" + integrity sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M= + dependencies: + concat-with-sourcemaps "^1.0.0" + through2 "^2.0.0" + vinyl "^2.0.0" + +gulp-jshint@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/gulp-jshint/-/gulp-jshint-2.1.0.tgz#bfaf927f78eee263c5bbac5f63e314d44a7bd41e" + integrity sha512-sP3NK8Y/1e58O0PH9t6s7DAr/lKDSUbIY207oWSeufM6/VclB7jJrIBcPCsyhrFTCDUl9DauePbt6VqP2vPM5w== + dependencies: + lodash "^4.12.0" + minimatch "^3.0.3" + plugin-error "^0.1.2" + rcloader "^0.2.2" + through2 "^2.0.0" + +gulp-less@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/gulp-less/-/gulp-less-5.0.0.tgz#edafce75e9202fd62c9f653fb57b8d0d9fd731e5" + integrity sha512-W2I3TewO/By6UZsM/wJG3pyK5M6J0NYmJAAhwYXQHR+38S0iDtZasmUgFCH3CQj+pQYw/PAIzxvFvwtEXz1HhQ== + dependencies: + less "^3.7.1 || ^4.0.0" + object-assign "^4.0.1" + plugin-error "^1.0.0" + replace-ext "^2.0.0" + through2 "^4.0.0" + vinyl-sourcemaps-apply "^0.2.0" + +gulp-nodemon@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/gulp-nodemon/-/gulp-nodemon-2.5.0.tgz#83a023f1ab4094fedae9a48e60937d768f107224" + integrity sha512-vXfaP72xo2C6XOaXrNcLEM3QqDJ1x21S3x97U4YtzN2Rl2kH57++aFkAVxe6BafGRSTxs/xVfE/jNNlCv5Ym2Q== + dependencies: + colors "^1.2.1" + gulp "^4.0.0" + nodemon "^2.0.2" + +gulp-plumber@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/gulp-plumber/-/gulp-plumber-1.2.1.tgz#d38700755a300b9d372318e4ffb5ff7ced0b2c84" + integrity sha512-mctAi9msEAG7XzW5ytDVZ9PxWMzzi1pS2rBH7lA095DhMa6KEXjm+St0GOCc567pJKJ/oCvosVAZEpAey0q2eQ== + dependencies: + chalk "^1.1.3" + fancy-log "^1.3.2" + plugin-error "^0.1.2" + through2 "^2.0.3" + +gulp-rename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-2.0.0.tgz#9bbc3962b0c0f52fc67cd5eaff6c223ec5b9cf6c" + integrity sha512-97Vba4KBzbYmR5VBs9mWmK+HwIf5mj+/zioxfZhOKeXtx5ZjBk57KFlePf5nxq9QsTtFl0ejnHE3zTC9MHXqyQ== + +gulp-uglify-es@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/gulp-uglify-es/-/gulp-uglify-es-3.0.0.tgz#00466e0e3b0486057c552b8b0d3e326791f2f832" + integrity sha512-dQ3czMFFojNgCajcrYl0oa98+YayaQ8kXRdaacpZRZ3iw2sdVURfdt8y8Ki1ogZGQqw8BUawnB7V6NkanxqnDg== + dependencies: + o-stream "^0.3.0" + plugin-error "^1.0.1" + terser "^5.7.1" + vinyl "^2.2.1" + vinyl-sourcemaps-apply "^0.2.1" + +gulp@^4.0.0, gulp@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/gulp/-/gulp-4.0.2.tgz#543651070fd0f6ab0a0650c6a3e6ff5a7cb09caa" + integrity sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA== + dependencies: + glob-watcher "^5.0.3" + gulp-cli "^2.2.0" + undertaker "^1.2.1" + vinyl-fs "^3.0.0" + +gulplog@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" + integrity sha1-4oxNRdBey77YGDY86PnFkmIp/+U= + dependencies: + glogg "^1.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-bigints@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" + integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== + +has-binary2@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-binary2/-/has-binary2-1.0.3.tgz#7776ac627f3ea77250cfc332dab7ddf5e4f5d11d" + integrity sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw== + dependencies: + isarray "2.0.1" + +has-cors@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39" + integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + has-symbols@^1.0.1, has-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" @@ -411,6 +4119,47 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has-yarn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" + integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -418,6 +4167,35 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +highlight.js@^11.3.1: + version "11.3.1" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.3.1.tgz#813078ef3aa519c61700f84fe9047231c5dc3291" + integrity sha512-PUhCRnPjLtiLHZAQ5A/Dt5F8cWZeMyj9KRsACsWT+OD6OP0x6dp5OmT5jdx0JgEyPxPZZIPQpRN2TciUT7occw== + +homedir-polyfill@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8" + integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA== + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +html-encoding-sniffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" + integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== + dependencies: + whatwg-encoding "^2.0.0" + +html-filter@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/html-filter/-/html-filter-4.3.2.tgz#44bd2cee365699e8d0674d3253911b97d9381aa6" + integrity sha512-g/f49MAtkzHdKu8VqE+6eW7PffNPOvR5nYOBRUgeSF4KaMcMPuscjHPXW9P0/6X2wDmczdReSiV4LRv/WkgTaA== + htmlparser2@3.8.x: version "3.8.3" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068" @@ -429,6 +4207,11 @@ htmlparser2@3.8.x: entities "1.0" readable-stream "1.1" +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + http-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" @@ -440,6 +4223,27 @@ http-errors@1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-errors@1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + http-errors@~1.7.2: version "1.7.3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" @@ -451,18 +4255,117 @@ http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -iconv-lite@0.4.24: +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +https-proxy-agent@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz#b8c286433e87602311b01c8ea34413d856a4af81" + integrity sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg== + dependencies: + agent-base "^4.3.0" + debug "^3.1.0" + +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-3.0.1.tgz#c740920859dafa50e5a3222da9d3bf4bb0e5eef5" + integrity sha512-rQLskxnM/5OCldHo+wNXbpVgDn5A17CUoKX+7Sokwaknlq7CdSnphy0W39GU8dw59XiCXmFXDg4fRuckQRKewQ== + +iconv-lite@0.4.24, iconv-lite@^0.4.13, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +idb@^6.1.4: + version "6.1.5" + resolved "https://registry.yarnpkg.com/idb/-/idb-6.1.5.tgz#dbc53e7adf1ac7c59f9b2bf56e00b4ea4fce8c7b" + integrity sha512-IJtugpKkiVXQn5Y+LteyBCNk1N8xpGV3wWZk9EVtZWH8DYkjBn0bX1XnGP9RkyZF0sAcywa6unHqSWKe7q4LGw== + ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= + +image-size@~0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= + +immutable@^3: + version "3.8.2" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" + integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +inflection@~1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.12.0.tgz#a200935656d6f5f6bc4dc7502e1aecb703228416" + integrity sha1-ogCTVlbW9fa8TcdQLhrstwMihBY= + +inflection@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.3.8.tgz#cbd160da9f75b14c3cc63578d4f396784bf3014e" + integrity sha1-y9Fg2p91sUw8xjV41POWeEvzAU4= + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -471,7 +4374,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@~2.0.1: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -481,11 +4384,162 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + +ini@^1.3.4, ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +interpret@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +ioredis@^4.27.0, ioredis@^4.28.2: + version "4.28.2" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.2.tgz#493ccd5d869fd0ec86c96498192718171f6c9203" + integrity sha512-kQ+Iv7+c6HsDdPP2XUHaMv8DhnSeAeKEwMbaoqsXYbO+03dItXt7+5jGQDRyjdRUV2rFJbzg7P4Qt1iX2tqkOg== + dependencies: + cluster-key-slot "^1.1.0" + debug "^4.3.1" + denque "^1.1.0" + lodash.defaults "^4.2.0" + lodash.flatten "^4.4.0" + lodash.isarguments "^3.1.0" + p-map "^2.1.0" + redis-commands "1.7.0" + redis-errors "^1.2.0" + redis-parser "^3.0.0" + standard-as-callback "^2.1.0" + +ip-address@^5.8.9: + version "5.9.4" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-5.9.4.tgz#4660ac261ad61bd397a860a007f7e98e4eaee386" + integrity sha512-dHkI3/YNJq4b/qQaz+c8LuarD3pY24JqZWfjB8aZx1gtpc2MDILu9L9jpZe1sHpzo/yWFweQVn+U//FhazUxmw== + dependencies: + jsbn "1.1.0" + lodash "^4.17.15" + sprintf-js "1.1.2" + +ip@1.1.5, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-absolute@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" + integrity sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA== + dependencies: + is-relative "^1.0.0" + is-windows "^1.0.1" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + is-core-module@^2.2.0: version "2.8.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" @@ -493,6 +4547,45 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + is-expression@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-4.0.0.tgz#c33155962abf21d0afd2552514d67d2ec16fd2ab" @@ -501,12 +4594,161 @@ is-expression@^4.0.0: acorn "^7.1.1" object-assign "^4.1.1" +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= + +is-nan@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + +is-negated-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" + integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= + +is-negative-zero@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + +is-npm@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" + integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== + +is-number-like@^1.0.3: + version "1.0.8" + resolved "https://registry.yarnpkg.com/is-number-like/-/is-number-like-1.0.8.tgz#2e129620b50891042e44e9bbbb30593e75cfbbe3" + integrity sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA== + dependencies: + lodash.isfinite "^3.3.2" + +is-number-object@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" + integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + is-promise@^2.0.0: version "2.2.2" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== -is-regex@^1.0.3: +is-regex@^1.0.3, is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -514,16 +4756,230 @@ is-regex@^1.0.3: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + +is-shared-array-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" + integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== + +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.3, is-typed-array@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.8.tgz#cbaa6585dc7db43318bc5b89523ea384a6f65e79" + integrity sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.18.5" + foreach "^2.0.5" + has-tostringtag "^1.0.0" + +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + +is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-valid-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" + integrity sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao= + +is-weakref@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" + integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== + dependencies: + call-bind "^1.0.0" + +is-what@^3.12.0: + version "3.14.1" + resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" + integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA== + +is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +is-yarn-global@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" + integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isarray@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" + integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +jake@^10.6.1: + version "10.8.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.2.tgz#ebc9de8558160a66d82d0eadc6a2e58fbc500a7b" + integrity sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A== + dependencies: + async "0.9.x" + chalk "^2.4.2" + filelist "^1.0.1" + minimatch "^3.0.4" + +jest-worker@^26.2.1: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest-worker@^27.0.6: + version "27.4.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.2.tgz#0fb123d50955af1a450267787f340a1bf7e12bc4" + integrity sha512-0QMy/zPovLfUPyHuOuuU4E+kGACXXE84nRnq6lBVI9GJg5DCBiA97SATi+ZP8CpiJwEQy1oCPjRBf8AnLjN+Ag== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + js-stringify@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db" integrity sha1-Fzb939lyTyijaCrcYjCufk6Weds= +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +jsbn@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha1-sBMHyym2GKHtJux56RH4A8TaAEA= + +jsdom@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-19.0.0.tgz#93e67c149fe26816d38a849ea30ac93677e16b6a" + integrity sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A== + dependencies: + abab "^2.0.5" + acorn "^8.5.0" + acorn-globals "^6.0.0" + cssom "^0.5.0" + cssstyle "^2.3.0" + data-urls "^3.0.1" + decimal.js "^10.3.1" + domexception "^4.0.0" + escodegen "^2.0.0" + form-data "^4.0.0" + html-encoding-sniffer "^3.0.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^3.0.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^2.0.0" + whatwg-mimetype "^3.0.0" + whatwg-url "^10.0.0" + ws "^8.2.3" + xml-name-validator "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + jshint@^2.13.1: version "2.13.1" resolved "https://registry.yarnpkg.com/jshint/-/jshint-2.13.1.tgz#16bbbecdbb4564d3758d9de4f24926f8c7f8f835" @@ -538,6 +4994,69 @@ jshint@^2.13.1: shelljs "0.3.x" strip-json-comments "1.0.x" +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-schema@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-stream/-/json-stream-1.0.0.tgz#1a3854e28d2bbeeab31cc7ddf683d2ddc5652708" + integrity sha1-GjhU4o0rvuqzHMfd9oPS3cVlJwg= + +json5@^2.1.2, json5@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + +jsonfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" + integrity sha1-pezG9l9T9mLEQVx2daAzHQmS7GY= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonpointer@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.0.tgz#f802669a524ec4805fa7389eadbc9921d5dc8072" + integrity sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg== + jstransformer@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3" @@ -546,21 +5065,353 @@ jstransformer@1.0.0: is-promise "^2.0.0" promise "^7.0.1" +just-debounce@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/just-debounce/-/just-debounce-1.1.0.tgz#2f81a3ad4121a76bc7cb45dbf704c0d76a8e5ddf" + integrity sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ== + kareem@2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/kareem/-/kareem-2.3.2.tgz#78c4508894985b8d38a0dc15e1a8e11078f2ca93" integrity sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ== -lodash@~4.17.21: +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +kind-of@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" + integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ= + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0, kind-of@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +last-run@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/last-run/-/last-run-1.1.1.tgz#45b96942c17b1c79c772198259ba943bebf8ca5b" + integrity sha1-RblpQsF7HHnHchmCWbqUO+v4yls= + dependencies: + default-resolution "^2.0.0" + es6-weak-map "^2.0.1" + +latest-version@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" + integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== + dependencies: + package-json "^6.3.0" + +lazy@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/lazy/-/lazy-1.0.11.tgz#daa068206282542c088288e975c297c1ae77b690" + integrity sha1-2qBoIGKCVCwIgojpdcKXwa53tpA= + +lazystream@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" + integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== + dependencies: + readable-stream "^2.0.5" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + +lead@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lead/-/lead-1.0.0.tgz#6f14f99a37be3a9dd784f5495690e5903466ee42" + integrity sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI= + dependencies: + flush-write-stream "^1.0.2" + +"less@^3.7.1 || ^4.0.0": + version "4.1.2" + resolved "https://registry.yarnpkg.com/less/-/less-4.1.2.tgz#6099ee584999750c2624b65f80145f8674e4b4b0" + integrity sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA== + dependencies: + copy-anything "^2.0.1" + parse-node-version "^1.0.1" + tslib "^2.3.0" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + make-dir "^2.1.0" + mime "^1.4.1" + needle "^2.5.2" + source-map "~0.6.0" + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +libphonenumber-js@^1.9.44: + version "1.9.44" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.9.44.tgz#d036364fe4c1e27205d1d283c7bf8fc25625200b" + integrity sha512-zhw8nUMJuQf7jG1dZfEOKKOS6M3QYIv3HnvB/vGohNd0QfxIQcObH3a6Y6s350H+9xgBeOXClOJkS0hJ0yvS3g== + +liftoff@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" + integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog== + dependencies: + extend "^3.0.0" + findup-sync "^3.0.0" + fined "^1.0.1" + flagged-respawn "^1.0.0" + is-plain-object "^2.0.4" + object.map "^1.0.0" + rechoir "^0.6.2" + resolve "^1.1.7" + +limiter@^1.0.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.5.tgz#8f92a25b3b16c6131293a0cc834b4a838a2aa7c2" + integrity sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA== + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +loader-runner@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" + integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== + +localtunnel@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-2.0.2.tgz#528d50087151c4790f89c2db374fe7b0a48501f0" + integrity sha512-n418Cn5ynvJd7m/N1d9WVJISLJF/ellZnfsLnx8WBWGzxv/ntNcFkJ1o6se5quUhCplfLGBNL5tYHiq5WF3Nug== + dependencies: + axios "0.21.4" + debug "4.3.2" + openurl "1.1.1" + yargs "17.1.1" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.assign@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= + +lodash.clone@^4.3.2, lodash.clone@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" + integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y= + +lodash.clonedeep@^4.3.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= + +lodash.flatten@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= + +lodash.isarguments@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= + +lodash.isfinite@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz#fb89b65a9a80281833f0b7478b3a5104f898ebb3" + integrity sha1-+4m2WpqAKBgz8LdHizpRBPiY67M= + +lodash.isobject@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d" + integrity sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0= + +lodash.merge@^4.6.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.some@^4.2.2: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash@^4.12.0, lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@~4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +magic-string@^0.25.0, magic-string@^0.25.7: + version "0.25.7" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" + integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== + dependencies: + sourcemap-codec "^1.4.4" + +mailgun-js@^0.22.0: + version "0.22.0" + resolved "https://registry.yarnpkg.com/mailgun-js/-/mailgun-js-0.22.0.tgz#128942b5e47a364a470791608852bf68c96b3a05" + integrity sha512-a2alg5nuTZA9Psa1pSEIEsbxr1Zrmqx4VkgGCQ30xVh0kIH7Bu57AYILo+0v8QLSdXtCyLaS+KVmdCrQo0uWFA== + dependencies: + async "^2.6.1" + debug "^4.1.0" + form-data "^2.3.3" + inflection "~1.12.0" + is-stream "^1.1.0" + path-proxy "~1.0.0" + promisify-call "^2.0.2" + proxy-agent "^3.0.3" + tsscmp "^1.0.6" + +make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-iterator@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/make-iterator/-/make-iterator-1.0.1.tgz#29b33f312aa8f547c4a5e490f56afcec99133ad6" + integrity sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw== + dependencies: + kind-of "^6.0.2" + +map-cache@^0.2.0, map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +marked@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.6.tgz#cd199503102b6807354f00574348d41ad4fd25d2" + integrity sha512-+H0bTf8DM8zLuFBUm/2VklxaCrwlBFgoJzHJcMZCnZ9cPgsllHwKpL6TPLdDeA38yPluMuVKOL1hO5w6HmG5Mg== + +matchdep@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/matchdep/-/matchdep-2.0.0.tgz#c6f34834a0d8dbc3b37c27ee8bbcb27c7775582e" + integrity sha1-xvNINKDY28OzfCfui7yyfHd1WC4= + dependencies: + findup-sync "^2.0.0" + micromatch "^3.0.4" + resolve "^1.4.0" + stack-trace "0.0.10" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + memory-pager@^1.0.2: version "1.5.0" resolved "https://registry.yarnpkg.com/memory-pager/-/memory-pager-1.5.0.tgz#d8751655d22d384682741c972f2c3d6dfa3e66b5" @@ -571,35 +5422,159 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +method-override@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/method-override/-/method-override-3.0.0.tgz#6ab0d5d574e3208f15b0c9cf45ab52000468d7a2" + integrity sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA== + dependencies: + debug "3.1.0" + methods "~1.1.2" + parseurl "~1.3.2" + vary "~1.1.2" + methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -mime-db@1.51.0: +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mime-db@1.51.0, "mime-db@>= 1.43.0 < 2": version "1.51.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== -mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@^2.1.14, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.24: version "2.1.34" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== dependencies: mime-db "1.51.0" -mime@1.6.0: +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + +mime@1.6.0, mime@^1.4.1: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -minimatch@^3.0.4, minimatch@~3.0.2: +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@~3.0.2: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + +minio@^7.0.23: + version "7.0.23" + resolved "https://registry.yarnpkg.com/minio/-/minio-7.0.23.tgz#282496e929631ddea7d1d43976420b7095257d60" + integrity sha512-bBunl3dm3BmeDpbPuNp0WfsCRWxLQ+aFjyyXTodSeupKH2ewbCMmUkInF0UncS7jmyHRvEbHMQEOGA70CxtByg== + dependencies: + async "^3.1.0" + block-stream2 "^2.0.0" + es6-error "^4.1.1" + fast-xml-parser "^3.17.5" + ipaddr.js "^2.0.1" + json-stream "^1.0.0" + lodash "^4.17.21" + mime-types "^2.1.14" + mkdirp "^0.5.1" + querystring "0.2.0" + through2 "^3.0.1" + web-encoding "^1.1.5" + xml "^1.0.0" + xml2js "^0.4.15" + +mitt@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.2.0.tgz#cb24e6569c806e31bd4e3995787fe38a04fdf90d" + integrity sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw== + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mkdirp@^0.5.1, mkdirp@^0.5.4: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +moment-timezone@^0.5.31, moment-timezone@^0.5.x: + version "0.5.34" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.34.tgz#a75938f7476b88f155d3504a9343f7519d9a405c" + integrity sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg== + dependencies: + moment ">= 2.9.0" + +"moment@>= 2.9.0", moment@^2.29.1: + version "2.29.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" + integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== + mongodb-connection-string-url@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/mongodb-connection-string-url/-/mongodb-connection-string-url-2.2.0.tgz#e2422bae91a953dc4ae5882e401301f5be39a227" @@ -634,6 +5609,17 @@ mongoose@^6.0.14: sift "13.5.2" sliced "1.0.1" +morgan@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" + integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== + dependencies: + basic-auth "~2.0.1" + debug "2.6.9" + depd "~2.0.0" + on-finished "~2.3.0" + on-headers "~1.0.2" + mpath@0.8.4: version "0.8.4" resolved "https://registry.yarnpkg.com/mpath/-/mpath-0.8.4.tgz#6b566d9581621d9e931dd3b142ed3618e7599313" @@ -663,50 +5649,705 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multer@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.3.tgz#4db352d6992e028ac0eacf7be45c6efd0264297b" + integrity sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg== + dependencies: + append-field "^1.0.0" + busboy "^0.2.11" + concat-stream "^1.5.2" + mkdirp "^0.5.4" + object-assign "^4.1.1" + on-finished "^2.3.0" + type-is "^1.6.4" + xtend "^4.0.0" + +mute-stdout@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mute-stdout/-/mute-stdout-1.0.1.tgz#acb0300eb4de23a7ddeec014e3e96044b3472331" + integrity sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg== + +nan@^2.12.1: + version "2.15.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" + integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +needle@^2.5.2: + version "2.9.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684" + integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -object-assign@^4.1.1: +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +netmask@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" + integrity sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU= + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +node-abi@^3.3.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.5.0.tgz#26e8b7b251c3260a5ac5ba5aef3b4345a0229248" + integrity sha512-LtHvNIBgOy5mO8mPEUtkCW/YCRWYEKshIvqhe1GHHyXEHEB5mgICyYnAcl4qan3uFeRROErKGzatFHPf6kDxWw== + dependencies: + semver "^7.3.5" + +node-addon-api@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.2.0.tgz#117cbb5a959dff0992e1c586ae0393573e4d2a87" + integrity sha512-eazsqzwG2lskuzBqCGPi7Ac2UgOoMz8JVOXVhTvvPDYhthvNpefx8jWD8Np7Gv+2Sz0FlPWZk0nJV0z598Wn8Q== + +node-fetch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.1.0.tgz#714f4922dc270239487654eaeeab86b8206cb52e" + integrity sha512-QU0WbIfMUjd5+MUzQOYhenAazakV7Irh1SGkWCsRzBwvm4fAhzEUaHMJ6QLP7gWT6WO9/oH2zhKMMGMuIrDyKw== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.2" + formdata-polyfill "^4.0.10" + +node-releases@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" + integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== + +nodemon@^2.0.2: + version "2.0.15" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.15.tgz#504516ce3b43d9dc9a955ccd9ec57550a31a8d4e" + integrity sha512-gdHMNx47Gw7b3kWxJV64NI+Q5nfl0y5DgDbiVtShiwa7Z0IZ07Ll4RLFo6AjrhzMtoEZn5PDE3/c2AbVsiCkpA== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.0.4" + pstree.remy "^1.1.8" + semver "^5.7.1" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + update-notifier "^5.1.0" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha1-bd0hvSoxQXuScn3Vhfim83YI6+4= + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + +notepack.io@~2.1.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/notepack.io/-/notepack.io-2.1.3.tgz#cc904045c751b1a27b2dcfd838d81d0bf3ced923" + integrity sha512-AgSt+cP5XMooho1Ppn8NB3FFaVWefV+qZoZncYTUSch2GAEwlYLcIIbT5YVkMlFeNHnfwOvc4HDlbvrB5BRxXA== + +notepack.io@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/notepack.io/-/notepack.io-2.2.0.tgz#d7ea71d1cb90094f88c6f3c8d84277c2d0cd101c" + integrity sha512-9b5w3t5VSH6ZPosoYnyDONnUTF8o0UkBw7JLA6eBlYJWyGT1Q3vQa8Hmuj1/X6RYvHjjygBDgw6fJhe0JEojfw== + +now-and-later@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/now-and-later/-/now-and-later-2.0.1.tgz#8e579c8685764a7cc02cb680380e94f43ccb1f7c" + integrity sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ== + dependencies: + once "^1.3.2" + +npm-run-path@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.0.1.tgz#748dd68ed7de377bb1f7132c7dafe657be5ab400" + integrity sha512-ybBJQUSyFwEEhqO2lXmyKOl9ucHtyZBWVM0h0FiMfT/+WKxCUZFa95qAR2X3w/w6oigN3B0b2UNHZbD+kdfD5w== + dependencies: + path-key "^4.0.0" + +npmlog@^4.0.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +numeral@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" + integrity sha1-StCAk21EPCVhrtnyGX7//iX05QY= + +nwsapi@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" + integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== + +o-stream@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/o-stream/-/o-stream-0.3.0.tgz#204d27bc3fb395164507d79b381e91752e8daedc" + integrity sha512-gbzl6qCJZ609x/M2t25HqCYQagFzWYCtQ84jcuObGr+V8D1Am4EVubkF4J+XFs6ukfiv96vNeiBb8FrbbMZYiQ== + +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -on-finished@~2.3.0: +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-inspect@^1.11.0, object-inspect@^1.9.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" + integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.0.4, object.assign@^4.1.0, object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.defaults@^1.0.0, object.defaults@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/object.defaults/-/object.defaults-1.1.0.tgz#3a7f868334b407dea06da16d88d5cd29e435fecf" + integrity sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8= + dependencies: + array-each "^1.0.1" + array-slice "^1.0.0" + for-own "^1.0.0" + isobject "^3.0.0" + +object.map@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" + integrity sha1-z4Plncj8wK1fQlDh94s7gb2AHTc= + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +object.pick@^1.2.0, object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +object.reduce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.reduce/-/object.reduce-1.0.1.tgz#6fe348f2ac7fa0f95ca621226599096825bb03ad" + integrity sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60= + dependencies: + for-own "^1.0.0" + make-iterator "^1.0.0" + +on-finished@^2.3.0, on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= dependencies: ee-first "1.1.1" -once@^1.3.0: +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" -parseurl@~1.3.3: +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +openurl@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/openurl/-/openurl-1.1.1.tgz#3875b4b0ef7a52c156f0db41d4609dbb0f94b387" + integrity sha1-OHW0sO96UsFW8NtB1GCduw+Us4c= + +opn@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c" + integrity sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g== + dependencies: + is-wsl "^1.1.0" + +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" + +ordered-read-streams@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" + integrity sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4= + dependencies: + readable-stream "^2.0.1" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + dependencies: + lcid "^1.0.0" + +otplib@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/otplib/-/otplib-12.0.1.tgz#c1d3060ab7aadf041ed2960302f27095777d1f73" + integrity sha512-xDGvUOQjop7RDgxTQ+o4pOol0/3xSZzawTiPKRrHnQWAy0WjhNs/5HdIDJCrqC4MBynmjXgULc6YfioaxZeFgg== + dependencies: + "@otplib/core" "^12.0.1" + "@otplib/preset-default" "^12.0.1" + "@otplib/preset-v11" "^12.0.1" + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-timeout@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pac-proxy-agent@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-3.0.1.tgz#115b1e58f92576cac2eba718593ca7b0e37de2ad" + integrity sha512-44DUg21G/liUZ48dJpUSjZnFfZro/0K5JTyFYLBcmh9+T6Ooi4/i4efwUiEy0+4oQusCBqWdhv16XohIj1GqnQ== + dependencies: + agent-base "^4.2.0" + debug "^4.1.1" + get-uri "^2.0.0" + http-proxy-agent "^2.1.0" + https-proxy-agent "^3.0.0" + pac-resolver "^3.0.0" + raw-body "^2.2.0" + socks-proxy-agent "^4.0.1" + +pac-resolver@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-3.0.0.tgz#6aea30787db0a891704deb7800a722a7615a6f26" + integrity sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA== + dependencies: + co "^4.6.0" + degenerator "^1.0.4" + ip "^1.1.5" + netmask "^1.0.6" + thunkify "^2.1.2" + +package-json@^6.3.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== + dependencies: + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" + +parse-filepath@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" + integrity sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE= + dependencies: + is-absolute "^1.0.0" + map-cache "^0.2.0" + path-root "^0.1.1" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-node-version@^1.0.0, parse-node-version@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" + integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= + +parse5@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + +parseqs@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.6.tgz#8e4bb5a19d1cdc844a08ac974d34e273afa670d5" + integrity sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w== + +parseuri@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.6.tgz#e1496e829e3ac2ff47f39a4dd044b32823c4a25a" + integrity sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow== + +parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +passport-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-local/-/passport-local-1.0.0.tgz#1fe63268c92e75606626437e3b906662c15ba6ee" + integrity sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4= + dependencies: + passport-strategy "1.x.x" + +passport-strategy@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= + +passport@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.5.0.tgz#7914aaa55844f9dce8c3aa28f7d6b73647ee0169" + integrity sha512-ln+ue5YaNDS+fes6O5PCzXKSseY5u8MYhX9H5Co4s+HfYI5oqvnHKoOORLYDUPh+8tHvrxugF2GFcUA1Q1Gqfg== + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-proxy@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/path-proxy/-/path-proxy-1.0.0.tgz#18e8a36859fc9d2f1a53b48dee138543c020de5e" + integrity sha1-GOijaFn8nS8aU7SN7hOFQ8Ag3l4= + dependencies: + inflection "~1.3.0" + +path-root-regex@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" + integrity sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0= + +path-root@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" + integrity sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc= + dependencies: + path-root-regex "^0.1.0" + path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +plugin-error@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" + integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= + dependencies: + ansi-cyan "^0.1.1" + ansi-red "^0.1.1" + arr-diff "^1.0.1" + arr-union "^2.0.1" + extend-shallow "^1.1.2" + +plugin-error@^1.0.0, plugin-error@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" + integrity sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA== + dependencies: + ansi-colors "^1.0.1" + arr-diff "^4.0.0" + arr-union "^3.1.0" + extend-shallow "^3.0.2" + +pngjs@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" + integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw== + +portscanner@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/portscanner/-/portscanner-2.1.1.tgz#eabb409e4de24950f5a2a516d35ae769343fbb96" + integrity sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y= + dependencies: + async "1.5.2" + is-number-like "^1.0.3" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +prebuild-install@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.0.tgz#3c5ce3902f1cb9d6de5ae94ca53575e4af0c1574" + integrity sha512-IvSenf33K7JcgddNz2D5w521EgO+4aMMjFt73Uk9FRzQ7P+QZPKrp7qPsDydsSwjGt3T5xRNnM1bj1zMTD5fTA== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: + version "5.6.0" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== + +pretty-hrtime@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + promise@^7.0.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -714,6 +6355,13 @@ promise@^7.0.1: dependencies: asap "~2.0.3" +promisify-call@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/promisify-call/-/promisify-call-2.0.4.tgz#d48c2d45652ccccd52801ddecbd533a6d4bd5fba" + integrity sha1-1IwtRWUszM1SgB3ey9UzptS9X7o= + dependencies: + with-callback "^1.0.2" + proxy-addr@~2.0.5: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -722,6 +6370,40 @@ proxy-addr@~2.0.5: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-agent@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-3.1.1.tgz#7e04e06bf36afa624a1540be247b47c970bd3014" + integrity sha512-WudaR0eTsDx33O3EJE16PjBRZWcX8GqCEeERw1W3hZJgH/F2a46g7jty6UGty6NeJ4CKQy8ds2CJPMiyeqaTvw== + dependencies: + agent-base "^4.2.0" + debug "4" + http-proxy-agent "^2.1.0" + https-proxy-agent "^3.0.0" + lru-cache "^5.1.1" + pac-proxy-agent "^3.0.1" + proxy-from-env "^1.0.0" + socks-proxy-agent "^4.0.1" + +proxy-from-env@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +psl@^1.1.33: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + pug-attrs@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-3.0.0.tgz#b10451e0348165e31fad1cc23ebddd9dc7347c41" @@ -825,21 +6507,90 @@ pug@^3.0.2: pug-runtime "^3.0.1" pug-strip-comments "^2.0.0" -punycode@^2.1.1: +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.5: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +pupa@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== + dependencies: + escape-goat "^2.0.0" + +qrcode@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.0.tgz#95abb8a91fdafd86f8190f2836abbfc500c72d1b" + integrity sha512-9MgRpgVc+/+47dFvQeD6U2s0Z92EsKzcHogtum4QB+UNd025WOJSHvn/hjk9xmzj7Stj95CyUAs31mrjxliEsQ== + dependencies: + dijkstrajs "^1.0.1" + encode-utf8 "^1.0.3" + pngjs "^5.0.0" + yargs "^15.3.1" + +qs@6.2.3: + version "6.2.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.3.tgz#1cfcb25c10a9b2b483053ff39f5dfc9233908cfe" + integrity sha1-HPyyXBCpsrSDBT/zn138kjOQjP4= + qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== -range-parser@~1.2.1: +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +random-bytes@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" + integrity sha1-T2ih3Arli9P7lYSMMDJNt11kNgs= + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@~1.2.0, range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== +rate-limiter-flexible@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/rate-limiter-flexible/-/rate-limiter-flexible-2.3.6.tgz#b1a2549dca91069c8a33d57c08a27262c0356c60" + integrity sha512-8DVFOe89rreyut/vzwBI7vgXJynyYoYnH5XogtAKs0F/neAbCTTglXxSJ7fZeZamcFXZDvMidCBvps4KM+1srw== + raw-body@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" @@ -850,6 +6601,60 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@^2.2.0, raw-body@^2.3.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" + integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== + dependencies: + bytes "3.1.1" + http-errors "1.8.1" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc@^1.2.7, rc@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +rcfinder@^0.1.6: + version "0.1.9" + resolved "https://registry.yarnpkg.com/rcfinder/-/rcfinder-0.1.9.tgz#f3e80f387ddf9ae80ae30a4100329642eae81115" + integrity sha1-8+gPOH3fmugK4wpBADKWQuroERU= + dependencies: + lodash.clonedeep "^4.3.2" + +rcloader@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/rcloader/-/rcloader-0.2.2.tgz#58d2298b462d0b9bfd2133d2a1ec74fbd705c717" + integrity sha1-WNIpi0YtC5v9ITPSoex0+9cFxxc= + dependencies: + lodash.assign "^4.2.0" + lodash.isobject "^3.0.2" + lodash.merge "^4.6.0" + rcfinder "^0.1.6" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + readable-stream@1.1: version "1.1.13" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e" @@ -860,25 +6665,363 @@ readable-stream@1.1: isarray "0.0.1" string_decoder "~0.10.x" +readable-stream@1.1.x: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +"readable-stream@2 || 3", readable-stream@3, readable-stream@^3.1.1, readable-stream@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + +redis-commands@1.7.0, redis-commands@^1.2.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89" + integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ== + +redis-errors@^1.0.0, redis-errors@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" + integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60= + +redis-parser@^2.0.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-2.6.0.tgz#52ed09dacac108f1a631c07e9b69941e7a19504b" + integrity sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs= + +redis-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" + integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ= + dependencies: + redis-errors "^1.0.0" + +redis@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/redis/-/redis-2.6.3.tgz#84305b92553c6a1f09c7c47c30b11ace7dbb7ad4" + integrity sha1-hDBbklU8ah8Jx8R8MLEazn27etQ= + dependencies: + double-ended-queue "^2.1.0-0" + redis-commands "^1.2.0" + redis-parser "^2.0.0" + +regenerate-unicode-properties@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326" + integrity sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + regexp-clone@1.0.0, regexp-clone@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/regexp-clone/-/regexp-clone-1.0.0.tgz#222db967623277056260b992626354a04ce9bf63" integrity sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw== -resolve@^1.15.1: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== +regexp.prototype.flags@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" + integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +regexpu-core@^4.7.1: + version "4.8.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0" + integrity sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^9.0.0" + regjsgen "^0.5.2" + regjsparser "^0.7.0" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + +registry-auth-token@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" + integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== + dependencies: + rc "^1.2.8" + +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + dependencies: + rc "^1.2.8" + +regjsgen@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== + +regjsparser@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968" + integrity sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ== + dependencies: + jsesc "~0.5.0" + +remove-bom-buffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" + integrity sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ== + dependencies: + is-buffer "^1.1.5" + is-utf8 "^0.2.1" + +remove-bom-stream@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz#05f1a593f16e42e1fb90ebf59de8e569525f9523" + integrity sha1-BfGlk/FuQuH7kOv1nejlaVJflSM= + dependencies: + remove-bom-buffer "^3.0.0" + safe-buffer "^5.1.0" + through2 "^2.0.3" + +remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +replace-ext@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" + integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== + +replace-ext@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-2.0.0.tgz#9471c213d22e1bcc26717cd6e50881d88f812b06" + integrity sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug== + +replace-homedir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-homedir/-/replace-homedir-1.0.0.tgz#e87f6d513b928dde808260c12be7fec6ff6e798c" + integrity sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw= + dependencies: + homedir-polyfill "^1.0.1" + is-absolute "^1.0.0" + remove-trailing-separator "^1.1.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-dir@^1.0.0, resolve-dir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M= + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-options@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve-options/-/resolve-options-1.1.0.tgz#32bb9e39c06d67338dc9378c0d6d6074566ad131" + integrity sha1-MrueOcBtZzONyTeMDW1gdFZq0TE= + dependencies: + value-or-function "^3.0.0" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.15.1, resolve@^1.19.0, resolve@^1.4.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" + integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + dependencies: + is-core-module "^2.2.0" + path-parse "^1.0.6" + +resp-modifier@6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/resp-modifier/-/resp-modifier-6.0.2.tgz#b124de5c4fbafcba541f48ffa73970f4aa456b4f" + integrity sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08= + dependencies: + debug "^2.2.0" + minimatch "^3.0.2" + +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rimraf@^2.5.2: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" + glob "^7.1.3" + +rollup-plugin-terser@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" + integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== + dependencies: + "@babel/code-frame" "^7.10.4" + jest-worker "^26.2.1" + serialize-javascript "^4.0.0" + terser "^5.0.0" + +rollup@^2.43.1: + version "2.60.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.60.2.tgz#3f45ace36a9b10b4297181831ea0719922513463" + integrity sha512-1Bgjpq61sPjgoZzuiDSGvbI1tD91giZABgjCQBKM5aYLnzjq52GoDuWVwT/cm/MCxCMPU8gqQvkj8doQ5C8Oqw== + optionalDependencies: + fsevents "~2.3.2" + +rotating-file-stream@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rotating-file-stream/-/rotating-file-stream-3.0.2.tgz#2e776cd3b8b734649d2da4e53b29c78389aa773b" + integrity sha512-P9PWUHjpkSk3QgDtOXKt/dE6NpjA00Yaa9kgZHf3Vq33hPjm4n42nc4TLeUqRhXsQ51X2Ywpsqtwbk7LlI9sCg== + +rx@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" + integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= + +rxjs@^5.5.6: + version "5.5.12" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" + integrity sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw== + dependencies: + symbol-observable "1.0.1" -safe-buffer@5.1.2: +safe-buffer@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -"safer-buffer@>= 2.1.2 < 3": +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -890,6 +7033,82 @@ saslprep@^1.0.3: dependencies: sparse-bitfield "^3.0.3" +sax@>=0.6.0, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +semver-diff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" + integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== + dependencies: + semver "^6.3.0" + +semver-greatest-satisfied-range@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz#13e8c2658ab9691cb0cd71093240280d36f77a5b" + integrity sha1-E+jCZYq5aRywzXEJMkAoDTb3els= + dependencies: + sver-compat "^1.5.0" + +"semver@2 || 3 || 4 || 5", semver@^5.6.0, semver@^5.7.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -909,6 +7128,54 @@ send@0.17.1: range-parser "~1.2.1" statuses "~1.5.0" +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-favicon@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0" + integrity sha1-k10kDN/g9YBTB/3+ln2IlCosvPA= + dependencies: + etag "~1.8.1" + fresh "0.5.2" + ms "2.1.1" + parseurl "~1.3.2" + safe-buffer "5.1.1" + +serve-index@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + serve-static@1.14.1: version "1.14.1" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" @@ -919,63 +7186,834 @@ serve-static@1.14.1: parseurl "~1.3.3" send "0.17.1" +server-destroy@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/server-destroy/-/server-destroy-1.0.1.tgz#f13bf928e42b9c3e79383e61cc3998b5d14e6cdd" + integrity sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0= + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + setprototypeof@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +sharp@^0.29.3: + version "0.29.3" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.3.tgz#0da183d626094c974516a48fab9b3e4ba92eb5c2" + integrity sha512-fKWUuOw77E4nhpyzCCJR1ayrttHoFHBT2U/kR/qEMRhvPEcluG4BKj324+SCO1e84+knXHwhJ1HHJGnUt4ElGA== + dependencies: + color "^4.0.1" + detect-libc "^1.0.3" + node-addon-api "^4.2.0" + prebuild-install "^7.0.0" + semver "^7.3.5" + simple-get "^4.0.0" + tar-fs "^2.1.1" + tunnel-agent "^0.6.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + shelljs@0.3.x: version "0.3.0" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1" integrity sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E= +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + sift@13.5.2: version "13.5.2" resolved "https://registry.yarnpkg.com/sift/-/sift-13.5.2.tgz#24a715e13c617b086166cd04917d204a591c9da6" integrity sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA== +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.0.tgz#73fa628278d21de83dadd5512d2cc1f4872bd675" + integrity sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + sliced@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/sliced/-/sliced-1.0.1.tgz#0b3a662b5d04c3177b1926bea82b03f837a2ef41" integrity sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E= -sparse-bitfield@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" - integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE= +slug@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/slug/-/slug-5.1.0.tgz#8a7e30ca1c3a6dc40cf74e269750913a865edb0b" + integrity sha512-IS39jKR6m+puU8zWgH6ruwx1sfzFNJ6Ai5PKIlUqd0X8C3ca7PB49Cvm0uayqgEt1jgaojO2wWEsQJngnh7fDA== + +smart-buffer@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +socket.io-adapter@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz#ab3f0d6f66b8fc7fca3959ab5991f82221789be9" + integrity sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g== + +socket.io-adapter@~2.3.0, socket.io-adapter@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.3.3.tgz#4d6111e4d42e9f7646e365b4f578269821f13486" + integrity sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ== + +socket.io-client@2.4.0, socket.io-client@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-2.4.0.tgz#aafb5d594a3c55a34355562fc8aea22ed9119a35" + integrity sha512-M6xhnKQHuuZd4Ba9vltCLT9oa+YvTsP8j9NcEiLElfIg8KeYPyhWOes6x4t+LTAC8enQbE/995AdTem2uNyKKQ== + dependencies: + backo2 "1.0.2" + component-bind "1.0.0" + component-emitter "~1.3.0" + debug "~3.1.0" + engine.io-client "~3.5.0" + has-binary2 "~1.0.2" + indexof "0.0.1" + parseqs "0.0.6" + parseuri "0.0.6" + socket.io-parser "~3.3.0" + to-array "0.1.4" + +socket.io-emitter@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/socket.io-emitter/-/socket.io-emitter-3.2.0.tgz#7cda562073c52ace4246cedec13cd5203af99fa1" + integrity sha512-mODyeT/7yB72pSbQWD1Nq7fKuwq2BvHq4bCTx+c1fzCNqjJ3cyaoaSR2eqBo+B3FEF/Aw3LHhZfzAgy3gH6ZnQ== + dependencies: + debug "~4.1.0" + notepack.io "~2.1.0" + redis "2.6.3" + socket.io-parser "3.1.2" + +socket.io-parser@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.1.2.tgz#dbc2282151fc4faebbe40aeedc0772eba619f7f2" + integrity sha1-28IoIVH8T6675Aru3Ady66YZ9/I= + dependencies: + component-emitter "1.2.1" + debug "~2.6.4" + has-binary2 "~1.0.2" + isarray "2.0.1" + +socket.io-parser@~3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.3.2.tgz#ef872009d0adcf704f2fbe830191a14752ad50b6" + integrity sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg== + dependencies: + component-emitter "~1.3.0" + debug "~3.1.0" + isarray "2.0.1" + +socket.io-parser@~3.4.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-3.4.1.tgz#b06af838302975837eab2dc980037da24054d64a" + integrity sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A== + dependencies: + component-emitter "1.2.1" + debug "~4.1.0" + isarray "2.0.1" + +socket.io-parser@~4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0" + integrity sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g== + dependencies: + "@types/component-emitter" "^1.2.10" + component-emitter "~1.3.0" + debug "~4.3.1" + +socket.io@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-2.4.0.tgz#01030a2727bd8eb2e85ea96d69f03692ee53d47e" + integrity sha512-9UPJ1UTvKayuQfVv2IQ3k7tCQC/fboDyIK62i99dAQIyHKaBsNdTpwHLgKJ6guRWxRtC9H+138UwpaGuQO9uWQ== + dependencies: + debug "~4.1.0" + engine.io "~3.5.0" + has-binary2 "~1.0.2" + socket.io-adapter "~1.1.0" + socket.io-client "2.4.0" + socket.io-parser "~3.4.0" + +socket.io@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.4.0.tgz#8140a0db2c22235f88a6dceb867e4d5c9bd70507" + integrity sha512-bnpJxswR9ov0Bw6ilhCvO38/1WPtE3eA2dtxi2Iq4/sFebiDJQzgKNYA7AuVVdGW09nrESXd90NbZqtDd9dzRQ== + dependencies: + accepts "~1.3.4" + base64id "~2.0.0" + debug "~4.3.2" + engine.io "~6.1.0" + socket.io-adapter "~2.3.3" + socket.io-parser "~4.0.4" + +socks-proxy-agent@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz#3c8991f3145b2799e70e11bd5fbc8b1963116386" + integrity sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg== + dependencies: + agent-base "~4.2.1" + socks "~2.3.2" + +socks@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.3.3.tgz#01129f0a5d534d2b897712ed8aceab7ee65d78e3" + integrity sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA== + dependencies: + ip "1.1.5" + smart-buffer "^4.1.0" + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + +source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== + +sourcemap-codec@^1.4.4: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + +sparkles@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.1.tgz#008db65edce6c50eec0c5e228e1945061dd0437c" + integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== + +sparse-bitfield@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz#ff4ae6e68656056ba4b3e792ab3334d38273ca11" + integrity sha1-/0rm5oZWBWuks+eSqzM004JzyhE= + dependencies: + memory-pager "^1.0.2" + +spdx-correct@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== + +stack-trace@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= + +standard-as-callback@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" + integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== + +stream-exhaust@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stream-exhaust/-/stream-exhaust-1.0.2.tgz#acdac8da59ef2bc1e17a2c0ccf6c320d120e555d" + integrity sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw== + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +stream-throttle@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/stream-throttle/-/stream-throttle-0.1.3.tgz#add57c8d7cc73a81630d31cd55d3961cfafba9c3" + integrity sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM= + dependencies: + commander "^2.2.0" + limiter "^1.0.5" + +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.matchall@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa" + integrity sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + get-intrinsic "^1.1.1" + has-symbols "^1.0.2" + internal-slot "^1.0.3" + regexp.prototype.flags "^1.3.1" + side-channel "^1.0.4" + +string.prototype.trimend@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" + integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string.prototype.trimstart@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" + integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringify-object@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-comments@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" + integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== + +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + +strip-json-comments@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +striptags@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.2.0.tgz#cc74a137db2de8b0b9a370006334161f7dd67052" + integrity sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw== + +strnum@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" + integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0, supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +sver-compat@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/sver-compat/-/sver-compat-1.5.0.tgz#3cf87dfeb4d07b4a3f14827bc186b3fd0c645cd8" + integrity sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg= + dependencies: + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" + +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ= + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +systeminformation@^5.9.16: + version "5.9.16" + resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-5.9.16.tgz#097d5b585401b209b3448d1fe84551a5a582b904" + integrity sha512-GDqen5wR9p3GVrTlyFYKbtQIE9eEhqd6Ya9Jr6HReSbDYJuYqhUgYTLuEt45qpSgNj1hKonUe/IzzdFXFmRBeg== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +tar-fs@^2.0.0, tar-fs@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +temp-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" + integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== + +tempy@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.6.0.tgz#65e2c35abc06f1124a97f387b08303442bde59f3" + integrity sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw== + dependencies: + is-stream "^2.0.0" + temp-dir "^2.0.0" + type-fest "^0.16.0" + unique-string "^2.0.0" + +terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.2.5: + version "5.2.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.2.5.tgz#ce65b9880a0c36872555c4874f45bbdb02ee32c9" + integrity sha512-3luOVHku5l0QBeYS8r4CdHYWEGMmIj3H1U64jgkdZzECcSOJAyJ9TjuqcQZvw1Y+4AOBN9SeYJPJmFn2cM4/2g== + dependencies: + jest-worker "^27.0.6" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + terser "^5.7.2" + +terser@^5.0.0, terser@^5.7.1, terser@^5.7.2: + version "5.10.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.10.0.tgz#b86390809c0389105eb0a0b62397563096ddafcc" + integrity sha512-AMmF99DMfEDiRJfxfY5jj5wNH/bYO09cniSqhfoyxc8sFoYIgkJy86G04UoZU5VjlpnplVu0K6Tx6E9b5+DlHA== + dependencies: + commander "^2.20.0" + source-map "~0.7.2" + source-map-support "~0.5.20" + +tfunk@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tfunk/-/tfunk-4.0.0.tgz#de9399feaf2060901d590b7faad80fcd5443077e" + integrity sha512-eJQ0dGfDIzWNiFNYFVjJ+Ezl/GmwHaFTBTjrtqNPW0S7cuVDBrZrmzUz6VkMeCR4DZFqhd4YtLwsw3i2wYHswQ== + dependencies: + chalk "^1.1.3" + dlv "^1.1.3" + +thirty-two@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/thirty-two/-/thirty-two-1.0.2.tgz#4ca2fffc02a51290d2744b9e3f557693ca6b627a" + integrity sha1-TKL//AKlEpDSdEueP1V2k8prYno= + +through2-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/through2-filter/-/through2-filter-3.0.0.tgz#700e786df2367c2c88cd8aa5be4cf9c1e7831254" + integrity sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA== + dependencies: + through2 "~2.0.0" + xtend "~4.0.0" + +through2@^2.0.0, through2@^2.0.3, through2@~2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through2@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.2.tgz#99f88931cfc761ec7678b41d5d7336b5b6a07bf4" + integrity sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ== dependencies: - memory-pager "^1.0.2" + inherits "^2.0.4" + readable-stream "2 || 3" -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +through2@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" + integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== + dependencies: + readable-stream "3" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -strip-json-comments@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" - integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= +thunkify@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d" + integrity sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0= + +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= + +tinymce@^5.10.2: + version "5.10.2" + resolved "https://registry.yarnpkg.com/tinymce/-/tinymce-5.10.2.tgz#cf1ff01025909be26c64348509e6de8e70d58e1d" + integrity sha512-5QhnZ6c8F28fYucLLc00MM37fZoAZ4g7QCYzwIl38i5TwJR5xGqzOv6YMideyLM4tytCzLCRwJoQen2LI66p5A== + +to-absolute-glob@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b" + integrity sha1-GGX0PZ50sIItufFFt4z/fQ98hJs= + dependencies: + is-absolute "^1.0.0" + is-negated-glob "^1.0.0" + +to-array@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/to-array/-/to-array-0.1.4.tgz#17e6c11f73dd4f3d74cda7a4ff3238e9ad9bf890" + integrity sha1-F+bBH3PdTz10zaek/zI46a2b+JA= to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +to-through@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-through/-/to-through-2.0.0.tgz#fc92adaba072647bc0b67d6b03664aa195093af6" + integrity sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY= + dependencies: + through2 "^2.0.3" + toidentifier@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + token-stream@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-1.0.0.tgz#cc200eab2613f4166d27ff9afc7ca56d49df6eb4" integrity sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ= +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + +tough-cookie@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + tr46@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" @@ -983,7 +8021,41 @@ tr46@^3.0.0: dependencies: punycode "^2.1.1" -type-is@~1.6.17, type-is@~1.6.18: +tslib@^2.0.1, tslib@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + +tsscmp@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" + integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-fest@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" + integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-is@^1.6.4, type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -991,31 +8063,451 @@ type-is@~1.6.17, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" + integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +ua-parser-js@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.2.tgz#e2976c34dbfb30b15d2c300b2a53eac87c57a775" + integrity sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg== + +uid-safe@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" + integrity sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA== + dependencies: + random-bytes "~1.0.0" + +uid2@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + integrity sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I= + +uikit@^3.9.4: + version "3.9.4" + resolved "https://registry.yarnpkg.com/uikit/-/uikit-3.9.4.tgz#2565a5c0239f49d3a75bfa89c519d40c006e3c46" + integrity sha512-mrOr/k3a/6/VBXgnqmQFg0l2ipZyoTpULZZgJ0RVHZz97HNrc28KQsb24pl8wxtw+BGpD39nfMhSmOznyOZuHw== + +unbox-primitive@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" + integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + dependencies: + function-bind "^1.1.1" + has-bigints "^1.0.1" + has-symbols "^1.0.2" + which-boxed-primitive "^1.0.2" + +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= + +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + +undertaker-registry@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50" + integrity sha1-XkvaMI5KiirlhPm5pDWaSZglzFA= + +undertaker@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/undertaker/-/undertaker-1.3.0.tgz#363a6e541f27954d5791d6fa3c1d321666f86d18" + integrity sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg== + dependencies: + arr-flatten "^1.0.1" + arr-map "^2.0.0" + bach "^1.0.0" + collection-map "^1.0.0" + es6-weak-map "^2.0.1" + fast-levenshtein "^1.0.0" + last-run "^1.1.0" + object.defaults "^1.0.0" + object.reduce "^1.0.0" + undertaker-registry "^1.0.0" + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" + integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" + integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +uniqid@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/uniqid/-/uniqid-5.4.0.tgz#4e17bfcab66dfe33563411ae0c801f46ef964e66" + integrity sha512-38JRbJ4Fj94VmnC7G/J/5n5SC7Ab46OM5iNtSstB/ko3l1b5g7ALt4qzHFgGciFkyiRNtDXtLNb+VsxtMSE77A== + +unique-stream@^2.0.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-2.3.1.tgz#c65d110e9a4adf9a6c5948b28053d9a8d04cbeac" + integrity sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A== + dependencies: + json-stable-stringify-without-jsonify "^1.0.1" + through2-filter "^3.0.0" + +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== + dependencies: + crypto-random-string "^2.0.0" + +universalify@^0.1.0, universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.1.1, upath@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + +update-notifier@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" + integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== + dependencies: + boxen "^5.0.0" + chalk "^4.1.0" + configstore "^5.0.1" + has-yarn "^2.1.0" + import-lazy "^2.1.0" + is-ci "^2.0.0" + is-installed-globally "^0.4.0" + is-npm "^5.0.0" + is-yarn-global "^0.3.0" + latest-version "^5.1.0" + pupa "^2.1.1" + semver "^7.3.4" + semver-diff "^3.1.1" + xdg-basedir "^4.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util@^0.12.3: + version "0.12.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" + integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + safe-buffer "^5.1.2" + which-typed-array "^1.1.2" + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -vary@~1.1.2: +uuid@^8.3.0, uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +v8flags@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" + integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== + dependencies: + homedir-polyfill "^1.0.1" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +value-or-function@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/value-or-function/-/value-or-function-3.0.0.tgz#1c243a50b595c1be54a754bfece8563b9ff8d813" + integrity sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM= + +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= +vinyl-fs@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-3.0.3.tgz#c85849405f67428feabbbd5c5dbdd64f47d31bc7" + integrity sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng== + dependencies: + fs-mkdirp-stream "^1.0.0" + glob-stream "^6.1.0" + graceful-fs "^4.0.0" + is-valid-glob "^1.0.0" + lazystream "^1.0.0" + lead "^1.0.0" + object.assign "^4.0.4" + pumpify "^1.3.5" + readable-stream "^2.3.3" + remove-bom-buffer "^3.0.0" + remove-bom-stream "^1.2.0" + resolve-options "^1.1.0" + through2 "^2.0.0" + to-through "^2.0.0" + value-or-function "^3.0.0" + vinyl "^2.0.0" + vinyl-sourcemap "^1.1.0" + +vinyl-sourcemap@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz#92a800593a38703a8cdb11d8b300ad4be63b3e16" + integrity sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY= + dependencies: + append-buffer "^1.0.2" + convert-source-map "^1.5.0" + graceful-fs "^4.1.6" + normalize-path "^2.1.1" + now-and-later "^2.0.0" + remove-bom-buffer "^3.0.0" + vinyl "^2.0.0" + +vinyl-sourcemaps-apply@^0.2.0, vinyl-sourcemaps-apply@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" + integrity sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU= + dependencies: + source-map "^0.5.1" + +vinyl@^2.0.0, vinyl@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" + integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + void-elements@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + +w3c-xmlserializer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923" + integrity sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg== + dependencies: + xml-name-validator "^4.0.0" + +watchpack@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.0.tgz#a41bca3da6afaff31e92a433f4c856a0c25ea0c4" + integrity sha512-MnN0Q1OsvB/GGHETrFeZPQaOelWh/7O+EiFlj8sM9GPjtQkis7k01aAxrg/18kTfoIVcLL+haEVFlXDaSRwKRw== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +web-encoding@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/web-encoding/-/web-encoding-1.1.5.tgz#fc810cf7667364a6335c939913f5051d3e0c4864" + integrity sha512-HYLeVCdJ0+lBYV2FvNZmv3HJ2Nt0QYXqZojk3d9FJOLkwnuhzM9tmamh8d7HPM8QqjKH8DeHkFTx+CFlWpZZDA== + dependencies: + util "^0.12.3" + optionalDependencies: + "@zxing/text-encoding" "0.9.0" + +web-streams-polyfill@^3.0.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz#a6b74026b38e4885869fb5c589e90b95ccfc7965" + integrity sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA== + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + webidl-conversions@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== +webpack-sources@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack-sources@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.2.tgz#d88e3741833efec57c4c789b6010db9977545260" + integrity sha512-cp5qdmHnu5T8wRg2G3vZZHoJPN14aqQ89SyQ11NpGH5zEMDCclt49rzo+MaRazk7/UeILhAI+/sEtcM+7Fr0nw== + +webpack-stream@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webpack-stream/-/webpack-stream-7.0.0.tgz#e6a1edb9568198499af872678e95031752d72f00" + integrity sha512-XoAQTHyCaYMo6TS7Atv1HYhtmBgKiVLONJbzLBl2V3eibXQ2IT/MCRM841RW/r3vToKD5ivrTJFWgd/ghoxoRg== + dependencies: + fancy-log "^1.3.3" + lodash.clone "^4.3.2" + lodash.some "^4.2.2" + memory-fs "^0.5.0" + plugin-error "^1.0.1" + supports-color "^8.1.1" + through "^2.3.8" + vinyl "^2.2.1" + +webpack@^5.64.4: + version "5.64.4" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.64.4.tgz#e1454b6a13009f57cc2c78e08416cd674622937b" + integrity sha512-LWhqfKjCLoYJLKJY8wk2C3h77i8VyHowG3qYNZiIqD6D0ZS40439S/KVuc/PY48jp2yQmy0mhMknq8cys4jFMw== + dependencies: + "@types/eslint-scope" "^3.7.0" + "@types/estree" "^0.0.50" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.4.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.8.3" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.4" + json-parse-better-errors "^1.0.2" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.3.0" + webpack-sources "^3.2.2" + +whatwg-encoding@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" + integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== + dependencies: + iconv-lite "0.6.3" + +whatwg-mimetype@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== + +whatwg-url@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-10.0.0.tgz#37264f720b575b4a311bd4094ed8c760caaa05da" + integrity sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w== + dependencies: + tr46 "^3.0.0" + webidl-conversions "^7.0.0" + whatwg-url@^11.0.0: version "11.0.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" @@ -1024,6 +8516,81 @@ whatwg-url@^11.0.0: tr46 "^3.0.0" webidl-conversions "^7.0.0" +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which-typed-array@^1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.7.tgz#2761799b9a22d4b8660b3c1b40abaa7739691793" + integrity sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.18.5" + foreach "^2.0.5" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.7" + +which@^1.2.14: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + +with-callback@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/with-callback/-/with-callback-1.0.2.tgz#a09629b9a920028d721404fb435bdcff5c91bc21" + integrity sha1-oJYpuakgAo1yFAT7Q1vc/1yRvCE= + with@^7.0.0: version "7.0.2" resolved "https://registry.yarnpkg.com/with/-/with-7.0.2.tgz#ccee3ad542d25538a7a7a80aad212b9828495bac" @@ -1034,7 +8601,402 @@ with@^7.0.0: assert-never "^1.2.1" babel-walk "3.0.0-canary-5" +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +workbox-background-sync@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.4.2.tgz#bb31b95928d376abcb9bde0de3a0cef9bae46cf7" + integrity sha512-P7c8uG5X2k+DMICH9xeSA9eUlCOjHHYoB42Rq+RtUpuwBxUOflAXR1zdsMWj81LopE4gjKXlTw7BFd1BDAHo7g== + dependencies: + idb "^6.1.4" + workbox-core "6.4.2" + +workbox-broadcast-update@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-6.4.2.tgz#5094c4767dfb590532ac03ee07e9e82b2ac206bc" + integrity sha512-qnBwQyE0+PWFFc/n4ISXINE49m44gbEreJUYt2ldGH3+CNrLmJ1egJOOyUqqu9R4Eb7QrXcmB34ClXG7S37LbA== + dependencies: + workbox-core "6.4.2" + +workbox-build@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-6.4.2.tgz#47f9baa946c3491533cd5ccb1f194a7160e8a6e3" + integrity sha512-WMdYLhDIsuzViOTXDH+tJ1GijkFp5khSYolnxR/11zmfhNDtuo7jof72xPGFy+KRpsz6tug39RhivCj77qqO0w== + dependencies: + "@apideck/better-ajv-errors" "^0.3.1" + "@babel/core" "^7.11.1" + "@babel/preset-env" "^7.11.0" + "@babel/runtime" "^7.11.2" + "@rollup/plugin-babel" "^5.2.0" + "@rollup/plugin-node-resolve" "^11.2.1" + "@rollup/plugin-replace" "^2.4.1" + "@surma/rollup-plugin-off-main-thread" "^2.2.3" + ajv "^8.6.0" + common-tags "^1.8.0" + fast-json-stable-stringify "^2.1.0" + fs-extra "^9.0.1" + glob "^7.1.6" + lodash "^4.17.20" + pretty-bytes "^5.3.0" + rollup "^2.43.1" + rollup-plugin-terser "^7.0.0" + source-map "^0.8.0-beta.0" + source-map-url "^0.4.0" + stringify-object "^3.3.0" + strip-comments "^2.0.1" + tempy "^0.6.0" + upath "^1.2.0" + workbox-background-sync "6.4.2" + workbox-broadcast-update "6.4.2" + workbox-cacheable-response "6.4.2" + workbox-core "6.4.2" + workbox-expiration "6.4.2" + workbox-google-analytics "6.4.2" + workbox-navigation-preload "6.4.2" + workbox-precaching "6.4.2" + workbox-range-requests "6.4.2" + workbox-recipes "6.4.2" + workbox-routing "6.4.2" + workbox-strategies "6.4.2" + workbox-streams "6.4.2" + workbox-sw "6.4.2" + workbox-window "6.4.2" + +workbox-cacheable-response@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-6.4.2.tgz#ebcabb3667019da232e986a9927af97871e37ccb" + integrity sha512-9FE1W/cKffk1AJzImxgEN0ceWpyz1tqNjZVtA3/LAvYL3AC5SbIkhc7ZCO82WmO9IjTfu8Vut2X/C7ViMSF7TA== + dependencies: + workbox-core "6.4.2" + +workbox-core@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-6.4.2.tgz#f99fd36a211cc01dce90aa7d5f2c255e8fe9d6bc" + integrity sha512-1U6cdEYPcajRXiboSlpJx6U7TvhIKbxRRerfepAJu2hniKwJ3DHILjpU/zx3yvzSBCWcNJDoFalf7Vgd7ey/rw== + +workbox-expiration@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-6.4.2.tgz#61613459fd6ddd1362730767618d444c6b9c9139" + integrity sha512-0hbpBj0tDnW+DZOUmwZqntB/8xrXOgO34i7s00Si/VlFJvvpRKg1leXdHHU8ykoSBd6+F2KDcMP3swoCi5guLw== + dependencies: + idb "^6.1.4" + workbox-core "6.4.2" + +workbox-google-analytics@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-6.4.2.tgz#eea7d511b3078665a726dc2ee9f11c6b7a897530" + integrity sha512-u+gxs3jXovPb1oul4CTBOb+T9fS1oZG+ZE6AzS7l40vnyfJV79DaLBvlpEZfXGv3CjMdV1sT/ltdOrKzo7HcGw== + dependencies: + workbox-background-sync "6.4.2" + workbox-core "6.4.2" + workbox-routing "6.4.2" + workbox-strategies "6.4.2" + +workbox-navigation-preload@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-6.4.2.tgz#35cd4ba416a530796af135410ca07db5bee11668" + integrity sha512-viyejlCtlKsbJCBHwhSBbWc57MwPXvUrc8P7d+87AxBGPU+JuWkT6nvBANgVgFz6FUhCvRC8aYt+B1helo166g== + dependencies: + workbox-core "6.4.2" + +workbox-precaching@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-6.4.2.tgz#8d87c05d54f32ac140f549faebf3b4d42d63621e" + integrity sha512-CZ6uwFN/2wb4noHVlALL7UqPFbLfez/9S2GAzGAb0Sk876ul9ukRKPJJ6gtsxfE2HSTwqwuyNVa6xWyeyJ1XSA== + dependencies: + workbox-core "6.4.2" + workbox-routing "6.4.2" + workbox-strategies "6.4.2" + +workbox-range-requests@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-6.4.2.tgz#050f0dfbb61cd1231e609ed91298b6c2442ae41b" + integrity sha512-SowF3z69hr3Po/w7+xarWfzxJX/3Fo0uSG72Zg4g5FWWnHpq2zPvgbWerBZIa81zpJVUdYpMa3akJJsv+LaO1Q== + dependencies: + workbox-core "6.4.2" + +workbox-recipes@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-6.4.2.tgz#68de41fa3a77b444b0f93c9c01a76ba1d41fd2bf" + integrity sha512-/oVxlZFpAjFVbY+3PoGEXe8qyvtmqMrTdWhbOfbwokNFtUZ/JCtanDKgwDv9x3AebqGAoJRvQNSru0F4nG+gWA== + dependencies: + workbox-cacheable-response "6.4.2" + workbox-core "6.4.2" + workbox-expiration "6.4.2" + workbox-precaching "6.4.2" + workbox-routing "6.4.2" + workbox-strategies "6.4.2" + +workbox-routing@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-6.4.2.tgz#65b1c61e8ca79bb9152f93263c26b1f248d09dcc" + integrity sha512-0ss/n9PAcHjTy4Ad7l2puuod4WtsnRYu9BrmHcu6Dk4PgWeJo1t5VnGufPxNtcuyPGQ3OdnMdlmhMJ57sSrrSw== + dependencies: + workbox-core "6.4.2" + +workbox-strategies@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-6.4.2.tgz#50c02bf2d116918e1a8052df5f2c1e4103c62d5d" + integrity sha512-YXh9E9dZGEO1EiPC3jPe2CbztO5WT8Ruj8wiYZM56XqEJp5YlGTtqRjghV+JovWOqkWdR+amJpV31KPWQUvn1Q== + dependencies: + workbox-core "6.4.2" + +workbox-streams@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-6.4.2.tgz#3bc615cccebfd62dedf28315afb7d9ee177912a5" + integrity sha512-ROEGlZHGVEgpa5bOZefiJEVsi5PsFjJG9Xd+wnDbApsCO9xq9rYFopF+IRq9tChyYzhBnyk2hJxbQVWphz3sog== + dependencies: + workbox-core "6.4.2" + workbox-routing "6.4.2" + +workbox-sw@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-6.4.2.tgz#9a6db5f74580915dc2f0dbd47d2ffe057c94a795" + integrity sha512-A2qdu9TLktfIM5NE/8+yYwfWu+JgDaCkbo5ikrky2c7r9v2X6DcJ+zSLphNHHLwM/0eVk5XVf1mC5HGhYpMhhg== + +workbox-webpack-plugin@^6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-6.4.2.tgz#aad9f11b028786d5b781420e68f4e8f570ea9936" + integrity sha512-CiEwM6kaJRkx1cP5xHksn13abTzUqMHiMMlp5Eh/v4wRcedgDTyv6Uo8+Hg9MurRbHDosO5suaPyF9uwVr4/CQ== + dependencies: + fast-json-stable-stringify "^2.1.0" + pretty-bytes "^5.4.1" + source-map-url "^0.4.0" + upath "^1.2.0" + webpack-sources "^1.4.3" + workbox-build "6.4.2" + +workbox-window@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-6.4.2.tgz#5319a3e343fa1e4bd15a1f53a07b58999d064c8a" + integrity sha512-KVyRKmrJg7iB+uym/B/CnEUEFG9CvnTU1Bq5xpXHbtgD9l+ShDekSl1wYpqw/O0JfeeQVOFb8CiNfvnwWwqnWQ== + dependencies: + "@types/trusted-types" "^2.0.2" + workbox-core "6.4.2" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^8.2.3: + version "8.3.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.3.0.tgz#7185e252c8973a60d57170175ff55fdbd116070d" + integrity sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw== + +ws@~7.4.2: + version "7.4.6" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" + integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== + +ws@~8.2.3: + version "8.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.2.3.tgz#63a56456db1b04367d0b721a0b80cae6d8becbba" + integrity sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA== + +xdg-basedir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" + integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== + +xml-js@^1.6.11: + version "1.6.11" + resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.11.tgz#927d2f6947f7f1c19a316dd8eea3614e8b18f8e9" + integrity sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g== + dependencies: + sax "^1.2.4" + +xml-name-validator@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" + integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== + +xml2js@^0.4.15: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xml@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" + integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU= + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +xmlhttprequest-ssl@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz#03b713873b01659dfa2c1c5d056065b27ddc2de6" + integrity sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q== + +xregexp@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" + integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM= + +xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + +y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-parser@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.1.tgz#7ede329c1d8cdbbe209bd25cdb990e9b1ebbb394" + integrity sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA== + dependencies: + camelcase "^3.0.0" + object.assign "^4.1.0" + +yargs@17.1.1: + version "17.1.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.1.1.tgz#c2a8091564bdb196f7c0a67c1d12e5b85b8067ba" + integrity sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^15.3.1, yargs@^15.4.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + +yargs@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.2.tgz#63a0a5d42143879fdbb30370741374e0641d55db" + integrity sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA== + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.1" + +yauzl@^2.9.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" + +yeast@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" + integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= + +zxcvbn@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/zxcvbn/-/zxcvbn-4.4.2.tgz#28ec17cf09743edcab056ddd8b1b06262cc73c30" + integrity sha1-KOwXzwl0PtyrBW3dixsGJizHPDA=