diff --git a/README.md b/README.md index 029eefbe..e44664d2 100644 --- a/README.md +++ b/README.md @@ -60,31 +60,42 @@ $ sudo systemctl start edumeet ## Manual installation -* Prerequisites: -Currently edumeet will run on nodejs v14.x -To install see here [here](https://github.com/nodesource/distributions/blob/master/README.md#debinstall). +* Install all the required dependencies and NodeJS v14 (Debian/Ubuntu): ```bash -$ sudo apt install git npm yarnpkg build-essential redis libssl-dev openssl pkg-config +sudo apt install -y curl git python build-essential redis openssl libssl-dev pkg-config +curl -fsSL https://deb.nodesource.com/setup_14.x | sudo bash - +sudo apt update && sudo apt install -y nodejs +``` + +* Install the Yarn package manager (recommended): + +```bash +curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null +echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list +sudo apt update && sudo apt install -y yarn ``` * Clone the project: ```bash -$ git clone https://github.com/edumeet/edumeet.git -$ cd edumeet +git clone https://github.com/edumeet/edumeet.git +cd edumeet + +# switch to the "develop" branch to get the latest version for developing +git checkout develop ``` * Copy `server/config/config.example.js` to `server/config/config.js` : ```bash -$ cp server/config/config.example.js server/config/config.js +cp server/config/config.example.js server/config/config.js ``` * Copy `app/public/config/config.example.js` to `app/public/config/config.js` : ```bash -$ cp app/public/config/config.example.js app/public/config/config.js +cp app/public/config/config.example.js app/public/config/config.js ``` * Edit your two `config.js` with appropriate settings (listening IP/port, logging options, **valid** TLS certificate, don't forget ip setting in last section in server config: (webRtcTransport), etc). @@ -92,19 +103,27 @@ $ cp app/public/config/config.example.js app/public/config/config.js * Set up the browser app: ```bash -$ cd app -$ yarn -$ yarn build +cd app + +# using Yarn (recommended) +yarn && yarn build + +# using NPM +npm i && npm run build ``` -This will build the client application and copy everythink to `server/public` from where the server can host client code to browser requests. +This will build the client application and copy everything to `server/public` from where the server can host client code to browser requests. * Set up the server: ```bash -$ cd .. -$ cd server -$ yarn +cd ../server + +# using Yarn (recommended) +yarn && yarn build + +# using NPM +npm i && npm run build ``` ## Run it locally @@ -112,8 +131,13 @@ $ yarn * Run the Node.js server application in a terminal: ```bash -$ cd server -$ yarn start +cd server + +# using Yarn (recommended) +yarn start + +# using NPM +npm run start ``` * Note: Do not run the server as root. If you need to use port 80/443 make a iptables-mapping for that or use systemd configuration for that (see further down this doc). @@ -124,21 +148,23 @@ $ yarn start * Stop your locally running server. Copy systemd-service file `edumeet.service` to `/etc/systemd/system/` and check location path settings: ```bash -$ cp edumeet.service /etc/systemd/system/ -$ edit /etc/systemd/system/edumeet.service +cp edumeet.service /etc/systemd/system/ + +# modify the install paths, if required +sudo edit /etc/systemd/system/edumeet.service ``` * Reload systemd configuration and start service: ```bash -$ systemctl daemon-reload -$ systemctl start edumeet +sudo systemctl daemon-reload +sudo systemctl start edumeet ``` * If you want to start edumeet at boot time: ```bash -$ systemctl enable edumeet +sudo systemctl enable edumeet ``` ## Ports and firewall diff --git a/app/.eslintrc.json b/app/.eslintrc.json index c4590994..c2bb6eaf 100644 --- a/app/.eslintrc.json +++ b/app/.eslintrc.json @@ -6,91 +6,48 @@ }, "overrides": [ { - "files":["**/*.{ts,tsx}"], - "plugins": ["prettier", "@typescript-eslint"], - "extends": ["airbnb-typescript", "react-app", "prettier"], + "files": ["**/*.{ts,tsx}"], + "plugins": ["@typescript-eslint"], + "extends":[ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ], "parser": "@typescript-eslint/parser", "parserOptions": { - "project": "./tsconfig.json" + "project": "./tsconfig.json" }, "settings": { - "import/resolver": { - "typescript": { - "alwaysTryTypes": true - } - } + "import/resolver": { + "typescript": { + "alwaysTryTypes": true + } + } }, "rules": { - "object-curly-spacing": ["warn", "always"], - "no-unused-vars": [ - "warn", - { - "vars": "all", - "args": "none" - } - ], - "@typescript-eslint/semi": [ - "off" - ], - "@typescript-eslint/no-unused-vars": [ - "warn", - { - "vars": "all", - "args": "none" - } - ], - "max-len": [ - "warn", - { - "code": 100, - "ignoreStrings": true, - "ignoreTemplateLiterals": true, - "ignoreComments": true - } - ], - "prefer-destructuring": [ - "error", - { - "VariableDeclarator": { - "array": false, - "object": true - }, - "AssignmentExpression": { - "array": false, - "object": false - } - }, { - "enforceForRenamedProperties": false - } - ], + "no-unused-vars" : 0, + "@typescript-eslint/ban-types" : 0, + "@typescript-eslint/ban-ts-comment" : 0, + "@typescript-eslint/ban-ts-ignore" : 0, + "@typescript-eslint/explicit-module-boundary-types" : 0, + "@typescript-eslint/member-delimiter-style" : [ 2, - "no-plusplus": [ - "error", - { - "allowForLoopAfterthoughts": true - } - ], - "react/jsx-key": "error", - "import/no-extraneous-dependencies": [ - "error", - { - "devDependencies": [ - "**/*.test.js", - "**/*.test.jsx", - "**/*.test.ts", - "**/*.test.tsx", - "src/tests/**/*" - ] - } - ], - "react/jsx-props-no-spreading": "off", - "import/prefer-default-export": "off", - "react/jsx-boolean-value": "off", - "react/prop-types": "off", - "react/no-unescaped-entities": "off", - "react/jsx-one-expression-per-line": "off", - "react/jsx-wrap-multilines": "off", - "react/destructuring-assignment": "off" + { + "multiline" : { "delimiter": "semi", "requireLast": true }, + "singleline" : { "delimiter": "semi", "requireLast": false } + } + ], + "@typescript-eslint/no-explicit-any" : 0, + "@typescript-eslint/no-unused-vars" : [ 2, + { + "vars" : "all", + "args" : "after-used", + "ignoreRestSiblings" : false + } + ], + "@typescript-eslint/no-use-before-define" : [ 2, { "functions": false } ], + "@typescript-eslint/no-empty-function" : 0, + "@typescript-eslint/no-non-null-assertion" : 0 } } ], diff --git a/app/.prettierrc b/app/.prettierrc index bcbc4f22..41222071 100644 --- a/app/.prettierrc +++ b/app/.prettierrc @@ -3,5 +3,5 @@ "printWidth": 100, "semi": false, "singleQuote": true, - "tabWidth": 2 + "tabWidth": 4 } \ No newline at end of file diff --git a/app/package.json b/app/package.json index c2bbd59d..25042c9b 100644 --- a/app/package.json +++ b/app/package.json @@ -20,12 +20,15 @@ "@material-ui/lab": "^4.0.0-alpha.57", "@react-hook/window-size": "^3.0.7", "@types/node": "^14.14.37", - "@types/react": "^16.10.2", - "@types/react-dom": "^16.9.12", - "bowser": "^2.11.0", + "@types/react": "^17.0.3", + "@types/react-dom": "^17.0.3", + "bowser": "^2.7.0", + "classnames": "^2.2.6", "chroma-js": "^2.1.1", - "classnames": "^2.3.1", + "convict": "^6.0.1", + "convict-format-with-validator": "^6.0.1", "create-torrent": "^4.4.1", + "deep-object-diff": "^1.1.0", "dompurify": "^2.0.7", "domready": "^1.0.8", "end-of-stream": "1.4.1", @@ -71,6 +74,7 @@ "electron": "electron --no-sandbox .", "dev": "nf start -p 3000", "lint": "eslint -c .eslintrc.json --ext .js,.ts,.tsx src", + "lint:fix": "eslint -c .eslintrc.json --ext .js,.ts,.tsx src --fix", "format": "prettier --write 'src/**/*.{ts,tsx}'" }, "browserslist": [ @@ -81,6 +85,8 @@ ], "devDependencies": { "@types/chroma-js": "^2.1.3", + "@types/convict": "^6.0.1", + "@types/convict-format-with-validator": "^6.0.2", "@typescript-eslint/eslint-plugin": "^4.20.0", "@typescript-eslint/parser": "^4.20.0", "babel-eslint": "^10.1.0", @@ -101,6 +107,7 @@ "prettier": "^2.2.1", "prettier-eslint": "^12.0.0", "prettier-eslint-cli": "^5.0.1", - "redux-mock-store": "^1.5.3" + "redux-mock-store": "^1.5.3", + "ts-node": "^9.1.1" } } diff --git a/app/public/config/config.example.js b/app/public/config/config.example.js index e4165004..055561f7 100644 --- a/app/public/config/config.example.js +++ b/app/public/config/config.example.js @@ -78,17 +78,17 @@ var config = } ], // The aspect ratio of the video from the camera // this is not changeable in settings, only config - videoAspectRatio : 1.777, - defaultResolution : 'medium', - defaultFrameRate : 15, - defaultScreenResolution : 'veryhigh', - defaultScreenSharingFrameRate : 5, + videoAspectRatio : 1.777, + resolution : 'medium', + frameRate : 15, + screenResolution : 'veryhigh', + screenSharingFrameRate : 5, // Enable or disable simulcast for webcam video - simulcast : true, + simulcast : true, // Enable or disable simulcast for screen sharing video - simulcastSharing : false, + simulcastSharing : false, // Define different encodings for various resolutions of the video - simulcastProfiles : + simulcastProfiles : { 3840 : [ diff --git a/app/src/components/ConfigDocumentation.tsx b/app/src/components/ConfigDocumentation.tsx new file mode 100644 index 00000000..d6b535b8 --- /dev/null +++ b/app/src/components/ConfigDocumentation.tsx @@ -0,0 +1,99 @@ +import React from 'react'; // eslint-disable-line no-use-before-define +import { withStyles } from '@material-ui/core/styles'; +import PropTypes from 'prop-types'; +import { FormattedMessage } from 'react-intl'; + +import Card from '@material-ui/core/Card'; +import CardActions from '@material-ui/core/CardActions'; +import CardContent from '@material-ui/core/CardContent'; +import Typography from '@material-ui/core/Typography'; +import Table from '@material-ui/core/Table'; +import TableBody from '@material-ui/core/TableBody'; +import TableCell from '@material-ui/core/TableCell'; +import TableContainer from '@material-ui/core/TableContainer'; +import TableHead from '@material-ui/core/TableHead'; +import TableRow from '@material-ui/core/TableRow'; +import Paper from '@material-ui/core/Paper'; +import Button from '@material-ui/core/Button'; + +import { configDocs } from '../config'; + +const styles = () => + ({ + table : { + minWidth : 700 + }, + pre : { + fontSize : '0.8rem' + }, + cell : { + maxWidth : '25vw', + overflow : 'auto' + } + }); + +const ConfigDocumentation = ({ + classes +}: { + classes : any; +}) => +{ + return ( + + + + + + + + + + + Property + Description + Format + Default value + + + + {Object.entries(configDocs).map(([ name, value ] : [ string, any ]) => + { + return ( + + {name} + {value.doc} + +
{value.format}
+
+ +
{value.default}
+
+
+ ); + })} +
+
+
+
+
+ + + +
+ ); +}; + +ConfigDocumentation.propTypes = +{ + classes : PropTypes.object.isRequired +}; + +export default withStyles(styles)(ConfigDocumentation); diff --git a/app/src/components/ConfigError.tsx b/app/src/components/ConfigError.tsx new file mode 100644 index 00000000..3b33e6cb --- /dev/null +++ b/app/src/components/ConfigError.tsx @@ -0,0 +1,75 @@ +import React from 'react'; // eslint-disable-line no-use-before-define +import { withStyles } from '@material-ui/core/styles'; +import PropTypes from 'prop-types'; +import { FormattedMessage } from 'react-intl'; + +import Dialog from '@material-ui/core/Dialog'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import DialogContent from '@material-ui/core/DialogContent'; +import Grid from '@material-ui/core/Grid'; +import ErrorIcon from '@material-ui/icons/Error'; +import Button from '@material-ui/core/Button'; + +const styles = () => + ({ + error : { + color : 'red' + } + }); + +const ConfigError = ({ + classes, + configError +}: { + classes : any; + configError : string; +}) => +{ + return ( + + + + + + + + + +

{configError}

