diff --git a/.env b/.env new file mode 100644 index 0000000000000000000000000000000000000000..3ccb8fff3ef022e5adf5166117b885f96292f080 --- /dev/null +++ b/.env @@ -0,0 +1 @@ +EXTEND_ESLINT=true \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index 75cd94e1e7746aea5d1569fb2f08167d78adac81..a07f51e6770e756c50518e784fefe34c8eacd9b7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,15 +1,39 @@ module.exports = { - extends: 'erb/typescript', + extends: [ + 'airbnb', + 'plugin:react/recommended', + 'plugin:import/recommended', + 'prettier', + 'plugin:prettier/recommended', + 'plugin:jest/recommended', + 'plugin:promise/recommended', + 'plugin:compat/recommended', + 'airbnb-typescript', + 'plugin:import/typescript', + 'plugin:@typescript-eslint/recommended', + 'prettier/@typescript-eslint', + ], rules: { // A temporary hack related to IDE not resolving correct package.json 'import/no-extraneous-dependencies': 'off', 'no-console': 'off', + 'react/jsx-indent': 'off', 'prettier/prettier': [ 'error', { endOfLine: 'auto', }, ], + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-var-requires': 'off', + 'no-param-reassign': ['error', { props: false }], + 'comma-dangle': 'off', + 'operator-linebreak': 'off', + 'object-curly-newline': 'off', + 'max-len': 'off', + 'implicit-arrow-linebreak': 'off', + 'function-paren-newline': 'off', }, parserOptions: { ecmaVersion: 2020, diff --git a/.gitignore b/.gitignore index 38e1fb2ce1376370d9f83352eeb75edea7d9d176..2b7e9672a0f0c23298dbe55aa0e4058cd1b91d65 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,11 @@ loginDetails.json +package-lock.json + +out/ *.LICENSE +*.LICENSE.txt +app/main.prod.js.LICENSE.txt # Logs logs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 22ac592e5fa9941276d03d106c06936419715fbc..5abd08a393707b9e12d85ef37bd5ecb4b38d7313 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,23 +1,22 @@ image: node:lts-alpine -stages: - - pre - - test - cache: - key: ${CI_COMMIT_REF_SLUG} + key: + files: + - yarn.lock paths: - node_modules/ -before_script: - - yarn install - - yarn build-main - - yarn build-renderer +stages: + - test + - deploy lint: stage: test script: + - yarn install - yarn run lint + #lint:types: # stage: test # script: @@ -26,12 +25,25 @@ lint: tests:unit: stage: test script: + - yarn install + - yarn build - yarn run test -#expo-deployments: -# stage: deploy -# only: -# - master -# script: -# - echo fs.inotify.max_user_watches=524288 | tee -a /etc/sysctl.conf && sysctl -p -# - npx expo login -u $EXPO_USERNAME -p $EXPO_PASSWORD -# - npx expo publish --non-interactive + +publish: + stage: deploy + only: + - master + image: simpliston/mysql-query-profiler:latest + script: + - node -v + # Getting version number from app/package.json + - ticked_version=$(jq .version app/package.json) + - version=${ticked_version//[\"]/} + # Packaging the app + - yarn install --check-files + - yarn run package-all + # Uploading to snap store + - snapcraft login --with ${snapcraft_login} + - snapcraft upload --release=stable release/mysql-query-profiler_${version}_amd64.snap + # Creating new version on Bintray + - bash publish-bintray.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..5d8a4bb18055847b2a8bb6588bb3807f63a41643 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,43 @@ +FROM snapcore/snapcraft:stable + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get dist-upgrade -y + +RUN apt-get install -y snapcraft && apt-get clean + +RUN apt-get install -y curl + +RUN curl -sL https://deb.nodesource.com/setup_lts.x | sudo -E bash - + +RUN apt-get install -y nodejs + +RUN node -v + +RUN npm install -g yarn + +RUN nodejs -v + +RUN apt-get install -y rpm + +RUN apt-get purge wine + +RUN apt-get update && apt-get autoremove && apt-get clean && apt-get autoclean + +RUN dpkg --add-architecture i386 + +RUN apt-get install -y software-properties-common + +RUN add-apt-repository ppa:ubuntu-wine/ppa && apt-get update + +RUN apt-get install -y wine1.8 + +RUN apt-get install jq -y + +# TO BUILD: +# docker build -t simpliston/mysql-query-profiler . + +# TO PUSH: +# docker login +# docker push simpliston/mysql-query-profiler:latest + diff --git a/README.md b/README.md index 7932189748901def0ae9ff69aa5e44a27657e424..3d7c5de4ac567b7378ef421d7fd7e2b2fe88c12e 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,40 @@ # MySQL Query Profiler -## Requirements +[](https://bintray.com/kpro4/mysql-query-profiler/mysql-query-profiler/_latestVersion) + +## Installation and use + +### Install + +#### **Linux** + +Either use the AppImage, deb, or rpm file in [Bintray](https://bintray.com/kpro4/mysql-query-profiler/mysql-query-profiler) or install the snap: + +```bash +snap install mysql-query-profiler +``` + +#### **Windows** + +Install the exe-file from [Bintray](https://bintray.com/kpro4/mysql-query-profiler/mysql-query-profiler). + +#### **MacOS** + +Use the zip-file from [Bintray](https://bintray.com/kpro4/mysql-query-profiler/mysql-query-profiler). + +### Usage + +Start the application, connect to a database (remote or local) and insert a query you want to debug. Performance will be shown along with an optimizer trace in addition to more options you can configure. + +## Development + +### Requirements - Node 10 or later - Npm - Yarn -## Install +### Install for development First, clone the repo via git and install dependencies: @@ -18,7 +46,7 @@ yarn Test database: [test_db](https://github.com/datacharmer/test_db) -## Starting Development +### Starting Development Start the app in the `dev` environment. This starts the renderer process in [**hot-module-replacement**](https://webpack.js.org/guides/hmr-react/) mode and starts a webpack dev server that sends hot updates to the renderer process: @@ -26,7 +54,7 @@ Start the app in the `dev` environment. This starts the renderer process in [**h yarn dev ``` -## Packaging for Production +### Packaging for Production To package apps for the local platform: diff --git a/app/App.tsx b/app/App.tsx index 39d56c50db9969f34f7989ecf0774987eaf9c099..b4350105949cdb9c5e08472f708c6de431c57847 100644 --- a/app/App.tsx +++ b/app/App.tsx @@ -1,7 +1,6 @@ import React from 'react'; import { createMuiTheme, ThemeProvider } from '@material-ui/core'; import { HashRouter as Router, Switch, Route } from 'react-router-dom'; -import { SqlManagerProvider } from './context/SqlManagerContext'; import { LoadingProvider } from './context/LoadingContext'; import routes from './routes'; import LoginScreen from './containers/LoginScreen'; @@ -11,6 +10,9 @@ import { LoginDetailsProvider } from './context/LoginDetailsContext'; const theme = createMuiTheme({ palette: { type: 'dark', + error: { + main: '#FF9292', + }, primary: { light: '#769CFF', main: '#769CFF', @@ -45,26 +47,22 @@ const theme = createMuiTheme({ export default function App() { return ( - <div> + <div className="content"> <ThemeProvider theme={theme}> - <SqlManagerProvider> - <LoadingProvider> - <LoginDetailsProvider> - <div className="content"> - <Router> - <Switch> - <Route exact path={routes.login}> - <LoginScreen /> - </Route> - <Route path={routes.dashboard}> - <Dashboard /> - </Route> - </Switch> - </Router> - </div> - </LoginDetailsProvider> - </LoadingProvider> - </SqlManagerProvider> + <LoadingProvider> + <LoginDetailsProvider> + <Router> + <Switch> + <Route exact path={routes.login}> + <LoginScreen /> + </Route> + <Route path={routes.dashboard}> + <Dashboard /> + </Route> + </Switch> + </Router> + </LoginDetailsProvider> + </LoadingProvider> </ThemeProvider> </div> ); diff --git a/app/QueryOutput.ts b/app/QueryOutput.ts new file mode 100644 index 0000000000000000000000000000000000000000..1a7a89fc75f67c31b5bfe5a5508683ae23a44924 --- /dev/null +++ b/app/QueryOutput.ts @@ -0,0 +1,6 @@ +import { Result } from '../backend/utils/mysql'; + +export interface QueryOutput { + results: Result | undefined; + error: undefined; +} diff --git a/app/app.global.css b/app/app.global.css index 529eb368c19146638be71f9e840f411fa3ea3280..eed1a3f2d664da147cb1875058b76488799089b5 100644 --- a/app/app.global.css +++ b/app/app.global.css @@ -4,15 +4,19 @@ * See https://github.com/webpack-contrib/sass-loader#imports */ -body { +body, +body #root { color: rgba(255, 255, 255, 0.9); + max-height: 100vh; + max-width: 100vw; height: 100vh; - background-color: #404040; + width: 100vw; + background-color: #393939; margin: 0; + overflow: hidden; } .content { - display: flex; - flex-flow: column nowrap; - justify-content: space-between; + min-height: 100%; + min-width: 100%; } diff --git a/app/app.html b/app/app.html index 6307190b216ff19a4edaa0d2f31f2038b52b413b..29649a36b3c9af33ca7058fec9543efeebd2c21e 100644 --- a/app/app.html +++ b/app/app.html @@ -2,8 +2,12 @@ <!DOCTYPE html> <html> <head> - <meta charset="utf-8" /> - <title>Hello Electron React!</title> + <meta + charset="utf-8" + name="viewport" + content="width=device-width, initial-scale=1.0" + /> + <title>MySQL Query Profiler</title> <link href="https://fonts.googleapis.com/css2?family=Raleway:wght@200;300;400;500;600;700&display=swap" rel="stylesheet" diff --git a/app/components/Login.tsx b/app/components/Login.tsx index 36166d56969e7b9f6a7cce80c76cafbfd2cfc41e..d8aa34fc491a7052f03d672196f730580560fd56 100644 --- a/app/components/Login.tsx +++ b/app/components/Login.tsx @@ -5,11 +5,11 @@ import { Paper, Typography, makeStyles, + LinearProgress, } from '@material-ui/core'; import { useHistory, useLocation } from 'react-router'; import clsx from 'clsx'; -import { SqlManagerContext } from '../context/SqlManagerContext'; -import SqlManager from '../../backend/recorder/SqlManager'; +import SqlManagerSingleton from '../../backend/recorder/SqlManagerSingleton'; import { LoadingContext } from '../context/LoadingContext'; import routes from '../routes'; import { LoginDetailsContext } from '../context/LoginDetailsContext'; @@ -41,6 +41,13 @@ const useStyles = makeStyles((theme) => ({ textAlign: 'center', marginBottom: theme.spacing(2), }, + errorMessage: { + textAlign: 'center', + whiteSpace: 'pre-line', + }, + progressBar: { + borderRadius: '2px', + }, })); interface LoginProps { @@ -52,7 +59,6 @@ const DefaultProps = { }; export default function Login({ onConnect = undefined }: LoginProps) { - const sqlManagerContext = useContext(SqlManagerContext); const loadingContext = useContext(LoadingContext); const loginDetailsContext = useContext(LoginDetailsContext); @@ -74,19 +80,17 @@ export default function Login({ onConnect = undefined }: LoginProps) { const [database, setDatabase] = useState( loginDetailsContext?.loginDetails?.database || '' ); + const [connecting, setConnecting] = useState(false); + const [errorMessage, setErrorMessage] = useState(''); async function handleConnectByLogin() { - let manager; - if (!sqlManagerContext?.sqlManager) { - manager = new SqlManager(); - sqlManagerContext?.setSqlManager(manager); - } else { - manager = sqlManagerContext.sqlManager; - } + setConnecting(true); + const manager = SqlManagerSingleton.getInstance(); try { loadingContext?.setConnected(false); loadingContext?.setConnecting(true); await manager.connect({ host, user, password, port }, database); + setErrorMessage(''); loadingContext?.setConnecting(false); loadingContext?.setConnected(true); @@ -98,12 +102,43 @@ export default function Login({ onConnect = undefined }: LoginProps) { } } catch (error) { console.error(error); + if (error?.info?.msg?.includes('Unknown database')) { + const newErrorMessage = `${error.info.msg.replace( + 'Unknown', + 'The' + )} does not exist on the chosen server`; + setErrorMessage(newErrorMessage); + } else if (String(error).includes('database was not passed')) { + setErrorMessage('There was no database to connect to'); + } else if ( + String(error).includes('EAI_AGAIN') || + String(error).includes('ENOTFOUND') + ) { + setErrorMessage(`The host '${host}' could not be found`); + } else if (String(error).includes('Access denied')) { + setErrorMessage(`Wrong username or password, user: ${user}@${host}`); + } else if (String(error).includes('The server has gone away')) { + setErrorMessage( + `The server connection is not using the X Protocol. + Make sure you are connecting to the correct port and using a MySQL 5.7.12 (or higher) server instance. + Default port for X Protocol servers is 33060` + ); + } else { + setErrorMessage('Failed to connect'); + } loadingContext?.setConnecting(false); loadingContext?.setConnected(false); + + setConnecting(false); + } + } + + function handleKeyUp(e: { key: string }) { + if (e.key === 'Enter') { + handleConnectByLogin(); } } - // TODO: Show connection indicator (spinning circle) // TODO: Show result of connection (success/failure) const classes = useStyles(); @@ -116,11 +151,13 @@ export default function Login({ onConnect = undefined }: LoginProps) { </Typography> <div className={clsx(classes.content, classes.element)}> <TextField + autoFocus className={classes.element} variant="filled" label="Host" value={host} onChange={(event) => setHost(event.target.value)} + onKeyUp={handleKeyUp} /> <TextField className={classes.element} @@ -128,6 +165,7 @@ export default function Login({ onConnect = undefined }: LoginProps) { label="User" value={user} onChange={(event) => setUser(event.target.value)} + onKeyUp={handleKeyUp} /> <TextField className={classes.element} @@ -136,6 +174,7 @@ export default function Login({ onConnect = undefined }: LoginProps) { type="password" value={password} onChange={(event) => setPassword(event.target.value)} + onKeyUp={handleKeyUp} /> <TextField className={classes.element} @@ -143,6 +182,7 @@ export default function Login({ onConnect = undefined }: LoginProps) { label="Port" value={port} onChange={(event) => setPort(Number(event.target.value))} + onKeyUp={handleKeyUp} /> <TextField className={classes.element} @@ -150,9 +190,19 @@ export default function Login({ onConnect = undefined }: LoginProps) { label="Database" value={database} onChange={(event) => setDatabase(event.target.value)} + onKeyUp={handleKeyUp} /> </div> + {!!errorMessage && ( + <Typography + color="error" + className={clsx(classes.element, classes.errorMessage)} + > + {errorMessage} + </Typography> + )} <Button + className={classes.element} type="button" variant="contained" color="primary" @@ -160,6 +210,11 @@ export default function Login({ onConnect = undefined }: LoginProps) { > Connect </Button> + <LinearProgress + hidden={!connecting} + className={clsx(classes.element, classes.progressBar)} + color="primary" + /> </Paper> </div> ); diff --git a/app/components/MemoryChart.tsx b/app/components/MemoryChart.tsx index b86754e32784aec62ff5d75a1ba5c14ff7a3d861..0d19382f39abeff45394b9e3ebbf4a3314b8fa1e 100644 --- a/app/components/MemoryChart.tsx +++ b/app/components/MemoryChart.tsx @@ -1,4 +1,5 @@ -import React, { useState, ReactElement, ReactNode } from 'react'; +import _ from 'lodash'; +import React, { useState, useContext } from 'react'; import { Legend, LineChart, @@ -10,11 +11,10 @@ import { ResponsiveContainer, Surface, Symbols, - ContentRenderer, - LegendProps, + ReferenceLine, + Label, } from 'recharts'; -import _ from 'lodash'; -import { MemoryPerformance } from '../../backend/data-processor/DataProcessor'; +import { RecordingContext } from '../context/RecordingContext'; interface Payload { value: string; @@ -23,38 +23,47 @@ interface Payload { color: string; } -const chartDataMock: MemoryPerformance = [ - { relative_time: 0, geom: 0, total: 235378 }, - { relative_time: 1, geom: 0, total: 263058 }, - { relative_time: 2, geom: 0, total: 263058 }, - { relative_time: 3, geom: 265, total: 263371 }, - { relative_time: 4, geom: 265, total: 263371 }, - { relative_time: 5, geom: 387, total: 263493 }, - { relative_time: 6, geom: 3267, total: 266373 }, - { relative_time: 7, geom: 3267, total: 266373 }, - { relative_time: 8, geom: 32067, total: 295173 }, - { relative_time: 9, geom: 32067, total: 295173 }, - { relative_time: 10, geom: 256503, total: 519609 }, - { relative_time: 11, geom: 320067, total: 726837 }, - { relative_time: 12, geom: 320067, total: 726837 }, - { relative_time: 13, geom: 1349729, total: 1756499 }, - { relative_time: 14, geom: 1442129, total: 1848899 }, - { relative_time: 15, geom: 1785089, total: 2191859 }, - { relative_time: 16, geom: 1980689, total: 2387459 }, - { relative_time: 17, geom: 1164423, total: 1571193 }, - { relative_time: 18, geom: 1418583, total: 1825353 }, - { relative_time: 19, geom: 1589703, total: 1996473 }, - { relative_time: 20, geom: 0, total: 216938 }, -]; +interface ChartColors { + [key: string]: string; +} export default function MemoryChart() { const [disabled, setDisabled] = useState<Array<string>>([]); - const [chartData, setChartData] = useState<MemoryPerformance>(chartDataMock); - const [chartColors, setChartColors] = useState({ - geom: '#8884d8', - total: '#82ca9d', - }); + const [chartColors, setChartColors] = useState({ total: '#82ca9d' }); + const validStages = [ + 'stage/sql/preparing', + 'stage/sql/optimizing', + 'stage/sql/executing', + 'stage/sql/end', + ]; + + const recordingContext = useContext(RecordingContext); + const stageTimes = recordingContext?.stageTimes; + const chartData = recordingContext?.chartData; + + function getColor() { + return `#${(0x1000000 + Math.random() * 0xffffff) + .toString(16) + .substr(1, 6)}`; + } + + function assignColor(key: string) { + const tempObject: ChartColors = {}; + tempObject[key] = getColor(); + return tempObject; + } + + if (chartData && _.keys(chartColors).length === 1) { + const dataKeys = _.keys(chartData[0]).slice(1); + _.forEach(dataKeys, (key) => _.assign(chartColors, assignColor(key))); + } + + function getMaxTime() { + // eslint-disable-next-line prefer-spread + return Math.max.apply(Math, _.map(chartData, 'relative_time')); + } + // When a legend is clicked the datakey is added to the disabled list, which will remove it form the line chart function handleClick(dataKey: string) { if (_.includes(disabled, dataKey)) { setDisabled(disabled.filter((obj) => obj !== dataKey)); @@ -63,9 +72,7 @@ export default function MemoryChart() { } } - function renderCustomizedLegend(props: { - payload: Array<Payload>; - }): ReactNode { + function renderCustomizedLegend(props: { payload: Array<Payload> }) { const { payload } = props; return ( <div className="customized-legend"> @@ -85,14 +92,13 @@ export default function MemoryChart() { style={style} key={value} > - {/* viewBox="0 0 10 10" */} <Surface width={10} height={10}> <Symbols cx={5} cy={5} type="circle" size={50} fill={color} /> {active && ( <Symbols cx={5} cy={5} type="circle" size={25} fill="#FFF" /> )} </Surface> - <span>{value}</span> + <span style={{ color: '#FFF' }}>{value}</span> </span> ); })} @@ -100,6 +106,16 @@ export default function MemoryChart() { ); } + function formatBytes(byte: number) { + if (Math.abs(byte) > 10000000) { + return `${Math.floor(byte / 1024 / 1024)} MB`; + } + if (Math.abs(byte) > 10000) { + return `${Math.floor(byte / 1024)} KB`; + } + return `${Math.floor(byte)} B`; + } + return ( <div className="highlight-bar-charts"> <ResponsiveContainer height={400}> @@ -110,13 +126,27 @@ export default function MemoryChart() { margin={{ top: 20, right: 30, left: 20, bottom: 5 }} > <CartesianGrid strokeDasharray="3 10" /> - <XAxis dataKey="relative_time" /> - <YAxis /> - <Tooltip /> + {/* TODO: Create our own Axis tick component like this: http://recharts.org/en-US/examples/CustomizedLabelLineChart */} + <XAxis + dataKey="relative_time" + type="number" + tick={{ stroke: '#FFFFFF', strokeWidth: '0.5px' }} + domain={[0, getMaxTime()]} + tickCount={20} + /> + <YAxis + type="number" + tickFormatter={formatBytes} + tick={{ stroke: '#FFFFFF', strokeWidth: '0.5px' }} + /> + <Tooltip + formatter={(value) => formatBytes(Number(value))} + offset={100} + /> <Legend verticalAlign="bottom" height={36} - align="left" + align="center" payload={_.toPairs(chartColors).map((pair, i) => ({ value: pair[0], id: i, @@ -125,6 +155,9 @@ export default function MemoryChart() { }))} content={renderCustomizedLegend} /> + + {/* Creates an array from the key:value pairs in chartColors. + The keys that are not disabled becomes a line */} {_.toPairs(chartColors) .filter((pair) => !_.includes(disabled, pair[0])) .map((pair) => ( @@ -133,8 +166,27 @@ export default function MemoryChart() { dataKey={pair[0]} key={pair[0]} stroke={pair[1]} + dot={false} /> ))} + {/* Filters stageTimes to only include stages that are in validStages and only the first instance of them. + Then creates reference lines from the data that remains */} + + {_.forEach(_.uniqBy(stageTimes, 'stage')) + ?.filter((stage) => _.includes(validStages, stage.stage)) + ?.map((item) => ( + <ReferenceLine + x={item.startTime} + stroke="#769CFF" + key={_.uniqueId('ref_')} + > + <Label + value={item.stage} + position="top" + style={{ color: '#FFFFFF' }} + /> + </ReferenceLine> + ))} </LineChart> </ResponsiveContainer> </div> diff --git a/app/components/OptimizerTrace.tsx b/app/components/OptimizerTrace.tsx new file mode 100644 index 0000000000000000000000000000000000000000..cb2f869e48bb67e5f11a4768dc369b8ab2919b4c --- /dev/null +++ b/app/components/OptimizerTrace.tsx @@ -0,0 +1,21 @@ +import React, { useContext } from 'react'; +import ReactJson from 'react-json-view'; +import { RecordingContext } from '../context/RecordingContext'; + +export default function OptimizerTrace() { + const recordingContext = useContext(RecordingContext); + const optimizerTrace = recordingContext?.optimizerTrace; + return ( + <div> + {optimizerTrace && ( + <ReactJson + src={optimizerTrace} + theme="twilight" + name="OptimizerTrace" + collapsed={5} + indentWidth={2} + /> + )} + </div> + ); +} diff --git a/app/components/QueryRecorder.tsx b/app/components/QueryRecorder.tsx index 6aaa0a3c635736dfce0dc78425060bad04671bad..1889d6e910f17e8e3eceef27ad52cd5b7b8457a2 100644 --- a/app/components/QueryRecorder.tsx +++ b/app/components/QueryRecorder.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/jsx-wrap-multilines */ import React, { useState, useContext } from 'react'; import { makeStyles } from '@material-ui/core/styles'; import { @@ -7,11 +8,12 @@ import { Typography, FormControlLabel, Checkbox, + CircularProgress, } from '@material-ui/core'; import clsx from 'clsx'; -import { SqlManagerContext } from '../context/SqlManagerContext'; -import { DataProcessor } from '../../backend/data-processor/DataProcessor'; import { RecordingContext } from '../context/RecordingContext'; +import ResultJson from './ResultJson'; +import SqlManagerSingleton from '../../backend/recorder/SqlManagerSingleton'; const useStyles = makeStyles((theme) => ({ container: { @@ -32,7 +34,11 @@ const useStyles = makeStyles((theme) => ({ display: 'flex', flexFlow: 'column nowrap', flexGrow: 1, - width: '600px', + }, + recordButtonWrapper: { + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', }, output: { userSelect: 'none', @@ -44,13 +50,15 @@ const useStyles = makeStyles((theme) => ({ export default function QueryRecorder() { const [changedQuery, setChangedQuery] = useState(''); - const [output, setOutput] = useState<string>(''); + const [output, setOutput] = useState(''); const [explainAnalyze, setExplainAnalyze] = useState(false); + const [waitRecording, setWaitRecording] = useState(false); - const manager = useContext(SqlManagerContext)?.sqlManager; + const manager = SqlManagerSingleton.getInstance(); const recordingContext = useContext(RecordingContext); async function record() { + setWaitRecording(true); if (!manager) { console.log('not connected'); return; @@ -58,34 +66,34 @@ export default function QueryRecorder() { try { const result = await manager.record(changedQuery, explainAnalyze); - console.log(result); if (result?.error) { console.log(`QueryRecorder: Result: ${result}`); - setOutput(JSON.stringify(result.error.info.msg, undefined, 2)); + recordingContext?.setQueryOutput(result.result.error); + const errorcode = JSON.stringify(result.error.info.code, undefined, 2); + const errormsg = JSON.stringify(result.error.info.msg, undefined, 2); + setOutput(`Errorcode: ${errorcode}\n${errormsg}`); } else { + recordingContext?.setQueryOutput(result.result); setOutput(JSON.stringify(result?.result, undefined, 2)); - const memoryPerformance = DataProcessor.processMemoryPerformance( - result.memoryPerformance - ); - recordingContext?.setMemoryPerformance(memoryPerformance); + recordingContext?.setOptimizerTrace(result.optimizerTrace); + recordingContext?.setChartData(result.memoryPerformance); + recordingContext?.setStageTimes(result.stageTimes); } } catch (error) { console.log(`QueryRecorder: Error: ${error}`); + } finally { + setWaitRecording(false); } } - async function doOptimizerQuery() { - if (!manager) { - console.log('not connected'); - return; + const classes = useStyles(); + + function handleKeyUp(e: { key: string; ctrlKey: boolean }) { + if (e.key === 'Enter' && e.ctrlKey) { + record(); } - const traceResult = await manager.executeWithTrace(changedQuery); - setOutput(JSON.stringify(traceResult.result, undefined, 2)); - console.log(traceResult.trace); } - const classes = useStyles(); - return ( <div className={classes.container}> <Paper className={classes.content} elevation={1}> @@ -94,6 +102,7 @@ export default function QueryRecorder() { </div> <div className={clsx(classes.element, classes.input)}> <TextField + autoFocus multiline InputProps={{ classes: { @@ -106,12 +115,13 @@ export default function QueryRecorder() { rowsMax={10} value={changedQuery} onChange={(event) => setChangedQuery(event.target.value)} + onKeyUp={handleKeyUp} + helperText="Ctrl + Enter: Run" /> </div> <div className={classes.element}> <FormControlLabel control={ - // eslint-disable-next-line react/jsx-wrap-multilines <Checkbox color="primary" checked={explainAnalyze} @@ -121,29 +131,25 @@ export default function QueryRecorder() { label="Explain analyze" /> </div> - <div className={classes.element}> - <Button variant="contained" color="primary" onClick={() => record()}> + <div className={clsx(classes.element, classes.recordButtonWrapper)}> + <Button + disabled={waitRecording} + variant="contained" + color="primary" + onClick={() => record()} + > Record </Button> - </div> - <div className={classes.element}> - <Button variant="contained" onClick={() => doOptimizerQuery()}> - Optimizer - </Button> + {waitRecording && ( + <CircularProgress + style={{ marginLeft: '16px' }} + size="24px" + color="primary" + /> + )} </div> <div className={clsx(classes.element, classes.input)}> - <TextField - className={classes.output} - InputProps={{ - classes: { - input: classes.code, - }, - }} - multiline - rows={10} - variant="outlined" - value={output} - /> + <ResultJson result={output} /> </div> </Paper> </div> diff --git a/app/components/ResultJson.tsx b/app/components/ResultJson.tsx new file mode 100644 index 0000000000000000000000000000000000000000..9cdb8ebb1f3c72ba951a1f46bc2a3d59bb621418 --- /dev/null +++ b/app/components/ResultJson.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import { TextField } from '@material-ui/core'; +import clsx from 'clsx'; + +interface TResultProps { + result: string; +} + +const useStyles = makeStyles((theme) => ({ + container: { + maxWidth: 600 + theme.spacing(4), + }, + content: { + display: 'flex', + flexFlow: 'column nowrap', + paddingTop: theme.spacing(1), + paddingBottom: theme.spacing(1), + paddingLeft: theme.spacing(2), + paddingRight: theme.spacing(2), + }, + element: { + marginBottom: theme.spacing(1), + }, + input: { + display: 'flex', + flexFlow: 'column nowrap', + flexGrow: 1, + }, + result: { + userSelect: 'none', + }, + code: { + fontFamily: 'Roboto Mono !important', + }, +})); + +export default function ResultJson(props: TResultProps) { + const classes = useStyles(); + const { result } = props; + return ( + <div className={clsx(classes.element, classes.input)}> + <TextField + className={classes.result} + InputProps={{ + classes: { + input: classes.code, + }, + }} + multiline + rows={10} + variant="outlined" + value={result} + /> + </div> + ); +} diff --git a/app/components/ResultTable.tsx b/app/components/ResultTable.tsx new file mode 100644 index 0000000000000000000000000000000000000000..90a9675ca10cd8cbdb7418eca66bfe2ef01af666 --- /dev/null +++ b/app/components/ResultTable.tsx @@ -0,0 +1,111 @@ +/* eslint-disable prefer-template */ +import React, { useContext } from 'react'; +import { + makeStyles, + withStyles, + createStyles, + Theme, +} from '@material-ui/core/styles'; +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 { ResultValue } from '@mysql/xdevapi'; +import { RecordingContext } from '../context/RecordingContext'; + +// interface TResultProps { +// result: TResult | undefined; +// } + +const useStyles = makeStyles({ + table: { + minWidth: 650, + }, + container: { + maxHeight: 211, + }, +}); + +const StyledTableCell = withStyles((theme: Theme) => + createStyles({ + head: { + backgroundColor: '#404040', + color: theme.palette.common.white, + }, + body: { + fontSize: 14, + }, + }) +)(TableCell); + +export default function ResultTable() { + const recordingContext = useContext(RecordingContext); + + const classes = useStyles(); + + const result = recordingContext?.queryOutput; + + const tableHeader: string[] | undefined = result?.results?.labels; + const tableBody: ResultValue[][] | undefined = result?.results?.values; + const types: number[] | undefined = result?.results?.types; + + function formatDate(d: Date) { + let month = '' + (d.getMonth() + 1); + let day = '' + d.getDate(); + const year = d.getFullYear(); + + if (month.length < 2) month = '0' + month; + if (day.length < 2) day = '0' + day; + + return [year, month, day].join('-'); + } + + function format(index: number, entry: any): string { + let datatype = 0; + if (types) { + datatype = types[index]; + } + if (datatype === 12) { + if (typeof entry === 'number') { + const date = new Date(entry); + return formatDate(date); + } + const date = new Date(entry); + return formatDate(date); + } + return entry; + } + + return ( + <TableContainer className={classes.container} component={Paper}> + <Table className={classes.table} aria-label="simple table" stickyHeader> + <TableHead> + <TableRow> + {tableHeader?.map((column) => ( + <StyledTableCell key={column}>{column}</StyledTableCell> + ))} + </TableRow> + </TableHead> + <TableBody> + {tableBody?.map((row) => ( + <TableRow key={row.join('-')}> + {row.map((cell) => ( + <TableCell + key={tableBody + .indexOf(row) + .toString() + .concat(row.indexOf(cell).toString())} + > + {format(row.indexOf(cell), cell)} + </TableCell> + ))} + </TableRow> + ))} + </TableBody> + </Table> + </TableContainer> + ); +} diff --git a/app/components/TreeViewExplainAnalyze.tsx b/app/components/TreeViewExplainAnalyze.tsx new file mode 100644 index 0000000000000000000000000000000000000000..55261710a27b8893050683a83ee0b01ff94de916 --- /dev/null +++ b/app/components/TreeViewExplainAnalyze.tsx @@ -0,0 +1,135 @@ +import React, { useContext, useState } from 'react'; +import { makeStyles } from '@material-ui/core/styles'; +import TreeView from '@material-ui/lab/TreeView'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import ChevronRightIcon from '@material-ui/icons/ChevronRight'; +import TreeItem from '@material-ui/lab/TreeItem'; +import { RecordingContext } from '../context/RecordingContext'; + +interface Node { + id: string; + offset: number; + command: string; + cost_est?: number; + rows_est?: number; + time: string; + rows: number; + loops: number; + children: Node[]; +} + +const rootNode: Node = { + id: '0', + offset: -1, + command: '', + time: '', + rows: -1, + loops: -1, + children: [], +}; + +const useStyles = makeStyles({ + root: { + flexGrow: 1, + }, +}); + +/* + Helper function + INPUT: EXPLAIN ANALYZE data (string) + RETURN: List of Node objects + */ +function extractData(data: string) { + rootNode.children = []; + const regexp = /([ ]*)?-> (.+?)( \(cost=([\d.]+) rows=(\d+)\))? \(actual time=([\d.]+) rows=(\d+) loops=(\d+)\)/gm; + const matches = [...data.matchAll(regexp)]; + const nodes: Node[] = [rootNode]; + // Create object for each line. Root has ID 0 + let idIterator = 1; + matches.forEach((element) => { + const node: Node = { + id: idIterator.toString(), + offset: element[1] === undefined ? 0 : element[1].length, + command: element[2], + cost_est: Number(element[4]), + rows_est: Number(element[5]), + time: element[6], + rows: Number(element[7]), + loops: Number(element[8]), + children: [], + }; + nodes.push(node); + idIterator += 1; + }); + return nodes; +} + +/* + INPUT: EXPLAIN ANALYZE data + ACTION: Assigns children of root node, and to all child nodes, based on offset and order + RETURN: List of Node objects +*/ +function buildTree(explainAnalyzeData: string) { + // Extract relevant data + const nodes: Node[] = extractData(explainAnalyzeData); + // Assign children of each object + // Iterate through all objects + for (let i = 1; i < nodes.length; i += 1) { + // Set current node as child if its offset is smaller + if (nodes[i - 1].offset < nodes[i].offset) { + nodes[i - 1].children.push(nodes[i]); + } else { + // If current node's offset is smaller then it cannot be child of the previous node + // Iterate backwards from current node until a node with smaller offset has been reached + for (let j = i - 1; i > 0; j -= 1) { + if (nodes[j].offset < nodes[i].offset) { + nodes[j].children.push(nodes[i]); + break; + } + } + } + } +} + +export default function RecursiveTreeView() { + const recordingContext = useContext(RecordingContext); + + const classes = useStyles(); + const [previousData, setPreviousData] = useState(''); + const data = JSON.stringify(recordingContext?.queryOutput, undefined, 2); + if (!data) return null; + // TODO: Only run when EXPLAIN ANALYZE detected + if (data !== previousData) { + buildTree(data); + setPreviousData(data); + } + + const RenderTree = (nodes: Node) => ( + <TreeItem key={nodes.id} nodeId={nodes.id} label={nodes.command}> + {Array.isArray(nodes.children) + ? nodes.children.map((node) => RenderTree(node)) + : null} + </TreeItem> + ); + + const RenderTreeWithoutRoot = (root: Node) => { + // Renders only the children of root + const elements: JSX.Element[] = []; + root.children.forEach((child) => { + elements.push(RenderTree(child)); + }); + return elements; + }; + + // TODO: Find dynamic solution to defaultExpanded + return ( + <TreeView + className={classes.root} + defaultCollapseIcon={<ExpandMoreIcon />} + defaultExpanded={['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']} + defaultExpandIcon={<ChevronRightIcon />} + > + {[RenderTreeWithoutRoot(rootNode)]} + </TreeView> + ); +} diff --git a/app/containers/Dashboard.tsx b/app/containers/Dashboard.tsx index 302cd0eb802fbf5ba858d36b460f05bc1234512b..9142121b71a68a3ae4be50c081f08d8dcca83271 100644 --- a/app/containers/Dashboard.tsx +++ b/app/containers/Dashboard.tsx @@ -1,13 +1,31 @@ import React, { useContext, useState } from 'react'; -import { Button, Dialog } from '@material-ui/core'; +import { Button, Dialog, makeStyles } from '@material-ui/core'; import { useLocation, useHistory } from 'react-router'; +import PanelGroup from 'react-panelgroup'; import QueryRecorder from '../components/QueryRecorder'; import { LoadingContext } from '../context/LoadingContext'; import routes from '../routes'; import Login from '../components/Login'; import { LoginDetailsContext } from '../context/LoginDetailsContext'; import { RecordingProvider } from '../context/RecordingContext'; -import MemoryChart from '../components/MemoryChart'; +import ResultView from './ResultView'; + +const useStyles = makeStyles((theme) => ({ + wrapper: { + minHeight: '100%', + height: '100%', + maxHeight: '100vh', + }, + column: { + display: 'flex', + flexFlow: 'column nowrap', + maxHeight: '98vh', + height: '100%', + padding: `${theme.spacing(1)}px ${theme.spacing(2)}px`, + width: '100%', + overflowY: 'auto', + }, +})); export default function Dashboard() { const [changeConnectionOpen, setChangeConnectionOpen] = useState(false); @@ -32,26 +50,41 @@ export default function Dashboard() { setChangeConnectionOpen(true); } + const classes = useStyles(); + return ( - <div> - <div> - <Button - variant="outlined" - color="primary" - onClick={() => openConnectionDialog()} - > - Change connection - </Button> - <Dialog - open={changeConnectionOpen} - onClose={() => setChangeConnectionOpen(false)} - > - <Login onConnect={() => setChangeConnectionOpen(false)} /> - </Dialog> - </div> + <div className={classes.wrapper}> <RecordingProvider> - <QueryRecorder /> - <MemoryChart /> + <PanelGroup + borderColor="#4B4B4B" + spacing={16} + panelWidths={[ + { minSize: 200, size: 700, resize: 'dynamic' }, + { minSize: 200, resize: 'dynamic' }, + ]} + > + <div className={classes.column}> + <div> + <Button + variant="outlined" + color="primary" + onClick={() => openConnectionDialog()} + > + Change connection + </Button> + <Dialog + open={changeConnectionOpen} + onClose={() => setChangeConnectionOpen(false)} + > + <Login onConnect={() => setChangeConnectionOpen(false)} /> + </Dialog> + </div> + <QueryRecorder /> + </div> + <div className={classes.column}> + <ResultView /> + </div> + </PanelGroup> </RecordingProvider> </div> ); diff --git a/app/containers/LoginScreen.tsx b/app/containers/LoginScreen.tsx index 5522ff0095ef59407d10e8f33452b4aba351af0f..fe128ae2dec5206c4fd29c3ca7accc2d3a7e92b7 100644 --- a/app/containers/LoginScreen.tsx +++ b/app/containers/LoginScreen.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState, useContext } from 'react'; import { Typography, makeStyles } from '@material-ui/core'; import Login from '../components/Login'; -import { loadLoginDetails } from '../../backend/utils/fileutils'; +import FileIO from '../../backend/utils/FileIO'; import { LoginDetailsContext } from '../context/LoginDetailsContext'; const useStyles = makeStyles((theme) => ({ @@ -14,10 +14,10 @@ const useStyles = makeStyles((theme) => ({ flexFlow: 'column nowrap', alignItems: 'center', justifyContent: 'space-between', - padding: `${theme.spacing(8)}px ${theme.spacing(16)}px`, + padding: `${theme.spacing(6)}px ${theme.spacing(16)}px`, }, title: { - marginBottom: theme.spacing(8), + marginBottom: theme.spacing(6), textAlign: 'center', }, })); @@ -28,7 +28,7 @@ export default function LoginScreen() { const loginDetailsContext = useContext(LoginDetailsContext); useEffect(() => { - loadLoginDetails() + FileIO.loadLoginDetails() .then((response) => { if (response) { loginDetailsContext?.setLoginDetails(response); @@ -37,7 +37,6 @@ export default function LoginScreen() { return true; }) .catch((error) => console.error(error)); - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const classes = useStyles(); @@ -46,7 +45,7 @@ export default function LoginScreen() { <div className={classes.wrapper}> {!loading && ( <div className={classes.content}> - <Typography className={classes.title} variant="h2"> + <Typography className={classes.title} variant="h3"> Welcome to MySQL query profiler! </Typography> <Login /> diff --git a/app/containers/ResultView.tsx b/app/containers/ResultView.tsx new file mode 100644 index 0000000000000000000000000000000000000000..27a909d41af83256334fd2ceec7e67d6d61b8ac2 --- /dev/null +++ b/app/containers/ResultView.tsx @@ -0,0 +1,105 @@ +/* eslint-disable react/jsx-wrap-multilines */ +import { + makeStyles, + Checkbox, + FormControlLabel, + Paper, +} from '@material-ui/core'; +import React, { useContext, useState } from 'react'; +import MemoryChart from '../components/MemoryChart'; +import OptimizerTrace from '../components/OptimizerTrace'; +import ResultTable from '../components/ResultTable'; +import { RecordingContext } from '../context/RecordingContext'; +import TreeViewExplainAnalyze from '../components/TreeViewExplainAnalyze'; + +const useStyles = makeStyles((theme) => ({ + wrapper: { + display: 'flex', + flexFlow: 'column nowrap', + alignContent: 'center', + }, + item: { + margin: `${theme.spacing(1)}px ${theme.spacing(0)}`, + }, +})); + +export default function ResultView() { + const [showMemoryChart, setShowMemoryChart] = useState(true); + const [showOptimizerTrace, setShowOptimizerTrace] = useState(false); + const [showResultTable, setShowResultTable] = useState(false); + const [showExplainAnalyze, setShowExplainAnalyze] = useState(false); + + const recordingContext = useContext(RecordingContext); + + const classes = useStyles(); + + return ( + <div className={classes.wrapper} style={{ minWidth: '200px' }}> + <div> + <FormControlLabel + label="Show result table" + control={ + <Checkbox + color="primary" + checked={showResultTable} + onChange={(event) => setShowResultTable(event.target.checked)} + /> + } + /> + <FormControlLabel + label="Show memory chart" + control={ + <Checkbox + color="primary" + checked={showMemoryChart} + onChange={(event) => setShowMemoryChart(event.target.checked)} + /> + } + /> + <FormControlLabel + label="Show optimizer trace" + control={ + <Checkbox + color="primary" + checked={showOptimizerTrace} + onChange={(event) => setShowOptimizerTrace(event.target.checked)} + /> + } + /> + <FormControlLabel + label="Show explain analyze" + control={ + <Checkbox + color="primary" + checked={showExplainAnalyze} + onChange={(event) => setShowExplainAnalyze(event.target.checked)} + /> + } + /> + </div> + {showResultTable && ( + <Paper className={classes.item}> + <ResultTable /> + </Paper> + )} + {showMemoryChart && ( + <Paper + className={classes.item} + style={{ paddingBottom: 80, paddingTop: 8 }} + > + <MemoryChart /> + </Paper> + )} + {showOptimizerTrace && recordingContext?.optimizerTrace && ( + <Paper className={classes.item} style={{ padding: 8 }}> + <OptimizerTrace /> + </Paper> + )} + {showExplainAnalyze && ( + <Paper className={classes.item}> + <TreeViewExplainAnalyze /> + </Paper> + )} + </div> + ); +} diff --git a/app/context/RecordingContext.tsx b/app/context/RecordingContext.tsx index 66ec853091b5f8790aa4bb6a0ec9ce25146774d0..b64e3d9f270ed8054b8cff117755305a77f30b5a 100644 --- a/app/context/RecordingContext.tsx +++ b/app/context/RecordingContext.tsx @@ -1,13 +1,24 @@ +import { ResultValue } from '@mysql/xdevapi'; import React, { useState, createContext } from 'react'; -import { MemoryPerformance } from '../../backend/data-processor/DataProcessor'; +import { + ChartData, + StageTimes, +} from '../../backend/data-processor/DataProcessor'; +import { QueryOutput } from '../QueryOutput'; type ChildrenType = { children: React.ReactNode; }; type ContextType = { - memoryPerformance: MemoryPerformance | undefined; - setMemoryPerformance: (value: MemoryPerformance | undefined) => void; + chartData: ChartData | undefined; + setChartData: (value: ChartData | undefined) => void; + stageTimes: StageTimes | undefined; + setStageTimes: (value: StageTimes | undefined) => void; + optimizerTrace: ResultValue[][] | undefined; + setOptimizerTrace: (value: ResultValue[][] | undefined) => void; + queryOutput: QueryOutput | undefined; + setQueryOutput: (value: QueryOutput | undefined) => void; }; export const RecordingContext = createContext<ContextType | undefined>( @@ -15,12 +26,28 @@ export const RecordingContext = createContext<ContextType | undefined>( ); export const RecordingProvider = ({ children }: ChildrenType) => { - const [memoryPerformance, setMemoryPerformance] = useState< - MemoryPerformance | undefined + const [chartData, setChartData] = useState<ChartData | undefined>(undefined); + const [stageTimes, setStageTimes] = useState<StageTimes | undefined>( + undefined + ); + const [optimizerTrace, setOptimizerTrace] = useState< + ResultValue[][] | undefined >(undefined); + const [queryOutput, setQueryOutput] = useState<QueryOutput | undefined>( + undefined + ); return ( <RecordingContext.Provider - value={{ memoryPerformance, setMemoryPerformance }} + value={{ + chartData, + setChartData, + stageTimes, + setStageTimes, + optimizerTrace, + setOptimizerTrace, + queryOutput, + setQueryOutput, + }} > {children} </RecordingContext.Provider> diff --git a/app/context/SqlManagerContext.tsx b/app/context/SqlManagerContext.tsx deleted file mode 100644 index 486baf6cf1c89ac445f237b479942b4cc7019d8d..0000000000000000000000000000000000000000 --- a/app/context/SqlManagerContext.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React, { useState, createContext } from 'react'; -import SqlManager from '../../backend/recorder/SqlManager'; - -type ChildrenType = { - children: React.ReactNode; -}; - -type ContextType = { - sqlManager: SqlManager | undefined; - setSqlManager: (value: SqlManager | undefined) => void; -}; - -export const SqlManagerContext = createContext<ContextType | undefined>( - undefined -); - -export const SqlManagerProvider = ({ children }: ChildrenType) => { - const [sqlManager, setSqlManager] = useState<SqlManager | undefined>( - undefined - ); - return ( - <SqlManagerContext.Provider value={{ sqlManager, setSqlManager }}> - {children} - </SqlManagerContext.Provider> - ); -}; diff --git a/app/main.dev.ts b/app/main.dev.ts index 63b86d851e970aedee61d230ac45d5a5c4eb1944..28d4d12c5feee2d2d05a9bce195e6fc1c4dbf38c 100644 --- a/app/main.dev.ts +++ b/app/main.dev.ts @@ -1,3 +1,4 @@ +/* eslint-disable compat/compat */ /* eslint global-require: off, no-console: off */ /** @@ -10,12 +11,16 @@ */ import 'core-js/stable'; import 'regenerator-runtime/runtime'; -import path from 'path'; import { app, BrowserWindow } from 'electron'; import { autoUpdater } from 'electron-updater'; import log from 'electron-log'; +// import installExtension, { +// REACT_DEVELOPER_TOOLS, +// } from 'electron-devtools-installer'; import MenuBuilder from './menu'; +// app.allowRendererProcessReuse = true; + export default class AppUpdater { constructor() { log.transports.file.level = 'info'; @@ -31,52 +36,42 @@ if (process.env.NODE_ENV === 'production') { sourceMapSupport.install(); } -if ( - process.env.NODE_ENV === 'development' || - process.env.DEBUG_PROD === 'true' -) { - require('electron-debug')(); -} +// if ( +// process.env.NODE_ENV === 'development' || +// process.env.DEBUG_PROD === 'true' +// ) { +// require('electron-debug')(); +// } -const installExtensions = async () => { - const installer = require('electron-devtools-installer'); - const forceDownload = !!process.env.UPGRADE_EXTENSIONS; - const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS']; +// const installExtensions = async () => { +// const forceDownload = !!process.env.UPGRADE_EXTENSIONS; +// const extensions = [REACT_DEVELOPER_TOOLS]; - return Promise.all( - extensions.map((name) => installer.default(installer[name], forceDownload)) - ).catch(console.log); -}; +// return Promise.all( +// extensions.map((name) => installExtension(name, forceDownload)) +// ).catch(console.log); +// }; const createWindow = async () => { - if ( - process.env.NODE_ENV === 'development' || - process.env.DEBUG_PROD === 'true' - ) { - await installExtensions(); - } + // if ( + // process.env.NODE_ENV === 'development' || + // process.env.DEBUG_PROD === 'true' + // ) { + // await installExtensions(); + // } mainWindow = new BrowserWindow({ show: false, width: 1080, height: 900, - webPreferences: - (process.env.NODE_ENV === 'development' || - process.env.E2E_BUILD === 'true') && - process.env.ERB_SECURE !== 'true' - ? { - nodeIntegration: true, - } - : { - preload: path.join(__dirname, 'dist/renderer.prod.js'), - }, + webPreferences: { + nodeIntegration: true, + }, }); mainWindow.loadURL(`file://${__dirname}/app.html`); - // @TODO: Use 'ready-to-show' event - // https://github.com/electron/electron/blob/master/docs/api/browser-window.md#using-ready-to-show-event - mainWindow.webContents.on('did-finish-load', () => { + mainWindow.once('ready-to-show', () => { if (!mainWindow) { throw new Error('"mainWindow" is not defined'); } @@ -85,6 +80,7 @@ const createWindow = async () => { } else { mainWindow.show(); mainWindow.focus(); + mainWindow.maximize(); } }); diff --git a/app/package.json b/app/package.json index 17220ff8b282f84950f1d73af38738bf5a68f0c5..44aac567f561e3768c9b6a6891f61250672b2248 100644 --- a/app/package.json +++ b/app/package.json @@ -1,13 +1,12 @@ { - "name": "electron-react-boilerplate", - "productName": "electron-react-boilerplate", - "version": "1.3.0", - "description": "Electron application boilerplate based on React, React Router, Webpack, React Hot Loader for rapid application development", + "name": "mysql-query-profiler", + "productName": "MySQL Query Profiler", + "version": "0.2.0", + "description": "A profiler for MySQL queries using Electron and React", "main": "./main.prod.js", "author": { - "name": "Electron React Boilerplate Maintainers", - "email": "electronreactboilerplate@gmail.com", - "url": "https://github.com/electron-react-boilerplate" + "name": "Customer driven project group 4", + "email": "er.yd37@protonmail.com" }, "scripts": { "electron-rebuild": "node -r ../internals/scripts/BabelRegister.js ../internals/scripts/ElectronRebuild.js", diff --git a/backend/data-processor/DataProcessor.ts b/backend/data-processor/DataProcessor.ts index 6b25ce1e159a5ad68e62ecd0104632c9415ae089..2cb653aa1b5b75ac61bc4955e008564befbe5e6d 100644 --- a/backend/data-processor/DataProcessor.ts +++ b/backend/data-processor/DataProcessor.ts @@ -1,30 +1,141 @@ +/* eslint-disable class-methods-use-this */ import { ResultValue } from '@mysql/xdevapi'; import { Result } from '../utils/mysql'; +export interface MemoryPerformanceTimeline { + eventName: string; + isBytesUsedZero: boolean; + times: Array<number>; + bytesUsed: Array<number>; +} + export interface MemoryPerformanceDataPoint { relative_time: number; - geom: number; - total: number; + [eventName: string]: number; } -export type MemoryPerformance = Array<MemoryPerformanceDataPoint>; +export interface StageTimePoint { + stage: string; + source: string; + startTime: number; + endTime: number; +} + +export type MemoryPerformance = Array<MemoryPerformanceTimeline>; + +export type ChartData = Array<MemoryPerformanceDataPoint>; + +export type StageTimes = Array<StageTimePoint>; export class DataProcessor { static processMemoryPerformance(performanceData?: Result) { // TODO: Add more restrictive tests - if (!performanceData || performanceData.labels.indexOf('geom') !== -1) { - // TODO: Figure out why we need to skip the first element - return <MemoryPerformance>( - performanceData?.values.slice(1).map((value: Array<ResultValue>) => { - const dataPoint: MemoryPerformanceDataPoint = { - relative_time: Number(value[1]), - geom: Number(value[2]), - total: Number(value[3]), - }; - return dataPoint; - }) - ); + if (performanceData && performanceData.labels && performanceData.values) { + const { values } = performanceData; + const result: MemoryPerformance = [ + { + eventName: 'total', + isBytesUsedZero: true, + times: [], + bytesUsed: [], + }, + ]; + values.forEach((resultValue: ResultValue[]) => { + const foundTimeline = result.find( + (value) => value.eventName === resultValue[1] + ); + // Sorting through and adding times and bytes used to timelines + if (foundTimeline) { + foundTimeline.times.push(Number(resultValue[0])); + foundTimeline.bytesUsed.push(Number(resultValue[2])); + } else { + result.push({ + eventName: String(resultValue[1]), + isBytesUsedZero: true, + times: [Number(resultValue[0])], + bytesUsed: [Number(resultValue[2])], + }); + } + // Adding bytes to total timeline + const foundTotalTimeline = result.find( + (value) => value.eventName === 'total' + ); + if (foundTotalTimeline) { + // Adding timestamps not in the total timeline + if (!foundTotalTimeline.times.includes(Number(resultValue[0]))) { + foundTotalTimeline.times.push(Number(resultValue[0])); + foundTotalTimeline.bytesUsed.push(0); // Starting at 0 bytes, will increment + } + // Incrementing the bytes used for the current timestamp + foundTotalTimeline.bytesUsed[ + foundTotalTimeline.times.length - 1 + ] += Number(resultValue[2]); + } + }); + // Checking if some timelines do not have memory use, setting a flag if no bytes used + result.forEach((timeLine) => { + timeLine.isBytesUsedZero = + timeLine.bytesUsed.reduce((a, b) => a + b, 0) === 0; + }); + console.log(result); + return DataProcessor.getChartData(result); } throw new Error('DataProcessor: performanceData had wrong format'); } + + static getChartData(memoryPerformance: MemoryPerformance) { + const result: ChartData = []; + + memoryPerformance[0].bytesUsed.forEach((_, index) => { + const memoryPerformanceDataPoint: MemoryPerformanceDataPoint = { + relative_time: memoryPerformance[0].times[index], + }; + + memoryPerformance.forEach((performanceTimeline) => { + if (!performanceTimeline.isBytesUsedZero) { + memoryPerformanceDataPoint[performanceTimeline.eventName] = + performanceTimeline.bytesUsed[index]; + } + }); + result.push(memoryPerformanceDataPoint); + }); + + console.log(result); + return result; + } + + static processStageTimes(stageTimesRaw?: Result) { + if (stageTimesRaw && stageTimesRaw.labels && stageTimesRaw.values) { + const { values } = stageTimesRaw; + const result: StageTimes = []; + values.forEach((resultValue: ResultValue[]) => { + result.push({ + stage: String(resultValue[0]), + source: String(resultValue[1]), + startTime: Number(resultValue[2]), + endTime: Number(resultValue[3]), + }); + }); + console.log(result); + return result; + } + throw new Error('DataProcessor: stageTimesRaw had wrong format'); + } + + static processOptimizerTrace(optimizerTrace?: Result) { + let traceResult; + if (optimizerTrace && optimizerTrace.values) { + traceResult = optimizerTrace; + console.log( + `Dataprocessor.processOptimizerTrace: Traceresult: ${JSON.stringify( + traceResult + )}` + ); + if (traceResult.values.length > 0 && traceResult.values[0].length > 1) { + traceResult.values[0][1] = JSON.parse(String(traceResult.values[0][1])); + } + return traceResult.values; + } + throw new Error('DataProcessor: optimizerTrace had wrong format'); + } } diff --git a/backend/recorder/SqlManager.ts b/backend/recorder/SqlManager.ts index 3c7d0530a57f1e788281afb8f51c629802427ae7..ab5ca284fb3d55bd6eea8783e175b91063523e65 100644 --- a/backend/recorder/SqlManager.ts +++ b/backend/recorder/SqlManager.ts @@ -1,10 +1,11 @@ import { URI, Client } from '@mysql/xdevapi'; -import { saveLoginDetails } from '../utils/fileutils'; +import FileIO from '../utils/FileIO'; import SqlRunner from './SqlRunner'; import SqlMonitor from './SqlMonitor'; import { closeConnection } from '../utils/mysql'; +import { DataProcessor } from '../data-processor/DataProcessor'; -class SqlManager { +export default class SqlManager { connection?: URI; database?: string; @@ -22,29 +23,52 @@ class SqlManager { this.client = await this.runner.connect(connection, database); this.monitor = new SqlMonitor(); await this.monitor.connect(this.client, database); - await saveLoginDetails({ ...connection, database }); + await FileIO.saveLoginDetails({ ...connection, database }); } async record(query: string, explainAnalyze?: boolean) { - if (!this.runner || !this.monitor || !this.runner.connectionID) + if (!this.runner || !this.monitor || !this.runner.connectionID) { throw new Error( - 'SqlManager: Runner, monitor or connectionID was missing. Maybe you forgot to call connect()?' + 'SqlManager.record: Runner, monitor or connectionID was missing. Maybe you forgot to call connect()?' ); + } + await this.monitor.prepareMonitoring(this.runner.connectionID); this.monitor.monitorConnection(this.runner.connectionID); + + // Wait to make sure monitor is ready for runner to execute query + // TODO: Find a more optimal solution than waiting 1 second + // eslint-disable-next-line compat/compat + await new Promise((resolve) => setTimeout(resolve, 1000)); + const result = await this.runner.executeQuery(query, explainAnalyze); if (result?.error) { await this.reset(); return { result, memoryPerformance: undefined, error: result.error }; } + const optimizerTrace = await this.runner.getOptimizerTrace(); const memoryPerformance = await this.monitor.dumpData(); + const stageTimes = await this.monitor.getStageTimes(); return { result, - memoryPerformance: memoryPerformance.results, + optimizerTrace: DataProcessor.processOptimizerTrace( + optimizerTrace.results + ), + memoryPerformance: DataProcessor.processMemoryPerformance( + memoryPerformance.results + ), + stageTimes: DataProcessor.processStageTimes(stageTimes.results), error: undefined, }; } async reset() { + if (!this.runner || !this.monitor || !this.monitor.connectionID) { + throw new Error( + `SqlManager.reset: Runner, monitor or connectionID was missing. Invalid attempt at reset?` + ); + } + // Kill monitor manually from runner as client.close won't interfere if monitor has called its procedure + await this.runner.executeQuery(`kill ${this.monitor.connectionID};`); await closeConnection(this.client); await this.connect(this.connection, this.database); } @@ -54,12 +78,4 @@ class SqlManager { const result = await this.runner.executeQuery(query); return result; } - - async executeWithTrace(query: string) { - if (!this.runner) return { result: [], trace: [] }; - const result = await this.runner.executeTraceQuery(query); - return result; - } } - -export default SqlManager; diff --git a/backend/recorder/SqlManagerSingleton.ts b/backend/recorder/SqlManagerSingleton.ts new file mode 100644 index 0000000000000000000000000000000000000000..c60832ed2c1dcc7ad5e10acd6314789cade07abe --- /dev/null +++ b/backend/recorder/SqlManagerSingleton.ts @@ -0,0 +1,25 @@ +import SqlManager from './SqlManager'; + +interface Singleton { + instance: SqlManager | undefined; + createInstance: () => SqlManager; + getInstance: () => SqlManager; +} + +const SqlManagerSingleton: Singleton = { + instance: undefined, + + createInstance: () => { + const manager = new SqlManager(); + return manager; + }, + + getInstance: () => { + if (!SqlManagerSingleton.instance) { + SqlManagerSingleton.instance = SqlManagerSingleton.createInstance(); + } + return SqlManagerSingleton.instance; + }, +}; + +export default SqlManagerSingleton; diff --git a/backend/recorder/SqlMonitor.ts b/backend/recorder/SqlMonitor.ts index 5c27ae4d40795152fcab1545ba252500f22ae0a8..6c9af3285bc41aacbf7335c430bbf01fe4096788 100644 --- a/backend/recorder/SqlMonitor.ts +++ b/backend/recorder/SqlMonitor.ts @@ -6,8 +6,6 @@ export default class SqlMonitor { connectionID?: string; - fileCount = 0; - async connect(client?: Client, database?: string) { this.session = await createSession(client, database); const resultSet = await runQuery(`SELECT connection_id();`, this.session); @@ -15,11 +13,35 @@ export default class SqlMonitor { console.log(`SqlMonitor: ConnectionID: ${this.connectionID}`); } - async monitorConnection(connectionID: string) { + async prepareMonitoring(connectionID: string) { + await this.enableStageLogging(); + const stageIgnoreBeforeResult = await runQuery( + `SELECT MAX(TIMER_END) FROM performance_schema.events_stages_history_long WHERE THREAD_ID=(SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID=${connectionID});`, + this.session + ); + await this.createMonitorProcedure( + Number(stageIgnoreBeforeResult.results?.values[0]) + ); + } + + async enableStageLogging() { + // Allow logging of stages + await runQuery( + `update performance_schema.setup_instruments set enabled="YES", timed="yes" where name like "stage/%";`, + this.session + ); + await runQuery( + `update performance_schema.setup_consumers set enabled="YES" where name like "events_stages%";`, + this.session + ); + } + + async createMonitorProcedure(stageIgnoreBefore: number) { await runQuery( 'DROP PROCEDURE IF EXISTS monitor_connection;', this.session ); + // Create monitoring procedure await runQuery( `CREATE PROCEDURE monitor_connection( IN conn_id BIGINT UNSIGNED @@ -32,34 +54,28 @@ export default class SqlMonitor { SET thd_id = (SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID=conn_id); - SET stage_ignore_before = (SELECT MAX(TIMER_END) FROM performance_schema.events_stages_history_long WHERE THREAD_ID=thd_id); + SET stage_ignore_before = ${stageIgnoreBefore}; DROP TABLE IF EXISTS monitoring_data; - CREATE TABLE monitoring_data AS - SELECT - NOW(6) AS 'TS', - THREAD_ID, - EVENT_NAME, - COUNT_ALLOC, - COUNT_FREE, - SUM_NUMBER_OF_BYTES_ALLOC, - SUM_NUMBER_OF_BYTES_FREE, - LOW_COUNT_USED, - CURRENT_COUNT_USED, - HIGH_COUNT_USED, - LOW_NUMBER_OF_BYTES_USED, - CURRENT_NUMBER_OF_BYTES_USED, - HIGH_NUMBER_OF_BYTES_USED - FROM performance_schema.memory_summary_by_thread_by_event_name - WHERE THREAD_ID = thd_id; - - SELECT CONCAT ('Waiting for connection ', conn_id, ' (thread ', thd_id, ') to start executing a query') AS 'Status'; + CREATE TABLE monitoring_data ( + TS DATETIME(6), + THREAD_ID BIGINT UNSIGNED, + EVENT_NAME VARCHAR(128), + COUNT_ALLOC BIGINT UNSIGNED, + COUNT_FREE BIGINT UNSIGNED, + SUM_NUMBER_OF_BYTES_ALLOC BIGINT UNSIGNED, + SUM_NUMBER_OF_BYTES_FREE BIGINT UNSIGNED, + LOW_COUNT_USED BIGINT, + CURRENT_COUNT_USED BIGINT, + HIGH_COUNT_USED BIGINT, + LOW_NUMBER_OF_BYTES_USED BIGINT, + CURRENT_NUMBER_OF_BYTES_USED BIGINT, + HIGH_NUMBER_OF_BYTES_USED BIGINT + ); REPEAT SET state = (SELECT PROCESSLIST_COMMAND FROM performance_schema.threads WHERE THREAD_ID=thd_id); UNTIL state = 'Query' END REPEAT; - SELECT 'Connection monitoring starting' AS 'Status'; - REPEAT SET state = (SELECT PROCESSLIST_COMMAND FROM performance_schema.threads WHERE THREAD_ID=thd_id); INSERT INTO monitoring_data @@ -82,19 +98,7 @@ export default class SqlMonitor { DO SLEEP(0.1); UNTIL state = 'Sleep' END REPEAT; - SELECT 'Connection monitoring ended' AS 'Status'; - SET stage_min_ts = (SELECT MIN(timer_start) FROM performance_schema.events_stages_history_long WHERE THREAD_ID=thd_id AND timer_start > stage_ignore_before); - SELECT stage_min_ts AS 'stage_min_ts', stage_ignore_before AS 'stage_ignore_before'; - SELECT - EVENT_NAME, - SOURCE, - timer_start, - timer_end, - (timer_start - stage_min_ts) / 1000000000000 AS start, - (timer_end - stage_min_ts) / 1000000000000 AS end - FROM performance_schema.events_stages_history_long - WHERE THREAD_ID = thd_id AND timer_start > stage_ignore_before ORDER BY timer_start; DROP TABLE IF EXISTS monitoring_stages; CREATE TABLE monitoring_stages AS @@ -110,6 +114,9 @@ export default class SqlMonitor { END`, this.session ); + } + + async monitorConnection(connectionID: string) { await runQuery(`call monitor_connection(${connectionID});`, this.session); } @@ -120,26 +127,17 @@ export default class SqlMonitor { ); const data = await runQuery( - `(SELECT - 'wall_clock', - 'relative time', - 'geom', - CAST('total' AS CHAR)) - UNION - (SELECT - TS AS the_ts, - UNIX_TIMESTAMP(TS) - @min_ts, - (SELECT - CURRENT_NUMBER_OF_BYTES_USED - FROM monitoring_data - WHERE EVENT_NAME='memory/sql/Geometry::ptr_and_wkb_data' AND TS=the_ts), - SUM(CURRENT_NUMBER_OF_BYTES_USED) - FROM monitoring_data - GROUP BY the_ts - );`, + `SELECT UNIX_TIMESTAMP(TS) - @min_ts, EVENT_NAME, CURRENT_NUMBER_OF_BYTES_USED FROM monitoring_data ORDER BY 1;`, this.session ); - console.log(data); return data; } + + async getStageTimes() { + const stageTimesRaw = await runQuery( + `select event_name, source, start, end from monitoring_stages;`, + this.session + ); + return stageTimesRaw; + } } diff --git a/backend/recorder/SqlRunner.ts b/backend/recorder/SqlRunner.ts index 10168c8e78f9ecbe51f3a57758e03670b0b61add..1f94564e0a95c48102b4125a28518df4a2cb6a15 100644 --- a/backend/recorder/SqlRunner.ts +++ b/backend/recorder/SqlRunner.ts @@ -1,10 +1,5 @@ import { URI, Session } from '@mysql/xdevapi'; -import { - createConnection, - createSession, - runQuery, - getOptimizerTrace, -} from '../utils/mysql'; +import { createConnection, createSession, runQuery } from '../utils/mysql'; export default class SqlRunner { session?: Session; @@ -23,14 +18,18 @@ export default class SqlRunner { } async executeQuery(query: string, explainAnalyze?: boolean) { - if (explainAnalyze) { + await runQuery('SET optimizer_trace="enabled=on";', this.session); + if (explainAnalyze && !query.toLowerCase().includes('explain analyze')) { const newQuery = `EXPLAIN ANALYZE ${query}`; return runQuery(newQuery, this.session); } return runQuery(query, this.session); } - async executeTraceQuery(query: string) { - return getOptimizerTrace(query, this.session); + async getOptimizerTrace() { + return runQuery( + 'SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;', + this.session + ); } } diff --git a/backend/utils/FileIO.ts b/backend/utils/FileIO.ts new file mode 100644 index 0000000000000000000000000000000000000000..7dfc66e3a28c05342c9bed78897c2e293fa34e9f --- /dev/null +++ b/backend/utils/FileIO.ts @@ -0,0 +1,26 @@ +import * as fs from 'fs'; +import { LoginDetails } from './LoginDetails'; + +// fs docs: https://nodejs.org/api/fs.html#fs_file_paths + +export default class FileIO { + static async saveLoginDetails(loginDetails: LoginDetails) { + const loginDetailsLocation = 'loginDetails.json'; + await fs.promises.writeFile( + loginDetailsLocation, + JSON.stringify(loginDetails, undefined, 2) + ); + } + + static async loadLoginDetails(): Promise<LoginDetails | undefined> { + const loginDetailsLocation = 'loginDetails.json'; + if (fs.existsSync(loginDetailsLocation)) { + const data = await fs.promises.readFile(loginDetailsLocation); + return JSON.parse(String(data)); + } + console.log(`${loginDetailsLocation} does not exist!`); + return undefined; + } +} + +// export default { saveLoginDetails, loadLoginDetails }; diff --git a/backend/utils/fileutils.ts b/backend/utils/fileutils.ts deleted file mode 100644 index c847e51e62b739e34e5153abb69f1597de7f5c05..0000000000000000000000000000000000000000 --- a/backend/utils/fileutils.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as fs from 'fs'; -import { LoginDetails } from './LoginDetails'; - -// fs docs: https://nodejs.org/api/fs.html#fs_file_paths - -export async function saveLoginDetails(loginDetails: LoginDetails) { - const loginDetailsLocation = 'loginDetails.json'; - await fs.promises.writeFile( - loginDetailsLocation, - JSON.stringify(loginDetails, undefined, 2) - ); -} - -export async function loadLoginDetails(): Promise<LoginDetails | undefined> { - const loginDetailsLocation = 'loginDetails.json'; - if (fs.existsSync(loginDetailsLocation)) { - const data = await fs.promises.readFile(loginDetailsLocation); - return JSON.parse(String(data)); - } - console.log(`${loginDetailsLocation} does not exist!`); - return undefined; -} - -// export default { saveLoginDetails, loadLoginDetails }; diff --git a/backend/utils/mysql.ts b/backend/utils/mysql.ts index d346c156fe78ffbad0f293800f72f716756e0e9a..79a45106b8040805e5efe117a5a77246a8b6033b 100644 --- a/backend/utils/mysql.ts +++ b/backend/utils/mysql.ts @@ -11,9 +11,32 @@ import mysqlx, { export interface Result { labels: Array<string>; + types: Array<number>; values: Array<Array<ResultValue>>; } +export type ColumnTypes = { + BIT: 1; + TINYINT: 2; + SMALLINT: 3; + MEDIUMINT: 4; + INT: 5; + BIGINT: 6; + FLOAT: 7; + DECIMAL: 8; + DOUBLE: 9; + JSON: 10; + STRING: 11; + BYTES: 12; + TIME: 13; + DATE: 14; + DATETIME: 15; + TIMESTAMP: 16; + SET: 17; + ENUM: 18; + GEOMETRY: 19; +}; + /** * Run a query using a Session * @param session (Session) @@ -25,22 +48,19 @@ export async function runQuery(query: string, session?: Session) { if (!session) throw new Error('No session was passed to runQuery'); const result = await session.sql(query).execute(); const columns = result.getColumns(); + const types = columns.map((column) => column.getType()); const fetchedResultSets = result.fetchAll(); const results: Result = { - labels: columns.map((value: Column) => { - return value.getColumnLabel(); - }), - values: fetchedResultSets.map((valueArray: Array<ResultValue>) => { - return valueArray.map((value: ResultValue) => value); - }), + labels: columns.map((value: Column) => value.getColumnLabel()), + types, + values: fetchedResultSets.map((valueArray: Array<ResultValue>) => + valueArray.map((value: ResultValue) => value) + ), }; - console.log( - `Result from query '${query}':\n${JSON.stringify(results, undefined, 2)}` - ); return { results, error: undefined }; } catch (error) { // TODO: Do more to handle errors - console.error(`Error while running query: ${error}`); + console.error(`Error while running query: ${error}\nQuery was: ${query}`); return { results: undefined, error }; } } @@ -67,23 +87,6 @@ export async function commit(session?: Session) { } } -/** - * Run a query using a Session and return its optimizer trace - * @param session (Session) - * @param query (string) - * @returns Object: Optimizer trace steps - */ -export async function getOptimizerTrace(query: string, session?: Session) { - await runQuery('SET optimizer_trace="enabled=on";', session); - const result = await runQuery(query, session); - const optimizerTrace = await runQuery( - 'SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;', - session - ); - await runQuery('SET optimizer_trace="enabled=on";', session); - return { result, trace: optimizerTrace }; -} - /** * Create a connection to a MySQL server and return a Client * @param connection (URI | string): Connection config or a connectionstring @@ -97,18 +100,19 @@ export async function createConnection( } ) { try { - if (!connection) + if (!connection) { throw new Error( 'No connection information was passed to createConnection' ); + } // Since this will only run locally, it's ok that the password is printed - console.log( - `Connecting with connectionstring: ${JSON.stringify( - connection, - undefined, - 2 - )}` - ); + // console.log( + // `Connecting with connectionstring: ${JSON.stringify( + // connection, + // undefined, + // 2 + // )}` + // ); return await mysqlx.getClient(connection, poolingOptions); } catch (error) { // TODO: Do more to handle errors @@ -124,17 +128,18 @@ export async function createConnection( * @returns Session */ export async function createSession(client?: Client, database?: string) { - try { - if (!client) throw new Error('No client was passed to createSession'); - const session = await client.getSession(); - if (database) runQuery(`USE ${database};`, session); - console.log(session.inspect()); - return session; - } catch (error) { - // TODO: Do more to handle errors - console.error(`Error while creating session: ${error}`); - throw error; + if (!client || !database) { + throw new Error( + 'Either client or database was not passed to createSession' + ); + } + const session = await client.getSession(); + if (database) { + const result = await runQuery(`USE ${database};`, session); + if (result.error) throw result.error; } + console.log(session.inspect()); + return session; } /** diff --git a/package.json b/package.json index 317db12e48c2922baf99085e55216f71a0439d05..d7cb1fce85f735472d4c1c2162de312c09442c8c 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,21 @@ { "name": "mysql-query-profiler", "productName": "MySQL Query Profiler", - "version": "0.0.1", "description": "A profiler for MySQL queries using Electron and React", + "repository": "https://gitlab.stud.idi.ntnu.no/erlenyd/mysql-query-profiler", + "homepage": "https://gitlab.stud.idi.ntnu.no/erlenyd/mysql-query-profiler", + "license": "MIT", + "author": { + "name": "Customer driven project group 4", + "email": "er.yd37@protonmail.com" + }, + "keywords": [ + "Electron", + "MySQL", + "Query profiler", + "Query", + "Profiler" + ], "scripts": { "build": "concurrently \"yarn build-main\" \"yarn build-renderer\"", "build-dll": "cross-env NODE_ENV=development webpack --config ./configs/webpack.config.renderer.dev.dll.babel.js --colors", @@ -16,11 +29,11 @@ "lint-styles": "stylelint --ignore-path .eslintignore '**/*.*(css|scss)' --syntax scss", "lint-styles-fix": "yarn --silent lint-styles --fix; exit 0", "package": "yarn build && electron-builder build --publish never", - "package-all": "yarn build && electron-builder build -mwl", + "package-all": "yarn build && electron-builder build -mwl --publish never", "package-ci": "yarn postinstall && yarn build && electron-builder --publish always", - "package-mac": "yarn build && electron-builder build --mac", - "package-linux": "yarn build && electron-builder build --linux", - "package-win": "yarn build && electron-builder build --win --x64", + "package-mac": "yarn build && electron-builder build --mac --publish never", + "package-linux": "yarn build && electron-builder build --linux --publish never", + "package-win": "yarn build && electron-builder build --win --x64 --publish never", "postinstall": "node -r @babel/register internals/scripts/CheckNativeDep.js && electron-builder install-app-deps && yarn build-dll && opencollective-postinstall", "postlint-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{js,jsx,json,html,css,less,scss,yml}'", "postlint-styles-fix": "prettier --ignore-path .eslintignore --single-quote --write '**/*.{css,scss}'", @@ -51,8 +64,8 @@ ] }, "build": { - "productName": "ElectronReact", - "appId": "org.develar.ElectronReact", + "productName": "MySQL Query Profiler", + "appId": "id.mysql.query.profiler", "files": [ "dist/", "node_modules/", @@ -61,31 +74,19 @@ "main.prod.js.map", "package.json" ], - "dmg": { - "contents": [ - { - "x": 130, - "y": 220 - }, - { - "x": 410, - "y": 220, - "type": "link", - "path": "/Applications" - } - ] + "mac": { + "target": "zip", + "category": "public.app-category.developer-tools" }, "win": { - "target": [ - "nsis", - "msi" - ] + "target": "nsis" }, "linux": { "target": [ "deb", "rpm", - "AppImage" + "AppImage", + "snap" ], "category": "Development" }, @@ -93,14 +94,8 @@ "buildResources": "resources", "output": "release" }, - "publish": { - "provider": "gitlab", - "owner": "mysql-query-profiler", - "repo": "mysql-query-profiler", - "private": false - } + "publish": [] }, - "license": "MIT", "jest": { "testURL": "http://localhost/", "moduleNameMapper": { @@ -147,6 +142,7 @@ "@babel/preset-react": "^7.10.4", "@babel/preset-typescript": "^7.10.4", "@babel/register": "^7.10.5", + "@types/electron-devtools-installer": "^2.2.0", "@types/enzyme": "^3.10.5", "@types/enzyme-adapter-react-16": "^1.0.6", "@types/history": "^4.7.6", @@ -155,12 +151,12 @@ "@types/node": "12", "@types/react": "^16.9.49", "@types/react-dom": "^16.9.8", - "@types/react-redux": "^7.1.9", + "@types/react-panelgroup": "^1.0.1", "@types/react-router": "^5.1.8", "@types/react-router-dom": "^5.1.5", "@types/react-test-renderer": "^16.9.2", "@types/recharts": "^1.8.15", - "@types/redux-logger": "^3.0.8", + "@types/regenerator-runtime": "^0.13.0", "@types/webpack": "^4.41.21", "@types/webpack-env": "^1.15.2", "@typescript-eslint/eslint-plugin": "^4.0.1", @@ -171,24 +167,21 @@ "babel-loader": "^8.1.0", "babel-plugin-dev-expression": "^0.2.2", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", - "browserslist-config-erb": "^0.0.1", "chalk": "^4.1.0", - "concurrently": "^5.2.0", "core-js": "^3.6.5", - "cross-env": "^7.0.0", + "cross-env": "^7.0.2", "css-loader": "^3.6.0", "detect-port": "^1.3.0", - "electron": "^8", + "electron": "^10", "electron-builder": "^22.3.6", - "electron-devtools-installer": "^2.2.4", + "electron-devtools-installer": "^3.1.1", "electron-rebuild": "^1.10.0", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.2", "enzyme-to-json": "^3.5.0", - "eslint": "^7.8.1", + "eslint": "^7.9.0", "eslint-config-airbnb": "^18.2.0", "eslint-config-airbnb-typescript": "^9.0.0", - "eslint-config-erb": "^1.0.0", "eslint-config-prettier": "^6.11.0", "eslint-import-resolver-webpack": "^0.12.2", "eslint-plugin-compat": "^3.8.0", @@ -210,7 +203,6 @@ "optimize-css-assets-webpack-plugin": "^5.0.3", "prettier": "^2.1.1", "react-test-renderer": "^16.12.0", - "redux-logger": "^3.0.6", "rimraf": "^3.0.0", "sass-loader": "^9.0.2", "style-loader": "^1.2.1", @@ -233,28 +225,25 @@ "yarn": "^1.22.5" }, "dependencies": { - "@fortawesome/fontawesome-free": "^5.14.0", "@hot-loader/react-dom": "^16.13.0", "@material-ui/core": "^4.11.0", + "@material-ui/lab": "^4.0.0-alpha.56", + "@material-ui/icons": "^4.9.1", "@mysql/xdevapi": "8.0.21", - "@reduxjs/toolkit": "^1.4.0", - "connected-react-router": "^6.6.1", - "electron-debug": "^3.1.0", - "electron-log": "^4.2.2", + "concurrently": "^5.3.0", + "electron-log": "^4.2.4", "electron-react-devtools": "^0.5.3", - "electron-updater": "^4.3.1", + "electron-updater": "^4.3.5", "history": "^4.7.2", "lodash": "^4.17.20", "react": "^16.13.1", "react-dom": "^16.12.0", "react-hot-loader": "^4.12.21", - "react-redux": "^7.2.0", + "react-json-view": "^1.19.1", + "react-panelgroup": "^1.0.12", "react-router-dom": "^5.2.0", - "react-textarea-autosize": "^8.2.0", "recharts": "^1.8.5", - "redux": "^4.0.5", - "redux-thunk": "^2.3.0", - "regenerator-runtime": "^0.13.5", + "regenerator-runtime": "^0.13.7", "source-map-support": "^0.5.19", "use-deep-compare-effect": "^1.4.0" }, @@ -263,10 +252,6 @@ "npm": ">=4.x", "yarn": ">=0.21.3" }, - "collective": { - "url": "https://opencollective.com/electron-react-boilerplate-594" - }, - "browserslist": [], "prettier": { "overrides": [ { @@ -298,5 +283,11 @@ "hooks": { "pre-commit": "lint-staged" } - } + }, + "browserslist": [ + "last 2 version", + "not IE 11", + "not op_mini all", + "not dead" + ] } diff --git a/publish-bintray.sh b/publish-bintray.sh new file mode 100644 index 0000000000000000000000000000000000000000..6e0052f17ed0fe02f8bee3e4db8359d9b7dc8fcb --- /dev/null +++ b/publish-bintray.sh @@ -0,0 +1,15 @@ +#! /bin/bash + +# Creating new version on Bintray +ticked_version=$(jq .version app/package.json) +version=${ticked_version//[\"]/} +desc=$(jq .description package.json) +# Uploading to Bintray +curl -v -T release/'MySQL Query Profiler'-${version}.AppImage -ukpro4:${BT_TOKEN} -H "X-Bintray-Package:mysql-query-profiler" -H "X-Bintray-Version:${version}" https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler-${version}.AppImage +curl -v -T release/mysql-query-profiler_${version}_amd64.deb -ukpro4:${BT_TOKEN} -H "X-Bintray-Package:mysql-query-profiler" -H "X-Bintray-Version:${version}" https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler-${version}.deb +curl -v -T release/mysql-query-profiler-${version}.x86_64.rpm -ukpro4:${BT_TOKEN} -H "X-Bintray-Package:mysql-query-profiler" -H "X-Bintray-Version:${version}" https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler-${version}.rpm +curl -v -T release/'MySQL Query Profiler Setup '${version}.exe -ukpro4:${BT_TOKEN} -H "X-Bintray-Package:mysql-query-profiler" -H "X-Bintray-Version:${version}" https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler-${version}.exe +curl -v -T release/'MySQL Query Profiler'-${version}-mac.zip -ukpro4:${BT_TOKEN} -H "X-Bintray-Package:mysql-query-profiler" -H "X-Bintray-Version:${version}" https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler-${version}-mac.zip +# Publishing the new version +curl -v -X POST -ukpro4:${BT_TOKEN} https://api.bintray.com/content/kpro4/mysql-query-profiler/mysql-query-profiler/${version}/publish + diff --git a/resources/icon.ico b/resources/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..15e5d78bb470d7236df9db38259c730560d1141d Binary files /dev/null and b/resources/icon.ico differ diff --git a/resources/icon.png b/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2c0f60050d903da7e723646396a896be9b90a9a8 Binary files /dev/null and b/resources/icon.png differ diff --git a/resources/icons/16x16.png b/resources/icons/16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..b2a9c915f2c8059368c8e6a4c14168756e886745 Binary files /dev/null and b/resources/icons/16x16.png differ diff --git a/resources/icons/32x32.png b/resources/icons/32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..2fca10cdbc0186242fbec8f6edbbdad44bc64f0f Binary files /dev/null and b/resources/icons/32x32.png differ diff --git a/resources/icons/48x48.png b/resources/icons/48x48.png new file mode 100644 index 0000000000000000000000000000000000000000..581a1367d311e6b6cdffe536b6f3936c1f956230 Binary files /dev/null and b/resources/icons/48x48.png differ diff --git a/resources/icons/512x512.png b/resources/icons/512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..6ff3ba1ecab12c8d4dbfb34dc88b3c6a7350ca27 Binary files /dev/null and b/resources/icons/512x512.png differ diff --git a/resources/icons/96x96.png b/resources/icons/96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..ecc2b8a558bf6dd2089bf90cc5c92ece116cd4ed Binary files /dev/null and b/resources/icons/96x96.png differ diff --git a/yarn.lock b/yarn.lock index 2ca3862b99b97a2ac4c7a1ba253388f032ef5218..d79c754ed012a760f7173780032ef7e955876933 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,11 +7,6 @@ resolved "https://registry.yarnpkg.com/7zip-bin/-/7zip-bin-5.0.3.tgz#bc5b5532ecafd923a61f2fb097e3b108c0106a3f" integrity sha512-GLyWIFBbGvpKPGo55JyRZAo4lVbnBiD52cKlw/0Vt+wnmKvWJkpZvsjVoaIolyBXDeAQKSicRtqFNPem9w0WYA== -"7zip@0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/7zip/-/7zip-0.0.6.tgz#9cafb171af82329490353b4816f03347aa150a30" - integrity sha1-nK+xca+CMpSQNTtIFvAzR6oVCjA= - "@amilajack/testcafe-browser-provider-electron@^0.0.15-alpha.1": version "0.0.15-alpha.1" resolved "https://registry.yarnpkg.com/@amilajack/testcafe-browser-provider-electron/-/testcafe-browser-provider-electron-0.0.15-alpha.1.tgz#506080ec623c1509fae489b13cb2a2894ec6fbb9" @@ -47,7 +42,29 @@ invariant "^2.2.4" semver "^5.5.0" -"@babel/core@>=7.9.0", "@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.7.5": +"@babel/core@>=7.9.0", "@babel/core@^7.11.1": + version "7.11.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651" + integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.6" + "@babel/helper-module-transforms" "^7.11.0" + "@babel/helpers" "^7.10.4" + "@babel/parser" "^7.11.5" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.11.5" + "@babel/types" "^7.11.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.19" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/core@^7.1.0", "@babel/core@^7.7.5": version "7.11.4" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.4.tgz#4301dfdfafa01eeb97f1896c5501a3f0655d4229" integrity sha512-5deljj5HlqRXN+5oJTY7Zs37iH3z3b++KjiKtIsJy1NrjOOVSEaJHEetLBhyu0aQOSNNZ/0IuEAan9GzRuDXHg== @@ -69,12 +86,12 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.11.0", "@babel/generator@^7.11.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.4.tgz#1ec7eec00defba5d6f83e50e3ee72ae2fee482be" - integrity sha512-Rn26vueFx0eOoz7iifCN2UHT6rGtnkSGWSoDRIy8jZN3B91PzeSULbswfLoOWuTuAcNwpG/mxy+uCTDnZ9Mp1g== +"@babel/generator@^7.11.0", "@babel/generator@^7.11.4", "@babel/generator@^7.11.5", "@babel/generator@^7.11.6": + version "7.11.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" + integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA== dependencies: - "@babel/types" "^7.11.0" + "@babel/types" "^7.11.5" jsesc "^2.5.1" source-map "^0.5.0" @@ -302,11 +319,16 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.4", "@babel/parser@^7.7.0": +"@babel/parser@^7.1.0", "@babel/parser@^7.7.0": version "7.11.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.4.tgz#6fa1a118b8b0d80d0267b719213dc947e88cc0ca" integrity sha512-MggwidiH+E9j5Sh8pbrX5sJvMcsqS5o+7iB42M9/k0CD63MjYbdP4nhSh7uB5wnv2/RVzTZFTxzF/kIa5mrCqA== +"@babel/parser@^7.10.4", "@babel/parser@^7.11.0", "@babel/parser@^7.11.4", "@babel/parser@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" + integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== + "@babel/plugin-proposal-async-generator-functions@^7.10.4": version "7.10.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" @@ -366,9 +388,9 @@ "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-proposal-function-bind@^7.10.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-function-bind/-/plugin-proposal-function-bind-7.10.5.tgz#62acbdde1c43e7dfae6efc9ddd5bc60920cee719" - integrity sha512-1lYbE2ynV9yN0LCEYCdEBD5pR6GaNkRfjn1z1tWDdWMJgunTFcJBZDJUgiMPcTMqAc3D6Vrm8v2khxjjx6FrCg== + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-function-bind/-/plugin-proposal-function-bind-7.11.5.tgz#6ce571686dd1bc2f5c1ae7bdebad8aaa7fda3893" + integrity sha512-gkCyUqJp6jRPdHFAYZxGal6d6Poj17G+6FGbyUcHKew2sccp5HVilTgnreYqTzDsY10Ys0ZVB/U2knTnnJdkUQ== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-function-bind" "^7.10.4" @@ -959,9 +981,9 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/preset-env@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.0.tgz#860ee38f2ce17ad60480c2021ba9689393efb796" - integrity sha512-2u1/k7rG/gTh02dylX2kL3S0IJNF+J6bfDSp4DI2Ma8QN6Y9x9pmAax59fsCk6QUQG0yqH47yJWA+u1I1LccAg== + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272" + integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA== dependencies: "@babel/compat-data" "^7.11.0" "@babel/helper-compilation-targets" "^7.10.4" @@ -1025,7 +1047,7 @@ "@babel/plugin-transform-unicode-escapes" "^7.10.4" "@babel/plugin-transform-unicode-regex" "^7.10.4" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.11.0" + "@babel/types" "^7.11.5" browserslist "^4.12.0" core-js-compat "^3.6.2" invariant "^2.2.2" @@ -1033,9 +1055,9 @@ semver "^5.5.0" "@babel/preset-modules@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" - integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== + version "0.1.4" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" + integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" @@ -1065,9 +1087,9 @@ "@babel/plugin-transform-typescript" "^7.10.4" "@babel/register@^7.10.5": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.10.5.tgz#354f3574895f1307f79efe37a51525e52fd38d89" - integrity sha512-eYHdLv43nyvmPn9bfNfrcC4+iYNwdQ8Pxk1MFJuU/U5LpSYl/PH4dFMazCYZDFVi8ueG3shvO+AQfLrxpYulQw== + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.11.5.tgz#79becf89e0ddd0fba8b92bc279bc0f5d2d7ce2ea" + integrity sha512-CAml0ioKX+kOAvBQDHa/+t1fgOt3qkTIz0TrRtRAT6XY0m5qYZXR85k6/sLCNPMGhYDlCFHCYuU0ybTJbvlC6w== dependencies: find-cache-dir "^2.0.0" lodash "^4.17.19" @@ -1099,7 +1121,7 @@ "@babel/parser" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.7.0": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.7.0": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.0.tgz#9b996ce1b98f53f7c3e4175115605d56ed07dd24" integrity sha512-ZB2V+LskoWKNpMq6E5UUCrjtDUh5IOTAyIl0dTjIEoXum/iKWkoIEKIRDnUucO6f+2FzNkE0oD4RLKoPIufDtg== @@ -1114,7 +1136,22 @@ globals "^11.1.0" lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": +"@babel/traverse@^7.10.4", "@babel/traverse@^7.11.0", "@babel/traverse@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" + integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.5" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/parser" "^7.11.5" + "@babel/types" "^7.11.5" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.19" + +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.7.0": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.0.tgz#2ae6bf1ba9ae8c3c43824e5861269871b206e90d" integrity sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA== @@ -1123,6 +1160,15 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.4.4": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" + integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -1181,11 +1227,6 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@fortawesome/fontawesome-free@^5.14.0": - version "5.14.0" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.14.0.tgz#a371e91029ebf265015e64f81bfbf7d228c9681f" - integrity sha512-OfdMsF+ZQgdKHP9jUbmDcRrP0eX90XXrsXIdyjLbkmSBzmMXPABB8eobUJtivaupucYaByz6WNe1PI1JuYm3qA== - "@hot-loader/react-dom@^16.13.0": version "16.13.0" resolved "https://registry.yarnpkg.com/@hot-loader/react-dom/-/react-dom-16.13.0.tgz#de245b42358110baf80aaf47a0592153d4047997" @@ -1411,6 +1452,24 @@ react-is "^16.8.0" react-transition-group "^4.4.0" +"@material-ui/icons@^4.9.1": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@material-ui/icons/-/icons-4.9.1.tgz#fdeadf8cb3d89208945b33dbc50c7c616d0bd665" + integrity sha512-GBitL3oBWO0hzBhvA9KxqcowRUsA0qzwKkURyC8nppnC3fw54KPKZ+d4V1Eeg/UnDRSzDaI9nGCdel/eh9AQMg== + dependencies: + "@babel/runtime" "^7.4.4" + +"@material-ui/lab@^4.0.0-alpha.56": + version "4.0.0-alpha.56" + resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.56.tgz#ff63080949b55b40625e056bbda05e130d216d34" + integrity sha512-xPlkK+z/6y/24ka4gVJgwPfoCF4RCh8dXb1BNE7MtF9bXEBLN/lBxNTK8VAa0qm3V2oinA6xtUIdcRh0aeRtVw== + dependencies: + "@babel/runtime" "^7.4.4" + "@material-ui/utils" "^4.10.2" + clsx "^1.0.4" + prop-types "^15.7.2" + react-is "^16.8.0" + "@material-ui/styles@^4.10.0": version "4.10.0" resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.10.0.tgz#2406dc23aa358217aa8cc772e6237bd7f0544071" @@ -1506,16 +1565,6 @@ dependencies: mkdirp "^1.0.4" -"@reduxjs/toolkit@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.4.0.tgz#ee2e2384cc3d1d76780d844b9c2da3580d32710d" - integrity sha512-hkxQwVx4BNVRsYdxjNF6cAseRmtrkpSlcgJRr3kLUcHPIAMZAmMJkXmHh/eUEGTMqPzsYpJLM7NN2w9fxQDuGw== - dependencies: - immer "^7.0.3" - redux "^4.0.0" - redux-thunk "^2.3.0" - reselect "^4.0.0" - "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -1535,7 +1584,7 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@stylelint/postcss-css-in-js@^0.37.1": +"@stylelint/postcss-css-in-js@^0.37.2": version "0.37.2" resolved "https://registry.yarnpkg.com/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.2.tgz#7e5a84ad181f4234a2480803422a47b8749af3d2" integrity sha512-nEhsFoJurt8oUmieT8qy4nk81WRHmJynmVwn/Vts08PL9fhgIsMhk1GId5yAN643OzqEEb5S/6At2TZW7pqPDA== @@ -1624,6 +1673,11 @@ resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ== +"@types/electron-devtools-installer@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@types/electron-devtools-installer/-/electron-devtools-installer-2.2.0.tgz#32ee4ebbe99b3daf9847a6d2097dc00b5de94f10" + integrity sha512-HJNxpaOXuykCK4rQ6FOMxAA0NLFYsf7FiPFGmab0iQmtVBHSAfxzy3MRFpLTTDDWbV0yD2YsHOQvdu8yCqtCfw== + "@types/enzyme-adapter-react-16@^1.0.6": version "1.0.6" resolved "https://registry.yarnpkg.com/@types/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.0.6.tgz#8aca7ae2fd6c7137d869b6616e696d21bb8b0cec" @@ -1631,7 +1685,7 @@ dependencies: "@types/enzyme" "*" -"@types/enzyme@*", "@types/enzyme@^3.10.5": +"@types/enzyme@*": version "3.10.5" resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.5.tgz#fe7eeba3550369eed20e7fb565bfb74eec44f1f0" integrity sha512-R+phe509UuUYy9Tk0YlSbipRpfVtIzb/9BHn5pTEtjJTF5LXvUjrIQcZvNyANNEyFrd2YGs196PniNT1fgvOQA== @@ -1639,6 +1693,14 @@ "@types/cheerio" "*" "@types/react" "*" +"@types/enzyme@^3.10.5": + version "3.10.6" + resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.6.tgz#a34a6b09ff732be29c194dc8d786555f4717fd85" + integrity sha512-Jxyn2U+UfhmrE7EaeZYfV1sPA5OEDuZmg9Lxj8TxOnfCn71flf0Cn1136LWdCVYj7yapLFmUWqKCcgplWNZCJg== + dependencies: + "@types/cheerio" "*" + "@types/react" "*" + "@types/error-stack-parser@^1.3.18": version "1.3.18" resolved "https://registry.yarnpkg.com/@types/error-stack-parser/-/error-stack-parser-1.3.18.tgz#e01c9f8c85ca83b610320c62258b0c9026ade0f7" @@ -1676,18 +1738,15 @@ dependencies: "@types/node" "*" -"@types/history@*", "@types/history@^4.7.6": +"@types/history@*": version "4.7.7" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.7.tgz#613957d900fab9ff84c8dfb24fa3eef0c2a40896" integrity sha512-2xtoL22/3Mv6a70i4+4RB7VgbDDORoWwjcqeNysojZA0R7NK17RbY5Gof/2QiFfJgX+KkWghbwJ+d/2SB8Ndzg== -"@types/hoist-non-react-statics@^3.3.0": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" - integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== - dependencies: - "@types/react" "*" - hoist-non-react-statics "^3.3.0" +"@types/history@^4.7.6": + version "4.7.8" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934" + integrity sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA== "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.3" @@ -1717,17 +1776,17 @@ "@types/istanbul-lib-report" "*" "@types/jest@^26.0.10": - version "26.0.10" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.10.tgz#8faf7e9756c033c39014ae76a7329efea00ea607" - integrity sha512-i2m0oyh8w/Lum7wWK/YOZJakYF8Mx08UaKA1CtbmFeDquVhAEdA7znacsVSf2hJ1OQ/OfVMGN90pw/AtzF8s/Q== + version "26.0.14" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.14.tgz#078695f8f65cb55c5a98450d65083b2b73e5a3f3" + integrity sha512-Hz5q8Vu0D288x3iWXePSn53W7hAjP0H7EQ6QvDO9c7t46mR0lNOLlfuwQ+JkVxuhygHzlzPX+0jKdA3ZgSh+Vg== dependencies: jest-diff "^25.2.1" pretty-format "^25.2.1" -"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" - integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== +"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" + integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== "@types/json5@^0.0.29": version "0.0.29" @@ -1735,9 +1794,9 @@ integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/lodash@^4.14.72": - version "4.14.160" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.160.tgz#2f1bba6500bc3cb9a732c6d66a083378fb0b0b29" - integrity sha512-aP03BShJoO+WVndoVj/WNcB/YBPt+CIU1mvaao2GRAHy2yg4pT/XS4XnVHEQBjPJGycWf/9seKEO9vopTJGkvA== + version "4.14.161" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.161.tgz#a21ca0777dabc6e4f44f3d07f37b765f54188b18" + integrity sha512-EP6O3Jkr7bXvZZSZYlsgt5DIjiGr0dXP1/jVEwVLTFgg0d+3lWVQkRavYVQszV7dYUwvg0B8R0MBDpcmXg7XIA== "@types/minimatch@*": version "3.0.3" @@ -1757,20 +1816,25 @@ "@types/node" "*" "@types/node@*": - version "14.6.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.0.tgz#7d4411bf5157339337d7cff864d9ff45f177b499" - integrity sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA== + version "14.11.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.1.tgz#56af902ad157e763f9ba63d671c39cda3193c835" + integrity sha512-oTQgnd0hblfLsJ6BvJzzSL+Inogp3lq9fGgqRkMB/ziKMgEUaFl801OncOzUmalfzt14N0oPHMK47ipl+wbTIw== + +"@types/node@12": + version "12.12.62" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.62.tgz#733923d73669188d35950253dd18a21570085d2b" + integrity sha512-qAfo81CsD7yQIM9mVyh6B/U47li5g7cfpVQEDMfQeF8pSZVwzbhwU3crc0qG4DmpsebpJPR49AKOExQyJ05Cpg== -"@types/node@12", "@types/node@^12.0.12": +"@types/node@^10.12.19": + version "10.17.35" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.35.tgz#58058f29b870e6ae57b20e4f6e928f02b7129f56" + integrity sha512-gXx7jAWpMddu0f7a+L+txMplp3FnHl53OhQIF9puXKq3hDGY/GjH+MF04oWnV/adPSCrbtHumDCFwzq2VhltWA== + +"@types/node@^12.0.12": version "12.12.54" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.54.tgz#a4b58d8df3a4677b6c08bfbc94b7ad7a7a5f82d1" integrity sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w== -"@types/node@^10.12.19": - version "10.17.28" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.28.tgz#0e36d718a29355ee51cec83b42d921299200f6d9" - integrity sha512-dzjES1Egb4c1a89C7lKwQh8pwjYmlOAG9dW1pBgxEk57tMrLnssOfEthz8kdkNaBd7lIqQx7APm5+mZ619IiCQ== - "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" @@ -1803,15 +1867,12 @@ dependencies: "@types/react" "*" -"@types/react-redux@^7.1.9": - version "7.1.9" - resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.9.tgz#280c13565c9f13ceb727ec21e767abe0e9b4aec3" - integrity sha512-mpC0jqxhP4mhmOl3P4ipRsgTgbNofMRXJb08Ms6gekViLj61v1hOZEKWDCyWsdONr6EjEA6ZHXC446wdywDe0w== +"@types/react-panelgroup@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/react-panelgroup/-/react-panelgroup-1.0.1.tgz#c25bf7d2a7c41323ef3744b191f128093675d9e5" + integrity sha512-dIeK8YQcS3yEyXhdsd8YpMK16ttWvrah2xQRiy6atqGmm6yPyHpvpzx4HldGWRJhsSjDWnl/6HHLaUV19dUo7w== dependencies: - "@types/hoist-non-react-statics" "^3.3.0" "@types/react" "*" - hoist-non-react-statics "^3.3.0" - redux "^4.0.0" "@types/react-router-dom@^5.1.5": version "5.1.5" @@ -1844,15 +1905,7 @@ dependencies: "@types/react" "*" -"@types/react@*": - version "16.9.47" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.47.tgz#fb092936f0b56425f874d0ff1b08051fdf70c1ba" - integrity sha512-dAJO4VbrjYqTUwFiQqAKjLyHHl4RSTNnRyPdX3p16MPbDKvow51wxATUPxoe2QsiXNMEYrOjc2S6s92VjG+1VQ== - dependencies: - "@types/prop-types" "*" - csstype "^3.0.2" - -"@types/react@^16.9.49": +"@types/react@*", "@types/react@^16.9.49": version "16.9.49" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.49.tgz#09db021cf8089aba0cdb12a49f8021a69cce4872" integrity sha512-DtLFjSj0OYAdVLBbyjhuV9CdGVHCkHn2R+xr3XkBvK2rS1Y1tkc14XSGjYgm5Fjjr90AxH9tiSzc1pCFMGO06g== @@ -1868,17 +1921,15 @@ "@types/d3-shape" "*" "@types/react" "*" -"@types/redux-logger@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@types/redux-logger/-/redux-logger-3.0.8.tgz#1fb6d26917bb198792bb1cf57feb31cae1532c5d" - integrity sha512-zM+cxiSw6nZtRbxpVp9SE3x/X77Z7e7YAfHD1NkxJyJbAGSXJGF0E9aqajZfPOa/sTYnuwutmlCldveExuCeLw== - dependencies: - redux "^4.0.0" +"@types/regenerator-runtime@^0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@types/regenerator-runtime/-/regenerator-runtime-0.13.0.tgz#8b81e6047da0fbb71927c23d749e2a9edf9aad9b" + integrity sha512-U5osy6qZU3lOPGQRHGDIAt/hC/jAE7zP4Aq258UMXnF8/htmZ+72ALrSsmWTtqML7lCztKkKaPz6Pb5XHJF0Vw== "@types/semver@^7.3.1": - version "7.3.3" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.3.tgz#3ad6ed949e7487e7bda6f886b4a2434a2c3d7b1a" - integrity sha512-jQxClWFzv9IXdLdhSaTf16XI3NYe6zrEbckSpb5xhKfPbWgIyAY0AFyWWWfaiDcBuj3UHmMkCIwSRqpKMTZL2Q== + version "7.3.4" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb" + integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ== "@types/source-list-map@*": version "0.1.2" @@ -1915,9 +1966,9 @@ "@types/react" "*" "@types/webpack-env@^1.15.2": - version "1.15.2" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.2.tgz#927997342bb9f4a5185a86e6579a0a18afc33b0a" - integrity sha512-67ZgZpAlhIICIdfQrB5fnDvaKFcDxpKibxznfYRVAT4mQE41Dido/3Ty+E3xGBmTogc5+0Qb8tWhna+5B8z1iQ== + version "1.15.3" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.3.tgz#fb602cd4c2f0b7c0fb857e922075fdf677d25d84" + integrity sha512-5oiXqR7kwDGZ6+gmzIO2lTC+QsriNuQXZDWNYRV3l2XRN/zmPgnC21DLSx2D05zvD8vnXW6qUg7JnXZ4I6qLVQ== "@types/webpack-sources@*": version "1.4.2" @@ -1929,9 +1980,9 @@ source-map "^0.7.3" "@types/webpack@^4.41.21": - version "4.41.21" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.21.tgz#cc685b332c33f153bb2f5fc1fa3ac8adeb592dee" - integrity sha512-2j9WVnNrr/8PLAB5csW44xzQSJwS26aOnICsP3pSGCEdsu6KYtfQ6QJsVUKHWRnm1bL7HziJsfh5fHqth87yKA== + version "4.41.22" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.22.tgz#ff9758a17c6bd499e459b91e78539848c32d0731" + integrity sha512-JQDJK6pj8OMV9gWOnN1dcLCyU9Hzs6lux0wBO4lr1+gyEhIBR9U3FMrz12t2GPkg110XAxEAw2WHF6g7nZIbRQ== dependencies: "@types/anymatch" "*" "@types/node" "*" @@ -1953,12 +2004,12 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.0.1.tgz#88bde9239e29d688315718552cf80a3490491017" - integrity sha512-pQZtXupCn11O4AwpYVUX4PDFfmIJl90ZgrEBg0CEcqlwvPiG0uY81fimr1oMFblZnpKAq6prrT9a59pj1x58rw== + version "4.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.1.1.tgz#78d5b18e259b13c2f4ec41dd9105af269a161a75" + integrity sha512-Hoxyt99EA9LMmqo/5PuWWPeWeB3mKyvibfJ1Hy5SfiUpjE8Nqp+5QNd9fOkzL66+fqvIWSIE+Ett16LGMzCGnQ== dependencies: - "@typescript-eslint/experimental-utils" "4.0.1" - "@typescript-eslint/scope-manager" "4.0.1" + "@typescript-eslint/experimental-utils" "4.1.1" + "@typescript-eslint/scope-manager" "4.1.1" debug "^4.1.1" functional-red-black-tree "^1.0.1" regexpp "^3.0.0" @@ -1976,15 +2027,15 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/experimental-utils@4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.0.1.tgz#7d9a3ab6821ad5274dad2186c1aa0d93afd696eb" - integrity sha512-gAqOjLiHoED79iYTt3F4uSHrYmg/GPz/zGezdB0jAdr6S6gwNiR/j7cTZ8nREKVzMVKLd9G3xbg1sV9GClW3sw== +"@typescript-eslint/experimental-utils@4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.1.1.tgz#52ff4e37c93113eb96385a4e6d075abece1ea72d" + integrity sha512-jzYsNciHoa4Z3c1URtmeT/bamYm8Dwfw6vuN3WHIE/BXb1iC4KveAnXDErTAZtPVxTYBaYn3n2gbt6F6D2rm1A== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.0.1" - "@typescript-eslint/types" "4.0.1" - "@typescript-eslint/typescript-estree" "4.0.1" + "@typescript-eslint/scope-manager" "4.1.1" + "@typescript-eslint/types" "4.1.1" + "@typescript-eslint/typescript-estree" "4.1.1" eslint-scope "^5.0.0" eslint-utils "^2.0.0" @@ -2010,32 +2061,32 @@ eslint-visitor-keys "^1.1.0" "@typescript-eslint/parser@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.0.1.tgz#73772080db7a7a4534a35d719e006f503e664dc3" - integrity sha512-1+qLmXHNAWSQ7RB6fdSQszAiA7JTwzakj5cNYjBTUmpH2cqilxMZEIV+DRKjVZs8NzP3ALmKexB0w/ExjcK9Iw== + version "4.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.1.1.tgz#324b4b35e314075adbc92bd8330cf3ef0c88cf3e" + integrity sha512-NLIhmicpKGfJbdXyQBz9j48PA6hq6e+SDOoXy7Ak6bq1ebGqbgG+fR1UIDAuay6OjQdot69c/URu2uLlsP8GQQ== dependencies: - "@typescript-eslint/scope-manager" "4.0.1" - "@typescript-eslint/types" "4.0.1" - "@typescript-eslint/typescript-estree" "4.0.1" + "@typescript-eslint/scope-manager" "4.1.1" + "@typescript-eslint/types" "4.1.1" + "@typescript-eslint/typescript-estree" "4.1.1" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.0.1.tgz#24d93c3000bdfcc5a157dc4d32b742405a8631b5" - integrity sha512-u3YEXVJ8jsj7QCJk3om0Y457fy2euEOkkzxIB/LKU3MdyI+FJ2gI0M4aKEaXzwCSfNDiZ13a3lDo5DVozc+XLQ== +"@typescript-eslint/scope-manager@4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.1.1.tgz#bdb8526e82435f32b4ccd9dd4cec01af97b48850" + integrity sha512-0W8TTobCvIIQ2FsrYTffyZGAAFUyIbEHq5EYJb1m7Rpd005jrnOvKOo8ywCLhs/Bm17C+KsrUboBvBAARQVvyA== dependencies: - "@typescript-eslint/types" "4.0.1" - "@typescript-eslint/visitor-keys" "4.0.1" + "@typescript-eslint/types" "4.1.1" + "@typescript-eslint/visitor-keys" "4.1.1" "@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.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.0.1.tgz#1cf72582f764931f085cb8230ff215980fe467b2" - integrity sha512-S+gD3fgbkZYW2rnbjugNMqibm9HpEjqZBZkTiI3PwbbNGWmAcxolWIUwZ0SKeG4Dy2ktpKKaI/6+HGYVH8Qrlg== +"@typescript-eslint/types@4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.1.1.tgz#57500c4a86b28cb47094c1a62f1177ea279a09cb" + integrity sha512-zrBiqOKYerMTllKcn+BP+i1b7LW/EbMMYytroXMxUTvFPn1smkCu0D7lSAx29fTUO4jnwV0ljSvYQtn2vNrNxA== "@typescript-eslint/typescript-estree@2.34.0": version "2.34.0" @@ -2064,13 +2115,13 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/typescript-estree@4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.0.1.tgz#29a43c7060641ec51c902d9f50ac7c5866ec479f" - integrity sha512-zGzleORFXrRWRJAMLTB2iJD1IZbCPkg4hsI8mGdpYlKaqzvKYSEWVAYh14eauaR+qIoZVWrXgYSXqLtTlxotiw== +"@typescript-eslint/typescript-estree@4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.1.tgz#2015a84d71303ecdb6f46efd807ac19a51aab490" + integrity sha512-2AUg5v0liVBsqbGxBphbJ0QbGqSRVaF5qPoTPWcxop+66vMdU1h4CCvHxTC47+Qb+Pr4l2RhXDd41JNpwcQEKw== dependencies: - "@typescript-eslint/types" "4.0.1" - "@typescript-eslint/visitor-keys" "4.0.1" + "@typescript-eslint/types" "4.1.1" + "@typescript-eslint/visitor-keys" "4.1.1" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" @@ -2085,12 +2136,12 @@ dependencies: eslint-visitor-keys "^1.1.0" -"@typescript-eslint/visitor-keys@4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.0.1.tgz#d4e8de62775f2a6db71c7e8539633680039fdd6c" - integrity sha512-yBSqd6FjnTzbg5RUy9J+9kJEyQjTI34JdGMJz+9ttlJzLCnGkBikxw+N5n2VDcc3CesbIEJ0MnZc5uRYnrEnCw== +"@typescript-eslint/visitor-keys@4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.1.tgz#bb05664bf4bea28dc120d1da94f3027d42ab0f6f" + integrity sha512-/EOOXbA2ferGLG6RmCHEQ0lTTLkOlXYDgblCmQk3tIU7mTPLm4gKhFMeeUSe+bcchTUsKeCk8xcpbop5Zr/8Rw== dependencies: - "@typescript-eslint/types" "4.0.1" + "@typescript-eslint/types" "4.1.1" eslint-visitor-keys "^2.0.0" "@webassemblyjs/ast@1.9.0": @@ -2282,9 +2333,9 @@ acorn-hammerhead@^0.3.0: "@types/estree" "^0.0.39" acorn-jsx@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" - integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== + version "5.3.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" + integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== acorn-walk@^7.1.1: version "7.2.0" @@ -2339,12 +2390,22 @@ ajv-errors@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4: +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.2, ajv@^6.12.4: + version "6.12.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" + integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^6.12.3: version "6.12.4" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234" integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ== @@ -2454,26 +2515,26 @@ anymatch@^3.0.3, anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -app-builder-bin@3.5.9: - version "3.5.9" - resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.9.tgz#a3ac0c25286bac68357321cb2eaf7128b0bc0a4f" - integrity sha512-NSjtqZ3x2kYiDp3Qezsgukx/AUzKPr3Xgf9by4cYt05ILWGAptepeeu0Uv+7MO+41o6ujhLixTou8979JGg2Kg== +app-builder-bin@3.5.10: + version "3.5.10" + resolved "https://registry.yarnpkg.com/app-builder-bin/-/app-builder-bin-3.5.10.tgz#4a7f9999fccc0c435b6284ae1366bc76a17c4a7d" + integrity sha512-Jd+GW68lR0NeetgZDo47PdWBEPdnD+p0jEa7XaxjRC8u6Oo/wgJsfKUkORRgr2NpkD19IFKN50P6JYy04XHFLQ== -app-builder-lib@22.8.0: - version "22.8.0" - resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.8.0.tgz#342a8976f50ae35cfd07412dbfd4f6c895b32eac" - integrity sha512-RGaIRjCUrqkmh6QOGsyekQPEOaVynHfmeh8JZuyUymFYUOFdzBbPamkA2nhBVBTkkgfjRHsxK7LhedFKPzvWEQ== +app-builder-lib@22.8.1: + version "22.8.1" + resolved "https://registry.yarnpkg.com/app-builder-lib/-/app-builder-lib-22.8.1.tgz#02cd14c0a83d3a758675d28c327731832b2c0bc1" + integrity sha512-D/ac1+vuGIAAwEeTtXl8b+qWl7Gz/IQatFyzYl2ocag/7N8LqUjKzZFJJISQPWt6PFDPDH0oCj8/GMh63aV0yw== dependencies: "7zip-bin" "~5.0.3" "@develar/schema-utils" "~2.6.5" async-exit-hook "^2.0.1" bluebird-lst "^1.0.9" - builder-util "22.8.0" + builder-util "22.8.1" builder-util-runtime "8.7.2" chromium-pickle-js "^0.2.0" - debug "^4.1.1" + debug "^4.2.0" ejs "^3.1.3" - electron-publish "22.8.0" + electron-publish "22.8.1" fs-extra "^9.0.1" hosted-git-info "^3.0.5" is-ci "^2.0.0" @@ -2616,6 +2677,11 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + asar@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/asar/-/asar-2.1.0.tgz#97c6a570408c4e38a18d4a3fb748a621b5a7844e" @@ -2743,7 +2809,7 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@^9.8.0: +autoprefixer@^9.8.6: version "9.8.6" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" integrity sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg== @@ -3602,6 +3668,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= +base16@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70" + integrity sha1-4pf2DX7BAUp6lxo568ipjAtoHnA= + base64-js@^1.0.2, base64-js@^1.1.2: version "1.3.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" @@ -3740,9 +3811,9 @@ bowser@1.6.0: integrity sha1-N/w4e2Fstq7zcNq01r1AK3TFxU0= bowser@^2.8.1: - version "2.10.0" - resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.10.0.tgz#be3736f161c4bb8b10958027ab99465d2a811198" - integrity sha512-OCsqTQboTEWWsUjcp5jLSw2ZHsBiv2C105iFs61bOT0Hnwi9p7/uuXdd7mu8RYcarREfdjNN+8LitmEHATsLYg== + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== boxen@^4.2.0: version "4.2.0" @@ -3867,11 +3938,6 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist-config-erb@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/browserslist-config-erb/-/browserslist-config-erb-0.0.1.tgz#0a93648bbe11fac5b9fe555bf061f31980db64db" - integrity sha512-QQQzCXrYVVdSWxO0UuV+f2HGBt7xdGRRvgr49W1lcwoyXNpRQFVi5cTz8+B/rLHyBkWd4JbRFeTIKHAw7BpCBg== - browserslist@^3.2.6: version "3.2.8" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" @@ -3880,7 +3946,17 @@ browserslist@^3.2.6: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.12.2, browserslist@^4.8.5: +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.8.5: + version "4.14.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.3.tgz#381f9e7f13794b2eb17e1761b4f118e8ae665a53" + integrity sha512-GcZPC5+YqyPO4SFnz48/B0YaCwS47Q9iPChRGi6t7HhflKBcINzFrJvRfC+jp30sRMKxF+d4EHGs27Z0XP1NaQ== + dependencies: + caniuse-lite "^1.0.30001131" + electron-to-chromium "^1.3.570" + escalade "^3.1.0" + node-releases "^1.1.61" + +browserslist@^4.12.2: version "4.14.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.0.tgz#2908951abfe4ec98737b72f34c3bcedc8d43b000" integrity sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ== @@ -3934,19 +4010,19 @@ builder-util-runtime@8.7.2: debug "^4.1.1" sax "^1.2.4" -builder-util@22.8.0: - version "22.8.0" - resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.8.0.tgz#01684085d1f2370b1bd182f69cbd007426f63f64" - integrity sha512-H80P1JzVy3TGpi63x81epQDK24XalL034+jAZlrPb5IhLtYmnNNdxCCAVJvg3VjSISd73Y71O+uhqCxWpqbPHw== +builder-util@22.8.1: + version "22.8.1" + resolved "https://registry.yarnpkg.com/builder-util/-/builder-util-22.8.1.tgz#efdfb327dbc22c59aa1e2f55adbe0e771086e839" + integrity sha512-LZG+E1xszMdut5hL5h7RkJQ7yOsQqdhJYgn1wvOP7MmF3MoUPRNDiRodLpYiWlaqZmgYhcfaipR/Mb8F/RqK8w== dependencies: "7zip-bin" "~5.0.3" "@types/debug" "^4.1.5" "@types/fs-extra" "^9.0.1" - app-builder-bin "3.5.9" + app-builder-bin "3.5.10" bluebird-lst "^1.0.9" builder-util-runtime "8.7.2" chalk "^4.1.0" - debug "^4.1.1" + debug "^4.2.0" fs-extra "^9.0.1" is-ci "^2.0.0" js-yaml "^3.14.0" @@ -4123,10 +4199,10 @@ caniuse-db@^1.0.30001090: resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001118.tgz#60f56de236d7b68859d9a377a7f2f69092283247" integrity sha512-yMoV0unAwrdNkqKbNI4jlyUHrLsBYrzf9IOYTNxhy3t1onqpLK2nH0IPHzr2isrmmY8pQ6UPqFGka/8Gc8Yt9w== -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111: - version "1.0.30001118" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001118.tgz#116a9a670e5264aec895207f5e918129174c6f62" - integrity sha512-RNKPLojZo74a0cP7jFMidQI7nvLER40HgNfgKQEJ2PFm225L0ectUungNQoK3Xk3StQcFbpBPNEvoWD59436Hg== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001111, caniuse-lite@^1.0.30001131: + version "1.0.30001132" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001132.tgz#309279274f10d3aa736aa91fa269fcc8d0cd7ef9" + integrity sha512-zk5FXbnsmHa0Ktc/NOZJRr+ilXva+2KFJuRiQfnjkxJfV/7DYP5C27lSQF++/veCUzVWE5xecZnSBJjf6fSwJA== capture-exit@^2.0.0: version "2.0.0" @@ -4351,9 +4427,9 @@ clean-stack@^2.0.0: integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== cli-boxes@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d" - integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w== + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== cli-cursor@^2.1.0: version "2.1.0" @@ -4548,9 +4624,9 @@ commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, commander@^2.8.1: integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commander@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.0.0.tgz#2b270da94f8fb9014455312f829a1129dbf8887e" - integrity sha512-s7EA+hDtTYNhuXkTlhqew4txMZVdszBmKWSPEMxGr8ru8JXR7bLUFIAtPhcSuFdJQ0ILMxnJi8GkQL0yvDy/YA== + version "6.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.1.0.tgz#f8d722b78103141006b66f4c7ba1e97315ba75bc" + integrity sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA== commondir@^1.0.1: version "1.0.1" @@ -4602,7 +4678,7 @@ concat-stream@^1.5.0, concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" -concurrently@^5.2.0: +concurrently@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-5.3.0.tgz#7500de6410d043c912b2da27de3202cb489b1e7b" integrity sha512-8MhqOB6PWlBfA2vJ8a0bSFKATOdWlHiQlk11IfmQBPaHVP8oP2gsh2MObE6UR3hqDHqvaIvLTyceNW6obVuFHQ== @@ -4647,13 +4723,6 @@ connect-history-api-fallback@^1.6.0: resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== -connected-react-router@^6.6.1: - version "6.8.0" - resolved "https://registry.yarnpkg.com/connected-react-router/-/connected-react-router-6.8.0.tgz#ddc687b31d498322445d235d660798489fa56cae" - integrity sha512-E64/6krdJM3Ag3MMmh2nKPtMbH15s3JQDuaYJvOVXzu6MbHbDyIvuwLOyhQIuP4Om9zqEfZYiVyflROibSsONg== - dependencies: - prop-types "^15.7.2" - console-browserify@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" @@ -4763,17 +4832,6 @@ cosmiconfig@^5.0.0: js-yaml "^3.13.1" parse-json "^4.0.0" -cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.7.2" - cosmiconfig@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3" @@ -4816,7 +4874,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" -cross-env@^7.0.0: +cross-env@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw== @@ -4843,11 +4901,6 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" -cross-unzip@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/cross-unzip/-/cross-unzip-0.0.2.tgz#5183bc47a09559befcf98cc4657964999359372f" - integrity sha1-UYO8R6CVWb78+YzEZXlkmZNZNy8= - crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -5178,9 +5231,9 @@ data-urls@^2.0.0: whatwg-url "^8.0.0" date-fns@^2.0.1: - version "2.15.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.15.0.tgz#424de6b3778e4e69d3ff27046ec136af58ae5d5f" - integrity sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ== + version "2.16.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.16.1.tgz#05775792c3f3331da812af253e1a935851d3834b" + integrity sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ== debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.5.1, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" @@ -5189,7 +5242,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.5.1, debug@^2.6.0, debug@^2.6. dependencies: ms "2.0.0" -debug@4.1.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: +debug@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -5203,6 +5256,13 @@ debug@^3.1.1, debug@^3.2.5: dependencies: ms "^2.1.1" +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" + integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== + dependencies: + ms "2.1.2" + decamelize-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" @@ -5253,11 +5313,6 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= -deep-diff@^0.3.5: - version "0.3.8" - resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84" - integrity sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ= - deep-eql@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" @@ -5312,7 +5367,7 @@ defer-to-connect@^1.0.1: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== -define-properties@^1.1.2, define-properties@^1.1.3: +define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -5496,13 +5551,13 @@ discontinuous-range@1.0.0: resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo= -dmg-builder@22.8.0: - version "22.8.0" - resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.8.0.tgz#2b17127837ed444db3086317eda5cf8912f6e6a9" - integrity sha512-orePWjcrl97SYLA8F/6UUtbXJSoZCYu5KOP1lVqD4LOomr8bjGDyEVYZmZYcg5WqKmXucdmO6OpqgzH/aRMMuA== +dmg-builder@22.8.1: + version "22.8.1" + resolved "https://registry.yarnpkg.com/dmg-builder/-/dmg-builder-22.8.1.tgz#9b3bcbbc43e5fed232525d61a5567ea4b66085c3" + integrity sha512-WeGom1moM00gBII6swljl4DQGrlJuEivoUhOmh8U9p1ALgeJL+EiTHbZFERlj8Ejy62xUUjURV+liOxUKmJFWg== dependencies: - app-builder-lib "22.8.0" - builder-util "22.8.0" + app-builder-lib "22.8.1" + builder-util "22.8.1" fs-extra "^9.0.1" iconv-lite "^0.6.2" js-yaml "^3.14.0" @@ -5597,9 +5652,9 @@ domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== domelementtype@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" - integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + version "2.0.2" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.2.tgz#f3b6e549201e46f588b59463dd77187131fe6971" + integrity sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA== domexception@^2.0.1: version "2.0.1" @@ -5632,9 +5687,9 @@ domutils@^1.5.1, domutils@^1.7.0: domelementtype "1" dot-prop@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" - integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A== + version "5.3.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== dependencies: is-obj "^2.0.0" @@ -5699,76 +5754,47 @@ ejs@^3.1.3: jake "^10.6.1" electron-builder@^22.3.6: - version "22.8.0" - resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.8.0.tgz#d2c9fc5438c834e41fd794a271fca200165a3bad" - integrity sha512-dUv4F3srJouqxhWivtKqSoQP4Df6vYgjooGdzms+iYMTFi9f0b4LlEbr7kgsPvte8zAglee7VOGOODkCRJDkUQ== + version "22.8.1" + resolved "https://registry.yarnpkg.com/electron-builder/-/electron-builder-22.8.1.tgz#84295190dae17b3892df7aa39ac334983aeaea06" + integrity sha512-Hs7KTMq1rGSvT0fwGKXrjbLiJkK6sAKDQooUSwklOkktUgWi4ATjlP0fVE3l8SmS7zcLoww2yDZonSDqxEFhaQ== dependencies: "@types/yargs" "^15.0.5" - app-builder-lib "22.8.0" + app-builder-lib "22.8.1" bluebird-lst "^1.0.9" - builder-util "22.8.0" + builder-util "22.8.1" builder-util-runtime "8.7.2" chalk "^4.1.0" - dmg-builder "22.8.0" + dmg-builder "22.8.1" fs-extra "^9.0.1" is-ci "^2.0.0" lazy-val "^1.0.4" read-config-file "6.0.0" sanitize-filename "^1.6.3" update-notifier "^4.1.0" - yargs "^15.3.1" - -electron-debug@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/electron-debug/-/electron-debug-3.1.0.tgz#0df17297487fa3c82344d810812853bf67f0bd69" - integrity sha512-SWEqLj4MgfV3tGuO5eBLQ5/Nr6M+KPxsnE0bUJZvQebGJus6RAcdmvd7L+l0Ji31h2mmrN23l2tHFtCa2FvurA== - dependencies: - electron-is-dev "^1.1.0" - electron-localshortcut "^3.1.0" - -electron-devtools-installer@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/electron-devtools-installer/-/electron-devtools-installer-2.2.4.tgz#261a50337e37121d338b966f07922eb4939a8763" - integrity sha512-b5kcM3hmUqn64+RUcHjjr8ZMpHS2WJ5YO0pnG9+P/RTdx46of/JrEjuciHWux6pE+On6ynWhHJF53j/EDJN0PA== - dependencies: - "7zip" "0.0.6" - cross-unzip "0.0.2" - rimraf "^2.5.2" - semver "^5.3.0" - -electron-is-accelerator@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz#509e510c26a56b55e17f863a4b04e111846ab27b" - integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns= - -electron-is-dev@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-1.2.0.tgz#2e5cea0a1b3ccf1c86f577cee77363ef55deb05e" - integrity sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw== + yargs "^15.4.1" -electron-localshortcut@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/electron-localshortcut/-/electron-localshortcut-3.2.1.tgz#cfc83a3eff5e28faf98ddcc87f80a2ce4f623cd3" - integrity sha512-DWvhKv36GsdXKnaFFhEiK8kZZA+24/yFLgtTwJJHc7AFgDjNRIBJZ/jq62Y/dWv9E4ypYwrVWN2bVrCYw1uv7Q== +electron-devtools-installer@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/electron-devtools-installer/-/electron-devtools-installer-3.1.1.tgz#7b56c8c86475c5e4e10de6917d150c53c9ceb55e" + integrity sha512-g2D4J6APbpsiIcnLkFMyKZ6bOpEJ0Ltcc2m66F7oKUymyGAt628OWeU9nRZoh1cNmUs/a6Cls2UfOmsZtE496Q== dependencies: - debug "^4.0.1" - electron-is-accelerator "^0.1.0" - keyboardevent-from-electron-accelerator "^2.0.0" - keyboardevents-areequal "^0.2.1" + rimraf "^3.0.2" + semver "^7.2.1" + unzip-crx-3 "^0.2.0" -electron-log@^4.2.2: +electron-log@^4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/electron-log/-/electron-log-4.2.4.tgz#a13e42a9fc42ca2cc7d2603c3746352efa82112e" integrity sha512-CXbDU+Iwi+TjKzugKZmTRIORIPe3uQRqgChUl19fkW/reFUn5WP7dt+cNGT3bkLV8xfPilpkPFv33HgtmLLewQ== -electron-publish@22.8.0: - version "22.8.0" - resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.8.0.tgz#7f410fe043abc5d3d896c4ee9eea7a43ea352c7d" - integrity sha512-uM0Zdi9hUqqGOrPj478v7toTvV1Kgto1w11rIiI168batiXAJvNLD8VZRfehOrZT0ibUyZlw8FtxoGCrjyHUOw== +electron-publish@22.8.1: + version "22.8.1" + resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-22.8.1.tgz#747e0d7f921cd1808f999713d29f599dbb390c4f" + integrity sha512-zqI66vl7j1CJZJ60J+1ez1tQNQeuqVspW44JvYDa5kZbM5wSFDAJFMK9RWHOqRF1Ezd4LDeiBa4aeTOwOt9syA== dependencies: "@types/fs-extra" "^9.0.1" bluebird-lst "^1.0.9" - builder-util "22.8.0" + builder-util "22.8.1" builder-util-runtime "8.7.2" chalk "^4.1.0" fs-extra "^9.0.1" @@ -5795,15 +5821,15 @@ electron-rebuild@^1.10.0: spawn-rx "^3.0.0" yargs "^14.2.0" -electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.523: - version "1.3.548" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.548.tgz#b1bda6b24f7a1c1fa6250bb039a0bbed148f26f2" - integrity sha512-Xf4m3GFwCEcQ+4W45IHeZ6enPC1i+8/3aaXz8Pcd2VkNLULP0DMvoP7aKv2tQ+M/CH2SC7Qlm4S6DpzZUS2w1Q== +electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.523, electron-to-chromium@^1.3.570: + version "1.3.570" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.570.tgz#3f5141cc39b4e3892a276b4889980dabf1d29c7f" + integrity sha512-Y6OCoVQgFQBP5py6A/06+yWxUZHDlNr/gNDGatjH8AZqXl8X0tE4LfjLJsXGz/JmWJz8a6K7bR1k+QzZ+k//fg== -electron-updater@^4.3.1: - version "4.3.4" - resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.4.tgz#6003f88be9004d7834e4dd757167033d0fc2d29a" - integrity sha512-ekpgxDrYl+Wi24ktO4qfj2CtCABxrmK1C/oekp0tai6q4VR4ZdPkit4CX8+GenvKMme7uMmfPFnLp/vwhP/ThQ== +electron-updater@^4.3.5: + version "4.3.5" + resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.5.tgz#4fb36f593a031c87ea07ee141c9f064d5deffb15" + integrity sha512-5jjN7ebvfj1cLI0VZMdCnJk6aC4bP+dy7ryBf21vArR0JzpRVk0OZHA2QBD+H5rm6ZSeDYHOY6+8PrMEqJ4wlQ== dependencies: "@types/semver" "^7.3.1" builder-util-runtime "8.7.2" @@ -5813,10 +5839,10 @@ electron-updater@^4.3.1: lodash.isequal "^4.5.0" semver "^7.3.2" -electron@^8: - version "8.5.0" - resolved "https://registry.yarnpkg.com/electron/-/electron-8.5.0.tgz#a202738672214775fda27450b00ee516a66bffc4" - integrity sha512-ERqSTRlaQ4PqME5a1z9DWQbwQy2LbgSN1Jnau1MJCRRvHgq1FJlqbbb/ij/RGWuQuaxy4Djb2KnTs5rsemR5mQ== +electron@^10: + version "10.1.2" + resolved "https://registry.yarnpkg.com/electron/-/electron-10.1.2.tgz#30b6fd7669f8daf08c56219a61dfa053fa2b0c70" + integrity sha512-SvN8DcKCmPZ0UcQSNAJBfaUu+LGACqtRhUn1rW0UBLHgdbbDM76L0GU5/XGQEllH5pu5bwlCZwax3srzIl+Aeg== dependencies: "@electron/get" "^1.0.1" "@types/node" "^12.0.12" @@ -5880,6 +5906,13 @@ encodeurl@^1.0.2, encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +encoding@^0.1.11: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -5936,9 +5969,9 @@ env-paths@^2.2.0: integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== enzyme-adapter-react-16@^1.15.2: - version "1.15.3" - resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.3.tgz#90154055be3318d70a51df61ac89cfa22e3d5f60" - integrity sha512-98rqNI4n9HZslWIPuuwy4hK1bxRuMy+XX0CU1dS8iUqcgisTxeBaap6oPp2r4MWC8OphCbbqAT8EU/xHz3zIaQ== + version "1.15.4" + resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.4.tgz#328a782365a363ecb424f99283c4833dd92c0f21" + integrity sha512-wPzxs+JaGDK2TPYzl5a9YWGce6i2SQ3Cg51ScLeyj2WotUZ8Obcq1ke/U1Y2VGpYlb9rrX2yCjzSMgtKCeAt5w== dependencies: enzyme-adapter-utils "^1.13.1" enzyme-shallow-equal "^1.0.4" @@ -6076,10 +6109,10 @@ es6-error@^4.1.1: resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== -escalade@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.2.tgz#6a580d70edb87880f22b4c91d0d56078df6962c4" - integrity sha512-gPYAU37hYCUhW5euPeR+Y74F7BL+IBsV93j5cvGriSaD1aG6MGsqsV1yamRdrWrb2j3aiZvb0X+UBOWpx3JWtQ== +escalade@^3.0.2, escalade@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e" + integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig== escape-goat@^2.0.0: version "2.1.1" @@ -6145,13 +6178,6 @@ eslint-config-airbnb@^18.2.0: object.assign "^4.1.0" object.entries "^1.1.2" -eslint-config-erb@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-erb/-/eslint-config-erb-1.0.0.tgz#f6dd13de09e3ed805b30576a6f20532e0753bf72" - integrity sha512-UvmtvjCxaPkYzmpDLYDjmvAxoTggpW+NWYT/Dq4QkfMPqx1nAooU+YU3QsTFrme3x3xp8fj1n3cvimO1kwxb1g== - dependencies: - babel-eslint "^10.1.0" - eslint-config-prettier@^6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz#f6d2238c1290d01c859a8b5c1f7d352a0b0da8b1" @@ -6261,9 +6287,9 @@ eslint-plugin-promise@^4.2.1: integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== eslint-plugin-react-hooks@^4.0.8: - version "4.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.1.0.tgz#6323fbd5e650e84b2987ba76370523a60f4e7925" - integrity sha512-36zilUcDwDReiORXmcmTc6rRumu9JIM3WjSvV0nclHoUQ0CNrX866EwONvLR/UqaeqFutbAnVu8PEmctdo2SRQ== + version "4.1.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.1.2.tgz#2eb53731d11c95826ef7a7272303eabb5c9a271e" + integrity sha512-ykUeqkGyUGgwTtk78C0o8UG2fzwmgJ0qxBGPp2WqRKsTwcLuVf01kTDRAtOsd4u6whX2XOC8749n2vPydP82fg== eslint-plugin-react@^7.20.3: version "7.20.6" @@ -6296,11 +6322,11 @@ eslint-scope@^4.0.3: estraverse "^4.1.1" eslint-scope@^5.0.0, eslint-scope@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" - integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: - esrecurse "^4.1.0" + esrecurse "^4.3.0" estraverse "^4.1.1" eslint-utils@^2.0.0, eslint-utils@^2.1.0: @@ -6320,10 +6346,10 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@^7.8.1: - version "7.8.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.8.1.tgz#e59de3573fb6a5be8ff526c791571646d124a8fa" - integrity sha512-/2rX2pfhyUG0y+A123d0ccXtMm7DV7sH1m3lk9nk2DZ2LReq39FXHueR9xZwshE5MdfSf0xunSaMWRqyIA6M1w== +eslint@^7.9.0: + version "7.9.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.9.0.tgz#522aeccc5c3a19017cf0cb46ebfd660a79acf337" + integrity sha512-V6QyhX21+uXp4T+3nrNfI3hQNBDa/P8ga7LoQOenwrlEFXrEnUEE+ok1dMtaS3b6rmLXhT1TkTIsG75HMLbknA== dependencies: "@babel/code-frame" "^7.0.0" "@eslint/eslintrc" "^0.1.3" @@ -6363,10 +6389,10 @@ eslint@^7.8.1: text-table "^0.2.0" v8-compile-cache "^2.0.3" -esotope-hammerhead@0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/esotope-hammerhead/-/esotope-hammerhead-0.5.5.tgz#dccae8ffe588238c3c3db9b78df45fe95add498a" - integrity sha512-EuSYJDtF8gLMB24lzjHw2KotauPsVJybFrtGfQyMm48oC7sTkspA26DqcqcbnRl4GC6sPVKWEx+ex72eqopX9Q== +esotope-hammerhead@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/esotope-hammerhead/-/esotope-hammerhead-0.5.6.tgz#f846638bc10adf068642decdf54b9a9ac856ccfb" + integrity sha512-E5cJKuecAEt/psafJ8rBjAezBS5/5iqyzgzRPH2JWEhZYTRzkphX9c9djqpJj8Zcfv7PpqgNgXXbaqxgCIVsPw== dependencies: "@types/estree" "^0.0.39" @@ -6391,19 +6417,19 @@ esquery@^1.2.0: dependencies: estraverse "^5.1.0" -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== +esrecurse@^4.1.0, esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: - estraverse "^4.1.0" + estraverse "^5.2.0" -estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.1.0: +estraverse@^5.1.0, estraverse@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== @@ -6653,7 +6679,7 @@ fast-glob@^2.2.6: merge2 "^1.2.3" micromatch "^3.1.10" -fast-glob@^3.0.3, fast-glob@^3.1.1: +fast-glob@^3.0.3, fast-glob@^3.1.1, fast-glob@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== @@ -6675,6 +6701,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fastest-levenshtein@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" + integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== + fastq@^1.6.0: version "1.8.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" @@ -6703,6 +6734,26 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fbemitter@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-2.1.1.tgz#523e14fdaf5248805bb02f62efc33be703f51865" + integrity sha1-Uj4U/a9SSIBbsC9i78M75wP1GGU= + dependencies: + fbjs "^0.8.4" + +fbjs@^0.8.0, fbjs@^0.8.4: + version "0.8.17" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" + integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.18" + fd-slicer@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" @@ -6730,12 +6781,12 @@ file-entry-cache@^5.0.1: flat-cache "^2.0.1" file-loader@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f" - integrity sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ== + version "6.1.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.1.0.tgz#65b9fcfb0ea7f65a234a1f10cdd7f1ab9a33f253" + integrity sha512-26qPdHyTsArQ6gU4P1HJbAbnFTyT2r0pG7czh1GFAd9TZbj0n94wWbupgixZH/ET/meqi2/5+F7DhW4OAXD+Lg== dependencies: loader-utils "^2.0.0" - schema-utils "^2.6.5" + schema-utils "^2.7.1" file-uri-to-path@1.0.0: version "1.0.0" @@ -6876,6 +6927,14 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +flux@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/flux/-/flux-3.1.3.tgz#d23bed515a79a22d933ab53ab4ada19d05b2f08a" + integrity sha1-0jvtUVp5oi2TOrU6tK2hnQWy8Io= + dependencies: + fbemitter "^2.0.0" + fbjs "^0.8.0" + follow-redirects@^1.0.0: version "1.13.0" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" @@ -7380,7 +7439,7 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.0, has-symbols@^1.0.1: +has-symbols@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== @@ -7676,14 +7735,14 @@ human-signals@^1.1.1: integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== husky@^4.2.5: - version "4.2.5" - resolved "https://registry.yarnpkg.com/husky/-/husky-4.2.5.tgz#2b4f7622673a71579f901d9885ed448394b5fa36" - integrity sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/husky/-/husky-4.3.0.tgz#0b2ec1d66424e9219d359e26a51c58ec5278f0de" + integrity sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA== dependencies: chalk "^4.0.0" ci-info "^2.0.0" compare-versions "^3.6.0" - cosmiconfig "^6.0.0" + cosmiconfig "^7.0.0" find-versions "^3.2.0" opencollective-postinstall "^2.0.2" pkg-dir "^4.2.0" @@ -7751,10 +7810,10 @@ ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== -immer@^7.0.3: - version "7.0.8" - resolved "https://registry.yarnpkg.com/immer/-/immer-7.0.8.tgz#41dcbc5669a76500d017bef3ad0d03ce0a1d7c1e" - integrity sha512-XnpIN8PXBBaOD43U8Z17qg6RQiKQYGDGGCIbz1ixmLGwBkSWwmrmx5X7d+hTtXDM8ur7m5OdLE0PiO+y5RB3pw== +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= import-fresh@^2.0.0: version "2.0.0" @@ -7764,7 +7823,7 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: +import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== @@ -7990,7 +8049,12 @@ is-buffer@^2.0.0: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== -is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.0: +is-callable@^1.1.4, is-callable@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.1.tgz#4d1e21a4f437509d25ce55f8184350771421c96d" + integrity sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg== + +is-callable@^1.1.5: version "1.2.0" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== @@ -8300,7 +8364,7 @@ is-resolvable@^1.0.0: resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== -is-stream@^1.1.0: +is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= @@ -8408,6 +8472,14 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -8942,9 +9014,9 @@ json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== json-parse-even-better-errors@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.0.tgz#371873c5ffa44304a6ba12419bcfa95f404ae081" - integrity sha512-o3aP+RsWDJZayj1SbHNQAI8x0v3T3SKiGoZlNYfbUP1S3omJQ6i9CnqADqkSPaOAxwua4/1YWx5CM7oiChJt2Q== + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-schema-traverse@^0.4.1: version "0.4.1" @@ -9094,15 +9166,15 @@ jsx-ast-utils@^2.4.1: array-includes "^3.1.1" object.assign "^4.1.0" -keyboardevent-from-electron-accelerator@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-2.0.0.tgz#ace21b1aa4e47148815d160057f9edb66567c50c" - integrity sha512-iQcmNA0M4ETMNi0kG/q0h/43wZk7rMeKYrXP7sqKIJbHkTU8Koowgzv+ieR/vWJbOwxx5nDC3UnudZ0aLSu4VA== - -keyboardevents-areequal@^0.2.1: - version "0.2.2" - resolved "https://registry.yarnpkg.com/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz#88191ec738ce9f7591c25e9056de928b40277194" - integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw== +jszip@^3.1.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.5.0.tgz#b4fd1f368245346658e781fec9675802489e15f6" + integrity sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA== + dependencies: + lie "~3.3.0" + pako "~1.0.2" + readable-stream "~2.3.6" + set-immediate-shim "~1.0.1" keyv@^3.0.0: version "3.1.0" @@ -9215,15 +9287,22 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lie@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" + integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ== + dependencies: + immediate "~3.0.5" + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= lint-staged@^10.2.11: - version "10.2.13" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.2.13.tgz#b9c504683470edfc464b7d3fe3845a5a1efcd814" - integrity sha512-conwlukNV6aL9SiMWjFtDp5exeDnTMekdNPDZsKGnpfQuHcO0E3L3Bbf58lcR+M7vk6LpCilxDAVks/DDVBYlA== + version "10.4.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.4.0.tgz#d18628f737328e0bbbf87d183f4020930e9a984e" + integrity sha512-uaiX4U5yERUSiIEQc329vhCTDDwUcSvKdRLsNomkYLRzijk3v8V9GWm2Nz0RMVB87VcuzLvtgy6OsjoH++QHIg== dependencies: chalk "^4.1.0" cli-truncate "^2.1.0" @@ -9249,9 +9328,9 @@ linux-platform-info@^0.0.3: os-family "^1.0.0" listr2@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/listr2/-/listr2-2.6.0.tgz#788a3d202978a1b8582062952cbc49272c8e206a" - integrity sha512-nwmqTJYQQ+AsKb4fCXH/6/UmLCEDL1jkRAdSn9M6cEUzoRGrs33YD/3N86gAZQnGZ6hxV18XSdlBcJ1GTmetJA== + version "2.6.2" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-2.6.2.tgz#4912eb01e1e2dd72ec37f3895a56bf2622d6f36a" + integrity sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA== dependencies: chalk "^4.1.0" cli-truncate "^2.1.0" @@ -9333,6 +9412,11 @@ lodash.assign@^4.2.0: resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= +lodash.curry@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170" + integrity sha1-JI42By7ekGUB11lmIAqG2riyMXA= + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -9348,6 +9432,11 @@ lodash.flattendeep@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= +lodash.flow@^3.3.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a" + integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o= + lodash.isequal@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" @@ -9607,10 +9696,10 @@ memory-fs@^0.5.0: errno "^0.1.3" readable-stream "^2.0.1" -meow@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-7.1.0.tgz#50ecbcdafa16f8b58fb7eb9675b933f6473b3a59" - integrity sha512-kq5F0KVteskZ3JdfyQFivJEj2RaA8NFsS4+r9DaMKLcUHpk5OcHS3Q0XkCXONB1mZRPsu/Y/qImKri0nwSEZog== +meow@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-7.1.1.tgz#7c01595e3d337fcb0ec4e8eed1666ea95903d306" + integrity sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA== dependencies: "@types/minimist" "^1.2.0" camelcase-keys "^6.2.2" @@ -9887,9 +9976,9 @@ moment-duration-format-commonjs@^1.0.0: integrity sha512-MVFR4hIh4jfuwSCPBEE5CCwn3refvTsxK/Yv/DpKJ6YcNnCimlVJ6DQeTJG1KVQPw1o8m3tkbHE9gVjivyv9iA== moment@^2.10.3, moment@^2.14.1: - version "2.27.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d" - integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ== + version "2.28.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.28.0.tgz#cdfe73ce01327cee6537b0fafac2e0f21a237d75" + integrity sha512-Z5KOjYmnHyd/ukynmFd/WwyXHd7L4J9vTI/nn5Ap9AVUgaAE15VvQ9MOGmJJygEUklupqIrFnor/tjTwRU+tQw== moo@^0.5.0: version "0.5.1" @@ -9918,7 +10007,7 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@^2.1.1: +ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -9946,11 +10035,6 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== -nanoid@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-0.2.2.tgz#e2ebc6ad3db5e0454fd8124d30ca39b06555fe56" - integrity sha512-GHoRrvNEKiwdkwQ/enKL8AhQkkrBC/2KxMZkDvQzp8OtkpX8ZAmoYJWFVl7l8F2+HcEJUfdg21Ab2wXXfrvACQ== - nanoid@^1.0.1: version "1.3.4" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-1.3.4.tgz#ad89f62c9d1f4fd69710d4a90953d2893d2d31f4" @@ -9961,6 +10045,11 @@ nanoid@^2.1.3: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280" integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA== +nanoid@^3.1.12: + version "3.1.12" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.12.tgz#6f7736c62e8d39421601e4a0c77623a97ea69654" + integrity sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -10016,6 +10105,14 @@ node-abi@^2.11.0: dependencies: semver "^5.4.1" +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" @@ -10098,10 +10195,10 @@ node-notifier@^8.0.0: uuid "^8.3.0" which "^2.0.2" -node-releases@^1.1.60: - version "1.1.60" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084" - integrity sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA== +node-releases@^1.1.60, node-releases@^1.1.61: + version "1.1.61" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.61.tgz#707b0fca9ce4e11783612ba4a2fcba09047af16e" + integrity sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g== node-version@^1.0.0: version "1.2.0" @@ -10254,7 +10351,7 @@ object-is@^1.0.1, object-is@^1.0.2, object-is@^1.1.2: define-properties "^1.1.3" es-abstract "^1.17.5" -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -10267,14 +10364,14 @@ object-visit@^1.0.0: isobject "^3.0.0" object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + version "4.1.1" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd" + integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA== dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.0" + has-symbols "^1.0.1" + object-keys "^1.1.1" object.entries@^1.1.1, object.entries@^1.1.2: version "1.1.2" @@ -10364,9 +10461,9 @@ opencollective-postinstall@^2.0.2, opencollective-postinstall@^2.0.3: integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== opener@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" - integrity sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA== + version "1.5.2" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" + integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== opn@^5.5.0: version "5.5.0" @@ -10376,9 +10473,9 @@ opn@^5.5.0: is-wsl "^1.1.0" optimize-css-assets-webpack-plugin@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz#e2f1d4d94ad8c0af8967ebd7cf138dcb1ef14572" - integrity sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA== + version "5.0.4" + resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.4.tgz#85883c6528aaa02e30bbad9908c92926bb52dc90" + integrity sha512-wqd6FdI2a5/FdoiCNNkEvLeA//lHHfG24Ln2Xm2qqdIk4aOlsR18jwpyOihqQ8849W3qu2DX8fOYxpvTMj+93A== dependencies: cssnano "^4.1.10" last-call-webpack-plugin "^3.0.0" @@ -10567,7 +10664,7 @@ package-json@^6.3.0: registry-url "^5.0.0" semver "^6.2.0" -pako@~1.0.5: +pako@~1.0.2, pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== @@ -10814,16 +10911,16 @@ pinkie-promise@^2.0.0: dependencies: pinkie "^2.0.0" -pinkie@1.0.0, pinkie@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4" - integrity sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q= - -pinkie@^2.0.0, pinkie@^2.0.1, pinkie@^2.0.4: +pinkie@2.0.4, pinkie@^2.0.0, pinkie@^2.0.1, pinkie@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= +pinkie@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4" + integrity sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q= + pirates@^4.0.0, pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" @@ -10884,9 +10981,9 @@ posix-character-classes@^0.1.0: integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= postcss-calc@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.3.tgz#d65cca92a3c52bf27ad37a5f732e0587b74f1623" - integrity sha512-IB/EAEmZhIMEIhG7Ov4x+l47UaXOS1n2f4FBUk/aKllQhtSCxWhTzn0nJgkqN7fo/jcWySvWTSB6Syk9L+31bA== + version "7.0.4" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-7.0.4.tgz#5e177ddb417341e6d4a193c5d9fd8ada79094f8b" + integrity sha512-0I79VRAd1UTkaHzY9w83P39YGO/M3bG7/tNLrHGEunBolfoGM0hSjrGvjoeaj0JE/zIw5GsI2KZ0UwDJqv5hjw== dependencies: postcss "^7.0.27" postcss-selector-parser "^6.0.2" @@ -11163,16 +11260,6 @@ postcss-reduce-transforms@^4.0.2: postcss "^7.0.0" postcss-value-parser "^3.0.0" -postcss-reporter@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-reporter/-/postcss-reporter-6.0.1.tgz#7c055120060a97c8837b4e48215661aafb74245f" - integrity sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw== - dependencies: - chalk "^2.4.1" - lodash "^4.17.11" - log-symbols "^2.2.0" - postcss "^7.0.7" - postcss-resolve-nested-selector@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz#29ccbc7c37dedfac304e9fff0bf1596b3f6a0e4e" @@ -11252,7 +11339,16 @@ postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7: +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21, postcss@^7.0.26, postcss@^7.0.27, postcss@^7.0.32, postcss@^7.0.6: + version "7.0.34" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.34.tgz#f2baf57c36010df7de4009940f21532c16d65c20" + integrity sha512-H/7V2VeNScX9KE83GDrDZNiGT1m2H+UTnlinIzhjlLX9hfMUn1mHNnGeX81a1c8JSBdBvqk7c2ZOG6ZPn5itGw== + dependencies: + chalk "^2.4.2" + source-map "^0.6.1" + supports-color "^6.1.0" + +postcss@^7.0.5: version "7.0.32" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== @@ -11289,9 +11385,9 @@ prettier-linter-helpers@^1.0.0: fast-diff "^1.1.2" prettier@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.1.tgz#d9485dd5e499daa6cb547023b87a6cf51bee37d6" - integrity sha512-9bY+5ZWCfqj3ghYBLxApy2zf6m+NJo5GzmLTpr9FsApsfjriNnS2dahWReHMi7qNPhhHl9SYHJs2cHZLgexNIw== + version "2.1.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.1.2.tgz#3050700dae2e4c8b67c4c3f666cdb8af405e1ce5" + integrity sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg== pretty-format@^25.2.1, pretty-format@^25.5.0: version "25.5.0" @@ -11338,6 +11434,13 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + promisify-event@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/promisify-event/-/promisify-event-1.0.0.tgz#bd7523ea06b70162f370979016b53a686c60e90f" @@ -11462,6 +11565,11 @@ pupa@^2.0.1: dependencies: escape-goat "^2.0.0" +pure-color@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" + integrity sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4= + q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -11570,6 +11678,16 @@ rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-base16-styling@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c" + integrity sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw= + dependencies: + base16 "^1.0.0" + lodash.curry "^4.0.1" + lodash.flow "^3.3.0" + pure-color "^1.2.0" + react-dom@^16.12.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" @@ -11594,26 +11712,32 @@ react-hot-loader@^4.12.21: shallowequal "^1.1.0" source-map "^0.7.3" -react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.6, react-is@^16.9.0: +react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.6: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-json-view@^1.19.1: + version "1.19.1" + resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.19.1.tgz#95d8e59e024f08a25e5dc8f076ae304eed97cf5c" + integrity sha512-u5e0XDLIs9Rj43vWkKvwL8G3JzvXSl6etuS5G42a8klMohZuYFQzSN6ri+/GiBptDqlrXPTdExJVU7x9rrlXhg== + dependencies: + flux "^3.1.3" + react-base16-styling "^0.6.0" + react-lifecycles-compat "^3.0.4" + react-textarea-autosize "^6.1.0" + react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== -react-redux@^7.2.0: - version "7.2.1" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.1.tgz#8dedf784901014db2feca1ab633864dee68ad985" - integrity sha512-T+VfD/bvgGTUA74iW9d2i5THrDQWbweXP0AVNI8tNd1Rk5ch1rnMiJkDD67ejw7YBKM4+REvcvqRuWJb7BLuEg== +react-panelgroup@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/react-panelgroup/-/react-panelgroup-1.0.12.tgz#e19c2d9d1fa4fbe504cdac9255eebc1c569c08f4" + integrity sha512-DuA+6TnxLK1TmlQqijYCbzvEVZYS3i6SyG9xqk7SW/S4pzzIxQ73lkSHLkMBG55/iOvGQEL/uH3Y96btk6mPDw== dependencies: - "@babel/runtime" "^7.5.5" - hoist-non-react-statics "^3.3.0" - loose-envify "^1.4.0" - prop-types "^15.7.2" - react-is "^16.9.0" + prop-types "^15.6.1" react-resize-detector@^2.3.0: version "2.3.0" @@ -11674,14 +11798,12 @@ react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0: react-is "^16.8.6" scheduler "^0.19.1" -react-textarea-autosize@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.2.0.tgz#fae38653f5ec172a855fd5fffb39e466d56aebdb" - integrity sha512-grajUlVbkx6VdtSxCgzloUIphIZF5bKr21OYMceWPKkniy7H0mRAT/AXPrRtObAe+zUePnNlBwUc4ivVjUGIjw== +react-textarea-autosize@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-6.1.0.tgz#df91387f8a8f22020b77e3833c09829d706a09a5" + integrity sha512-F6bI1dgib6fSvG8so1HuArPUv+iVEfPliuLWusLF+gAKz0FbB4jLrWUrTAeq1afnPT2c9toEZYUdz/y1uKMy4A== dependencies: - "@babel/runtime" "^7.10.2" - use-composed-ref "^1.0.0" - use-latest "^1.0.0" + prop-types "^15.6.0" react-transition-group@^2.5.0: version "2.9.0" @@ -11861,26 +11983,6 @@ reduce-function-call@^1.0.1: dependencies: balanced-match "^1.0.0" -redux-logger@^3.0.6: - version "3.0.6" - resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf" - integrity sha1-91VZZvMJjzyIYExEnPC69XeCdL8= - dependencies: - deep-diff "^0.3.5" - -redux-thunk@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" - integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== - -redux@^4.0.0, redux@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" - integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== - dependencies: - loose-envify "^1.4.0" - symbol-observable "^1.2.0" - reflect.ownkeys@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460" @@ -11903,7 +12005,7 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== -regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.5: +regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== @@ -11955,9 +12057,9 @@ regexpu-core@^2.0.0: regjsparser "^0.1.4" regexpu-core@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.0.tgz#fcbf458c50431b0bb7b45d6967b8192d91f3d938" - integrity sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ== + version "4.7.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" + integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== dependencies: regenerate "^1.4.0" regenerate-unicode-properties "^8.2.0" @@ -12151,11 +12253,6 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= -reselect@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" - integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== - resize-observer-polyfill@^1.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" @@ -12287,7 +12384,7 @@ rimraf@2.6.3: dependencies: glob "^7.1.3" -rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.3: +rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -12346,13 +12443,20 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rxjs@^6.3.1, rxjs@^6.5.2, rxjs@^6.6.2: +rxjs@^6.3.1: version "6.6.2" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.2.tgz#8096a7ac03f2cc4fe5860ef6e572810d9e01c0d2" integrity sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg== dependencies: tslib "^1.9.0" +rxjs@^6.5.2, rxjs@^6.6.2: + version "6.6.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.3.tgz#8ca84635c4daa900c0d3967a6ee7ac60271ee552" + integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== + dependencies: + tslib "^1.9.0" + safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -12437,7 +12541,16 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: +schema-utils@^2.6.5, schema-utils@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +schema-utils@^2.6.6, schema-utils@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== @@ -12561,6 +12674,11 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= +set-immediate-shim@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E= + set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" @@ -12571,7 +12689,7 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" -setimmediate@^1.0.4: +setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= @@ -12854,9 +12972,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== + version "3.0.6" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz#c80757383c28abf7296744998cbc106ae8b854ce" + integrity sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw== spdy-transport@^3.0.0: version "3.0.0" @@ -13245,18 +13363,20 @@ stylelint-config-standard@^20.0.0: stylelint-config-recommended "^3.0.0" stylelint@^13.6.1: - version "13.6.1" - resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.6.1.tgz#cc1d76338116d55e8ff2be94c4a4386c1239b878" - integrity sha512-XyvKyNE7eyrqkuZ85Citd/Uv3ljGiuYHC6UiztTR6sWS9rza8j3UeQv/eGcQS9NZz/imiC4GKdk1EVL3wst5vw== + version "13.7.1" + resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-13.7.1.tgz#bee97ee78d778a3f1dbe3f7397b76414973e263e" + integrity sha512-qzqazcyRxrSRdmFuO0/SZOJ+LyCxYy0pwcvaOBBnl8/2VfHSMrtNIE+AnyJoyq6uKb+mt+hlgmVrvVi6G6XHfQ== dependencies: - "@stylelint/postcss-css-in-js" "^0.37.1" + "@stylelint/postcss-css-in-js" "^0.37.2" "@stylelint/postcss-markdown" "^0.36.1" - autoprefixer "^9.8.0" + autoprefixer "^9.8.6" balanced-match "^1.0.0" chalk "^4.1.0" - cosmiconfig "^6.0.0" + cosmiconfig "^7.0.0" debug "^4.1.1" execall "^2.0.0" + fast-glob "^3.2.4" + fastest-levenshtein "^1.0.12" file-entry-cache "^5.0.1" get-stdin "^8.0.0" global-modules "^2.0.0" @@ -13267,18 +13387,16 @@ stylelint@^13.6.1: import-lazy "^4.0.0" imurmurhash "^0.1.4" known-css-properties "^0.19.0" - leven "^3.1.0" - lodash "^4.17.15" + lodash "^4.17.20" log-symbols "^4.0.0" mathml-tag-names "^2.1.3" - meow "^7.0.1" + meow "^7.1.1" micromatch "^4.0.2" normalize-selector "^0.2.0" postcss "^7.0.32" postcss-html "^0.36.0" postcss-less "^3.1.4" postcss-media-query-parser "^0.2.3" - postcss-reporter "^6.0.1" postcss-resolve-nested-selector "^0.1.1" postcss-safe-parser "^4.0.2" postcss-sass "^0.4.4" @@ -13294,7 +13412,7 @@ stylelint@^13.6.1: style-search "^0.1.0" sugarss "^2.0.0" svg-tags "^1.0.0" - table "^5.4.6" + table "^6.0.1" v8-compile-cache "^2.1.1" write-file-atomic "^3.0.3" @@ -13331,13 +13449,20 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== dependencies: has-flag "^4.0.0" +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + supports-hyperlinks@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47" @@ -13370,17 +13495,12 @@ svgo@^1.0.0: unquote "~1.1.1" util.promisify "~1.0.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== - symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -table@^5.2.3, table@^5.4.6: +table@^5.2.3: version "5.4.6" resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== @@ -13390,6 +13510,16 @@ table@^5.2.3, table@^5.4.6: slice-ansi "^2.1.0" string-width "^3.0.0" +table@^6.0.1: + version "6.0.3" + resolved "https://registry.yarnpkg.com/table/-/table-6.0.3.tgz#e5b8a834e37e27ad06de2e0fda42b55cfd8a0123" + integrity sha512-8321ZMcf1B9HvVX/btKv8mMZahCjn2aYrDlpqHaBFCfnox64edeH9kEid0vTLTRR8gWR2A20aDgeuTTea4sVtw== + dependencies: + ajv "^6.12.4" + lodash "^4.17.20" + slice-ansi "^4.0.0" + string-width "^4.2.0" + tapable@^0.1.8: version "0.1.10" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4" @@ -13534,10 +13664,10 @@ testcafe-browser-tools@2.0.13: read-file-relative "^1.2.0" which-promise "^1.0.0" -testcafe-hammerhead@17.1.13: - version "17.1.13" - resolved "https://registry.yarnpkg.com/testcafe-hammerhead/-/testcafe-hammerhead-17.1.13.tgz#e2ab9589e48aa145fa886c2303891e9e997d33fa" - integrity sha512-swNsC4gbs1vhKM9F9zmCcStA8oMg2FUTJZYUE30xL5ZdHae87x2tfg9T58jUcZK3CX0S9B2NCU1AJbwCsS0uqw== +testcafe-hammerhead@17.1.18: + version "17.1.18" + resolved "https://registry.yarnpkg.com/testcafe-hammerhead/-/testcafe-hammerhead-17.1.18.tgz#1de65d6f63f7037a150f0987826f1f528df91c71" + integrity sha512-mrIMd1NsX+aRH37wb6tlGZoQMttXw0cwJn23iI4Y00oD8VwJfBz0x01Df1HVSuodjTqCEKdJHvDnyjAAsGjaAw== dependencies: acorn-hammerhead "^0.3.0" asar "^2.0.1" @@ -13546,7 +13676,7 @@ testcafe-hammerhead@17.1.13: crypto-md5 "^1.0.0" css "2.2.3" debug "4.1.1" - esotope-hammerhead "0.5.5" + esotope-hammerhead "0.5.6" iconv-lite "0.5.1" lodash "^4.17.19" lru-cache "2.6.3" @@ -13554,10 +13684,10 @@ testcafe-hammerhead@17.1.13: merge-stream "^1.0.1" mime "~1.4.1" mustache "^2.1.1" - nanoid "^0.2.2" + nanoid "^3.1.12" os-family "^1.0.0" parse5 "2.2.3" - pinkie "1.0.0" + pinkie "2.0.4" read-file-relative "^1.2.0" semver "5.5.0" tough-cookie "2.3.3" @@ -13614,9 +13744,9 @@ testcafe-reporter-xunit@^2.1.0: integrity sha1-5tZsVyzhWvJmcGrw/WELKoQd1EM= testcafe@^1.8.8: - version "1.9.1" - resolved "https://registry.yarnpkg.com/testcafe/-/testcafe-1.9.1.tgz#2e3183d69561bf90da611408436c5b34b22f799c" - integrity sha512-18yGuCJvcdaGFhS3l4NhDwRnvJ24/mwXVfM+gqZm6vxNdw2NCujzXh36/BNr0qP2MhAEN56Y96G8XKkzn+5zYg== + version "1.9.3" + resolved "https://registry.yarnpkg.com/testcafe/-/testcafe-1.9.3.tgz#049b5d10127ce83993a46e35f429696ce774770b" + integrity sha512-1L5c8lHitGz/0Ta6AtA+J4e+YveV+XeoaY06mBWuVnijp56zJG4Xz1O2XNbMgprfLj7oNl96DW/MjJyW9B8QzA== dependencies: "@types/node" "^10.12.19" async-exit-hook "^1.1.2" @@ -13647,6 +13777,7 @@ testcafe@^1.8.8: emittery "^0.4.1" endpoint-utils "^1.0.2" error-stack-parser "^1.3.6" + execa "^4.0.3" globby "^9.2.0" graceful-fs "^4.1.11" graphlib "^2.1.5" @@ -13682,7 +13813,7 @@ testcafe@^1.8.8: source-map-support "^0.5.16" strip-bom "^2.0.0" testcafe-browser-tools "2.0.13" - testcafe-hammerhead "17.1.13" + testcafe-hammerhead "17.1.18" testcafe-legacy-api "4.0.0" testcafe-reporter-json "^2.1.0" testcafe-reporter-list "^2.1.0" @@ -13906,11 +14037,6 @@ tryer@^1.0.1: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== -ts-essentials@^2.0.3: - version "2.0.12" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" - integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== - ts-node@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.0.0.tgz#e7699d2a110cc8c0d3b831715e417688683460b3" @@ -14039,6 +14165,11 @@ typings-for-css-modules-loader@^1.7.0: graceful-fs "4.1.4" loader-utils "0.2.16" +ua-parser-js@^0.7.18: + version "0.7.22" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.22.tgz#960df60a5f911ea8f1c818f3747b99c6e177eae3" + integrity sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q== + ultron@~1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" @@ -14199,6 +14330,15 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +unzip-crx-3@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/unzip-crx-3/-/unzip-crx-3-0.2.0.tgz#d5324147b104a8aed9ae8639c95521f6f7cda292" + integrity sha512-0+JiUq/z7faJ6oifVB5nSwt589v1KCduqIJupNVDoWSXZtWDmjDGO3RAEOvwJ07w90aoXoP4enKsR7ecMrJtWQ== + dependencies: + jszip "^3.1.0" + mkdirp "^0.5.1" + yaku "^0.16.6" + upath@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" @@ -14224,9 +14364,9 @@ update-notifier@^4.1.0: xdg-basedir "^4.0.0" uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + version "4.4.0" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.0.tgz#aa714261de793e8a82347a7bcc9ce74e86f28602" + integrity sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== dependencies: punycode "^2.1.0" @@ -14267,13 +14407,6 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" -use-composed-ref@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.0.0.tgz#bb13e8f4a0b873632cde4940abeb88b92d03023a" - integrity sha512-RVqY3NFNjZa0xrmK3bIMWNmQ01QjKPDc7DeWR3xa/N8aliVppuutOE5bZzPkQfvL+5NRWMMp0DJ99Trd974FIw== - dependencies: - ts-essentials "^2.0.3" - use-deep-compare-effect@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/use-deep-compare-effect/-/use-deep-compare-effect-1.4.0.tgz#3f40e3fa5b0b8d79e4126e83be384ed602472405" @@ -14283,18 +14416,6 @@ use-deep-compare-effect@^1.4.0: "@types/use-deep-compare-effect" "^1.2.0" dequal "^2.0.2" -use-isomorphic-layout-effect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.0.0.tgz#f56b4ed633e1c21cd9fc76fe249002a1c28989fb" - integrity sha512-JMwJ7Vd86NwAt1jH7q+OIozZSIxA4ND0fx6AsOe2q1H8ooBUp5aN6DvVCqZiIaYU6JaMRJGyR0FO7EBCIsb/Rg== - -use-latest@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.1.0.tgz#7bf9684555869c3f5f37e10d0884c8accf4d3aa6" - integrity sha512-gF04d0ZMV3AMB8Q7HtfkAWe+oq1tFXP6dZKwBHQF5nVXtGsh2oAYeeqma5ZzxtlpOcW8Ro/tLcfmEodjDeqtuw== - dependencies: - use-isomorphic-layout-effect "^1.0.0" - use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -14493,9 +14614,9 @@ webidl-conversions@^6.1.0: integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== webpack-bundle-analyzer@^3.8.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.8.0.tgz#ce6b3f908daf069fd1f7266f692cbb3bded9ba16" - integrity sha512-PODQhAYVEourCcOuU+NiYI7WdR8QyELZGgPvB1y2tjbUpbmcQOt5Q7jEK+ttd5se0KSBKD9SXHCEozS++Wllmw== + version "3.9.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.9.0.tgz#f6f94db108fb574e415ad313de41a2707d33ef3c" + integrity sha512-Ob8amZfCm3rMB1ScjQVlbYYUEJyEjdEtQ92jqiFUYt5VkEeO2v5UMbv49P/gnmCZm3A6yaFQzCBvpZqN4MUsdA== dependencies: acorn "^7.1.1" acorn-walk "^7.1.1" @@ -14506,7 +14627,7 @@ webpack-bundle-analyzer@^3.8.0: express "^4.16.3" filesize "^3.6.1" gzip-size "^5.0.0" - lodash "^4.17.15" + lodash "^4.17.19" mkdirp "^0.5.1" opener "^1.5.1" ws "^6.0.0" @@ -14587,9 +14708,9 @@ webpack-log@^2.0.0: uuid "^3.3.2" webpack-merge@^5.0.9: - version "5.1.2" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.1.2.tgz#21dc1ed0e860c305cf5a07a48750f53a99750855" - integrity sha512-/slG0Kh0OKTf0zxdFJlhQHzv8bU9gUYVK5DkBjB3i/yoc1Xx4ADG0KITGO5S/6cqn2Ug43+8VR6Sz8daA/c+5g== + version "5.1.4" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.1.4.tgz#a2c3a0c38ac2c02055c47bb1d42de1f072f1aea4" + integrity sha512-LSmRD59mxREGkCBm9PCW3AaV4doDqxykGlx1NvioEE0FgkT2GQI54Wyvg39ptkiq2T11eRVoV39udNPsQvK+QQ== dependencies: clone-deep "^4.0.1" wildcard "^2.0.0" @@ -14603,9 +14724,9 @@ webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack- source-map "~0.6.1" webpack@^4.43.0: - version "4.44.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.1.tgz#17e69fff9f321b8f117d1fda714edfc0b939cc21" - integrity sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ== + version "4.44.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.44.2.tgz#6bfe2b0af055c8b2d1e90ed2cd9363f841266b72" + integrity sha512-6KJVGlCxYdISyurpQ0IPTklv+DULv05rs2hseIXer6D7KrUicRDLFb4IUM1S6LUAKypPM/nSiVSuv8jHu1m3/Q== dependencies: "@webassemblyjs/ast" "1.9.0" "@webassemblyjs/helper-module-context" "1.9.0" @@ -14659,6 +14780,11 @@ whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" +whatwg-fetch@>=0.10.0: + version "3.4.1" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz#e5f871572d6879663fa5674c8f833f15a8425ab3" + integrity sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ== + whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" @@ -14831,6 +14957,11 @@ y18n@^4.0.0: resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== +yaku@^0.16.6: + version "0.16.7" + resolved "https://registry.yarnpkg.com/yaku/-/yaku-0.16.7.tgz#1d195c78aa9b5bf8479c895b9504fd4f0847984e" + integrity sha1-HRlceKqbW/hHnIlblQT9TwhHmE4= + yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" @@ -14841,7 +14972,7 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0, yaml@^1.7.2: +yaml@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== @@ -14903,7 +15034,7 @@ yargs@^14.2.0: y18n "^4.0.0" yargs-parser "^15.0.1" -yargs@^15.3.1: +yargs@^15.3.1, yargs@^15.4.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==