diff options
121 files changed, 4942 insertions, 3559 deletions
diff --git a/client/js/app/package.json b/client/js/app/package.json index f88c4234ad5..f2f8f6cb433 100644 --- a/client/js/app/package.json +++ b/client/js/app/package.json @@ -7,23 +7,26 @@ "build": "vite build", "preview": "vite preview", "prepare": "cd ../../../ && husky install client/js/app/.husky", + "test": "jest", "lint": "eslint '{**/*,*}.{js,jsx}'" }, "dependencies": { "react": "^18", - "react-bootstrap": "^2.4.0", "react-dom": "^18" }, "devDependencies": { + "@emotion/react": "^11", "@fortawesome/fontawesome-svg-core": "^6", "@fortawesome/free-regular-svg-icons": "^6", "@fortawesome/free-solid-svg-icons": "^6", "@fortawesome/react-fontawesome": "^0", - "@mantine/core": "^4", - "@mantine/hooks": "^4", + "@mantine/core": "^5", + "@mantine/hooks": "^5", + "@mantine/notifications": "^5", "@types/react": "^18", "@types/react-dom": "^18", "@vitejs/plugin-react": "^1", + "esbuild-jest": "^0", "eslint": "^8", "eslint-plugin-import": "^2", "eslint-plugin-prettier": "^4", @@ -32,11 +35,31 @@ "eslint-plugin-react-perf": "^3", "eslint-plugin-unused-imports": "^2", "husky": "^7", + "jest": "^28", "lodash": "^4", "prettier": "2", "pretty-quick": "^3", "react-router-dom": "^6", "use-context-selector": "^1", "vite": "^2" + }, + "jest": { + "testMatch": [ + "<rootDir>/src/**/*.test.{js,jsx,ts,tsx}" + ], + "transform": { + "^.+\\.(js|jsx|mjs|cjs|ts|tsx)$": [ + "esbuild-jest" + ] + }, + "transformIgnorePatterns": [ + "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$" + ], + "moduleNameMapper": { + "^app/(.*)$": [ + "<rootDir>/src/app/$1" + ] + }, + "resetMocks": true } } diff --git a/client/js/app/src/app/app.jsx b/client/js/app/src/app/app.jsx index 9fa912c89a5..704a5bcbeeb 100644 --- a/client/js/app/src/app/app.jsx +++ b/client/js/app/src/app/app.jsx @@ -1,8 +1,9 @@ import React from 'react'; -import { BrowserRouter, Route } from 'react-router-dom'; +import { BrowserRouter } from 'react-router-dom'; +import { NotificationsProvider as MantineNotificationsProvider } from '@mantine/notifications'; import { Layout } from 'app/components'; import { Home } from 'app/pages/home/home'; -import { QueryBuilder } from 'app/pages/querybuilder/query-builder'; +import { QueryBuilder } from 'app/pages/querybuilder'; import { QueryTracer } from 'app/pages/querytracer/query-tracer'; import { ThemeProvider } from 'app/libs/theme-provider'; import { Router } from 'app/libs/router'; @@ -11,13 +12,15 @@ export function App() { return ( <BrowserRouter> <ThemeProvider> - <Layout> - <Router> - <Route path="/" element={<Home />} /> - <Route path="querybuilder" element={<QueryBuilder />} /> - <Route path="querytracer" element={<QueryTracer />} /> - </Router> - </Layout> + <MantineNotificationsProvider> + <Layout> + <Router> + <Home path="/" title="Home" /> + <QueryBuilder path="querybuilder" title="Query Builder" /> + <QueryTracer path="querytracer" title="Query Tracer" /> + </Router> + </Layout> + </MantineNotificationsProvider> </ThemeProvider> </BrowserRouter> ); diff --git a/client/js/app/src/app/assets/index.js b/client/js/app/src/app/assets/index.js index a62869fa71b..bf132dd86a7 100644 --- a/client/js/app/src/app/assets/index.js +++ b/client/js/app/src/app/assets/index.js @@ -1,2 +1 @@ export { default as VespaLogo } from 'app/assets/img/vespa-logo.svg'; -export { default as VespaIcon } from 'app/assets/img/vespa-icon.svg'; diff --git a/client/js/app/src/app/components/icon/icon.jsx b/client/js/app/src/app/components/icon/icon.jsx index e860d293cce..edc86250b01 100644 --- a/client/js/app/src/app/components/icon/icon.jsx +++ b/client/js/app/src/app/components/icon/icon.jsx @@ -1,13 +1,47 @@ import React from 'react'; import { library } from '@fortawesome/fontawesome-svg-core'; +import { Box } from '@mantine/core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faArrowsToDot, faChartGantt } from '@fortawesome/free-solid-svg-icons'; +import { + faArrowsToDot, + faChartGantt, + faCheck, + faCircleMinus, + faCopy, + faDownload, + faPaste, + faPlus, + faXmark, + faInfo, + faExclamation, +} from '@fortawesome/free-solid-svg-icons'; // TODO: use dynamic import -library.add(faArrowsToDot, faChartGantt); +library.add( + faArrowsToDot, + faChartGantt, + faCircleMinus, + faPlus, + faPaste, + faDownload, + faCopy, + faCheck, + faXmark, + faInfo, + faExclamation +); -export function Icon({ name, type = 'solid', ...rest }) { +export function Icon({ name, type = 'solid', color, ...rest }) { const icon = `fa-${type} fa-${name}`; - return <FontAwesomeIcon icon={icon} {...rest} />; + return ( + <Box + sx={(theme) => ({ + ...(color && { color: theme.cr.getSolidBackground(color) }), + })} + component={FontAwesomeIcon} + icon={icon} + {...rest} + /> + ); } diff --git a/client/js/app/src/app/components/layout/layout.jsx b/client/js/app/src/app/components/layout/layout.jsx index f0f5a0594c0..532a9ce3630 100644 --- a/client/js/app/src/app/components/layout/layout.jsx +++ b/client/js/app/src/app/components/layout/layout.jsx @@ -3,9 +3,5 @@ import { AppShell } from '@mantine/core'; import { Header } from 'app/components/layout/header'; export function Layout({ children }) { - return ( - <AppShell header={<Header />} fixed> - {children} - </AppShell> - ); + return <AppShell header={<Header />}>{children}</AppShell>; } diff --git a/client/js/app/src/app/libs/notification/index.jsx b/client/js/app/src/app/libs/notification/index.jsx new file mode 100644 index 00000000000..9313e3c9adf --- /dev/null +++ b/client/js/app/src/app/libs/notification/index.jsx @@ -0,0 +1,2 @@ +export * from 'app/libs/notification/rest-message'; +export * from 'app/libs/notification/messages'; diff --git a/client/js/app/src/app/libs/notification/messages.jsx b/client/js/app/src/app/libs/notification/messages.jsx new file mode 100644 index 00000000000..87f94b0dda0 --- /dev/null +++ b/client/js/app/src/app/libs/notification/messages.jsx @@ -0,0 +1,77 @@ +import React from 'react'; +import { showNotification } from '@mantine/notifications'; +import { Icon } from 'app/components'; +import { SHADE } from 'app/styles/theme/colors'; + +function getStyles(color) { + return (theme) => ({ + root: { + color: theme.fn.themeColor(color, SHADE.LOW_CONTRAST_TEXT), + background: theme.fn.themeColor(color, SHADE.UI_ELEMENT_BACKGROUND), + borderColor: theme.fn.themeColor( + color, + SHADE.UI_ELEMENT_BORDER_AND_FOCUS + ), + }, + title: { + fontWeight: 700, + color: theme.fn.themeColor(color, SHADE.LOW_CONTRAST_TEXT), + '&:hover': { + color: theme.fn.themeColor(color, SHADE.LOW_CONTRAST_TEXT), + }, + }, + description: { + color: theme.fn.themeColor(color, SHADE.LOW_CONTRAST_TEXT), + '&:hover': { + color: theme.fn.themeColor(color, SHADE.LOW_CONTRAST_TEXT), + }, + }, + closeButton: { + color: theme.fn.themeColor(color, SHADE.LOW_CONTRAST_TEXT), + '&:hover': { + backgroundColor: theme.fn.themeColor( + color, + SHADE.HOVERED_UI_ELEMENT_BACKGROUND + ), + }, + }, + }); +} + +const commonMessage = ({ title, icon, color, message }) => { + return showNotification({ + styles: getStyles(color), + icon: <Icon name={icon} />, + title, + color, + message, + }); +}; + +export const infoMessage = ( + message, + title = 'Info', + icon = 'info', + color = 'blue' +) => commonMessage({ title, icon, color, message }); + +export const warningMessage = ( + message, + title = 'Warning', + icon = 'exclamation', + color = 'orange' +) => commonMessage({ title, icon, color, message }); + +export const errorMessage = ( + message, + title = 'Error', + icon = 'xmark', + color = 'red' +) => commonMessage({ title, icon, color, message }); + +export const successMessage = ( + message, + title = 'Success', + icon = 'check', + color = 'green' +) => commonMessage({ title, icon, color, message }); diff --git a/client/js/app/src/app/libs/notification/rest-message.jsx b/client/js/app/src/app/libs/notification/rest-message.jsx new file mode 100644 index 00000000000..d05d28754b8 --- /dev/null +++ b/client/js/app/src/app/libs/notification/rest-message.jsx @@ -0,0 +1,43 @@ +import { + errorMessage, + infoMessage, + successMessage, +} from 'app/libs/notification/index'; + +export const restMessage = (response, prefix, code = 200) => { + // Gracefully handle various types of rest responses input + // Response can be a raw fetch request, an already decoded object or a plain string + if (typeof response === 'object') { + if (typeof response.text === 'function') { + Promise.resolve(response.text()).then((text) => { + restMessageContent(response.status || code, text, prefix); + }); + } else { + restMessageContent( + response.code || 200, + response.message || JSON.stringify(response), + prefix + ); + } + } else if (typeof response === 'string') { + restMessageContent(code, response, prefix); + } +}; + +const restMessageContent = (code, message, prefix) => { + // Trunk long messages + if (message.length > 200) message = message.substring(0, 200) + '...'; + + // Add pre-message if given + // Most of the time the message is just "Success" - so you would like + // to prefix it with eg. 'Adding user: ' + message = prefix ? prefix + message : message; + + if (code < 300) { + successMessage(message); + } else if (code < 400) { + infoMessage(message); + } else { + errorMessage(message); + } +}; diff --git a/client/js/app/src/app/libs/theme-provider.jsx b/client/js/app/src/app/libs/theme-provider.jsx index 58496ce15c2..c5e9cbee963 100644 --- a/client/js/app/src/app/libs/theme-provider.jsx +++ b/client/js/app/src/app/libs/theme-provider.jsx @@ -1,6 +1,5 @@ import React from 'react'; import { Global, MantineProvider } from '@mantine/core'; -import { defaultProps, defaultStyles } from 'app/styles/default'; import { Colors } from 'app/styles/theme/colors'; import { styles } from 'app/styles/global'; import { getTheme } from 'app/styles/theme'; @@ -12,11 +11,7 @@ function setColorResolver(theme) { export function ThemeProvider({ children }) { return ( - <MantineProvider - styles={defaultStyles} - defaultProps={defaultProps} - theme={getTheme()} - > + <MantineProvider theme={getTheme()}> <Global styles={(theme) => styles(setColorResolver(theme))} /> {children} </MantineProvider> diff --git a/client/js/app/src/app/pages/querybuilder/Components/Buttons/CopyResponseButton.jsx b/client/js/app/src/app/pages/querybuilder/Components/Buttons/CopyResponseButton.jsx deleted file mode 100644 index 2c53c4dd1e6..00000000000 --- a/client/js/app/src/app/pages/querybuilder/Components/Buttons/CopyResponseButton.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import React, { useState } from 'react'; -import { OverlayTrigger, Tooltip } from 'react-bootstrap'; -import ImageButton from './ImageButton'; -import { useQueryBuilderContext } from 'app/pages/querybuilder/Components/Contexts/QueryBuilderProvider'; -import copyImage from 'app/pages/querybuilder/assets/img/copy.svg'; - -export default function CopyResponseButton() { - const response = useQueryBuilderContext((ctx) => ctx.http.response); - const [show, setShow] = useState(false); - - const handleCopy = () => { - setShow(true); - navigator.clipboard.writeText(response); - setTimeout(() => { - setShow(false); - }, 2000); - }; - - return ( - <OverlayTrigger - placement="left-end" - overlay={ - <Tooltip>{show ? 'Response copied to clipboard' : 'Copy'}</Tooltip> - } - > - <span> - <ImageButton - className="intro-copy" - image={copyImage} - height={30} - width={30} - onClick={handleCopy} - /> - </span> - </OverlayTrigger> - ); -} diff --git a/client/js/app/src/app/pages/querybuilder/Components/Buttons/DownloadJSONButton.jsx b/client/js/app/src/app/pages/querybuilder/Components/Buttons/DownloadJSONButton.jsx deleted file mode 100644 index b89e3f14b3b..00000000000 --- a/client/js/app/src/app/pages/querybuilder/Components/Buttons/DownloadJSONButton.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; -import transform from 'app/pages/querybuilder/TransformVespaTrace'; - -export default function DownloadJSONButton({ children, response }) { - const handleClick = () => { - let content; - try { - content = JSON.stringify(transform(JSON.parse(response), null, 4)); - } catch (error) { - alert(`Failed to transform response to Jaeger format: ${error}`); // TODO: Change to toast - return; - } - - // copied from safakeskin´s answer on SO, link: https://stackoverflow.com/questions/55613438/reactwrite-to-json-file-or-export-download-no-server - const blob = new Blob([content], { type: 'application/json' }); - const href = URL.createObjectURL(blob); - - // create "a" HTML element with href to file - const link = document.createElement('a'); - link.href = href; - link.download = 'vespa-response.json'; - document.body.appendChild(link); - link.click(); - - // clean up "a" element & remove ObjectURL - document.body.removeChild(link); - URL.revokeObjectURL(href); - }; - - return <button onClick={handleClick}>{children}</button>; -} diff --git a/client/js/app/src/app/pages/querybuilder/Components/Buttons/ImageButton.jsx b/client/js/app/src/app/pages/querybuilder/Components/Buttons/ImageButton.jsx deleted file mode 100644 index 711229d82cd..00000000000 --- a/client/js/app/src/app/pages/querybuilder/Components/Buttons/ImageButton.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; - -export default function ImageButton({ - onClick, - children, - className, - image, - height = 15, - width = 15, - style, -}) { - return ( - <button className={className} onClick={onClick}> - <img - src={image} - height={height} - width={width} - style={style} - alt="Missing" - /> - {children} - </button> - ); -} diff --git a/client/js/app/src/app/pages/querybuilder/Components/Buttons/PasteJSONButton.jsx b/client/js/app/src/app/pages/querybuilder/Components/Buttons/PasteJSONButton.jsx deleted file mode 100644 index f01f5b177a5..00000000000 --- a/client/js/app/src/app/pages/querybuilder/Components/Buttons/PasteJSONButton.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import React, { useState } from 'react'; -import pasteImage from '../../assets/img/paste.svg'; -import ImageButton from './ImageButton'; -import { - ACTION, - dispatch, -} from 'app/pages/querybuilder/Components/Contexts/QueryBuilderProvider'; - -export default function PasteJSONButton() { - const [paste, setPaste] = useState(false); - - const handleClick = () => { - setPaste(true); - window.addEventListener('paste', handlePaste); - }; - - const handlePaste = (e) => { - setPaste(false); - // Stop data actually being pasted into div - e.stopPropagation(); - e.preventDefault(); - const pastedData = e.clipboardData.getData('text'); - window.removeEventListener('paste', handlePaste); - dispatch(ACTION.SET_QUERY, pastedData); - }; - - return ( - <> - <ImageButton - className="pasteJSON" - image={pasteImage} - onClick={handleClick} - > - {paste ? 'Press CMD + V' : 'Paste JSON'} - </ImageButton> - </> - ); -} diff --git a/client/js/app/src/app/pages/querybuilder/Components/Contexts/QueryBuilderProvider.jsx b/client/js/app/src/app/pages/querybuilder/Components/Contexts/QueryBuilderProvider.jsx deleted file mode 100644 index 2eebbb9b8b5..00000000000 --- a/client/js/app/src/app/pages/querybuilder/Components/Contexts/QueryBuilderProvider.jsx +++ /dev/null @@ -1,146 +0,0 @@ -import React, { useReducer } from 'react'; -import { createContext, useContextSelector } from 'use-context-selector'; -import { cloneDeep, last } from 'lodash'; -import parameters from 'app/pages/querybuilder/parameters'; - -let _dispatch; -const root = { type: { children: parameters } }; -const context = createContext(null); - -export const ACTION = Object.freeze({ - SET_QUERY: 0, - SET_HTTP: 1, - - INPUT_ADD: 10, - INPUT_UPDATE: 11, - INPUT_REMOVE: 12, -}); - -function inputsToJson(inputs) { - return Object.fromEntries( - inputs.map(({ children, input, type: { name, type } }) => [ - name, - children ? inputsToJson(children) : parseInput(input, type), - ]) - ); -} - -function jsonToInputs(json, parent) { - return Object.entries(json).map(([key, value], i) => { - const node = { - id: parent.id ? `${parent.id}.${i}` : i.toString(), - type: parent.type.children[key], - parent, - }; - if (typeof value === 'object') { - node.input = ''; - node.children = jsonToInputs(value, node); - } else node.input = value.toString(); - return node; - }); -} - -function parseInput(input, type) { - if (type === 'Integer' || type === 'Long') return parseInt(input); - if (type === 'Float') return parseFloat(input); - if (type === 'Boolean') return input.toLowerCase() === 'true'; - return input; -} - -function inputAdd(query, { id: parentId, type: typeName }) { - const inputs = cloneDeep(query.children); - const parent = parentId ? findInput(inputs, parentId) : query; - - const nextId = - parseInt(last(last(parent.children)?.id?.split('.')) ?? -1) + 1; - const id = parentId ? `${parentId}.${nextId}` : nextId.toString(); - const type = parent.type.children[typeName]; - - parent.children.push( - Object.assign( - { id, input: '', type, parent }, - type.children && { children: [] } - ) - ); - return { ...query, children: inputs }; -} - -function inputUpdate(query, { id, ...props }) { - const keys = Object.keys(props); - if (keys.length !== 1) - throw new Error(`Expected to update exactly 1 input prop, got: ${keys}`); - if (!['input', 'type'].includes(keys[0])) - throw new Error(`Cannot update key ${keys[0]}`); - - const inputs = cloneDeep(query.children); - const node = Object.assign(findInput(inputs, id), props); - if (node.type.children) node.children = []; - else delete node.children; - return { ...query, children: inputs }; -} - -function findInput(inputs, id, Delete = false) { - let end = -1; - while ((end = id.indexOf('.', end + 1)) > 0) - inputs = inputs.find((input) => input.id === id.substring(0, end)).children; - const index = inputs.findIndex((input) => input.id === id); - return Delete ? inputs.splice(index, 1)[0] : inputs[index]; -} - -function reducer(state, action) { - const result = preReducer(state, action); - if (state.query.children !== result.query.children) { - const json = inputsToJson(result.query.children); - result.query.input = JSON.stringify(json, null, 4); - } - - return result; -} -function preReducer(state, { action, data }) { - switch (action) { - case ACTION.SET_QUERY: { - try { - const children = jsonToInputs(JSON.parse(data), root); - return { ...state, query: { ...root, children } }; - } catch (error) { - alert(`Failed to parse query: ${error}`); // TODO: Change to toast - return state; - } - } - case ACTION.SET_HTTP: - return { ...state, http: data }; - - case ACTION.INPUT_ADD: - return { ...state, query: inputAdd(state.query, data) }; - case ACTION.INPUT_UPDATE: - return { ...state, query: inputUpdate(state.query, data) }; - case ACTION.INPUT_REMOVE: { - const inputs = cloneDeep(state.query.children); - findInput(inputs, data, true); - return { ...state, query: { ...state.query, children: inputs } }; - } - - default: - throw new Error(`Unknown action ${action}`); - } -} - -export function QueryBuilderProvider({ children }) { - const [value, dispatch] = useReducer( - reducer, - { http: {}, query: { ...root, input: '', children: [] } }, - (s) => reducer(s, { action: ACTION.SET_QUERY, data: '{"yql":""}' }) - ); - _dispatch = dispatch; - - return <context.Provider value={value}>{children}</context.Provider>; -} - -export function useQueryBuilderContext(selector) { - const func = typeof selector === 'string' ? (c) => c[selector] : selector; - return useContextSelector(context, func); -} - -export function dispatch(action, data) { - _dispatch({ action, data }); -} diff --git a/client/js/app/src/app/pages/querybuilder/Components/Text/QueryInput.jsx b/client/js/app/src/app/pages/querybuilder/Components/Text/QueryInput.jsx deleted file mode 100644 index 5f5a9fdbd89..00000000000 --- a/client/js/app/src/app/pages/querybuilder/Components/Text/QueryInput.jsx +++ /dev/null @@ -1,91 +0,0 @@ -import React from 'react'; -import { OverlayTrigger, Tooltip } from 'react-bootstrap'; -import SimpleDropDownForm from 'app/pages/querybuilder/Components/Text/SimpleDropDownForm'; -import { - ACTION, - dispatch, - useQueryBuilderContext, -} from 'app/pages/querybuilder/Components/Contexts/QueryBuilderProvider'; - -export default function QueryInput() { - const { children, type } = useQueryBuilderContext('query'); - return <Inputs type={type.children} inputs={children} />; -} - -function Inputs({ id, type, inputs }) { - const usedTypes = inputs.map(({ type }) => type.name); - const remainingTypes = Object.fromEntries( - Object.entries(type).filter(([name]) => !usedTypes.includes(name)) - ); - const firstRemaining = Object.keys(remainingTypes)[0]; - return ( - <> - {inputs.map(({ id, input, type, children }) => ( - <Input - key={id} - types={remainingTypes} - {...{ id, input, type, children }} - /> - ))} - {firstRemaining && <AddPropertyButton id={id} type={firstRemaining} />} - </> - ); -} - -function Input({ id, input, types, type, children }) { - return ( - <div className="queryinput"> - <SimpleDropDownForm - onChange={({ target }) => - dispatch(ACTION.INPUT_UPDATE, { - id, - type: types[target.value], - }) - } - options={{ [type.name]: type, ...types }} - value={type.name} - /> - {children ? ( - <Inputs id={id} type={type.children} inputs={children} /> - ) : ( - <input - size="30" - onChange={({ target }) => - dispatch(ACTION.INPUT_UPDATE, { - id, - input: target.value, - }) - } - placeholder={type.type} - value={input} - /> - )} - <OverlayTrigger - placement="right" - delay={{ show: 250, hide: 400 }} - overlay={<Tooltip id="button-tooltip">Remove row</Tooltip>} - > - <span> - <button - className="removeRow" - onClick={() => dispatch(ACTION.INPUT_REMOVE, id)} - > - - - </button> - </span> - </OverlayTrigger> - <br /> - </div> - ); -} - -function AddPropertyButton({ id, type }) { - return ( - <button - className="addpropsbutton" - onClick={() => dispatch(ACTION.INPUT_ADD, { id, type })} - > - + Add property - </button> - ); -} diff --git a/client/js/app/src/app/pages/querybuilder/Components/Text/SendQuery.jsx b/client/js/app/src/app/pages/querybuilder/Components/Text/SendQuery.jsx deleted file mode 100644 index 303bc8bfc83..00000000000 --- a/client/js/app/src/app/pages/querybuilder/Components/Text/SendQuery.jsx +++ /dev/null @@ -1,56 +0,0 @@ -import React, { useState } from 'react'; -import SimpleDropDownForm from './SimpleDropDownForm'; -import { - ACTION, - dispatch, - useQueryBuilderContext, -} from 'app/pages/querybuilder/Components/Contexts/QueryBuilderProvider'; - -function send(method, url, query) { - dispatch(ACTION.SET_HTTP, { loading: true }); - fetch(url, { - method, - headers: { 'Content-Type': 'application/json;charset=utf-8' }, - body: query, - }) - .then((response) => response.json()) - .then((result) => - dispatch(ACTION.SET_HTTP, { - response: JSON.stringify(result, null, 4), - }) - ) - .catch((error) => dispatch(ACTION.SET_HTTP, { error })); -} - -export default function SendQuery() { - const messageMethods = { post: { name: 'POST' }, get: { name: 'GET' } }; - const [method, setMethod] = useState(messageMethods.post.name); - const [url, setUrl] = useState('http://localhost:8080/search/'); - const query = useQueryBuilderContext((ctx) => ctx.query.input); - - const updateMethod = (e) => { - e.preventDefault(); - const newMethod = e.target.value; - setMethod(newMethod); - }; - - return ( - <> - <SimpleDropDownForm - options={messageMethods} - value={method} - className="methodselector" - onChange={updateMethod} - /> - <input - size="30" - className="textbox" - value={url} - onChange={({ target }) => setUrl(target.value)} - /> - <button className="button" onClick={() => send(method, url, query)}> - Send - </button> - </> - ); -} diff --git a/client/js/app/src/app/pages/querybuilder/Components/Text/SimpleDropDownForm.jsx b/client/js/app/src/app/pages/querybuilder/Components/Text/SimpleDropDownForm.jsx deleted file mode 100644 index 99342a5ae81..00000000000 --- a/client/js/app/src/app/pages/querybuilder/Components/Text/SimpleDropDownForm.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; - -export default function SimpleDropDownForm({ - options, - value, - className = 'input', - ...props -}) { - return ( - <select className={className} {...props} value={value}> - {Object.values(options).map(({ name }) => ( - <option className="options" key={name} value={name}> - {name} - </option> - ))} - </select> - ); -} diff --git a/client/js/app/src/app/pages/querybuilder/assets/img/Vespa-V2.png b/client/js/app/src/app/pages/querybuilder/assets/img/Vespa-V2.png Binary files differdeleted file mode 100644 index ac87f8e94d0..00000000000 --- a/client/js/app/src/app/pages/querybuilder/assets/img/Vespa-V2.png +++ /dev/null diff --git a/client/js/app/src/app/pages/querybuilder/assets/img/VespaIcon.png b/client/js/app/src/app/pages/querybuilder/assets/img/VespaIcon.png Binary files differdeleted file mode 100644 index 33063432c20..00000000000 --- a/client/js/app/src/app/pages/querybuilder/assets/img/VespaIcon.png +++ /dev/null diff --git a/client/js/app/src/app/pages/querybuilder/assets/img/copy.svg b/client/js/app/src/app/pages/querybuilder/assets/img/copy.svg deleted file mode 100644 index eada154413a..00000000000 --- a/client/js/app/src/app/pages/querybuilder/assets/img/copy.svg +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0"?> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 488.3 488.3" style="enable-background:new 0 0 488.3 488.3;" xml:space="preserve" width="512px" height="512px" class=""><g><g> - <g> - <path d="M314.25,85.4h-227c-21.3,0-38.6,17.3-38.6,38.6v325.7c0,21.3,17.3,38.6,38.6,38.6h227c21.3,0,38.6-17.3,38.6-38.6V124 C352.75,102.7,335.45,85.4,314.25,85.4z M325.75,449.6c0,6.4-5.2,11.6-11.6,11.6h-227c-6.4,0-11.6-5.2-11.6-11.6V124 c0-6.4,5.2-11.6,11.6-11.6h227c6.4,0,11.6,5.2,11.6,11.6V449.6z" data-original="#000000" class="active-path" data-old_color="#F8F5F5" fill="#FCFCFC"/> - <path d="M401.05,0h-227c-21.3,0-38.6,17.3-38.6,38.6c0,7.5,6,13.5,13.5,13.5s13.5-6,13.5-13.5c0-6.4,5.2-11.6,11.6-11.6h227 c6.4,0,11.6,5.2,11.6,11.6v325.7c0,6.4-5.2,11.6-11.6,11.6c-7.5,0-13.5,6-13.5,13.5s6,13.5,13.5,13.5c21.3,0,38.6-17.3,38.6-38.6 V38.6C439.65,17.3,422.35,0,401.05,0z" data-original="#000000" class="active-path" data-old_color="#F8F5F5" fill="#FCFCFC"/> - </g> -</g></g> </svg> diff --git a/client/js/app/src/app/pages/querybuilder/assets/img/down-arrow.svg b/client/js/app/src/app/pages/querybuilder/assets/img/down-arrow.svg deleted file mode 100644 index d78d2f9c17f..00000000000 --- a/client/js/app/src/app/pages/querybuilder/assets/img/down-arrow.svg +++ /dev/null @@ -1 +0,0 @@ -<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 36 36"><defs><style>.cls-1{clip-path:url(#clip-path);}.cls-2{clip-path:url(#clip-path-2);}.cls-3{clip-path:url(#clip-path-3);}</style><clipPath id="clip-path"><path d="M18,4.09A13.91,13.91,0,1,1,4.09,18,13.91,13.91,0,0,1,18,4.09ZM18,35A17,17,0,1,0,6,30,17,17,0,0,0,18,35Z"/></clipPath><clipPath id="clip-path-2"><rect x="-723.82" y="-837.15" width="1483.64" height="3802.85" fill="#FFFFFF"/></clipPath><clipPath id="clip-path-3"><path d="M26,13.83a1.55,1.55,0,0,0-2.16,0L18,19.75l-5.88-6A1.54,1.54,0,0,0,9.93,16L18,24.18,26.07,16a1.57,1.57,0,0,0,0-2.19Z"/></clipPath></defs><title>down-arrow</title><path d="M18,4.09A13.91,13.91,0,1,1,4.09,18,13.91,13.91,0,0,1,18,4.09ZM18,35A17,17,0,1,0,6,30,17,17,0,0,0,18,35Z"/><g class="cls-1"><rect x="-723.82" y="-837.15" width="1483.64" height="3802.85" fill="#FFFFFF"/><g class="cls-2"><rect x="-4.15" y="-4.15" width="44.3" height="44.3" fill="#FFFFFF"/></g></g><path d="M26,13.83a1.55,1.55,0,0,0-2.16,0L18,19.75l-5.88-6A1.54,1.54,0,0,0,9.93,16L18,24.18,26.07,16a1.57,1.57,0,0,0,0-2.19Z"/><g class="cls-3"><rect x="-723.82" y="-837.15" width="1483.64" height="3802.85" fill="#FFFFFF"/><g class="cls-2"><rect x="4.35" y="8.21" width="27.3" height="21.12" fill="#FFFFFF"/></g></g></svg> diff --git a/client/js/app/src/app/pages/querybuilder/assets/img/features-help.png b/client/js/app/src/app/pages/querybuilder/assets/img/features-help.png Binary files differdeleted file mode 100644 index 65702f8b91f..00000000000 --- a/client/js/app/src/app/pages/querybuilder/assets/img/features-help.png +++ /dev/null diff --git a/client/js/app/src/app/pages/querybuilder/assets/img/information.svg b/client/js/app/src/app/pages/querybuilder/assets/img/information.svg deleted file mode 100644 index da42cf2caf6..00000000000 --- a/client/js/app/src/app/pages/querybuilder/assets/img/information.svg +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0"?> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve" width="512px" height="512px"><g><g> - <g> - <g> - <circle cx="256" cy="378.5" r="25" data-original="#000000" class="active-path" data-old_color="#898989" fill="#767474"/> - <path d="M256,0C114.516,0,0,114.497,0,256c0,141.484,114.497,256,256,256c141.484,0,256-114.497,256-256 C512,114.516,397.503,0,256,0z M256,472c-119.377,0-216-96.607-216-216c0-119.377,96.607-216,216-216 c119.377,0,216,96.607,216,216C472,375.377,375.393,472,256,472z" data-original="#000000" class="active-path" data-old_color="#898989" fill="#767474"/> - <path d="M256,128.5c-44.112,0-80,35.888-80,80c0,11.046,8.954,20,20,20s20-8.954,20-20c0-22.056,17.944-40,40-40 c22.056,0,40,17.944,40,40c0,22.056-17.944,40-40,40c-11.046,0-20,8.954-20,20v50c0,11.046,8.954,20,20,20 c11.046,0,20-8.954,20-20v-32.531c34.466-8.903,60-40.26,60-77.469C336,164.388,300.112,128.5,256,128.5z" data-original="#000000" class="active-path" data-old_color="#898989" fill="#767474"/> - </g> - </g> -</g></g> </svg> diff --git a/client/js/app/src/app/pages/querybuilder/assets/img/paste.svg b/client/js/app/src/app/pages/querybuilder/assets/img/paste.svg deleted file mode 100644 index b2edac680bf..00000000000 --- a/client/js/app/src/app/pages/querybuilder/assets/img/paste.svg +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0"?> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" width="512px" height="512px" viewBox="0 0 561 561" style="enable-background:new 0 0 561 561;" xml:space="preserve" class=""><g><g> - <g id="content-paste"> - <path d="M459,51H351.9c-10.2-30.6-38.25-51-71.4-51c-33.15,0-61.2,20.4-71.4,51H102c-28.05,0-51,22.95-51,51v408 c0,28.05,22.95,51,51,51h357c28.05,0,51-22.95,51-51V102C510,73.95,487.05,51,459,51z M280.5,51c15.3,0,25.5,10.2,25.5,25.5 S295.8,102,280.5,102S255,91.8,255,76.5S265.2,51,280.5,51z M459,510H102V102h51v76.5h255V102h51V510z" data-original="#000000" class="active-path" data-old_color="#F9F6F6" fill="#FBF9F9"/> - </g> -</g></g> </svg> diff --git a/client/js/app/src/app/pages/querybuilder/assets/img/reload.svg b/client/js/app/src/app/pages/querybuilder/assets/img/reload.svg deleted file mode 100644 index c5381f9f232..00000000000 --- a/client/js/app/src/app/pages/querybuilder/assets/img/reload.svg +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0"?> -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve" width="512px" height="512px" class=""><g><g> - <g> - <path d="M482.195,226.196C482.195,101.471,380.725,0,256.001,0S29.805,101.471,29.805,226.196c0,7.409,6.007,13.416,13.416,13.416 s13.416-6.008,13.416-13.416c0-109.93,89.434-199.363,199.363-199.363s199.363,89.434,199.363,199.363 c0,109.928-89.434,199.362-199.363,199.362h-23.276l33.282-37.255c4.937-5.525,4.458-14.007-1.067-18.944 c-5.525-4.937-14.008-4.457-18.944,1.068l-47.576,53.255c-7.788,8.718-7.788,21.866,0,30.584l47.576,53.255 c2.651,2.968,6.322,4.478,10.01,4.478c3.181,0,6.375-1.126,8.934-3.41c5.526-4.937,6.004-13.419,1.067-18.944l-33.282-37.255 h23.276C380.725,452.39,482.195,350.919,482.195,226.196z" data-original="#000000" class="active-path" data-old_color="#F0EDED" fill="#F3F2F2"/> - </g> -</g></g> </svg> diff --git a/client/js/app/src/app/pages/querybuilder/context/__test__/query-builder-provider.test.jsx b/client/js/app/src/app/pages/querybuilder/context/__test__/query-builder-provider.test.jsx new file mode 100644 index 00000000000..5ccad2a054e --- /dev/null +++ b/client/js/app/src/app/pages/querybuilder/context/__test__/query-builder-provider.test.jsx @@ -0,0 +1,179 @@ +import { + ACTION, + reducer, +} from 'app/pages/querybuilder/context/query-builder-provider'; +import parameters from 'app/pages/querybuilder/context/parameters'; +import { cloneDeep, omitBy } from 'lodash'; + +const state = reducer(); + +test('default state', () => { + const fixed = { ...state, params: hideTypes(state.params) }; + expect(fixed).toEqual({ + http: {}, + params: { + value: [{ id: '0', value: '', type: 'yql' }], + }, + query: { + input: '{\n "yql": ""\n}', + }, + request: { + body: '{\n "yql": ""\n}', + fullUrl: 'http://localhost:8080/search/', + method: 'POST', + url: 'http://localhost:8080/search/', + }, + }); +}); + +test('manipulates inputs', () => { + function assert(state, queryJson, querySearchParams, params) { + expect(hideTypes(state.params).value).toEqual(params); + expect({ ...state.query, input: JSON.parse(state.query.input) }).toEqual( + queryJson + ); + + const spState = reducer(state, { action: ACTION.SET_METHOD, data: 'GET' }); + expect(hideTypes(spState.params).value).toEqual(params); + expect(spState.query).toEqual(querySearchParams); + } + + const s1 = reduce(state, [[ACTION.INPUT_ADD, { type: 'hits' }]]); + assert(s1, { input: { yql: '', hits: null } }, { input: 'yql=&hits=' }, [ + { id: '0', value: '', type: 'yql' }, + { id: '1', value: '', type: 'hits' }, + ]); + + const s2 = reduce(s1, [ + [ACTION.INPUT_UPDATE, { id: '1', value: '12' }], + [ACTION.INPUT_ADD, { type: 'ranking' }], + [ACTION.INPUT_UPDATE, { id: '1', type: 'offset' }], + [ACTION.INPUT_REMOVE, '0'], + [ACTION.INPUT_ADD, { id: '2', type: 'location' }], + [ACTION.INPUT_ADD, { id: '2', type: 'matchPhase' }], + [ACTION.INPUT_UPDATE, { id: '2.0', value: 'us' }], + ]); + assert( + s2, + { input: { offset: 12, ranking: { location: 'us', matchPhase: {} } } }, + { input: 'offset=12&ranking.location=us' }, + [ + { id: '1', value: '12', type: 'offset' }, + { + id: '2', + type: 'ranking', + value: [ + { id: '2.0', value: 'us', type: 'location' }, + { id: '2.1', type: 'matchPhase', value: [] }, + ], + }, + ] + ); + + assert( + reduce(s2, [[ACTION.INPUT_UPDATE, { id: '2', type: 'noCache' }]]), + { input: { offset: 12, noCache: false } }, + { input: 'offset=12&noCache=' }, + [ + { id: '1', value: '12', type: 'offset' }, + { id: '2', value: '', type: 'noCache' }, + ] + ); + + assert( + reduce(s2, [[ACTION.INPUT_REMOVE, '2']]), + { input: { offset: 12 } }, + { input: 'offset=12' }, + [{ id: '1', value: '12', type: 'offset' }] + ); +}); + +test('set query', () => { + const query = (method, input) => + reduce(state, [ + [ACTION.INPUT_REMOVE, '0'], + [ACTION.SET_METHOD, method], + [ACTION.SET_QUERY, input], + ]); + function assert(inputJson, inputSearchParams, params) { + const s2 = query('POST', inputJson); + expect(hideTypes(s2.params).value).toEqual(params); + expect(s2.query.input).toEqual(inputJson); + expect(s2.query.error).toBeUndefined(); + + if (inputSearchParams == null) return; + const s3 = query('GET', inputSearchParams); + expect(hideTypes(s3.params).value).toEqual(params); + expect(s3.query.input).toEqual(inputSearchParams); + expect(s3.query.error).toBeUndefined(); + } + + function error(method, input, error) { + const s = query(method, input); + expect(s.params.value).toEqual([]); + expect(s.query.input).toEqual(input); + expect(s.query.error).toEqual(error); + } + + assert('{"yql":"abc"}', '?yql=abc', [{ id: '0', value: 'abc', type: 'yql' }]); + + assert( + '{"hits":12,"ranking":{"location":"us","matchPhase":{"attribute":"[\\"a b\\"]"}},"noCache":true,"offset":""}', + 'hits=12&ranking.location=us&noCache=true&ranking.matchPhase.attribute=%5B%22a+b%22%5D&offset', + [ + { id: '0', value: '12', type: 'hits' }, + { + id: '1', + type: 'ranking', + value: [ + { id: '1.0', value: 'us', type: 'location' }, + { + id: '1.1', + type: 'matchPhase', + value: [{ id: '1.1.0', value: '["a b"]', type: 'attribute' }], + }, + ], + }, + { id: '2', value: 'true', type: 'noCache' }, + { id: '3', value: '', type: 'offset' }, + ] + ); + + assert('{"ranking":{"matchPhase":{}}}', null, [ + { + id: '0', + type: 'ranking', + value: [{ id: '0.0', type: 'matchPhase', value: [] }], + }, + ]); + + let msg = "Unknown property 'asd' on root level"; + error('POST', '{"asd":123}', msg); + error('GET', 'asd=123', msg); + + msg = "Unknown property 'asd' under 'matchPhase'"; + error('POST', '{"ranking":{"matchPhase":{"asd":123}}}', msg); + error('GET', 'ranking.matchPhase.asd=123', msg); + + error('POST', '{"yql":"test}', 'Unexpected end of JSON input'); + + msg = + "Property 'ranking' cannot have a value, supported children: features,freshness,listFeatures,location,matchPhase,profile,properties,queryCache,sorting"; + error('POST', '{"ranking":123}', msg); + error('GET', 'ranking=123', msg); + + error('POST', '{"yql":{}}', "Expected property 'yql' to be String"); +}); + +function hideTypes({ type, value, ...copy }) { + if (type.name) copy.type = type.name; + copy.value = type.children ? value.map(hideTypes) : value; + return copy; +} + +function reduce(state, operations) { + return operations.reduce( + (acc, [action, data]) => reducer(acc, { action, data }), + state + ); +} diff --git a/client/js/app/src/app/pages/querybuilder/parameters.jsx b/client/js/app/src/app/pages/querybuilder/context/parameters.jsx index 6557cfc0ea0..b3ca2425c9c 100644 --- a/client/js/app/src/app/pages/querybuilder/parameters.jsx +++ b/client/js/app/src/app/pages/querybuilder/context/parameters.jsx @@ -89,16 +89,6 @@ export default { timing: { name: 'timing', type: 'Boolean' }, }, }, - pos: { - name: 'pos', - type: 'Parent', - children: { - ll: { name: 'll', type: 'String' }, - radius: { name: 'radius', type: 'String' }, - bb: { name: 'bb', type: 'List' }, - attribute: { name: 'attribute', type: 'String' }, - }, - }, streaming: { name: 'streaming', type: 'Parent', diff --git a/client/js/app/src/app/pages/querybuilder/context/query-builder-provider.jsx b/client/js/app/src/app/pages/querybuilder/context/query-builder-provider.jsx new file mode 100644 index 00000000000..74585e1340c --- /dev/null +++ b/client/js/app/src/app/pages/querybuilder/context/query-builder-provider.jsx @@ -0,0 +1,217 @@ +import { last, set } from 'lodash'; +import React, { useReducer } from 'react'; +import { createContext, useContextSelector } from 'use-context-selector'; +import parameters from 'app/pages/querybuilder/context/parameters'; + +let _dispatch; +const root = { type: { children: parameters } }; +const context = createContext(null); + +export const ACTION = Object.freeze({ + SET_QUERY: 0, + SET_HTTP: 1, + SET_METHOD: 2, + SET_URL: 3, + + INPUT_ADD: 10, + INPUT_UPDATE: 11, + INPUT_REMOVE: 12, +}); + +function cloneParams(params) { + if (!Array.isArray(params.value)) return { ...params }; + return { ...params, value: params.value.map(cloneParams) }; +} + +function inputsToQuery(method, inputs) { + if (method === 'POST') { + const inputsToJson = (inputs, parent) => + Object.fromEntries( + inputs.map(({ value, type: { name, type, children } }) => [ + name, + children ? inputsToJson(value) : parseInput(value, type), + ]) + ); + return JSON.stringify(inputsToJson(inputs), null, 4); + } + + const inputsToSearchParams = (inputs, parent) => + inputs.reduce((acc, { value, type: { name, children } }) => { + const key = parent ? `${parent}.${name}` : name; + return Object.assign( + acc, + children ? inputsToSearchParams(value, key) : { [key]: value } + ); + }, {}); + return new URLSearchParams(inputsToSearchParams(inputs)).toString(); +} + +function queryToInputs(method, query) { + if (method === 'POST') return jsonToInputs(JSON.parse(query)); + + const json = [...new URLSearchParams(query).entries()].reduce( + (acc, [key, value]) => set(acc, key, value), + {} + ); + return jsonToInputs(json); +} + +function jsonToInputs(json, parent = root) { + return Object.entries(json).map(([key, value], i) => { + const node = { + id: parent.id ? `${parent.id}.${i}` : i.toString(), + type: parent.type.children[key], + }; + if (!node.type) { + const location = parent.type.name + ? `under '${parent.type.name}'` + : 'on root level'; + throw new Error(`Unknown property '${key}' ${location}`); + } + if (value != null && typeof value === 'object') { + if (!node.type.children) + throw new Error(`Expected property '${key}' to be ${node.type.type}`); + node.value = jsonToInputs(value, node); + } else { + if (node.type.children) + throw new Error( + `Property '${key}' cannot have a value, supported children: ${Object.keys( + node.type.children + ).sort()}` + ); + node.value = value?.toString(); + } + return node; + }); +} + +function parseInput(value, type) { + if (type === 'Integer' || type === 'Long') return parseInt(value); + if (type === 'Float') return parseFloat(value); + if (type === 'Boolean') return value.toLowerCase() === 'true'; + return value; +} + +function inputAdd(params, { id: parentId, type: typeName }) { + const cloned = cloneParams(params); + const parent = findInput(cloned, parentId); + + const nextId = parseInt(last(last(parent.value)?.id?.split('.')) ?? -1) + 1; + const id = parentId ? `${parentId}.${nextId}` : nextId.toString(); + const type = parent.type.children[typeName]; + + parent.value.push({ id, value: type.children ? [] : '', type }); + + return cloned; +} + +function inputUpdate(params, { id, type, value }) { + const cloned = cloneParams(params); + const node = findInput(cloned, id); + if (type) { + const parent = findInput(cloned, id.substring(0, id.lastIndexOf('.'))); + const newType = parent.type.children[type]; + if ((node.type.children != null) !== (newType.children != null)) + node.value = newType.children ? [] : ''; + node.type = newType; + } + if (value) node.value = value; + + return cloned; +} + +function findInput(params, id, Delete = false) { + if (!id) return params; + let end = -1; + while ((end = id.indexOf('.', end + 1)) > 0) + params = params.value.find((input) => input.id === id.substring(0, end)); + const index = params.value.findIndex((input) => input.id === id); + return Delete ? params.value.splice(index, 1)[0] : params.value[index]; +} + +export function reducer(state, action) { + if (state == null) { + state = { http: {}, params: {}, query: {}, request: {} }; + + return [ + [ACTION.SET_URL, 'http://localhost:8080/search/'], + [ACTION.SET_QUERY, 'yql='], + [ACTION.SET_METHOD, 'POST'], + ].reduce((s, [action, data]) => reducer(s, { action, data }), state); + } + + const result = preReducer(state, action); + const { request: sr, params: sp, query: sq } = state; + const { request: rr, params: rp, query: rq } = result; + + if ((sp.value !== rp.value && sq === rq) || sr.method !== rr.method) + result.query = { input: inputsToQuery(rr.method, rp.value) }; + + const input = result.query.input; + if (sr.url !== rr.url || sq.input !== input || sr.method !== rr.method) { + if (rr.method === 'POST') { + result.request = { ...result.request, fullUrl: rr.url, body: input }; + } else { + const url = new URL(rr.url); + url.search = input; + result.request = { + ...result.request, + fullUrl: url.toString(), + body: null, + }; + } + } + + return result; +} + +function preReducer(state, { action, data }) { + switch (action) { + case ACTION.SET_QUERY: { + try { + const value = queryToInputs(state.request.method, data); + return { + ...state, + params: { ...root, value }, + query: { input: data }, + }; + } catch (error) { + return { ...state, query: { input: data, error: error.message } }; + } + } + case ACTION.SET_HTTP: + return { ...state, http: data }; + case ACTION.SET_METHOD: + return { ...state, request: { ...state.request, method: data } }; + case ACTION.SET_URL: + return { ...state, request: { ...state.request, url: data } }; + + case ACTION.INPUT_ADD: + return { ...state, params: inputAdd(state.params, data) }; + case ACTION.INPUT_UPDATE: + return { ...state, params: inputUpdate(state.params, data) }; + case ACTION.INPUT_REMOVE: { + const cloned = cloneParams(state.params); + findInput(cloned, data, true); + return { ...state, params: cloned }; + } + + default: + throw new Error(`Unknown action ${action}`); + } +} + +export function QueryBuilderProvider({ children }) { + const [value, dispatch] = useReducer(reducer, null, reducer); + _dispatch = dispatch; + return <context.Provider value={value}>{children}</context.Provider>; +} + +export function useQueryBuilderContext(selector) { + const func = typeof selector === 'string' ? (c) => c[selector] : selector; + return useContextSelector(context, func); +} + +export function dispatch(action, data) { + _dispatch({ action, data }); +} diff --git a/client/js/app/src/app/pages/querybuilder/index.jsx b/client/js/app/src/app/pages/querybuilder/index.jsx new file mode 100644 index 00000000000..b8889dfd7c5 --- /dev/null +++ b/client/js/app/src/app/pages/querybuilder/index.jsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { SimpleGrid, Title } from '@mantine/core'; +import { Container, Content, Icon } from 'app/components'; +import { QueryBuilderProvider } from 'app/pages/querybuilder/context/query-builder-provider'; +import { QueryFilters } from 'app/pages/querybuilder/query-filters/query-filters'; +import { QueryDerived } from 'app/pages/querybuilder/query-derived/query-derived'; +import { QueryResponse } from 'app/pages/querybuilder/query-response/query-response'; +import QueryEndpoint from 'app/pages/querybuilder/query-endpoint/query-endpoint'; + +export function QueryBuilder() { + return ( + <QueryBuilderProvider> + <Container sx={{ rowGap: '21px' }}> + <Title order={2}> + <Icon name="arrows-to-dot" /> Query Builder + </Title> + <QueryEndpoint /> + <SimpleGrid + breakpoints={[{ maxWidth: 'sm', cols: 1 }]} + cols={3} + spacing="lg" + > + <Content> + <QueryFilters /> + </Content> + <Content> + <QueryDerived /> + </Content> + <Content> + <QueryResponse /> + </Content> + </SimpleGrid> + </Container> + </QueryBuilderProvider> + ); +} diff --git a/client/js/app/src/app/pages/querybuilder/query-builder.jsx b/client/js/app/src/app/pages/querybuilder/query-builder.jsx deleted file mode 100644 index b101e8639fb..00000000000 --- a/client/js/app/src/app/pages/querybuilder/query-builder.jsx +++ /dev/null @@ -1,58 +0,0 @@ -import React from 'react'; -import QueryInput from './Components/Text/QueryInput'; -import SendQuery from './Components/Text/SendQuery'; -import PasteJSONButton from './Components/Buttons/PasteJSONButton'; -import CopyResponseButton from './Components/Buttons/CopyResponseButton'; -import DownloadJSONButton from './Components/Buttons/DownloadJSONButton'; -import { - QueryBuilderProvider, - useQueryBuilderContext, -} from 'app/pages/querybuilder/Components/Contexts/QueryBuilderProvider'; - -import '../../styles/agency.css'; -import '../../styles/vespa.css'; - -function QueryBox() { - const query = useQueryBuilderContext((ctx) => ctx.query.input); - return <textarea readOnly cols="70" rows="15" value={query}></textarea>; -} - -function ResponseBox() { - const response = useQueryBuilderContext((ctx) => ctx.http.response); - return ( - <> - <textarea readOnly cols="70" rows="25" value={response} /> - <CopyResponseButton /> - <DownloadJSONButton response={response}> - Download in Jeager format - </DownloadJSONButton> - </> - ); -} - -export function QueryBuilder() { - return ( - <header> - <div className="intro container"> - <p className="intro-lead-in">Vespa Search Engine</p> - <p className="intro-long"> - Select the method for sending a request and construct a query. - </p> - <QueryBuilderProvider> - <SendQuery /> - <br /> - <div id="request"> - <QueryInput /> - </div> - <br /> - <PasteJSONButton /> - <QueryBox /> - <p className="response">Response</p> - <ResponseBox /> - </QueryBuilderProvider> - <br /> - <br /> - </div> - </header> - ); -} diff --git a/client/js/app/src/app/pages/querybuilder/query-derived/query-derived.jsx b/client/js/app/src/app/pages/querybuilder/query-derived/query-derived.jsx new file mode 100644 index 00000000000..fca06defc5d --- /dev/null +++ b/client/js/app/src/app/pages/querybuilder/query-derived/query-derived.jsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { + Badge, + Group, + Stack, + Button, + CopyButton, + Textarea, +} from '@mantine/core'; +import { + ACTION, + dispatch, + useQueryBuilderContext, +} from 'app/pages/querybuilder/context/query-builder-provider'; +import { Icon } from 'app/components'; + +export function QueryDerived() { + const { input, error } = useQueryBuilderContext('query'); + + return ( + <Stack> + <Group position="apart"> + <Badge variant="filled">Query</Badge> + <Group spacing="xs"> + <CopyButton value={input}> + {({ copied, copy }) => ( + <Button + leftIcon={<Icon name={copied ? 'check' : 'copy'} />} + color={copied ? 'teal' : 'blue'} + variant="outline" + onClick={copy} + size="xs" + compact + > + Copy + </Button> + )} + </CopyButton> + </Group> + </Group> + <Textarea + styles={(theme) => ({ + input: { + fontFamily: theme.fontFamilyMonospace, + fontSize: theme.fontSizes.xs, + }, + })} + value={input} + error={error} + onChange={({ target }) => dispatch(ACTION.SET_QUERY, target.value)} + variant="unstyled" + minRows={21} + autosize + /> + </Stack> + ); +} diff --git a/client/js/app/src/app/pages/querybuilder/query-endpoint/query-endpoint.jsx b/client/js/app/src/app/pages/querybuilder/query-endpoint/query-endpoint.jsx new file mode 100644 index 00000000000..09d52640936 --- /dev/null +++ b/client/js/app/src/app/pages/querybuilder/query-endpoint/query-endpoint.jsx @@ -0,0 +1,63 @@ +import React from 'react'; +import { Select, TextInput, Button } from '@mantine/core'; +import { errorMessage } from 'app/libs/notification'; +import { + ACTION, + dispatch, + useQueryBuilderContext, +} from 'app/pages/querybuilder/context/query-builder-provider'; +import { Container, Content } from 'app/components'; + +function send(event, method, url, body) { + event.preventDefault(); + dispatch(ACTION.SET_HTTP, { loading: true }); + fetch(url, { + method, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + body, + }) + .then((response) => response.json()) + .then((result) => + dispatch(ACTION.SET_HTTP, { + response: JSON.stringify(result, null, 4), + }) + ) + .catch((error) => { + errorMessage(error.message); + dispatch(ACTION.SET_HTTP, {}); + }); +} + +export default function QueryEndpoint() { + const { method, url, fullUrl, body } = useQueryBuilderContext('request'); + const hasError = useQueryBuilderContext((ctx) => ctx.query.error != null); + const loading = useQueryBuilderContext((ctx) => ctx.http.loading); + + return ( + <Content> + <form onSubmit={(event) => send(event, method, fullUrl, body)}> + <Container sx={{ gridTemplateColumns: 'max-content auto max-content' }}> + <Select + data={['POST', 'GET']} + onChange={(value) => dispatch(ACTION.SET_METHOD, value)} + value={method} + radius={0} + /> + <TextInput + onChange={(e) => dispatch(ACTION.SET_URL, e.currentTarget.value)} + value={url} + radius={0} + /> + <Button + radius={0} + type="submit" + loading={loading} + disabled={hasError} + > + Send + </Button> + </Container> + </form> + </Content> + ); +} diff --git a/client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx b/client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx new file mode 100644 index 00000000000..178270eb71f --- /dev/null +++ b/client/js/app/src/app/pages/querybuilder/query-filters/query-filters.jsx @@ -0,0 +1,128 @@ +import React from 'react'; +import { + Select, + TextInput, + ActionIcon, + Button, + Box, + Stack, + Badge, + Group, +} from '@mantine/core'; +import { Container, Content, Icon } from 'app/components'; +import { + ACTION, + dispatch, + useQueryBuilderContext, +} from 'app/pages/querybuilder/context/query-builder-provider'; +import { SHADE } from 'app/styles/theme/colors'; + +function AddProperty(props) { + return ( + <Button leftIcon={<Icon name="plus" />} {...props}> + Add property + </Button> + ); +} + +function Input({ id, value, types, type }) { + const options = { [type.name]: type, ...types }; + return ( + <> + <Box sx={{ display: 'flex', alignItems: 'center', gap: '5px' }}> + <Select + sx={{ flex: 1 }} + data={Object.values(options).map(({ name }) => name)} + onChange={(type) => dispatch(ACTION.INPUT_UPDATE, { id, type })} + value={type.name} + searchable + /> + {!type.children && ( + <TextInput + sx={{ flex: 1 }} + onChange={(event) => + dispatch(ACTION.INPUT_UPDATE, { + id, + value: event.currentTarget.value, + }) + } + placeholder={type.type} + value={value} + /> + )} + <ActionIcon onClick={() => dispatch(ACTION.INPUT_REMOVE, id)}> + <Icon name="circle-minus" /> + </ActionIcon> + </Box> + {type.children && ( + <Box + py={8} + sx={(theme) => ({ + borderLeft: `1px dashed ${theme.fn.themeColor( + 'gray', + SHADE.UI_ELEMENT_BORDER_AND_FOCUS + )}`, + marginLeft: '13px', + paddingLeft: '13px', + })} + > + <Inputs id={id} type={type.children} inputs={value} /> + </Box> + )} + </> + ); +} + +function Inputs({ id, type, inputs }) { + const usedTypes = inputs.map(({ type }) => type.name); + const remainingTypes = Object.fromEntries( + Object.entries(type).filter(([name]) => !usedTypes.includes(name)) + ); + const firstRemaining = Object.keys(remainingTypes)[0]; + return ( + <Container sx={{ rowGap: '5px' }}> + {inputs.map(({ id, value, type }) => ( + <Input key={id} types={remainingTypes} {...{ id, value, type }} /> + ))} + {firstRemaining && ( + <> + {id != null ? ( + <Container sx={{ justifyContent: 'start' }}> + <AddProperty + onClick={() => + dispatch(ACTION.INPUT_ADD, { id, type: firstRemaining }) + } + variant="subtle" + size="xs" + compact + /> + </Container> + ) : ( + <AddProperty + onClick={() => + dispatch(ACTION.INPUT_ADD, { id, type: firstRemaining }) + } + mt={13} + /> + )} + </> + )} + </Container> + ); +} + +export function QueryFilters() { + const { value, type } = useQueryBuilderContext('params'); + return ( + <Stack> + <Group> + <Badge variant="filled">Parameters</Badge> + </Group> + <Container sx={{ alignContent: 'start' }}> + <Content padding={0}> + <Inputs type={type.children} inputs={value} /> + </Content> + </Container> + </Stack> + ); +} diff --git a/client/js/app/src/app/pages/querybuilder/query-response/download-jeager.jsx b/client/js/app/src/app/pages/querybuilder/query-response/download-jeager.jsx new file mode 100644 index 00000000000..4130172a329 --- /dev/null +++ b/client/js/app/src/app/pages/querybuilder/query-response/download-jeager.jsx @@ -0,0 +1,55 @@ +import { Button } from '@mantine/core'; +import React from 'react'; +import { errorMessage } from 'app/libs/notification'; +import { Icon } from 'app/components'; +import transform from 'app/pages/querybuilder/TransformVespaTrace'; + +// copied from safakeskin´s answer on SO, link: https://stackoverflow.com/questions/55613438/reactwrite-to-json-file-or-export-download-no-server +function downloadFile(filename, blob) { + const href = URL.createObjectURL(blob); + + // create "a" HTML element with href to file + const link = document.createElement('a'); + link.href = href; + link.download = filename; + document.body.appendChild(link); + link.click(); + + // clean up "a" element & remove ObjectURL + document.body.removeChild(link); + URL.revokeObjectURL(href); +} + +export function DownloadJeager({ response, ...props }) { + const handleClick = () => { + try { + const json = JSON.parse(response); + + try { + const content = JSON.stringify(transform(json), null, 4); + downloadFile( + 'vespa-response.json', + new Blob([content], { type: 'application/json' }) + ); + } catch (error) { + errorMessage( + 'Request must be made with tracelevel ≥ 4', + 'Failed to transform response to Jaeger format' + ); + } + } catch (error) { + errorMessage(error.message); + } + }; + + return ( + <Button + {...props} + leftIcon={<Icon name="download" />} + onClick={handleClick} + disabled={!(response?.length > 0)} + > + Jaeger Format + </Button> + ); +} diff --git a/client/js/app/src/app/pages/querybuilder/query-response/query-response.jsx b/client/js/app/src/app/pages/querybuilder/query-response/query-response.jsx new file mode 100644 index 00000000000..56562ae1717 --- /dev/null +++ b/client/js/app/src/app/pages/querybuilder/query-response/query-response.jsx @@ -0,0 +1,58 @@ +import React from 'react'; +import { + Badge, + Button, + Group, + Stack, + CopyButton, + Textarea, +} from '@mantine/core'; +import { DownloadJeager } from 'app/pages/querybuilder/query-response/download-jeager'; +import { useQueryBuilderContext } from 'app/pages/querybuilder/context/query-builder-provider'; +import { Icon } from 'app/components'; + +export function QueryResponse() { + const response = useQueryBuilderContext((ctx) => ctx.http.response); + + return ( + <Stack> + <Group position="apart"> + <Badge variant="filled">Response</Badge> + <Group spacing="xs"> + <CopyButton value={response}> + {({ copied, copy }) => ( + <Button + leftIcon={<Icon name={copied ? 'check' : 'copy'} />} + color={copied ? 'teal' : 'blue'} + variant="outline" + onClick={copy} + size="xs" + compact + > + Copy + </Button> + )} + </CopyButton> + <DownloadJeager + variant="outline" + size="xs" + compact + response={response} + /> + </Group> + </Group> + <Textarea + styles={(theme) => ({ + input: { + fontFamily: theme.fontFamilyMonospace, + fontSize: theme.fontSizes.xs, + }, + })} + value={response ?? ''} + variant="unstyled" + minRows={21} + autosize + /> + </Stack> + ); +} diff --git a/client/js/app/src/app/pages/querytracer/query-tracer.jsx b/client/js/app/src/app/pages/querytracer/query-tracer.jsx index c3212c70c8a..758182d4f3f 100644 --- a/client/js/app/src/app/pages/querytracer/query-tracer.jsx +++ b/client/js/app/src/app/pages/querytracer/query-tracer.jsx @@ -1,21 +1,25 @@ import React, { useState } from 'react'; -import DownloadJSONButton from '../querybuilder/Components/Buttons/DownloadJSONButton'; -import { Container } from 'app/components'; +import { Stack, Textarea } from '@mantine/core'; +import { DownloadJeager } from 'app/pages/querybuilder/query-response/download-jeager'; export function QueryTracer() { const [response, setResponse] = useState(''); return ( - <Container> - <textarea - cols="70" - rows="25" + <Stack> + <Textarea + styles={(theme) => ({ + input: { + fontFamily: theme.fontFamilyMonospace, + fontSize: theme.fontSizes.xs, + }, + })} + minRows={21} + autosize value={response} onChange={({ target }) => setResponse(target.value)} - ></textarea> - <DownloadJSONButton response={response}> - Download in Jeager format - </DownloadJSONButton> - </Container> + /> + <DownloadJeager fullWidth response={response} /> + </Stack> ); } diff --git a/client/js/app/src/app/styles/agency.css b/client/js/app/src/app/styles/agency.css deleted file mode 100644 index e17809338c6..00000000000 --- a/client/js/app/src/app/styles/agency.css +++ /dev/null @@ -1,895 +0,0 @@ -/*! - * Start Bootstrap - Agency Bootstrap Theme (http://startbootstrap.com) - * Code licensed under the Apache License v2.0. - * For details, see http://www.apache.org/licenses/LICENSE-2.0. - */ -:root { - --primary: #188fff; - --secondary: #003abc; - --secondary-dark: #333; - --muted: #777; - - --fontprimary: HelveticaNeue, Helvetica, Arial, sans-serif; - --fontsecondary: HelveticaNeue-Thin, Helvetica, Arial, sans-serif; -} - -body { - overflow-x: hidden; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - color: var(--secondary-dark); -} - -.text-muted { - color: var(--muted); -} - -.text-primary { - color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -p { - font-size: 14px; - line-height: 1.75; -} - -p.large { - font-size: 16px; -} - -a, -a:hover, -a:focus, -a:active, -a.active { - outline: 0; -} - -a { - color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -a:hover, -a:focus, -a:active, -a.active { - color: HelveticaNeue-Thin, Helvetica, Arial, sans-serif; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - text-transform: uppercase; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - font-weight: 700; -} - -.img-centered { - margin: 0 auto; -} - -.bg-light-gray { - background-color: #f7f7f7; -} - -.bg-darkest-gray { - background-color: #222; -} - -.btn-primary { - border-color: HelveticaNeue, Helvetica, Arial, sans-serif; - text-transform: uppercase; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - font-weight: 700; - color: #fff; - background-color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -.btn-primary:hover, -.btn-primary:focus, -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary { - border-color: HelveticaNeue, Helvetica, Arial, sans-serif; - color: #fff; - background-color: HelveticaNeue-Thin, Helvetica, Arial, sans-serif; -} - -.btn-primary:active, -.btn-primary.active, -.open .dropdown-toggle.btn-primary { - background-image: none; -} - -.btn-primary.disabled, -.btn-primary[disabled], -fieldset[disabled] .btn-primary, -.btn-primary.disabled:hover, -.btn-primary[disabled]:hover, -fieldset[disabled] .btn-primary:hover, -.btn-primary.disabled:focus, -.btn-primary[disabled]:focus, -fieldset[disabled] .btn-primary:focus, -.btn-primary.disabled:active, -.btn-primary[disabled]:active, -fieldset[disabled] .btn-primary:active, -.btn-primary.disabled.active, -.btn-primary[disabled].active, -fieldset[disabled] .btn-primary.active { - border-color: HelveticaNeue, Helvetica, Arial, sans-serif; - background-color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -.btn-primary .badge { - color: HelveticaNeue, Helvetica, Arial, sans-serif; - background-color: #fff; -} - -.btn-xl { - padding: 20px 40px; - border-color: HelveticaNeue, Helvetica, Arial, sans-serif; - border-radius: 3px; - text-transform: uppercase; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - font-size: 18px; - font-weight: 700; - color: #fff; - background-color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -.btn-xl:hover, -.btn-xl:focus, -.btn-xl:active, -.btn-xl.active, -.open .dropdown-toggle.btn-xl { - border-color: HelveticaNeue, Helvetica, Arial, sans-serif; - color: #fff; - background-color: HelveticaNeue-Thin, Helvetica, Arial, sans-serif; -} - -.btn-xl:active, -.btn-xl.active, -.open .dropdown-toggle.btn-xl { - background-image: none; -} - -.btn-xl.disabled, -.btn-xl[disabled], -fieldset[disabled] .btn-xl, -.btn-xl.disabled:hover, -.btn-xl[disabled]:hover, -fieldset[disabled] .btn-xl:hover, -.btn-xl.disabled:focus, -.btn-xl[disabled]:focus, -fieldset[disabled] .btn-xl:focus, -.btn-xl.disabled:active, -.btn-xl[disabled]:active, -fieldset[disabled] .btn-xl:active, -.btn-xl.disabled.active, -.btn-xl[disabled].active, -fieldset[disabled] .btn-xl.active { - border-color: HelveticaNeue, Helvetica, Arial, sans-serif; - background-color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -.btn-xl .badge { - color: HelveticaNeue, Helvetica, Arial, sans-serif; - background-color: #fff; -} - -.navbar-default { - border-color: transparent; - background-color: #222; -} - -.navbar-default .navbar-brand { - font-family: 'Kaushan Script', 'Helvetica Neue', Helvetica, Arial, cursive; - color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -.navbar-default .navbar-brand:hover, -.navbar-default .navbar-brand:focus, -.navbar-default .navbar-brand:active, -.navbar-default .navbar-brand.active { - color: HelveticaNeue-Thin, Helvetica, Arial, sans-serif; -} - -.navbar-default .navbar-collapse { - border-color: rgba(255, 255, 255, 0.02); -} - -.navbar-default .navbar-toggle { - border-color: HelveticaNeue, Helvetica, Arial, sans-serif; - background-color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -.navbar-default .navbar-toggle .icon-bar { - background-color: #fff; -} - -.navbar-default .navbar-toggle:hover, -.navbar-default .navbar-toggle:focus { - background-color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -.navbar-default .nav li a { - text-transform: uppercase; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - font-weight: 400; - letter-spacing: 1px; - color: #fff; - -webkit-transition: all ease 0.35s; - -moz-transition: all ease 0.35s; - transition: all ease 0.35s; -} - -.navbar-default .nav li a:hover, -.navbar-default .nav li a:focus { - outline: 0; - color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -.navbar-default .navbar-nav > .active > a { - border-radius: 0; - color: #fff; - background-color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -.navbar-default .navbar-nav > .active > a:hover, -.navbar-default .navbar-nav > .active > a:focus { - color: #fff; - background-color: HelveticaNeue-Thin, Helvetica, Arial, sans-serif; -} - -@media (min-width: 768px) { - .navbar-default { - padding: 25px 0; - border: 0; - background-color: transparent; - -webkit-transition: padding 0.3s; - -moz-transition: padding 0.3s; - transition: padding 0.3s; - } - - .navbar-default .navbar-brand { - font-size: 2em; - -webkit-transition: all 0.3s; - -moz-transition: all 0.3s; - transition: all 0.3s; - } - - .navbar-default .navbar-nav > .active > a { - border-radius: 3px; - } - - .navbar-default.navbar-shrink { - padding: 10px 0; - background-color: #222; - } - - .navbar-default.navbar-shrink .navbar-brand { - font-size: 1.5em; - } -} - -header { - text-align: center; - color: #fff; - background-attachment: scroll; - /*background-image: url('../img/header-bg.png');*/ - background-position: center center; - background-repeat: none; - -webkit-background-size: cover; - -moz-background-size: cover; - background-size: cover; - -o-background-size: cover; -} - -header .intro-text { - padding-top: 100px; - padding-bottom: 50px; -} - -header .intro-text .intro-lead-in { - margin-bottom: 25px; - font-family: HelveticaNeue-Thin, Helvetica, Arial, sans-serif; - font-size: 22px; - font-style: italic; - line-height: 22px; -} - -header .intro-text .intro-heading { - margin-bottom: 25px; - text-transform: uppercase; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - font-size: 50px; - font-weight: 700; - line-height: 50px; -} - -@media (min-width: 768px) { - header .intro-text { - padding-top: 300px; - padding-bottom: 200px; - } - - header .intro-text .intro-lead-in { - margin-bottom: 25px; - font-family: HelveticaNeue-Thin, Helvetica, Arial, sans-serif; - font-size: 40px; - font-style: italic; - line-height: 40px; - } - - header .intro-text .intro-heading { - margin-bottom: 50px; - text-transform: uppercase; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - font-size: 75px; - font-weight: 700; - line-height: 75px; - } -} - -section { - padding: 100px 0; -} - -section h2.section-heading { - margin-top: 0; - margin-bottom: 15px; - font-size: 40px; -} - -section h3.section-subheading { - margin-bottom: 75px; - text-transform: none; - font-family: HelveticaNeue-Thin, Helvetica, Arial, sans-serif; - font-size: 16px; - font-style: italic; - font-weight: 400; -} - -@media (min-width: 768px) { - section { - padding: 150px 0; - } -} - -.service-heading { - margin: 15px 0; - text-transform: none; -} - -#portfolio .portfolio-item { - right: 0; - margin: 0 0 15px; -} - -#portfolio .portfolio-item .portfolio-link { - display: block; - position: relative; - margin: 0 auto; - max-width: 400px; -} - -#portfolio .portfolio-item .portfolio-link .portfolio-hover { - position: absolute; - width: 100%; - height: 100%; - opacity: 0; - -webkit-transition: all ease 0.5s; - -moz-transition: all ease 0.5s; - transition: all ease 0.5s; - background: rgba(254, 209, 54, 0.9); /* Fallback when no plugin support */ - background: rgba(var(--primary) | hex_to_rgb | join: ','}}, 0.9); -} - -#portfolio .portfolio-item .portfolio-link .portfolio-hover:hover { - opacity: 1; -} - -#portfolio - .portfolio-item - .portfolio-link - .portfolio-hover - .portfolio-hover-content { - position: absolute; - top: 50%; - width: 100%; - height: 20px; - margin-top: -12px; - text-align: center; - font-size: 20px; - color: #fff; -} - -#portfolio - .portfolio-item - .portfolio-link - .portfolio-hover - .portfolio-hover-content - i { - margin-top: -12px; -} - -#portfolio - .portfolio-item - .portfolio-link - .portfolio-hover - .portfolio-hover-content - h3, -#portfolio - .portfolio-item - .portfolio-link - .portfolio-hover - .portfolio-hover-content - h4 { - margin: 0; -} - -#portfolio .portfolio-item .portfolio-caption { - margin: 0 auto; - padding: 25px; - max-width: 400px; - text-align: center; - background-color: #fff; -} - -#portfolio .portfolio-item .portfolio-caption h4 { - margin: 0; - text-transform: none; -} - -#portfolio .portfolio-item .portfolio-caption p { - margin: 0; - font-family: HelveticaNeue-Thin, Helvetica, Arial, sans-serif; - font-size: 16px; - font-style: italic; -} - -#portfolio * { - z-index: 2; -} - -@media (min-width: 767px) { - #portfolio .portfolio-item { - margin: 0 0 30px; - } -} - -.timeline { - position: relative; - padding: 0; - list-style: none; -} - -.timeline:before { - content: ''; - position: absolute; - top: 0; - bottom: 0; - left: 40px; - width: 2px; - margin-left: -1.5px; - background-color: #f1f1f1; -} - -.timeline > li { - position: relative; - margin-bottom: 50px; - min-height: 50px; -} - -.timeline > li:before, -.timeline > li:after { - content: ' '; - display: table; -} - -.timeline > li:after { - clear: both; -} - -.timeline > li .timeline-panel { - float: right; - position: relative; - width: 100%; - padding: 0 20px 0 100px; - text-align: left; -} - -.timeline > li .timeline-panel:before { - right: auto; - left: -15px; - border-right-width: 15px; - border-left-width: 0; -} - -.timeline > li .timeline-panel:after { - right: auto; - left: -14px; - border-right-width: 14px; - border-left-width: 0; -} - -.timeline > li .timeline-image { - z-index: 100; - position: absolute; - left: 0; - width: 80px; - height: 80px; - margin-left: 0; - border: 7px solid #f1f1f1; - border-radius: 100%; - text-align: center; - color: #fff; - background-color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -.timeline > li .timeline-image h4 { - margin-top: 12px; - font-size: 10px; - line-height: 14px; -} - -.timeline > li.timeline-inverted > .timeline-panel { - float: right; - padding: 0 20px 0 100px; - text-align: left; -} - -.timeline > li.timeline-inverted > .timeline-panel:before { - right: auto; - left: -15px; - border-right-width: 15px; - border-left-width: 0; -} - -.timeline > li.timeline-inverted > .timeline-panel:after { - right: auto; - left: -14px; - border-right-width: 14px; - border-left-width: 0; -} - -.timeline > li:last-child { - margin-bottom: 0; -} - -.timeline .timeline-heading h4 { - margin-top: 0; - color: inherit; -} - -.timeline .timeline-heading h4.subheading { - text-transform: none; -} - -.timeline .timeline-body > p, -.timeline .timeline-body > ul { - margin-bottom: 0; -} - -@media (min-width: 768px) { - .timeline:before { - left: 50%; - } - - .timeline > li { - margin-bottom: 100px; - min-height: 100px; - } - - .timeline > li .timeline-panel { - float: left; - width: 41%; - padding: 0 20px 20px 30px; - text-align: right; - } - - .timeline > li .timeline-image { - left: 50%; - width: 100px; - height: 100px; - margin-left: -50px; - } - - .timeline > li .timeline-image h4 { - margin-top: 16px; - font-size: 13px; - line-height: 18px; - } - - .timeline > li.timeline-inverted > .timeline-panel { - float: right; - padding: 0 30px 20px 20px; - text-align: left; - } -} - -@media (min-width: 992px) { - .timeline > li { - min-height: 150px; - } - - .timeline > li .timeline-panel { - padding: 0 20px 20px; - } - - .timeline > li .timeline-image { - width: 150px; - height: 150px; - margin-left: -75px; - } - - .timeline > li .timeline-image h4 { - margin-top: 30px; - font-size: 18px; - line-height: 26px; - } - - .timeline > li.timeline-inverted > .timeline-panel { - padding: 0 20px 20px; - } -} - -@media (min-width: 1200px) { - .timeline > li { - min-height: 170px; - } - - .timeline > li .timeline-panel { - padding: 0 20px 20px 100px; - } - - .timeline > li .timeline-image { - width: 170px; - height: 170px; - margin-left: -85px; - } - - .timeline > li .timeline-image h4 { - margin-top: 40px; - } - - .timeline > li.timeline-inverted > .timeline-panel { - padding: 0 100px 20px 20px; - } -} - -.team-member { - margin-bottom: 50px; - text-align: center; -} - -.team-member img { - margin: 0 auto; - border: 7px solid #fff; -} - -.team-member h4 { - margin-top: 25px; - margin-bottom: 0; - text-transform: none; -} - -.team-member p { - margin-top: 0; -} - -aside.clients img { - margin: 50px auto; -} - -section#contact { - background-color: #222; - /* background-image: url('../img/map-image.png'); */ - background-position: center; - background-repeat: no-repeat; -} - -section#contact .section-heading { - color: #fff; -} - -section#contact .form-group { - margin-bottom: 25px; -} - -section#contact .form-group input, -section#contact .form-group textarea { - padding: 20px; -} - -section#contact .form-group input.form-control { - height: auto; -} - -section#contact .form-group textarea.form-control { - height: 236px; -} - -section#contact .form-control:focus { - border-color: HelveticaNeue, Helvetica, Arial, sans-serif; - box-shadow: none; -} - -section#contact::-webkit-input-placeholder { - text-transform: uppercase; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - font-weight: 700; - color: #bbb; -} - -section#contact:-moz-placeholder { - text-transform: uppercase; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - font-weight: 700; - color: #bbb; -} - -section#contact::-moz-placeholder { - text-transform: uppercase; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - font-weight: 700; - color: #bbb; -} - -section#contact:-ms-input-placeholder { - text-transform: uppercase; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - font-weight: 700; - color: #bbb; -} - -section#contact .text-danger { - color: #e74c3c; -} - -footer { - padding: 25px 0; - text-align: center; -} - -footer span.copyright { - text-transform: uppercase; - text-transform: none; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - line-height: 40px; -} - -footer ul.quicklinks { - margin-bottom: 0; - text-transform: uppercase; - text-transform: none; - font-family: HelveticaNeue, Helvetica, Arial, sans-serif; - line-height: 40px; -} - -ul.social-buttons { - margin-bottom: 0; -} - -ul.social-buttons li a { - display: block; - width: 40px; - height: 40px; - border-radius: 100%; - font-size: 20px; - line-height: 40px; - outline: 0; - color: #fff; - background-color: #222; - -webkit-transition: all 0.3s; - -moz-transition: all 0.3s; - transition: all 0.3s; -} - -ul.social-buttons li a:hover, -ul.social-buttons li a:focus, -ul.social-buttons li a:active { - background-color: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -.btn:focus, -.btn:active, -.btn.active, -.btn:active:focus { - outline: 0; -} - -.portfolio-modal .modal-content { - padding: 100px 0; - min-height: 100%; - border: 0; - border-radius: 0; - text-align: center; - background-clip: border-box; - -webkit-box-shadow: none; - box-shadow: none; -} - -.portfolio-modal .modal-content h2 { - margin-bottom: 15px; - font-size: 3em; -} - -.portfolio-modal .modal-content p { - margin-bottom: 30px; -} - -.portfolio-modal .modal-content p.item-intro { - margin: 20px 0 30px; - font-family: HelveticaNeue-Thin, Helvetica, Arial, sans-serif; - font-size: 16px; - font-style: italic; -} - -.portfolio-modal .modal-content ul.list-inline { - margin-top: 0; - margin-bottom: 30px; -} - -.portfolio-modal .modal-content img { - margin-bottom: 30px; -} - -.portfolio-modal .close-modal { - position: absolute; - top: 25px; - right: 25px; - width: 75px; - height: 75px; - background-color: transparent; - cursor: pointer; -} - -.portfolio-modal .close-modal:hover { - opacity: 0.3; -} - -.portfolio-modal .close-modal .lr { - z-index: 1051; - width: 1px; - height: 75px; - margin-left: 35px; - background-color: #222; - -webkit-transform: rotate(45deg); - -ms-transform: rotate(45deg); - transform: rotate(45deg); -} - -.portfolio-modal .close-modal .lr .rl { - z-index: 1052; - width: 1px; - height: 75px; - background-color: #222; - -webkit-transform: rotate(90deg); - -ms-transform: rotate(90deg); - transform: rotate(90deg); -} - -::-moz-selection { - text-shadow: none; - background: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -::selection { - text-shadow: none; - background: HelveticaNeue, Helvetica, Arial, sans-serif; -} - -img::selection { - background: 0 0; -} - -img::-moz-selection { - background: 0 0; -} - -body { - webkit-tap-highlight-color: HelveticaNeue, Helvetica, Arial, sans-serif; -} diff --git a/client/js/app/src/app/styles/theme/components.js b/client/js/app/src/app/styles/theme/components.js new file mode 100644 index 00000000000..0994ad322d0 --- /dev/null +++ b/client/js/app/src/app/styles/theme/components.js @@ -0,0 +1,10 @@ +export const components = { + AppShell: { + styles: () => ({ + main: { + maxWidth: '1920px', + margin: '0 auto', + }, + }), + }, +}; diff --git a/client/js/app/src/app/styles/theme/index.js b/client/js/app/src/app/styles/theme/index.js index fbd74bf13fc..2c69eb2af81 100644 --- a/client/js/app/src/app/styles/theme/index.js +++ b/client/js/app/src/app/styles/theme/index.js @@ -1,6 +1,7 @@ import { common } from 'app/styles/theme/common'; +import { components } from 'app/styles/theme/components'; import { commonColors } from 'app/styles/theme/common-colors'; export const getTheme = () => { - return { ...common, colors: commonColors }; + return { ...common, components, colors: commonColors }; }; diff --git a/client/js/app/src/app/styles/vespa.css b/client/js/app/src/app/styles/vespa.css deleted file mode 100644 index 4017f0275c3..00000000000 --- a/client/js/app/src/app/styles/vespa.css +++ /dev/null @@ -1,752 +0,0 @@ -/** -* Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -* Based on vespa.css from https://github.com/vespa-engine/frontpage for header- and footer-elements -*/ -:root { - --primary: #188fff; - --secondary: #003abc; - --secondary-dark: #333; - --muted: #777; - - --fontprimary: 'Hind Madurai', Helvetica, Arial, sans-serif; - --fontsecondary: 'Hind Madurai', Helvetica, Arial, sans-serif; -} - -.bg-light-blue { - background-image: linear-gradient( - -1deg, - rgba(63, 157, 216, 0.08) 0%, - rgba(163, 195, 215, 0.08) 97% - ); -} - -.yql { -} - -.yql:focus { - outline: none; -} - -.information { - margin-left: -40px; - margin-right: 28px; - margin-top: -2.5px; - opacity: 0.6; - transition: transform 0.1s; /* Animation */ -} - -.information:hover { - transform: scale(1.05); -} - -/*** Tooltips! ***/ -.tip { - visibility: visible; - border-bottom: 1px dotted; - position: relative; - cursor: help; - text-decoration: none; - color: #fff !important; -} -.tip span { - display: none; - z-index: 100; - position: absolute; - padding: 0.6em; - padding-left: 1em; - top: 1.5em; - left: 2.4em; - width: 15em; - background-color: #4da2d6; - border: 1px solid #ffffff; - border-radius: 0.5em; -} - -.tip span td { - text-align: left; - vertical-align: top; - padding-left: 5px; -} - -.tip span a { - text-decoration: none; - color: white; -} - -.tip:hover span { - display: inline-block; -} -.sg-question-set, -.sg-type-radio ul.sg-list-vertical li, -.sg-type-checkbox ul.sg-list-vertical li, -.sg-question-options, -.sg-type-radio-likert .sg-question-options, -.sg-type-table .sg-question-options, -.sg-instructions { - overflow: visible; -} - -section h2.section-heading, -section h2.section-subheading, -section h3.section-heading, -section h3.section-subheading { - text-transform: none; - font-family: 'Hind Madurai', Helvetica, Arial, sans-serif; - font-weight: normal; - font-style: normal; -} - -section h2.section-heading, -section h3.section-heading { - font-size: 50px; - color: #3f9dd8; - margin-bottom: 5px; -} - -section h2.section-subheading, -section h3.section-subheading { - line-height: 26px; - margin-top: 0; -} - -header .help-title { - color: #ffc43c; - text-transform: uppercase; - font-weight: bold; -} - -.text-muted { - color: #303030; -} - -#banner { - background-color: #336699; - color: #ffffff; - font-weight: bold; - padding-bottom: 2px; - padding-top: 2px; - width: 100%; -} - -#banner a { - color: #ffffff; - text-decoration: underline; -} - -.navbar-default { - background-color: #005a8e; - padding: 0; - border-bottom: 2px solid rgba(255, 255, 255, 0.2); -} - -.navbar-default .navbar-header { - margin-left: 13px; -} - -.navbar-default .navbar-brand { - background: transparent url('https://vespa.ai/assets/vespa-logo.png') - no-repeat; - background-size: contain; - direction: ltr; - text-indent: -9000px; - height: 28px; - width: 100px; - display: inline-block; - font-family: 'Hind Madurai', Helvetica, Arial, sans-serif; - font-weight: bold; - color: var(--primary); - margin-top: 16px; - margin-left: 10px; -} - -.navbar-nav .nav-link { - font-weight: bold; - font-size: 14px; - letter-spacing: 1px; - color: #ffffff; - text-transform: none; - font-family: 'Hind Madurai', Helvetica, Arial, sans-serif; -} - -.navbar-default .navbar-nav > a:hover, -.navbar-default .navbar-nav > .active > a, -.navbar-default .navbar-nav > .active > a:hover { - color: #ffc43c; -} - -.navbar-default .navbar-toggler-icon { - background-image: url('data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 30 30%27%3e%3cpath stroke=%27rgba%280, 0, 0, 0.55%29%27 stroke-linecap=%27round%27 stroke-miterlimit=%2710%27 stroke-width=%272%27 d=%27M4 7h22M4 15h22M4 23h22%27/%3e%3c/svg%3e'); -} - -.navbar-default .navbar-toggler { - margin-right: 45px; - border: 1px solid; - border-color: #1a242f; -} -.navbar-toggler:hover, -.navbar-default .navbar-toggler:focus { - background-color: #1a242f; - box-shadow: 0 0 0 0; -} - -.navbar-toggle { - margin-right: 45px; -} - -/* Trick to prevent anchored links to hide heading behind navbar */ -section[id]:before { - display: block; - content: ' '; - margin-top: -80px; - height: 100px; - visibility: hidden; -} - -header { - /*background-image: linear-gradient(0deg, #98C1DB 7%, #3F9DD8 100%); */ - background-color: #005a8e; - min-height: 1150px; -} - -@media (max-height: 1150px) { - header { - min-height: 100vh; - } -} - -header .intro { - margin-top: -80px; - max-width: 350px; - padding-top: 10px; - padding-bottom: 50px; -} - -header .intro-logo { - max-width: 120px; - padding-bottom: 30px; -} - -header .intro-button { - box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5); - padding-left: 50px; - padding-right: 50px; -} - -header .intro-long { - line-height: 27px; - font-size: 16px; - padding-bottom: 20px; -} - -header .intro-param { - line-height: 27px; - font-size: 16px; - padding-bottom: 0px; - margin-bottom: 5px; -} -header .response { - line-height: 27px; - font-size: 20px; - padding-top: 10px; - padding-bottom: 8px; -} - -header .methodselector { - font-size: 15px; - color: #fff; - background-color: #99c1da; - width: 70px; - height: 25px; - border-width: 0px; - -o-transition: 0.3s; - -ms-transition: 0.3s; - -moz-transition: 0.3s; - -webkit-transition: 0.3s; - transition: 0.3s; -} -header .intro-help:hover { - background-color: #4ea2d6 !important; -} -header .methodselector:hover { - background-color: #79b4d8; -} -header .button:hover { - background-color: #79b4d8; -} -header .removeRow:hover { - background-color: #79b4d8; -} -header .addRow:hover { - background-color: #79b4d8; -} -header .showJSON:hover { - background-color: #79b4d8; -} -header .copyURL:hover { - background-color: #79b4d8; -} -header .copyJSON:hover { - background-color: #79b4d8; -} -header .methodselector:focus { - outline: none; -} -header .textbox:focus { - outline: none; -} -header .input:focus { - outline: none; -} -header .responsebox::selection { - background-color: grey; -} -header .textbox::selection { - background-color: grey; -} -header .input::selection { - background-color: grey; -} -header .propvalue::selection { - background-color: grey; -} -header .responsebox:focus { - outline: none; -} -header .responseinfo:focus { - outline: none; -} -header .propvalue:focus { - outline: none; -} -header .addpropsbutton:focus { - outline: none; -} - -header .input { - color: #000; - width: 190px; - border-width: 0px; - margin-right: 2px; -} - -header .input2 { - color: #000; - width: 175px; - border-width: 0px; - margin-right: 2px; -} - -header .textbox { - color: #000; - padding-left: 2px; -} - -header .responsebox { - color: #000; - background-color: #fff; -} - -header .responseinfo { - color: #d6e6f0; - text-align: center; - border-width: 0px; - background-color: transparent; -} - -header .propvalue { - color: #000; - background-color: #fff; - width: 175px; - border-width: 0px; - margin-bottom: 3px; -} - -header .propvalue::-webkit-input-placeholder { - /* Safari, Chrome(, Opera?) */ - color: gray; - font-style: italic; -} -header .propvalue:-moz-placeholder { - /* Firefox 18- */ - color: gray; - font-style: italic; -} -header .propvalue:-moz-placeholder { - /* Firefox 19+ */ - color: gray; - font-style: italic; -} -header .propvalue-ms-input-placeholder { - /* IE (10+?) */ - color: gray; - font-style: italic; -} - -header .button { - font-size: 15px; - color: #fff; - background-color: #99c1da; - width: 70px; - height: 25px; - border-width: 0px; - border-radius: 5px; - padding: 0px; -} -header .button:focus { - outline: none; -} - -header .addpropsbutton { - font-size: 15px; - color: #fff; - background-color: #99c1da; - width: 175px; - height: 23px; - border-width: 0px; - border-radius: 5px; - padding: 0px; - margin-left: 2px; - margin-bottom: 3px; -} -header .addRow { - font-size: 15px; - color: #fff; - background-color: #99c1da; - width: 70px; - height: 25px; - border-width: 0px; - border-radius: 5px; - padding: 0px; -} -header .addRow:focus { - outline: none; -} - -header .removeRow { - font-size: 16px; - color: #fff; - background-color: #99c1da; - width: 35px; - height: 23px; - border-width: 0px; - border-radius: 5px; - padding: 0px; - padding-bottom: 2px; - margin-left: 3px; - text-align: center; - line-height: normal; -} -header .removeRow:focus { - outline: none; -} - -header .json:focus { - outline: none; -} -header .copyJSON:focus { - outline: none; -} -header .showJSON:focus { - outline: none; -} -header .copyURL:focus { - outline: none; -} -header .pasteJSON:focus { - outline: none; -} - -header .copyJSON { - font-size: 15px; - color: #fff; - background-color: #99c1da; - width: 130px; - height: 25px; - border-width: 0px; - border-radius: 5px; - padding-left: 1px; - margin-top: 10px; - margin-bottom: 20px; - margin-right: 2px; - display: none; -} - -header .showJSON { - font-size: 15px; - color: #fff; - background-color: #99c1da; - width: 140px; - height: 25px; - border-width: 0px; - border-radius: 5px; - padding: 0px; - margin-top: 5px; - margin-bottom: 10px; -} - -header .pasteJSON { - font-size: 15px; - color: #fff; - background-color: #99c1da; - width: 140px; - height: 25px; - border-width: 0px; - border-radius: 5px; - padding-left: 0px; - padding-bottom: 2px; - margin-top: 35px; - margin-bottom: 10px; -} - -header .copyURL { - font-size: 15px; - color: #fff; - background-color: #99c1da; - width: 130px; - height: 25px; - border-width: 0px; - border-radius: 5px; - padding-left: 1px; - margin-top: 25px; - margin-bottom: 10px; - margin-left: 2px; - display: none; -} - -header .intro .intro-lead-in { - font-style: normal; - font-size: 22px; - line-height: 50px; - margin-bottom: 25px; - font-family: 'Hind Madurai', Helvetica, Arial, sans-serif; -} - -header .intro .intro-heading { - font-style: normal; -} - -header .intro-button { - box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5); -} - -header .intro .btn-xl { - background: #ffffff; - border: 1px solid #3f9dd8; - border-radius: 2px; - font-size: 20px; - color: #3f9dd8; - font-weight: normal; - text-transform: none; - font-family: 'Hind Madurai', Helvetica, Arial, sans-serif; -} - -header span { - display: inline-block; - position: inherit; - margin-top: 10px; - /*padding-left: 50px;*/ - transform: translateX(-50%); - background: transparent; - border: none !important; - font-size: 0; -} - -header .intro-copy { - background: transparent; - border: none !important; - font-size: 0; -} - -header .intro-help { - display: inline-block; - margin-top: 15px; - width: 134px; - height: 45px; - background-color: transparent; - border: none !important; - font-size: 0; - - border-top-left-radius: 30%; - border-top-right-radius: 29%; - border-bottom-right-radius: 24%; - border-bottom-left-radius: 26%; -} - -header .intro-refresh { - display: inline-block; - margin-top: 15px; - /* transform: translateX(-50%); */ - background: transparent; - border: none !important; - font-size: 0; -} - -@media (min-height: 1150px) { - header .intro-down-arrow { - /* Hard code top: 1150 (height of top section) - 20 (bottom) - 36 (image height) = 1094 */ - top: 1094px; - } -} - -@media (max-height: 825px) { - header .intro-down-arrow { - display: none; - } -} - -@media (min-width: 768px) { - header .intro { - padding-top: 200px; - padding-bottom: 200px; - max-width: 620px; - } - - header .intro-logo { - max-width: 238px; - padding-bottom: 70px; - } - - header .intro .intro-lead-in { - font-size: 51px; - font-style: normal; - line-height: 50px; - } - - header .intro .intro-long { - margin-left: 80px; - margin-right: 80px; - } - - header .intro .intro-heading { - margin-bottom: 25px; - font-size: 90px; - font-weight: 600; - } -} - -section { - padding: 50px 0; -} - -section h3.section-subheading { - margin-bottom: 50px; - font-weight: normal; -} - -@media (min-width: 768px) { - section { - padding: 50px 0; - } -} - -footer .row { - font-size: 12px; - text-align: left; -} - -footer .row h4 { - font-size: 14px; - padding-left: 40px; -} - -footer .row .quicklinks { - line-height: 25px; - list-style: none; - text-align: left; -} - -footer .credits { - font-size: 10px; - text-align: center; -} - -#description p { - font-weight: 300; - font-size: 25px; -} - -footer { - font-size: 14px; - color: #ffffff; - background-color: #3f9dd8; - line-height: 22px; - letter-spacing: 0; - text-align: left; - display: flex; - flex-wrap: wrap; -} - -footer .footer-row { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - flex-wrap: wrap; -} - -footer quicklinks { - font-size: 14px; - color: #ffffff; -} - -footer ul.quicklinks { - margin: 0; - padding: 0; -} - -footer .footer-title { - color: #ffc43c; - text-transform: uppercase; - font-weight: bold; -} - -footer ul.quicklinks a { - font-size: 14px; - color: #ffffff; -} - -footer .quicklink-section { - padding: 0; - min-width: 120px; -} - -footer .credits { - float: left; - font-size: 12px; - font-weight: normal; - text-align: right; - font-family: 'Hind Madurai', Helvetica, Arial, sans-serif; -} - -footer .credits a { - color: #ffffff; -} - -footer .credits span { - color: #ffc43c; -} - -footer a { - text-decoration: none; -} - -footer .table { - width: fit-content; - margin-right: auto; - margin-left: auto; - float: left; - margin-bottom: 0em; -} - -footer .table tbody th { - font-size: 13px; - padding-right: 2em; -} - -footer table thead { - color: #ffc43c; -} - -footer table tbody a { - color: #ffffff; -} diff --git a/client/js/app/yarn.lock b/client/js/app/yarn.lock index 6ef7814c807..39a2213d77c 100644 --- a/client/js/app/yarn.lock +++ b/client/js/app/yarn.lock @@ -10,335 +10,444 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== dependencies: - "@babel/highlight" "^7.16.7" + "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.17.10": - version "7.18.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.5.tgz#acac0c839e317038c73137fbb6ef71a1d6238471" - integrity sha512-BxhE40PVCBxVEJsSBhB6UWyAuqJRxGsAw8BdHMJ3AKGydcwuWW4kOO3HmqBQAdcq/OP+/DlTVxLvsCzRTnZuGg== +"@babel/compat-data@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== -"@babel/core@^7.17.10": - version "7.18.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.5.tgz#c597fa680e58d571c28dda9827669c78cdd7f000" - integrity sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ== +"@babel/core@^7.1.0", "@babel/core@^7.11.6", "@babel/core@^7.12.17", "@babel/core@^7.12.3", "@babel/core@^7.17.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8" + integrity sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw== dependencies: "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.18.2" - "@babel/helper-compilation-targets" "^7.18.2" - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helpers" "^7.18.2" - "@babel/parser" "^7.18.5" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.18.5" - "@babel/types" "^7.18.4" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.10" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.10" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.18.10" + "@babel/types" "^7.18.10" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.1" semver "^6.3.0" -"@babel/generator@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.2.tgz#33873d6f89b21efe2da63fe554460f3df1c5880d" - integrity sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw== +"@babel/generator@^7.18.10", "@babel/generator@^7.7.2": + version "7.18.12" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.12.tgz#fa58daa303757bd6f5e4bbca91b342040463d9f4" + integrity sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg== dependencies: - "@babel/types" "^7.18.2" - "@jridgewell/gen-mapping" "^0.3.0" + "@babel/types" "^7.18.10" + "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" - integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== +"@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" -"@babel/helper-compilation-targets@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz#67a85a10cbd5fc7f1457fec2e7f45441dc6c754b" - integrity sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ== +"@babel/helper-compilation-targets@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" + integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== dependencies: - "@babel/compat-data" "^7.17.10" - "@babel/helper-validator-option" "^7.16.7" + "@babel/compat-data" "^7.18.8" + "@babel/helper-validator-option" "^7.18.6" browserslist "^4.20.2" semver "^6.3.0" -"@babel/helper-environment-visitor@^7.16.7", "@babel/helper-environment-visitor@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz#8a6d2dedb53f6bf248e31b4baf38739ee4a637bd" - integrity sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ== +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== -"@babel/helper-function-name@^7.17.9": - version "7.17.9" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" - integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== +"@babel/helper-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" + integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== dependencies: - "@babel/template" "^7.16.7" - "@babel/types" "^7.17.0" + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.9" -"@babel/helper-hoist-variables@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" - integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" -"@babel/helper-module-imports@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" - integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== +"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" + integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.8.0": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f" + integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w== + +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" -"@babel/helper-module-transforms@^7.18.0": - version "7.18.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz#baf05dec7a5875fb9235bd34ca18bad4e21221cd" - integrity sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA== +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.18.0" - "@babel/types" "^7.18.0" - -"@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz#86c2347da5acbf5583ba0a10aed4c9bf9da9cf96" - integrity sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA== - -"@babel/helper-simple-access@^7.17.7": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz#4dc473c2169ac3a1c9f4a51cfcd091d1c36fcff9" - integrity sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ== - dependencies: - "@babel/types" "^7.18.2" - -"@babel/helper-split-export-declaration@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" - integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== - dependencies: - "@babel/types" "^7.16.7" - -"@babel/helper-validator-identifier@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" - integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== - -"@babel/helper-validator-option@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" - integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== - -"@babel/helpers@^7.18.2": - version "7.18.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.2.tgz#970d74f0deadc3f5a938bfa250738eb4ac889384" - integrity sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg== - dependencies: - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.18.2" - "@babel/types" "^7.18.2" - -"@babel/highlight@^7.16.7": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.12.tgz#257de56ee5afbd20451ac0a75686b6b404257351" - integrity sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg== - dependencies: - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/types" "^7.18.6" + +"@babel/helper-string-parser@^7.18.10": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" + integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== + +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helpers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" + integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== + dependencies: + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.16.7", "@babel/parser@^7.18.5": - version "7.18.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.5.tgz#337062363436a893a2d22faa60be5bb37091c83c" - integrity sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.18.10", "@babel/parser@^7.18.11": + version "7.18.11" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9" + integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ== -"@babel/plugin-syntax-jsx@^7.17.12": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.17.12.tgz#834035b45061983a491f60096f61a2e7c5674a47" - integrity sha512-spyY3E3AURfxh/RHtjx5j6hs8am5NbUBGfcZ2vB3uShSpZdQyXSf5rR5Mk76vbtlAZOelyVQ71Fg0x9SG4fsog== +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-transform-react-jsx-development@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz#43a00724a3ed2557ed3f276a01a929e6686ac7b8" - integrity sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A== +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== dependencies: - "@babel/plugin-transform-react-jsx" "^7.16.7" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-transform-react-jsx-self@^7.16.7": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.17.12.tgz#7f2e9b8c08d6a4204733138d8c29d4dba4bb66c2" - integrity sha512-7S9G2B44EnYOx74mue02t1uD8ckWZ/ee6Uz/qfdzc35uWHX5NgRy9i+iJSb2LFRgMd+QV9zNcStQaazzzZ3n3Q== +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-react-jsx-source@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.16.7.tgz#1879c3f23629d287cc6186a6c683154509ec70c0" - integrity sha512-rONFiQz9vgbsnaMtQlZCjIRwhJvlrPET8TabIUK2hzlXw9B9s2Ieaxte1SCOOXMbWRHodbKixNf3BLcWVOQ8Bw== +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-jsx@^7.16.7", "@babel/plugin-transform-react-jsx@^7.17.3": - version "7.17.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.12.tgz#2aa20022709cd6a3f40b45d60603d5f269586dba" - integrity sha512-Lcaw8bxd1DKht3thfD4A12dqo1X16he1Lm8rIv8sTwjAYNInRS1qHa9aJoqvzpscItXvftKDCfaEQzwoVyXpEQ== +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/plugin-syntax-jsx" "^7.17.12" - "@babel/types" "^7.17.12" + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.17.12", "@babel/plugin-syntax-jsx@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/runtime@^7.10.2", "@babel/runtime@^7.13.10", "@babel/runtime@^7.7.6": - version "7.18.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4" - integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug== +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== dependencies: - regenerator-runtime "^0.13.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" + integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-modules-commonjs@^7.12.13": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" + integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== + dependencies: + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-react-jsx-development@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" + integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.18.6" + +"@babel/plugin-transform-react-jsx-self@^7.16.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.18.6.tgz#3849401bab7ae8ffa1e3e5687c94a753fc75bda7" + integrity sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/runtime@^7.13.16", "@babel/runtime@^7.17.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.7": +"@babel/plugin-transform-react-jsx-source@^7.16.7": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.6.tgz#6a1ef59f838debd670421f8c7f2cbb8da9751580" - integrity sha512-t9wi7/AW6XtKahAe20Yw0/mMljKq0B1r2fPdvaAdV/KPDZewFXdaaa6K7lxmZBZ8FBNpCiAT6iHPmd6QO9bKfQ== + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.18.6.tgz#06e9ae8a14d2bc19ce6e3c447d842032a50598fc" + integrity sha512-utZmlASneDfdaMh0m/WausbjUjEdGrQJz0vFK93d7wD3xf5wBtX219+q6IlCNZeguIcxS2f/CvLZrlLSvSHQXw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-react-jsx@^7.17.3", "@babel/plugin-transform-react-jsx@^7.18.6": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.18.10.tgz#ea47b2c4197102c196cbd10db9b3bb20daa820f1" + integrity sha512-gCy7Iikrpu3IZjYZolFE4M1Sm+nrh1/6za2Ewj77Z+XirT4TsbJcvOFOyF+fRPwU6AKKK136CZxx6L8AbSFG6A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-jsx" "^7.18.6" + "@babel/types" "^7.18.10" + +"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.7": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" + integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" - integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/parser" "^7.16.7" - "@babel/types" "^7.16.7" - -"@babel/traverse@^7.18.0", "@babel/traverse@^7.18.2", "@babel/traverse@^7.18.5": - version "7.18.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.5.tgz#94a8195ad9642801837988ab77f36e992d9a20cd" - integrity sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA== - dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.18.2" - "@babel/helper-environment-visitor" "^7.18.2" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.18.5" - "@babel/types" "^7.18.4" +"@babel/template@^7.18.10", "@babel/template@^7.18.6", "@babel/template@^7.3.3": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" + +"@babel/traverse@^7.18.10", "@babel/traverse@^7.18.9", "@babel/traverse@^7.7.2": + version "7.18.11" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.11.tgz#3d51f2afbd83ecf9912bcbb5c4d94e3d2ddaa16f" + integrity sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.10" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.11" + "@babel/types" "^7.18.10" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.16.7", "@babel/types@^7.17.0", "@babel/types@^7.17.12", "@babel/types@^7.18.0", "@babel/types@^7.18.2", "@babel/types@^7.18.4": - version "7.18.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.4.tgz#27eae9b9fd18e9dccc3f9d6ad051336f307be354" - integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw== +"@babel/types@^7.0.0", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.10.tgz#4908e81b6b339ca7c6b7a555a5fc29446f26dde6" + integrity sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ== dependencies: - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/helper-string-parser" "^7.18.10" + "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" -"@emotion/cache@11.7.1": - version "11.7.1" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.7.1.tgz#08d080e396a42e0037848214e8aa7bf879065539" - integrity sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A== +"@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" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@cnakazawa/watch@^1.0.3": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" + integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + +"@emotion/babel-plugin@^11.10.0": + version "11.10.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.10.0.tgz#ae545b8faa6b42d3a50ec86b70b758296f3c4467" + integrity sha512-xVnpDAAbtxL1dsuSelU5A7BnY/lftws0wUexNJZTPsvX/1tM4GZJbclgODhvW4E+NH7E5VFcH0bBn30NvniPJA== dependencies: - "@emotion/memoize" "^0.7.4" - "@emotion/sheet" "^1.1.0" - "@emotion/utils" "^1.0.0" - "@emotion/weak-memoize" "^0.2.5" + "@babel/helper-module-imports" "^7.16.7" + "@babel/plugin-syntax-jsx" "^7.17.12" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.0" + "@emotion/memoize" "^0.8.0" + "@emotion/serialize" "^1.1.0" + babel-plugin-macros "^3.1.0" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" stylis "4.0.13" -"@emotion/cache@^11.7.1": - version "11.9.3" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.9.3.tgz#96638449f6929fd18062cfe04d79b29b44c0d6cb" - integrity sha512-0dgkI/JKlCXa+lEXviaMtGBL0ynpx4osh7rjOXE71q9bIF8G+XhJgvi+wDu0B0IdCVx37BffiwXlN9I3UuzFvg== +"@emotion/cache@^11.10.0": + version "11.10.1" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.10.1.tgz#75a157c2a6bb9220450f73ebef1df2e1467dc65d" + integrity sha512-uZTj3Yz5D69GE25iFZcIQtibnVCFsc/6+XIozyL3ycgWvEdif2uEw9wlUt6umjLr4Keg9K6xRPHmD8LGi+6p1A== dependencies: - "@emotion/memoize" "^0.7.4" - "@emotion/sheet" "^1.1.1" - "@emotion/utils" "^1.0.0" - "@emotion/weak-memoize" "^0.2.5" + "@emotion/memoize" "^0.8.0" + "@emotion/sheet" "^1.2.0" + "@emotion/utils" "^1.2.0" + "@emotion/weak-memoize" "^0.3.0" stylis "4.0.13" -"@emotion/hash@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" - integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== - -"@emotion/memoize@^0.7.4": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50" - integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ== +"@emotion/hash@^0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.0.tgz#c5153d50401ee3c027a57a177bc269b16d889cb7" + integrity sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ== -"@emotion/react@11.7.1": - version "11.7.1" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.7.1.tgz#3f800ce9b20317c13e77b8489ac4a0b922b2fe07" - integrity sha512-DV2Xe3yhkF1yT4uAUoJcYL1AmrnO5SVsdfvu+fBuS7IbByDeTVx9+wFmvx9Idzv7/78+9Mgx2Hcmr7Fex3tIyw== - dependencies: - "@babel/runtime" "^7.13.10" - "@emotion/cache" "^11.7.1" - "@emotion/serialize" "^1.0.2" - "@emotion/sheet" "^1.1.0" - "@emotion/utils" "^1.0.0" - "@emotion/weak-memoize" "^0.2.5" +"@emotion/memoize@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" + integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== + +"@emotion/react@^11": + version "11.10.0" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.0.tgz#53c577f063f26493f68a05188fb87528d912ff2e" + integrity sha512-K6z9zlHxxBXwN8TcpwBKcEsBsOw4JWCCmR+BeeOWgqp8GIU1yA2Odd41bwdAAr0ssbQrbJbVnndvv7oiv1bZeQ== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.10.0" + "@emotion/cache" "^11.10.0" + "@emotion/serialize" "^1.1.0" + "@emotion/utils" "^1.2.0" + "@emotion/weak-memoize" "^0.3.0" hoist-non-react-statics "^3.3.1" -"@emotion/serialize@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.0.2.tgz#77cb21a0571c9f68eb66087754a65fa97bfcd965" - integrity sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A== - dependencies: - "@emotion/hash" "^0.8.0" - "@emotion/memoize" "^0.7.4" - "@emotion/unitless" "^0.7.5" - "@emotion/utils" "^1.0.0" - csstype "^3.0.2" - -"@emotion/serialize@^1.0.2": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.0.4.tgz#ff31fd11bb07999611199c2229e152faadc21a3c" - integrity sha512-1JHamSpH8PIfFwAMryO2bNka+y8+KA5yga5Ocf2d7ZEiJjb7xlLW7aknBGZqJLajuLOvJ+72vN+IBSwPlXD1Pg== +"@emotion/serialize@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.0.tgz#b1f97b1011b09346a40e9796c37a3397b4ea8ea8" + integrity sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA== dependencies: - "@emotion/hash" "^0.8.0" - "@emotion/memoize" "^0.7.4" - "@emotion/unitless" "^0.7.5" - "@emotion/utils" "^1.0.0" + "@emotion/hash" "^0.9.0" + "@emotion/memoize" "^0.8.0" + "@emotion/unitless" "^0.8.0" + "@emotion/utils" "^1.2.0" csstype "^3.0.2" -"@emotion/sheet@^1.1.0", "@emotion/sheet@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.1.1.tgz#015756e2a9a3c7c5f11d8ec22966a8dbfbfac787" - integrity sha512-J3YPccVRMiTZxYAY0IOq3kd+hUP8idY8Kz6B/Cyo+JuXq52Ek+zbPbSQUrVQp95aJ+lsAW7DPL1P2Z+U1jGkKA== +"@emotion/sheet@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.0.tgz#771b1987855839e214fc1741bde43089397f7be5" + integrity sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w== -"@emotion/unitless@^0.7.5": - version "0.7.5" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" - integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== +"@emotion/unitless@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.0.tgz#a4a36e9cbdc6903737cd20d38033241e1b8833db" + integrity sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw== -"@emotion/utils@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.0.0.tgz#abe06a83160b10570816c913990245813a2fd6af" - integrity sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA== +"@emotion/utils@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.0.tgz#9716eaccbc6b5ded2ea5a90d65562609aab0f561" + integrity sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw== -"@emotion/utils@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.1.0.tgz#86b0b297f3f1a0f2bdb08eeac9a2f49afd40d0cf" - integrity sha512-iRLa/Y4Rs5H/f2nimczYmS5kFJEbpiVvgN3XVfZ022IYhuNA1IRSHEizcof88LtCTXtl9S2Cxt32KgaXEu72JQ== +"@emotion/weak-memoize@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" + integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== -"@emotion/weak-memoize@^0.2.5": - version "0.2.5" - resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" - integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== +"@esbuild/linux-loong64@0.14.54": + version "0.14.54" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028" + integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw== "@eslint/eslintrc@^1.3.0": version "1.3.0" @@ -355,53 +464,328 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@fortawesome/fontawesome-common-types@6.1.1": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.1.1.tgz#7dc996042d21fc1ae850e3173b5c67b0549f9105" - integrity sha512-wVn5WJPirFTnzN6tR95abCx+ocH+3IFLXAgyavnf9hUmN0CfWoDjPT/BAWsUVwSlYYVBeCLJxaqi7ZGe4uSjBA== +"@floating-ui/core@^0.7.3": + version "0.7.3" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-0.7.3.tgz#d274116678ffae87f6b60e90f88cc4083eefab86" + integrity sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg== + +"@floating-ui/dom@^0.5.3": + version "0.5.4" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-0.5.4.tgz#4eae73f78bcd4bd553ae2ade30e6f1f9c73fe3f1" + integrity sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg== + dependencies: + "@floating-ui/core" "^0.7.3" + +"@floating-ui/react-dom-interactions@0.6.6": + version "0.6.6" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom-interactions/-/react-dom-interactions-0.6.6.tgz#8542e8c4bcbee2cd0d512de676c6a493e0a2d168" + integrity sha512-qnao6UPjSZNHnXrF+u4/n92qVroQkx0Umlhy3Avk1oIebm/5ee6yvDm4xbHob0OjY7ya8WmUnV3rQlPwX3Atwg== + dependencies: + "@floating-ui/react-dom" "^0.7.2" + aria-hidden "^1.1.3" + use-isomorphic-layout-effect "^1.1.1" + +"@floating-ui/react-dom@^0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-0.7.2.tgz#0bf4ceccb777a140fc535c87eb5d6241c8e89864" + integrity sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg== + dependencies: + "@floating-ui/dom" "^0.5.3" + use-isomorphic-layout-effect "^1.1.1" + +"@fortawesome/fontawesome-common-types@6.1.2": + version "6.1.2" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.1.2.tgz#c1095b1bbabf19f37f9ff0719db38d92a410bcfe" + integrity sha512-wBaAPGz1Awxg05e0PBRkDRuTsy4B3dpBm+zreTTyd9TH4uUM27cAL4xWyWR0rLJCrRwzVsQ4hF3FvM6rqydKPA== "@fortawesome/fontawesome-svg-core@^6": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.1.1.tgz#3424ec6182515951816be9b11665d67efdce5b5f" - integrity sha512-NCg0w2YIp81f4V6cMGD9iomfsIj7GWrqmsa0ZsPh59G7PKiGN1KymZNxmF00ssuAlo/VZmpK6xazsGOwzKYUMg== + version "6.1.2" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.1.2.tgz#11e2e8583a7dea75d734e4d0e53d91c63fae7511" + integrity sha512-853G/Htp0BOdXnPoeCPTjFrVwyrJHpe8MhjB/DYE9XjwhnNDfuBCd3aKc2YUYbEfHEcBws4UAA0kA9dymZKGjA== dependencies: - "@fortawesome/fontawesome-common-types" "6.1.1" + "@fortawesome/fontawesome-common-types" "6.1.2" "@fortawesome/free-regular-svg-icons@^6": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.1.1.tgz#3f2f58262a839edf0643cbacee7a8a8230061c98" - integrity sha512-xXiW7hcpgwmWtndKPOzG+43fPH7ZjxOaoeyooptSztGmJxCAflHZxXNK0GcT0uEsR4jTGQAfGklDZE5NHoBhKg== + version "6.1.2" + resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.1.2.tgz#9f04009098addcc11d0d185126f058ed042c3099" + integrity sha512-xR4hA+tAwsaTHGfb+25H1gVU/aJ0Rzu+xIUfnyrhaL13yNQ7TWiI2RvzniAaB+VGHDU2a+Pk96Ve+pkN3/+TTQ== dependencies: - "@fortawesome/fontawesome-common-types" "6.1.1" + "@fortawesome/fontawesome-common-types" "6.1.2" "@fortawesome/free-solid-svg-icons@^6": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.1.1.tgz#3369e673f8fe8be2fba30b1ec274d47490a830a6" - integrity sha512-0/5exxavOhI/D4Ovm2r3vxNojGZioPwmFrKg0ZUH69Q68uFhFPs6+dhAToh6VEQBntxPRYPuT5Cg1tpNa9JUPg== + version "6.1.2" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.1.2.tgz#491d668b8a6603698d0ce1ac620f66fd22b74c84" + integrity sha512-lTgZz+cMpzjkHmCwOG3E1ilUZrnINYdqMmrkv30EC3XbRsGlbIOL8H9LaNp5SV4g0pNJDfQ4EdTWWaMvdwyLiQ== dependencies: - "@fortawesome/fontawesome-common-types" "6.1.1" + "@fortawesome/fontawesome-common-types" "6.1.2" "@fortawesome/react-fontawesome@^0": - version "0.1.18" - resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.18.tgz#dae37f718a24e14d7a99a5496c873d69af3fbd73" - integrity sha512-RwLIB4TZw0M9gvy5u+TusAA0afbwM4JQIimNH/j3ygd6aIvYPQLqXMhC9ErY26J23rDPyDZldIfPq/HpTTJ/tQ== + version "0.2.0" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz#d90dd8a9211830b4e3c08e94b63a0ba7291ddcf4" + integrity sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw== dependencies: prop-types "^15.8.1" -"@humanwhocodes/config-array@^0.9.2": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" - integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== +"@humanwhocodes/config-array@^0.10.4": + version "0.10.4" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.4.tgz#01e7366e57d2ad104feea63e72248f22015c520c" + integrity sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" minimatch "^3.0.4" +"@humanwhocodes/gitignore-to-minimatch@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" + integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== + "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" + integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + slash "^3.0.0" + +"@jest/core@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7" + integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== + dependencies: + "@jest/console" "^28.1.3" + "@jest/reporters" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^28.1.3" + jest-config "^28.1.3" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-resolve-dependencies "^28.1.3" + jest-runner "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + jest-watcher "^28.1.3" + micromatch "^4.0.4" + pretty-format "^28.1.3" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e" + integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== + dependencies: + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + jest-mock "^28.1.3" + +"@jest/expect-utils@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" + integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== + dependencies: + jest-get-type "^28.0.2" + +"@jest/expect@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72" + integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== + dependencies: + expect "^28.1.3" + jest-snapshot "^28.1.3" + +"@jest/fake-timers@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e" + integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== + dependencies: + "@jest/types" "^28.1.3" + "@sinonjs/fake-timers" "^9.1.2" + "@types/node" "*" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-util "^28.1.3" + +"@jest/globals@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333" + integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/types" "^28.1.3" + +"@jest/reporters@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a" + integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + jest-worker "^28.1.3" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + terminal-link "^2.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" + integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== + dependencies: + "@sinclair/typebox" "^0.24.1" + +"@jest/source-map@^28.1.2": + version "28.1.2" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24" + integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww== + dependencies: + "@jridgewell/trace-mapping" "^0.3.13" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" + integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== + dependencies: + "@jest/console" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3" + integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== + dependencies: + "@jest/test-result" "^28.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + slash "^3.0.0" + +"@jest/transform@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" + integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^26.6.2" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^26.6.2" + jest-regex-util "^26.0.0" + jest-util "^26.6.2" + micromatch "^4.0.2" + pirates "^4.0.1" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + +"@jest/transform@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0" + integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.1" + +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + +"@jest/types@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" + integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== + dependencies: + "@jest/schemas" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + "@jridgewell/gen-mapping@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" @@ -410,189 +794,185 @@ "@jridgewell/set-array" "^1.0.0" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/gen-mapping@^0.3.0": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz#cf92a983c83466b8c0ce9124fadeaf09f7c66ea9" - integrity sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg== +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== dependencies: - "@jridgewell/set-array" "^1.0.0" + "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" "@jridgewell/resolve-uri@^3.0.3": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz#30cd49820a962aff48c8fffc5cd760151fca61fe" - integrity sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== -"@jridgewell/set-array@^1.0.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.1.tgz#36a6acc93987adcf0ba50c66908bd0b70de8afea" - integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ== +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.13" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz#b6461fb0c2964356c469e115f504c95ad97ab88c" - integrity sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w== + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.13" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea" - integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w== +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@mantine/core@^4": - version "4.2.10" - resolved "https://registry.yarnpkg.com/@mantine/core/-/core-4.2.10.tgz#6b4973bc5c79cd077341ab2bbe327749ca3ed8c4" - integrity sha512-UCPhDcumygfBvik64VkMnBvqy0ZN9q+1AQ0fPdK8aAUvjRBWSyH0dJPL55vsK1ODboKktSEsyjHtb09DroL7fA== +"@mantine/core@^5": + version "5.1.6" + resolved "https://registry.yarnpkg.com/@mantine/core/-/core-5.1.6.tgz#98c984bf08ceeb8684a8dc7146034c85e35de9f7" + integrity sha512-ZG/ccTc+LcxcUahxMu4m3hOkAss8LetETFbZ5zsDotJTvij2lzMzNcuPebLeyxNt714VEWIXNzIUotNtGXDSGg== dependencies: - "@mantine/styles" "4.2.10" - "@popperjs/core" "^2.9.3" - "@radix-ui/react-scroll-area" "^0.1.1" - react-popper "^2.2.5" - react-textarea-autosize "^8.3.2" + "@floating-ui/react-dom-interactions" "0.6.6" + "@mantine/styles" "5.1.6" + "@mantine/utils" "5.1.6" + "@radix-ui/react-scroll-area" "1.0.0" + react-textarea-autosize "8.3.4" -"@mantine/hooks@^4": - version "4.2.10" - resolved "https://registry.yarnpkg.com/@mantine/hooks/-/hooks-4.2.10.tgz#ad55d5ad3c5814eab924dfb6fd04f9ffd44e3d30" - integrity sha512-gVYWeE4Ieu6FBwh9h/3FjcrrNzKx1k6Yw07/LSngJP0uT3fLt1gvY2p4PtPpOh7z2/RpTXBR1x+dOgEUKomYUQ== +"@mantine/hooks@^5": + version "5.1.6" + resolved "https://registry.yarnpkg.com/@mantine/hooks/-/hooks-5.1.6.tgz#07d4850d3444526268a749c965ce64eea8cb7583" + integrity sha512-wD+Cx9W00YQchudIvkiEy52e/UCB0EhTkJs2fr2JbTlfKCWfWSilE/CPbLz6NWmK58bbyB/qjdKUDwXV6qyasw== -"@mantine/styles@4.2.10": - version "4.2.10" - resolved "https://registry.yarnpkg.com/@mantine/styles/-/styles-4.2.10.tgz#967f0b09f4b3adaa23e650f9112be362ed07e953" - integrity sha512-dWwCzBLYE8CwPJSPlV3MyIuR4ET3u6O+T+VmxY0lab6w/bqflseNSh9UBIW2AUoIYtxPVDjbZfzeTw32aV8CxA== - dependencies: - "@emotion/cache" "11.7.1" - "@emotion/react" "11.7.1" - "@emotion/serialize" "1.0.2" - "@emotion/utils" "1.0.0" - clsx "^1.1.1" +"@mantine/notifications@^5": + version "5.1.6" + resolved "https://registry.yarnpkg.com/@mantine/notifications/-/notifications-5.1.6.tgz#6311c928e821fdee6963048a698fce465482a589" + integrity sha512-JT0nLOoNO/NDuB2Xn4kVOSo+4Y4F+ogrWLN7qHgpmZlRsxc/8S1DFwgubTMwvJR38AHrOVaqp1hFsqdHDww0Ow== + dependencies: + "@mantine/utils" "5.1.6" + react-transition-group "4.4.2" + +"@mantine/styles@5.1.6": + version "5.1.6" + resolved "https://registry.yarnpkg.com/@mantine/styles/-/styles-5.1.6.tgz#cfb4a33d4c38ffb499d51cd0af35abd436ebe831" + integrity sha512-7d112DIHauP+X0JaVh0uzlpVndWqw/muaz77C5hLlA8yP7gVuRWOhEqJDuTnZzNtj/utIJJDAyVM2+DHFqtQtg== + dependencies: + clsx "1.1.1" csstype "3.0.9" -"@popperjs/core@^2.10.1", "@popperjs/core@^2.9.3": - version "2.11.5" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" - integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw== +"@mantine/utils@5.1.6": + version "5.1.6" + resolved "https://registry.yarnpkg.com/@mantine/utils/-/utils-5.1.6.tgz#992cd1e8850467533aa88dc5fd933650674abf5e" + integrity sha512-y7va2keQ+TPwn2j668r889NhQWO0OhSvaxT5P8n2iBaTyPg+Xp5Jm2IE5UjI+OrZErrgmQq1sxbfg6v5vdK+0A== -"@radix-ui/number@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-0.1.0.tgz#73ad13d5cc5f75fa5e147d72e5d5d5e50d688256" - integrity sha512-rpf6QiOWLHAkM4FEMYu9i+5Jr8cKT893+R4mPpcdsy4LD7omr9JfdOqj/h/xPA5+EcVrpMMlU6rrRYpUB5UI8g== +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: - "@babel/runtime" "^7.13.10" + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" -"@radix-ui/primitive@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-0.1.0.tgz#6206b97d379994f0d1929809db035733b337e543" - integrity sha512-tqxZKybwN5Fa3VzZry4G6mXAAb9aAqKmPtnVbZpL0vsBwvOHTBwsjHVPXylocYLwEtBY9SCe665bYnNB515uoA== +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: - "@babel/runtime" "^7.13.10" + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" -"@radix-ui/react-compose-refs@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz#cff6e780a0f73778b976acff2c2a5b6551caab95" - integrity sha512-eyclbh+b77k+69Dk72q3694OHrn9B3QsoIRx7ywX341U9RK1ThgQjMFZoPtmZNQTksXHLNEiefR8hGVeFyInGg== +"@radix-ui/number@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.0.0.tgz#4c536161d0de750b3f5d55860fc3de46264f897b" + integrity sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA== dependencies: "@babel/runtime" "^7.13.10" -"@radix-ui/react-context@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-0.1.1.tgz#06996829ea124d9a1bc1dbe3e51f33588fab0875" - integrity sha512-PkyVX1JsLBioeu0jB9WvRpDBBLtLZohVDT3BB5CTSJqActma8S8030P57mWZb4baZifMvN7KKWPAA40UmWKkQg== +"@radix-ui/primitive@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.0.tgz#e1d8ef30b10ea10e69c76e896f608d9276352253" + integrity sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA== dependencies: "@babel/runtime" "^7.13.10" -"@radix-ui/react-presence@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-0.1.2.tgz#9f11cce3df73cf65bc348e8b76d891f0d54c1fe3" - integrity sha512-3BRlFZraooIUfRlyN+b/Xs5hq1lanOOo/+3h6Pwu2GMFjkGKKa4Rd51fcqGqnVlbr3jYg+WLuGyAV4KlgqwrQw== +"@radix-ui/react-compose-refs@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz#37595b1f16ec7f228d698590e78eeed18ff218ae" + integrity sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "0.1.0" - "@radix-ui/react-use-layout-effect" "0.1.0" -"@radix-ui/react-primitive@0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz#6c233cf08b0cb87fecd107e9efecb3f21861edc1" - integrity sha512-6gSl2IidySupIMJFjYnDIkIWRyQdbu/AHK7rbICPani+LW4b0XdxBXc46og/iZvuwW8pjCS8I2SadIerv84xYA== +"@radix-ui/react-context@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.0.tgz#f38e30c5859a9fb5e9aa9a9da452ee3ed9e0aee0" + integrity sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-slot" "0.1.2" -"@radix-ui/react-scroll-area@^0.1.1": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-scroll-area/-/react-scroll-area-0.1.4.tgz#be1d32c113ee9f64e3d2e7ee3983d98f00b42038" - integrity sha512-QHxRsjy+hsHwQYJ9cCNgSJ5+6ioZu1KhwD1UOXoHNciuFGMX08v+uJPKXIz+ySv03Rx6cOz6f/Fk5aPHRMFi/A== +"@radix-ui/react-direction@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.0.tgz#a2e0b552352459ecf96342c79949dd833c1e6e45" + integrity sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/number" "0.1.0" - "@radix-ui/primitive" "0.1.0" - "@radix-ui/react-compose-refs" "0.1.0" - "@radix-ui/react-context" "0.1.1" - "@radix-ui/react-presence" "0.1.2" - "@radix-ui/react-primitive" "0.1.4" - "@radix-ui/react-use-callback-ref" "0.1.0" - "@radix-ui/react-use-direction" "0.1.0" - "@radix-ui/react-use-layout-effect" "0.1.0" - -"@radix-ui/react-slot@0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-0.1.2.tgz#e6f7ad9caa8ce81cc8d532c854c56f9b8b6307c8" - integrity sha512-ADkqfL+agEzEguU3yS26jfB50hRrwf7U4VTwAOZEmi/g+ITcBWe12yM46ueS/UCIMI9Py+gFUaAdxgxafFvY2Q== + +"@radix-ui/react-presence@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.0.tgz#814fe46df11f9a468808a6010e3f3ca7e0b2e84a" + integrity sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "0.1.0" + "@radix-ui/react-compose-refs" "1.0.0" + "@radix-ui/react-use-layout-effect" "1.0.0" -"@radix-ui/react-use-callback-ref@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-0.1.0.tgz#934b6e123330f5b3a6b116460e6662cbc663493f" - integrity sha512-Va041McOFFl+aV+sejvl0BS2aeHx86ND9X/rVFmEFQKTXCp6xgUK0NGUAGcgBlIjnJSbMYPGEk1xKSSlVcN2Aw== +"@radix-ui/react-primitive@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz#376cd72b0fcd5e0e04d252ed33eb1b1f025af2b0" + integrity sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ== dependencies: "@babel/runtime" "^7.13.10" + "@radix-ui/react-slot" "1.0.0" -"@radix-ui/react-use-direction@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-direction/-/react-use-direction-0.1.0.tgz#97ac1d52e497c974389e7988f809238ed72e7df7" - integrity sha512-NajpY/An9TCPSfOVkgWIdXJV+VuWl67PxB6kOKYmtNAFHvObzIoh8o0n9sAuwSAyFCZVq211FEf9gvVDRhOyiA== +"@radix-ui/react-scroll-area@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.0.tgz#10d0262a52266af528798f36947145f7e3a3a52c" + integrity sha512-3SNFukAjS5remgtpAVR9m3Zgo23ZojBZ8V3TCyR3A+56x2mtVqKlPV4+e8rScZUFMuvtbjIdQCmsJBFBazKZig== dependencies: "@babel/runtime" "^7.13.10" - -"@radix-ui/react-use-layout-effect@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz#ebf71bd6d2825de8f1fbb984abf2293823f0f223" - integrity sha512-+wdeS51Y+E1q1Wmd+1xSSbesZkpVj4jsg0BojCbopWvgq5iBvixw5vgemscdh58ep98BwUbsFYnrywFhV9yrVg== + "@radix-ui/number" "1.0.0" + "@radix-ui/primitive" "1.0.0" + "@radix-ui/react-compose-refs" "1.0.0" + "@radix-ui/react-context" "1.0.0" + "@radix-ui/react-direction" "1.0.0" + "@radix-ui/react-presence" "1.0.0" + "@radix-ui/react-primitive" "1.0.0" + "@radix-ui/react-use-callback-ref" "1.0.0" + "@radix-ui/react-use-layout-effect" "1.0.0" + +"@radix-ui/react-slot@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.0.tgz#7fa805b99891dea1e862d8f8fbe07f4d6d0fd698" + integrity sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ== dependencies: "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.0" -"@react-aria/ssr@^3.0.1": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.2.0.tgz#88460384b43204f91c972d5b0de24ee44d6a2984" - integrity sha512-wwJFdkl+Q8NU5yJ4NvdAOqx5LM3QtUVoSjuK7Ey8jZ4WS4bB0EqT3Kr3IInBs257HzZ5nXCiKXKE4NGXXuIRWA== +"@radix-ui/react-use-callback-ref@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz#9e7b8b6b4946fe3cbe8f748c82a2cce54e7b6a90" + integrity sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg== dependencies: - "@babel/runtime" "^7.6.2" + "@babel/runtime" "^7.13.10" -"@restart/hooks@^0.4.0", "@restart/hooks@^0.4.6": - version "0.4.7" - resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.7.tgz#d79ca6472c01ce04389fc73d4a79af1b5e33cd39" - integrity sha512-ZbjlEHcG+FQtpDPHd7i4FzNNvJf2enAwZfJbpM8CW7BhmOAbsHpZe3tsHwfQUrBuyrxWqPYp2x5UMnilWcY22A== +"@radix-ui/react-use-layout-effect@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz#2fc19e97223a81de64cd3ba1dc42ceffd82374dc" + integrity sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ== dependencies: - dequal "^2.0.2" - -"@restart/ui@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@restart/ui/-/ui-1.2.0.tgz#fb90251aa25f99b41ccedc78a91d2a15f3c5e0fb" - integrity sha512-oIh2t3tG8drZtZ9SlaV5CY6wGsUViHk8ZajjhcI+74IQHyWy+AnxDv8rJR5wVgsgcgrPBUvGNkC1AEdcGNPaLQ== - dependencies: - "@babel/runtime" "^7.13.16" - "@popperjs/core" "^2.10.1" - "@react-aria/ssr" "^3.0.1" - "@restart/hooks" "^0.4.0" - "@types/warning" "^3.0.0" - dequal "^2.0.2" - dom-helpers "^5.2.0" - uncontrollable "^7.2.1" - warning "^4.0.3" + "@babel/runtime" "^7.13.10" "@rollup/pluginutils@^4.2.1": version "4.2.1" @@ -602,6 +982,84 @@ estree-walker "^2.0.1" picomatch "^2.2.2" +"@sinclair/typebox@^0.24.1": + version "0.24.28" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.28.tgz#15aa0b416f82c268b1573ab653e4413c965fe794" + integrity sha512-dgJd3HLOkLmz4Bw50eZx/zJwtBq65nms3N9VBYu5LTjJ883oBFkTyXRlCB/ZGGwqYpJJHA5zW2Ibhl5ngITfow== + +"@sinonjs/commons@^1.7.0": + version "1.8.3" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" + integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.7": + version "7.1.19" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" + integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.1" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.0.tgz#8134fd78cb39567465be65b9fdc16d378095f41f" + integrity sha512-v4Vwdko+pgymgS+A2UIaJru93zQd85vIGWObM5ekZNdXCKtDYqATlEYnWgfo86Q6I1Lh0oXnksDnMU1cwmlPDw== + dependencies: + "@babel/types" "^7.3.0" + +"@types/graceful-fs@^4.1.2", "@types/graceful-fs@^4.1.3": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" @@ -612,38 +1070,37 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== +"@types/node@*": + version "18.7.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.3.tgz#432c89796eab539b7a30b7b8801a727b585238a4" + integrity sha512-LJgzOEwWuMTBxHzgBR/fhhBOWrvBjvO+zPteUgbbuQi80rYIZHrk1mNbRUqPZqSLP2H7Rwt1EFLL/tNLD1Xx/w== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + +"@types/prettier@^2.1.5": + version "2.7.0" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.0.tgz#ea03e9f0376a4446f44797ca19d9c46c36e352dc" + integrity sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A== + "@types/prop-types@*": version "15.7.5" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== "@types/react-dom@^18": - version "18.0.5" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.5.tgz#330b2d472c22f796e5531446939eacef8378444a" - integrity sha512-OWPWTUrY/NIrjsAPkAk1wW9LZeIjSvkXRhclsFO8CZcZGCOg2G0YZy4ft+rOyYxy8B7ui5iZzi9OkDebZ7/QSA== + version "18.0.6" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.6.tgz#36652900024842b74607a17786b6662dd1e103a1" + integrity sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA== dependencies: "@types/react" "*" -"@types/react-transition-group@^4.4.4": - version "4.4.4" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e" - integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug== - dependencies: - "@types/react" "*" - -"@types/react@*": - version "18.0.13" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.13.tgz#0f5bd24a5f26593e04e450fe85ff43f51c1524ff" - integrity sha512-psqptIYQxGUFuGYwP3KCFVtPTkMpIcrqFmtKblWEUQhLuYLpHBwJkXhjp6eHfDM5IbyskY4x7qQpLedEsPkHlA== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/react@>=16.9.11", "@types/react@^18": - version "18.0.14" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.14.tgz#e016616ffff51dba01b04945610fe3671fdbe06d" - integrity sha512-x4gGuASSiWmo0xjDLpm5mPb52syZHJx02VKbqUKdLmKtAwIh63XClGsiTI1K6DO5q7ox4xAsQrU+Gl3+gGXF9Q== +"@types/react@*", "@types/react@^18": + version "18.0.17" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.17.tgz#4583d9c322d67efe4b39a935d223edcc7050ccf4" + integrity sha512-38ETy4tL+rn4uQQi7mB81G7V1g0u2ryquNmsVIOKUAEIDK+3CUjZ6rSRpdvS99dNBnkLFL83qfmtLacGOTIhwQ== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -654,10 +1111,29 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== -"@types/warning@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52" - integrity sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA== +"@types/stack-utils@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + +"@types/yargs@^15.0.0": + version "15.0.14" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" + integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs@^17.0.8": + version "17.0.11" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.11.tgz#5e10ca33e219807c0eee0f08b5efcba9b6a42c06" + integrity sha512-aB4y9UDUXTSMxmM4MH+YnuR0g5Cph3FLQBoWoMB21DSvFVAxRVEHEMx3TLh+zUZYMCQtKiqazz0Q4Rre31f/OA== + dependencies: + "@types/yargs-parser" "*" "@vitejs/plugin-react@^1": version "1.3.2" @@ -678,10 +1154,10 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.7.1: - version "8.7.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" - integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== +acorn@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" @@ -693,6 +1169,13 @@ ajv@^6.10.0, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -705,18 +1188,68 @@ ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.1.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +anymatch@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + argparse@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +aria-hidden@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.1.3.tgz#bb48de18dc84787a3c6eee113709c473c64ec254" + integrity sha512-RhVWFtKH5BiGMycI72q2RAFMLQi8JP9bLuQXgR5a8Znp7P5KOIADSJeyfI8PCVxLEp067B2HbP5JIiI/PXIZeA== + dependencies: + tslib "^1.0.0" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + array-differ@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" @@ -738,6 +1271,11 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== + array.prototype.flat@^1.2.5: version "1.3.0" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" @@ -763,11 +1301,142 @@ arrify@^2.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +babel-jest@^26.6.3: + version "26.6.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" + integrity sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA== + dependencies: + "@jest/transform" "^26.6.2" + "@jest/types" "^26.6.2" + "@types/babel__core" "^7.1.7" + babel-plugin-istanbul "^6.0.0" + babel-preset-jest "^26.6.2" + chalk "^4.0.0" + graceful-fs "^4.2.4" + slash "^3.0.0" + +babel-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" + integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== + dependencies: + "@jest/transform" "^28.1.3" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^28.1.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + +babel-plugin-istanbul@^6.0.0, babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz#8185bd030348d254c6d7dd974355e6a28b21e62d" + integrity sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + +babel-plugin-jest-hoist@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe" + integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-plugin-macros@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== + dependencies: + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz#747872b1171df032252426586881d62d31798fee" + integrity sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ== + dependencies: + babel-plugin-jest-hoist "^26.6.2" + babel-preset-current-node-syntax "^1.0.0" + +babel-preset-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" + integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== + dependencies: + babel-plugin-jest-hoist "^28.1.3" + babel-preset-current-node-syntax "^1.0.0" + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -776,16 +1445,65 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + browserslist@^4.20.2: - version "4.20.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.4.tgz#98096c9042af689ee1e0271333dbc564b8ce4477" - integrity sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw== + version "4.21.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" + integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== dependencies: - caniuse-lite "^1.0.30001349" - electron-to-chromium "^1.4.147" - escalade "^3.1.1" - node-releases "^2.0.5" - picocolors "^1.0.0" + caniuse-lite "^1.0.30001370" + electron-to-chromium "^1.4.202" + node-releases "^2.0.6" + update-browserslist-db "^1.0.5" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" @@ -800,10 +1518,27 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -caniuse-lite@^1.0.30001349: - version "1.0.30001355" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001355.tgz#e240b7177443ed0198c737a7f609536976701c77" - integrity sha512-Sd6pjJHF27LzCB7pT7qs+kuX2ndurzCzkpJl6Qct7LPSZ9jn0bkOA8mdgMgmqnQAWLVOOGjLpc+66V57eLtb1g== +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001370: + version "1.0.30001375" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001375.tgz#8e73bc3d1a4c800beb39f3163bf0190d7e5d7672" + integrity sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw== + +capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== + dependencies: + rsvp "^4.8.4" chalk@^2.0.0: version "2.4.2" @@ -830,16 +1565,68 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -classnames@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" - integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -clsx@^1.1.1: +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +ci-info@^3.2.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128" + integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg== + +cjs-module-lexer@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +clsx@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +collect-v8-coverage@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -864,19 +1651,51 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -convert-source-map@^1.7.0: +convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== dependencies: safe-buffer "~5.1.1" -cross-spawn@^7.0.0, cross-spawn@^7.0.2: +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== + +cosmiconfig@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" + integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -895,7 +1714,7 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2" integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA== -debug@^2.6.9: +debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -916,11 +1735,26 @@ debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: dependencies: ms "2.1.2" +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og== + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + define-properties@^1.1.3, define-properties@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" @@ -929,10 +1763,44 @@ define-properties@^1.1.3, define-properties@^1.1.4: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -dequal@^2.0.2: +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d" - integrity sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug== + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff-sequences@^28.1.1: + version "28.1.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" + integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" doctrine@^2.1.0: version "2.1.0" @@ -948,7 +1816,7 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-helpers@^5.0.1, dom-helpers@^5.2.0, dom-helpers@^5.2.1: +dom-helpers@^5.0.1: version "5.2.1" resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== @@ -956,10 +1824,20 @@ dom-helpers@^5.0.1, dom-helpers@^5.2.0, dom-helpers@^5.2.1: "@babel/runtime" "^7.8.7" csstype "^3.0.2" -electron-to-chromium@^1.4.147: - version "1.4.158" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.158.tgz#abbdaaf64676bfa4bc0307522125db34424a0ada" - integrity sha512-gppO3/+Y6sP432HtvwvuU8S+YYYLH4PmAYvQwqUtt9HDOmEsBwQfLnK9T8+1NIKwAS1BEygIjTaATC4H5EzvxQ== +electron-to-chromium@^1.4.202: + version "1.4.219" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.219.tgz#a7a672304b6aa4f376918d3f63a47f2c3906009a" + integrity sha512-zoQJsXOUw0ZA0YxbjkmzBumAJRtr6je5JySuL/bAoFs0DuLiLJ+5FzRF7/ZayihxR2QcewlRZVm5QZdUhwjOgA== + +emittery@^0.10.2: + version "0.10.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" + integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== end-of-stream@^1.1.0: version "1.4.4" @@ -968,6 +1846,13 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5: version "1.20.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" @@ -1013,131 +1898,141 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -esbuild-android-64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.44.tgz#62f5cb563d0ba318d898b6eb230c61ad3dc93619" - integrity sha512-dFPHBXmx385zuJULAD/Cmq/LyPRXiAWbf9ylZtY0wJ8iVyWfKYaCYxeJx8OAZUuj46ZwNa7MzW2GBAQLOeiemg== - -esbuild-android-arm64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.44.tgz#ee7fcc9f47855b3395dfd1abcc2c43d8c53e57db" - integrity sha512-qqaqqyxHXjZ/0ddKU3I3Nb7lAvVM69ELMhb8+91FyomAUmQPlHtxe+TTiWxXGHE72XEzcgTEGq4VauqLNkN22g== - -esbuild-darwin-64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.44.tgz#75ea7f594687a7189a8ba62070d42f13178e68d0" - integrity sha512-RBmtGKGY06+AW6IOJ1LE/dEeF7HH34C1/Ces9FSitU4bIbIpL4KEuQpTFoxwb4ry5s2hyw7vbPhhtyOd18FH9g== - -esbuild-darwin-arm64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.44.tgz#550631fd135688abda042f4039b962a27f3a5f78" - integrity sha512-Bmhx5Cfo4Hdb7WyyyDupTB8HPmnFZ8baLfPlzLdYvF6OzsIbV+CY+m/AWf0OQvY40BlkzCLJ/7Lfwbb71Tngmg== - -esbuild-freebsd-64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.44.tgz#f98069b964266ca79bb361cfb9d7454a05b7e8ca" - integrity sha512-O4HpWa5ZgxbNPQTF7URicLzYa+TidGlmGT/RAC3GjbGEQQYkd0R1Slyh69Yrmb2qmcOcPAgWHbNo1UhK4WmZ4w== - -esbuild-freebsd-arm64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.44.tgz#247a8553d6033a58b6c3ba4d539216300497d7f6" - integrity sha512-f0/jkAKccnDY7mg1F9l/AMzEm+VXWXK6c3IrOEmd13jyKfpTZKTIlt+yI04THPDCDZTzXHTRUBLozqp+m8Mg5Q== - -esbuild-linux-32@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.44.tgz#4b72747f9f367d3ee3c1d80bf75c617e6b109821" - integrity sha512-WSIhzLldMR7YUoEL7Ix319tC+NFmW9Pu7NgFWxUfOXeWsT0Wg484hm6bNgs7+oY2pGzg715y/Wrqi1uNOMmZJw== - -esbuild-linux-64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.44.tgz#6cd158fdd11f8d037c45139ccddb4fa5966f7ab6" - integrity sha512-zgscTrCMcRZRIsVugqBTP/B5lPLNchBlWjQ8sQq2Epnv+UDtYKgXEq1ctWAmibZNy2E9QRCItKMeIEqeTUT5kA== - -esbuild-linux-arm64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.44.tgz#f14f3c8c3501067f5b2cef7a79c9a0058092cb22" - integrity sha512-H0H/2/wgiScTwBve/JR8/o+Zhabx5KPk8T2mkYZFKQGl1hpUgC+AOmRyqy/Js3p66Wim4F4Akv3I3sJA1sKg0w== - -esbuild-linux-arm@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.44.tgz#625478cc6ea4f64f5335e7fb07f80d6f659aeb5c" - integrity sha512-laPBPwGfsbBxGw6F6jnqic2CPXLyC1bPrmnSOeJ9oEnx1rcKkizd4HWCRUc0xv+l4z/USRfx/sEfYlWSLeqoJQ== - -esbuild-linux-mips64le@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.44.tgz#593c909bb612998300af7f7db2809a63a0d62eec" - integrity sha512-ri3Okw0aleYy7o5n9zlIq+FCtq3tcMlctN6X1H1ucILjBJuH8pan2trJPKWeb8ppntFvE28I9eEXhwkWh6wYKg== - -esbuild-linux-ppc64le@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.44.tgz#8fc2fcee671e322a5d44fcf8da6889095a187df9" - integrity sha512-96TqL/MvFRuIVXz+GtCIXzRQ43ZwEk4XTn0RWUNJduXXMDQ/V1iOV28U6x6Oe3NesK4xkoKSaK2+F3VHcU8ZrA== - -esbuild-linux-riscv64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.44.tgz#cc2b7158c8345b67e74458a0ec020c80ca777046" - integrity sha512-rrK9qEp2M8dhilsPn4T9gxUsAumkITc1kqYbpyNMr9EWo+J5ZBj04n3GYldULrcCw4ZCHAJ+qPjqr8b6kG2inA== - -esbuild-linux-s390x@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.44.tgz#5a1e87d5d6236a8791026820936478f3b9cf8e35" - integrity sha512-2YmTm9BrW5aUwBSe8wIEARd9EcnOQmkHp4+IVaO09Ez/C5T866x+ABzhG0bwx0b+QRo9q97CRMaQx2Ngb6/hfw== - -esbuild-netbsd-64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.44.tgz#8afb16880b530264ce2ed9fb3df26071eb841312" - integrity sha512-zypdzPmZTCqYS30WHxbcvtC0E6e/ECvl4WueUdbdWhs2dfWJt5RtCBME664EpTznixR3lSN1MQ2NhwQF8MQryw== - -esbuild-openbsd-64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.44.tgz#a87455be446d6f5b07a60f060e1eafad454c9d4b" - integrity sha512-8J43ab9ByYl7KteC03HGQjr2HY1ge7sN04lFnwMFWYk2NCn8IuaeeThvLeNjzOYhyT3I6K8puJP0uVXUu+D1xw== - -esbuild-sunos-64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.44.tgz#74ce7d5fd815fa60fe0a85b9db7549b1dcb32804" - integrity sha512-OH1/09CGUJwffA+HNM6mqPkSIyHVC3ZnURU/4CCIx7IqWUBn1Sh1HRLQC8/TWNgcs0/1u7ygnc2pgf/AHZJ/Ow== - -esbuild-windows-32@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.44.tgz#499e1c6cb46c216bdcb62f5b006fec3999bb06a7" - integrity sha512-mCAOL9/rRqwfOfxTu2sjq/eAIs7eAXGiU6sPBnowggI7QS953Iq6o3/uDu010LwfN7zr18c/lEj6/PTwwTB3AA== - -esbuild-windows-64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.44.tgz#a8dae69a4615b17f62375859ce9536dd96940a06" - integrity sha512-AG6BH3+YG0s2Q/IfB1cm68FdyFnoE1P+GFbmgFO3tA4UIP8+BKsmKGGZ5I3+ZjcnzOwvT74bQRVrfnQow2KO5Q== - -esbuild-windows-arm64@0.14.44: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.44.tgz#db73bb68aa75a880bdaa938ccacc0f17e7a4bfea" - integrity sha512-ygYPfYE5By4Sd6szsNr10B0RtWVNOSGmZABSaj4YQBLqh9b9i45VAjVWa8tyIy+UAbKF7WGwybi2wTbSVliO8A== +esbuild-android-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz#505f41832884313bbaffb27704b8bcaa2d8616be" + integrity sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ== + +esbuild-android-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz#8ce69d7caba49646e009968fe5754a21a9871771" + integrity sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg== + +esbuild-darwin-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz#24ba67b9a8cb890a3c08d9018f887cc221cdda25" + integrity sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug== + +esbuild-darwin-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz#3f7cdb78888ee05e488d250a2bdaab1fa671bf73" + integrity sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw== + +esbuild-freebsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz#09250f997a56ed4650f3e1979c905ffc40bbe94d" + integrity sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg== + +esbuild-freebsd-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz#bafb46ed04fc5f97cbdb016d86947a79579f8e48" + integrity sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q== + +esbuild-jest@^0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/esbuild-jest/-/esbuild-jest-0.5.0.tgz#7a9964bfdecafca3b675a8aeb08193bcdba8b9d7" + integrity sha512-AMZZCdEpXfNVOIDvURlqYyHwC8qC1/BFjgsrOiSL1eyiIArVtHL8YAC83Shhn16cYYoAWEW17yZn0W/RJKJKHQ== + dependencies: + "@babel/core" "^7.12.17" + "@babel/plugin-transform-modules-commonjs" "^7.12.13" + babel-jest "^26.6.3" + +esbuild-linux-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz#e2a8c4a8efdc355405325033fcebeb941f781fe5" + integrity sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw== + +esbuild-linux-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz#de5fdba1c95666cf72369f52b40b03be71226652" + integrity sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg== + +esbuild-linux-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz#dae4cd42ae9787468b6a5c158da4c84e83b0ce8b" + integrity sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig== + +esbuild-linux-arm@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz#a2c1dff6d0f21dbe8fc6998a122675533ddfcd59" + integrity sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw== + +esbuild-linux-mips64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz#d9918e9e4cb972f8d6dae8e8655bf9ee131eda34" + integrity sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw== + +esbuild-linux-ppc64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz#3f9a0f6d41073fb1a640680845c7de52995f137e" + integrity sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ== + +esbuild-linux-riscv64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz#618853c028178a61837bc799d2013d4695e451c8" + integrity sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg== + +esbuild-linux-s390x@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz#d1885c4c5a76bbb5a0fe182e2c8c60eb9e29f2a6" + integrity sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA== + +esbuild-netbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz#69ae917a2ff241b7df1dbf22baf04bd330349e81" + integrity sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w== + +esbuild-openbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz#db4c8495287a350a6790de22edea247a57c5d47b" + integrity sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw== + +esbuild-sunos-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz#54287ee3da73d3844b721c21bc80c1dc7e1bf7da" + integrity sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw== + +esbuild-windows-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz#f8aaf9a5667630b40f0fb3aa37bf01bbd340ce31" + integrity sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w== + +esbuild-windows-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz#bf54b51bd3e9b0f1886ffdb224a4176031ea0af4" + integrity sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ== + +esbuild-windows-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz#937d15675a15e4b0e4fafdbaa3a01a776a2be982" + integrity sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg== esbuild@^0.14.27: - version "0.14.44" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.44.tgz#27fa3cd4f55d36780650c7f32cab581abc7a4473" - integrity sha512-Rn+lRRfj60r/3svI6NgAVnetzp3vMOj17BThuhshSj/gS1LR03xrjkDYyfPmrYG/0c3D68rC6FNYMQ3yRbiXeQ== + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.54.tgz#8b44dcf2b0f1a66fc22459943dccf477535e9aa2" + integrity sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA== optionalDependencies: - esbuild-android-64 "0.14.44" - esbuild-android-arm64 "0.14.44" - esbuild-darwin-64 "0.14.44" - esbuild-darwin-arm64 "0.14.44" - esbuild-freebsd-64 "0.14.44" - esbuild-freebsd-arm64 "0.14.44" - esbuild-linux-32 "0.14.44" - esbuild-linux-64 "0.14.44" - esbuild-linux-arm "0.14.44" - esbuild-linux-arm64 "0.14.44" - esbuild-linux-mips64le "0.14.44" - esbuild-linux-ppc64le "0.14.44" - esbuild-linux-riscv64 "0.14.44" - esbuild-linux-s390x "0.14.44" - esbuild-netbsd-64 "0.14.44" - esbuild-openbsd-64 "0.14.44" - esbuild-sunos-64 "0.14.44" - esbuild-windows-32 "0.14.44" - esbuild-windows-64 "0.14.44" - esbuild-windows-arm64 "0.14.44" + "@esbuild/linux-loong64" "0.14.54" + esbuild-android-64 "0.14.54" + esbuild-android-arm64 "0.14.54" + esbuild-darwin-64 "0.14.54" + esbuild-darwin-arm64 "0.14.54" + esbuild-freebsd-64 "0.14.54" + esbuild-freebsd-arm64 "0.14.54" + esbuild-linux-32 "0.14.54" + esbuild-linux-64 "0.14.54" + esbuild-linux-arm "0.14.54" + esbuild-linux-arm64 "0.14.54" + esbuild-linux-mips64le "0.14.54" + esbuild-linux-ppc64le "0.14.54" + esbuild-linux-riscv64 "0.14.54" + esbuild-linux-s390x "0.14.54" + esbuild-netbsd-64 "0.14.54" + esbuild-openbsd-64 "0.14.54" + esbuild-sunos-64 "0.14.54" + esbuild-windows-32 "0.14.54" + esbuild-windows-64 "0.14.54" + esbuild-windows-arm64 "0.14.54" escalade@^3.1.1: version "3.1.1" @@ -1149,6 +2044,11 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" @@ -1163,12 +2063,11 @@ eslint-import-resolver-node@^0.3.6: resolve "^1.20.0" eslint-module-utils@^2.7.3: - version "2.7.3" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz#ad7e3a10552fdd0642e1e55292781bd6e34876ee" - integrity sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ== + version "2.7.4" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" + integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== dependencies: debug "^3.2.7" - find-up "^2.1.0" eslint-plugin-import@^2: version "2.26.0" @@ -1190,9 +2089,9 @@ eslint-plugin-import@^2: tsconfig-paths "^3.14.1" eslint-plugin-prettier@^4: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz#8b99d1e4b8b24a762472b4567992023619cb98e0" - integrity sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ== + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" + integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== dependencies: prettier-linter-helpers "^1.0.0" @@ -1207,9 +2106,9 @@ eslint-plugin-react-perf@^3: integrity sha512-iOx2UtEOH50TmQhezTS4jbBAj/2gbrUdX+ZM28c2K9mwTvtRX6gdnd2P4WPQrejITDsAMNTCz95zu5HcjCD0xg== eslint-plugin-react@^7: - version "7.30.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.30.0.tgz#8e7b1b2934b8426ac067a0febade1b13bd7064e3" - integrity sha512-RgwH7hjW48BleKsYyHK5vUAvxtE9SMPDKmcPRQgtRCYaZA0XQPt5FSkrU3nhz5ifzMZcA8opwmRJ2cmOO8tr5A== + version "7.30.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.30.1.tgz#2be4ab23ce09b5949c6631413ba64b2810fd3e22" + integrity sha512-NbEvI9jtqO46yJA3wcRF9Mo0lF9T/jhdHqhCHXiXtD+Zcb98812wvokjWpU7Q4QH5edo6dmqrukxVvWWXHlsUg== dependencies: array-includes "^3.1.5" array.prototype.flatmap "^1.3.0" @@ -1264,12 +2163,13 @@ eslint-visitor-keys@^3.3.0: integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== eslint@^8: - version "8.18.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.18.0.tgz#78d565d16c993d0b73968c523c0446b13da784fd" - integrity sha512-As1EfFMVk7Xc6/CvhssHUjsAQSkpfXvUGMFC3ce8JDe6WvqCgRrLOBQbVpsBFr1X1V+RACOadnzVvcUS5ni2bA== + version "8.22.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.22.0.tgz#78fcb044196dfa7eef30a9d65944f6f980402c48" + integrity sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA== dependencies: "@eslint/eslintrc" "^1.3.0" - "@humanwhocodes/config-array" "^0.9.2" + "@humanwhocodes/config-array" "^0.10.4" + "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -1279,14 +2179,17 @@ eslint@^8: eslint-scope "^7.1.1" eslint-utils "^3.0.0" eslint-visitor-keys "^3.3.0" - espree "^9.3.2" + espree "^9.3.3" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" + find-up "^5.0.0" functional-red-black-tree "^1.0.1" glob-parent "^6.0.1" globals "^13.15.0" + globby "^11.1.0" + grapheme-splitter "^1.0.4" ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" @@ -1304,15 +2207,20 @@ eslint@^8: text-table "^0.2.0" v8-compile-cache "^2.0.3" -espree@^9.3.2: - version "9.3.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.2.tgz#f58f77bd334731182801ced3380a8cc859091596" - integrity sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA== +espree@^9.3.2, espree@^9.3.3: + version "9.3.3" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d" + integrity sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng== dependencies: - acorn "^8.7.1" + acorn "^8.8.0" acorn-jsx "^5.3.2" eslint-visitor-keys "^3.3.0" +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + esquery@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" @@ -1342,6 +2250,24 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +exec-sh@^0.3.2: + version "0.3.6" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" + integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" @@ -1357,6 +2283,79 @@ execa@^4.0.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expect@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" + integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== + dependencies: + "@jest/expect-utils" "^28.1.3" + jest-get-type "^28.0.2" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -1367,6 +2366,17 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== +fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -1377,6 +2387,20 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -1384,14 +2408,29 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: - locate-path "^2.0.0" + to-regex-range "^5.0.1" + +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== -find-up@^4.1.0: +find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -1399,6 +2438,14 @@ find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -1408,16 +2455,28 @@ flat-cache@^3.0.4: rimraf "^3.0.2" flatted@^3.1.0: - version "3.2.5" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" - integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== + version "3.2.6" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" + integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== + dependencies: + map-cache "^0.2.2" fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@~2.3.2: +fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -1452,6 +2511,11 @@ gensync@^1.0.0-beta.2: resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" @@ -1461,6 +2525,18 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.3" +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + get-stream@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" @@ -1468,6 +2544,11 @@ get-stream@^5.0.0: dependencies: pump "^3.0.0" +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -1476,6 +2557,18 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + glob-parent@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" @@ -1483,7 +2576,7 @@ glob-parent@^6.0.1: dependencies: is-glob "^4.0.3" -glob@^7.1.3: +glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -1501,12 +2594,34 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.15.0: - version "13.15.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.15.0.tgz#38113218c907d2f7e98658af246cef8b77e90bac" - integrity sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog== + version "13.17.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" + integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== dependencies: type-fest "^0.20.2" +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +graceful-fs@^4.2.4, graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -1529,7 +2644,7 @@ has-property-descriptors@^1.0.0: dependencies: get-intrinsic "^1.1.1" -has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: +has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== @@ -1541,6 +2656,37 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -1562,11 +2708,21 @@ hoist-non-react-statics@^3.3.1: dependencies: react-is "^16.7.0" +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + husky@^7: version "7.0.4" resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.4.tgz#242048245dc49c8fb1bf0cc7cfb98dd722531535" @@ -1585,6 +2741,14 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -1612,12 +2776,24 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== dependencies: - loose-envify "^1.0.0" + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-bigint@^1.0.1: version "1.0.4" @@ -1634,18 +2810,44 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" - integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + version "2.10.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" + integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== dependencies: has "^1.0.3" +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + is-date-object@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" @@ -1653,12 +2855,52 @@ is-date-object@^1.0.1: dependencies: has-tostringtag "^1.0.0" +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-glob@^4.0.0, is-glob@^4.0.3: +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -1677,6 +2919,25 @@ is-number-object@^1.0.4: dependencies: has-tostringtag "^1.0.0" +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -1692,6 +2953,11 @@ is-shared-array-buffer@^1.0.2: dependencies: call-bind "^1.0.2" +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" @@ -1711,6 +2977,11 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -1718,16 +2989,501 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-report@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^3.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.5" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831" + integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== + dependencies: + execa "^5.0.0" + p-limit "^3.1.0" + +jest-circus@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4" + integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + is-generator-fn "^2.0.0" + jest-each "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + p-limit "^3.1.0" + pretty-format "^28.1.3" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2" + integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== + dependencies: + "@jest/core" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + prompts "^2.0.1" + yargs "^17.3.1" + +jest-config@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60" + integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^28.1.3" + "@jest/types" "^28.1.3" + babel-jest "^28.1.3" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^28.1.3" + jest-environment-node "^28.1.3" + jest-get-type "^28.0.2" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-runner "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^28.1.3" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" + integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== + dependencies: + chalk "^4.0.0" + diff-sequences "^28.1.1" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + +jest-docblock@^28.1.1: + version "28.1.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-28.1.1.tgz#6f515c3bf841516d82ecd57a62eed9204c2f42a8" + integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA== + dependencies: + detect-newline "^3.0.0" + +jest-each@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81" + integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== + dependencies: + "@jest/types" "^28.1.3" + chalk "^4.0.0" + jest-get-type "^28.0.2" + jest-util "^28.1.3" + pretty-format "^28.1.3" + +jest-environment-node@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" + integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + jest-mock "^28.1.3" + jest-util "^28.1.3" + +jest-get-type@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" + integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== + +jest-haste-map@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" + integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== + dependencies: + "@jest/types" "^26.6.2" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-regex-util "^26.0.0" + jest-serializer "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" + micromatch "^4.0.2" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.1.2" + +jest-haste-map@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b" + integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== + dependencies: + "@jest/types" "^28.1.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + jest-worker "^28.1.3" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d" + integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== + dependencies: + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + +jest-matcher-utils@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" + integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== + dependencies: + chalk "^4.0.0" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + +jest-message-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" + integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^28.1.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^28.1.3" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da" + integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + +jest-pnp-resolver@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== + +jest-regex-util@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" + integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== + +jest-regex-util@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" + integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== + +jest-resolve-dependencies@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66" + integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== + dependencies: + jest-regex-util "^28.0.2" + jest-snapshot "^28.1.3" + +jest-resolve@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8" + integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-pnp-resolver "^1.2.2" + jest-util "^28.1.3" + jest-validate "^28.1.3" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + +jest-runner@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1" + integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== + dependencies: + "@jest/console" "^28.1.3" + "@jest/environment" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.10.2" + graceful-fs "^4.2.9" + jest-docblock "^28.1.1" + jest-environment-node "^28.1.3" + jest-haste-map "^28.1.3" + jest-leak-detector "^28.1.3" + jest-message-util "^28.1.3" + jest-resolve "^28.1.3" + jest-runtime "^28.1.3" + jest-util "^28.1.3" + jest-watcher "^28.1.3" + jest-worker "^28.1.3" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f" + integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/globals" "^28.1.3" + "@jest/source-map" "^28.1.2" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-serializer@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" + integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" + +jest-snapshot@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668" + integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/babel__traverse" "^7.0.6" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^28.1.3" + graceful-fs "^4.2.9" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + jest-haste-map "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + natural-compare "^1.4.0" + pretty-format "^28.1.3" + semver "^7.3.5" + +jest-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" + integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + graceful-fs "^4.2.4" + is-ci "^2.0.0" + micromatch "^4.0.2" + +jest-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" + integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df" + integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== + dependencies: + "@jest/types" "^28.1.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^28.0.2" + leven "^3.1.0" + pretty-format "^28.1.3" + +jest-watcher@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" + integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== + dependencies: + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.10.2" + jest-util "^28.1.3" + string-length "^4.0.1" + +jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest-worker@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" + integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^28: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.3.tgz#e9c6a7eecdebe3548ca2b18894a50f45b36dfc6b" + integrity sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA== + dependencies: + "@jest/core" "^28.1.3" + "@jest/types" "^28.1.3" + import-local "^3.0.2" + jest-cli "^28.1.3" + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" @@ -1740,6 +3496,11 @@ jsesc@^2.5.1: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +json-parse-even-better-errors@^2.3.0: + 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" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -1763,12 +3524,46 @@ json5@^2.2.1: integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== "jsx-ast-utils@^2.4.1 || ^3.0.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.0.tgz#e624f259143b9062c92b6413ff92a164c80d3ccb" - integrity sha512-XzO9luP6L0xkxwhIJMTJQpZo/eeN60K08jHdexfD569AGxeNug6UketeHXEhROoM8aR7EcUoOQmIhcJQjcuq8Q== + version "3.3.3" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" + integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== dependencies: - array-includes "^3.1.4" - object.assign "^4.1.2" + array-includes "^3.1.5" + object.assign "^4.1.3" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== levn@^0.4.1: version "0.4.1" @@ -1778,13 +3573,10 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== locate-path@^5.0.0: version "5.0.0" @@ -1793,6 +3585,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" @@ -1800,21 +3599,86 @@ lodash.merge@^4.6.2: lodash@^4: version "4.17.21" - resolved "https://registry.npm.ouryahoo.com:4443/npm-registry/api/npm/npm-registry/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== + dependencies: + object-visit "^1.0.0" + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -1827,11 +3691,19 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + mri@^1.1.5: version "1.2.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" @@ -1868,17 +3740,63 @@ nanoid@^3.3.4: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -node-releases@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.5.tgz#280ed5bc3eba0d96ce44897d8aee478bfb3d9666" - integrity sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q== +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -npm-run-path@^4.0.0: +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== + dependencies: + path-key "^2.0.0" + +npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -1890,6 +3808,15 @@ object-assign@^4.1.1: resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + object-inspect@^1.12.0, object-inspect@^1.9.0: version "1.12.2" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" @@ -1900,14 +3827,21 @@ object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" - integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - has-symbols "^1.0.1" + isobject "^3.0.0" + +object.assign@^4.1.0, object.assign@^4.1.2, object.assign@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.3.tgz#d36b7700ddf0019abb6b1df1bb13f6445f79051f" + integrity sha512-ZFJnX3zltyjcYJL0RoCJuzb+11zWGyaDbjgxZbdV7rFEcHQuYxrZqhow67aA7xpes6LhojyFDaBKAFfogQrikA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" object-keys "^1.1.1" object.entries@^1.1.5: @@ -1936,6 +3870,13 @@ object.hasown@^1.1.1: define-properties "^1.1.4" es-abstract "^1.19.5" +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== + dependencies: + isobject "^3.0.1" + object.values@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" @@ -1952,7 +3893,7 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -onetime@^5.1.0: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -1971,12 +3912,10 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== p-limit@^2.2.0: version "2.3.0" @@ -1985,12 +3924,12 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== +p-limit@^3.0.2, p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: - p-limit "^1.1.0" + yocto-queue "^0.1.0" p-locate@^4.1.0: version "4.1.0" @@ -1999,10 +3938,12 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" p-try@^2.0.0: version "2.2.0" @@ -2016,10 +3957,20 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== +parse-json@^5.0.0, parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== path-exists@^4.0.0: version "4.0.0" @@ -2031,6 +3982,11 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -2041,20 +3997,42 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.2.2: +picomatch@^2.0.4, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pirates@^4.0.1, pirates@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== + postcss@^8.4.13: - version "8.4.14" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" - integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== + version "8.4.16" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" + integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== dependencies: nanoid "^3.3.4" picocolors "^1.0.0" @@ -2077,6 +4055,16 @@ prettier@2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== +pretty-format@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" + integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== + dependencies: + "@jest/schemas" "^28.1.3" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^18.0.0" + pretty-quick@^3: version "3.1.3" resolved "https://registry.yarnpkg.com/pretty-quick/-/pretty-quick-3.1.3.tgz#15281108c0ddf446675157ca40240099157b638e" @@ -2089,13 +4077,13 @@ pretty-quick@^3: mri "^1.1.5" multimatch "^4.0.0" -prop-types-extra@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" - integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew== +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== dependencies: - react-is "^16.3.2" - warning "^4.0.0" + kleur "^3.0.3" + sisteransi "^1.0.5" prop-types@^15.6.2, prop-types@^15.8.1: version "15.8.1" @@ -2119,23 +4107,10 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -react-bootstrap@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-2.4.0.tgz#99bf9656e2e7a23ae1ae135d18fd5ad7c344b416" - integrity sha512-dn599jNK1Fg5GGjJH+lQQDwELVzigh/MdusKpB/0el+sCjsO5MZDH5gRMmBjRhC+vb7VlCDr6OXffPIDSkNMLw== - dependencies: - "@babel/runtime" "^7.17.2" - "@restart/hooks" "^0.4.6" - "@restart/ui" "^1.2.0" - "@types/react-transition-group" "^4.4.4" - classnames "^2.3.1" - dom-helpers "^5.2.1" - invariant "^2.2.4" - prop-types "^15.8.1" - prop-types-extra "^1.1.0" - react-transition-group "^4.4.2" - uncontrollable "^7.2.1" - warning "^4.0.3" +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== react-dom@^18: version "18.2.0" @@ -2145,28 +4120,15 @@ react-dom@^18: loose-envify "^1.1.0" scheduler "^0.23.0" -react-fast-compare@^3.0.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" - integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== - -react-is@^16.13.1, react-is@^16.3.2, react-is@^16.7.0: +react-is@^16.13.1, react-is@^16.7.0: 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-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-popper@^2.2.5: - version "2.3.0" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba" - integrity sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q== - dependencies: - react-fast-compare "^3.0.1" - warning "^4.0.2" +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== react-refresh@^0.13.0: version "0.13.0" @@ -2175,7 +4137,7 @@ react-refresh@^0.13.0: react-router-dom@^6: version "6.3.0" - resolved "https://registry.npm.ouryahoo.com:4443/npm-registry/api/npm/npm-registry/react-router-dom/-/react-router-dom-6.3.0.tgz#a0216da813454e521905b5fa55e0e5176123f43d" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.3.0.tgz#a0216da813454e521905b5fa55e0e5176123f43d" integrity sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw== dependencies: history "^5.2.0" @@ -2188,7 +4150,7 @@ react-router@6.3.0: dependencies: history "^5.2.0" -react-textarea-autosize@^8.3.2: +react-textarea-autosize@8.3.4: version "8.3.4" resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz#270a343de7ad350534141b02c9cb78903e553524" integrity sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ== @@ -2197,7 +4159,7 @@ react-textarea-autosize@^8.3.2: use-composed-ref "^1.3.0" use-latest "^1.2.1" -react-transition-group@^4.4.2: +react-transition-group@4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470" integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg== @@ -2219,6 +4181,14 @@ regenerator-runtime@^0.13.4: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" @@ -2233,12 +4203,54 @@ regexpp@^3.2.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.20.0: +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + +resolve.exports@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== + +resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -2247,15 +4259,6 @@ resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^1.22.0: - version "1.22.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" - integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== - dependencies: - is-core-module "^2.8.1" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - resolve@^2.0.0-next.3: version "2.0.0-next.4" resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" @@ -2265,25 +4268,69 @@ resolve@^2.0.0-next.3: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -rimraf@^3.0.2: +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" -rollup@^2.59.0: - version "2.75.6" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.75.6.tgz#ac4dc8600f95942a0180f61c7c9d6200e374b439" - integrity sha512-OEf0TgpC9vU6WGROJIk1JA3LR5vk/yvqlzxqdrE2CzzXnqKXNzbAwlWUXis8RS3ZPe7LAq+YUxsRa0l3r27MLA== +"rollup@>=2.59.0 <2.78.0": + version "2.77.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.77.3.tgz#8f00418d3a2740036e15deb653bed1a90ee0cc12" + integrity sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g== optionalDependencies: fsevents "~2.3.2" +rsvp@^4.8.4: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== + dependencies: + ret "~0.1.10" + +sane@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + scheduler@^0.23.0: version "0.23.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" @@ -2291,11 +4338,40 @@ scheduler@^0.23.0: dependencies: loose-envify "^1.1.0" -semver@^6.3.0: +semver@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + +semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.3.5: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -2303,6 +4379,11 @@ shebang-command@^2.0.0: dependencies: shebang-regex "^3.0.0" +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" @@ -2317,16 +4398,134 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.2: +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + +source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== + dependencies: + escape-string-regexp "^2.0.0" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string.prototype.matchall@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d" @@ -2359,7 +4558,7 @@ string.prototype.trimstart@^1.0.5: define-properties "^1.1.4" es-abstract "^1.19.5" -strip-ansi@^6.0.1: +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -2371,6 +4570,16 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== + strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" @@ -2393,28 +4602,97 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.1.0: +supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-hyperlinks@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb" + integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + tsconfig-paths@^3.14.1: version "3.14.1" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" @@ -2425,6 +4703,11 @@ tsconfig-paths@^3.14.1: minimist "^1.2.6" strip-bom "^3.0.0" +tslib@^1.0.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -2432,11 +4715,28 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -2447,15 +4747,31 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -uncontrollable@^7.2.1: - version "7.2.1" - resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-7.2.1.tgz#1fa70ba0c57a14d5f78905d533cf63916dc75738" - integrity sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ== +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +update-browserslist-db@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== dependencies: - "@babel/runtime" "^7.6.3" - "@types/react" ">=16.9.11" - invariant "^2.2.4" - react-lifecycles-compat "^3.0.4" + escalade "^3.1.1" + picocolors "^1.0.0" uri-js@^4.2.2: version "4.4.1" @@ -2464,6 +4780,11 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== + use-composed-ref@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.3.0.tgz#3d8104db34b7b264030a9d916c5e94fbe280dbda" @@ -2471,7 +4792,7 @@ use-composed-ref@^1.3.0: use-context-selector@^1: version "1.4.1" - resolved "https://registry.npm.ouryahoo.com:4443/npm-registry/api/npm/npm-registry/use-context-selector/-/use-context-selector-1.4.1.tgz#eb96279965846b72915d7f899b8e6ef1d768b0ae" + resolved "https://registry.yarnpkg.com/use-context-selector/-/use-context-selector-1.4.1.tgz#eb96279965846b72915d7f899b8e6ef1d768b0ae" integrity sha512-Io2ArvcRO+6MWIhkdfMFt+WKQX+Vb++W8DS2l03z/Vw/rz3BclKpM0ynr4LYGyU85Eke+Yx5oIhTY++QR0ZDoA== use-isomorphic-layout-effect@^1.1.1: @@ -2486,29 +4807,43 @@ use-latest@^1.2.1: dependencies: use-isomorphic-layout-effect "^1.1.1" +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +v8-to-istanbul@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" + integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + vite@^2: - version "2.9.13" - resolved "https://registry.yarnpkg.com/vite/-/vite-2.9.13.tgz#859cb5d4c316c0d8c6ec9866045c0f7858ca6abc" - integrity sha512-AsOBAaT0AD7Mhe8DuK+/kE4aWYFMx/i0ZNi98hJclxb4e0OhQcZYUrvLjIaQ8e59Ui7txcvKMiJC1yftqpQoDw== + version "2.9.15" + resolved "https://registry.yarnpkg.com/vite/-/vite-2.9.15.tgz#2858dd5b2be26aa394a283e62324281892546f0b" + integrity sha512-fzMt2jK4vQ3yK56te3Kqpkaeq9DkcZfBbzHwYpobasvgYmP2SoAr6Aic05CsB4CzCZbsDv4sujX3pkEGhLabVQ== dependencies: esbuild "^0.14.27" postcss "^8.4.13" resolve "^1.22.0" - rollup "^2.59.0" + rollup ">=2.59.0 <2.78.0" optionalDependencies: fsevents "~2.3.2" -warning@^4.0.0, warning@^4.0.2, warning@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" - integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== +walker@^1.0.7, walker@^1.0.8, walker@~1.0.5: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: - loose-envify "^1.0.0" + makeerror "1.0.12" which-boxed-primitive@^1.0.2: version "1.0.2" @@ -2521,6 +4856,13 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -2533,7 +4875,72 @@ word-wrap@^1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +write-file-atomic@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.1.tgz#9faa33a964c1c85ff6f849b80b42a88c2c537c8f" + integrity sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yargs-parser@^21.0.0: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.3.1: + version "17.5.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" + integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java index 8b335e877cd..4097810b633 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/FleetController.java @@ -28,6 +28,8 @@ import com.yahoo.vespa.clustercontroller.core.status.statuspage.StatusPageServer import com.yahoo.vespa.clustercontroller.core.status.statuspage.StatusPageServerInterface; import com.yahoo.vespa.clustercontroller.utils.util.MetricReporter; import java.io.FileNotFoundException; +import java.time.Duration; +import java.time.Instant; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -1156,16 +1158,18 @@ public class FleetController implements NodeListener, SlobrokListener, SystemSta public NodeListener getNodeStateUpdateListener() { return FleetController.this; } }; - public void waitForCompleteCycle(long timeoutMS) { - long endTime = System.currentTimeMillis() + timeoutMS; + public void waitForCompleteCycle(Duration timeout) { + Instant endTime = Instant.now().plus(timeout); synchronized (monitor) { // To wait at least one complete cycle, if a cycle is already running we need to wait for the next one beyond. long wantedCycle = cycleCount + (processingCycle ? 2 : 1); waitingForCycle = true; try{ while (cycleCount < wantedCycle) { - if (System.currentTimeMillis() > endTime) throw new IllegalStateException("Timed out waiting for cycle to complete. Not completed after " + timeoutMS + " ms."); - if ( !isRunning() ) throw new IllegalStateException("Fleetcontroller not running. Will never complete cycles"); + if (Instant.now().isAfter(endTime)) + throw new IllegalStateException("Timed out waiting for cycle to complete. Not completed after " + timeout); + if ( !isRunning() ) + throw new IllegalStateException("Fleetcontroller not running. Will never complete cycles"); try{ monitor.wait(100); } catch (InterruptedException e) {} } } finally { @@ -1179,8 +1183,8 @@ public class FleetController implements NodeListener, SlobrokListener, SystemSta * But it is only used in unit tests that should not trigger any thread issues. Don't want to add locks that reduce * live performance to remove a non-problem. */ - public void waitForNodesHavingSystemStateVersionEqualToOrAbove(int version, int nodeCount, int timeout) throws InterruptedException { - long maxTime = System.currentTimeMillis() + timeout; + public void waitForNodesHavingSystemStateVersionEqualToOrAbove(int version, int nodeCount, Duration timeout) throws InterruptedException { + Instant endTime = Instant.now().plus(timeout); synchronized (monitor) { while (true) { int ackedNodes = 0; @@ -1193,17 +1197,16 @@ public class FleetController implements NodeListener, SlobrokListener, SystemSta context.log(logger, Level.INFO, ackedNodes + " nodes now have acked system state " + version + " or higher."); return; } - long remainingTime = maxTime - System.currentTimeMillis(); - if (remainingTime <= 0) { - throw new IllegalStateException("Did not get " + nodeCount + " nodes to system state " + version + " within timeout of " + timeout + " milliseconds."); + if (Instant.now().isAfter(endTime)) { + throw new IllegalStateException("Did not get " + nodeCount + " nodes to system state " + version + " within timeout of " + timeout); } monitor.wait(10); } } } - public void waitForNodesInSlobrok(int distNodeCount, int storNodeCount, int timeoutMillis) throws InterruptedException { - long maxTime = System.currentTimeMillis() + timeoutMillis; + public void waitForNodesInSlobrok(int distNodeCount, int storNodeCount, Duration timeout) throws InterruptedException { + Instant endTime = Instant.now().plus(timeout); synchronized (monitor) { while (true) { int distCount = 0, storCount = 0; @@ -1215,10 +1218,9 @@ public class FleetController implements NodeListener, SlobrokListener, SystemSta } if (distCount == distNodeCount && storCount == storNodeCount) return; - long remainingTime = maxTime - System.currentTimeMillis(); - if (remainingTime <= 0) { + if (Instant.now().isAfter(endTime)) { throw new IllegalStateException("Did not get all " + distNodeCount + " distributors and " + storNodeCount - + " storage nodes registered in slobrok within timeout of " + timeoutMillis + " ms. (Got " + + " storage nodes registered in slobrok within timeout of " + timeout + ". (Got " + distCount + " distributors and " + storCount + " storage nodes)"); } monitor.wait(10); diff --git a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/rpc/RPCCommunicator.java b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/rpc/RPCCommunicator.java index 502fc37dead..e223ad12fb9 100644 --- a/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/rpc/RPCCommunicator.java +++ b/clustercontroller-core/src/main/java/com/yahoo/vespa/clustercontroller/core/rpc/RPCCommunicator.java @@ -22,6 +22,8 @@ import com.yahoo.vespa.clustercontroller.core.GetNodeStateRequest; import com.yahoo.vespa.clustercontroller.core.NodeInfo; import com.yahoo.vespa.clustercontroller.core.SetClusterStateRequest; import com.yahoo.vespa.clustercontroller.core.Timer; + +import java.time.Duration; import java.util.logging.Level; import java.util.logging.Logger; @@ -46,10 +48,10 @@ public class RPCCommunicator implements Communicator { private final Timer timer; private final Supervisor supervisor; - private double nodeStateRequestTimeoutIntervalMaxSeconds; + private Duration nodeStateRequestTimeoutIntervalMax; private int nodeStateRequestTimeoutIntervalStartPercentage; private int nodeStateRequestTimeoutIntervalStopPercentage; - private int nodeStateRequestRoundTripTimeMaxSeconds; + private Duration nodeStateRequestRoundTripTimeMax; private final int fleetControllerIndex; public static Supervisor createRealSupervisor() { @@ -72,10 +74,10 @@ public class RPCCommunicator implements Communicator { checkArgument(nodeStateRequestTimeoutIntervalStopPercentage >= nodeStateRequestTimeoutIntervalStartPercentage); checkArgument(nodeStateRequestTimeoutIntervalStopPercentage <= 100); checkArgument(nodeStateRequestRoundTripTimeMaxSeconds >= 0); - this.nodeStateRequestTimeoutIntervalMaxSeconds = nodeStateRequestTimeoutIntervalMaxMs / 1000D; + this.nodeStateRequestTimeoutIntervalMax = Duration.ofMillis(nodeStateRequestTimeoutIntervalMaxMs); this.nodeStateRequestTimeoutIntervalStartPercentage = nodeStateRequestTimeoutIntervalStartPercentage; this.nodeStateRequestTimeoutIntervalStopPercentage = nodeStateRequestTimeoutIntervalStopPercentage; - this.nodeStateRequestRoundTripTimeMaxSeconds = nodeStateRequestRoundTripTimeMaxSeconds; + this.nodeStateRequestRoundTripTimeMax = Duration.ofSeconds(nodeStateRequestRoundTripTimeMaxSeconds); this.supervisor = supervisor; } @@ -100,10 +102,10 @@ public class RPCCommunicator implements Communicator { >= options.nodeStateRequestTimeoutEarliestPercentage); checkArgument(options.nodeStateRequestTimeoutLatestPercentage <= 100); checkArgument(options.nodeStateRequestRoundTripTimeMaxSeconds >= 0); - this.nodeStateRequestTimeoutIntervalMaxSeconds = options.nodeStateRequestTimeoutMS / 1000.0; + this.nodeStateRequestTimeoutIntervalMax = Duration.ofMillis(options.nodeStateRequestTimeoutMS); this.nodeStateRequestTimeoutIntervalStartPercentage = options.nodeStateRequestTimeoutEarliestPercentage; this.nodeStateRequestTimeoutIntervalStopPercentage = options.nodeStateRequestTimeoutLatestPercentage; - this.nodeStateRequestRoundTripTimeMaxSeconds = options.nodeStateRequestRoundTripTimeMaxSeconds; + this.nodeStateRequestRoundTripTimeMax = Duration.ofSeconds(options.nodeStateRequestRoundTripTimeMaxSeconds); } @Override @@ -117,16 +119,15 @@ public class RPCCommunicator implements Communicator { req.parameters().add(new StringValue( currentState.getState().equals(State.DOWN) || node.getConnectionAttemptCount() > 0 ? "unknown" : currentState.serialize())); - req.parameters().add(new Int32Value(generateNodeStateRequestTimeoutMs())); + req.parameters().add(new Int32Value((int)generateNodeStateRequestTimeout().toMillis())); req.parameters().add(new Int32Value(fleetControllerIndex)); RPCGetNodeStateRequest stateRequest = new RPCGetNodeStateRequest(node, req); RPCGetNodeStateWaiter waiter = new RPCGetNodeStateWaiter(stateRequest, externalWaiter, timer); - double requestTimeoutSeconds = - nodeStateRequestTimeoutIntervalMaxSeconds + nodeStateRequestRoundTripTimeMaxSeconds; + Duration requestTimeout = nodeStateRequestTimeoutIntervalMax.plus(nodeStateRequestRoundTripTimeMax); - connection.invokeAsync(req, requestTimeoutSeconds, waiter); + connection.invokeAsync(req, requestTimeout, waiter); node.setCurrentNodeStateRequest(stateRequest, timer.getCurrentTimeInMillis()); node.lastRequestInfoConnection = connection; } @@ -161,7 +162,7 @@ public class RPCCommunicator implements Communicator { RPCSetClusterStateRequest stateRequest = new RPCSetClusterStateRequest(node, req, baselineState.getVersion()); waiter.setRequest(stateRequest); - connection.invokeAsync(req, 60, waiter); + connection.invokeAsync(req, Duration.ofSeconds(60), waiter); node.setClusterStateVersionBundleSent(stateBundle); } @@ -183,20 +184,20 @@ public class RPCCommunicator implements Communicator { var activationRequest = new RPCActivateClusterStateVersionRequest(node, req, clusterStateVersion); waiter.setRequest(activationRequest); - connection.invokeAsync(req, 60, waiter); + connection.invokeAsync(req, Duration.ofSeconds(60), waiter); node.setClusterStateVersionActivationSent(clusterStateVersion); } // protected for testing. - protected int generateNodeStateRequestTimeoutMs() { + protected Duration generateNodeStateRequestTimeout() { double intervalFraction = Math.random(); - double earliestTimeoutSeconds = - nodeStateRequestTimeoutIntervalMaxSeconds * nodeStateRequestTimeoutIntervalStartPercentage / 100.0; - double latestTimeoutSeconds = - nodeStateRequestTimeoutIntervalMaxSeconds * nodeStateRequestTimeoutIntervalStopPercentage / 100.0; - double interval = latestTimeoutSeconds - earliestTimeoutSeconds; - double timeoutSeconds = earliestTimeoutSeconds + intervalFraction * interval; - return (int) (timeoutSeconds * 1000); + long earliestTimeoutNanos = + nodeStateRequestTimeoutIntervalMax.toNanos() * nodeStateRequestTimeoutIntervalStartPercentage / 100; + long latestTimeoutNanos = + nodeStateRequestTimeoutIntervalMax.toNanos() * nodeStateRequestTimeoutIntervalStopPercentage / 100; + long interval = latestTimeoutNanos - earliestTimeoutNanos; + long timeoutNanos = earliestTimeoutNanos + (long)(intervalFraction * interval); + return Duration.ofNanos(timeoutNanos); } } diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DatabaseTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DatabaseTest.java index dc297e7a549..9a6a9e063ac 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DatabaseTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DatabaseTest.java @@ -60,7 +60,7 @@ public class DatabaseTest extends FleetControllerTest { log.info("CHECK THAT WANTED STATES PERSIST FLEETCONTROLLER RESTART"); stopFleetController(); - startFleetController(); + startFleetController(false); waitForState("version:\\d+ distributor:10 .2.s:d storage:10 .3.s:m .7.s:r"); assertWantedStates(wantedStates); @@ -124,7 +124,7 @@ public class DatabaseTest extends FleetControllerTest { stopFleetController(); for (int i = 6; i < nodes.size(); ++i) nodes.get(i).disconnect(); - startFleetController(); + startFleetController(false); waitForState("version:\\d+ distributor:3 storage:7 .1.s:m .3.s:d .4.s:d .5.s:d .6.s:m"); @@ -154,7 +154,7 @@ public class DatabaseTest extends FleetControllerTest { Request req = new Request("setNodeState"); req.parameters().add(new StringValue("storage/cluster.mycluster/" + n.getType().toString() + "/" + n.getIndex())); req.parameters().add(new StringValue(ns.serialize(true))); - connection.invokeSync(req, timeoutS); + connection.invokeSync(req, timeout()); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("s"), req.toString()); wantedStates.put(n, ns); diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DummyVdsNode.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DummyVdsNode.java index af067cc394f..fd24966e26a 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DummyVdsNode.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/DummyVdsNode.java @@ -21,6 +21,8 @@ import com.yahoo.vdslib.state.NodeType; import com.yahoo.vdslib.state.State; import com.yahoo.vespa.clustercontroller.core.rpc.RPCCommunicator; import com.yahoo.vespa.clustercontroller.core.rpc.RPCUtil; +import java.time.Duration; +import java.time.Instant; import java.util.Iterator; import java.util.LinkedList; import java.util.List; @@ -194,11 +196,11 @@ public class DummyVdsNode { public int getStateCommunicationVersion() { return stateCommunicationVersion; } - void waitForSystemStateVersion(int version) { + void waitForSystemStateVersion(int version, Duration timeout) { try { - long startTime = System.currentTimeMillis(); + Instant endTime = Instant.now().plus(timeout); while (getLatestSystemStateVersion().orElse(-1) < version) { - if ( (System.currentTimeMillis() - startTime) > (long) FleetControllerTest.timeoutMS) + if (Instant.now().isAfter(endTime)) throw new RuntimeException("Timed out waiting for state version " + version + " in " + this); Thread.sleep(10); } diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/FleetControllerTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/FleetControllerTest.java index 5e4b62e0462..371a57e08c0 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/FleetControllerTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/FleetControllerTest.java @@ -22,7 +22,6 @@ import com.yahoo.vespa.clustercontroller.core.rpc.RPCCommunicator; import com.yahoo.vespa.clustercontroller.core.rpc.RpcServer; import com.yahoo.vespa.clustercontroller.core.rpc.SlobrokClient; import com.yahoo.vespa.clustercontroller.core.status.StatusHandler; -import com.yahoo.vespa.clustercontroller.core.status.statuspage.StatusPageServerInterface; import com.yahoo.vespa.clustercontroller.core.testutils.WaitCondition; import com.yahoo.vespa.clustercontroller.core.testutils.WaitTask; import com.yahoo.vespa.clustercontroller.core.testutils.Waiter; @@ -31,14 +30,13 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.TestWatcher; - +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; @@ -59,9 +57,10 @@ public abstract class FleetControllerTest implements Waiter { private static final Logger log = Logger.getLogger(FleetControllerTest.class.getName()); private static final int DEFAULT_NODE_COUNT = 10; - Supervisor supervisor; + private final Duration timeout = Duration.ofSeconds(30); protected final FakeTimer timer = new FakeTimer(); - boolean usingFakeTimer = false; + + Supervisor supervisor; protected Slobrok slobrok; protected FleetControllerOptions options; ZooKeeperTestServer zooKeeperServer; @@ -69,8 +68,6 @@ public abstract class FleetControllerTest implements Waiter { protected List<DummyVdsNode> nodes = new ArrayList<>(); private String testName; - final static int timeoutS; - final static int timeoutMS; private final Waiter waiter = new Waiter.Impl(new DataRetriever() { @Override public Object getMonitor() { return timer; } @@ -79,13 +76,11 @@ public abstract class FleetControllerTest implements Waiter { @Override public List<DummyVdsNode> getDummyNodes() { return nodes; } @Override - public int getTimeoutMS() { return timeoutMS; } + public Duration getTimeout() { return timeout; } }); static { LogSetup.initVespaLogging("fleetcontroller"); - timeoutS = 30; - timeoutMS = timeoutS * 1000; } static class BackOff implements BackOffPolicy { @@ -142,7 +137,7 @@ public abstract class FleetControllerTest implements Waiter { return opts; } - void setUpSystem(boolean useFakeTimer, FleetControllerOptions options) throws Exception { + void setUpSystem(FleetControllerOptions options) throws Exception { log.log(Level.FINE, "Setting up system"); slobrok = new Slobrok(); this.options = options; @@ -151,21 +146,15 @@ public abstract class FleetControllerTest implements Waiter { this.options.zooKeeperServerAddress = zooKeeperServer.getAddress(); log.log(Level.FINE, "Set up new zookeeper server at " + this.options.zooKeeperServerAddress); } - this.options.slobrokConnectionSpecs = new String[1]; - this.options.slobrokConnectionSpecs[0] = "tcp/localhost:" + slobrok.port(); - this.usingFakeTimer = useFakeTimer; + this.options.slobrokConnectionSpecs = getSlobrokConnectionSpecs(slobrok); } - FleetController createFleetController(boolean useFakeTimer, FleetControllerOptions options, boolean startThread, StatusPageServerInterface status) throws Exception { - Objects.requireNonNull(status, "status server cannot be null"); + FleetController createFleetController(boolean useFakeTimer, FleetControllerOptions options) throws Exception { var context = new TestFleetControllerContext(options); Timer timer = useFakeTimer ? this.timer : new RealTimer(); var metricUpdater = new MetricUpdater(new NoMetricReporter(), options.fleetControllerIndex, options.clusterName); var log = new EventLog(timer, metricUpdater); - var cluster = new ContentCluster( - options.clusterName, - options.nodes, - options.storageDistribution); + var cluster = new ContentCluster(options.clusterName, options.nodes, options.storageDistribution); var stateGatherer = new NodeStateGatherer(timer, timer, log); var communicator = new RPCCommunicator( RPCCommunicator.createRealSupervisor(), @@ -188,24 +177,18 @@ public abstract class FleetControllerTest implements Waiter { var stateGenerator = new StateChangeHandler(context, timer, log); var stateBroadcaster = new SystemStateBroadcaster(context, timer, timer); var masterElectionHandler = new MasterElectionHandler(context, options.fleetControllerIndex, options.fleetControllerCount, timer, timer); - var controller = new FleetController(context, timer, log, cluster, stateGatherer, communicator, status, rpcServer, lookUp, database, stateGenerator, stateBroadcaster, masterElectionHandler, metricUpdater, options); - if (startThread) { - controller.start(); - } + + var status = new StatusHandler.ContainerStatusPageServer(); + var controller = new FleetController(context, timer, log, cluster, stateGatherer, communicator, status, rpcServer, lookUp, + database, stateGenerator, stateBroadcaster, masterElectionHandler, metricUpdater, options); + controller.start(); return controller; } protected void setUpFleetController(boolean useFakeTimer, FleetControllerOptions options) throws Exception { - setUpFleetController(useFakeTimer, options, true); - } - - protected void setUpFleetController(boolean useFakeTimer, FleetControllerOptions options, boolean startThread) throws Exception { - setUpFleetController(useFakeTimer, options, startThread, new StatusHandler.ContainerStatusPageServer()); - } - protected void setUpFleetController(boolean useFakeTimer, FleetControllerOptions options, boolean startThread, StatusPageServerInterface status) throws Exception { - if (slobrok == null) setUpSystem(useFakeTimer, options); + if (slobrok == null) setUpSystem(options); if (fleetController == null) { - fleetController = createFleetController(useFakeTimer, options, startThread, status); + fleetController = createFleetController(useFakeTimer, options); } else { throw new Exception("called setUpFleetcontroller but it was already setup"); } @@ -218,9 +201,9 @@ public abstract class FleetControllerTest implements Waiter { } } - void startFleetController() throws Exception { + void startFleetController(boolean useFakeTimer) throws Exception { if (fleetController == null) { - fleetController = createFleetController(usingFakeTimer, options, true, new StatusHandler.ContainerStatusPageServer()); + fleetController = createFleetController(useFakeTimer, options); } else { log.log(Level.WARNING, "already started fleetcontroller, not starting another"); } @@ -239,8 +222,7 @@ public abstract class FleetControllerTest implements Waiter { setUpVdsNodes(useFakeTimer, options, startDisconnected, nodeIndexes); } protected void setUpVdsNodes(boolean useFakeTimer, DummyVdsNodeOptions options, boolean startDisconnected, Set<Integer> nodeIndexes) throws Exception { - String[] connectionSpecs = new String[1]; - connectionSpecs[0] = "tcp/localhost:" + slobrok.port(); + String[] connectionSpecs = getSlobrokConnectionSpecs(slobrok); for (int nodeIndex : nodeIndexes) { nodes.add(new DummyVdsNode(useFakeTimer ? timer : new RealTimer(), options, connectionSpecs, this.options.clusterName, true, nodeIndex)); if ( ! startDisconnected) nodes.get(nodes.size() - 1).connect(); @@ -256,8 +238,7 @@ public abstract class FleetControllerTest implements Waiter { * the returned list is twice as large as configuredNodes. */ protected List<DummyVdsNode> setUpVdsNodes(boolean useFakeTimer, DummyVdsNodeOptions options, boolean startDisconnected, List<ConfiguredNode> configuredNodes) throws Exception { - String[] connectionSpecs = new String[1]; - connectionSpecs[0] = "tcp/localhost:" + slobrok.port(); + String[] connectionSpecs = getSlobrokConnectionSpecs(slobrok); nodes = new ArrayList<>(); final boolean distributor = true; for (ConfiguredNode configuredNode : configuredNodes) { @@ -296,7 +277,7 @@ public abstract class FleetControllerTest implements Waiter { .collect(Collectors.toList()); } @Override - public int getTimeoutMS() { return timeoutMS; } + public Duration getTimeout() { return timeout; } }); subsetWaiter.waitForState(expectedState); } @@ -341,16 +322,16 @@ public abstract class FleetControllerTest implements Waiter { public ClusterState waitForState(String state) throws Exception { return waiter.waitForState(state); } public ClusterState waitForStateInAllSpaces(String state) throws Exception { return waiter.waitForStateInAllSpaces(state); } public ClusterState waitForStateInSpace(String space, String state) throws Exception { return waiter.waitForStateInSpace(space, state); } - public ClusterState waitForState(String state, int timeoutMS) throws Exception { return waiter.waitForState(state, timeoutMS); } + public ClusterState waitForState(String state, Duration timeout) throws Exception { return waiter.waitForState(state, timeout); } public ClusterState waitForInitProgressPassed(Node n, double progress) { return waiter.waitForInitProgressPassed(n, progress); } public ClusterState waitForClusterStateIncludingNodesWithMinUsedBits(int bitcount, int nodecount) { return waiter.waitForClusterStateIncludingNodesWithMinUsedBits(bitcount, nodecount); } - public void wait(WaitCondition c, WaitTask wt, int timeoutMS) { - waiter.wait(c, wt, timeoutMS); + public void wait(WaitCondition condition, WaitTask task, Duration timeout) { + waiter.wait(condition, task, timeout); } void waitForCompleteCycle() { - fleetController.waitForCompleteCycle(timeoutMS); + fleetController.waitForCompleteCycle(timeout); } private static class ExpectLine { @@ -479,7 +460,7 @@ public abstract class FleetControllerTest implements Waiter { Request req = new Request("setNodeState"); req.parameters().add(new StringValue(node.getSlobrokName())); req.parameters().add(new StringValue(ns.serialize())); - connection.invokeSync(req, timeoutS); + connection.invokeSync(req, timeout()); if (req.isError()) { fail("Failed to invoke setNodeState(): " + req.errorCode() + ": " + req.errorMessage()); } @@ -488,4 +469,12 @@ public abstract class FleetControllerTest implements Waiter { } } + static String[] getSlobrokConnectionSpecs(Slobrok slobrok) { + String[] connectionSpecs = new String[1]; + connectionSpecs[0] = "tcp/localhost:" + slobrok.port(); + return connectionSpecs; + } + + Duration timeout() { return timeout; } + } diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/MasterElectionTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/MasterElectionTest.java index fb468ee4d5b..16a3e41f149 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/MasterElectionTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/MasterElectionTest.java @@ -11,12 +11,11 @@ import com.yahoo.vdslib.state.ClusterState; import com.yahoo.vdslib.state.NodeState; import com.yahoo.vdslib.state.NodeType; import com.yahoo.vdslib.state.State; -import com.yahoo.vespa.clustercontroller.core.status.StatusHandler; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.extension.ExtendWith; - +import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeoutException; @@ -44,46 +43,42 @@ public class MasterElectionTest extends FleetControllerTest { zooKeeperServer = new ZooKeeperTestServer(); } slobrok = new Slobrok(); - usingFakeTimer = useFakeTimer; this.options = options; this.options.zooKeeperSessionTimeout = defaultZkSessionTimeoutInMillis(); this.options.zooKeeperServerAddress = zooKeeperServer.getAddress(); - this.options.slobrokConnectionSpecs = new String[1]; - this.options.slobrokConnectionSpecs[0] = "tcp/localhost:" + slobrok.port(); + this.options.slobrokConnectionSpecs = getSlobrokConnectionSpecs(slobrok); this.options.fleetControllerCount = count; for (int i=0; i<count; ++i) { FleetControllerOptions nodeOptions = options.clone(); nodeOptions.fleetControllerIndex = i; - fleetControllers.add(createFleetController(usingFakeTimer, nodeOptions, true, new StatusHandler.ContainerStatusPageServer())); + fleetControllers.add(createFleetController(useFakeTimer, nodeOptions)); } } - private FleetControllerOptions adjustConfig(FleetControllerOptions o, - int fleetControllerIndex, int fleetControllerCount) { + private FleetControllerOptions adjustConfig(FleetControllerOptions o, int fleetControllerIndex, int fleetControllerCount) { FleetControllerOptions options = o.clone(); options.zooKeeperSessionTimeout = defaultZkSessionTimeoutInMillis(); options.zooKeeperServerAddress = zooKeeperServer.getAddress(); - options.slobrokConnectionSpecs = new String[1]; - options.slobrokConnectionSpecs[0] = "tcp/localhost:" + slobrok.port(); // Spec.fromLocalHostName(slobrok.port()).toString(); + options.slobrokConnectionSpecs = getSlobrokConnectionSpecs(slobrok); options.fleetControllerIndex = fleetControllerIndex; options.fleetControllerCount = fleetControllerCount; return options; } private void waitForZookeeperDisconnected() throws TimeoutException { - long maxTime = System.currentTimeMillis() + timeoutMS; + Instant maxTime = Instant.now().plus(timeout()); for (FleetController f : fleetControllers) { while (f.hasZookeeperConnection()) { try { Thread.sleep(1); } catch (InterruptedException e) { /* ignore */ } - if (System.currentTimeMillis() > maxTime) - throw new TimeoutException("Failed to notice zookeeper down within timeout of " + timeoutMS + " ms"); + if (Instant.now().isAfter(maxTime)) + throw new TimeoutException("Failed to notice zookeeper down within timeout of " + timeout()); } } waitForCompleteCycles(); } private void waitForCompleteCycle(int findex) { - fleetControllers.get(findex).waitForCompleteCycle(timeoutMS); + fleetControllers.get(findex).waitForCompleteCycle(timeout()); } private void waitForCompleteCycles() { @@ -117,7 +112,8 @@ public class MasterElectionTest extends FleetControllerTest { log.log(Level.INFO, "STARTING TEST: MasterElectionTest::testMasterElection()"); FleetControllerOptions options = defaultOptions("mycluster"); options.masterZooKeeperCooldownPeriod = 100; - setUpFleetController(5, false, options); + boolean usingFakeTimer = false; + setUpFleetController(5, usingFakeTimer, options); waitForMaster(0); log.log(Level.INFO, "SHUTTING DOWN FLEET CONTROLLER 0"); fleetControllers.get(0).shutdown(); @@ -134,15 +130,14 @@ public class MasterElectionTest extends FleetControllerTest { assertFalse(fleetControllers.get(i).isMaster(), "Fleet controller " + i); } - StatusHandler.ContainerStatusPageServer statusPageServer = new StatusHandler.ContainerStatusPageServer(); log.log(Level.INFO, "STARTING FLEET CONTROLLER 2"); - fleetControllers.set(2, createFleetController(usingFakeTimer, fleetControllers.get(2).getOptions(), true, statusPageServer)); + fleetControllers.set(2, createFleetController(usingFakeTimer, fleetControllers.get(2).getOptions())); waitForMaster(2); log.log(Level.INFO, "STARTING FLEET CONTROLLER 0"); - fleetControllers.set(0, createFleetController(usingFakeTimer, fleetControllers.get(0).getOptions(), true, statusPageServer)); + fleetControllers.set(0, createFleetController(usingFakeTimer, fleetControllers.get(0).getOptions())); waitForMaster(0); log.log(Level.INFO, "STARTING FLEET CONTROLLER 1"); - fleetControllers.set(1, createFleetController(usingFakeTimer, fleetControllers.get(1).getOptions(), true, statusPageServer)); + fleetControllers.set(1, createFleetController(usingFakeTimer, fleetControllers.get(1).getOptions())); waitForMaster(0); log.log(Level.INFO, "SHUTTING DOWN FLEET CONTROLLER 4"); @@ -164,7 +159,7 @@ public class MasterElectionTest extends FleetControllerTest { private void waitForMaster(int master) { log.log(Level.INFO, "Entering waitForMaster"); boolean isOnlyMaster = false; - for (int i = 0; i < FleetControllerTest.timeoutMS; i += 100) { + for (int i = 0; i < timeout().toMillis(); i += 100) { if (!fleetControllers.get(master).isMaster()) { log.log(Level.INFO, "Node " + master + " is not master yet, sleeping more"); timer.advanceTime(100); @@ -183,7 +178,7 @@ public class MasterElectionTest extends FleetControllerTest { break; } } - // Have to wait to get zookeeper communication chance to happen. + // Have to wait to get zookeeper communication chance to happen. try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } @@ -312,13 +307,13 @@ public class MasterElectionTest extends FleetControllerTest { waitForMaster(1); } - private void waitForMasterReason(String reason, Integer master, List<Target> connections, int nodes[]) { - long endTime = System.currentTimeMillis() + timeoutMS; - while (System.currentTimeMillis() < endTime) { + private void waitForMasterReason(String reason, Integer master, List<Target> connections, int[] nodes) { + Instant endTime = Instant.now().plus(timeout()); + while (Instant.now().isBefore(endTime)) { boolean allOk = true; for (int node : nodes) { Request req = new Request("getMaster"); - connections.get(node).invokeSync(req, FleetControllerTest.timeoutS); + connections.get(node).invokeSync(req, timeout()); if (req.isError()) { allOk = false; break; @@ -335,8 +330,7 @@ public class MasterElectionTest extends FleetControllerTest { if (allOk) return; try{ Thread.sleep(100); } catch (InterruptedException e) { /* ignore */ } } - throw new IllegalStateException("Did not get master reason '" + reason - + "' within timeout of " + timeoutMS + " ms"); + throw new IllegalStateException("Did not get master reason '" + reason + "' within timeout of " + timeout()); } @Test @@ -361,10 +355,11 @@ public class MasterElectionTest extends FleetControllerTest { Request req = new Request("getMaster"); + long maxRetries = timeout().toMillis() / 100; for (int nodeIndex = 0; nodeIndex < 3; ++nodeIndex) { - for (int retry = 0; retry < FleetControllerTest.timeoutS * 10; ++retry) { + for (int retry = 0; retry < maxRetries; ++retry) { req = new Request("getMaster"); - connections.get(nodeIndex).invokeSync(req, FleetControllerTest.timeoutS); + connections.get(nodeIndex).invokeSync(req, timeout()); assertFalse(req.isError(), req.errorMessage()); if (req.returnValues().get(0).asInt32() == 0 && req.returnValues().get(1).asString().equals("All 3 nodes agree that 0 is current master.")) { @@ -395,13 +390,13 @@ public class MasterElectionTest extends FleetControllerTest { waitForMaster(1); req = new Request("getMaster"); - connections.get(0).invokeSync(req, FleetControllerTest.timeoutS); + connections.get(0).invokeSync(req, timeout()); assertEquals(104, req.errorCode(), req.toString()); assertEquals("Connection error", req.errorMessage(), req.toString()); - for (int i = 0; i < FleetControllerTest.timeoutS * 10; ++i) { + for (int i = 0; i < maxRetries; ++i) { req = new Request("getMaster"); - connections.get(1).invokeSync(req, FleetControllerTest.timeoutS); + connections.get(1).invokeSync(req, timeout()); assertFalse(req.isError(), req.errorMessage()); if (req.returnValues().get(0).asInt32() != -1) break; // We may have bad timing causing node not to have realized it is master yet @@ -409,9 +404,9 @@ public class MasterElectionTest extends FleetControllerTest { assertEquals(1, req.returnValues().get(0).asInt32(), req.toString()); assertEquals("2 of 3 nodes agree 1 is master.", req.returnValues().get(1).asString(), req.toString()); - for (int i = 0; i < FleetControllerTest.timeoutS * 10; ++i) { + for (int i = 0; i < maxRetries; ++i) { req = new Request("getMaster"); - connections.get(2).invokeSync(req, FleetControllerTest.timeoutS); + connections.get(2).invokeSync(req, timeout()); assertFalse(req.isError(), req.errorMessage()); if (req.returnValues().get(0).asInt32() != -1) break; } @@ -497,7 +492,8 @@ public class MasterElectionTest extends FleetControllerTest { options.clusterHasGlobalDocumentTypes = true; options.masterZooKeeperCooldownPeriod = 1; options.minTimeBeforeFirstSystemStateBroadcast = 100000; - setUpFleetController(3, false, options); + boolean useFakeTimer = false; + setUpFleetController(3, useFakeTimer, options); setUpVdsNodes(false, new DummyVdsNodeOptions()); fleetController = fleetControllers.get(0); // Required to prevent waitForStableSystem from NPE'ing waitForMaster(0); @@ -523,7 +519,7 @@ public class MasterElectionTest extends FleetControllerTest { waitForMaster(1); waitForCompleteCycle(1); - fleetControllers.set(0, createFleetController(usingFakeTimer, fleetControllers.get(0).getOptions(), true, new StatusHandler.ContainerStatusPageServer())); + fleetControllers.set(0, createFleetController(useFakeTimer, fleetControllers.get(0).getOptions())); waitForMaster(0); waitForCompleteCycle(0); diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/RpcServerTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/RpcServerTest.java index 41d7465b602..641f15467a6 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/RpcServerTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/RpcServerTest.java @@ -52,8 +52,7 @@ public class RpcServerTest extends FleetControllerTest { void testRebinding() throws Exception { startingTest("RpcServerTest::testRebinding"); Slobrok slobrok = new Slobrok(); - String[] slobrokConnectionSpecs = new String[1]; - slobrokConnectionSpecs[0] = "tcp/localhost:" + slobrok.port(); + String[] slobrokConnectionSpecs = getSlobrokConnectionSpecs(slobrok); RpcServer server = new RpcServer(timer, new Object(), "mycluster", 0, new BackOff()); server.setSlobrokConnectionSpecs(slobrokConnectionSpecs, 18347); int portUsed = server.getPort(); @@ -101,7 +100,7 @@ public class RpcServerTest extends FleetControllerTest { log.log(Level.INFO, "Disconnecting distributor 0. Waiting for state to reflect change."); nodes.get(0).disconnect(); nodes.get(19).disconnect(); - fleetController.waitForNodesInSlobrok(9, 9, timeoutMS); + fleetController.waitForNodesInSlobrok(9, 9, timeout()); timer.advanceTime(options.nodeStateRequestTimeoutMS + options.maxSlobrokDisconnectGracePeriod); wait(new WaitCondition.StateWait(fleetController, fleetController.getMonitor()) { @@ -120,7 +119,7 @@ public class RpcServerTest extends FleetControllerTest { } return null; } - }, null, timeoutMS); + }, null, timeout()); int rpcPort = fleetController.getRpcPort(); supervisor = new Supervisor(new Transport()); @@ -128,7 +127,7 @@ public class RpcServerTest extends FleetControllerTest { assertTrue(connection.isValid()); Request req = new Request("getSystemState"); - connection.invokeSync(req, timeoutS); + connection.invokeSync(req, timeout()); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("ss"), req.toString()); String systemState = req.returnValues().get(1).asString(); @@ -148,10 +147,7 @@ public class RpcServerTest extends FleetControllerTest { Node node = new Node(nodeType, nodeIndex); NodeState newNodeState = new NodeState(nodeType, newState); - Request req = new Request("setNodeState"); - req.parameters().add(new StringValue("storage/cluster.mycluster/" + node.getType().toString() + "/" + node.getIndex())); - req.parameters().add(new StringValue(newNodeState.serialize(true))); - connection.invokeSync(req, timeoutS); + Request req = setNodeState("storage/cluster.mycluster/" + node.getType().toString() + "/" + node.getIndex(), newNodeState, connection); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("s"), req.toString()); } @@ -193,10 +189,7 @@ public class RpcServerTest extends FleetControllerTest { Target connection = supervisor.connect(new Spec("localhost", rpcPort)); assertTrue(connection.isValid()); - Request req = new Request("getNodeState"); - req.parameters().add(new StringValue("distributor")); - req.parameters().add(new Int32Value(0)); - connection.invokeSync(req, timeoutS); + Request req = getNodeState("distributor", 0, connection); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("ssss"), req.toString()); assertEquals(State.DOWN, NodeState.deserialize(NodeType.DISTRIBUTOR, req.returnValues().get(0).asString()).getState()); @@ -204,48 +197,33 @@ public class RpcServerTest extends FleetControllerTest { assertTrue(reported.getState().oneOf("d-"), req.returnValues().get(1).asString()); assertEquals("", req.returnValues().get(2).asString()); - req = new Request("getNodeState"); - req.parameters().add(new StringValue("distributor")); - req.parameters().add(new Int32Value(2)); - connection.invokeSync(req, timeoutS); + req = getNodeState("distributor",2, connection); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("ssss"), req.toString()); assertEquals(State.DOWN, NodeState.deserialize(NodeType.DISTRIBUTOR, req.returnValues().get(0).asString()).getState()); assertEquals("t:946080000", req.returnValues().get(1).asString()); assertEquals(State.DOWN, NodeState.deserialize(NodeType.DISTRIBUTOR, req.returnValues().get(2).asString()).getState()); - req = new Request("getNodeState"); - req.parameters().add(new StringValue("distributor")); - req.parameters().add(new Int32Value(4)); - connection.invokeSync(req, timeoutS); + req = getNodeState("distributor", 4, connection); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("ssss"), req.toString()); assertEquals("", req.returnValues().get(0).asString()); assertEquals("t:946080000", req.returnValues().get(1).asString()); assertEquals("", req.returnValues().get(2).asString()); - req = new Request("getNodeState"); - req.parameters().add(new StringValue("distributor")); - req.parameters().add(new Int32Value(15)); - connection.invokeSync(req, timeoutS); + req = getNodeState("distributor", 15, connection); assertEquals(ErrorCode.METHOD_FAILED, req.errorCode(), req.toString()); assertEquals("No node distributor.15 exists in cluster mycluster", req.errorMessage()); assertFalse(req.checkReturnTypes("ssss"), req.toString()); - req = new Request("getNodeState"); - req.parameters().add(new StringValue("storage")); - req.parameters().add(new Int32Value(1)); - connection.invokeSync(req, timeoutS); + req = getNodeState("storage", 1, connection); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("ssss"), req.toString()); assertEquals("s:i i:0.2", req.returnValues().get(0).asString()); assertEquals("s:i i:0.2", req.returnValues().get(1).asString()); assertEquals("", req.returnValues().get(2).asString()); - req = new Request("getNodeState"); - req.parameters().add(new StringValue("storage")); - req.parameters().add(new Int32Value(2)); - connection.invokeSync(req, timeoutS); + req = getNodeState("storage", 2, connection); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("ssss"), req.toString()); assertEquals(State.DOWN, NodeState.deserialize(NodeType.STORAGE, req.returnValues().get(0).asString()).getState()); @@ -253,20 +231,14 @@ public class RpcServerTest extends FleetControllerTest { assertTrue(reported.getState().oneOf("d-"), req.returnValues().get(1).asString()); assertEquals(State.RETIRED, NodeState.deserialize(NodeType.STORAGE, req.returnValues().get(2).asString()).getState()); - req = new Request("getNodeState"); - req.parameters().add(new StringValue("storage")); - req.parameters().add(new Int32Value(5)); - connection.invokeSync(req, timeoutS); + req = getNodeState("storage", 5, connection); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("ssss"), req.toString()); assertEquals("", req.returnValues().get(0).asString()); assertEquals("t:946080000", req.returnValues().get(1).asString()); assertEquals("", req.returnValues().get(2).asString()); - req = new Request("getNodeState"); - req.parameters().add(new StringValue("storage")); - req.parameters().add(new Int32Value(7)); - connection.invokeSync(req, timeoutS); + req = getNodeState("storage", 7, connection); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("ssss"), req.toString()); assertEquals(State.MAINTENANCE, NodeState.deserialize(NodeType.STORAGE, req.returnValues().get(0).asString()).getState()); @@ -483,19 +455,13 @@ public class RpcServerTest extends FleetControllerTest { Target connection = supervisor.connect(new Spec("localhost", rpcPort)); assertTrue(connection.isValid()); - Request req = new Request("setNodeState"); - req.parameters().add(new StringValue("storage/cluster.mycluster/storage/14")); - req.parameters().add(new StringValue("s:r")); - connection.invokeSync(req, timeoutS); + Request req = setNodeState("storage/cluster.mycluster/storage/14", "s:r", connection); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("s"), req.toString()); waitForState("version:\\d+ distributor:26 .* storage:26 .* .14.s:r .*"); - req = new Request("setNodeState"); - req.parameters().add(new StringValue("storage/cluster.mycluster/storage/16")); - req.parameters().add(new StringValue("s:m")); - connection.invokeSync(req, timeoutS); + req = setNodeState("storage/cluster.mycluster/storage/16", "s:m", connection); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); assertTrue(req.checkReturnTypes("s"), req.toString()); @@ -528,24 +494,15 @@ public class RpcServerTest extends FleetControllerTest { Target connection = supervisor.connect(new Spec("localhost", rpcPort)); assertTrue(connection.isValid()); - Request req = new Request("setNodeState"); - req.parameters().add(new StringValue("storage/cluster.mycluster/storage/10")); - req.parameters().add(new StringValue("s:m")); - connection.invokeSync(req, timeoutS); + Request req = setNodeState("storage/cluster.mycluster/storage/10", "s:m", connection); assertEquals(ErrorCode.METHOD_FAILED, req.errorCode(), req.toString()); assertEquals("Cannot set wanted state of node storage.10. Index does not correspond to a configured node.", req.errorMessage(), req.toString()); - req = new Request("setNodeState"); - req.parameters().add(new StringValue("storage/cluster.mycluster/distributor/10")); - req.parameters().add(new StringValue("s:m")); - connection.invokeSync(req, timeoutS); + req = setNodeState("storage/cluster.mycluster/distributor/10", "s:m", connection); assertEquals(ErrorCode.METHOD_FAILED, req.errorCode(), req.toString()); assertEquals("Cannot set wanted state of node distributor.10. Index does not correspond to a configured node.", req.errorMessage(), req.toString()); - req = new Request("setNodeState"); - req.parameters().add(new StringValue("storage/cluster.mycluster/storage/9")); - req.parameters().add(new StringValue("s:m")); - connection.invokeSync(req, timeoutS); + req = setNodeState("storage/cluster.mycluster/storage/9", "s:m", connection); assertEquals(ErrorCode.NONE, req.errorCode(), req.toString()); waitForState("version:\\d+ distributor:10 storage:10 .9.s:m"); @@ -566,7 +523,7 @@ public class RpcServerTest extends FleetControllerTest { assertTrue(connection.isValid()); Request req = new Request("getMaster"); - connection.invokeSync(req, timeoutS); + connection.invokeSync(req, timeout()); assertEquals(0, req.returnValues().get(0).asInt32(), req.toString()); assertEquals("All 1 nodes agree that 0 is current master.", req.returnValues().get(1).asString(), req.toString()); @@ -590,36 +547,52 @@ public class RpcServerTest extends FleetControllerTest { Target connection = supervisor.connect(new Spec("localhost", rpcPort)); assertTrue(connection.isValid()); - // Possibly do request multiple times if we haven't lost slobrok contact first times yet. - for (int j = 0; j <= nodeCount; ++j) { - Request req = new Request("getNodeList"); - connection.invokeSync(req, timeoutS); - assertEquals(ErrorCode.NONE, req.errorCode(), req.errorMessage()); - assertTrue(req.checkReturnTypes("SS"), req.toString()); - String[] slobrok = req.returnValues().get(0).asStringArray().clone(); - String[] rpc = req.returnValues().get(1).asStringArray().clone(); - - assertEquals(2 * nodeCount, slobrok.length); - assertEquals(2 * nodeCount, rpc.length); - - // Verify that we can connect to all addresses returned. - for (int i = 0; i < 2 * nodeCount; ++i) { - if (slobrok[i].equals("storage/cluster.mycluster/distributor/0")) { - if (i < nodeCount && !"".equals(rpc[i])) { - continue; - } - assertEquals("", rpc[i], slobrok[i]); + Request req = new Request("getNodeList"); + connection.invokeSync(req, timeout()); + assertEquals(ErrorCode.NONE, req.errorCode(), req.errorMessage()); + assertTrue(req.checkReturnTypes("SS"), req.toString()); + String[] slobrok = req.returnValues().get(0).asStringArray().clone(); + String[] rpc = req.returnValues().get(1).asStringArray().clone(); + + assertEquals(2 * nodeCount, slobrok.length); + assertEquals(2 * nodeCount, rpc.length); + + // Verify that we can connect to all addresses returned. + for (int i = 0; i < 2 * nodeCount; ++i) { + if (slobrok[i].equals("storage/cluster.mycluster/distributor/0")) { + if (i < nodeCount && !"".equals(rpc[i])) { continue; } - assertNotEquals("", rpc[i]); - Request req2 = new Request("getnodestate2"); - req2.parameters().add(new StringValue("unknown")); - Target connection2 = supervisor.connect(new Spec(rpc[i])); - connection2.invokeSync(req2, timeoutS); - assertEquals(ErrorCode.NONE, req.errorCode(), req2.toString()); + assertEquals("", rpc[i], slobrok[i]); + continue; } - break; + assertNotEquals("", rpc[i]); + Request req2 = new Request("getnodestate2"); + req2.parameters().add(new StringValue("unknown")); + Target connection2 = supervisor.connect(new Spec(rpc[i])); + connection2.invokeSync(req2, timeout()); + assertEquals(ErrorCode.NONE, req.errorCode(), req2.toString()); } } + private Request setNodeState(String node, NodeState newNodeState, Target connection) { + return setNodeState(node, newNodeState.serialize(true), connection); + } + + private Request setNodeState(String node, String newNodeState, Target connection) { + Request req = new Request("setNodeState"); + req.parameters().add(new StringValue(node)); + req.parameters().add(new StringValue(newNodeState)); + connection.invokeSync(req, timeout()); + return req; + } + + private Request getNodeState(String nodeType, int nodeIndex, Target connection) { + Request req = new Request("getNodeState"); + req.parameters().add(new StringValue(nodeType)); + req.parameters().add(new Int32Value(nodeIndex)); + connection.invokeSync(req, timeout()); + return req; + } + } diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/SlobrokTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/SlobrokTest.java index b59c90f4955..78576f9600c 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/SlobrokTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/SlobrokTest.java @@ -2,14 +2,13 @@ package com.yahoo.vespa.clustercontroller.core; import com.yahoo.jrt.slobrok.server.Slobrok; -import java.util.logging.Level; import org.junit.jupiter.api.Test; +import java.util.logging.Level; +import java.util.logging.Logger; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.logging.Logger; - public class SlobrokTest extends FleetControllerTest { private static final Logger log = Logger.getLogger(SlobrokTest.class.getName()); @@ -50,10 +49,10 @@ public class SlobrokTest extends FleetControllerTest { } //fleetController.setFreshSlobrokMirror(); waitForCompleteCycle(); - fleetController.waitForNodesInSlobrok(10, 10, timeoutMS); + fleetController.waitForNodesInSlobrok(10, 10, timeout()); log.log(Level.INFO, "Waiting for cluster to be up and available again"); - for (int i = 0; i < timeoutMS; i += 10) { + for (int i = 0; i < timeout().toMillis(); i += 10) { if (clusterAvailable()) break; timer.advanceTime(1000); waitForCompleteCycle(); @@ -81,7 +80,7 @@ public class SlobrokTest extends FleetControllerTest { int version = fleetController.getSystemState().getVersion(); nodes.get(0).disconnectSlobrok(); log.log(Level.INFO, "DISCONNECTED NODE FROM SLOBROK. SHOULD BE IN COOLDOWN PERIOD"); - fleetController.waitForNodesInSlobrok(9, 10, timeoutMS); + fleetController.waitForNodesInSlobrok(9, 10, timeout()); synchronized(timer) { nodes.get(0).sendGetNodeStateReply(0); } diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateChangeTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateChangeTest.java index 24e65a89d2b..6ad0430b5c3 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateChangeTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateChangeTest.java @@ -951,22 +951,23 @@ public class StateChangeTest extends FleetControllerTest { startingTest("StateChangeTest::testNoSystemStateBeforeInitialTimePeriod()"); FleetControllerOptions options = defaultOptions("mycluster", createNodes(10)); options.minTimeBeforeFirstSystemStateBroadcast = 3 * 60 * 1000; - setUpSystem(true, options); - setUpVdsNodes(true, new DummyVdsNodeOptions(), true); + setUpSystem(options); + boolean useFakeTimer = true; + setUpVdsNodes(useFakeTimer, new DummyVdsNodeOptions(), true); // Leave one node down to avoid sending cluster state due to having seen all node states. for (int i = 0; i < nodes.size(); ++i) { if (i != 3) { nodes.get(i).connect(); } } - setUpFleetController(true, options); + setUpFleetController(useFakeTimer, options); StateWaiter waiter = new StateWaiter(timer); fleetController.addSystemStateListener(waiter); // Ensure all nodes have been seen by fleetcontroller and that it has had enough time to possibly have sent a cluster state // Note: this is a candidate state and therefore NOT versioned yet - waiter.waitForState("^distributor:10 (\\.\\d+\\.t:\\d+ )*storage:10 (\\.\\d+\\.t:\\d+ )*.1.s:d( \\.\\d+\\.t:\\d+)*", timeoutMS); + waiter.waitForState("^distributor:10 (\\.\\d+\\.t:\\d+ )*storage:10 (\\.\\d+\\.t:\\d+ )*.1.s:d( \\.\\d+\\.t:\\d+)*", timeout()); waitForCompleteCycle(); new StateMessageChecker(nodes) { @Override @@ -977,10 +978,10 @@ public class StateChangeTest extends FleetControllerTest { // Pass time and see that the nodes get state timer.advanceTime(3 * 60 * 1000); - waiter.waitForState("version:\\d+ distributor:10 storage:10 .1.s:d", timeoutMS); + waiter.waitForState("version:\\d+ distributor:10 storage:10 .1.s:d", timeout()); int version = waiter.getCurrentSystemState().getVersion(); - fleetController.waitForNodesHavingSystemStateVersionEqualToOrAbove(version, 19, timeoutMS); + fleetController.waitForNodesHavingSystemStateVersionEqualToOrAbove(version, 19, timeout()); new StateMessageChecker(nodes) { @Override @@ -997,9 +998,10 @@ public class StateChangeTest extends FleetControllerTest { final FleetControllerOptions options = defaultOptions("mycluster", createNodes(10)); options.minTimeBeforeFirstSystemStateBroadcast = 300 * 60 * 1000; - setUpSystem(true, options); + boolean useFakeTimer = true; + setUpSystem(options); - setUpVdsNodes(true, new DummyVdsNodeOptions(), true); + setUpVdsNodes(useFakeTimer, new DummyVdsNodeOptions(), true); for (DummyVdsNode node : nodes) { node.connect(); @@ -1007,16 +1009,16 @@ public class StateChangeTest extends FleetControllerTest { // Marking one node as 'initializing' improves testing of state later on. nodes.get(3).setNodeState(State.INITIALIZING); - setUpFleetController(true, options); + setUpFleetController(useFakeTimer, options); final StateWaiter waiter = new StateWaiter(timer); fleetController.addSystemStateListener(waiter); - waiter.waitForState("version:\\d+ distributor:10 storage:10 .1.s:i .1.i:1.0", timeoutMS); + waiter.waitForState("version:\\d+ distributor:10 storage:10 .1.s:i .1.i:1.0", timeout()); waitForCompleteCycle(); final int version = waiter.getCurrentSystemState().getVersion(); - fleetController.waitForNodesHavingSystemStateVersionEqualToOrAbove(version, 20, timeoutMS); + fleetController.waitForNodesHavingSystemStateVersionEqualToOrAbove(version, 20, timeout()); // The last two versions of the cluster state should be seen (all nodes up, // zero out timestate) @@ -1042,10 +1044,10 @@ public class StateChangeTest extends FleetControllerTest { nodes.get(1).failSetSystemState(true); int versionBeforeChange = nodes.get(1).getSystemStatesReceived().get(0).getVersion(); nodes.get(2).disconnect(); // cause a new state - waiter.waitForState("version:\\d+ distributor:10 .1.s:d storage:10", timeoutMS); + waiter.waitForState("version:\\d+ distributor:10 .1.s:d storage:10", timeout()); int versionAfterChange = waiter.getCurrentSystemState().getVersion(); assertTrue(versionAfterChange > versionBeforeChange); - fleetController.waitForNodesHavingSystemStateVersionEqualToOrAbove(versionAfterChange, 18, timeoutMS); + fleetController.waitForNodesHavingSystemStateVersionEqualToOrAbove(versionAfterChange, 18, timeout()); // Assert that the failed node has not acknowledged the latest version. // (The version may still be larger than versionBeforeChange if the fleet controller sends a @@ -1120,7 +1122,7 @@ public class StateChangeTest extends FleetControllerTest { // Simulate netsplit. Take node down without node booting assertTrue(nodes.get(0).isDistributor()); nodes.get(0).disconnectImmediately(); - waiter.waitForState("version:\\d+ distributor:10 .0.s:d storage:10", timeoutMS); + waiter.waitForState("version:\\d+ distributor:10 .0.s:d storage:10", timeout()); // Add node back. nodes.get(0).connect(); @@ -1128,7 +1130,7 @@ public class StateChangeTest extends FleetControllerTest { // At this time, node taken down should have cluster states with all starting timestamps set. Others node should not. for (DummyVdsNode node : nodes) { - node.waitForSystemStateVersion(waiter.getCurrentSystemState().getVersion()); + node.waitForSystemStateVersion(waiter.getCurrentSystemState().getVersion(), timeout()); List<ClusterState> states = node.getSystemStatesReceived(); ClusterState lastState = states.get(0); StringBuilder stateHistory = new StringBuilder(); diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateGatherTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateGatherTest.java index 892aefbb865..656d5a187d1 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateGatherTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/StateGatherTest.java @@ -1,10 +1,10 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.clustercontroller.core; -import java.util.logging.Level; import org.junit.jupiter.api.Test; - +import java.time.Instant; import java.util.concurrent.TimeoutException; +import java.util.logging.Level; import java.util.logging.Logger; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -33,8 +33,7 @@ public class StateGatherTest extends FleetControllerTest { options.nodeStateRequestTimeoutEarliestPercentage = 80; options.nodeStateRequestTimeoutLatestPercentage = 80; setUpFleetController(true, options); - String[] connectionSpecs = new String[1]; - connectionSpecs[0] = "tcp/localhost:" + slobrok.port(); + String[] connectionSpecs = getSlobrokConnectionSpecs(slobrok); DummyVdsNodeOptions dummyOptions = new DummyVdsNodeOptions(); DummyVdsNode dnode = new DummyVdsNode(timer, dummyOptions, connectionSpecs, this.options.clusterName, true, 0); DummyVdsNode snode = new DummyVdsNode(timer, dummyOptions, connectionSpecs, this.options.clusterName, false, 0); @@ -58,11 +57,11 @@ public class StateGatherTest extends FleetControllerTest { } private void waitUntilTimedOutGetNodeState(DummyVdsNode dnode, DummyVdsNode snode) throws TimeoutException { - long timeout = System.currentTimeMillis() + timeoutMS; + Instant endTime = Instant.now().plus(timeout()); synchronized (timer) { while (dnode.timedOutStateReplies != 1 || snode.timedOutStateReplies != 1) { - if (System.currentTimeMillis() > timeout) { - throw new TimeoutException("Did not get to have one timed out within timeout of " + timeoutMS + " ms" + if (Instant.now().isAfter(endTime)) { + throw new TimeoutException("Did not get to have one timed out within timeout of " + timeout() + ", " + getGetNodeStateReplyCounts(dnode) + ", " + getGetNodeStateReplyCounts(snode)); } try{ timer.wait(1); } catch (InterruptedException e) { /* ignore */ } @@ -71,9 +70,9 @@ public class StateGatherTest extends FleetControllerTest { } private void waitUntilPendingGetNodeState(DummyVdsNode dnode, DummyVdsNode snode) throws TimeoutException { - long timeout = System.currentTimeMillis() + timeoutMS; + Instant endTime = Instant.now().plus(timeout()); while (dnode.getPendingNodeStateCount() != 1 || snode.getPendingNodeStateCount() != 1) { - if (System.currentTimeMillis() > timeout) throw new TimeoutException("Did not get to have one pending within timeout of " + timeoutMS + " ms"); + if (Instant.now().isAfter(endTime)) throw new TimeoutException("Did not get to have one pending within timeout of " + timeout()); try{ Thread.sleep(1); } catch (InterruptedException e) { /* ignore */ } } } diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/rpc/RPCCommunicatorTest.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/rpc/RPCCommunicatorTest.java index 809979620c2..b9a9d7fbf8f 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/rpc/RPCCommunicatorTest.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/rpc/RPCCommunicatorTest.java @@ -24,15 +24,14 @@ import com.yahoo.vespa.clustercontroller.core.Timer; import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import java.time.Duration; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsNot.not; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyDouble; @@ -60,18 +59,18 @@ public class RPCCommunicatorTest { NODE_STATE_REQUEST_TIMEOUT_INTERVAL_START_PERCENTAGE, NODE_STATE_REQUEST_TIMEOUT_INTERVAL_STOP_PERCENTAGE, 0); - int max = -1; - int min = 100000; - final Set<Integer> uniqueTimeoutValues = new HashSet<>(); + long max = -1; + long min = 100000; + final Set<Long> uniqueTimeoutValues = new HashSet<>(); for (int x = 0; x < TEST_ITERATIONS; x++) { - int timeOutMs = communicator.generateNodeStateRequestTimeoutMs(); + long timeOutMs = communicator.generateNodeStateRequestTimeout().toMillis(); min = Math.min(min, timeOutMs); max = Math.max(max, timeOutMs); uniqueTimeoutValues.add(timeOutMs); } assertTrue(max <= NODE_STATE_REQUEST_TIMEOUT_INTERVAL_MAX_MS * NODE_STATE_REQUEST_TIMEOUT_INTERVAL_STOP_PERCENTAGE / 100.); - assertThat(min, is(not(max))); + assertNotEquals(min, max); assertTrue(min >= NODE_STATE_REQUEST_TIMEOUT_INTERVAL_START_PERCENTAGE * NODE_STATE_REQUEST_TIMEOUT_INTERVAL_MAX_MS / 100); assertTrue(uniqueTimeoutValues.size() > TEST_ITERATIONS / 2); @@ -85,8 +84,8 @@ public class RPCCommunicatorTest { fleetControllerOptions.nodeStateRequestTimeoutLatestPercentage = 100; fleetControllerOptions.nodeStateRequestTimeoutMS = NODE_STATE_REQUEST_TIMEOUT_INTERVAL_MAX_MS; communicator.propagateOptions(fleetControllerOptions); - int timeOutMs = communicator.generateNodeStateRequestTimeoutMs(); - assertThat(timeOutMs, is(NODE_STATE_REQUEST_TIMEOUT_INTERVAL_MAX_MS)); + long timeOutMs = communicator.generateNodeStateRequestTimeout().toMillis(); + assertEquals(timeOutMs, NODE_STATE_REQUEST_TIMEOUT_INTERVAL_MAX_MS); } @Test @@ -111,7 +110,7 @@ public class RPCCommunicatorTest { communicator.getNodeState(nodeInfo, null); Mockito.verify(target).invokeAsync( any(), - eq(ROUNDTRIP_LATENCY_SECONDS + NODE_STATE_REQUEST_TIMEOUT_INTERVAL_MAX_MS / 1000.0), + eq(Duration.ofSeconds(ROUNDTRIP_LATENCY_SECONDS).plusMillis(NODE_STATE_REQUEST_TIMEOUT_INTERVAL_MAX_MS)), any()); } @@ -141,7 +140,7 @@ public class RPCCommunicatorTest { receivedRequest.set((Request) invocation.getArguments()[0]); receivedWaiter.set((RequestWaiter) invocation.getArguments()[2]); return null; - }).when(mockTarget).invokeAsync(any(), anyDouble(), any()); + }).when(mockTarget).invokeAsync(any(), any(Duration.class), any()); } } @@ -153,12 +152,12 @@ public class RPCCommunicatorTest { f.communicator.setSystemState(sentBundle, cf.cluster().getNodeInfo(Node.ofStorage(1)), f.mockWaiter); Request req = f.receivedRequest.get(); - assertThat(req, notNullValue()); - assertThat(req.methodName(), equalTo(RPCCommunicator.SET_DISTRIBUTION_STATES_RPC_METHOD_NAME)); + assertNotNull(req); + assertEquals(req.methodName(), RPCCommunicator.SET_DISTRIBUTION_STATES_RPC_METHOD_NAME); assertTrue(req.parameters().satisfies("bix")); // <compression type>, <uncompressed size>, <payload> ClusterStateBundle receivedBundle = RPCUtil.decodeStateBundleFromSetDistributionStatesRequest(req); - assertThat(receivedBundle, equalTo(sentBundle)); + assertEquals(receivedBundle, sentBundle); } @Test @@ -169,9 +168,9 @@ public class RPCCommunicatorTest { f.communicator.setSystemState(sentBundle, cf.cluster().getNodeInfo(Node.ofStorage(1)), f.mockWaiter); RequestWaiter waiter = f.receivedWaiter.get(); - assertThat(waiter, notNullValue()); + assertNotNull(waiter); Request req = f.receivedRequest.get(); - assertThat(req, notNullValue()); + assertNotNull(req); req.setError(ErrorCode.NO_SUCH_METHOD, "que?"); waiter.handleRequestDone(req); @@ -183,8 +182,8 @@ public class RPCCommunicatorTest { // Now when we try again, we should have been downgraded to the legacy setsystemstate2 RPC f.communicator.setSystemState(sentBundle, cf.cluster().getNodeInfo(Node.ofStorage(1)), f.mockWaiter); req = f.receivedRequest.get(); - assertThat(req, notNullValue()); - assertThat(req.methodName(), equalTo(RPCCommunicator.LEGACY_SET_SYSTEM_STATE2_RPC_METHOD_NAME)); + assertNotNull(req); + assertEquals(req.methodName(), RPCCommunicator.LEGACY_SET_SYSTEM_STATE2_RPC_METHOD_NAME); } @Test @@ -194,10 +193,10 @@ public class RPCCommunicatorTest { f.communicator.activateClusterStateVersion(12345, cf.cluster().getNodeInfo(Node.ofDistributor(1)), f.mockWaiter); Request req = f.receivedRequest.get(); - assertThat(req, notNullValue()); - assertThat(req.methodName(), equalTo(RPCCommunicator.ACTIVATE_CLUSTER_STATE_VERSION_RPC_METHOD_NAME)); + assertNotNull(req); + assertEquals(req.methodName(), RPCCommunicator.ACTIVATE_CLUSTER_STATE_VERSION_RPC_METHOD_NAME); assertTrue(req.parameters().satisfies("i")); // <cluster state version> - assertThat(req.parameters().get(0).asInt32(), equalTo(12345)); + assertEquals(req.parameters().get(0).asInt32(), 12345); } } diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/StateWaiter.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/StateWaiter.java index 4cfab796a4e..d131c330381 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/StateWaiter.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/StateWaiter.java @@ -5,7 +5,7 @@ import com.yahoo.vdslib.state.ClusterState; import com.yahoo.vespa.clustercontroller.core.ClusterStateBundle; import com.yahoo.vespa.clustercontroller.core.FakeTimer; import com.yahoo.vespa.clustercontroller.core.listeners.SystemStateListener; - +import java.time.Duration; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -57,8 +57,8 @@ public class StateWaiter implements SystemStateListener { } } - public void waitForState(String stateRegex, long timeout) { - waitForState(stateRegex, timeout, 0); + public void waitForState(String stateRegex, Duration timeout) { + waitForState(stateRegex, timeout.toMillis(), 0); } /** diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/WaitCondition.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/WaitCondition.java index d6c43f54259..d6d3e2876a5 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/WaitCondition.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/WaitCondition.java @@ -156,9 +156,10 @@ public interface WaitCondition { @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("RegexStateMatcher(\n wanted: '").append(pattern.pattern()) - .append("'\n last checked: '").append(lastCheckedState).append("'") - .append("'\n current: '").append(currentState).append(")"); + sb.append("RegexStateMatcher:") + .append("\n wanted: '").append(pattern.pattern()).append("'") + .append("\n last checked: '").append(lastCheckedState).append("'") + .append("\n current: '").append(currentState).append("'"); return sb.toString(); } } diff --git a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/Waiter.java b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/Waiter.java index 6336de3d1a3..7960cd7c9d2 100644 --- a/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/Waiter.java +++ b/clustercontroller-core/src/test/java/com/yahoo/vespa/clustercontroller/core/testutils/Waiter.java @@ -1,16 +1,17 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.clustercontroller.core.testutils; -import java.util.logging.Level; import com.yahoo.vdslib.state.ClusterState; import com.yahoo.vdslib.state.Node; import com.yahoo.vespa.clustercontroller.core.DummyVdsNode; import com.yahoo.vespa.clustercontroller.core.FleetController; - +import java.time.Duration; +import java.time.Instant; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Set; +import java.util.logging.Level; import java.util.logging.Logger; public interface Waiter { @@ -19,18 +20,18 @@ public interface Waiter { Object getMonitor(); FleetController getFleetController(); List<DummyVdsNode> getDummyNodes(); - int getTimeoutMS(); + Duration getTimeout(); } ClusterState waitForState(String state) throws Exception; ClusterState waitForStateInSpace(String space, String state) throws Exception; ClusterState waitForStateInAllSpaces(String state) throws Exception; - ClusterState waitForState(String state, int timeoutMS) throws Exception; + ClusterState waitForState(String state, Duration timeoutMS) throws Exception; ClusterState waitForStableSystem() throws Exception; ClusterState waitForStableSystem(int nodeCount) throws Exception; ClusterState waitForInitProgressPassed(Node n, double progress); ClusterState waitForClusterStateIncludingNodesWithMinUsedBits(int bitcount, int nodecount); - void wait(WaitCondition c, WaitTask wt, int timeoutMS); + void wait(WaitCondition c, WaitTask wt, Duration timeout); class Impl implements Waiter { @@ -42,7 +43,7 @@ public interface Waiter { } // TODO refactor - private ClusterState waitForState(String state, int timeoutMS, boolean checkAllSpaces, Set<String> checkSpaces) { + private ClusterState waitForState(String state, Duration timeoutMS, boolean checkAllSpaces, Set<String> checkSpaces) { LinkedList<DummyVdsNode> nodesToCheck = new LinkedList<>(); for(DummyVdsNode node : data.getDummyNodes()) { if (node.isConnected()) nodesToCheck.add(node); @@ -57,15 +58,15 @@ public interface Waiter { } public ClusterState waitForState(String state) { - return waitForState(state, data.getTimeoutMS()); + return waitForState(state, data.getTimeout()); } public ClusterState waitForStateInAllSpaces(String state) { - return waitForState(state, data.getTimeoutMS(), true, Collections.emptySet()); + return waitForState(state, data.getTimeout(), true, Collections.emptySet()); } public ClusterState waitForStateInSpace(String space, String state) { - return waitForState(state, data.getTimeoutMS(), false, Collections.singleton(space)); + return waitForState(state, data.getTimeout(), false, Collections.singleton(space)); } - public ClusterState waitForState(String state, int timeoutMS) { + public ClusterState waitForState(String state, Duration timeoutMS) { return waitForState(state, timeoutMS, false, Collections.emptySet()); } public ClusterState waitForStableSystem() { @@ -73,24 +74,23 @@ public interface Waiter { } public ClusterState waitForStableSystem(int nodeCount) { WaitCondition.StateWait swc = new WaitCondition.RegexStateMatcher("version:\\d+ distributor:"+nodeCount+" storage:"+nodeCount, data.getFleetController(), data.getMonitor()).includeNotifyingNodes(data.getDummyNodes()); - wait(swc, new WaitTask.StateResender(data.getFleetController()), data.getTimeoutMS()); + wait(swc, new WaitTask.StateResender(data.getFleetController()), data.getTimeout()); return swc.getCurrentState(); } public ClusterState waitForInitProgressPassed(Node n, double progress) { WaitCondition.StateWait swc = new WaitCondition.InitProgressPassedMatcher(n, progress, data.getFleetController(), data.getMonitor()); - wait(swc, new WaitTask.StateResender(data.getFleetController()), data.getTimeoutMS()); + wait(swc, new WaitTask.StateResender(data.getFleetController()), data.getTimeout()); return swc.getCurrentState(); } public ClusterState waitForClusterStateIncludingNodesWithMinUsedBits(int bitcount, int nodecount) { WaitCondition.StateWait swc = new WaitCondition.MinUsedBitsMatcher(bitcount, nodecount, data.getFleetController(), data.getMonitor()); - wait(swc, new WaitTask.StateResender(data.getFleetController()), data.getTimeoutMS()); + wait(swc, new WaitTask.StateResender(data.getFleetController()), data.getTimeout()); return swc.getCurrentState(); } - public final void wait(WaitCondition c, WaitTask wt, int timeoutMS) { + public final void wait(WaitCondition c, WaitTask wt, Duration timeout) { log.log(Level.INFO, "Waiting for " + c + (wt == null ? "" : " with wait task " + wt)); - final long startTime = System.currentTimeMillis(); - final long endTime = startTime + timeoutMS; + Instant endTime = Instant.now().plus(timeout); String lastReason = null; while (true) { synchronized (data.getMonitor()) { @@ -111,11 +111,11 @@ public interface Waiter { allowWait = false; } } - final long timeLeft = endTime - System.currentTimeMillis(); - if (timeLeft <= 0) { - throw new IllegalStateException("Timed out waiting max " + timeoutMS + " ms for " + c + (wt == null ? "" : "\n with wait task " + wt) + ",\n reason: " + reason); - } - if (allowWait) data.getMonitor().wait(wt == null ? WaitTask.defaultTaskFrequencyMillis : Math.min(wt.getWaitTaskFrequencyInMillis(), timeLeft)); + Duration timeLeft = Duration.between(Instant.now(), endTime); + if (timeLeft.isNegative()) + throw new IllegalStateException("Timed out waiting max " + timeout + " ms for " + c + (wt == null ? "" : "\n with wait task " + wt) + ",\n reason: " + reason); + if (allowWait) + data.getMonitor().wait(wt == null ? WaitTask.defaultTaskFrequencyMillis : Math.min(wt.getWaitTaskFrequencyInMillis(), timeLeft.toMillis())); } catch (InterruptedException e) { } } diff --git a/config-model/src/main/java/com/yahoo/schema/derived/IndexInfo.java b/config-model/src/main/java/com/yahoo/schema/derived/IndexInfo.java index 4887ad52974..277858bed26 100644 --- a/config-model/src/main/java/com/yahoo/schema/derived/IndexInfo.java +++ b/config-model/src/main/java/com/yahoo/schema/derived/IndexInfo.java @@ -178,13 +178,11 @@ public class IndexInfo extends Derived implements IndexInfoConfig.Producer { PrimitiveDataType primitive = dataType.getPrimitiveType(); if (primitive == PrimitiveDataType.STRING) return true; if (primitive != null) return false; - if (dataType instanceof StructuredDataType) { - StructuredDataType structured = (StructuredDataType) dataType; + if (dataType instanceof StructuredDataType structured) { for (Field field : structured.getFields()) { if (isAnyChildString(field.getDataType())) return true; } - } else if (dataType instanceof MapDataType) { - MapDataType mapType = (MapDataType) dataType; + } else if (dataType instanceof MapDataType mapType) { return isAnyChildString(mapType.getKeyType()) || isAnyChildString(mapType.getValueType()); } return false; @@ -494,9 +492,9 @@ public class IndexInfo extends Derived implements IndexInfoConfig.Producer { */ public static class IndexCommand { - private String index; + private final String index; - private String command; + private final String command; public IndexCommand(String index, String command) { this.index = index; @@ -523,14 +521,12 @@ public class IndexInfo extends Derived implements IndexInfoConfig.Producer { } public boolean equals(Object object) { - if (!(object instanceof IndexCommand)) { + if (!(object instanceof IndexCommand other)) { return false; } - IndexCommand other = (IndexCommand)object; - return - other.index.equals(this.index) && - other.command.equals(this.command); + return other.index.equals(this.index) && + other.command.equals(this.command); } public String toString() { @@ -544,7 +540,7 @@ public class IndexInfo extends Derived implements IndexInfoConfig.Producer { */ private static abstract class IndexOverrider { - protected IndexInfo owner; + protected final IndexInfo owner; public IndexOverrider(IndexInfo owner) { this.owner = owner; @@ -560,7 +556,7 @@ public class IndexInfo extends Derived implements IndexInfoConfig.Producer { private static class StemmingOverrider extends IndexOverrider { - private Schema schema; + private final Schema schema; public StemmingOverrider(IndexInfo owner, Schema schema) { super(owner); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/FilterChains.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/FilterChains.java index bc9a45da08a..476c6249a1e 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/FilterChains.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/FilterChains.java @@ -11,6 +11,7 @@ import com.yahoo.vespa.model.container.component.chain.Chain; import com.yahoo.vespa.model.container.component.chain.Chains; import java.util.Collections; +import java.util.Set; /** * @author Tony Vaagenes @@ -44,8 +45,8 @@ public class FilterChains extends Chains<Chain<Filter>> { public static ChainSpecification emptyChainSpec(ComponentId chainId) { return new ChainSpecification(chainId, new ChainSpecification.Inheritance(null, null), - Collections.<Phase>emptySet(), - Collections.<ComponentSpecification>emptySet()); + Set.of(), + Set.of()); } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/FederationSearcher.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/FederationSearcher.java index 1abb62fedab..799309b8ca1 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/FederationSearcher.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/FederationSearcher.java @@ -45,7 +45,7 @@ public class FederationSearcher extends Searcher<FederationSearcherModel> implem this.documentTypes = documentTypes; } - public FederationConfig.Target.SearchChain.Builder getSearchChainConfig() { + FederationConfig.Target.SearchChain.Builder getSearchChainConfig() { FederationConfig.Target.SearchChain.Builder sB = new FederationConfig.Target.SearchChain.Builder(); FederationOptions resolvedOptions = targetOptions.inherit(searchChain.federationOptions()); sB. @@ -70,12 +70,12 @@ public class FederationSearcher extends Searcher<FederationSearcherModel> implem final ComponentId id; final FederationOptions targetOptions; - public Target(ComponentId id, FederationOptions targetOptions) { + Target(ComponentId id, FederationOptions targetOptions) { this.id = id; this.targetOptions = targetOptions; } - public FederationConfig.Target.Builder getTargetConfig() { + FederationConfig.Target.Builder getTargetConfig() { FederationConfig.Target.Builder tb = new FederationConfig.Target.Builder(); tb. id(id.stringValue()). @@ -92,7 +92,7 @@ public class FederationSearcher extends Searcher<FederationSearcherModel> implem private final SearchChainConfig searchChainConfig; - public SearchChainTarget(SearchChain searchChain, FederationOptions targetOptions) { + SearchChainTarget(SearchChain searchChain, FederationOptions targetOptions) { super(searchChain.getComponentId(), targetOptions); searchChainConfig = new SearchChainConfig(searchChain, null, targetOptions, searchChain.getDocumentTypes()); } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/defaultsearchchains/LocalClustersCreator.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/defaultsearchchains/LocalClustersCreator.java index 229afd56360..0307d5d5774 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/defaultsearchchains/LocalClustersCreator.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/defaultsearchchains/LocalClustersCreator.java @@ -2,15 +2,12 @@ package com.yahoo.vespa.model.container.search.searchchain.defaultsearchchains; import com.yahoo.component.ComponentId; -import com.yahoo.component.ComponentSpecification; -import com.yahoo.component.chain.Phase; import com.yahoo.component.chain.model.ChainSpecification; import com.yahoo.search.searchchain.model.federation.FederationOptions; import com.yahoo.search.searchchain.model.federation.LocalProviderSpec; import com.yahoo.vespa.model.container.search.searchchain.LocalProvider; import com.yahoo.vespa.model.container.search.searchchain.SearchChains; -import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -21,20 +18,20 @@ import java.util.Set; */ public class LocalClustersCreator { - static ChainSpecification emptySearchChainSpecification(String componentName) { + private static ChainSpecification emptySearchChainSpecification(String componentName) { return new ChainSpecification(new ComponentId(componentName), VespaSearchChainsCreator.inheritsVespaPhases(), //TODO: refactor List.of(), Set.of()); } - static LocalProvider createDefaultLocalProvider(String clusterName) { + private static LocalProvider createDefaultLocalProvider(String clusterName) { return new LocalProvider(emptySearchChainSpecification(clusterName), new FederationOptions(), new LocalProviderSpec(clusterName)); } - static Set<String> presentClusters(SearchChains searchChains) { + private static Set<String> presentClusters(SearchChains searchChains) { Set<String> presentClusters = new LinkedHashSet<>(); for (LocalProvider provider : searchChains.localProviders()) { presentClusters.add(provider.getClusterName()); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/defaultsearchchains/VespaSearchChainsCreator.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/defaultsearchchains/VespaSearchChainsCreator.java index eb396c52fca..d9c3beaaf0e 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/defaultsearchchains/VespaSearchChainsCreator.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/defaultsearchchains/VespaSearchChainsCreator.java @@ -9,10 +9,18 @@ import com.yahoo.component.chain.model.ChainedComponentModel; import com.yahoo.search.searchchain.PhaseNames; import com.yahoo.search.searchchain.model.VespaSearchers; import com.yahoo.search.searchchain.model.federation.FederationSearcherModel; -import com.yahoo.vespa.model.container.component.Component; -import com.yahoo.vespa.model.container.search.searchchain.*; +import com.yahoo.vespa.model.container.search.searchchain.FederationSearcher; +import com.yahoo.vespa.model.container.search.searchchain.SearchChain; +import com.yahoo.vespa.model.container.search.searchchain.SearchChains; +import com.yahoo.vespa.model.container.search.searchchain.Searcher; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.Optional; -import java.util.*; /** * Creates the search chains vespaPhases, vespa and native. @@ -36,17 +44,15 @@ public class VespaSearchChainsCreator { return new Phase(phase, set(before), null); } - public static Collection<Phase> linearPhases(String... phases) { + static Collection<Phase> linearPhases(String... phases) { List<Phase> result = new ArrayList<>(); for (int i=0; i < phases.length - 1; ++i) { - result.add( - createPhase(phases[i], phases[i+1])); + result.add(createPhase(phases[i], phases[i+1])); } if (phases.length > 0) { - result.add( - createPhase(lastElement(phases), null)); + result.add(createPhase(lastElement(phases), null)); } return result; @@ -54,11 +60,11 @@ public class VespaSearchChainsCreator { } private static Set<ComponentSpecification> noSearcherReferences() { - return Collections.emptySet(); + return Set.of(); } private static Collection<Phase> noPhases() { - return Collections.emptySet(); + return Set.of(); } private static ChainSpecification.Inheritance inherits(ComponentId chainId) { @@ -79,7 +85,7 @@ public class VespaSearchChainsCreator { private static Searcher<? extends ChainedComponentModel> createSearcher(ChainedComponentModel searcherModel) { if (searcherModel instanceof FederationSearcherModel) { - return new FederationSearcher((FederationSearcherModel) searcherModel, Optional.<Component>empty()); + return new FederationSearcher((FederationSearcherModel) searcherModel, Optional.empty()); } else { return new Searcher<>(searcherModel); } diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/FederationSearcherTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/FederationSearcherTest.java index 89319877d03..98f5bdbcd52 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/FederationSearcherTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/FederationSearcherTest.java @@ -19,12 +19,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.Set; -import static java.util.Collections.emptyList; -import static java.util.Collections.emptySet; -import static java.util.Collections.singletonList; -import static java.util.stream.Collectors.toList; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author Tony Vaagenes @@ -33,9 +32,9 @@ import static org.junit.jupiter.api.Assertions.*; public class FederationSearcherTest { private static class FederationFixture { - FederationSearcher federationSearchWithDefaultSources = newFederationSearcher(true, emptyList()); - private ComponentRegistry<SearchChain> searchChainRegistry = new ComponentRegistry<>(); - private SourceGroupRegistry sourceGroupRegistry = new SourceGroupRegistry(); + FederationSearcher federationSearchWithDefaultSources = newFederationSearcher(true, List.of()); + private final ComponentRegistry<SearchChain> searchChainRegistry = new ComponentRegistry<>(); + private final SourceGroupRegistry sourceGroupRegistry = new SourceGroupRegistry(); void initializeFederationSearcher(FederationSearcher searcher) { searcher.initialize(searchChainRegistry, sourceGroupRegistry); @@ -96,14 +95,14 @@ public class FederationSearcherTest { assertEquals(2, target.searchChain().size()); assertTrue(target.searchChain().stream() .map(FederationConfig.Target.SearchChain::providerId) - .collect(toList()).containsAll(List.of("provider1", "provider2"))); + .toList().containsAll(List.of("provider1", "provider2"))); } @Test void source_groups_are_not_inherited_when_inheritDefaultSources_is_false() throws Exception { FederationFixture f = new ProvidersWithSourceFixture(); - FederationSearcher federationSearcherWithoutDefaultSources = newFederationSearcher(false, emptyList()); + FederationSearcher federationSearcherWithoutDefaultSources = newFederationSearcher(false, List.of()); f.initializeFederationSearcher(federationSearcherWithoutDefaultSources); FederationConfig federationConfig = getConfig(federationSearcherWithoutDefaultSources); @@ -127,7 +126,7 @@ public class FederationSearcherTest { f.registerProviderWithSources(createProvider(ComponentId.fromString("provider1"))); FederationSearcher federation = newFederationSearcher(true, - singletonList(new TargetSpec(ComponentSpecification.fromString("provider1"), + List.of(new TargetSpec(ComponentSpecification.fromString("provider1"), new FederationOptions().setTimeoutInMilliseconds(12345)))); f.initializeFederationSearcher(federation); @@ -147,7 +146,7 @@ public class FederationSearcherTest { } private static ChainSpecification searchChainSpecification(ComponentId id) { - return new ChainSpecification(id, new ChainSpecification.Inheritance(null, null), emptyList(), emptySet()); + return new ChainSpecification(id, new ChainSpecification.Inheritance(null, null), List.of(), Set.of()); } private static Provider createProvider(ComponentId id) { @@ -161,7 +160,7 @@ public class FederationSearcherTest { private static FederationConfig getConfig(ConfigProducer configProducer) throws Exception { Optional<Class<?>> builderClassOpt = Arrays.stream(FederationConfig.class.getDeclaredClasses()) .filter(c -> c.getSimpleName().equals("Builder")).findFirst(); - if (builderClassOpt.isPresent() == false) { + if ( builderClassOpt.isEmpty()) { throw new RuntimeException("No Builder class in ConfigInstance."); } Class<?> builderClass = builderClassOpt.get(); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SchemaChainsTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SchemaChainsTest.java index 21223974be1..5588787119c 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SchemaChainsTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/searchchain/SchemaChainsTest.java @@ -5,12 +5,17 @@ import com.yahoo.component.ComponentId; import com.yahoo.container.core.ChainsConfig; import com.yahoo.prelude.cluster.ClusterSearcher; import com.yahoo.search.config.ClusterConfig; +import com.yahoo.search.searchchain.PhaseNames; import com.yahoo.vespa.defaults.Defaults; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.w3c.dom.Element; +import java.util.Collection; + import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** @@ -21,10 +26,15 @@ import static org.junit.jupiter.api.Assertions.assertEquals; */ public class SchemaChainsTest extends SchemaChainsTestBase { + private ChainsConfig chainsConfig; private ClusterConfig clusterConfig; @BeforeEach public void subscribe() { + ChainsConfig.Builder chainsBuilder = new ChainsConfig.Builder(); + chainsBuilder = (ChainsConfig.Builder)root.getConfig(chainsBuilder, "searchchains"); + chainsConfig = new ChainsConfig(chainsBuilder); + ClusterConfig.Builder clusterBuilder = new ClusterConfig.Builder(); clusterBuilder = (ClusterConfig.Builder)root.getConfig(clusterBuilder, "searchchains/chain/cluster2/component/" + ClusterSearcher.class.getName()); clusterConfig = new ClusterConfig(clusterBuilder); @@ -81,4 +91,79 @@ public class SchemaChainsTest extends SchemaChainsTestBase { assertEquals("cluster2", clusterConfig.clusterName()); } + private ChainsConfig.Chains findChain(String name) { + for (ChainsConfig.Chains chain : chainsConfig.chains()) { + if (name.equals(chain.id())) { + return chain; + } + } + return null; + } + + private static boolean contains(Collection<ChainsConfig.Chains.Phases> phases, String name) { + for (var phase : phases) { + if (name.equals(phase.id())) { + return true; + } + } + return false; + } + + private static void validateVespaPhasesChain(ChainsConfig.Chains chain) { + assertNotNull(chain); + assertEquals("vespaPhases", chain.id()); + assertEquals(5, chain.phases().size()); + assertTrue(contains(chain.phases(), PhaseNames.BACKEND)); + assertTrue(contains(chain.phases(), PhaseNames.BLENDED_RESULT)); + assertTrue(contains(chain.phases(), PhaseNames.RAW_QUERY)); + assertTrue(contains(chain.phases(), PhaseNames.TRANSFORMED_QUERY)); + assertTrue(contains(chain.phases(), PhaseNames.UNBLENDED_RESULT)); + assertTrue(chain.inherits().isEmpty()); + assertTrue(chain.components().isEmpty()); + assertTrue(chain.excludes().isEmpty()); + assertEquals(ChainsConfig.Chains.Type.SEARCH, chain.type()); + } + + private static void validateNativeChain(ChainsConfig.Chains chain) { + assertNotNull(chain); + assertEquals("native", chain.id()); + assertTrue(chain.phases().isEmpty()); + assertEquals(1, chain.inherits().size()); + assertEquals("vespaPhases", chain.inherits(0)); + assertEquals(2, chain.components().size()); + assertEquals("federation@native", chain.components(0)); + assertEquals("com.yahoo.prelude.statistics.StatisticsSearcher@native", chain.components(1)); + assertTrue(chain.excludes().isEmpty()); + assertEquals(ChainsConfig.Chains.Type.SEARCH, chain.type()); + } + + private static void validateVespaChain(ChainsConfig.Chains chain) { + assertNotNull(chain); + assertEquals("vespa", chain.id()); + assertTrue(chain.phases().isEmpty()); + assertEquals(1, chain.inherits().size()); + assertEquals("native", chain.inherits(0)); + assertEquals(10, chain.components().size()); + assertEquals("com.yahoo.prelude.querytransform.PhrasingSearcher@vespa", chain.components(0)); + assertEquals("com.yahoo.prelude.searcher.FieldCollapsingSearcher@vespa", chain.components(1)); + assertEquals("com.yahoo.search.yql.MinimalQueryInserter@vespa", chain.components(2)); + assertEquals("com.yahoo.search.yql.FieldFilter@vespa", chain.components(3)); + assertEquals("com.yahoo.prelude.searcher.JuniperSearcher@vespa", chain.components(4)); + assertEquals("com.yahoo.prelude.searcher.BlendingSearcher@vespa", chain.components(5)); + assertEquals("com.yahoo.prelude.searcher.PosSearcher@vespa", chain.components(6)); + assertEquals("com.yahoo.prelude.semantics.SemanticSearcher@vespa", chain.components(7)); + assertEquals("com.yahoo.search.grouping.GroupingQueryParser@vespa", chain.components(8)); + assertEquals("com.yahoo.search.querytransform.WeakAndReplacementSearcher@vespa", chain.components(9)); + assertTrue(chain.excludes().isEmpty()); + assertEquals(ChainsConfig.Chains.Type.SEARCH, chain.type()); + } + + @Test + public void require_all_default_chains_are_correct() { + assertEquals(61, chainsConfig.components().size()); + assertEquals(10, chainsConfig.chains().size()); + validateVespaPhasesChain(findChain("vespaPhases")); + validateNativeChain(findChain("native")); + validateVespaChain(findChain("vespa")); + } } diff --git a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java index 02c5aeb33c7..994bdef5898 100644 --- a/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java +++ b/config-proxy/src/main/java/com/yahoo/vespa/config/proxy/RpcConfigSourceClient.java @@ -84,7 +84,7 @@ class RpcConfigSourceClient implements ConfigSourceClient, Runnable { for (String configSource : configSourceSet.getSources()) { Spec spec = new Spec(configSource); Target target = supervisor.connect(spec); - target.invokeSync(req, 30.0); + target.invokeSync(req, Duration.ofSeconds(30)); if (target.isValid()) return; diff --git a/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServerTest.java b/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServerTest.java index a946704234d..250f0705e5b 100644 --- a/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServerTest.java +++ b/config-proxy/src/test/java/com/yahoo/vespa/config/proxy/ConfigProxyRpcServerTest.java @@ -309,7 +309,7 @@ public class ConfigProxyRpcServerTest { } void invoke(Request request) { - target.invokeSync(request, Duration.ofMinutes(10).getSeconds()); + target.invokeSync(request, Duration.ofMinutes(10)); } @Override diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigRequester.java b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigRequester.java index d77cfc17c92..858dc46f77a 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigRequester.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/JRTConfigRequester.java @@ -45,7 +45,7 @@ public class JRTConfigRequester implements RequestWaiter { private static final Duration delayBetweenWarnings = Duration.ofSeconds(60); static final float randomFraction = 0.2f; /* Time to be added to server timeout to create client timeout. This is the time allowed for the server to respond after serverTimeout has elapsed. */ - private static final Double additionalTimeForClientTimeout = 10.0; + private static final Duration additionalTimeForClientTimeout = Duration.ofSeconds(10); private final TimingValues timingValues; private final ScheduledThreadPoolExecutor scheduler; @@ -100,7 +100,7 @@ public class JRTConfigRequester implements RequestWaiter { request.setContext(new RequestContext(sub, req, connection)); if (!req.validateParameters()) throw new ConfigurationRuntimeException("Error in parameters for config request: " + req); - double jrtClientTimeout = getClientTimeout(req); + Duration jrtClientTimeout = getClientTimeout(req); log.log(FINE, () -> "Requesting config for " + sub + " on connection " + connection + " with client timeout " + jrtClientTimeout + (log.isLoggable(FINEST) ? (",defcontent=" + req.getDefContent().asString()) : "")); @@ -271,7 +271,7 @@ public class JRTConfigRequester implements RequestWaiter { return connectionPool; } - private Double getClientTimeout(JRTClientConfigRequest request) { - return (request.getTimeout() / 1000.0) + additionalTimeForClientTimeout; + private Duration getClientTimeout(JRTClientConfigRequest request) { + return Duration.ofMillis(request.getTimeout()).plus(additionalTimeForClientTimeout); } } diff --git a/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java b/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java index 24a080d5824..dc0372cea7f 100644 --- a/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java +++ b/config/src/main/java/com/yahoo/config/subscription/impl/MockConnection.java @@ -10,6 +10,8 @@ import com.yahoo.vespa.config.PayloadChecksums; import com.yahoo.vespa.config.protocol.JRTServerConfigRequestV3; import com.yahoo.vespa.config.protocol.Payload; +import java.time.Duration; + /** * For unit testing * @@ -37,14 +39,14 @@ public class MockConnection implements ConnectionPool, Connection { } @Override - public void invokeAsync(Request request, double jrtTimeout, RequestWaiter requestWaiter) { + public void invokeAsync(Request request, Duration jrtTimeout, RequestWaiter requestWaiter) { numberOfRequests++; lastRequest = request; responseHandler.handle(request, requestWaiter); } @Override - public void invokeSync(Request request, double jrtTimeout) { + public void invokeSync(Request request, Duration jrtTimeout) { numberOfRequests++; lastRequest = request; } diff --git a/config/src/main/java/com/yahoo/vespa/config/Connection.java b/config/src/main/java/com/yahoo/vespa/config/Connection.java index ea6419c62e1..69e8fcf9963 100644 --- a/config/src/main/java/com/yahoo/vespa/config/Connection.java +++ b/config/src/main/java/com/yahoo/vespa/config/Connection.java @@ -4,14 +4,16 @@ package com.yahoo.vespa.config; import com.yahoo.jrt.Request; import com.yahoo.jrt.RequestWaiter; +import java.time.Duration; + /** * @author hmusum */ public interface Connection { - void invokeAsync(Request request, double jrtTimeout, RequestWaiter requestWaiter); + void invokeAsync(Request request, Duration jrtTimeout, RequestWaiter requestWaiter); - void invokeSync(Request request, double jrtTimeout); + void invokeSync(Request request, Duration jrtTimeout); String getAddress(); diff --git a/config/src/main/java/com/yahoo/vespa/config/JRTConnection.java b/config/src/main/java/com/yahoo/vespa/config/JRTConnection.java index 2d7c96febd6..f2a104696c1 100644 --- a/config/src/main/java/com/yahoo/vespa/config/JRTConnection.java +++ b/config/src/main/java/com/yahoo/vespa/config/JRTConnection.java @@ -7,6 +7,7 @@ import com.yahoo.jrt.Spec; import com.yahoo.jrt.Supervisor; import com.yahoo.jrt.Target; +import java.time.Duration; import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; @@ -30,12 +31,12 @@ public class JRTConnection implements Connection { } @Override - public void invokeAsync(Request request, double jrtTimeout, RequestWaiter requestWaiter) { + public void invokeAsync(Request request, Duration jrtTimeout, RequestWaiter requestWaiter) { getTarget().invokeAsync(request, jrtTimeout, requestWaiter); } @Override - public void invokeSync(Request request, double jrtTimeout) { + public void invokeSync(Request request, Duration jrtTimeout) { getTarget().invokeSync(request, jrtTimeout); } diff --git a/config/src/main/java/com/yahoo/vespa/config/UrlDownloader.java b/config/src/main/java/com/yahoo/vespa/config/UrlDownloader.java index b3a4590fdb2..62308315c95 100644 --- a/config/src/main/java/com/yahoo/vespa/config/UrlDownloader.java +++ b/config/src/main/java/com/yahoo/vespa/config/UrlDownloader.java @@ -11,6 +11,7 @@ import com.yahoo.jrt.Transport; import com.yahoo.vespa.defaults.Defaults; import java.io.File; +import java.time.Duration; import java.util.logging.Logger; import static java.util.logging.Level.FINE; @@ -47,7 +48,7 @@ public class UrlDownloader { target = supervisor.connect(spec); // ping to check if connection is working Request request = new Request("frt.rpc.ping"); - target.invokeSync(request, 5.0); + target.invokeSync(request, Duration.ofSeconds(5)); if (! request.isError()) { log.log(FINE, () -> "Successfully connected to '" + spec + "', this = " + System.identityHashCode(this)); return; diff --git a/config/src/main/java/com/yahoo/vespa/config/benchmark/LoadTester.java b/config/src/main/java/com/yahoo/vespa/config/benchmark/LoadTester.java index 345118b5fd4..5b0f1351ff5 100644 --- a/config/src/main/java/com/yahoo/vespa/config/benchmark/LoadTester.java +++ b/config/src/main/java/com/yahoo/vespa/config/benchmark/LoadTester.java @@ -26,6 +26,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -239,7 +240,7 @@ public class LoadTester { System.out.println("# Requesting: " + reqKey); long start = System.nanoTime(); - target.invokeSync(request.getRequest(), 10.0); + target.invokeSync(request.getRequest(), Duration.ofSeconds(10)); long durationInMillis = (System.nanoTime() - start) / 1_000_000; if (request.isError()) { diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/FileDistributionStatus.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/FileDistributionStatus.java index 23df938e0b7..c80faa2375a 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/FileDistributionStatus.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/FileDistributionStatus.java @@ -65,7 +65,7 @@ public class FileDistributionStatus extends AbstractComponent { HostStatus getHostStatus(String hostname, int port, Duration timeout) { Target target = supervisor.connect(new Spec(hostname, port)); Request request = new Request("filedistribution.getActiveFileReferencesStatus"); - target.invokeSync(request, timeout.toMillis() / 1000); + target.invokeSync(request, timeout); HostStatus hostStatus = createHostStatusFromResponse(hostname, request); target.close(); return hostStatus; diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDistributionImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDistributionImpl.java index abb8a3e8487..7d7d4aa1d7d 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDistributionImpl.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/filedistribution/FileDistributionImpl.java @@ -10,6 +10,7 @@ import com.yahoo.jrt.StringArray; import com.yahoo.jrt.Supervisor; import com.yahoo.jrt.Target; +import java.time.Duration; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -20,7 +21,7 @@ import java.util.logging.Logger; public class FileDistributionImpl implements FileDistribution, RequestWaiter { private final static Logger log = Logger.getLogger(FileDistributionImpl.class.getName()); - private final static double rpcTimeout = 1.0; + private final static Duration rpcTimeout = Duration.ofSeconds(1); private final Supervisor supervisor; diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/RpcServer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/RpcServer.java index 6518957a4ab..b36967d76a4 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/RpcServer.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/rpc/RpcServer.java @@ -45,6 +45,7 @@ import com.yahoo.vespa.filedistribution.FileReceiver; import com.yahoo.vespa.filedistribution.FileReferenceData; import com.yahoo.vespa.filedistribution.FileReferenceDownload; import java.nio.ByteBuffer; +import java.time.Duration; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -571,7 +572,7 @@ public class RpcServer implements Runnable, ConfigActivationListener, TenantList private void invokeRpcIfValidConnection(Request request) { if (target.isValid()) { - target.invokeSync(request, 600); + target.invokeSync(request, Duration.ofMinutes(10)); } else { throw new RuntimeException("Connection to " + target + " is invalid", target.getConnectionLostReason()); } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/RpcTester.java b/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/RpcTester.java index 40ed20b7969..441f6c3a6ce 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/RpcTester.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/rpc/RpcTester.java @@ -166,7 +166,7 @@ public class RpcTester implements AutoCloseable { void performRequest(Request req) { clock.advance(Duration.ofMillis(10)); - sup.connect(spec).invokeSync(req, 10.0); + sup.connect(spec).invokeSync(req, Duration.ofSeconds(10)); if (req.methodName().equals(RpcServer.getConfigMethodName)) assertEquals(clock.instant(), hostLivenessTracker.lastRequestFrom(myHostname).get()); } diff --git a/container-core/src/main/java/com/yahoo/component/chain/model/ChainSpecification.java b/container-core/src/main/java/com/yahoo/component/chain/model/ChainSpecification.java index a1c169dc387..f53b431265c 100644 --- a/container-core/src/main/java/com/yahoo/component/chain/model/ChainSpecification.java +++ b/container-core/src/main/java/com/yahoo/component/chain/model/ChainSpecification.java @@ -6,7 +6,15 @@ import com.yahoo.component.ComponentId; import com.yahoo.component.ComponentSpecification; import com.yahoo.component.chain.Phase; -import java.util.*; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Collections; +import java.util.Deque; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + /** * Specifies how the components should be selected to create a chain. Immutable. @@ -20,7 +28,7 @@ public class ChainSpecification { public final Set<ComponentSpecification> excludedComponents; Inheritance flattened() { - return new Inheritance(Collections.<ComponentSpecification>emptySet(), excludedComponents); + return new Inheritance(Set.of(), excludedComponents); } public Inheritance(Set<ComponentSpecification> inheritedChains, Set<ComponentSpecification> excludedComponents) { @@ -38,7 +46,7 @@ public class ChainSpecification { public final ComponentId componentId; public final Inheritance inheritance; - final Map<String, Phase> phases; + private final Map<String, Phase> phases; public final Set<ComponentSpecification> componentReferences; public ChainSpecification(ComponentId componentId, Inheritance inheritance, diff --git a/container-search/src/main/java/com/yahoo/search/querytransform/WeakAndReplacementSearcher.java b/container-search/src/main/java/com/yahoo/search/querytransform/WeakAndReplacementSearcher.java index b47b54bc362..898e348db92 100644 --- a/container-search/src/main/java/com/yahoo/search/querytransform/WeakAndReplacementSearcher.java +++ b/container-search/src/main/java/com/yahoo/search/querytransform/WeakAndReplacementSearcher.java @@ -1,7 +1,10 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.search.querytransform; -import com.yahoo.prelude.query.*; +import com.yahoo.prelude.query.CompositeItem; +import com.yahoo.prelude.query.Item; +import com.yahoo.prelude.query.OrItem; +import com.yahoo.prelude.query.WeakAndItem; import com.yahoo.processing.request.CompoundName; import com.yahoo.search.Query; import com.yahoo.search.Result; @@ -15,7 +18,8 @@ import com.yahoo.search.searchchain.Execution; * @author karowan */ public class WeakAndReplacementSearcher extends Searcher { - private static final CompoundName WEAKAND_REPLACE = new CompoundName("weakAnd.replace"); + static final CompoundName WEAKAND_REPLACE = new CompoundName("weakAnd.replace"); + static final CompoundName WAND_HITS = new CompoundName("wand.hits"); @Override public Result search(Query query, Execution execution) { if (!query.properties().getBoolean(WEAKAND_REPLACE)) { @@ -31,7 +35,7 @@ public class WeakAndReplacementSearcher extends Searcher { */ private void replaceOrItems(Query query) { Item root = query.getModel().getQueryTree().getRoot(); - int hits = query.properties().getInteger("wand.hits", WeakAndItem.defaultN); + int hits = query.properties().getInteger(WAND_HITS, WeakAndItem.defaultN); query.getModel().getQueryTree().setRoot(replaceOrItems(root, hits)); if (root != query.getModel().getQueryTree().getRoot()) query.trace("Replaced OR by WeakAnd", true, 2); @@ -45,10 +49,9 @@ public class WeakAndReplacementSearcher extends Searcher { * @return the original item or a WeakAndItem replacement of an OrItem */ private Item replaceOrItems(Item item, int hits) { - if (!(item instanceof CompositeItem)) { + if (!(item instanceof CompositeItem compositeItem)) { return item; } - CompositeItem compositeItem = (CompositeItem) item; if (compositeItem instanceof OrItem) { WeakAndItem newItem = new WeakAndItem(hits); newItem.setWeight(compositeItem.getWeight()); diff --git a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java index a149ae9323a..384be7798fa 100644 --- a/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java +++ b/container-search/src/main/java/com/yahoo/search/yql/YqlParser.java @@ -106,7 +106,7 @@ public class YqlParser implements Parser { public static final String ASCENDING_HITS_ORDER = "ascending"; private enum SegmentWhen { - NEVER, POSSIBLY, ALWAYS; + NEVER, POSSIBLY, ALWAYS } private static class IndexNameExpander { @@ -290,7 +290,7 @@ public class YqlParser implements Parser { Preconditions.checkArgument(filterPart.getArguments().length == 2, "Expected 2 arguments to filter, got %s.", filterPart.getArguments().length); - populateYqlSources(filterPart.<OperatorNode<?>> getArgument(0)); + populateYqlSources(filterPart.getArgument(0)); OperatorNode<ExpressionOperator> filterExpression = filterPart.getArgument(1); Item root = convertExpression(filterExpression); connectItems(); @@ -617,6 +617,8 @@ public class YqlParser implements Parser { // All terms below sameElement are relative to this. IndexNameExpander prev = swapIndexCreator(new PrefixExpander(field)); for (OperatorNode<ExpressionOperator> term : ast.<List<OperatorNode<ExpressionOperator>>> getArgument(1)) { + // TODO getIndex that is called once every term is rather expensive as it does sanity checking + // that is not necessary. This is an issue when having many elements sameElement.addItem(convertExpression(term)); } swapIndexCreator(prev); @@ -838,7 +840,7 @@ public class YqlParser implements Parser { OperatorNode<?> ast = toScan; while (ast.getOperator() == SequenceOperator.PIPE) { OperatorNode<ExpressionOperator> groupingAst = ast.<List<OperatorNode<ExpressionOperator>>> getArgument(2).get(0); - GroupingOperation groupingOperation = GroupingOperation.fromString(groupingAst.<String> getArgument(0)); + GroupingOperation groupingOperation = GroupingOperation.fromString(groupingAst.getArgument(0)); VespaGroupingStep groupingStep = new VespaGroupingStep(groupingOperation); List<Object> continuations = getAnnotation(groupingAst, "continuations", List.class, Collections.emptyList(), "grouping continuations"); @@ -854,8 +856,7 @@ public class YqlParser implements Parser { } private String dereference(Object constantOrVarref) { - if (constantOrVarref instanceof OperatorNode) { - OperatorNode<?> varref = (OperatorNode<?>)constantOrVarref; + if (constantOrVarref instanceof OperatorNode<?> varref) { Preconditions.checkState(userQuery != null, "properties must be available when trying to fetch user input"); return userQuery.properties().getString(varref.getArgument(0, String.class)); @@ -871,7 +872,7 @@ public class YqlParser implements Parser { List<FieldOrder> sortingInit = new ArrayList<>(); List<OperatorNode<?>> sortArguments = ast.getArgument(1); for (OperatorNode<?> op : sortArguments) { - OperatorNode<ExpressionOperator> fieldNode = op.<OperatorNode<ExpressionOperator>> getArgument(0); + OperatorNode<ExpressionOperator> fieldNode = op.getArgument(0); String field = fetchFieldRead(fieldNode); String locale = getAnnotation(fieldNode, SORTING_LOCALE, String.class, null, "locale used by sorting function"); @@ -963,7 +964,7 @@ public class YqlParser implements Parser { Preconditions.checkArgument(ast.getArguments().length == 2, "Expected 2 arguments to PROJECT, got %s.", ast.getArguments().length); - populateYqlSummaryFields(ast.<List<OperatorNode<ProjectOperator>>> getArgument(1)); + populateYqlSummaryFields(ast.getArgument(1)); return ast.getArgument(0); } @@ -1127,7 +1128,6 @@ public class YqlParser implements Parser { return convertVarArgs(spec, 0, new OrItem()); } - @SuppressWarnings("deprecation") private CompositeItem buildWeakAnd(OperatorNode<ExpressionOperator> spec) { WeakAndItem weakAnd = new WeakAndItem(); Integer targetNumHits = getAnnotation(spec, TARGET_HITS, @@ -1175,7 +1175,7 @@ public class YqlParser implements Parser { if (userQuery != null && indexFactsSession.getIndex(field).isAttribute()) { userQuery.trace("Field '" + field + "' is an attribute, 'contains' will only match exactly (unless fuzzy is used)", 2); } - return instantiateLeafItem(field, ast.<OperatorNode<ExpressionOperator>> getArgument(1)); + return instantiateLeafItem(field, ast.getArgument(1)); } private Item buildRegExpSearch(OperatorNode<ExpressionOperator> ast) { @@ -1468,7 +1468,7 @@ public class YqlParser implements Parser { wordItem = new WordItem(wordData, fromQuery); break; case POSSIBLY: - if (shouldSegment(field, ast, fromQuery) && ! grammar.equals(USER_INPUT_RAW)) { + if (shouldSegment(field, fromQuery) && ! grammar.equals(USER_INPUT_RAW)) { wordItem = segment(field, ast, wordData, fromQuery, parent, language); } else { wordItem = new WordItem(wordData, fromQuery); @@ -1489,7 +1489,7 @@ public class YqlParser implements Parser { return (Item) leafStyleSettings(ast, wordItem); } - private boolean shouldSegment(String field, OperatorNode<ExpressionOperator> ast, boolean fromQuery) { + private boolean shouldSegment(String field, boolean fromQuery) { return fromQuery && ! indexFactsSession.getIndex(indexNameExpander.expand(field)).isAttribute(); } @@ -1584,8 +1584,7 @@ public class YqlParser implements Parser { leaf.setWeight(weight); } } - if (out instanceof IntItem) { - IntItem number = (IntItem) out; + if (out instanceof IntItem number) { Integer hitLimit = getCappedRangeSearchParameter(ast); if (hitLimit != null) { number.setHitLimit(hitLimit); @@ -1822,7 +1821,7 @@ public class YqlParser implements Parser { Object value = ast.getAnnotation(key); for (Iterator<OperatorNode<?>> i = annotationStack.iterator(); value == null && considerParents && i.hasNext();) { - OperatorNode node = i.next(); + OperatorNode<?> node = i.next(); if (node.getOperator() == ExpressionOperator.VARREF) { Preconditions.checkState(userQuery != null, "properties must be available when trying to fetch user input"); @@ -1886,8 +1885,7 @@ public class YqlParser implements Parser { @Override public boolean visit(Item item) { - if (item instanceof WordItem) { - WordItem w = (WordItem) item; + if (item instanceof WordItem w) { if (usePositionData != null) { w.setPositionData(usePositionData); } diff --git a/container-search/src/test/java/com/yahoo/search/querytransform/WeakAndReplacementSearcherTestCase.java b/container-search/src/test/java/com/yahoo/search/querytransform/WeakAndReplacementSearcherTestCase.java index 30d06510409..97e37c2f40c 100644 --- a/container-search/src/test/java/com/yahoo/search/querytransform/WeakAndReplacementSearcherTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/querytransform/WeakAndReplacementSearcherTestCase.java @@ -2,8 +2,14 @@ package com.yahoo.search.querytransform; import com.yahoo.component.chain.Chain; -import com.yahoo.prelude.query.*; -import com.yahoo.processing.request.CompoundName; +import com.yahoo.prelude.query.AndItem; +import com.yahoo.prelude.query.CompositeItem; +import com.yahoo.prelude.query.IntItem; +import com.yahoo.prelude.query.Item; +import com.yahoo.prelude.query.NotItem; +import com.yahoo.prelude.query.OrItem; +import com.yahoo.prelude.query.WeakAndItem; +import com.yahoo.prelude.query.WordItem; import com.yahoo.search.Query; import com.yahoo.search.Result; import com.yahoo.search.Searcher; @@ -12,11 +18,14 @@ import org.junit.jupiter.api.Test; import java.util.stream.IntStream; -import static org.junit.jupiter.api.Assertions.*; +import static com.yahoo.search.querytransform.WeakAndReplacementSearcher.WEAKAND_REPLACE; +import static com.yahoo.search.querytransform.WeakAndReplacementSearcher.WAND_HITS; -public class WeakAndReplacementSearcherTestCase { +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; - private static final CompoundName WEAKAND_REPLACE = new CompoundName("weakAnd.replace"); +public class WeakAndReplacementSearcherTestCase { private static final int N = 99; @@ -27,7 +36,7 @@ public class WeakAndReplacementSearcherTestCase { private Query buildDefaultQuery(boolean searcherEnabled) { Query query = new Query(); - query.properties().set("wand.hits", N); + query.properties().set(WAND_HITS, N); query.properties().set(WEAKAND_REPLACE, searcherEnabled); OrItem root = new OrItem(); root.addItem(new WordItem("text")); diff --git a/container-search/src/test/java/com/yahoo/search/searchchain/test/SearchChainTestCase.java b/container-search/src/test/java/com/yahoo/search/searchchain/test/SearchChainTestCase.java index 3e7a152122e..ef35b5beabe 100644 --- a/container-search/src/test/java/com/yahoo/search/searchchain/test/SearchChainTestCase.java +++ b/container-search/src/test/java/com/yahoo/search/searchchain/test/SearchChainTestCase.java @@ -26,7 +26,6 @@ import org.junit.jupiter.api.Test; * * @author bratseth */ -@SuppressWarnings("deprecation") public class SearchChainTestCase { @Test @@ -87,7 +86,7 @@ public class SearchChainTestCase { private List<Searcher> createSearchers(int count) { List<Searcher> searchers=new ArrayList<>(count); for (int i=0; i<count; i++) - searchers.add(new TestSearcher("s" + String.valueOf(i+1))); + searchers.add(new TestSearcher("s" + (i+1))); return searchers; } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/UserSessionManager.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/UserSessionManager.java new file mode 100644 index 00000000000..eae62c66b35 --- /dev/null +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/user/UserSessionManager.java @@ -0,0 +1,13 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.api.integration.user; + +import com.yahoo.vespa.hosted.controller.api.role.SecurityContext; + +/** + * @author freva + */ +public interface UserSessionManager { + + /** Returns whether the existing session for the given SecurityContext should be expired */ + boolean shouldExpireSessionFor(SecurityContext context); +} diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudTenant.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudTenant.java index 54924b9c456..44f9c0ea3b8 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudTenant.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/tenant/CloudTenant.java @@ -25,17 +25,19 @@ public class CloudTenant extends Tenant { private final TenantInfo info; private final List<TenantSecretStore> tenantSecretStores; private final ArchiveAccess archiveAccess; + private final Optional<Instant> invalidateUserSessionsBefore; /** Public for the serialization layer — do not use! */ public CloudTenant(TenantName name, Instant createdAt, LastLoginInfo lastLoginInfo, Optional<Principal> creator, BiMap<PublicKey, Principal> developerKeys, TenantInfo info, - List<TenantSecretStore> tenantSecretStores, ArchiveAccess archiveAccess) { + List<TenantSecretStore> tenantSecretStores, ArchiveAccess archiveAccess, Optional<Instant> invalidateUserSessionsBefore) { super(name, createdAt, lastLoginInfo, Optional.empty()); this.creator = creator; this.developerKeys = developerKeys; this.info = Objects.requireNonNull(info); this.tenantSecretStores = tenantSecretStores; this.archiveAccess = Objects.requireNonNull(archiveAccess); + this.invalidateUserSessionsBefore = invalidateUserSessionsBefore; } /** Creates a tenant with the given name, provided it passes validation. */ @@ -44,7 +46,7 @@ public class CloudTenant extends Tenant { createdAt, LastLoginInfo.EMPTY, Optional.ofNullable(creator), - ImmutableBiMap.of(), TenantInfo.empty(), List.of(), new ArchiveAccess()); + ImmutableBiMap.of(), TenantInfo.empty(), List.of(), new ArchiveAccess(), Optional.empty()); } /** The user that created the tenant */ @@ -75,6 +77,11 @@ public class CloudTenant extends Tenant { return archiveAccess; } + /** Returns instant before which all user sessions that have access to this tenant must be refreshed */ + public Optional<Instant> invalidateUserSessionsBefore() { + return invalidateUserSessionsBefore; + } + @Override public Type type() { return Type.cloud; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedTenant.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedTenant.java index 4f58e87035b..ac7c6319c1b 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedTenant.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/LockedTenant.java @@ -129,25 +129,27 @@ public abstract class LockedTenant { private final TenantInfo info; private final List<TenantSecretStore> tenantSecretStores; private final ArchiveAccess archiveAccess; + private final Optional<Instant> invalidateUserSessionsBefore; private Cloud(TenantName name, Instant createdAt, LastLoginInfo lastLoginInfo, Optional<Principal> creator, BiMap<PublicKey, Principal> developerKeys, TenantInfo info, - List<TenantSecretStore> tenantSecretStores, ArchiveAccess archiveAccess) { + List<TenantSecretStore> tenantSecretStores, ArchiveAccess archiveAccess, Optional<Instant> invalidateUserSessionsBefore) { super(name, createdAt, lastLoginInfo); this.developerKeys = ImmutableBiMap.copyOf(developerKeys); this.creator = creator; this.info = info; this.tenantSecretStores = tenantSecretStores; this.archiveAccess = archiveAccess; + this.invalidateUserSessionsBefore = invalidateUserSessionsBefore; } private Cloud(CloudTenant tenant) { - this(tenant.name(), tenant.createdAt(), tenant.lastLoginInfo(), tenant.creator(), tenant.developerKeys(), tenant.info(), tenant.tenantSecretStores(), tenant.archiveAccess()); + this(tenant.name(), tenant.createdAt(), tenant.lastLoginInfo(), tenant.creator(), tenant.developerKeys(), tenant.info(), tenant.tenantSecretStores(), tenant.archiveAccess(), tenant.invalidateUserSessionsBefore()); } @Override public CloudTenant get() { - return new CloudTenant(name, createdAt, lastLoginInfo, creator, developerKeys, info, tenantSecretStores, archiveAccess); + return new CloudTenant(name, createdAt, lastLoginInfo, creator, developerKeys, info, tenantSecretStores, archiveAccess, invalidateUserSessionsBefore); } public Cloud withDeveloperKey(PublicKey key, Principal principal) { @@ -155,38 +157,42 @@ public abstract class LockedTenant { if (keys.containsKey(key)) throw new IllegalArgumentException("Key " + KeyUtils.toPem(key) + " is already owned by " + keys.get(key)); keys.put(key, principal); - return new Cloud(name, createdAt, lastLoginInfo, creator, keys, info, tenantSecretStores, archiveAccess); + return new Cloud(name, createdAt, lastLoginInfo, creator, keys, info, tenantSecretStores, archiveAccess, invalidateUserSessionsBefore); } public Cloud withoutDeveloperKey(PublicKey key) { BiMap<PublicKey, Principal> keys = HashBiMap.create(developerKeys); keys.remove(key); - return new Cloud(name, createdAt, lastLoginInfo, creator, keys, info, tenantSecretStores, archiveAccess); + return new Cloud(name, createdAt, lastLoginInfo, creator, keys, info, tenantSecretStores, archiveAccess, invalidateUserSessionsBefore); } public Cloud withInfo(TenantInfo newInfo) { - return new Cloud(name, createdAt, lastLoginInfo, creator, developerKeys, newInfo, tenantSecretStores, archiveAccess); + return new Cloud(name, createdAt, lastLoginInfo, creator, developerKeys, newInfo, tenantSecretStores, archiveAccess, invalidateUserSessionsBefore); } @Override public LockedTenant with(LastLoginInfo lastLoginInfo) { - return new Cloud(name, createdAt, lastLoginInfo, creator, developerKeys, info, tenantSecretStores, archiveAccess); + return new Cloud(name, createdAt, lastLoginInfo, creator, developerKeys, info, tenantSecretStores, archiveAccess, invalidateUserSessionsBefore); } public Cloud withSecretStore(TenantSecretStore tenantSecretStore) { ArrayList<TenantSecretStore> secretStores = new ArrayList<>(tenantSecretStores); secretStores.add(tenantSecretStore); - return new Cloud(name, createdAt, lastLoginInfo, creator, developerKeys, info, secretStores, archiveAccess); + return new Cloud(name, createdAt, lastLoginInfo, creator, developerKeys, info, secretStores, archiveAccess, invalidateUserSessionsBefore); } public Cloud withoutSecretStore(TenantSecretStore tenantSecretStore) { ArrayList<TenantSecretStore> secretStores = new ArrayList<>(tenantSecretStores); secretStores.remove(tenantSecretStore); - return new Cloud(name, createdAt, lastLoginInfo, creator, developerKeys, info, secretStores, archiveAccess); + return new Cloud(name, createdAt, lastLoginInfo, creator, developerKeys, info, secretStores, archiveAccess, invalidateUserSessionsBefore); } public Cloud withArchiveAccess(ArchiveAccess archiveAccess) { - return new Cloud(name, createdAt, lastLoginInfo, creator, developerKeys, info, tenantSecretStores, archiveAccess); + return new Cloud(name, createdAt, lastLoginInfo, creator, developerKeys, info, tenantSecretStores, archiveAccess, invalidateUserSessionsBefore); + } + + public Cloud withInvalidateUserSessionsBefore(Instant invalidateUserSessionsBefore) { + return new Cloud(name, createdAt, lastLoginInfo, creator, developerKeys, info, tenantSecretStores, archiveAccess, Optional.of(invalidateUserSessionsBefore)); } } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TenantSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TenantSerializer.java index e7cf0c34511..e91fbe8b1b7 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TenantSerializer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/TenantSerializer.java @@ -81,6 +81,7 @@ public class TenantSerializer { private static final String archiveAccessField = "archiveAccess"; private static final String awsArchiveAccessRoleField = "awsArchiveAccessRole"; private static final String gcpArchiveAccessMemberField = "gcpArchiveAccessMember"; + private static final String invalidateUserSessionsBeforeField = "invalidateUserSessionsBefore"; private static final String awsIdField = "awsId"; private static final String roleField = "role"; @@ -123,6 +124,7 @@ public class TenantSerializer { toSlime(tenant.info(), root); toSlime(tenant.tenantSecretStores(), root); toSlime(tenant.archiveAccess(), root); + tenant.invalidateUserSessionsBefore().ifPresent(instant -> root.setLong(invalidateUserSessionsBeforeField, instant.toEpochMilli())); } private void toSlime(ArchiveAccess archiveAccess, Cursor root) { @@ -187,7 +189,8 @@ public class TenantSerializer { TenantInfo info = tenantInfoFromSlime(tenantObject.field(tenantInfoField)); List<TenantSecretStore> tenantSecretStores = secretStoresFromSlime(tenantObject.field(secretStoresField)); ArchiveAccess archiveAccess = archiveAccessFromSlime(tenantObject); - return new CloudTenant(name, createdAt, lastLoginInfo, creator, developerKeys, info, tenantSecretStores, archiveAccess); + Optional<Instant> invalidateUserSessionsBefore = SlimeUtils.optionalInstant(tenantObject.field(invalidateUserSessionsBeforeField)); + return new CloudTenant(name, createdAt, lastLoginInfo, creator, developerKeys, info, tenantSecretStores, archiveAccess, invalidateUserSessionsBefore); } private DeletedTenant deletedTenantFrom(Inspector tenantObject) { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java index e10defb4416..a407e5aa211 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiHandler.java @@ -111,7 +111,6 @@ public class UserApiHandler extends ThreadedHttpRequestHandler { private HttpResponse handlePOST(Path path, HttpRequest request) { if (path.matches("/user/v1/tenant/{tenant}")) return addTenantRoleMember(path.get("tenant"), request); - if (path.matches("/user/v1/tenant/{tenant}/application/{application}")) return addApplicationRoleMember(path.get("tenant"), path.get("application"), request); return ErrorResponse.notFoundError(Text.format("No '%s' handler at '%s'", request.getMethod(), request.getUri().getPath())); @@ -119,7 +118,6 @@ public class UserApiHandler extends ThreadedHttpRequestHandler { private HttpResponse handleDELETE(Path path, HttpRequest request) { if (path.matches("/user/v1/tenant/{tenant}")) return removeTenantRoleMember(path.get("tenant"), request); - if (path.matches("/user/v1/tenant/{tenant}/application/{application}")) return removeApplicationRoleMember(path.get("tenant"), path.get("application"), request); return ErrorResponse.notFoundError(Text.format("No '%s' handler at '%s'", request.getMethod(), request.getUri().getPath())); @@ -255,21 +253,6 @@ public class UserApiHandler extends ThreadedHttpRequestHandler { private HttpResponse addTenantRoleMember(String tenantName, HttpRequest request) { Inspector requestObject = bodyInspector(request); - if (requestObject.field("roles").valid()) { - return addMultipleTenantRoleMembers(tenantName, requestObject); - } - return addTenantRoleMember(tenantName, requestObject); - } - - private HttpResponse addTenantRoleMember(String tenantName, Inspector requestObject) { - String roleName = require("roleName", Inspector::asString, requestObject); - UserId user = new UserId(require("user", Inspector::asString, requestObject)); - Role role = Roles.toRole(TenantName.from(tenantName), roleName); - users.addUsers(role, List.of(user)); - return new MessageResponse(user + " is now a member of " + role); - } - - private HttpResponse addMultipleTenantRoleMembers(String tenantName, Inspector requestObject) { var tenant = TenantName.from(tenantName); var user = new UserId(require("user", Inspector::asString, requestObject)); var roles = SlimeStream.fromArray(requestObject.field("roles"), Inspector::asString) @@ -280,37 +263,8 @@ public class UserApiHandler extends ThreadedHttpRequestHandler { return new MessageResponse(user + " is now a member of " + roles.stream().map(Role::toString).collect(Collectors.joining(", "))); } - private HttpResponse addApplicationRoleMember(String tenantName, String applicationName, HttpRequest request) { - Inspector requestObject = bodyInspector(request); - String roleName = require("roleName", Inspector::asString, requestObject); - UserId user = new UserId(require("user", Inspector::asString, requestObject)); - Role role = Roles.toRole(TenantName.from(tenantName), ApplicationName.from(applicationName), roleName); - users.addUsers(role, List.of(user)); - return new MessageResponse(user + " is now a member of " + role); - } - private HttpResponse removeTenantRoleMember(String tenantName, HttpRequest request) { Inspector requestObject = bodyInspector(request); - if (requestObject.field("roles").valid()) { - return removeMultipleTenantRoleMembers(tenantName, requestObject); - } - return removeTenantRoleMember(tenantName, requestObject); - } - - private HttpResponse removeTenantRoleMember(String tenantName, Inspector requestObject) { - TenantName tenant = TenantName.from(tenantName); - String roleName = require("roleName", Inspector::asString, requestObject); - UserId user = new UserId(require("user", Inspector::asString, requestObject)); - List<Role> roles = Collections.singletonList(Roles.toRole(tenant, roleName)); - - enforceLastAdminOfTenant(tenant, user, roles); - removeDeveloperKey(tenant, user, roles); - users.removeFromRoles(user, roles); - - return new MessageResponse(user + " is no longer a member of " + roles.stream().map(Role::toString).collect(Collectors.joining(", "))); - } - - private HttpResponse removeMultipleTenantRoleMembers(String tenantName, Inspector requestObject) { var tenant = TenantName.from(tenantName); var user = new UserId(require("user", Inspector::asString, requestObject)); var roles = SlimeStream.fromArray(requestObject.field("roles"), Inspector::asString) @@ -321,6 +275,11 @@ public class UserApiHandler extends ThreadedHttpRequestHandler { removeDeveloperKey(tenant, user, roles); users.removeFromRoles(user, roles); + controller.tenants().lockIfPresent(tenant, LockedTenant.class, lockedTenant -> { + if (lockedTenant instanceof LockedTenant.Cloud cloudTenant) + controller.tenants().store(cloudTenant.withInvalidateUserSessionsBefore(controller.clock().instant())); + }); + return new MessageResponse(user + " is no longer a member of " + roles.stream().map(Role::toString).collect(Collectors.joining(", "))); } @@ -348,15 +307,6 @@ public class UserApiHandler extends ThreadedHttpRequestHandler { } } - private HttpResponse removeApplicationRoleMember(String tenantName, String applicationName, HttpRequest request) { - Inspector requestObject = bodyInspector(request); - String roleName = require("roleName", Inspector::asString, requestObject); - UserId user = new UserId(require("user", Inspector::asString, requestObject)); - Role role = Roles.toRole(TenantName.from(tenantName), ApplicationName.from(applicationName), roleName); - users.removeUsers(role, List.of(user)); - return new MessageResponse(user + " is no longer a member of " + role); - } - private boolean hasTrialCapacity() { if (! controller.system().isPublic()) return true; var existing = controller.tenants().asList().stream().map(Tenant::name).collect(Collectors.toList()); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudUserSessionManager.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudUserSessionManager.java new file mode 100644 index 00000000000..e2b5083abae --- /dev/null +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/security/CloudUserSessionManager.java @@ -0,0 +1,50 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.security; + +import com.yahoo.config.provision.TenantName; +import com.yahoo.vespa.flags.LongFlag; +import com.yahoo.vespa.flags.PermanentFlags; +import com.yahoo.vespa.hosted.controller.Controller; +import com.yahoo.vespa.hosted.controller.TenantController; +import com.yahoo.vespa.hosted.controller.api.integration.user.UserSessionManager; +import com.yahoo.vespa.hosted.controller.api.role.SecurityContext; +import com.yahoo.vespa.hosted.controller.api.role.TenantRole; +import com.yahoo.vespa.hosted.controller.tenant.CloudTenant; + +import java.time.Instant; + +/** + * @author freva + */ +public class CloudUserSessionManager implements UserSessionManager { + + private final TenantController tenantController; + private final LongFlag invalidateConsoleSessions; + + public CloudUserSessionManager(Controller controller) { + this.tenantController = controller.tenants(); + this.invalidateConsoleSessions = PermanentFlags.INVALIDATE_CONSOLE_SESSIONS.bindTo(controller.flagSource()); + } + + @Override + public boolean shouldExpireSessionFor(SecurityContext context) { + if (context.issuedAt().isBefore(Instant.ofEpochSecond(invalidateConsoleSessions.value()))) + return true; + + return context.roles().stream() + .filter(TenantRole.class::isInstance) + .map(TenantRole.class::cast) + .map(TenantRole::tenant) + .distinct() + .anyMatch(tenantName -> shouldExpireSessionFor(tenantName, context.issuedAt())); + } + + private boolean shouldExpireSessionFor(TenantName tenantName, Instant contextIssuedAt) { + return tenantController.get(tenantName) + .filter(CloudTenant.class::isInstance) + .map(CloudTenant.class::cast) + .flatMap(CloudTenant::invalidateUserSessionsBefore) + .map(contextIssuedAt::isBefore) + .orElse(false); + } +} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/notification/NotificationsDbTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/notification/NotificationsDbTest.java index 1a171341ee0..4c1344650f8 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/notification/NotificationsDbTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/notification/NotificationsDbTest.java @@ -61,7 +61,8 @@ public class NotificationsDbTest { List.of(TenantContacts.Audience.NOTIFICATIONS), email)))), List.of(), - new ArchiveAccess()); + new ArchiveAccess(), + Optional.empty()); private static final List<Notification> notifications = List.of( notification(1001, Type.deployment, Level.error, NotificationSource.from(tenant), "tenant msg"), notification(1101, Type.applicationPackage, Level.warning, NotificationSource.from(TenantAndApplicationId.from(tenant.value(), "app1")), "app msg"), diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/notification/NotifierTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/notification/NotifierTest.java index 00d8c100ced..7c07192d633 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/notification/NotifierTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/notification/NotifierTest.java @@ -41,7 +41,8 @@ public class NotifierTest { List.of(TenantContacts.Audience.NOTIFICATIONS), email)))), List.of(), - new ArchiveAccess()); + new ArchiveAccess(), + Optional.empty()); MockCuratorDb curatorDb = new MockCuratorDb(SystemName.Public); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/TenantSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/TenantSerializerTest.java index e29d4afabff..636620acf07 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/TenantSerializerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/TenantSerializerTest.java @@ -103,8 +103,8 @@ public class TenantSerializerTest { otherPublicKey, new SimplePrincipal("jane")), TenantInfo.empty(), List.of(), - new ArchiveAccess() - ); + new ArchiveAccess(), + Optional.empty()); CloudTenant serialized = (CloudTenant) serializer.tenantFrom(serializer.toSlime(tenant)); assertEquals(tenant.name(), serialized.name()); assertEquals(tenant.creator(), serialized.creator()); @@ -125,11 +125,12 @@ public class TenantSerializerTest { new TenantSecretStore("ss1", "123", "role1"), new TenantSecretStore("ss2", "124", "role2") ), - new ArchiveAccess().withAWSRole("arn:aws:iam::123456789012:role/my-role") - ); + new ArchiveAccess().withAWSRole("arn:aws:iam::123456789012:role/my-role"), + Optional.of(Instant.ofEpochMilli(1234567))); CloudTenant serialized = (CloudTenant) serializer.tenantFrom(serializer.toSlime(tenant)); assertEquals(tenant.info(), serialized.info()); assertEquals(tenant.tenantSecretStores(), serialized.tenantSecretStores()); + assertEquals(tenant.invalidateUserSessionsBefore(), serialized.invalidateUserSessionsBefore()); } @Test @@ -174,8 +175,8 @@ public class TenantSerializerTest { otherPublicKey, new SimplePrincipal("jane")), TenantInfo.empty(), List.of(), - new ArchiveAccess().withAWSRole("arn:aws:iam::123456789012:role/my-role").withGCPMember("user:foo@example.com") - ); + new ArchiveAccess().withAWSRole("arn:aws:iam::123456789012:role/my-role").withGCPMember("user:foo@example.com"), + Optional.empty()); CloudTenant serialized = (CloudTenant) serializer.tenantFrom(serializer.toSlime(tenant)); assertEquals(serialized.archiveAccess().awsRole().get(), "arn:aws:iam::123456789012:role/my-role"); assertEquals(serialized.archiveAccess().gcpMember().get(), "user:foo@example.com"); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/SignatureFilterTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/SignatureFilterTest.java index 9ff79213983..ec9be1f04c3 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/SignatureFilterTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/filter/SignatureFilterTest.java @@ -77,7 +77,8 @@ public class SignatureFilterTest { ImmutableBiMap.of(), TenantInfo.empty(), List.of(), - new ArchiveAccess())); + new ArchiveAccess(), + Optional.empty())); tester.curator().writeApplication(new Application(appId, tester.clock().instant())); } @@ -123,7 +124,8 @@ public class SignatureFilterTest { ImmutableBiMap.of(publicKey, () -> "user"), TenantInfo.empty(), List.of(), - new ArchiveAccess())); + new ArchiveAccess(), + Optional.empty())); verifySecurityContext(requestOf(signer.signed(request.copy(), Method.POST, () -> new ByteArrayInputStream(hiBytes)), hiBytes), new SecurityContext(new SimplePrincipal("user"), Set.of(Role.reader(id.tenant()), diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiTest.java index 3e9f6256134..1344b106bbe 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/UserApiTest.java @@ -84,7 +84,7 @@ public class UserApiTest extends ControllerContainerCloudTest { // POST a hosted operator role is not allowed. tester.assertResponse(request("/user/v1/tenant/my-tenant", POST) .roles(Set.of(Role.administrator(id.tenant()))) - .data("{\"user\":\"evil@evil\",\"roleName\":\"hostedOperator\"}"), + .data("{\"user\":\"evil@evil\",\"roles\":[\"hostedOperator\"]}"), "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Malformed or illegal role name 'hostedOperator'.\"}", 400); // POST a tenant developer is available to the tenant owner. @@ -96,15 +96,9 @@ public class UserApiTest extends ControllerContainerCloudTest { // POST a tenant admin is not available to a tenant developer. tester.assertResponse(request("/user/v1/tenant/my-tenant", POST) .roles(Set.of(Role.developer(id.tenant()))) - .data("{\"user\":\"developer@tenant\",\"roleName\":\"administrator\"}"), + .data("{\"user\":\"developer@tenant\",\"roles\":[\"administrator\"]}"), accessDenied, 403); - // POST a headless for a non-existent application fails. - tester.assertResponse(request("/user/v1/tenant/my-tenant/application/my-app", POST) - .roles(Set.of(Role.administrator(TenantName.from("my-tenant")))) - .data("{\"user\":\"headless@app\",\"roleName\":\"headless\"}"), - "{\"error-code\":\"BAD_REQUEST\",\"message\":\"role 'headless' of 'my-app' owned by 'my-tenant' not found\"}", 400); - // POST an application is allowed for a tenant developer. tester.assertResponse(request("/application/v4/tenant/my-tenant/application/my-app", POST) .principal("developer@tenant") @@ -116,22 +110,11 @@ public class UserApiTest extends ControllerContainerCloudTest { .roles(Set.of(Role.administrator(id.tenant()))), accessDenied, 403); - // POST a tenant role is not allowed to an application. - tester.assertResponse(request("/user/v1/tenant/my-tenant/application/my-app", POST) - .roles(Set.of(Role.hostedOperator())) - .data("{\"user\":\"developer@app\",\"roleName\":\"developer\"}"), - "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Malformed or illegal role name 'developer'.\"}", 400); - // GET tenant role information is available to readers. tester.assertResponse(request("/user/v1/tenant/my-tenant") .roles(Set.of(Role.reader(id.tenant()))), new File("tenant-roles.json")); - // GET application role information is available to tenant administrators. - tester.assertResponse(request("/user/v1/tenant/my-tenant/application/my-app") - .roles(Set.of(Role.administrator(id.tenant()))), - new File("application-roles.json")); - // POST a pem deploy key tester.assertResponse(request("/application/v4/tenant/my-tenant/application/my-app/key", POST) .roles(Set.of(Role.developer(id.tenant()))) @@ -200,7 +183,7 @@ public class UserApiTest extends ControllerContainerCloudTest { // DELETE the last tenant owner is not allowed. tester.assertResponse(request("/user/v1/tenant/my-tenant", DELETE) .roles(operator) - .data("{\"user\":\"administrator@tenant\",\"roleName\":\"administrator\"}"), + .data("{\"user\":\"administrator@tenant\",\"roles\":[\"administrator\"]}"), "{\"error-code\":\"BAD_REQUEST\",\"message\":\"Can't remove the last administrator of a tenant.\"}", 400); // DELETE the tenant is not allowed diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/responses/application-roles.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/responses/application-roles.json deleted file mode 100644 index 8497358fe40..00000000000 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/user/responses/application-roles.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "tenant": "my-tenant", - "application": "my-app", - "roleNames": [ ], - "users": [ - { - "name": "administrator@tenant", - "email": "administrator@tenant", - "verified": false, - "roles": { } - }, - { - "name": "developer@tenant", - "email": "developer@tenant", - "verified": false, - "roles": { } - } - ] -} diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/security/CloudUserSessionManagerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/security/CloudUserSessionManagerTest.java new file mode 100644 index 00000000000..710e75fb235 --- /dev/null +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/security/CloudUserSessionManagerTest.java @@ -0,0 +1,64 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.controller.security; + +import com.yahoo.config.provision.SystemName; +import com.yahoo.config.provision.TenantName; +import com.yahoo.vespa.flags.InMemoryFlagSource; +import com.yahoo.vespa.flags.PermanentFlags; +import com.yahoo.vespa.hosted.controller.ControllerTester; +import com.yahoo.vespa.hosted.controller.LockedTenant; +import com.yahoo.vespa.hosted.controller.api.role.Role; +import com.yahoo.vespa.hosted.controller.api.role.SecurityContext; +import com.yahoo.vespa.hosted.controller.api.role.SimplePrincipal; +import com.yahoo.vespa.hosted.controller.api.role.TenantRole; +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author freva + */ +class CloudUserSessionManagerTest { + + private final ControllerTester tester = new ControllerTester(SystemName.Public); + private final CloudUserSessionManager userSessionManager = new CloudUserSessionManager(tester.controller()); + + @Test + void test() { + createTenant("tenant1", null); + createTenant("tenant2", 1234); + createTenant("tenant3", 1543); + createTenant("tenant4", 2313); + + assertShouldExpire(false, 123); + assertShouldExpire(false, 123, "tenant1"); + assertShouldExpire(true, 123, "tenant2"); + assertShouldExpire(false, 2123, "tenant2"); + assertShouldExpire(true, 123, "tenant1", "tenant2"); + + ((InMemoryFlagSource) tester.controller().flagSource()).withLongFlag(PermanentFlags.INVALIDATE_CONSOLE_SESSIONS.id(), 150); + assertShouldExpire(true, 123); + assertShouldExpire(true, 123, "tenant1"); + } + + private void assertShouldExpire(boolean expected, long issuedAtSeconds, String... tenantNames) { + Set<Role> roles = Stream.of(tenantNames).map(name -> TenantRole.developer(TenantName.from(name))).collect(Collectors.toSet()); + SecurityContext context = new SecurityContext(new SimplePrincipal("dev"), roles, Instant.ofEpochSecond(issuedAtSeconds)); + assertEquals(expected, userSessionManager.shouldExpireSessionFor(context)); + } + + private void createTenant(String tenantName, Integer invalidateAfterSeconds) { + tester.createTenant(tenantName); + Optional.ofNullable(invalidateAfterSeconds) + .map(Instant::ofEpochSecond) + .ifPresent(instant -> + tester.controller().tenants().lockOrThrow(TenantName.from(tenantName), LockedTenant.Cloud.class, tenant -> + tester.controller().tenants().store(tenant.withInvalidateUserSessionsBefore(instant)))); + } +} diff --git a/fileacquirer/src/main/java/com/yahoo/filedistribution/fileacquirer/FileAcquirerImpl.java b/fileacquirer/src/main/java/com/yahoo/filedistribution/fileacquirer/FileAcquirerImpl.java index c85a24db9bb..122027d706b 100644 --- a/fileacquirer/src/main/java/com/yahoo/filedistribution/fileacquirer/FileAcquirerImpl.java +++ b/fileacquirer/src/main/java/com/yahoo/filedistribution/fileacquirer/FileAcquirerImpl.java @@ -5,6 +5,8 @@ import com.yahoo.cloud.config.filedistribution.FiledistributorrpcConfig; import com.yahoo.config.subscription.ConfigSubscriber; import com.yahoo.config.FileReference; import com.yahoo.jrt.*; + +import java.time.Duration; import java.util.logging.Level; import java.util.logging.Logger; @@ -56,7 +58,7 @@ class FileAcquirerImpl implements FileAcquirer { target = supervisor.connect(spec); // ping to check if connection is working Request request = new Request("frt.rpc.ping"); - target.invokeSync(request, 5.0); + target.invokeSync(request, Duration.ofSeconds(5)); if (request.isError()) { logWarning(); target.close(); diff --git a/fileacquirer/src/main/java/com/yahoo/filedistribution/fileacquirer/Timer.java b/fileacquirer/src/main/java/com/yahoo/filedistribution/fileacquirer/Timer.java index b1ef519d901..e8c08edb621 100644 --- a/fileacquirer/src/main/java/com/yahoo/filedistribution/fileacquirer/Timer.java +++ b/fileacquirer/src/main/java/com/yahoo/filedistribution/fileacquirer/Timer.java @@ -1,6 +1,7 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.filedistribution.fileacquirer; +import java.time.Duration; import java.util.concurrent.TimeUnit; /** @@ -10,16 +11,16 @@ import java.util.concurrent.TimeUnit; class Timer { private final long endTime; - private long timeLeft() { - return endTime - System.currentTimeMillis(); + private Duration timeLeft() { + return Duration.ofNanos(endTime - System.nanoTime()); } public Timer(long timeout, TimeUnit timeUnit) { - endTime = System.currentTimeMillis() + timeUnit.toMillis(timeout); + endTime = System.nanoTime() + timeUnit.toNanos(timeout); } public long timeLeft(TimeUnit timeUnit) { - long remaining = timeUnit.convert(timeLeft(), TimeUnit.MILLISECONDS); + long remaining = timeUnit.convert(timeLeft().toMillis(), TimeUnit.MILLISECONDS); if (remaining > 0) return remaining; @@ -28,6 +29,6 @@ class Timer { } public boolean isTimeLeft() { - return timeLeft() > 0; + return ! timeLeft().isNegative(); } } diff --git a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java index 7078c5aae6c..f6ebfcc416c 100644 --- a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java +++ b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/FileReferenceDownloader.java @@ -113,7 +113,7 @@ public class FileReferenceDownloader { private boolean startDownloadRpc(FileReferenceDownload fileReferenceDownload, int retryCount, Connection connection) { Request request = createRequest(fileReferenceDownload); Duration rpcTimeout = rpcTimeout(retryCount); - connection.invokeSync(request, rpcTimeout.getSeconds()); + connection.invokeSync(request, rpcTimeout); Level logLevel = (retryCount > 3 ? Level.INFO : Level.FINE); FileReference fileReference = fileReferenceDownload.fileReference(); diff --git a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/RpcTester.java b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/RpcTester.java index f3b166c60fe..571c1f3a81f 100644 --- a/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/RpcTester.java +++ b/filedistribution/src/main/java/com/yahoo/vespa/filedistribution/RpcTester.java @@ -13,6 +13,8 @@ import com.yahoo.jrt.StringValue; import com.yahoo.jrt.Supervisor; import com.yahoo.jrt.Target; import com.yahoo.jrt.Transport; + +import java.time.Duration; import java.util.logging.Level; import net.jpountz.xxhash.XXHash64; import net.jpountz.xxhash.XXHashFactory; @@ -91,7 +93,7 @@ public class RpcTester { fileBlob.parameters().add(new Int32Value(0)); fileBlob.parameters().add(new StringValue("OK")); log.log(Level.INFO, "Doing invokeSync"); - target.invokeSync(fileBlob, 5); + target.invokeSync(fileBlob, Duration.ofSeconds(5)); log.log(Level.INFO, "Done with invokeSync"); } } diff --git a/filedistribution/src/test/java/com/yahoo/vespa/filedistribution/FileDownloaderTest.java b/filedistribution/src/test/java/com/yahoo/vespa/filedistribution/FileDownloaderTest.java index 629ea5915df..ffef06e6367 100644 --- a/filedistribution/src/test/java/com/yahoo/vespa/filedistribution/FileDownloaderTest.java +++ b/filedistribution/src/test/java/com/yahoo/vespa/filedistribution/FileDownloaderTest.java @@ -334,12 +334,12 @@ public class FileDownloaderTest { } @Override - public void invokeAsync(Request request, double jrtTimeout, RequestWaiter requestWaiter) { + public void invokeAsync(Request request, Duration jrtTimeout, RequestWaiter requestWaiter) { responseHandler.request(request); } @Override - public void invokeSync(Request request, double jrtTimeout) { + public void invokeSync(Request request, Duration jrtTimeout) { responseHandler.request(request); } diff --git a/jrt/src/com/yahoo/jrt/Connection.java b/jrt/src/com/yahoo/jrt/Connection.java index 1e4092efb75..8a185907aae 100644 --- a/jrt/src/com/yahoo/jrt/Connection.java +++ b/jrt/src/com/yahoo/jrt/Connection.java @@ -464,8 +464,7 @@ class Connection extends Target { waiter.waitDone(); } - public void invokeAsync(Request req, double timeout, - RequestWaiter waiter) { + public void invokeAsync(Request req, double timeout, RequestWaiter waiter) { if (timeout < 0.0) { timeout = 0.0; } diff --git a/jrt/src/com/yahoo/jrt/Target.java b/jrt/src/com/yahoo/jrt/Target.java index 0e8c27deac5..6cb9d432e03 100644 --- a/jrt/src/com/yahoo/jrt/Target.java +++ b/jrt/src/com/yahoo/jrt/Target.java @@ -3,6 +3,8 @@ package com.yahoo.jrt; import com.yahoo.security.tls.ConnectionAuthContext; +import java.time.Duration; + /** * A Target represents a connection endpoint with RPC * capabilities. Each such connection has a client and a server @@ -101,6 +103,10 @@ public abstract class Target { */ public abstract void invokeSync(Request req, double timeout); + public void invokeSync(Request req, Duration timeout) { + invokeSync(req, toSeconds(timeout)); + } + /** * Invoke a request on this target and let the completion be * signalled with a callback. @@ -109,8 +115,15 @@ public abstract class Target { * @param timeout timeout in seconds * @param waiter callback handler */ - public abstract void invokeAsync(Request req, double timeout, - RequestWaiter waiter); + public abstract void invokeAsync(Request req, double timeout, RequestWaiter waiter); + + public void invokeAsync(Request req, Duration timeout, RequestWaiter waiter) { + invokeAsync(req, toSeconds(timeout), waiter); + } + + private static double toSeconds(Duration duration) { + return ((double)duration.toMillis())/1000.0; + } /** * Invoke a request on this target, but ignore the return diff --git a/jrt/src/com/yahoo/jrt/slobrok/api/Mirror.java b/jrt/src/com/yahoo/jrt/slobrok/api/Mirror.java index 7963cd51c75..778cb0455e8 100644 --- a/jrt/src/com/yahoo/jrt/slobrok/api/Mirror.java +++ b/jrt/src/com/yahoo/jrt/slobrok/api/Mirror.java @@ -13,6 +13,7 @@ import com.yahoo.jrt.Task; import com.yahoo.jrt.TransportThread; import com.yahoo.jrt.Values; +import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -206,7 +207,7 @@ public class Mirror implements IMirror { req = new Request("slobrok.incremental.fetch"); req.parameters().add(new Int32Value(specsGeneration)); // gencnt req.parameters().add(new Int32Value(5000)); // mstimeout - target.invokeAsync(req, 40.0, reqWait); + target.invokeAsync(req, Duration.ofSeconds(40), reqWait); } private void handleUpdate() { diff --git a/jrt/src/com/yahoo/jrt/slobrok/api/Register.java b/jrt/src/com/yahoo/jrt/slobrok/api/Register.java index 14afea396bf..e529dea2eff 100644 --- a/jrt/src/com/yahoo/jrt/slobrok/api/Register.java +++ b/jrt/src/com/yahoo/jrt/slobrok/api/Register.java @@ -15,6 +15,7 @@ import com.yahoo.jrt.Task; import com.yahoo.jrt.TransportThread; import com.yahoo.jrt.Values; +import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -279,7 +280,7 @@ public class Register { req.parameters().add(new StringValue(name)); req.parameters().add(new StringValue(mySpec)); log.log(Level.FINE, logMessagePrefix() + " now"); - target.invokeAsync(req, 35.0, reqWait); + target.invokeAsync(req, Duration.ofSeconds(35), reqWait); } private String logMessagePrefix() { diff --git a/jrt/src/com/yahoo/jrt/slobrok/server/Slobrok.java b/jrt/src/com/yahoo/jrt/slobrok/server/Slobrok.java index 24ab63c1d2f..5fd8beb3cc7 100644 --- a/jrt/src/com/yahoo/jrt/slobrok/server/Slobrok.java +++ b/jrt/src/com/yahoo/jrt/slobrok/server/Slobrok.java @@ -17,6 +17,7 @@ import com.yahoo.jrt.TargetWatcher; import com.yahoo.jrt.Task; import com.yahoo.jrt.Transport; +import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -225,7 +226,7 @@ public class Slobrok { this.spec = spec; target = orb.connect(new Spec(spec)); Request cbReq = new Request("slobrok.callback.listNamesServed"); - target.invokeAsync(cbReq, 5.0, this); + target.invokeAsync(cbReq, Duration.ofSeconds(5), this); } @Override diff --git a/jrt/src/com/yahoo/jrt/tool/RpcInvoker.java b/jrt/src/com/yahoo/jrt/tool/RpcInvoker.java index 71049673d90..67933cfafde 100644 --- a/jrt/src/com/yahoo/jrt/tool/RpcInvoker.java +++ b/jrt/src/com/yahoo/jrt/tool/RpcInvoker.java @@ -16,6 +16,7 @@ import com.yahoo.jrt.Transport; import com.yahoo.jrt.Value; import com.yahoo.jrt.Values; +import java.time.Duration; import java.util.Arrays; import java.util.List; import java.util.ArrayList; @@ -80,7 +81,7 @@ public class RpcInvoker { supervisor = new Supervisor(new Transport("invoker")); target = supervisor.connect(new Spec(connectspec)); Request request = createRequest(method,arguments); - target.invokeSync(request,10.0); + target.invokeSync(request, Duration.ofSeconds(10)); if (request.isError()) { System.err.println("error(" + request.errorCode() + "): " + request.errorMessage()); return; diff --git a/jrt/tests/com/yahoo/jrt/AbortTest.java b/jrt/tests/com/yahoo/jrt/AbortTest.java index 2f31b3a52f6..df1f207458e 100644 --- a/jrt/tests/com/yahoo/jrt/AbortTest.java +++ b/jrt/tests/com/yahoo/jrt/AbortTest.java @@ -4,6 +4,8 @@ package com.yahoo.jrt; import org.junit.After; import org.junit.Before; +import java.time.Duration; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -44,7 +46,7 @@ public class AbortTest { Test.Waiter w = new Test.Waiter(); Request req = new Request("test"); req.parameters().add(new Int32Value(20)); - target.invokeAsync(req, 5.0, w); + target.invokeAsync(req, Duration.ofSeconds(5), w); req.abort(); barrier.breakIt(); w.waitDone(); @@ -54,7 +56,7 @@ public class AbortTest { Request req2 = new Request("test"); req2.parameters().add(new Int32Value(30)); - target.invokeSync(req2, 5.0); + target.invokeSync(req2, Duration.ofSeconds(5)); assertTrue(!req2.isError()); assertEquals(1, req2.returnValues().size()); assertEquals(30, req2.returnValues().get(0).asInt32()); diff --git a/jrt/tests/com/yahoo/jrt/BackTargetTest.java b/jrt/tests/com/yahoo/jrt/BackTargetTest.java index a55a6d7f474..5b9e7ccb157 100644 --- a/jrt/tests/com/yahoo/jrt/BackTargetTest.java +++ b/jrt/tests/com/yahoo/jrt/BackTargetTest.java @@ -4,6 +4,8 @@ package com.yahoo.jrt; import org.junit.After; import org.junit.Before; +import java.time.Duration; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -81,24 +83,24 @@ public class BackTargetTest { @org.junit.Test public void testBackTarget() { checkTargets(false, false); - target.invokeSync(new Request("sample_target"), 5.0); + target.invokeSync(new Request("sample_target"), Duration.ofSeconds(5)); checkTargets(true, false); - serverBackTarget.invokeSync(new Request("sample_target"), 5.0); + serverBackTarget.invokeSync(new Request("sample_target"), Duration.ofSeconds(5)); checkTargets(true, true); checkValues(0, 0); - target.invokeSync(new Request("inc"), 5.0); + target.invokeSync(new Request("inc"), Duration.ofSeconds(5)); checkValues(1, 0); - serverBackTarget.invokeSync(new Request("inc"), 5.0); + serverBackTarget.invokeSync(new Request("inc"), Duration.ofSeconds(5)); checkValues(1, 1); - clientBackTarget.invokeSync(new Request("inc"), 5.0); + clientBackTarget.invokeSync(new Request("inc"), Duration.ofSeconds(5)); checkValues(2, 1); - target.invokeSync(new Request("back_inc"), 5.0); + target.invokeSync(new Request("back_inc"), Duration.ofSeconds(5)); checkValues(2, 2); - serverBackTarget.invokeSync(new Request("back_inc"), 5.0); + serverBackTarget.invokeSync(new Request("back_inc"), Duration.ofSeconds(5)); checkValues(3, 2); - clientBackTarget.invokeSync(new Request("back_inc"), 5.0); + clientBackTarget.invokeSync(new Request("back_inc"), Duration.ofSeconds(5)); checkValues(3, 3); } diff --git a/jrt/tests/com/yahoo/jrt/DetachTest.java b/jrt/tests/com/yahoo/jrt/DetachTest.java index 3c3356b53e2..4c3ee085913 100644 --- a/jrt/tests/com/yahoo/jrt/DetachTest.java +++ b/jrt/tests/com/yahoo/jrt/DetachTest.java @@ -4,6 +4,8 @@ package com.yahoo.jrt; import org.junit.After; import org.junit.Before; +import java.time.Duration; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -66,11 +68,11 @@ public class DetachTest { Test.Waiter w1 = new Test.Waiter(); Request req1 = new Request("d_inc"); req1.parameters().add(new Int32Value(50)); - target.invokeAsync(req1, 5.0, w1); + target.invokeAsync(req1, Duration.ofSeconds(5), w1); Request req2 = new Request("d_inc_r"); req2.parameters().add(new Int32Value(60)); - target.invokeSync(req2, 5.0); + target.invokeSync(req2, Duration.ofSeconds(5)); assertTrue(!req2.isError()); assertEquals(1, req2.returnValues().size()); @@ -123,7 +125,7 @@ public class DetachTest { Test.Waiter w = new Test.Waiter(); Request req3 = new Request("inc_b"); req3.parameters().add(new Int32Value(100)); - target.invokeAsync(req3, 5.0, w); + target.invokeAsync(req3, Duration.ofSeconds(5), w); Request blocked = (Request) receptor.get(); try { blocked.returnRequest(); diff --git a/jrt/tests/com/yahoo/jrt/EchoTest.java b/jrt/tests/com/yahoo/jrt/EchoTest.java index 47c6e806635..11742fa42e2 100644 --- a/jrt/tests/com/yahoo/jrt/EchoTest.java +++ b/jrt/tests/com/yahoo/jrt/EchoTest.java @@ -11,6 +11,7 @@ import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; import java.security.cert.X509Certificate; +import java.time.Duration; import java.util.List; import static com.yahoo.jrt.CryptoUtils.createTestTlsContext; @@ -156,7 +157,7 @@ public class EchoTest { for (int i = 0; i < refValues.size(); i++) { p.add(refValues.get(i)); } - target.invokeSync(req, 60.0); + target.invokeSync(req, Duration.ofSeconds(60)); assertTrue(req.checkReturnTypes("bBhHiIlLfFdDxXsS")); assertTrue(Test.equals(req.returnValues(), req.parameters())); assertTrue(Test.equals(req.returnValues(), refValues)); diff --git a/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java b/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java index 436b650198e..e17b6c0cfdd 100644 --- a/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java +++ b/jrt/tests/com/yahoo/jrt/InvokeAsyncTest.java @@ -5,6 +5,8 @@ package com.yahoo.jrt; import org.junit.After; import org.junit.Before; +import java.time.Duration; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -57,7 +59,7 @@ public class InvokeAsyncTest { req.parameters().add(new StringValue("def")); Test.Waiter w = new Test.Waiter(); - target.invokeAsync(req, 5.0, w); + target.invokeAsync(req, Duration.ofSeconds(5), w); assertFalse(w.isDone()); barrier.breakIt(); w.waitDone(); @@ -75,7 +77,7 @@ public class InvokeAsyncTest { req.parameters().add(new StringValue("def")); assertFalse(filter.invoked); Test.Waiter w = new Test.Waiter(); - target.invokeAsync(req, 10, w); + target.invokeAsync(req, Duration.ofSeconds(10), w); assertFalse(w.isDone()); barrier.breakIt(); w.waitDone(); diff --git a/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java b/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java index 3b58ba2f42e..0b75fe713c2 100644 --- a/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java +++ b/jrt/tests/com/yahoo/jrt/InvokeErrorTest.java @@ -5,13 +5,15 @@ package com.yahoo.jrt; import org.junit.After; import org.junit.Before; +import java.time.Duration; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; public class InvokeErrorTest { - final double timeout=60.0; + final Duration timeout = Duration.ofSeconds(60); Supervisor server; Acceptor acceptor; Supervisor client; diff --git a/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java b/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java index ec196bea47c..ff44017e1bc 100644 --- a/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java +++ b/jrt/tests/com/yahoo/jrt/InvokeSyncTest.java @@ -10,6 +10,7 @@ import java.io.FileDescriptor; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; +import java.time.Duration; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -67,7 +68,7 @@ public class InvokeSyncTest { req.parameters().add(new StringValue("abc")); req.parameters().add(new StringValue("def")); - target.invokeSync(req, 5.0); + target.invokeSync(req, Duration.ofSeconds(5)); assertTrue(!req.isError()); assertEquals(1, req.returnValues().size()); @@ -94,7 +95,7 @@ public class InvokeSyncTest { req.parameters().add(new StringValue("abc")); req.parameters().add(new StringValue("def")); assertFalse(filter.invoked); - target.invokeSync(req, 10); + target.invokeSync(req, Duration.ofSeconds(10)); assertFalse(req.isError()); assertEquals("abcdef", req.returnValues().get(0).asString()); assertTrue(filter.invoked); diff --git a/jrt/tests/com/yahoo/jrt/InvokeVoidTest.java b/jrt/tests/com/yahoo/jrt/InvokeVoidTest.java index 8b674136fe2..64c3bc91371 100644 --- a/jrt/tests/com/yahoo/jrt/InvokeVoidTest.java +++ b/jrt/tests/com/yahoo/jrt/InvokeVoidTest.java @@ -5,6 +5,8 @@ package com.yahoo.jrt; import org.junit.After; import org.junit.Before; +import java.time.Duration; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -56,7 +58,7 @@ public class InvokeVoidTest { public void testInvokeVoid() { Request req = new Request("set"); req.parameters().add(new Int32Value(40)); - target.invokeSync(req, 5.0); + target.invokeSync(req, Duration.ofSeconds(5)); assertTrue(!req.isError()); assertEquals(0, req.returnValues().size()); @@ -64,7 +66,7 @@ public class InvokeVoidTest { target.invokeVoid(new Request("inc")); req = new Request("get"); - target.invokeSync(req, 5.0); + target.invokeSync(req, Duration.ofSeconds(5)); assertTrue(!req.isError()); assertEquals(42, req.returnValues().get(0).asInt32()); diff --git a/jrt/tests/com/yahoo/jrt/LatencyTest.java b/jrt/tests/com/yahoo/jrt/LatencyTest.java index 0df15ed400b..945833e51a8 100644 --- a/jrt/tests/com/yahoo/jrt/LatencyTest.java +++ b/jrt/tests/com/yahoo/jrt/LatencyTest.java @@ -2,6 +2,7 @@ package com.yahoo.jrt; +import java.time.Duration; import java.util.concurrent.CountDownLatch; import java.util.concurrent.CyclicBarrier; import java.util.logging.Logger; @@ -116,7 +117,7 @@ public class LatencyTest { } Request req = new Request("inc"); req.parameters().add(new Int32Value(value)); - target.invokeSync(req, 60.0); + target.invokeSync(req, Duration.ofSeconds(60)); long duration = System.nanoTime() - t; assertTrue(req.checkReturnTypes("i")); assertEquals(value + 1, req.returnValues().get(0).asInt32()); diff --git a/jrt/tests/com/yahoo/jrt/MandatoryMethodsTest.java b/jrt/tests/com/yahoo/jrt/MandatoryMethodsTest.java index 212447dd6da..c0ef9606b1f 100644 --- a/jrt/tests/com/yahoo/jrt/MandatoryMethodsTest.java +++ b/jrt/tests/com/yahoo/jrt/MandatoryMethodsTest.java @@ -5,6 +5,7 @@ package com.yahoo.jrt; import org.junit.After; import org.junit.Before; +import java.time.Duration; import java.util.HashSet; import static org.junit.Assert.assertEquals; @@ -38,7 +39,7 @@ public class MandatoryMethodsTest { @org.junit.Test public void testPing() { Request req = new Request("frt.rpc.ping"); - target.invokeSync(req, 5.0); + target.invokeSync(req, Duration.ofSeconds(5)); assertFalse(req.isError()); assertEquals(0, req.returnValues().size()); @@ -47,7 +48,7 @@ public class MandatoryMethodsTest { @org.junit.Test public void testGetMethodList() { Request req = new Request("frt.rpc.getMethodList"); - target.invokeSync(req, 5.0); + target.invokeSync(req, Duration.ofSeconds(5)); assertFalse(req.isError()); assertTrue(req.checkReturnTypes("SSS")); @@ -81,7 +82,7 @@ public class MandatoryMethodsTest { public void testGetMethodInfo() { Request req = new Request("frt.rpc.getMethodInfo"); req.parameters().add(new StringValue("frt.rpc.getMethodInfo")); - target.invokeSync(req, 5.0); + target.invokeSync(req, Duration.ofSeconds(5)); assertFalse(req.isError()); assertTrue(req.checkReturnTypes("sssSSSS")); diff --git a/jrt/tests/com/yahoo/jrt/TimeoutTest.java b/jrt/tests/com/yahoo/jrt/TimeoutTest.java index 0366020b221..1a802758e60 100644 --- a/jrt/tests/com/yahoo/jrt/TimeoutTest.java +++ b/jrt/tests/com/yahoo/jrt/TimeoutTest.java @@ -5,6 +5,8 @@ package com.yahoo.jrt; import org.junit.After; import org.junit.Before; +import java.time.Duration; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -52,11 +54,11 @@ public class TimeoutTest { req.parameters().add(new StringValue("abc")); req.parameters().add(new StringValue("def")); - target.invokeSync(req, 0.1); + target.invokeSync(req, Duration.ofMillis(100)); barrier.breakIt(); Request flush = new Request("frt.rpc.ping"); - target.invokeSync(flush, 5.0); + target.invokeSync(flush, Duration.ofSeconds(5)); assertTrue(!flush.isError()); assertTrue(req.isError()); @@ -72,7 +74,7 @@ public class TimeoutTest { req.parameters().add(new StringValue("def")); Test.Waiter w = new Test.Waiter(); - target.invokeAsync(req, 30.0, w); + target.invokeAsync(req, Duration.ofSeconds(30), w); try { Thread.sleep(2500); } catch (InterruptedException e) {} barrier.breakIt(); w.waitDone(); diff --git a/logserver/src/test/java/ai/vespa/logserver/protocol/ArchiveLogMessagesMethodTest.java b/logserver/src/test/java/ai/vespa/logserver/protocol/ArchiveLogMessagesMethodTest.java index d60587d1642..1a95909c8a4 100644 --- a/logserver/src/test/java/ai/vespa/logserver/protocol/ArchiveLogMessagesMethodTest.java +++ b/logserver/src/test/java/ai/vespa/logserver/protocol/ArchiveLogMessagesMethodTest.java @@ -15,6 +15,7 @@ import com.yahoo.log.LogMessage; import com.yahoo.logserver.LogDispatcher; import org.junit.Test; +import java.time.Duration; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.ArrayList; @@ -68,7 +69,7 @@ public class ArchiveLogMessagesMethodTest { request.parameters().add(new Int8Value((byte)0)); request.parameters().add(new Int32Value(requestPayload.length)); request.parameters().add(new DataValue(requestPayload)); - target.invokeSync(request, 30/*seconds*/); + target.invokeSync(request, Duration.ofSeconds(30)); Values returnValues = request.returnValues(); assertEquals(3, returnValues.size()); assertEquals(0, returnValues.get(0).asInt8()); diff --git a/messagebus/src/main/java/com/yahoo/messagebus/network/rpc/RPCNetwork.java b/messagebus/src/main/java/com/yahoo/messagebus/network/rpc/RPCNetwork.java index 811d8a25459..b4fa7d8f887 100644 --- a/messagebus/src/main/java/com/yahoo/messagebus/network/rpc/RPCNetwork.java +++ b/messagebus/src/main/java/com/yahoo/messagebus/network/rpc/RPCNetwork.java @@ -32,6 +32,7 @@ import com.yahoo.messagebus.routing.RoutingNode; import java.io.PrintWriter; import java.io.StringWriter; +import java.time.Duration; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -240,7 +241,7 @@ public class RPCNetwork implements Network, MethodHandler { @Override public void send(Message msg, List<RoutingNode> recipients) { SendContext ctx = new SendContext(this, msg, recipients); - double timeout = ctx.msg.getTimeRemainingNow() / 1000.0; + Duration timeout = Duration.ofMillis(ctx.msg.getTimeRemainingNow()); for (RoutingNode recipient : ctx.recipients) { RPCServiceAddress address = (RPCServiceAddress)recipient.getServiceAddress(); address.getTarget().resolveVersion(timeout, ctx); diff --git a/messagebus/src/main/java/com/yahoo/messagebus/network/rpc/RPCTarget.java b/messagebus/src/main/java/com/yahoo/messagebus/network/rpc/RPCTarget.java index 85f50051e34..6fbab1a4b7f 100755 --- a/messagebus/src/main/java/com/yahoo/messagebus/network/rpc/RPCTarget.java +++ b/messagebus/src/main/java/com/yahoo/messagebus/network/rpc/RPCTarget.java @@ -7,6 +7,8 @@ import com.yahoo.jrt.RequestWaiter; import com.yahoo.jrt.Spec; import com.yahoo.jrt.Supervisor; import com.yahoo.jrt.Target; + +import java.time.Duration; import java.util.logging.Level; import com.yahoo.text.Utf8Array; @@ -95,7 +97,7 @@ public class RPCTarget implements RequestWaiter { * @param timeout The timeout for the request in seconds. * @param handler The handler to be called once the version is available. */ - void resolveVersion(double timeout, VersionHandler handler) { + void resolveVersion(Duration timeout, VersionHandler handler) { boolean hasVersion = false; boolean shouldInvoke = false; boolean shouldLog = log.isLoggable(Level.FINE); @@ -158,8 +160,7 @@ public class RPCTarget implements RequestWaiter { /** * <p>Declares a version handler used when resolving the version of a * target. An instance of this is passed to {@link - * RPCTarget#resolveVersion(double, - * com.yahoo.messagebus.network.rpc.RPCTarget.VersionHandler)}, and invoked + * RPCTarget#resolveVersion(Duration, RPCTarget.VersionHandler)}, and invoked * either synchronously or asynchronously, depending on whether or not the * version is already available.</p> */ diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/ConfigSentinelClient.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/ConfigSentinelClient.java index 6d41fc93c25..ec5bd53cb21 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/ConfigSentinelClient.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/service/ConfigSentinelClient.java @@ -3,6 +3,8 @@ package ai.vespa.metricsproxy.service; import com.yahoo.component.annotation.Inject; import com.yahoo.component.AbstractComponent; + +import java.time.Duration; import java.util.logging.Level; import com.yahoo.jrt.ErrorCode; @@ -170,7 +172,7 @@ public class ConfigSentinelClient extends AbstractComponent { } if (connection.isValid()) { Request req = new Request("sentinel.ls"); - connection.invokeSync(req, 5.0); + connection.invokeSync(req, Duration.ofSeconds(5)); if (req.errorCode() == ErrorCode.NONE && req.checkReturnTypes("s")) { diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcHealthMetricsTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcHealthMetricsTest.java index 8c8a44deae6..cf3610fe0bb 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcHealthMetricsTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcHealthMetricsTest.java @@ -14,6 +14,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.Timeout; +import java.time.Duration; import java.util.List; import static ai.vespa.metricsproxy.TestUtil.getFileContents; @@ -35,7 +36,7 @@ public class RpcHealthMetricsTest { getFileContents("health-check-failed.response.json"); private static final String WANTED_RPC_RESPONSE = getFileContents("rpc-json-output-check.json").trim(); - private static final double RPC_INVOKE_TIMEOUT = 60.0; + private static final Duration RPC_INVOKE_TIMEOUT = Duration.ofSeconds(60); @Rule diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java index cedf7542233..1e7a398b3d0 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/rpc/RpcMetricsTest.java @@ -19,6 +19,7 @@ import org.junit.Test; import org.junit.rules.Timeout; import java.io.IOException; +import java.time.Duration; import java.util.List; import static ai.vespa.metricsproxy.TestUtil.getFileContents; @@ -45,7 +46,7 @@ public class RpcMetricsTest { private static final String METRICS_RESPONSE = getFileContents("metrics-storage-simple.json").trim(); private static final String EXTRA_APP = "extra"; - private static final double RPC_INVOKE_TIMEOUT = 60.0; + private static final Duration RPC_INVOKE_TIMEOUT = Duration.ofSeconds(60); private static class RpcClient implements AutoCloseable { private final Supervisor supervisor; diff --git a/vespaclient-java/src/main/java/com/yahoo/vespasummarybenchmark/VespaSummaryBenchmark.java b/vespaclient-java/src/main/java/com/yahoo/vespasummarybenchmark/VespaSummaryBenchmark.java index 49a8c7fc583..fae602425ae 100644 --- a/vespaclient-java/src/main/java/com/yahoo/vespasummarybenchmark/VespaSummaryBenchmark.java +++ b/vespaclient-java/src/main/java/com/yahoo/vespasummarybenchmark/VespaSummaryBenchmark.java @@ -28,6 +28,7 @@ import java.io.DataInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; +import java.time.Duration; import java.util.ArrayList; import java.util.List; @@ -146,7 +147,7 @@ public class VespaSummaryBenchmark { r.parameters().add(new Int8Value(CompressionType.NONE.getCode())); r.parameters().add(new Int32Value(blob.length)); r.parameters().add(new DataValue(blob)); - target.invokeAsync(r, 100.0, waiter); + target.invokeAsync(r, Duration.ofSeconds(100), waiter); } try { waiter.waitForReplies(); |