+
+ +
+
+
+ ); +}; + +ConfigError.propTypes = +{ + classes : PropTypes.object.isRequired, + configError : PropTypes.string.isRequired +}; + +export default withStyles(styles)(ConfigError); diff --git a/app/src/components/MeetingDrawer/Chat/Message.js b/app/src/components/MeetingDrawer/Chat/Message.js index d1ad32fa..731a91c0 100644 --- a/app/src/components/MeetingDrawer/Chat/Message.js +++ b/app/src/components/MeetingDrawer/Chat/Message.js @@ -50,6 +50,8 @@ const styles = (theme) => { borderRadius : '50%', height : '2rem', + width : '2rem', + objectFit : 'cover', alignSelf : 'center' } }); diff --git a/app/src/components/MeetingDrawer/FileSharing/File.js b/app/src/components/MeetingDrawer/FileSharing/File.js index fbcad8b9..d8e98fe8 100644 --- a/app/src/components/MeetingDrawer/FileSharing/File.js +++ b/app/src/components/MeetingDrawer/FileSharing/File.js @@ -25,7 +25,9 @@ const styles = (theme) => avatar : { borderRadius : '50%', - height : '2rem' + height : '2rem', + width : '2rem', + objectFit : 'cover' }, text : { diff --git a/app/src/components/MeetingDrawer/ParticipantList/ListMe.js b/app/src/components/MeetingDrawer/ParticipantList/ListMe.js index 33873d20..a3c7825a 100644 --- a/app/src/components/MeetingDrawer/ParticipantList/ListMe.js +++ b/app/src/components/MeetingDrawer/ParticipantList/ListMe.js @@ -24,6 +24,8 @@ const styles = (theme) => { borderRadius : '50%', height : '2rem', + width : '2rem', + objectFit : 'cover', marginTop : theme.spacing(0.5) }, peerInfo : diff --git a/app/src/components/MeetingDrawer/ParticipantList/ListPeer.js b/app/src/components/MeetingDrawer/ParticipantList/ListPeer.js index 29f582a4..dbf8be44 100644 --- a/app/src/components/MeetingDrawer/ParticipantList/ListPeer.js +++ b/app/src/components/MeetingDrawer/ParticipantList/ListPeer.js @@ -49,6 +49,8 @@ const styles = (theme) => { borderRadius : '50%', height : '2rem', + width : '2rem', + objectFit : 'cover', marginTop : theme.spacing(0.5) }, peerInfo : diff --git a/app/src/config.ts b/app/src/config.ts new file mode 100644 index 00000000..0694e489 --- /dev/null +++ b/app/src/config.ts @@ -0,0 +1,580 @@ +import convict from 'convict'; +import * as convictFormatWithValidator from 'convict-format-with-validator'; + +convict.addFormats(convictFormatWithValidator); + +function assert(assertion: Boolean, msg: string) +{ + if (!assertion) + throw new Error(msg); +} + +convict.addFormat({ + name : 'float', + coerce : (v: string) => parseFloat(v), + validate : (v: number) => assert(Number.isFinite(v), 'must be a number') +}); + +const configSchema = convict({ + loginEnabled : + { + doc : 'If the login is enabled.', + format : 'Boolean', + default : false + }, + developmentPort : + { + doc : 'The development server listening port.', + format : 'port', + default : 3443 + }, + productionPort : + { + doc : 'The production server listening port.', + format : 'port', + default : 443 + }, + serverHostname : + { + doc : 'If the server component runs on a different host than the app you can specify the host name.', + format : '*', + default : null + }, + + /** + * Supported browsers version in bowser satisfy format. + * See more: + * https://www.npmjs.com/package/bowser#filtering-browsers + * Otherwise you got a unsupported browser page + */ + supportedBrowsers : + { + doc : 'Supported browsers version in bowser satisfy format.', + format : Object, + default : + { + 'windows' : { + 'internet explorer' : '>12', + 'microsoft edge' : '>18' + }, + 'microsoft edge' : '>18', + 'safari' : '>12', + 'firefox' : '>=60', + 'chrome' : '>=74', + 'chromium' : '>=74', + 'opera' : '>=62', + 'samsung internet for android' : '>=11.1.1.52' + } + }, + + /** + * Network priorities + * DSCP bits set by browser according this priority values. + * ("high" means actually: EF for audio, and AF41 for Video in chrome) + * https://en.wikipedia.org/wiki/Differentiated_services + */ + networkPriorities : + { + doc : 'Network priorities.', + format : Object, + default : + { + audio : 'high', + mainVideo : 'high', + additionalVideos : 'medium', + screenShare : 'medium' + } + }, + // The aspect ratio of the videos as shown on the screen. + // This is changeable in client settings. + // This value must match one of the defined values in + // viewAspectRatios EXACTLY (e.g. 1.333) + viewAspectRatio : + { + doc : 'The aspect ratio of the videos as shown on the screen.', + format : 'float', + default : 1.777 + }, + viewAspectRatios : + { + doc : 'The selectable aspect ratios in the settings.', + format : Array, + default : + [ + { + value : 1.333, // 4 / 3 + label : '4 : 3' + }, + { + value : 1.777, // 16 / 9 + label : '16 : 9' + } + ] + }, + // The aspect ratio of the video from the camera + // this is not changeable in settings, only config + videoAspectRatio : + { + doc : 'The aspect ratio of the video from the camera.', + format : 'float', + default : 1.777 + }, + resolution : + { + doc : 'The default video camera capture resolution.', + format : [ 'low', 'medium', 'high', 'veryhigh', 'ultra' ], + default : 'medium' + }, + frameRate : + { + doc : 'The default video camera capture framerate.', + format : 'nat', + default : 15 + }, + screenResolution : + { + doc : 'The default screen sharing resolution.', + format : [ 'low', 'medium', 'high', 'veryhigh', 'ultra' ], + default : 'veryhigh' + }, + screenSharingFrameRate : + { + doc : 'The default screen sharing framerate.', + format : 'nat', + default : 5 + }, + simulcast : + { + doc : 'Enable or disable simulcast for webcam video.', + format : 'Boolean', + default : true + }, + simulcastSharing : + { + doc : 'Enable or disable simulcast for screen sharing video.', + format : 'Boolean', + default : false + }, + simulcastProfiles : + { + doc : 'Define different encodings for various resolutions of the video.', + format : Object, + default : + { + 3840 : + [ + { scaleResolutionDownBy: 4, maxBitRate: 1500000 }, + { scaleResolutionDownBy: 2, maxBitRate: 4000000 }, + { scaleResolutionDownBy: 1, maxBitRate: 10000000 } + ], + 1920 : + [ + { scaleResolutionDownBy: 4, maxBitRate: 750000 }, + { scaleResolutionDownBy: 2, maxBitRate: 1500000 }, + { scaleResolutionDownBy: 1, maxBitRate: 4000000 } + ], + 1280 : + [ + { scaleResolutionDownBy: 4, maxBitRate: 250000 }, + { scaleResolutionDownBy: 2, maxBitRate: 900000 }, + { scaleResolutionDownBy: 1, maxBitRate: 3000000 } + ], + 640 : + [ + { scaleResolutionDownBy: 2, maxBitRate: 250000 }, + { scaleResolutionDownBy: 1, maxBitRate: 900000 } + ], + 320 : + [ + { scaleResolutionDownBy: 1, maxBitRate: 250000 } + ] + } + }, + // The adaptive spatial layer selection scaling factor (in the range [0.5, 1.0]) + // example: + // with level width=640px, the minimum width required to trigger the + // level change will be: 640 * 0.75 = 480px + adaptiveScalingFactor : + { + doc : 'The adaptive spatial layer selection scaling factor.', + format : (value: number) => value >= 0.5 && value <= 1.0, + default : 0.75 + }, + + /** + * White listing browsers that support audio output device selection. + * It is not yet fully implemented in Firefox. + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=1498512 + */ + audioOutputSupportedBrowsers : + { + doc : 'White listing browsers that support audio output device selection.', + format : Array, + default : [ + 'chrome', + 'opera' + ] + }, + requestTimeout : + { + doc : 'The Socket.io request timeout.', + format : 'nat', + default : 20000 + }, + requestRetries : + { + doc : 'The Socket.io request maximum retries.', + format : 'nat', + default : 3 + }, + transportOptions : + { + doc : '', + format : Object, + default : { + tcp : true + } + }, + autoGainControl : + { + doc : 'Auto gain control enabled.', + format : 'Boolean', + default : true + }, + echoCancellation : + { + doc : 'Echo cancellation enabled.', + format : 'Boolean', + default : true + }, + noiseSuppression : + { + doc : 'Noise suppression enabled.', + format : 'Boolean', + default : true + }, + voiceActivatedUnmute : + { + doc : 'Automatically unmute speaking above noiseThreshold.', + format : 'Boolean', + default : false + }, + noiseThreshold : + { + doc : 'This is only for voiceActivatedUnmute and audio-indicator.', + format : 'int', + default : -60 + }, + // Audio options for now only centrally from config file: + centralAudioOptions : + { + doc : 'Defaults audio settings.', + format : Object, + default : + { + // will not eat that much bandwith thanks to opus + sampleRate : 48000, // default : 48000 and don't go higher + // usually mics are mono so this saves bandwidth + channelCount : 1, // default : 1 + volume : 1.0, // default : 1.0 + sampleSize : 16, // default : 16 + // usually mics are mono so this saves bandwidth + opusStereo : false, // default : false + opusDtx : true, // default : true / will save bandwidth + opusFec : true, // default : true / forward error correction + opusPtime : '20', // default : 20 / minimum packet time (3, 5, 10, 20, 40, 60, 120) + opusMaxPlaybackRate : 48000 // default : 48000 and don't go higher + } + }, + + /** + * Set max 'int' participants in one room that join + * unmuted. Next participant will join automatically muted + * Default value is 4 + * + * Set it to 0 to auto mute all, + * Set it to negative (-1) to never automatically auto mute + * but use it with caution + * full mesh audio strongly decrease room capacity! + */ + autoMuteThreshold : + { + doc : 'Set the max number of participants in one room that join unmuted.', + format : 'nat', + default : 4 + }, + background : + { + doc : 'The page background image URL', + format : String, + default : 'images/background.jpg' + }, + defaultLayout : + { + doc : 'The default layout', + format : [ 'democratic', 'filmstrip' ], + default : 'democratic' + }, + buttonControlBar : + { + doc : 'If true, will show media control buttons in separate control bar, not in the ME container.', + format : 'Boolean', + default : false + }, + drawerOverlayed : + { + doc : 'If false, will push videos away to make room for side drawer. If true, will overlay side drawer over videos.', + format : 'Boolean', + default : true + }, + notificationPosition : + { + doc : 'The position of notifications.', + format : [ 'left', 'right' ], + default : 'right' + }, + + /** + * Set the notificationSounds. Valid keys are: + * 'parkedPeer', 'parkedPeers', 'raisedHand', 'chatMessage', + * 'sendFile', 'newPeer' and 'default'. + * + * Not defining a key is equivalent to using the default notification sound. + * Setting 'play' to null disables the sound notification. + */ + notificationSounds : + { + doc : 'Set the notifications sounds.', + format : Object, + default : + { + chatMessage : { + play : '/sounds/notify-chat.mp3' + }, + raisedHand : { + play : '/sounds/notify-hand.mp3' + }, + default : { + delay : 5000, // minimum delay between alert sounds [ms] + play : '/sounds/notify.mp3' + } + } + }, + hideTimeout : + { + doc : 'Timeout for autohiding topbar and button control bar.', + format : 'int', + default : 3000 + }, + lastN : + { + doc : 'The max number of participant that will be visible in as speaker.', + format : 'nat', + default : 4 + }, + mobileLastN : + { + doc : 'The max number of participant that will be visible in as speaker for mobile users.', + format : 'nat', + default : 1 + }, + maxLastN : + { + doc : 'The highest number of lastN the user can select manually in the user interface.', + format : 'nat', + default : 5 + }, + lockLastN : + { + doc : 'If truthy, users can NOT change number of speakers visible.', + format : 'Boolean', + default : false + }, + // Show logo if "logo" is not null, else show title + // Set logo file name using logo.* pattern like "logo.png" to not track it by git + logo : + { + doc : 'If not null, it shows the logo loaded from URL, else it shows the title.', + format : 'url', + default : 'images/logo.edumeet.svg' + }, + title : + { + doc : 'The title to show if the logo is not specified.', + format : String, + default : 'edumeet' + }, + supportUrl : + { + doc : 'Service & Support URL if not set then not displayed on the about modals.', + format : 'url', + default : 'https://support.example.com' + }, + // Privacy and data protection URL or path by default privacy/privacy.html + // that is a placeholder for your policies + // + // but an external url could be also used here + privacyUrl : + { + doc : 'Privacy and data protection URL or path by default privacy/privacy.html.', + format : String, + default : 'privacy/privacy.html' + }, + // UI theme elements + theme : + { + palette : + { + primary : + { + main : { format: String, default: '#313131' } + } + }, + overrides : + { + MuiAppBar : + { + colorPrimary : + { + backgroundColor : { format: String, default: '#313131' } + } + }, + MuiButton : + { + containedPrimary : + { + backgroundColor : { format: String, default: '#5F9B2D' }, + '&:hover' : + { + backgroundColor : { format: String, default: '#5F9B2D' } + } + }, + containedSecondary : + { + backgroundColor : { format: String, default: '#f50057' }, + '&:hover' : + { + backgroundColor : { format: String, default: '#f50057' } + } + } + + }, + + /* + MuiIconButton : + { + colorPrimary : + { + backgroundColor : '#5F9B2D', + '&:hover' : + { + backgroundColor : '#5F9B2D' + } + }, + colorSecondary : + { + backgroundColor : '#f50057', + '&:hover' : + { + backgroundColor : '#f50057' + } + } + + }, + */ + + MuiFab : + { + primary : + { + backgroundColor : { format: String, default: '#5F9B2D' }, + '&:hover' : + { + backgroundColor : { format: String, default: '#5F9B2D' } + } + }, + secondary : + { + backgroundColor : { format: String, default: '#f50057' }, + '&:hover' : + { + backgroundColor : { format: String, default: '#f50057' } + } + } + + }, + MuiBadge : + { + colorPrimary : + { + backgroundColor : { format: String, default: '#5F9B2D' }, + '&:hover' : + { + backgroundColor : { format: String, default: '#518029' } + } + } + } + }, + typography : + { + useNextVariants : { format: 'Boolean', default: true } + } + } +}); + +function formatDocs(docs: any, property: string | null, schema: any) +{ + if (schema._cvtProperties) + { + Object.entries(schema._cvtProperties).forEach(([ name, value ]) => + { + formatDocs(docs, `${property ? `${property}.` : ''}${name}`, value); + }); + + return docs; + } + else if (property) + { + docs[property] = + { + doc : schema.doc, + format : JSON.stringify(schema.format, null, 2), + default : JSON.stringify(schema.default, null, 2) + }; + } + + return docs; +} + +let config: any = {}; +let configError = ''; + +// Load config from window object +configSchema.load((window as any).config); + +// Perform validation +try +{ + configSchema.validate({ allowed: 'strict' }); + config = configSchema.getProperties(); +} +catch (error: any) +{ + configError = error.message; +} + +// format docs +const configDocs = formatDocs({}, null, configSchema.getSchema()); + +// eslint-disable-next-line +console.log('Using config:', config, configDocs); + +// Override the window config with the validated properties. +(window as any)['config'] = config; + +export { + configSchema, + config, + configError, + configDocs +}; diff --git a/app/src/index.js b/app/src/index.js index 7fcfca83..e86a6482 100644 --- a/app/src/index.js +++ b/app/src/index.js @@ -16,6 +16,8 @@ import RoomContext from './RoomContext'; import deviceInfo from './deviceInfo'; import * as meActions from './actions/meActions'; import UnsupportedBrowser from './components/UnsupportedBrowser'; +import ConfigDocumentation from './components/ConfigDocumentation'; +import ConfigError from './components/ConfigError'; import JoinDialog from './components/JoinDialog'; import LoginDialog from './components/AccessControl/LoginDialog'; import LoadingView from './components/Loader/LoadingView'; @@ -29,11 +31,14 @@ import { detectDevice } from 'mediasoup-client'; import './index.css'; +import { config, configError } from './config'; + const App = LazyPreload(() => import(/* webpackChunkName: "app" */ './components/App')); // const cache = createIntlCache(); -const supportedBrowsers={ +const supportedBrowsers = +{ 'windows' : { 'internet explorer' : '>12', 'microsoft edge' : '>18' @@ -141,14 +146,48 @@ function run() if (unsupportedBrowser || webrtcUnavailable) { render( - - - - - , + + + + + + + , + document.getElementById('edumeet') + ); + + return; + } + + if (basePath === '/config') + { + render( + + + + + + + , + document.getElementById('edumeet') + ); + + return; + } + + if (configError) + { + render( + + + + + + + , document.getElementById('edumeet') ); diff --git a/app/src/reducers/config.js b/app/src/reducers/config.js new file mode 100644 index 00000000..975ca03c --- /dev/null +++ b/app/src/reducers/config.js @@ -0,0 +1,22 @@ +import { config as defaultConfig } from '../config'; + +const initialState = +{ + ...defaultConfig +}; + +const config = (state = initialState, action) => +{ + switch (action.type) + { + case 'CONFIG_SET': + { + return { ...action.payload }; + } + + default: + return state; + } +}; + +export default config; diff --git a/app/src/reducers/rootReducer.js b/app/src/reducers/rootReducer.js index ce82e306..d837c7f9 100644 --- a/app/src/reducers/rootReducer.js +++ b/app/src/reducers/rootReducer.js @@ -13,6 +13,7 @@ import files from './files'; import settings from './settings'; import transports from './transports'; import intl from './intl'; +import config from './config'; // import { intlReducer } from 'react-intl-redux'; export default combineReducers({ @@ -30,5 +31,6 @@ export default combineReducers({ files, settings, // intl : intlReducer - intl + intl, + config }); diff --git a/app/src/reducers/settings.js b/app/src/reducers/settings.js index f52a658f..aa2bd6f3 100644 --- a/app/src/reducers/settings.js +++ b/app/src/reducers/settings.js @@ -1,6 +1,37 @@ -export const defaultSettings = { - audioPreset : 'conference', - audioPresets : +import { config } from '../config'; + +const initialState = +{ + displayName : '', + selectedWebcam : null, + selectedAudioDevice : null, + advancedMode : false, + autoGainControl : config.autoGainControl, + echoCancellation : config.echoCancellation, + noiseSuppression : config.noiseSuppression, + voiceActivatedUnmute : config.voiceActivatedUnmute, + noiseThreshold : config.noiseThreshold, + audioMuted : false, + videoMuted : false, + // low, medium, high, veryhigh, ultra + resolution : config.resolution, + frameRate : config.frameRate, + screenSharingResolution : config.screenResolution, + screenSharingFrameRate : config.screenSharingFrameRate, + lastN : 4, + permanentTopBar : true, + hiddenControls : false, + showNotifications : true, + notificationSounds : true, + mirrorOwnVideo : true, + hideNoVideoParticipants : false, + buttonControlBar : config.buttonControlBar, + drawerOverlayed : config.drawerOverlayed, + aspectRatio : config.viewAspectRatio, + mediaPerms : { audio: true, video: true }, + localPicture : null, + audioPreset : 'conference', + audioPresets : { conference : { @@ -49,41 +80,6 @@ export const defaultSettings = { } }; -const initialState = -{ - displayName : '', - selectedWebcam : null, - selectedAudioDevice : null, - advancedMode : false, - autoGainControl : true, - echoCancellation : true, - noiseSuppression : true, - voiceActivatedUnmute : false, - noiseThreshold : -50, - audioMuted : false, - videoMuted : false, - // low, medium, high, veryhigh, ultra - resolution : window.config.defaultResolution || 'medium', - frameRate : window.config.defaultFrameRate || 15, - screenSharingResolution : window.config.defaultScreenResolution || 'veryhigh', - screenSharingFrameRate : window.config.defaultScreenSharingFrameRate || 5, - lastN : 4, - permanentTopBar : true, - hiddenControls : false, - showNotifications : true, - notificationSounds : true, - mirrorOwnVideo : true, - hideNoVideoParticipants : false, - buttonControlBar : window.config.buttonControlBar || false, - drawerOverlayed : (typeof window.config.drawerOverlayed === 'undefined') ? true : window.config.drawerOverlayed, - aspectRatio : window.config.viewAspectRatio || 1.777, // 16 : 9 - mediaPerms : { audio: true, video: true }, - localPicture : null -}; - -Object.assign(initialState, defaultSettings); -Object.assign(initialState, defaultSettings.audioPresets[defaultSettings.audioPreset]); - const settings = (state = initialState, action) => { switch (action.type) @@ -355,6 +351,11 @@ const settings = (state = initialState, action) => return { ...state, localPicture }; } + case 'SETTINGS_UPDATE': + { + return { ...state, ...action.payload }; + } + default: return state; } diff --git a/app/src/store.js b/app/src/store.js index aa066fa2..c0285a96 100644 --- a/app/src/store.js +++ b/app/src/store.js @@ -8,9 +8,14 @@ import { createLogger } from 'redux-logger'; import { createMigrate, persistStore, persistReducer } from 'redux-persist'; import storage from 'redux-persist/lib/storage'; import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2'; -import rootReducer from './reducers/rootReducer'; import { createFilter } from 'redux-persist-transform-filter'; import { defaultSettings } from './reducers/settings'; +import { diff } from 'deep-object-diff'; +import rootReducer from './reducers/rootReducer'; +import Logger from './Logger'; +import { config } from './config'; + +const logger = new Logger('store'); const migrations = { @@ -65,7 +70,7 @@ const persistConfig = version : 3, migrate : createMigrate(migrations, { debug: true }), stateReconciler : autoMergeLevel2, - whitelist : [ 'settings', 'intl' ] + whitelist : [ 'settings', 'intl', 'config' ] }; const saveSubsetFilter = createFilter( @@ -124,7 +129,27 @@ export const store = createStore( enhancer ); -export const persistor = persistStore(store); +export const persistor = persistStore(store, null, () => +{ + // Check if the app config differs from the stored version. + const currentConfig = store.getState().config; + const changed = diff(currentConfig, config); + const changedKeys = Object.keys(changed); + + if (changedKeys.length) + { + logger.debug('store config changed:', changed); + const changedSettings = {}; + + changedKeys.forEach((key) => + { + changedSettings[key] = config[key]; + }); + + store.dispatch({ type: 'SETTINGS_UPDATE', payload: changedSettings }); + store.dispatch({ type: 'CONFIG_SET', payload: config }); + } +}); /* diff --git a/app/src/translations/locales.ts b/app/src/translations/locales.ts index fd055b09..c219ceb8 100644 --- a/app/src/translations/locales.ts +++ b/app/src/translations/locales.ts @@ -2,151 +2,158 @@ /* eslint-disable import/no-dynamic-require */ const list = [ - { - name: 'English', - file: 'en', - locale: ['en', 'en-en'], - }, - { - name: 'Czech', - file: 'cs', - locale: ['cs', 'cs-cs'], - }, - { - name: 'Chinese (Simplified)', - file: 'cn', - locale: ['zn', 'zn-zn', 'zn-cn'], - }, // hans - { - name: 'Chinese (Traditional)', - file: 'tw', - locale: ['zn-tw', 'zn-hk', 'zn-sg'], - }, // hant - { - name: 'Croatian', - file: 'hr', - locale: ['hr', 'hr-hr'], - }, - { - name: 'Danish', - file: 'dk', - locale: ['dk', 'dk-dk'], - }, - { - name: 'French', - file: 'fr', - locale: ['fr', 'fr-fr'], - }, - { - name: 'German', - file: 'de', - locale: ['de', 'de-de'], - }, - { - name: 'Greek', - file: 'el', - locale: ['el', 'el-el'], - }, - { - name: 'Hindi', - file: 'hi', - locale: ['hi', 'hi-hi'], - }, - { - name: 'Hungarian', - file: 'hu', - locale: ['hu', 'hu-hu'], - }, - { - name: 'Italian', - file: 'it', - locale: ['it', 'it-it'], - }, - { - name: 'Kazakh', - file: 'kk', - locale: ['kk', 'kk-kz '], - }, - { - name: 'Latvian', - file: 'lv', - locale: ['lv', 'lv-lv'], - }, - { - name: 'Norwegian', - file: 'nb', - locale: ['nb', 'nb-no'], - }, - { - name: 'Polish', - file: 'pl', - locale: ['pl', 'pl-pl'], - }, - { - name: 'Portuguese', - file: 'pt', - locale: ['pt', 'pt-pt'], - }, - { - name: 'Romanian', - file: 'ro', - locale: ['ro', 'ro-ro'], - }, - { - name: 'Russian', - file: 'ru', - locale: ['ru', 'ru-ru'], - }, - { - name: 'Spanish', - file: 'es', - locale: ['es', 'es-es'], - }, - { - name: 'Turkish', - file: 'tr', - locale: ['tr', 'tr-tr'], - }, - { - name: 'Ukrainian', - file: 'uk', - locale: ['uk', 'uk-uk'], - }, -] + { + name : 'English', + file : 'en', + locale : [ 'en', 'en-en' ] + }, + { + name : 'Czech', + file : 'cs', + locale : [ 'cs', 'cs-cs' ] + }, + { + name : 'Chinese (Simplified)', + file : 'cn', + locale : [ 'zn', 'zn-zn', 'zn-cn' ] + }, // hans + { + name : 'Chinese (Traditional)', + file : 'tw', + locale : [ 'zn-tw', 'zn-hk', 'zn-sg' ] + }, // hant + { + name : 'Croatian', + file : 'hr', + locale : [ 'hr', 'hr-hr' ] + }, + { + name : 'Danish', + file : 'dk', + locale : [ 'dk', 'dk-dk' ] + }, + { + name : 'French', + file : 'fr', + locale : [ 'fr', 'fr-fr' ] + }, + { + name : 'German', + file : 'de', + locale : [ 'de', 'de-de' ] + }, + { + name : 'Greek', + file : 'el', + locale : [ 'el', 'el-el' ] + }, + { + name : 'Hindi', + file : 'hi', + locale : [ 'hi', 'hi-hi' ] + }, + { + name : 'Hungarian', + file : 'hu', + locale : [ 'hu', 'hu-hu' ] + }, + { + name : 'Italian', + file : 'it', + locale : [ 'it', 'it-it' ] + }, + { + name : 'Kazakh', + file : 'kk', + locale : [ 'kk', 'kk-kz ' ] + }, + { + name : 'Latvian', + file : 'lv', + locale : [ 'lv', 'lv-lv' ] + }, + { + name : 'Norwegian', + file : 'nb', + locale : [ 'nb', 'nb-no' ] + }, + { + name : 'Polish', + file : 'pl', + locale : [ 'pl', 'pl-pl' ] + }, + { + name : 'Portuguese', + file : 'pt', + locale : [ 'pt', 'pt-pt' ] + }, + { + name : 'Romanian', + file : 'ro', + locale : [ 'ro', 'ro-ro' ] + }, + { + name : 'Russian', + file : 'ru', + locale : [ 'ru', 'ru-ru' ] + }, + { + name : 'Spanish', + file : 'es', + locale : [ 'es', 'es-es' ] + }, + { + name : 'Turkish', + file : 'tr', + locale : [ 'tr', 'tr-tr' ] + }, + { + name : 'Ukrainian', + file : 'uk', + locale : [ 'uk', 'uk-uk' ] + } +]; -export const detect = () => { - const localeFull = (navigator.language || (navigator as any).browserLanguage).toLowerCase() +export const detect = () => +{ + const localeFull = (navigator.language || + (navigator as any).browserLanguage).toLowerCase(); - // const localeCountry = localeFull.split(/[-_]/)[0]; + // const localeCountry = localeFull.split(/[-_]/)[0]; - // const localeRegion = localeFull.split(/[-_]/)[1] || null; + // const localeRegion = localeFull.split(/[-_]/)[1] || null; - return localeFull -} + return localeFull; +}; -export const getList = () => list +export const getList = () => list; export interface ILocale { - name: string - file: string - locale: string[] - messages: any + name: string; + file: string; + locale: string[]; + messages: any; } -export const loadOne = (locale: string): ILocale => { - let res: any = {} +export const loadOne = (locale: string): ILocale => +{ + let res: any = {}; - try { - res = list.filter( - (item) => item.locale.includes(locale) || item.locale.includes(locale.split(/[-_]/)[0]) - )[0] + try + { + res = list.filter( + // (item) => item.locale.includes(locale) || item.locale.includes(locale.split(/[-_]/)[0]) + (item) => item.locale.includes(locale) + )[0]; - res.messages = require(`./${res.file}`) - } catch { - res = list.filter((item) => item.locale.includes('en'))[0] + res.messages = require(`./${res.file}`); + } + catch + { + res = list.filter((item) => item.locale.includes('en'))[0]; - res.messages = require(`./${res.file}`) - } + res.messages = require(`./${res.file}`); + } - return res -} + return res; +}; diff --git a/app/src/translations/tw.json b/app/src/translations/tw.json index 66ca85ae..d1b52ccc 100644 --- a/app/src/translations/tw.json +++ b/app/src/translations/tw.json @@ -1,58 +1,58 @@ { - "socket.disconnected": "您已斷開連接", - "socket.reconnecting": "嘗試重新連接", - "socket.reconnected": "您已重新連接", - "socket.requestError": "服務器請求錯誤", + "socket.disconnected": "您已中斷連線", + "socket.reconnecting": "嘗試重新連線", + "socket.reconnected": "已恢復連線", + "socket.requestError": "伺服器請求發生錯誤", - "room.chooseRoom": "選擇您要加入的房間的名稱", - "room.cookieConsent": "這個網站使用Cookies來提升您的使用者體驗", + "room.chooseRoom": "選擇您要加入的會議室名稱", + "room.cookieConsent": "本網站使用 Cookies 技術來提升您的使用者體驗", "room.consentUnderstand": "了解", - "room.joined": "您已加入房間", - "room.cantJoin": "無法加入房間", - "room.youLocked": "您已鎖定房間", - "room.cantLock": "無法鎖定房間", - "room.youUnLocked": "您解鎖了房間", - "room.cantUnLock": "無法解鎖房間", - "room.locked": "房間已鎖定", - "room.unlocked": "房間現已解鎖", + "room.joined": "您已加入會議室", + "room.cantJoin": "無法加入會議室", + "room.youLocked": "您已鎖定會議室", + "room.cantLock": "無法鎖定會議室", + "room.youUnLocked": "您解鎖了會議室", + "room.cantUnLock": "無法解鎖會議室", + "room.locked": "會議室已鎖定", + "room.unlocked": "會議室現已解鎖", "room.newLobbyPeer": "新參與者進入大廳", "room.lobbyPeerLeft": "參與者離開大廳", "room.lobbyPeerChangedDisplayName": "大廳的參與者將名稱變更為 {displayName}", "room.lobbyPeerChangedPicture": "大廳的參與者變更了圖片", - "room.setAccessCode": "設置房間的進入密碼", - "room.accessCodeOn": "房間的進入密碼現已啟用", - "room.accessCodeOff": "房間的進入密碼已停用", - "room.peerChangedDisplayName": "{oldDisplayName} 已變更名稱為 {displayName}", + "room.setAccessCode": "設定會議室的密碼", + "room.accessCodeOn": "已啟用會議室密碼", + "room.accessCodeOff": "已停用會議室密碼", + "room.peerChangedDisplayName": "{oldDisplayName} 已更名為 {displayName}", "room.newPeer": "{displayName} 加入了會議室", - "room.newFile": "有新文件", + "room.newFile": "有新檔案", "room.toggleAdvancedMode": "切換進階模式", - "room.setDemocraticView": "已更改為使用者佈局", - "room.setFilmStripView": "已更改為投影片佈局", + "room.setDemocraticView": "已更改為使用者版面", + "room.setFilmStripView": "已更改為投影片版面", "room.loggedIn": "您已登入", "room.loggedOut": "您已登出", "room.changedDisplayName": "您的顯示名稱已變更為 {displayName}", "room.changeDisplayNameError": "更改顯示名稱時發生錯誤", "room.chatError": "無法發送聊天消息", "room.aboutToJoin": "您即將參加會議", - "room.roomId": "房間ID: {roomName}", - "room.setYourName": "設置您的顯示名稱,並選擇您想加入的方式:", + "room.roomId": "會議室 ID: {roomName}", + "room.setYourName": "設定您的顯示名稱,並選擇您想加入的方式:", "room.audioOnly": "僅通話", "room.audioVideo": "通話和視訊", "room.youAreReady": "準備完畢!", - "room.emptyRequireLogin": "房間是空的! 您可以登錄以開始會議或等待主持人加入", - "room.locketWait": "房間已鎖定! 請等待其他人允許您進入...", + "room.emptyRequireLogin": "會議室空蕩蕩的… 您可以登入以開始會議或等待主持人加入", + "room.locketWait": "會議室已上鎖! 請等待其他人允許您進入…", "room.lobbyAdministration": "大廳管理", "room.peersInLobby": "大廳的參與者", "room.lobbyEmpty": "大廳目前沒有人", "room.hiddenPeers": "{hiddenPeersCount, plural, one {participant} other {participants}}", "room.me": "我", - "room.spotlights": "Spotlight中的參與者", + "room.spotlights": "Spotlight 中的參與者", "room.passive": "被動參與者", "room.videoPaused": "視訊已關閉", "room.muteAll": "全部靜音", "room.stopAllVideo": "關閉全部視訊", "room.closeMeeting": "關閉會議", - "room.clearChat": "清除聊天", + "room.clearChat": "清除聊天訊息", "room.clearFileSharing": "清除檔案", "room.speechUnsupported": "您的瀏覽器不支援語音辨識", "room.moderatoractions": "管理員動作", @@ -60,7 +60,7 @@ "room.loweredHand": "{displayName} 放下了他的手", "room.extraVideo": "其他視訊", "room.extraVideoDuplication": null, - "room.overRoomLimit": "房間已滿,請稍後重試", + "room.overRoomLimit": "會議室已滿,請稍後重試", "room.help": "幫助", "room.about": "關於", "room.shortcutKeys": "鍵盤快速鍵", @@ -68,7 +68,7 @@ "room.hideSelfView": null, "room.showSelfView": null, - "me.mutedPTT": "您已靜音,請按下 空白鍵 來說話", + "me.mutedPTT": "您已將麥克風靜音,請按下「空白鍵」來發言", "roles.gotRole": "您已取得身份: {role}", "roles.lostRole": "您的 {role} 身份已被撤銷", @@ -76,14 +76,14 @@ "tooltip.login": "登入", "tooltip.logout": "登出", "tooltip.admitFromLobby": "從大廳允許", - "tooltip.lockRoom": "鎖定房間", - "tooltip.unLockRoom": "解鎖房間", + "tooltip.lockRoom": "鎖上會議室", + "tooltip.unLockRoom": "解鎖會議室", "tooltip.enterFullscreen": "進入全螢幕", "tooltip.leaveFullscreen": "退出全螢幕", "tooltip.lobby": "顯示大廳", - "tooltip.settings": "顯示設置", + "tooltip.settings": "設定", "tooltip.participants": "顯示參加者", - "tooltip.kickParticipant": "踢出", + "tooltip.kickParticipant": "踢出會議室", "tooltip.muteParticipant": "靜音", "tooltip.muteParticipantVideo": "隱藏視訊", "tooltip.inSpotlight": null, @@ -95,11 +95,11 @@ "tooltip.unMuteParticipant": null, "tooltip.addParticipantToSpotlight": null, "tooltip.removeParticipantFromSpotlight": null, - "tooltip.muteParticipantAudioModerator": "關閉聲音", + "tooltip.muteParticipantAudioModerator": "噤聲", "tooltip.muteParticipantVideoModerator": "關閉視訊", "tooltip.muteScreenSharingModerator": "關閉螢幕分享", - "label.roomName": "房間名稱", + "label.roomName": "會議室名稱", "label.chooseRoomButton": "繼續", "label.yourName": "您的名字", "label.newWindow": "新視窗", @@ -108,14 +108,14 @@ "label.leave": "離開", "label.chatInput": "輸入聊天訊息", "label.chat": "聊天", - "label.filesharing": "文件分享", + "label.filesharing": "檔案分享", "label.participants": "參與者", - "label.shareFile": "分享文件", + "label.shareFile": "分享檔案", "label.shareGalleryFile": "分享圖片", - "label.fileSharingUnsupported": "不支援文件分享", + "label.fileSharingUnsupported": "不支援檔案分享", "label.unknown": "未知", - "label.democratic": "使用者佈局", - "label.filmstrip": "投影片佈局", + "label.democratic": "使用者版面", + "label.filmstrip": "投影片版面", "label.low": "低", "label.medium": "中", "label.high": "高 (HD)", @@ -135,7 +135,7 @@ "label.logout": null, "label.join": null, - "settings.settings": "設置", + "settings.settings": "設定", "settings.camera": "視訊來源", "settings.selectCamera": "選擇視訊來源", "settings.cantSelectCamera": "無法選擇此視訊來源", @@ -149,8 +149,8 @@ "settings.frameRate": null, "settings.screenSharingResolution": null, "settings.screenSharingFrameRate": null, - "settings.layout": "房間佈局", - "settings.selectRoomLayout": "選擇房間佈局", + "settings.layout": "會議室版面", + "settings.selectRoomLayout": "選擇會議室版面", "settings.advancedMode": "進階模式", "settings.permanentTopBar": "固定頂端列", "settings.aspectRatio": null, @@ -162,10 +162,10 @@ "settings.buttonControlBar": "獨立控制按鈕", "settings.showAdvancedVideo": null, "settings.showAdvancedAudio": null, - "settings.echoCancellation": "回音消除", + "settings.echoCancellation": "抑制回音", "settings.autoGainControl": "自動增益控制", - "settings.noiseSuppression": "噪音消除", - "settings.drawerOverlayed": "側邊欄覆蓋畫面", + "settings.noiseSuppression": "消除噪音", + "settings.drawerOverlayed": "側邊欄覆蓋", "settings.voiceActivatedUnmute": null, "settings.noiseThreshold": null, "settings.mirrorOwnVideo": null, @@ -176,18 +176,18 @@ "settings.myPhotoSizeError": null, "settings.myPhotoTypeError": null, - "filesharing.saveFileError": "無法保存文件", - "filesharing.startingFileShare": "開始分享文件", - "filesharing.successfulFileShare": "文件已成功分享", - "filesharing.unableToShare": "無法分享文件", - "filesharing.error": "文件分享發生錯誤", - "filesharing.finished": "文件分享成功", - "filesharing.save": "保存文件", - "filesharing.sharedFile": "{displayName} 分享了一個文件", - "filesharing.download": "下載文件", - "filesharing.missingSeeds": "如果過了很久還是無法下載,則可能沒有人播種了。請讓上傳者重新上傳您想要的文件。", + "filesharing.saveFileError": "無法儲存檔案", + "filesharing.startingFileShare": "開始分享檔案", + "filesharing.successfulFileShare": "成功分享檔案", + "filesharing.unableToShare": "無法分享檔案", + "filesharing.error": "分享檔案時發生錯誤", + "filesharing.finished": "檔案分享完成", + "filesharing.save": "儲存檔案", + "filesharing.sharedFile": "{displayName} 分享了一份檔案", + "filesharing.download": "下載檔案", + "filesharing.missingSeeds": "如果過了很久還是無法下載,則可能沒有人播種了。請讓上傳者重新上傳您需要的檔案。", - "devices.devicesChanged": "您的設備已更改,請在設置中設定您的設備", + "devices.devicesChanged": "您已變更裝置,請在設定中調整您的裝置", "devices.enableOnlyMicrophone": null, "device.audioUnsupported": "不支援您的音訊格式", @@ -201,18 +201,18 @@ "device.stopVideo": "關閉視訊", "device.screenSharingUnsupported": "不支援您的螢幕分享格式", - "device.startScreenSharing": "開始螢幕分享", + "device.startScreenSharing": "開始分享螢幕", "device.stopScreenSharing": "停止螢幕分享", - "devices.microphoneDisconnected": "麥克風已斷開", + "devices.microphoneDisconnected": "麥克風連線中斷", "devices.microphoneError": "麥克風發生錯誤", "devices.microphoneMute": "麥克風靜音", "devices.microphoneUnMute": "取消麥克風靜音", - "devices.microphoneEnable": "麥克風已啟用", + "devices.microphoneEnable": "已啟用麥克風", "devices.microphoneMuteError": "無法使麥克風靜音", "devices.microphoneUnMuteError": "無法取消麥克風靜音", - "devices.screenSharingDisconnected": "螢幕分享已斷開", + "devices.screenSharingDisconnected": "螢幕分享已中斷", "devices.screenSharingError": "螢幕分享時發生錯誤", "devices.cameraDisconnected": "相機已斷開連接", diff --git a/app/tsconfig.json b/app/tsconfig.json index 9670db89..f1b43720 100644 --- a/app/tsconfig.json +++ b/app/tsconfig.json @@ -21,7 +21,6 @@ "jsx": "react-jsx", "downlevelIteration": true }, - "include": [ - "src" - ] + "include": ["src/**/*.ts", "src/**/*.tsx"], + "exclude": ["node_modules", "**/*.spec.ts"] } diff --git a/app/yarn.lock b/app/yarn.lock index 7977fba9..79020a2f 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -23,10 +23,10 @@ dependencies: "@babel/highlight" "^7.12.13" -"@babel/compat-data@^7.12.1", "@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.12", "@babel/compat-data@^7.13.8": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.12.tgz#a8a5ccac19c200f9dd49624cac6e19d7be1236a1" - integrity sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ== +"@babel/compat-data@^7.12.1", "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.13.15", "@babel/compat-data@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.0.tgz#a901128bce2ad02565df95e6ecbf195cf9465919" + integrity sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q== "@babel/core@7.12.3": version "7.12.3" @@ -51,19 +51,19 @@ source-map "^0.5.0" "@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.5", "@babel/core@^7.8.4": - version "7.13.14" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.14.tgz#8e46ebbaca460a63497c797e574038ab04ae6d06" - integrity sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA== + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.3.tgz#5395e30405f0776067fbd9cf0884f15bfb770a38" + integrity sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg== dependencies: "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.13.9" - "@babel/helper-compilation-targets" "^7.13.13" - "@babel/helper-module-transforms" "^7.13.14" - "@babel/helpers" "^7.13.10" - "@babel/parser" "^7.13.13" + "@babel/generator" "^7.14.3" + "@babel/helper-compilation-targets" "^7.13.16" + "@babel/helper-module-transforms" "^7.14.2" + "@babel/helpers" "^7.14.0" + "@babel/parser" "^7.14.3" "@babel/template" "^7.12.13" - "@babel/traverse" "^7.13.13" - "@babel/types" "^7.13.14" + "@babel/traverse" "^7.14.2" + "@babel/types" "^7.14.2" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -71,12 +71,12 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.12.1", "@babel/generator@^7.13.9": - version "7.13.9" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39" - integrity sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw== +"@babel/generator@^7.12.1", "@babel/generator@^7.14.2", "@babel/generator@^7.14.3": + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.3.tgz#0c2652d91f7bddab7cccc6ba8157e4f40dcedb91" + integrity sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA== dependencies: - "@babel/types" "^7.13.0" + "@babel/types" "^7.14.2" jsesc "^2.5.1" source-map "^0.5.0" @@ -95,39 +95,40 @@ "@babel/helper-explode-assignable-expression" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/helper-compilation-targets@^7.12.1", "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.10", "@babel/helper-compilation-targets@^7.13.13", "@babel/helper-compilation-targets@^7.13.8": - version "7.13.13" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.13.tgz#2b2972a0926474853f41e4adbc69338f520600e5" - integrity sha512-q1kcdHNZehBwD9jYPh3WyXcsFERi39X4I59I3NadciWtNDyZ6x+GboOxncFK0kXlKIv6BJm5acncehXWUjWQMQ== +"@babel/helper-compilation-targets@^7.12.1", "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.16": + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz#6e91dccf15e3f43e5556dffe32d860109887563c" + integrity sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA== dependencies: - "@babel/compat-data" "^7.13.12" + "@babel/compat-data" "^7.13.15" "@babel/helper-validator-option" "^7.12.17" browserslist "^4.14.5" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.12.1", "@babel/helper-create-class-features-plugin@^7.13.0": - version "7.13.11" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz#30d30a005bca2c953f5653fc25091a492177f4f6" - integrity sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw== +"@babel/helper-create-class-features-plugin@^7.12.1", "@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.14.0", "@babel/helper-create-class-features-plugin@^7.14.3": + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.3.tgz#832111bcf4f57ca57a4c5b1a000fc125abc6554a" + integrity sha512-BnEfi5+6J2Lte9LeiL6TxLWdIlEv9Woacc1qXzXBgbikcOzMRM2Oya5XGg/f/ngotv1ej2A/b+3iJH8wbS1+lQ== dependencies: - "@babel/helper-function-name" "^7.12.13" - "@babel/helper-member-expression-to-functions" "^7.13.0" + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-function-name" "^7.14.2" + "@babel/helper-member-expression-to-functions" "^7.13.12" "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/helper-replace-supers" "^7.13.0" + "@babel/helper-replace-supers" "^7.14.3" "@babel/helper-split-export-declaration" "^7.12.13" "@babel/helper-create-regexp-features-plugin@^7.12.13": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.17.tgz#a2ac87e9e319269ac655b8d4415e94d38d663cb7" - integrity sha512-p2VGmBu9oefLZ2nQpgnEnG0ZlRPvL8gAGvPUMQwUdaE8k49rOMuZpOwdQoy5qJf6K8jL3bcAMhVUlHAjIgJHUg== + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.3.tgz#149aa6d78c016e318c43e2409a0ae9c136a86688" + integrity sha512-JIB2+XJrb7v3zceV2XzDhGIB902CmKGSpSl4q2C6agU9SNLG/2V1RtFRGPG1Ajh9STj3+q6zJMOC+N/pp2P9DA== dependencies: "@babel/helper-annotate-as-pure" "^7.12.13" regexpu-core "^4.7.1" -"@babel/helper-define-polyfill-provider@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" - integrity sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg== +"@babel/helper-define-polyfill-provider@^0.2.2": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz#0525edec5094653a282688d34d846e4c75e9c0b6" + integrity sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew== dependencies: "@babel/helper-compilation-targets" "^7.13.0" "@babel/helper-module-imports" "^7.12.13" @@ -145,14 +146,14 @@ dependencies: "@babel/types" "^7.13.0" -"@babel/helper-function-name@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" - integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== +"@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz#397688b590760b6ef7725b5f0860c82427ebaac2" + integrity sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ== dependencies: "@babel/helper-get-function-arity" "^7.12.13" "@babel/template" "^7.12.13" - "@babel/types" "^7.12.13" + "@babel/types" "^7.14.2" "@babel/helper-get-function-arity@^7.12.13": version "7.12.13" @@ -162,14 +163,14 @@ "@babel/types" "^7.12.13" "@babel/helper-hoist-variables@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz#5d5882e855b5c5eda91e0cadc26c6e7a2c8593d8" - integrity sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g== + version "7.13.16" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz#1b1651249e94b51f8f0d33439843e33e39775b30" + integrity sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg== dependencies: - "@babel/traverse" "^7.13.0" - "@babel/types" "^7.13.0" + "@babel/traverse" "^7.13.15" + "@babel/types" "^7.13.16" -"@babel/helper-member-expression-to-functions@^7.13.0", "@babel/helper-member-expression-to-functions@^7.13.12": +"@babel/helper-member-expression-to-functions@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72" integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw== @@ -183,19 +184,19 @@ dependencies: "@babel/types" "^7.13.12" -"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.13.14": - version "7.13.14" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.13.14.tgz#e600652ba48ccb1641775413cb32cfa4e8b495ef" - integrity sha512-QuU/OJ0iAOSIatyVZmfqB0lbkVP0kDRiKj34xy+QNsnVZi/PA6BoSoreeqnxxa9EHFAIL0R9XOaAR/G9WlIy5g== +"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0", "@babel/helper-module-transforms@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz#ac1cc30ee47b945e3e0c4db12fa0c5389509dfe5" + integrity sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA== dependencies: "@babel/helper-module-imports" "^7.13.12" "@babel/helper-replace-supers" "^7.13.12" "@babel/helper-simple-access" "^7.13.12" "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/helper-validator-identifier" "^7.12.11" + "@babel/helper-validator-identifier" "^7.14.0" "@babel/template" "^7.12.13" - "@babel/traverse" "^7.13.13" - "@babel/types" "^7.13.14" + "@babel/traverse" "^7.14.2" + "@babel/types" "^7.14.2" "@babel/helper-optimise-call-expression@^7.12.13": version "7.12.13" @@ -218,17 +219,17 @@ "@babel/helper-wrap-function" "^7.13.0" "@babel/types" "^7.13.0" -"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" - integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== +"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.12", "@babel/helper-replace-supers@^7.14.3": + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.3.tgz#ca17b318b859d107f0e9b722d58cf12d94436600" + integrity sha512-Rlh8qEWZSTfdz+tgNV/N4gz1a0TMNwCUcENhMjHTHKp3LseYH5Jha0NSlyTQWMnjbYcwFt+bqAMqSLHVXkQ6UA== dependencies: "@babel/helper-member-expression-to-functions" "^7.13.12" "@babel/helper-optimise-call-expression" "^7.12.13" - "@babel/traverse" "^7.13.0" - "@babel/types" "^7.13.12" + "@babel/traverse" "^7.14.2" + "@babel/types" "^7.14.2" -"@babel/helper-simple-access@^7.12.13", "@babel/helper-simple-access@^7.13.12": +"@babel/helper-simple-access@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6" integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA== @@ -249,10 +250,10 @@ dependencies: "@babel/types" "^7.12.13" -"@babel/helper-validator-identifier@^7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" - integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== +"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" + integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== "@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.12.17": version "7.12.17" @@ -269,28 +270,28 @@ "@babel/traverse" "^7.13.0" "@babel/types" "^7.13.0" -"@babel/helpers@^7.12.1", "@babel/helpers@^7.13.10": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.10.tgz#fd8e2ba7488533cdeac45cc158e9ebca5e3c7df8" - integrity sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ== +"@babel/helpers@^7.12.1", "@babel/helpers@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.0.tgz#ea9b6be9478a13d6f961dbb5f36bf75e2f3b8f62" + integrity sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg== dependencies: "@babel/template" "^7.12.13" - "@babel/traverse" "^7.13.0" - "@babel/types" "^7.13.0" + "@babel/traverse" "^7.14.0" + "@babel/types" "^7.14.0" "@babel/highlight@^7.10.4", "@babel/highlight@^7.12.13": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1" - integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg== + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf" + integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg== dependencies: - "@babel/helper-validator-identifier" "^7.12.11" + "@babel/helper-validator-identifier" "^7.14.0" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.12.3", "@babel/parser@^7.13.13", "@babel/parser@^7.7.0": - version "7.13.13" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.13.tgz#42f03862f4aed50461e543270916b47dd501f0df" - integrity sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw== +"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.12.3", "@babel/parser@^7.14.2", "@babel/parser@^7.14.3", "@babel/parser@^7.7.0": + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.3.tgz#9b530eecb071fd0c93519df25c5ff9f14759f298" + integrity sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ== "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12": version "7.13.12" @@ -301,10 +302,10 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-proposal-optional-chaining" "^7.13.12" -"@babel/plugin-proposal-async-generator-functions@^7.12.1", "@babel/plugin-proposal-async-generator-functions@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz#87aacb574b3bc4b5603f6fe41458d72a5a2ec4b1" - integrity sha512-rPBnhj+WgoSmgq+4gQUtXx/vOcU+UYtjy1AA/aeD61Hwj410fwYyqfUcRP3lR8ucgliVJL/G7sXcNUecC75IXA== +"@babel/plugin-proposal-async-generator-functions@^7.12.1", "@babel/plugin-proposal-async-generator-functions@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.2.tgz#3a2085abbf5d5f962d480dbc81347385ed62eb1e" + integrity sha512-b1AM4F6fwck4N8ItZ/AtC4FP/cqZqmKRQ4FaTDutwSYyjuhtvsGEMLK4N/ztV/ImP40BjIDyMgBQAeAMsQYVFQ== dependencies: "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-remap-async-to-generator" "^7.13.0" @@ -326,6 +327,15 @@ "@babel/helper-create-class-features-plugin" "^7.13.0" "@babel/helper-plugin-utils" "^7.13.0" +"@babel/plugin-proposal-class-static-block@^7.13.11": + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.3.tgz#5a527e2cae4a4753119c3a3e7f64ecae8ccf1360" + integrity sha512-HEjzp5q+lWSjAgJtSluFDrGGosmwTgKwCXdDQZvhKsRlwv3YdkUEqxNrrjesJd+B9E9zvr1PVPVBvhYZ9msjvQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.14.3" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-class-static-block" "^7.12.13" + "@babel/plugin-proposal-decorators@7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.12.1.tgz#59271439fed4145456c41067450543aee332d15f" @@ -335,34 +345,34 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-decorators" "^7.12.1" -"@babel/plugin-proposal-dynamic-import@^7.12.1", "@babel/plugin-proposal-dynamic-import@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d" - integrity sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ== +"@babel/plugin-proposal-dynamic-import@^7.12.1", "@babel/plugin-proposal-dynamic-import@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.2.tgz#01ebabd7c381cff231fa43e302939a9de5be9d9f" + integrity sha512-oxVQZIWFh91vuNEMKltqNsKLFWkOIyJc95k2Gv9lWVyDfPUQGSSlbDEgWuJUU1afGE9WwlzpucMZ3yDRHIItkA== dependencies: "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-proposal-export-namespace-from@^7.12.1", "@babel/plugin-proposal-export-namespace-from@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d" - integrity sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw== +"@babel/plugin-proposal-export-namespace-from@^7.12.1", "@babel/plugin-proposal-export-namespace-from@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.2.tgz#62542f94aa9ce8f6dba79eec698af22112253791" + integrity sha512-sRxW3z3Zp3pFfLAgVEvzTFutTXax837oOatUIvSG9o5gRj9mKwm3br1Se5f4QalTQs9x4AzlA/HrCWbQIHASUQ== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.12.1", "@babel/plugin-proposal-json-strings@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b" - integrity sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q== +"@babel/plugin-proposal-json-strings@^7.12.1", "@babel/plugin-proposal-json-strings@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.2.tgz#830b4e2426a782e8b2878fbfe2cba85b70cbf98c" + integrity sha512-w2DtsfXBBJddJacXMBhElGEYqCZQqN99Se1qeYn8DVLB33owlrlLftIbMzn5nz1OITfDVknXF433tBrLEAOEjA== dependencies: "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.12.1", "@babel/plugin-proposal-logical-assignment-operators@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a" - integrity sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A== +"@babel/plugin-proposal-logical-assignment-operators@^7.12.1", "@babel/plugin-proposal-logical-assignment-operators@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.2.tgz#222348c080a1678e0e74ea63fe76f275882d1fd7" + integrity sha512-1JAZtUrqYyGsS7IDmFeaem+/LJqujfLZ2weLR9ugB0ufUPjzf8cguyVT1g5im7f7RXxuLq1xUxEzvm68uYRtGg== dependencies: "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" @@ -375,10 +385,10 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3" - integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.2.tgz#425b11dc62fc26939a2ab42cbba680bdf5734546" + integrity sha512-ebR0zU9OvI2N4qiAC38KIAK75KItpIPTpAtd2r4OZmMFeKbKJpUFLYP2EuDut82+BmYi8sz42B+TfTptJ9iG5Q== dependencies: "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" @@ -391,29 +401,29 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-numeric-separator@^7.12.1", "@babel/plugin-proposal-numeric-separator@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db" - integrity sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w== +"@babel/plugin-proposal-numeric-separator@^7.12.1", "@babel/plugin-proposal-numeric-separator@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.2.tgz#82b4cc06571143faf50626104b335dd71baa4f9e" + integrity sha512-DcTQY9syxu9BpU3Uo94fjCB3LN9/hgPS8oUL7KrSW3bA2ePrKZZPJcc5y0hoJAM9dft3pGfErtEUvxXQcfLxUg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a" - integrity sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g== +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.2.tgz#e17d418f81cc103fedd4ce037e181c8056225abc" + integrity sha512-hBIQFxwZi8GIp934+nj5uV31mqclC1aYDhctDu5khTi9PCCUOczyy0b34W0oE9U/eJXiqQaKyVsmjeagOaSlbw== dependencies: - "@babel/compat-data" "^7.13.8" - "@babel/helper-compilation-targets" "^7.13.8" + "@babel/compat-data" "^7.14.0" + "@babel/helper-compilation-targets" "^7.13.16" "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.13.0" + "@babel/plugin-transform-parameters" "^7.14.2" -"@babel/plugin-proposal-optional-catch-binding@^7.12.1", "@babel/plugin-proposal-optional-catch-binding@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107" - integrity sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA== +"@babel/plugin-proposal-optional-catch-binding@^7.12.1", "@babel/plugin-proposal-optional-catch-binding@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.2.tgz#150d4e58e525b16a9a1431bd5326c4eed870d717" + integrity sha512-XtkJsmJtBaUbOxZsNk0Fvrv8eiqgneug0A6aqLFZ4TSkar2L5dSXWcnUKHgmjJt49pyB/6ZHvkr3dPgl9MOWRQ== dependencies: "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" @@ -427,10 +437,10 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.12.1", "@babel/plugin-proposal-optional-chaining@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz#ba9feb601d422e0adea6760c2bd6bbb7bfec4866" - integrity sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ== +"@babel/plugin-proposal-optional-chaining@^7.12.1", "@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.2.tgz#df8171a8b9c43ebf4c1dabe6311b432d83e1b34e" + integrity sha512-qQByMRPwMZJainfig10BoaDldx/+VDtNcrA7qdNaEOAj6VXud+gfrkA8j4CRAU5HjnWREXqIpSpH30qZX1xivA== dependencies: "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" @@ -444,6 +454,16 @@ "@babel/helper-create-class-features-plugin" "^7.13.0" "@babel/helper-plugin-utils" "^7.13.0" +"@babel/plugin-proposal-private-property-in-object@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.0.tgz#b1a1f2030586b9d3489cc26179d2eb5883277636" + integrity sha512-59ANdmEwwRUkLjB7CRtwJxxwtjESw+X2IePItA+RGQh+oy5RmpCh/EvVVvh5XQc3yxsm5gtv0+i9oBZhaDNVTg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.12.13" + "@babel/helper-create-class-features-plugin" "^7.14.0" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-private-property-in-object" "^7.14.0" + "@babel/plugin-proposal-unicode-property-regex@^7.12.1", "@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba" @@ -473,6 +493,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@babel/plugin-syntax-class-static-block@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.12.13.tgz#8e3d674b0613e67975ceac2776c97b60cafc5c9c" + integrity sha512-ZmKQ0ZXR0nYpHZIIuj9zE7oIqCx2hw9TKi+lIo73NNrMPAZGHfS92/VRV0ZmPj6H2ffBgyFHXvJ5NYsNeEaP2A== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + "@babel/plugin-syntax-decorators@^7.12.1": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.13.tgz#fac829bf3c7ef4a1bc916257b403e58c6bdaf648" @@ -564,6 +591,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-private-property-in-object@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.0.tgz#762a4babec61176fec6c88480dec40372b140c0b" + integrity sha512-bda3xF8wGl5/5btF794utNOL0Jw+9jE5C1sLZcoK7c4uonE/y3iQiyG+KbkF3WBV/paX58VCpjhxLPkdj5Fe4w== + dependencies: + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/plugin-syntax-top-level-await@^7.12.1", "@babel/plugin-syntax-top-level-await@^7.12.13", "@babel/plugin-syntax-top-level-await@^7.8.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178" @@ -601,23 +635,23 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-block-scoping@^7.12.1", "@babel/plugin-transform-block-scoping@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.13.tgz#f36e55076d06f41dfd78557ea039c1b581642e61" - integrity sha512-Pxwe0iqWJX4fOOM2kEZeUuAxHMWb9nK+9oh5d11bsLoB0xMg+mkDpt0eYuDZB7ETrY9bbcVlKUGTOGWy7BHsMQ== +"@babel/plugin-transform-block-scoping@^7.12.1", "@babel/plugin-transform-block-scoping@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.2.tgz#761cb12ab5a88d640ad4af4aa81f820e6b5fdf5c" + integrity sha512-neZZcP19NugZZqNwMTH+KoBjx5WyvESPSIOQb4JHpfd+zPfqcH65RMu5xJju5+6q/Y2VzYrleQTr+b6METyyxg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b" - integrity sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g== +"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.2.tgz#3f1196c5709f064c252ad056207d87b7aeb2d03d" + integrity sha512-7oafAVcucHquA/VZCsXv/gmuiHeYd64UJyyTYU+MPfNu0KeNlxw06IeENBO8bJjXVbolu+j1MM5aKQtH1OMCNg== dependencies: "@babel/helper-annotate-as-pure" "^7.12.13" - "@babel/helper-function-name" "^7.12.13" + "@babel/helper-function-name" "^7.14.2" "@babel/helper-optimise-call-expression" "^7.12.13" "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-replace-supers" "^7.13.0" + "@babel/helper-replace-supers" "^7.13.12" "@babel/helper-split-export-declaration" "^7.12.13" globals "^11.1.0" @@ -628,10 +662,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.13.0" -"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz#c5dce270014d4e1ebb1d806116694c12b7028963" - integrity sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA== +"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.13.17": + version "7.13.17" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.17.tgz#678d96576638c19d5b36b332504d3fd6e06dea27" + integrity sha512-UAUqiLv+uRLO+xuBKKMEpC+t7YRNVRqBsWWq1yKXbBZBje/t3IXCiSinZhjn/DC3qzBfICeYd2EFGEbHsh5RLA== dependencies: "@babel/helper-plugin-utils" "^7.13.0" @@ -695,23 +729,23 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-modules-amd@^7.12.1", "@babel/plugin-transform-modules-amd@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz#19f511d60e3d8753cc5a6d4e775d3a5184866cc3" - integrity sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ== +"@babel/plugin-transform-modules-amd@^7.12.1", "@babel/plugin-transform-modules-amd@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.2.tgz#6622806fe1a7c07a1388444222ef9535f2ca17b0" + integrity sha512-hPC6XBswt8P3G2D1tSV2HzdKvkqOpmbyoy+g73JG0qlF/qx2y3KaMmXb1fLrpmWGLZYA0ojCvaHdzFWjlmV+Pw== dependencies: - "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-module-transforms" "^7.14.2" "@babel/helper-plugin-utils" "^7.13.0" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.12.1", "@babel/plugin-transform-modules-commonjs@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz#7b01ad7c2dcf2275b06fa1781e00d13d420b3e1b" - integrity sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw== +"@babel/plugin-transform-modules-commonjs@^7.12.1", "@babel/plugin-transform-modules-commonjs@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz#52bc199cb581e0992edba0f0f80356467587f161" + integrity sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ== dependencies: - "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-module-transforms" "^7.14.0" "@babel/helper-plugin-utils" "^7.13.0" - "@babel/helper-simple-access" "^7.12.13" + "@babel/helper-simple-access" "^7.13.12" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-systemjs@^7.12.1", "@babel/plugin-transform-modules-systemjs@^7.13.8": @@ -725,12 +759,12 @@ "@babel/helper-validator-identifier" "^7.12.11" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.12.1", "@babel/plugin-transform-modules-umd@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz#8a3d96a97d199705b9fd021580082af81c06e70b" - integrity sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw== +"@babel/plugin-transform-modules-umd@^7.12.1", "@babel/plugin-transform-modules-umd@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz#2f8179d1bbc9263665ce4a65f305526b2ea8ac34" + integrity sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw== dependencies: - "@babel/helper-module-transforms" "^7.13.0" + "@babel/helper-module-transforms" "^7.14.0" "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-named-capturing-groups-regex@^7.12.1", "@babel/plugin-transform-named-capturing-groups-regex@^7.12.13": @@ -755,10 +789,10 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/helper-replace-supers" "^7.12.13" -"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007" - integrity sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw== +"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.14.2": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.2.tgz#e4290f72e0e9e831000d066427c4667098decc31" + integrity sha512-NxoVmA3APNCC1JdMXkdYXuQS+EMdqy0vIwyDHeKHiJKRxmp1qGSdb0JLEIoPRhkx6H/8Qi3RJ3uqOCYw8giy9A== dependencies: "@babel/helper-plugin-utils" "^7.13.0" @@ -784,11 +818,11 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-transform-react-display-name@^7.12.1", "@babel/plugin-transform-react-display-name@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz#c28effd771b276f4647411c9733dbb2d2da954bd" - integrity sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA== + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.14.2.tgz#2e854544d42ab3bb9c21f84e153d62e800fbd593" + integrity sha512-zCubvP+jjahpnFJvPaHPiGVfuVUjXHhFvJKQdNnsmSsiU9kR/rCZ41jHc++tERD2zV+p7Hr6is+t5b6iWTCqSw== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-react-jsx-development@^7.12.1", "@babel/plugin-transform-react-jsx-development@^7.12.17": version "7.12.17" @@ -805,22 +839,22 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-react-jsx-source@^7.12.1": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.12.13.tgz#051d76126bee5c9a6aa3ba37be2f6c1698856bcb" - integrity sha512-O5JJi6fyfih0WfDgIJXksSPhGP/G0fQpfxYy87sDc+1sFmsCS6wr3aAn+whbzkhbjtq4VMqLRaSzR6IsshIC0Q== + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.14.2.tgz#2620b57e7de775c0687f65d464026d15812941da" + integrity sha512-OMorspVyjxghAjzgeAWc6O7W7vHbJhV69NeTGdl9Mxgz6PaweAuo7ffB9T5A1OQ9dGcw0As4SYMUhyNC4u7mVg== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-transform-react-jsx@^7.12.1", "@babel/plugin-transform-react-jsx@^7.12.17", "@babel/plugin-transform-react-jsx@^7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.13.12.tgz#1df5dfaf0f4b784b43e96da6f28d630e775f68b3" - integrity sha512-jcEI2UqIcpCqB5U5DRxIl0tQEProI2gcu+g8VTIqxLO5Iidojb4d77q+fwGseCvd8af/lJ9masp4QWzBXFE2xA== + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.3.tgz#0e26597805cf0862da735f264550933c38babb66" + integrity sha512-uuxuoUNVhdgYzERiHHFkE4dWoJx+UFVyuAl0aqN8P2/AKFHwqgUC5w2+4/PjpKXJsFgBlYAFXlUmDQ3k3DUkXw== dependencies: "@babel/helper-annotate-as-pure" "^7.12.13" "@babel/helper-module-imports" "^7.13.12" "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-jsx" "^7.12.13" - "@babel/types" "^7.13.12" + "@babel/types" "^7.14.2" "@babel/plugin-transform-react-pure-annotations@^7.12.1": version "7.12.1" @@ -830,10 +864,10 @@ "@babel/helper-annotate-as-pure" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-regenerator@^7.12.1", "@babel/plugin-transform-regenerator@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.13.tgz#b628bcc9c85260ac1aeb05b45bde25210194a2f5" - integrity sha512-lxb2ZAvSLyJ2PEe47hoGWPmW22v7CtSl9jW8mingV4H2sEX/JOcrAj2nPuGWi56ERUm2bUpjKzONAuT6HCn2EA== +"@babel/plugin-transform-regenerator@^7.12.1", "@babel/plugin-transform-regenerator@^7.13.15": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz#e5eb28945bf8b6563e7f818945f966a8d2997f39" + integrity sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ== dependencies: regenerator-transform "^0.14.2" @@ -891,11 +925,11 @@ "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-transform-typescript@^7.12.1": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz#4a498e1f3600342d2a9e61f60131018f55774853" - integrity sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ== + version "7.14.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.3.tgz#44f67f725a60cccee33d9d6fee5e4f338258f34f" + integrity sha512-G5Bb5pY6tJRTC4ag1visSgiDoGgJ1u1fMUgmc2ijLkcIdzP83Q1qyZX4ggFQ/SkR+PNOatkaYC+nKcTlpsX4ag== dependencies: - "@babel/helper-create-class-features-plugin" "^7.13.0" + "@babel/helper-create-class-features-plugin" "^7.14.3" "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-typescript" "^7.12.13" @@ -987,30 +1021,33 @@ semver "^5.5.0" "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.8.4": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.13.12.tgz#6dff470478290582ac282fb77780eadf32480237" - integrity sha512-JzElc6jk3Ko6zuZgBtjOd01pf9yYDEIH8BcqVuYIuOkzOwDesoa/Nz4gIo4lBG6K861KTV9TvIgmFuT6ytOaAA== + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.2.tgz#e80612965da73579c84ad2f963c2359c71524ed5" + integrity sha512-7dD7lVT8GMrE73v4lvDEb85cgcQhdES91BSD7jS/xjC6QY8PnRhux35ac+GCpbiRhp8crexBvZZqnaL6VrY8TQ== dependencies: - "@babel/compat-data" "^7.13.12" - "@babel/helper-compilation-targets" "^7.13.10" + "@babel/compat-data" "^7.14.0" + "@babel/helper-compilation-targets" "^7.13.16" "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-validator-option" "^7.12.17" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.13.12" - "@babel/plugin-proposal-async-generator-functions" "^7.13.8" + "@babel/plugin-proposal-async-generator-functions" "^7.14.2" "@babel/plugin-proposal-class-properties" "^7.13.0" - "@babel/plugin-proposal-dynamic-import" "^7.13.8" - "@babel/plugin-proposal-export-namespace-from" "^7.12.13" - "@babel/plugin-proposal-json-strings" "^7.13.8" - "@babel/plugin-proposal-logical-assignment-operators" "^7.13.8" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.13.8" - "@babel/plugin-proposal-numeric-separator" "^7.12.13" - "@babel/plugin-proposal-object-rest-spread" "^7.13.8" - "@babel/plugin-proposal-optional-catch-binding" "^7.13.8" - "@babel/plugin-proposal-optional-chaining" "^7.13.12" + "@babel/plugin-proposal-class-static-block" "^7.13.11" + "@babel/plugin-proposal-dynamic-import" "^7.14.2" + "@babel/plugin-proposal-export-namespace-from" "^7.14.2" + "@babel/plugin-proposal-json-strings" "^7.14.2" + "@babel/plugin-proposal-logical-assignment-operators" "^7.14.2" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.2" + "@babel/plugin-proposal-numeric-separator" "^7.14.2" + "@babel/plugin-proposal-object-rest-spread" "^7.14.2" + "@babel/plugin-proposal-optional-catch-binding" "^7.14.2" + "@babel/plugin-proposal-optional-chaining" "^7.14.2" "@babel/plugin-proposal-private-methods" "^7.13.0" + "@babel/plugin-proposal-private-property-in-object" "^7.14.0" "@babel/plugin-proposal-unicode-property-regex" "^7.12.13" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.12.13" "@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" @@ -1020,14 +1057,15 @@ "@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.0" "@babel/plugin-syntax-top-level-await" "^7.12.13" "@babel/plugin-transform-arrow-functions" "^7.13.0" "@babel/plugin-transform-async-to-generator" "^7.13.0" "@babel/plugin-transform-block-scoped-functions" "^7.12.13" - "@babel/plugin-transform-block-scoping" "^7.12.13" - "@babel/plugin-transform-classes" "^7.13.0" + "@babel/plugin-transform-block-scoping" "^7.14.2" + "@babel/plugin-transform-classes" "^7.14.2" "@babel/plugin-transform-computed-properties" "^7.13.0" - "@babel/plugin-transform-destructuring" "^7.13.0" + "@babel/plugin-transform-destructuring" "^7.13.17" "@babel/plugin-transform-dotall-regex" "^7.12.13" "@babel/plugin-transform-duplicate-keys" "^7.12.13" "@babel/plugin-transform-exponentiation-operator" "^7.12.13" @@ -1035,16 +1073,16 @@ "@babel/plugin-transform-function-name" "^7.12.13" "@babel/plugin-transform-literals" "^7.12.13" "@babel/plugin-transform-member-expression-literals" "^7.12.13" - "@babel/plugin-transform-modules-amd" "^7.13.0" - "@babel/plugin-transform-modules-commonjs" "^7.13.8" + "@babel/plugin-transform-modules-amd" "^7.14.2" + "@babel/plugin-transform-modules-commonjs" "^7.14.0" "@babel/plugin-transform-modules-systemjs" "^7.13.8" - "@babel/plugin-transform-modules-umd" "^7.13.0" + "@babel/plugin-transform-modules-umd" "^7.14.0" "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13" "@babel/plugin-transform-new-target" "^7.12.13" "@babel/plugin-transform-object-super" "^7.12.13" - "@babel/plugin-transform-parameters" "^7.13.0" + "@babel/plugin-transform-parameters" "^7.14.2" "@babel/plugin-transform-property-literals" "^7.12.13" - "@babel/plugin-transform-regenerator" "^7.12.13" + "@babel/plugin-transform-regenerator" "^7.13.15" "@babel/plugin-transform-reserved-words" "^7.12.13" "@babel/plugin-transform-shorthand-properties" "^7.12.13" "@babel/plugin-transform-spread" "^7.13.0" @@ -1054,10 +1092,10 @@ "@babel/plugin-transform-unicode-escapes" "^7.12.13" "@babel/plugin-transform-unicode-regex" "^7.12.13" "@babel/preset-modules" "^0.1.4" - "@babel/types" "^7.13.12" - babel-plugin-polyfill-corejs2 "^0.1.4" - babel-plugin-polyfill-corejs3 "^0.1.3" - babel-plugin-polyfill-regenerator "^0.1.2" + "@babel/types" "^7.14.2" + babel-plugin-polyfill-corejs2 "^0.2.0" + babel-plugin-polyfill-corejs3 "^0.2.0" + babel-plugin-polyfill-regenerator "^0.2.0" core-js-compat "^3.9.0" semver "^6.3.0" @@ -1106,9 +1144,9 @@ "@babel/plugin-transform-typescript" "^7.12.1" "@babel/runtime-corejs3@^7.10.2": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.13.10.tgz#14c3f4c85de22ba88e8e86685d13e8861a82fe86" - integrity sha512-x/XYVQ1h684pp1mJwOV4CyvqZXqbc8CMsMGUnAbuc82ZCdv1U63w5RSUzgDSXQHG5Rps/kiksH6g2D5BuaKyXg== + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.14.0.tgz#6bf5fbc0b961f8e3202888cb2cd0fb7a0a9a3f66" + integrity sha512-0R0HTZWHLk6G8jIk0FtoX+AatCtKnswS98VhXwGImFc759PJRp4Tru0PQYZofyijTFUr+gT8Mu7sgXVJLQ0ceg== dependencies: core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" @@ -1120,10 +1158,10 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" - integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" + integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== dependencies: regenerator-runtime "^0.13.4" @@ -1136,27 +1174,26 @@ "@babel/parser" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13", "@babel/traverse@^7.7.0": - version "7.13.13" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.13.tgz#39aa9c21aab69f74d948a486dd28a2dbdbf5114d" - integrity sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg== +"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.1", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0", "@babel/traverse@^7.14.2", "@babel/traverse@^7.7.0": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.2.tgz#9201a8d912723a831c2679c7ebbf2fe1416d765b" + integrity sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA== dependencies: "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.13.9" - "@babel/helper-function-name" "^7.12.13" + "@babel/generator" "^7.14.2" + "@babel/helper-function-name" "^7.14.2" "@babel/helper-split-export-declaration" "^7.12.13" - "@babel/parser" "^7.13.13" - "@babel/types" "^7.13.13" + "@babel/parser" "^7.14.2" + "@babel/types" "^7.14.2" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.6", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.13", "@babel/types@^7.13.14", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": - version "7.13.14" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.14.tgz#c35a4abb15c7cd45a2746d78ab328e362cbace0d" - integrity sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ== +"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.6", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.14.2" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.2.tgz#4208ae003107ef8a057ea8333e56eb64d2f6a2c3" + integrity sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw== dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - lodash "^4.17.19" + "@babel/helper-validator-identifier" "^7.14.0" to-fast-properties "^2.0.0" "@bcoe/v8-coverage@^0.2.3": @@ -1203,10 +1240,10 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== -"@eslint/eslintrc@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.0.tgz#99cc0a0584d72f1df38b900fb062ba995f395547" - integrity sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog== +"@eslint/eslintrc@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.1.tgz#442763b88cecbe3ee0ec7ca6d6dd6168550cbf14" + integrity sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ== dependencies: ajv "^6.12.4" debug "^4.1.1" @@ -1471,14 +1508,14 @@ chalk "^4.0.0" "@material-ui/core@^4.11.3": - version "4.11.3" - resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.11.3.tgz#f22e41775b0bd075e36a7a093d43951bf7f63850" - integrity sha512-Adt40rGW6Uds+cAyk3pVgcErpzU/qxc7KBR94jFHBYretU4AtWZltYcNsbeMn9tXL86jjVL1kuGcIHsgLgFGRw== + version "4.11.4" + resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.11.4.tgz#4fb9fe5dec5dcf780b687e3a40cff78b2b9640a4" + integrity sha512-oqb+lJ2Dl9HXI9orc6/aN8ZIAMkeThufA5iZELf2LQeBn2NtjVilF5D2w7e9RpntAzDb4jK5DsVhkfOvFY/8fg== dependencies: "@babel/runtime" "^7.4.4" - "@material-ui/styles" "^4.11.3" + "@material-ui/styles" "^4.11.4" "@material-ui/system" "^4.11.3" - "@material-ui/types" "^5.1.0" + "@material-ui/types" "5.1.0" "@material-ui/utils" "^4.11.2" "@types/react-transition-group" "^4.2.0" clsx "^1.0.4" @@ -1496,9 +1533,9 @@ "@babel/runtime" "^7.4.4" "@material-ui/lab@^4.0.0-alpha.57": - version "4.0.0-alpha.57" - resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.57.tgz#e8961bcf6449e8a8dabe84f2700daacfcafbf83a" - integrity sha512-qo/IuIQOmEKtzmRD2E4Aa6DB4A87kmY6h0uYhjUmrrgmEAgbbw9etXpWPVXuRK6AGIQCjFzV6WO2i21m1R4FCw== + version "4.0.0-alpha.58" + resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.58.tgz#c7ebb66f49863c5acbb20817163737caa299fafc" + integrity sha512-GKHlJqLxUeHH3L3dGQ48ZavYrqGOTXkFkiEiuYMAnAvXAZP4rhMIqeHOPXSUQan4Bd8QnafDcpovOSLnadDmKw== dependencies: "@babel/runtime" "^7.4.4" "@material-ui/utils" "^4.11.2" @@ -1506,14 +1543,14 @@ prop-types "^15.7.2" react-is "^16.8.0 || ^17.0.0" -"@material-ui/styles@^4.11.3": - version "4.11.3" - resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.11.3.tgz#1b8d97775a4a643b53478c895e3f2a464e8916f2" - integrity sha512-HzVzCG+PpgUGMUYEJ2rTEmQYeonGh41BYfILNFb/1ueqma+p1meSdu4RX6NjxYBMhf7k+jgfHFTTz+L1SXL/Zg== +"@material-ui/styles@^4.11.4": + version "4.11.4" + resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.11.4.tgz#eb9dfccfcc2d208243d986457dff025497afa00d" + integrity sha512-KNTIZcnj/zprG5LW0Sao7zw+yG3O35pviHzejMdcSGCdWbiO8qzRgOYL8JAxAsWBKOKYwVZxXtHWaB5T2Kvxew== dependencies: "@babel/runtime" "^7.4.4" "@emotion/hash" "^0.8.0" - "@material-ui/types" "^5.1.0" + "@material-ui/types" "5.1.0" "@material-ui/utils" "^4.11.2" clsx "^1.0.4" csstype "^2.5.2" @@ -1538,6 +1575,11 @@ csstype "^2.5.2" prop-types "^15.7.2" +"@material-ui/types@5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-5.1.0.tgz#efa1c7a0b0eaa4c7c87ac0390445f0f88b0d88f2" + integrity sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A== + "@material-ui/types@^4.1.1": version "4.1.1" resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-4.1.1.tgz#b65e002d926089970a3271213a3ad7a21b17f02b" @@ -1545,11 +1587,6 @@ dependencies: "@types/react" "*" -"@material-ui/types@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@material-ui/types/-/types-5.1.0.tgz#efa1c7a0b0eaa4c7c87ac0390445f0f88b0d88f2" - integrity sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A== - "@material-ui/utils@^4.11.2": version "4.11.2" resolved "https://registry.yarnpkg.com/@material-ui/utils/-/utils-4.11.2.tgz#f1aefa7e7dff2ebcb97d31de51aecab1bb57540a" @@ -1674,9 +1711,9 @@ integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== "@sinonjs/commons@^1.7.0": - version "1.8.2" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.2.tgz#858f5c4b48d80778fde4b9d541f27edc0d56488b" - integrity sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw== + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== dependencies: type-detect "4.0.8" @@ -1805,10 +1842,10 @@ dependencies: defer-to-connect "^1.0.1" -"@types/anymatch@*": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" - integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7": version "7.1.14" @@ -1848,6 +1885,20 @@ resolved "https://registry.yarnpkg.com/@types/chroma-js/-/chroma-js-2.1.3.tgz#0b03d737ff28fad10eb884e0c6cedd5ffdc4ba0a" integrity sha512-1xGPhoSGY1CPmXLCBcjVZSQinFjL26vlR8ZqprsBWiFyED4JacJJ9zHhh5aaUXqbY9B37mKQ73nlydVAXmr1+g== +"@types/convict-format-with-validator@^6.0.2": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/convict-format-with-validator/-/convict-format-with-validator-6.0.2.tgz#5275be2815a955f1891e0065c6c2be85c79f9a56" + integrity sha512-H8AfvvijYaFRE5sLje5ugldjGcwOqzre/TzrrWfrMHtVUhoN5eaUf6BqkFB9QJ24iUUoCDCceej2KTmbS/GaTg== + dependencies: + "@types/convict" "*" + +"@types/convict@*", "@types/convict@^6.0.1": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@types/convict/-/convict-6.0.2.tgz#0827a974620931c69b64b3a52359f42de753e9fc" + integrity sha512-lYFEgTO7c36/Sq8+FKTn64jA/6B7xLeKv0/NZkWIaavMlBzlU5zgiyfJvl9rOTCxvlUT2rXTD6In5DmEGTK5+w== + dependencies: + "@types/node" "*" + "@types/debug@^4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" @@ -1859,9 +1910,9 @@ integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== "@types/eslint@^7.2.6": - version "7.2.8" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.8.tgz#45cd802380fcc352e5680e1781d43c50916f12ee" - integrity sha512-RTKvBsfz0T8CKOGZMfuluDNyMFHnu5lvNr4hWEsQeHXH6FcmIDIozOyWMh36nLGMwVd5UFNXC2xztA8lln22MQ== + version "7.2.12" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.12.tgz#fefaa48a4db2415b621fe315e4baeedde525927e" + integrity sha512-HjikV/jX6e0Pg4DcB+rtOBKSrG6w5IaxWpmi3efL/eLxMz5lZTK+W1DKERrX5a+mNzL78axfsDNXu7JHFP4uLg== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -1948,10 +1999,15 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== -"@types/node@*", "@types/node@^14.14.37", "@types/node@^14.6.2": - version "14.14.37" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e" - integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw== +"@types/node@*": + version "15.6.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.1.tgz#32d43390d5c62c5b6ec486a9bc9c59544de39a08" + integrity sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA== + +"@types/node@^14.14.37", "@types/node@^14.6.2": + version "14.17.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.1.tgz#5e07e0cb2ff793aa7a1b41deae76221e6166049f" + integrity sha512-/tpUyFD7meeooTRwl3sYlihx2BrJE7q9XF71EguPFIySj9B7qgnRtHsHTho+0AUm4m1SvWGm6uSncrR94q6Vtw== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -1978,12 +2034,12 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== -"@types/react-dom@^16.9.12": - version "16.9.12" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.12.tgz#55cd6b17e73922edb9545e5355a0016c1734e6f4" - integrity sha512-i7NPZZpPte3jtVOoW+eLB7G/jsX5OM6GqQnH+lC0nq0rqwlK0x8WcMEvYDgFWqWhWMlTltTimzdMax6wYfZssA== +"@types/react-dom@^17.0.3": + version "17.0.5" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.5.tgz#df44eed5b8d9e0b13bb0cd38e0ea6572a1231227" + integrity sha512-ikqukEhH4H9gr4iJCmQVNzTB307kROe3XFfHAOTxOXPOw7lAoEXnM5KWTkzeANGL5Ce6ABfiMl/zJBYNi7ObmQ== dependencies: - "@types/react" "^16" + "@types/react" "*" "@types/react-redux@^7.1.16": version "7.1.16" @@ -2002,19 +2058,10 @@ dependencies: "@types/react" "*" -"@types/react@*": - version "17.0.3" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.3.tgz#ba6e215368501ac3826951eef2904574c262cc79" - integrity sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/react@^16", "@types/react@^16.10.2": - version "16.14.5" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.5.tgz#2c39b5cadefaf4829818f9219e5e093325979f4d" - integrity sha512-YRRv9DNZhaVTVRh9Wmmit7Y0UFhEVqXqCSw3uazRWMxa2x85hWQZ5BN24i7GXZbaclaLXEcodEeIHsjBA8eAMw== +"@types/react@*", "@types/react@^17.0.3": + version "17.0.8" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.8.tgz#fe76e3ba0fbb5602704110fd1e3035cf394778e3" + integrity sha512-3sx4c0PbXujrYAKwXxNONXUtRp9C+hE2di0IuxFyf5BELD+B+AXL8G7QrmSKhVwKZDbv0igiAjQAMhXj8Yg3aw== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -2064,15 +2111,15 @@ source-map "^0.7.3" "@types/webpack@^4.41.8": - version "4.41.27" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.27.tgz#f47da488c8037e7f1b2dbf2714fbbacb61ec0ffc" - integrity sha512-wK/oi5gcHi72VMTbOaQ70VcDxSQ1uX8S2tukBK9ARuGXrYM/+u4ou73roc7trXDNmCxCoerE8zruQqX/wuHszA== + version "4.41.29" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.29.tgz#2e66c1de8223c440366469415c50a47d97625773" + integrity sha512-6pLaORaVNZxiB3FSHbyBiWM7QdazAWda1zvAq4SbZObZqHSDbWLi62iFdblVea6SK9eyBIVp5yHhKt/yNQdR7Q== dependencies: - "@types/anymatch" "*" "@types/node" "*" "@types/tapable" "^1" "@types/uglify-js" "*" "@types/webpack-sources" "*" + anymatch "^3.0.0" source-map "^0.6.0" "@types/yargs-parser@*": @@ -2088,12 +2135,12 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^4.20.0", "@typescript-eslint/eslint-plugin@^4.5.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.20.0.tgz#9d8794bd99aad9153092ad13c96164e3082e9a92" - integrity sha512-sw+3HO5aehYqn5w177z2D82ZQlqHCwcKSMboueo7oE4KU9QiC0SAgfS/D4z9xXvpTc8Bt41Raa9fBR8T2tIhoQ== + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.25.0.tgz#d82657b6ab4caa4c3f888ff923175fadc2f31f2a" + integrity sha512-Qfs3dWkTMKkKwt78xp2O/KZQB8MPS1UQ5D3YW2s6LQWBE1074BE+Rym+b1pXZIX3M3fSvPUDaCvZLKV2ylVYYQ== dependencies: - "@typescript-eslint/experimental-utils" "4.20.0" - "@typescript-eslint/scope-manager" "4.20.0" + "@typescript-eslint/experimental-utils" "4.25.0" + "@typescript-eslint/scope-manager" "4.25.0" debug "^4.1.1" functional-red-black-tree "^1.0.1" lodash "^4.17.15" @@ -2121,15 +2168,15 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/experimental-utils@4.20.0", "@typescript-eslint/experimental-utils@^4.0.1": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.20.0.tgz#a8ab2d7b61924f99042b7d77372996d5f41dc44b" - integrity sha512-sQNlf6rjLq2yB5lELl3gOE7OuoA/6IVXJUJ+Vs7emrQMva14CkOwyQwD7CW+TkmOJ4Q/YGmoDLmbfFrpGmbKng== +"@typescript-eslint/experimental-utils@4.25.0", "@typescript-eslint/experimental-utils@^4.0.1": + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.25.0.tgz#b2febcfa715d2c1806fd5f0335193a6cd270df54" + integrity sha512-f0doRE76vq7NEEU0tw+ajv6CrmPelw5wLoaghEHkA2dNLFb3T/zJQqGPQ0OYt5XlZaS13MtnN+GTPCuUVg338w== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.20.0" - "@typescript-eslint/types" "4.20.0" - "@typescript-eslint/typescript-estree" "4.20.0" + "@typescript-eslint/scope-manager" "4.25.0" + "@typescript-eslint/types" "4.25.0" + "@typescript-eslint/typescript-estree" "4.25.0" eslint-scope "^5.0.0" eslint-utils "^2.0.0" @@ -2155,32 +2202,32 @@ eslint-visitor-keys "^1.1.0" "@typescript-eslint/parser@^4.20.0", "@typescript-eslint/parser@^4.4.1", "@typescript-eslint/parser@^4.5.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.20.0.tgz#8dd403c8b4258b99194972d9799e201b8d083bdd" - integrity sha512-m6vDtgL9EABdjMtKVw5rr6DdeMCH3OA1vFb0dAyuZSa3e5yw1YRzlwFnm9knma9Lz6b2GPvoNSa8vOXrqsaglA== + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.25.0.tgz#6b2cb6285aa3d55bfb263c650739091b0f19aceb" + integrity sha512-OZFa1SKyEJpAhDx8FcbWyX+vLwh7OEtzoo2iQaeWwxucyfbi0mT4DijbOSsTgPKzGHr6GrF2V5p/CEpUH/VBxg== dependencies: - "@typescript-eslint/scope-manager" "4.20.0" - "@typescript-eslint/types" "4.20.0" - "@typescript-eslint/typescript-estree" "4.20.0" + "@typescript-eslint/scope-manager" "4.25.0" + "@typescript-eslint/types" "4.25.0" + "@typescript-eslint/typescript-estree" "4.25.0" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.20.0.tgz#953ecbf3b00845ece7be66246608be9d126d05ca" - integrity sha512-/zm6WR6iclD5HhGpcwl/GOYDTzrTHmvf8LLLkwKqqPKG6+KZt/CfSgPCiybshmck66M2L5fWSF/MKNuCwtKQSQ== +"@typescript-eslint/scope-manager@4.25.0": + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.25.0.tgz#9d86a5bcc46ef40acd03d85ad4e908e5aab8d4ca" + integrity sha512-2NElKxMb/0rya+NJG1U71BuNnp1TBd1JgzYsldsdA83h/20Tvnf/HrwhiSlNmuq6Vqa0EzidsvkTArwoq+tH6w== dependencies: - "@typescript-eslint/types" "4.20.0" - "@typescript-eslint/visitor-keys" "4.20.0" + "@typescript-eslint/types" "4.25.0" + "@typescript-eslint/visitor-keys" "4.25.0" "@typescript-eslint/types@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727" integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ== -"@typescript-eslint/types@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.20.0.tgz#c6cf5ef3c9b1c8f699a9bbdafb7a1da1ca781225" - integrity sha512-cYY+1PIjei1nk49JAPnH1VEnu7OYdWRdJhYI5wiKOUMhLTG1qsx5cQxCUTuwWCmQoyriadz3Ni8HZmGSofeC+w== +"@typescript-eslint/types@4.25.0": + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.25.0.tgz#0e444a5c5e3c22d7ffa5e16e0e60510b3de5af87" + integrity sha512-+CNINNvl00OkW6wEsi32wU5MhHti2J25TJsJJqgQmJu3B3dYDBcmOxcE5w9cgoM13TrdE/5ND2HoEnBohasxRQ== "@typescript-eslint/typescript-estree@1.13.0": version "1.13.0" @@ -2204,13 +2251,13 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.20.0.tgz#8b3b08f85f18a8da5d88f65cb400f013e88ab7be" - integrity sha512-Knpp0reOd4ZsyoEJdW8i/sK3mtZ47Ls7ZHvD8WVABNx5Xnn7KhenMTRGegoyMTx6TiXlOVgMz9r0pDgXTEEIHA== +"@typescript-eslint/typescript-estree@4.25.0": + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.25.0.tgz#942e4e25888736bff5b360d9b0b61e013d0cfa25" + integrity sha512-1B8U07TGNAFMxZbSpF6jqiDs1cVGO0izVkf18Q/SPcUAc9LhHxzvSowXDTvkHMWUVuPpagupaW63gB6ahTXVlg== dependencies: - "@typescript-eslint/types" "4.20.0" - "@typescript-eslint/visitor-keys" "4.20.0" + "@typescript-eslint/types" "4.25.0" + "@typescript-eslint/visitor-keys" "4.25.0" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" @@ -2224,12 +2271,12 @@ dependencies: eslint-visitor-keys "^1.1.0" -"@typescript-eslint/visitor-keys@4.20.0": - version "4.20.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.20.0.tgz#1e84db034da13f208325e6bfc995c3b75f7dbd62" - integrity sha512-NXKRM3oOVQL8yNFDNCZuieRIwZ5UtjNLYtmMx2PacEAGmbaEYtGgVHUHVyZvU/0rYZcizdrWjDo+WBtRPSgq+A== +"@typescript-eslint/visitor-keys@4.25.0": + version "4.25.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.25.0.tgz#863e7ed23da4287c5b469b13223255d0fde6aaa7" + integrity sha512-AmkqV9dDJVKP/TcZrbf6s6i1zYXt5Hl8qOLrRDTFfRNae4+LB8A4N3i+FLZPW85zIxRy39BgeWOfMS3HoH5ngg== dependencies: - "@typescript-eslint/types" "4.20.0" + "@typescript-eslint/types" "4.25.0" eslint-visitor-keys "^2.0.0" "@webassemblyjs/ast@1.9.0": @@ -2445,10 +2492,10 @@ acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.1.0.tgz#52311fd7037ae119cbb134309e901aa46295b3fe" - integrity sha512-LWCF/Wn0nfHOmJ9rzQApGnxnvgfROzGilS8936rqN/lfcYkY9MYZzdMqN+2NJ4SlTc+m5HiSa+kNfDtI64dwUA== +acorn@^8.2.4: + version "8.2.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0" + integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg== addr-to-ip-port@^1.0.1, addr-to-ip-port@^1.5.1: version "1.5.1" @@ -2473,6 +2520,13 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= +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" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -2491,7 +2545,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.9.1: +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.9.1: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2502,9 +2556,9 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5, ajv uri-js "^4.2.2" ajv@^8.0.1: - version "8.0.5" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.0.5.tgz#f07d6fdeffcdbb80485570ce3f1bc845fcc812b9" - integrity sha512-RkiLa/AeJx7+9OvniQ/qeWu0w74A8DiPPBclQ6ji3ZQkv5KamO+QGpqmi7O4JIw3rHGUXZ6CoP9tsAkn3gyazg== + version "8.5.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b" + integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -2590,10 +2644,10 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.3, anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== +anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.1: + 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" @@ -2603,6 +2657,11 @@ aproba@^1.1.1: resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -2681,7 +2740,7 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -array.prototype.flat@^1.2.3: +array.prototype.flat@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== @@ -2725,18 +2784,6 @@ asn1.js@^5.2.0: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - assert@^1.1.1: version "1.5.0" resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" @@ -2820,20 +2867,10 @@ awaitqueue@^2.3.3: resolved "https://registry.yarnpkg.com/awaitqueue/-/awaitqueue-2.3.3.tgz#35e6568970fcac3de1644a2c28abc1074045b570" integrity sha512-RbzQg6VtPUtyErm55iuQLTrBJ2uihy5BKBOEkyBwv67xm5Fn2o/j+Bz+a5BmfSoe2oZ5dcz9Z3fExS8pL+LLhw== -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" - integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== - axe-core@^4.0.2: - version "4.1.4" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.1.4.tgz#f19cd99a84ee32a318b9c5b5bb8ed373ad94f143" - integrity sha512-Pdgfv6iP0gNx9ejRGa3zE7Xgkj/iclXqLfe7BnatdZz0QnLZ3jrRHUVH8wNSdN68w05Sk3ShGTb3ydktMTooig== + version "4.2.1" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.2.1.tgz#2e50bcf10ee5b819014f6e342e41e45096239e34" + integrity sha512-evY7DN8qSIbsW2H/TWQ1bX3sXN1d4MNb5Vb4n7BzPuCwRHdkZ1H2eNLuSh73EoQqkGKUtju2G2HCcjCfhvZIAA== axobject-query@^2.2.0: version "2.2.0" @@ -2926,29 +2963,29 @@ babel-plugin-named-asset-import@^0.3.7: resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz#156cd55d3f1228a5765774340937afc8398067dd" integrity sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw== -babel-plugin-polyfill-corejs2@^0.1.4: - version "0.1.10" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.1.10.tgz#a2c5c245f56c0cac3dbddbf0726a46b24f0f81d1" - integrity sha512-DO95wD4g0A8KRaHKi0D51NdGXzvpqVLnLu5BTvDlpqUEpTmeEtypgC1xqesORaWmiUOQI14UHKlzNd9iZ2G3ZA== +babel-plugin-polyfill-corejs2@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz#e9124785e6fd94f94b618a7954e5693053bf5327" + integrity sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ== dependencies: - "@babel/compat-data" "^7.13.0" - "@babel/helper-define-polyfill-provider" "^0.1.5" + "@babel/compat-data" "^7.13.11" + "@babel/helper-define-polyfill-provider" "^0.2.2" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.1.3: - version "0.1.7" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" - integrity sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw== +babel-plugin-polyfill-corejs3@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz#7424a1682ee44baec817327710b1b094e5f8f7f5" + integrity sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A== dependencies: - "@babel/helper-define-polyfill-provider" "^0.1.5" - core-js-compat "^3.8.1" + "@babel/helper-define-polyfill-provider" "^0.2.2" + core-js-compat "^3.9.1" -babel-plugin-polyfill-regenerator@^0.1.2: - version "0.1.6" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.1.6.tgz#0fe06a026fe0faa628ccc8ba3302da0a6ce02f3f" - integrity sha512-OUrYG9iKPKz8NxswXbRAdSwF0GhRdIEMTloQATJi4bDuFqrXaXcCUT/VGNrr8pBcjMh1RxZ7Xt9cytVJTJfvMg== +babel-plugin-polyfill-regenerator@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz#b310c8d642acada348c1fa3b3e6ce0e851bee077" + integrity sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.1.5" + "@babel/helper-define-polyfill-provider" "^0.2.2" babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" @@ -3034,9 +3071,9 @@ backo2@1.0.2: integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + 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" @@ -3066,13 +3103,6 @@ batch@0.6.1: resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - bencode@^2.0.0, bencode@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/bencode/-/bencode-2.0.1.tgz#667a6a31c5e038d558608333da6b7c94e836c85b" @@ -3174,9 +3204,9 @@ bittorrent-protocol@^3.1.1: unordered-array-remove "^1.0.2" bittorrent-tracker@^9.0.0: - version "9.16.1" - resolved "https://registry.yarnpkg.com/bittorrent-tracker/-/bittorrent-tracker-9.16.1.tgz#8eff88dcf8180fe2b5c57943127d1fdef5918ee7" - integrity sha512-JjegXwpWK8xRTHd5sqKTVqPhlhzAqJrR37gSiciTa1UkSSM6SWKVUDq7ZiGS3d8FhqonDSuPLQ9wUOC2q2jeIA== + version "9.17.0" + resolved "https://registry.yarnpkg.com/bittorrent-tracker/-/bittorrent-tracker-9.17.0.tgz#8b4b6f6a49efa9023267c3ca22e1a5f63216fc1f" + integrity sha512-ErpOx8AAUW8eLwxnEHp15vs0LDJECLADHISEBM+HXclG3J2/9kMBJ31IjwlB8kUNigknSwm8odAThjJEeyL1yA== dependencies: bencode "^2.0.1" bittorrent-peerid "^1.3.2" @@ -3269,16 +3299,16 @@ boolbase@^1.0.0, boolbase@~1.0.0: integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= boolean@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.3.tgz#0fee0c9813b66bef25a8a6a904bb46736d05f024" - integrity sha512-EqrTKXQX6Z3A2nRmMEIlAIfjQOgFnVO2nqZGpbcsPnYGWBwpFqzlrozU1dy+S2iqfYDLh26ef4KrgTxu9xQrxA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.4.tgz#aa1df8749af41d7211b66b4eee584722ff428c27" + integrity sha512-5pyOr+w2LNN72F2mAq6J0ckHUfJYSgRKma7e/wlcMMhgOLV9OI0ERhERYXxUqo+dPyVxcbXKy9n+wg13+LpNnA== boolify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/boolify/-/boolify-1.0.1.tgz#b5c09e17cacd113d11b7bb3ed384cc012994d86b" integrity sha1-tcCeF8rNET0Rt7s+04TMASmU2Gs= -bowser@^2.11.0: +bowser@^2.11.0, bowser@^2.7.0: version "2.11.0" resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== @@ -3400,16 +3430,16 @@ browserslist@4.14.2: escalade "^3.0.2" node-releases "^1.1.61" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.3, browserslist@^4.6.2, browserslist@^4.6.4: - version "4.16.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" - integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.6.2, browserslist@^4.6.4: + version "4.16.6" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" + integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== dependencies: - caniuse-lite "^1.0.30001181" - colorette "^1.2.1" - electron-to-chromium "^1.3.649" + caniuse-lite "^1.0.30001219" + colorette "^1.2.2" + electron-to-chromium "^1.3.723" escalade "^3.1.1" - node-releases "^1.1.70" + node-releases "^1.1.71" bser@2.1.1: version "2.1.1" @@ -3470,7 +3500,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^6.0.2: +buffer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== @@ -3527,9 +3557,9 @@ cacache@^12.0.2: y18n "^4.0.0" cacache@^15.0.5: - version "15.0.6" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.6.tgz#65a8c580fda15b59150fb76bf3f3a8e45d583099" - integrity sha512-g1WYDMct/jzW+JdWEyjaX2zoBkZ6ZT9VpOyp2I/VMtDsNLffNat3kqPFfi1eDRSK9/SuKGyORDHcQMcPF8sQ/w== + version "15.2.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.2.0.tgz#73af75f77c58e72d8c630a7a2858cb18ef523389" + integrity sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw== dependencies: "@npmcli/move-file" "^1.0.1" chownr "^2.0.0" @@ -3646,10 +3676,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001181: - version "1.0.30001205" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001205.tgz#d79bf6a6fb13196b4bb46e5143a22ca0242e0ef8" - integrity sha512-TL1GrS5V6LElbitPazidkBMD9sa448bQDDLrumDqaggmKFcuU2JW1wTOHJPukAcOMtEmLcmDJEzfRrf+GjM0Og== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001219: + version "1.0.30001230" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71" + integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ== capture-exit@^2.0.0: version "2.0.0" @@ -3663,11 +3693,6 @@ case-sensitive-paths-webpack-plugin@2.3.0: resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz#23ac613cc9a856e4f88ff8bb73bbb5e989825cf7" integrity sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - chalk@2.4.2, chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -3689,9 +3714,9 @@ chalk@^1.1.3: supports-color "^2.0.0" chalk@^4.0.0, chalk@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== dependencies: ansi-styles "^4.1.0" supports-color "^7.1.0" @@ -3756,9 +3781,9 @@ chownr@^2.0.0: integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== chroma-js@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.1.1.tgz#413c8fbcc4c0988dc7c77bb59c4de36573b8fe97" - integrity sha512-gYc5/Dooshun2OikK7oY/hYnoEiZ0dxqRpXosEdYRYm505vU5mRsHFqIW062C9nMtr32DVErP6mlxuepo2kNkw== + version "2.1.2" + resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-2.1.2.tgz#1075cb9ae25bcb2017c109394168b5cf3aa500ec" + integrity sha512-ri/ouYDWuxfus3UcaMxC1Tfp3IE9K5iQzxc2hSxbBRVNQFut1UuGAsZmiAf2mOUubzGJwgMSv9lHg+XqLaz1QQ== dependencies: cross-env "^6.0.3" @@ -3785,11 +3810,9 @@ chrome-net@^3.3.2, chrome-net@^3.3.3, chrome-net@^3.3.4: inherits "^2.0.1" chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== - dependencies: - tslib "^1.9.0" + 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== chunk-store-stream@^4.1.0: version "4.3.0" @@ -3827,7 +3850,7 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classnames@^2.2.6, classnames@^2.3.1: +classnames@^2.2.6: version "2.3.1" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== @@ -3967,7 +3990,7 @@ colorette@^1.2.1, colorette@^1.2.2: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== -combined-stream@^1.0.6, 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== @@ -4086,11 +4109,6 @@ constants-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - content-disposition@0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" @@ -4115,6 +4133,21 @@ convert-source-map@^0.3.3: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-0.3.5.tgz#f1d802950af7dd2631a1febe0596550c86ab3190" integrity sha1-8dgClQr33SYxof6+BZZVDIarMZA= +convict-format-with-validator@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/convict-format-with-validator/-/convict-format-with-validator-6.0.1.tgz#a0ff08b663c40beac480d1a0d39b40382b9e39a3" + integrity sha512-6/O0W9/0MESdL+0fY7glQlWHs+wnP9xXlB1tjY/Wb9ujCCEBqMP8VCjtLvRlBdfwgONrpb+DTPSHQRhUO5aTlQ== + dependencies: + validator "^11.1.0" + +convict@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/convict/-/convict-6.1.0.tgz#5b393bd675a0e743390abd0c5bf9e2b9a2edf4b5" + integrity sha512-8dzppr6Z9URlm6P8N9NiydFRq2NWtQyf4RZOK5m0Q48fWWuKamHLXD7Qz/SiLvRXnjQcKCuHayIk9Fk51sax0w== + dependencies: + lodash.clonedeep "^4.5.0" + yargs-parser "^18.1.3" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -4142,18 +4175,18 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-compat@^3.6.2, core-js-compat@^3.8.1, core-js-compat@^3.9.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.10.0.tgz#3600dc72869673c110215ee7a005a8609dea0fe1" - integrity sha512-9yVewub2MXNYyGvuLnMHcN1k9RkvB7/ofktpeKTIaASyB88YYqGzUnu0ywMMhJrDHOMiTjSHWGzR+i7Wb9Z1kQ== +core-js-compat@^3.6.2, core-js-compat@^3.9.0, core-js-compat@^3.9.1: + version "3.13.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.13.0.tgz#a88f5fa81d8e9b15d7f98abc4447a4dfca2a358f" + integrity sha512-jhbI2zpVskgfDC9mGRaDo1gagd0E0i/kYW0+WvibL/rafEHKAHO653hEXIxJHqRlRLITluXtRH3AGTL5qJmifQ== dependencies: - browserslist "^4.16.3" + browserslist "^4.16.6" semver "7.0.0" core-js-pure@^3.0.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.10.0.tgz#dab9d6b141779b622b40567e7a536d2276646c15" - integrity sha512-CC582enhrFZStO4F8lGI7QL3SYx7/AIRc+IdSi3btrQGrVsTawo5K/crmKbRrQ+MOMhNX4v+PATn0k2NN6wI7A== + version "3.13.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.13.0.tgz#9d267fb47d1d7046cfbc05e7b67bb235b6735355" + integrity sha512-7VTvXbsMxROvzPAVczLgfizR8CyYnvWPrb1eGrtlZAJfjQWEHLofVfCKljLHdpazTfpaziRORwUH/kfGDKvpdA== core-js@^2.4.0: version "2.6.12" @@ -4161,11 +4194,11 @@ core-js@^2.4.0: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.1.4, core-js@^3.6.5: - version "3.10.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.10.0.tgz#9a020547c8b6879f929306949e31496bbe2ae9b3" - integrity sha512-MQx/7TLgmmDVamSyfE+O+5BHvG1aUGj/gHhLn1wVtm2B5u1eVIPvh7vkfjwWKNCjrTJB8+He99IntSQ1qP+vYQ== + version "3.13.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.13.0.tgz#58ca436bf01d6903aee3d364089868d0d89fe58d" + integrity sha512-iWDbiyha1M5vFwPFmQnvRv+tJzGbFAm6XimJUT0NgHYW3xZEs1SkCAcasWSVFxpI2Xb/V1DDJckq3v90+bQnog== -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= @@ -4241,10 +4274,15 @@ create-react-class@^15.6.0: loose-envify "^1.3.1" object-assign "^4.1.1" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + create-torrent@^4.4.1, create-torrent@^4.4.2: - version "4.6.0" - resolved "https://registry.yarnpkg.com/create-torrent/-/create-torrent-4.6.0.tgz#63d639d0f7c23e65ba9c18a053e57c71f9cda35b" - integrity sha512-fIGI7w1K27XK3WSLrH7OS7A7p5me4IcXWbXSn5VNu48Hp7+HlRsQGqYGJX1DXHgpVWICoq5w8pdYQ/nENnGljQ== + version "4.7.0" + resolved "https://registry.yarnpkg.com/create-torrent/-/create-torrent-4.7.0.tgz#ba5d52d41e7621d0d61c895c8026d3fb22aa4333" + integrity sha512-Pb3XjZNKdCs0Nk46yFKb82y+a3xRQeMvGi1AlJfIV40y/iwkgBqzS5EfqdnakEOvh2jzTOx3v8QxZpkz4hPzyw== dependencies: bencode "^2.0.1" block-stream2 "^2.1.0" @@ -4431,10 +4469,10 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz#51ec662ccfca0f88b396dcd9679cdb931be17f76" - integrity sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA== +cssnano-preset-default@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz#920622b1fc1e95a34e8838203f1397a504f2d3ff" + integrity sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ== dependencies: css-declaration-sorter "^4.0.1" cssnano-util-raw-cache "^4.0.1" @@ -4464,7 +4502,7 @@ cssnano-preset-default@^4.0.7: postcss-ordered-values "^4.1.2" postcss-reduce-initial "^4.0.3" postcss-reduce-transforms "^4.0.2" - postcss-svgo "^4.0.2" + postcss-svgo "^4.0.3" postcss-unique-selectors "^4.0.1" cssnano-util-get-arguments@^4.0.0: @@ -4490,12 +4528,12 @@ cssnano-util-same-parent@^4.0.0: integrity sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q== cssnano@^4.1.10: - version "4.1.10" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.10.tgz#0ac41f0b13d13d465487e111b778d42da631b8b2" - integrity sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ== + version "4.1.11" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-4.1.11.tgz#c7b5f5b81da269cb1fd982cb960c1200910c9a99" + integrity sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g== dependencies: cosmiconfig "^5.0.0" - cssnano-preset-default "^4.0.7" + cssnano-preset-default "^4.0.8" is-resolvable "^1.0.0" postcss "^7.0.0" @@ -4524,14 +4562,14 @@ cssstyle@^2.3.0: cssom "~0.3.6" csstype@^2.5.2: - version "2.6.16" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.16.tgz#544d69f547013b85a40d15bff75db38f34fe9c39" - integrity sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q== + version "2.6.17" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.17.tgz#4cf30eb87e1d1a005d8b6510f95292413f6a1c0e" + integrity sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A== csstype@^3.0.2: - version "3.0.7" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b" - integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g== + version "3.0.8" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" + integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== cyclist@^1.0.1: version "1.0.1" @@ -4547,16 +4585,9 @@ d@1, d@^1.0.1: type "^1.0.1" damerau-levenshtein@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz#143c1641cb3d85c60c32329e26899adea8701791" - integrity sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug== - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" + version "1.0.7" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" + integrity sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw== data-urls@^2.0.0: version "2.0.0" @@ -4574,20 +4605,20 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6. dependencies: ms "2.0.0" -debug@^3.1.0, debug@^3.1.1, debug@^3.2.6: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1: +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" +debug@^3.1.0, debug@^3.1.1, 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@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -4658,6 +4689,11 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= +deep-object-diff@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/deep-object-diff/-/deep-object-diff-1.1.0.tgz#d6fabf476c2ed1751fc94d5ca693d2ed8c18bc5a" + integrity sha512-b+QLs5vHgS+IoSNcUE4n9HP2NwcHj7aqnJWsjPtuG75Rh5TOaGt0OjAYInh77d5T16V5cRDC+Pw/6ZZZiETBGw== + deepmerge@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" @@ -4747,9 +4783,9 @@ detect-newline@^3.0.0: integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== detect-node@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79" - integrity sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw== + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== detect-port-alt@1.1.6: version "1.1.6" @@ -4764,6 +4800,11 @@ diff-sequences@^26.6.2: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -4791,9 +4832,9 @@ dns-equal@^1.0.0: integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= dns-packet@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" - integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== + version "1.3.4" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" + integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== dependencies: ip "^1.1.0" safe-buffer "^5.0.1" @@ -4805,14 +4846,6 @@ dns-txt@^2.0.2: dependencies: buffer-indexof "^1.0.0" -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -4835,9 +4868,9 @@ dom-converter@^0.2: utila "~0.4" dom-helpers@^5.0.1: - version "5.2.0" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b" - integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ== + version "5.2.1" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" + integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== dependencies: "@babel/runtime" "^7.8.7" csstype "^3.0.2" @@ -4880,9 +4913,9 @@ domhandler@^2.3.0: domelementtype "1" dompurify@^2.0.7: - version "2.2.7" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.7.tgz#a5f055a2a471638680e779bd08fc334962d11fd8" - integrity sha512-jdtDffdGNY+C76jvodNTu9jt5yYj59vuTUyx+wXdzcSwAGTYZDAQkQ7Iwx9zcGrA4ixC1syU4H3RZROqRxokxg== + version "2.2.8" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.8.tgz#ce88e395f6d00b6dc53f80d6b2a6fdf5446873c6" + integrity sha512-9H0UL59EkDLgY3dUFjLV6IEUaHm5qp3mxSqWw7Yyx4Zhk2Jn2cmLe+CNPP3xy13zl8Bqg+0NehQzkdMoVhGRww== domready@^1.0.8: version "1.0.8" @@ -4942,14 +4975,6 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -4967,15 +4992,15 @@ ejs@^3.1.5: dependencies: jake "^10.6.1" -electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.649: - version "1.3.707" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.707.tgz#71386d0ceca6727835c33ba31f507f6824d18c35" - integrity sha512-BqddgxNPrcWnbDdJw7SzXVzPmp+oiyjVrc7tkQVaznPGSS9SKZatw6qxoP857M+HbOyyqJQwYQtsuFIMSTNSZA== +electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.723: + version "1.3.741" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.741.tgz#dc1024b19b31e27fb2c8c0a1f120cb05fc6ca695" + integrity sha512-4i3T0cwnHo1O4Mnp9JniEco8bZiXoqbm3PhW5hv7uu8YLg35iajYrRnNyKFaN8/8SSTskU2hYqVTeYVPceSpUA== electron@^12.0.0: - version "12.0.2" - resolved "https://registry.yarnpkg.com/electron/-/electron-12.0.2.tgz#d92be205f1937627bd6718aad44ac161382b4c2d" - integrity sha512-14luh9mGzfL4e0sncyy0+kW37IU7Y0Y1tvI97FDRSW0ZBQxi5cmAwSs5dmPmNBFBIGtzkaGaEB01j9RjZuCmow== + version "12.0.9" + resolved "https://registry.yarnpkg.com/electron/-/electron-12.0.9.tgz#d582afa8f6fc0c429606f0961a4c89b376994823" + integrity sha512-p5aEt1tIh/PYjwN+6MHTc5HtW529XR9r4Qlj9PPcSb5ubkotSsS0BtWJoRPhDenSAN8sgHk3sbZLxXPJtdnRYA== dependencies: "@electron/get" "^1.0.1" "@types/node" "^14.6.2" @@ -5044,9 +5069,9 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: once "^1.4.0" engine.io-client@~3.5.0: - version "3.5.1" - resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.5.1.tgz#b500458a39c0cd197a921e0e759721a746d0bdb9" - integrity sha512-oVu9kBkGbcggulyVF0kz6BV3ganqUeqXvD79WOFKa+11oK692w1NyFkuEj4xrkFRpZhn92QOqTk4RQq5LiBXbQ== + 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" @@ -5057,7 +5082,7 @@ engine.io-client@~3.5.0: parseqs "0.0.6" parseuri "0.0.6" ws "~7.4.2" - xmlhttprequest-ssl "~1.5.4" + xmlhttprequest-ssl "~1.6.2" yeast "0.1.2" engine.io-parser@~2.2.0: @@ -5102,10 +5127,10 @@ env-paths@^2.2.0: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== -err-code@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== +err-code@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-3.0.1.tgz#a444c7b992705f2b120ee320b09972eef331c920" + integrity sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA== errno@^0.1.3, errno@~0.1.7: version "0.1.8" @@ -5114,7 +5139,7 @@ errno@^0.1.3, errno@~0.1.7: dependencies: prr "~1.0.1" -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -5128,10 +5153,10 @@ error-stack-parser@^2.0.6: dependencies: stackframe "^1.1.1" -es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: - version "1.18.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" - integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== +es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2: + version "1.18.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" + integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" @@ -5141,14 +5166,14 @@ es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: has-symbols "^1.0.2" is-callable "^1.2.3" is-negative-zero "^2.0.1" - is-regex "^1.1.2" - is-string "^1.0.5" - object-inspect "^1.9.0" + is-regex "^1.1.3" + is-string "^1.0.6" + object-inspect "^1.10.3" 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.0" + unbox-primitive "^1.0.1" es-to-primitive@^1.2.1: version "1.2.1" @@ -5255,9 +5280,9 @@ eslint-config-airbnb@^18.2.0: object.entries "^1.1.2" eslint-config-prettier@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.1.0.tgz#4ef1eaf97afe5176e6a75ddfb57c335121abc5a6" - integrity sha512-oKMhGv3ihGbCIimCAjqkdzx2Q+jthoqnXSP+d86M9tptwugycmTFdVR4IpLgq2c4SHifbwO90z2fQ8/Aio73yw== + version "8.3.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" + integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== eslint-config-react-app@^6.0.0: version "6.0.0" @@ -5285,45 +5310,47 @@ eslint-import-resolver-typescript@^2.4.0: resolve "^1.17.0" tsconfig-paths "^3.9.0" -eslint-module-utils@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" - integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== +eslint-module-utils@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz#b51be1e473dd0de1c5ea638e22429c2490ea8233" + integrity sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A== dependencies: - debug "^2.6.9" + debug "^3.2.7" pkg-dir "^2.0.0" eslint-plugin-flowtype@^5.2.0, eslint-plugin-flowtype@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.4.0.tgz#a559526e56403cb97b470b524957fc526e2485fe" - integrity sha512-O0s0iTT5UxYuoOpHMLSIO2qZMyvrb9shhk1EM5INNGtJ2CffrfUmsnh6TVsnoT41fkXIEndP630WNovhoO87xQ== + version "5.7.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.7.2.tgz#482a42fe5d15ee614652ed256d37543d584d7bc0" + integrity sha512-7Oq/N0+3nijBnYWQYzz/Mp/7ZCpwxYvClRyW/PLAmimY9uLCBvoXsNsERcJdkKceyOjgRbFhhxs058KTrne9Mg== dependencies: lodash "^4.17.15" string-natural-compare "^3.0.1" eslint-plugin-import@^2.22.1: - version "2.22.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" - integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== + version "2.23.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.23.3.tgz#8a1b073289fff03c4af0f04b6df956b7d463e191" + integrity sha512-wDxdYbSB55F7T5CC7ucDjY641VvKmlRwT0Vxh7PkY1mI4rclVRFWYfsrjDgZvwYYDZ5ee0ZtfFKXowWjqvEoRQ== dependencies: - array-includes "^3.1.1" - array.prototype.flat "^1.2.3" - contains-path "^0.1.0" + array-includes "^3.1.3" + array.prototype.flat "^1.2.4" debug "^2.6.9" - doctrine "1.5.0" + doctrine "^2.1.0" eslint-import-resolver-node "^0.3.4" - eslint-module-utils "^2.6.0" + eslint-module-utils "^2.6.1" + find-up "^2.0.0" has "^1.0.3" + is-core-module "^2.4.0" minimatch "^3.0.4" - object.values "^1.1.1" - read-pkg-up "^2.0.0" - resolve "^1.17.0" + object.values "^1.1.3" + pkg-up "^2.0.0" + read-pkg-up "^3.0.0" + resolve "^1.20.0" tsconfig-paths "^3.9.0" eslint-plugin-jest@^24.1.0, eslint-plugin-jest@^24.3.3: - version "24.3.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.3.3.tgz#4e0f9dd6b1667990e7be3a7d7c9a85b952056df9" - integrity sha512-IQ9tLHyKEyBw1BM3IE13WxOXQm03h/7dy1KFknUVkoY2N2+Hw7lb/3YFz/4jwcrxXt2+KhA/GoiK7jt8aK19ww== + version "24.3.6" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-24.3.6.tgz#5f0ca019183c3188c5ad3af8e80b41de6c8e9173" + integrity sha512-WOVH4TIaBLIeCX576rLcOgjNXqP+jNlCiEmRgFTfQtJ52DpwnIQKAVGlGPAN7CZ33bW6eNfHD6s8ZbEUTQubJg== dependencies: "@typescript-eslint/experimental-utils" "^4.0.1" @@ -5345,9 +5372,9 @@ eslint-plugin-jsx-a11y@^6.3.1, eslint-plugin-jsx-a11y@^6.4.1: language-tags "^1.0.5" eslint-plugin-prettier@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.1.tgz#7079cfa2497078905011e6f82e8dd8453d1371b7" - integrity sha512-Rq3jkcFY8RYeQLgk2cCwuc0P7SEFwDravPhsJZOQ5N4YI4DSg50NyqJ/9gdZHzQlHf8MvafSesbNJCcP/FF6pQ== + version "3.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz#cdbad3bf1dbd2b177e9825737fe63b476a08f0c7" + integrity sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw== dependencies: prettier-linter-helpers "^1.0.0" @@ -5357,9 +5384,9 @@ eslint-plugin-react-hooks@^4.2.0: integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ== eslint-plugin-react@^7.21.5, eslint-plugin-react@^7.23.1: - version "7.23.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.23.1.tgz#f1a2e844c0d1967c822388204a8bc4dee8415b11" - integrity sha512-MvFGhZjI8Z4HusajmSw0ougGrq3Gs4vT/0WgwksZgf5RrLrRa2oYAw56okU4tZJl8+j7IYNuTM+2RnFEuTSdRQ== + version "7.23.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.23.2.tgz#2d2291b0f95c03728b55869f01102290e792d494" + integrity sha512-AfjgFQB+nYszudkxRkTFu0UR1zEQig0ArVMPloKhxwlwkzaw/fBiH0QWcBBhZONlXqQC51+nfqFrkn4EzHcGBw== dependencies: array-includes "^3.1.3" array.prototype.flatmap "^1.2.4" @@ -5425,19 +5452,20 @@ eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3 integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== eslint-visitor-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" - integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== eslint-webpack-plugin@^2.5.2, eslint-webpack-plugin@^2.5.3: - version "2.5.3" - resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-2.5.3.tgz#a125585a1d8bb9c939f2a920a9bc9be4a21cdb58" - integrity sha512-LewNevZf9ghDCxCGT6QltNWVi8KIYWc4LKcin8K9Azh1hypG7YAmobUDIU67fAPa+eMjRnU4rjEkLbYI1w5/UA== + version "2.5.4" + resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-2.5.4.tgz#473b84932f1a8e2c2b8e66a402d0497bf440b986" + integrity sha512-7rYh0m76KyKSDE+B+2PUQrlNS4HJ51t3WKpkJg6vo2jFMbEPTG99cBV0Dm7LXSHucN4WGCG65wQcRiTFrj7iWw== dependencies: "@types/eslint" "^7.2.6" arrify "^2.0.1" jest-worker "^26.6.2" micromatch "^4.0.2" + normalize-path "^3.0.0" schema-utils "^3.0.0" eslint@^5.0.0: @@ -5483,24 +5511,26 @@ eslint@^5.0.0: text-table "^0.2.0" eslint@^7.11.0, eslint@^7.9.0: - version "7.23.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.23.0.tgz#8d029d252f6e8cf45894b4bee08f5493f8e94325" - integrity sha512-kqvNVbdkjzpFy0XOszNwjkKzZ+6TcwCQ/h+ozlcIWwaimBBuhlQ4nN6kbiM2L+OjDcznkTJxzYfRFH92sx4a0Q== + version "7.27.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.27.0.tgz#665a1506d8f95655c9274d84bd78f7166b07e9c7" + integrity sha512-JZuR6La2ZF0UD384lcbnd0Cgg6QJjiCwhMD6eU4h/VGPcVGwawNNzKU41tgokGXnfjOOyI6QIffthhJTPzzuRA== dependencies: "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.0" + "@eslint/eslintrc" "^0.4.1" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.0.1" doctrine "^3.0.0" enquirer "^2.3.5" + escape-string-regexp "^4.0.0" eslint-scope "^5.1.1" eslint-utils "^2.1.0" eslint-visitor-keys "^2.0.0" espree "^7.3.1" esquery "^1.4.0" esutils "^2.0.2" + fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" glob-parent "^5.0.0" @@ -5512,7 +5542,7 @@ eslint@^7.11.0, eslint@^7.9.0: js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" - lodash "^4.17.21" + lodash.merge "^4.6.2" minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" @@ -5521,7 +5551,7 @@ eslint@^7.11.0, eslint@^7.9.0: semver "^7.2.1" strip-ansi "^6.0.0" strip-json-comments "^3.1.0" - table "^6.0.4" + table "^6.0.9" text-table "^0.2.0" v8-compile-cache "^2.0.3" @@ -5755,11 +5785,6 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -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== - external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -5793,17 +5818,7 @@ extract-zip@^1.0.3: mkdirp "^0.5.4" yauzl "^2.10.0" -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 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== @@ -5843,9 +5858,9 @@ fastq@^1.6.0: reusify "^1.0.4" faye-websocket@^0.11.3: - version "0.11.3" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" - integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== dependencies: websocket-driver ">=0.5.1" @@ -6045,9 +6060,9 @@ flush-write-stream@^1.0.0: readable-stream "^2.3.6" follow-redirects@^1.0.0: - version "1.13.3" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267" - integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA== + version "1.14.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" + integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== for-in@^1.0.2: version "1.0.2" @@ -6064,11 +6079,6 @@ foreman@^3.0.1: mustache "^2.2.1" shell-quote "^1.6.1" -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - fork-ts-checker-webpack-plugin@4.1.6: version "4.1.6" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" @@ -6082,13 +6092,13 @@ fork-ts-checker-webpack-plugin@4.1.6: tapable "^1.0.0" worker-rpc "^0.1.0" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" forwarded@~0.1.2: @@ -6211,7 +6221,7 @@ gensync@^1.0.0-beta.1, gensync@^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== -get-browser-rtc@^1.0.2: +get-browser-rtc@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/get-browser-rtc/-/get-browser-rtc-1.1.0.tgz#d1494e299b00f33fc8e9d6d3343ba4ba99711a2c" integrity sha512-MghbMJ61EJrRsDe7w1Bvqt3ZsBuqhce5nrn/XAwgwOXhcsz53/ltdxOse1h/8eKXj5slzxdsz56g5rzOFSGwfQ== @@ -6264,13 +6274,6 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -6287,9 +6290,9 @@ glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: is-glob "^4.0.1" glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -6350,9 +6353,9 @@ globals@^12.1.0: type-fest "^0.8.1" globals@^13.6.0: - version "13.7.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.7.0.tgz#aed3bcefd80ad3ec0f0be2cf0c895110c0591795" - integrity sha512-Aipsz6ZKRxa/xQkZhNg0qIWXT6x6rD46f6x/PCnBomlttdIyAPak4YD9jTmKpZ72uROSMU87qJtcgpgHaVchiA== + version "13.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.9.0.tgz#4bf2bf635b334a173fb1daf7c5e6b218ecdc06cb" + integrity sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA== dependencies: type-fest "^0.20.2" @@ -6452,19 +6455,6 @@ handle-thing@^2.0.0: resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - hark@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/hark/-/hark-1.2.3.tgz#959981400f561be5580ecd4321a9f55b16bacbd0" @@ -6473,9 +6463,9 @@ hark@^1.2.3: wildemitter "^1.2.0" harmony-reflect@^1.4.6: - version "1.6.1" - resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.1.tgz#c108d4f2bb451efef7a37861fdbdae72c9bdefa9" - integrity sha512-WJTeyp0JzGtHcuMsi7rw2VwtkvLa+JyfEKJCFyfcS0+CDkjQ5lHPu7zEhFZP+PDSRrEgXa5Ah0l1MbgbE41XjA== + version "1.6.2" + resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.2.tgz#31ecbd32e648a34d030d86adb67d4d47547fe710" + integrity sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g== has-ansi@^2.0.0: version "2.0.0" @@ -6615,9 +6605,9 @@ hoopy@^0.1.4: integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== hosted-git-info@^2.1.4: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== + 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== hpack.js@^2.1.6: version "2.1.6" @@ -6639,11 +6629,6 @@ hsla-regex@^1.0.0: resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= -html-comment-regex@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.2.tgz#97d4688aeb5c81886a364faa0cad1dda14d433a7" - integrity sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ== - html-encoding-sniffer@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" @@ -6761,6 +6746,15 @@ http-parser-js@^0.4.3: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.13.tgz#3bd6d6fde6e3172c9334c3b33b6c193d80fe1137" integrity sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc= +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + http-proxy-middleware@0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" @@ -6780,20 +6774,19 @@ http-proxy@^1.17.0: follow-redirects "^1.0.0" requires-port "^1.0.0" -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +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@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -6846,11 +6839,11 @@ ignore@^5.1.2, ignore@^5.1.4: integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== immediate-chunk-store@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/immediate-chunk-store/-/immediate-chunk-store-2.1.1.tgz#4b9f001beaab38d62e4aae630ec7ffb98be805ce" - integrity sha512-y5AxkxqpPTj2dkaAEkDnrMuSX4JNicXHD6yTpLfFnflVejL6yJpzf27obrnlf2PSSQiWUf3735Y9tJEjxvqnoA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/immediate-chunk-store/-/immediate-chunk-store-2.2.0.tgz#f56d30ecc7171f6cfcf632b0eb8395a89f92c03c" + integrity sha512-1bHBna0hCa6arRXicu91IiL9RvvkbNYLVq+mzWdaLGZC3hXvX4doh8e1dLhMKez5siu63CYgO5NrGJbRX5lbPA== dependencies: - queue-microtask "^1.2.0" + queue-microtask "^1.2.3" immer@8.0.1: version "8.0.1" @@ -7093,9 +7086,9 @@ is-ascii@^1.0.0: integrity sha1-8CrQJZoJIc0Zn/Ic4bCeD2tOOSk= is-bigint@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" - integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a" + integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA== is-binary-path@^1.0.0: version "1.0.1" @@ -7112,11 +7105,11 @@ is-binary-path@~2.1.0: binary-extensions "^2.0.0" is-boolean-object@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" - integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" + integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" is-buffer@^1.1.5: version "1.1.6" @@ -7147,10 +7140,10 @@ is-color-stop@^1.0.0: rgb-regex "^1.0.1" rgba-regex "^1.0.0" -is-core-module@^2.0.0, is-core-module@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" - integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== +is-core-module@^2.0.0, is-core-module@^2.2.0, is-core-module@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" + integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== dependencies: has "^1.0.3" @@ -7169,9 +7162,9 @@ is-data-descriptor@^1.0.0: kind-of "^6.0.0" is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5" + integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A== is-descriptor@^0.1.0: version "0.1.6" @@ -7197,9 +7190,9 @@ is-directory@^0.3.1: integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= is-docker@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" - integrity sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw== + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== is-electron@^2.2.0: version "2.2.0" @@ -7273,9 +7266,9 @@ is-negative-zero@^2.0.1: integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== is-number-object@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" - integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb" + integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw== is-number@^3.0.0: version "3.0.0" @@ -7330,18 +7323,18 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-potential-custom-element-name@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" - integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= +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-regex@^1.0.4, is-regex@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" - integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== +is-regex@^1.0.4, is-regex@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" + integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== dependencies: call-bind "^1.0.2" - has-symbols "^1.0.1" + has-symbols "^1.0.2" is-regexp@^1.0.0: version "1.0.0" @@ -7368,26 +7361,19 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-svg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-svg/-/is-svg-3.0.0.tgz#9321dbd29c212e5ca99c4fa9794c714bcafa2f75" - integrity sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ== - dependencies: - html-comment-regex "^1.1.0" +is-string@^1.0.5, is-string@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" + integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== + 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.1" + has-symbols "^1.0.2" -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -7441,11 +7427,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - istanbul-lib-coverage@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" @@ -7950,18 +7931,13 @@ js-yaml@^3.13.0, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - jsdom@^16.4.0: - version "16.5.2" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.2.tgz#583fac89a0aea31dbf6237e7e4bedccd9beab472" - integrity sha512-JxNtPt9C1ut85boCbJmffaQ06NBnzkQY/MWO3YxPW8IWS38A26z+B1oBvA9LwKrytewdfymnhi4UNH3/RAgZrg== + version "16.6.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.6.0.tgz#f79b3786682065492a3da6a60a4695da983805ac" + integrity sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg== dependencies: abab "^2.0.5" - acorn "^8.1.0" + acorn "^8.2.4" acorn-globals "^6.0.0" cssom "^0.4.4" cssstyle "^2.3.0" @@ -7969,12 +7945,13 @@ jsdom@^16.4.0: decimal.js "^10.2.1" domexception "^2.0.1" escodegen "^2.0.0" + form-data "^3.0.0" html-encoding-sniffer "^2.0.1" - is-potential-custom-element-name "^1.0.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" nwsapi "^2.2.0" parse5 "6.0.1" - request "^2.88.2" - request-promise-native "^1.0.9" saxes "^5.0.1" symbol-tree "^3.2.4" tough-cookie "^4.0.0" @@ -7984,7 +7961,7 @@ jsdom@^16.4.0: whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" whatwg-url "^8.5.0" - ws "^7.4.4" + ws "^7.4.5" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -8022,17 +7999,12 @@ json-schema-traverse@^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.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= @@ -8072,16 +8044,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - jss-plugin-camel-case@^10.5.1: version "10.6.0" resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz#93d2cd704bf0c4af70cc40fb52d74b8a2554b170" @@ -8300,14 +8262,14 @@ load-ip-set@^2.1.0: simple-get "^4.0.0" split "^1.0.1" -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= dependencies: graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" + parse-json "^4.0.0" + pify "^3.0.0" strip-bom "^3.0.0" loader-runner@^2.4.0: @@ -8380,11 +8342,6 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -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.forin@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.forin/-/lodash.forin-4.4.0.tgz#5d3f20ae564011fbe88381f7d98949c9c9519731" @@ -8410,7 +8367,7 @@ lodash.memoize@^4.1.2: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.merge@^4.6.0: +lodash.merge@^4.6.0, lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== @@ -8460,7 +8417,7 @@ lodash.unset@^4.5.2: resolved "https://registry.yarnpkg.com/lodash.unset/-/lodash.unset-4.5.2.tgz#370d1d3e85b72a7e1b0cdf2d272121306f23e4ed" integrity sha1-Nw0dPoW3Kn4bDN8tJyEhMG8j5O0= -"lodash@>=3.5 <5", lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.7.0: +"lodash@>=3.5 <5", lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -8553,6 +8510,11 @@ make-dir@^3.0.0, make-dir@^3.0.2: dependencies: semver "^6.0.0" +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + make-plural@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-4.3.0.tgz#f23de08efdb0cac2e0c9ba9f315b0dff6b4c2735" @@ -8573,9 +8535,9 @@ map-cache@^0.2.2: integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= map-obj@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.2.0.tgz#0e8bc823e2aaca8a0942567d12ed14f389eec153" - integrity sha512-NAq0fCmZYGz9UFEQyndp7sisrow4GroyGeKluyKC/chuITZsPyOyC1UJZPJlVFImhXdROIP5xqouRLThT3BbpQ== + version "4.2.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.2.1.tgz#e4ea399dbc979ae735c83c863dd31bdf364277b7" + integrity sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ== map-visit@^1.0.0: version "1.0.0" @@ -8597,9 +8559,9 @@ matcher@^3.0.0: escape-string-regexp "^4.0.0" material-ui-popup-state@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/material-ui-popup-state/-/material-ui-popup-state-1.8.0.tgz#602cdad7f00dbc475e7e29e36daeff29eb021f60" - integrity sha512-czXksi+b1I1Dgemp82UNUBjIy9DV60ttw6a9fyk60UX/Axqmf4hzcp/ulhd3JcMS5HgmmO1Vw/DNkV10ngj16A== + version "1.8.3" + resolved "https://registry.yarnpkg.com/material-ui-popup-state/-/material-ui-popup-state-1.8.3.tgz#1e263682659c6b39af38c68c21ce4f316f2bb56e" + integrity sha512-qvrX5snjXwn3rv5i3+w/T1WF3NHRPZ6KzB/gOzh9cxowEvlWV0HkCSbPmEDTnfQt6s6r964cMV987QZ50eNhxA== dependencies: "@babel/runtime" "^7.12.5" "@material-ui/types" "^4.1.1" @@ -8631,9 +8593,9 @@ media-typer@0.3.0: integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= mediasoup-client@^3.6.29: - version "3.6.29" - resolved "https://registry.yarnpkg.com/mediasoup-client/-/mediasoup-client-3.6.29.tgz#27fdb3547144a83a1907026ae6aeb033bcd7bd0d" - integrity sha512-Q2c1uR6B8UUyqEckot3q0xegwENykP7hRHNVDKw7kCC2XH09/tKKM+5RcqKgB4fHUKlHIwtcWCgN54uSUN7OfA== + version "3.6.30" + resolved "https://registry.yarnpkg.com/mediasoup-client/-/mediasoup-client-3.6.30.tgz#a962458e31cc691eb19e1a6d72888a9ca070b52b" + integrity sha512-ll8koVsracUQVdvxR0HRE7cfamkDf4YOlzFjI3YE8d/rfhFiPNcI5X7sEP59VU1PZqOu65Gg56ZR8IrYZpIZBQ== dependencies: "@types/debug" "^4.1.5" "@types/events" "^3.0.0" @@ -8655,11 +8617,11 @@ mediasource@^2.2.2, mediasource@^2.3.0: to-arraybuffer "^1.0.1" memory-chunk-store@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/memory-chunk-store/-/memory-chunk-store-1.3.2.tgz#3bde573c957c0260d8116e6e2c0ce62ff2032894" - integrity sha512-EBcbwpdQlzT5aNV0FTT+RAfh1cGEssjiCcRGcTk57mKsnZlRMOtH4Cfk/AqQnkz8xP2dUF+/lgpmErSGwwE1FA== + version "1.3.5" + resolved "https://registry.yarnpkg.com/memory-chunk-store/-/memory-chunk-store-1.3.5.tgz#700f712415895600bc5466007333efa19f1de07c" + integrity sha512-E1Xc1U4ifk/FkC2ZsWhCaW1xg9HbE/OBmQTLe2Tr9c27YPSLbW7kw1cnb3kQWD1rDtErFJHa7mB9EVrs7aTx9g== dependencies: - queue-microtask "^1.2.2" + queue-microtask "^1.2.3" memory-fs@^0.4.1: version "0.4.1" @@ -8741,12 +8703,12 @@ micromatch@^3.1.10, micromatch@^3.1.4: to-regex "^3.0.2" micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + 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.0.5" + picomatch "^2.2.3" miller-rabin@^4.0.0: version "4.0.1" @@ -8761,7 +8723,7 @@ mime-db@1.47.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c" integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.24: version "2.1.30" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d" integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg== @@ -9005,10 +8967,10 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== -nanoid@^3.1.22: - version "3.1.22" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" - integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== +nanoid@^3.1.23: + version "3.1.23" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" + integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== nanomatch@^1.2.9: version "1.2.13" @@ -9138,10 +9100,10 @@ node-notifier@^8.0.0: uuid "^8.3.0" which "^2.0.2" -node-releases@^1.1.61, node-releases@^1.1.70: - version "1.1.71" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" - integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== +node-releases@^1.1.61, node-releases@^1.1.71: + version "1.1.72" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" + integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" @@ -9186,9 +9148,9 @@ normalize-url@^3.0.0: integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== normalize-url@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== notistack@^0.9.5: version "0.9.17" @@ -9237,11 +9199,6 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - object-assign@^4.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" @@ -9256,10 +9213,10 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" - integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== +object-inspect@^1.10.3, object-inspect@^1.9.0: + version "1.10.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" + integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== object-is@^1.0.1: version "1.1.5" @@ -9292,14 +9249,13 @@ object.assign@^4.1.0, object.assign@^4.1.2: object-keys "^1.1.1" object.entries@^1.1.0, object.entries@^1.1.2, object.entries@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.3.tgz#c601c7f168b62374541a07ddbd3e2d5e4f7711a6" - integrity sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg== + version "1.1.4" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd" + integrity sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" - has "^1.0.3" + es-abstract "^1.18.2" object.fromentries@^2.0.4: version "2.0.4" @@ -9327,15 +9283,14 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.0, object.values@^1.1.1, object.values@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" - integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== +object.values@^1.1.0, object.values@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30" + integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" - has "^1.0.3" + es-abstract "^1.18.2" obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" @@ -9572,13 +9527,6 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: pbkdf2 "^3.0.3" safe-buffer "^5.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-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -9688,9 +9636,9 @@ path-key@^3.0.0, path-key@^3.1.0: integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + 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-to-regexp@0.1.7: version "0.1.7" @@ -9704,12 +9652,12 @@ path-to-regexp@^1.7.0: dependencies: isarray "0.0.1" -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== dependencies: - pify "^2.0.0" + pify "^3.0.0" path-type@^4.0.0: version "4.0.0" @@ -9717,9 +9665,9 @@ path-type@^4.0.0: integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pbkdf2@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" - integrity sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg== + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== dependencies: create-hash "^1.1.2" create-hmac "^1.1.4" @@ -9737,10 +9685,10 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1, picomatch@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" - integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +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== piece-length@^2.0.1: version "2.0.1" @@ -9809,6 +9757,13 @@ pkg-up@3.1.0: dependencies: find-up "^3.0.0" +pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" + integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= + dependencies: + find-up "^2.1.0" + pnp-webpack-plugin@1.6.4: version "1.6.4" resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" @@ -10039,11 +9994,10 @@ postcss-image-set-function@^3.0.1: postcss-values-parser "^2.0.0" postcss-initial@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.2.tgz#f018563694b3c16ae8eaabe3c585ac6319637b2d" - integrity sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.4.tgz#9d32069a10531fe2ecafa0b6ac750ee0bc7efc53" + integrity sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg== dependencies: - lodash.template "^4.5.0" postcss "^7.0.2" postcss-lab-function@^2.0.1: @@ -10432,21 +10386,18 @@ postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: uniq "^1.0.1" postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: - version "6.0.4" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz#56075a1380a04604c38b063ea7767a129af5c2b3" - integrity sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw== + version "6.0.6" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" + integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== dependencies: cssesc "^3.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" util-deprecate "^1.0.2" -postcss-svgo@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.2.tgz#17b997bc711b333bab143aaed3b8d3d6e3d38258" - integrity sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw== +postcss-svgo@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-4.0.3.tgz#343a2cdbac9505d416243d496f724f38894c941e" + integrity sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw== dependencies: - is-svg "^3.0.0" postcss "^7.0.0" postcss-value-parser "^3.0.0" svgo "^1.0.0" @@ -10498,13 +10449,13 @@ postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, po supports-color "^6.1.0" postcss@^8.1.0: - version "8.2.9" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.9.tgz#fd95ff37b5cee55c409b3fdd237296ab4096fba3" - integrity sha512-b+TmuIL4jGtCHtoLi+G/PisuIl9avxs8IZMSmlABRwNz5RLUUACrC+ws81dcomz1nRezm5YPdXiMEzBEKgYn+Q== + version "8.3.0" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f" + integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ== dependencies: colorette "^1.2.2" - nanoid "^3.1.22" - source-map "^0.6.1" + nanoid "^3.1.23" + source-map-js "^0.6.2" prelude-ls@^1.2.1: version "1.2.1" @@ -10599,9 +10550,9 @@ prettier@^1.7.0: integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== prettier@^2.0.0, prettier@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" - integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== + version "2.3.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18" + integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w== pretty-bytes@^5.3.0: version "5.6.0" @@ -10704,7 +10655,7 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= -psl@^1.1.28, psl@^1.1.33: +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== @@ -10771,11 +10722,6 @@ qs@6.7.0: resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - query-string@^4.1.0: version "4.3.4" resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" @@ -10804,7 +10750,7 @@ querystringify@^2.1.1: resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== -queue-microtask@^1.2.0, queue-microtask@^1.2.2: +queue-microtask@^1.2.2, queue-microtask@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== @@ -11009,9 +10955,9 @@ react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== react-redux@^7.2.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.3.tgz#4c084618600bb199012687da9e42123cca3f0be9" - integrity sha512-ZhAmQ1lrK+Pyi0ZXNMUZuYxYAZd59wFuVDGUt536kSGdD0ya9Q7BfsE95E3TsFLE3kOSFp5m6G5qbatE+Ic1+w== + version "7.2.4" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.4.tgz#1ebb474032b72d806de2e0519cd07761e222e225" + integrity sha512-hOQ5eOSkEJEXdpIKbnRyl04LhaWabkDPV+Ix97wqQX3T3d2NQ8DUblNXXtNMavc7DpswyQM6xfaN4HQDKNY2JA== dependencies: "@babel/runtime" "^7.12.1" "@types/react-redux" "^7.1.16" @@ -11147,13 +11093,13 @@ react@^16.10.2, react@^16.12.0: object-assign "^4.1.1" prop-types "^15.6.2" -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= dependencies: find-up "^2.0.0" - read-pkg "^2.0.0" + read-pkg "^3.0.0" read-pkg-up@^7.0.1: version "7.0.1" @@ -11164,14 +11110,14 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= dependencies: - load-json-file "^2.0.0" + load-json-file "^4.0.0" normalize-package-data "^2.3.2" - path-type "^2.0.0" + path-type "^3.0.0" read-pkg@^5.2.0: version "5.2.0" @@ -11222,9 +11168,9 @@ readdirp@~3.5.0: picomatch "^2.2.1" record-cache@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/record-cache/-/record-cache-1.1.0.tgz#f8a467a691a469584b26e88d36b18afdb3932037" - integrity sha512-u8rbtLEJV7HRacl/ZYwSBFD8NFyB3PfTTfGLP37IW3hftQCwu6z4Q2RLyxo1YJUNRTEzJfpLpGwVuEYdaIkG9Q== + version "1.1.1" + resolved "https://registry.yarnpkg.com/record-cache/-/record-cache-1.1.1.tgz#ba3088a489f50491a4af7b14d410822c394fb811" + integrity sha512-L5hZlgWc7CmGbztnemQoKE1bLu9rtI2skOB0ttE4C5+TVszLE8Rd0YLTROSgvXKLAqPumS/soyN5tJW5wJLmJQ== recursive-readdir@2.2.2: version "2.2.2" @@ -11271,12 +11217,11 @@ redux-thunk@^2.3.0: integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== redux@^4.0.0, redux@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" - integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== + version "4.1.0" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4" + integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g== dependencies: - loose-envify "^1.4.0" - symbol-observable "^1.2.0" + "@babel/runtime" "^7.9.2" regenerate-unicode-properties@^8.2.0: version "8.2.0" @@ -11400,57 +11345,15 @@ renderkid@^2.0.4: strip-ansi "^3.0.0" repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + 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= -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -11516,9 +11419,9 @@ resolve-pathname@^3.0.0: integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== resolve-url-loader@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz#235e2c28e22e3e432ba7a5d4e305c59a58edfc08" - integrity sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ== + version "3.1.3" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.3.tgz#49ec68340f67d8d2ab6b401948d5def3ab2d0367" + integrity sha512-WbDSNFiKPPLem1ln+EVTE+bFUBdTTytfQZWbmghroaFNFaAVmGq0Saqw6F/306CwgPXsGwXVxbODE+3xAo/YbA== dependencies: adjust-sourcemap-loader "3.0.0" camelcase "5.3.1" @@ -11544,7 +11447,7 @@ resolve@1.18.1: is-core-module "^2.0.0" path-parse "^1.0.6" -resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.3.2, resolve@^1.8.1: +resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.8.1: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -11762,7 +11665,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -11788,9 +11691,9 @@ sanitize.css@^10.0.0: integrity sha512-vTxrZz4dX5W86M6oVWVdOVe72ZiPs41Oi7Z6Km4W5Turyz28mrXSJhhEBZoRtzJWIv3833WKVwLSDWWkEfupMg== sass-loader@^10.0.5: - version "10.1.1" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.1.1.tgz#4ddd5a3d7638e7949065dd6e9c7c04037f7e663d" - integrity sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw== + version "10.2.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.2.0.tgz#3d64c1590f911013b3fa48a0b22a83d5e1494716" + integrity sha512-kUceLzC1gIHz0zNJPpqRsJyisWatGYNFRmv2CKZK2/ngMJgLqxTbXwe/hJ85luyvZkgqU3VlJ33UVF2T/0g6mw== dependencies: klona "^2.0.4" loader-utils "^2.0.0" @@ -11856,9 +11759,9 @@ select-hose@^2.0.0: integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= selfsigned@^1.10.8: - version "1.10.8" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30" - integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w== + version "1.10.11" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" + integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== dependencies: node-forge "^0.10.0" @@ -12077,15 +11980,15 @@ simple-get@^4.0.0: simple-concat "^1.0.0" simple-peer@^9.7.1, simple-peer@^9.7.2: - version "9.10.0" - resolved "https://registry.yarnpkg.com/simple-peer/-/simple-peer-9.10.0.tgz#f458444300f635e6fcc2f5a5166c45d71eafb57f" - integrity sha512-sKrKtca1UdmwdZIbvuT3iEL05tDGt/xdLP6+ej8rh1ADgtDk44yLaEZjIyPJ6c34zsSih46Ou7zUIT7e4hPK7g== + version "9.11.0" + resolved "https://registry.yarnpkg.com/simple-peer/-/simple-peer-9.11.0.tgz#e8d27609c7a610c3ddd75767da868e8daab67571" + integrity sha512-qvdNu/dGMHBm2uQ7oLhQBMhYlrOZC1ywXNCH/i8I4etxR1vrjCnU6ZSQBptndB1gcakjo2+w4OHo7Sjza1SHxg== dependencies: - buffer "^6.0.2" - debug "^4.2.0" - err-code "^2.0.3" - get-browser-rtc "^1.0.2" - queue-microtask "^1.2.0" + buffer "^6.0.3" + debug "^4.3.1" + err-code "^3.0.1" + get-browser-rtc "^1.1.0" + queue-microtask "^1.2.3" randombytes "^2.1.0" readable-stream "^3.6.0" @@ -12250,6 +12153,11 @@ source-map-explorer@^2.1.0: temp "^0.9.4" yargs "^16.2.0" +source-map-js@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" + integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== + source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" @@ -12261,7 +12169,7 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.19: +source-map-support@^0.5.17, source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.19: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -12316,9 +12224,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.7" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" - integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== + version "3.0.9" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz#8a595135def9592bda69709474f1cbeea7c2467f" + integrity sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ== spdy-transport@^3.0.0: version "3.0.0" @@ -12372,25 +12280,10 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - ssri@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" - integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + version "6.0.2" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" + integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== dependencies: figgy-pudding "^3.5.1" @@ -12431,11 +12324,6 @@ static-extend@^0.1.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= - stream-browserify@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" @@ -12532,14 +12420,15 @@ string-width@^4.1.0, string-width@^4.2.0: strip-ansi "^6.0.0" string.prototype.matchall@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.4.tgz#608f255e93e072107f5de066f81a2dfb78cf6b29" - integrity sha512-pknFIWVachNcyqRfaQSeu/FUfpvJTe4uskUSZ9Wc1RijsPuzbZ8TyYT8WCNnntCjUEqQ3vUHMAfVj2+wLAisPQ== + version "4.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da" + integrity sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" - has-symbols "^1.0.1" + es-abstract "^1.18.2" + 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" @@ -12715,9 +12604,9 @@ supports-color@^8.1.1: has-flag "^4.0.0" supports-hyperlinks@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47" - integrity sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== dependencies: has-flag "^4.0.0" supports-color "^7.0.0" @@ -12746,7 +12635,7 @@ svgo@^1.0.0, svgo@^1.2.2: unquote "~1.1.1" util.promisify "~1.0.0" -symbol-observable@1.2.0, symbol-observable@^1.2.0: +symbol-observable@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== @@ -12766,20 +12655,17 @@ table@^5.2.3: slice-ansi "^2.1.0" string-width "^3.0.0" -table@^6.0.4: - version "6.0.9" - resolved "https://registry.yarnpkg.com/table/-/table-6.0.9.tgz#790a12bf1e09b87b30e60419bafd6a1fd85536fb" - integrity sha512-F3cLs9a3hL1Z7N4+EkSscsel3z55XT950AvB05bwayrNg5T1/gykXtigioTAjbltvbMSJvvhFCbnf6mX+ntnJQ== +table@^6.0.9: + version "6.7.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" + integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== dependencies: ajv "^8.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" lodash.clonedeep "^4.5.0" - lodash.flatten "^4.4.0" lodash.truncate "^4.4.2" slice-ansi "^4.0.0" string-width "^4.2.0" + strip-ansi "^6.0.0" tapable@^1.0.0, tapable@^1.1.3: version "1.1.3" @@ -12868,9 +12754,9 @@ terser@^4.1.2, terser@^4.6.2, terser@^4.6.3: source-map-support "~0.5.12" terser@^5.3.4: - version "5.6.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.6.1.tgz#a48eeac5300c0a09b36854bf90d9c26fb201973c" - integrity sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw== + version "5.7.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.0.tgz#a761eeec206bc87b605ab13029876ead938ae693" + integrity sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g== dependencies: commander "^2.20.0" source-map "~0.7.2" @@ -13025,14 +12911,6 @@ torrent-piece@^2.0.0: resolved "https://registry.yarnpkg.com/torrent-piece/-/torrent-piece-2.0.1.tgz#a1a50fffa589d9bf9560e38837230708bc3afdc6" integrity sha512-JLSOyvQVLI6JTWqioY4vFL0JkEUKQcaHQsU3loxkCvPTSttw8ePs2tFwsP4XIjw99Fz8EdOzt/4faykcbnPbCQ== -tough-cookie@^2.3.3, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tough-cookie@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" @@ -13043,9 +12921,9 @@ tough-cookie@^4.0.0: universalify "^0.1.2" tr46@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" - integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== dependencies: punycode "^2.1.1" @@ -13054,6 +12932,18 @@ tryer@^1.0.1: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== +ts-node@^9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" + integrity sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg== + dependencies: + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + ts-pnp@1.2.0, ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" @@ -13075,9 +12965,9 @@ tslib@^1.8.1, tslib@^1.9.0: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + version "2.2.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" + integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== tsutils@^3.17.1: version "3.21.0" @@ -13091,23 +12981,11 @@ tty-browserify@0.0.0: resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - tunnel@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -13193,9 +13071,9 @@ typescript@^3.2.1, typescript@^3.9.3: integrity sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w== typescript@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" - integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== + version "4.3.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" + integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw== uint64be@^2.0.2: version "2.0.2" @@ -13204,7 +13082,7 @@ uint64be@^2.0.2: dependencies: buffer-alloc "^1.1.0" -unbox-primitive@^1.0.0: +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== @@ -13385,9 +13263,9 @@ ut_pex@^2.0.0: string2compact "^1.2.5" utf-8-validate@^5.0.2: - version "5.0.4" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.4.tgz#72a1735983ddf7a05a43a9c6b67c5ce1c910f9b8" - integrity sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q== + version "5.0.5" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.5.tgz#dd32c2e82c72002dc9f02eb67ba6761f43456ca1" + integrity sha512-+pnxRYsS/axEpkrrEpzYfNZGXp0IjC/9RIxwM5gntY4Koi8SHmUGSfxfWqxZdRxrtaoVstuOzUp/rbs3JSPELQ== dependencies: node-gyp-build "^4.2.0" @@ -13454,9 +13332,9 @@ v8-compile-cache@^2.0.3: integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== v8-to-istanbul@^7.0.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.1.tgz#04bfd1026ba4577de5472df4f5e89af49de5edda" - integrity sha512-p0BB09E5FRjx0ELN6RgusIPsSPhtgexSRcKETybEs6IGOTXJSZqfwxp7r//55nnu0f1AxltY5VvdVqy2vZf9AA== + version "7.1.2" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz#30898d1a7fa0c84d225a2c1434fb958f290883c1" + integrity sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" @@ -13470,6 +13348,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validator@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-11.1.0.tgz#ac18cac42e0aa5902b603d7a5d9b7827e2346ac4" + integrity sha512-qiQ5ktdO7CD6C/5/mYV4jku/7qnqzjrxb3C/Q5wR3vGGinHTgJZN/TdFT3ZX4vXhX2R1PXx42fB1cn5W+uJ4lg== + value-equal@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" @@ -13485,15 +13368,6 @@ vendors@^1.0.0: resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - videostream@^3.2.1: version "3.2.2" resolved "https://registry.yarnpkg.com/videostream/-/videostream-3.2.2.tgz#e3e8d44f5159892f8f31ad35cbf9302d7a6e6afc" @@ -14046,10 +13920,10 @@ ws@^6.2.1: dependencies: async-limiter "~1.0.0" -ws@^7.3.0, ws@^7.4.2, ws@^7.4.4, ws@~7.4.2: - version "7.4.4" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59" - integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw== +ws@^7.3.0, ws@^7.4.2, ws@^7.4.5, 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== xml-name-validator@^3.0.0: version "3.0.0" @@ -14061,10 +13935,10 @@ xmlchars@^2.2.0: resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -xmlhttprequest-ssl@~1.5.4: - version "1.5.5" - resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" - integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= +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== xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" @@ -14072,14 +13946,14 @@ xtend@^4.0.0, xtend@~4.0.1: integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" - integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== + 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.5" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18" - integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg== + 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" @@ -14104,7 +13978,7 @@ yargs-parser@^13.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^18.1.2: +yargs-parser@^18.1.2, yargs-parser@^18.1.3: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== @@ -14176,6 +14050,11 @@ yeast@0.1.2: resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" diff --git a/compose/README.md b/compose/README.md index 50a809aa..816913ab 100644 --- a/compose/README.md +++ b/compose/README.md @@ -28,5 +28,15 @@ also for the websocket connection. Rebuild the web application bundle: ```sh -docker-compose exec edumeet sh -c "cd app && yarn && yarn build" +docker-compose exec -u $UID edumeet sh -c "cd app && yarn && yarn build" +``` + +## Known issues + +The docker virtual network used by this compose configuration (`172.22.0.0/24`) +should be reacheble from all the started services. If iptables is filtering the +INPUT chain, this rule is required to make the services communicating with each other: + +``` +iptables -A INPUT --src 172.22.0.0/16 -j ACCEPT ``` diff --git a/compose/config/edumeet-app-config.js b/compose/config/edumeet-app-config.js index 7c636a4e..dc87a31a 100644 --- a/compose/config/edumeet-app-config.js +++ b/compose/config/edumeet-app-config.js @@ -1,311 +1,6 @@ // eslint-disable-next-line var config = { - loginEnabled : false, developmentPort : 8443, - productionPort : 3443, - - /* - // If the server component runs on a different host than the app - // you can uncomment the following line and specify the host name. - serverHostname : 'external-server.com', - */ - - /** - * Supported browsers version - * in bowser satisfy format. - * See more: - * https://www.npmjs.com/package/bowser#filtering-browsers - * Otherwise you got a unsupported browser page - */ - supportedBrowsers : - { - 'windows' : { - 'internet explorer' : '>12', - 'microsoft edge' : '>18' - }, - 'safari' : '>12', - 'firefox' : '>=60', - 'chrome' : '>=74', - 'chromium' : '>=74', - 'opera' : '>=62', - 'samsung internet for android' : '>=11.1.1.52' - }, - - /** - * Network priorities - * DSCP bits set by browser according this priority values. - * ("high" means actually: EF for audio, and AF41 for Video in chrome) - * https://en.wikipedia.org/wiki/Differentiated_services - */ - networkPriorities : - { - 'audio' : 'high', - 'mainVideo' : 'high', - 'additionalVideos' : 'medium', - 'screenShare' : 'medium' - }, - - /** - * Resolutions: - * - * low ~ 320x240 - * medium ~ 640x480 - * high ~ 1280x720 - * veryhigh ~ 1920x1080 - * ultra ~ 3840x2560 - * - **/ - - /** - * Frame rates: - * - * 1, 5, 10, 15, 20, 25, 30 - * - **/ - // The aspect ratio of the videos as shown on - // the screen. This is changeable in client settings. - // This value must match one of the defined values in - // viewAspectRatios EXACTLY (e.g. 1.333) - viewAspectRatio : 1.777, - // These are the selectable aspect ratios in the settings - viewAspectRatios : [ { - value : 1.333, // 4 / 3 - label : '4 : 3' - }, { - value : 1.777, // 16 / 9 - label : '16 : 9' - } ], - // The aspect ratio of the video from the camera - // this is not changeable in settings, only config - videoAspectRatio : 1.777, - defaultResolution : 'medium', - defaultFrameRate : 15, - defaultScreenResolution : 'veryhigh', - defaultScreenSharingFrameRate : 5, - // Enable or disable simulcast for webcam video - simulcast : true, - // Enable or disable simulcast for screen sharing video - simulcastSharing : false, - // Define different encodings for various resolutions of the video - simulcastProfiles : - { - 3840 : - [ - { scaleResolutionDownBy: 4, maxBitRate: 1500000 }, - { scaleResolutionDownBy: 2, maxBitRate: 4000000 }, - { scaleResolutionDownBy: 1, maxBitRate: 10000000 } - ], - 1920 : - [ - { scaleResolutionDownBy: 4, maxBitRate: 750000 }, - { scaleResolutionDownBy: 2, maxBitRate: 1500000 }, - { scaleResolutionDownBy: 1, maxBitRate: 4000000 } - ], - 1280 : - [ - { scaleResolutionDownBy: 4, maxBitRate: 250000 }, - { scaleResolutionDownBy: 2, maxBitRate: 900000 }, - { scaleResolutionDownBy: 1, maxBitRate: 3000000 } - ], - 640 : - [ - { scaleResolutionDownBy: 2, maxBitRate: 250000 }, - { scaleResolutionDownBy: 1, maxBitRate: 900000 } - ], - 320 : - [ - { scaleResolutionDownBy: 1, maxBitRate: 250000 } - ] - }, - - // The adaptive spatial layer selection scaling factor (in the range [0.5, 1.0]) - // example: - // with level width=640px, the minimum width required to trigger the - // level change will be: 640 * 0.75 = 480px - adaptiveScalingFactor : 0.75, - - /** - * White listing browsers that support audio output device selection. - * It is not yet fully implemented in Firefox. - * See: https://bugzilla.mozilla.org/show_bug.cgi?id=1498512 - */ - audioOutputSupportedBrowsers : - [ - 'chrome', - 'opera' - ], - // Socket.io request timeout - requestTimeout : 20000, - requestRetries : 3, - transportOptions : - { - tcp : true - }, - - /** - * Set max number participants in one room that join - * unmuted. Next participant will join automatically muted - * Default value is 4 - * - * Set it to 0 to auto mute all, - * Set it to negative (-1) to never automatically auto mute - * but use it with caution - * full mesh audio strongly decrease room capacity! - */ - autoMuteThreshold : 4, - background : 'images/background.jpg', - defaultLayout : 'democratic', // democratic, filmstrip - // If true, will show media control buttons in separate - // control bar, not in the ME container. - buttonControlBar : false, - // If false, will push videos away to make room for side - // drawer. If true, will overlay side drawer over videos - drawerOverlayed : true, - // Position of notifications - notificationPosition : 'right', - - /** - * Set the notificationSounds. Valid keys are: - * 'parkedPeer', 'parkedPeers', 'raisedHand', 'chatMessage', - * 'sendFile', 'newPeer' and 'default'. - * - * Not defining a key is equivalent to using the default notification sound. - * Setting 'play' to null disables the sound notification. - */ - notificationSounds : { - chatMessage : { - play : '/sounds/notify-chat.mp3' - }, - raisedHand : { - play : '/sounds/notify-hand.mp3' - }, - default : { - delay : 5000, // minimum delay between alert sounds [ms] - play : '/sounds/notify.mp3' - } - }, - // Timeout for autohiding topbar and button control bar - hideTimeout : 3000, - // max number of participant that will be visible in - // as speaker - lastN : 4, - mobileLastN : 1, - // Highest number of lastN the user can select manually in - // userinteface - maxLastN : 5, - // If truthy, users can NOT change number of speakers visible - lockLastN : false, - // Show logo if "logo" is not null, else show title - // Set logo file name using logo.* pattern like "logo.png" to not track it by git - logo : 'images/logo.edumeet.svg', - title : 'edumeet', - // Service & Support URL - // if not set then not displayed on the about modals - supportUrl : 'https://support.example.com', - // Privacy and dataprotection URL or path - // by default privacy/privacy.html - // that is a placeholder for your policies - // - // but an external url could be also used here - privacyUrl : 'privacy/privacy.html', - theme : - { - palette : - { - primary : - { - main : '#313131' - } - }, - overrides : - { - MuiAppBar : - { - colorPrimary : - { - backgroundColor : '#313131' - } - }, - MuiButton : - { - containedPrimary : - { - backgroundColor : '#5F9B2D', - '&:hover' : - { - backgroundColor : '#5F9B2D' - } - }, - containedSecondary : - { - backgroundColor : '#f50057', - '&:hover' : - { - backgroundColor : '#f50057' - } - } - - }, - - /* - MuiIconButton : - { - colorPrimary : - { - backgroundColor : '#5F9B2D', - '&:hover' : - { - backgroundColor : '#5F9B2D' - } - }, - colorSecondary : - { - backgroundColor : '#f50057', - '&:hover' : - { - backgroundColor : '#f50057' - } - } - - }, - */ - - MuiFab : - { - primary : - { - backgroundColor : '#5F9B2D', - '&:hover' : - { - backgroundColor : '#5F9B2D' - } - }, - secondary : - { - backgroundColor : '#f50057', - '&:hover' : - { - backgroundColor : '#f50057' - } - } - - }, - MuiBadge : - { - colorPrimary : - { - backgroundColor : '#5F9B2D', - '&:hover' : - { - backgroundColor : '#518029' - } - } - } - }, - typography : - { - useNextVariants : true - } - } + productionPort : 3443 }; diff --git a/compose/config/edumeet-server-config.js b/compose/config/edumeet-server-config.js index f38a04a5..1da42fb4 100644 --- a/compose/config/edumeet-server-config.js +++ b/compose/config/edumeet-server-config.js @@ -1,33 +1,7 @@ const os = require('os'); -// const fs = require('fs'); - -const userRoles = require('../userRoles'); - -import { - BYPASS_ROOM_LOCK, - BYPASS_LOBBY -} from '../access'; - -const { - CHANGE_ROOM_LOCK, - PROMOTE_PEER, - MODIFY_ROLE, - SEND_CHAT, - MODERATE_CHAT, - SHARE_AUDIO, - SHARE_VIDEO, - SHARE_SCREEN, - EXTRA_VIDEO, - SHARE_FILE, - MODERATE_FILES, - MODERATE_ROOM -} = require('../permissions'); - -// const AwaitQueue = require('awaitqueue'); -// const axios = require('axios'); // To gather ip address only on interface like eth0, ens0p3 -const ifaceWhiteListRegex = /^(eth.*)|(ens.*)|(tun.*)/ +const ifaceWhiteListRegex = /^(eth.*)|(ens.*)|(tun.*)|(wlp.*)/ function getListenIps() { let listenIP = []; @@ -53,351 +27,6 @@ function getListenIps() { module.exports = { - - // Auth conf - /* - auth : - { - // Always enabled if configured - lti : - { - consumerKey : 'key', - consumerSecret : 'secret' - }, - - // Auth strategy to use (default oidc) - strategy : 'oidc', - oidc : - { - // The issuer URL for OpenID Connect discovery - // The OpenID Provider Configuration Document - // could be discovered on: - // issuerURL + '/.well-known/openid-configuration' - - // e.g. google OIDC config - // Follow this guide to get credential: - // https://developers.google.com/identity/protocols/oauth2/openid-connect - // use this issuerURL - // issuerURL : 'https://accounts.google.com/', - - issuerURL : 'https://example.com', - clientOptions : - { - client_id : '', - client_secret : '', - scope : 'openid email profile', - // where client.example.com is your edumeet server - redirect_uri : 'https://client.example.com/auth/callback' - } - - }, - saml : - { - // where edumeet.example.com is your edumeet server - callbackUrl : 'https://edumeet.example.com/auth/callback', - issuer : 'https://edumeet.example.com', - entryPoint : 'https://openidp.feide.no/simplesaml/saml2/idp/SSOService.php', - privateCert : fs.readFileSync('config/saml_privkey.pem', 'utf-8'), - signingCert : fs.readFileSync('config/saml_cert.pem', 'utf-8'), - decryptionPvk : fs.readFileSync('config/saml_privkey.pem', 'utf-8'), - decryptionCert : fs.readFileSync('config/saml_cert.pem', 'utf-8'), - // Federation cert - cert : fs.readFileSync('config/federation_cert.pem', 'utf-8') - }, - - // to create password hash use: node server/utils/password_encode.js cleartextpassword - local : - { - users : [ - { - id : 1, - username : 'alice', - passwordHash : '$2b$10$PAXXw.6cL3zJLd7ZX.AnL.sFg2nxjQPDmMmGSOQYIJSa0TrZ9azG6', - displayName : 'Alice', - emails : [ { value: 'alice@atlanta.com' } ] - }, - { - id : 2, - username : 'bob', - passwordHash : '$2b$10$BzAkXcZ54JxhHTqCQcFn8.H6klY/G48t4jDBeTE2d2lZJk/.tvv0G', - displayName : 'Bob', - emails : [ { value: 'bob@biloxi.com' } ] - } - ] - } - }, - */ - // URI and key for requesting geoip-based TURN server closest to the client - //turnAPIKey : 'examplekey', - //turnAPIURI : 'https://example.com/api/turn', - //turnAPIparams : { - // 'uri_schema' : 'turn', - // 'transport' : 'tcp', - // 'ip_ver' : 'ipv4', - // 'servercount' : '2' - //}, - //turnAPITimeout : 2 * 1000, - // Backup turnservers if REST fails or is not configured - //backupTurnServers : [ - // { - // urls : [ - // 'turn:turn.example.com:443?transport=tcp' - // ], - // username : 'example', - // credential : 'example' - // } - //], - // bittorrent tracker - fileTracker : 'wss://tracker.lab.vvc.niif.hu:443', - // redis server options - redisOptions : { - host: 'redis', - port: 6379 - }, - // session cookie secret - cookieSecret : 'T0P-S3cR3t_cook!e', - cookieName : 'edumeet.sid', - // if you use encrypted private key the set the passphrase - tls : - { - cert : `${__dirname}/../certs/mediasoup-demo.localhost.cert.pem`, - // passphrase: 'key_password' - key : `${__dirname}/../certs/mediasoup-demo.localhost.key.pem` - }, - // listening Host or IP - // If omitted listens on every IP. ("0.0.0.0" and "::") - // listeningHost: 'localhost', - // Listening port for https server. - listeningPort : 3443, - // Any http request is redirected to https. - // Listening port for http server. - listeningRedirectPort : 8080, - // Listens only on http, only on listeningPort - // listeningRedirectPort disabled - // use case: loadbalancer backend - httpOnly : false, - // WebServer/Express trust proxy config for httpOnly mode - // You can find more info: - // - https://expressjs.com/en/guide/behind-proxies.html - // - https://www.npmjs.com/package/proxy-addr - // use case: loadbalancer backend - trustProxy : '', - // This logger class will have the log function - // called every time there is a room created or destroyed, - // or peer created or destroyed. This would then be able - // to log to a file or external service. - /* StatusLogger : class - { - constructor() - { - this._queue = new AwaitQueue(); - } - - // rooms: rooms object - // peers: peers object - // eslint-disable-next-line no-unused-vars - async log({ rooms, peers }) - { - this._queue.push(async () => - { - // Do your logging in here, use queue to keep correct order - - // eslint-disable-next-line no-console - console.log('Number of rooms: ', rooms.size); - // eslint-disable-next-line no-console - console.log('Number of peers: ', peers.size); - }) - .catch((error) => - { - // eslint-disable-next-line no-console - console.log('error in log', error); - }); - } - }, */ - // This function will be called on successful login through oidc. - // Use this function to map your oidc userinfo to the Peer object. - // The roomId is equal to the room name. - // See examples below. - // Examples: - /* - // All authenicated users will be MODERATOR and AUTHENTICATED - userMapping : async ({ peer, room, roomId, userinfo }) => - { - peer.addRole(userRoles.MODERATOR); - peer.addRole(userRoles.AUTHENTICATED); - }, - // All authenicated users will be AUTHENTICATED, - // and those with the moderator role set in the userinfo - // will also be MODERATOR - userMapping : async ({ peer, room, roomId, userinfo }) => - { - if ( - Array.isArray(userinfo.meet_roles) && - userinfo.meet_roles.includes('moderator') - ) - { - peer.addRole(userRoles.MODERATOR); - } - - if ( - Array.isArray(userinfo.meet_roles) && - userinfo.meet_roles.includes('meetingadmin') - ) - { - peer.addRole(userRoles.ADMIN); - } - - peer.addRole(userRoles.AUTHENTICATED); - }, - // First authenticated user will be moderator, - // all others will be AUTHENTICATED - userMapping : async ({ peer, room, roomId, userinfo }) => - { - if (room) - { - const peers = room.getJoinedPeers(); - - if (peers.some((_peer) => _peer.authenticated)) - peer.addRole(userRoles.AUTHENTICATED); - else - { - peer.addRole(userRoles.MODERATOR); - peer.addRole(userRoles.AUTHENTICATED); - } - } - }, - // All authenicated users will be AUTHENTICATED, - // and those with email ending with @example.com - // will also be MODERATOR - userMapping : async ({ peer, room, roomId, userinfo }) => - { - if (userinfo.email && userinfo.email.endsWith('@example.com')) - { - peer.addRole(userRoles.MODERATOR); - } - - peer.addRole(userRoles.AUTHENTICATED); - }, - // All authenicated users will be AUTHENTICATED, - // and those with email ending with @example.com - // will also be MODERATOR - userMapping : async ({ peer, room, roomId, userinfo }) => - { - if (userinfo.email && userinfo.email.endsWith('@example.com')) - { - peer.addRole(userRoles.MODERATOR); - } - - peer.addRole(userRoles.AUTHENTICATED); - }, - */ - // eslint-disable-next-line no-unused-vars - userMapping : async ({ peer, room, roomId, userinfo }) => - { - if (userinfo.picture != null) - { - if (!userinfo.picture.match(/^http/g)) - { - peer.picture = `data:image/jpeg;base64, ${userinfo.picture}`; - } - else - { - peer.picture = userinfo.picture; - } - } - if (userinfo['urn:oid:0.9.2342.19200300.100.1.60'] != null) - { - peer.picture = `data:image/jpeg;base64, ${userinfo['urn:oid:0.9.2342.19200300.100.1.60']}`; - } - - if (userinfo.nickname != null) - { - peer.displayName = userinfo.nickname; - } - - if (userinfo.name != null) - { - peer.displayName = userinfo.name; - } - - if (userinfo.displayName != null) - { - peer.displayName = userinfo.displayName; - } - - if (userinfo['urn:oid:2.16.840.1.113730.3.1.241'] != null) - { - peer.displayName = userinfo['urn:oid:2.16.840.1.113730.3.1.241']; - } - - if (userinfo.email != null) - { - peer.email = userinfo.email; - } - }, - // All users have the role "NORMAL" by default. Other roles need to be - // added in the "userMapping" function. The following accesses and - // permissions are arrays of roles. Roles can be changed in userRoles.js - // - // Example: - // [ userRoles.MODERATOR, userRoles.AUTHENTICATED ] - accessFromRoles : { - // The role(s) will gain access to the room - // even if it is locked (!) - [BYPASS_ROOM_LOCK] : [ userRoles.ADMIN ], - // The role(s) will gain access to the room without - // going into the lobby. If you want to restrict access to your - // server to only directly allow authenticated users, you could - // add the userRoles.AUTHENTICATED to the user in the userMapping - // function, and change to BYPASS_LOBBY : [ userRoles.AUTHENTICATED ] - [BYPASS_LOBBY] : [ userRoles.NORMAL ] - }, - permissionsFromRoles : { - // The role(s) have permission to lock/unlock a room - [CHANGE_ROOM_LOCK] : [ userRoles.MODERATOR ], - // The role(s) have permission to promote a peer from the lobby - [PROMOTE_PEER] : [ userRoles.NORMAL ], - // The role(s) have permission to give/remove other peers roles - [MODIFY_ROLE] : [ userRoles.NORMAL ], - // The role(s) have permission to send chat messages - [SEND_CHAT] : [ userRoles.NORMAL ], - // The role(s) have permission to moderate chat - [MODERATE_CHAT] : [ userRoles.MODERATOR ], - // The role(s) have permission to share audio - [SHARE_AUDIO] : [ userRoles.NORMAL ], - // The role(s) have permission to share video - [SHARE_VIDEO] : [ userRoles.NORMAL ], - // The role(s) have permission to share screen - [SHARE_SCREEN] : [ userRoles.NORMAL ], - // The role(s) have permission to produce extra video - [EXTRA_VIDEO] : [ userRoles.NORMAL ], - // The role(s) have permission to share files - [SHARE_FILE] : [ userRoles.NORMAL ], - // The role(s) have permission to moderate files - [MODERATE_FILES] : [ userRoles.MODERATOR ], - // The role(s) have permission to moderate room (e.g. kick user) - [MODERATE_ROOM] : [ userRoles.MODERATOR ] - }, - // Array of permissions. If no peer with the permission in question - // is in the room, all peers are permitted to do the action. The peers - // that are allowed because of this rule will not be able to do this - // action as soon as a peer with the permission joins. In this example - // everyone will be able to lock/unlock room until a MODERATOR joins. - allowWhenRoleMissing : [ CHANGE_ROOM_LOCK ], - // When truthy, the room will be open to all users when as long as there - // are allready users in the room - activateOnHostJoin : true, - // When set, maxUsersPerRoom defines how many users can join - // a single room. If not set, there is no limit. - // maxUsersPerRoom : 20, - // Room size before spreading to new router - routerScaleSize : 40, - // Socket timout value - requestTimeout : 20000, - // Socket retries when timeout - requestRetries : 3, - // If > 0, sets a cache-control max-age (in seconds) to static files responses. - staticFilesCachePeriod : 0, // Mediasoup settings mediasoup : { @@ -479,32 +108,6 @@ module.exports = webRtcTransport : { listenIps : getListenIps(), - /*[ - // change 192.0.2.1 IPv4 to your server's IPv4 address!! - //{ ip: '192.0.2.1', announcedIp: null } - // Can have multiple listening interfaces - // change 2001:DB8::1 IPv6 to your server's IPv6 address!! - // { ip: '2001:DB8::1', announcedIp: null } - ],*/ - initialAvailableOutgoingBitrate : 1000000, - minimumAvailableOutgoingBitrate : 600000, - // Additional options that are not part of WebRtcTransportOptions. - maxIncomingBitrate : 1500000 } } - - - , - // Prometheus exporter - prometheus : { - deidentify : false, // deidentify IP addresses - // listen : 'localhost', // exporter listens on this address - numeric : true, // show numeric IP addresses - port : 8889, // allocated port - quiet : false, // include fewer labels - // aggregated metrics options - period : 15, // update period (seconds) - secret : null // if set, checks the authorization header: `Bearer ` - } - }; diff --git a/compose/config/edumeet-server-config.yaml b/compose/config/edumeet-server-config.yaml new file mode 100644 index 00000000..0779a2a5 --- /dev/null +++ b/compose/config/edumeet-server-config.yaml @@ -0,0 +1,12 @@ +redisOptions: + host: redis + port: 6379 + +listeningPort: 3443 +listeningRedirectPort: 0 +httpOnly: false +trustProxy: '' + +prometheus: + enabled: true + listen: 0.0.0.0 diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index ee58f3b2..f4e39467 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -18,6 +18,7 @@ services: volumes: - ${PWD}/..:/edumeet - ${PWD}/config/edumeet-server-config.js:/edumeet/server/config/config.js:ro + - ${PWD}/config/edumeet-server-config.yaml:/edumeet/server/config/config.yaml:ro - ${PWD}/config/edumeet-app-config.js:/edumeet/app/public/config/config.js:ro network_mode: "host" extra_hosts: diff --git a/compose/edumeet/Dockerfile b/compose/edumeet/Dockerfile index 140828dc..d7b52c3b 100644 --- a/compose/edumeet/Dockerfile +++ b/compose/edumeet/Dockerfile @@ -6,5 +6,7 @@ WORKDIR /edumeet ENV DEBUG=edumeet*,mediasoup* RUN npm install -g nodemon && \ npm install -g concurrently -RUN touch /.yarnrc && mkdir /.yarn && chmod 775 /.yarn /.yarnrc -CMD concurrently --names "server,app" "cd server && yarn && yarn dev" "cd app && yarn && yarn build && yarn start" \ No newline at end of file +RUN touch /.yarnrc && mkdir -p /.yarn /.cache/yarn && chmod 775 /.yarn /.yarnrc /.cache/yarn +CMD concurrently --names "server,app" \ + "cd server && yarn && yarn dev" \ + "cd app && yarn && yarn build && yarn start" diff --git a/edumeet.service b/edumeet.service index 94b940e6..f5f648c1 100644 --- a/edumeet.service +++ b/edumeet.service @@ -3,13 +3,18 @@ Description=edumeet is a audio / video meeting service running in the browser an After=network.target [Service] -ExecStart=/usr/local/src/edumeet/server/server.js +# modify the paths accordingly with your installation +ExecStart=/usr/local/src/edumeet/server/dist/server.js +WorkingDirectory=/usr/local/src/edumeet/server Restart=always +RestartSec=1 User=nobody Group=nogroup Environment=PATH=/usr/bin:/usr/local/bin Environment=NODE_ENV=production -WorkingDirectory=/usr/local/src/edumeet/server +Environment=DEBUG="*ERROR*,*WARN*,*INFO*" +StandardOutput=syslog +StandardError=syslog AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] diff --git a/server/.eslintrc.json b/server/.eslintrc.json index 7df6a6db..4d490dcf 100644 --- a/server/.eslintrc.json +++ b/server/.eslintrc.json @@ -7,8 +7,12 @@ "overrides": [ { "files":["**/*.ts"], - "plugins": ["prettier", "@typescript-eslint"], - "extends": ["airbnb-typescript/base", "prettier"], + "plugins": ["@typescript-eslint"], + "extends":[ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ], "parser": "@typescript-eslint/parser", "parserOptions": { "project": "./tsconfig.json" @@ -21,69 +25,29 @@ // } // }, "rules": { - "no-underscore-dangle":"off", - "object-curly-spacing": [ - "warn", - "always" - ], - "no-unused-vars": [ - "warn", + "no-unused-vars" : 0, + "@typescript-eslint/ban-types" : 0, + "@typescript-eslint/ban-ts-comment" : 0, + "@typescript-eslint/ban-ts-ignore" : 0, + "@typescript-eslint/explicit-module-boundary-types" : 0, + "@typescript-eslint/member-delimiter-style" : [ 2, + { - "vars": "all", - "args": "none" + "multiline" : { "delimiter": "semi", "requireLast": true }, + "singleline" : { "delimiter": "semi", "requireLast": false } } ], - "@typescript-eslint/semi": [ - "off" - ], - "@typescript-eslint/no-unused-vars": [ - "warn", + "@typescript-eslint/no-explicit-any" : 0, + "@typescript-eslint/no-unused-vars" : [ 2, { - "vars": "all", - "args": "none" + "vars" : "all", + "args" : "after-used", + "ignoreRestSiblings" : false } ], - "max-len": [ - "warn", - { - "code": 100, - "ignoreStrings": true, - "ignoreTemplateLiterals": true, - "ignoreComments": true - } - ], - "prefer-destructuring": [ - "error", - { - "VariableDeclarator": { - "array": false, - "object": true - }, - "AssignmentExpression": { - "array": false, - "object": false - } - }, - { - "enforceForRenamedProperties": false - } - ], - "no-plusplus": [ - "error", - { - "allowForLoopAfterthoughts": true - } - ], - "import/no-extraneous-dependencies": [ - "error", - { - "devDependencies": [ - "**/*.test.js", - "**/*.test.ts", - "src/tests/**/*" - ] - } - ] + "@typescript-eslint/no-use-before-define" : [ 2, { "functions": false } ], + "@typescript-eslint/no-empty-function" : 0, + "@typescript-eslint/no-non-null-assertion" : 0 } } ], diff --git a/server/README.md b/server/README.md new file mode 100644 index 00000000..65cad0d3 --- /dev/null +++ b/server/README.md @@ -0,0 +1,81 @@ +# Edumeet Server Configuration + +The server configuration file can use one of the following formats: + +- config/config.json +- config/config.json5 +- config/config.yaml +- config/config.yml +- config/config.toml + +Example `config.yaml`: + +```yaml +redisOptions: + host: redis + port: 6379 + +listeningPort: 3443 +``` + +Additionally, a `config/config.js` can be used to override specific properties +with runtime generated values and to set additional configuration functions and classes. +Look at the default `config/config.example.js` file for documentation. + +## Configuration properties + +| Name | Description | Format | Default value | +| :--- | :---------- | :----- | :------------ | +| turnAPIKey | TURN server key for requesting a geoip-based TURN server closest to the client. | `"string"` | ``""`` | +| turnAPIURI | TURN server URL for requesting a geoip-based TURN server closest to the client. | `"string"` | ``""`` | +| turnAPIparams.uri_schema | TURN server URL schema. | `"string"` | ``"turn"`` | +| turnAPIparams.transport | TURN server transport. | `[ "tcp", "udp"]` | ``"tcp"`` | +| turnAPIparams.ip_ver | TURN server IP version. | `[ "ipv4", "ipv6"]` | ``"ipv4"`` | +| turnAPIparams.servercount | TURN server count. | `"nat"` | ``2`` | +| turnAPITimeout | TURN server API timeout (seconds). | `"nat"` | ``2000`` | +| backupTurnServers | Backup TURN servers if REST fails or is not configured | `"*"` | ``[ { "urls": [ "turn:turn.example.com:443?transport=tcp" ], "username": "example", "credential": "example" }]`` | +| fileTracker | Bittorrent tracker. | `"string"` | ``"wss://tracker.lab.vvc.niif.hu:443"`` | +| redisOptions.host | Redis server host. | `"string"` | ``"localhost"`` | +| redisOptions.port | Redis server port. | `"port"` | ``6379`` | +| redisOptions.password | Redis server password. | `"string"` | ``""`` | +| cookieSecret | Session cookie secret. | `"string"` | ``"T0P-S3cR3t_cook!e"`` | +| cookieName | Session cookie name. | `"string"` | ``"edumeet.sid"`` | +| tls.cert | SSL certificate path. | `"string"` | ``"./certs/mediasoup-demo.localhost.cert.pem"`` | +| tls.key | SSL key path. | `"string"` | ``"./certs/mediasoup-demo.localhost.key.pem"`` | +| listeningHost | The listening Host or IP address. | `"string"` | ``"0.0.0.0"`` | +| listeningPort | The HTTPS listening port. | `"port"` | ``8443`` | +| listeningRedirectPort | The HTTP server listening port used for redirecting any HTTP request to HTTPS. If 0, the redirect server is disabled. | `"port"` | ``8080`` | +| httpOnly | Listens only on HTTP on listeningPort; listeningRedirectPort disabled. Use case: load balancer backend. | `"boolean"` | ``false`` | +| trustProxy | WebServer/Express trust proxy config for httpOnly mode. More infos: [expressjs](https://expressjs.com/en/guide/behind-proxies.html), [proxy-addr](https://www.npmjs.com/package/proxy-addr) | `"string"` | ``""`` | +| staticFilesCachePeriod | The max-age in milliseconds for HTTP caching of static resources. This can also be a string accepted by the [ms module](https://www.npmjs.com/package/ms#readme). | `"*"` | ``0`` | +| activateOnHostJoin | When true, the room will be open to all users since there are users in the room. | `"boolean"` | ``true`` | +| roomsUnlocked | An array of rooms users can enter without waiting in the lobby. | `"array"` | ``[]`` | +| maxUsersPerRoom | It defines how many users can join a single room. If not set, no limit is applied. | `"nat"` | ``0`` | +| routerScaleSize | Room size before spreading to a new router. | `"nat"` | ``40`` | +| requestTimeout | Socket timeout value (ms). | `"nat"` | ``20000`` | +| requestRetries | Socket retries when a timeout occurs. | `"nat"` | ``3`` | +| mediasoup.numWorkers | The number of Mediasoup workers to spawn. Defaults to the available CPUs count. | `"nat"` | ``8`` | +| mediasoup.worker.logLevel | The Mediasoup log level. | `"string"` | ``"warn"`` | +| mediasoup.worker.logTags | The Mediasoup log tags. | `"array"` | ``[ "info", "ice", "dtls", "rtp", "srtp", "rtcp"]`` | +| mediasoup.worker.rtcMinPort | The Mediasoup start listening port number. | `"port"` | ``40000`` | +| mediasoup.worker.rtcMaxPort | The Mediasoup end listening port number. | `"port"` | ``49999`` | +| mediasoup.router.mediaCodecs | The Mediasoup codecs settings. [supportedRtpCapabilities](https://github.com/versatica/mediasoup/blob/v3/src/supportedRtpCapabilities.ts) | `"*"` | ``[ { "kind": "audio", "mimeType": "audio/opus", "clockRate": 48000, "channels": 2 }, { "kind": "video", "mimeType": "video/VP8", "clockRate": 90000, "parameters": { "x-google-start-bitrate": 1000 } }, { "kind": "video", "mimeType": "video/VP9", "clockRate": 90000, "parameters": { "profile-id": 2, "x-google-start-bitrate": 1000 } }, { "kind": "video", "mimeType": "video/h264", "clockRate": 90000, "parameters": { "packetization-mode": 1, "profile-level-id": "4d0032", "level-asymmetry-allowed": 1, "x-google-start-bitrate": 1000 } }, { "kind": "video", "mimeType": "video/h264", "clockRate": 90000, "parameters": { "packetization-mode": 1, "profile-level-id": "42e01f", "level-asymmetry-allowed": 1, "x-google-start-bitrate": 1000 } }]`` | +| mediasoup.webRtcTransport.listenIps | The Mediasoup listen IPs. [TransportListenIp](https://mediasoup.org/documentation/v3/mediasoup/api/#TransportListenIp) | `"array"` | ``[ { "ip": "0.0.0.0", "announcedIp": null }]`` | +| mediasoup.webRtcTransport.initialAvailableOutgoingBitrate | The Mediasoup initial available outgoing bitrate (in bps). [WebRtcTransportOptions](https://mediasoup.org/documentation/v3/mediasoup/api/#WebRtcTransportOptions) | `"nat"` | ``1000000`` | +| mediasoup.webRtcTransport.maxIncomingBitrate | The Mediasoup maximum incoming bitrate for each transport. (in bps). [setMaxIncomingBitrate](https://mediasoup.org/documentation/v3/mediasoup/api/#transport-setMaxIncomingBitrate) | `"nat"` | ``1500000`` | +| prometheus.enabled | Enables the Prometheus metrics exporter. | `"boolean"` | ``false`` | +| prometheus.listen | Prometheus metrics exporter listening address. | `"string"` | ``"localhost"`` | +| prometheus.port | The Prometheus metrics exporter listening port. | `"port"` | ``8889`` | +| prometheus.deidentify | De-identify IP addresses in Prometheus logs. | `"boolean"` | ``false`` | +| prometheus.numeric | Show numeric IP addresses in Prometheus logs. | `"boolean"` | ``false`` | +| prometheus.quiet | Include fewer labels in Prometheus metrics. | `"boolean"` | ``false`` | +| prometheus.period | The Prometheus metrics exporter update period (seconds). | `"nat"` | ``15`` | +| prometheus.secret | The Prometheus metrics exporter authorization header: `Bearer ` required to allow scraping. | `"string"` | ``""`` | +| accessFromRoles | User roles. | `"*"` | ``{ "BYPASS_ROOM_LOCK": [ { "id": 2529, "label": "admin", "level": 50, "promotable": true } ], "BYPASS_LOBBY": [ { "id": 4261, "label": "normal", "level": 10, "promotable": false } ]}`` | +| permissionsFromRoles | User permissions from roles. | `"*"` | ``{ "CHANGE_ROOM_LOCK": [ { "id": 5337, "label": "moderator", "level": 40, "promotable": true } ], "PROMOTE_PEER": [ { "id": 4261, "label": "normal", "level": 10, "promotable": false } ], "MODIFY_ROLE": [ { "id": 4261, "label": "normal", "level": 10, "promotable": false } ], "SEND_CHAT": [ { "id": 4261, "label": "normal", "level": 10, "promotable": false } ], "MODERATE_CHAT": [ { "id": 5337, "label": "moderator", "level": 40, "promotable": true } ], "SHARE_AUDIO": [ { "id": 4261, "label": "normal", "level": 10, "promotable": false } ], "SHARE_VIDEO": [ { "id": 4261, "label": "normal", "level": 10, "promotable": false } ], "SHARE_SCREEN": [ { "id": 4261, "label": "normal", "level": 10, "promotable": false } ], "EXTRA_VIDEO": [ { "id": 4261, "label": "normal", "level": 10, "promotable": false } ], "SHARE_FILE": [ { "id": 4261, "label": "normal", "level": 10, "promotable": false } ], "MODERATE_FILES": [ { "id": 5337, "label": "moderator", "level": 40, "promotable": true } ], "MODERATE_ROOM": [ { "id": 5337, "label": "moderator", "level": 40, "promotable": true } ]}`` | +| allowWhenRoleMissing | Allow when role missing. | `"array"` | ``[ "CHANGE_ROOM_LOCK"]`` | + + +--- + +*Document generated with:* `yarn gen-config-docs` diff --git a/server/config/config.example.js b/server/config/config.example.js index 1deea6ba..0a925839 100644 --- a/server/config/config.example.js +++ b/server/config/config.example.js @@ -1,4 +1,4 @@ -const os = require('os'); +// const os = require('os'); // const fs = require('fs'); const userRoles = require('../userRoles'); @@ -28,7 +28,6 @@ const { module.exports = { - // Auth conf /* auth : @@ -104,58 +103,6 @@ module.exports = } }, */ - // URI and key for requesting geoip-based TURN server closest to the client - turnAPIKey : 'examplekey', - turnAPIURI : 'https://example.com/api/turn', - turnAPIparams : { - 'uri_schema' : 'turn', - 'transport' : 'tcp', - 'ip_ver' : 'ipv4', - 'servercount' : '2' - }, - turnAPITimeout : 2 * 1000, - // Backup turnservers if REST fails or is not configured - backupTurnServers : [ - { - urls : [ - 'turn:turn.example.com:443?transport=tcp' - ], - username : 'example', - credential : 'example' - } - ], - // bittorrent tracker - fileTracker : 'wss://tracker.lab.vvc.niif.hu:443', - // redis server options - redisOptions : {}, - // session cookie secret - cookieSecret : 'T0P-S3cR3t_cook!e', - cookieName : 'edumeet.sid', - // if you use encrypted private key the set the passphrase - tls : - { - cert : `${__dirname}/../certs/mediasoup-demo.localhost.cert.pem`, - // passphrase: 'key_password' - key : `${__dirname}/../certs/mediasoup-demo.localhost.key.pem` - }, - // listening Host or IP - // If omitted listens on every IP. ("0.0.0.0" and "::") - // listeningHost: 'localhost', - // Listening port for https server. - listeningPort : 443, - // Any http request is redirected to https. - // Listening port for http server. - listeningRedirectPort : 80, - // Listens only on http, only on listeningPort - // listeningRedirectPort disabled - // use case: loadbalancer backend - httpOnly : false, - // WebServer/Express trust proxy config for httpOnly mode - // You can find more info: - // - https://expressjs.com/en/guide/behind-proxies.html - // - https://www.npmjs.com/package/proxy-addr - // use case: loadbalancer backend - trustProxy : '', // This logger class will have the log function // called every time there is a room created or destroyed, // or peer created or destroyed. This would then be able @@ -345,135 +292,5 @@ module.exports = // that are allowed because of this rule will not be able to do this // action as soon as a peer with the permission joins. In this example // everyone will be able to lock/unlock room until a MODERATOR joins. - allowWhenRoleMissing : [ CHANGE_ROOM_LOCK ], - // When true, the room will be open to all users as long as there - // are allready users in the room - activateOnHostJoin : true, - // roomsUnlocked is an array of rooms users can enter without waiting - // in the lobby. If the array is undefined or null, users can enter - // any room without waiting in the lobby. This is the default. The - // aim of roomsUnlocked is to enforce moderated access to all rooms - // with the exception of the rooms defined in the array. - // roomsUnlocked : [ 'unlocked1', 'unlocked2', 'unlocked3' ], - // When set, maxUsersPerRoom defines how many users can join - // a single room. If not set, there is no limit. - // maxUsersPerRoom : 20, - // Room size before spreading to new router - routerScaleSize : 40, - // Socket timeout value - requestTimeout : 20000, - // Socket retries when timeout - requestRetries : 3, - // If > 0, sets a cache-control max-age (in seconds) to static files responses. - staticFilesCachePeriod : 0, - // Mediasoup settings - mediasoup : - { - numWorkers : Object.keys(os.cpus()).length, - // mediasoup Worker settings. - worker : - { - logLevel : 'warn', - logTags : - [ - 'info', - 'ice', - 'dtls', - 'rtp', - 'srtp', - 'rtcp' - ], - rtcMinPort : 40000, - rtcMaxPort : 49999 - }, - // mediasoup Router settings. - router : - { - // Router media codecs. - mediaCodecs : - [ - { - kind : 'audio', - mimeType : 'audio/opus', - clockRate : 48000, - channels : 2 - }, - { - kind : 'video', - mimeType : 'video/VP8', - clockRate : 90000, - parameters : - { - 'x-google-start-bitrate' : 1000 - } - }, - { - kind : 'video', - mimeType : 'video/VP9', - clockRate : 90000, - parameters : - { - 'profile-id' : 2, - 'x-google-start-bitrate' : 1000 - } - }, - { - kind : 'video', - mimeType : 'video/h264', - clockRate : 90000, - parameters : - { - 'packetization-mode' : 1, - 'profile-level-id' : '4d0032', - 'level-asymmetry-allowed' : 1, - 'x-google-start-bitrate' : 1000 - } - }, - { - kind : 'video', - mimeType : 'video/h264', - clockRate : 90000, - parameters : - { - 'packetization-mode' : 1, - 'profile-level-id' : '42e01f', - 'level-asymmetry-allowed' : 1, - 'x-google-start-bitrate' : 1000 - } - } - ] - }, - // mediasoup WebRtcTransport settings. - webRtcTransport : - { - listenIps : - [ - // change 192.0.2.1 IPv4 to your server's IPv4 address!! - { ip: '192.0.2.1', announcedIp: null } - - // Can have multiple listening interfaces - // change 2001:DB8::1 IPv6 to your server's IPv6 address!! - // { ip: '2001:DB8::1', announcedIp: null } - ], - initialAvailableOutgoingBitrate : 1000000, - minimumAvailableOutgoingBitrate : 600000, - // Additional options that are not part of WebRtcTransportOptions. - maxIncomingBitrate : 1500000 - } - } - - /* - , - // Prometheus exporter - prometheus : { - deidentify : false, // deidentify IP addresses - // listen : 'localhost', // exporter listens on this address - numeric : true, // show numeric IP addresses - port : 8889, // allocated port - quiet : false // include fewer labels - // aggregated metrics options - period : 15 // update period (seconds) - secret : null // if set, checks the authorization header: `Bearer ` - } - */ + allowWhenRoleMissing : [ CHANGE_ROOM_LOCK ] }; diff --git a/server/gen-config-docs.ts b/server/gen-config-docs.ts new file mode 100644 index 00000000..b1663ff0 --- /dev/null +++ b/server/gen-config-docs.ts @@ -0,0 +1,59 @@ +import { configDocs } from './lib/config'; +import { writeFile } from 'fs/promises'; + +function formatJson(data) +{ + return `\`${data.replace(/\n/g, '')}\``; +} + +let data = `# Edumeet Server Configuration + +The server configuration file can use one of the following formats: + +- config/config.json +- config/config.json5 +- config/config.yaml +- config/config.yml +- config/config.toml + +Example \`config.yaml\`: + +\`\`\`yaml +redisOptions: + host: redis + port: 6379 + +listeningPort: 3443 +\`\`\` + +Additionally, a \`config/config.js\` can be used to override specific properties +with runtime generated values and to set additional configuration functions and classes. +Look at the default \`config/config.example.js\` file for documentation. + +## Configuration properties + +| Name | Description | Format | Default value | +| :--- | :---------- | :----- | :------------ | +`; + +Object.entries(configDocs).forEach((entry: [string, any]) => +{ + const [ name, value ] = entry; + + data += `| ${name} | ${value.doc} | ${formatJson(value.format)} | \`${formatJson(value.default)}\` |\n`; +}); + +data += ` + +--- + +*Document generated with:* \`yarn gen-config-docs\` +`; + +writeFile('README.md', data).then(() => +{ + console.log('done'); // eslint-disable-line +}, (err) => +{ + console.error(`Error writing file: ${err.message}`); // eslint-disable-line +}); diff --git a/server/lib/Room.js b/server/lib/Room.js index 2216b1c8..12a1f530 100644 --- a/server/lib/Room.js +++ b/server/lib/Room.js @@ -29,7 +29,7 @@ const permissions = require('../permissions'), { MODERATE_ROOM } = permissions; -const config = require('../config/config'); +const { config } = require('./config'); const logger = new Logger('Room'); @@ -263,7 +263,7 @@ class Room extends EventEmitter this._queue = new AwaitQueue(); // Locked flag. - this._locked = config.roomsUnlocked && Array.isArray(config.roomsUnlocked) + this._locked = config.roomsUnlocked.length && !config.roomsUnlocked.includes(roomId); // if true: accessCode is a possibility to open the room @@ -395,7 +395,7 @@ class Room extends EventEmitter else if (this._hasAccess(peer, BYPASS_ROOM_LOCK)) this._peerJoining(peer); else if ( - 'maxUsersPerRoom' in config && + config.maxUsersPerRoom && ( Object.keys(this._peers).length + this._lobby.peerList().length @@ -674,7 +674,7 @@ class Room extends EventEmitter let turnServers; - if ('turnAPIURI' in config) + if (config.turnAPIURI) { try { @@ -697,13 +697,13 @@ class Room extends EventEmitter } catch (error) { - if ('backupTurnServers' in config) + if (config.backupTurnServers) turnServers = config.backupTurnServers; logger.error('_peerJoining() | error on REST turn [error:"%o"]', error); } } - else if ('backupTurnServers' in config) + else if (config.backupTurnServers) { turnServers = config.backupTurnServers; } diff --git a/server/lib/config.ts b/server/lib/config.ts new file mode 100644 index 00000000..40b1768a --- /dev/null +++ b/server/lib/config.ts @@ -0,0 +1,546 @@ +import * as fs from 'fs'; +import convict from 'convict'; +import { ipaddress, url } from 'convict-format-with-validator'; +import json5 from 'json5'; +import yaml from 'yaml'; +import toml from 'toml'; +import { cpus } from 'os'; + +import Logger from './Logger'; + +import * as userRoles from '../userRoles'; +import { + BYPASS_ROOM_LOCK, + BYPASS_LOBBY +} from '../access'; +import { + CHANGE_ROOM_LOCK, + PROMOTE_PEER, + MODIFY_ROLE, + SEND_CHAT, + MODERATE_CHAT, + SHARE_AUDIO, + SHARE_VIDEO, + SHARE_SCREEN, + EXTRA_VIDEO, + SHARE_FILE, + MODERATE_FILES, + MODERATE_ROOM +} from '../permissions'; + +const logger = new Logger('config'); + +// add parsers +convict.addParser([ + { extension: 'json', parse: JSON.parse }, + { extension: 'json5', parse: json5.parse }, + { extension: [ 'yml', 'yaml' ], parse: yaml.parse }, + { extension: 'toml', parse: toml.parse } +]); + +// add formats +function assert(assertion: Boolean, msg: string) +{ + if (!assertion) + throw new Error(msg); +} + +const isFloat = { + name : 'float', + coerce : (v: string) => parseFloat(v), + validate : (v: number) => assert(Number.isFinite(v), 'must be a number') +}; + +convict.addFormats({ ipaddress, url, isFloat }); + +// config schema +const configSchema = convict({ + turnAPIKey : + { + doc : 'TURN server key for requesting a geoip-based TURN server closest to the client.', + format : String, + default : '' + }, + turnAPIURI : + { + doc : 'TURN server URL for requesting a geoip-based TURN server closest to the client.', + format : String, + default : '' + }, + turnAPIparams : + { + 'uri_schema' : { + doc : 'TURN server URL schema.', + format : String, + default : 'turn' + }, + 'transport' : { + doc : 'TURN server transport.', + format : [ 'tcp', 'udp' ], + default : 'tcp' + }, + 'ip_ver' : { + doc : 'TURN server IP version.', + format : [ 'ipv4', 'ipv6' ], + default : 'ipv4' + }, + 'servercount' : { + doc : 'TURN server count.', + format : 'nat', + default : 2 + } + }, + turnAPITimeout : { + doc : 'TURN server API timeout (seconds).', + format : 'nat', + default : 2 * 1000 + }, + backupTurnServers : { + doc : 'Backup TURN servers if REST fails or is not configured', + format : '*', + default : [ + { + urls : [ + 'turn:turn.example.com:443?transport=tcp' + ], + username : 'example', + credential : 'example' + } + ] + }, + fileTracker : { + doc : 'Bittorrent tracker.', + format : String, + default : 'wss://tracker.lab.vvc.niif.hu:443' + }, + redisOptions : { + host : { + doc : 'Redis server host.', + format : String, + default : 'localhost' + }, + port : { + doc : 'Redis server port.', + format : 'port', + default : 6379 + }, + password : { + doc : 'Redis server password.', + format : String, + default : '' + } + }, + cookieSecret : { + doc : 'Session cookie secret.', + format : String, + default : 'T0P-S3cR3t_cook!e' + }, + cookieName : { + doc : 'Session cookie name.', + format : String, + default : 'edumeet.sid' + }, + tls : { + cert : { + doc : 'SSL certificate path.', + format : String, + default : './certs/mediasoup-demo.localhost.cert.pem' + }, + key : { + doc : 'SSL key path.', + format : String, + default : './certs/mediasoup-demo.localhost.key.pem' + } + }, + listeningHost : { + doc : 'The listening Host or IP address.', + format : String, + default : '0.0.0.0' + }, + listeningPort : { + doc : 'The HTTPS listening port.', + format : 'port', + default : 8443 + }, + listeningRedirectPort : { + doc : 'The HTTP server listening port used for redirecting any HTTP request to HTTPS. If 0, the redirect server is disabled.', + format : 'port', + default : 8080 + }, + httpOnly : { + doc : 'Listens only on HTTP on listeningPort; listeningRedirectPort disabled. Use case: load balancer backend.', + format : 'Boolean', + default : false + }, + trustProxy : { + doc : 'WebServer/Express trust proxy config for httpOnly mode. More infos: [expressjs](https://expressjs.com/en/guide/behind-proxies.html), [proxy-addr](https://www.npmjs.com/package/proxy-addr)', + format : String, + default : '' + }, + staticFilesCachePeriod : { + doc : 'The max-age in milliseconds for HTTP caching of static resources. This can also be a string accepted by the [ms module](https://www.npmjs.com/package/ms#readme).', + format : '*', + default : 0 + }, + activateOnHostJoin : { + doc : 'When true, the room will be open to all users since there are users in the room.', + format : 'Boolean', + default : true + }, + roomsUnlocked : { + doc : 'An array of rooms users can enter without waiting in the lobby.', + format : Array, + default : [] + }, + maxUsersPerRoom : { + doc : 'It defines how many users can join a single room. If not set, no limit is applied.', + format : 'nat', + default : 0 + }, + routerScaleSize : { + doc : 'Room size before spreading to a new router.', + format : 'nat', + default : 40 + }, + requestTimeout : { + doc : 'Socket timeout value (ms).', + format : 'nat', + default : 20000 + }, + requestRetries : { + doc : 'Socket retries when a timeout occurs.', + format : 'nat', + default : 3 + }, + // Mediasoup settings + mediasoup : + { + numWorkers : { + doc : 'The number of Mediasoup workers to spawn. Defaults to the available CPUs count.', + format : 'nat', + default : Object.keys(cpus()).length + }, + worker : + { + logLevel : { + doc : 'The Mediasoup log level.', + format : String, + default : 'warn' + }, + logTags : { + doc : 'The Mediasoup log tags.', + format : Array, + default : [ + 'info', + 'ice', + 'dtls', + 'rtp', + 'srtp', + 'rtcp' + ] + }, + rtcMinPort : { + doc : 'The Mediasoup start listening port number.', + format : 'port', + default : 40000 + }, + rtcMaxPort : { + doc : 'The Mediasoup end listening port number.', + format : 'port', + default : 49999 + } + }, + // mediasoup Router settings. + router : + { + // Router media codecs. + mediaCodecs : { + doc : 'The Mediasoup codecs settings. [supportedRtpCapabilities](https://github.com/versatica/mediasoup/blob/v3/src/supportedRtpCapabilities.ts)', + format : '*', + default : + [ + { + kind : 'audio', + mimeType : 'audio/opus', + clockRate : 48000, + channels : 2 + }, + { + kind : 'video', + mimeType : 'video/VP8', + clockRate : 90000, + parameters : + { + 'x-google-start-bitrate' : 1000 + } + }, + { + kind : 'video', + mimeType : 'video/VP9', + clockRate : 90000, + parameters : + { + 'profile-id' : 2, + 'x-google-start-bitrate' : 1000 + } + }, + { + kind : 'video', + mimeType : 'video/h264', + clockRate : 90000, + parameters : + { + 'packetization-mode' : 1, + 'profile-level-id' : '4d0032', + 'level-asymmetry-allowed' : 1, + 'x-google-start-bitrate' : 1000 + } + }, + { + kind : 'video', + mimeType : 'video/h264', + clockRate : 90000, + parameters : + { + 'packetization-mode' : 1, + 'profile-level-id' : '42e01f', + 'level-asymmetry-allowed' : 1, + 'x-google-start-bitrate' : 1000 + } + } + ] + } + }, + // mediasoup WebRtcTransport settings. + webRtcTransport : + { + listenIps : { + doc : 'The Mediasoup listen IPs. [TransportListenIp](https://mediasoup.org/documentation/v3/mediasoup/api/#TransportListenIp)', + format : Array, + default : [ + { ip: '0.0.0.0', announcedIp: null } + ] + }, + initialAvailableOutgoingBitrate : { + doc : 'The Mediasoup initial available outgoing bitrate (in bps). [WebRtcTransportOptions](https://mediasoup.org/documentation/v3/mediasoup/api/#WebRtcTransportOptions)', + format : 'nat', + default : 1000000 + }, + maxIncomingBitrate : { + doc : 'The Mediasoup maximum incoming bitrate for each transport. (in bps). [setMaxIncomingBitrate](https://mediasoup.org/documentation/v3/mediasoup/api/#transport-setMaxIncomingBitrate)', + format : 'nat', + default : 1500000 + } + } + }, + // Prometheus exporter + prometheus : { + enabled : { + doc : 'Enables the Prometheus metrics exporter.', + format : 'Boolean', + default : false + }, + listen : { + doc : 'Prometheus metrics exporter listening address.', + format : 'String', + default : 'localhost' + }, + port : { + doc : 'The Prometheus metrics exporter listening port.', + format : 'port', + default : 8889 + }, + // default metrics options + deidentify : { + doc : 'De-identify IP addresses in Prometheus logs.', + format : 'Boolean', + default : false + }, + numeric : { + doc : 'Show numeric IP addresses in Prometheus logs.', + format : 'Boolean', + default : false + }, + quiet : { + doc : 'Include fewer labels in Prometheus metrics.', + format : 'Boolean', + default : false + }, + // aggregated metrics options + period : { + doc : 'The Prometheus metrics exporter update period (seconds).', + format : 'nat', + default : 15 + }, + secret : { + doc : 'The Prometheus metrics exporter authorization header: `Bearer ` required to allow scraping.', + format : String, + default : '' + } + }, + // User roles + // All users have the role "NORMAL" by default. Other roles need to be + // added in the "userMapping" function. The following accesses and + // permissions are arrays of roles. Roles can be changed in userRoles.js + // + // Example: + // [ userRoles.MODERATOR, userRoles.AUTHENTICATED ] + accessFromRoles : { + doc : 'User roles.', + format : '*', + default : { + // The role(s) will gain access to the room + // even if it is locked (!) + [BYPASS_ROOM_LOCK] : [ userRoles.ADMIN ], + // The role(s) will gain access to the room without + // going into the lobby. If you want to restrict access to your + // server to only directly allow authenticated users, you could + // add the userRoles.AUTHENTICATED to the user in the userMapping + // function, and change to BYPASS_LOBBY : [ userRoles.AUTHENTICATED ] + [BYPASS_LOBBY] : [ userRoles.NORMAL ] + } + }, + permissionsFromRoles : { + doc : 'User permissions from roles.', + format : '*', + default : { + // The role(s) have permission to lock/unlock a room + [CHANGE_ROOM_LOCK] : [ userRoles.MODERATOR ], + // The role(s) have permission to promote a peer from the lobby + [PROMOTE_PEER] : [ userRoles.NORMAL ], + // The role(s) have permission to give/remove other peers roles + [MODIFY_ROLE] : [ userRoles.NORMAL ], + // The role(s) have permission to send chat messages + [SEND_CHAT] : [ userRoles.NORMAL ], + // The role(s) have permission to moderate chat + [MODERATE_CHAT] : [ userRoles.MODERATOR ], + // The role(s) have permission to share audio + [SHARE_AUDIO] : [ userRoles.NORMAL ], + // The role(s) have permission to share video + [SHARE_VIDEO] : [ userRoles.NORMAL ], + // The role(s) have permission to share screen + [SHARE_SCREEN] : [ userRoles.NORMAL ], + // The role(s) have permission to produce extra video + [EXTRA_VIDEO] : [ userRoles.NORMAL ], + // The role(s) have permission to share files + [SHARE_FILE] : [ userRoles.NORMAL ], + // The role(s) have permission to moderate files + [MODERATE_FILES] : [ userRoles.MODERATOR ], + // The role(s) have permission to moderate room (e.g. kick user) + [MODERATE_ROOM] : [ userRoles.MODERATOR ] + } + }, + // Array of permissions. If no peer with the permission in question + // is in the room, all peers are permitted to do the action. The peers + // that are allowed because of this rule will not be able to do this + // action as soon as a peer with the permission joins. In this example + // everyone will be able to lock/unlock room until a MODERATOR joins. + allowWhenRoleMissing : { + doc : 'Allow when role missing.', + format : Array, + default : [ CHANGE_ROOM_LOCK ] + } +}); + +/** + * Formats the schema documentation, calling the same function recursively. + * @param docs the documentation object to extend + * @param property the root property + * @param schema the config schema fragment + * @returns the documentation object + */ +function formatDocs(docs: any, property: string | null, schema: any) +{ + if (schema._cvtProperties) + { + Object.entries(schema._cvtProperties).forEach(([ name, value ]) => + { + formatDocs(docs, `${property ? `${property}.` : ''}${name}`, value); + }); + + return docs; + } + + if (property) + { + docs[property] = // eslint-disable-line no-param-reassign + { + doc : schema.doc, + format : JSON.stringify(schema.format, null, 2), + default : JSON.stringify(schema.default, null, 2) + }; + } + + return docs; +} + +// format docs +const configDocs = formatDocs({}, null, configSchema.getSchema()); + +let config: any = {}; +let configError = ''; +let configLoaded = false; + +// Load config from file +for (const format of [ 'json', 'json5', 'yaml', 'yml', 'toml' ]) // eslint-disable-line no-restricted-syntax +{ + const filepath = `./config/config.${format}`; + + if (fs.existsSync(filepath)) + { + try + { + logger.debug(`Loading config from ${filepath}`); + configSchema.loadFile(filepath); + configLoaded = true; + break; + } + catch (err) + { + logger.debug(`Loading config from ${filepath} failed: ${err.message}`); + } + } +} + +if (!configLoaded) +{ + logger.warn('No config file found, using defaults.'); + configSchema.load({}); +} + +// Perform validation +try +{ + configSchema.validate({ allowed: 'strict' }); + config = configSchema.getProperties(); +} +catch (error: any) +{ + configError = error.message; +} + +// load additional config module (no validation is performed) +if (fs.existsSync(`${__dirname}/../config/config.js`)) +{ + try + { + const configModule = require('../config/config.js'); // eslint-disable-line @typescript-eslint/no-var-requires + + Object.assign(config, configModule); + } + catch (err) + { + logger.error(`Error loading ${config.configFile} module: ${err.message}`); + } +} + +// eslint-disable-next-line +// logger.debug('Using config:', config); + +// +export { + configSchema, + config, + configError, + configDocs +}; diff --git a/server/lib/configLoader.ts b/server/lib/configLoader.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/server/lib/metrics/aggregated.js b/server/lib/metrics/aggregated.js index 4124c589..2e9f1112 100644 --- a/server/lib/metrics/aggregated.js +++ b/server/lib/metrics/aggregated.js @@ -9,83 +9,88 @@ const logger = new Logger('metrics:aggregated'); // module.exports = function(workers, rooms_, peers_, config) { - const register = new promClient.Registry(); - promClient.collectDefaultMetrics({ prefix: 'mediasoup_', register }); - - const mediasoupStats = {}; - let mediasoupStatsUpdate = 0; + const register = new promClient.Registry(); - const formatStats = (s) => - { - return { - length: s.length || 0, - sum: s.sum || 0, - mean: s.amean() || 0, - stddev: s.stddev() || 0, - p25: s.percentile(25) || 0, - min: s.min || 0, - max: s.max || 0, - }; - }; + promClient.collectDefaultMetrics({ prefix: 'mediasoup_', register }); - const collectStats = async () => - { - const now = Date.now(); + const mediasoupStats = {}; + let mediasoupStatsUpdate = 0; - if (now - mediasoupStatsUpdate < config.period * 1000) - { - return; - } - mediasoupStatsUpdate = now; + const formatStats = (s) => + { + return { + length : s.length || 0, + sum : s.sum || 0, + mean : s.amean() || 0, + stddev : s.stddev() || 0, + p25 : s.percentile(25) || 0, + min : s.min || 0, + max : s.max || 0 + }; + }; - const start = process.hrtime(); + const collectStats = async () => + { + const now = Date.now(); - let workers_cpu = new Stats(); - let workers_memory = new Stats(); + if (now - mediasoupStatsUpdate < config.period * 1000) + { + return; + } + mediasoupStatsUpdate = now; - let rooms = new Stats(); - rooms.push(rooms_.size); + const start = process.hrtime(); - let peers = new Stats(); - peers.push(peers_.size); + const workersCpu = new Stats(); + const workersMemory = new Stats(); - // in - let video_bitrates_in = new Stats(); - let audio_bitrates_in = new Stats(); - let video_scores_in = new Stats(); - let audio_scores_in = new Stats(); + const rooms = new Stats(); - let packets_counts_in = new Stats(); - let packets_losts_in = new Stats(); - let packets_retransmitted_in = new Stats(); + rooms.push(rooms_.size); - // out - let video_bitrates_out = new Stats(); - let audio_bitrates_out = new Stats(); + const peers = new Stats(); - let round_trip_times_out = new Stats(); - let packets_counts_out = new Stats(); - let packets_losts_out = new Stats(); + peers.push(peers_.size); - let spatial_layers_out = new Stats(); - let temporal_layers_out = new Stats(); + // in + const videoBitratesIn = new Stats(); + const audioBitratesIn = new Stats(); + const videoScoresIn = new Stats(); + const audioScoresIn = new Stats(); - try { - // iterate workers - for (const worker of workers.values()) - { - // worker process stats - const workerStats = await pidusage(worker._pid); - workers_cpu.push(workerStats.cpu / 100); - workers_memory.push(workerStats.memory); - - // iterate routers - for (const router of worker._routers.values()) - { - // iterate transports - for (const transport of router._transports.values()) - { - /* let stats = []; + const packetsCountsIn = new Stats(); + const packetsLostsIn = new Stats(); + const packetsRetransmittedIn = new Stats(); + + // out + const videoBitratesOut = new Stats(); + const audioBitratesOut = new Stats(); + + const roundTripTimesOut = new Stats(); + const packetsCountsOut = new Stats(); + const packetsLostsOut = new Stats(); + + const spatialLayersOut = new Stats(); + const temporalLayersOut = new Stats(); + + try + { + // iterate workers + for (const worker of workers) + { + // worker process stats + const workerStats = await pidusage(worker.pid); + + workersCpu.push(workerStats.cpu / 100); + workersMemory.push(workerStats.memory); + + // iterate routers + for (const router of worker._routers.values()) + { + // iterate transports + for (const transport of router._transports.values()) + { + /* let stats = []; try { stats = await transport.getStats(); @@ -102,212 +107,225 @@ module.exports = function(workers, rooms_, peers_, config) } } */ - // iterate producers - for (const producer of transport._producers.values()) - { - let stats = []; - try - { - stats = await producer.getStats(); - } - catch(err) - { - logger.error('producer.getStats error:', err.message); - continue; - } - for (const s of stats) - { - if (s.type !== 'inbound-rtp') - { - continue; - } - if (s.kind === 'video') - { - video_bitrates_in.push(s.bitrate); - video_scores_in.push(s.score); - } - else if (s.kind === 'audio') - { - audio_bitrates_in.push(s.bitrate); - audio_scores_in.push(s.score); - } - packets_counts_in.push(s.packetCount || 0); - packets_losts_in.push(s.packetsLost || 0); - packets_retransmitted_in.push(s.packetsRetransmitted || 0); - } - } + // iterate producers + for (const producer of transport._producers.values()) + { + let stats = []; - // iterate consumers - for (const consumer of transport._consumers.values()) - { - if (consumer.type === 'pipe') - { - continue; - } - let stats = []; - try - { - stats = await consumer.getStats(); - } - catch(err) - { - logger.error('consumer.getStats error:', err.message); - continue; - } - for (const s of stats) - { - if(s.type !== 'outbound-rtp'){ - continue; - } - if (s.kind === 'video') - { - video_bitrates_out.push(s.bitrate || 0); - spatial_layers_out.push(consumer.currentLayers ? consumer.currentLayers.spatialLayer : 0); - temporal_layers_out.push(consumer.currentLayers ? consumer.currentLayers.temporalLayer : 0); - } - else if(s.kind === 'audio') - { - audio_bitrates_out.push(s.bitrate || 0); - } - round_trip_times_out.push(s.roundTripTime || 0); - packets_counts_out.push(s.packetCount || 0); - packets_losts_out.push(s.packetsLost || 0); - } - } - } - } - } - } - catch(err) - { - logger.error('collectStats error:', err.message); - } - finally - { - Object.assign(mediasoupStats, { - workers_cpu: formatStats(workers_cpu), - workers_memory: formatStats(workers_memory), - rooms: formatStats(rooms), - peers: formatStats(peers), - // in - video_bitrates_in: formatStats(video_bitrates_in), - video_scores_in: formatStats(video_scores_in), - audio_bitrates_in: formatStats(audio_bitrates_in), - audio_scores_in: formatStats(audio_scores_in), - packets_counts_in: formatStats(packets_counts_in), - packets_losts_in: formatStats(packets_losts_in), - packets_retransmitted_in: formatStats(packets_retransmitted_in), - // out - video_bitrates_out: formatStats(video_bitrates_out), - audio_bitrates_out: formatStats(audio_bitrates_out), - round_trip_times_out: formatStats(round_trip_times_out), - packets_counts_out: formatStats(packets_counts_out), - packets_losts_out: formatStats(packets_losts_out), - spatial_layers_out: formatStats(spatial_layers_out), - temporal_layers_out: formatStats(temporal_layers_out), - }); - } + try + { + stats = await producer.getStats(); + } + catch (err) + { + logger.error('producer.getStats error:', err.message); + continue; + } + for (const s of stats) + { + if (s.type !== 'inbound-rtp') + { + continue; + } + if (s.kind === 'video') + { + videoBitratesIn.push(s.bitrate); + videoScoresIn.push(s.score); + } + else if (s.kind === 'audio') + { + audioBitratesIn.push(s.bitrate); + audioScoresIn.push(s.score); + } + packetsCountsIn.push(s.packetCount || 0); + packetsLostsIn.push(s.packetsLost || 0); + packetsRetransmittedIn.push(s.packetsRetransmitted || 0); + } + } - const end = process.hrtime(start); - logger.info(`collectStats (elapsed: ${end[0] * 1e3 + end[1] * 1e-6} ms)`); - } + // iterate consumers + for (const consumer of transport._consumers.values()) + { + if (consumer.type === 'pipe') + { + continue; + } + let stats = []; - // mediasoup metrics - [ - { name: 'workers_count', statName: 'workers_cpu', statValue: 'length' }, - { name: 'workers_cpu', statName: 'workers_cpu', statValue: 'sum' }, - { name: 'workers_memory', statName: 'workers_memory', statValue: 'sum' }, - // - { name: 'rooms', statName: 'rooms', statValue: 'sum' }, - { name: 'peers', statName: 'peers', statValue: 'sum' }, - // audio in - { name: 'audio_in_count', statName: 'audio_bitrates_in', statValue: 'length' }, - // audio in bitrates - { name: 'audio_bitrates_in_sum', statName: 'audio_bitrates_in', statValue: 'sum' }, - { name: 'audio_bitrates_in_mean', statName: 'audio_bitrates_in', statValue: 'mean' }, - { name: 'audio_bitrates_in_min', statName: 'audio_bitrates_in', statValue: 'min' }, - { name: 'audio_bitrates_in_max', statName: 'audio_bitrates_in', statValue: 'max' }, - { name: 'audio_bitrates_in_p25', statName: 'audio_bitrates_in', statValue: 'p25' }, - // audio in scores - { name: 'audio_scores_in_mean', statName: 'audio_scores_in', statValue: 'mean' }, - { name: 'audio_scores_in_min', statName: 'audio_scores_in', statValue: 'min' }, - { name: 'audio_scores_in_max', statName: 'audio_scores_in', statValue: 'max' }, - { name: 'audio_scores_in_p25', statName: 'audio_scores_in', statValue: 'p25' }, - // video in - { name: 'video_in_count', statName: 'video_bitrates_in', statValue: 'length' }, - // video in bitrates - { name: 'video_bitrates_in_sum', statName: 'video_bitrates_in', statValue: 'sum' }, - { name: 'video_bitrates_in_mean', statName: 'video_bitrates_in', statValue: 'mean' }, - { name: 'video_bitrates_in_min', statName: 'video_bitrates_in', statValue: 'min' }, - { name: 'video_bitrates_in_max', statName: 'video_bitrates_in', statValue: 'max' }, - { name: 'video_bitrates_in_p25', statName: 'video_bitrates_in', statValue: 'p25' }, - // video in scores - { name: 'video_scores_in_mean', statName: 'video_scores_in', statValue: 'mean' }, - { name: 'video_scores_in_min', statName: 'video_scores_in', statValue: 'min' }, - { name: 'video_scores_in_max', statName: 'video_scores_in', statValue: 'max' }, - { name: 'video_scores_in_p25', statName: 'video_scores_in', statValue: 'p25' }, - // packets in - { name: 'packets_counts_in_sum', statName: 'packets_counts_in', statValue: 'sum' }, - { name: 'packets_counts_in_mean', statName: 'packets_counts_in', statValue: 'mean' }, - { name: 'packets_counts_in_min', statName: 'packets_counts_in', statValue: 'min' }, - { name: 'packets_counts_in_max', statName: 'packets_counts_in', statValue: 'max' }, - { name: 'packets_counts_in_p25', statName: 'packets_counts_in', statValue: 'p25' }, - { name: 'packets_losts_in_sum', statName: 'packets_losts_in', statValue: 'sum' }, - { name: 'packets_losts_in_mean', statName: 'packets_losts_in', statValue: 'mean' }, - { name: 'packets_losts_in_min', statName: 'packets_losts_in', statValue: 'min' }, - { name: 'packets_losts_in_max', statName: 'packets_losts_in', statValue: 'max' }, - { name: 'packets_losts_in_p25', statName: 'packets_losts_in', statValue: 'p25' }, - { name: 'packets_retransmitted_in_sum', statName: 'packets_retransmitted_in', statValue: 'sum' }, - { name: 'packets_retransmitted_in_mean', statName: 'packets_retransmitted_in', statValue: 'mean' }, - { name: 'packets_retransmitted_in_min', statName: 'packets_retransmitted_in', statValue: 'min' }, - { name: 'packets_retransmitted_in_max', statName: 'packets_retransmitted_in', statValue: 'max' }, - { name: 'packets_retransmitted_in_p25', statName: 'packets_retransmitted_in', statValue: 'p25' }, - // audio out - { name: 'audio_out_count', statName: 'audio_bitrates_out', statValue: 'length' }, - { name: 'audio_bitrates_out_sum', statName: 'audio_bitrates_out', statValue: 'sum' }, - { name: 'audio_bitrates_out_mean', statName: 'audio_bitrates_out', statValue: 'mean' }, - { name: 'audio_bitrates_out_min', statName: 'audio_bitrates_out', statValue: 'min' }, - { name: 'audio_bitrates_out_max', statName: 'audio_bitrates_out', statValue: 'max' }, - { name: 'audio_bitrates_out_p25', statName: 'audio_bitrates_out', statValue: 'p25' }, - // video out - { name: 'video_out_count', statName: 'video_bitrates_out', statValue: 'length' }, - { name: 'video_bitrates_out_sum', statName: 'video_bitrates_out', statValue: 'sum' }, - { name: 'video_bitrates_out_mean', statName: 'video_bitrates_out', statValue: 'mean' }, - { name: 'video_bitrates_out_min', statName: 'video_bitrates_out', statValue: 'min' }, - { name: 'video_bitrates_out_max', statName: 'video_bitrates_out', statValue: 'max' }, - { name: 'video_bitrates_out_p25', statName: 'video_bitrates_out', statValue: 'p25' }, - // sl - { name: 'spatial_layers_out_mean', statName: 'spatial_layers_out', statValue: 'mean' }, - { name: 'spatial_layers_out_min', statName: 'spatial_layers_out', statValue: 'min' }, - { name: 'spatial_layers_out_max', statName: 'spatial_layers_out', statValue: 'max' }, - { name: 'spatial_layers_out_p25', statName: 'spatial_layers_out', statValue: 'p25' }, - // tl - { name: 'temporal_layers_out_mean', statName: 'temporal_layers_out', statValue: 'mean' }, - { name: 'temporal_layers_out_min', statName: 'temporal_layers_out', statValue: 'min' }, - { name: 'temporal_layers_out_max', statName: 'temporal_layers_out', statValue: 'max' }, - { name: 'temporal_layers_out_p25', statName: 'temporal_layers_out', statValue: 'p25' }, - // rtt out - { name: 'round_trip_times_out_mean', statName: 'round_trip_times_out', statValue: 'mean' }, - { name: 'round_trip_times_out_min', statName: 'round_trip_times_out', statValue: 'min' }, - { name: 'round_trip_times_out_max', statName: 'round_trip_times_out', statValue: 'max' }, - { name: 'round_trip_times_out_p25', statName: 'round_trip_times_out', statValue: 'p25' }, + try + { + stats = await consumer.getStats(); + } + catch (err) + { + logger.error('consumer.getStats error:', err.message); + continue; + } + for (const s of stats) + { + if (s.type !== 'outbound-rtp') + { + continue; + } + if (s.kind === 'video') + { + videoBitratesOut.push(s.bitrate || 0); + spatialLayersOut.push(consumer.currentLayers + ? consumer.currentLayers.spatialLayer : 0); + temporalLayersOut.push(consumer.currentLayers + ? consumer.currentLayers.temporalLayer : 0); + } + else if (s.kind === 'audio') + { + audioBitratesOut.push(s.bitrate || 0); + } + roundTripTimesOut.push(s.roundTripTime || 0); + packetsCountsOut.push(s.packetCount || 0); + packetsLostsOut.push(s.packetsLost || 0); + } + } + } + } + } + } + catch (err) + { + logger.error('collectStats error:', err.message); + } + finally + { + Object.assign(mediasoupStats, { + workersCpu : formatStats(workersCpu), + workersMemory : formatStats(workersMemory), + rooms : formatStats(rooms), + peers : formatStats(peers), + // in + videoBitratesIn : formatStats(videoBitratesIn), + videoScoresIn : formatStats(videoScoresIn), + audioBitratesIn : formatStats(audioBitratesIn), + audioScoresIn : formatStats(audioScoresIn), + packetsCountsIn : formatStats(packetsCountsIn), + packetsLostsIn : formatStats(packetsLostsIn), + packetsRetransmittedIn : formatStats(packetsRetransmittedIn), + // out + videoBitratesOut : formatStats(videoBitratesOut), + audioBitratesOut : formatStats(audioBitratesOut), + roundTripTimesOut : formatStats(roundTripTimesOut), + packetsCountsOut : formatStats(packetsCountsOut), + packetsLostsOut : formatStats(packetsLostsOut), + spatialLayersOut : formatStats(spatialLayersOut), + temporalLayersOut : formatStats(temporalLayersOut) + }); + } - ].forEach(({ name, statName, statValue }) => { - new promClient.Gauge({ - name: `mediasoup_${name}`, - help: `MediaSoup ${name}`, - labelNames: [], - registers: [ register ], - async collect() - { - await collectStats(); - if (mediasoupStats[statName] !== undefined && mediasoupStats[statName][statValue] !== undefined) - { - this.set({}, mediasoupStats[statName][statValue]); - } - } - }); - }); + const end = process.hrtime(start); - return register; + logger.info(`collectStats (elapsed: ${(end[0] * 1e3) + (end[1] * 1e-6)} ms)`); + }; + + // mediasoup metrics + [ + { name: 'workers_count', statName: 'workersCpu', statValue: 'length' }, + { name: 'workers_cpu', statName: 'workersCpu', statValue: 'sum' }, + { name: 'workers_memory', statName: 'workersMemory', statValue: 'sum' }, + // + { name: 'rooms', statName: 'rooms', statValue: 'sum' }, + { name: 'peers', statName: 'peers', statValue: 'sum' }, + // audio in + { name: 'audio_in_count', statName: 'audioBitratesIn', statValue: 'length' }, + // audio in bitrates + { name: 'audio_bitrates_in_sum', statName: 'audioBitratesIn', statValue: 'sum' }, + { name: 'audio_bitrates_in_mean', statName: 'audioBitratesIn', statValue: 'mean' }, + { name: 'audio_bitrates_in_min', statName: 'audioBitratesIn', statValue: 'min' }, + { name: 'audio_bitrates_in_max', statName: 'audioBitratesIn', statValue: 'max' }, + { name: 'audio_bitrates_in_p25', statName: 'audioBitratesIn', statValue: 'p25' }, + // audio in scores + { name: 'audio_scores_in_mean', statName: 'audioScoresIn', statValue: 'mean' }, + { name: 'audio_scores_in_min', statName: 'audioScoresIn', statValue: 'min' }, + { name: 'audio_scores_in_max', statName: 'audioScoresIn', statValue: 'max' }, + { name: 'audio_scores_in_p25', statName: 'audioScoresIn', statValue: 'p25' }, + // video in + { name: 'video_in_count', statName: 'videoBitratesIn', statValue: 'length' }, + // video in bitrates + { name: 'video_bitrates_in_sum', statName: 'videoBitratesIn', statValue: 'sum' }, + { name: 'video_bitrates_in_mean', statName: 'videoBitratesIn', statValue: 'mean' }, + { name: 'video_bitrates_in_min', statName: 'videoBitratesIn', statValue: 'min' }, + { name: 'video_bitrates_in_max', statName: 'videoBitratesIn', statValue: 'max' }, + { name: 'video_bitrates_in_p25', statName: 'videoBitratesIn', statValue: 'p25' }, + // video in scores + { name: 'video_scores_in_mean', statName: 'videoScoresIn', statValue: 'mean' }, + { name: 'video_scores_in_min', statName: 'videoScoresIn', statValue: 'min' }, + { name: 'video_scores_in_max', statName: 'videoScoresIn', statValue: 'max' }, + { name: 'video_scores_in_p25', statName: 'videoScoresIn', statValue: 'p25' }, + // packets in + { name: 'packets_counts_in_sum', statName: 'packetsCountsIn', statValue: 'sum' }, + { name: 'packets_counts_in_mean', statName: 'packetsCountsIn', statValue: 'mean' }, + { name: 'packets_counts_in_min', statName: 'packetsCountsIn', statValue: 'min' }, + { name: 'packets_counts_in_max', statName: 'packetsCountsIn', statValue: 'max' }, + { name: 'packets_counts_in_p25', statName: 'packetsCountsIn', statValue: 'p25' }, + { name: 'packets_losts_in_sum', statName: 'packetsLostsIn', statValue: 'sum' }, + { name: 'packets_losts_in_mean', statName: 'packetsLostsIn', statValue: 'mean' }, + { name: 'packets_losts_in_min', statName: 'packetsLostsIn', statValue: 'min' }, + { name: 'packets_losts_in_max', statName: 'packetsLostsIn', statValue: 'max' }, + { name: 'packets_losts_in_p25', statName: 'packetsLostsIn', statValue: 'p25' }, + { name: 'packets_retransmitted_in_sum', statName: 'packetsRetransmittedIn', statValue: 'sum' }, + { name: 'packets_retransmitted_in_mean', statName: 'packetsRetransmittedIn', statValue: 'mean' }, + { name: 'packets_retransmitted_in_min', statName: 'packetsRetransmittedIn', statValue: 'min' }, + { name: 'packets_retransmitted_in_max', statName: 'packetsRetransmittedIn', statValue: 'max' }, + { name: 'packets_retransmitted_in_p25', statName: 'packetsRetransmittedIn', statValue: 'p25' }, + // audio out + { name: 'audio_out_count', statName: 'audioBitratesOut', statValue: 'length' }, + { name: 'audio_bitrates_out_sum', statName: 'audioBitratesOut', statValue: 'sum' }, + { name: 'audio_bitrates_out_mean', statName: 'audioBitratesOut', statValue: 'mean' }, + { name: 'audio_bitrates_out_min', statName: 'audioBitratesOut', statValue: 'min' }, + { name: 'audio_bitrates_out_max', statName: 'audioBitratesOut', statValue: 'max' }, + { name: 'audio_bitrates_out_p25', statName: 'audioBitratesOut', statValue: 'p25' }, + // video out + { name: 'video_out_count', statName: 'videoBitratesOut', statValue: 'length' }, + { name: 'video_bitrates_out_sum', statName: 'videoBitratesOut', statValue: 'sum' }, + { name: 'video_bitrates_out_mean', statName: 'videoBitratesOut', statValue: 'mean' }, + { name: 'video_bitrates_out_min', statName: 'videoBitratesOut', statValue: 'min' }, + { name: 'video_bitrates_out_max', statName: 'videoBitratesOut', statValue: 'max' }, + { name: 'video_bitrates_out_p25', statName: 'videoBitratesOut', statValue: 'p25' }, + // sl + { name: 'spatial_layers_out_mean', statName: 'spatialLayersOut', statValue: 'mean' }, + { name: 'spatial_layers_out_min', statName: 'spatialLayersOut', statValue: 'min' }, + { name: 'spatial_layers_out_max', statName: 'spatialLayersOut', statValue: 'max' }, + { name: 'spatial_layers_out_p25', statName: 'spatialLayersOut', statValue: 'p25' }, + // tl + { name: 'temporal_layers_out_mean', statName: 'temporalLayersOut', statValue: 'mean' }, + { name: 'temporal_layers_out_min', statName: 'temporalLayersOut', statValue: 'min' }, + { name: 'temporal_layers_out_max', statName: 'temporalLayersOut', statValue: 'max' }, + { name: 'temporal_layers_out_p25', statName: 'temporalLayersOut', statValue: 'p25' }, + // rtt out + { name: 'round_trip_times_out_mean', statName: 'roundTripTimesOut', statValue: 'mean' }, + { name: 'round_trip_times_out_min', statName: 'roundTripTimesOut', statValue: 'min' }, + { name: 'round_trip_times_out_max', statName: 'roundTripTimesOut', statValue: 'max' }, + { name: 'round_trip_times_out_p25', statName: 'roundTripTimesOut', statValue: 'p25' } + + ].forEach(({ name, statName, statValue }) => + { + // eslint-disable-next-line no-new + new promClient.Gauge({ + name : `mediasoup_${name}`, + help : `MediaSoup ${name}`, + labelNames : [], + registers : [ register ], + async collect() + { + await collectStats(); + if (mediasoupStats[statName] !== undefined + && mediasoupStats[statName][statValue] !== undefined) + { + this.set({}, mediasoupStats[statName][statValue]); + } + else + { + logger.warn(`${statName}.${statValue} not found`); + } + } + }); + }); + + return register; }; diff --git a/server/lib/metrics/default.js b/server/lib/metrics/default.js index 4e9feeed..2062a61c 100644 --- a/server/lib/metrics/default.js +++ b/server/lib/metrics/default.js @@ -19,218 +19,218 @@ const metadata = { module.exports = async function(workers, rooms, peers, registry, config) { - const newMetrics = function(subsystem) - { - const namespace = 'mediasoup'; - const metrics = new Map(); + const newMetrics = function(subsystem) + { + const namespace = 'mediasoup'; + const metrics = new Map(); - for (const key in metadata) - { - if (Object.prototype.hasOwnProperty.call(metadata, key)) - { - const value = metadata[key]; - const name = key.split(/(?=[A-Z])/).join('_') - .toLowerCase(); - const unit = value.unit; - const metricType = value.metricType; - let s = `${namespace}_${subsystem}_${name}`; + for (const key in metadata) + { + if (Object.prototype.hasOwnProperty.call(metadata, key)) + { + const value = metadata[key]; + const name = key.split(/(?=[A-Z])/).join('_') + .toLowerCase(); + const unit = value.unit; + const metricType = value.metricType; + let s = `${namespace}_${subsystem}_${name}`; - if (unit) - { - s += `_${unit}`; - } - const m = new metricType({ - name : s, help : `${subsystem}.${key}`, labelNames : labelNames, registers : [ registry ] }); + if (unit) + { + s += `_${unit}`; + } + const m = new metricType({ + name : s, help : `${subsystem}.${key}`, labelNames : labelNames, registers : [ registry ] }); - metrics.set(key, m); - } - } + metrics.set(key, m); + } + } - return metrics; - }; + return metrics; + }; - const commonLabels = function(both, fn) - { - for (const roomId of rooms.keys()) - { - for (const [ peerId, peer ] of peers) - { - if (fn(peer)) - { - const displayName = peer._displayName; - const userAgent = peer._socket.client.request.headers['user-agent']; - const kind = both.kind; - const codec = both.rtpParameters.codecs[0].mimeType.split('/')[1]; + const commonLabels = function(both, fn) + { + for (const roomId of rooms.keys()) + { + for (const [ peerId, peer ] of peers) + { + if (fn(peer)) + { + const displayName = peer._displayName; + const userAgent = peer._socket.client.request.headers['user-agent']; + const kind = both.kind; + const codec = both.rtpParameters.codecs[0].mimeType.split('/')[1]; - return { roomId, peerId, displayName, userAgent, kind, codec }; - } - } - } - throw new Error('cannot find common labels'); - }; + return { roomId, peerId, displayName, userAgent, kind, codec }; + } + } + } + throw new Error('cannot find common labels'); + }; - const addr = async function(ip, port) - { - if (config.deidentify) - { - const a = ip.split('.'); + const addr = async function(ip, port) + { + if (config.deidentify) + { + const a = ip.split('.'); - for (let i = 0; i < a.length - 2; i++) - { - a[i] = 'xx'; - } + for (let i = 0; i < a.length - 2; i++) + { + a[i] = 'xx'; + } - return `${a.join('.')}:${port}`; - } - else if (config.numeric) - { - return `${ip}:${port}`; - } - else - { - try - { - const a = await resolver.reverse(ip); + return `${a.join('.')}:${port}`; + } + else if (config.numeric) + { + return `${ip}:${port}`; + } + else + { + try + { + const a = await resolver.reverse(ip); - ip = a[0]; - } - catch (err) - { - logger.error(`reverse DNS query failed: ${ip} ${err.code}`); - } + ip = a[0]; + } + catch (err) + { + logger.error(`reverse DNS query failed: ${ip} ${err.code}`); + } - return `${ip}:${port}`; - } - }; + return `${ip}:${port}`; + } + }; - const quiet = function(s) - { - return config.quiet ? '' : s; - }; + const quiet = function(s) + { + return config.quiet ? '' : s; + }; - const setValue = function(key, m, labels, v) - { - logger.debug(`setValue key=${key} v=${v}`); - switch (metadata[key].metricType) - { - case prom.Counter: - m.inc(labels, v); - break; - case prom.Gauge: - m.set(labels, v); - break; - default: - throw new Error(`unexpected metric: ${m}`); - } - }; + const setValue = function(key, m, labels, v) + { + logger.debug(`setValue key=${key} v=${v}`); + switch (metadata[key].metricType) + { + case prom.Counter: + m.inc(labels, v); + break; + case prom.Gauge: + m.set(labels, v); + break; + default: + throw new Error(`unexpected metric: ${m}`); + } + }; - logger.debug('collect'); - const mRooms = new prom.Gauge({ name: 'edumeet_rooms', help: '#rooms', registers: [ registry ] }); + logger.debug('collect'); + const mRooms = new prom.Gauge({ name: 'edumeet_rooms', help: '#rooms', registers: [ registry ] }); - mRooms.set(rooms.size); - const mPeers = new prom.Gauge({ name: 'edumeet_peers', help: '#peers', labelNames: [ 'room_id' ], registers: [ registry ] }); + mRooms.set(rooms.size); + const mPeers = new prom.Gauge({ name: 'edumeet_peers', help: '#peers', labelNames: [ 'room_id' ], registers: [ registry ] }); - for (const [ roomId, room ] of rooms) - { - mPeers.labels(roomId).set(Object.keys(room._peers).length); - } + for (const [ roomId, room ] of rooms) + { + mPeers.labels(roomId).set(Object.keys(room._peers).length); + } - const mConsumer = newMetrics('consumer'); - const mProducer = newMetrics('producer'); + const mConsumer = newMetrics('consumer'); + const mProducer = newMetrics('producer'); - for (const [ pid, worker ] of workers) - { - logger.debug(`visiting worker ${pid}`); - for (const router of worker._routers) - { - logger.debug(`visiting router ${router.id}`); - for (const [ transportId, transport ] of router._transports) - { - logger.debug(`visiting transport ${transportId}`); - const transportJson = await transport.dump(); + for (const worker of workers) + { + logger.debug(`visiting worker ${worker.pid}`); + for (const router of worker._routers) + { + logger.debug(`visiting router ${router.id}`); + for (const [ transportId, transport ] of router._transports) + { + logger.debug(`visiting transport ${transportId}`); + const transportJson = await transport.dump(); - if (transportJson.iceState != 'completed') - { - logger.debug(`skipping transport ${transportId}}: ${transportJson.iceState}`); - continue; - } - const iceSelectedTuple = transportJson.iceSelectedTuple; - const proto = iceSelectedTuple.protocol; - const localAddr = await addr(iceSelectedTuple.localIp, - iceSelectedTuple.localPort); - const remoteAddr = await addr(iceSelectedTuple.remoteIp, - iceSelectedTuple.remotePort); + if (transportJson.iceState != 'completed') + { + logger.debug(`skipping transport ${transportId}}: ${transportJson.iceState}`); + continue; + } + const iceSelectedTuple = transportJson.iceSelectedTuple; + const proto = iceSelectedTuple.protocol; + const localAddr = await addr(iceSelectedTuple.localIp, + iceSelectedTuple.localPort); + const remoteAddr = await addr(iceSelectedTuple.remoteIp, + iceSelectedTuple.remotePort); - for (const [ producerId, producer ] of transport._producers) - { - logger.debug(`visiting producer ${producerId}`); - const { roomId, peerId, displayName, userAgent, kind, codec } = + for (const [ producerId, producer ] of transport._producers) + { + logger.debug(`visiting producer ${producerId}`); + const { roomId, peerId, displayName, userAgent, kind, codec } = commonLabels(producer, (peer) => peer._producers.has(producerId)); - const a = await producer.getStats(); + const a = await producer.getStats(); - for (const x of a) - { - const type = x.type; - const labels = { - 'pid' : pid, - 'room_id' : roomId, - 'peer_id' : peerId, - 'display_name' : displayName, - 'user_agent' : userAgent, - 'transport_id' : quiet(transportId), - 'proto' : proto, - 'local_addr' : localAddr, - 'remote_addr' : remoteAddr, - 'id' : quiet(producerId), - 'kind' : kind, - 'codec' : codec, - 'type' : type - }; + for (const x of a) + { + const type = x.type; + const labels = { + 'pid' : worker.pid, + 'room_id' : roomId, + 'peer_id' : peerId, + 'display_name' : displayName, + 'user_agent' : userAgent, + 'transport_id' : quiet(transportId), + 'proto' : proto, + 'local_addr' : localAddr, + 'remote_addr' : remoteAddr, + 'id' : quiet(producerId), + 'kind' : kind, + 'codec' : codec, + 'type' : type + }; - for (const [ key, m ] of mProducer) - { - setValue(key, m, labels, x[key]); - } - } - } - for (const [ consumerId, consumer ] of transport._consumers) - { - logger.debug(`visiting consumer ${consumerId}`); - const { roomId, peerId, displayName, userAgent, kind, codec } = + for (const [ key, m ] of mProducer) + { + setValue(key, m, labels, x[key]); + } + } + } + for (const [ consumerId, consumer ] of transport._consumers) + { + logger.debug(`visiting consumer ${consumerId}`); + const { roomId, peerId, displayName, userAgent, kind, codec } = commonLabels(consumer, (peer) => peer._consumers.has(consumerId)); - const a = await consumer.getStats(); + const a = await consumer.getStats(); - for (const x of a) - { - if (x.type == 'inbound-rtp') - { - continue; - } - const type = x.type; - const labels = - { - 'pid' : pid, - 'room_id' : roomId, - 'peer_id' : peerId, - 'display_name' : displayName, - 'user_agent' : userAgent, - 'transport_id' : quiet(transportId), - 'proto' : proto, - 'local_addr' : localAddr, - 'remote_addr' : remoteAddr, - 'id' : quiet(consumerId), - 'kind' : kind, - 'codec' : codec, - 'type' : type - }; + for (const x of a) + { + if (x.type == 'inbound-rtp') + { + continue; + } + const type = x.type; + const labels = + { + 'pid' : worker.pid, + 'room_id' : roomId, + 'peer_id' : peerId, + 'display_name' : displayName, + 'user_agent' : userAgent, + 'transport_id' : quiet(transportId), + 'proto' : proto, + 'local_addr' : localAddr, + 'remote_addr' : remoteAddr, + 'id' : quiet(consumerId), + 'kind' : kind, + 'codec' : codec, + 'type' : type + }; - for (const [ key, m ] of mConsumer) - { - setValue(key, m, labels, x[key]); - } - } - } - } - } - } + for (const [ key, m ] of mConsumer) + { + setValue(key, m, labels, x[key]); + } + } + } + } + } + } }; \ No newline at end of file diff --git a/server/lib/promExporter.js b/server/lib/promExporter.js index fb8ba2ef..6f4ed096 100644 --- a/server/lib/promExporter.js +++ b/server/lib/promExporter.js @@ -1,35 +1,24 @@ import Logger from './Logger'; const express = require('express'); -const mediasoup = require('mediasoup'); const promClient = require('prom-client'); const collectDefaultMetrics = require('./metrics/default'); const RegisterAggregated = require('./metrics/aggregated'); const logger = new Logger('promClient'); -const workers = new Map(); -module.exports = async function(rooms, peers, config) +import { config } from './config'; + +module.exports = async function(workers, rooms, peers) { try { - logger.debug(`config.deidentify=${config.deidentify}`); - logger.debug(`config.listen=${config.listen}`); - logger.debug(`config.numeric=${config.numeric}`); - logger.debug(`config.port=${config.port}`); - logger.debug(`config.quiet=${config.quiet}`); - - mediasoup.observer.on('newworker', (worker) => - { - logger.debug(`observing newworker ${worker.pid} #${workers.size}`); - workers.set(worker.pid, worker); - worker.observer.on('close', () => - { - logger.debug(`observing close worker ${worker.pid} #${workers.size - 1}`); - workers.delete(worker.pid); - }); - }); + logger.debug(`config.prometheus.deidentify=${config.prometheus.deidentify}`); + logger.debug(`config.prometheus.listen=${config.prometheus.listen}`); + logger.debug(`config.prometheus.numeric=${config.prometheus.numeric}`); + logger.debug(`config.prometheus.port=${config.prometheus.port}`); + logger.debug(`config.prometheus.quiet=${config.prometheus.quiet}`); const app = express(); @@ -39,7 +28,8 @@ module.exports = async function(rooms, peers, config) logger.debug(`GET ${req.originalUrl}`); const registry = new promClient.Registry(); - await collectDefaultMetrics(workers, rooms, peers, registry, config); + await collectDefaultMetrics( + workers, rooms, peers, registry, config.prometheus); res.set('Content-Type', registry.contentType); const data = await registry.metrics(); @@ -47,31 +37,33 @@ module.exports = async function(rooms, peers, config) }); // aggregated register - const registerAggregated = RegisterAggregated(workers, rooms, peers, config); + const registerAggregated = RegisterAggregated( + workers, rooms, peers, config.prometheus); app.get('/metrics', async (req, res) => { logger.debug(`GET ${req.originalUrl}`); - if (config.secret && req.headers.authorization !== 'Bearer ' + config.secret) + if (config.prometheus.secret + && req.headers.authorization !== `Bearer ${ config.prometheus.secret}`) { - logger.error(`Invalid authorization header`); + logger.error('Invalid authorization header'); + return res.status(401).end(); } - + res.set('Content-Type', registerAggregated.contentType); const data = await registerAggregated.metrics(); res.end(data); }); - const server = app.listen(config.port || 8889, - config.listen || undefined, () => - { - const address = server.address(); + const server = app.listen(config.prometheus.port, config.prometheus.listen, () => + { + const address = server.address(); - logger.info(`listening ${address.address}:${address.port}`); - }); + logger.info(`listening ${address.address}:${address.port}`); + }); } catch (err) { diff --git a/server/package.json b/server/package.json index ef7ad3ed..13ee8f07 100644 --- a/server/package.json +++ b/server/package.json @@ -14,12 +14,13 @@ "license": "MIT", "main": "lib/index.js", "scripts": { - "start": "yarn build && node dist/server.js", - "build": "rm -rf dist && tsc && ln -s ../certs dist/certs && ln -s ../public dist/public", + "start": "node dist/server.js", + "build": "rm -rf dist && tsc && ln -s ../certs dist/certs && ln -s ../public dist/public && chmod 755 dist/server.js", "dev": "nodemon --exec ts-node --ignore dist/ -e js,ts server.js", "connect": "ts-node connect.js", "lint": "eslint -c .eslintrc.json --ext .js,.ts *.js *.ts lib/", - "format": "prettier --write '**/*.ts' && npm run lint --fix" + "format": "prettier --write '**/*.ts' && npm run lint --fix", + "gen-config-docs": "ts-node gen-config-docs.ts" }, "dependencies": { "awaitqueue": "^1.0.0", @@ -30,6 +31,8 @@ "colors": "^1.4.0", "compression": "^1.7.4", "connect-redis": "^4.0.3", + "convict": "^6.1.0", + "convict-format-with-validator": "^6.0.1", "cookie-parser": "^1.4.4", "debug": "^4.3.1", "express": "^4.17.1", @@ -38,6 +41,7 @@ "fast-stats": "^0.0.6", "helmet": "^3.21.2", "ims-lti": "^3.0.2", + "json5": "^2.2.0", "jsonwebtoken": "^8.5.1", "mediasoup": "vpalmisano/mediasoup#3.7.1-build-with-system-openssl", "openid-client": "^3.7.3", @@ -50,7 +54,9 @@ "redis": "^2.8.0", "socket.io": "^2.4.0", "spdy": "^4.0.1", - "uuid": "^7.0.2" + "toml": "^3.0.0", + "uuid": "^7.0.2", + "yaml": "^1.10.2" }, "devDependencies": { "@types/base-64": "^0.1.3", diff --git a/server/server.js b/server/server.js index b8306e77..e5c975f6 100755 --- a/server/server.js +++ b/server/server.js @@ -3,9 +3,18 @@ process.title = 'edumeet-server'; import Logger from './lib/Logger'; +const Room = require('./lib/Room'); +const Peer = require('./lib/Peer'); +const userRoles = require('./userRoles'); +const { + loginHelper, + logoutHelper +} = require('./httpHelper'); +const { config, configError } = require('./lib/config'); +const interactiveServer = require('./lib/interactiveServer'); +const promExporter = require('./lib/promExporter'); const bcrypt = require('bcrypt'); -const config = require('./config/config'); const fs = require('fs'); const http = require('http'); const spdy = require('spdy'); @@ -15,15 +24,8 @@ const cookieParser = require('cookie-parser'); const compression = require('compression'); const mediasoup = require('mediasoup'); const AwaitQueue = require('awaitqueue'); -const Room = require('./lib/Room'); -const Peer = require('./lib/Peer'); const base64 = require('base-64'); const helmet = require('helmet'); -const userRoles = require('./userRoles'); -const { - loginHelper, - logoutHelper -} = require('./httpHelper'); // auth const passport = require('passport'); const LTIStrategy = require('passport-lti'); @@ -31,15 +33,21 @@ const imsLti = require('ims-lti'); const SAMLStrategy = require('passport-saml').Strategy; const LocalStrategy = require('passport-local').Strategy; const redis = require('redis'); -const redisClient = redis.createClient(config.redisOptions); const { Issuer, Strategy } = require('openid-client'); const expressSession = require('express-session'); const RedisStore = require('connect-redis')(expressSession); const sharedSession = require('express-socket.io-session'); -const interactiveServer = require('./lib/interactiveServer'); -const promExporter = require('./lib/promExporter'); const { v4: uuidv4 } = require('uuid'); +if (configError) +{ + /* eslint-disable no-console */ + console.error(`Invalid config file: ${configError}`); + process.exit(-1); +} + +const redisClient = redis.createClient(config.redisOptions); + /* eslint-disable no-console */ console.log('- process.env.DEBUG:', process.env.DEBUG); console.log('- config.mediasoup.worker.logLevel:', config.mediasoup.worker.logLevel); @@ -138,12 +146,6 @@ async function run() // Open the interactive server. await interactiveServer(rooms, peers); - // start Prometheus exporter - if (config.prometheus) - { - await promExporter(rooms, peers, config.prometheus); - } - if (typeof (config.auth) === 'undefined') { logger.warn('Auth is not configured properly!'); @@ -159,6 +161,12 @@ async function run() // Run HTTPS server. await runHttpsServer(); + // start Prometheus exporter + if (config.prometheus.enabled) + { + await promExporter(mediasoupWorkers, rooms, peers); + } + // Run WebSocketServer. await runWebSocketServer(); @@ -630,11 +638,11 @@ async function runHttpsServer() // Serve all files in the public folder as static files. app.use(express.static('public', { - maxAge : (config.staticFilesCachePeriod || 0) * 1000 + maxAge : config.staticFilesCachePeriod })); app.use((req, res) => res.sendFile(`${__dirname}/public/index.html`, { - maxAge : (config.staticFilesCachePeriod || 0) * 1000 + maxAge : config.staticFilesCachePeriod })); if (config.httpOnly === true) @@ -647,13 +655,16 @@ async function runHttpsServer() // https mainListener = spdy.createServer(tls, app); - // http - const redirectListener = http.createServer(app); + // http -> https redirect server + if (config.listeningRedirectPort) + { + const redirectListener = http.createServer(app); - if (config.listeningHost) - redirectListener.listen(config.listeningRedirectPort, config.listeningHost); - else - redirectListener.listen(config.listeningRedirectPort); + if (config.listeningHost) + redirectListener.listen(config.listeningRedirectPort, config.listeningHost); + else + redirectListener.listen(config.listeningRedirectPort); + } } // https or http diff --git a/server/yarn.lock b/server/yarn.lock index 31fce029..af0571ce 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -801,6 +801,11 @@ camelcase@^2.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= +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== + camelize@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" @@ -1011,6 +1016,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== +convict-format-with-validator@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/convict-format-with-validator/-/convict-format-with-validator-6.0.1.tgz#a0ff08b663c40beac480d1a0d39b40382b9e39a3" + integrity sha512-6/O0W9/0MESdL+0fY7glQlWHs+wnP9xXlB1tjY/Wb9ujCCEBqMP8VCjtLvRlBdfwgONrpb+DTPSHQRhUO5aTlQ== + dependencies: + validator "^11.1.0" + +convict@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/convict/-/convict-6.1.0.tgz#5b393bd675a0e743390abd0c5bf9e2b9a2edf4b5" + integrity sha512-8dzppr6Z9URlm6P8N9NiydFRq2NWtQyf4RZOK5m0Q48fWWuKamHLXD7Qz/SiLvRXnjQcKCuHayIk9Fk51sax0w== + dependencies: + lodash.clonedeep "^4.5.0" + yargs-parser "^18.1.3" + cookie-parser@^1.4.4: version "1.4.5" resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.5.tgz#3e572d4b7c0c80f9c61daf604e4336831b5d1d49" @@ -1138,7 +1158,7 @@ debug@~4.1.0: dependencies: ms "^2.1.1" -decamelize@^1.1.2: +decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -2528,6 +2548,13 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +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" + jsonwebtoken@^8.5.1: version "8.5.1" resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" @@ -4261,6 +4288,11 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toml@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" + integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== + tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" @@ -4441,6 +4473,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validator@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-11.1.0.tgz#ac18cac42e0aa5902b603d7a5d9b7827e2346ac4" + integrity sha512-qiQ5ktdO7CD6C/5/mYV4jku/7qnqzjrxb3C/Q5wR3vGGinHTgJZN/TdFT3ZX4vXhX2R1PXx42fB1cn5W+uJ4lg== + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -4608,6 +4645,19 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^18.1.3: + 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" + yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"