diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000000000000000000000000000000000..325d9788d5c60ee00a3c0dd4e32890c3854e5768 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,6 @@ +node_modules/* +node_modules/ +node_modules +*.d.ts +*.mjs +*.tsbuildinfo \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3d93465678e50e59eee44154ab14c9c571ebdfaa..6f9727aa490805744fd8ffe20eeefb8576dd3cad 100644 --- a/.gitignore +++ b/.gitignore @@ -75,4 +75,7 @@ Thumbs.db # Certs certs/*.pem -node_modules \ No newline at end of file +node_modules + +tsconfig.tsbuildinfo +vite.config.ts.* \ No newline at end of file diff --git a/apps/web/.env.development b/apps/web/.env.development index ddbadbf753f827d5f00b6a1eb88735a9bd1e0582..3fc5fd002a8a8661e5fc47775de4b6473c843750 100644 --- a/apps/web/.env.development +++ b/apps/web/.env.development @@ -4,4 +4,5 @@ VITE_STAGING=dev VITE_SKIP_LOGIN=true VITE_BACKEND_USER=:3000 VITE_BACKEND_QUERY=:3003 -VITE_BACKEND_SCHEMA=:3002 \ No newline at end of file +VITE_BACKEND_SCHEMA=:3002 + diff --git a/apps/web/.env.production b/apps/web/.env.production index 4c548bc854517657480fc48afaedcf963e8ee62a..af3e58d1c908dedc543afe43a056eb55fdc800a6 100644 --- a/apps/web/.env.production +++ b/apps/web/.env.production @@ -1,7 +1,9 @@ VITE_BACKEND_URL=https://api.graphpolaris.com VITE_BACKEND_WSS_URL=ws://api.graphpolaris.com/socket/ VITE_STAGING=prod + VITE_SKIP_LOGIN=false VITE_BACKEND_USER=/user VITE_BACKEND_QUERY=/query -VITE_BACKEND_SCHEMA=/schema \ No newline at end of file +VITE_BACKEND_SCHEMA=/schema + diff --git a/apps/web/.eslintignore b/apps/web/.eslintignore index ebd538ec932a946561d31334f3d21743d2776543..ed9d65c51ee65528569330ac08d99a1383f2a614 100644 --- a/apps/web/.eslintignore +++ b/apps/web/.eslintignore @@ -1,4 +1,6 @@ node_modules/* node_modules/ node_modules -*.d.ts \ No newline at end of file +*.d.ts +*.mjs +*.tsbuildinfo \ No newline at end of file diff --git a/apps/web/.eslintrc.json b/apps/web/.eslintrc.json index 351d714ab66565664d2f52885fdeb9d1d52c0976..8144cb41a186f2f60c5912d27eecfa48121cfa75 100644 --- a/apps/web/.eslintrc.json +++ b/apps/web/.eslintrc.json @@ -1,25 +1,3 @@ { - "extends": ["plugin:react-hooks/recommended"], - "parserOptions": { - "sourceType": "module", - "ecmaVersion": "latest", - "ecmaFeatures": { - "jsx": true - } - }, - "ignorePatterns": ["!**/*", "node.d.ts"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": {} - }, - { - "files": ["*.ts", "*.tsx"], - "rules": {} - }, - { - "files": ["*.js", "*.jsx"], - "rules": {} - } - ] + "extends": ["./node_modules/config/.eslintrc.json"] } diff --git a/apps/web/.gitignore b/apps/web/.gitignore index a547bf36d8d11a4f89c59c144f24795749086dd1..dd4d473b2c788cb5054c8bc2acfd284dd80b08d2 100644 --- a/apps/web/.gitignore +++ b/apps/web/.gitignore @@ -22,3 +22,6 @@ dist-ssr *.njsproj *.sln *.sw? + +tsconfig.tsbuildinfo +vite.config.ts.* \ No newline at end of file diff --git a/apps/web/index.html b/apps/web/index.html index ef4d4065309f84f55011e0f2ae1b6a05e03e4df1..1f53c36c99a343b00e20aab44339eda4e15c765c 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -1,13 +1,19 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="UTF-8" /> - <link rel="icon" type="image/svg+xml" href="/vite.svg" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>Vite + React + TS</title> - </head> - <body> - <div id="root"></div> - <script type="module" src="./src/main.tsx"></script> - </body> -</html> +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <title>Graphpolaris</title> + <base href="/" /> + <meta name="description" content="Graphpolaris" /> + + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Vite + React + TS</title> + <link rel="preconnect" href="https://fonts.googleapis.com" /> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> + <link href="https://fonts.googleapis.com/css2?family=Inter&display=swap" rel="stylesheet" /> + </head> + <body> + <div id="root" data-theme="graphpolaris"></div> + <script type="module" src="./src/main.tsx"></script> + </body> +</html> diff --git a/apps/web/node.d.ts b/apps/web/node.d.ts deleted file mode 100644 index 544d25be2e3874c8a1e1fac2cb9507e4ff20a295..0000000000000000000000000000000000000000 --- a/apps/web/node.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -interface ImportMeta { - env: { - VITE_BACKEND_URL: string; - VITE_BACKEND_WSS_URL: string; - VITE_BACKEND_USER: string; - VITE_BACKEND_SCHEMA: string; - VITE_BACKEND_QUERY: string; - VITE_STAGING: string; - VITE_KEYCLOAK_URL: string; - VITE_KEYCLOAK_REALM: string; - VITE_KEYCLOAK_CLIENT: string; - }; -} - -declare module "*.png"; -declare module "*.svg"; -declare module "*.jpeg"; -declare module "*.jpg"; \ No newline at end of file diff --git a/apps/web/package.json b/apps/web/package.json index 24c4e5bfc0da9e8dc4326f8cf8e9f0efe279d257..e70fa522b7fecafe93a09170a7926d790e48d523 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,49 +1,56 @@ -{ - "name": "web", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev2": "vite --host local.graphpolaris.com --port 4200", - "dev": "vite --port 4200", - "build": "tsc && vite build", - "build-dev": "tsc && vite build --mode development", - "preview": "vite preview", - "lint": "eslint *.ts*", - "test": "vitest run" - }, - "dependencies": { - "@graphpolaris/shared": "workspace:*", - "@mui/base": "5.0.0-alpha.118", - "@mui/icons-material": "^5.11.11", - "@mui/material": "^5.11.13", - "@reduxjs/toolkit": "^1.9.2", - "graphology": "^0.25.1", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-grid-layout": "^1.3.4", - "react-redux": "^8.0.5", - "react-router-dom": "^6.8.1", - "reactflow": "11.4.0-next.1", - "styled-components": "^5.3.6" - }, - "devDependencies": { - "@storybook/react": "7.0.0-rc.5", - "@testing-library/react": "14.0.0", - "@types/react": "^18.0.28", - "@types/react-dom": "^18.0.11", - "@types/react-grid-layout": "^1.3.2", - "@types/styled-components": "^5.1.26", - "@vitejs/plugin-basic-ssl": "^1.0.1", - "@vitejs/plugin-react-swc": "^3.0.0", - "autoprefixer": "^10.4.14", - "graphology-types": "^0.24.7", - "postcss": "^8.4.21", - "react-is": "^18.2.0", - "tailwindcss": "^3.3.1", - "typescript": "^4.9.3", - "vite": "^4.2.0", - "vite-plugin-dts": "^2.1.0", - "vitest": "^0.29.2" - } -} +{ + "name": "web", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev2": "vite --host local.graphpolaris.com --port 4200", + "dev": "vite --port 4200", + "build": "tsc && vite build", + "build-dev": "tsc && vite build --mode development", + "preview": "vite preview", + "lint": "eslint *.ts*", + "test": "vitest run" + }, + "dependencies": { + "@graphpolaris/shared": "workspace:*", + "@mui/icons-material": "^5.11.11", + "@reduxjs/toolkit": "^1.9.2", + "config": "workspace:*", + "graphology": "^0.25.1", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-grid-layout": "^1.3.4", + "react-redux": "^8.0.5", + "react-router-dom": "^6.8.1", + "reactflow": "11.4.0-next.1", + "styled-components": "^5.3.6" + }, + "devDependencies": { + "@iconify/json": "^2.2.95", + "@iconify/react": "^4.1.1", + "@storybook/react": "7.0.0-rc.5", + "@svgr/core": "^8.0.0", + "@svgr/plugin-jsx": "^8.0.1", + "@tailwindcss/typography": "^0.5.9", + "@testing-library/react": "14.0.0", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@types/react-grid-layout": "^1.3.2", + "@types/styled-components": "^5.1.26", + "@vitejs/plugin-basic-ssl": "^1.0.1", + "@vitejs/plugin-react-swc": "^3.0.0", + "autoprefixer": "^10.4.14", + "daisyui": "^3.5.0", + "graphology-types": "^0.24.7", + "npm": "^9.8.1", + "postcss": "^8.4.21", + "react-is": "^18.2.0", + "tailwindcss": "^3.3.1", + "typescript": "^4.9.3", + "vite": "^4.2.0", + "vite-plugin-dts": "^2.1.0", + "vite-plugin-sass-dts": "^1.3.2", + "vitest": "^0.29.2" + } +} diff --git a/apps/web/src/app/app.stories.tsx b/apps/web/src/app/app.stories.tsx index fd3880b4a01057fceb4c01da9775ae3bad8a57b0..cb1816ebeb3d5431944a104e308cd98237dbecc0 100644 --- a/apps/web/src/app/app.stories.tsx +++ b/apps/web/src/app/app.stories.tsx @@ -3,18 +3,13 @@ import { Meta, Story } from '@storybook/react'; import { App } from './app'; import { Provider } from 'react-redux'; import { store } from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; export default { component: App, title: 'App', decorators: [ // using the real store here - (story) => ( - <Provider store={store}> - <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> - </Provider> - ), + (story) => <Provider store={store}>{story()}</Provider>, ], } as Meta; diff --git a/apps/web/src/app/app.tsx b/apps/web/src/app/app.tsx index c616b6452aca9754acfd38ccee16dcc4f3e84364..1e6aee5f7d6212c03acefb7db3f308a9ce9b3148 100644 --- a/apps/web/src/app/app.tsx +++ b/apps/web/src/app/app.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { readInSchemaFromBackend, useAuth, @@ -17,11 +18,10 @@ import { GraphQueryResultFromBackendPayload, resetGraphQueryResults, } from '@graphpolaris/shared/lib/data-access/store/graphQueryResultSlice'; -import { Query2BackendQuery, QueryBuilder } from '@graphpolaris/shared/lib/querybuilder'; +import { Query2BackendQuery, QueryBuilder, QueryMultiGraph } from '@graphpolaris/shared/lib/querybuilder'; import { Schema } from '@graphpolaris/shared/lib/schema/panel'; import { useCallback, useEffect, useRef, useState } from 'react'; import { Navbar } from '../components/navbar/navbar'; -import Panel from '../components/panels/panel'; import { VisualizationPanel } from './panels/Visualization'; import styles from './app.module.scss'; import { logout } from '@graphpolaris/shared/lib/data-access/store/authSlice'; @@ -37,7 +37,7 @@ export function App(props: App) { const api_query = useQueryAPI(); const dispatch = useAppDispatch(); const session = useSessionCache(); - const query = useQuerybuilderGraph(); + const query = useQuerybuilderGraph() as QueryMultiGraph; const queryHash = useQuerybuilderHash(); const ws = useRef(new WebSocketHandler(import.meta.env.VITE_BACKEND_WSS_URL)); const [authCheck, setAuthCheck] = useState(false); @@ -82,7 +82,7 @@ export function App(props: App) { const runQuery = () => { if (session?.currentDatabase && query) { - if (query.edges.length === 0) { + if (query.nodes.length === 0) { dispatch(resetGraphQueryResults()); } else { api_query.execute(Query2BackendQuery(session.currentDatabase, query)); @@ -96,33 +96,28 @@ export function App(props: App) { return ( <div className="h-screen w-screen"> - <div className={'flex h-screen w-screen overflow-hidden ' + (!auth.authorized ? 'blur-sm pointer-events-none ' : '')}> - <div className="h-full relative flex flex-col flex-1 overflow-y-auto overflow-x-hidden"> - <div className="h-fit flex-grow-0"> + <div className={'h-screen w-screen ' + (!auth.authorized ? 'blur-sm pointer-events-none ' : '')}> + <div className="flex flex-col h-screen max-h-screen relative"> + <aside className="h-[4rem]"> <Navbar /> - </div> - <main className={styles.mainContainer}> - <div className={styles.schema}> - <Panel content="Schema"> - <Schema auth={authCheck} /> - </Panel> + </aside> + <main className="flex w-screen h-[calc(100%-4.2rem)] gap-0.5"> + <div className="h-full min-w-[35vw] max-w-[35vw] panel"> + <Schema auth={authCheck} /> </div> - <div className={styles.panel}> - <div className={styles.visualization}> - <Panel content="Visualization Panel"> - <VisualizationPanel /> - </Panel> + <div className="h-full min-w-[calc(65vw-0.125rem)] max-w-[calc(65vw-0.125rem)] flex-grow-0"> + <div className="w-full panel h-[50%]"> + <VisualizationPanel /> </div> - <div className={styles.queryBuilder}> - <Panel content="Query Panel"> - <QueryBuilder - onRunQuery={() => { - console.log('Run Query'); - - runQuery(); - }} - /> - </Panel> + <div className="h-0.5"></div> + <div className="w-full panel h-[calc(50%-0.125rem)]"> + {/* <h1>Query Panel</h1> */} + <QueryBuilder + onRunQuery={() => { + console.log('Run Query'); + runQuery(); + }} + /> </div> </div> </main> diff --git a/apps/web/src/app/panels/Visualization.tsx b/apps/web/src/app/panels/Visualization.tsx index 10f7820ccc18335955e5f27e7682ff8442f0b448..4aa79b6b35e74a415da7e570a2dfe7ea141453ac 100644 --- a/apps/web/src/app/panels/Visualization.tsx +++ b/apps/web/src/app/panels/Visualization.tsx @@ -1,12 +1,11 @@ +import React from 'react'; import { RawJSONVis, NodeLinkVis, PaohVis, SemanticSubstrates } from '@graphpolaris/shared/lib/vis'; -import Panel from '../../components/panels/panel'; import { assignNewGraphQueryResult, useAppDispatch } from '@graphpolaris/shared/lib/data-access'; export const VisualizationPanel = () => { - const dispatch = useAppDispatch(); - return ( - <div> + <div className="h-full w-full overflow-y-auto"> + <h1>Visualization Panel</h1> {/* <div> <button onClick={() => @@ -36,17 +35,9 @@ export const VisualizationPanel = () => { {/* width: '83%', height: '95vh', */} - <div className="h-[60vh] overflow-y-auto"> - {/* <div className="h-full overflow-y-auto"> */} - {/* <RawJSONVis /> */} - - {/* <PaohVis - rowHeight={30} - hyperedgeColumnWidth={30} - gapBetweenRanges={3} - /> */} - {/* <RawJSONVis /> */} + <div className="w-full h-[calc(100%-2rem)]"> {/* <RawJSONVis /> */} + {/* <PaohVis rowHeight={30} hyperedgeColumnWidth={30} gapBetweenRanges={3} /> */} <NodeLinkVis /> {/* <SemanticSubstrates /> */} </div> diff --git a/apps/web/src/components/navbar/AddDatabaseForm/add-database-form.module.scss b/apps/web/src/components/navbar/AddDatabaseForm/add-database-form.module.scss deleted file mode 100644 index 979ce55dec403ac92bf98859fc5c86a679c8f874..0000000000000000000000000000000000000000 --- a/apps/web/src/components/navbar/AddDatabaseForm/add-database-form.module.scss +++ /dev/null @@ -1,90 +0,0 @@ -.wrapper { - height: 100%; - display: flex; - align-items: center; - width: 100vw; - background-color: rgba(0, 0, 0, 0.2); - position: absolute; - z-index: 1225; - margin-top: 50px; -} - -.authWrapper { - font-family: Poppins, sans-serif; - display: flex; - flex-direction: column; - flex-wrap: wrap; - justify-content: center; - gap: 1em; - max-width: 600px; - margin: auto; - overflow: auto; - min-height: 300px; - background-color: #f7f8fc; - padding: 30px; - border-radius: 5px; - padding-bottom: 300px; -} - -.header { - text-align: center; -} - -.formWrapper { - display: flex; - flex-direction: column; - flex-wrap: wrap; - gap: 1em; -} - -.loginContainer { - margin: 0.5rem 0 !important; -} - -.loginContainerRow { - display: flex; - flex-direction: row; - gap: 0.5em; - margin: 5px 0px; -} - -.loginContainerButton { - margin-top: 0.5rem !important; - display: flex; - flex-direction: row; - - & button { - width: 50%; - } - & :nth-child(1) { - margin: 0 0.5rem 0 0; - } - - & :nth-child(2) { - margin: 0 0 0 0.5rem; - } -} - -.hostLabel { - flex: 1 0 66.66667%; - - & div { - width: 95%; - } -} - -.portLabel { - flex: 1 0 33.33334%; -} - -.userLabel { - width: 100%; -} - -.passLabel { - width: 100%; -} - -.cancelButton { - margin-top: 2.5%; -} diff --git a/apps/web/src/components/navbar/AddDatabaseForm/add-database-form.module.scss.d.ts b/apps/web/src/components/navbar/AddDatabaseForm/add-database-form.module.scss.d.ts deleted file mode 100644 index 2d4431d5bd1e59589c2c46367ff59684c61e6bf6..0000000000000000000000000000000000000000 --- a/apps/web/src/components/navbar/AddDatabaseForm/add-database-form.module.scss.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -declare const classNames: { - readonly wrapper: 'wrapper'; - readonly authWrapper: 'authWrapper'; - readonly header: 'header'; - readonly formWrapper: 'formWrapper'; - readonly loginContainer: 'loginContainer'; - readonly loginContainerRow: 'loginContainerRow'; - readonly loginContainerButton: 'loginContainerButton'; - readonly hostLabel: 'hostLabel'; - readonly portLabel: 'portLabel'; - readonly userLabel: 'userLabel'; - readonly passLabel: 'passLabel'; - readonly cancelButton: 'cancelButton'; -}; -export = classNames; diff --git a/apps/web/src/components/navbar/AddDatabaseForm/index.tsx b/apps/web/src/components/navbar/AddDatabaseForm/index.tsx deleted file mode 100644 index 8df366cd416b8e49c60c86a967121b9175cf05ed..0000000000000000000000000000000000000000 --- a/apps/web/src/components/navbar/AddDatabaseForm/index.tsx +++ /dev/null @@ -1,278 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -/* istanbul ignore file */ -/* The comment above was added so the code coverage wouldn't count this file towards code coverage. - * We do not test components/renderfunctions/styling files. - * See testing plan for more details.*/ -import React, { useState, useEffect } from 'react'; -import { TextField, Button, NativeSelect } from '@mui/material'; -import styles from './add-database-form.module.scss'; -import { AddDatabaseRequest, DatabaseType, databaseNameMapping, databaseProtocolMapping } from '@graphpolaris/shared/lib/data-access'; - -/** AddDatabaseFormProps is an interface containing the AuthViewModel. */ -export interface AddDatabaseFormProps { - styles: any; - open: boolean; - onClose(): void; - onSubmit(data: AddDatabaseRequest): void; -} - -/** AddDatabaseFormState is an interface containing the databasehost information. */ -export interface AddDatabaseFormState extends AddDatabaseRequest { - // username: string; - // password: string; - // hostname: string; - // port: number; - // databaseName: string; - // internalDatabase: string; - // databaseType: string; - // styles: Record<string, string>; // TODO: check if needed -} - -/** AddDatabaseForm is the View implementation for the connect screen that will be rendered. */ -export default function AddDatabaseForm(props: AddDatabaseFormProps) { - const [state, setState] = useState<AddDatabaseFormState>({ - // username: 'root', - // password: 'DikkeDraak', - // url: 'https://datastrophe.science.uu.nl/', - // port: 8529, - // name: 'Tweede Kamer Dataset', - // internal_database_name: 'TweedeKamer', - // type: DatabaseType.ArangoDB, - - // username: 'neo4j', - // password: 'oL3nNlebrx4le2A0zxaFVqAo3HAvodHxwEiI_7_2JxI', - // url: '635176c8.databases.neo4j.io', - // port: 7687, - // name: 'neo4j', - // internal_database_name: 'neo4j', - // type: DatabaseType.Neo4j, - - username: 'neo4j', - password: 'StrongPass2022', - url: 'localhost', - port: 7687, - name: 'neo4j', - protocol: 'neo4j://', - internal_database_name: 'neo4j', - type: DatabaseType.Neo4j, - }); - const [portValidation, setPortValidation] = useState<string>('valid'); - - useEffect(() => { - if (state && state.port && state.port > 9999) { - setPortValidation('error'); - } else { - setPortValidation('valid'); - } - }, [state.port]); - - useEffect(() => { - if (!state) return; - if (state.type === DatabaseType.ArangoDB && state.port === 7687) { - setState({ ...state, port: 8529 }); - } else if (state.type === DatabaseType.Neo4j && state.port === 8529) { - setState({ ...state, port: 7687 }); - } - }, [state.type]); - - /** - * Validates if the port value is numerical. Only then will the state be updated. - * @param port The new port value. - */ - function handlePortChanged(port: string): void { - if (!isNaN(Number(port))) setState({ ...state, port: Number(port) }); - } - - /** Handles the submit button click. Calls the onSubmit in the props with all the fields. */ - function handleSubmitClicked(): void { - props.onSubmit(state); - } - - return props.open ? ( - // return ( - <div - className={styles.wrapper} - onMouseDown={() => { - props.onClose(); - }} - > - <div - className={styles.authWrapper} - onMouseDown={(e) => { - e.stopPropagation(); - }} - > - <h1 className={styles.header}>Database Connect</h1> - <form - className={styles.formWrapper} - onSubmit={(event: React.FormEvent) => { - event.preventDefault(); - handleSubmitClicked(); - }} - > - <div className={styles.loginContainer}> - <TextField - className={styles.passLabel} - label="Database name" - type="databaseName" - value={state.name} - onChange={(event) => - setState({ - ...state, - name: event.currentTarget.value, - }) - } - required - /> - </div> - <div className={styles.loginContainer}> - <NativeSelect - className={styles.passLabel} - value={databaseNameMapping[state.type]} - onChange={(event) => { - setState({ - ...state, - type: databaseNameMapping.indexOf(event.currentTarget.value), - }); - }} - > - {databaseNameMapping.map((dbName) => ( - <option value={dbName} key={dbName}> - {dbName} - </option> - ))} - </NativeSelect> - </div> - <div className={styles.loginContainer}> - <NativeSelect - className={styles.passLabel} - value={state.protocol} - onChange={(event) => { - setState({ - ...state, - protocol: event.currentTarget.value, - }); - }} - > - {databaseProtocolMapping.map((protocol) => ( - <option value={protocol} key={protocol}> - {protocol} - </option> - ))} - </NativeSelect> - </div> - <div className={styles.loginContainerRow}> - <TextField - className={styles.hostLabel} - label="Hostname/IP" - type="hostname" - value={state.url} - onChange={(event) => - setState({ - ...state, - url: event.currentTarget.value, - }) - } - required - /> - {portValidation && portValidation == 'error' ? ( - <TextField - error - className={styles.portLabel} - label="Port error" - type="port" - value={state.port} - onChange={(event) => handlePortChanged(event.currentTarget.value)} - required - /> - ) : ( - <TextField - className={styles.portLabel} - label="Port" - type="port" - value={state.port} - onChange={(event) => handlePortChanged(event.currentTarget.value)} - required - /> - )} - </div> - <div className={styles.loginContainer}> - <TextField - className={styles.userLabel} - label="Username" - type="username" - value={state.username} - onChange={(event) => - setState({ - ...state, - username: event.currentTarget.value, - }) - } - required - /> - </div> - <div className={styles.loginContainer}> - <TextField - className={styles.passLabel} - label="Password" - type="password" - value={state.password} - onChange={(event) => - setState({ - ...state, - password: event.currentTarget.value, - }) - } - required - /> - </div> - <div className={styles.loginContainer}> - <TextField - className={styles.passLabel} - label="Internal database" - type="internalDatabaseName" - value={state.internal_database_name} - onChange={(event) => - setState({ - ...state, - internal_database_name: event.currentTarget.value, - }) - } - required - /> - </div> - <div className={styles.loginContainerButton}> - {portValidation && portValidation == 'error' ? ( - <Button disabled variant="contained" type="submit" color="success"> - Submit - </Button> - ) : ( - <Button variant="contained" type="submit" color="success"> - Submit - </Button> - )} - - <Button - className={styles.cancelButton} - variant="outlined" - color="error" - onClick={() => { - props.onClose(); - }} - > - Cancel - </Button> - </div> - </form> - </div> - </div> - ) : ( - //); - <></> - ); -} diff --git a/apps/web/src/components/navbar/AddDatabaseForm/newdatabaseform.tsx b/apps/web/src/components/navbar/AddDatabaseForm/newdatabaseform.tsx new file mode 100644 index 0000000000000000000000000000000000000000..d7ede2afe87b4fece35d6969d8440ac94c2ba64b --- /dev/null +++ b/apps/web/src/components/navbar/AddDatabaseForm/newdatabaseform.tsx @@ -0,0 +1,271 @@ +import { + AddDatabaseRequest, + DatabaseType, + databaseNameMapping, + databaseProtocolMapping, + useDatabaseAPI, + useSchemaAPI, +} from '@graphpolaris/shared/lib/data-access'; +import React, { useEffect, useRef, useState } from 'react'; +import { RequiredInput } from './requiredinput'; + +export const NewDatabaseForm = (props: { onClose(): void; open: boolean }) => { + const ref = useRef<HTMLDialogElement>(null); + const [state, setState] = useState<AddDatabaseRequest>({ + // username: 'root', + // password: 'DikkeDraak', + // url: 'https://datastrophe.science.uu.nl/', + // port: 8529, + // name: 'Tweede Kamer Dataset', + // internal_database_name: 'TweedeKamer', + // type: DatabaseType.ArangoDB, + + // username: 'neo4j', + // password: 'oL3nNlebrx4le2A0zxaFVqAo3HAvodHxwEiI_7_2JxI', + // url: '635176c8.databases.neo4j.io', + // port: 7687, + // name: 'neo4j', + // internal_database_name: 'neo4j', + // type: DatabaseType.Neo4j, + + username: 'neo4j', + password: 'DevOnlyPass', + url: 'localhost', + port: 7687, + name: 'neo4j', + protocol: 'neo4j://', + internal_database_name: 'neo4j', + type: DatabaseType.Neo4j, + }); + const api = useDatabaseAPI(); + const schemaApi = useSchemaAPI(); + const [hasError, setHasError] = useState({}); + + useEffect(() => { + if (props.open) ref.current?.showModal(); + else ref.current?.close(); + }, [props.open]); + + useEffect(() => { + if (!state) return; + if (state.type === DatabaseType.ArangoDB && state.port === 7687) { + setState({ ...state, port: 8529 }); + } else if (state.type === DatabaseType.Neo4j && state.port === 8529) { + setState({ ...state, port: 7687 }); + } + }, [state.type]); + + /** + * Validates if the port value is numerical. Only then will the state be updated. + * @param port The new port value. + */ + function handlePortChanged(port: string): void { + if (!isNaN(Number(port))) setState({ ...state, port: Number(port) }); + } + + /** Handles the submit button click. Calls the onSubmit in the props with all the fields. */ + function handleSubmitClicked(): void { + ref.current?.close(); + if (!Object.values(hasError).some((e) => e === true)) { + api.AddDatabase(state, { updateDatabaseCache: true, setAsCurrent: true }).then(() => { + schemaApi.RequestSchema(state.name); + }); + } + // props.onSubmit(state); + } + + return ( + <dialog ref={ref}> + <form + className="card flex gap-4" + onSubmit={(event: React.FormEvent) => { + event.preventDefault(); + handleSubmitClicked(); + }} + > + <h1 className="card-title">New Database</h1> + <RequiredInput + errorText="This field is required" + label="Name of the database" + placeHolder="neo4j" + value={state.name} + validate={(v) => { + setHasError({ ...hasError, name: v.length === 0 }); + return v.length > 0; + }} + onChange={(value) => + setState({ + ...state, + name: value, + }) + } + type="text" + /> + + <RequiredInput + errorText="This field is required" + label="Internal database name" + placeHolder="internal_database_name" + value={state.internal_database_name} + validate={(v) => { + setHasError({ ...hasError, internal_database_name: v.length === 0 }); + return v.length > 0; + }} + onChange={(value) => + setState({ + ...state, + internal_database_name: value, + }) + } + type="internalDatabaseName" + /> + + <div className="flex w-full gap-2"> + <div className="w-full"> + <label className="label"> + <span className="label-text">Database Type</span> + </label> + <select + className="select select-bordered w-full max-w-xs" + value={databaseNameMapping[state.type]} + onChange={(event) => { + setState({ + ...state, + type: databaseNameMapping.indexOf(event.currentTarget.value), + }); + }} + > + {databaseNameMapping.map((dbName) => ( + <option value={dbName} key={dbName}> + {dbName} + </option> + ))} + </select> + </div> + <div className="w-full"> + <label className="label"> + <span className="label-text">Database Protocol</span> + </label> + <select + className="select select-bordered w-full max-w-xs" + value={state.protocol} + onChange={(event) => { + setState({ + ...state, + protocol: event.currentTarget.value, + }); + }} + > + {databaseProtocolMapping.map((protocol) => ( + <option value={protocol} key={protocol}> + {protocol} + </option> + ))} + </select> + </div> + </div> + + <div className="flex w-full gap-2"> + <RequiredInput + errorText="This field is required" + label="Hostname/IP" + placeHolder="neo4j" + value={state.url} + validate={(v) => { + setHasError({ ...hasError, url: v.length === 0 }); + return v.length > 0; + }} + onChange={(value) => + setState({ + ...state, + url: value, + }) + } + type="hostname" + /> + + <RequiredInput + errorText="Must be between 1 and 9999" + label="Port" + placeHolder="neo4j" + value={state.port} + validate={(v) => { + setHasError({ ...hasError, port: !(v <= 9999 && v > 0) }); + return v <= 9999 && v > 0; + }} + onChange={(value) => handlePortChanged(value)} + type="port" + /> + </div> + + <div className="flex w-full gap-2"> + <RequiredInput + errorText="This field is required" + label="Username" + placeHolder="username" + value={state.username} + validate={(v) => { + setHasError({ ...hasError, username: v.length === 0 }); + return v.length > 0; + }} + onChange={(value) => + setState({ + ...state, + username: value, + }) + } + type="text" + /> + <RequiredInput + errorText="This field is required" + label="Password" + placeHolder="password" + value={state.password} + validate={(v) => { + setHasError({ ...hasError, password: v.length === 0 }); + return v.length > 0; + }} + onChange={(value) => + setState({ + ...state, + password: value, + }) + } + type="password" + /> + </div> + + <div className="card-actions w-full justify-center"> + <button className={`btn btn-primary ${Object.values(hasError).some((e) => e === true) ? 'btn-disabled' : ''}`}>Submit</button> + <button className="btn btn-outline" onClick={() => props.onClose()}> + Cancel + </button> + </div> + {/* + + <div className={styles.loginContainerButton}> + {portValidation && portValidation == 'error' ? ( + <Button disabled variant="contained" type="submit" color="success"> + Submit + </Button> + ) : ( + <Button variant="contained" type="submit" color="success"> + Submit + </Button> + )} + + <Button + className={styles.cancelButton} + variant="outlined" + color="error" + onClick={() => { + props.onClose(); + }} + > + Cancel + </Button> + </div> */} + </form> + </dialog> + ); +}; diff --git a/apps/web/src/components/navbar/AddDatabaseForm/requiredinput.tsx b/apps/web/src/components/navbar/AddDatabaseForm/requiredinput.tsx new file mode 100644 index 0000000000000000000000000000000000000000..2c83f22297eb2e90869d98a9273835931bce966e --- /dev/null +++ b/apps/web/src/components/navbar/AddDatabaseForm/requiredinput.tsx @@ -0,0 +1,33 @@ +import React from 'react'; + +export const RequiredInput = (props: { + value: any; + label: string; + placeHolder: string; + type: string; + errorText: string; + validate: (value: any) => boolean; + onChange: (value: any) => void; +}) => { + const [isValid, setIsValid] = React.useState<boolean>(true); + + return ( + <div className="form-control w-full "> + <label className="label"> + <span className="label-text">{props.label}</span> + {isValid ? null : <span className="label-text-alt text-error">{props.errorText}</span>} + </label> + <input + type={props.type} + placeholder={props.placeHolder} + className={`input input-bordered w-full ${isValid ? '' : 'input-error'}`} + value={props.value} + onChange={(event) => { + setIsValid(props.validate(event.target.value)); + props.onChange(event.target.value); + }} + required + /> + </div> + ); +}; diff --git a/apps/web/src/components/navbar/AddDatabaseForm/stories/add-database-form.stories.tsx b/apps/web/src/components/navbar/AddDatabaseForm/stories/add-database-form.stories.tsx deleted file mode 100644 index 446dbf80a5aa6d000ce56ea28caddac57cdb2223..0000000000000000000000000000000000000000 --- a/apps/web/src/components/navbar/AddDatabaseForm/stories/add-database-form.stories.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { AddDatabaseRequest, GraphPolarisThemeProvider, store } from '@graphpolaris/shared/lib/data-access'; -import AddDatabaseForm, { AddDatabaseFormProps } from '../index'; -import { Provider } from 'react-redux'; -import { Meta } from '@storybook/react'; -import { ReactFlowProvider } from 'reactflow'; - -const Component: Meta<typeof AddDatabaseForm> = { - title: 'Add database form', - component: AddDatabaseForm, - decorators: [ - // using the real store here - (story: () => any) => ( - <Provider store={store}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> - </Provider> - ), - ], -}; - -export default Component; - -export const Simple = { - args: { open: true }, -}; diff --git a/apps/web/src/components/navbar/databasemenu.tsx b/apps/web/src/components/navbar/databasemenu.tsx new file mode 100644 index 0000000000000000000000000000000000000000..ff3e41e47c255cbab2e0c0f3bdee2fc7f4ea25b8 --- /dev/null +++ b/apps/web/src/components/navbar/databasemenu.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { useSessionCache } from '@graphpolaris/shared/lib/data-access'; + +export const DatabaseMenu = (props: { onClick: (database: string) => void }) => { + const session = useSessionCache(); + + return ( + <ul className="menu dropdown-content absolute right-48 z-[1] p-2 shadow-xl bg-offwhite-100 rounded-box w-52" tabIndex={0}> + {session.databases.map((db: any) => ( + <li key={db}> + <button onClick={() => props.onClick(db)}>{db}</button> + </li> + ))} + </ul> + ); +}; diff --git a/apps/web/src/components/navbar/navbar.module.scss b/apps/web/src/components/navbar/navbar.module.scss index 339c62c0bdcfd45e3d48f1e0b69cde6fb1519d08..6504cf40b1b320ad2cf1ce7b1feeb8cc807859ba 100644 --- a/apps/web/src/components/navbar/navbar.module.scss +++ b/apps/web/src/components/navbar/navbar.module.scss @@ -1,44 +1,42 @@ -.root { - display: flex; - overflow: hidden; - height: 50px; -} - -.appBar { - display: flex; - flex-direction: column; - justify-content: center; - background-color: #fff; - height: 50px; -} - -.menubox { - display: flex; - flex-direction: row; - justify-content: flex-end; - width: 100%; -} - -.menuText { - margin: 5px; - color: #181520; - font-family: Poppins, sans-serif; - font-weight: 400; - font-size: 15px; - align-self: flex-end; - text-transform: none; -} - -.logo { - margin: auto; - display: block; -} - -.loginButton { - margin: 6px; -} - -.loginButtonText { - color: black; - font-weight: bold; -} +// .root { +// display: flex; +// overflow: hidden; +// height: 50px; +// } + +// .appBar { +// display: flex; +// flex-direction: column; +// justify-content: center; +// height: 50px; +// } + +// .menubox { +// display: flex; +// flex-direction: row; +// justify-content: flex-end; +// width: 100%; +// } + +// .menuText { +// margin: 5px; +// color: #181520; +// font-weight: 400; +// font-size: 15px; +// align-self: flex-end; +// text-transform: none; +// } + +// .logo { +// margin: auto; +// display: block; +// } + +// .loginButton { +// margin: 6px; +// } + +// .loginButtonText { +// color: black; +// font-weight: bold; +// } diff --git a/apps/web/src/components/navbar/navbar.tsx b/apps/web/src/components/navbar/navbar.tsx index 9e1fe77168fcb8d28e5cbf22a98d7a16da8281ef..60db1b8f0e7561bf218f9ec35ca1aee3de1e5200 100644 --- a/apps/web/src/components/navbar/navbar.tsx +++ b/apps/web/src/components/navbar/navbar.tsx @@ -9,13 +9,9 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ import React, { useEffect, useState } from 'react'; -import { AppBar, Toolbar, CssBaseline, Typography, MenuItem, ListItemText, Menu, IconButton, Button } from '@mui/material'; import { AccountCircle } from '@mui/icons-material'; import logo from './logogp.png'; import logo_white from './logogpwhite.png'; -import AddDatabaseForm from './AddDatabaseForm'; -import { useTheme } from '@mui/material/styles'; -import styles from './navbar.module.scss'; import { updateCurrentDatabase, updateDatabaseList } from '@graphpolaris/shared/lib/data-access/store/sessionSlice'; import { @@ -26,6 +22,8 @@ import { useSchemaAPI, useSessionCache, } from '@graphpolaris/shared/lib/data-access'; +import { DatabaseMenu } from './databasemenu'; +import { NewDatabaseForm } from './AddDatabaseForm/newdatabaseform'; /** NavbarComponentProps is an interface containing the NavbarViewModel. */ export interface NavbarComponentProps { @@ -50,67 +48,15 @@ export interface NavbarSubComponentState { /** NavbarComponent is the View implementation for Navbar */ export const Navbar = (props: NavbarComponentProps) => { - const theme = useTheme(); const auth = useAuthorizationCache(); const session = useSessionCache(); const api = useDatabaseAPI(); const schemaApi = useSchemaAPI(); const dispatch = useAppDispatch(); - useEffect(() => { - // console.log(auth); - }, [auth.accessToken]); - - // const { navbarViewModel, currentColours } = props; - // this.navbarViewModel = navbarViewModel; - - const [state, setState] = useState<NavbarComponentState>({ - userMenuAnchor: undefined, - selectDatabaseMenuAnchor: undefined, - deleteDatabaseMenuAnchor: undefined, - showAddDatabaseForm: false, - }); - - const [subMenuChangeDisplay, setSubMenuChangewDisplay] = useState('block'); - const [subMenuDeleteDisplay, setSubMenuDeletewDisplay] = useState('block'); - - /** Closes the user menu. */ - function closeUserMenu(): void { - // If a nested window is open, close the main user menu a bit later - setState({ - ...state, - selectDatabaseMenuAnchor: undefined, - deleteDatabaseMenuAnchor: undefined, - }); - - setTimeout(() => { - setState({ ...state, userMenuAnchor: undefined }); - }, 100); - } - - /** Open nested menu's. */ - const openChangeSubMenu = () => { - if (subMenuChangeDisplay === 'none') { - setSubMenuChangewDisplay('block'); - } - }; - const openDeleteSubMenu = () => { - if (subMenuDeleteDisplay === 'none') { - setSubMenuDeletewDisplay('block'); - } - }; - - /** Closes nested menu's. */ - const closeChangeSubMenu = () => { - setSubMenuChangewDisplay('none'); - }; - const closeDeleteSubMenu = () => { - setSubMenuDeletewDisplay('none'); - }; - - function changeColourPalette() { - // TODO - } + const [addDatabaseFormOpen, setAddDatabaseFormOpen] = useState(false); + const [menuOpen, setMenuOpen] = useState(false); + const [subMenuOpen, setSubMenuOpen] = useState<string | undefined>(undefined); /** * Called when the user clicks on the 'submit' button of the add database form. @@ -121,257 +67,134 @@ export const Navbar = (props: NavbarComponentProps) => { }); } - const currentLogo = theme.palette.custom.logo == 'white' ? logo_white : logo; + const currentLogo = !'dark' ? logo_white : logo; // TODO: support dark mode return ( - <div className={styles.root}> - <CssBaseline /> - <AppBar - title="GraphPolaris" - style={{ - backgroundColor: theme.palette.custom.background, - }} - sx={{ - zIndex: 9999, - }} - position="fixed" - className={styles.appBar} - > - <Toolbar style={{ marginLeft: -5 }}> - <a href="https://graphpolaris.com/" className={styles.logo}> - <img src={currentLogo} className={styles.logo} /> - </a> - <div className={styles.menubox}> - {/* <Button - className={styles.menuText} - style={{ color: theme.palette.custom.menuText }} - onClick={changeColourPalette} - > - Change Palette - </Button> */} - <Button href="https://graphpolaris.com/" className={styles.menuText} style={{ color: theme.palette.custom.menuText }}> - Home - </Button> - <Button - href="https://graphpolaris.com/index.php/products/" - className={styles.menuText} - style={{ color: theme.palette.custom.menuText }} + <div className="w-full h-auto px-5"> + <NewDatabaseForm open={addDatabaseFormOpen} onClose={() => setAddDatabaseFormOpen(false)} /> + <div title="GraphPolaris" className="navbar w-full"> + <a href="https://graphpolaris.com/" className="w-full"> + <img src={currentLogo} /> + </a> + <div className="w-fit"> + <div className=""> + <button + tabIndex={0} + className="btn btn-circle btn-ghost hover:bg-gray-200" + onClick={(event) => { + setMenuOpen(!menuOpen); + setSubMenuOpen(undefined); + }} > - Products - </Button> - <Button href="https://graphpolaris.com#usecases" className={styles.menuText} style={{ color: theme.palette.custom.menuText }}> - Use Cases - </Button> - <Button - href="https://graphpolaris.com#earlyadoption" - className={styles.menuText} - style={{ color: theme.palette.custom.menuText }} - > - Contact - </Button> - {auth.authorized ? ( - <div> - <IconButton - color="inherit" - onClick={(event) => - setState({ - ...state, - userMenuAnchor: event.currentTarget, - }) - } - > - <AccountCircle htmlColor={theme.palette.custom.menuText} /> - </IconButton> - <Menu - id="user-menus" - anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }} - transformOrigin={{ vertical: 'top', horizontal: 'left' }} - anchorEl={state.userMenuAnchor} - keepMounted - open={Boolean(state.userMenuAnchor)} - onClose={() => closeUserMenu()} - > - <MenuItem> - <ListItemText primary={'userID: ' + auth.userID} /> - </MenuItem> - <MenuItem> - <ListItemText primary={'sessionID: ' + auth.sessionID} /> - </MenuItem> - {/* <MenuItem - onClick={() => - navbarViewModel.handleLoginButtonClicked('google') - } - > - <ListItemText primary={'request new'} /> - </MenuItem> */} - {/*<MenuItem onClick={() => LocalStorage.instance().Reset()}>*/} - {/* <ListItemText primary={'Empty localstorage'} />*/} - {/*</MenuItem>*/} - <MenuItem - onClick={() => - setState({ - ...state, - userMenuAnchor: undefined, - showAddDatabaseForm: true, - }) - } - > - <ListItemText primary={'Add database'} /> - </MenuItem> - <MenuItem - onClick={(event) => - setState({ - ...state, - selectDatabaseMenuAnchor: event.currentTarget, - }) - } - > - <ListItemText onClick={() => openChangeSubMenu()} primary={'Change database'} /> - </MenuItem> - <Menu - id="databases-menus" - anchorOrigin={{ vertical: 'top', horizontal: 'left' }} - transformOrigin={{ vertical: 'top', horizontal: 'right' }} - anchorEl={state.selectDatabaseMenuAnchor} - keepMounted - disableAutoFocusItem - open={Boolean(state.selectDatabaseMenuAnchor)} - sx={{ display: subMenuChangeDisplay }} - onClose={() => closeChangeSubMenu()} - > - {session.databases.length > 0 ? ( - session.databases.map((database) => ( - <MenuItem - key={database} - selected={database == session.currentDatabase} - sx={{ display: subMenuChangeDisplay }} + <AccountCircle htmlColor="black" /> + </button> + {menuOpen && ( + <> + <div + className="z-10 bg-transparent absolute w-screen h-screen top-0 left-0" + onClick={() => { + setMenuOpen(false); + setSubMenuOpen(undefined); + }} + ></div> + <ul tabIndex={0} className="z-20 dropdown-content menu absolute right-4 p-2 shadow-xl bg-offwhite-100 rounded-box w-52"> + {auth.authorized ? ( + <> + <div className="menu-title"> + <h2>user: {auth.userID}</h2> + <h3 className="text-xs">session: {auth.sessionID}</h3> + </div> + <li> + <button onClick={() => { - if (session.currentDatabase != database) { - dispatch(updateCurrentDatabase(database)); - } - closeChangeSubMenu(); + setAddDatabaseFormOpen(true); + setMenuOpen(false); + setSubMenuOpen(undefined); + }} + > + Add database + </button> + </li> + <li> + <button + onClick={(e) => { + e.stopPropagation(); + setSubMenuOpen(subMenuOpen === 'changeDb' ? undefined : 'changeDb'); }} + className={`${session.databases.length === 0 ? 'btn-disabled' : ''} ${ + subMenuOpen === 'changeDb' ? 'btn-active' : '' + }`} + > + Change Database + </button> + {subMenuOpen === 'changeDb' && ( + <DatabaseMenu + onClick={(db) => { + if (session.currentDatabase != db) { + dispatch(updateCurrentDatabase(db)); + } + setSubMenuOpen(undefined); + setMenuOpen(false); + }} + /> + )} + </li> + <li> + <button + onClick={() => setSubMenuOpen(subMenuOpen === 'deleteDb' ? undefined : 'deleteDb')} + className={`${session.databases.length === 0 ? 'btn-disabled' : ''} ${ + subMenuOpen === 'deleteDb' ? 'btn-active' : '' + }`} > - <ListItemText primary={database} /> - </MenuItem> - )) - ) : ( - <MenuItem key="placeholder" value="" disabled> - no databases connected - </MenuItem> - )} - </Menu> - <MenuItem - onClick={(event) => - setState({ - ...state, - deleteDatabaseMenuAnchor: event.currentTarget, - }) - } - > - <ListItemText onClick={() => openDeleteSubMenu()} primary={'Delete database'} /> - </MenuItem> - <Menu - id="delete-databases-menus" - anchorOrigin={{ vertical: 'top', horizontal: 'left' }} - transformOrigin={{ vertical: 'top', horizontal: 'right' }} - anchorEl={state.deleteDatabaseMenuAnchor} - keepMounted - disableAutoFocusItem - open={Boolean(state?.deleteDatabaseMenuAnchor)} - sx={{ display: subMenuDeleteDisplay }} - onClose={() => closeDeleteSubMenu()} - > - {session.databases.length > 0 ? ( - session.databases.map((database) => ( - <MenuItem - key={database} - selected={database == session.currentDatabase} + Delete Database + </button> + {subMenuOpen === 'deleteDb' && ( + <DatabaseMenu + onClick={(db) => { + if (session.currentDatabase === db) { + dispatch(updateCurrentDatabase('')); + } + api.DeleteDatabase(db); + setSubMenuOpen(undefined); + setMenuOpen(false); + }} + /> + )} + </li> + </> + ) : ( + <> + <div className="menu-title"> + <h2>user: {auth.userID}</h2> + <h3 className="text-xs">session: {auth.sessionID}</h3> + </div> + <div> + <button + className="btn btn-ghost" onClick={() => { - if (session.currentDatabase === database) { - dispatch(updateCurrentDatabase('')); - } - api.DeleteDatabase(database); - closeDeleteSubMenu(); + setMenuOpen(false); }} > - <ListItemText primary={database} /> - </MenuItem> - )) - ) : ( - <MenuItem key="placeholder" value="" disabled> - no databases connected - </MenuItem> - )} - </Menu> - </Menu> - </div> - ) : ( - <div> - <Button - className={styles.loginButton} - onClick={(event) => - setState({ - ...state, - userMenuAnchor: event.currentTarget, - }) - } - > - <span - className={styles.loginButtonText} - style={{ - color: theme.palette.custom.menuText, - }} - > - Login - </span> - </Button> - {/* <Menu - id="user-menus" - getContentAnchorEl={null} - anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }} - transformOrigin={{ vertical: 'top', horizontal: 'left' }} - anchorEl={state.userMenuAnchor} - keepMounted - open={Boolean(state.userMenuAnchor)} - onClose={() => closeUserMenu()} - > - <MenuItem - onClick={() => - navbarViewModel.handleLoginButtonClicked('google') - } - > - <ListItemText primary={'Login with Google'} /> - </MenuItem> - <MenuItem - onClick={() => - navbarViewModel.handleLoginButtonClicked('github') - } - > - <ListItemText primary={'Login with GitHub'} /> - </MenuItem> - <MenuItem - onClick={() => - navbarViewModel.handleLoginButtonClicked('free') - } - > - <ListItemText primary={'Login with free (debug)'} /> - </MenuItem> - </Menu> */} - </div> + <span>Login</span> + {/* !TODO */} + </button> + </div> + </> + )} + </ul> + </> )} </div> - </Toolbar> - </AppBar> - <AddDatabaseForm + </div> + </div> + {/* <AddDatabaseForm open={state.showAddDatabaseForm} onClose={() => setState({ ...state, showAddDatabaseForm: false })} onSubmit={(...params) => { onAddDatabaseFormSubmit(...params); setState({ ...state, showAddDatabaseForm: false }); }} - styles={undefined} - /> + /> */} </div> ); }; diff --git a/apps/web/src/components/panels/panel.stories.tsx b/apps/web/src/components/panels/panel.stories.tsx deleted file mode 100644 index 9cf95d601a6788bf5553e9ef0140fcfa89c59aa7..0000000000000000000000000000000000000000 --- a/apps/web/src/components/panels/panel.stories.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import React from 'react'; -import Panel from './panel'; -import { ComponentStory, Meta } from '@storybook/react'; -import { configureStore } from '@reduxjs/toolkit'; -import { colorPaletteConfigSlice } from '@graphpolaris/shared/lib/data-access/store'; -import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; - -const Component: Meta<typeof Panel> = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/react/configure/overview#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'Panel', - component: Panel, - decorators: [ - (story) => ( - <Provider store={Mockstore}> - <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> - </Provider> - ), - ], -}; - -// A super-simple mock of a redux store -const Mockstore = configureStore({ - reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, - }, -}); - -const Template: ComponentStory<typeof Panel> = (args) => <Panel {...args} />; - -export const Primary = Template.bind({}); - -Primary.args = { - content: 'Testing header #1', - color: 'blue', -}; - -export const Secondary = Template.bind({}); - -Secondary.args = { - content: 'Testing header number twoooo', - color: 'purple', - children: <h1>I AM A CHILD</h1>, -}; - -export default Component; diff --git a/apps/web/src/components/panels/panel.tsx b/apps/web/src/components/panels/panel.tsx deleted file mode 100644 index 93ca8bd86e3a7a5e3da8d840e9f69e0082ec86c6..0000000000000000000000000000000000000000 --- a/apps/web/src/components/panels/panel.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import styled from 'styled-components'; -import { ReactNode } from 'react'; -import { useTheme } from '@mui/material/styles'; -interface Props { - content: string; - color?: string; - children?: ReactNode; -} - -const Wrapper = styled.div<{ color: string }>` - background-color: ${(props) => props.color}; - font-family: 'Arial'; - - // Light shadow - // box-shadow: 0 3px 10px rgb(0 0 0 / 0.2); - border: 1px solid #dddddd; - - height: 100%; - width: 100%; - - display: flex; - justify-content: center; - align-items: center; -`; - -const Content = styled.div` - margin: 0.8em; - border-radius: 8px; - width: 100%; - height: 98%; - overflow: hidden; -`; - -const Panel = (props: Props) => { - return ( - <Wrapper color={props?.color || 'white'} className=""> - <Content className=""> - <h1 - style={ - { - // backgroundColor: theme.palette.custom.dataPointColors[1], - } - } - > - {props.content} - </h1> - {props.children} - </Content> - </Wrapper> - ); -}; - -export default Panel; diff --git a/apps/web/src/index.html b/apps/web/src/index.html deleted file mode 100644 index fb97c0641cfe83e26fb2990ce93e8ffbb585f198..0000000000000000000000000000000000000000 --- a/apps/web/src/index.html +++ /dev/null @@ -1,15 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="utf-8" /> - <title>Graphpolaris</title> - <base href="/" /> - - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <link rel="icon" type="image/x-icon" href="favicon.ico" /> - </head> - - <body> - <div id="root"></div> - </body> -</html> diff --git a/apps/web/src/main.tsx b/apps/web/src/main.tsx index b6d8c226a8380854efa7ccfd37ce8c77c0868828..aecf30009f4ed5838ecd2126fd787f57874ab0c3 100644 --- a/apps/web/src/main.tsx +++ b/apps/web/src/main.tsx @@ -1,14 +1,9 @@ import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import React from 'react'; -import ReactDOM from 'react-dom/client'; - -import { StrictMode } from 'react'; import { Provider } from 'react-redux'; import { store } from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; import App from './app/app'; -import { CssBaseline } from '@mui/material'; import { createRoot } from 'react-dom/client'; import './styles.css'; @@ -18,15 +13,12 @@ if (domNode) { const root = createRoot(domNode); root.render( <Provider store={store}> - <GraphPolarisThemeProvider> - <CssBaseline /> - <Router> - <Routes> - {/* App */} - <Route path="/" element={<App />}></Route> - </Routes> - </Router> - </GraphPolarisThemeProvider> + <Router> + <Routes> + {/* App */} + <Route path="/" element={<App />}></Route> + </Routes> + </Router> </Provider>, ); } diff --git a/apps/web/src/styles.css b/apps/web/src/styles.css index b5c61c956711f981a41e95f7fcf0038436cfbb22..eae4343098ce499729772044bf9565c46bb98046 100644 --- a/apps/web/src/styles.css +++ b/apps/web/src/styles.css @@ -1,3 +1,19 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@tailwind base; +@tailwind components; +@tailwind utilities; + +* { + font-family: 'Inter', ubuntu, sans-serif; + box-sizing: border-box; +} + +.panel { + padding: 0.3rem; + background-color: #ffffff; + border: 1px solid #dddddd; +} + +.tooltip::before { + @apply z-50; + @apply content-[attr(data-tip)]; +} diff --git a/apps/web/tailwind.config.js b/apps/web/tailwind.config.js index d21f1cdae70ca548855964467cc032c21ce5c1bb..c53c66015777548be03fe08a1af0d1215a40c98a 100644 --- a/apps/web/tailwind.config.js +++ b/apps/web/tailwind.config.js @@ -1,8 +1,5 @@ -/** @type {import('tailwindcss').Config} */ -export default { - content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'], - theme: { - extend: {}, - }, - plugins: [], +const sharedConfig = require('../../libs/config/tailwind.config.js'); + +module.exports = { + presets: [sharedConfig], }; diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index e3f42121eadfdee5dbebd030346e1e78f3fa4b7d..61ae61c7af7ee214bd795fbf704ef4282a82d0be 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -1,4 +1,7 @@ { + "$schema": "https://json.schemastore.org/tsconfig", + "display": "React Library", + "target": "ESNext", "compilerOptions": { "jsx": "react-jsx", "allowJs": true, @@ -19,12 +22,14 @@ "isolatedModules": true, "noEmit": true, "baseUrl": ".", + "types": ["vite/client"], "paths": { - "@graphpolaris/shared/lib/*": ["../../libs/shared/lib/*"] + "@graphpolaris/shared/lib/*": ["../../libs/shared/lib/*"], + "@graphpolaris/config/*": ["../../libs/config/src/*"] } }, - "exclude": ["node_modules", "public"], - "include": ["src", "../../libs/shared/lib/querybuilder/panel/attributepill"], - "files": ["./node.d.ts"], + "exclude": ["node_modules", "public", "dist", "build"], + "include": ["vite.config.ts", "../../libs/shared/lib/**/*", "../../libs/config/src/**/*", "src/**/*"], + "files": ["vite.config.ts"], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index 44c0c7d6058d86b6955579f13e00a5a6f9872b99..8ff675b28bec1836b58625c637cb4cf75a8d105c 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -1,10 +1,9 @@ -/// <reference types="vitest" /> import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react-swc'; import path from 'path'; import dts from 'vite-plugin-dts'; +import sassDts from 'vite-plugin-sass-dts'; -// https://vitejs.dev/config/ export default defineConfig({ plugins: [ react(), @@ -12,10 +11,12 @@ export default defineConfig({ dts({ insertTypesEntry: true, }), + sassDts(), ], resolve: { alias: { '@graphpolaris/shared/lib': path.resolve(__dirname, '../../libs/shared/lib'), + '@graphpolaris/config': path.resolve(__dirname, '../../libs/config/src'), }, }, }); diff --git a/libs/config/.eslintignore b/libs/config/.eslintignore new file mode 100644 index 0000000000000000000000000000000000000000..ed9d65c51ee65528569330ac08d99a1383f2a614 --- /dev/null +++ b/libs/config/.eslintignore @@ -0,0 +1,6 @@ +node_modules/* +node_modules/ +node_modules +*.d.ts +*.mjs +*.tsbuildinfo \ No newline at end of file diff --git a/libs/config/.eslintrc.json b/libs/config/.eslintrc.json new file mode 100644 index 0000000000000000000000000000000000000000..351d714ab66565664d2f52885fdeb9d1d52c0976 --- /dev/null +++ b/libs/config/.eslintrc.json @@ -0,0 +1,25 @@ +{ + "extends": ["plugin:react-hooks/recommended"], + "parserOptions": { + "sourceType": "module", + "ecmaVersion": "latest", + "ecmaFeatures": { + "jsx": true + } + }, + "ignorePatterns": ["!**/*", "node.d.ts"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/config/.gitignore b/libs/config/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a547bf36d8d11a4f89c59c144f24795749086dd1 --- /dev/null +++ b/libs/config/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/libs/config/package.json b/libs/config/package.json new file mode 100644 index 0000000000000000000000000000000000000000..dc3741af0c5cbd8382a7feb92abb196914e34e62 --- /dev/null +++ b/libs/config/package.json @@ -0,0 +1,20 @@ +{ + "name": "config", + "private": true, + "version": "0.0.0", + "type": "module", + "main": "src/index.js", + "license": "MIT", + "files": [ + ".eslintrc.js", + "eslint-preset.js", + "postcss.config.js", + "tailwind.config.js" + ], + "devDependencies": { + "@tailwindcss/typography": "^0.5.9", + "daisyui": "^3.5.0", + "postcss": "^8.4.21", + "tailwindcss": "^3.3.1" + } +} diff --git a/libs/config/postcss.config.js b/libs/config/postcss.config.js new file mode 100644 index 0000000000000000000000000000000000000000..2f20e4a741aecf2ad32e5e236c551954c0cb556b --- /dev/null +++ b/libs/config/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: { config: './tailwind.config.js' }, + autoprefixer: {}, + }, +}; diff --git a/libs/config/src/colors.js b/libs/config/src/colors.js new file mode 100644 index 0000000000000000000000000000000000000000..2ca7a396fc18178f012ac0ed338d0c7a0e8c5034 --- /dev/null +++ b/libs/config/src/colors.js @@ -0,0 +1,84 @@ +import * as defaultTheme from 'tailwindcss/defaultTheme'; + +export const tailwindColors = { + ...defaultTheme.colors, + entity: { + // https://www.tailwindshades.com/#color=29.41176470588235%2C100%2C50&step-up=8&step-down=8&hue-shift=5&name=flush-orange&base-stop=6&v=1&overrides=e30%3D + DEFAULT: '#FF7D00', + 0: '#FFFAF9', + 50: '#FFF3E6', + 100: '#FFE7CC', + 200: '#FFD3A3', + 300: '#FFBF7A', + 400: '#FFA952', + 500: '#FF9429', + 600: '#FF7D00', // primary + 700: '#D66700', + 800: '#AD5200', + 900: '#853E00', + 950: '#703400', + }, + relation: { + //https://www.tailwindshades.com/#color=207.97297297297297%2C62.184873949579824%2C46.666666666666664&step-up=9&step-down=10&hue-shift=0&name=mariner&base-stop=6&v=1&overrides=e30%3D + DEFAULT: '#2D7CC1', + 50: '#EFF6FB', + 100: '#DDEBF7', + 200: '#B7D5EE', + 300: '#92BFE6', + 400: '#6DA9DD', + 500: '#4893D4', + 600: '#2D7CC1', + 700: '#236198', + 800: '#1A476E', + 900: '#102C45', + 950: '#0B1F30', + }, + line: { + 100: '#dee9f0', + 300: '#ccd6dc', + }, + logic: { + DEFAULT: '#A36A30', + 50: '#FBF6F1', + 100: '#F5E9DD', + 200: '#E9D0B6', + 300: '#DEB68E', + 400: '#D29D67', + 500: '#C7843F', + 600: '#A36A30', + 700: '#7C5024', + 800: '#543719', + 900: '#2D1D0D', + 950: '#191007', + }, + offwhite: { + DEFAULT: '#F7F9FA', + 100: '#F7F9FA', + 200: '#f4f6f7', + 300: '#d4dce1', + }, + custom: { + nodes: [ + '#181520', // black + '#d49350', // orange + '#1e9797', // blue + '#d56a50', // red + '#800000', + '#fabed4', + '#808000', + '#ffe119', + '#bfef45', + '#3cb44b', + '#42d4f4', + '#000075', + '#4363d8', + '#911eb4', + '#dcbeff', + '#f032e6', + '#a9a9a9', + '#2d7c0b', + '#00ff00', + '#0000ff', + ], + }, +}; diff --git a/libs/config/src/index.js b/libs/config/src/index.js new file mode 100644 index 0000000000000000000000000000000000000000..de90165e61e14ba3904a8d77f520842d377c0a17 --- /dev/null +++ b/libs/config/src/index.js @@ -0,0 +1 @@ +export * from './colors.js'; diff --git a/libs/config/styles.css b/libs/config/styles.css new file mode 100644 index 0000000000000000000000000000000000000000..04b35af2af65c8f08f0ffa850b9147d1694bc94e --- /dev/null +++ b/libs/config/styles.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/libs/config/tailwind.config.js b/libs/config/tailwind.config.js new file mode 100644 index 0000000000000000000000000000000000000000..553663a5b770180969d1b721dfa99480697b619c --- /dev/null +++ b/libs/config/tailwind.config.js @@ -0,0 +1,58 @@ +/** @type {import('tailwindcss').Config} */ +import * as defaultTheme from 'tailwindcss/defaultTheme'; +import { tailwindColors } from './src/colors.js'; + +export default { + content: ['./index.html', 'src/**/*.{js,ts,jsx,tsx}', '../../libs/*/lib/**/*.{js,ts,jsx,tsx}'], + theme: { + extend: { + fontFamily: { + inter: ['"Inter"', ...defaultTheme.fontFamily.sans], + }, + colors: tailwindColors, + }, + }, + plugins: [require('@tailwindcss/typography'), require('daisyui')], + // daisyUI config (optional - here are the default values) + daisyui: { + themes: [ + { + graphpolarisWhite: { + ...require('daisyui/src/theming/themes')['[data-theme=corporate]'], + fontFamily: 'inter,ubuntu,courier,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace', + primary: '#112646', + secondary: '#B0B8C2', + accent: '#FF7D00', + neutral: '#1c1917', + 'base-100': '#F7F9FA', + // 'base-200': '#F9FBFC', + info: '#99622E', + success: '#2DC177', + warning: '#eab308', + error: '#dc2626', + + // "--rounded-box": "0rem", // border radius rounded-box utility class, used in card and other large boxes + // "--rounded-btn": "0.5rem", // border radius rounded-btn utility class, used in buttons and similar element + // "--rounded-badge": "1.9rem", // border radius rounded-badge utility class, used in badges and similar + // "--animation-btn": "0.25s", // duration of animation when you click on button + // "--animation-input": "0.2s", // duration of animation for inputs like checkbox, toggle, radio, etc + // "--btn-text-case": "uppercase", // set default text transform for buttons + // "--btn-focus-scale": "0.95", // scale transform of button when you focus on it + // "--border-btn": "1px", // border width of buttons + // "--tab-border": "1px", // border width of tabs + // "--tab-radius": "0.5rem", // border radius of tabs + }, + }, + 'dark', + 'corporate', + ], // true: all themes | false: only light + dark | array: specific themes like this ["light", "dark", "cupcake"] + darkTheme: false, // disabled for now + // darkTheme: 'dark', // name of one of the included themes for dark mode + base: true, // applies background color and foreground color for root element by default + styled: true, // include daisyUI colors and design decisions for all components + utils: true, // adds responsive and modifier utility classes + rtl: false, // rotate style direction from left-to-right to right-to-left. You also need to add dir="rtl" to your html tag and install `tailwindcss-flip` plugin for Tailwind CSS. + prefix: '', // prefix for daisyUI classnames (components, modifiers and responsive class names. Not colors) + logs: false, // Shows info about daisyUI version and used config in the console when building your CSS + }, +}; diff --git a/libs/config/tsconfig.json b/libs/config/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..8f623bfdd35165d37d3cbcafd2d52a5da69b7eaf --- /dev/null +++ b/libs/config/tsconfig.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "display": "React Library", + "target": "ESNext", + "compilerOptions": { + "jsx": "react-jsx", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": false, + "strict": true, + "noImplicitOverride": false, + "noImplicitReturns": false, + "noFallthroughCasesInSwitch": false, + "target": "ESNext", + "useDefineForClassFields": true, + "lib": ["DOM", "DOM.Iterable", "ESNext", "ES6", "ES2017"], + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": false, + "noEmit": true, + "baseUrl": ".", + "inlineSources": false, + "noUnusedLocals": false, + "noUnusedParameters": false, + "composite": true, + "types": ["vite/client"] + } +} diff --git a/libs/config/tsconfig.lib.json b/libs/config/tsconfig.lib.json new file mode 100644 index 0000000000000000000000000000000000000000..a1f1afa7aefeed6dfb74d2f91ba6a1eaf5b07a97 --- /dev/null +++ b/libs/config/tsconfig.lib.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "composite": false, + "declaration": true, + "preserveWatchOutput": true, + "lib": ["ES2017", "DOM", "DOM.Iterable", "ESNext"] + }, + "exclude": ["dist", "build", "node_modules"], + "include": ["src", "lib", "lib/**/*"], + "files": [], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/libs/storybook/tsconfig.node.json b/libs/config/tsconfig.node.json similarity index 64% rename from libs/storybook/tsconfig.node.json rename to libs/config/tsconfig.node.json index 9d31e2aed93c876bc048cf2f863cb2a847c901e8..a54ca1adb820b30780b53c9b7049fc731bf73452 100644 --- a/libs/storybook/tsconfig.node.json +++ b/libs/config/tsconfig.node.json @@ -3,7 +3,8 @@ "composite": true, "module": "ESNext", "moduleResolution": "Node", - "allowSyntheticDefaultImports": true + "allowSyntheticDefaultImports": true, + "types": ["node", "vite/client"] }, "include": ["vite.config.ts"] } diff --git a/libs/config/vitest.shared.config.js b/libs/config/vitest.shared.config.js new file mode 100644 index 0000000000000000000000000000000000000000..1559a52a9c6e1de04a8dba4153ed352d30a52724 --- /dev/null +++ b/libs/config/vitest.shared.config.js @@ -0,0 +1,27 @@ +const { configDefaults, defineConfig } = require('vitest/config'); + +module.exports = defineConfig({ + test: { + environment: 'happy-dom', + globals: true, + threads: true, + exclude: [...configDefaults.exclude], + deps: { + experimentalOptimizer: { + web: { enabled: true }, + ssr: { enabled: true }, + }, + }, + benchmark: { reporters: ['default'] }, + reporters: ['default'], + passWithNoTests: true, + coverage: { + provider: 'v8', + }, + environmentOptions: { + jsdom: { + resources: 'usable', + }, + }, + }, +}); diff --git a/libs/shared/.eslintignore b/libs/shared/.eslintignore index 86439d7da52543b11217f39ba86cdd13c4283c7f..ed9d65c51ee65528569330ac08d99a1383f2a614 100644 --- a/libs/shared/.eslintignore +++ b/libs/shared/.eslintignore @@ -2,3 +2,5 @@ node_modules/* node_modules/ node_modules *.d.ts +*.mjs +*.tsbuildinfo \ No newline at end of file diff --git a/libs/shared/.eslintrc.json b/libs/shared/.eslintrc.json index 2707c1f4120744f9e9e9e736c8aad7cf59a0862c..8144cb41a186f2f60c5912d27eecfa48121cfa75 100644 --- a/libs/shared/.eslintrc.json +++ b/libs/shared/.eslintrc.json @@ -1,25 +1,3 @@ { - "extends": ["plugin:react-hooks/recommended"], - "parserOptions": { - "sourceType": "module", - "ecmaVersion": "latest", - "ecmaFeatures": { - "jsx": true - } - }, - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": {} - }, - { - "files": ["*.ts", "*.tsx"], - "rules": {} - }, - { - "files": ["*.js", "*.jsx"], - "rules": {} - } - ] + "extends": ["./node_modules/config/.eslintrc.json"] } diff --git a/libs/shared/.gitignore b/libs/shared/.gitignore index a547bf36d8d11a4f89c59c144f24795749086dd1..dd4d473b2c788cb5054c8bc2acfd284dd80b08d2 100644 --- a/libs/shared/.gitignore +++ b/libs/shared/.gitignore @@ -22,3 +22,6 @@ dist-ssr *.njsproj *.sln *.sw? + +tsconfig.tsbuildinfo +vite.config.ts.* \ No newline at end of file diff --git a/libs/shared/.postcssrc.cjs b/libs/shared/.postcssrc.cjs deleted file mode 100644 index 70ea41d8c21b1f89f54e138b8dc8a7044f18b681..0000000000000000000000000000000000000000 --- a/libs/shared/.postcssrc.cjs +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - parser: 'postcss-scss', - map: false, - plugins: [require('postcss-nesting')], -}; diff --git a/libs/shared/lib/components/Dialog.tsx b/libs/shared/lib/components/Dialog.tsx new file mode 100644 index 0000000000000000000000000000000000000000..c975753399caf237003d19386079c98dd5e443d9 --- /dev/null +++ b/libs/shared/lib/components/Dialog.tsx @@ -0,0 +1,26 @@ +import { PropsWithChildren, useEffect, useRef } from 'react'; + +export type DialogProps = { + onClose(): void; + open: boolean; +}; + +export const Dialog = (props: PropsWithChildren<DialogProps>) => { + const ref = useRef<HTMLDialogElement>(null); + + useEffect(() => { + if (props.open) ref.current?.showModal(); + else ref.current?.close(); + }, [props.open]); + + return ( + <dialog className="modal" ref={ref} onClose={() => props.onClose()}> + <form method="dialog" className="modal-box card flex gap-4"> + {props.children} + </form> + <form method="dialog" className="modal-backdrop"> + <button>close</button> + </form> + </dialog> + ); +}; diff --git a/libs/shared/lib/data-access/api/schema.ts b/libs/shared/lib/data-access/api/schema.ts index 417b607835f553030bb195ecc5459621cb27fc9d..dbe1e7a774100181022d92aa8176a2391e57960b 100644 --- a/libs/shared/lib/data-access/api/schema.ts +++ b/libs/shared/lib/data-access/api/schema.ts @@ -16,7 +16,8 @@ export const useSchemaAPI = () => { const request = { databaseName, - cached: true, + cached: false, + // cached: true, }; const response = await fetch(`${domain}${schema}/`, { diff --git a/libs/shared/lib/data-access/index.ts b/libs/shared/lib/data-access/index.ts index 2706d3a0fb81b9e4dd8efef4815026a3044aa2e0..1084b2e70f182f2f4be6541f0baef9ea070439f7 100644 --- a/libs/shared/lib/data-access/index.ts +++ b/libs/shared/lib/data-access/index.ts @@ -1,4 +1,3 @@ export * from './api'; export * from './authorization'; export * from './store'; -export * from './theme'; diff --git a/libs/shared/lib/data-access/store/graphQueryResultSlice.ts b/libs/shared/lib/data-access/store/graphQueryResultSlice.ts index a776ada94396ee7a1f3659386bfae9894272e7c1..a37a20e2fe5a26f85a5bec4e2de86f75e64905ee 100644 --- a/libs/shared/lib/data-access/store/graphQueryResultSlice.ts +++ b/libs/shared/lib/data-access/store/graphQueryResultSlice.ts @@ -76,7 +76,7 @@ export const graphQueryResultSlice = createSlice({ let _node = { ...node }; let nodeType = node.id.split('/')[0]; let innerLabels = node?.attributes?.labels as string[]; - if (innerLabels.length > 0) { + if (innerLabels?.length > 0) { nodeType = innerLabels[0] as string; } if (!nodeTypes.includes(nodeType)) nodeTypes.push(nodeType); @@ -85,12 +85,13 @@ export const graphQueryResultSlice = createSlice({ }); payload.edges = payload.edges.map((edge) => { + let _edge = { ...edge }; let edgeType = edge.id.split('/')[0]; - if (!edge.id.includes('/')) { + if (!_edge.id.includes('/')) { edgeType = edge.attributes.Type as string; } - edge.label = edgeType; - return edge; + _edge.label = edgeType; + return _edge; }); // Assign new state diff --git a/libs/shared/lib/data-access/store/index.ts b/libs/shared/lib/data-access/store/index.ts index be78c8572eb4499824eadfa8307e748c6fad549c..02dc9bb14ef580d5ed5baf6ccaf5d0be5deccff9 100644 --- a/libs/shared/lib/data-access/store/index.ts +++ b/libs/shared/lib/data-access/store/index.ts @@ -11,14 +11,6 @@ export { resetGraphQueryResults, graphQueryResultSlice, } from './graphQueryResultSlice'; -export { - changePrimary, - changeDataPointColors, - toggleDarkMode, - selectColorPaletteConfig, - colorPaletteConfigSlice, -} from './colorPaletteConfigSlice'; // Exported types export type { Node, Edge, GraphQueryResult } from './graphQueryResultSlice'; -export type { ColorPaletteConfig, ExtraColorsForMui5 } from './colorPaletteConfigSlice'; diff --git a/libs/shared/lib/data-access/store/schemaSlice.ts b/libs/shared/lib/data-access/store/schemaSlice.ts index 80f9573051bf67a33f5763e50a61468103a10cfc..b187a78d9c3f41b642bdda555c1fca5d8732d13d 100644 --- a/libs/shared/lib/data-access/store/schemaSlice.ts +++ b/libs/shared/lib/data-access/store/schemaSlice.ts @@ -6,16 +6,17 @@ import { SchemaFromBackend, SchemaGraph, SchemaGraphology } from '../../schema'; /**************************************************************** */ -// Define the initial state using that type -export const initialState: { +type schemaSliceI = { graphologySerialized: SchemaGraph; layoutName: AllLayoutAlgorithms; -} = { +}; + +// Define the initial state using that type +export const initialState: schemaSliceI = { graphologySerialized: new SchemaGraphology().export(), // layoutName: 'Cytoscape_fcose', layoutName: CytoscapeLayoutAlgorithms.KLAY as AllLayoutAlgorithms, }; - export const schemaSlice = createSlice({ name: 'schema', // `createSlice` will infer the state type from the `initialState` argument @@ -69,7 +70,6 @@ export const schemaSlice = createSlice({ }, }, }); - export const { readInSchemaFromBackend, setSchema } = schemaSlice.actions; /** diff --git a/libs/shared/lib/data-access/store/store.ts b/libs/shared/lib/data-access/store/store.ts index b7be9dcd3c59f92a623c75a423f80158d2f88e18..aa32a4d6aba58d3ae82bddf133279c784acfbd5f 100644 --- a/libs/shared/lib/data-access/store/store.ts +++ b/libs/shared/lib/data-access/store/store.ts @@ -1,5 +1,4 @@ import { configureStore } from '@reduxjs/toolkit'; -import colorPaletteConfigSlice from './colorPaletteConfigSlice'; import graphQueryResultSlice from './graphQueryResultSlice'; import querybuilderSlice from './querybuilderSlice'; import schemaSlice from './schemaSlice'; @@ -11,7 +10,6 @@ export const store = configureStore({ reducer: { graphQueryResult: graphQueryResultSlice, schema: schemaSlice, - colorPaletteConfig: colorPaletteConfigSlice, querybuilder: querybuilderSlice, sessionCache: sessionSlice, auth: authSlice, diff --git a/libs/shared/lib/data-access/store/colorPaletteConfigSlice.ts b/libs/shared/lib/data-access/theme/colorPaletteConfigSlice.ts similarity index 78% rename from libs/shared/lib/data-access/store/colorPaletteConfigSlice.ts rename to libs/shared/lib/data-access/theme/colorPaletteConfigSlice.ts index 57f59630344427d76244284475c303261c72615a..f8c83ebf12077737950b7813903824c664ff3976 100644 --- a/libs/shared/lib/data-access/store/colorPaletteConfigSlice.ts +++ b/libs/shared/lib/data-access/theme/colorPaletteConfigSlice.ts @@ -1,6 +1,3 @@ -import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import type { RootState } from './store'; - /** Extra properties that are not present in the default PaletteOptions of mui. For autocompletion */ export interface ExtraColorsForMui5 { /** Colors that can be used for data visualisation, e.g. nodes, edges */ @@ -189,41 +186,3 @@ export const initialState: ColorPaletteConfig = { }, darkMode: false, }; - -export const colorPaletteConfigSlice = createSlice({ - name: 'colorPaletteConfig', - // `createSlice` will infer the state type from the `initialState` argument - initialState, - reducers: { - changePrimary: ( - state, - action: PayloadAction<{ - main?: string; - light?: string; - dark?: string; - darkMode?: 'light' | 'dark'; - }> - ) => { - const { main, light, dark, darkMode } = action.payload; - let palette = state.lightPalette; - if (darkMode == 'dark') palette = state.darkPalette; - - if (main) palette.primary.main = main; - if (light) palette.primary.light = light; - if (dark) palette.primary.dark = dark; - }, - changeDataPointColors: (state, action: PayloadAction<string[]>) => { - state.lightPalette.custom.dataPointColors = action.payload; - }, - toggleDarkMode: (state) => { - state.darkMode = !state.darkMode; - }, - }, -}); - -export const { changePrimary, changeDataPointColors, toggleDarkMode } = colorPaletteConfigSlice.actions; - -// Select the schema and convert it to a graphology object -export const selectColorPaletteConfig = (state: RootState) => state.colorPaletteConfig; - -export default colorPaletteConfigSlice.reducer; diff --git a/libs/shared/lib/data-access/theme/colours.tsx b/libs/shared/lib/data-access/theme/colours.tsx index 60870f15aed7317e04f3faa50326020a8e0e6801..153bdaeb7a5d67738bab4c4894e3dd6a85071495 100644 --- a/libs/shared/lib/data-access/theme/colours.tsx +++ b/libs/shared/lib/data-access/theme/colours.tsx @@ -3,6 +3,13 @@ * Utrecht University within the Software Project course. * © Copyright Utrecht University (Department of Information and Computing Sciences) */ + +import resolveConfig from 'tailwindcss/resolveConfig'; +import tailwindConfig from '../../../tailwind.config.js'; + +//@ts-ignore +export const tailwindcss = resolveConfig(tailwindConfig); + export const ColourPalettes: { [key: string]: any } = { availablePalettes: ['default', 'dark'], diff --git a/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.spec.tsx b/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.spec.tsx deleted file mode 100644 index 6a262bc1ed4eeef9aa8c34ce588857d0da7de865..0000000000000000000000000000000000000000 --- a/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.spec.tsx +++ /dev/null @@ -1,33 +0,0 @@ -// import Button from '@mui/material/Button'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import { MockTheme, MockThemeGraphPolaris } from './mockTheme'; -import { assert, describe, expect, it } from 'vitest'; - -describe('<MockTheme GraphPolarisThemeProvider>', () => { - // TODO: This test should be implemented and running, but I get import issues in the mono-repo with jest (MIB) - // https://emotion.sh/docs/@emotion/jest - - it('renders without crashing', () => undefined); - // it('passes smoke test no config of mocktheme', () => { - // const div = document.createElement('div'); - - // ReactDOM.render( - // <MockTheme> - // <Button variant="text">Text</Button> - // </MockTheme>, - // div - // ); - // }); - - // it('passes smoke test config GraphPolaris', () => { - // const div = document.createElement('div'); - - // ReactDOM.render( - // <MockThemeGraphPolaris> - // <Button variant="text">Text</Button> - // </MockThemeGraphPolaris>, - // div - // ); - // }); -}); diff --git a/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.tsx b/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.tsx deleted file mode 100644 index f9ead3f6218e256ab46223310f57fe03a5febade..0000000000000000000000000000000000000000 --- a/libs/shared/lib/data-access/theme/graphPolarisThemeProvider.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React, { ReactNode } from 'react'; -import { ColorPaletteConfig, ExtraColorsForMui5, selectColorPaletteConfig, useAppSelector } from '../../data-access/store'; -import { createTheme, ThemeOptions, ThemeProvider } from '@mui/material/styles'; -import { ColorPalette } from '../store/colorPaletteConfigSlice'; - -// Add custom theme variables to the mui theme types -declare module '@mui/material/styles' { - interface Palette extends ColorPalette {} - interface Theme { - palette: Palette; - } - interface PaletteOptions extends Partial<ColorPalette> {} - interface ThemeOptions { - palette?: PaletteOptions; - } -} - -export function GraphPolarisThemeProvider({ children }: { children: ReactNode }) { - const colorPaletteConfig = useAppSelector(selectColorPaletteConfig); - - // Create a new theme when our custom color palette in redux changed - const theme = React.useMemo( - () => - // Map our color palette config (stored in redux) to the mui 5 format - createTheme(MapColorsConfigToMuiTheme(colorPaletteConfig)), - [colorPaletteConfig] - ); - - return <ThemeProvider theme={theme}>{children}</ThemeProvider>; -} - -export function MapColorsConfigToMuiTheme(colorsConfig: ColorPaletteConfig): ThemeOptions { - return { - palette: { - mode: colorsConfig.darkMode ? 'dark' : 'light', - ...(colorsConfig.darkMode ? colorsConfig.darkPalette : colorsConfig.lightPalette), - // ...(colorsConfig.darkMode - // ? colorsConfig.darkPalette.custom - // : colorsConfig.lightPalette.custom) as ExtraColorsForMui5, - }, - }; -} - -export default GraphPolarisThemeProvider; diff --git a/libs/shared/lib/data-access/theme/index.ts b/libs/shared/lib/data-access/theme/index.ts deleted file mode 100644 index 322a845050978cfcf920dc89b4f95fd04d112776..0000000000000000000000000000000000000000 --- a/libs/shared/lib/data-access/theme/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './graphPolarisThemeProvider'; -export * from './colours'; diff --git a/libs/shared/lib/data-access/theme/mockTheme.tsx b/libs/shared/lib/data-access/theme/mockTheme.tsx deleted file mode 100644 index fccc611d7f80317eab5d898853171fb4e2404459..0000000000000000000000000000000000000000 --- a/libs/shared/lib/data-access/theme/mockTheme.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; - -import { createTheme, ThemeProvider } from '@mui/material/styles'; - -export function MockTheme({ children }: any) { - const theme = React.useMemo( - () => - // Map our color palette config (stored in redux) to the mui 5 format - createTheme({}), - [] - ); - - return <ThemeProvider theme={theme}>{children}</ThemeProvider>; -} - -export function MockThemeGraphPolaris({ children }: any) { - const theme = React.useMemo( - () => - // Map our color palette config (stored in redux) to the mui 5 format - createTheme({}), - [] - ); - - return <ThemeProvider theme={theme}>{children}</ThemeProvider>; -} diff --git a/libs/shared/lib/graph-layout/cytoscape-layouts.ts b/libs/shared/lib/graph-layout/cytoscape-layouts.ts index 7b0fe6945d9501d8ff42a2d8bd24ab32826eaa2a..50267d6b9e316002349de9bf42d419713a622fec 100644 --- a/libs/shared/lib/graph-layout/cytoscape-layouts.ts +++ b/libs/shared/lib/graph-layout/cytoscape-layouts.ts @@ -137,20 +137,9 @@ export abstract class Cytoscape extends Layout<CytoscapeProvider> { selector: 'node', style: { label: 'data(id)', - width: (node: any) => { - const ctx = document.createElement('canvas').getContext('2d'); - const fStyle = node.pstyle('font-style').strValue; - const size = node.pstyle('font-size').pfValue + 'px'; - const family = node.pstyle('font-family').strValue; - const weight = node.pstyle('font-weight').strValue; - - // const padding = node.pstyle('padding-left').; - - ctx!.font = fStyle + ' ' + weight + ' ' + size + ' ' + family; - return ctx!.measureText(node.data('id')).width; - }, - height: '15px', - shape: 'round-rectangle', + width: '150px', + height: '50px', + shape: 'rectangle', 'background-color': '#fff', 'text-valign': 'center', color: '#333333', @@ -234,7 +223,12 @@ class CytoscapeKlay extends Cytoscape { const layout = cy.layout({ name: 'klay', - + padding: 40, + klay: { + borderSpacing: 40, + aspectRatio: 0.5, + compactComponents: true, + }, nodeDimensionsIncludeLabels: true, // Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h } diff --git a/libs/shared/lib/mock-data/schema/mock-data.spec.ts b/libs/shared/lib/mock-data/schema/mock-data.spec.ts index 3f041e343257e269da6162ea8cc22d01d63c8584..0817e82dfd753d82394c4adcaae37e8746b24ed7 100644 --- a/libs/shared/lib/mock-data/schema/mock-data.spec.ts +++ b/libs/shared/lib/mock-data/schema/mock-data.spec.ts @@ -1,6 +1,5 @@ import { assert, describe, expect, it, test } from 'vitest'; -import Graph from 'graphology'; import { movieSchemaRaw, movieSchema } from '..'; import { northWindSchema, northwindSchemaRaw } from '..'; import { simpleSchema, simpleSchemaRaw } from '..'; diff --git a/libs/shared/lib/querybuilder/model/graphology/utils.ts b/libs/shared/lib/querybuilder/model/graphology/utils.ts index 5da3f1cd3861eb71913ab41f24e5c48eeeaca88c..a629f8d1cca26b087386ed1aea4195345ebc3e3d 100644 --- a/libs/shared/lib/querybuilder/model/graphology/utils.ts +++ b/libs/shared/lib/querybuilder/model/graphology/utils.ts @@ -93,7 +93,7 @@ export class QueryMultiGraphology extends Graph<QueryGraphNodes, QueryGraphEdges } // Add a node to the graphology object - const nodeId = this.addNode(attributes.id, { ...attributes }); + this.addNode(attributes.id, { ...attributes }); // Set the new nodes in the query builder slice TODO: maybe remove for efficiency // dispatch(setQuerybuilderNodes(this.export())); // Can't do this due to loop import @@ -118,7 +118,7 @@ export class QueryMultiGraphology extends Graph<QueryGraphNodes, QueryGraphEdges } else throw Error('using wrong function! use addPill2Graphology instead'); // Add a node to the graphology object - const nodeId = this.addNode(attributes.id, { ...attributes }); + this.addNode(attributes.id, { ...attributes }); // Set the new nodes in the query builder slice TODO: maybe remove for efficiency // dispatch(setQuerybuilderNodes(this.export())); // Can't do this due to loop import diff --git a/libs/shared/lib/querybuilder/model/logic/general.ts b/libs/shared/lib/querybuilder/model/logic/general.ts index 7963d68accbba848401df7ecbb36169e9d4835a5..9d233739336f3d4c2a9eac8ff3455d875150fc59 100644 --- a/libs/shared/lib/querybuilder/model/logic/general.ts +++ b/libs/shared/lib/querybuilder/model/logic/general.ts @@ -1,7 +1,7 @@ export type InputNodeTypeTypes = string | number | boolean; export type InputNodeType = 'string' | 'float' | 'int' | 'bool' | 'date' | 'time' | 'datetime' | 'duration'; -export enum MathFilterTypes { +export enum NumberFilterTypes { EQUAL = '==', NOT_EQUAL = '!=', GREATER_THAN = '>', @@ -10,7 +10,7 @@ export enum MathFilterTypes { LESS_THAN_EQUAL = '<=', } -export enum MathAggregationTypes { +export enum NumberAggregationTypes { AVG = 'Avg', COUNT = 'Count', MAX = 'Max', @@ -18,7 +18,7 @@ export enum MathAggregationTypes { SUM = 'Sum', } -export enum MathFunctionTypes { +export enum NumberFunctionTypes { ADD = '+', SUBTRACT = '-', MULTIPLY = '*', @@ -202,4 +202,5 @@ export interface GeneralDescription<T> { output: OutputNode; key: string; logic: AllLogicStatement; + icon?: string; } diff --git a/libs/shared/lib/querybuilder/model/logic/index.ts b/libs/shared/lib/querybuilder/model/logic/index.ts index 00f4dfeff9c0e16898eec9ed21875671f9cac1b7..01d4062551732c0ae3a205cdc488389445e92b48 100644 --- a/libs/shared/lib/querybuilder/model/logic/index.ts +++ b/libs/shared/lib/querybuilder/model/logic/index.ts @@ -1,31 +1,31 @@ import { GeneralDescription, InputNodeType, - MathFunctionTypes, - MathFilterTypes, + NumberFunctionTypes, + NumberFilterTypes, StringFilterTypes, StringFunctionTypes, - MathAggregationTypes, + NumberAggregationTypes, } from './general'; -import { MathAggregations } from './mathAggregations'; -import { MathFilters } from './mathFilters'; -import { MathFunctions } from './mathFunctions'; +import { MathAggregations } from './numberAggregations'; +import { MathFilters } from './numberFilters'; +import { NumberFunctions } from './numberFunctions'; import { StringFilters } from './stringFilters'; import { StringFunctions } from './stringFunctions'; -export type AllLogicTypes = MathFilterTypes | MathFunctionTypes | MathAggregationTypes | StringFilterTypes | StringFunctionTypes; +export type AllLogicTypes = NumberFilterTypes | NumberFunctionTypes | NumberAggregationTypes | StringFilterTypes | StringFunctionTypes; export type AllLogicDescriptions = GeneralDescription<AllLogicTypes>; export const AllLogicMap: Record<string, AllLogicDescriptions> = { ...Object.fromEntries(Object.values(MathFilters).map((x) => [x.key, x])), - ...Object.fromEntries(Object.values(MathFunctions).map((x) => [x.key, x])), + ...Object.fromEntries(Object.values(NumberFunctions).map((x) => [x.key, x])), ...Object.fromEntries(Object.values(MathAggregations).map((x) => [x.key, x])), ...Object.fromEntries(Object.values(StringFilters).map((x) => [x.key, x])), ...Object.fromEntries(Object.values(StringFunctions).map((x) => [x.key, x])), }; export * from './graphFunctions'; -export * from './mathFunctions'; -export * from './mathFilters'; +export * from './numberFunctions'; +export * from './numberFilters'; export * from './stringFunctions'; export * from './stringFilters'; diff --git a/libs/shared/lib/querybuilder/model/logic/mathAggregations.tsx b/libs/shared/lib/querybuilder/model/logic/numberAggregations.tsx similarity index 86% rename from libs/shared/lib/querybuilder/model/logic/mathAggregations.tsx rename to libs/shared/lib/querybuilder/model/logic/numberAggregations.tsx index 5baebb3b616deeca5186e454d524bc2f07fa6e3e..32c5604b04285891c5779915e5132ae15d59f86c 100644 --- a/libs/shared/lib/querybuilder/model/logic/mathAggregations.tsx +++ b/libs/shared/lib/querybuilder/model/logic/numberAggregations.tsx @@ -5,23 +5,23 @@ */ import { Position } from 'reactflow'; -import { GeneralDescription, MathAggregationTypes } from './general'; +import { GeneralDescription, NumberAggregationTypes } from './general'; -export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<MathAggregationTypes>> = { - [MathAggregationTypes.AVG]: { - key: 'mathFunctionAvg', +export const MathAggregations: Record<NumberAggregationTypes, GeneralDescription<NumberAggregationTypes>> = { + [NumberAggregationTypes.AVG]: { + key: 'numberAggregationAvg', name: 'Average', - type: MathAggregationTypes.AVG, + type: NumberAggregationTypes.AVG, description: 'Average of all values', numInputs: 1, inputs: [{ name: '1', type: 'float', default: 0 }], output: { name: 'avg', type: 'float' }, logic: ['Avg', '@1'], }, - [MathAggregationTypes.COUNT]: { - key: 'mathFunctionCount', + [NumberAggregationTypes.COUNT]: { + key: 'numberAggregationCount', name: 'Count', - type: MathAggregationTypes.COUNT, + type: NumberAggregationTypes.COUNT, description: 'Count the number of values', numInputs: 1, inputs: [{ name: '1', type: 'float', default: 0 }], @@ -29,30 +29,30 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M output: { name: 'count', type: 'float' }, logic: ['Count', '@1'], }, - [MathAggregationTypes.MAX]: { - key: 'mathFunctionMax', + [NumberAggregationTypes.MAX]: { + key: 'numberAggregationMax', name: 'Maximum', - type: MathAggregationTypes.MAX, + type: NumberAggregationTypes.MAX, description: 'Maximum of all values', numInputs: 1, inputs: [{ name: '1', type: 'float', default: 0 }], output: { name: 'max', type: 'float' }, logic: ['Max', '@1'], }, - [MathAggregationTypes.MIN]: { - key: 'mathFunctionMin', + [NumberAggregationTypes.MIN]: { + key: 'numberAggregationMin', name: 'Minimum', - type: MathAggregationTypes.MIN, + type: NumberAggregationTypes.MIN, description: 'Minimum of all values', numInputs: 1, inputs: [{ name: '1', type: 'float', default: 0 }], output: { name: 'min', type: 'float' }, logic: ['Min', '@1'], }, - [MathAggregationTypes.SUM]: { - key: 'mathFunctionSum', + [NumberAggregationTypes.SUM]: { + key: 'numberAggregationSum', name: 'Sum', - type: MathAggregationTypes.SUM, + type: NumberAggregationTypes.SUM, description: 'Sum of all values', numInputs: 1, inputs: [{ name: '1', type: 'float', default: 0 }], @@ -60,7 +60,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M logic: ['Sum', '@1'], }, // [MathAggregationTypes.STD]: { - // key: 'mathFunctionStd', + // key: 'numberAggregationStd', // name: 'Standard Deviation', // type: MathAggregationTypes.STD, // description: 'Standard deviation of all values', @@ -70,7 +70,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Std', '@1'], // }, // [MathAggregationTypes.ADD]: { - // key: 'mathFunctionAdd', + // key: 'numberAggregationAdd', // name: 'Add', // type: MathAggregationTypes.ADD, // description: 'Add two values', @@ -83,7 +83,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['+', '@1', '@2'], // }, // [MathAggregationTypes.SUBTRACT]: { - // key: 'mathFunctionSubtract', + // key: 'numberAggregationSubtract', // name: 'Subtract', // type: MathAggregationTypes.SUBTRACT, // description: 'Subtract two values', @@ -96,7 +96,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['-', '@1', '@2'], // }, // [MathAggregationTypes.MULTIPLY]: { - // key: 'mathFunctionMultiply', + // key: 'numberAggregationMultiply', // name: 'Multiply', // type: MathAggregationTypes.MULTIPLY, // description: 'Multiply two values', @@ -109,7 +109,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['*', '@1', '@2'], // }, // [MathAggregationTypes.DIVIDE]: { - // key: 'mathFunctionDivide', + // key: 'numberAggregationDivide', // name: 'Divide', // type: MathAggregationTypes.DIVIDE, // description: 'Divide two values', @@ -123,7 +123,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['/', '@1', '@2'], // }, // [MathAggregationTypes.POWER]: { - // key: 'mathFunctionPower', + // key: 'numberAggregationPower', // name: 'Power', // type: MathAggregationTypes.POWER, // description: 'Raise a value to the power of another value', @@ -136,7 +136,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['^', '@1', '@2'], // }, // [MathAggregationTypes.SQRT]: { - // key: 'mathFunctionSqrt', + // key: 'numberAggregationSqrt', // name: 'Square Root', // type: MathAggregationTypes.SQRT, // description: 'Square root of a value', @@ -146,7 +146,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Sqrt', '@1'], // }, // [MathAggregationTypes.LOG]: { - // key: 'mathFunctionLog', + // key: 'numberAggregationLog', // name: 'Logarithm', // type: MathAggregationTypes.LOG, // description: 'Logarithm of a value', @@ -156,7 +156,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Log', '@1'], // }, // [MathAggregationTypes.EXP]: { - // key: 'mathFunctionExp', + // key: 'numberAggregationExp', // name: 'Exponential', // type: MathAggregationTypes.EXP, // description: 'Exponential of a value', @@ -166,7 +166,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Exp', '@1'], // }, // [MathAggregationTypes.ABS]: { - // key: 'mathFunctionAbs', + // key: 'numberAggregationAbs', // name: 'Absolute Value', // type: MathAggregationTypes.ABS, // description: 'Absolute value of a value', @@ -176,7 +176,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Abs', '@1'], // }, // [MathAggregationTypes.CEIL]: { - // key: 'mathFunctionCeil', + // key: 'numberAggregationCeil', // name: 'Ceiling', // type: MathAggregationTypes.CEIL, // description: 'Ceiling of a value', @@ -186,7 +186,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Ceil', '@1'], // }, // [MathAggregationTypes.FLOOR]: { - // key: 'mathFunctionFloor', + // key: 'numberAggregationFloor', // name: 'Floor', // type: MathAggregationTypes.FLOOR, // description: 'Floor of a value', @@ -196,7 +196,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Floor', '@1'], // }, // [MathAggregationTypes.ROUND]: { - // key: 'mathFunctionRound', + // key: 'numberAggregationRound', // name: 'Round', // type: MathAggregationTypes.ROUND, // description: 'Round a value to the nearest integer', @@ -206,7 +206,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Round', '@1'], // }, // [MathAggregationTypes.TRUNC]: { - // key: 'mathFunctionTrunc', + // key: 'numberAggregationTrunc', // name: 'Truncate', // type: MathAggregationTypes.TRUNC, // description: 'Truncate a value to the nearest integer towards zero', @@ -217,7 +217,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Trunc', '@1'], // }, // [MathAggregationTypes.RANDOM]: { - // key: 'mathFunctionRandom', + // key: 'numberAggregationRandom', // name: 'Random', // type: MathAggregationTypes.RANDOM, // description: 'Random value between 0 and 1', @@ -227,7 +227,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Random'], // }, // [MathAggregationTypes.RANDOMINT]: { - // key: 'mathFunctionRandomInt', + // key: 'numberAggregationRandomInt', // name: 'Random Integer', // type: MathAggregationTypes.RANDOMINT, // description: 'Random integer between two values', @@ -240,7 +240,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['RandomInt', '@1', '@2'], // }, // [MathAggregationTypes.SIN]: { - // key: 'mathFunctionSin', + // key: 'numberAggregationSin', // name: 'Sine', // type: MathAggregationTypes.SIN, // description: 'Sine of a value', @@ -250,7 +250,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Sin', '@1'], // }, // [MathAggregationTypes.COS]: { - // key: 'mathFunctionCos', + // key: 'numberAggregationCos', // name: 'Cosine', // type: MathAggregationTypes.COS, // description: 'Cosine of a value', @@ -260,7 +260,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Cos', '@1'], // }, // [MathAggregationTypes.TAN]: { - // key: 'mathFunctionTan', + // key: 'numberAggregationTan', // name: 'Tangent', // type: MathAggregationTypes.TAN, // description: 'Tangent of a value', @@ -270,7 +270,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Tan', '@1'], // }, // [MathAggregationTypes.ASIN]: { - // key: 'mathFunctionAsin', + // key: 'numberAggregationAsin', // name: 'Arcsine', // type: MathAggregationTypes.ASIN, // description: 'Arcsine of a value', @@ -280,7 +280,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Asin', '@1'], // }, // [MathAggregationTypes.ACOS]: { - // key: 'mathFunctionAcos', + // key: 'numberAggregationAcos', // name: 'Arccosine', // type: MathAggregationTypes.ACOS, // description: 'Arccosine of a value', @@ -290,7 +290,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Acos', '@1'], // }, // [MathAggregationTypes.ATAN]: { - // key: 'mathFunctionAtan', + // key: 'numberAggregationAtan', // name: 'Arctangent', // type: MathAggregationTypes.ATAN, // description: 'Arctangent of a value', @@ -300,7 +300,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Atan', '@1'], // }, // [MathAggregationTypes.SINH]: { - // key: 'mathFunctionSinh', + // key: 'numberAggregationSinh', // name: 'Hyperbolic Sine', // type: MathAggregationTypes.SINH, // description: 'Hyperbolic sine of a value', @@ -310,7 +310,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Sinh', '@1'], // }, // [MathAggregationTypes.COSH]: { - // key: 'mathFunctionCosh', + // key: 'numberAggregationCosh', // name: 'Hyperbolic Cosine', // type: MathAggregationTypes.COSH, // description: 'Hyperbolic cosine of a value', @@ -320,7 +320,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Cosh', '@1'], // }, // [MathAggregationTypes.TANH]: { - // key: 'mathFunctionTanh', + // key: 'numberAggregationTanh', // name: 'Hyperbolic Tangent', // type: MathAggregationTypes.TANH, // description: 'Hyperbolic tangent of a value', @@ -330,7 +330,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Tanh', '@1'], // }, // [MathAggregationTypes.ASINH]: { - // key: 'mathFunctionAsinh', + // key: 'numberAggregationAsinh', // name: 'Hyperbolic Arcsine', // type: MathAggregationTypes.ASINH, // description: 'Hyperbolic arcsine of a value', @@ -340,7 +340,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Asinh', '@1'], // }, // [MathAggregationTypes.ACOSH]: { - // key: 'mathFunctionAcosh', + // key: 'numberAggregationAcosh', // name: 'Hyperbolic Arccosine', // type: MathAggregationTypes.ACOSH, // description: 'Hyperbolic arccosine of a value', @@ -350,7 +350,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Acosh', '@1'], // }, // [MathAggregationTypes.ATANH]: { - // key: 'mathFunctionAtanh', + // key: 'numberAggregationAtanh', // name: 'Hyperbolic Arctangent', // type: MathAggregationTypes.ATANH, // description: 'Hyperbolic arctangent of a value', @@ -360,7 +360,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Atanh', '@1'], // }, // [MathAggregationTypes.DEGREES]: { - // key: 'mathFunctionDegrees', + // key: 'numberAggregationDegrees', // name: 'Degrees', // type: MathAggregationTypes.DEGREES, // description: 'Convert a value from radians to degrees', @@ -370,7 +370,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Degrees', '@1'], // }, // [MathAggregationTypes.RADIANS]: { - // key: 'mathFunctionRadians', + // key: 'numberAggregationRadians', // name: 'Radians', // type: MathAggregationTypes.RADIANS, // description: 'Convert a value from degrees to radians', @@ -381,7 +381,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Radians', '@1'], // }, // [MathAggregationTypes.SIGN]: { - // key: 'mathFunctionSign', + // key: 'numberAggregationSign', // name: 'Sign', // type: MathAggregationTypes.SIGN, // description: 'Sign of a value', @@ -391,7 +391,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Sign', '@1'], // }, // [MathAggregationTypes.RANDOMNORMAL]: { - // key: 'mathFunctionRandomNormal', + // key: 'numberAggregationRandomNormal', // name: 'Random Normal', // type: MathAggregationTypes.RANDOMNORMAL, // description: 'Random value from a normal distribution', @@ -404,7 +404,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['RandomNormal', '@1', '@2'], // }, // [MathAggregationTypes.RANDOMLOGNORMAL]: { - // key: 'mathFunctionRandomLogNormal', + // key: 'numberAggregationRandomLogNormal', // name: 'Random Log Normal', // type: MathAggregationTypes.RANDOMLOGNORMAL, // description: 'Random value from a log normal distribution', @@ -417,7 +417,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['RandomLogNormal', '@1', '@2'], // }, // [MathAggregationTypes.RANDOMEXPONENTIAL]: { - // key: 'mathFunctionRandomExponential', + // key: 'numberAggregationRandomExponential', // name: 'Random Exponential', // type: MathAggregationTypes.RANDOMEXPONENTIAL, // description: 'Random value from an exponential distribution', @@ -427,7 +427,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['RandomExponential', '@1'], // }, // [MathAggregationTypes.RANDOMGAMMA]: { - // key: 'mathFunctionRandomGamma', + // key: 'numberAggregationRandomGamma', // name: 'Random Gamma', // type: MathAggregationTypes.RANDOMGAMMA, // description: 'Random value from a gamma distribution', @@ -440,7 +440,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['RandomGamma', '@1', '@2'], // }, // [MathAggregationTypes.RANDOMBETA]: { - // key: 'mathFunctionRandomBeta', + // key: 'numberAggregationRandomBeta', // name: 'Random Beta', // type: MathAggregationTypes.RANDOMBETA, // description: 'Random value from a beta distribution', @@ -453,7 +453,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['RandomBeta', '@1', '@2'], // }, // [MathAggregationTypes.RANDOMCHISQUARE]: { - // key: 'mathFunctionRandomChiSquare', + // key: 'numberAggregationRandomChiSquare', // name: 'Random Chi Square', // type: MathAggregationTypes.RANDOMCHISQUARE, // description: 'Random value from a chi square distribution', @@ -463,7 +463,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['RandomChiSquare', '@1'], // }, // [MathAggregationTypes.RANDOMWEIBULL]: { - // key: 'mathFunctionRandomWeibull', + // key: 'numberAggregationRandomWeibull', // name: 'Random Weibull', // type: MathAggregationTypes.RANDOMWEIBULL, // description: 'Random value from a Weibull distribution', @@ -476,7 +476,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['RandomWeibull', '@1', '@2'], // }, // [MathAggregationTypes.RANDOMCAUCHY]: { - // key: 'mathFunctionRandomCauchy', + // key: 'numberAggregationRandomCauchy', // name: 'Random Cauchy', // type: MathAggregationTypes.RANDOMCAUCHY, // description: 'Random value from a Cauchy distribution', @@ -489,7 +489,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['RandomCauchy', '@1', '@2'], // }, // [MathAggregationTypes.RANDOMPOISSON]: { - // key: 'mathFunctionRandomPoisson', + // key: 'numberAggregationRandomPoisson', // name: 'Random Poisson', // type: MathAggregationTypes.RANDOMPOISSON, // description: 'Random value from a Poisson distribution', @@ -499,7 +499,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['RandomPoisson', '@1'], // }, // [MathAggregationTypes.RANDOMIRWINHALL]: { - // key: 'mathFunctionRandomIrwinHall', + // key: 'numberAggregationRandomIrwinHall', // name: 'Random Irwin Hall', // type: MathAggregationTypes.RANDOMIRWINHALL, // description: 'Random value from an Irwin Hall distribution', @@ -512,7 +512,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['RandomIrwinHall', '@1', '@2'], // }, // [MathAggregationTypes.CHIQUARETEST]: { - // key: 'mathFunctionChiSquareTest', + // key: 'numberAggregationChiSquareTest', // name: 'Chi Square Test', // type: MathAggregationTypes.CHIQUARETEST, // description: 'Chi square test', @@ -525,7 +525,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['ChiSquareTest', '@1', '@2'], // }, // [MathAggregationTypes.CORRELATION]: { - // key: 'mathFunctionCorrelation', + // key: 'numberAggregationCorrelation', // name: 'Correlation', // type: MathAggregationTypes.CORRELATION, // description: 'Correlation between two values', @@ -538,7 +538,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Correlation', '@1', '@2'], // }, // [MathAggregationTypes.COVARIANCE]: { - // key: 'mathFunctionCovariance', + // key: 'numberAggregationCovariance', // name: 'Covariance', // type: MathAggregationTypes.COVARIANCE, // description: 'Covariance between two values', @@ -551,7 +551,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Covariance', '@1', '@2'], // }, // [MathAggregationTypes.FREQUENCY]: { - // key: 'mathFunctionFrequency', + // key: 'numberAggregationFrequency', // name: 'Frequency', // type: MathAggregationTypes.FREQUENCY, // description: 'Frequency of a value in a dataset', @@ -564,7 +564,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Frequency', '@1', '@2'], // }, // [MathAggregationTypes.MEAN]: { - // key: 'mathFunctionMean', + // key: 'numberAggregationMean', // name: 'Mean', // type: MathAggregationTypes.MEAN, // description: 'Mean of a dataset', @@ -574,7 +574,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Mean', '@1'], // }, // [MathAggregationTypes.MEDIAN]: { - // key: 'mathFunctionMedian', + // key: 'numberAggregationMedian', // name: 'Median', // type: MathAggregationTypes.MEDIAN, // description: 'Median of a dataset', @@ -584,7 +584,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Median', '@1'], // }, // [MathAggregationTypes.MODE]: { - // key: 'mathFunctionMode', + // key: 'numberAggregationMode', // name: 'Mode', // type: MathAggregationTypes.MODE, // description: 'Mode of a dataset', @@ -594,7 +594,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Mode', '@1'], // }, // [MathAggregationTypes.RANK]: { - // key: 'mathFunctionRank', + // key: 'numberAggregationRank', // name: 'Rank', // type: MathAggregationTypes.RANK, // description: 'Rank of a value in a dataset', @@ -607,7 +607,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Rank', '@1', '@2'], // }, // [MathAggregationTypes.STDEV]: { - // key: 'mathFunctionStdev', + // key: 'numberAggregationStdev', // name: 'Standard Deviation', // type: MathAggregationTypes.STDEV, // description: 'Standard deviation of a dataset', @@ -617,7 +617,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Stdev', '@1'], // }, // [MathAggregationTypes.VARIANCE]: { - // key: 'mathFunctionVariance', + // key: 'numberAggregationVariance', // name: 'Variance', // type: MathAggregationTypes.VARIANCE, // description: 'Variance of a dataset', @@ -627,7 +627,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Variance', '@1'], // }, // [MathAggregationTypes.ZSCORE]: { - // key: 'mathFunctionZscore', + // key: 'numberAggregationZscore', // name: 'Z-Score', // type: MathAggregationTypes.ZSCORE, // description: 'Z-score of a value in a dataset', @@ -640,7 +640,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Zscore', '@1', '@2'], // }, // [MathAggregationTypes.AND]: { - // key: 'mathFunctionAnd', + // key: 'numberAggregationAnd', // name: 'And', // type: MathAggregationTypes.AND, // description: 'Logical AND of two values', @@ -653,7 +653,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['And', '@1', '@2'], // }, // [MathAggregationTypes.OR]: { - // key: 'mathFunctionOr', + // key: 'numberAggregationOr', // name: 'Or', // type: MathAggregationTypes.OR, // description: 'Logical OR of two values', @@ -666,7 +666,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Or', '@1', '@2'], // }, // [MathAggregationTypes.NOT]: { - // key: 'mathFunctionNot', + // key: 'numberAggregationNot', // name: 'Not', // type: MathAggregationTypes.NOT, // description: 'Logical NOT of a value', @@ -677,7 +677,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // }, // { - // key: 'mathFunctionCount', + // key: 'numberAggregationCount', // name: 'Count', // type: MathAggregationTypes.COUNT, // description: 'Count the number of values', @@ -687,7 +687,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Count', '@1'], // }, // { - // key: 'mathFunctionMax', + // key: 'numberAggregationMax', // name: 'Maximum', // type: MathAggregationTypes.MAX, // description: 'Maximum of all values', @@ -697,7 +697,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Max', '@1'], // }, // { - // key: 'mathFunctionMin', + // key: 'numberAggregationMin', // name: 'Minimum', // type: MathAggregationTypes.MIN, // description: 'Minimum of all values', @@ -707,7 +707,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Min', '@1'], // }, // { - // key: 'mathFunctionSum', + // key: 'numberAggregationSum', // name: 'Sum', // type: MathAggregationTypes.SUM, // description: 'Sum of all values', @@ -717,7 +717,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // logic: ['Sum', '@1'], // }, // // { - // // key: 'mathFunctionStd', + // // key: 'numberAggregationStd', // // name: 'Standard Deviation', // // type: MathAggregationTypes.STD, // // description: 'Standard deviation of all values', @@ -727,7 +727,7 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // // logic: ['Std', '@1'], // // }, // { - // key: 'mathFunctionAdd', + // key: 'numberAggregationAdd', // name: 'Add', // type: MathAggregationTypes.ADD, // description: 'Add two values', @@ -741,5 +741,5 @@ export const MathAggregations: Record<MathAggregationTypes, GeneralDescription<M // }, }; -/** All available functions in the function bar. */ -export const MathAggregationArray: Array<GeneralDescription<MathAggregationTypes>> = Object.values(MathAggregations); +/** All available Aggregations in the Aggregation bar. */ +export const MathAggregationArray: Array<GeneralDescription<NumberAggregationTypes>> = Object.values(MathAggregations); diff --git a/libs/shared/lib/querybuilder/model/logic/mathFilters.tsx b/libs/shared/lib/querybuilder/model/logic/numberFilters.tsx similarity index 66% rename from libs/shared/lib/querybuilder/model/logic/mathFilters.tsx rename to libs/shared/lib/querybuilder/model/logic/numberFilters.tsx index 0c235dd780eddf0da0e5f0f2f62d3ad494cd9396..b54336f44ca2630023894dd9e27aec93d926d1ea 100644 --- a/libs/shared/lib/querybuilder/model/logic/mathFilters.tsx +++ b/libs/shared/lib/querybuilder/model/logic/numberFilters.tsx @@ -5,13 +5,13 @@ */ import { Position } from 'reactflow'; -import { GeneralDescription, InputNode, MathFilterTypes } from './general'; +import { GeneralDescription, InputNode, NumberFilterTypes } from './general'; -export const MathFilters: Record<MathFilterTypes, GeneralDescription<MathFilterTypes>> = { - [MathFilterTypes.EQUAL]: { - key: 'mathFilterEqual', +export const MathFilters: Record<NumberFilterTypes, GeneralDescription<NumberFilterTypes>> = { + [NumberFilterTypes.EQUAL]: { + key: 'numberFilterEqual', name: 'Equal', - type: MathFilterTypes.EQUAL, + type: NumberFilterTypes.EQUAL, description: 'Equal to another value', numInputs: 2, inputs: [ @@ -20,11 +20,12 @@ export const MathFilters: Record<MathFilterTypes, GeneralDescription<MathFilterT ], output: { name: '==', type: 'float' }, logic: ['==', '@1', '@2'], + icon: '=', }, - [MathFilterTypes.NOT_EQUAL]: { - key: 'mathFilterNotEqual', + [NumberFilterTypes.NOT_EQUAL]: { + key: 'numberFilterNotEqual', name: 'Not Equal', - type: MathFilterTypes.NOT_EQUAL, + type: NumberFilterTypes.NOT_EQUAL, description: 'Not equal to another value', numInputs: 2, inputs: [ @@ -33,11 +34,12 @@ export const MathFilters: Record<MathFilterTypes, GeneralDescription<MathFilterT ], output: { name: '!=', type: 'float' }, logic: ['!=', '@1', '@2'], + icon: '≠', }, - [MathFilterTypes.LESS_THAN]: { - key: 'mathFilterLessThan', + [NumberFilterTypes.LESS_THAN]: { + key: 'numberFilterLessThan', name: 'Less Than', - type: MathFilterTypes.LESS_THAN, + type: NumberFilterTypes.LESS_THAN, description: 'Less than another value', numInputs: 2, inputs: [ @@ -46,11 +48,12 @@ export const MathFilters: Record<MathFilterTypes, GeneralDescription<MathFilterT ], output: { name: '<', type: 'float' }, logic: ['<', '@1', '@2'], + icon: '<', }, - [MathFilterTypes.LESS_THAN_EQUAL]: { - key: 'mathFilterLessThanOrEqual', + [NumberFilterTypes.LESS_THAN_EQUAL]: { + key: 'numberFilterLessThanOrEqual', name: 'Less Than or Equal', - type: MathFilterTypes.LESS_THAN_EQUAL, + type: NumberFilterTypes.LESS_THAN_EQUAL, description: 'Less than or equal to another value', numInputs: 2, inputs: [ @@ -59,11 +62,12 @@ export const MathFilters: Record<MathFilterTypes, GeneralDescription<MathFilterT ], output: { name: '<=', type: 'float' }, logic: ['<=', '@1', '@2'], + icon: '≤', }, - [MathFilterTypes.GREATER_THAN]: { - key: 'mathFilterGreaterThan', + [NumberFilterTypes.GREATER_THAN]: { + key: 'numberFilterGreaterThan', name: 'Greater Than', - type: MathFilterTypes.GREATER_THAN, + type: NumberFilterTypes.GREATER_THAN, description: 'Greater than another value', numInputs: 2, @@ -73,11 +77,12 @@ export const MathFilters: Record<MathFilterTypes, GeneralDescription<MathFilterT ], output: { name: '>', type: 'float' }, logic: ['>', '@1', '@2'], + icon: '>', }, - [MathFilterTypes.GREATER_THAN_EQUAL]: { - key: 'mathFilterGreaterThanOrEqual', + [NumberFilterTypes.GREATER_THAN_EQUAL]: { + key: 'numberFilterGreaterThanOrEqual', name: 'Greater Than or Equal', - type: MathFilterTypes.GREATER_THAN_EQUAL, + type: NumberFilterTypes.GREATER_THAN_EQUAL, description: 'Greater than or equal to another value', numInputs: 2, inputs: [ @@ -86,8 +91,9 @@ export const MathFilters: Record<MathFilterTypes, GeneralDescription<MathFilterT ], output: { name: '>=', type: 'float' }, logic: ['>=', '@1', '@2'], + icon: '≥', }, }; /** All available functions in the function bar. */ -export const MathFilterArray: Array<GeneralDescription<MathFilterTypes>> = Object.values(MathFilters); +export const MathFilterArray: Array<GeneralDescription<NumberFilterTypes>> = Object.values(MathFilters); diff --git a/libs/shared/lib/querybuilder/model/logic/mathFunctions.tsx b/libs/shared/lib/querybuilder/model/logic/numberFunctions.tsx similarity index 64% rename from libs/shared/lib/querybuilder/model/logic/mathFunctions.tsx rename to libs/shared/lib/querybuilder/model/logic/numberFunctions.tsx index 5375664aa5ef832c5ca60840f7e5c829d526c67f..25d6c689954b5c226413004e50dcd8c3b98d2d70 100644 --- a/libs/shared/lib/querybuilder/model/logic/mathFunctions.tsx +++ b/libs/shared/lib/querybuilder/model/logic/numberFunctions.tsx @@ -5,13 +5,13 @@ */ import { Position } from 'reactflow'; -import { GeneralDescription, MathFunctionTypes } from './general'; +import { GeneralDescription, NumberFunctionTypes } from './general'; -export const MathFunctions: Record<MathFunctionTypes, GeneralDescription<MathFunctionTypes>> = { - [MathFunctionTypes.ADD]: { - key: 'mathFunctionAdd', +export const NumberFunctions: Record<NumberFunctionTypes, GeneralDescription<NumberFunctionTypes>> = { + [NumberFunctionTypes.ADD]: { + key: 'numberFunctionAdd', name: 'Add', - type: MathFunctionTypes.ADD, + type: NumberFunctionTypes.ADD, description: 'Add two values', numInputs: 2, inputs: [ @@ -20,11 +20,12 @@ export const MathFunctions: Record<MathFunctionTypes, GeneralDescription<MathFun ], output: { name: '+', type: 'float' }, logic: ['+', '@1', '@2'], + icon: '+', }, - [MathFunctionTypes.SUBTRACT]: { - key: 'mathFunctionSubtract', + [NumberFunctionTypes.SUBTRACT]: { + key: 'numberFunctionSubtract', name: 'Subtract', - type: MathFunctionTypes.SUBTRACT, + type: NumberFunctionTypes.SUBTRACT, description: 'Subtract two values', numInputs: 2, inputs: [ @@ -33,11 +34,12 @@ export const MathFunctions: Record<MathFunctionTypes, GeneralDescription<MathFun ], output: { name: '-', type: 'float' }, logic: ['-', '@1', '@2'], + icon: '-', }, - [MathFunctionTypes.MULTIPLY]: { - key: 'mathFunctionMultiply', + [NumberFunctionTypes.MULTIPLY]: { + key: 'numberFunctionMultiply', name: 'Multiply', - type: MathFunctionTypes.MULTIPLY, + type: NumberFunctionTypes.MULTIPLY, description: 'Multiply two values', numInputs: 2, inputs: [ @@ -46,11 +48,12 @@ export const MathFunctions: Record<MathFunctionTypes, GeneralDescription<MathFun ], output: { name: '*', type: 'float' }, logic: ['*', '@1', '@2'], + icon: '×', }, - [MathFunctionTypes.DIVIDE]: { - key: 'mathFunctionDivide', + [NumberFunctionTypes.DIVIDE]: { + key: 'numberFunctionDivide', name: 'Divide', - type: MathFunctionTypes.DIVIDE, + type: NumberFunctionTypes.DIVIDE, description: 'Divide two values', numInputs: 2, @@ -60,8 +63,9 @@ export const MathFunctions: Record<MathFunctionTypes, GeneralDescription<MathFun ], output: { name: '/', type: 'float' }, logic: ['/', '@1', '@2'], + icon: '÷', }, }; /** All available functions in the function bar. */ -export const MathFunctionArray: Array<GeneralDescription<MathFunctionTypes>> = Object.values(MathFunctions); +export const MathFunctionArray: Array<GeneralDescription<NumberFunctionTypes>> = Object.values(NumberFunctions); diff --git a/libs/shared/lib/querybuilder/model/logic/utils.ts b/libs/shared/lib/querybuilder/model/logic/utils.ts deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/libs/shared/lib/querybuilder/panel/nodeUtils.ts b/libs/shared/lib/querybuilder/panel/nodeUtils.ts deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss index aa0cb37370c2c6c2e4ca011da7c348ed99e637f9..388d9f8ac08b57501d0122e01362a5a32074cbaa 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss +++ b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss @@ -29,8 +29,6 @@ } .menuText { - font-size: small; - font-family: Poppins, sans-serif; } .full { diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts index 719453220eb707f167461ba152e57d8955da8ad1..f475ca66c5f8c200d7c3f7ce8e72a6bd0f18ccf3 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts +++ b/libs/shared/lib/querybuilder/panel/querybuilder.module.scss.d.ts @@ -2,7 +2,6 @@ declare const classNames: { readonly reactflow: 'reactflow'; readonly controls: 'controls'; readonly buttons: 'buttons'; - readonly menuText: 'menuText'; readonly full: 'full'; }; export = classNames; diff --git a/libs/shared/lib/querybuilder/panel/querybuilder.tsx b/libs/shared/lib/querybuilder/panel/querybuilder.tsx index 73bc730e7caf1961e35f4613792cec44f278f851..d25ee62444aa69b0ac51ad06bf010d171100f954 100644 --- a/libs/shared/lib/querybuilder/panel/querybuilder.tsx +++ b/libs/shared/lib/querybuilder/panel/querybuilder.tsx @@ -1,92 +1,49 @@ +import React, { useCallback, useMemo, useRef, useState } from 'react'; import { setQuerybuilderNodes, - useAppDispatch, useConfig, useQuerybuilderGraph, useQuerybuilderGraphology, - useSchemaGraph, useSchemaGraphology, } from '@graphpolaris/shared/lib/data-access/store'; import ReactFlow, { - ReactFlowProvider, Background, - Node, - isNode, - ReactFlowInstance, - Controls, + Connection, ControlButton, - NodeChange, - ConnectionMode, - NodeMouseHandler, - OnConnectStartParams, - useReactFlow, + Controls, Edge, - Connection, HandleType, - XYPosition, - Position, - OnEdgesChange, + Node, + NodeChange, NodePositionChange, + OnConnectStartParams, + OnEdgesChange, + ReactFlowInstance, + ReactFlowProvider, + XYPosition, + isNode, + useReactFlow, } from 'reactflow'; import styles from './querybuilder.module.scss'; -import CachedIcon from '@mui/icons-material/Cached'; -import React, { ReactComponentElement, useMemo, useRef, useEffect, useCallback, useState, DragEventHandler } from 'react'; -import { AttributePill, ConnectionDragLine, ConnectionLine, EntityFlowElement, RelationPill } from '../pills'; -import { dragPillStarted, dragPillStopped, movePillTo } from '../pills/dragging/dragPill'; -import { Settings as SettingsIcon, Delete as DeleteIcon, ImportExport as ExportIcon } from '@mui/icons-material'; import { clearQB } from '@graphpolaris/shared/lib/data-access/store/querybuilderSlice'; -import { RelationPosToFromEntityPos, RelationPosToToEntityPos } from '@graphpolaris/shared/lib/querybuilder/model/graphology/utils'; +import { Cached as CachedIcon, Delete as DeleteIcon, ImportExport as ExportIcon, Settings as SettingsIcon } from '@mui/icons-material'; import { useDispatch } from 'react-redux'; -import { - Box, - Card, - CardContent, - Dialog, - DialogTitle, - Grid, - List, - ListItem, - ListItemButton, - ListItemText, - Paper, - PaperProps, - Tab, - Tabs, - Typography, -} from '@mui/material'; import { AllLogicDescriptions, AllLogicMap, - Handles, - MathFilters, - StringFilters, - MathFunctions, NodeAttribute, QueryElementTypes, QueryGraphNodes, - StringFunctions, createReactFlowElements, toHandleData, - QueryGraphEdgeHandle, } from '../model'; -import Draggable from 'react-draggable'; -import { GeneralDescription, InputNodeType } from '../model/logic/general'; +import { InputNodeType } from '../model/logic/general'; +import { ConnectionDragLine, ConnectionLine, EntityFlowElement, RelationPill } from '../pills'; import LogicPill from '../pills/customFlowPills/logicpill/logicpill'; -import { current } from '@reduxjs/toolkit'; -import { SchemaAttributeTypes } from '../../schema'; -import { MathAggregations } from '../model/logic/mathAggregations'; - -const nodeTypes = { - entity: EntityFlowElement, - relation: RelationPill, - logic: LogicPill, - attribute: AttributePill, -}; -const edgeTypes = { - connection: ConnectionLine, - attribute_connection: ConnectionLine, -}; +import { dragPillStarted, movePillTo } from '../pills/dragging/dragPill'; +import { QueryBuilderModal } from './querypopup'; +import { QuerySidePanel, QueryBuilderProps } from './querysidepanel'; /** * This is the main querybuilder component. It is responsible for holding all pills and fire off the visual part of the querybuilder panel logic @@ -95,6 +52,17 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { const [openPopup, setOpenPopup] = useState(false); const reactFlowWrapper = useRef<HTMLDivElement>(null); + var nodeTypes = { + entity: EntityFlowElement, + relation: RelationPill, + logic: LogicPill, + }; + + var edgeTypes = { + connection: ConnectionLine, + attribute_connection: ConnectionLine, + }; + const schema = useSchemaGraphology(); const graphologyGraph = useQuerybuilderGraphology(); const graph = useQuerybuilderGraph(); @@ -250,8 +218,6 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { break; // Creates a relation element and will also create the 2 related entities together with the connections case QueryElementTypes.Relation: - console.log('relation drop', dragData, schema.export()); - const relation = graphologyGraph.addPill2Graphology( { type: QueryElementTypes.Relation, @@ -387,7 +353,8 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { [reactFlow.project] ); - const onNewNodeFromPopup = (value: AllLogicDescriptions, type: InputNodeType) => { + const onNewNodeFromPopup = (value: AllLogicDescriptions) => { + setOpenPopup(false); if (connectingNodeId.current === null || connectingNodeId.current?.params?.handleId == null) return; const params = connectingNodeId.current.params; const position = connectingNodeId.current.position; @@ -474,10 +441,10 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { }; return ( - <div ref={reactFlowWrapper} className={styles.full}> - <PopupMenu + <div ref={reactFlowWrapper} className="h-full w-full"> + <QueryBuilderModal open={openPopup} - type={connectingNodeId.current?.attribute.handleData.attributeType || 'int'} + handle={connectingNodeId.current?.attribute.handleData} onClose={() => { setOpenPopup(false); }} @@ -515,15 +482,6 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { attributionPosition="top-right" > <Background gap={10} size={0.7} /> - {elements && elements.edges.length == 0 && elements.nodes.length == 0 && ( - <Card variant="outlined" sx={{ minWidth: 275, marginTop: 3, marginRight: 10 }}> - <CardContent> - <Typography sx={{ fontSize: 20 }} color="text.secondary"> - Drag some node from the Schema panel - </Typography> - </CardContent> - </Card> - )} <Controls showZoom={false} showInteractive={false} className={styles.controls}> <ControlButton className={styles.buttons} title={'Remove all elements'} onClick={() => clearAllNodes()}> @@ -571,206 +529,10 @@ export const QueryBuilderInner = (props: QueryBuilderProps) => { ); }; -// const math_functions = ['AVG', 'COUNT', 'MAX', 'MIN', 'SUM', 'ROUND', 'CEIL', 'FLOOR', '+', '-', '*', '/', '%', 'CUSTOM']; -// const string_functions = ['CONCAT', 'LOWER', 'UPPER', 'SUBSTRING', 'TRIM']; -// const math_filters = ['==', '!=', '>', '<', '>=', '<=']; -// const string_filters = ['==', '!=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN']; - -function PaperComponent(props: PaperProps) { - return ( - <Draggable handle="#draggable-dialog-title" cancel={'[class*="MuiDialogContent-root"]'}> - <Paper {...props} /> - </Draggable> - ); -} - -interface TabPanelProps { - children?: React.ReactNode; - index: number; - value: number; -} - -function CustomTabPanel(props: TabPanelProps) { - const { children, value, index, ...other } = props; - - return ( - <div - role="tabpanel" - hidden={value !== index} - id={`simple-tabpanel-${index}`} - aria-labelledby={`simple-tab-${index}`} - {...other} - style={{ maxHeight: '85%', overflow: 'auto' }} - > - {value === index && ( - <Box> - <Typography>{children}</Typography> - </Box> - )} - </div> - ); -} - -function PopupMenu(props: { - open: boolean; - type: InputNodeType; - onClose: () => void; - onClick: (value: AllLogicDescriptions, type: InputNodeType) => void; -}) { - const [value, setValue] = React.useState(props.type === 'string' ? 1 : 0); - - const handleChange = (event: React.SyntheticEvent, newValue: number) => { - setValue(newValue); - }; - - const handleClose = () => { - props.onClose(); - }; - - const handleListItemClick = (value: AllLogicDescriptions, type: InputNodeType) => { - props.onClick(value, type); - }; - - const generateList = (list: Record<string, AllLogicDescriptions>, type: InputNodeType) => ( - <List sx={{ pt: 0 }}> - {Object.keys(list).map((f, i) => ( - <ListItemButton onClick={() => handleListItemClick(list[f], type)} key={f + type}> - {/* <ListItemAvatar> - <Avatar sx={{ bgcolor: blue[100], color: blue[600] }}> - <PersonIcon /> - </Avatar> - </ListItemAvatar> */} - <ListItemText primary={list[f].name} secondary={list[f].description} /> - </ListItemButton> - ))} - </List> - ); - - function a11yProps(index: number) { - return { - id: `simple-tab-${index}`, - 'aria-controls': `simple-tabpanel-${index}`, - }; - } - - return ( - <Dialog onClose={handleClose} open={props.open} PaperComponent={PaperComponent}> - <DialogTitle>Add New Node</DialogTitle> - <Box> - <Box sx={{ borderBottom: 1, borderColor: 'divider' }}> - <Tabs value={value} onChange={handleChange} aria-label="basic tabs example"> - <Tab label="Aggregations" disabled={props.type === 'string'} {...a11yProps(0)} /> - <Tab label="Operations" {...a11yProps(1)} /> - <Tab label="Filters" {...a11yProps(2)} /> - </Tabs> - </Box> - <CustomTabPanel value={value} index={0}> - {props.type === 'float' && generateList(MathAggregations, props.type)} - {props.type === 'int' && generateList(MathAggregations, props.type)} - {/* {props.type === 'string' && generateList(MathAggregations, props.type)} */} - </CustomTabPanel> - <CustomTabPanel value={value} index={1}> - {props.type === 'float' && generateList(MathFunctions, props.type)} - {props.type === 'int' && generateList(MathFunctions, props.type)} - {props.type === 'string' && generateList(StringFunctions, props.type)} - </CustomTabPanel> - <CustomTabPanel value={value} index={2}> - {props.type === 'float' && generateList(MathFilters, props.type)} - {props.type === 'int' && generateList(MathFilters, props.type)} - {props.type === 'string' && generateList(StringFilters, props.type)} - </CustomTabPanel> - </Box> - </Dialog> - ); -} - -export const QueryBuilderPills = () => { - const onDragStart = (event: React.DragEvent, value: AllLogicDescriptions, nodeType: InputNodeType) => { - console.log('drag start', nodeType); - - event.dataTransfer.setData('application/reactflow', JSON.stringify({ value, nodeType })); - event.dataTransfer.effectAllowed = 'move'; - }; - - const [value, setValue] = React.useState(0); - - const handleChange = (event: React.SyntheticEvent, newValue: number) => { - setValue(newValue); - }; - - function a11yProps(index: number) { - return { - id: `simple-tab-${index}`, - 'aria-controls': `simple-tabpanel-${index}`, - }; - } - - const handleListItemClick = (value: AllLogicDescriptions, type: InputNodeType) => {}; - - // const generateList = (list: Record<string, AllLogicDescriptions>, type: InputNodeType) => ( - // <List sx={{ pt: 0 }}> - // {Object.keys(list).map((f, i) => ( - // <ListItemButton onClick={() => handleListItemClick(list[f], type)} key={f + type}> - // <ListItemText primary={list[f].name} secondary={list[f].description} /> - // </ListItemButton> - // ))} - // </List> - // ); - const generateList = (list: Record<string, AllLogicDescriptions>, type: InputNodeType) => ( - <List> - {Object.keys(list).map((f, i) => ( - <ListItem key={JSON.stringify(list[f]) + type + i}> - <ListItemText - draggable - primary={list[f].name} - secondary={list[f].description} - onDragStart={(event) => onDragStart(event, list[f], type)} - key={f + type} - /> - </ListItem> - ))} - </List> - ); - - return ( - <aside className=""> - <Box> - <Tabs value={value} onChange={handleChange} aria-label="basic tabs example"> - <Tab label="Aggregations" {...a11yProps(0)} /> - <Tab label="Operations" {...a11yProps(1)} /> - <Tab label="Filters" {...a11yProps(2)} /> - </Tabs> - </Box> - <CustomTabPanel value={value} index={0}> - {generateList(MathAggregations, 'float')} - </CustomTabPanel> - <CustomTabPanel value={value} index={1}> - {generateList(MathFunctions, 'float')} - {generateList(StringFunctions, 'string')} - </CustomTabPanel> - <CustomTabPanel value={value} index={2}> - {generateList(MathFilters, 'float')} - {generateList(StringFilters, 'string')} - </CustomTabPanel> - </aside> - ); -}; - -export type QueryBuilderProps = { - onRunQuery?: () => void; -}; - export const QueryBuilder = (props: QueryBuilderProps) => { return ( - <div - style={{ - width: '100%', - height: '22rem', - display: 'flex', - gap: '1rem', - }} - > - <QueryBuilderPills /> + <div className="flex w-full h-full"> + <QuerySidePanel title="Query Panel" draggable /> <ReactFlowProvider> <QueryBuilderInner {...props} /> </ReactFlowProvider> @@ -778,21 +540,4 @@ export const QueryBuilder = (props: QueryBuilderProps) => { ); }; -// export const QueryBuilder = () => { -// const graphologyGraph = useQuerybuilderGraphology(); -// const schema = useSchemaGraphology(); -// const graph = useQuerybuilderGraph(); -// const config = useConfig(); -// const dispatch = useDispatch(); - -// return ( -// <QueryBuilderRaw -// graphologyGraph={graphologyGraph} -// schema={schema} -// graph={graph} -// config={config} -// /> -// ); -// }; - export default QueryBuilder; diff --git a/libs/shared/lib/querybuilder/panel/querypopup.tsx b/libs/shared/lib/querybuilder/panel/querypopup.tsx new file mode 100644 index 0000000000000000000000000000000000000000..1749d96977f42603dfc96eeb43aa9c0c122ceb99 --- /dev/null +++ b/libs/shared/lib/querybuilder/panel/querypopup.tsx @@ -0,0 +1,38 @@ +import React, { useEffect } from 'react'; +import Draggable from 'react-draggable'; +import { AllLogicDescriptions, MathFilters, NumberFunctions, QueryGraphEdgeHandle, StringFilters, StringFunctions } from '../model'; +import { InputNodeType } from '../model/logic/general'; +import { QuerySidePanel } from './querysidepanel'; + +export function QueryBuilderModal(props: { + open: boolean; + handle: QueryGraphEdgeHandle | undefined; + onClose: () => void; + onClick: (item: AllLogicDescriptions) => void; +}) { + const modal = React.useRef<HTMLDialogElement>(null); + + useEffect(() => { + if (props.open) { + modal.current?.showModal(); + } else { + modal.current?.close(); + } + }, [props.open]); + + function onClose() { + props.onClose(); + } + + return ( + <dialog id="my_modal_1" className="modal " ref={modal} onClose={() => onClose()}> + <form method="dialog" className="modal-box h-auto"> + <QuerySidePanel title="Logic Pills usable by the node" filter={props.handle?.attributeType} onClick={props.onClick} /> + </form> + + <form method="dialog" className="modal-backdrop"> + <button>close</button> + </form> + </dialog> + ); +} diff --git a/libs/shared/lib/querybuilder/panel/querysidepanel.tsx b/libs/shared/lib/querybuilder/panel/querysidepanel.tsx new file mode 100644 index 0000000000000000000000000000000000000000..1ce5fc49b724d1810acc8ca591f356b46c402a6b --- /dev/null +++ b/libs/shared/lib/querybuilder/panel/querysidepanel.tsx @@ -0,0 +1,129 @@ +import React, { useState } from 'react'; +import { AllLogicDescriptions, AllLogicMap } from '../model'; +import FilterAltIcon from '@mui/icons-material/FilterAlt'; +import FunctionsIcon from '@mui/icons-material/Functions'; +import GridOnIcon from '@mui/icons-material/GridOn'; +import NumbersIcon from '@mui/icons-material/Numbers'; +import AbcIcon from '@mui/icons-material/Abc'; + +export const QuerySidePanel = (props: { + title: string; + filter?: string; + draggable?: boolean; + onClick?: (item: AllLogicDescriptions) => void; +}) => { + const dataOps = [ + { + title: 'aggregation', + description: 'Aggregation Functions', + icon: <GridOnIcon fontSize="small" />, + }, + { + title: 'function', + description: 'Math Functions', + icon: <FunctionsIcon fontSize="small" />, + }, + { + title: 'filter', + description: 'Filter Functions', + icon: <FilterAltIcon fontSize="small" />, + }, + ]; + const dataTypes = [ + { + title: 'number', + description: 'Number', + icon: <NumbersIcon fontSize="small" />, + }, + { + title: 'string', + description: 'Text', + icon: <AbcIcon fontSize="small" />, + }, + ]; + + const filter = props.filter === 'number' ? 'float' : props.filter; + const [selectedOp, setSelectedOp] = useState(dataOps.findIndex((item) => item.title === filter) || -1); + const [selectedType, setSelectedType] = useState(dataTypes.findIndex((item) => item.title === filter) || -1); + + const onDragStart = (event: React.DragEvent, value: AllLogicDescriptions) => { + console.log('drag start'); + + event.dataTransfer.setData('application/reactflow', JSON.stringify({ value })); + event.dataTransfer.effectAllowed = 'move'; + }; + + return ( + <div className="bg-offwhite-100 h-flex flex flex-col gap-2"> + <h2 className="menu-title">{props.title}</h2> + <div className="btn-group w-full justify-center"> + {dataOps.map((item, index) => ( + <div key={item.title} data-tip={item.description} className="tooltip tooltip-top m-0 p-0"> + <button + className={'btn btn-sm ' + (selectedOp === index ? 'btn-active' : '')} + onClick={(e) => { + e.preventDefault(); + index === selectedOp ? setSelectedOp(-1) : setSelectedOp(index); + }} + > + {item.icon} + </button> + </div> + ))} + <div className="w-2" /> + {dataTypes.map((item, index) => ( + <div key={item.title} data-tip={item.description} className=" tooltip tooltip-top m-0 p-0"> + <button + className={'btn btn-sm block ' + (selectedType === index ? 'btn-active' : '')} + onClick={(e) => { + e.preventDefault(); + index === selectedType ? setSelectedType(-1) : setSelectedType(index); + }} + > + {item.icon} + </button> + </div> + ))} + </div> + <div className="overflow-x-hidden flex-shrink flex-grow-0 w-full"> + <ul className="menu bg-base-200 p-0 [&_li>*]:rounded-none h-full w-full"> + {Object.values(AllLogicMap) + .filter((item) => !filter || item.key.toLowerCase().includes(filter === 'number' ? 'float' : 'string')) + .filter((item) => selectedOp === -1 || item.key.toLowerCase().includes(dataOps?.[selectedOp].title)) + .filter((item) => selectedType === -1 || item.key.toLowerCase().includes(dataTypes?.[selectedType].title)) + .map((item, index) => ( + <li key={item.key + item.description} className="h-fit"> + <span + data-tip={item.description} + className="flex before:w-[10rem] before:text-center tooltip tooltip-bottom text-start " + onDragStart={(e) => onDragStart(e, item)} + draggable={props.draggable} + onClick={() => { + if (!props.draggable && props?.onClick) props.onClick(item); + }} + > + {item.icon && ( + <div className="w-[1rem] rounded-sm justify-center flex"> + <span>{item.icon}</span> + </div> + )} + <span className="w-full">{item.name}</span> + <span className="flex scale-75"> + {item.key.toLowerCase().includes('filter') && <FilterAltIcon fontSize="small" />} + {item.key.toLowerCase().includes('function') && <FunctionsIcon fontSize="small" />} + {item.key.toLowerCase().includes('aggregation') && <GridOnIcon fontSize="small" />} + {item.key.toLowerCase().includes('number') && <NumbersIcon fontSize="small" />} + {item.key.toLowerCase().includes('string') && <AbcIcon fontSize="small" />} + </span> + </span> + </li> + ))} + </ul> + </div> + </div> + ); +}; + +export type QueryBuilderProps = { + onRunQuery?: () => void; +}; diff --git a/libs/shared/lib/querybuilder/panel/shemaquerybuilder.stories.tsx b/libs/shared/lib/querybuilder/panel/shemaquerybuilder.stories.tsx index f0ee5ed0d98e4e529b9c7484c2539ea17eb38307..3f6ebb25b86b821f35757e1468fbcf1bdaa422da 100644 --- a/libs/shared/lib/querybuilder/panel/shemaquerybuilder.stories.tsx +++ b/libs/shared/lib/querybuilder/panel/shemaquerybuilder.stories.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; import { setQuerybuilderNodes, setSchema, store } from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; + import { SchemaUtils } from '@graphpolaris/shared/lib/schema/schema-utils'; import { Schema } from '@graphpolaris/shared/lib/schema/panel'; import { movieSchemaRaw } from '@graphpolaris/shared/lib/mock-data'; @@ -37,16 +37,14 @@ const Component: Meta = { // using the real store here (story) => ( <Provider store={store}> - <GraphPolarisThemeProvider> - <div - style={{ - width: '100%', - height: '95vh', - }} - > - {story()} - </div> - </GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '95vh', + }} + > + {story()} + </div> </Provider> ), ], diff --git a/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple-disconnected.stories.tsx b/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple-disconnected.stories.tsx index 6d8c661f340482b9ea1a03da3902bce9462e58db..736ae8d21d0b51cb1cfbe6e063b0d972a2d7eaae 100644 --- a/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple-disconnected.stories.tsx +++ b/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple-disconnected.stories.tsx @@ -1,12 +1,6 @@ import React from 'react'; -import { - colorPaletteConfigSlice, - querybuilderSlice, - setQuerybuilderNodes, - setSchema, - store, -} from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; +import { querybuilderSlice, setQuerybuilderNodes, setSchema, store } from '@graphpolaris/shared/lib/data-access/store'; + import { configureStore } from '@reduxjs/toolkit'; import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; @@ -89,16 +83,14 @@ export const SimpleDisconnected = { return ( <Provider store={store}> - <GraphPolarisThemeProvider> - <div - style={{ - width: '100%', - height: '95vh', - }} - > - <ReactFlowProvider>{story()}</ReactFlowProvider> - </div> - </GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '95vh', + }} + > + <ReactFlowProvider>{story()}</ReactFlowProvider> + </div> </Provider> ); }, diff --git a/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple.stories.tsx b/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple.stories.tsx index bd57e342d07dc0c4b8541317fec3fc306c6615da..68c0849ba9d04824ba1cc1781dc0b40bdc16cd42 100644 --- a/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple.stories.tsx +++ b/libs/shared/lib/querybuilder/panel/stories/querybuilder-simple.stories.tsx @@ -1,12 +1,6 @@ import React from 'react'; -import { - colorPaletteConfigSlice, - querybuilderSlice, - setQuerybuilderNodes, - setSchema, - store, -} from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; +import { querybuilderSlice, setQuerybuilderNodes, setSchema, store } from '@graphpolaris/shared/lib/data-access/store'; + import { configureStore } from '@reduxjs/toolkit'; import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; @@ -20,16 +14,14 @@ const Component: Meta<typeof QueryBuilder> = { decorators: [ (story) => ( <Provider store={store}> - <GraphPolarisThemeProvider> - <div - style={{ - width: '100%', - height: '95vh', - }} - > - {story()} - </div> - </GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '95vh', + }} + > + {story()} + </div> </Provider> ), ], diff --git a/libs/shared/lib/querybuilder/panel/stories/querybuilder-single-entity.stories.tsx b/libs/shared/lib/querybuilder/panel/stories/querybuilder-single-entity.stories.tsx index c147c023d91d4dc49e80b3b4a6a6c392c3d5a910..acd8b87cc9c480686eb357e7a3946147da85e7cd 100644 --- a/libs/shared/lib/querybuilder/panel/stories/querybuilder-single-entity.stories.tsx +++ b/libs/shared/lib/querybuilder/panel/stories/querybuilder-single-entity.stories.tsx @@ -1,12 +1,6 @@ import React from 'react'; -import { - colorPaletteConfigSlice, - querybuilderSlice, - setQuerybuilderNodes, - setSchema, - store, -} from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; +import { querybuilderSlice, setQuerybuilderNodes, setSchema, store } from '@graphpolaris/shared/lib/data-access/store'; + import { configureStore } from '@reduxjs/toolkit'; import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; @@ -19,16 +13,14 @@ const Component: Meta<typeof QueryBuilder> = { decorators: [ (story) => ( <Provider store={store}> - <GraphPolarisThemeProvider> - <div - style={{ - width: '100%', - height: '95vh', - }} - > - {story()} - </div> - </GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '95vh', + }} + > + {story()} + </div> </Provider> ), ], diff --git a/libs/shared/lib/querybuilder/panel/stories/querybuilder-single-relationship.stories.tsx b/libs/shared/lib/querybuilder/panel/stories/querybuilder-single-relationship.stories.tsx index db2d6634ff70de4183e8bf89a578cc71fc822533..c94a3f367c9684cd67583e0735616e7c8a6d4165 100644 --- a/libs/shared/lib/querybuilder/panel/stories/querybuilder-single-relationship.stories.tsx +++ b/libs/shared/lib/querybuilder/panel/stories/querybuilder-single-relationship.stories.tsx @@ -1,12 +1,6 @@ import React from 'react'; -import { - colorPaletteConfigSlice, - querybuilderSlice, - setQuerybuilderNodes, - setSchema, - store, -} from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; +import { querybuilderSlice, setQuerybuilderNodes, setSchema, store } from '@graphpolaris/shared/lib/data-access/store'; + import { configureStore } from '@reduxjs/toolkit'; import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; @@ -19,16 +13,14 @@ const Component: Meta<typeof QueryBuilder> = { decorators: [ (story) => ( <Provider store={store}> - <GraphPolarisThemeProvider> - <div - style={{ - width: '100%', - height: '95vh', - }} - > - {story()} - </div> - </GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '95vh', + }} + > + {story()} + </div> </Provider> ), ], diff --git a/libs/shared/lib/querybuilder/pills/customFlowLines/connection.scss b/libs/shared/lib/querybuilder/pills/customFlowLines/connection.scss new file mode 100644 index 0000000000000000000000000000000000000000..4e133c2c64d948d2a26b8079022581886cc8bde7 --- /dev/null +++ b/libs/shared/lib/querybuilder/pills/customFlowLines/connection.scss @@ -0,0 +1,3 @@ +g { + @apply stroke-line-300; +} diff --git a/libs/shared/lib/querybuilder/pills/customFlowLines/connection.tsx b/libs/shared/lib/querybuilder/pills/customFlowLines/connection.tsx index ef15a7b00a63d7c2adbe636a14717808649a49f2..9ac746889c46692c1f85171944e0e3c4b5c8aca0 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowLines/connection.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowLines/connection.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { EdgeProps, getSmoothStepPath, Position } from 'reactflow'; +import './connection.scss'; /** * A custom query element edge line component. @@ -16,7 +17,7 @@ export function ConnectionLine({ id, sourceX, sourceY, targetX, targetY, style, // if (targetHandleId == Handles.ToAttributeHandle) targetX += 2; - let spos: Position = sourcePosition; + // let spos: Position = sourcePosition; // if (sourceHandleId == handles.relation.fromEntity) { // spos = Position.Left; // sourceX += 7; @@ -35,32 +36,29 @@ export function ConnectionLine({ id, sourceX, sourceY, targetX, targetY, style, // sourceY += 3; // } - let tpos: Position = targetPosition; - // if (targetHandleId == handles.relation.fromEntity) { - // tpos = Position.Left; - // targetX += 7; - // targetY += 3; - // } else if (targetHandleId == handles.relation.toEntity) { - // tpos = Position.Right; - // targetX -= 2; - // targetY -= 3; - // } + if (targetPosition === Position.Left) { + targetX += 2; + targetY += 0.5; + } else if (targetPosition === Position.Right) { + targetX -= 2; + targetY -= 0.5; + } // Create smoothstep line const path = getSmoothStepPath({ sourceX: sourceX, sourceY: sourceY, - sourcePosition: spos, + sourcePosition, targetX: targetX, targetY: targetY, - targetPosition: tpos, + targetPosition, }); // console.log(source, target, path); return ( <g stroke="#2e2e2e"> - <path id={id} fill="none" strokeWidth={3} style={style} d={path[0]} /> + <path id={id} fill="none" strokeWidth={1.5} style={style} d={path[0]} /> </g> ); } diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss deleted file mode 100644 index 880216ca8cced12e4a78c98955880278d4e7a1e8..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss +++ /dev/null @@ -1,151 +0,0 @@ -@use './variables.module.scss'; -@import '../../querypills.module.scss'; - -.attribute { - display: flex; - font-family: monospace; - font-weight: bold; - font-size: variables.$fontsize; - border-radius: 2px; -} - -// .handle { -// border: 0px; -// border-radius: 10px; -// left: 12px; -// width: 7px; -// height: 7px; -// margin-bottom: 11px; -// background: rgba(255; 255; 255; 0.6); -// box-shadow: 0 0 0 1px rgba(0; 0; 0; 0.3); -// transform-origin: center; -// } - -.contentWrapper { - display: flex; - align-items: center; - - .content { - padding: variables.$ypad 0 variables.$ypad 1ch; - max-width: 15ch; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - } -} - -// Attribute Element -.attributeMain { - background: #bfb6af; - color: #fff; - border-radius: 18px; - font-family: monospace; - font-weight: bold; - font-size: 11px; - padding-top: 0.1em; - padding-right: 0.5em; - padding-bottom: 0.1em; - padding-left: 0.5em; -} - -.attributeHandleLeft { - left: 4px !important; - background: rgba(0, 0, 0, 0.3); - &::before { - content: ''; - width: 6; - height: 6; - left: 1; - bottom: 1; - border: 0; - border-radius: 5; - background: rgba(255, 255, 255, 0.6); - z-index: -1; - display: inline-block; - position: fixed; - } -} - -.attributeInput { - float: right; - padding: 0 1ch 0 0; - display: flex; - align-items: center; - - input { - background-color: rgba(100, 100, 100, 0.1); - font-family: monospace; - font-size: variables.$fontsize; - border: 1px solid rgba(100, 100, 100, 0.3); - border-radius: 2px; - height: variables.$height; - outline: none; - transition: border 0.3s; - color: black; - &::placeholder { - color: black; - } - - &:focus { - border: 1px solid rgba(0, 0, 0, 0.3); - } - } -} - -.attributeWrapper { - height: 100%; - color: black; - display: flex; - align-items: center; - gap: 0.6em; - margin-left: 0.8em; -} -.attributeWrapperSpan { - margin-left: 4px; -} - -// Attribute select component -.matchTypeSelect { - background-color: rgba(255, 255, 255, 0.6); - border-radius: 2px; - display: flex; - pointer-events: all; - cursor: pointer; - & select { - background: transparent; - border: none; - appearance: none; - - font-family: monospace; - font-size: 11px; - text-align: center; - } - & option { - font-family: monospace; - font-size: 11px; - } -} -.matchModifierTypeSelect { - background-color: rgba(255, 255, 255, 0.6); - border-radius: 2px; - - text-align: center; - & select { - background: transparent; - border: none; - appearance: none; - font-family: monospace; - font-weight: bolder; - color: black; - font-size: 11; - } - & option { - font-family: monospace; - font-size: 11px; - } -} - -.disable { - opacity: 1 !important; - pointer-events: none; -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss.d.ts deleted file mode 100644 index 634416569f9c073c84c7a27f7a928f775495e66f..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.module.scss.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -declare const classNames: { - readonly handle: 'handle'; - readonly handle_logic: 'handle_logic'; - readonly handle_logic_duration: 'handle_logic_duration'; - readonly handle_logic_datetime: 'handle_logic_datetime'; - readonly handle_logic_time: 'handle_logic_time'; - readonly handle_logic_date: 'handle_logic_date'; - readonly handle_logic_bool: 'handle_logic_bool'; - readonly handle_logic_float: 'handle_logic_float'; - readonly handle_logic_int: 'handle_logic_int'; - readonly handle_logic_string: 'handle_logic_string'; - readonly handle_from_relation: 'handle_from_relation'; - readonly handle_to_relation: 'handle_to_relation'; - readonly 'react-flow__node': 'react-flow__node'; - readonly selected: 'selected'; - readonly entityWrapper: 'entityWrapper'; - readonly hidden: 'hidden'; - readonly 'react-flow__edges': 'react-flow__edges'; - readonly 'react-flow__edge-default': 'react-flow__edge-default'; - readonly handleConnectedFill: 'handleConnectedFill'; - readonly handleConnectedBorderRight: 'handleConnectedBorderRight'; - readonly handleConnectedBorderLeft: 'handleConnectedBorderLeft'; - readonly handleFunction: 'handleFunction'; - readonly attribute: 'attribute'; - readonly contentWrapper: 'contentWrapper'; - readonly content: 'content'; - readonly attributeMain: 'attributeMain'; - readonly attributeHandleLeft: 'attributeHandleLeft'; - readonly attributeInput: 'attributeInput'; - readonly attributeWrapper: 'attributeWrapper'; - readonly attributeWrapperSpan: 'attributeWrapperSpan'; - readonly matchTypeSelect: 'matchTypeSelect'; - readonly matchModifierTypeSelect: 'matchModifierTypeSelect'; - readonly disable: 'disable'; -}; -export = classNames; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.storiesDEFUNCT.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.storiesDEFUNCT.tsx deleted file mode 100644 index a1788066ca8edece8fc69afab0ae41e258cc9cc2..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.storiesDEFUNCT.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import { Meta } from '@storybook/react'; -import AttributePill from './attributepill'; -import { configureStore } from '@reduxjs/toolkit'; -import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; - -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; -import { ReactFlowProvider } from 'reactflow'; - -const Component: Meta<typeof AttributePill> = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/react/configure/overview#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'Querybuilder/Pills/AttributePill', - component: AttributePill, - decorators: [ - (story) => ( - <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> - </Provider> - ), - ], -}; - -export default Component; - -// A super-simple mock of a redux store -const Mockstore = configureStore({ - reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, - querybuilder: querybuilderSlice.reducer, - // schema: schemaSlice.reducer, - }, -}); - -export const Simple = { - args: { - data: { - name: 'TestEntity', - }, - }, -}; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx deleted file mode 100644 index 0875fe2a2661ca5efb771afb596b0e4c07dd30e7..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/attributepill.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import { useTheme } from '@mui/material'; -import React, { useMemo, useState } from 'react'; -import styles from './attributepill.module.scss'; -import { Handle, NodeProps, Position } from 'reactflow'; -import { AttributeOperatorSelect } from './operator'; -import Select from './select-component'; -import { Handles } from '../../../model'; - -/** - * Component to render an attribute flow element - * @param {FlowElement<EntityData>)} param0 The data of an entity flow element. - */ -export const AttributePill = React.memo(({ id, data }: any) => { - const theme = useTheme(); - const [read, setRead] = useState(true); - // console.log('AttributePill', data); - - /** - * Check if the pressed key is enter in order to send the new query. - * @param event Key press event. - */ - const _onKeyDown = (event: any): void => { - if (event.key == 'Enter') setRead(true); - }; - - /** - * Checks if the string input is a number. - * @param x String input. - * @returns {boolean} True if input is a number. - */ - const isNumber = (x: string): boolean => { - { - if (typeof x != 'string') return false; - return !Number.isNaN(x) && !Number.isNaN(parseFloat(x)); - } - }; - - /** - * Calculates the width of an element based on the length of a monospaced font. - * @param str Input string. - * @returns {string} Containing the length in css format. - */ - const calcWidth = (str: string) => { - if (str == '') { - return 1.5 + 'ch'; - } - return str.length + 0.5 + 'ch'; - }; - - /** - * Input contraint checker for the attribute input fields. - * @param type Data.dataType. - * @param str Input string. - * @returns {string} Result string after the contraints are applied. - */ - const inputConstraint = (type: string, str: string): string => { - let res = ''; - switch (type) { - case 'string': - res = str; - break; - case 'bool': - res = str; - break; // TODO: only false and true live update will break since it will not allow to write more that 1 letter - case 'int': - isNumber(str) ? (res = str) : (res = ''); - break; // TODO: check if letters after number - default: - res = str; - break; - } - return res; - }; - - //TODO: docstrings - const className = styles.attributeHandleLeft + ' ' + (false ? styles.handleConnectedFill : ''); - - const onChange = (e: any) => { - if (data != undefined) { - data.value = inputConstraint(data.dataType, e.target.value); - e.target.style.maxWidth = calcWidth(data.value); - } - }; - - /**Constraint datatypes back end. - * string MatchTypes: EQ/NEQ/contains/excludes. - * int MatchTypes: EQ/NEQ/GT/LT/GET/LET. - * bool MatchTypes: EQ/NEQ. - */ - //TODO: fix use of relation boilerplate styling - - return ( - <div className={styles.attributeMain} style={{ backgroundColor: theme.palette.custom.elements.attribute[0] }}> - <Handle - id={Handles.OnAttribute} - type="source" - position={Position.Left} - className={styles.attributeHandleLeft + ' ' + (false ? styles.handleConnectedFill : '')} - style={{ backgroundColor: theme.palette.custom.elements.attribute[1] }} - /> - <Handle - id={Handles.ToAttribute} - type="source" - position={Position.Left} - className={styles.attributeHandleLeft + ' ' + (false ? styles.handleConnectedFill : '')} - style={{ - backgroundColor: theme.palette.custom.elements.attribute[1], - left: 50, - }} - /> - <div className={styles.attributeWrapper}> - <span className={styles.attributeWrapperSpan}>{data?.name}</span> - <Select data={data} /> - <span className={styles.attributeInput}> - <input type="hidden"></input> - <input - style={{ maxWidth: calcWidth(data?.value || '') }} - type="string" - readOnly={read} - placeholder={'?'} - value={data?.value || ''} - onChange={onChange} - onDoubleClick={() => { - setRead(false); - }} - onBlur={() => { - setRead(true); - }} - onKeyDown={_onKeyDown} - ></input> - </span> - </div> - </div> - ); -}); -AttributePill.displayName = 'AttributePill'; - -export default AttributePill; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/checkInput.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/checkInput.ts deleted file mode 100644 index a1c29ab1f05d62105afaf80faaa405c30ce60535..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/checkInput.ts +++ /dev/null @@ -1,34 +0,0 @@ -/** Checks if the string input is a number. */ -function isNumber(x: string): boolean { - if (typeof x != 'string') return false; - return !Number.isNaN(x) && !Number.isNaN(parseFloat(x)); -} -function isBoolean(s: string): boolean { - return s == 'true' || s == 'false' || s == '0' || s == '1'; -} -function toBoolean(s: string): string { - if (s == '1' || s == 'true') return 'true'; - return 'false'; -} - -/** Checks if the provided value has the same as the datatype of the attribute. */ -export function CheckDatatypeConstraint(type: string, str: string): string { - let res = ''; - switch (type) { - case 'string': - res = str; - break; - case 'bool': - isBoolean(str) ? (res = toBoolean(str)) : (res = ''); - break; - case 'int': - case 'float': - case 'number': - isNumber(str) ? (res = '' + parseFloat(str)) : (res = ''); - break; - default: - res = str; - break; - } - return res; -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/getAttributeBoolOperators.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/getAttributeBoolOperators.ts deleted file mode 100644 index 0d01e2c01350ccb17ad98405eed7f8ba5b499d36..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/getAttributeBoolOperators.ts +++ /dev/null @@ -1,61 +0,0 @@ -/** Determines the available boolean operators for a certain datatype. */ -export function GetAttributeBoolOperators(datatype: string): { label: string; value: string }[] { - switch (datatype) { - case 'text': - case 'string': - return [ - { - label: '=', - value: 'EQ', - }, - { - label: '≠', - value: 'NEQ', - }, - { - label: 'inc', - value: 'includes', - }, - { - label: 'exc', - value: 'excludes', - }, - ]; - case 'int': - case 'float': - return [ - { - label: '=', - value: 'EQ', - }, - { - label: '≠', - value: 'NEQ', - }, - { - label: '>', - value: 'GT', - }, - { - label: '≥', - value: 'GTE', - }, - { - label: '<', - value: 'LT', - }, - { - label: '≤', - value: 'LTE', - }, - ]; - case 'bool': - default: - return [ - { - label: '=', - value: 'EQ', - }, - ]; - } -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/index.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/index.ts deleted file mode 100644 index 63a80940c20e9a7ea73f295a8c7cb4e7f5ecd685..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './attributepill'; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/index.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/index.ts deleted file mode 100644 index fe9dde909b79825b1cb1e46e3402762141b2d25f..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './operatorselect'; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.module.scss deleted file mode 100644 index 286fa1da405db69f96f095a6801d825502da3e6c..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.module.scss +++ /dev/null @@ -1,70 +0,0 @@ -@use '../variables.module.scss'; - -.container { - position: relative; - vertical-align: baseline; - margin: 0 1ch; - font-weight: normal; - font-size: 7px; -} - -.valueContainer { - color: #6a6a6a; - border: 1px solid rgba(0, 0, 0, 0); - border-radius: 2px; - background-color: transparent; - - transition: border-color 0.2s; - - height: variables.$height; - align-items: center; - display: flex; - padding: 0 1px 1px 1px; - - &.highlighted, - &:hover { - border-color: rgba(0, 0, 0, 0.4); - } -} - -.listbox { - font-size: 10px; - box-sizing: border-box; - padding: 5px; - margin: 5px 0 0 0; - list-style: none; - position: absolute; - height: auto; - box-shadow: 0 5px 13px -3px #e0e3e7; - background: white; - border: 1px solid #cdd2d7; - border-radius: 0.75em; - color: #1a2027; - overflow: auto; - z-index: 1; - outline: 0px; - left: -8px; - - &.hidden { - opacity: 0; - visibility: hidden; - transition: opacity 0.4s 0.1s ease, visibility 0.4s 0.1s step-end; - } - - & > li { - padding: 1px 4px; - border-radius: 2px; - - &.selected { - background: #f1f1f1; - } - - &:hover { - background: #e7ebf0; - } - - &[aria-selected='true'] { - background: #e0e3e7; - } - } -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.module.scss.d.ts deleted file mode 100644 index c913abdebc3840c2beb51337a0c059aa39538ceb..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.module.scss.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -declare const classNames: { - readonly container: 'container'; - readonly valueContainer: 'valueContainer'; - readonly highlighted: 'highlighted'; - readonly listbox: 'listbox'; - readonly hidden: 'hidden'; - readonly selected: 'selected'; -}; -export = classNames; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.tsx deleted file mode 100644 index 4ea581df8075eefd2b699c4d5d563dde5199f332..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/operator/operatorselect.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import * as React from 'react'; -import { SelectOption } from '@mui/base'; -import styles from './operatorselect.module.scss'; -import { useRef, useState } from 'react'; - -// const grey = { -// 100: '#E7EBF0', -// 200: '#E0E3E7', -// 300: '#CDD2D7', -// 400: '#B2BAC2', -// 500: '#A0AAB4', -// 600: '#6F7E8C', -// 700: '#3E5060', -// 800: '#2D3843', -// 900: '#1A2027', -// }; - -interface Props { - options: SelectOption<string>[]; - selected: string; - changed?: (newSelected: SelectOption<string>) => void; -} - -export function AttributeOperatorSelect({ - options, - selected, - changed = () => { - return; - }, -}: Props) { - const listboxRef = useRef<HTMLUListElement>(null); - const [listboxVisible, setListboxVisible] = useState(false); - const [currSelected, setCurrSelected] = useState(options.find((o) => o.value == selected)?.label || options[0].label); - - React.useEffect(() => { - if (listboxVisible) { - listboxRef.current?.focus(); - } - }, [listboxVisible]); - - const changeSelected = (option: SelectOption<string>) => { - if (option.label != currSelected) { - setCurrSelected(option.label); - changed(option); - } - }; - - return ( - <div - className={styles.container} - // onMouseOver={() => setListboxVisible(true)} - onMouseOut={() => setListboxVisible(false)} - onClick={() => setListboxVisible(true)} - onFocus={() => setListboxVisible(true)} - onBlur={() => setListboxVisible(false)} - > - <div className={styles.valueContainer + ' ' + (listboxVisible && styles.highlighted)}> - <span>{currSelected}</span> - </div> - {options.length > 1 && ( - <ul - className={styles.listbox + ' ' + (!listboxVisible && styles.hidden)} - ref={listboxRef} - onMouseOver={() => setListboxVisible(true)} - > - {options.map((option) => ( - <li className={option.label == currSelected ? styles.selected : ''} key={option.value} onClick={() => changeSelected(option)}> - {option.label} - </li> - ))} - </ul> - )} - </div> - ); -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/select-component.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/select-component.tsx deleted file mode 100644 index 2f804d657771df47ec71a84a381c175c630ffca8..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/select-component.tsx +++ /dev/null @@ -1,84 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -/* istanbul ignore file */ -/* The comment above was added so the code coverage wouldn't count this file towards code coverage. - * We do not test components/renderfunctions/styling files. - * See testing plan for more details.*/ -import { useTheme } from '@mui/material'; -import React, { useState } from 'react'; -import styles from './attributepill.module.scss'; - -export default function SelectComponent({ data }: { data: any }) { - const theme = useTheme(); - - /** - * Calculate the width of the select element based on the displayed value. - * @param str Input string. - * @returns {string} Containing the length in css format. - */ - const calcSelectWidth = (str: string): string => { - if (str == '') { - return 1.5 + 'ch'; - } - return str.length + 1.5 + 'ch'; - }; - - /** - * Constant switch to append the right options for the select element based on the data.dataType. - * @returns {JSX.Element} Option list using React.Fragment as parent element. - */ - const list = (): JSX.Element => { - switch (data.dataType) { - case 'string': - return ( - <React.Fragment> - <option value="EQ">==</option> - <option value="NEQ">!=</option> - <option value="contains">contains</option> - <option value="excludes">excludes</option> - </React.Fragment> - ); - case 'int': - case 'float': - return ( - <React.Fragment> - <option value="EQ">==</option> - <option value="NEQ">!=</option> - <option value="GT">{'>'}</option> - <option value="LT">{'<'}</option> - <option value="GET">{'>='}</option> - <option value="LET">{'<='}</option> - </React.Fragment> - ); - case 'bool': - return ( - <React.Fragment> - <option value="EQ">==</option> - <option value="NEQ">!=</option> - </React.Fragment> - ); - default: - return <option>Error</option>; - } - }; - - return ( - <div className={styles.matchTypeSelect} style={{ backgroundColor: theme.palette.custom.elements.attribute[1] }}> - <select - style={{ maxWidth: calcSelectWidth('==') }} - value={data.matchType} - name="operators" - onChange={(e) => { - data.matchType = e.target.value; - e.target.style.maxWidth = calcSelectWidth(e.target.value); - }} - > - {list()} - </select> - </div> - ); -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/variables.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/variables.module.scss deleted file mode 100644 index 08bc31bb67c70a043d0114880fceada930fe14b1..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/variables.module.scss +++ /dev/null @@ -1,3 +0,0 @@ -$height: 5px; -$fontsize: 6px; -$ypad: 2px; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/variables.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/variables.module.scss.d.ts deleted file mode 100644 index 5fc8829cc55093ac225af1acd319611c23d9ac9f..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/attributepill/variables.module.scss.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -declare const classNames: {}; -export = classNames; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx index fd47ee277672faa3352036060444216684637321..22698240b93e394ec7fff9e9cc855da97f088171 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill-full.stories.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { colorPaletteConfigSlice, querybuilderSlice, setQuerybuilderNodes } from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; +import { querybuilderSlice, setQuerybuilderNodes } from '@graphpolaris/shared/lib/data-access/store'; + import { configureStore } from '@reduxjs/toolkit'; import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; @@ -11,19 +11,12 @@ import { QueryElementTypes } from '../../../model'; const Component: Meta<typeof QueryBuilder> = { component: QueryBuilder, title: 'Querybuilder/Pills/EntityPill', - decorators: [ - (story) => ( - <Provider store={mockStore}> - <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> - </Provider> - ), - ], + decorators: [(story) => <Provider store={mockStore}>{story()}</Provider>], }; // Mock palette store const mockStore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, }, }); diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss index 2590cb9d86996c39f88e06a402d3b4088df79327..d2b9ad3b24793b5de65b3cc45d26a96c145fc7e1 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss @@ -4,13 +4,6 @@ box-shadow: black 0 0 2px; } -.react-flow__edges { - zindex: 3; -} -.react-flow__nodes { -} -.react-flow__pane { -} .react-flow__edge-default .selected { stroke: gray !important; } @@ -29,18 +22,12 @@ // Entity element .entity { - background: #e9e9e9; - // display: flex; - // border: #ffffff solid 2px; - border-radius: 2px; - font-family: monospace; + border-left: 3px solid; + @apply bg-entity-50; + @apply border-l-entity-600; font-weight: bold; - color: black; min-width: 8rem; - - font-size: 10px; - border-radius: 2px; - // padding-left: 45px; + font-size: 13px; .title { position: relative; @@ -72,6 +59,11 @@ animation: slide-down 0.2s ease-out; overflow: hidden; max-height: 0; + font-weight: normal; + // border-left: 1px solid; + // @apply bg-entity-50; + // @apply border-l-entity-800; + // @apply bg-base-100; } .content_display { @@ -105,81 +97,3 @@ } } } - -.entityHandleLeft { - border: 0; - border-radius: 0; - left: 12; - width: 8; - height: 8; - margin-bottom: 15; - background: rgba(0, 0, 0, 0.3); - transform-origin: center; - &::before { - content: ''; - width: 6; - height: 6; - left: 1; - bottom: 1; - border: 0; - border-radius: 0; - background: rgba(255, 255, 255, 0.6); - z-index: -1; - display: inline-block; - position: fixed; - } -} - -.entityHandleBottom { - border: 0; - border-radius: 0; - width: 8; - height: 8; - left: 27.5; - margin-bottom: 15; - background: rgba(0, 0, 0, 0.3); - transform: rotate(-45deg); - transform-origin: center; - &::before { - content: ''; - width: 6; - height: 6; - left: 1; - bottom: 1; - border: 0; - border-radius: 0; - background: rgba(255, 255, 255, 0.6); - z-index: -1; - display: inline-block; - position: fixed; - } -} - -.entityWrapper { - display: block; -} - -.entitySpan { - display: block; -} - -// General style - -.ToAttributeHandle { - border-radius: 1px !important; - left: 20px !important; - top: 35% !important; - background: rgba(0, 0, 0, 0.3) !important; - transform: rotate(45deg) scale(0.9) !important; - transform-origin: center, center; -} - -.ReceiveFunctionHandle { - left: 37px !important; - top: 35% !important; - background: rgba(0, 0, 0, 0.3) !important; -} - -.handleFunctionEntity { - margin-left: 5px; -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss.d.ts index 2812eed57afbb7ec00fc2a40c9065dc6604e1cd6..e37860555e977a33004154e95938b792b0edaf16 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss.d.ts +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.module.scss.d.ts @@ -30,11 +30,5 @@ declare const classNames: { readonly io: 'io'; readonly io_right: 'io_right'; readonly entityFade: 'entityFade'; - readonly entityHandleLeft: 'entityHandleLeft'; - readonly entityHandleBottom: 'entityHandleBottom'; - readonly entitySpan: 'entitySpan'; - readonly ToAttributeHandle: 'ToAttributeHandle'; - readonly ReceiveFunctionHandle: 'ReceiveFunctionHandle'; - readonly handleFunctionEntity: 'handleFunctionEntity'; }; export = classNames; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.stories.tsx index edff6caa00e498d0c9493a1017b50a62c6f64410..7de4cbc2af54dc602612809808b5ebbbc0d6937e 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.stories.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.stories.tsx @@ -3,9 +3,8 @@ import { Meta, StoryObj } from '@storybook/react'; import EntityFlowElement from './entitypill'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; +import { querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; import { ReactFlowProvider } from 'reactflow'; import { EntityData } from '../../../model'; @@ -19,9 +18,7 @@ const Component: Meta<typeof EntityFlowElement> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> + <ReactFlowProvider>{story()}</ReactFlowProvider> </Provider> ), ], @@ -32,7 +29,6 @@ export default Component; // A super-simple mock of a redux store const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, // schema: schemaSlice.reducer, }, @@ -51,7 +47,7 @@ export const Default: StoryObj<{ data: EntityData }> = { // Default.decorators = [ // (story) => ( // <Provider store={Mockstore}> -// <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> +// {story()} // </Provider> // ), // ]; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx index 2d0cd37a3ff2e83066dae23b967e489ad8da1de5..c8391055c504fad796313813d47572f14d5b6958 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/entitypill/entitypill.tsx @@ -1,28 +1,16 @@ // import { handles } from '@graphpolaris/shared/lib/querybuilder/usecases'; -import { useTheme } from '@mui/material'; -import React, { MouseEventHandler, useEffect, useMemo } from 'react'; -import { ReactFlow, Handle, Position, getConnectedEdges } from 'reactflow'; -import styles from './entitypill.module.scss'; -import { - SchemaReactflowEntityNode, - Handles, - toHandleId, - handleDataFromReactflowToId, - QueryElementTypes, - NodeAttribute, -} from '../../../model'; -import { SchemaAttribute } from '@graphpolaris/shared/lib/schema'; -import { styleHandleMap } from '../../utils'; import { useQuerybuilderGraph } from '@graphpolaris/shared/lib/data-access'; +import React, { useMemo } from 'react'; +import { Handle, Position } from 'reactflow'; +import { NodeAttribute, SchemaReactflowEntityNode, handleDataFromReactflowToId, toHandleId } from '../../../model'; +import { styleHandleMap } from '../../utils'; +import styles from './entitypill.module.scss'; /** * Component to render an entity flow element * @param {NodeProps} param0 The data of an entity flow element. */ export const EntityFlowElement = React.memo((node: SchemaReactflowEntityNode) => { - const theme = useTheme(); - // console.log('EntityFlowElement', node); - const data = node.data; const forceOpen: boolean = false; if (!data.leftRelationHandleId) throw new Error('EntityFlowElement: data.leftRelationHandleId is undefined'); @@ -37,9 +25,6 @@ export const EntityFlowElement = React.memo((node: SchemaReactflowEntityNode) => const [hovered, setHovered] = React.useState(false); const [handleBeingDragged, setHandleBeingDragged] = React.useState(-1); - // TODO: Change flow element width when text overflows - const animation = styles.entityFade; // TODO: Check if correct - const onMouseEnter = (event: React.MouseEvent) => { setHovered(true); }; @@ -65,62 +50,10 @@ export const EntityFlowElement = React.memo((node: SchemaReactflowEntityNode) => const showingDropdown = hovered || handleBeingDragged !== -1 || attributeEdges.length > 0; return ( - <div - className={`${styles.entity} ${animation} query_builder-entity`} - onMouseEnter={onMouseEnter} - onMouseLeave={onMouseLeave} - style={ - { - // borderColor: theme.palette.custom.elements.entityBase[0], - } - } - > - <Handle - // id={getHandleId(data.name, data.type, Handles.ToRelation, '')} - id={toHandleId(data.leftRelationHandleId)} - type="target" - position={Position.Left} - className={styles.handle_to_relation} - /> - <Handle - // id={getHandleId(data.name, data.type, Handles.ToRelation, '')} - id={toHandleId(data.rightRelationHandleId)} - type="source" - position={Position.Right} - className={styles.handle_to_relation} - /> - {/* <Handle - id={Handles.ToAttribute} - type="target" - position={Position.Bottom} - className={ - styles.ToAttributeHandle + - ' ' + - (false ? styles.handleConnectedFill : '') - } - /> - <Handle - id={Handles.ReceiveFunction} - type="target" - position={Position.Bottom} - className={ - styles.ReceiveFunctionHandle + - ' ' + - (false ? styles.handleConnectedFill : '') - } - /> */} - - <div - className={styles.title} - style={{ - backgroundColor: theme.palette.custom.elements.entityBase[0], - }} - > - {data.name} - </div> - {/* <div className={styles.entityWrapper}> - <span className={styles.entitySpan}>{data.name}</span> - </div> */} + <div className={`${styles.entity} ${styles.entityFade} query_builder-entity`} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}> + <Handle id={toHandleId(data.leftRelationHandleId)} type="target" position={Position.Left} className={styles.handle_from_relation} /> + <Handle id={toHandleId(data.rightRelationHandleId)} type="source" position={Position.Right} className={styles.handle_to_relation} /> + <div className={styles.title}>{data.name}</div> {data?.attributes && ( <div className={styles.content + ' ' + (showingDropdown || forceOpen || hovered ? styles.content_display : '')}> {data.attributes diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/SelectFunction.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/SelectFunction.tsx deleted file mode 100644 index 5a6fd8c4c5b1a7c57186fb5217534496f1a3dbe8..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/SelectFunction.tsx +++ /dev/null @@ -1,84 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -/* istanbul ignore file */ -/* The comment above was added so the code coverage wouldn't count this file towards code coverage. - * We do not test components/renderfunctions/styling files. - * See testing plan for more details.*/ -import { makeStyles } from '@mui/material'; -import React, { useState } from 'react'; -import styles from './functionpill.module.scss'; - -// Create style constant to prevent rereaction of styles -// const madeStyles = makeStyles(useStyles); - -/** - * The flow element for the modifier. - * @param param0 The data of the modifier flow element. - */ -export default function ModifierFlowElement({ data }: any) { - const [disable, setDisable] = useState(true); - const [disClass, setDisClass] = useState<string>(styles.disable); - - /** - * Calculate the width of the select element based on the displayed value. - * @param str Input string. - * @returns String containg the length in css format. - */ - const calcSelectWidth = (str: string): string => { - if (str == '') return 1.5 + 'ch'; - return str.length + 1.5 + 'ch'; - }; - - /** Disable the select field */ - const disableSelect = (): void => { - setDisable(true); - setDisClass(styles.disable); - }; - - /** Enable the select field */ - const enableSelect = (): void => { - setDisable(false); - setDisClass(''); - }; - - /** - * Constant switch to append the right options for the select element based on the data.type. - * @returns {JSX.Element} Option list using React.Fragment as parent element. - */ - const list = (): JSX.Element => { - return ( - <React.Fragment> - <option color="black" value="COUNT"> - COUNT - </option> - <option value="SUM">SUM</option> - <option value="MIN">MIN</option> - <option value="MAX">MAX</option> - </React.Fragment> - ); - }; - - return ( - <div className={styles.matchModifierTypeSelect} onBlur={disableSelect} onDoubleClick={enableSelect}> - <select - style={{ - color: disable ? 'black' : 'black', - maxWidth: calcSelectWidth('COUNT'), - }} - name="operators" - className={disClass} - disabled={disable} - onChange={(e) => { - data.type = e.target.value; - e.target.style.maxWidth = calcSelectWidth(e.target.value); - }} - > - {list()} - </select> - </div> - ); -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss deleted file mode 100644 index ec1d4a5e97eba412aea899ab181fbea3bf072ca1..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss +++ /dev/null @@ -1,175 +0,0 @@ -@import '../entitypill/entitypill.module.scss'; - -$baseColor: #8c75c9; - -.disable { - pointer-events: none; - opacity: 0.4; -} -.matchModifierTypeSelect { - opacity: 0.4; -} - -// Function element -.function { - background-color: $baseColor; - display: 'flex'; - border-radius: '1px'; - font-family: monospace; - font-weight: 'bold'; - font-size: 11px; - color: black; - min-width: '140px'; - text-align: 'center'; - line-height: 20px; - padding-top: 2; - padding-right: 5; - padding-bottom: 4; - padding-left: 5; - - &::before { - position: 'absolute'; - content: '""'; - width: '100%'; - left: '0px'; - top: '0px'; - height: '100%'; - border-radius: '3px'; - z-index: -1; - background-color: $baseColor; - border-bottom: 'none'; - } - - &::after { - position: 'absolute'; - content: '""'; - width: '100%'; - left: '0px'; - top: '0'; - height: '100%'; - border-radius: '3px'; - z-index: -1; - background-color: $baseColor; - border-top: 'none'; - } -} - -.functionWrapper { - display: 'block'; - width: 'inherit'; - align-items: 'center'; - justify-content: 'space-between'; -} -.functionHandleFiller { - flex: '1 1 0'; - display: 'flow-root'; -} -.functionHandle { - border: 0; - border-radius: 0; - width: 8; - height: 8; - left: 9; - top: 7; - background: 'rgba(0, 0, 0, 0.3)'; - transform-origin: 'center'; - position: 'relative'; - float: 'right'; - margin-right: '20px'; - &::before { - content: '""'; - width: 6; - height: 6; - left: 1; - bottom: 1; - border: 0; - border-radius: 0; - background: 'rgba(255, 255, 255, 0.6)'; - z-index: -1; - display: 'inline-block'; - position: 'fixed'; - } -} -.functionHandleBottom { - border: 0; - border-radius: 0; - width: 8; - height: 8; - left: 27.5; - margin-bottom: 10; - background-color: 'rgba(255, 255, 255, 0.6)'; - transform: 'rotate(-45deg)'; - transform-origin: 'center'; - &::before { - content: '""'; - width: 6; - height: 6; - left: 1; - bottom: 1; - border: 0; - border-radius: 0; - background-color: 'rgba(255, 255, 255, 0.6)'; - z-index: -1; - display: 'inline-block'; - position: 'fixed'; - } -} -.functionInputHolder { - display: 'flex'; - float: 'right'; - margin-right: '20px'; - margin-top: '4px'; - margin-left: '5px'; - max-width: '80px'; - background-color: 'rgba(255, 255, 255, 0.6)'; - border-radius: '2px'; - align-items: 'center'; - max-height: '12px'; -} -.functionInput { - z-index: 1; - cursor: 'text'; - min-width: '0px'; - max-width: '1.5ch'; - height: '14px'; - border: 'none'; - background-color: 'rgba(255, 255, 255, 0.6)'; - text-align: 'center'; - font-family: 'monospace'; - font-weight: 'bold'; - font-size: '11px'; - color: '#181520'; - user-select: 'none'; - font-style: 'italic'; - float: 'right'; - margin: '3px 0'; - margin-right: '10px'; - &:focus { - outline: 'none'; - user-select: 'none'; - } - &::placeholder { - outline: 'none'; - user-select: 'none'; - font-style: 'italic'; - } -} -.functionReadonly { - cursor: 'grab !important'; - color: '#181520 !important'; - user-select: 'none'; - font-style: 'normal !important'; -} -.functionSpan { - float: 'left'; - margin-left: 20; - margin-right: 20; -} -.functionSpanRight { - float: 'right'; - margin-right: 10; -} - -.functionDataWrapper { - display: block; -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss.d.ts deleted file mode 100644 index ae6d376d7d5e2717be1aec03dfb15ef173fcea35..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.module.scss.d.ts +++ /dev/null @@ -1,53 +0,0 @@ -declare const classNames: { - readonly disable: 'disable'; - readonly matchModifierTypeSelect: 'matchModifierTypeSelect'; - readonly handle: 'handle'; - readonly handle_logic: 'handle_logic'; - readonly handle_logic_duration: 'handle_logic_duration'; - readonly handle_logic_datetime: 'handle_logic_datetime'; - readonly handle_logic_time: 'handle_logic_time'; - readonly handle_logic_date: 'handle_logic_date'; - readonly handle_logic_bool: 'handle_logic_bool'; - readonly handle_logic_float: 'handle_logic_float'; - readonly handle_logic_int: 'handle_logic_int'; - readonly handle_logic_string: 'handle_logic_string'; - readonly handle_from_relation: 'handle_from_relation'; - readonly handle_to_relation: 'handle_to_relation'; - readonly 'react-flow__node': 'react-flow__node'; - readonly selected: 'selected'; - readonly entityWrapper: 'entityWrapper'; - readonly hidden: 'hidden'; - readonly 'react-flow__edges': 'react-flow__edges'; - readonly 'react-flow__edge-default': 'react-flow__edge-default'; - readonly handleConnectedFill: 'handleConnectedFill'; - readonly handleConnectedBorderRight: 'handleConnectedBorderRight'; - readonly handleConnectedBorderLeft: 'handleConnectedBorderLeft'; - readonly handleFunction: 'handleFunction'; - readonly highlighted: 'highlighted'; - readonly contentWrapper: 'contentWrapper'; - readonly entity: 'entity'; - readonly title: 'title'; - readonly content: 'content'; - readonly content_display: 'content_display'; - readonly io: 'io'; - readonly io_right: 'io_right'; - readonly entityFade: 'entityFade'; - readonly entityHandleLeft: 'entityHandleLeft'; - readonly entityHandleBottom: 'entityHandleBottom'; - readonly entitySpan: 'entitySpan'; - readonly ToAttributeHandle: 'ToAttributeHandle'; - readonly ReceiveFunctionHandle: 'ReceiveFunctionHandle'; - readonly handleFunctionEntity: 'handleFunctionEntity'; - readonly function: 'function'; - readonly functionWrapper: 'functionWrapper'; - readonly functionHandleFiller: 'functionHandleFiller'; - readonly functionHandle: 'functionHandle'; - readonly functionHandleBottom: 'functionHandleBottom'; - readonly functionInputHolder: 'functionInputHolder'; - readonly functionInput: 'functionInput'; - readonly functionReadonly: 'functionReadonly'; - readonly functionSpan: 'functionSpan'; - readonly functionSpanRight: 'functionSpanRight'; - readonly functionDataWrapper: 'functionDataWrapper'; -}; -export = classNames; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.stories.tsx deleted file mode 100644 index b086172fde78bfdb8dded949a4d1ec6e014f8e1b..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.stories.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React from 'react'; -import { Meta, StoryObj } from '@storybook/react'; -import FunctionFlowElement from './functionpill'; -import { configureStore } from '@reduxjs/toolkit'; -import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; - -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; -import { ReactFlowProvider } from 'reactflow'; - -const Component: Meta<typeof FunctionFlowElement> = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/react/configure/overview#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'Querybuilder/Pills/FunctionPill', - component: FunctionFlowElement, - decorators: [ - (story) => ( - <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> - </Provider> - ), - ], -}; - -export default Component; - -// A super-simple mock of a redux store -const Mockstore = configureStore({ - reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, - querybuilder: querybuilderSlice.reducer, - // schema: schemaSlice.reducer, - }, -}); - -// const Template = (args: any) => <EntityRFPill {...args} />; - -export const Default: StoryObj = { - args: { - data: { - functionType: 'test', - args: { - string: { - displayName: 'testarg', - connectable: false, - value: 'testvalue', - visible: true, - }, - }, - }, - }, -}; - -// Default.decorators = [ -// (story) => ( -// <Provider store={Mockstore}> -// <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> -// </Provider> -// ), -// ]; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.tsx deleted file mode 100644 index aeaa2b0039324401a7960f73462704c7e84dcce5..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/functionpill.tsx +++ /dev/null @@ -1,143 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -/* istanbul ignore file */ -/* The comment above was added so the code coverage wouldn't count this file towards code coverage. - * We do not test components/renderfunctions/styling files. - * See testing plan for more details.*/ -import React, { useState } from 'react'; -import { Handle, Position } from 'reactflow'; -import styles from './functionpill.module.scss'; -import { useTheme } from '@mui/material'; -import { Handles } from '../../../model'; - -const countArgs = (data: any) => { - if (data !== undefined) { - let count = 0; - - for (const name in data.args) { - if (data.args[name].visible) { - count++; - } - } - return count; - } - return 1; -}; - -/** - * Capitalize the first letter of a string. - * @param string This is the given string. - * @returns {string} This is the modified string. - */ -export const capitalizeFirstLetter = (string: string) => { - return string.charAt(0).toUpperCase() + string.slice(1); -}; - -/** - * Component to render a relation flow element - * @param { FlowElement<FunctionData>} param0 The data of a relation flow element. - */ -export default function RelationFlowElement({ data }: any) { - const [read, setRead] = useState(true); - const theme = useTheme(); - - const numOfArgs = countArgs(data); - const height = numOfArgs * 20; - - const _onKeyDown = (event: any): void => { - if (event.key == 'Enter') setRead(true); - }; - - const getArgs = (styles: any, data: any, setRead: any) => { - let rows: JSX.Element[] = []; - - if (data != undefined) { - let index = 0; - - for (const name in data.args) { - const item = data.args[name]; - if (item.visible) { - rows.push( - <span className={styles.functionHandleFiller} key={name}> - <span className={styles.functionSpan}>{capitalizeFirstLetter(name)}</span> - <Handle - id={Handles.FunctionBase + name} - type="source" - position={Position.Top} - className={styles.functionHandle + ' ' + (false ? styles.handleConnectedFill : '')} - style={{ - visibility: item.connectable ? 'inherit' : 'hidden', - }} - /> - {item.value !== undefined && ( - <input - className={styles.functionInput} - style={{ maxWidth: 50 }} - type="string" - placeholder={'?'} - value={item.value} - onChange={(e) => { - if (item.value != undefined) { - item.value = e.target.value; - //TODO restore SetElementsUseCase.updateFunctionCompleteness(data); - } - }} - onDoubleClick={() => { - setRead(false); - }} - onBlur={() => { - setRead(true); - }} - onKeyDown={_onKeyDown} - ></input> - )} - </span> - ); - index++; - } - } - } - - return rows; - }; - - const rows = getArgs(styles, data, setRead); - const entity = undefined; //TODO fix: data !== undefined ? data.entityName : undefined; - - return ( - <div> - <div - className={styles.function} - style={{ - minHeight: height, - background: theme.palette.custom.nodesBase[0], - borderTop: `4px solid ${theme.palette.custom.nodesBase[0]}`, - borderBottom: `6px solid ${theme.palette.custom.elements.function[0]}`, - }} - > - <div className={styles.functionWrapper}>{rows}</div> - </div> - <div className={`${styles.entity} entityWrapper ${entity === undefined ? 'hidden' : ''}`}> - <Handle - id={Handles.FromAttribute} - type="source" - position={Position.Bottom} - className={styles.entityHandleLeft + ' ' + (false ? styles.handleConnectedFill : '')} - /> - <Handle - id={Handles.ToAttribute} - type="source" - position={Position.Bottom} - className={styles.entityHandleBottom + ' ' + (false ? styles.handleConnectedFill : '')} - /> - <div className={styles.entityWrapper}> - <span className={styles.entitySpan}>{entity ? entity : ''}</span> - </div> - </div> - </div> - ); -} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/index.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/index.ts deleted file mode 100644 index 3785778d3f39f91150faaa2df086c695ac8c766f..0000000000000000000000000000000000000000 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/functionpill/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './functionpill'; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/index.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/index.ts index 22ce04749a394b0e823e421a57b6fed3370e1358..9587dafcef70cd31f38a874d05dffaa6fee21fac 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/index.ts +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/index.ts @@ -1,3 +1,2 @@ -export * from './attributepill'; export * from './entitypill'; export * from './relationpill'; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss index 81e3710c83b8462aeabfba66f132a52991ea5f0f..d4090da752aa4c8a5b54970c72cabcb153bef568 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.module.scss @@ -1,28 +1,29 @@ @import '../../querypills.module.scss'; .logic { - color: '#181520'; - // background-color: #e68067; - background-color: #fdfdfd; - border: #e68067 solid 1px; - border-radius: 2px; - font-family: monospace; + text-align: center; font-weight: bold; - font-size: 10; + border-left: 3px solid; + @apply border-l-logic-600; + @apply bg-logic-100; + font-size: 13px; display: flex; - // border-top-right-radius: 5px; - // border-bottom-right-radius: 5px; - // height: 3rem; + min-width: 5rem; + .logicInput { // float: right; // background-color: #ee917a; padding-left: 2px; padding-right: 2px; + margin-top: 5px; width: 3rem; height: 1.2rem; position: relative; left: 0.8rem; bottom: 0.3rem; + border: 1px solid; + border-radius: 0.1rem; + @apply border-logic-600; } .logicSpan { // height: 100%; @@ -32,27 +33,3 @@ // align-items: center; } } - -// .matchlogicTypeSelect { -// float: left; -// background-color: rgba(255, 255, 255, 0.6); -// border-radius: 2px; -// text-align: center; -// & select { -// background: transparent; -// border: none; -// appearance: none; -// font-family: monospace; -// font-weight: bolder; -// color: black; -// font-size: 11; -// } -// & option { -// font-family: monospace; -// font-size: 11px; -// } -// } -// .disable { -// opacity: 1 !important; -// pointer-events: none; -// } diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx index 538e6391a46ad144c4fbabb4be100f7c078aed5c..5e853e044837bea61068d9cf2690e01e36f3096c 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/logicpill/logicpill.tsx @@ -8,31 +8,19 @@ /* The comment above was added so the code coverage wouldn't count this file towards code coverage. * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import React, { useCallback, useMemo } from 'react'; -import { Handle, HandleType, NodeProps, Position } from 'reactflow'; -import styles from './logicpill.module.scss'; -import { - AllLogicMap, - EntityNodeAttributes, - Handles, - LogicData, - LogicNodeAttributes, - QueryGraphEdges, - QueryGraphNodes, - SchemaReactflowLogicNode, - toHandleData, - toHandleId, -} from '../../../model'; -import { Input } from '@mui/material'; -import { styleHandleMap } from '../../utils'; import { setQuerybuilderNodes, useAppDispatch, useQuerybuilderGraph, useQuerybuilderGraphology, + useQuerybuilderHash, } from '@graphpolaris/shared/lib/data-access'; +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { Handle, HandleType, Position } from 'reactflow'; +import { LogicNodeAttributes, SchemaReactflowLogicNode, toHandleId } from '../../../model'; import { InputNode, InputNodeTypeTypes } from '../../../model/logic/general'; -import { SerializedEdge, SerializedNode } from 'graphology-types'; +import { styleHandleMap } from '../../utils'; +import styles from './logicpill.module.scss'; /** * Component to render an entity flow element @@ -46,8 +34,14 @@ export default function LogicPill(node: SchemaReactflowLogicNode) { const graph = useQuerybuilderGraph(); const graphology = useQuerybuilderGraphology(); + const graphologyHash = useQuerybuilderHash(); const connectionsToLeft = useMemo(() => graph.edges.filter((edge) => edge.target === node.id), [graph]); const connectionsToRight = useMemo(() => graph.edges.filter((edge) => edge.source === node.id), [graph]); + const graphologyNodeAttributes = useMemo<LogicNodeAttributes | undefined>( + () => (graphology.hasNode(node.id) ? { ...(graphology.getNodeAttributes(node.id) as LogicNodeAttributes) } : undefined), + [node.id] + ); + const [localInputCache, setLocalInputCache] = useState<Record<string, InputNodeTypeTypes>>({ ...graphologyNodeAttributes?.inputs }); if (!data.id) throw new Error('LogicPill: data.id is undefined'); const defaultHandleData = { @@ -57,61 +51,30 @@ export default function LogicPill(node: SchemaReactflowLogicNode) { }; const onInputUpdated = (value: string, input: InputNode, idx: number) => { - let logicNode = { ...(graphology.getNodeAttributes(node.id) as LogicNodeAttributes) }; + let logicNode = { ...graphologyNodeAttributes }; if (!logicNode) throw new Error('LogicPill: logicNode is undefined'); + let logicNodeInputs = { ...logicNode.inputs }; if (logicNodeInputs[input.name] != value) { logicNodeInputs[input.name] = value; logicNode.inputs = logicNodeInputs; graphology.setNodeAttribute<any>(node.id, 'inputs', logicNodeInputs); // FIXME: I'm not sure why TS requires <any> to work here dispatch(setQuerybuilderNodes(graphology.export())); + console.log('updated input', input.name, 'to', value); } }; const createLeftHandles = useCallback( - (sideInputs: InputNode[], positionSide: Position, handleType: HandleType) => { - let numOfInputs = 0; - let ret = sideInputs.map((input, i) => { - let inputTextBox = null; - if ( - !connectionsToLeft.some( - (edge) => - edge?.attributes?.targetHandleData.nodeId === data.id && edge?.attributes?.targetHandleData.attributeName === input.name - ) - ) { - inputTextBox = ( - <Input - className={styles.logicInput} - // value={0} - style={{ top: -5, transform: `translateY(-${i * 20}%)` }} - // onChange={(e) => onInputUpdated(e.target.value, input)} - onKeyDown={(e) => { - if (e.key === 'Enter') onInputUpdated((e.target as HTMLInputElement).value, input, i); - }} - onBlur={(e) => onInputUpdated(e.target.value, input, i)} - /> - ); - numOfInputs++; - } - return ( - <Handle - type={handleType} - position={positionSide} - id={toHandleId({ ...defaultHandleData, attributeName: input.name, attributeType: input.type })} // TODO - key={input.name + input.type} - // style={{ top: `${((i + 0.8) / (side.length + 0.6)) * 120}%` }} - style={{ top: `${((i + 0.8) / (sideInputs.length + 0.6)) * 100}%` }} - className={styleHandleMap[input.type]} - > - {inputTextBox} - </Handle> + (sideInputs: InputNode[]) => { + return sideInputs.filter((input, i) => { + return !connectionsToLeft.some( + (edge) => edge?.attributes?.targetHandleData.nodeId === data.id && edge?.attributes?.targetHandleData.attributeName === input.name ); - }); - return { handles: ret, number: numOfInputs }; + }).length; }, [node] ); - const { handles: leftHandles, number: leftInputsNumber } = createLeftHandles(node.data.logic.inputs, Position.Left, 'target'); + const leftInputsNumber = createLeftHandles(node.data.logic.inputs); return ( <div className={styles.logic}> @@ -121,13 +84,47 @@ export default function LogicPill(node: SchemaReactflowLogicNode) { {connectionsToLeft.map((e) => e?.attributes?.sourceHandleData.attributeName)}.{output.name} </span> } - {leftHandles} + {node.data.logic.inputs.map((input, i) => { + let inputTextBox = null; + if ( + !connectionsToLeft.some( + (edge) => + edge?.attributes?.targetHandleData.nodeId === data.id && edge?.attributes?.targetHandleData.attributeName === input.name + ) + ) { + inputTextBox = ( + <input + className={styles.logicInput} + value={localInputCache?.[input.name] as string} + style={{ top: -5, transform: `translateY(-${i * 20}%)` }} + onChange={(e) => { + setLocalInputCache({ ...localInputCache, [input.name]: e.target.value }); + }} + onKeyDown={(e) => { + if (e.key === 'Enter') onInputUpdated((e.target as HTMLInputElement).value, input, i); + }} + onBlur={(e) => onInputUpdated(e.target.value, input, i)} + /> + ); + } + return ( + <Handle + type={'target'} + position={Position.Left} + id={toHandleId({ ...defaultHandleData, attributeName: input.name, attributeType: input.type })} + key={input.name + input.type} + style={{ top: `${((i + 0.8) / (node.data.logic.inputs.length + 0.6)) * 100}%` }} + className={styleHandleMap[input.type]} + > + {inputTextBox} + </Handle> + ); + })} {!!node.data.logic.output && ( <Handle type={'source'} position={Position.Right} - id={toHandleId({ ...defaultHandleData, attributeName: output.name, attributeType: output.type })} // TODO - // style={{ top: `${((i + 0.8) / (side.length + 0.6)) * 100}%` }} + id={toHandleId({ ...defaultHandleData, attributeName: output.name, attributeType: output.type })} className={styleHandleMap?.[output.type]} ></Handle> )} diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full_reactflow.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full_reactflow.stories.tsx index 5b6d0c2313a98ec3c9cd1e54b1d44ec3c121bc08..0d7b64dad8a2fe4776d14cd4e9052a20b6e1e7d1 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full_reactflow.stories.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relation-full_reactflow.stories.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { colorPaletteConfigSlice, querybuilderSlice, setQuerybuilderNodes } from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; +import { querybuilderSlice, setQuerybuilderNodes } from '@graphpolaris/shared/lib/data-access/store'; + import { configureStore } from '@reduxjs/toolkit'; import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; @@ -11,19 +11,12 @@ import { QueryElementTypes, QueryMultiGraphology } from '../../../model'; const Component: Meta<typeof QueryBuilder> = { component: QueryBuilder, title: 'Querybuilder/Pills/relationPill', - decorators: [ - (story) => ( - <Provider store={mockStore}> - <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> - </Provider> - ), - ], + decorators: [(story) => <Provider store={mockStore}>{story()}</Provider>], }; // Mock palette store const mockStore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, }, }); diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss index 1f8d81b42bb9dd2606b65c17253f93274824547c..bd38e97d08cb3a012c6a0ea798b56c6c8be879b5 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss @@ -1,317 +1,117 @@ @import '../../querypills.module.scss'; -// .relation { -// display: flex; -// text-align: center; -// font-family: monospace; -// font-weight: bold; -// font-size: 10px; -// background-color: blue; -// } - -.highlighted { - box-shadow: black 0 0 2px; -} - -.contentWrapper { - display: flex; - align-items: center; - - .handleLeft { - position: relative; - z-index: 3; - - top: 25%; - border: 0px; - border-radius: 0px; - - background: transparent; - transform-origin: center; - - width: 0; - height: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-right: rgba(255, 255, 255, 0.7) 6px solid; - - &::after { - content: ''; - display: block; - position: absolute; - width: 0; - height: 0; - border-top: 7px solid transparent; - border-bottom: 7px solid transparent; - border-right: rgba(0, 0, 0, 0.1) 8px solid; - top: -7px; - right: -7px; - } - } - .highlighted { - z-index: -1; - box-shadow: 0 0 2px 1px gray; - } - - .content { - margin: 0 2ch; - padding: 3px 0; - max-width: 20ch; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - // pointer-events: none; - } - - .handleRight { - position: relative; - top: 25%; - border: 0px; - border-radius: 0px; - - background: transparent; - transform-origin: center; - - width: 0; - height: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-left: rgba(255, 255, 255, 0.7) 6px solid; - - &::after { - content: ''; - display: block; - position: absolute; - width: 0; - height: 0; - border-top: 7px solid transparent; - border-bottom: 7px solid transparent; - border-left: rgba(0, 0, 0, 0.1) 8px solid; - top: -7px; - left: -7px; - } - } -} - $height: 10px; -.arrowLeft { - z-index: 2; - width: 0; - height: 0; - border-top: $height solid transparent; - border-bottom: $height solid transparent; - transform: scale(1.028) translate(0.3px 0px); - - border-right: $height solid; -} - -.arrowRight { - width: 0; - height: 0; - border-top: $height solid transparent; - border-bottom: $height solid transparent; - transform: scale(1.02) translate(-0.3px 0px); - - border-left: $height solid; -} - $width: 325; // Relation element + .relation { - position: relative; - display: flex; - width: $width + px; - background: transparent; + min-width: $width + px; text-align: center; - text-decoration: none; - color: black; - box-sizing: border-box; - line-height: 20px; - font-family: monospace; font-weight: bold; - font-size: 11px; + border-left: 3px solid; + @apply bg-relation-50; + @apply border-l-relation-600; + font-size: 13px; } -.rightArrow { - border-style: solid; - border-width: $height 0 $height $height * 1.5; - border-color: transparent transparent transparent black; - margin-top: 0.5; - background: transparent; - display: inline-block; - position: absolute; - right: -$height * 1.5; - transform: translate(-0.2px, 0px) scale(1.02); -} -.leftArrow { - border-style: solid; - border-width: $height $height * 1.5 $height 0; - border-color: transparent black transparent transparent; - margin-top: 0.5; - background: transparent; - display: inline-block; - position: absolute; - z-index: -1; - left: -$height * 1.5; - transform: translate(0.2px, 0px) scale(1.02); -} -.relationTop { - position: absolute; - content: ''; - width: inherit; - left: 0px; - height: $height + px; - z-index: -1; - background-color: #1fa2a2; - transform: perspective(15px) rotateX(5deg); - border-bottom: none; -} -.relationBottom { - position: absolute; - content: ''; - width: inherit; - left: 0px; - height: $height + px; - z-index: -1; - background-color: #1fa2a2; - top: $height + px; - transform: perspective(15px) rotateX(-5deg); - border-top: none; -} .relationWrapper { display: inherit; width: inherit; align-items: center; justify-content: space-between; } -.relationHandleFiller { - flex: 1 1 0; -} -.relationHandleLeft { - // FIRST ONE - position: absolute !important; - border-style: solid !important; - border-width: 6px 10px 6px 0 !important; +.relationHandleTriangle { border-radius: 0px !important; - border-color: transparent rgba(0, 0, 0, 0.3) transparent transparent !important; background: transparent !important; - min-height: 0 !important; - min-width: 0 !important; width: 0 !important; - height: 0px !important; - - &::before { - content: ''; - border-style: solid; - border-width: 4px 7.5px 4px 0; - border-color: transparent rgba(255, 255, 255, 0.6) transparent transparent; - margin-top: 0.5; - background: transparent; - z-index: -1; - display: inline-block; - position: absolute; - top: -4px; - left: 2px; - } -} - -.relationHandleAttribute { - // SECOND ONE - border-radius: 1px !important; - left: 22.5px !important; - background: rgba(255, 255, 255, 0.6) !important; - transform: rotate(45deg) translate(-68%, 0) scale(0.9) !important; - border-color: rgba(22, 110, 110, 1) !important; - border-width: 1px !important; - transform-origin: center, center; + height: 0 !important; + border-left: 5px solid transparent !important; + border-right: 5px solid transparent !important; + border-bottom: 8px solid !important; + @apply border-b-relation-200 #{!important}; } -.relationHandleFunction { - // THIRD ONE - left: 39px !important; - background: rgba(255, 255, 255, 0.6) !important; - border-color: rgba(22, 110, 110, 1) !important; - border-width: 1px !important; - transform-origin: center, center; +.relationHandleLeft { + @extend .relationHandleTriangle; + transform: rotate(-90deg) translate(50%, 150%) !important; } .relationHandleRight { - // LAST ONE - width: 0 !important; - height: 0 !important; - position: absolute !important; - - border-radius: 1px !important; - border-width: 6px 0px 6px 10px !important; - border-color: transparent transparent transparent rgba(0, 0, 0, 0.3) !important; - background: transparent !important; - min-height: 0 !important; - min-width: 0 !important; - - &::before { - content: ''; - border-style: solid; - border-width: 4px 0 4px 7.5px; - border-color: transparent transparent transparent rgba(255, 255, 255, 0.6); - margin-top: 0.5; - background: transparent; - z-index: -1; - display: inline-block; - position: absolute; - top: -4px; - right: 2px; - } -} + @extend .relationHandleTriangle; + transform: rotate(90deg) translate(-50%, 150%) !important; +} + +// .relationHandleAttribute { +// // SECOND ONE +// border-radius: 1px !important; +// left: 22.5px !important; +// background: rgba(255, 255, 255, 0.6) !important; +// transform: rotate(45deg) translate(-68%, 0) scale(0.9) !important; +// border-color: rgba(22, 110, 110, 1) !important; +// border-width: 1px !important; +// transform-origin: center, center; +// } -.relationInputHolder { - display: flex; - float: right; - margin-right: 20px; - margin-top: 4px; - margin-left: 5px; - max-width: 80px; - background-color: rgba(255, 255, 255, 0.6); - border-radius: 2px; - align-items: center; - max-height: 12px; -} -.relationInput { - z-index: 1; - cursor: text; - min-width: 0px; - max-width: 1.5ch; - border: none; - background: transparent; - text-align: center; - font-family: monospace; - font-weight: bold; - font-size: 11px; - color: #181520; - user-select: none; - font-style: italic; - &:focus { - outline: none; - user-select: none; - } - &::placeholder { - outline: none; - user-select: none; - font-style: italic; - } -} -.relationReadonly { - cursor: grab !important; - color: #181520 !important; - user-select: none; - font-style: normal !important; -} -.relationSpan { - float: left; - margin-left: 5; -} +// .relationHandleFunction { +// // THIRD ONE +// left: 39px !important; +// background: rgba(255, 255, 255, 0.6) !important; +// border-color: rgba(22, 110, 110, 1) !important; +// border-width: 1px !important; +// transform-origin: center, center; +// } .relationDataWrapper { display: flex; width: 100%; justify-content: center; + + .relationHandleFiller { + flex: 1 1 0; + } + + .relationSpan { + float: left; + margin-left: 5; + } + + .relationInputHolder { + display: flex; + float: right; + margin-right: 20px; + margin-top: 4px; + margin-left: 5px; + max-width: 80px; + border-radius: 2px; + align-items: center; + max-height: 12px; + + .relationInput { + z-index: 1; + cursor: text; + min-width: 0px; + max-width: 1.5ch; + border: none; + background: transparent; + text-align: center; + font-size: 0.8rem; + user-select: none; + &:focus { + outline: none; + user-select: none; + } + &::placeholder { + outline: none; + user-select: none; + font-style: italic; + } + } + + .relationReadonly { + cursor: grab !important; + user-select: none; + font-style: normal !important; + } + } } diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss.d.ts b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss.d.ts index 2938864f674c166a78f7a5981621e75edeb550d8..55a3ce3a826e9c53c3143e7acdfd95a2043966fa 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss.d.ts +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.module.scss.d.ts @@ -21,28 +21,16 @@ declare const classNames: { readonly handleConnectedBorderRight: 'handleConnectedBorderRight'; readonly handleConnectedBorderLeft: 'handleConnectedBorderLeft'; readonly handleFunction: 'handleFunction'; - readonly highlighted: 'highlighted'; - readonly contentWrapper: 'contentWrapper'; - readonly handleLeft: 'handleLeft'; - readonly content: 'content'; - readonly handleRight: 'handleRight'; - readonly arrowLeft: 'arrowLeft'; - readonly arrowRight: 'arrowRight'; readonly relation: 'relation'; - readonly rightArrow: 'rightArrow'; - readonly leftArrow: 'leftArrow'; - readonly relationTop: 'relationTop'; - readonly relationBottom: 'relationBottom'; readonly relationWrapper: 'relationWrapper'; - readonly relationHandleFiller: 'relationHandleFiller'; - readonly relationHandleLeft: 'relationHandleLeft'; - readonly relationHandleAttribute: 'relationHandleAttribute'; - readonly relationHandleFunction: 'relationHandleFunction'; + readonly relationHandleTriangle: 'relationHandleTriangle'; readonly relationHandleRight: 'relationHandleRight'; + readonly relationHandleLeft: 'relationHandleLeft'; + readonly relationDataWrapper: 'relationDataWrapper'; + readonly relationHandleFiller: 'relationHandleFiller'; + readonly relationSpan: 'relationSpan'; readonly relationInputHolder: 'relationInputHolder'; readonly relationInput: 'relationInput'; readonly relationReadonly: 'relationReadonly'; - readonly relationSpan: 'relationSpan'; - readonly relationDataWrapper: 'relationDataWrapper'; }; export = classNames; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.stories.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.stories.tsx index b288a8764a9e6eb0258571b919c7b30813d1de1b..2dfb0e5371cf830d4ff827059c6e6ea93a19150f 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.stories.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.stories.tsx @@ -3,9 +3,8 @@ import { Meta, StoryObj } from '@storybook/react'; import RelationPill from './relationpill'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; +import { querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; import { ReactFlowProvider } from 'reactflow'; import { RelationData } from '../../../model'; @@ -19,9 +18,7 @@ const Component: Meta<typeof RelationPill> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> + <ReactFlowProvider>{story()}</ReactFlowProvider> </Provider> ), ], @@ -32,7 +29,6 @@ export default Component; // A super-simple mock of a redux store const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, // schema: schemaSlice.reducer, }, @@ -53,7 +49,7 @@ export const Default: StoryObj<{ data: RelationData }> = { // Default.decorators = [ // (story) => ( // <Provider store={Mockstore}> -// <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> +// {story()} // </Provider> // ), // ]; diff --git a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.tsx b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.tsx index 323310f8a6cdd6d1fd5900594a2b5aef5c20895d..90c89512a7df84df25be0dd3fb459766a87c3d26 100644 --- a/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.tsx +++ b/libs/shared/lib/querybuilder/pills/customFlowPills/relationpill/relationpill.tsx @@ -1,19 +1,7 @@ -import React, { memo, useRef, useState } from 'react'; - -import { useTheme } from '@mui/material'; +import { memo, useRef, useState } from 'react'; import { Handle, Position } from 'reactflow'; - +import { SchemaReactflowRelationNode, toHandleId } from '../../../model'; import styles from './relationpill.module.scss'; -import { SchemaReactflowRelationNode, Handles, toHandleId } from '../../../model'; - -// export type RelationRFPillProps = { -// data: { -// name: string; -// suggestedForConnection: any; -// isFromEntityConnected?: boolean; -// isToEntityConnected?: boolean; -// }; -// }; /** * Component to render a relation flow element @@ -21,10 +9,6 @@ import { SchemaReactflowRelationNode, Handles, toHandleId } from '../../../model */ export const RelationPill = memo((node: SchemaReactflowRelationNode) => { const data = node.data; - // export default function RelationRFPill({ data }: { data: any }) { - const theme = useTheme(); - // console.log('RelationRFPill', data); - const minRef = useRef<HTMLInputElement>(null); const maxRef = useRef<HTMLInputElement>(null); @@ -34,7 +18,7 @@ export const RelationPill = memo((node: SchemaReactflowRelationNode) => { const onDepthChanged = (depth: string) => { // Don't allow depth above 99 const limit = 99; - if (data != undefined) { + if (data?.depth != undefined) { data.depth.min = data.depth.min >= limit ? limit : data.depth.min; data.depth.max = data.depth.max >= limit ? limit : data.depth.max; @@ -65,29 +49,11 @@ export const RelationPill = memo((node: SchemaReactflowRelationNode) => { }; return ( - <div className={styles.relation} style={{ backgroundColor: theme.palette.custom.elements.relation[0] }}> - <div className={styles.rightArrow} style={{ borderLeftColor: theme.palette.custom.elements.relation[0] }}></div> - <div className={styles.leftArrow} style={{ borderRightColor: theme.palette.custom.elements.relation[0] }}></div> - {/* <span - className={styles.relationTop} - style={{ backgroundColor: theme.palette.custom.elements.relation[0] }} - ></span> - <span - className={styles.relationBottom} - style={{ backgroundColor: theme.palette.custom.elements.relation[0] }} - ></span> */} + <div className={styles.relation}> <div className={styles.relationWrapper}> - <span - className={styles.relationHandleFiller} - // style={{ transform: 'translate(-100px,0)' }} - > + <span className={styles.relationHandleFiller}> {data.leftEntityHandleId && ( - <Handle - id={toHandleId(data.leftEntityHandleId)} - type="target" - position={Position.Left} - className={styles.relationHandleLeft + ' ' + (false ? styles.handleConnectedBorderLeft : '')} - /> + <Handle id={toHandleId(data.leftEntityHandleId)} type="target" position={Position.Left} className={styles.relationHandleLeft} /> )} </span> {/* <span className={styles.relationHandleFiller}> diff --git a/libs/shared/lib/querybuilder/pills/handles.module.scss b/libs/shared/lib/querybuilder/pills/handles.module.scss index a39b5f8ea31b24060a1cf612dc6ad6ccadc0e86f..aa9f290050aa3d1f30e0f0480bb2a129f13a2e7a 100644 --- a/libs/shared/lib/querybuilder/pills/handles.module.scss +++ b/libs/shared/lib/querybuilder/pills/handles.module.scss @@ -7,16 +7,15 @@ .handle_to_relation { @extend .handle; border-radius: 1px !important; - top: 0.6rem !important; - background: rgb(39, 131, 145) !important; + top: 0.75rem !important; + @apply bg-entity-800 #{!important}; //css-ignore } .handle_from_relation { @extend .handle; border-radius: 1px !important; - // left: 10px !important; - top: 0.55rem !important; - // background: rgba(0, 0, 0, 0.3) !important; + top: 0.75rem !important; + @apply bg-entity-800 #{!important}; //css-ignore } .handle_logic { diff --git a/libs/shared/lib/querybuilder/query-utils/query2backend.spec.ts b/libs/shared/lib/querybuilder/query-utils/query2backend.spec.ts index e99347c6f47572236228dfb87d9744cf726b3dbb..c82c1f65581f799e376a79be6cad5f4cb8383c3e 100644 --- a/libs/shared/lib/querybuilder/query-utils/query2backend.spec.ts +++ b/libs/shared/lib/querybuilder/query-utils/query2backend.spec.ts @@ -1,11 +1,11 @@ import { describe, expect, it } from 'vitest'; // import { Query2BackendQuery } from './query-utils'; -import { BackendQueryFormat, LogicNodeAttributes, MathFilters, MathFunctions, QueryElementTypes } from '../model'; +import { BackendQueryFormat, LogicNodeAttributes, MathFilters, NumberFunctions, QueryElementTypes } from '../model'; import { QueryMultiGraphology } from '../model/graphology/utils'; -import { MathAggregationTypes, MathFilterTypes, MathFunctionTypes } from '../model/logic/general'; +import { NumberAggregationTypes, NumberFilterTypes, NumberFunctionTypes } from '../model/logic/general'; import { Query2BackendQuery, calculateQueryLogic } from './query2backend'; import { SerializedNode } from 'graphology-types'; -import { MathAggregations } from '../model/logic/mathAggregations'; +import { MathAggregations } from '../model/logic/numberAggregations'; const defaultQuery = { databaseName: 'database', @@ -722,7 +722,7 @@ describe('QueryUtils calculateQueryLogic', () => { x: 100, y: 100, name: 'Logic 1', - logic: MathFilters[MathFilterTypes.EQUAL], + logic: MathFilters[NumberFilterTypes.EQUAL], }); graph.addEdge2Graphology(e1, l1, { type: 'connection' }, { sourceHandleName: 'age', targetHandleName: '1' }); @@ -730,7 +730,7 @@ describe('QueryUtils calculateQueryLogic', () => { let logics = graphExport.nodes.filter((n) => n?.attributes?.type === QueryElementTypes.Logic) as SerializedNode<LogicNodeAttributes>[]; const ret = calculateQueryLogic(logics[0], graphExport, logics); - console.log(ret); + // console.log(ret); }); }); @@ -755,7 +755,7 @@ describe('QueryUtils with Logic', () => { x: 100, y: 100, name: 'Logic 1', - logic: MathFilters[MathFilterTypes.EQUAL], + logic: MathFilters[NumberFilterTypes.EQUAL], }); graph.addEdge2Graphology(e1, l1, { type: 'connection' }, { sourceHandleName: 'age', targetHandleName: '1' }); @@ -811,7 +811,7 @@ describe('QueryUtils with Logic', () => { x: 100, y: 100, name: 'Filter EQ', - logic: MathFilters[MathFilterTypes.EQUAL], + logic: MathFilters[NumberFilterTypes.EQUAL], }); const l2 = graph.addLogicPill2Graphology({ @@ -820,12 +820,12 @@ describe('QueryUtils with Logic', () => { x: 100, y: 100, name: 'Logic ADD', - logic: MathFunctions[MathFunctionTypes.ADD], + logic: NumberFunctions[NumberFunctionTypes.ADD], }); graph.addEdge2Graphology(e1, l2, { type: 'connection' }, { sourceHandleName: 'age', targetHandleName: '1' }); graph.addEdge2Graphology(e2, l2, { type: 'connection' }, { sourceHandleName: 'age', targetHandleName: '2' }); - graph.addEdge2Graphology(l2, l1, { type: 'connection' }, { sourceHandleName: MathFilterTypes.EQUAL, targetHandleName: '1' }); + graph.addEdge2Graphology(l2, l1, { type: 'connection' }, { sourceHandleName: NumberFilterTypes.EQUAL, targetHandleName: '1' }); const expected: BackendQueryFormat = { ...defaultQuery, @@ -875,7 +875,7 @@ describe('QueryUtils with Logic', () => { x: 100, y: 100, name: 'Logic LT', - logic: MathFilters[MathFilterTypes.LESS_THAN], + logic: MathFilters[NumberFilterTypes.LESS_THAN], }); const l2 = graph.addLogicPill2Graphology({ @@ -884,11 +884,11 @@ describe('QueryUtils with Logic', () => { x: 100, y: 100, name: 'Logic average', - logic: MathAggregations[MathAggregationTypes.AVG], + logic: MathAggregations[NumberAggregationTypes.AVG], }); graph.addEdge2Graphology(e1, l2, { type: 'connection' }, { sourceHandleName: 'age', targetHandleName: '1' }); - graph.addEdge2Graphology(l2, l1, { type: 'connection' }, { sourceHandleName: MathAggregationTypes.AVG, targetHandleName: '1' }); + graph.addEdge2Graphology(l2, l1, { type: 'connection' }, { sourceHandleName: NumberAggregationTypes.AVG, targetHandleName: '1' }); const expected: BackendQueryFormat = { ...defaultQuery, @@ -931,7 +931,7 @@ describe('QueryUtils with Logic', () => { x: 100, y: 100, name: 'Logic LT', - logic: MathFilters[MathFilterTypes.LESS_THAN], + logic: MathFilters[NumberFilterTypes.LESS_THAN], }, { '2': 5 } ); diff --git a/libs/shared/lib/querybuilder/query-utils/query2backend.ts b/libs/shared/lib/querybuilder/query-utils/query2backend.ts index f4f74943dbd01ac7efa25e1fcc0c39273129efe2..50245ef1df77c10ba3e7ed5ec6a3f8b59132ae09 100644 --- a/libs/shared/lib/querybuilder/query-utils/query2backend.ts +++ b/libs/shared/lib/querybuilder/query-utils/query2backend.ts @@ -124,7 +124,9 @@ export function calculateQueryLogic( if (!connectionToInputRef) { // Not connected, search for set or default value let val = node.attributes.inputs?.[inputRef.name] || inputRef.default; - if (val && inputRef.type === 'string') val = `\"${val}\"`; + if (val && inputRef.type === 'string') { + val = `\"${val}\"`; + } console.log('val', val, inputRef, node); return val; } else if (connectionToInputRef.attributes?.sourceHandleData.nodeType === QueryElementTypes.Logic) { @@ -189,24 +191,11 @@ export function Query2BackendQuery( const newOrigin = graphologyQuery.addNode(origin + 'cycle', graphologyQuery.getNodeAttributes(origin)); const edgeAttributes = graphologyQuery.getEdgeAttributes(target, origin); graphologyQuery.dropEdge(target, origin); - // edgeAttributes.target = newOrigin; graphologyQuery.addEdge(target, newOrigin, edgeAttributes); }); }); - console.log('graph', graph); return Query2BackendQuery(databaseName, graphologyQuery.export()); - - // if ( - // relations.some((entity, i) => { - // return allSimplePaths(graphologyQuery, entity.id, entity.id); - // }) - // ) - // throw Error('Cycles in query are not supported yet'); - // console.log('cycles', cycles); - // return null; - // } - // return null; } // Chunk extraction: traverse graph to find all paths of logic between relations and entities let graphSequenceChunks: QueryGraphNodes[][] = []; @@ -289,7 +278,7 @@ export function Query2BackendQuery( return ret; }); - console.debug('New query', graph, query); + console.info('New query', graph, query); return query; } diff --git a/libs/shared/lib/schema/panel/schema.stories.tsx b/libs/shared/lib/schema/panel/schema.stories.tsx index 79a7114d46f7beed76b8b4ace2074222c9bf8bce..8a91d933736efb5be30685cb4b791d1a14df2a5a 100644 --- a/libs/shared/lib/schema/panel/schema.stories.tsx +++ b/libs/shared/lib/schema/panel/schema.stories.tsx @@ -2,8 +2,8 @@ import React from 'react'; import { Meta, Story, ComponentStory } from '@storybook/react'; import { SchemaUtils } from '@graphpolaris/shared/lib/schema/schema-utils'; -import { colorPaletteConfigSlice, schemaSlice, setSchema } from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; +import { schemaSlice, setSchema } from '@graphpolaris/shared/lib/data-access/store'; + import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; import Schema from './schema'; @@ -30,16 +30,14 @@ const Component: Meta<typeof Schema> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <div - style={{ - width: '100%', - height: '100vh', - }} - > - {story()} - </div> - </GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '100vh', + }} + > + {story()} + </div> </Provider> ), ], @@ -49,7 +47,6 @@ const Component: Meta<typeof Schema> = { const Mockstore = configureStore({ reducer: { schema: schemaSlice.reducer, - colorPaletteConfig: colorPaletteConfigSlice.reducer, }, }); diff --git a/libs/shared/lib/schema/panel/schema.tsx b/libs/shared/lib/schema/panel/schema.tsx index 846faaeeab9806381efa6a450c8d7f8d5ad0092e..def690e907db2e986a0a7af772863c92bd2a031f 100644 --- a/libs/shared/lib/schema/panel/schema.tsx +++ b/libs/shared/lib/schema/panel/schema.tsx @@ -1,8 +1,7 @@ import { AlgorithmToLayoutProvider, AllLayoutAlgorithms, LayoutFactory } from '@graphpolaris/shared/lib/graph-layout'; import { schemaGraphology2Reactflow, schemaExpandRelation } from '@graphpolaris/shared/lib/schema/schema-utils'; -import { useSchemaGraph, useSchemaGraphology, useSchemaLayout } from '@graphpolaris/shared/lib/data-access/store'; -import { MultiGraph } from 'graphology'; -// import { AllLayoutAlgorithms, LayoutFactory } from '@graphpolaris/graph-layout'; +import { useSchemaGraph, useSchemaGraphology, useSchemaLayout, useSessionCache } from '@graphpolaris/shared/lib/data-access/store'; + import { useEffect, useMemo, useRef, useState } from 'react'; import ReactFlow, { ControlButton, @@ -16,26 +15,19 @@ import ReactFlow, { Background, } from 'reactflow'; import CachedIcon from '@mui/icons-material/Cached'; +import SettingsIcon from '@mui/icons-material/Settings'; import 'reactflow/dist/style.css'; import styles from './schema.module.scss'; -import { - EntityFlowElement, - RelationPill, - AttributePill, - ConnectionDragLine, - ConnectionLine, -} from '@graphpolaris/shared/lib/querybuilder/pills'; +import { ConnectionDragLine, ConnectionLine } from '@graphpolaris/shared/lib/querybuilder/pills'; import { EntityNode } from '../pills/nodes/entity/entity-node'; import { RelationNode } from '../pills/nodes/relation/relation-node'; -import { NodeQualityEntityPopupNode } from '../pills/nodes/popup/node-quality-entity-popup'; -import { NodeQualityRelationPopupNode } from '../pills/nodes/popup/node-quality-relation-popup'; -import { AttributeAnalyticsPopupMenu } from '../pills/nodes/popup/attribute-analytics-popup-menu'; import NodeEdge from '../pills/edges/node-edge'; import SelfEdge from '../pills/edges/self-edge'; -import { Card, CardContent, LinearProgress, Typography } from '@mui/material'; +import { useSchemaAPI } from '../../data-access'; +import { SchemaDialog } from './schemaDialog'; interface Props { content?: string; @@ -65,28 +57,23 @@ const edgeTypes = { }; export const Schema = (props: Props) => { + const api_schema = useSchemaAPI(); + const session = useSessionCache(); + + const [toggleSchemaSettings, setToggleSchemaSettings] = useState(false); const [nodes, setNodes, onNodeChanged] = useNodesState([] as Node[]); const [edges, setEdges, onEdgeChanged] = useEdgesState([] as Edge[]); const [firstUserConnection, setFirstUserConnection] = useState<boolean>(true); - const [firstUserConnectionCheck, setFirstUserConnectionCheck] = useState<string | null>(sessionStorage.getItem('firstUserConnection')); const [auth, setAuth] = useState(props.auth); - const [authCheck, setAuthCheck] = useState<boolean | null | undefined>(false); + const settingsIconRef = useRef<SVGSVGElement>(null); + const dialogRef = useRef<HTMLDivElement>(null); // In case the schema is updated const schemaGraphology = useSchemaGraphology(); const schemaGraph = useSchemaGraph(); - // const [schemaGraphology, setSchema] = useState(useSchema()); const schemaLayout = useSchemaLayout(); const layout = useRef<AlgorithmToLayoutProvider<AllLayoutAlgorithms>>(); - // console.log('dbSchema', schemaGraphology.edges()); - // useEffect(() => { - // console.log('dbSchema', schemaGraphology, schemaGraphology.order); - // }, [schemaGraphology]); - - const toggleNodeQualityPopup = (id: string) => {}; - const toggleAttributeAnalyticsPopupMenu = (id: string) => {}; - function updateLayout() { const layoutFactory = new LayoutFactory(); layout.current = layoutFactory.createLayout(schemaLayout as AllLayoutAlgorithms); // TODO: more layouts here @@ -101,27 +88,6 @@ export const Schema = (props: Props) => { setAuth(props.auth); }, [props.auth]); - useEffect(() => { - setAuthCheck(auth); - }, [auth]); - - useEffect(() => { - if (authCheck) { - if (!firstUserConnectionCheck || firstUserConnectionCheck === 'true') { - setFirstUserConnection(true); - } else { - setFirstUserConnection(false); - } - setTimeout(() => { - let sessionStorageUserConnection = sessionStorage.getItem('firstUserConnection'); - if (sessionStorageUserConnection && sessionStorageUserConnection === 'true') { - sessionStorage.setItem('firstUserConnection', 'false'); - setFirstUserConnection(false); - } - }, 5000); - } - }, [authCheck]); - useEffect(() => { if (schemaGraphology == undefined || schemaGraphology.order == 0) { return; @@ -132,6 +98,7 @@ export const Schema = (props: Props) => { updateLayout(); const expandedSchema = schemaExpandRelation(schemaGraphology); layout.current?.layout(expandedSchema); + console.log(expandedSchema); const schemaFlow = schemaGraphology2Reactflow(expandedSchema); @@ -161,49 +128,37 @@ export const Schema = (props: Props) => { // console.log(nodes, edges); + useEffect(() => { + console.log(settingsIconRef.current?.getBoundingClientRect()); + if (dialogRef.current && settingsIconRef.current) { + dialogRef.current.style.top = `${settingsIconRef.current.getBoundingClientRect().top}px`; + dialogRef.current.style.left = `${settingsIconRef.current.getBoundingClientRect().left + 30}px`; + } + }, [settingsIconRef, dialogRef, toggleSchemaSettings]); + return ( - <div className={styles.schemaPanel}> - {firstUserConnection && ( - <Card - variant="outlined" - sx={{ - width: '20rem', - marginTop: 3, - zIndex: 9, - backgroundColor: '#ffffff', - position: 'absolute', - }} - > - <CardContent> - <Typography sx={{ fontSize: 20 }} color="text.secondary"> - Press "space" while you move the schema - </Typography> - <LinearProgress - sx={{ - color: (theme) => theme.palette.grey[theme.palette.mode === 'light' ? 200 : 800], - }} - /> - </CardContent> - </Card> - )} - {nodes.length === 0 && <p>DEBUG: No Elements</p>} + <div className="w-full h-full"> + <SchemaDialog open={toggleSchemaSettings} onClose={() => setToggleSchemaSettings(false)} ref={dialogRef} /> + <h1 className="h-[1rem]">Schema</h1> + {nodes.length === 0 && <p>No Elements</p>} <ReactFlowProvider> - <ReactFlow - onlyRenderVisibleElements={false} - nodesDraggable={false} - nodeTypes={nodeTypes} - edgeTypes={edgeTypes} - connectionLineComponent={ConnectionDragLine} - onNodesChange={onNodeChanged} - onEdgesChange={onEdgeChanged} - nodes={nodes} - edges={edges} - onInit={onInit} - panOnDrag={false} - attributionPosition="top-right" - > - <Controls showInteractive={false} showZoom={false} showFitView={true} className={styles.controls}> - {/* <ControlButton + <div className="h-[calc(100%-.8rem)] w-full"> + <ReactFlow + onlyRenderVisibleElements={false} + nodesDraggable={false} + nodeTypes={nodeTypes} + edgeTypes={edgeTypes} + connectionLineComponent={ConnectionDragLine} + onNodesChange={onNodeChanged} + onEdgesChange={onEdgeChanged} + nodes={nodes} + edges={edges} + onInit={onInit} + panOnDrag={false} + attributionPosition="top-right" + > + <Controls showInteractive={false} showZoom={false} showFitView={true} className={styles.controls}> + {/* <ControlButton className={styles.exportButton} title={'Export graph schema'} onClick={(event) => { @@ -216,26 +171,32 @@ export const Schema = (props: Props) => { > <img src={exportIcon} width={21}></img> </ControlButton> */} - <ControlButton - className={styles.exportButton} - title={'Refresh graph schema'} - onClick={(event) => { - event.stopPropagation(); - }} - > - <CachedIcon /> - </ControlButton> - </Controls> - </ReactFlow> + <ControlButton + className={styles.exportButton} + title={'Refresh graph schema'} + onClick={(event) => { + event.stopPropagation(); + api_schema.RequestSchema(session.currentDatabase); + }} + > + <CachedIcon /> + </ControlButton> + <ControlButton + className={styles.exportButton} + title={'Open Settings'} + onClick={(event) => { + event.stopPropagation(); + setToggleSchemaSettings(!toggleSchemaSettings); + }} + > + <SettingsIcon ref={settingsIconRef} /> + </ControlButton> + </Controls> + </ReactFlow> + </div> </ReactFlowProvider> </div> ); }; export default Schema; - -// Fix layout of the schema -// create reactflow elements on xy coords -// connect reactflow elements together - -// maybe ook gelijk instellingen knoppie fixen op alle panels diff --git a/libs/shared/lib/schema/panel/schemaDialog.tsx b/libs/shared/lib/schema/panel/schemaDialog.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e2bb5ffd846143403d1c0de8ee2c0866bca16d92 --- /dev/null +++ b/libs/shared/lib/schema/panel/schemaDialog.tsx @@ -0,0 +1,78 @@ +import { PropsWithChildren, useEffect, useRef } from 'react'; +import { Dialog, DialogProps } from '../../components/Dialog'; +import React from 'react'; +import CloseIcon from '@mui/icons-material/Close'; + +export const SchemaDialog = React.forwardRef<HTMLDivElement, DialogProps>((props, ref) => { + return ( + <> + {props.open && ( + <div className="absolute top-0 left-10 opacity-100 transition-opacity group-hover:opacity-100 z-50 " ref={ref}> + <div className="card absolute card-bordered bg-white rounded-none"> + <form + className="card-body px-0 w-72 py-5" + onSubmit={(e) => { + e.preventDefault(); + }} + > + <div className="card-title p-5 py-0 flex w-full"> + <h2 className="w-full">Quick Settings</h2> + <button className="btn btn-circle btn-sm btn-ghost" onClick={() => props.onClose()}> + <CloseIcon fontSize="small" /> + </button> + </div> + <div className="divider m-0"></div> + <div className="form-control px-5"> + <label className="label cursor-pointer w-fit gap-2 px-0 py-1"> + <input type="checkbox" checked={true} className="checkbox checkbox-xs" /> + <span className="label-text">Points</span> + </label> + <label className="label cursor-pointer w-fit gap-2 px-0 py-1"> + <input type="checkbox" checked={true} className="checkbox checkbox-xs" /> + <span className="label-text">Line</span> + </label> + <label className="label cursor-pointer w-fit gap-2 px-0 py-1"> + <input type="checkbox" checked={true} className="checkbox checkbox-xs" /> + <span className="label-text">Line</span> + </label> + </div> + <div className="divider m-0"></div> + <div className="form-control px-5"> + <label className="label"> + <span className="label-text">Opacity</span> + </label> + <input type="range" min={0} max="100" value="40" className="range range-sm" /> + </div> + <div className="divider m-0"></div> + <div className="form-control px-5"> + <label className="label"> + <span className="label-text">Histogram</span> + </label> + ... + </div> + <div className="divider m-0"></div> + <div className="form-control px-5"> + <label className="label"> + <span className="label-text">Goal Value</span> + </label> + <select className="select select-primary select-sm "> + <option className="option">35438</option> + </select> + </div> + <div className="divider m-0"></div> + <div className="card-actions w-full px-5"> + <button className="btn btn-primary w-full">Apply</button> + </div> + <div className="card-actions w-full px-5"> + <button className="btn btn-secondary w-full">Cancel</button> + </div> + <div className="card-actions w-full px-5"> + <button className="btn btn-outline w-full">Advance settings</button> + </div> + </form> + </div> + </div> + )} + </> + ); +}); diff --git a/libs/shared/lib/schema/panel/schemaOLD.tsx b/libs/shared/lib/schema/panel/schemaOLD.tsx deleted file mode 100644 index 6f6d33e743615687a0d49b8a19427def6f91ac6c..0000000000000000000000000000000000000000 --- a/libs/shared/lib/schema/panel/schemaOLD.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import { AllLayoutAlgorithms, LayoutFactory } from '@graphpolaris/shared/lib/graph-layout'; -import { schemaGraphology2Reactflow, schemaExpandRelation } from '@graphpolaris/shared/lib/schema/schema-utils'; -import { useSchemaGraphology, useSchemaLayout } from '@graphpolaris/shared/lib/data-access/store'; -import { MultiGraph } from 'graphology'; -// import { AllLayoutAlgorithms, LayoutFactory } from '@graphpolaris/graph-layout'; -import { useEffect, useMemo, useState } from 'react'; -import ReactFlow, { ControlButton, Controls, Node, Edge, ReactFlowProvider, useNodesState, useEdgesState } from 'reactflow'; - -import 'reactflow/dist/style.css'; - -import styles from './schema.module.scss'; - -import { - EntityFlowElement, - RelationPill, - AttributePill, - ConnectionDragLine, - ConnectionLine, -} from '@graphpolaris/shared/lib/querybuilder/pills'; - -interface Props { - content?: string; -} - -const onLoad = (reactFlowInstance: any) => { - setTimeout(() => reactFlowInstance.fitView(), 100); -}; - -const nodeTypes = { - entity: EntityFlowElement, - relation: RelationPill, - attribute: AttributePill, -}; -const edgeTypes = { - connection: ConnectionLine, -}; - -export const Schema = (props: Props) => { - const [nodes, setNodes, onNodeChanged] = useNodesState([] as Node[]); - const [edges, setEdges, onEdgeChanged] = useEdgesState([] as Edge[]); - // In case the schema is updated - const dbschema = useSchemaGraphology(); - // const [dbschema, setSchema] = useState(useSchema()); - const [schemaLayout, setSchemaLayout] = useState(useSchemaLayout()); - - // useEffect(() => { - // console.log('dbSchema', dbschema, dbschema.order); - // }, [dbschema]); - - const expandedSchema = useMemo(() => schemaExpandRelation(dbschema), [dbschema]); - - useEffect(() => { - if (dbschema == undefined || dbschema.order == 0) { - return; - } - - const layoutFactory = new LayoutFactory(); - console.log('schema Layout', schemaLayout, 'order', expandedSchema); - const layout = layoutFactory.createLayout(schemaLayout as AllLayoutAlgorithms); - layout?.layout(expandedSchema); - - const flowElements = schemaGraphology2Reactflow(expandedSchema); - setNodes(flowElements.nodes); - setEdges(flowElements.edges); - console.log('update schema useEffect', dbschema, dbschema.order, flowElements); - }, [dbschema, schemaLayout]); - - const graphStyles = { width: '100%', height: '500px' }; - - // console.log(nodes, edges); - - return ( - <div - style={{ - width: '100%', - height: '100%', - }} - > - {nodes.length === 0 && <p>DEBUG: No Elements</p>} - <ReactFlowProvider> - <ReactFlow - className={styles.schemaPanel} - onlyRenderVisibleElements={false} - nodesDraggable={false} - nodeTypes={nodeTypes} - connectionLineComponent={ConnectionDragLine} - onNodesChange={onNodeChanged} - onEdgesChange={onEdgeChanged} - nodes={nodes} - edges={edges} - style={graphStyles} - onLoad={onLoad} - attributionPosition="top-right" - > - <Controls showInteractive={false} showZoom={false} showFitView={true} className={styles.controls}> - <ControlButton - className={styles.exportButton} - title={'Export graph schema'} - onClick={(event) => { - event.stopPropagation(); - // this.setState({ - // ...this.state, - // exportMenuAnchor: event.currentTarget, - // }); - }} - > - {/* <img src={exportIcon} width={21}></img> */} - </ControlButton> - </Controls> - </ReactFlow> - </ReactFlowProvider> - </div> - ); -}; - -export default Schema; - -// Fix layout of the schema -// create reactflow elements on xy coords -// connect reactflow elements together - -// maybe ook gelijk instellingen knoppie fixen op alle panels diff --git a/libs/shared/lib/schema/pills/edges/node-edge.tsx b/libs/shared/lib/schema/pills/edges/node-edge.tsx index 030980394ca9d6936f87bc81b5fb231a8ce683e6..52114f9a01e70729daf08cc9bc3915960e0ce363 100644 --- a/libs/shared/lib/schema/pills/edges/node-edge.tsx +++ b/libs/shared/lib/schema/pills/edges/node-edge.tsx @@ -11,7 +11,6 @@ import React, { useEffect } from 'react'; import { EdgeProps, getMarkerEnd } from 'reactflow'; import { getCenter } from '@graphpolaris/shared/lib/schema/schema-utils'; -import { useTheme } from '@mui/material'; /** * NodeEdge is used for the edges between the nodes in the schema. * It has a path that is altered depending on the algorithm in the SchemaViewModelImpl. @@ -33,7 +32,6 @@ export default function NodeEdge({ }: EdgeProps) { const offset = data.d; const setRelationNodePosition = data.setRelationNodePosition; - const theme = useTheme(); const [centerX, centerY] = getCenter({ sourceX, @@ -57,7 +55,7 @@ export default function NodeEdge({ }); return ( - <g stroke={theme.palette.custom.logo} strokeWidth={0.5} style={{ pointerEvents: 'none' }}> + <g strokeWidth={0.5} style={{ pointerEvents: 'none' }}> <path type="smoothstep" id={id} diff --git a/libs/shared/lib/schema/pills/edges/self-edge.tsx b/libs/shared/lib/schema/pills/edges/self-edge.tsx index 3ea0bb0050a4f7dd54172667ead9bcb949b62b40..d0c1b217fb226c8d16b3519e393340d5c0cf5762 100644 --- a/libs/shared/lib/schema/pills/edges/self-edge.tsx +++ b/libs/shared/lib/schema/pills/edges/self-edge.tsx @@ -9,7 +9,6 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ import { getCenter } from '@graphpolaris/shared/lib/schema/schema-utils'; -import { useTheme } from '@mui/material'; import React, { useEffect } from 'react'; import { EdgeProps, getMarkerEnd } from 'reactflow'; @@ -34,7 +33,6 @@ export default function SelfEdge({ }: EdgeProps) { const offset = 0; const setRelationNodePosition = data.setRelationNodePosition; - const theme = useTheme(); const [centerX, centerY] = getCenter({ sourceX, @@ -57,14 +55,8 @@ export default function SelfEdge({ } }); - if (style !== undefined) { - style.stroke = theme.palette.custom.builderEdge; - } else { - style = { stroke: theme.palette.custom.builderEdge }; - } - return ( - <g stroke={theme.palette.custom.logo} strokeWidth={0.5} style={{ pointerEvents: 'none' }}> + <g strokeWidth={0.5} style={{ pointerEvents: 'none' }}> <path type="smoothstep" id={id} diff --git a/libs/shared/lib/schema/pills/nodes/entity/entity-node.stories.tsx b/libs/shared/lib/schema/pills/nodes/entity/entity-node.stories.tsx index 0b1d036712f27d66220fc7745938516c4778613e..23db8c9160df65de282c271cfd365e1345d2fb57 100644 --- a/libs/shared/lib/schema/pills/nodes/entity/entity-node.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/entity/entity-node.stories.tsx @@ -1,9 +1,9 @@ import React from 'react'; -import { Meta, Story, ComponentStory } from '@storybook/react'; +import { Meta } from '@storybook/react'; import { SchemaUtils } from '@graphpolaris/shared/lib/schema/schema-utils'; -import { colorPaletteConfigSlice, schemaSlice, setSchema } from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; +import { schemaSlice, setSchema } from '@graphpolaris/shared/lib/data-access/store'; + import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; @@ -20,16 +20,14 @@ const Component: Meta<typeof Schema> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <div - style={{ - width: '100%', - height: '100vh', - }} - > - {story()} - </div> - </GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '100vh', + }} + > + {story()} + </div> </Provider> ), ], @@ -39,7 +37,6 @@ const Component: Meta<typeof Schema> = { const Mockstore = configureStore({ reducer: { schema: schemaSlice.reducer, - colorPaletteConfig: colorPaletteConfigSlice.reducer, }, }); diff --git a/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx b/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx index 49d6a6500fbd5dadd32d2d5b660eee712ef8e82a..81cfe7a4bafc3971e0e0b3c579d61c2a6e125596 100644 --- a/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx +++ b/libs/shared/lib/schema/pills/nodes/entity/entity-node.tsx @@ -12,7 +12,6 @@ import React, { useState } from 'react'; import { Node, Handle, Position, NodeProps } from 'reactflow'; import styles from './entity.module.scss'; import { calcWidthEntityNodeBox, calculateAttributeQuality, calculateEntityQuality } from '@graphpolaris/shared/lib/schema/schema-utils'; -import { useTheme } from '@mui/material'; import { SchemaReactflowNodeWithFunctions } from '../../../model/reactflow'; import { QueryElementTypes } from '@graphpolaris/shared/lib/querybuilder'; @@ -26,7 +25,6 @@ export const EntityNode = React.memo(({ id, data }: NodeProps<SchemaReactflowNod // console.log(data); const [hidden, setHidden] = useState<boolean>(true); - const theme = useTheme(); /** * adds drag functionality in order to be able to drag the entityNode to the schema @@ -54,17 +52,8 @@ export const EntityNode = React.memo(({ id, data }: NodeProps<SchemaReactflowNod }; return ( - <div - className={styles.entityNode} - onDragStart={(event) => onDragStart(event)} - draggable - style={{ - backgroundColor: theme.palette.custom.nodesBase[0], - borderTop: `4px solid ${theme.palette.custom.nodesBase[0]}`, - borderBottom: `6px solid ${theme.palette.custom.elements.entityBase[0]}`, - }} - > - <div + <div className={styles.entityNode} onDragStart={(event) => onDragStart(event)} draggable> + {/* <div className={styles.entityNodeAttributesBox} onClick={() => onClickToggleAttributeAnalyticsPopupMenu()} style={{ @@ -85,8 +74,8 @@ export const EntityNode = React.memo(({ id, data }: NodeProps<SchemaReactflowNod A </span> <span className={styles.nodeSpan}>{data.attributes.length}</span> - </div> - <div + </div> */} + {/* <div className={styles.entityNodeNodesBox} onClick={() => onClickToggleNodeQualityPopup()} style={{ @@ -107,18 +96,20 @@ export const EntityNode = React.memo(({ id, data }: NodeProps<SchemaReactflowNod N </span> <span className={styles.nodeSpan}>{data.nodeCount}</span> - </div> - <Handle + </div> */} + {/* <Handle style={{ pointerEvents: 'none' }} id="entitySourceLeft" position={Position.Left} + className={styles.handleTriangleLeft} type="source" // hidden={Array.from(data.handles).includes('entitySourceLeft') ? false : true} - ></Handle> + ></Handle> */} <Handle style={{ pointerEvents: 'none' }} id="entityTargetLeft" position={Position.Left} + className={styles.handleTriangleLeft} type="target" // hidden={Array.from(data.handles).includes('entityTargetLeft') ? false : true} ></Handle> @@ -126,17 +117,18 @@ export const EntityNode = React.memo(({ id, data }: NodeProps<SchemaReactflowNod style={{ pointerEvents: 'none' }} id="entitySourceRight" position={Position.Right} + className={styles.handleTriangleRight} type="source" // hidden={Array.from(data.handles).includes('entitySourceRight') ? false : true} ></Handle> - <Handle + {/* <Handle style={{ pointerEvents: 'none' }} id="entityTargetRight" position={Position.Right} type="target" // hidden={Array.from(data.handles).includes('entityTargetRight') ? false : true} - ></Handle> - <Handle + ></Handle> */} + {/* <Handle style={{ pointerEvents: 'none' }} id="entitySourceTop" position={Position.Top} @@ -149,8 +141,8 @@ export const EntityNode = React.memo(({ id, data }: NodeProps<SchemaReactflowNod position={Position.Top} type="target" // hidden={Array.from(data.handles).includes('entityTargetTop') ? false : true} - ></Handle> - <Handle + ></Handle> */} + {/* <Handle style={{ pointerEvents: 'none' }} id="entitySourceBottom" position={Position.Bottom} @@ -163,11 +155,9 @@ export const EntityNode = React.memo(({ id, data }: NodeProps<SchemaReactflowNod position={Position.Bottom} type="target" // hidden={Array.from(data.handles).includes('entityTargetBottom') ? false : true} - ></Handle> + ></Handle> */} <div className={styles.nodeWrapper}> - <span className={styles.nodeData} style={{ color: theme.palette.custom.elementText }}> - {id} - </span> + <span className={styles.nodeData}>{id}</span> </div> </div> ); diff --git a/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss b/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss index 4f04b7071fa41b1f194b53a742e2bcb17afc5cef..6c88a9becfd34a52a0972ba5554bd06910607741 100644 --- a/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss +++ b/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss @@ -1,14 +1,11 @@ @import '../schema-pills.module.scss'; .entityNode { - background: #e9e9e9; - display: flex; - border-radius: 1px; - font-family: monospace; - font-weight: bold; - font-size: 11px; - width: 165px; - line-height: 20px; + border-left: 3px solid; + @apply bg-offwhite-200; + @apply border-l-entity-600; + min-width: 8rem; + font-size: 13px; } .entityNodeAttributesBox { @@ -22,6 +19,28 @@ text-align: right; } +.handleTriangle { + border-radius: 0px !important; + background: transparent !important; + width: 0 !important; + height: 0 !important; + border-left: 5px solid transparent !important; + border-right: 5px solid transparent !important; + border-bottom: 8px solid !important; + @apply border-b-base-300 #{!important}; +} + +.handleTriangleLeft { + @extend .handleTriangle; + transform: rotate(-90deg) translate(50%, -55%) scale(0.65) !important; +} + +.handleTriangleRight { + @extend .handleTriangle; + transform: rotate(90deg) translate(-50%, -45%) scale(0.65) !important; + @apply border-b-entity-300 #{!important}; +} + // nodeWrapper: { // display: 'inherit', // color: SchemaThemeHolder.entity.textColor, diff --git a/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss.d.ts b/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss.d.ts index 9610a5664f0b4404bfa1a2a3aaa88cd1f1b40b2f..ad5150215e515f585e2005bf915fd7282b631f43 100644 --- a/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss.d.ts +++ b/libs/shared/lib/schema/pills/nodes/entity/entity.module.scss.d.ts @@ -5,5 +5,8 @@ declare const classNames: { readonly nodeData: 'nodeData'; readonly entityNode: 'entityNode'; readonly entityNodeAttributesBox: 'entityNodeAttributesBox'; + readonly handleTriangle: 'handleTriangle'; + readonly handleTriangleRight: 'handleTriangleRight'; + readonly handleTriangleLeft: 'handleTriangleLeft'; }; export = classNames; diff --git a/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.stories.tsx b/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.stories.tsx index ad5a59f0d2f2be9abe09bf6deaba2d6f6832a236..cda94217032d8ac20e1cfd08f91596582aa96ad2 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.stories.tsx @@ -2,9 +2,8 @@ import React from 'react'; import { Meta, StoryObj } from '@storybook/react'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; +import { querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; import { ReactFlowProvider } from 'reactflow'; import { AttributeAnalyticsPopupMenu } from './attribute-analytics-popup-menu'; import { AttributeCategory, NodeType } from '../../../model/reactflow'; @@ -19,9 +18,7 @@ const Component: Meta<typeof AttributeAnalyticsPopupMenu> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> + <ReactFlowProvider>{story()}</ReactFlowProvider> </Provider> ), ], @@ -32,7 +29,6 @@ export default Component; // A super-simple mock of a redux store const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, // schema: schemaSlice.reducer, }, diff --git a/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.tsx b/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.tsx index 5fbfd9f5b3f84212857c5e2296416b7ea4479372..e8755e486fe1f9e2febc12abb832ffdcadd33add 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/attribute-analytics-popup-menu.tsx @@ -8,7 +8,6 @@ /* The comment above was added so the code coverage wouldn't count this file towards code coverage. * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { ButtonBase, MenuItem, Accordion, AccordionSummary, AccordionDetails, Typography, useTheme } from '@mui/material'; import { ExpandMore, Visibility } from '@mui/icons-material'; import React, { ReactElement } from 'react'; import { AttributeAnalyticsData, AttributeWithData, NodeType } from '../../../model/reactflow'; @@ -20,95 +19,91 @@ import './attribute-analytics-popup-menu.module.scss'; * @param data Input data of type AttributeAnalyticsData, which is for the popup menu. */ export const AttributeAnalyticsPopupMenu = ({ data }: NodeProps<AttributeAnalyticsData>) => { - const theme = useTheme(); - if (data == undefined) throw new Error('No Attribute Analytics data is available for the node.'); - let entityOrRelationBase: [string, string, string]; - if (data.nodeType == NodeType.entity) entityOrRelationBase = theme.palette.custom.elements.entityBase; - else entityOrRelationBase = theme.palette.custom.elements.relationBase; - - let attributesDivs: any[] = []; - if (data.isAttributeDataIn) { - data.attributes.forEach((attributeItem: any) => { - attributesDivs.push( - <Accordion className="attributesAccordion"> - <AccordionSummary className="attribute" expandIcon={<ExpandMore className="expandIcon" />}> - {attributeItem.attribute.name} - </AccordionSummary> - <AccordionDetails className="accordionDetails">{attributeItem.category}</AccordionDetails> - <AccordionDetails className="accordionDetails"> - <span>Null values:</span> - <span - className="nullAmountValue" - style={{ - backgroundColor: entityOrRelationBase[0], - }} - > - {attributeItem.nullAmount}% - </span> - </AccordionDetails> - <AccordionDetails className="accordionDetails"> - <div className="attributeButtons"> - <span>See visualisation</span> - <span className="rightSideValue"> - <Visibility className="visualisationEye" /> - </span> - </div> - </AccordionDetails> - <AccordionDetails className="accordionDetails"> - <div - className="attributeButtons" - onClick={() => data.onClickPlaceInQueryBuilderButton(attributeItem.attribute.name, attributeItem.attribute.type)} - > - <span>Place in query builder</span> - </div> - </AccordionDetails> - </Accordion> - ); - }); - } else { - data.attributes.forEach((attributeItem: AttributeWithData) => { - attributesDivs.push( - <Accordion className="attributesAccordion"> - <AccordionSummary className="attribute" expandIcon={<ExpandMore className="expandIcon" />}> - {attributeItem.attribute.name} - </AccordionSummary> - <AccordionDetails className="accordionDetails"> - <div - className="attributeButtons" - onClick={() => data.onClickPlaceInQueryBuilderButton(attributeItem.attribute.name, attributeItem.attribute.type)} - > - <span>Place in query builder</span> - </div> - </AccordionDetails> - </Accordion> - ); - }); - } - - console.log(data.attributes); - - return ( - <div> - <div className="title"> - <span id="name">Attributes</span> - <span className="rightSideValue">{data.attributes.length}</span> - </div> - <div className="bar">search bar</div> - <div className="bar">filter bar</div> - - <div className="attributesWrapper">{attributesDivs}</div> - - <div className="closeButtonWrapper"> - <ButtonBase - onClick={() => data.onClickCloseButton()} - id="closeButton" - style={{ - backgroundColor: entityOrRelationBase[0], - }} - > - Close - </ButtonBase> - </div> - </div> - ); + return <div></div>; + // const theme = useTheme(); + // if (data == undefined) throw new Error('No Attribute Analytics data is available for the node.'); + // let entityOrRelationBase: [string, string, string]; + // if (data.nodeType == NodeType.entity) entityOrRelationBase = theme.palette.custom.elements.entityBase; + // else entityOrRelationBase = theme.palette.custom.elements.relationBase; + // let attributesDivs: any[] = []; + // if (data.isAttributeDataIn) { + // data.attributes.forEach((attributeItem: any) => { + // attributesDivs.push( + // <Accordion className="attributesAccordion"> + // <AccordionSummary className="attribute" expandIcon={<ExpandMore className="expandIcon" />}> + // {attributeItem.attribute.name} + // </AccordionSummary> + // <AccordionDetails className="accordionDetails">{attributeItem.category}</AccordionDetails> + // <AccordionDetails className="accordionDetails"> + // <span>Null values:</span> + // <span + // className="nullAmountValue" + // style={{ + // backgroundColor: entityOrRelationBase[0], + // }} + // > + // {attributeItem.nullAmount}% + // </span> + // </AccordionDetails> + // <AccordionDetails className="accordionDetails"> + // <div className="attributeButtons"> + // <span>See visualisation</span> + // <span className="rightSideValue"> + // <Visibility className="visualisationEye" /> + // </span> + // </div> + // </AccordionDetails> + // <AccordionDetails className="accordionDetails"> + // <div + // className="attributeButtons" + // onClick={() => data.onClickPlaceInQueryBuilderButton(attributeItem.attribute.name, attributeItem.attribute.type)} + // > + // <span>Place in query builder</span> + // </div> + // </AccordionDetails> + // </Accordion> + // ); + // }); + // } else { + // data.attributes.forEach((attributeItem: AttributeWithData) => { + // attributesDivs.push( + // <Accordion className="attributesAccordion"> + // <AccordionSummary className="attribute" expandIcon={<ExpandMore className="expandIcon" />}> + // {attributeItem.attribute.name} + // </AccordionSummary> + // <AccordionDetails className="accordionDetails"> + // <div + // className="attributeButtons" + // onClick={() => data.onClickPlaceInQueryBuilderButton(attributeItem.attribute.name, attributeItem.attribute.type)} + // > + // <span>Place in query builder</span> + // </div> + // </AccordionDetails> + // </Accordion> + // ); + // }); + // } + // console.log(data.attributes); + // return ( + // <div> + // <div className="title"> + // <span id="name">Attributes</span> + // <span className="rightSideValue">{data.attributes.length}</span> + // </div> + // <div className="bar">search bar</div> + // <div className="bar">filter bar</div> + // <div className="attributesWrapper">{attributesDivs}</div> + // <div className="closeButtonWrapper"> + // <ButtonBase + // onClick={() => data.onClickCloseButton()} + // id="closeButton" + // style={{ + // backgroundColor: entityOrRelationBase[0], + // }} + // > + // Close + // </ButtonBase> + // </div> + // </div> + // ); }; diff --git a/libs/shared/lib/schema/pills/nodes/popup/node-quality-entity-popup.stories.tsx b/libs/shared/lib/schema/pills/nodes/popup/node-quality-entity-popup.stories.tsx index 84a64a45b8dcc278b3b0762c93604ebd5910aeae..2009a5a307129fb1dcf42ee0233d31862798cad3 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/node-quality-entity-popup.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/node-quality-entity-popup.stories.tsx @@ -2,9 +2,8 @@ import React from 'react'; import { Meta } from '@storybook/react'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; +import { querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; import { ReactFlowProvider } from 'reactflow'; import { NodeQualityEntityPopupNode } from './node-quality-entity-popup'; @@ -18,9 +17,7 @@ const Component: Meta<typeof NodeQualityEntityPopupNode> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> + <ReactFlowProvider>{story()}</ReactFlowProvider> </Provider> ), ], @@ -31,7 +28,6 @@ export default Component; // A super-simple mock of a redux store const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, // schema: schemaSlice.reducer, }, diff --git a/libs/shared/lib/schema/pills/nodes/popup/node-quality-entity-popup.tsx b/libs/shared/lib/schema/pills/nodes/popup/node-quality-entity-popup.tsx index 4071f98c7f61d8e855ef1fce21ab945bb345c801..cab64e2dfeab631536de783333d98a66bad9d1c2 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/node-quality-entity-popup.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/node-quality-entity-popup.tsx @@ -9,7 +9,6 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { ButtonBase, useTheme } from '@mui/material'; import React from 'react'; import { NodeProps } from 'reactflow'; import { NodeQualityDataForEntities } from '../../../model/reactflow'; @@ -19,7 +18,6 @@ import { NodeQualityDataForEntities } from '../../../model/reactflow'; * @param data Input data of type NodeQualityDataForEntities, which is for the popup. */ export const NodeQualityEntityPopupNode = ({ data }: NodeProps<NodeQualityDataForEntities>) => { - const theme = useTheme(); if (data == undefined) throw new Error('No node quality data is available for this node.'); if (data.isAttributeDataIn) @@ -40,15 +38,9 @@ export const NodeQualityEntityPopupNode = ({ data }: NodeProps<NodeQualityDataFo </div> </div> <div className="closeButtonWrapper"> - <ButtonBase - onClick={() => data.onClickCloseButton()} - id="closeButton" - style={{ - backgroundColor: theme.palette.custom.elements.entityBase[0], - }} - > + <button onClick={() => data.onClickCloseButton()} id="closeButton"> Close - </ButtonBase> + </button> </div> </div> ); @@ -61,15 +53,9 @@ export const NodeQualityEntityPopupNode = ({ data }: NodeProps<NodeQualityDataFo </div> <div className="information"></div> <div className="closeButtonWrapper"> - <ButtonBase - onClick={() => data.onClickCloseButton()} - id="closeButton" - style={{ - backgroundColor: theme.palette.custom.elements.entityBase[0], - }} - > + <button onClick={() => data.onClickCloseButton()} id="closeButton"> Close - </ButtonBase> + </button> </div> </div> ); diff --git a/libs/shared/lib/schema/pills/nodes/popup/node-quality-relation-popup.stories.tsx b/libs/shared/lib/schema/pills/nodes/popup/node-quality-relation-popup.stories.tsx index a29cba02879bf1317bab6781448690af4c05a299..cf43b5ac90f520e3d29911cd40914b3fa5e10d8b 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/node-quality-relation-popup.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/node-quality-relation-popup.stories.tsx @@ -2,9 +2,8 @@ import React from 'react'; import { Meta } from '@storybook/react'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; +import { querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; import { ReactFlowProvider } from 'reactflow'; import { NodeQualityRelationPopupNode } from './node-quality-relation-popup'; @@ -18,9 +17,7 @@ const Component: Meta<typeof NodeQualityRelationPopupNode> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> + <ReactFlowProvider>{story()}</ReactFlowProvider> </Provider> ), ], @@ -31,7 +28,6 @@ export default Component; // A super-simple mock of a redux store const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, // schema: schemaSlice.reducer, }, diff --git a/libs/shared/lib/schema/pills/nodes/popup/node-quality-relation-popup.tsx b/libs/shared/lib/schema/pills/nodes/popup/node-quality-relation-popup.tsx index a1933b4e1398f188a6bba7495f412b17edbcc661..ad5fe9931743d547f86bc8682d6b14af376ef10f 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/node-quality-relation-popup.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/node-quality-relation-popup.tsx @@ -9,7 +9,6 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { ButtonBase, useTheme } from '@mui/material'; import React from 'react'; import { NodeProps } from 'reactflow'; import { NodeQualityDataForRelations } from '../../../model/reactflow'; @@ -20,7 +19,6 @@ import './node-quality-popup.module.scss'; * @param data Input data of type NodeQualityDataForRelations, which is for the popup. */ export const NodeQualityRelationPopupNode = React.memo(({ data }: NodeProps<NodeQualityDataForRelations>) => { - const theme = useTheme(); if (data == undefined) throw new Error('No node quality data is available for this node.'); if (data.isAttributeDataIn) @@ -45,15 +43,9 @@ export const NodeQualityRelationPopupNode = React.memo(({ data }: NodeProps<Node </div> </div> <div className="closeButtonWrapper"> - <ButtonBase - onClick={() => data.onClickCloseButton()} - id="closeButton" - style={{ - backgroundColor: theme.palette.custom.elements.relationBase[0], - }} - > + <button onClick={() => data.onClickCloseButton()} id="closeButton"> Close - </ButtonBase> + </button> </div> </div> ); @@ -66,15 +58,9 @@ export const NodeQualityRelationPopupNode = React.memo(({ data }: NodeProps<Node </div> <div className="information"></div> <div className="closeButtonWrapper"> - <ButtonBase - onClick={() => data.onClickCloseButton()} - id="closeButton" - style={{ - backgroundColor: theme.palette.custom.elements.relationBase[0], - }} - > + <button onClick={() => data.onClickCloseButton()} id="closeButton"> Close - </ButtonBase> + </button> </div> </div> ); diff --git a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.stories.tsx b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.stories.tsx index 053778e329ec9ca22c5afb921292d28dcd1228bd..75f124ae7151d8ea73ef309bf18aa7f7e8af462e 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.stories.tsx @@ -2,9 +2,8 @@ import React from 'react'; import { Meta, StoryObj } from '@storybook/react'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; +import { querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; import { ReactFlowProvider } from 'reactflow'; import { AttributeAnalyticsPopupMenu } from './attribute-analytics-popup-menu'; import { AttributeCategory, NodeType } from '../../../../model/reactflow'; @@ -19,9 +18,7 @@ const Component: Meta<typeof AttributeAnalyticsPopupMenu> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> + <ReactFlowProvider>{story()}</ReactFlowProvider> </Provider> ), ], @@ -32,7 +29,6 @@ export default Component; // A super-simple mock of a redux store const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, // schema: schemaSlice.reducer, }, @@ -57,7 +53,7 @@ export const Default: Story = { ], isAttributeDataIn: false, onClickCloseButton: () => {}, - onClickPlaceInQueryBuilderButton: (name: string, type) => {}, + onClickPlaceInQueryBuilderButton: (name: string, type: string) => {}, searchForAttributes: (id: string, searchbarValue: string) => {}, resetAttributeFilters: (id: string) => {}, applyAttributeFilters: (id: string, category: AttributeCategory, predicate: string, percentage: number) => {}, diff --git a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.tsx b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.tsx index 6db13f653bc78fc5c1396d275f2c996b6efd9a79..5ef056983dca184b60d49ce6790491b4993c319f 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/attribute-analytics-popup-menu.tsx @@ -9,7 +9,6 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { ButtonBase, Accordion, AccordionSummary, AccordionDetails, useTheme } from '@mui/material'; import { ExpandMore, Visibility } from '@mui/icons-material'; import React, { ReactElement } from 'react'; import { NodeType, AttributeAnalyticsData, AttributeCategory } from '../../../../model/reactflow'; @@ -22,120 +21,114 @@ import { NodeProps } from 'reactflow'; * @param data Input data of type AttributeAnalyticsData, which is for the popup menu. */ export const AttributeAnalyticsPopupMenu = ({ data }: NodeProps<AttributeAnalyticsData>) => { - const theme = useTheme(); - - if (data == undefined) throw new Error('No Attribute Analytics data is available for the node.'); - let entityOrRelationBase: [string, string, string]; - if (data.nodeType == NodeType.entity) entityOrRelationBase = theme.palette.custom.elements.entityBase; - else entityOrRelationBase = theme.palette.custom.elements.relationBase; - - let dataCopy = { ...data }; - let attributesDivs = calculateAttributeDivs(data); - let render = renderPopupMenu(dataCopy, attributesDivs); - return render; - - /** - * Creates the divs of the attributes with their data processed. - * @param attributeData Data that is contained in the attributes. - * @returns A list of divs that contain the appearance and information of the attributes. - */ - function calculateAttributeDivs(attributeData: AttributeAnalyticsData): any[] { - let attributesDivs: any[] = []; - if (attributeData.isAttributeDataIn) { - attributeData.attributes.forEach((attributeItem: any) => { - attributesDivs.push( - <Accordion className="attributesAccordion"> - <AccordionSummary className="attribute" expandIcon={<ExpandMore className="expandIcon" />}> - {attributeItem.attribute.name} - </AccordionSummary> - <AccordionDetails className="accordionDetails">{attributeItem.category}</AccordionDetails> - <AccordionDetails className="accordionDetails"> - <span>Null-values:</span> - <span - className="nullAmountValue" - style={{ - backgroundColor: '#' + entityOrRelationBase[0], - }} - > - {attributeItem.nullAmount}% - </span> - </AccordionDetails> - <AccordionDetails className="accordionDetails"> - <div className="attributeButtons"> - <span>See visualisation</span> - <span className="rightSideValue"> - <Visibility className="visualisationEye" /> - </span> - </div> - </AccordionDetails> - <AccordionDetails className="accordionDetails"> - <div - className="attributeButtons" - onClick={() => attributeData.onClickPlaceInQueryBuilderButton(attributeItem.attribute.name, attributeItem.attribute.type)} - > - <span>Place in query builder</span> - </div> - </AccordionDetails> - </Accordion> - ); - }); - } else { - attributeData.attributes.forEach((attributeItem) => { - attributesDivs.push( - <Accordion className="attributesAccordion"> - <AccordionSummary className="attribute" expandIcon={<ExpandMore className="expandIcon" />}> - {attributeItem.attribute.name} - </AccordionSummary> - <AccordionDetails className="accordionDetails"> - <div - className="attributeButtons" - onClick={() => attributeData.onClickPlaceInQueryBuilderButton(attributeItem.attribute.name, attributeItem.attribute.type)} - > - <span>Place in query builder</span> - </div> - </AccordionDetails> - </Accordion> - ); - }); - } - return attributesDivs; - } - - /** - * Renders the popup-menu. - * @param data This contains the data of the attributes. - * @param attributesDivs This contains the list of divs of the attributes. - */ - function renderPopupMenu(data: AttributeAnalyticsData, attributesDivs: any[]) { - return ( - <div> - <div className="title"> - <span id="name">Attributes</span> - <span className="rightSideValue">{data.attributes.length}</span> - </div> - <Search searchForAttributes={(searchbarValue: string) => data.searchForAttributes(data.nodeID, searchbarValue)} /> - <Filter - data={data} - resetAttributeFilters={() => data.resetAttributeFilters(data.nodeID)} - applyAttributeFilters={(dataType: AttributeCategory, predicate: string, percentage: number) => - data.applyAttributeFilters(data.nodeID, dataType, predicate, percentage) - } - /> - - <div className="attributesWrapper">{attributesDivs}</div> - - <div className="closeButtonWrapper"> - <ButtonBase - onClick={() => data.onClickCloseButton()} - id="closeButton" - style={{ - backgroundColor: '#' + entityOrRelationBase[0], - }} - > - Close - </ButtonBase> - </div> - </div> - ); - } + return <div></div>; + // if (data == undefined) throw new Error('No Attribute Analytics data is available for the node.'); + // let entityOrRelationBase: [string, string, string]; + // if (data.nodeType == NodeType.entity) entityOrRelationBase = theme.palette.custom.elements.entityBase; + // else entityOrRelationBase = theme.palette.custom.elements.relationBase; + // let dataCopy = { ...data }; + // let attributesDivs = calculateAttributeDivs(data); + // let render = renderPopupMenu(dataCopy, attributesDivs); + // return render; + // /** + // * Creates the divs of the attributes with their data processed. + // * @param attributeData Data that is contained in the attributes. + // * @returns A list of divs that contain the appearance and information of the attributes. + // */ + // function calculateAttributeDivs(attributeData: AttributeAnalyticsData): any[] { + // let attributesDivs: any[] = []; + // if (attributeData.isAttributeDataIn) { + // attributeData.attributes.forEach((attributeItem: any) => { + // attributesDivs.push( + // <Accordion className="attributesAccordion"> + // <AccordionSummary className="attribute" expandIcon={<ExpandMore className="expandIcon" />}> + // {attributeItem.attribute.name} + // </AccordionSummary> + // <AccordionDetails className="accordionDetails">{attributeItem.category}</AccordionDetails> + // <AccordionDetails className="accordionDetails"> + // <span>Null-values:</span> + // <span + // className="nullAmountValue" + // style={{ + // backgroundColor: '#' + entityOrRelationBase[0], + // }} + // > + // {attributeItem.nullAmount}% + // </span> + // </AccordionDetails> + // <AccordionDetails className="accordionDetails"> + // <div className="attributeButtons"> + // <span>See visualisation</span> + // <span className="rightSideValue"> + // <Visibility className="visualisationEye" /> + // </span> + // </div> + // </AccordionDetails> + // <AccordionDetails className="accordionDetails"> + // <div + // className="attributeButtons" + // onClick={() => attributeData.onClickPlaceInQueryBuilderButton(attributeItem.attribute.name, attributeItem.attribute.type)} + // > + // <span>Place in query builder</span> + // </div> + // </AccordionDetails> + // </Accordion> + // ); + // }); + // } else { + // attributeData.attributes.forEach((attributeItem) => { + // attributesDivs.push( + // <Accordion className="attributesAccordion"> + // <AccordionSummary className="attribute" expandIcon={<ExpandMore className="expandIcon" />}> + // {attributeItem.attribute.name} + // </AccordionSummary> + // <AccordionDetails className="accordionDetails"> + // <div + // className="attributeButtons" + // onClick={() => attributeData.onClickPlaceInQueryBuilderButton(attributeItem.attribute.name, attributeItem.attribute.type)} + // > + // <span>Place in query builder</span> + // </div> + // </AccordionDetails> + // </Accordion> + // ); + // }); + // } + // return attributesDivs; + // } + // /** + // * Renders the popup-menu. + // * @param data This contains the data of the attributes. + // * @param attributesDivs This contains the list of divs of the attributes. + // */ + // function renderPopupMenu(data: AttributeAnalyticsData, attributesDivs: any[]) { + // return ( + // <div> + // <div className="title"> + // <span id="name">Attributes</span> + // <span className="rightSideValue">{data.attributes.length}</span> + // </div> + // <Search searchForAttributes={(searchbarValue: string) => data.searchForAttributes(data.nodeID, searchbarValue)} /> + // <Filter + // data={data} + // resetAttributeFilters={() => data.resetAttributeFilters(data.nodeID)} + // applyAttributeFilters={(dataType: AttributeCategory, predicate: string, percentage: number) => + // data.applyAttributeFilters(data.nodeID, dataType, predicate, percentage) + // } + // /> + // <div className="attributesWrapper">{attributesDivs}</div> + // <div className="closeButtonWrapper"> + // <ButtonBase + // onClick={() => data.onClickCloseButton()} + // id="closeButton" + // style={{ + // backgroundColor: '#' + entityOrRelationBase[0], + // }} + // > + // Close + // </ButtonBase> + // </div> + // </div> + // ); + // } }; diff --git a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/filterbar.stories.tsx b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/filterbar.stories.tsx index cb8fa3223a6ea01c73683b813c0b41a58316f15a..852723d38484b7c1c0319a21d14cdfb7367990fb 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/filterbar.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/filterbar.stories.tsx @@ -2,9 +2,8 @@ import React from 'react'; import { Meta } from '@storybook/react'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; +import { querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; import { ReactFlowProvider } from 'reactflow'; import { Filter } from './filterbar'; @@ -15,13 +14,7 @@ const Component: Meta<typeof Filter> = { */ title: 'Schema/Pills/Popups/Menus/Filter', component: Filter, - decorators: [ - (story) => ( - <Provider store={Mockstore}> - <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> - </Provider> - ), - ], + decorators: [(story) => <Provider store={Mockstore}>{story()}</Provider>], }; export default Component; @@ -29,7 +22,6 @@ export default Component; // A super-simple mock of a redux store const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, // schema: schemaSlice.reducer, }, diff --git a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/filterbar.tsx b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/filterbar.tsx index df5f60ea242f62406eb1f28ca1f5d565bd99ac95..6dcaec7b7495c9cd78886099f1cd06072cdd9272 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/filterbar.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/filterbar.tsx @@ -9,7 +9,6 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { Accordion, AccordionDetails, AccordionSummary, ButtonBase, useTheme } from '@mui/material'; import { ExpandMore } from '@mui/icons-material'; import React, { ReactElement, useState } from 'react'; import { AttributeAnalyticsData, AttributeCategory, NodeType } from '../../../../model/reactflow'; @@ -40,8 +39,6 @@ export const Filter = (props: FilterbarProps) => { onHoverResetButton: false, }); - const theme = useTheme(); - /** * Processes the chosen data-type in the new state. * @param event The event that contains the value of the chosen data-type. @@ -134,106 +131,107 @@ export const Filter = (props: FilterbarProps) => { }; let entityOrRelationBase: [string, string, string]; - if (props.data.nodeType == NodeType.entity) entityOrRelationBase = theme.palette.custom.elements.entityBase; - else entityOrRelationBase = theme.palette.custom.elements.relationBase; + // if (props.data.nodeType == NodeType.entity) entityOrRelationBase = theme.palette.custom.elements.entityBase; + // else entityOrRelationBase = theme.palette.custom.elements.relationBase; - let applyButtonColor; - if (state.onHoverApplyButton) applyButtonColor = '#' + entityOrRelationBase[0]; - else applyButtonColor = 'inherit'; + // let applyButtonColor; + // if (state.onHoverApplyButton) applyButtonColor = '#' + entityOrRelationBase[0]; + // else applyButtonColor = 'inherit'; - let resetButtonColor; - if (state.onHoverResetButton) resetButtonColor = '#' + entityOrRelationBase[0]; - else resetButtonColor = 'inherit'; + // let resetButtonColor; + // if (state.onHoverResetButton) resetButtonColor = '#' + entityOrRelationBase[0]; + // else resetButtonColor = 'inherit'; return ( - <div className="bar"> - <Accordion className={['attributesAccordion', 'filterbarAccordion'].join(' ')}> - <AccordionSummary className="filterbarSummary" expandIcon={<ExpandMore className="expandIcon" />}> - Filter bar - </AccordionSummary> - <AccordionDetails className={['accordionDetails', 'accordionDetailsFilterbar'].join(' ')}> - <span>Datatype:</span> - <span> - <select - className={['nullAmountValue', 'dataTypeSelect'].join(' ')} - style={{ - backgroundColor: entityOrRelationBase[0], - }} - value={state.dataTypeValue} - onChange={dataTypeChanged} - > - <option value=""></option> - <option value="Categorical">Categorical</option> - <option value="Numerical">Numerical</option> - <option value="Other">Other</option> - </select> - </span> - </AccordionDetails> - <AccordionDetails className={['accordionDetails', 'accordionDetailsFilterbar'].join(' ')}> - <span>Null-values:</span> - <span - className={['nullAmountValue', 'nullValuesBox'].join(' ')} - style={{ - backgroundColor: entityOrRelationBase[0], - }} - > - <input - className="nullValuesSelect" - style={{ - backgroundColor: entityOrRelationBase[0], - }} - value={state.nullValuesValue} - onChange={nullValuesValueChanged} - type="text" - pattern="[0-9]*" - ></input> - % - </span> - <span> - <select - className={['nullAmountValue', 'dataTypeSelect', 'predicateSelect'].join(' ')} - style={{ - backgroundColor: entityOrRelationBase[0], - }} - value={state.nullValuesPredicate} - onChange={nullValuesPredicateChanged} - > - <option value=""></option> - <option value="Equal">==</option> - <option value="NotEqual">!=</option> - <option value="Smaller"><</option> - <option value="SmallerOrEqual">≤</option> - <option value="Bigger">></option> - <option value="BiggerOrEqual">≥</option> - </select> - </span> - - <ButtonBase - className="attributeButtons" - onClick={() => resetFilters()} - onMouseEnter={toggleHoverReset} - onMouseLeave={toggleHoverReset} - id="resetFiltersButton" - style={{ - backgroundColor: resetButtonColor, - }} - > - Reset - </ButtonBase> - <ButtonBase - className="attributeButtons" - onClick={() => applyFilters()} - onMouseEnter={toggleHoverApply} - onMouseLeave={toggleHoverApply} - id="applyFiltersButton" - style={{ - backgroundColor: applyButtonColor, - }} - > - Apply - </ButtonBase> - </AccordionDetails> - </Accordion> - </div> + <div /> + // <div className="bar"> + // <Accordion className={['attributesAccordion', 'filterbarAccordion'].join(' ')}> + // <AccordionSummary className="filterbarSummary" expandIcon={<ExpandMore className="expandIcon" />}> + // Filter bar + // </AccordionSummary> + // <AccordionDetails className={['accordionDetails', 'accordionDetailsFilterbar'].join(' ')}> + // <span>Datatype:</span> + // <span> + // <select + // className={['nullAmountValue', 'dataTypeSelect'].join(' ')} + // style={{ + // backgroundColor: entityOrRelationBase[0], + // }} + // value={state.dataTypeValue} + // onChange={dataTypeChanged} + // > + // <option value=""></option> + // <option value="Categorical">Categorical</option> + // <option value="Numerical">Numerical</option> + // <option value="Other">Other</option> + // </select> + // </span> + // </AccordionDetails> + // <AccordionDetails className={['accordionDetails', 'accordionDetailsFilterbar'].join(' ')}> + // <span>Null-values:</span> + // <span + // className={['nullAmountValue', 'nullValuesBox'].join(' ')} + // style={{ + // backgroundColor: entityOrRelationBase[0], + // }} + // > + // <input + // className="nullValuesSelect" + // style={{ + // backgroundColor: entityOrRelationBase[0], + // }} + // value={state.nullValuesValue} + // onChange={nullValuesValueChanged} + // type="text" + // pattern="[0-9]*" + // ></input> + // % + // </span> + // <span> + // <select + // className={['nullAmountValue', 'dataTypeSelect', 'predicateSelect'].join(' ')} + // style={{ + // backgroundColor: entityOrRelationBase[0], + // }} + // value={state.nullValuesPredicate} + // onChange={nullValuesPredicateChanged} + // > + // <option value=""></option> + // <option value="Equal">==</option> + // <option value="NotEqual">!=</option> + // <option value="Smaller"><</option> + // <option value="SmallerOrEqual">≤</option> + // <option value="Bigger">></option> + // <option value="BiggerOrEqual">≥</option> + // </select> + // </span> + + // <ButtonBase + // className="attributeButtons" + // onClick={() => resetFilters()} + // onMouseEnter={toggleHoverReset} + // onMouseLeave={toggleHoverReset} + // id="resetFiltersButton" + // style={{ + // backgroundColor: resetButtonColor, + // }} + // > + // Reset + // </ButtonBase> + // <ButtonBase + // className="attributeButtons" + // onClick={() => applyFilters()} + // onMouseEnter={toggleHoverApply} + // onMouseLeave={toggleHoverApply} + // id="applyFiltersButton" + // style={{ + // backgroundColor: applyButtonColor, + // }} + // > + // Apply + // </ButtonBase> + // </AccordionDetails> + // </Accordion> + // </div> ); }; diff --git a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.stories.tsx b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.stories.tsx index 76f59b77c1420e5daf7a8e5bde724d10133fecb0..9bf2cc97f6e863738b995838a22e087af9a20cf9 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.stories.tsx @@ -2,9 +2,8 @@ import React from 'react'; import { Meta } from '@storybook/react'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; +import { querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; import { ReactFlowProvider } from 'reactflow'; import { NodeQualityEntityPopupNode } from './node-quality-entity-popup'; @@ -18,9 +17,7 @@ const Component: Meta<typeof NodeQualityEntityPopupNode> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> + <ReactFlowProvider>{story()}</ReactFlowProvider> </Provider> ), ], @@ -31,7 +28,6 @@ export default Component; // A super-simple mock of a redux store const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, // schema: schemaSlice.reducer, }, diff --git a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.tsx b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.tsx index da68e57ad8e6a0f6cab7dcbe4a01efe15b3d8229..6a98b386fbdc100e943e9f7723f6722db164ba6d 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-entity-popup.tsx @@ -9,7 +9,6 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { ButtonBase, useTheme } from '@mui/material'; import React from 'react'; import { NodeProps } from 'reactflow'; import { NodeQualityDataForEntities } from '../../../../model/reactflow'; @@ -19,7 +18,6 @@ import { NodeQualityDataForEntities } from '../../../../model/reactflow'; * @param data Input data of type NodeQualityDataForEntities, which is for the popup. */ export const NodeQualityEntityPopupNode = ({ data }: NodeProps<NodeQualityDataForEntities>) => { - const theme = useTheme(); if (data == undefined) throw new Error('No node quality data is available for this node.'); if (data.isAttributeDataIn) @@ -40,15 +38,9 @@ export const NodeQualityEntityPopupNode = ({ data }: NodeProps<NodeQualityDataFo </div> </div> <div className="closeButtonWrapper"> - <ButtonBase - onClick={() => data.onClickCloseButton()} - id="closeButton" - style={{ - backgroundColor: theme.palette.custom.elements.entityBase[0], - }} - > + <button onClick={() => data.onClickCloseButton()} id="closeButton"> Close - </ButtonBase> + </button> </div> </div> ); @@ -60,15 +52,9 @@ export const NodeQualityEntityPopupNode = ({ data }: NodeProps<NodeQualityDataFo </div> <div className="information"></div> <div className="closeButtonWrapper"> - <ButtonBase - onClick={() => data.onClickCloseButton()} - id="closeButton" - style={{ - backgroundColor: theme.palette.custom.elements.entityBase[0], - }} - > + <button onClick={() => data.onClickCloseButton()} id="closeButton"> Close - </ButtonBase> + </button> </div> </div> ); diff --git a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-relation-popup.stories.tsx b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-relation-popup.stories.tsx index 33dc68b42d48f85d9c8dd540ca2544bde2a0f0b7..64c65d4876c4bb1552afe954cb9e68eafef198e5 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-relation-popup.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-relation-popup.stories.tsx @@ -2,9 +2,8 @@ import React from 'react'; import { Meta } from '@storybook/react'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; +import { querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; import { ReactFlowProvider } from 'reactflow'; import { NodeQualityRelationPopupNode } from './node-quality-relation-popup'; @@ -18,9 +17,7 @@ const Component: Meta<typeof NodeQualityRelationPopupNode> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <ReactFlowProvider>{story()}</ReactFlowProvider> - </GraphPolarisThemeProvider> + <ReactFlowProvider>{story()}</ReactFlowProvider> </Provider> ), ], @@ -31,7 +28,6 @@ export default Component; // A super-simple mock of a redux store const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, // schema: schemaSlice.reducer, }, diff --git a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-relation-popup.tsx b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-relation-popup.tsx index a851e008501c8112b7e010aa983b2f816ab64fa9..5fb1967e6bd728ead240b27168a984bef0a18d0d 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-relation-popup.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/node-quality-relation-popup.tsx @@ -9,7 +9,6 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { ButtonBase, useTheme } from '@mui/material'; import React from 'react'; import { NodeProps } from 'reactflow'; import { NodeQualityDataForRelations, NodeType } from '../../../../model/reactflow'; @@ -19,7 +18,6 @@ import { NodeQualityDataForRelations, NodeType } from '../../../../model/reactfl * @param data Input data of type NodeQualityDataForRelations, which is for the popup. */ export const NodeQualityRelationPopupNode = ({ data }: NodeProps<NodeQualityDataForRelations>) => { - const theme = useTheme(); if (data == undefined) throw new Error('No node quality data is available for this node.'); if (data.isAttributeDataIn) @@ -44,15 +42,9 @@ export const NodeQualityRelationPopupNode = ({ data }: NodeProps<NodeQualityData </div> </div> <div className="closeButtonWrapper"> - <ButtonBase - onClick={() => data.onClickCloseButton()} - id="closeButton" - style={{ - backgroundColor: theme.palette.custom.elements.relationBase[0], - }} - > + <button onClick={() => data.onClickCloseButton()} id="closeButton"> Close - </ButtonBase> + </button> </div> </div> ); @@ -64,15 +56,9 @@ export const NodeQualityRelationPopupNode = ({ data }: NodeProps<NodeQualityData </div> <div className="information"></div> <div className="closeButtonWrapper"> - <ButtonBase - onClick={() => data.onClickCloseButton()} - id="closeButton" - style={{ - backgroundColor: theme.palette.custom.elements.relationBase[0], - }} - > + <button onClick={() => data.onClickCloseButton()} id="closeButton"> Close - </ButtonBase> + </button> </div> </div> ); diff --git a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/searchbar.stories.tsx b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/searchbar.stories.tsx index c9987ffb42e7da2a58ea3077ca3f71f5aac2db70..abaa5977fb1e5d653ed1e2932b9d0f8f8356870b 100644 --- a/libs/shared/lib/schema/pills/nodes/popup/popupmenus/searchbar.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/popup/popupmenus/searchbar.stories.tsx @@ -2,9 +2,8 @@ import React from 'react'; import { Meta } from '@storybook/react'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; -import { colorPaletteConfigSlice, querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; +import { querybuilderSlice, schemaSlice } from '@graphpolaris/shared/lib/data-access/store'; import { ReactFlowProvider } from 'reactflow'; import { Search } from './searchbar'; @@ -15,13 +14,7 @@ const Component: Meta<typeof Search> = { */ title: 'Schema/Pills/Popups/Menus/Search', component: Search, - decorators: [ - (story) => ( - <Provider store={Mockstore}> - <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> - </Provider> - ), - ], + decorators: [(story) => <Provider store={Mockstore}>{story()}</Provider>], }; export default Component; @@ -29,7 +22,6 @@ export default Component; // A super-simple mock of a redux store const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, querybuilder: querybuilderSlice.reducer, // schema: schemaSlice.reducer, }, diff --git a/libs/shared/lib/schema/pills/nodes/relation/relation-node.stories.tsx b/libs/shared/lib/schema/pills/nodes/relation/relation-node.stories.tsx index 836d745c7f6fd5b8f48067a798d9cbd9a109434c..fc6012764468904474519c1964d472f721179479 100644 --- a/libs/shared/lib/schema/pills/nodes/relation/relation-node.stories.tsx +++ b/libs/shared/lib/schema/pills/nodes/relation/relation-node.stories.tsx @@ -2,8 +2,8 @@ import React from 'react'; import { Meta, Story, ComponentStory } from '@storybook/react'; import { SchemaUtils } from '@graphpolaris/shared/lib/schema/schema-utils'; -import { colorPaletteConfigSlice, schemaSlice, setSchema } from '@graphpolaris/shared/lib/data-access/store'; -import { GraphPolarisThemeProvider } from '@graphpolaris/shared/lib/data-access/theme'; +import { schemaSlice, setSchema } from '@graphpolaris/shared/lib/data-access/store'; + import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; @@ -20,16 +20,14 @@ const Component: Meta<typeof Schema> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <div - style={{ - width: '100%', - height: '100vh', - }} - > - {story()} - </div> - </GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '100vh', + }} + > + {story()} + </div> </Provider> ), ], @@ -39,7 +37,6 @@ const Component: Meta<typeof Schema> = { const Mockstore = configureStore({ reducer: { schema: schemaSlice.reducer, - colorPaletteConfig: colorPaletteConfigSlice.reducer, }, }); diff --git a/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx b/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx index 6eab676f8161c4d7aff9542d67bf7f24f3f9e129..760231dd8ae21feb7a3566a5f0b7b80fc0048b67 100644 --- a/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx +++ b/libs/shared/lib/schema/pills/nodes/relation/relation-node.tsx @@ -11,14 +11,6 @@ import React, { useState } from 'react'; import { Node, Handle, Position, NodeProps } from 'reactflow'; import styles from './relation.module.scss'; -import { - calcWidthEntityNodeBox, - calculateAttributeQuality, - calculateEntityQuality, - calcWidthRelationNodeBox, - calculateRelationQuality, -} from '@graphpolaris/shared/lib/schema/schema-utils'; -import { useTheme } from '@mui/material'; import { SchemaReactflowRelation, SchemaReactflowRelationWithFunctions } from '../../../model/reactflow'; import { QueryElementTypes } from '@graphpolaris/shared/lib/querybuilder'; @@ -29,8 +21,6 @@ import { QueryElementTypes } from '@graphpolaris/shared/lib/querybuilder'; */ export const RelationNode = React.memo(({ id, data }: NodeProps<SchemaReactflowRelationWithFunctions>) => { const [hidden, setHidden] = useState<boolean>(true); - const theme = useTheme(); - // console.log(data); /** * Adds drag functionality in order to be able to drag the relationNode to the schema. @@ -66,55 +56,21 @@ export const RelationNode = React.memo(({ id, data }: NodeProps<SchemaReactflowR data.toggleAttributeAnalyticsPopupMenu(data.collection); }; - const widthExternalBoxes = data.attributes ? calcWidthRelationNodeBox(data.attributes.length, data.nodeCount) : 0; - return ( <div onDragStart={(event) => onDragStart(event)} draggable // style={{ width: 100, height: 100 }} > - <div - className={styles.relationNode} - style={{ - background: theme.palette.custom.nodesBase[0], - borderTop: `4px solid ${theme.palette.custom.nodesBase[0]}`, - borderBottom: `6px solid ${theme.palette.custom.elements.relationBase[0]}`, - }} - > - <div - className={[styles.relationNodeTriangleGeneral, styles.relationNodeTriangleLeft].join(' ')} - style={{ - borderRightColor: theme.palette.custom.nodesBase[0], - }} - ></div> - <div - className={[styles.relationNodeTriangleGeneral, styles.relationNodeSmallTriangleLeft].join(' ')} - style={{ - borderRightColor: theme.palette.custom.elements.relationBase[0], - }} - ></div> - <div - className={[styles.relationNodeTriangleGeneral, styles.relationNodeTriangleRight].join(' ')} - style={{ borderLeftColor: theme.palette.custom.nodesBase[0] }} - ></div> - <div - className={[styles.relationNodeTriangleGeneral, styles.relationNodeSmallTriangleRight].join(' ')} - style={{ - borderLeftColor: theme.palette.custom.elements.relationBase[0], - }} - ></div> + <div className={styles.relationNode}> <Handle - style={{ - pointerEvents: 'none', - borderBottomColor: theme.palette.custom.nodesBase[0], - }} - className={styles.arrowup} + style={{ pointerEvents: 'none' }} + className={styles.handleTriangleTop} id="entitySourceLeft" position={Position.Top} - type="source" + type="target" ></Handle> - <div + {/* <div className={styles.relationNodeAttributesBox} onClick={() => onClickToggleAttributeAnalyticsPopupMenu()} style={{ @@ -134,8 +90,8 @@ export const RelationNode = React.memo(({ id, data }: NodeProps<SchemaReactflowR A </span> <span className={styles.nodeSpan}>{data.attributes.length}</span> - </div> - <div + </div> */} + {/* <div className={styles.relationNodeNodesBox} onClick={() => onClickToggleNodeQualityPopup()} style={{ @@ -155,21 +111,13 @@ export const RelationNode = React.memo(({ id, data }: NodeProps<SchemaReactflowR N </span> <span className={styles.nodeSpan}>{data.nodeCount}</span> - </div> + </div> */} - <div className={styles.nodeWrapper} style={{ backgroundColor: theme.palette.custom.nodesBase[0] }}> + <div className={styles.nodeWrapper}> <span className={styles.nodeData}>{data.collection}</span> </div> - <Handle - className={styles.arrowdown} - style={{ - pointerEvents: 'none', - borderTopColor: theme.palette.custom.elements.relationBase[0], - }} - position={Position.Bottom} - type="target" - ></Handle> + <Handle className={styles.handleTriangleBottom} style={{ pointerEvents: 'none' }} position={Position.Bottom} type="source"></Handle> </div> </div> ); diff --git a/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss b/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss index 37835ab2df17f8a2eda7126d637ca43556904ac6..a059d3a4bd17474a1c75282d7fd47ae18469ce0a 100644 --- a/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss +++ b/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss @@ -3,108 +3,33 @@ $width: 145; .relationNode { - height: 36px; - display: flex; - font-family: monospace; - font-weight: bold; - font-size: 11px; - width: $width + px; - line-height: 20px; + border-left: 3px solid; + @apply bg-offwhite-200; + @apply border-l-relation-600; + min-width: 8rem; + font-size: 13px; } -.relationNodeTriangleGeneral { - position: absolute; - width: 0; - height: 0; - margin: auto 0; - border-style: solid; - border-color: transparent; +.handleTriangle { + border-radius: 0px !important; + background: transparent !important; + width: 0 !important; + height: 0 !important; + border-left: 4px solid transparent !important; + border-right: 4px solid transparent !important; + border-bottom: 6px solid !important; + @apply border-b-base-200 #{!important}; } -.relationNodeTriangleLeft { - transform: translateX(-100%); - top: 0px; - border-width: 18px 24px 18px 0; +.handleTriangleTop { + @extend .handleTriangle; + transform: translate(0, -40%) !important; } -.relationNodeSmallTriangleLeft { - transform: translateX(-100%); - top: 30px; - border-width: 0 8px 6px 0px; -} - -.relationNodeTriangleRight { - transform: translateX($width + px); - top: 0px; - border-width: 18px 0 18px 24px; -} - -.relationNodeSmallTriangleRight { - transform: translateX($width + px); - top: 30px; - border-width: 0 0 6px 8px; -} - -.relationNodeAttributesBox { - position: absolute; - top: -4px; - transform: translateX(($width + 4) + px); - clip-path: polygon(0 0, 100% 0, 100% 100%, 26.5px 100%); - height: 20px; - text-align: right; -} - -.relationNodeNodesBox { - position: absolute; - top: 20px; - transform: translateX(($width + 4) + px); - clip-path: polygon(26.5px 0, 100% 0, 100% 100%, 0 100%); - height: 20px; - text-align: right; -} - -.arrowup { - width: 0; - height: 0; - position: absolute; - left: 50%; - top: -20%; - transform: translateX(-50%); - margin: 0 auto; - background-color: transparent; - border-style: solid; - border-top-width: 0; - border-right-width: 8px; - border-bottom-width: 5px; - border-left-width: 8px; - border-top-color: transparent; - border-right-color: transparent; - border-left-color: transparent; - border-radius: 0; - min-width: auto; - min-height: auto; -} - -.arrowdown { - width: 0; - height: 0; - position: absolute; - left: 50%; - bottom: -20%; - transform: translateX(-50%); - margin: 0 auto; - background-color: transparent; - border-style: solid; - border-top-width: 5px; - border-right-width: 8px; - border-bottom-width: 0; - border-left-width: 8px; - border-right-color: transparent; - border-bottom-color: transparent; - border-left-color: transparent; - border-radius: 0; - min-width: auto; - min-height: auto; +.handleTriangleBottom { + @extend .handleTriangle; + transform: rotate(-180deg) translate(0, -40%) !important; + @apply border-b-relation-700 #{!important}; } .controls { diff --git a/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss.d.ts b/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss.d.ts index d82dc1fd0a883182d8e6ca40494e35837849d187..e2dbf0e7c7f0284448badc4500a89c5e4ab64a0a 100644 --- a/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss.d.ts +++ b/libs/shared/lib/schema/pills/nodes/relation/relation.module.scss.d.ts @@ -4,15 +4,9 @@ declare const classNames: { readonly nodeWrapper: 'nodeWrapper'; readonly nodeData: 'nodeData'; readonly relationNode: 'relationNode'; - readonly relationNodeTriangleGeneral: 'relationNodeTriangleGeneral'; - readonly relationNodeTriangleLeft: 'relationNodeTriangleLeft'; - readonly relationNodeSmallTriangleLeft: 'relationNodeSmallTriangleLeft'; - readonly relationNodeTriangleRight: 'relationNodeTriangleRight'; - readonly relationNodeSmallTriangleRight: 'relationNodeSmallTriangleRight'; - readonly relationNodeAttributesBox: 'relationNodeAttributesBox'; - readonly relationNodeNodesBox: 'relationNodeNodesBox'; - readonly arrowup: 'arrowup'; - readonly arrowdown: 'arrowdown'; + readonly handleTriangle: 'handleTriangle'; + readonly handleTriangleBottom: 'handleTriangleBottom'; + readonly handleTriangleTop: 'handleTriangleTop'; readonly controls: 'controls'; readonly exportButton: 'exportButton'; readonly menuText: 'menuText'; diff --git a/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss b/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss index 7ff638a6af8f377f2845c9935442920fbba3474d..9ff43aef72953b0f0385b9c6b12b5f7026cf033a 100644 --- a/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss +++ b/libs/shared/lib/schema/pills/nodes/schema-pills.module.scss @@ -10,16 +10,17 @@ top: 54%; transform: translateX(50%); border-radius: 1px; - box-shadow: -1px 2px 5px #888888; text-align: right; } .nodeWrapper { display: inherit; color: black; - text-align: center; - justify-content: space-between; - align-items: center; + @apply p-2; + @apply py-1; + // text-align: center; + // justify-content: space-between; + // align-items: center; width: inherit; } diff --git a/libs/shared/lib/schema/schema-utils/schema-backend-models.ts b/libs/shared/lib/schema/schema-utils/schema-backend-models.ts deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/libs/shared/lib/vis/geovis/GeoNodeLinkMap.stories.tsx b/libs/shared/lib/vis/geovis/GeoNodeLinkMap.stories.tsx index 501880b4b672ac4ff09ce3bc58d3751e03657e28..332defe3efc36d3c1bcc30dd20c30bee3f764dd8 100644 --- a/libs/shared/lib/vis/geovis/GeoNodeLinkMap.stories.tsx +++ b/libs/shared/lib/vis/geovis/GeoNodeLinkMap.stories.tsx @@ -2,14 +2,12 @@ import React from 'react'; import GeoNodeLinkMap from './GeoNodeLinkMap'; import { Provider } from 'react-redux'; import { configureStore } from '@reduxjs/toolkit'; -import { GraphPolarisThemeProvider } from '../../data-access/theme'; -import { colorPaletteConfigSlice, graphQueryResultSlice, assignNewGraphQueryResult } from '../../data-access/store'; +import { graphQueryResultSlice, assignNewGraphQueryResult } from '../../data-access/store'; import { flights } from '../../mock-data/query-result/geo-mock-data'; import { Meta } from '@storybook/react'; const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, graphQueryResult: graphQueryResultSlice.reducer, }, }); @@ -20,16 +18,14 @@ const Component: Meta<typeof GeoNodeLinkMap> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <div - style={{ - width: '100%', - height: '100vh', - }} - > - {story()} - </div> - </GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '100vh', + }} + > + {story()} + </div> </Provider> ), ], diff --git a/libs/shared/lib/vis/geovis/GeoNodeLinkMap.tsx b/libs/shared/lib/vis/geovis/GeoNodeLinkMap.tsx index 127b5fc3c4c9eb01fd9d177202d6ff5692993f5f..e8e5225212a785319578152e3117c01ce4bb7868 100644 --- a/libs/shared/lib/vis/geovis/GeoNodeLinkMap.tsx +++ b/libs/shared/lib/vis/geovis/GeoNodeLinkMap.tsx @@ -15,7 +15,6 @@ import { generateBaseLayer } from './layers/BaseLayer'; import { FacetingLayer } from './layers/FacetingLayer'; import { ClusterLayer } from './layers/ClusterLayer'; import { NodeLinkLayer } from './layers/NodeLinkLayer'; -import { useTheme } from '@mui/material'; type Props = { mapType: number; @@ -26,7 +25,6 @@ type Props = { }; export const GeoNodeLinkMap = React.memo(({ mapType = 0, isAggregated, isFanned, nodelink = 'nodelink', brushing = false }: Props) => { - const theme = useTheme(); const [graph, setGraph] = useState<NodeLinkViewModel | null>(null); const [isHovering, setIsHovering] = useState<boolean>(); const [isLoading, setIsLoading] = useState<boolean>(true); diff --git a/libs/shared/lib/vis/nodelink/NodeLinkConfigPanelViewModelImpl.tsx b/libs/shared/lib/vis/nodelink/NodeLinkConfigPanelViewModelImpl.tsx deleted file mode 100644 index 989cc6760d609f00e2f51728d7577cdd7568ad53..0000000000000000000000000000000000000000 --- a/libs/shared/lib/vis/nodelink/NodeLinkConfigPanelViewModelImpl.tsx +++ /dev/null @@ -1,813 +0,0 @@ -// /** -// * This program has been developed by students from the bachelor Computer Science at -// * Utrecht University within the Software Project course. -// * © Copyright Utrecht University (Department of Information and Computing Sciences) -// */ -// -// import { -// GraphType, -// NodeType, -// AssignedColors, -// Colors, -// TypeNode, -// CommunityDetectionNode, -// } from './nodelinkviz.types'; -// import NodeLinkViewModel from './NodeLinkViewModel'; -// import { range } from 'd3'; -// -// export default class NodeLinkConfigPanelViewModelImpl -// { -// //VARIABLES--------------------------------------------------------------------------------------------------------------- -// private graph: GraphType; -// private currentColours: any; -// public nodeLinkViewModel: NodeLinkViewModel; -// private realNodes: NodeType[]; -// private unEditedNodes: NodeType[]; -// private typeNodes: TypeNode[] = []; -// public communityDetectionNodes: CommunityDetectionNode[] = []; -// public assignedColorsTypes: AssignedColors[] = []; -// public assignedColorsCommunityDetection: AssignedColors[] = []; -// private colors: Colors[] = [ -// { -// name: 'Default', -// }, -// { -// name: 'FF0000', -// }, -// { -// name: '0083FF', -// }, -// { -// name: 'FF00F7', -// }, -// ]; -// -// public currentNodeType = 0; -// public currentNodeCommunityDetection = 0; -// -// public getCurrentNodeType(): number { -// return this.currentNodeType; -// } -// public getCurrentNodeCommunityDetection(): number { -// return this.currentNodeCommunityDetection; -// } -// public setCurrentNodeType(num: number): void { -// this.currentNodeType = num; -// } -// public setCurrentNodeCommunityDetection(num: number): void { -// this.currentNodeCommunityDetection = num; -// } -// public getTypeNodes(): TypeNode[] { -// return this.typeNodes; -// } -// public getCommunityDetectionNodes(): CommunityDetectionNode[] { -// return this.communityDetectionNodes; -// } -// public getrealNodes() { -// return this.realNodes; -// } -// public getCurrentColours() { -// return this.currentColours; -// } -// -// public constructor(graph: GraphType, nodeLinkViewModel: NodeLinkViewModel) { -// this.graph = graph; -// this.currentColours = nodeLinkViewModel.currentColours; -// this.nodeLinkViewModel = nodeLinkViewModel; -// this.realNodes = graph.nodes; -// this.unEditedNodes = graph.nodes; -// this.init(); -// } -// -// //INITIALISATION---------------------------------------------------------------------------------------------------------- -// //initialise the visualisation -// -// /**init initializes the visualisation by calling the following functions; -// * makeNodeType: translates the NodeTypes received from the NodeLinkViewModel into collectionNodes (typeNode), -// * applyVisualizations: takes the stored Visualtion objects and applies them to the screen, using helper functions, -// * initializeAssignedColorsTypes: initializeAssignedColorsTypes initializes the AssignedColors for the typeNodes. -// */ -// init() { -// this.makeNodeTypes(); -// this.applyVisualizations(); -// this.initializeAssignedColorsTypes(); -// this.makeNodeCommunityDetection(); -// this.initializeAssignedColorsCommunityDetection(); -// } -// -// /**makeNodeTypes translates the NodeTypes received from the NodeLinkViewModel into collectionNodes (typeNode)*/ -// makeNodeTypes() { -// this.typeNodes = []; -// for (let entry of this.realNodes) { -// let entryType = entry.id.split('/')[0]; -// let node = this.typeNodes.find((x) => x.name == entryType); -// if (node) { -// //if node is already logged -// //then insert any unlogged attribute names -// //loop over realNode attribute names not stored yet, push them on the typeNode -// for (let attr in entry.attributes) { -// if (node.attributes.indexOf(attr) == -1) { -// node.attributes.push(attr); -// } -// } -// } else { -// //if node not in typeNodes yet -// //push all attributes on the typeNode -// let newattributes = []; -// for (let attr in entry.attributes) { -// newattributes.push(attr); -// } -// this.typeNodes.push({ -// name: entryType, -// attributes: newattributes, -// type: entry.type, -// visualisations: [], -// }); -// } -// } -// //this makes sure we don't get a null reference/ not found when currentnode is not set yet -// if (!this.nodeIsSet() && this.typeNodes[0]) { -// if (this.typeNodes[0].type) { -// this.setCurrentNodeType(this.typeNodes[0].type); -// } -// } -// } -// -// /**to prevent uninitialised errors when no diagram is present */ -// nodeIsSet() { -// for (let i in range(this.typeNodes.length)) { -// let n = this.typeNodes[i as any]; -// if (this.currentNodeType == n.type) { -// return true; -// } -// } -// return false; -// } -// -// /**makeNodeCommunityDetection translates the nodes from the NodeLinkViewModel into communityDetectionNodes*/ -// makeNodeCommunityDetection() { -// let numberOfClusters = this.graph.numberOfMlClusters; -// if (numberOfClusters) { -// for (let i = 0; i < numberOfClusters; i++) { -// this.communityDetectionNodes.push({ cluster: i + 1 }); -// } -// } -// } -// -// /**initializeAssignedColorsTypes initializes the AssignedColors for the typeNodes*/ -// initializeAssignedColorsTypes() { -// this.assignedColorsTypes = []; -// for (let j in range(this.typeNodes.length)) { -// let type = this.typeNodes[j as any].type; -// let defaultcolor = '000000'; -// //check if both currentColours and type are not undefined -// if (this.currentColours && type) { -// defaultcolor = this.currentColours.nodes[type]; -// } -// -// this.assignedColorsTypes.push({ -// collection: this.typeNodes[j].type, -// color: 'Default', -// default: defaultcolor, -// }); -// } -// } -// -// /**initializeAssignedColorsCommunityDetection initializes the AssignedColors for the communityDetectionNodes*/ -// initializeAssignedColorsCommunityDetection() { -// this.assignedColorsCommunityDetection = []; -// for (let j in range(this.communityDetectionNodes.length)) { -// let cluster = this.communityDetectionNodes[j].cluster; -// let defaultcolor = '000000'; -// if (this.currentColours) { -// defaultcolor = this.currentColours.nodes[cluster]; -// } -// -// this.assignedColorsCommunityDetection.push({ -// collection: this.communityDetectionNodes[j].cluster, -// color: 'Default', -// default: defaultcolor, -// }); -// } -// } -// -// //APPLYING VISUALISATIONS------------------------------------------------------------------------------------------------- -// /**handleVis takes all the currently said menu options and generates a new Visualisation, placing it in the correct typeNode */ -// handleVis() { -// //retrieve the currently selected attribute (so not from memory) -// let attr = this.getSelectedAttr(); -// //get the currently set Vis -// let vis = this.getSelectedVis(); -// //Set visualistation to the selected attribute and visualisation method -// let node = this.typeNodes.find((x) => x.type == this.currentNodeType); -// if (node) { -// let newVis = { attribute: attr, vis: vis }; -// if (vis != 'none') { -// let currentVis = node.visualisations.find((x) => x.attribute == attr); -// //check if this attr is already visualised -// if (currentVis) { -// let index = node.visualisations.indexOf(currentVis); -// node.visualisations[index] = newVis; -// } -// -// let conflictingVis = node.visualisations.find((x) => x.vis == vis); -// //check if this visualisation is already in use (for combining multiple visualisations per nodetype) -// if (conflictingVis) { -// let index = node.visualisations.indexOf(conflictingVis); -// node.visualisations.splice(index, 1); -// node.visualisations.push(newVis); -// } -// //else a new visualisation -// else { -// node.visualisations.push(newVis); -// } -// } else { -// let current = node.visualisations.find((x) => x.attribute == attr); -// if (current) { -// let index = node.visualisations.indexOf(current); -// node.visualisations[index] = newVis; -// } -// } -// } -// this.applyVisualizations(); -// } -// -// /**applyVisualizations takes the stored Visualtion objects and applies them to the screen, using helper functions */ -// applyVisualizations() { -// //remove all currently made changes to the NodeType[] nodes -// this.resetRadiusNodes(); -// -// //iterate over typeNodes -// for (let i in range(this.typeNodes.length)) { -// let visualisations = this.typeNodes[i].visualisations; -// let nodeType = this.typeNodes[i].name; -// if (visualisations) { -// for (let i in range(visualisations.length)) { -// let vis = visualisations[i]; -// let attr = vis.attribute; -// let attrVal = 1; -// -// //todo check attrVal for real and make sure vis is compatible with said value -// // if number visualization -// if (typeof attrVal === 'number') { -// this.applyNumericalAttribute(nodeType, attr, vis.vis); -// } -// // other visualisations -// else { -// //todo implement some other visualisations -// } -// } -// } -// } -// this.nodeLinkViewModel.UpdateRadius( -// this.graph, -// //this.nodeLinkViewModel.graph, -// this.nodeLinkViewModel.radius -// ); -// } -// -// /**applyNumericalAttributes handles all numerical related visualisations like age, seniority, seats, amounts etc*/ -// applyNumericalAttribute(nodetype: string, attr: string, vis: string) { -// //scaling function -// let scale = this.calcScale(attr); -// -// let localNode = this.typeNodes.find((x) => x.name == nodetype); -// if (localNode) { -// //all realNodes that belong to this collection -// let realNodes = -// this.realNodes.filter((x) => x.id.split('/')[0] == localNode?.name) || -// this.typeNodes[0]; -// for (let j in range(realNodes.length)) { -// let realNode = realNodes[j]; -// if (vis == 'radius') { -// this.applyRadiusAttr(attr, realNode, scale); -// } -// } -// } -// this.nodeLinkViewModel.UpdateRadius(this.graph, 5); -// } -// -// /**applyRadiusAttr gives nodes a radius based on their value. Expects a scaling function*/ -// applyRadiusAttr( -// attr: string, -// realNode: NodeType, -// scale: (x: number) => number -// ) { -// let scaleAuto = scale; -// -// if (realNode.attributes != undefined) { -// let attributeValue = realNode.attributes[attr]; -// if (attributeValue) { -// realNode.radius = scaleAuto(attributeValue); -// } -// } -// } -// /**calScale is a higher order helper function for applyRadiusAttr/applyNumericalattribute, which returns a linear scaling function */ -// calcScale(attr: string): (x: number) => number { -// //list all values -// let values: number[] = []; -// this.realNodes.forEach((node) => { -// if (node.attributes) { -// if (node.attributes[attr] != undefined) { -// values.push(node.attributes[attr]); -// } -// } -// }); -// //pixel sizes for the nodes -// let maxP = 10; -// let minP = 5; -// //value min/max -// let minX = Math.min(...values); -// let maxX = Math.max(...values); -// let a = (maxP - minP) / (maxX - minX); -// let b = maxP - a * maxX; -// //linear scaling between minP and maxP (based on y = ax + b) -// return (x: number) => a * x + b; -// } -// -// /**applyAssignedColors assigns the chosen colors to the assignedColors(Types/CommunityDetection) holders, -// * which then updates the currentColors. -// * @param colorsBasedOn colorBasedOn is a string which indicates which assignedColors(Types/CommunityDetection) needs to be changed. -// */ -// applyAssignedColors(colorsBasedOn: string) { -// let newNodeColors = this.currentColours.nodes; //holder variable for new node settings -// //different implementation for which assignedColors (Types/CommunityDetection) needs to be changed -// switch (colorsBasedOn) { -// case 'type': { -// for (let j in range(this.assignedColorsTypes.length)) { -// let node = this.assignedColorsTypes[j as any]; -// let node1 = -// this.typeNodes.find((x) => x.type == node.collection) || -// this.typeNodes[0]; //find the node in MockNodes that matches this Assigned color entry -// let type = node1.type; //find the type it belongs to -// //check if current colours and type are initialised, then apply to storage -// if (this.currentColours.nodes && type) { -// if (node?.color != 'Default') { -// newNodeColors[type] = node?.color; //assign the color to the newNodeColors storage -// } else { -// newNodeColors[type] = node.default; -// } -// } -// } -// break; -// } -// case 'communityDetection': { -// for (let j in range(this.assignedColorsCommunityDetection.length)) { -// let node = this.assignedColorsCommunityDetection[j as any]; -// let node1 = -// this.communityDetectionNodes.find( -// (x) => x.cluster == node.collection -// )?.cluster || this.communityDetectionNodes[0].cluster; //find the node in MockNodes that matches this Assigned color entry -// let cluster = node1; //find the cluster it belongs to -// //check if current colours is initialised, then apply to storage -// if (this.currentColours.nodes) { -// if (node?.color != 'Default') { -// newNodeColors[cluster] = node?.color; //assign the color to the newNodeColors storage -// } else { -// newNodeColors[cluster] = node.default; -// } -// } -// } -// break; -// } -// default: { -// } -// } -// //apply the stored colors -// this.currentColours.nodes = newNodeColors; -// this.nodeLinkViewModel.currentColours = this.currentColours; -// this.nodeLinkViewModel.UpdateColours(this.graph, 5); -// } -// -// /**resetRadiusNodes resets the radius of all the nodes to the standardRadius (this.nodeLinkViewModel.radius).*/ -// resetRadiusNodes() { -// let standardRadius = this.nodeLinkViewModel.radius; -// for (let i in range(this.realNodes.length)) { -// this.realNodes[i].radius = standardRadius; -// } -// } -// -// /**use this when deep copy is fixed, for now use the other one*/ -// // resetNodesWIP() { -// // throw new Error('warning not implemented'); -// // this.graph.nodes = this.unEditedNodes; -// // this.realNodes = this.graph.nodes; -// // } -// -// /** initializeMlAttributeValues gets the number of clusters from the NodeLinkViewModel and creates an string array of the different clusters. */ -// initializeMlAttributeValues(): void { -// let mldata = []; -// let numberOfMlClusters = this.graph.numberOfMlClusters; -// // check if not undefined -// if (numberOfMlClusters) { -// for (let index = 0; index < numberOfMlClusters; index++) -// mldata[index] = String(index + 1); -// } -// this.nodeLinkViewModel.uniqueAttributeValues['mldata'] = mldata; -// } -// -// //DOM MANIPULATION-------------------------------------------------------------------------------------------------------- -// /** fill the attribute list with the correct values for the node */ -// generateAttributes() { -// const attributes = this.typeNodes.find( -// (x) => x.type == this.currentNodeType -// )?.attributes; -// const sel = document.getElementById( -// 'attribute-select' -// ) as HTMLSelectElement; -// let opts = sel.options; -// for (let i in range(opts.length)) { -// opts.remove(0); -// } -// if (attributes) { -// for (let j in range(attributes.length)) { -// let newOption = document.createElement('option'); -// newOption.value = attributes[j]; -// newOption.text = attributes[j]; -// opts.add(newOption); -// } -// } -// } -// -// //GENERATORS-------------------------------------------------------------------------------------------------------------- -// /** initial generation for the node select element */ -// nodeSelect() { -// return ( -// <select -// onChange={(e) => this.nodeOnChange(parseInt(e.target.value))} -// defaultValue="" -// > -// <option value="" disabled> -// Node Type -// </option> -// {this.typeNodes.map((node) => ( -// <option key={node.name} value={node.type}> -// {node.name} -// </option> -// ))} -// </select> -// ); -// } -// -// /** initial generation for the attribute select element */ -// attrSelect() { -// return ( -// <select -// id="attribute-select" -// onChange={(e) => { -// this.attrOnChange(e.target.value); -// }} -// defaultValue="" -// > -// <option value="" key="" disabled> -// Attributes -// </option> -// {this.typeNodes -// .find((node) => node.type == this.currentNodeType) -// ?.attributes.map((attributes) => ( -// <option key={attributes}>{attributes}</option> -// ))} -// </select> -// ); -// } -// /** initial generation for the color select element */ -// colorSelect() { -// return ( -// <select -// id="color-select" -// onChange={(e) => { -// this.colorOnChange(e.target.value); -// }} -// defaultValue="Default" -// > -// {this.colors.map((color) => ( -// <option key={color.name} value={color.name}> -// {color.name} -// </option> -// ))} -// </select> -// ); -// } -// -// /** initial generation for the visualisation select element */ -// visSelect() { -// return ( -// <select -// id="visualisation-select" -// onChange={(e) => this.visOnChange(e.target.value)} -// defaultValue="Visualize attribute" -// > -// <option key="none" value="none"> -// Visualize attribute -// </option> -// <option key="radius" value="radius"> -// Radius -// </option> -// </select> -// ); -// } -// -// /** initial generation for the community detection cluster on select element */ -// cdClusterBasedOnSelect() { -// let uniqueValues = this.getUniqueAttributes(); -// return ( -// <select -// // cd = community detection -// id="cd-cluster-select" -// onChange={(e) => this.cdClusterBasedOnOnChange(e.target.value)} -// defaultValue="" -// > -// {uniqueValues.map((attr) => ( -// <option key={attr} value={attr}> -// {attr} -// </option> -// ))} -// </select> -// ); -// } -// -// /** initial generation for the community detection value select element -// * updates when the cluster on select element has been changed. -// */ -// cdValueSelect() { -// this.initializeMlAttributeValues(); -// return ( -// <select -// id="cd-value-select" -// // selectedIndex + 1 so you dont get 0, which is interpreted as 'undefined' -// onChange={(e) => this.cdValueOnChange(e.target.selectedIndex + 1)} -// > -// {this.nodeLinkViewModel.uniqueAttributeValues['mldata'].map( -// (attrValue) => ( -// <option key={attrValue} value={attrValue}> -// {attrValue} -// </option> -// ) -// )} -// </select> -// ); -// } -// -// /** initial generation for the community detection color select element */ -// cdColorSelect() { -// return ( -// <select -// id="cd-color-select" -// onChange={(e) => { -// this.cdColorOnChange(e.target.value); -// }} -// defaultValue="Default" -// > -// {this.colors.map((color) => ( -// <option key={color.name} value={color.name}> -// {color.name} -// </option> -// ))} -// </select> -// ); -// } -// -// //GETTERS--------------------------------------------------------------------------------------------------------------------- -// /** returns value of selected attribute of attribute select element */ -// getSelectedAttr(): string { -// const sel = document.getElementById( -// 'attribute-select' -// ) as HTMLSelectElement; -// return sel.value; -// } -// /** returns value of selected visualisation of visualisation select element */ -// getSelectedVis(): string { -// const sel = document.getElementById( -// 'visualisation-select' -// ) as HTMLSelectElement; -// return sel.value; -// } -// /** returns value of selected cluster of community detection cluster on select element */ -// getSelectedClusterBasedOn(): any { -// const select = document.getElementById( -// 'cd-cluster-select' -// ) as HTMLSelectElement; -// return select.value; -// } -// /** returns unique values of the selected cluster of community detection value select element */ -// getValuesOfSelectedCluster(): any[] { -// const select = document.getElementById( -// 'cd-value-select' -// ) as HTMLSelectElement; -// const options = select.options; -// let values: any[] = []; -// for (let index in range(options.length)) { -// values[index] = options[index].value; -// } -// return values; -// } -// /** returns unique categorical attributes */ -// getUniqueAttributes(): string[] { -// let uniqueAttributes = Object.keys( -// this.nodeLinkViewModel.uniqueAttributeValues -// ); -// // delete 'mldata'. -// uniqueAttributes.forEach((attribute, index) => { -// if (attribute == 'mldata') uniqueAttributes.splice(index, 1); -// }); -// // add 'mldata' to the front, so it appears immediately after sends query with community detection. -// let mldata = ['mldata']; -// return mldata.concat(uniqueAttributes); -// } -// -// //SETTERS------------------------------------------------------------------------------------------------------------------ -// /** set the index of the visualisation select element according to the attribute string. -// * @param attr attr is the attribute the visualisation select element should get set to. -// */ -// setSelectedVis(attr: string) { -// const visualisations = this.typeNodes.find( -// (x) => x.type == this.currentNodeType -// )?.visualisations; //stored vis method -// const val = visualisations?.find((x) => x.attribute == attr)?.vis; -// const sel = document.getElementById( -// 'visualisation-select' -// ) as HTMLSelectElement; -// const opts = sel.options; -// if (val) { -// for (let opt, j = 0; (opt = opts[j]); j++) { -// if (opt.value == val) { -// sel.selectedIndex = j; -// break; -// } -// } -// } else { -// sel.selectedIndex = 0; -// } -// } -// /** Find the selected value in assignedcolors for current node and select it in the dropdown */ -// setSelectedColor() { -// const val = this.assignedColorsTypes.find( -// (x) => x.collection == this.currentNodeType -// )?.color; -// const sel = document.getElementById('color-select') as HTMLSelectElement; -// const opts = sel.options; -// for (let opt, j = 0; (opt = opts[j]); j++) { -// if (opt.value == val) { -// sel.selectedIndex = j; -// break; -// } -// } -// } -// -// /**find the selected value in assignedcolors for current communityDetectionNode -// * and select it in the dropdown of the community detection color select element.*/ -// setSelectedCdColor() { -// const val = this.assignedColorsCommunityDetection.find( -// (x) => x.collection == this.currentNodeCommunityDetection -// )?.color; -// const sel = document.getElementById('cd-color-select') as HTMLSelectElement; -// const opts = sel.options; -// for (let opt, j = 0; (opt = opts[j]); j++) { -// if (opt.value == val) { -// sel.selectedIndex = j; -// break; -// } -// } -// } -// -// //------------------------------------------------------------------------------------------------------------------------ -// //ONCHANGE FUNCTIONS------------------------------------------------------------------------------------------------------ -// /** on switching nodes in the dropdown, update variables and dropdowns. -// * @param numberNodeType numberType is the number of the new nodeType that is selected. -// */ -// nodeOnChange(numberNodeType: number) { -// this.setCurrentNodeType(numberNodeType); -// this.setSelectedColor(); -// this.generateAttributes(); -// this.setSelectedVis(this.getSelectedAttr()); -// this.applyVisualizations(); -// } -// -// /**assign a newly selected color to the currentTypeNode -// * @param targetColor targetColors is the new color that is selected. -// */ -// colorOnChange(targetColor: string) { -// let node = this.assignedColorsTypes.find( -// (x) => x.collection == this.currentNodeType -// ); -// //check if not undefined -// if (node && node.collection) { -// node.color = targetColor; -// this.nodeLinkViewModel.resetClusterOfNodes(node.collection); //reset cluster of nodes which could have been changed by community detection ml algorithm -// } -// this.applyAssignedColors('type'); -// this.applyVisualizations(); -// } -// -// /**retrieve the current visualisation and set the vis dropdown to this, then apply said visualisation -// * @param targetAttribute targetAttribute is the new attribute that is selected. -// */ -// attrOnChange(targetAttribute: string) { -// this.setSelectedVis(targetAttribute); -// this.handleVis(); -// } -// -// /**handle setting a new visualisation -// * @param targetVis targetVis is the new visualisation that is selected. -// */ -// visOnChange(targetVis: string) { -// this.handleVis(); -// return; -// } -// -// /**handle visualisations for community detection based on another categorical attribute. -// * @param targetCluster target is the categorical attribute on which the new clustering is based on. -// */ -// cdClusterBasedOnOnChange(targetCluster: string) { -// let attributeValueSelect = document.getElementById( -// 'cd-value-select' -// ) as HTMLSelectElement; -// this.removeAllOptions(attributeValueSelect); -// let uniqueValues = -// this.nodeLinkViewModel.uniqueAttributeValues[targetCluster]; -// this.addPossibleValuesToSelect(attributeValueSelect, uniqueValues); -// if (targetCluster == 'mldata') { -// for (let i = 0; i < this.realNodes.length; i++) { -// let currentMlData = this.realNodes[i].clusterAccoringToMLData; -// let currentMlDataString = ''; -// // check if not undefined -// if (currentMlData) { -// currentMlDataString = currentMlData.toString(); -// } -// const sameAsCurrentValue = (element: string) => -// element == currentMlDataString; -// let valueIndex = uniqueValues.findIndex(sameAsCurrentValue); -// // save group of node in mldata entry to later reset the group entry to the correct group -// this.realNodes[i].cluster = valueIndex; -// } -// } else { -// for (let i = 0; i < this.realNodes.length; i++) { -// let attributes = this.realNodes[i].attributes; -// if (typeof attributes != 'undefined') { -// let currentValue = attributes[targetCluster as keyof NodeType]; -// const sameAsCurrentValue = (element: string) => -// element == currentValue; -// let clusterIndex = uniqueValues.findIndex(sameAsCurrentValue); -// if (clusterIndex != -1) { -// // clusterIndex + 1 so you dont get 0, which is interpreted as 'undefined'. -// // only if node does not have the attribute on which is being clustered. -// clusterIndex++; -// } -// this.realNodes[i].cluster = clusterIndex; -// } -// } -// } -// this.graph.nodes = this.realNodes; -// this.nodeLinkViewModel.UpdateColours(this.graph, 5); -// //this.makeNodeCommunityDetection(); -// } -// -// /**update the currentNodeCommunityDetection to the selected value -// * and update dropdown of community detection color select element. -// * @param targetClusterValue cluster is the number which represents the selected cluster. -// */ -// cdValueOnChange(targetClusterValue: number) { -// this.setCurrentNodeCommunityDetection(targetClusterValue); -// this.setSelectedCdColor(); -// } -// -// /**assign a newly selected color to the currentCommunityDetectionNode -// * @param targetColor targetColors is the new color that is selected. -// */ -// cdColorOnChange(targetColor: string) { -// let node = this.assignedColorsCommunityDetection.find( -// (x) => x.collection == this.currentNodeCommunityDetection -// ); -// //check if not undefined -// if (node) { -// node.color = targetColor; -// //reset group of nodes which could have been changed by community detection ml algorithm -// } -// this.applyAssignedColors('communityDetection'); -// this.applyVisualizations(); -// } -// -// //HELPER FUNCTIONS----------------------------------------------------------------------------------------------------------- -// /**removeAllOptions removes all options from a select element -// * @param select select is the select element from which all options will be removed. -// */ -// removeAllOptions(select: HTMLSelectElement) { -// let options = select.options; -// while (options.length > 0) { -// select.remove(0); -// } -// } -// -// /**addPossibleValuesToSelect adds all values of a string array as options to a select element -// * @param select select is the select element where new options will be added. -// * @param uniqueValues uniqueValues is a string array with all unique values of a cluster. -// */ -// addPossibleValuesToSelect(select: HTMLSelectElement, uniqueValues: string[]) { -// this.removeAllOptions(select); -// for (let index in range(uniqueValues.length)) { -// let currentValue = uniqueValues[index]; -// let newOption = new Option(currentValue, currentValue); -// select.add(newOption, undefined); -// } -// } -// } diff --git a/libs/shared/lib/vis/nodelink/NodeLinkViewModel.tsx b/libs/shared/lib/vis/nodelink/NodeLinkViewModel.tsx deleted file mode 100644 index fa2a2ffc8efbfb959291faa3f41aa5878d9c7f50..0000000000000000000000000000000000000000 --- a/libs/shared/lib/vis/nodelink/NodeLinkViewModel.tsx +++ /dev/null @@ -1,852 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ -import { GraphType, LinkType, NodeType } from '../nodelink/Types'; - -import * as PIXI from 'pixi.js'; -import React from 'react'; -import * as d3 from 'd3'; -import { jsPDF } from 'jspdf'; -import ResultNodeLinkParserUseCase, { isNodeLinkResult } from '../shared/ResultNodeLinkParserUseCase'; -import { AttributeData, NodeAttributeData } from '../shared/InputDataTypes'; -import { AttributeCategory } from '../shared/Types'; -import { GraphQueryResult } from '../../data-access/store'; // TODO remove -import { Theme } from '@mui/material'; - -export type AttributesCollection = Record<string, boolean>; // TODO remove -export type NodesAttrCollection = Record<string, AttributesCollection>; // TODO remove - -export default class NodeLinkViewModel { - private resultNodeLinkParserUseCase: ResultNodeLinkParserUseCase; - private nodesMoving; - - public graph: GraphType; - public stage: PIXI.Container; - public links: PIXI.Graphics; - public simulation: d3.Simulation<NodeType, LinkType>; - public myRef: React.RefObject<HTMLDivElement>; - public renderer: PIXI.IRenderer; - public dragOffset: any; - public panOffset: any; - public scalexy: number; - public width: number; - public height: number; - public theme: Theme; - public radius: number; - public visibleAttributes: NodesAttrCollection; - public currentHightlightedNodes: NodeType[]; - public currentlyHighlightedLinks: LinkType[]; - public currentShortestPathEdges: LinkType[]; - public jaccardThreshold: number; - public uniqueAttributeValues: { [key: string]: any[] }; - public numberOfMlClusters: number; - - /** - * Creates the NodeLinkViewModelImpl using a given graph and window dimensions. - * It initialises the d3 simulation, the PIXI containers and the offsets for dragging and zooming. - * - * @param graph The graph has a list of nodes and a list of links to build the nodelink diagram. - * @param width The width of the window. - * @param height The height of the window. - * @param currentColours The current colour palette. - */ - public constructor( - resultNodeLinkParserUseCase: ResultNodeLinkParserUseCase, - graph: GraphQueryResult, - width: number, - height: number, - ref: React.RefObject<HTMLDivElement>, - theme: Theme - ) { - this.radius = 5; - - this.resultNodeLinkParserUseCase = resultNodeLinkParserUseCase; - - // Graph holds the nodes and edges for the simulation and graphics - this.graph = this.resultNodeLinkParserUseCase.parseQueryResult(graph); - - // Stage is the PIXI container holding all the graphics - this.stage = new PIXI.Container(); - - // Links is a graphics object that draws the lines between the nodes - this.links = new PIXI.Graphics(); - - // Simulation is a d3 object that calculates the movement and position of the nodes and edges - this.simulation = d3.forceSimulation<NodeType, LinkType>(); - - // Create a hook where the renderer will be attached to - this.myRef = ref; - - // The width and height are for the window - this.width = width; - this.height = height; - this.scalexy = 1; - - this.renderer = PIXI.autoDetectRenderer({ - width: this.width, - height: this.height, - antialias: !0, - backgroundAlpha: 0, - resolution: 1, - }); - - this.dragOffset = { - x: 0, - y: 0, - }; - - this.panOffset = { - x: 0, - y: 0, - }; - - this.theme = theme; - - // this becomes true when the nodes are moving due to onDrag being active - this.nodesMoving = false; - - // this is a dictionary of attributes that should be hidden - this.visibleAttributes = {}; - this.currentHightlightedNodes = []; - this.currentlyHighlightedLinks = []; - this.currentShortestPathEdges = []; - this.jaccardThreshold = -1; // All should be visable regardless now. - this.uniqueAttributeValues = {}; - this.numberOfMlClusters = 0; - } - - public notifyViewAboutChanges(): void { - return; //TODO - } - - /** - * Will be called by the broker if a query_result is available. - * This object is subscribed with the query_result routingkey. - * @param jsonObject The query_result coming from the broker. - */ - public consumeMessageFromBackend(jsonObject: GraphQueryResult): void { - this.graph = this.resultNodeLinkParserUseCase.parseQueryResult(jsonObject); - this.SetNodeGraphics(this.graph, this.radius); - this.simulation.restart(); - console.debug('simulation restarted', jsonObject, this.graph); - // this.notifyViewAboutChanges(); - - // if (isNodeLinkResult(jsonObject)) { - // this.graph = this.resultNodeLinkParserUseCase.parseQueryResult(jsonObject); - // - // this.SetNodeGraphics(this.graph, this.radius); - // this.simulation.restart(); - // // this.notifyViewAboutChanges(); - // } else if (isAttributeDataEntity(jsonObject)) { - // // Add all information from the received message to the popup-menu's. - // this.initializeUniqueAttributes(jsonObject, 'gsa_node_result'); - // - // this.notifyViewAboutChanges(); - // } - } - - /** Exports the nodelink diagram as a pdf for downloading. */ - public async exportToPDF(): Promise<void> { - const b = await this.renderer.extract.canvas(this.stage).convertToBlob?.({ type: 'image/png' }); - if (!b) return; - const pdf = new jsPDF(); - if (b) { - pdf.addImage(URL.createObjectURL(b), 'JPEG', 0, 0, 100, 100, '', 'NONE', 0); - pdf.save('diagram.pdf'); - } else { - console.log('null blob in exportToPDF'); - } - } - - /** Exports the nodelink diagram as a png for downloading. */ - public async exportToPNG(): Promise<void> { - const b = await this.renderer.extract.canvas(this.stage).convertToBlob?.({ type: 'image/png' }); - if (b) { - const a = document.createElement('a'); - document.body.append(a); - a.download = 'diagram'; - a.href = URL.createObjectURL(b); - a.click(); - a.remove(); - } else { - console.log('null blob in exportToPNG'); - } - } - - /** SelectD3Elements sets the eventlisteners for drag and drop and zooming. */ - public selectD3Elements(): void { - const radius = this.radius; - const radiusoffset = 5; - // Set event listeners for drag and drop behavior - d3.select<HTMLCanvasElement, any>(this.renderer.view as HTMLCanvasElement).call( - d3 - .drag<HTMLCanvasElement, any>() - .container(this.renderer.view as HTMLCanvasElement) - .subject((event: any) => - this.simulation.find( - (event.x - this.panOffset.x) / this.scalexy, - (event.y - this.panOffset.y) / this.scalexy, - radius + radiusoffset / this.scalexy - ) - ) - .on('start', this.onDragStart) - .on('drag', this.onDragMove) - .on('end', this.onDragEnd) - ); - - // Eventlisteners for zooming (mousewheel events) - d3.select<HTMLCanvasElement, any>(this.renderer.view as HTMLCanvasElement).call( - d3.zoom<HTMLCanvasElement, any>().on('zoom', this.zoom) - ); - } - - /** StartSimulation starts the d3 forcelink simulation. This has to be called after the simulation is initialised. */ - public startSimulation(): void { - this.simulation - .force( - 'link', - d3.forceLink().id((d: any) => d.id) - ) - .force('charge', d3.forceManyBody()) - .force('center', d3.forceCenter(this.width / 2, this.height / 2)); - - // Set PIXI as rendering engine - this.myRef.current?.appendChild(this.renderer.view as HTMLCanvasElement); - } - - /** UpdateColours updates the colours of the nodelink elements */ - public UpdateColours = (graph: GraphType, radius: number) => { - // update for each node in graph - graph.nodes.forEach((node: NodeType) => { - const item = this.stage.getChildByName('node_' + node.id); - if (item != null) { - item.destroy(); - this.createNode(node, radius); - } - }); - - // update text colour (written after nodes so that text appears on top of nodes) - this.UpdateAttributes(graph); - - // refresh - this.simulation.alphaTarget(0).restart(); - }; - - /** - * Refreshes the attributes. This function is called when the attribute filter has been changed - * @param graph the graph of which its nodes should be checked for attributes - */ - public UpdateAttributes = (graph: GraphType) => { - this.simulation.alphaTarget(0).restart(); // required so that the visualisation updates - graph.nodes.forEach((node: NodeType) => { - if (node.gfxAttributes !== undefined) { - // destroy and add the attributes pop-up again - node.gfxAttributes.destroy(); - this.createAttributes(node); - node.gfxAttributes.scale.x = 1 / this.scalexy + 0.001 * this.scalexy; - node.gfxAttributes.scale.y = 1 / this.scalexy + 0.001 * this.scalexy; - // make the pop-up visible if it was visible before - if (node.selected) { - node.gfxAttributes.alpha = 1; - } - } - }); - }; - - /** UpdateRadius works just like UpdateColours, but also applies radius*/ - public UpdateRadius = (graph: GraphType, radius: number) => { - // update for each node in graph - graph.nodes.forEach((node: NodeType) => { - const item = this.stage.getChildByName('node_' + node.id); - if (item != null) { - item.destroy(); - if (node.radius) { - this.createNode(node, node.radius); - } else { - this.createNode(node, radius); - } - } - }); - - // update text colour (written after nodes so that text appears on top of nodes) - graph.nodes.forEach((node: NodeType) => { - if (node.gfxAttributes !== undefined) { - const selected = node.selected === true; - node.gfxAttributes.destroy(); - this.createAttributes(node); - if (selected) { - this.showAttributes(node); - } - } - }); - - // refresh - this.simulation.alphaTarget(0).restart(); - }; - - /** - * SetNodeGraphics is an initialising function. It attaches the nodes and links to the simulation. - * It creates graphic objects and adds these to the PIXI containers. It also clears both of these of previous nodes and links. - * @param graph The graph returned from the database and that is parsed into a nodelist and edgelist. - * @param radius The radius of the node. - */ - public SetNodeGraphics = (graph: GraphType, radius: number) => { - // Set the nodes for the d3 simulation - this.simulation.nodes(this.graph.nodes); - - this.simulation.force<d3.ForceLink<NodeType, LinkType>>('link')?.links(this.graph.links); - - // Clear the stage and add the new nodes and links - this.simulation.alpha(0.5).restart(); - this.stage.removeChildren(); - this.stage.addChild(this.links); - - // Create and initialise graphic objects for the nodes - this.graph.nodes.forEach((node: NodeType) => { - if (node.radius) { - this.createNode(node, node.radius); - } else { - this.createNode(node, radius); - } - }); - }; - - /** - * Zoom is the function called when an event is triggered by using the mousewheel. - * @param event The event of the mousewheel. - */ - public zoom = (event: any) => { - // Update the pan offset with the mousemovement - this.panOffset.x += event.sourceEvent.movementX; - this.panOffset.y += event.sourceEvent.movementY; - - // Get the mouse position in the container coördinates - const mousePos = { - x: (event.sourceEvent.x - event.sourceEvent.target.offsetLeft - this.panOffset.x) / this.scalexy, - y: (event.sourceEvent.y - event.sourceEvent.target.offsetTop - this.panOffset.y) / this.scalexy, - }; - - this.simulation.restart(); - - // Change the scale - if (event.sourceEvent.deltaY < 0) { - this.scalexy *= 1.2; - this.stage.scale.x = this.scalexy; - this.stage.scale.y = this.scalexy; - } else if (event.sourceEvent.deltaY > 0) { - this.scalexy /= 1.2; - this.stage.scale.x = this.scalexy; - this.stage.scale.y = this.scalexy; - } - - // Scale the text of the nodes - this.graph.nodes.forEach((node: NodeType) => { - if (node.gfxAttributes) { - node.gfxAttributes.scale.x = 1 / this.scalexy + 0.001 * this.scalexy; - node.gfxAttributes.scale.y = 1 / this.scalexy + 0.001 * this.scalexy; - } - }); - - // Calculate the difference in position, to zoom at the mouse - const dx = ((event.sourceEvent.x - event.sourceEvent.target.offsetLeft - this.panOffset.x) / this.scalexy - mousePos.x) * this.scalexy; - const dy = ((event.sourceEvent.y - event.sourceEvent.target.offsetTop - this.panOffset.y) / this.scalexy - mousePos.y) * this.scalexy; - if (dx && dy) { - this.panOffset.x += dx; - this.panOffset.y += dy; - } - - // Apply the panOffset changes to the stage position - this.stage.position.x = this.panOffset.x; - this.stage.position.y = this.panOffset.y; - this.renderer.render(this.stage); - }; - - /** - * Creates and adds a node to the stage - * @param node The node from the graph that needs to be made - * @param radius The radius of the visible node - */ - private createNode = (node: NodeType, radius: number, selected?: boolean) => { - node.gfx = new PIXI.Graphics(); - node.selected = selected; - const lineColour = selected ? this.theme.palette.custom.nodeHighlightedEdge : this.theme.palette.custom.visBackground; - const lineWidth = selected ? 3 : 1.5; - node.gfx.lineStyle(lineWidth, Number('0x' + lineColour.replace('#', ''))); - //check if not undefined. - if (node.cluster) { - node.gfx.beginFill(this.colour(node.cluster)); - } else { - //if cluster is undefined, use type to determine the color. - //check if not undefined. - if (node.type) { - node.gfx.beginFill(this.colour(node.type)); - } - } - node.gfx.drawCircle(0, 0, radius); - node.gfx.eventMode = 'auto'; - node.gfx.hitArea = new PIXI.Circle(0, 0, 4); - node.gfx.name = 'node_' + node.id; - this.stage.addChild(node.gfx); - }; - - /** - * Creates a list of attributes from a given node, that can be visualised when the node is clicked - * @param node The node from the graph which attributes need to be visualised - */ - private createAttributes = (node: NodeType) => { - node.gfxAttributes = new PIXI.Graphics(); - node.gfxAttributes.beginFill(0xeeeeee); - node.gfxAttributes.name = 'attributes_' + node.id; - node.gfxAttributes.alpha = 0; - node.gfxAttributes.interactive = true; - // add title - const gfxName = new PIXI.Text(); - if (node.displayInfo != undefined) { - gfxName.text = node.displayInfo; - } else { - gfxName.text = node.id; - } - gfxName.style.fontSize = 16; - gfxName.style.fontFamily = 'Poppins, arial, sans-serif'; - gfxName.style.fontWeight = 'bold'; - gfxName.x = 10; - gfxName.y = 10; - gfxName.name = 'header'; - node.gfxAttributes.addChild(gfxName); - - // add attributes container - const container = new PIXI.Container(); - node.gfxAttributes.addChild(container); - // add container for keys - const keys = new PIXI.Container(); - container.addChild(keys); - // add container for values - const values = new PIXI.Container(); - container.addChild(values); - - // add attributes - if (node.attributes) { - let index = 0; - for (const key in node.attributes) { - const attributes = this.visibleAttributes[node?.label || node.id]; - const attributeHidden = attributes ? attributes[key] === false : false; - if (attributeHidden) continue; // if attribute should be hidden, then skip - this.addAttribute(keys, values, key, String(node.attributes[key]), index); - index++; - } - } - - // position attribute containers - container.x = 10; - container.y = 45; - values.x = keys.width + 10; - - // calculate width - const width = this.calcAttrWidth(node.gfxAttributes) + 40; - const height = container.height + 55; - node.gfxAttributes.drawRoundedRect(0, 0, width, height, 10); - - // add stripe - const gfxLine = new PIXI.Graphics(); - gfxLine.beginFill(0xbbbbbb); - gfxLine.drawRect(10, 35, width - 20, 1); - node.gfxAttributes.addChild(gfxLine); - - this.stage.addChild(node.gfxAttributes); - }; - - /** - * Helper function of createAttributes: adds an attribute to the new attributes graphic - */ - private addAttribute(keys: PIXI.Container, values: PIXI.Container, key: string, value: string, index: number): void { - // add text for key - const keyText = new PIXI.Text(); - keyText.style.fontSize = 14; - keyText.style.fontFamily = 'Poppins, arial, sans-serif'; - keyText.style.fontWeight = 'bold'; - keyText.name = 'key'; - keyText.text = key + ':'; - keyText.y = index * 20; - keys.addChild(keyText); - // add text for value - const valueText = new PIXI.Text(); - valueText.style.fontSize = 14; - valueText.style.fontFamily = 'Poppins, arial, sans-serif'; - valueText.name = 'value'; - valueText.text = value; - valueText.y = index * 20; - values.addChild(valueText); - } - - /** - * Helper function of createAttributes: calculates the width of the attributes graphic - */ - private calcAttrWidth(gfxAttributes: PIXI.Graphics): number { - let width = 0; - gfxAttributes.children.forEach((child) => { - width = this.calcObjectWidth(child as PIXI.Text | PIXI.Graphics, width); - }); - - return width; - } - - /** - * Helper function of calcAttrWidth: calculates the width of a child element of the attributes graphic - */ - private calcObjectWidth(object: PIXI.Text | PIXI.Graphics, minWidth?: number): number { - const newWidth = object.width; - return minWidth ? Math.max(newWidth, minWidth) : newWidth; - } - - /** - * The first click that starts the dragging. - * @param event The mouseDown event. - */ - private onDragStart = (event: any) => { - event.subject.fx = event.subject.x; - event.subject.fy = event.subject.y; - this.dragOffset.x = event.subject.x; - this.dragOffset.y = event.subject.y; - }; - - /** - * Calls for the Display that pops up and highlights the node and the links - * if ShortestPath turns on, it turns off the highlightedlinks! - * @param node The node clicked in the event - */ - public ToggleInformationOnNode(node: NodeType) { - this.simulation.alphaTarget(0).restart(); // renderer will not always update without this line - this.showAttributes(node); - // this.highlightNode(node); - // this.highlightLinks(node); - // this.showShortestPath(); - } - - /** - * The actual drawing of the shortest path is done in the ticked method - * This recalculates what should be shown and adds it to a list currentShortestPathEdges - * Small note; the order in which nodes are clicked matters. - * Also turns off highlightLinks - * */ - public showShortestPath(): boolean { - const shortestPathNodes: NodeType[] = []; - this.currentHightlightedNodes.forEach((node) => { - if (node.shortestPathData != undefined) { - shortestPathNodes.push(node); - } - }); - if (shortestPathNodes.length < 2) { - this.currentShortestPathEdges = []; - return false; - } - let index = 0; - let allPaths: LinkType[] = []; - while (index < shortestPathNodes.length - 1) { - const shortestPathData = shortestPathNodes[index].shortestPathData; - if (shortestPathData === undefined) { - console.warn('Something went wrong with shortest path calculation'); - } else { - const path: string[] = shortestPathData[shortestPathNodes[index + 1].id]; - allPaths = allPaths.concat(this.getShortestPathEdges(path)); - } - index++; - } - this.currentShortestPathEdges = allPaths; - - //This turns of the highlightedlinks - this.currentlyHighlightedLinks = []; - return true; - } - - /** - * Gets the edges corresponding to the shortestPath. - * @param pathString The path as a string. - * @returns The path as a LinkType[] - */ - public getShortestPathEdges(pathString: string[]): LinkType[] { - try { - const newPath: LinkType[] = []; - let index = 0; - while (index < pathString.length) { - if (pathString[index + 1] == undefined) { - index++; - continue; - } - let edgeFound = false; - this.graph.links.forEach((link: any) => { - const { source, target } = link; - if ( - (pathString[index] == source.id && pathString[index + 1] == target.id) || - (pathString[index] == source && pathString[index + 1] == target) || - (pathString[index + 1] == source.id && pathString[index] == target.id) || - (pathString[index + 1] == source && pathString[index] == target) - ) { - newPath.push(link); - edgeFound = true; - } - }); - if (!edgeFound) { - console.warn('skipped path: ' + pathString[index] + ' ' + pathString[index + 1]); - } - index++; - } - return newPath; - } catch { - return []; - } - } - - /** - * When mouseDown on a node, this is called. - * @param event The moving of the mouse. - */ - private onDragMove = (event: any) => { - // this condition only passes when this is the first iteration of onDragMove after onDragStart - if (!this.nodesMoving) { - this.simulation.alphaTarget(0.3).restart(); // this makes all the nodes move - this.nodesMoving = true; - } - - // Moving the node - if (this.scalexy != 1) { - event.subject.fx = this.dragOffset.x - (this.dragOffset.x - event.x) / this.scalexy; - event.subject.fy = this.dragOffset.y - (this.dragOffset.y - event.y) / this.scalexy; - } else { - event.subject.fx = event.x; - event.subject.fy = event.y; - } - }; - - /** - * MouseUp on the node, stopping the drag. - * @param event The mouseUp event. - */ - private onDragEnd = (event: any) => { - if (this.nodesMoving) { - this.simulation.alphaTarget(0); // this will stop the nodes from moving - this.nodesMoving = false; - } - event.subject.fx = null; - event.subject.fy = null; - - // Toggle display of the attributes of the node - const node = this.simulation.find(event.x, event.y, 15); - // Null check - if (!!node) { - this.ToggleInformationOnNode(node); - } - }; - - /** - * Updates the currentlyHighlightedLinks value. - * That value is used in the ticked function. - * @param node The node clicked in the event. - */ - public highlightLinks(node: NodeType) { - //If node is already clicked we should remove it from the list. - if (this.currentHightlightedNodes.includes(node)) { - const index = this.currentHightlightedNodes.indexOf(node, 0); - if (index > -1) { - this.currentHightlightedNodes.splice(index, 1); - } - } - //Else add it to the list. - else this.currentHightlightedNodes.push(node); - //Update the list of edges that need to be highlighted - this.currentlyHighlightedLinks = this.getRelatedLinks(this.currentHightlightedNodes); - } - - /** - * When clicking on a node, toggle the select, making the text visible/invisible. - * @param node The node which text should be toggled. - */ - public showAttributes = (node: NodeType) => { - if (node.selected) { - if (node.gfxAttributes) { - node.gfxAttributes.alpha = 0; - node.selected = false; - } - } else { - if (node.gfxAttributes) node.gfxAttributes.destroy(); - this.createAttributes(node); - if (node.gfxAttributes) { - node.gfxAttributes.scale.x = 1 / this.scalexy + 0.001 * this.scalexy; - node.gfxAttributes.scale.y = 1 / this.scalexy + 0.001 * this.scalexy; - node.gfxAttributes.alpha = 1; - node.selected = true; - } - } - }; - - /** Highlight the selected node */ - public highlightNode = (node: NodeType) => { - const radius = node.radius ? node.radius : this.radius; - const item = this.stage.getChildByName('node_' + node.id); - if (item != null) { - item.destroy(); - this.createNode(node, radius, node.selected); - } - }; - - /** - * Used when you select nodes. - * The highlight is drawn in ticked. - * @param nodes The nodes you want to related edges to. - * @returns {LinkType[]} All the links related to all the nodes - */ - public getRelatedLinks(nodes: NodeType[]): LinkType[] { - const relatedLinks: LinkType[] = []; - this.graph.links.forEach((link: LinkType) => { - const { source, target } = link; - if (this.isLinkVisiable(link)) { - nodes.forEach((node: NodeType) => { - if (source == node || target == node || source == node.id || target == node.id) { - relatedLinks.push(link); - } - }); - } - }); - return relatedLinks; - } - - /** When the screen gets resized, resize the node link canvas ViewModel. */ - public handleResize = () => { - this.width = window.innerWidth; - this.height = window.innerHeight - 6; - this.renderer.resize(this.width, this.height); - this.ticked(); - this.notifyViewAboutChanges(); - }; - - /** Ticked is the updater function of the simulation. Every 'tick' all the new positions of the nodes (and thus the edges) are recalculated and updated. */ - public ticked = () => { - this.graph.nodes.forEach((node: any) => { - if (!node || !node.x || !node.y) return; - // if (node?.gfx === undefined) node.gfx = {}; - node.gfx.position = new PIXI.Point(node.x, node.y); - // Update attributes position if they exist - if (node.gfxAttributes) { - node.gfxAttributes.position = new PIXI.Point(node.x - node.gfxAttributes.width / 2, node.y - node.gfxAttributes.height - 20); - } - }); - - this.links.clear(); - this.links.alpha = 0.6; - - // Update forces of the links - this.graph.links.forEach((link: any) => { - const { source, target } = link; - this.links.lineStyle(0, 0x000000); - // Check if link is a machine learning edge - if (link.mlEdge && this.jaccardThreshold != null) { - if (link.value > this.jaccardThreshold) { - this.links.moveTo(source.x, source.y); - this.links.lineTo(target.x, target.y); - this.links.lineStyle(link.value * 1.8, 0x0000ff); - } - } else this.links.lineStyle(0.2, 0x000000); - - //Check if link is hightlighted - if (this.currentlyHighlightedLinks.includes(link)) { - //If highlighted and ML edge make it purple - if (link.mlEdge && this.jaccardThreshold != null) { - if (link.value > this.jaccardThreshold != null) { - this.links.lineStyle(link.value * 1.8, 0xaa00ff); - } - //If highlight and not ML edge make it red - } else { - this.links.lineStyle(1.0, 0xff0000); - } - } - - if (this.currentShortestPathEdges.includes(link)) { - this.links.lineStyle(3.0, 0x00ff00); - } - - this.links.moveTo(source.x, source.y); - this.links.lineTo(target.x, target.y); - }); - - this.links.endFill(); - - // This updates the canvas - this.renderer.render(this.stage); - }; - - /** - * Colour is a function that takes a string of a number and returns a number of a color out of the d3 color scheme. - * @param num Num is the input string representing a number of a colorgroup. - * @returns {number} A number corresponding to a color in the d3 color scheme. - */ - public colour = (num: number) => { - //num = num % 4; - const col = this.theme.palette.custom.nodes[num % this.theme.palette.custom.nodes.length]; - return Number('0x' + col.replace('#', '')); - }; - - //MACHINE LEARNING-------------------------------------------------------------------------------------------------- - /** - * updates the JacccardThresh value. - * This is called in the component - * This makes testing purposes easier and makes sure you dont have to read out the value 2000 times, - * but only when you change the value. - */ - public updateJaccardThreshHold(): void { - const slider = document.getElementById('Slider'); - this.jaccardThreshold = Number(slider?.innerText); - } - - /** - * Checks wheter a link is visible. - * This is used for highlighting nodes. - * @param link The link you want to check wheter it's visable or not - * @returns {boolean} - */ - public isLinkVisiable(link: LinkType): boolean { - //About the next line, If you don't do this here but lets say in the constructor it errors. So far no performance issues where noticed. - if (link.mlEdge) { - if (link.value > this.jaccardThreshold) { - return true; - } - } else return true; - return false; - } - - /** initializeUniqueAttributes fills the uniqueAttributeValues with data from graph scheme analytics. - * @param attributeData NodeAttributeData returned by graph scheme analytics. - * @param attributeDataType Routing key. - */ - public initializeUniqueAttributes(attributeData: AttributeData, attributeDataType: string): void { - if (attributeDataType === 'gsa_node_result') { - const entity = attributeData as NodeAttributeData; - entity.attributes.forEach((attribute) => { - if (attribute.type === AttributeCategory.categorical) { - const nameAttribute = attribute.name; - const valuesAttribute = attribute.uniqueCategoricalValues; - // check if not null - if (valuesAttribute) { - this.uniqueAttributeValues[nameAttribute] = valuesAttribute; - } - } - }); - } - } - - /** - * resetClusterOfNodes is a function that resets the cluster of the nodes that are being customised by the user, - * after a community detection algorithm, where the cluster of these node could have been changed. - */ - public resetClusterOfNodes = (type: number): void => { - this.graph.nodes.forEach((node: NodeType) => { - const numberOfClusters = this.numberOfMlClusters; - if (node.cluster == type) { - node.cluster = numberOfClusters; - } - if (node.type == type) { - node.cluster = node.type; - } - }); - }; -} diff --git a/libs/shared/lib/vis/nodelink/Types.tsx b/libs/shared/lib/vis/nodelink/Types.tsx index 377847dc51a5c265da1e1002e8d708df4bfc4fb4..8df3a97da2430966c7940f46ec997aecf017bc30 100644 --- a/libs/shared/lib/vis/nodelink/Types.tsx +++ b/libs/shared/lib/vis/nodelink/Types.tsx @@ -29,8 +29,7 @@ export interface NodeType extends d3.SimulationNodeDatum { shortestPathData?: Record<string, string[]>; // Node that is drawn. - gfx?: PIXI.Graphics; - radius?: number; + radius: number; // Text to be displayed on top of the node. gfxtext?: PIXI.Text; gfxAttributes?: PIXI.Graphics; diff --git a/libs/shared/lib/vis/nodelink/components/NLExport.tsx b/libs/shared/lib/vis/nodelink/components/NLExport.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e6907ecc307f5f4a20188c543f80d76413adc520 --- /dev/null +++ b/libs/shared/lib/vis/nodelink/components/NLExport.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import jsPDF from 'jspdf'; +import { Container, IRenderer } from 'pixi.js'; + +/** Exports the nodelink diagram as a pdf for downloading. */ +async function exportToPDF(renderer: IRenderer, stage: Container): Promise<void> { + const b = await renderer.extract.canvas(stage).convertToBlob?.({ type: 'image/png' }); + if (!b) return; + const pdf = new jsPDF(); + if (b) { + pdf.addImage(URL.createObjectURL(b), 'JPEG', 0, 0, 100, 100, '', 'NONE', 0); + pdf.save('diagram.pdf'); + } else { + console.log('null blob in exportToPDF'); + } +} + +/** Exports the nodelink diagram as a png for downloading. */ +async function exportToPNG(renderer: IRenderer, stage: Container): Promise<void> { + const b = await renderer.extract.canvas(stage).convertToBlob?.({ type: 'image/png' }); + if (b) { + const a = document.createElement('a'); + document.body.append(a); + a.download = 'diagram'; + a.href = URL.createObjectURL(b); + a.click(); + a.remove(); + } else { + console.log('null blob in exportToPNG'); + } +} + +const useExport = () => { + return { exportToPDF, exportToPNG }; +}; diff --git a/libs/shared/lib/vis/nodelink/components/NLForce.tsx b/libs/shared/lib/vis/nodelink/components/NLForce.tsx new file mode 100644 index 0000000000000000000000000000000000000000..54bdd14f7a0efa419993276651d2d8e04ebcf8c5 --- /dev/null +++ b/libs/shared/lib/vis/nodelink/components/NLForce.tsx @@ -0,0 +1,39 @@ +import { forceCenter, forceCollide, forceLink, forceManyBody, forceRadial, forceSimulation } from 'd3'; +import { GraphType, LinkType, NodeType } from '../Types'; +import { useEffect } from 'react'; + +export const simulation = forceSimulation<NodeType, LinkType>(); + +/** StartSimulation starts the d3 forcelink simulation. This has to be called after the simulation is initialized. */ +export function startSimulation(graph: GraphType, windowSize: { width: number; height: number }): void { + simulation + .alpha(1.8) + .force( + 'link', + forceLink() + .id((d: any) => d.id) + .strength(1) + .distance(25) + ) + .force('charge', forceManyBody().strength(-1)) + .force('center', forceCenter(windowSize.width / 2, windowSize.height / 2).strength(0.5)) + .force('collide', forceCollide().strength(1).radius(5).iterations(1)) // Force that avoids circle overlapping + .force('attract', forceRadial(50, windowSize.width / 2, windowSize.height / 2).strength(0.005)); + simulation.nodes(graph.nodes); + simulation.force<d3.ForceLink<NodeType, LinkType>>('link')?.links(graph.links); + simulation.alphaTarget(0).restart(); +} + +// export const useNLForce = ({ graph, windowSize }: Props) => { +// useEffect(() => { +// if (graph && graph.nodes.length > 0 && graph.links.length > 0 && windowSize.width && windowSize.height) { +// startSimulation(graph); +// } +// }, [graph, windowSize.width, windowSize.height]); + +// function refresh(): void { +// simulation.restart(); +// } + +// return { simulation, refresh, startSimulation }; +// }; diff --git a/libs/shared/lib/vis/nodelink/components/NLMachineLearning.tsx b/libs/shared/lib/vis/nodelink/components/NLMachineLearning.tsx new file mode 100644 index 0000000000000000000000000000000000000000..a06ebc311d45fdbe3a00d7d02bd52b207303ac96 --- /dev/null +++ b/libs/shared/lib/vis/nodelink/components/NLMachineLearning.tsx @@ -0,0 +1,136 @@ +import { useState } from 'react'; +import { AttributeData, NodeAttributeData } from '../../shared/InputDataTypes'; +import { AttributeCategory } from '../../shared/Types'; +import { GraphType, LinkType, NodeType } from '../Types'; + +export const useNLMachineLearning = (props: { + graph: GraphType; + highlightedNodes: NodeType[]; + jaccardThreshold: number; + numberOfMlClusters: number; +}) => { + const [shortestPathEdges, setShortestPathEdges] = useState<LinkType[]>([]); + + /** + * The actual drawing of the shortest path is done in the ticked method + * This recalculates what should be shown and adds it to a list currentShortestPathEdges + * Small note; the order in which nodes are clicked matters. + * Also turns off highlightLinks + * */ + function showShortestPath(): void { + const shortestPathNodes: NodeType[] = []; + props.highlightedNodes.forEach((node) => { + if (node.shortestPathData != undefined) { + shortestPathNodes.push(node); + } + }); + if (shortestPathNodes.length < 2) { + setShortestPathEdges([]); + } + let index = 0; + let allPaths: LinkType[] = []; + while (index < shortestPathNodes.length - 1) { + const shortestPathData = shortestPathNodes[index].shortestPathData; + if (shortestPathData === undefined) { + console.warn('Something went wrong with shortest path calculation'); + } else { + const path: string[] = shortestPathData[shortestPathNodes[index + 1].id]; + allPaths = allPaths.concat(getShortestPathEdges(path)); + } + index++; + } + setShortestPathEdges(allPaths); + } + + /** + * Gets the edges corresponding to the shortestPath. + * @param pathString The path as a string. + * @returns The path as a LinkType[] + */ + function getShortestPathEdges(pathString: string[]): LinkType[] { + try { + const newPath: LinkType[] = []; + let index = 0; + while (index < pathString.length) { + if (pathString[index + 1] == undefined) { + index++; + continue; + } + let edgeFound = false; + props.graph.links.forEach((link: any) => { + const { source, target } = link; + if ( + (pathString[index] == source.id && pathString[index + 1] == target.id) || + (pathString[index] == source && pathString[index + 1] == target) || + (pathString[index + 1] == source.id && pathString[index] == target.id) || + (pathString[index + 1] == source && pathString[index] == target) + ) { + newPath.push(link); + edgeFound = true; + } + }); + if (!edgeFound) { + console.warn('skipped path: ' + pathString[index] + ' ' + pathString[index + 1]); + } + index++; + } + return newPath; + } catch { + return []; + } + } + + //MACHINE LEARNING-------------------------------------------------------------------------------------------------- + // /** + // * updates the JacccardThresh value. + // * This is called in the component + // * This makes testing purposes easier and makes sure you dont have to read out the value 2000 times, + // * but only when you change the value. + // */ + // function updateJaccardThreshHold(): void { + // const slider = document.getElementById('Slider'); + // props.jaccardThreshold = Number(slider?.innerText); + // } + + // /** initializeUniqueAttributes fills the uniqueAttributeValues with data from graph scheme analytics. + // * @param attributeData NodeAttributeData returned by graph scheme analytics. + // * @param attributeDataType Routing key. + // */ + // function initializeUniqueAttributes(attributeData: AttributeData, attributeDataType: string): void { + // if (attributeDataType === 'gsa_node_result') { + // const entity = attributeData as NodeAttributeData; + // entity.attributes.forEach((attribute) => { + // if (attribute.type === AttributeCategory.categorical) { + // const nameAttribute = attribute.name; + // const valuesAttribute = attribute.uniqueCategoricalValues; + // // check if not null + // if (valuesAttribute) { + // this.uniqueAttributeValues[nameAttribute] = valuesAttribute; + // } + // } + // }); + // } + // } + + /** + * resetClusterOfNodes is a function that resets the cluster of the nodes that are being customised by the user, + * after a community detection algorithm, where the cluster of these node could have been changed. + */ + const resetClusterOfNodes = (type: number): void => { + props.graph.nodes.forEach((node: NodeType) => { + const numberOfClusters = props.numberOfMlClusters; + if (node.cluster == type) { + node.cluster = numberOfClusters; + } + if (node.type == type) { + node.cluster = node.type; + } + }); + }; + + return { + shortestPathEdges, + showShortestPath, + resetClusterOfNodes, + }; +}; diff --git a/libs/shared/lib/vis/nodelink/components/NLPixi.tsx b/libs/shared/lib/vis/nodelink/components/NLPixi.tsx new file mode 100644 index 0000000000000000000000000000000000000000..3ff52dc93ec380912d2a6ef8277e3c4124006d11 --- /dev/null +++ b/libs/shared/lib/vis/nodelink/components/NLPixi.tsx @@ -0,0 +1,332 @@ +import { GraphType, LinkType, NodeType } from '../Types'; +import { tailwindColors } from 'config'; +import { useEffect, useMemo, useRef, useState } from 'react'; +import { Application, Circle, Container, FederatedPointerEvent, Graphics, Point, Sprite, Texture, autoDetectRenderer } from 'pixi.js'; +import { binaryColor, nodeColor as nodeColor } from './utils'; +import { select, zoom as d3zoom, drag as d3drag } from 'd3'; +import * as force from './NLForce'; +import { Viewport } from 'pixi-viewport'; +import ResultNodeLinkParserUseCase from '../../shared/ResultNodeLinkParserUseCase'; +import { GraphQueryResult, GraphQueryResultFromBackendPayload } from '@graphpolaris/shared/lib/data-access/store/graphQueryResultSlice'; + +type Props = { + windowSize: { width: number; height: number }; + onClick: (node: NodeType) => void; + highlightNodes: NodeType[]; + currentShortestPathEdges?: LinkType[]; + highlightedLinks?: LinkType[]; + jaccardThreshold?: number; + myDiv: HTMLDivElement | null; +}; + +const app = new Application({ background: 0xffffff, antialias: true, autoDensity: true, eventMode: 'auto' }); +const nodes = new Container(); +const links = new Container(); + +////////////////// +// MAIN COMPONENT +////////////////// + +export const useNLPixi = (props: Props) => { + const [drag, setDrag] = useState({ x: 0, y: 0 }); + const nodeMap = useRef(new Map<string, Graphics>()); + const linkMap = useRef(new Map<string, Graphics>()); + const graph = useRef<GraphType>(); + const viewport = useRef<Viewport>(); + + useEffect(() => { + app.renderer.resize(props.windowSize.width, props.windowSize.height); + app.render(); + }, [props.windowSize]); + + useEffect(() => { + if (props.myDiv && props.myDiv.children.length === 0) props.myDiv.appendChild(app.view as HTMLCanvasElement); + }, [props.myDiv]); + + const updateNode = (node: NodeType) => { + // console.log(item); + const gfx = nodeMap.current.get(node.id); + gfx?.position.set(node.x, node.y); + + // if (!item.position) { + // item.position = new Point(node.x, node.y); + // } else { + // item.position.set(node.x, node.y); + // } + // Update attributes position if they exist + // if (node.gfxAttributes) { + // const x = node.x - node.gfxAttributes.width / 2; + // const y = node.y - node.gfxAttributes.height - 20; + // if (!node.gfxAttributes?.position) node.gfxAttributes.position = new Point(x, y); + // else { + // node.gfxAttributes.position.set(x, y); + // } + // } + }; + + const dragging = useRef<{ node: NodeType; gfx: Graphics } | null>(null); + function onDragStart(event: FederatedPointerEvent, node: NodeType, gfx: Graphics) { + // store a reference to the data + // the reason for this is because of multitouch + // we want to track the movement of this particular touch + event.stopPropagation(); + if (viewport.current) viewport.current.pause = true; + dragging.current = { node, gfx }; + } + + function onDragEnd(event: FederatedPointerEvent) { + if (dragging.current) { + event.stopPropagation(); + dragging.current.node.fx = null; + dragging.current.node.fy = null; + dragging.current = null; + if (viewport.current) viewport.current.pause = false; + } + } + + function onDragMove(event: FederatedPointerEvent) { + if (dragging.current) { + event.stopPropagation(); + console.log(viewport.current?.scaled); + + if (!dragging.current.node.fx) dragging.current.node.fx = dragging.current.node.x || 0; + if (!dragging.current.node.fy) dragging.current.node.fy = dragging.current.node.y || 0; + dragging.current.node.fx += event.movementX / (viewport.current?.scaled || 1); + dragging.current.node.fy += event.movementY / (viewport.current?.scaled || 1); + force.simulation.alpha(0.1).restart(); + } + } + + const createNode = (node: NodeType, selected?: boolean) => { + // check if node is already drawn, and if so, delete it + if (node && node?.id && nodeMap.current?.has(node.id)) { + nodeMap.current.delete(node.id); + } + const gfx = new Graphics(); + node.selected = selected; + const lineColor = selected ? tailwindColors.entity[400] : '#000000'; + + const lineWidth = selected ? 3 : 1.5; + gfx.lineStyle(lineWidth, binaryColor(lineColor)); + //check if not undefined. + if (node.cluster) { + gfx.beginFill(nodeColor(node.cluster)); + } else { + //if cluster is undefined, use type to determine the color. + //check if not undefined. + if (node.type) { + gfx.beginFill(nodeColor(node.type)); + } + } + gfx.drawCircle(0, 0, Math.max(node.radius || 5, 5)); + gfx.hitArea = new Circle(0, 0, 4); + gfx.name = 'node_' + node.id; + gfx.position.set(node.x, node.y); + gfx.eventMode = 'dynamic'; + gfx.on('mousedown', (e) => onDragStart(e, node, gfx)); + gfx.on('mousemove', onDragMove); + gfx.on('mouseup', onDragEnd); + + nodes.addChild(gfx); + nodeMap.current.set(node.id, gfx); + return gfx; + }; + + /** UpdateRadius works just like UpdateColors, but also applies radius*/ + const UpdateRadius = (graph: GraphType, radius: number) => { + // update for each node in graph + graph.nodes.forEach((node: NodeType) => { + createNode(node); + }); + }; + + const updateLink = (link: LinkType) => { + if (!graph.current) return; + + const _source = link.source; + const _target = link.target; + + if (!_source || !_target) { + console.log('source or target not found', _source, _target); + return; + } + + let sourceId = ''; + let targetId = ''; + let source: NodeType | undefined; + let target: NodeType | undefined; + + if (typeof _source === 'string') { + sourceId = link.source as string; + targetId = link.target as string; + source = nodeMap.current.get(sourceId) as NodeType | undefined; + target = nodeMap.current.get(targetId) as NodeType | undefined; + } else { + source = link.source as NodeType; + target = link.target as NodeType; + sourceId = source.id; + targetId = target.id; + } + if (!source || !target) { + console.log('source or target not found', source, target, sourceId, targetId); + return; + } + + const id = sourceId + targetId; + const gfx = linkMap.current.get(id); + + if (gfx) { + gfx.clear(); + gfx.beginFill(); + // Check if link is a machine learning edge + // if (link.mlEdge && props.jaccardThreshold) { + // if (link.value > props.jaccardThreshold) { + // gfx.moveTo(source.x, source.y); + // gfx.lineTo(target.x, target.y); + // gfx.lineStyle(link.value * 1.8, 0x0000ff); + // } + // } else gfx.lineStyle(0.2, 0x000000); + // //Check if link is hightlighted + // if (props.highlightedLinks && props.highlightedLinks.includes(link)) { + // //If highlighted and ML edge make it purple + // if (link.mlEdge && props.jaccardThreshold) { + // if (link.value > props.jaccardThreshold) { + // gfx.lineStyle(link.value * 1.8, 0xaa00ff); + // } + // //If highlight and not ML edge make it red + // } else { + // gfx.lineStyle(1.0, 0xff0000); + // } + // } + // if (props.currentShortestPathEdges && props.currentShortestPathEdges.includes(link)) { + // gfx.lineStyle(3.0, 0x00ff00); + // } + // console.log('link', source.x); + + // gfx.position.set(source.x, source.y); + // gfx.moveTo(source.x || 0, source.y || 0); + // gfx.lineTo(target.x || 1000, target.y || 1000); + // gfx.position.set(source.x, source.y); + gfx + .lineStyle(0.5, 0x000000) + .moveTo(source.x || 0, source.y || 0) + .lineTo(target.x || 0, target.y || 0); + gfx.endFill(); + } + }; + + const createLink = (link: LinkType) => { + const sourceId = link.source as string; + const targetId = link.target as string; + const id = sourceId + targetId; + + if (linkMap.current.has(id)) { + linkMap.current.delete(id); + } + const gfx = new Graphics(); + gfx.name = 'link_' + id; + linkMap.current.set(id, gfx); + updateLink(link); + links.addChild(gfx); + return gfx; + }; + + /** + * SetNodeGraphics is an initializing function. It attaches the nodes and links to the simulation. + * It creates graphic objects and adds these to the PIXI containers. It also clears both of these of previous nodes and links. + * @param graph The graph returned from the database and that is parsed into a nodelist and edgelist. + * @param radius The radius of the node. + */ + const refresh = (graphQueryResult: GraphQueryResult) => { + const resultNodeLinkParserUseCase = new ResultNodeLinkParserUseCase(); + graph.current = resultNodeLinkParserUseCase.parseQueryResult(graphQueryResult); + + nodes.removeChildren(); + links.removeChildren(); + app.stage.removeChildren(); + + viewport.current = new Viewport({ + screenWidth: props.windowSize.width, + screenHeight: props.windowSize.height, + worldWidth: props.windowSize.width, + worldHeight: props.windowSize.height, + stopPropagation: true, + events: app.renderer.events, // the interaction module is important for wheel to work properly when renderer.view is placed or scaled + }); + app.stage.addChild(viewport.current); + // activate plugins + viewport.current.drag().pinch().wheel().animate({}).decelerate({ friction: 0.75 }); + + viewport.current.addChild(links); + viewport.current.addChild(nodes); + // app.stage.addChild(links); + // app.stage.addChild(nodes); + app.stage.eventMode = 'dynamic'; + app.stage.on('mouseup', onDragEnd); + app.stage.on('pointerup', onDragEnd); + + app.ticker.add(function (delta) { + if (graph.current) { + graph.current.nodes.forEach((node: any) => { + const gfx = nodeMap.current.get(node.id); + if (!gfx) return; + const pos = gfx.position; + // gfx.position.set(pos.x + (node.x - pos.x) / delta, pos.y + (node.y - pos.y) / delta); + gfx.position.set(node.x, node.y); + }); + + // Update forces of the links + graph.current.links.forEach((link: any) => { + updateLink(link); + }); + } + }); + + // app.stage.onmousedown = (e) => { + // isPanning.current = true; + // console.log('mousedown'); + // }; + // app.stage.onmousemove = (e) => { + // if (isPanning.current) { + // setPan({ x: pan.x + e.movementX, y: pan.y + e.movementY }); + // app.stage.setTransform(pan.x + e.movementX, pan.y + e.movementY, scale, scale); + // } + // }; + // app.stage.onmouseup = (e) => { + // isPanning.current = false; + // console.log('mouseup'); + // }; + + // Create and initialise graphic objects for the nodes + if (graph && graph.current.nodes && graph.current.links) { + nodeMap.current.clear(); + graph.current.nodes.forEach((node: NodeType) => { + createNode(node); + }); + linkMap.current.clear(); + graph.current.links.forEach((link: LinkType) => { + createLink(link); + }); + + // // update text colour (written after nodes so that text appears on top of nodes) + // nodes.forEach((node: NodeType) => { + // if (node.gfxAttributes !== undefined) { + // const selected = node.selected === true; + // node.gfxAttributes.destroy(); + // createAttributes(node); + // if (selected) { + // showAttributes(node); + // } + // } + // }); + + // // refresh + // force.simulation.alphaTarget(0).restart(); + + force.startSimulation(graph.current, props.windowSize); + force.simulation.on('tick', () => {}); + } + }; + + return { renderer: app.renderer, stage: app.stage, links, refresh, graph: graph.current }; +}; diff --git a/libs/shared/lib/vis/nodelink/components/NLPopup.tsx b/libs/shared/lib/vis/nodelink/components/NLPopup.tsx new file mode 100644 index 0000000000000000000000000000000000000000..d6c016daf2bb1554a02c6369009b4762298a330a --- /dev/null +++ b/libs/shared/lib/vis/nodelink/components/NLPopup.tsx @@ -0,0 +1,168 @@ +/** + * Creates a list of attributes from a given node, that can be visualized when the node is clicked + * @param node The node from the graph which attributes need to be visualized + */ + +import { NodeType } from '../Types'; + +export const useNLPopup = (node: NodeType) => {}; +// private createAttributes = (node: NodeType) => { +// node.gfxAttributes = new PIXI.Graphics(); +// node.gfxAttributes.beginFill(0xeeeeee); +// node.gfxAttributes.name = 'attributes_' + node.id; +// node.gfxAttributes.alpha = 0; +// node.gfxAttributes.eventMode = 'auto'; +// // add title +// const gfxName = new PIXI.Text(); +// if (node.displayInfo != undefined) { +// gfxName.text = node.displayInfo; +// } else { +// gfxName.text = node.id; +// } +// gfxName.style.fontSize = 16; +// gfxName.style.fontFamily = 'Poppins, arial, sans-serif'; +// gfxName.style.fontWeight = 'bold'; +// gfxName.x = 10; +// gfxName.y = 10; +// gfxName.name = 'header'; +// node.gfxAttributes.addChild(gfxName); + +// // add attributes container +// const container = new PIXI.Container(); +// node.gfxAttributes.addChild(container); +// // add container for keys +// const keys = new PIXI.Container(); +// container.addChild(keys); +// // add container for values +// const values = new PIXI.Container(); +// container.addChild(values); + +// // add attributes +// if (node.attributes) { +// let index = 0; +// for (const key in node.attributes) { +// const attributes = this.visibleAttributes[node?.label || node.id]; +// const attributeHidden = attributes ? attributes[key] === false : false; +// if (attributeHidden) continue; // if attribute should be hidden, then skip +// this.addAttribute(keys, values, key, String(node.attributes[key]), index); +// index++; +// } +// } + +// // position attribute containers +// container.x = 10; +// container.y = 45; +// values.x = keys.width + 10; + +// // calculate width +// const width = this.calcAttrWidth(node.gfxAttributes) + 40; +// const height = container.height + 55; +// node.gfxAttributes.drawRoundedRect(0, 0, width, height, 10); + +// // add stripe +// const gfxLine = new PIXI.Graphics(); +// gfxLine.beginFill(0xbbbbbb); +// gfxLine.drawRect(10, 35, width - 20, 1); +// node.gfxAttributes.addChild(gfxLine); + +// this.stage.addChild(node.gfxAttributes); +// }; + +// /** +// * Helper function of createAttributes: adds an attribute to the new attributes graphic +// */ +// private addAttribute(keys: PIXI.Container, values: PIXI.Container, key: string, value: string, index: number): void { +// // add text for key +// const keyText = new PIXI.Text(); +// keyText.style.fontSize = 14; +// keyText.style.fontFamily = 'Poppins, arial, sans-serif'; +// keyText.style.fontWeight = 'bold'; +// keyText.name = 'key'; +// keyText.text = key + ':'; +// keyText.y = index * 20; +// keys.addChild(keyText); +// // add text for value +// const valueText = new PIXI.Text(); +// valueText.style.fontSize = 14; +// valueText.style.fontFamily = 'Poppins, arial, sans-serif'; +// valueText.name = 'value'; +// valueText.text = value; +// valueText.y = index * 20; +// values.addChild(valueText); +// } + +// /** +// * Helper function of createAttributes: calculates the width of the attributes graphic +// */ +// private calcAttrWidth(gfxAttributes: PIXI.Graphics): number { +// let width = 0; +// gfxAttributes.children.forEach((child) => { +// width = this.calcObjectWidth(child as PIXI.Text | PIXI.Graphics, width); +// }); + +// return width; +// } + +// /** +// * Helper function of calcAttrWidth: calculates the width of a child element of the attributes graphic +// */ +// private calcObjectWidth(object: PIXI.Text | PIXI.Graphics, minWidth?: number): number { +// const newWidth = object.width; +// return minWidth ? Math.max(newWidth, minWidth) : newWidth; +// } + +// /** +// * Calls for the Display that pops up and highlights the node and the links +// * if ShortestPath turns on, it turns off the highlightedlinks! +// * @param node The node clicked in the event +// */ +// public ToggleInformationOnNode(node: NodeType) { +// this.simulation.alphaTarget(0).restart(); // renderer will not always update without this line +// this.showAttributes(node); +// // this.highlightNode(node); +// // this.highlightLinks(node); +// // this.showShortestPath(); +// } + +// /** +// * When clicking on a node, toggle the select, making the text visible/invisible. +// * @param node The node which text should be toggled. +// */ +// public showAttributes = (node: NodeType) => { +// if (node.selected) { +// if (node.gfxAttributes) { +// node.gfxAttributes.alpha = 0; +// node.selected = false; +// } +// } else { +// if (node.gfxAttributes) node.gfxAttributes.destroy(); +// this.createAttributes(node); +// if (node.gfxAttributes) { +// node.gfxAttributes.scale.x = 1 / this.scalexy + 0.001 * this.scalexy; +// node.gfxAttributes.scale.y = 1 / this.scalexy + 0.001 * this.scalexy; +// node.gfxAttributes.alpha = 1; +// node.selected = true; +// } +// } +// }; + +// /** +// * Refreshes the attributes. This function is called when the attribute filter has been changed +// * @param graph the graph of which its nodes should be checked for attributes +// */ +// const UpdateAttributes = (graph: GraphType) => { +// this.simulation.alphaTarget(0).restart(); // required so that the visualization updates +// graph.nodes.forEach((node: NodeType) => { +// if (node.gfxAttributes !== undefined) { +// // destroy and add the attributes pop-up again +// node.gfxAttributes.destroy(); +// this.createAttributes(node); +// node.gfxAttributes.scale.x = 1 / this.scalexy + 0.001 * this.scalexy; +// node.gfxAttributes.scale.y = 1 / this.scalexy + 0.001 * this.scalexy; +// // make the pop-up visible if it was visible before +// if (node.selected) { +// node.gfxAttributes.alpha = 1; +// } +// } +// }); +// }; diff --git a/libs/shared/lib/vis/nodelink/components/utils.tsx b/libs/shared/lib/vis/nodelink/components/utils.tsx new file mode 100644 index 0000000000000000000000000000000000000000..84513035db3164c9c223119b23ee625e534ed120 --- /dev/null +++ b/libs/shared/lib/vis/nodelink/components/utils.tsx @@ -0,0 +1,55 @@ +import { tailwindColors } from 'config'; +import { GraphType, LinkType, NodeType } from '../Types'; + +/** + * Colour is a function that takes a string of a number and returns a number of a color out of the d3 color scheme. + * @param num Num is the input string representing a number of a colorgroup. + * @returns {number} A number corresponding to a color in the d3 color scheme. + */ +export function nodeColor(num: number) { + // num = num % 4; + // const col = '#000000'; + const col = tailwindColors.custom.nodes[num % tailwindColors.custom.nodes.length]; + return binaryColor(col); +} + +export function binaryColor(color: string) { + return Number('0x' + color.replace('#', '')); +} + +/** + * Used when you select nodes. + * The highlight is drawn in ticked. + * @param nodes The nodes you want to related edges to. + * @returns {LinkType[]} All the links related to all the nodes + */ +export const getRelatedLinks = (graph: GraphType, nodes: NodeType[], jaccardThreshold: number): LinkType[] => { + const relatedLinks: LinkType[] = []; + graph.links.forEach((link: LinkType) => { + const { source, target } = link; + if (isLinkVisible(link, jaccardThreshold)) { + nodes.forEach((node: NodeType) => { + if (source == node || target == node || source == node.id || target == node.id) { + relatedLinks.push(link); + } + }); + } + }); + return relatedLinks; +}; + +/** + * Checks wheter a link is visible. + * This is used for highlighting nodes. + * @param link The link you want to check wheter it's visable or not + * @returns {boolean} + */ +export function isLinkVisible(link: LinkType, jaccardThreshold: number): boolean { + //About the next line, If you don't do this here but lets say in the constructor it errors. So far no performance issues where noticed. + if (link.mlEdge) { + if (link.value > jaccardThreshold) { + return true; + } + } else return true; + return false; +} diff --git a/libs/shared/lib/vis/nodelink/nodelinkvis.stories.tsx b/libs/shared/lib/vis/nodelink/nodelinkvis.stories.tsx index 113e73554ae23c0a0f0e30960bee464b2609770e..6521896c33b123f2fd66c39f93516a3fda7634a6 100644 --- a/libs/shared/lib/vis/nodelink/nodelinkvis.stories.tsx +++ b/libs/shared/lib/vis/nodelink/nodelinkvis.stories.tsx @@ -1,17 +1,10 @@ import React from 'react'; -import { ComponentStory, Meta } from '@storybook/react'; +import { Meta } from '@storybook/react'; import { NodeLinkVis } from './nodelinkvis'; -import { - assignNewGraphQueryResult, - colorPaletteConfigSlice, - graphQueryResultSlice, - resetGraphQueryResults, - store, -} from '../../data-access/store'; +import { assignNewGraphQueryResult, graphQueryResultSlice, resetGraphQueryResults, store } from '../../data-access/store'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '../../data-access/theme'; import { big2ndChamberQueryResult, smallFlightsQueryResults, mockLargeQueryResults } from '../../mock-data'; const Component: Meta<typeof NodeLinkVis> = { @@ -24,16 +17,14 @@ const Component: Meta<typeof NodeLinkVis> = { decorators: [ (story) => ( <Provider store={Mockstore}> - <GraphPolarisThemeProvider> - <div - style={{ - width: '100%', - height: '100vh', - }} - > - {story()} - </div> - </GraphPolarisThemeProvider> + <div + style={{ + width: '100%', + height: '100vh', + }} + > + {story()} + </div> </Provider> ), ], @@ -41,12 +32,12 @@ const Component: Meta<typeof NodeLinkVis> = { const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, graphQueryResult: graphQueryResultSlice.reducer, }, }); export const TestWithData = { + layout: 'fullscreen', args: { loading: false, }, diff --git a/libs/shared/lib/vis/nodelink/nodelinkvis.tsx b/libs/shared/lib/vis/nodelink/nodelinkvis.tsx index 8a4b6aa11d106bf04d9fc1b66a62d883ace58dbd..58d75ce677e2b245f8ede222f08590add3cdd36e 100644 --- a/libs/shared/lib/vis/nodelink/nodelinkvis.tsx +++ b/libs/shared/lib/vis/nodelink/nodelinkvis.tsx @@ -1,15 +1,10 @@ -import { changePrimary, useAppDispatch, useGraphQueryResult } from '../../data-access/store'; -import { useTheme } from '@mui/material'; +import { GraphQueryResult, useAppDispatch, useGraphQueryResult } from '../../data-access/store'; import React, { LegacyRef, useEffect, useRef, useState } from 'react'; import styled from 'styled-components'; -import ReactJSONView from 'react-json-view'; -import styles from './nodelinkvis.module.scss'; import * as PIXI from 'pixi.js'; import { GraphType, LinkType, NodeType } from './Types'; -import NodeLinkViewModel from './NodeLinkViewModel'; -import ResultNodeLinkParserUseCase from '../shared/ResultNodeLinkParserUseCase'; -import VisConfigPanelComponent from '../shared/VisConfigPanel/VisConfigPanel'; -import { use } from 'cytoscape'; +import { useNLPixi } from './components/NLPixi'; +import { getRelatedLinks } from './components/utils'; interface Props { loading?: boolean; @@ -42,84 +37,70 @@ export interface NodeLinkComponentState { } export const NodeLinkVis = React.memo((props: Props) => { + const jaccardThreshold = undefined; const myRef = useRef<HTMLDivElement>(null); - const nodeLinkViewModelRef = useRef<NodeLinkViewModel>(); - - // const [state, setState] = useState<NodeLinkComponentState>({ - // graph: nodeLinkViewModel.graph, - // width: nodeLinkViewModel.width, - // height: nodeLinkViewModel.height, - // stage: nodeLinkViewModel.stage, - // links: nodeLinkViewModel.links, - // simulation: nodeLinkViewModel.simulation, - // myRef: nodeLinkViewModel.myRef, - // renderer: nodeLinkViewModel.renderer, - // panOffset: nodeLinkViewModel.panOffset, - // dragOffset: nodeLinkViewModel.dragOffset, - // scalexy: nodeLinkViewModel.scalexy, - // }); + const [graph, setGraph] = useState<GraphType>(); + const [windowSize, setWindowSize] = useState({ width: 1000, height: 1000 }); + const [highlightNodes, setHighlightNodes] = useState<NodeType[]>([]); + const [highlightedLinks, setHighlightedLinks] = useState<LinkType[]>([]); + + const pixi = useNLPixi({ + windowSize: windowSize, + onClick: (node) => { + if (graph) { + //If node is already clicked we should remove it from the list. + if (highlightNodes.includes(node)) { + const index = highlightNodes.indexOf(node, 0); + setHighlightNodes(highlightNodes.splice(index, 1)); + } else { + //Else add it to the list. + setHighlightNodes(highlightNodes.concat(node)); + } + //Update the list of edges that need to be highlighted + setHighlightedLinks(getRelatedLinks(graph, highlightNodes, jaccardThreshold || -1)); + } + }, + highlightNodes: highlightNodes, + currentShortestPathEdges: [], + highlightedLinks: highlightedLinks, + jaccardThreshold: jaccardThreshold, + myDiv: myRef.current, + }); const graphQueryResult = useGraphQueryResult(); - const dispatch = useAppDispatch(); - const theme = useTheme(); useEffect(() => { console.debug('update nodelink useEffect', graphQueryResult); - nodeLinkViewModelRef?.current?.consumeMessageFromBackend(graphQueryResult); - nodeLinkViewModelRef?.current?.startSimulation(); - nodeLinkViewModelRef?.current?.selectD3Elements(); + pixi.refresh(graphQueryResult); }, [graphQueryResult]); useEffect(() => { - console.debug('loaded NodeLinkVis'); - const resultNodeLinkParserUseCase = new ResultNodeLinkParserUseCase(); - const nodeLinkViewModel = new NodeLinkViewModel( - resultNodeLinkParserUseCase, - graphQueryResult, - myRef?.current?.clientWidth || 1000, - myRef?.current?.clientHeight || 1000, - myRef, - theme - ); - nodeLinkViewModelRef.current = nodeLinkViewModel; - - // Attach Viewmodel Observer - // nodeLinkViewModel.attachView(this); - - window.addEventListener('resize', nodeLinkViewModel.handleResize); - - // Init simulation - nodeLinkViewModel.startSimulation(); - - // Init the graph, with node radius 5 - // nodeLinkViewModel.radius = Radius(); - // nodeLinkViewModel.consumeMessageFromBackend(graphQueryResult); - // nodeLinkViewModel.SetNodeGraphics(graphQueryResult, Radius()); - - // Select d3 elements for zooming, panning and dragging - nodeLinkViewModel.selectD3Elements(); - - nodeLinkViewModel.simulation.on('tick', nodeLinkViewModel.ticked); - + console.log('loaded NodeLinkVis'); + window.addEventListener('resize', handleResize); // nodeLinkViewModel.subscribeToQueryResult(); // nodeLinkViewModel.setThisVisAsExportable(); // nodeLinkViewModel.subscribeToAnalyticsData(); - }, [myRef]); - useEffect(() => { return () => { console.log('unloaded NodeLinkVis'); - - if (nodeLinkViewModelRef?.current) { - // Detach Viewmodel Observer - // nodeLinkViewModel.detachView(); - window.removeEventListener('resize', nodeLinkViewModelRef.current.handleResize); - } + window.removeEventListener('resize', handleResize); }; }, []); + useEffect(() => { + console.debug('loaded NodeLinkVis'); + setWindowSize({ width: myRef?.current?.clientWidth || 1000, height: myRef?.current?.clientHeight || 1000 }); + }, [myRef]); + const loading = props.loading; + // FUNCIONS FROM MODEL + + /** When the screen gets resized, resize the node link canvas ViewModel. */ + const handleResize = () => { + setWindowSize({ width: window.innerWidth, height: window.innerHeight - 6 }); + }; + return ( <> {/* <input @@ -131,60 +112,22 @@ export const NodeLinkVis = React.memo((props: Props) => { value={theme.palette.primary.main} /> */} {loading && ( - <div - style={{ - marginTop: '40px', - paddingLeft: '30px', - }} - > - <svg - // className={styles.rotating} - xmlns="http://www.w3.org/2000/svg" - viewBox="0 0 50 50" - > - <circle - // className={styles.ring} - cx="25" - cy="25" - r="20" - ></circle> - <circle - // className={styles.ball} - cx="25" - cy="5" - r="3.5" - ></circle> - </svg> + <div className="w-full h-full flex justify-center self-center items-center"> + <span className="loading loading-spinner loading-lg"></span> </div> )} {!loading && ( - <div - className="viscontainer" - style={{ - overflowY: 'auto', - width: '100%', - height: '100%', - }} - > - <div - style={{ - width: '100%', - height: '100%', - overflow: 'hidden', - backgroundColor: theme.palette.custom.visBackground, - }} - className="renderer" - ref={myRef} - ></div> - <VisConfigPanelComponent> - {/* <NodeLinkConfigPanelComponent + <div className="h-full overflow-hidden"> + <div className="h-full overflow-hidden" ref={myRef}></div> + {/* <VisConfigPanelComponent> */} + {/* <NodeLinkConfigPanelComponent graph={this.state.graph} nlViewModel={this.nodeLinkViewModel} /> */} - {/*</VisConfigPanelComponent>*/} - {/*<VisConfigPanelComponent isLeft>*/} - {/* <AttributesConfigPanel nodeLinkViewModel={this.nodeLinkViewModel} />*/} - </VisConfigPanelComponent> + {/*</VisConfigPanelComponent>*/} + {/*<VisConfigPanelComponent isLeft>*/} + {/* <AttributesConfigPanel nodeLinkViewModel={this.nodeLinkViewModel} />*/} + {/* </VisConfigPanelComponent> */} </div> )} </> diff --git a/libs/shared/lib/vis/nodelink/nodelinkviz.logic.tsx b/libs/shared/lib/vis/nodelink/nodelinkviz.logic.tsx deleted file mode 100644 index 591ef18c86f8f7d72aed08fa412da8bdc5dd4659..0000000000000000000000000000000000000000 --- a/libs/shared/lib/vis/nodelink/nodelinkviz.logic.tsx +++ /dev/null @@ -1,97 +0,0 @@ -/** - * This program has been developed by students from the bachelor Computer Science at - * Utrecht University within the Software Project course. - * © Copyright Utrecht University (Department of Information and Computing Sciences) - */ - -import * as PIXI from 'pixi.js'; - -/** Types for the nodes and links in the node-link diagram. */ -export type GraphType = { - nodes: NodeType[]; - links: LinkType[]; - linkPrediction: boolean; - shortestPath: boolean; - communityDetection: boolean; - numberOfMlClusters?: number; -}; - -/** The interface for a node in the node-link diagram */ -export interface NodeType extends d3.SimulationNodeDatum { - id: string; - - // Number to determine the color of the node - type: number; - attributes?: Record<string, any>; - cluster?: number; - clusterAccoringToMLData?: number; - shortestPathData?: Record<string, string[]>; - - // Node that is drawn. - gfx?: PIXI.Graphics; - radius?: number; - // Text to be displayed on top of the node. - gfxtext?: PIXI.Text; - gfxAttributes?: PIXI.Graphics; - selected?: boolean; - index?: number; - - // The text that will be shown on top of the node if selected. - displayInfo?: string; - - // Node’s current x-position. - x?: number; - - // Node’s current y-position. - y?: number; - - // Node’s current x-velocity - vx?: number; - - // Node’s current y-velocity - vy?: number; - - // Node’s fixed x-position (if position was fixed) - fx?: number | null; - - // Node’s fixed y-position (if position was fixed) - fy?: number | null; -} - -/** The interface for a link in the node-link diagram */ -export interface LinkType extends d3.SimulationLinkDatum<NodeType> { - // The thickness of a line - value: number; - // To check if an edge is calculated based on a ML algorithm - mlEdge: boolean; -} - -/**collectionNode holds 1 entry per node kind (so for example a MockNode with name "parties" and all associated attributes,) */ -export type TypeNode = { - name: string; //Collection name - attributes: string[]; //attributes. This includes all attributes found in the collection - type: number | undefined; //number that represents collection of node, for colorscheme - visualisations: Visualisation[]; //The way to visualize attributes of this Node kind -}; - -export type CommunityDetectionNode = { - cluster: number; //group as used by colouring scheme -}; - -/**Visualisation holds the visualisation method for an attribute */ -export type Visualisation = { - attribute: string; //attribute type (e.g. 'age') - vis: string; //visualisation type (e.g. 'radius') -}; - -/** possible colors to pick from*/ -export type Colors = { - name: string; -}; - -/**AssignedColors is a simple holder for color selection */ -export type AssignedColors = { - collection: number | undefined; //number of the collection (type or group) - color: string; //color in hex - default: string; //default color, for easy switching back -}; diff --git a/libs/shared/lib/vis/paohvis/components/MakePaohvisMenu.tsx b/libs/shared/lib/vis/paohvis/components/MakePaohvisMenu.tsx index 1d2f2a04e62c9119c543034064ef21a85d6c7087..7c152154363f2a9871b0ea0eddc1672415fa978b 100644 --- a/libs/shared/lib/vis/paohvis/components/MakePaohvisMenu.tsx +++ b/libs/shared/lib/vis/paohvis/components/MakePaohvisMenu.tsx @@ -8,8 +8,7 @@ /* The comment above was added so the code coverage wouldn't count this file towards code coverage. * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { Button, MenuItem, TextField, IconButton } from '@mui/material'; -import React, { ReactElement, useEffect } from 'react'; +import React, { ChangeEventHandler, ReactElement, useEffect, useMemo } from 'react'; import { Attribute, AttributeNames, @@ -96,6 +95,10 @@ export const MakePaohvisMenu = (props: MakePaohvisMenuProps) => { attributeValue: '?', }); + useEffect(() => { + if (state.entityVertical) onChangeEntity(state.entityVertical); + }, [state.entityVertical, state.entitiesFromSchema]); + // // FUNCTIONS // @@ -103,11 +106,11 @@ export const MakePaohvisMenu = (props: MakePaohvisMenuProps) => { /** * Called when the entity field is changed. * Calculates the `relationNameOptions`, resets the `entityHorizontal`, `relationName` and `attributeName` and sets the new state. - * @param {React.ChangeEvent<HTMLInputElement>} event The event that is given by the input field when a change event is fired. * It has the value of the entity you clicked on. */ - function onChangeEntity(event: React.ChangeEvent<HTMLInputElement>): void { - const newEntity = event.target.value; + function onChangeEntity(newEntity: string): void { + console.log(newEntity, state.entitiesFromSchema.relationsPerEntity); + setState((draft) => { draft.relationNameOptions = []; const relationNames: string[] = state.entitiesFromSchema.relationsPerEntity[newEntity]; @@ -138,9 +141,8 @@ export const MakePaohvisMenu = (props: MakePaohvisMenuProps) => { draft.relationValue = ''; draft.attributeValue = ''; - draft.entityVertical = newEntity; draft.entityHorizontal = ''; - draft.relationName = ''; + draft.relationName = draft.relationNameOptions.length > 0 ? draft.relationNameOptions[0] : ''; draft.isEntityVerticalEqualToRelationFrom = true; draft.attributeNameAndOrigin = ''; draft.isButtonEnabled = false; @@ -149,20 +151,25 @@ export const MakePaohvisMenu = (props: MakePaohvisMenuProps) => { }); } + useEffect(() => { + console.log(state.relationName, state.relationNameOptions); + + if (state.relationName) onChangeRelationName(state.relationName); + }, [state.relationName, state.relationNameOptions, state.entityVertical]); /** * Called when the relationName field is changed. * Calculates the possible attribute values, resets the `attributeValue`, sets the `entityHorizontal`. * @param {React.ChangeEvent<HTMLInputElement>} event The event that is given by the input field when a change event is fired. * It has the value of the relation you clicked on. */ - function onChangeRelationName(event: React.ChangeEvent<HTMLInputElement>): void { + function onChangeRelationName(relationName: string): void { + console.log('onChangeRelationName'); setState((draft) => { - draft.relationName = event.target.value; draft.attributeValue = ''; draft.attributeNameAndOrigin = ''; draft.isButtonEnabled = false; - const newRelationSplit = event.target.value.split(':'); + const newRelationSplit = relationName.split(':'); const newRelation = newRelationSplit[0]; // This value should always be there @@ -221,17 +228,18 @@ export const MakePaohvisMenu = (props: MakePaohvisMenuProps) => { }); } + useEffect(() => { + if (state.attributeValue) onChangeAttributeName(state.attributeValue); + }, [state.attributeValue, state.relationName]); /** * Called when the attributeName field is changed. * Sets the chosen attribute value, enables the "Make" button and sets the state. * @param {React.ChangeEvent<HTMLInputElement>} event The event that is given by the input field when a change event is fired. * It has the value of the attributeName you clicked on. */ - function onChangeAttributeName(event: React.ChangeEvent<HTMLInputElement>): void { - const newAttribute = event.target.value; + function onChangeAttributeName(newAttribute: string): void { setState((draft) => { const isSelectedAttributeFromEntity = newAttribute.split(':')[1] == AttributeOrigin.entity; - draft.attributeValue = newAttribute; // render changes draft.attributeNameAndOrigin = newAttribute; @@ -241,13 +249,15 @@ export const MakePaohvisMenu = (props: MakePaohvisMenuProps) => { }); } + useEffect(() => { + if (state.sortOrder) onChangeSortOrder(state.sortOrder); + }, [state.sortOrder]); /** * Called when the sort order field is changed. * Sets the state by changing the sort order. - * @param {React.ChangeEvent<HTMLInputElement>} event The event that is given by the input field when a change event is fired. */ - function onChangeSortOrder(event: React.ChangeEvent<HTMLInputElement>): void { - const newSortOrder: NodeOrder = event.target.value as NodeOrder; + function onChangeSortOrder(value: string): void { + const newSortOrder: NodeOrder = value as NodeOrder; const nodeOrders: string[] = Object.values(NodeOrder); if (nodeOrders.includes(newSortOrder)) { unflipReverseIconButton(); @@ -432,34 +442,31 @@ export const MakePaohvisMenu = (props: MakePaohvisMenuProps) => { // // Retrieve the possible entity options. If none available, set helper message. - let entityMenuItems: ReactElement[]; - if (state.entitiesFromQueryResult.length > 0) { - entityMenuItems = state.entitiesFromQueryResult.map((entity) => ( - <MenuItem key={entity} value={entity}> - {entity} - </MenuItem> - )); - } else - entityMenuItems = [ - <MenuItem key="placeholder" value="" disabled> - No query data available - </MenuItem>, - ]; + let entityMenuItems: ReactElement[] = useMemo(() => { + if (state.entitiesFromQueryResult.length > 0) { + return state.entitiesFromQueryResult.map((entity) => ( + <option key={entity} value={entity}> + {entity} + </option> + )); + } else + return [ + <option key="placeholder" value="" disabled> + No query data available + </option>, + ]; + }, [state.entitiesFromQueryResult]); // Retrieve the possible relationName options. If none available, set helper message. - let relationNameMenuItems: ReactElement[]; - if (state.relationNameOptions.length > 0) - relationNameMenuItems = state.relationNameOptions.map((relation) => ( - <MenuItem key={relation} value={relation}> - {relation} - </MenuItem> - )); - else - relationNameMenuItems = [ - <MenuItem key="placeholder" value="" disabled> - First select an entity with one or more relations - </MenuItem>, - ]; + let relationNameMenuItems: ReactElement[] = useMemo(() => { + if (state.relationNameOptions.length > 0) + return state.relationNameOptions.map((relation) => ( + <option key={relation} value={relation}> + {relation} + </option> + )); + else return []; + }, [state.relationNameOptions]); // Retrieve all the possible attributeName options. If none available, set helper message. let attributeNameMenuItems: ReactElement[] = []; @@ -468,35 +475,30 @@ export const MakePaohvisMenu = (props: MakePaohvisMenuProps) => { let attributeNameMenuItemsRelation: ReactElement[] = []; if (state.attributeNameOptions['Entity'] && state.attributeNameOptions['Relation']) { attributeNameMenuItemsNoAttribute = state.attributeNameOptions['No attribute'].map((attribute) => ( - <MenuItem key={attribute} value={`${attribute}:NoAttribute`}> + <option key={attribute} value={`${attribute}:NoAttribute`}> {attribute} - </MenuItem> + </option> )); attributeNameMenuItemsEntity = state.attributeNameOptions['Entity'].map((attribute) => ( - <MenuItem key={`${attribute}:Entity`} value={`${attribute}:Entity`}> + <option key={`${attribute}:Entity`} value={`${attribute}:Entity`}> {`${attribute} : Entity`} - </MenuItem> + </option> )); attributeNameMenuItemsRelation = state.attributeNameOptions['Relation'].map((attribute) => ( - <MenuItem key={`${attribute}:Relation`} value={`${attribute}:Relation`}> + <option key={`${attribute}:Relation`} value={`${attribute}:Relation`}> {`${attribute} : Relation`} - </MenuItem> + </option> )); attributeNameMenuItems = attributeNameMenuItemsNoAttribute.concat(attributeNameMenuItemsEntity).concat(attributeNameMenuItemsRelation); - } else - attributeNameMenuItems = [ - <MenuItem key="placeholder" value="" disabled> - First select an relation with one or more attributes - </MenuItem>, - ]; + } else attributeNameMenuItems = []; // make sort order menu items const sortOrderMenuItems: ReactElement[] = Object.values(NodeOrder).map((nodeOrder) => { return ( - <MenuItem key={nodeOrder} value={nodeOrder}> + <option key={nodeOrder} value={nodeOrder}> {nodeOrder} - </MenuItem> + </option> ); }); @@ -512,55 +514,50 @@ export const MakePaohvisMenu = (props: MakePaohvisMenuProps) => { } // return the whole MakePaohvisMenu + // TODO! fix inputs to select return ( - <div className="makePaohvisMenu"> - <TextField - select - className="textFieldMakePaohvisMenu" - id="standard-select-entity" - label="Entity" - value={state.entityVertical} - onChange={onChangeEntity} - > - {entityMenuItems} - </TextField> - <TextField - select - className="textFieldMakePaohvisMenu" - id="standard-select-relation" - label="Relation" - value={state.relationName} - onChange={onChangeRelationName} - > - {relationNameMenuItems} - </TextField> - <TextField - select - className="textFieldMakePaohvisMenu" - id="standard-select-attribute" - label="Attribute" - value={state.attributeNameAndOrigin} - onChange={onChangeAttributeName} - > - {attributeNameMenuItems} - </TextField> - <TextField - select - className="textFieldMakePaohvisMenu" - id="standard-select-sort-order" - label="Sort order" - value={state.sortOrder} - onChange={onChangeSortOrder} - > - {sortOrderMenuItems} - </TextField> - <IconButton className={'reverseIconButton'} color="inherit" onClick={onClickReverseOrder}> - {reverseIcon} - </IconButton> - - <Button id="makeButton" variant="contained" disabled={!state.isButtonEnabled} onClick={onClickMakeButton}> - <span>Make</span> - </Button> + <div className="nav card"> + <div className="card-body flex flex-row overflow-y-auto max-w-[60vw]"> + <select + className="select" + id="standard-select-entity" + value={state.entityVertical} + onChange={(e) => setState({ ...state, entityVertical: e.target.value })} + > + {entityMenuItems} + </select> + <select + className={`select ${relationNameMenuItems.length === 0 ? 'select-disabled' : ''}`} + id="standard-select-relation" + value={state.relationName} + onChange={(e) => setState({ ...state, relationName: e.target.value })} + > + {relationNameMenuItems} + </select> + <select + className={`select ${attributeNameMenuItems.length === 0 ? 'select-disabled' : ''}`} + id="standard-select-attribute" + value={state.attributeNameAndOrigin} + onChange={(e) => setState({ ...state, attributeValue: e.target.value })} + > + {attributeNameMenuItems} + </select> + <select + className="select" + id="standard-select-sort-order" + value={state.sortOrder} + onChange={(e) => setState({ ...state, sortOrder: e.target.value as NodeOrder })} + > + {sortOrderMenuItems} + </select> + <button className={'reverseIconButton'} color="inherit" onClick={onClickReverseOrder}> + {reverseIcon} + </button> + + <button id="makeButton" className="btn btn-outline" disabled={!state.isButtonEnabled} onClick={onClickMakeButton}> + <span>Make</span> + </button> + </div> </div> ); }; diff --git a/libs/shared/lib/vis/paohvis/components/PaohvisFilterComponent.tsx b/libs/shared/lib/vis/paohvis/components/PaohvisFilterComponent.tsx index 76377ee7d0077e7134dfae6f13b97773c3ed410a..e64495e5391b1b142608b9b750065afb94591d95 100644 --- a/libs/shared/lib/vis/paohvis/components/PaohvisFilterComponent.tsx +++ b/libs/shared/lib/vis/paohvis/components/PaohvisFilterComponent.tsx @@ -8,11 +8,10 @@ /* The comment above was added so the code coverage wouldn't count this file towards code coverage. * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import React, { ChangeEventHandler, ReactElement, useState, MouseEventHandler, useEffect } from 'react'; +import React, { ChangeEventHandler, ReactElement, useState, MouseEventHandler, useEffect, useMemo } from 'react'; import styles from './PaohvisFilterComponent.module.scss'; import { AttributeNames, FilterType } from '../Types'; import { useImmer } from 'use-immer'; -import { Button, MenuItem, TextField } from '@mui/material'; import { useGraphQueryResult, useSchemaGraph } from '@graphpolaris/shared/lib/data-access'; import { isNodeLinkResult } from '../../shared/ResultNodeLinkParserUseCase'; import { calculateAttributesAndRelations, calculateAttributesFromRelation } from '../utils/utils'; @@ -101,7 +100,7 @@ export const PaohvisFilterComponent = (props: PaohvisFilterProps) => { * Based on the type of the chosen attribute, a different list with predicates is generated. * @param event that called this eventhandler. */ - function onChangeAttributeName(event: React.ChangeEvent<HTMLInputElement>): void { + function onChangeAttributeName(event: React.ChangeEvent<HTMLSelectElement>): void { const newAttributeNameAndType = event.target.value; const newAttributeSplit = event.target.value.split(':'); const newAttributeType = newAttributeSplit[1]; @@ -135,7 +134,7 @@ export const PaohvisFilterComponent = (props: PaohvisFilterProps) => { * This is called when the value of the predicate is changed in the filter component. * @param event that called this eventhandler. */ - function onChangePredicate(event: React.ChangeEvent<HTMLInputElement>): void { + function onChangePredicate(event: React.ChangeEvent<HTMLSelectElement>): void { const newpredicate = event.target.value; if (!isPredicateValid(newpredicate)) throw new Error('The chosen predicate is invalid'); @@ -157,7 +156,13 @@ export const PaohvisFilterComponent = (props: PaohvisFilterProps) => { function onChangeCompareValue(event: React.ChangeEvent<HTMLInputElement>): void { setState((draft) => { draft.compareValue = event.target.value; - draft.isFilterButtonEnabled = isFilterConfigurationValid(); + console.log( + containsFilterTargetChosenAttribute(draft.attributeNameAndType), + isPredicateValid(draft.predicate), + isCompareValueTypeValid(draft.compareValue) + ); + + draft.isFilterButtonEnabled = isFilterConfigurationValid(draft); return draft; }); } @@ -167,7 +172,7 @@ export const PaohvisFilterComponent = (props: PaohvisFilterProps) => { * It checks if the input is correct and sends the information for the filters to the PaohvisViewModelImpl. */ function onClickFilterPaohvisButton(): void { - if (!isFilterConfigurationValid()) throw new Error('Error: chosen attribute of predicate-value is invalid.'); + if (!isFilterConfigurationValid(state)) throw new Error('Error: chosen attribute of predicate-value is invalid.'); props.filterPaohvis(isTargetEntity, state.filterTarget, state.attributeNameAndType, state.predicate, state.compareValue); } @@ -192,7 +197,7 @@ export const PaohvisFilterComponent = (props: PaohvisFilterProps) => { * Checks if the filter configuration is valid. * @returns {boolean} true if the filter configuration is valid. */ - function isFilterConfigurationValid(): boolean { + function isFilterConfigurationValid(state: PaohvisFilterState): boolean { return ( containsFilterTargetChosenAttribute(state.attributeNameAndType) && isPredicateValid(state.predicate) && @@ -309,66 +314,81 @@ export const PaohvisFilterComponent = (props: PaohvisFilterProps) => { // // Check if the given entity or relation is in the queryResult - let attributeNameMenuItems: ReactElement[] = []; - if (state.attributeNamesOptions.length > 0) { - attributeNameMenuItems = state.attributeNamesOptions.map((attributeNameAndType) => { - const attributeName = attributeNameAndType.split(':')[0]; - return ( - <MenuItem key={attributeName} value={attributeNameAndType}> - {attributeNameAndType} - </MenuItem> - ); - }); - } else - attributeNameMenuItems = [ - <MenuItem key="placeholder" value="" disabled> - First select an entity/relation with one or more attributes - </MenuItem>, - ]; - - let predicateTypeList: ReactElement[] = []; - if (state.predicateTypeList.length > 0) { - predicateTypeList = state.predicateTypeList.map((predicate) => ( - <MenuItem key={predicate} value={predicate}> - {predicate} - </MenuItem> - )); - } else - predicateTypeList = [ - <MenuItem key="placeholder" value="" disabled> - First select an attribute - </MenuItem>, - ]; + let attributeNameMenuItems: ReactElement[] = useMemo(() => { + if (state.attributeNamesOptions.length > 0) { + return state.attributeNamesOptions.map((attributeNameAndType, i) => { + const attributeName = attributeNameAndType.split(':')[0]; + return ( + <option key={attributeName + i} value={attributeNameAndType}> + {attributeNameAndType} + </option> + ); + }); + } else + return [ + <option key="placeholder" value="" disabled> + First select an entity/relation with one or more attributes + </option>, + ]; + }, [state.attributeNamesOptions]); + + let predicateTypeList: ReactElement[] = useMemo(() => { + if (state.predicateTypeList.length > 0) { + return state.predicateTypeList.map((predicate, i) => ( + <option key={predicate + i} value={predicate}> + {predicate} + </option> + )); + } else + return [ + <option key="placeholder" value="" disabled> + First select an attribute + </option>, + ]; + }, [state.predicateTypeList]); return ( - <div className={styles.container}> - <p className={styles.title}>PAOHVis filters{props.axis}:</p> - <div className={styles.selectContainer}> - <p className={styles.subtitle}>{state.filterTarget}</p> - <div className={styles.selectGroup}> - <TextField - select - id="standard-select-entity" - label="Attribute" - value={state.attributeNameAndType} - onChange={onChangeAttributeName} - > - {attributeNameMenuItems} - </TextField> - <TextField select id="standard-select-relation" label="Relation" value={state.predicate} onChange={onChangePredicate}> - {predicateTypeList} - </TextField> - <TextField id="standard-select-relation" label="Value" value={state.compareValue} onChange={onChangeCompareValue}> - {} - </TextField> - - <div className={styles.selectButtonGroup}> - <Button variant="contained" disabled={!state.isFilterButtonEnabled} onClick={onClickFilterPaohvisButton}> - <span style={{ fontWeight: 'bold' }}>Apply filter</span> - </Button> - <Button variant="contained" onClick={onClickResetFilter}> - <span style={{ fontWeight: 'bold' }}>Reset filter</span> - </Button> + <div className="card w-full"> + <div className="card-body w-full p-4"> + <h2 className="card-title">PAOHVis filters{props.axis}:</h2> + <div> + <p>{state.filterTarget}</p> + <div className="flex flex-col gap-3"> + <div className="form-control"> + <label className="label">Attribute</label> + <select + id="standard-select-entity" + className="select w-full" + value={state.attributeNameAndType} + onChange={onChangeAttributeName} + > + {attributeNameMenuItems} + </select> + </div> + <div className="form-control"> + <label className="label">Relation</label> + <select id="standard-select-relation" className="select w-full" value={state.predicate} onChange={onChangePredicate}> + {predicateTypeList} + </select> + </div> + <div className="form-control"> + <label className="label">Value</label> + <input + id="standard-select-relation" + className="select w-full" + value={state.compareValue} + onChange={onChangeCompareValue} + ></input> + </div> + + <div className="btn-group w-full flex flex-col gap-2"> + <button className="btn btn-primary w-full" disabled={!state.isFilterButtonEnabled} onClick={onClickFilterPaohvisButton}> + Apply filter + </button> + <button className="btn btn-outline w-full" onClick={onClickResetFilter}> + Reset filter + </button> + </div> </div> </div> </div> diff --git a/libs/shared/lib/vis/paohvis/paohvis.stories.tsx b/libs/shared/lib/vis/paohvis/paohvis.stories.tsx index a06fae382ded0af732c5ab1f38ef0df0bd3ddc3f..f9935803d22798df4a35c09ba116d4f7bcb8acf8 100644 --- a/libs/shared/lib/vis/paohvis/paohvis.stories.tsx +++ b/libs/shared/lib/vis/paohvis/paohvis.stories.tsx @@ -1,5 +1,4 @@ -import { assignNewGraphQueryResult, colorPaletteConfigSlice, graphQueryResultSlice, schemaSlice, setSchema } from '../../data-access/store'; -import { GraphPolarisThemeProvider } from '../../data-access/theme'; +import { assignNewGraphQueryResult, graphQueryResultSlice, schemaSlice, setSchema } from '../../data-access/store'; import { configureStore } from '@reduxjs/toolkit'; import { Meta, ComponentStory } from '@storybook/react'; import { Provider } from 'react-redux'; @@ -24,9 +23,7 @@ const Component: Meta<typeof Paohvis> = { height: '95vh', }} > - <Provider store={Mockstore}> - <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> - </Provider> + <Provider store={Mockstore}>{story()}</Provider> </div> ), ], @@ -35,7 +32,6 @@ const Component: Meta<typeof Paohvis> = { const Mockstore = configureStore({ reducer: { schema: schemaSlice.reducer, - colorPaletteConfig: colorPaletteConfigSlice.reducer, graphQueryResult: graphQueryResultSlice.reducer, }, }); diff --git a/libs/shared/lib/vis/paohvis/paohvis.tsx b/libs/shared/lib/vis/paohvis/paohvis.tsx index 4c2ab978d030686205b55ebab9f2ad75e4499ddb..d3c435dcce7b9ed57cb75e1c0e6c4143f7414186 100644 --- a/libs/shared/lib/vis/paohvis/paohvis.tsx +++ b/libs/shared/lib/vis/paohvis/paohvis.tsx @@ -579,63 +579,60 @@ export const PaohVis = (props: Props) => { // returns the whole PAOHvis visualisation panel return ( <div className={styles.container}> - <div className={styles.visContainer}> - <div className={styles.full}> - <div className={styles.full} onMouseMove={onMouseMoveToolTip}> - <MakePaohvisMenu // render the MakePAOHvisMenu - makePaohvis={onClickMakeButton} - /> - {tableMessage} - <div className={styles.visContainerSvg}> - <svg - ref={svgRef} - style={{ - width: tableWidthWithExtraColumnLabelWidth, - height: yOffset + (data.rowLabels.length + 1) * props.rowHeight, - }} - > - <RowLabelColumn // render the PAOHvis itself - onMouseEnter={onMouseEnterRow} - onMouseLeave={onMouseLeaveRow} - titles={data.rowLabels} - width={rowLabelColumnWidth} - rowHeight={props.rowHeight} // viewModel.rowHeight? - yOffset={yOffset} - /> - {hyperEdgeRangeColumns} - </svg> - </div> - <Tooltip /> + <MakePaohvisMenu // render the MakePAOHvisMenu + makePaohvis={onClickMakeButton} + /> + <div className="w-full h-full"> + <div className="w-full h-full" onMouseMove={onMouseMoveToolTip}> + {tableMessage} + <div className="w-full h-full"> + <svg + ref={svgRef} + style={{ + width: tableWidthWithExtraColumnLabelWidth, + height: yOffset + (data.rowLabels.length + 1) * props.rowHeight, + }} + > + <RowLabelColumn // render the PAOHvis itself + onMouseEnter={onMouseEnterRow} + onMouseLeave={onMouseLeaveRow} + titles={data.rowLabels} + width={rowLabelColumnWidth} + rowHeight={props.rowHeight} // viewModel.rowHeight? + yOffset={yOffset} + /> + {hyperEdgeRangeColumns} + </svg> </div> + <Tooltip /> </div> + <VisConfigPanelComponent> + <PaohvisFilterComponent // render the PaohvisFilterComponent with all three different filter options + axis={FilterType.yaxis} + filterPaohvis={onClickFilterButton} + resetFilter={onClickResetButton} + entityVertical={viewModel.entityVertical} + entityHorizontal={viewModel.entityHorizontal} + relationName={viewModel.chosenRelation} + /> + <PaohvisFilterComponent + axis={FilterType.xaxis} + filterPaohvis={onClickFilterButton} + resetFilter={onClickResetButton} + entityVertical={viewModel.entityVertical} + entityHorizontal={viewModel.entityHorizontal} + relationName={viewModel.chosenRelation} + /> + <PaohvisFilterComponent + axis={FilterType.edge} + filterPaohvis={onClickFilterButton} + resetFilter={onClickResetButton} + entityVertical={viewModel.entityVertical} + entityHorizontal={viewModel.entityHorizontal} + relationName={viewModel.chosenRelation} + /> + </VisConfigPanelComponent> </div> - <VisConfigPanelComponent> - {configPanelMessage} - <PaohvisFilterComponent // render the PaohvisFilterComponent with all three different filter options - axis={FilterType.yaxis} - filterPaohvis={onClickFilterButton} - resetFilter={onClickResetButton} - entityVertical={viewModel.entityVertical} - entityHorizontal={viewModel.entityHorizontal} - relationName={viewModel.chosenRelation} - /> - <PaohvisFilterComponent - axis={FilterType.xaxis} - filterPaohvis={onClickFilterButton} - resetFilter={onClickResetButton} - entityVertical={viewModel.entityVertical} - entityHorizontal={viewModel.entityHorizontal} - relationName={viewModel.chosenRelation} - /> - <PaohvisFilterComponent - axis={FilterType.edge} - filterPaohvis={onClickFilterButton} - resetFilter={onClickResetButton} - entityVertical={viewModel.entityVertical} - entityHorizontal={viewModel.entityHorizontal} - relationName={viewModel.chosenRelation} - /> - </VisConfigPanelComponent> </div> ); }; diff --git a/libs/shared/lib/vis/paohvis/paohvisViewModel.tsx b/libs/shared/lib/vis/paohvis/paohvisViewModel.tsx deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/libs/shared/lib/vis/rawjsonvis/rawjsonvis.jsx b/libs/shared/lib/vis/rawjsonvis/rawjsonvis.jsx deleted file mode 100644 index 0846c8abd0bba77c96525aa5f39ceb699d2dfb74..0000000000000000000000000000000000000000 --- a/libs/shared/lib/vis/rawjsonvis/rawjsonvis.jsx +++ /dev/null @@ -1,45 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.RawJSONVis = void 0; -var store_1 = require("../../data-access/store"); -var material_1 = require("@mui/material"); -var react_1 = require("react"); -var react_json_view_1 = require("react-json-view"); -var rawjsonvis_module_scss_1 = require("./rawjsonvis.module.scss"); -exports.RawJSONVis = react_1.default.memo(function (props) { - var graphQueryResult = (0, store_1.useGraphQueryResult)(); - var dispatch = (0, store_1.useAppDispatch)(); - var theme = (0, material_1.useTheme)(); - console.log('update rawjson'); - (0, react_1.useEffect)(function () { - console.log('update rawjson useEffect'); - }, [graphQueryResult]); - (0, react_1.useEffect)(function () { - return function () { - console.log('unloaded RawJSONVis'); - }; - }, []); - var loading = props.loading; - return (<> - <input onChange={function (v) { - return dispatch((0, store_1.changePrimary)({ main: v.currentTarget.value })); - }} type="color" name="head" value={theme.palette.custom.primary.main}/> - {loading && (<div style={{ - marginTop: '40px', - paddingLeft: '30px', - }}> - <svg className={rawjsonvis_module_scss_1.default.rotating} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50"> - <circle className={rawjsonvis_module_scss_1.default.ring} cx="25" cy="25" r="20"></circle> - <circle className={rawjsonvis_module_scss_1.default.ball} cx="25" cy="5" r="3.5"></circle> - </svg> - </div>)} - {!loading && (<div style={{ overflowY: 'auto' }}> - <div style={{ - marginTop: '40px', - paddingLeft: '30px', - }}> - <react_json_view_1.default src={graphQueryResult} collapsed={1} quotesOnKeys={false} displayDataTypes={false}/> - </div> - </div>)} - </>); -}); diff --git a/libs/shared/lib/vis/rawjsonvis/rawjsonvis.stories.tsx b/libs/shared/lib/vis/rawjsonvis/rawjsonvis.stories.tsx index 70492c16e01d919d772367dbbbc4361fc11800be..d8ffc3214acf5e05069921aafd822856f00fe61b 100644 --- a/libs/shared/lib/vis/rawjsonvis/rawjsonvis.stories.tsx +++ b/libs/shared/lib/vis/rawjsonvis/rawjsonvis.stories.tsx @@ -2,16 +2,9 @@ import React from 'react'; import { ComponentStory, Meta } from '@storybook/react'; import { RawJSONVis } from './rawjsonvis'; -import { - assignNewGraphQueryResult, - colorPaletteConfigSlice, - graphQueryResultSlice, - resetGraphQueryResults, - store, -} from '../../data-access/store'; +import { assignNewGraphQueryResult, graphQueryResultSlice, resetGraphQueryResults, store } from '../../data-access/store'; import { configureStore } from '@reduxjs/toolkit'; import { Provider } from 'react-redux'; -import { GraphPolarisThemeProvider } from '../../data-access/theme'; import { mockLargeQueryResults } from '../../mock-data/query-result'; const Component: Meta<typeof RawJSONVis> = { @@ -21,18 +14,11 @@ const Component: Meta<typeof RawJSONVis> = { */ title: 'Components/Visualizations/RawJSONVIS', component: RawJSONVis, - decorators: [ - (story) => ( - <Provider store={Mockstore}> - <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> - </Provider> - ), - ], + decorators: [(story) => <Provider store={Mockstore}>{story()}</Provider>], }; const Mockstore = configureStore({ reducer: { - colorPaletteConfig: colorPaletteConfigSlice.reducer, graphQueryResult: graphQueryResultSlice.reducer, }, }); diff --git a/libs/shared/lib/vis/rawjsonvis/rawjsonvis.tsx b/libs/shared/lib/vis/rawjsonvis/rawjsonvis.tsx index 302335135140e363fc774fb0de37f9550ae8d372..a90933c95371769db19dd568d2976c43606e7d20 100644 --- a/libs/shared/lib/vis/rawjsonvis/rawjsonvis.tsx +++ b/libs/shared/lib/vis/rawjsonvis/rawjsonvis.tsx @@ -1,5 +1,4 @@ -import { changePrimary, useAppDispatch, useGraphQueryResult } from '../../data-access/store'; -import { useTheme } from '@mui/material'; +import { useAppDispatch, useGraphQueryResult } from '../../data-access/store'; import React, { useEffect, useState } from 'react'; import ReactJSONView from 'react-json-view'; @@ -13,7 +12,6 @@ export interface RawJSONVisProps { export const RawJSONVis = React.memo((props: RawJSONVisProps) => { const graphQueryResult = useGraphQueryResult(); const dispatch = useAppDispatch(); - const theme = useTheme(); console.log('update rawjson'); useEffect(() => { @@ -30,12 +28,6 @@ export const RawJSONVis = React.memo((props: RawJSONVisProps) => { return ( <div className="overflow-scroll"> - <input - onChange={(v) => dispatch(changePrimary({ main: v.currentTarget.value }))} - type="color" - name="head" - value={theme.palette.primary.main} - /> {loading && ( <div style={{ diff --git a/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.stories.tsx b/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.stories.tsx index 448b1edf9cb49575b82546e3f9c22c82faf79252..57c317575dbdfeb0961403711ef5fe65eb84076b 100644 --- a/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.stories.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.stories.tsx @@ -1,7 +1,6 @@ -import { assignNewGraphQueryResult, colorPaletteConfigSlice, graphQueryResultSlice, schemaSlice, setSchema } from '../../data-access/store'; -import { GraphPolarisThemeProvider } from '../../data-access/theme'; +import { assignNewGraphQueryResult, graphQueryResultSlice, schemaSlice, setSchema } from '../../data-access/store'; import { configureStore } from '@reduxjs/toolkit'; -import { Meta, ComponentStory } from '@storybook/react'; +import { Meta } from '@storybook/react'; import { Provider } from 'react-redux'; import SemanticSubstrates from './semanticsubstrates'; @@ -16,19 +15,12 @@ const Component: Meta<typeof SemanticSubstrates> = { */ title: 'Components/Visualizations/SemanticSubstrates', component: SemanticSubstrates, - decorators: [ - (story) => ( - <Provider store={Mockstore}> - <GraphPolarisThemeProvider>{story()}</GraphPolarisThemeProvider> - </Provider> - ), - ], + decorators: [(story) => <Provider store={Mockstore}>{story()}</Provider>], }; const Mockstore = configureStore({ reducer: { schema: schemaSlice.reducer, - colorPaletteConfig: colorPaletteConfigSlice.reducer, graphQueryResult: graphQueryResultSlice.reducer, }, }); diff --git a/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.tsx b/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.tsx index b05dcb58c0ad6b4d2e3846ddd493b1bfd02c268c..3cf14ed04a3c843f1cb1499c811c00b9d52577b7 100644 --- a/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/semanticsubstrates.tsx @@ -1,4 +1,3 @@ -import { useTheme } from '@mui/material'; import { useAppDispatch, useGraphQueryResult, useSchemaGraph } from '@graphpolaris/shared/lib/data-access/store'; import { useEffect, useRef, useState } from 'react'; import { AxisLabel, EntitiesFromSchema, MinMaxType, PlotSpecifications, PlotType, RelationType } from './Types'; @@ -8,7 +7,6 @@ import AddPlotButtonComponent from './subcomponents/AddPlotButtonComponent'; import SVGCheckboxesWithSemanticSubstrLabel from './subcomponents/SVGCheckBoxComponent'; import AddPlotPopup from './subcomponents/AddPlotPopup'; import VisConfigPanelComponent from '../shared/VisConfigPanel/VisConfigPanel'; -import FSSConfigPanel from './configpanel/SemanticSubstrateConfigPanel'; import Plot from './subcomponents/PlotComponent'; import LinesBetweenPlots from './subcomponents/LinesBetweenPlotsComponent'; import Color from 'color'; @@ -76,8 +74,6 @@ const relationScaleCalculation: (x: number) => number = (x: number) => { }; export const SemanticSubstrates = () => { - const dispatch = useAppDispatch(); - const theme = useTheme(); const graphQueryResult = useGraphQueryResult(); const schema = useSchemaGraph(); const [entitiesFromSchema, setEntitiesFromSchema] = useState<EntitiesFromSchema>({ entityNames: [], attributesPerEntity: {} }); diff --git a/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.tsx b/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.tsx index 8700ebc2f863aa553cfb3b392b6a1a9e89721732..ee8f9803a02effdc9f6257743e793967ecaef5fc 100644 --- a/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotButtonComponent.tsx @@ -9,7 +9,6 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ import React from 'react'; -import { createStyles, Theme } from '@mui/material'; import styles from './AddPlotButtonComponent.module.scss'; /** diff --git a/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotPopup.tsx b/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotPopup.tsx index d770915c30412a1172df07fbd7f60cc4a279d908..0ea7c200d330d16ef13302a8bf3124b4e1d0292d 100644 --- a/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotPopup.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/subcomponents/AddPlotPopup.tsx @@ -8,7 +8,6 @@ /* The comment above was added so the code coverage wouldn't count this file towards code coverage. * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { Button, MenuItem, Popover, TextField } from '@mui/material'; import React, { ReactElement } from 'react'; import { EntitiesFromSchema } from '../Types'; import OptimizedAutocomplete from './OptimizedAutocomplete'; @@ -125,69 +124,53 @@ export default class AddPlotPopup extends React.Component<AddPlotPopupProps, Add let entityMenuItems: ReactElement[]; if (this.props.entitiesFromSchema.entityNames.length > 0) entityMenuItems = entitiesFromSchema.entityNames.map((entity) => ( - <MenuItem key={entity} value={entity}> + <option key={entity} value={entity}> {entity} - </MenuItem> + </option> )); else entityMenuItems = [ - <MenuItem key="placeholder" value="" disabled> + <option key="placeholder" value="" disabled> No schema data available - </MenuItem>, + </option>, ]; // Retrieve the possible attributeName options. If none available, set helper message. let attributeNameMenuItems: ReactElement[]; if (this.attributeNameOptions.length > 0) attributeNameMenuItems = this.attributeNameOptions.map((attribute) => ( - <MenuItem key={attribute} value={attribute}> + <option key={attribute} value={attribute}> {attribute} - </MenuItem> + </option> )); else attributeNameMenuItems = [ - <MenuItem key="placeholder" value="" disabled> + <option key="placeholder" value="" disabled> First select an entity - </MenuItem>, + </option>, ]; return ( <div> - <Popover - id={'simple-addplot-popover'} - open={open} - anchorEl={anchorEl} - onClose={handleClose} - anchorOrigin={{ - vertical: 'top', - horizontal: 'center', - }} - transformOrigin={{ - vertical: 'top', - horizontal: 'center', - }} - > + <dialog open={open} onClose={handleClose} id={'simple-addplot-popover'}> <div style={{ padding: 20, paddingTop: 10, display: 'flex' }}> - <TextField - select - id="standard-select-entity" - style={{ minWidth: 120 }} - label="Entity" - value={this.state.entity} - onChange={this.entityChanged} - > - {entityMenuItems} - </TextField> - <TextField - select - id="standard-select-attribute" - style={{ minWidth: 120, marginLeft: 20, marginRight: 20 }} - label="Attribute" - value={this.state.attributeName} - onChange={this.attrNameChanged} - > - {attributeNameMenuItems} - </TextField> + <div> + <label>Entity</label> + <input id="standard-select-entity" style={{ minWidth: 120 }} value={this.state.entity} onChange={this.entityChanged}> + {entityMenuItems} + </input> + </div> + <div> + <label>Attribute</label> + <input + id="standard-select-attribute" + style={{ minWidth: 120, marginLeft: 20, marginRight: 20 }} + value={this.state.attributeName} + onChange={this.attrNameChanged} + > + {attributeNameMenuItems} + </input> + </div> <OptimizedAutocomplete currentValue={this.attributeValue} options={this.possibleAttrValues} @@ -195,12 +178,12 @@ export default class AddPlotPopup extends React.Component<AddPlotPopupProps, Add useMaterialStyle={{ label: 'Value', helperText: '' }} /> <div style={{ height: 40, paddingTop: 10, marginLeft: 30 }}> - <Button variant="contained" disabled={!this.state.isButtonEnabled} onClick={this.addPlotButtonClicked}> + <button className="btn btn-outline" disabled={!this.state.isButtonEnabled} onClick={this.addPlotButtonClicked}> <span style={{ fontWeight: 'bold' }}>Add</span> - </Button> + </button> </div> </div> - </Popover> + </dialog> </div> ); } diff --git a/libs/shared/lib/vis/semanticsubstrates/subcomponents/OptimizedAutocomplete.tsx b/libs/shared/lib/vis/semanticsubstrates/subcomponents/OptimizedAutocomplete.tsx index 47d3f8c03f3f69b39ab3fd49201eb80587a45be2..c9fc977fecd266e7a12737e5f1dc35987568bf6b 100644 --- a/libs/shared/lib/vis/semanticsubstrates/subcomponents/OptimizedAutocomplete.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/subcomponents/OptimizedAutocomplete.tsx @@ -8,17 +8,7 @@ /* The comment above was added so the code coverage wouldn't count this file towards code coverage. * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { - Autocomplete, - AutocompleteRenderGroupParams, - AutocompleteRenderInputParams, - ListSubheader, - TextField, - Typography, - makeStyles, - useMediaQuery, - useTheme, -} from '@mui/material'; + import React from 'react'; import { VariableSizeList, ListChildComponentProps } from 'react-window'; import styles from './OptimizedAutocomplete.module.scss'; @@ -57,56 +47,13 @@ function useResetCache(data: any) { const ListboxComponent = React.forwardRef<HTMLDivElement>(function ListboxComponent(props: any, ref) { const { children, ...other } = props; const itemData = React.Children.toArray(children); - const theme = useTheme(); - const smUp = useMediaQuery(theme.breakpoints.up('sm'), { noSsr: true }); const itemCount = itemData.length; - const itemSize = smUp ? 36 : 48; - - const getChildSize = (child: React.ReactNode) => { - if (React.isValidElement(child) && child.type === ListSubheader) { - return 48; - } + const itemSize = 36; - return itemSize; - }; - - const getHeight = () => { - if (itemCount > 8) { - return 8 * itemSize; - } - return itemData.map(getChildSize).reduce((a, b) => a + b, 0); - }; - - const gridRef = useResetCache(itemCount); - - return ( - <div ref={ref}> - <OuterElementContext.Provider value={other}> - <VariableSizeList - itemData={itemData} - height={getHeight() + 2 * LISTBOX_PADDING} - width="100%" - ref={gridRef} - outerElementType={OuterElementType} - innerElementType="ul" - itemSize={(index: number) => getChildSize(itemData[index])} - overscanCount={5} - itemCount={itemCount} - itemKey={(index: number) => 'autolist-key' + index} - > - {renderRow} - </VariableSizeList> - </OuterElementContext.Provider> - </div> - ); + return <div ref={ref}></div>; }); -const renderGroup = (params: AutocompleteRenderGroupParams) => [ - <ListSubheader key={params.key} component="div"> - {params.group} - </ListSubheader>, - params.children, -]; +const renderGroup = (params: any) => [<div key={params.key}>{params.group}</div>, params.children]; type OptimizedAutocomplete = { currentValue: string; @@ -123,35 +70,15 @@ export default function OptimizedAutocomplete(props: OptimizedAutocomplete) { console.log(props); return ( - <Autocomplete + <input id="optimized-autocomplete" style={{ width: 200 }} - disableListWrap - autoHighlight className={styles.listbox} - ListboxComponent={ListboxComponent as React.ComponentType<React.HTMLAttributes<HTMLElement>>} - renderGroup={renderGroup} - options={props.options} - // groupBy={(option: string) => option[0].toUpperCase()} - renderInput={(params: AutocompleteRenderInputParams) => - props.useMaterialStyle != undefined ? ( - <TextField - {...params} - variant="standard" - // size="small" - label={props.useMaterialStyle.label} - helperText={props.useMaterialStyle.helperText} - /> - ) : ( - <div ref={params.InputProps.ref}> - <input style={{ width: 200 }} type="text" {...params.inputProps} autoFocus /> - </div> - ) - } // defaultValue={props.currentValue} placeholder={props.currentValue} // renderOption={(props, option, state) => <Typography noWrap>{option}</Typography>} - onChange={(_: React.ChangeEvent<any>, value: string | null) => { + onChange={(e) => { + let value = e.target.value; console.log(value); newValue = value || '?'; diff --git a/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotAxisLabelsComponent.tsx b/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotAxisLabelsComponent.tsx index e9adc8352d79c3180fad2ff73e1a1f0de7d374e1..7a8693d3980d5ee92e63be9a6d5c0861d927e58f 100644 --- a/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotAxisLabelsComponent.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotAxisLabelsComponent.tsx @@ -9,7 +9,6 @@ * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ import React, { ReactElement } from 'react'; -import { Menu, MenuItem } from '@mui/material'; import styles from './PlotAxisLabelStyles.module.css'; /** Props of the axis labels component. */ @@ -69,30 +68,13 @@ export default class PlotAxisLabelsComponent extends React.Component<PlotAxisLab > {yAxisLabel} </text> - <Menu + <div id="simple-menu" - anchorEl={this.state.menuAnchor} - keepMounted // getContentAnchorEl={null} - anchorOrigin={ - this.state.menuOpenForAxis == 'x' ? { vertical: 'bottom', horizontal: 'center' } : { vertical: 'center', horizontal: 'right' } - } - transformOrigin={ - this.state.menuOpenForAxis == 'x' ? { vertical: 'top', horizontal: 'center' } : { vertical: 'center', horizontal: 'left' } - } - open={Boolean(this.state.menuAnchor)} - onClose={() => this.setState({ menuAnchor: null })} - transitionDuration={150} - PaperProps={{ - style: { - maxHeight: 48 * 4.5, // 48 ITEM_HEIGHT - }, - }} > {axisLabelOptions.map((option) => ( - <MenuItem + <label key={option} - selected={option == (this.state.menuOpenForAxis == 'x' ? xAxisLabel : yAxisLabel)} onClick={() => { this.setState({ menuAnchor: null }); @@ -100,9 +82,9 @@ export default class PlotAxisLabelsComponent extends React.Component<PlotAxisLab }} > {option} - </MenuItem> + </label> ))} - </Menu> + </div> </g> ); } diff --git a/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotTitleComponent.tsx b/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotTitleComponent.tsx index 6247214dd6637b9aee14edbf34270be038433134..c69f9e5e569a66851c88ba81d6ef1d8106b9817a 100644 --- a/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotTitleComponent.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/subcomponents/PlotTitleComponent.tsx @@ -8,7 +8,6 @@ /* The comment above was added so the code coverage wouldn't count this file towards code coverage. * We do not test components/renderfunctions/styling files. * See testing plan for more details.*/ -import { Menu, MenuItem } from '@mui/material'; import Color from 'color'; import React, { ReactElement, useState } from 'react'; import { EntitiesFromSchema } from '../Types'; @@ -172,31 +171,10 @@ export default function PlotTitleComponent(props: PlotTitleProps) { {renderAttributeValue(attrValueOffset)} - <Menu - id="simple-menu" - anchorEl={state.menuAnchor} - keepMounted - // getContentAnchorEl={null} - anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} - transformOrigin={{ vertical: 'top', horizontal: 'center' }} - open={Boolean(state.menuAnchor)} - onClose={() => - setState({ - ...state, - menuAnchor: null, - }) - } - transitionDuration={150} - PaperProps={{ - style: { - maxHeight: 48 * 4.5, // 48 ITEM_HEIGHT - }, - }} - > + <div id="simple-menu"> {state.menuItems.map((option) => ( - <MenuItem + <label key={option} - selected={option == state.menuAnchor?.innerHTML} onClick={() => { setState({ ...state, @@ -208,9 +186,9 @@ export default function PlotTitleComponent(props: PlotTitleProps) { }} > {option} - </MenuItem> + </label> ))} - </Menu> + </div> </g> ); } diff --git a/libs/shared/lib/vis/semanticsubstrates/utils/CalcConnectionLinePositionsUseCase.tsx b/libs/shared/lib/vis/semanticsubstrates/utils/CalcConnectionLinePositionsUseCase.tsx index 1961a67600e25281e7e46121ab394823ff07a6a3..4dabbf3e095d9990217df06896cd8af6671d889e 100644 --- a/libs/shared/lib/vis/semanticsubstrates/utils/CalcConnectionLinePositionsUseCase.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/utils/CalcConnectionLinePositionsUseCase.tsx @@ -8,7 +8,7 @@ import { RotateVectorByDeg } from '../utils/RotateVec'; import { XYPosition } from 'reactflow'; /** The return type for this usecase. controlPoint is used for the curvature of the line. */ -type ConnecionLinePositions = { +type ConnectionLinePositions = { start: XYPosition; end: XYPosition; controlPoint: XYPosition; @@ -25,9 +25,9 @@ export default class CalcConnectionLinePositionsUseCase { * @param {XYPosition} startNodePos The position of the start node. * @param {XYPosition} endNodePos The position of the end node. * @param {number} nodeRadius The node radius, used to calculate the start and end offset. - * @returns {ConnecionLinePositions} The positions for drawing the curved line. + * @returns {ConnectionLinePositions} The positions for drawing the curved line. */ - public static calculatePositions(startNodePos: XYPosition, endNodePos: XYPosition, nodeRadius: number): ConnecionLinePositions { + public static calculatePositions(startNodePos: XYPosition, endNodePos: XYPosition, nodeRadius: number): ConnectionLinePositions { // Calculate the control point for the quadratic curve path, see https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths const distance = CalcDistance(startNodePos, endNodePos); if (distance == 0) return this.returnStartPosition(startNodePos); @@ -62,7 +62,7 @@ export default class CalcConnectionLinePositionsUseCase { * @param {XYPosition} startNodePos The position of the start node. * @returns {ConnectionLinePosition} The positions for drawing the curved line. */ - private static returnStartPosition(startNodePos: XYPosition): ConnecionLinePositions { + private static returnStartPosition(startNodePos: XYPosition): ConnectionLinePositions { return { start: startNodePos, end: startNodePos, diff --git a/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromResultUseCase.tsx b/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromResultUseCase.tsx index 05dc2909bb71ffc626bce5371c26f39d6de8c60b..b903d7d81b5eb7d064189653f265209102602ce2 100644 --- a/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromResultUseCase.tsx +++ b/libs/shared/lib/vis/semanticsubstrates/utils/CalcEntityAttrNamesFromResultUseCase.tsx @@ -4,7 +4,6 @@ * © Copyright Utrecht University (Department of Information and Computing Sciences) */ -import { SchemaFromBackend } from '@graphpolaris/shared/lib/schema'; import { EntitiesFromSchema } from '../Types'; import { GraphQueryResult } from '@graphpolaris/shared/lib/data-access'; diff --git a/libs/shared/lib/vis/shared/ResultNodeLinkParserUseCase.tsx b/libs/shared/lib/vis/shared/ResultNodeLinkParserUseCase.tsx index ca67ade05adc3488ae75a1f2fa1434cefbabcd32..3ba91aa1346155239d6b391c6156a34607d562ca 100644 --- a/libs/shared/lib/vis/shared/ResultNodeLinkParserUseCase.tsx +++ b/libs/shared/lib/vis/shared/ResultNodeLinkParserUseCase.tsx @@ -170,11 +170,12 @@ export default class ResultNodeLinkParserUseCase { if (queryResult.nodes[i].attributes.label != undefined) preferredText = queryResult.nodes[i].attributes.label as string; if (queryResult.nodes[i].attributes.naam != undefined) preferredText = queryResult.nodes[i].attributes.naam as string; - let data = { + let data: NodeType = { id: queryResult.nodes[i].id, attributes: queryResult.nodes[i].attributes, type: typeNumber, displayInfo: preferredText, + radius: 5, }; let mlExtra = {}; diff --git a/libs/shared/node.d.ts b/libs/shared/node.d.ts deleted file mode 100644 index 3d2ced5bc73ee7e961f830942deb2a6115058ed5..0000000000000000000000000000000000000000 --- a/libs/shared/node.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -interface ImportMeta { - env: { - VITE_BACKEND_URL: string; - VITE_BACKEND_WSS_URL: string; - VITE_BACKEND_USER: string; - VITE_BACKEND_SCHEMA: string; - VITE_BACKEND_QUERY: string; - VITE_STAGING: string; - VITE_KEYCLOAK_URL: string; - VITE_KEYCLOAK_REALM: string; - VITE_KEYCLOAK_CLIENT: string; - }; -} diff --git a/libs/shared/package.json b/libs/shared/package.json index 221adab0f26c255ac9acce3f4b3ecc0e87ef98e8..47c4124bfc85482ae054931666bbfb96114c4e12 100644 --- a/libs/shared/package.json +++ b/libs/shared/package.json @@ -20,11 +20,7 @@ "@deck.gl/layers": "^8.9.19", "@emotion/react": "^11.10.6", "@emotion/styled": "^11.10.6", - "@mui/base": "5.0.0-alpha.118", "@mui/icons-material": "^5.11.11", - "@mui/material": "^5.11.9", - "@mui/styled-engine-sc": "^5.11.9", - "@mui/system": "^5.11.9", "@reactflow/node-resizer": "^2.0.1", "@reduxjs/toolkit": "^1.9.2", "@types/cytoscape": "^3.19.9", @@ -33,6 +29,7 @@ "@types/supercluster": "^7.1.0", "classnames": "^2.3.2", "color": "^4.2.3", + "config": "workspace:*", "core-js": "^3.28.0", "cytoscape": "^3.23.0", "d3": "^6.6", @@ -47,6 +44,7 @@ "immer": "^10.0.2", "jspdf": "^2.5.1", "keycloak-js": "^21.1.1", + "pixi-viewport": "^5.0.2", "pixi.js": "^7.1.4", "react-cookie": "^4.1.1", "react-draggable": "^4.4.5", @@ -65,6 +63,7 @@ "web-worker": "^1.2.0" }, "devDependencies": { + "@iconify/json": "^2.2.95", "@storybook/addon-styling": "^0.3.2", "@storybook/preset-scss": "^1.0.3", "@storybook/react": "7.0.22", @@ -86,6 +85,7 @@ "cytoscape-elk": "^2.1.0", "cytoscape-fcose": "^2.2.0", "cytoscape-klay": "^3.1.4", + "daisyui": "^3.5.0", "eslint": "^7.32.0", "eslint-config-next": "13.0.0", "eslint-config-prettier": "^8.3.0", @@ -114,8 +114,10 @@ "react-redux": "^8.0.5", "react-test-renderer": "18.2.0", "require-from-string": "^2.0.2", + "tailwindcss": "^3.3.1", "ts-node": "10.9.1", "typescript": "^4.5.2", + "unplugin-icons": "^0.16.5", "url-loader": "^4.1.1", "vite": "^4.1.0", "vite-plugin-dts": "^2.1.0", diff --git a/libs/shared/postcss.config.js b/libs/shared/postcss.config.js new file mode 100644 index 0000000000000000000000000000000000000000..2f20e4a741aecf2ad32e5e236c551954c0cb556b --- /dev/null +++ b/libs/shared/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: { config: './tailwind.config.js' }, + autoprefixer: {}, + }, +}; diff --git a/libs/shared/tailwind.config.js b/libs/shared/tailwind.config.js new file mode 100644 index 0000000000000000000000000000000000000000..7d43c678e6b4cf9ba4e0d062bb527ac6b9178d96 --- /dev/null +++ b/libs/shared/tailwind.config.js @@ -0,0 +1,6 @@ +/** @type {import('tailwindcss').Config} */ +import sharedConfig from 'config/tailwind.config.js'; + +export default { + presets: [sharedConfig], +}; diff --git a/libs/shared/tsconfig.json b/libs/shared/tsconfig.json index 0f1e0dd82a0b4f829bc2ef3b38c1af3d013c6c5d..ca5bc26a48a32b2d90ef32e9f7c5455007b2ce9d 100644 --- a/libs/shared/tsconfig.json +++ b/libs/shared/tsconfig.json @@ -25,11 +25,12 @@ "baseUrl": ".", "noImplicitOverride": false, "paths": { - "@graphpolaris/shared/lib/*": ["./lib/*"] - } + "@graphpolaris/shared/lib/*": ["./lib/*"], + "@graphpolaris/config/*": ["../../libs/config/src/*"] + }, + "types": ["node", "vite/client"] }, "exclude": ["dist", "build", "node_modules"], - "include": ["src", "lib"], - "files": ["./node.d.ts"], + "include": ["src", "lib", "../../libs/config/src/**/*"], "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/libs/shared/tsconfig.node.json b/libs/shared/tsconfig.node.json index 223fa3b61022b657d75c5f0299f6626f57afa30f..a54ca1adb820b30780b53c9b7049fc731bf73452 100644 --- a/libs/shared/tsconfig.node.json +++ b/libs/shared/tsconfig.node.json @@ -2,7 +2,7 @@ "compilerOptions": { "composite": true, "module": "ESNext", - "moduleResolution": "node", + "moduleResolution": "Node", "allowSyntheticDefaultImports": true, "types": ["node", "vite/client"] }, diff --git a/libs/shared/vite.config.ts b/libs/shared/vite.config.ts index 2f263c107da35d9ffdc9bad6eee216978771431c..585b3bc2924e81b110c544f254dac078f739ab08 100644 --- a/libs/shared/vite.config.ts +++ b/libs/shared/vite.config.ts @@ -40,16 +40,8 @@ export default defineConfig({ resolve: { alias: { '@graphpolaris/shared/lib': path.resolve(__dirname, './lib'), - }, - }, - test: { - environment: 'happy-dom', - deps: {}, - threads: true, - environmentOptions: { - jsdom: { - resources: 'usable', - }, + '@graphpolaris/config': path.resolve(__dirname, '../../libs/config/src'), + '@/': path.resolve(__dirname, './lib'), }, }, }); diff --git a/libs/storybook/.eslintignore b/libs/storybook/.eslintignore new file mode 100644 index 0000000000000000000000000000000000000000..ed9d65c51ee65528569330ac08d99a1383f2a614 --- /dev/null +++ b/libs/storybook/.eslintignore @@ -0,0 +1,6 @@ +node_modules/* +node_modules/ +node_modules +*.d.ts +*.mjs +*.tsbuildinfo \ No newline at end of file diff --git a/libs/storybook/.eslintrc.json b/libs/storybook/.eslintrc.json new file mode 100644 index 0000000000000000000000000000000000000000..8144cb41a186f2f60c5912d27eecfa48121cfa75 --- /dev/null +++ b/libs/storybook/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["./node_modules/config/.eslintrc.json"] +} diff --git a/libs/storybook/.gitignore b/libs/storybook/.gitignore index a547bf36d8d11a4f89c59c144f24795749086dd1..dd4d473b2c788cb5054c8bc2acfd284dd80b08d2 100644 --- a/libs/storybook/.gitignore +++ b/libs/storybook/.gitignore @@ -22,3 +22,6 @@ dist-ssr *.njsproj *.sln *.sw? + +tsconfig.tsbuildinfo +vite.config.ts.* \ No newline at end of file diff --git a/libs/storybook/.postcssrc.cjs b/libs/storybook/.postcssrc.cjs deleted file mode 100644 index 70ea41d8c21b1f89f54e138b8dc8a7044f18b681..0000000000000000000000000000000000000000 --- a/libs/storybook/.postcssrc.cjs +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - parser: 'postcss-scss', - map: false, - plugins: [require('postcss-nesting')], -}; diff --git a/libs/storybook/.storybook/main.ts b/libs/storybook/.storybook/main.ts index d027d6dc3f07018aa6ac03395982baa2517daa20..8fa1245cb6b48b7fcd9d4e4ee19ea81592251c6e 100644 --- a/libs/storybook/.storybook/main.ts +++ b/libs/storybook/.storybook/main.ts @@ -19,8 +19,11 @@ const config: StorybookConfig = { name: '@storybook/addon-styling', options: { // sass: { - // Require your Sass preprocessor here - // implementation: require('sass'), + // // Require your Sass preprocessor here + // implementation: require('sass'), + // }, + // postCss: { + // implementation: require.resolve('postcss'), // }, }, }, diff --git a/libs/storybook/.storybook/preview.ts b/libs/storybook/.storybook/preview.ts index 8c2a141ca698dc200b76966ccf32cbee3798f4cb..d8ff918d3b8fe6c80918b4613691b7d206d936f4 100644 --- a/libs/storybook/.storybook/preview.ts +++ b/libs/storybook/.storybook/preview.ts @@ -1,8 +1,11 @@ import type { Preview } from '@storybook/react'; +import '../src/tailwind.css'; +import { withThemeByDataAttribute } from '@storybook/addon-styling'; const preview: Preview = { parameters: { actions: { argTypesRegex: '^on[A-Z].*' }, + layout: 'fullscreen', controls: { matchers: { color: /(background|color)$/i, @@ -12,4 +15,16 @@ const preview: Preview = { }, }; +export const decorators = [ + withThemeByDataAttribute({ + themes: { + graphpolarisWhite: 'graphpolarisWhite', + light: 'graphpolarisWhite', + dark: 'graphpolaris', + }, + defaultTheme: 'graphpolarisWhite', + attributeName: 'data-mode', + }), +]; + export default preview; diff --git a/libs/storybook/package.json b/libs/storybook/package.json index a12ddd4ca6ed8d384e6ff5c7ea888b3272b96fab..2d08d638121e2edee5b55f3735a48ac598bd96bc 100644 --- a/libs/storybook/package.json +++ b/libs/storybook/package.json @@ -10,36 +10,40 @@ }, "dependencies": { "@graphpolaris/shared": "workspace:*", - "web": "workspace:*", "postcss-scss": "^4.0.6", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "web": "workspace:*" }, "devDependencies": { - "@storybook/addon-essentials": "next", - "@storybook/addon-interactions": "next", - "@storybook/addon-links": "^7.0.22", - "@storybook/addon-styling": "^1.3.0", - "@storybook/blocks": "^7.0.22", + "@storybook/addon-essentials": "7.2.1", + "@storybook/addon-interactions": "7.2.1", + "@storybook/addon-links": "^7.2.1", + "@storybook/addon-styling": "^1.3.5", + "@storybook/blocks": "^7.2.1", "@storybook/preset-scss": "^1.0.3", - "@storybook/react": "^7.0.22", - "@storybook/react-vite": "^7.0.22", - "@storybook/testing-library": "0.1.0", - "@types/node": "18.13.0", - "@types/react": "^18.0.28", - "@types/react-dom": "^18.0.11", - "@vitejs/plugin-react": "^3.1.0", - "postcss": "^8.4.21", + "@storybook/react": "^7.2.1", + "@storybook/react-vite": "^7.2.1", + "@storybook/testing-library": "0.2.0", + "@types/node": "20.4.6", + "@types/react": "^18.2.18", + "@types/react-dom": "^18.2.7", + "@vitejs/plugin-react": "^4.0.4", + "autoprefixer": "^10.4.14", + "config": "workspace:*", + "daisyui": "^3.5.0", + "postcss": "^8.4.27", "postcss-load-config": "^4.0.1", - "postcss-nesting": "^11.2.2", + "postcss-nesting": "^12.0.0", "postcss-plugin": "^1.0.0", "prop-types": "15.8.1", - "sass": "^1.59.3", - "sass-loader": "^13.2.2", - "storybook": "^7.0.22", - "typescript": "^4.9.3", - "vite": "^4.2.0", - "vite-plugin-sass-dts": "^1.3.2", - "vite-tsconfig-paths": "^4.0.7" + "sass": "^1.64.2", + "sass-loader": "^13.3.2", + "storybook": "^7.2.1", + "tailwindcss": "^3.3.3", + "typescript": "^5.1.6", + "vite": "^4.4.8", + "vite-plugin-sass-dts": "^1.3.9", + "vite-tsconfig-paths": "^4.2.0" } } diff --git a/libs/storybook/postcss.config.js b/libs/storybook/postcss.config.js new file mode 100644 index 0000000000000000000000000000000000000000..2f20e4a741aecf2ad32e5e236c551954c0cb556b --- /dev/null +++ b/libs/storybook/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: { config: './tailwind.config.js' }, + autoprefixer: {}, + }, +}; diff --git a/libs/storybook/src/tailwind.css b/libs/storybook/src/tailwind.css new file mode 100644 index 0000000000000000000000000000000000000000..b5c61c956711f981a41e95f7fcf0038436cfbb22 --- /dev/null +++ b/libs/storybook/src/tailwind.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/libs/storybook/tailwind.config.js b/libs/storybook/tailwind.config.js new file mode 100644 index 0000000000000000000000000000000000000000..34e6e517ba92e6f0d77c87ba48e396b6adf8c81b --- /dev/null +++ b/libs/storybook/tailwind.config.js @@ -0,0 +1,5 @@ +const sharedConfig = require('config/tailwind.config.js'); + +module.exports = { + ...sharedConfig, +}; diff --git a/libs/storybook/tsconfig.json b/libs/storybook/tsconfig.json index 3d0a51a86e202419758206adb6effe775229ba38..3944a537990f8720e892d71fe27a392294b479f7 100644 --- a/libs/storybook/tsconfig.json +++ b/libs/storybook/tsconfig.json @@ -1,21 +1,7 @@ { + "extends": "config/tsconfig.json", "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "lib": ["DOM", "DOM.Iterable", "ESNext"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": false, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "ESNext", - "moduleResolution": "Node", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx" + "types": ["node", "vite/client"] }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] + "include": ["vite.config.ts", "lib"] } diff --git a/libs/storybook/vite.config.ts b/libs/storybook/vite.config.ts index 04cdcde5db05a8e9710e5a5ca72351ef8ab4e8fc..279e2c0bc2a82baca514d5b0ec205a09d0725221 100644 --- a/libs/storybook/vite.config.ts +++ b/libs/storybook/vite.config.ts @@ -1,6 +1,7 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import sassDts from 'vite-plugin-sass-dts'; +import path from 'path'; // https://vitejs.dev/config/ export default defineConfig({ @@ -21,4 +22,9 @@ export default defineConfig({ ], }, }, + resolve: { + alias: { + '@graphpolaris/shared/lib': path.resolve(__dirname, '../../libs/shared/lib'), + }, + }, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 73e36f4b94ecb26a651ddce45fb071acf7c5eb96..6d7bfbdd4a91ca61903262a6e71e4a1449499d50 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,13 +25,13 @@ importers: version: 8.0.3 prettier: specifier: latest - version: 3.0.0 + version: 3.0.1 turbo: specifier: latest - version: 1.10.8 + version: 1.10.12 vitest: specifier: ^0.29.2 - version: 0.29.4(happy-dom@8.9.0)(jsdom@21.1.1)(sass@1.59.3) + version: 0.29.4 apps/docs: dependencies: @@ -75,18 +75,15 @@ importers: '@graphpolaris/shared': specifier: workspace:* version: link:../../libs/shared - '@mui/base': - specifier: 5.0.0-alpha.118 - version: 5.0.0-alpha.118(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0) '@mui/icons-material': specifier: ^5.11.11 version: 5.11.11(@mui/material@5.11.13)(@types/react@18.0.28)(react@18.2.0) - '@mui/material': - specifier: ^5.11.13 - version: 5.11.13(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0) '@reduxjs/toolkit': specifier: ^1.9.2 version: 1.9.3(react-redux@8.0.5)(react@18.2.0) + config: + specifier: workspace:* + version: link:../../libs/config graphology: specifier: ^0.25.1 version: 0.25.1(graphology-types@0.24.7) @@ -112,9 +109,24 @@ importers: specifier: ^5.3.6 version: 5.3.9(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0) devDependencies: + '@iconify/json': + specifier: ^2.2.95 + version: 2.2.95 + '@iconify/react': + specifier: ^4.1.1 + version: 4.1.1(react@18.2.0) '@storybook/react': specifier: 7.0.0-rc.5 version: 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5) + '@svgr/core': + specifier: ^8.0.0 + version: 8.0.0 + '@svgr/plugin-jsx': + specifier: ^8.0.1 + version: 8.0.1(@svgr/core@8.0.0) + '@tailwindcss/typography': + specifier: ^0.5.9 + version: 0.5.9(tailwindcss@3.3.1) '@testing-library/react': specifier: 14.0.0 version: 14.0.0(react-dom@18.2.0)(react@18.2.0) @@ -139,9 +151,15 @@ importers: autoprefixer: specifier: ^10.4.14 version: 10.4.14(postcss@8.4.21) + daisyui: + specifier: ^3.5.0 + version: 3.5.0(ts-node@10.9.1) graphology-types: specifier: ^0.24.7 version: 0.24.7 + npm: + specifier: ^9.8.1 + version: 9.8.1 postcss: specifier: ^8.4.21 version: 8.4.21 @@ -156,13 +174,31 @@ importers: version: 4.9.5 vite: specifier: ^4.2.0 - version: 4.2.1(@types/node@17.0.12)(sass@1.59.3) + version: 4.2.1(@types/node@17.0.12)(sass@1.64.2) vite-plugin-dts: specifier: ^2.1.0 version: 2.1.0(@types/node@17.0.12)(vite@4.2.1) + vite-plugin-sass-dts: + specifier: ^1.3.2 + version: 1.3.2(postcss@8.4.21)(prettier@2.8.8)(sass@1.64.2)(vite@4.2.1) vitest: specifier: ^0.29.2 - version: 0.29.4(happy-dom@8.9.0)(jsdom@21.1.1)(sass@1.59.3) + version: 0.29.4(sass@1.64.2) + + libs/config: + devDependencies: + '@tailwindcss/typography': + specifier: ^0.5.9 + version: 0.5.9(tailwindcss@3.3.1) + daisyui: + specifier: ^3.5.0 + version: 3.5.0(ts-node@10.9.1) + postcss: + specifier: ^8.4.21 + version: 8.4.21 + tailwindcss: + specifier: ^3.3.1 + version: 3.3.1(postcss@8.4.21)(ts-node@10.9.1) libs/shared: dependencies: @@ -178,21 +214,9 @@ importers: '@emotion/styled': specifier: ^11.10.6 version: 11.10.6(@emotion/react@11.10.6)(@types/react@18.0.28)(react@18.2.0) - '@mui/base': - specifier: 5.0.0-alpha.118 - version: 5.0.0-alpha.118(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0) '@mui/icons-material': specifier: ^5.11.11 version: 5.11.11(@mui/material@5.11.13)(@types/react@18.0.28)(react@18.2.0) - '@mui/material': - specifier: ^5.11.9 - version: 5.11.13(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0) - '@mui/styled-engine-sc': - specifier: ^5.11.9 - version: 5.11.11(@types/styled-components@5.1.26)(styled-components@5.3.9) - '@mui/system': - specifier: ^5.11.9 - version: 5.11.13(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@18.0.28)(react@18.2.0) '@reactflow/node-resizer': specifier: ^2.0.1 version: 2.1.0(immer@10.0.2)(react-dom@18.2.0)(react@18.2.0) @@ -217,6 +241,9 @@ importers: color: specifier: ^4.2.3 version: 4.2.3 + config: + specifier: workspace:* + version: link:../config core-js: specifier: ^3.28.0 version: 3.29.1 @@ -259,6 +286,9 @@ importers: keycloak-js: specifier: ^21.1.1 version: 21.1.1 + pixi-viewport: + specifier: ^5.0.2 + version: 5.0.2 pixi.js: specifier: ^7.1.4 version: 7.2.1(@pixi/utils@7.2.1) @@ -308,12 +338,15 @@ importers: specifier: ^1.2.0 version: 1.2.0 devDependencies: + '@iconify/json': + specifier: ^2.2.95 + version: 2.2.95 '@storybook/addon-styling': specifier: ^0.3.2 - version: 0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.22)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2) + version: 0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.2.1)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.3.2) '@storybook/preset-scss': specifier: ^1.0.3 - version: 1.0.3(css-loader@6.7.3)(sass-loader@13.2.2)(style-loader@3.3.2) + version: 1.0.3(css-loader@6.7.3)(sass-loader@13.3.2)(style-loader@3.3.2) '@storybook/react': specifier: 7.0.22 version: 7.0.22(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5) @@ -368,6 +401,9 @@ importers: cytoscape-klay: specifier: ^3.1.4 version: 3.1.4(cytoscape@3.23.0) + daisyui: + specifier: ^3.5.0 + version: 3.5.0(ts-node@10.9.1) eslint: specifier: ^7.32.0 version: 7.32.0 @@ -379,7 +415,7 @@ importers: version: 8.7.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 1.10.9(eslint@7.32.0) + version: 1.10.12(eslint@7.32.0) eslint-plugin-import: specifier: 2.27.5 version: 2.27.5(@typescript-eslint/parser@5.52.0)(eslint-import-resolver-typescript@2.7.1)(eslint@7.32.0) @@ -437,18 +473,24 @@ importers: require-from-string: specifier: ^2.0.2 version: 2.0.2 + tailwindcss: + specifier: ^3.3.1 + version: 3.3.1(postcss@8.4.21)(ts-node@10.9.1) ts-node: specifier: 10.9.1 version: 10.9.1(@types/node@18.13.0)(typescript@4.9.5) typescript: specifier: ^4.5.2 version: 4.9.5 + unplugin-icons: + specifier: ^0.16.5 + version: 0.16.5 url-loader: specifier: ^4.1.1 version: 4.1.1(webpack@5.77.0) vite: specifier: ^4.1.0 - version: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3) + version: 4.2.1(@types/node@18.13.0)(sass@1.59.3) vite-plugin-dts: specifier: ^2.1.0 version: 2.1.0(@types/node@18.13.0)(vite@4.2.1) @@ -469,7 +511,7 @@ importers: version: link:../shared postcss-scss: specifier: ^4.0.6 - version: 4.0.6(postcss@8.4.21) + version: 4.0.6(postcss@8.4.27) react: specifier: ^18.2.0 version: 18.2.0 @@ -481,53 +523,62 @@ importers: version: link:../../apps/web devDependencies: '@storybook/addon-essentials': - specifier: next - version: 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) + specifier: 7.2.1 + version: 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-interactions': - specifier: next - version: 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) + specifier: 7.2.1 + version: 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-links': - specifier: ^7.0.22 - version: 7.0.22(react-dom@18.2.0)(react@18.2.0) + specifier: ^7.2.1 + version: 7.2.1(react-dom@18.2.0)(react@18.2.0) '@storybook/addon-styling': - specifier: ^1.3.0 - version: 1.3.0(less@4.1.3)(postcss@8.4.21)(react-dom@18.2.0)(react@18.2.0)(sass@1.59.3)(webpack@5.77.0) + specifier: ^1.3.5 + version: 1.3.5(less@4.1.3)(postcss@8.4.27)(react-dom@18.2.0)(react@18.2.0)(sass@1.64.2)(webpack@5.77.0) '@storybook/blocks': - specifier: ^7.0.22 - version: 7.0.22(react-dom@18.2.0)(react@18.2.0) + specifier: ^7.2.1 + version: 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) '@storybook/preset-scss': specifier: ^1.0.3 - version: 1.0.3(css-loader@6.7.3)(sass-loader@13.2.2)(style-loader@3.3.2) + version: 1.0.3(css-loader@6.7.3)(sass-loader@13.3.2)(style-loader@3.3.2) '@storybook/react': - specifier: ^7.0.22 - version: 7.0.22(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5) + specifier: ^7.2.1 + version: 7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.1.6) '@storybook/react-vite': - specifier: ^7.0.22 - version: 7.0.22(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.2.1) + specifier: ^7.2.1 + version: 7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.1.6)(vite@4.4.8) '@storybook/testing-library': - specifier: 0.1.0 - version: 0.1.0 + specifier: 0.2.0 + version: 0.2.0 '@types/node': - specifier: 18.13.0 - version: 18.13.0 + specifier: 20.4.6 + version: 20.4.6 '@types/react': - specifier: ^18.0.28 - version: 18.0.28 + specifier: ^18.2.18 + version: 18.2.18 '@types/react-dom': - specifier: ^18.0.11 - version: 18.0.11 + specifier: ^18.2.7 + version: 18.2.7 '@vitejs/plugin-react': - specifier: ^3.1.0 - version: 3.1.0(vite@4.2.1) + specifier: ^4.0.4 + version: 4.0.4(vite@4.4.8) + autoprefixer: + specifier: ^10.4.14 + version: 10.4.14(postcss@8.4.27) + config: + specifier: workspace:* + version: link:../config + daisyui: + specifier: ^3.5.0 + version: 3.5.0(ts-node@10.9.1) postcss: - specifier: ^8.4.21 - version: 8.4.21 + specifier: ^8.4.27 + version: 8.4.27 postcss-load-config: specifier: ^4.0.1 - version: 4.0.1(postcss@8.4.21)(ts-node@10.9.1) + version: 4.0.1(postcss@8.4.27)(ts-node@10.9.1) postcss-nesting: - specifier: ^11.2.2 - version: 11.2.2(postcss@8.4.21) + specifier: ^12.0.0 + version: 12.0.0(postcss@8.4.27) postcss-plugin: specifier: ^1.0.0 version: 1.0.0 @@ -535,26 +586,29 @@ importers: specifier: 15.8.1 version: 15.8.1 sass: - specifier: ^1.59.3 - version: 1.59.3 + specifier: ^1.64.2 + version: 1.64.2 sass-loader: - specifier: ^13.2.2 - version: 13.2.2(sass@1.59.3)(webpack@5.77.0) + specifier: ^13.3.2 + version: 13.3.2(sass@1.64.2)(webpack@5.77.0) storybook: - specifier: ^7.0.22 - version: 7.0.22 + specifier: ^7.2.1 + version: 7.2.1 + tailwindcss: + specifier: ^3.3.3 + version: 3.3.3(ts-node@10.9.1) typescript: - specifier: ^4.9.3 - version: 4.9.5 + specifier: ^5.1.6 + version: 5.1.6 vite: - specifier: ^4.2.0 - version: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3) + specifier: ^4.4.8 + version: 4.4.8(@types/node@20.4.6)(less@4.1.3)(sass@1.64.2) vite-plugin-sass-dts: - specifier: ^1.3.2 - version: 1.3.2(postcss@8.4.21)(prettier@2.8.8)(sass@1.59.3)(vite@4.2.1) + specifier: ^1.3.9 + version: 1.3.9(postcss@8.4.27)(prettier@2.8.8)(sass@1.64.2)(vite@4.4.8) vite-tsconfig-paths: - specifier: ^4.0.7 - version: 4.0.7(typescript@4.9.5)(vite@4.2.1) + specifier: ^4.2.0 + version: 4.2.0(typescript@5.1.6)(vite@4.4.8) libs/workspace/eslint-config-custom: dependencies: @@ -569,7 +623,7 @@ importers: version: 8.7.0(eslint@7.32.0) eslint-config-turbo: specifier: latest - version: 1.10.9(eslint@7.32.0) + version: 1.10.12(eslint@7.32.0) eslint-plugin-react: specifier: 7.31.8 version: 7.31.8(eslint@7.32.0) @@ -582,6 +636,11 @@ importers: packages: + /@alloc/quick-lru@5.2.0: + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + dev: true + /@ampproject/remapping@2.2.0: resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} engines: {node: '>=6.0.0'} @@ -589,8 +648,19 @@ packages: '@jridgewell/gen-mapping': 0.1.1 '@jridgewell/trace-mapping': 0.3.17 - /@aw-web-design/x-default-browser@1.4.88: - resolution: {integrity: sha512-AkEmF0wcwYC2QkhK703Y83fxWARttIWXDmQN8+cof8FmFZ5BRhnNXGymeb1S73bOCLfWjYELxtujL56idCN/XA==} + /@antfu/install-pkg@0.1.1: + resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} + dependencies: + execa: 5.1.1 + find-up: 5.0.0 + dev: true + + /@antfu/utils@0.7.5: + resolution: {integrity: sha512-dlR6LdS+0SzOAPx/TPRhnoi7hE251OVeT2Snw0RguNbBSbjUHdWr0l3vcUUDg26rEysT89kCbtw1lVorBXLLCg==} + dev: true + + /@aw-web-design/x-default-browser@1.4.126: + resolution: {integrity: sha512-Xk1sIhyNC/esHGGVjL/niHLowM0csl/kFO5uawBy4IrWwy0o1G8LGt3jP6nmWGz+USxeeqbihAmp/oVZju6wug==} hasBin: true dependencies: default-browser-id: 3.0.0 @@ -599,31 +669,36 @@ packages: /@babel/code-frame@7.12.11: resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==} dependencies: - '@babel/highlight': 7.18.6 + '@babel/highlight': 7.22.5 - /@babel/code-frame@7.18.6: - resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} + /@babel/code-frame@7.22.5: + resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/highlight': 7.18.6 + '@babel/highlight': 7.22.5 /@babel/compat-data@7.21.4: resolution: {integrity: sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==} engines: {node: '>=6.9.0'} + /@babel/compat-data@7.22.9: + resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/core@7.21.3: resolution: {integrity: sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.0 - '@babel/code-frame': 7.18.6 - '@babel/generator': 7.21.3 + '@babel/code-frame': 7.22.5 + '@babel/generator': 7.22.9 '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3) '@babel/helper-module-transforms': 7.21.2 '@babel/helpers': 7.21.0 - '@babel/parser': 7.21.3 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.3(supports-color@5.5.0) + '@babel/parser': 7.22.7 + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.8 '@babel/types': 7.22.5 convert-source-map: 1.9.0 debug: 4.3.4(supports-color@5.5.0) @@ -633,8 +708,31 @@ packages: transitivePeerDependencies: - supports-color - /@babel/generator@7.21.3: - resolution: {integrity: sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==} + /@babel/core@7.22.9: + resolution: {integrity: sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.22.5 + '@babel/generator': 7.22.9 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9) + '@babel/helpers': 7.22.6 + '@babel/parser': 7.22.7 + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.8 + '@babel/types': 7.22.5 + convert-source-map: 1.9.0 + debug: 4.3.4(supports-color@5.5.0) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.22.9: + resolution: {integrity: sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.5 @@ -648,11 +746,17 @@ packages: dependencies: '@babel/types': 7.22.5 - /@babel/helper-builder-binary-assignment-operator-visitor@7.18.9: - resolution: {integrity: sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==} + /@babel/helper-annotate-as-pure@7.22.5: + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor@7.22.5: + resolution: {integrity: sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-explode-assignable-expression': 7.18.6 '@babel/types': 7.22.5 dev: true @@ -669,78 +773,121 @@ packages: lru-cache: 5.1.1 semver: 6.3.0 - /@babel/helper-create-class-features-plugin@7.21.0(@babel/core@7.21.3): + /@babel/helper-compilation-targets@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.22.9 + '@babel/core': 7.22.9 + '@babel/helper-validator-option': 7.22.5 + browserslist: 4.21.10 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + + /@babel/helper-create-class-features-plugin@7.21.0(@babel/core@7.22.9): resolution: {integrity: sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.3 + '@babel/core': 7.22.9 '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.21.0 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 '@babel/helper-member-expression-to-functions': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 '@babel/helper-replace-supers': 7.20.7 '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-split-export-declaration': 7.22.6 transitivePeerDependencies: - supports-color dev: true - /@babel/helper-create-regexp-features-plugin@7.21.0(@babel/core@7.21.3): + /@babel/helper-create-class-features-plugin@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.9) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 + dev: true + + /@babel/helper-create-regexp-features-plugin@7.21.0(@babel/core@7.22.9): resolution: {integrity: sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.3 + '@babel/core': 7.22.9 '@babel/helper-annotate-as-pure': 7.18.6 regexpu-core: 5.3.2 dev: true - /@babel/helper-define-polyfill-provider@0.3.3(@babel/core@7.21.3): - resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} + /@babel/helper-create-regexp-features-plugin@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==} + engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.4.0-0 + '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-annotate-as-pure': 7.22.5 + regexpu-core: 5.3.2 + semver: 6.3.1 + dev: true + + /@babel/helper-define-polyfill-provider@0.4.2(@babel/core@7.22.9): + resolution: {integrity: sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 debug: 4.3.4(supports-color@5.5.0) lodash.debounce: 4.0.8 resolve: 1.22.1 - semver: 6.3.0 transitivePeerDependencies: - supports-color dev: true - /@babel/helper-environment-visitor@7.18.9: - resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} + /@babel/helper-environment-visitor@7.22.5: + resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} engines: {node: '>=6.9.0'} - /@babel/helper-explode-assignable-expression@7.18.6: - resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} + /@babel/helper-function-name@7.22.5: + resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} engines: {node: '>=6.9.0'} dependencies: + '@babel/template': 7.22.5 '@babel/types': 7.22.5 - dev: true - /@babel/helper-function-name@7.21.0: - resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.20.7 '@babel/types': 7.22.5 - /@babel/helper-hoist-variables@7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} + /@babel/helper-member-expression-to-functions@7.21.0: + resolution: {integrity: sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.5 + dev: true - /@babel/helper-member-expression-to-functions@7.21.0: - resolution: {integrity: sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==} + /@babel/helper-member-expression-to-functions@7.22.5: + resolution: {integrity: sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.5 @@ -752,21 +899,42 @@ packages: dependencies: '@babel/types': 7.22.5 + /@babel/helper-module-imports@7.22.5: + resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + /@babel/helper-module-transforms@7.21.2: resolution: {integrity: sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-environment-visitor': 7.22.5 '@babel/helper-module-imports': 7.18.6 '@babel/helper-simple-access': 7.20.2 - '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.5 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.3(supports-color@5.5.0) + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.8 '@babel/types': 7.22.5 transitivePeerDependencies: - supports-color + /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.5 + dev: true + /@babel/helper-optimise-call-expression@7.18.6: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} engines: {node: '>=6.9.0'} @@ -774,46 +942,74 @@ packages: '@babel/types': 7.22.5 dev: true + /@babel/helper-optimise-call-expression@7.22.5: + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + /@babel/helper-plugin-utils@7.20.2: resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} engines: {node: '>=6.9.0'} dev: true - /@babel/helper-remap-async-to-generator@7.18.9(@babel/core@7.21.3): - resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} + /@babel/helper-plugin-utils@7.22.5: + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-wrap-function': 7.20.5 - '@babel/types': 7.22.5 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.22.9 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-wrap-function': 7.22.9 dev: true /@babel/helper-replace-supers@7.20.7: resolution: {integrity: sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-environment-visitor': 7.22.5 '@babel/helper-member-expression-to-functions': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.3(supports-color@5.5.0) + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.8 '@babel/types': 7.22.5 transitivePeerDependencies: - supports-color dev: true + /@babel/helper-replace-supers@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + dev: true + /@babel/helper-simple-access@7.20.2: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.5 + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + /@babel/helper-skip-transparent-expression-wrappers@7.20.0: resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} engines: {node: '>=6.9.0'} @@ -821,8 +1017,15 @@ packages: '@babel/types': 7.22.5 dev: true - /@babel/helper-split-export-declaration@7.18.6: - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} + /@babel/helper-skip-transparent-expression-wrappers@7.22.5: + resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.22.5 @@ -839,30 +1042,43 @@ packages: resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} engines: {node: '>=6.9.0'} - /@babel/helper-wrap-function@7.20.5: - resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} + /@babel/helper-validator-option@7.22.5: + resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-wrap-function@7.22.9: + resolution: {integrity: sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-function-name': 7.21.0 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.3(supports-color@5.5.0) + '@babel/helper-function-name': 7.22.5 + '@babel/template': 7.22.5 '@babel/types': 7.22.5 - transitivePeerDependencies: - - supports-color dev: true /@babel/helpers@7.21.0: resolution: {integrity: sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.3(supports-color@5.5.0) + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.8 + '@babel/types': 7.22.5 + transitivePeerDependencies: + - supports-color + + /@babel/helpers@7.22.6: + resolution: {integrity: sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.8 '@babel/types': 7.22.5 transitivePeerDependencies: - supports-color + dev: true - /@babel/highlight@7.18.6: - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + /@babel/highlight@7.22.5: + resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-validator-identifier': 7.22.5 @@ -875,659 +1091,722 @@ packages: hasBin: true dependencies: '@babel/types': 7.22.5 + dev: true + + /@babel/parser@7.22.7: + resolution: {integrity: sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.22.5 - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.20.7(@babel/core@7.21.3): - resolution: {integrity: sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==} + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-transform-optional-chaining': 7.22.6(@babel/core@7.22.9) dev: true - /@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.21.3): - resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==} + /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.22.9): + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-environment-visitor': 7.18.9 + '@babel/core': 7.22.9 + '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.22.9) '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.21.3) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.21.3) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} + /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.22.9): + resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.21.3) + '@babel/core': 7.22.9 '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9) dev: true - /@babel/plugin-proposal-class-static-block@7.21.0(@babel/core@7.21.3): - resolution: {integrity: sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==} + /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.22.9): + resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.12.0 + '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.21.3) + '@babel/core': 7.22.9 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.21.3) - transitivePeerDependencies: - - supports-color + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9) dev: true - /@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.9): + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.21.3) + '@babel/core': 7.22.9 dev: true - /@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.21.3): - resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} - engines: {node: '>=6.9.0'} + /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.22.9): + resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} + engines: {node: '>=4'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-proposal-json-strings@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} - engines: {node: '>=6.9.0'} + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.9): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-proposal-logical-assignment-operators@7.20.7(@babel/core@7.21.3): - resolution: {integrity: sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==} - engines: {node: '>=6.9.0'} + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.9): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.22.9): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} - engines: {node: '>=6.9.0'} + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.21.3): - resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} - engines: {node: '>=6.9.0'} + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.21.4 - '@babel/core': 7.21.3 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.21.3) - '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} + /@babel/plugin-syntax-flow@7.18.6(@babel/core@7.22.9): + resolution: {integrity: sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 + '@babel/core': 7.22.9 '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.21.3) dev: true - /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.21.3): - resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==} + /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} + /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-proposal-private-property-in-object@7.21.0(@babel/core@7.21.3): - resolution: {integrity: sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==} - engines: {node: '>=6.9.0'} + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.9): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.21.3) - transitivePeerDependencies: - - supports-color + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} - engines: {node: '>=4'} + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.21.3): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.9): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.21.3): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.21.3): - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.9): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.21.3): - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.21.3): - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-flow@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==} - engines: {node: '>=6.9.0'} + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-import-assertions@7.20.0(@babel/core@7.21.3): - resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.22.9): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.21.3): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.9): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} + /@babel/plugin-syntax-typescript@7.20.0(@babel/core@7.22.9): + resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 + '@babel/core': 7.22.9 '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.21.3): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.22.9): + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.21.3): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.21.3): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + /@babel/plugin-transform-async-generator-functions@7.22.7(@babel/core@7.22.9): + resolution: {integrity: sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.9(@babel/core@7.22.9) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.9) dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.21.3): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.9(@babel/core@7.22.9) dev: true - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.21.3): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.21.3): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + /@babel/plugin-transform-block-scoping@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==} + engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.21.3): - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.21.3): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + /@babel/plugin-transform-class-static-block@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.12.0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.9) dev: true - /@babel/plugin-syntax-typescript@7.20.0(@babel/core@7.21.3): - resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} + /@babel/plugin-transform-classes@7.22.6(@babel/core@7.22.9): + resolution: {integrity: sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.9) + '@babel/helper-split-export-declaration': 7.22.6 + globals: 11.12.0 dev: true - /@babel/plugin-transform-arrow-functions@7.20.7(@babel/core@7.21.3): - resolution: {integrity: sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==} + /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.22.5 dev: true - /@babel/plugin-transform-async-to-generator@7.20.7(@babel/core@7.21.3): - resolution: {integrity: sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==} + /@babel/plugin-transform-destructuring@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.21.3) - transitivePeerDependencies: - - supports-color + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-block-scoped-functions@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} + /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-block-scoping@7.21.0(@babel/core@7.21.3): - resolution: {integrity: sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==} + /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-classes@7.21.0(@babel/core@7.21.3): - resolution: {integrity: sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==} + /@babel/plugin-transform-dynamic-import@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3) - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.21.0 - '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.20.7 - '@babel/helper-split-export-declaration': 7.18.6 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.9) dev: true - /@babel/plugin-transform-computed-properties@7.20.7(@babel/core@7.21.3): - resolution: {integrity: sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==} + /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/template': 7.20.7 + '@babel/core': 7.22.9 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-destructuring@7.21.3(@babel/core@7.21.3): - resolution: {integrity: sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==} + /@babel/plugin-transform-export-namespace-from@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.9) dev: true - /@babel/plugin-transform-dotall-regex@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} + /@babel/plugin-transform-flow-strip-types@7.21.0(@babel/core@7.22.9): + resolution: {integrity: sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.21.3) + '@babel/core': 7.22.9 '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-flow': 7.18.6(@babel/core@7.22.9) dev: true - /@babel/plugin-transform-duplicate-keys@7.18.9(@babel/core@7.21.3): - resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} + /@babel/plugin-transform-for-of@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-exponentiation-operator@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} + /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-function-name': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-flow-strip-types@7.21.0(@babel/core@7.21.3): - resolution: {integrity: sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==} + /@babel/plugin-transform-json-strings@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-flow': 7.18.6(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.9) dev: true - /@babel/plugin-transform-for-of@7.21.0(@babel/core@7.21.3): - resolution: {integrity: sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==} + /@babel/plugin-transform-literals@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-function-name@7.18.9(@babel/core@7.21.3): - resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} + /@babel/plugin-transform-logical-assignment-operators@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3) - '@babel/helper-function-name': 7.21.0 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.9) dev: true - /@babel/plugin-transform-literals@7.18.9(@babel/core@7.21.3): - resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} + /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-member-expression-literals@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} + /@babel/plugin-transform-modules-amd@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-modules-amd@7.20.11(@babel/core@7.21.3): - resolution: {integrity: sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==} + /@babel/plugin-transform-modules-commonjs@7.21.2(@babel/core@7.22.9): + resolution: {integrity: sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 + '@babel/core': 7.22.9 '@babel/helper-module-transforms': 7.21.2 '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-simple-access': 7.20.2 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-modules-commonjs@7.21.2(@babel/core@7.21.3): - resolution: {integrity: sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==} + /@babel/plugin-transform-modules-commonjs@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-simple-access': 7.20.2 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.22.9 + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 dev: true - /@babel/plugin-transform-modules-systemjs@7.20.11(@babel/core@7.21.3): - resolution: {integrity: sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==} + /@babel/plugin-transform-modules-systemjs@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-validator-identifier': 7.22.5 - transitivePeerDependencies: - - supports-color dev: true - /@babel/plugin-transform-modules-umd@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} + /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.22.9 + '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-named-capturing-groups-regex@7.20.5(@babel/core@7.21.3): - resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} + /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-new-target@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} + /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-object-super@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} + /@babel/plugin-transform-nullish-coalescing-operator@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.20.7 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9) dev: true - /@babel/plugin-transform-parameters@7.21.3(@babel/core@7.21.3): - resolution: {integrity: sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==} + /@babel/plugin-transform-numeric-separator@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.9) dev: true - /@babel/plugin-transform-property-literals@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} + /@babel/plugin-transform-object-rest-spread@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/compat-data': 7.22.9 + '@babel/core': 7.22.9 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-optional-catch-binding@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-optional-chaining@7.22.6(@babel/core@7.22.9): + resolution: {integrity: sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-parameters@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-private-property-in-object@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.9) + dev: true + + /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true /@babel/plugin-transform-react-jsx-self@7.21.0(@babel/core@7.21.3): @@ -1540,6 +1819,16 @@ packages: '@babel/helper-plugin-utils': 7.20.2 dev: true + /@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + /@babel/plugin-transform-react-jsx-source@7.19.6(@babel/core@7.21.3): resolution: {integrity: sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==} engines: {node: '>=6.9.0'} @@ -1550,260 +1839,283 @@ packages: '@babel/helper-plugin-utils': 7.20.2 dev: true - /@babel/plugin-transform-react-jsx@7.21.0(@babel/core@7.21.3): - resolution: {integrity: sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==} + /@babel/plugin-transform-react-jsx-source@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.21.3) - '@babel/types': 7.22.5 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-regenerator@7.20.5(@babel/core@7.21.3): - resolution: {integrity: sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==} + /@babel/plugin-transform-regenerator@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 regenerator-transform: 0.15.1 dev: true - /@babel/plugin-transform-reserved-words@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} + /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-shorthand-properties@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} + /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-spread@7.20.7(@babel/core@7.21.3): - resolution: {integrity: sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==} + /@babel/plugin-transform-spread@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: true - /@babel/plugin-transform-sticky-regex@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} + /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-template-literals@7.18.9(@babel/core@7.21.3): - resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} + /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-typeof-symbol@7.18.9(@babel/core@7.21.3): - resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} + /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-typescript@7.21.3(@babel/core@7.21.3): + /@babel/plugin-transform-typescript@7.21.3(@babel/core@7.22.9): resolution: {integrity: sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 + '@babel/core': 7.22.9 '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.21.3) + '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.22.9) '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.21.3) + '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.22.9) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-unicode-escapes@7.18.10(@babel/core@7.21.3): - resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} + /@babel/plugin-transform-unicode-escapes@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-unicode-regex@7.18.6(@babel/core@7.21.3): - resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} + /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/preset-env@7.21.4(@babel/core@7.21.3): - resolution: {integrity: sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==} + /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.21.4 - '@babel/core': 7.21.3 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.3) - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-validator-option': 7.21.0 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.20.7(@babel/core@7.21.3) - '@babel/plugin-proposal-async-generator-functions': 7.20.7(@babel/core@7.21.3) - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-proposal-class-static-block': 7.21.0(@babel/core@7.21.3) - '@babel/plugin-proposal-dynamic-import': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-proposal-export-namespace-from': 7.18.9(@babel/core@7.21.3) - '@babel/plugin-proposal-json-strings': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-proposal-logical-assignment-operators': 7.20.7(@babel/core@7.21.3) - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.21.3) - '@babel/plugin-proposal-optional-catch-binding': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.3) - '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-proposal-private-property-in-object': 7.21.0(@babel/core@7.21.3) - '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.21.3) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.21.3) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.21.3) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.21.3) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.21.3) - '@babel/plugin-syntax-import-assertions': 7.20.0(@babel/core@7.21.3) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.21.3) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.21.3) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.21.3) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.21.3) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.21.3) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.21.3) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.21.3) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.21.3) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.21.3) - '@babel/plugin-transform-arrow-functions': 7.20.7(@babel/core@7.21.3) - '@babel/plugin-transform-async-to-generator': 7.20.7(@babel/core@7.21.3) - '@babel/plugin-transform-block-scoped-functions': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-block-scoping': 7.21.0(@babel/core@7.21.3) - '@babel/plugin-transform-classes': 7.21.0(@babel/core@7.21.3) - '@babel/plugin-transform-computed-properties': 7.20.7(@babel/core@7.21.3) - '@babel/plugin-transform-destructuring': 7.21.3(@babel/core@7.21.3) - '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-duplicate-keys': 7.18.9(@babel/core@7.21.3) - '@babel/plugin-transform-exponentiation-operator': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-for-of': 7.21.0(@babel/core@7.21.3) - '@babel/plugin-transform-function-name': 7.18.9(@babel/core@7.21.3) - '@babel/plugin-transform-literals': 7.18.9(@babel/core@7.21.3) - '@babel/plugin-transform-member-expression-literals': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-modules-amd': 7.20.11(@babel/core@7.21.3) - '@babel/plugin-transform-modules-commonjs': 7.21.2(@babel/core@7.21.3) - '@babel/plugin-transform-modules-systemjs': 7.20.11(@babel/core@7.21.3) - '@babel/plugin-transform-modules-umd': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-named-capturing-groups-regex': 7.20.5(@babel/core@7.21.3) - '@babel/plugin-transform-new-target': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-object-super': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.21.3) - '@babel/plugin-transform-property-literals': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-regenerator': 7.20.5(@babel/core@7.21.3) - '@babel/plugin-transform-reserved-words': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-shorthand-properties': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-spread': 7.20.7(@babel/core@7.21.3) - '@babel/plugin-transform-sticky-regex': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-template-literals': 7.18.9(@babel/core@7.21.3) - '@babel/plugin-transform-typeof-symbol': 7.18.9(@babel/core@7.21.3) - '@babel/plugin-transform-unicode-escapes': 7.18.10(@babel/core@7.21.3) - '@babel/plugin-transform-unicode-regex': 7.18.6(@babel/core@7.21.3) - '@babel/preset-modules': 0.1.5(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.22.9): + resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/preset-env@7.22.9(@babel/core@7.22.9): + resolution: {integrity: sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.22.9 + '@babel/core': 7.22.9 + '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.22.5 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.9) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.9) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.9) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.9) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.9) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.9) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.9) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.9) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.9) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.22.9) + '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-async-generator-functions': 7.22.7(@babel/core@7.22.9) + '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-block-scoping': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-class-static-block': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-classes': 7.22.6(@babel/core@7.22.9) + '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-destructuring': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-dynamic-import': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-export-namespace-from': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-for-of': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-json-strings': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-logical-assignment-operators': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-modules-amd': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-modules-systemjs': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-nullish-coalescing-operator': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-numeric-separator': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-object-rest-spread': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-optional-catch-binding': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-optional-chaining': 7.22.6(@babel/core@7.22.9) + '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-private-property-in-object': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-regenerator': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-unicode-escapes': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.22.9) + '@babel/preset-modules': 0.1.5(@babel/core@7.22.9) '@babel/types': 7.22.5 - babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.21.3) - babel-plugin-polyfill-corejs3: 0.6.0(@babel/core@7.21.3) - babel-plugin-polyfill-regenerator: 0.4.1(@babel/core@7.21.3) - core-js-compat: 3.29.1 - semver: 6.3.0 + babel-plugin-polyfill-corejs2: 0.4.5(@babel/core@7.22.9) + babel-plugin-polyfill-corejs3: 0.8.3(@babel/core@7.22.9) + babel-plugin-polyfill-regenerator: 0.5.2(@babel/core@7.22.9) + core-js-compat: 3.32.0 + semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /@babel/preset-flow@7.18.6(@babel/core@7.21.3): + /@babel/preset-flow@7.18.6(@babel/core@7.22.9): resolution: {integrity: sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 + '@babel/core': 7.22.9 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-validator-option': 7.21.0 - '@babel/plugin-transform-flow-strip-types': 7.21.0(@babel/core@7.21.3) + '@babel/plugin-transform-flow-strip-types': 7.21.0(@babel/core@7.22.9) dev: true - /@babel/preset-modules@0.1.5(@babel/core@7.21.3): + /@babel/preset-modules@0.1.5(@babel/core@7.22.9): resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.22.9) + '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.9) '@babel/types': 7.22.5 esutils: 2.0.3 dev: true - /@babel/preset-typescript@7.21.0(@babel/core@7.21.3): + /@babel/preset-typescript@7.21.0(@babel/core@7.22.9): resolution: {integrity: sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 + '@babel/core': 7.22.9 '@babel/helper-plugin-utils': 7.20.2 '@babel/helper-validator-option': 7.21.0 - '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.21.3) + '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.22.9) transitivePeerDependencies: - supports-color dev: true - /@babel/register@7.21.0(@babel/core@7.21.3): + /@babel/register@7.21.0(@babel/core@7.22.9): resolution: {integrity: sha512-9nKsPmYDi5DidAqJaQooxIhsLJiNMkGr8ypQ8Uic7cIox7UCDsM7HuUGxdGT7mSDTYbqzIdsOWzfBton/YJrMw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 + '@babel/core': 7.22.9 clone-deep: 4.0.1 find-cache-dir: 2.1.0 make-dir: 2.1.0 @@ -1821,39 +2133,48 @@ packages: dependencies: regenerator-runtime: 0.13.11 - /@babel/template@7.20.7: - resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} + /@babel/template@7.22.5: + resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.18.6 - '@babel/parser': 7.21.3 + '@babel/code-frame': 7.22.5 + '@babel/parser': 7.22.7 '@babel/types': 7.22.5 /@babel/traverse@7.21.3(supports-color@5.5.0): resolution: {integrity: sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.18.6 - '@babel/generator': 7.21.3 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.21.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.21.3 + '@babel/code-frame': 7.22.5 + '@babel/generator': 7.22.9 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.22.7 '@babel/types': 7.22.5 debug: 4.3.4(supports-color@5.5.0) globals: 11.12.0 transitivePeerDependencies: - supports-color + dev: false - /@babel/types@7.21.4: - resolution: {integrity: sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==} + /@babel/traverse@7.22.8: + resolution: {integrity: sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 - to-fast-properties: 2.0.0 - dev: true + '@babel/code-frame': 7.22.5 + '@babel/generator': 7.22.9 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.22.7 + '@babel/types': 7.22.5 + debug: 4.3.4(supports-color@5.5.0) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color /@babel/types@7.22.5: resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==} @@ -2074,6 +2395,15 @@ packages: postcss-selector-parser: 6.0.11 dev: true + /@csstools/selector-specificity@3.0.0(postcss-selector-parser@6.0.13): + resolution: {integrity: sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss-selector-parser: ^6.0.13 + dependencies: + postcss-selector-parser: 6.0.13 + dev: true + /@deck.gl/aggregation-layers@8.9.19(@deck.gl/core@8.9.19)(@deck.gl/layers@8.9.19)(@luma.gl/core@8.5.20): resolution: {integrity: sha512-CYZy6dkOSXN+BWuR68YihomrLvEXdcAvUVM3gL5P4Dxi9ajdMKFBNo/34imHG/Bx5ukU2pxghDGrOmBXQ8XybQ==} peerDependencies: @@ -2434,16 +2764,25 @@ packages: dev: true optional: true - /@esbuild/android-arm@0.16.17: - resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} + /@esbuild/android-arm64@0.18.17: + resolution: {integrity: sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==} engines: {node: '>=12'} - cpu: [arm] + cpu: [arm64] os: [android] requiresBuild: true dev: true optional: true - /@esbuild/android-arm@0.17.12: + /@esbuild/android-arm@0.16.17: + resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.17.12: resolution: {integrity: sha512-E/sgkvwoIfj4aMAPL2e35VnUJspzVYl7+M1B2cqeubdBhADV4uPon0KCc8p2G+LqSJ6i8ocYPCqY3A4GGq0zkQ==} engines: {node: '>=12'} cpu: [arm] @@ -2452,6 +2791,15 @@ packages: dev: true optional: true + /@esbuild/android-arm@0.18.17: + resolution: {integrity: sha512-wHsmJG/dnL3OkpAcwbgoBTTMHVi4Uyou3F5mf58ZtmUyIKfcdA7TROav/6tCzET4A3QW2Q2FC+eFneMU+iyOxg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64@0.16.17: resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} engines: {node: '>=12'} @@ -2470,6 +2818,15 @@ packages: dev: true optional: true + /@esbuild/android-x64@0.18.17: + resolution: {integrity: sha512-O+FeWB/+xya0aLg23hHEM2E3hbfwZzjqumKMSIqcHbNvDa+dza2D0yLuymRBQQnC34CWrsJUXyH2MG5VnLd6uw==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64@0.16.17: resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} engines: {node: '>=12'} @@ -2488,6 +2845,15 @@ packages: dev: true optional: true + /@esbuild/darwin-arm64@0.18.17: + resolution: {integrity: sha512-M9uJ9VSB1oli2BE/dJs3zVr9kcCBBsE883prage1NWz6pBS++1oNn/7soPNS3+1DGj0FrkSvnED4Bmlu1VAE9g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64@0.16.17: resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} engines: {node: '>=12'} @@ -2506,6 +2872,15 @@ packages: dev: true optional: true + /@esbuild/darwin-x64@0.18.17: + resolution: {integrity: sha512-XDre+J5YeIJDMfp3n0279DFNrGCXlxOuGsWIkRb1NThMZ0BsrWXoTg23Jer7fEXQ9Ye5QjrvXpxnhzl3bHtk0g==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64@0.16.17: resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} engines: {node: '>=12'} @@ -2524,6 +2899,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-arm64@0.18.17: + resolution: {integrity: sha512-cjTzGa3QlNfERa0+ptykyxs5A6FEUQQF0MuilYXYBGdBxD3vxJcKnzDlhDCa1VAJCmAxed6mYhA2KaJIbtiNuQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64@0.16.17: resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} engines: {node: '>=12'} @@ -2542,6 +2926,15 @@ packages: dev: true optional: true + /@esbuild/freebsd-x64@0.18.17: + resolution: {integrity: sha512-sOxEvR8d7V7Kw8QqzxWc7bFfnWnGdaFBut1dRUYtu+EIRXefBc/eIsiUiShnW0hM3FmQ5Zf27suDuHsKgZ5QrA==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64@0.16.17: resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} engines: {node: '>=12'} @@ -2560,6 +2953,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm64@0.18.17: + resolution: {integrity: sha512-c9w3tE7qA3CYWjT+M3BMbwMt+0JYOp3vCMKgVBrCl1nwjAlOMYzEo+gG7QaZ9AtqZFj5MbUc885wuBBmu6aADQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm@0.16.17: resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} engines: {node: '>=12'} @@ -2578,6 +2980,15 @@ packages: dev: true optional: true + /@esbuild/linux-arm@0.18.17: + resolution: {integrity: sha512-2d3Lw6wkwgSLC2fIvXKoMNGVaeY8qdN0IC3rfuVxJp89CRfA3e3VqWifGDfuakPmp90+ZirmTfye1n4ncjv2lg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32@0.16.17: resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} engines: {node: '>=12'} @@ -2596,6 +3007,15 @@ packages: dev: true optional: true + /@esbuild/linux-ia32@0.18.17: + resolution: {integrity: sha512-1DS9F966pn5pPnqXYz16dQqWIB0dmDfAQZd6jSSpiT9eX1NzKh07J6VKR3AoXXXEk6CqZMojiVDSZi1SlmKVdg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64@0.16.17: resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} engines: {node: '>=12'} @@ -2614,6 +3034,15 @@ packages: dev: true optional: true + /@esbuild/linux-loong64@0.18.17: + resolution: {integrity: sha512-EvLsxCk6ZF0fpCB6w6eOI2Fc8KW5N6sHlIovNe8uOFObL2O+Mr0bflPHyHwLT6rwMg9r77WOAWb2FqCQrVnwFg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el@0.16.17: resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} engines: {node: '>=12'} @@ -2632,6 +3061,15 @@ packages: dev: true optional: true + /@esbuild/linux-mips64el@0.18.17: + resolution: {integrity: sha512-e0bIdHA5p6l+lwqTE36NAW5hHtw2tNRmHlGBygZC14QObsA3bD4C6sXLJjvnDIjSKhW1/0S3eDy+QmX/uZWEYQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64@0.16.17: resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} engines: {node: '>=12'} @@ -2650,6 +3088,15 @@ packages: dev: true optional: true + /@esbuild/linux-ppc64@0.18.17: + resolution: {integrity: sha512-BAAilJ0M5O2uMxHYGjFKn4nJKF6fNCdP1E0o5t5fvMYYzeIqy2JdAP88Az5LHt9qBoUa4tDaRpfWt21ep5/WqQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64@0.16.17: resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} engines: {node: '>=12'} @@ -2668,6 +3115,15 @@ packages: dev: true optional: true + /@esbuild/linux-riscv64@0.18.17: + resolution: {integrity: sha512-Wh/HW2MPnC3b8BqRSIme/9Zhab36PPH+3zam5pqGRH4pE+4xTrVLx2+XdGp6fVS3L2x+DrsIcsbMleex8fbE6g==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x@0.16.17: resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} engines: {node: '>=12'} @@ -2686,6 +3142,15 @@ packages: dev: true optional: true + /@esbuild/linux-s390x@0.18.17: + resolution: {integrity: sha512-j/34jAl3ul3PNcK3pfI0NSlBANduT2UO5kZ7FCaK33XFv3chDhICLY8wJJWIhiQ+YNdQ9dxqQctRg2bvrMlYgg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64@0.16.17: resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} engines: {node: '>=12'} @@ -2704,6 +3169,15 @@ packages: dev: true optional: true + /@esbuild/linux-x64@0.18.17: + resolution: {integrity: sha512-QM50vJ/y+8I60qEmFxMoxIx4de03pGo2HwxdBeFd4nMh364X6TIBZ6VQ5UQmPbQWUVWHWws5MmJXlHAXvJEmpQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64@0.16.17: resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} engines: {node: '>=12'} @@ -2722,6 +3196,15 @@ packages: dev: true optional: true + /@esbuild/netbsd-x64@0.18.17: + resolution: {integrity: sha512-/jGlhWR7Sj9JPZHzXyyMZ1RFMkNPjC6QIAan0sDOtIo2TYk3tZn5UDrkE0XgsTQCxWTTOcMPf9p6Rh2hXtl5TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64@0.16.17: resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} engines: {node: '>=12'} @@ -2740,6 +3223,15 @@ packages: dev: true optional: true + /@esbuild/openbsd-x64@0.18.17: + resolution: {integrity: sha512-rSEeYaGgyGGf4qZM2NonMhMOP/5EHp4u9ehFiBrg7stH6BYEEjlkVREuDEcQ0LfIl53OXLxNbfuIj7mr5m29TA==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64@0.16.17: resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} engines: {node: '>=12'} @@ -2758,6 +3250,15 @@ packages: dev: true optional: true + /@esbuild/sunos-x64@0.18.17: + resolution: {integrity: sha512-Y7ZBbkLqlSgn4+zot4KUNYst0bFoO68tRgI6mY2FIM+b7ZbyNVtNbDP5y8qlu4/knZZ73fgJDlXID+ohY5zt5g==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64@0.16.17: resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} engines: {node: '>=12'} @@ -2776,6 +3277,15 @@ packages: dev: true optional: true + /@esbuild/win32-arm64@0.18.17: + resolution: {integrity: sha512-bwPmTJsEQcbZk26oYpc4c/8PvTY3J5/QK8jM19DVlEsAB41M39aWovWoHtNm78sd6ip6prilxeHosPADXtEJFw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32@0.16.17: resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} engines: {node: '>=12'} @@ -2794,6 +3304,15 @@ packages: dev: true optional: true + /@esbuild/win32-ia32@0.18.17: + resolution: {integrity: sha512-H/XaPtPKli2MhW+3CQueo6Ni3Avggi6hP/YvgkEe1aSaxw+AeO8MFjq8DlgfTd9Iz4Yih3QCZI6YLMoyccnPRg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64@0.16.17: resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} engines: {node: '>=12'} @@ -2812,6 +3331,15 @@ packages: dev: true optional: true + /@esbuild/win32-x64@0.18.17: + resolution: {integrity: sha512-fGEb8f2BSA3CW7riJVurug65ACLuQAzKq0SSqkY2b2yHHH0MzDfbLyKIGzHwOI/gkHcxM/leuSW6D5w/LMNitA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@eslint/eslintrc@0.4.3: resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -2832,6 +3360,34 @@ packages: resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} dev: true + /@floating-ui/core@1.4.0: + resolution: {integrity: sha512-x5Ly1Eiyqt9aR38XzhraoWxgtQtvy3mVChWMZIr49XFyvIhNuqUxZKXBRoI5WiMRaaAZezCauJaEISu3z5y8sg==} + dependencies: + '@floating-ui/utils': 0.1.0 + dev: true + + /@floating-ui/dom@1.5.0: + resolution: {integrity: sha512-9jPin5dTlcEN+nXzBRhdreCzlJBIYWeMXpJJ5VnO1l9dLcP7uQNPbmwmIoHpHpH6GPYMYtQA7GfkvsSj/CQPwg==} + dependencies: + '@floating-ui/core': 1.4.0 + '@floating-ui/utils': 0.1.0 + dev: true + + /@floating-ui/react-dom@2.0.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-rZtAmSht4Lry6gdhAJDrCp/6rKN7++JnL1/Anbr/DdeyYXQPxvg/ivrbYvJulbRf4vL8b212suwMM2lxbv+RQA==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 1.5.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@floating-ui/utils@0.1.0: + resolution: {integrity: sha512-ZSlli/beGZdvoqT3/Y9oOW79XSEpBfxt8UY6vjyWJW0B8d/M+MKlkQ3kBzLKDXaSsB84IVj6QntQfHLzesB4mA==} + dev: true + /@humanwhocodes/config-array@0.5.0: resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==} engines: {node: '>=10.10.0'} @@ -2845,6 +3401,51 @@ packages: /@humanwhocodes/object-schema@1.2.1: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + /@iconify/json@2.2.95: + resolution: {integrity: sha512-54c4P8Z2Zuvgd3EEhAGV/byNPJ1sjVHO+Sd94376//6heUW73x04TjtNAnYviFdypI8S7SdYCn+ncyW4JhOmiA==} + dependencies: + '@iconify/types': 2.0.0 + pathe: 1.1.0 + dev: true + + /@iconify/react@4.1.1(react@18.2.0): + resolution: {integrity: sha512-jed14EjvKjee8mc0eoscGxlg7mSQRkwQG3iX3cPBCO7UlOjz0DtlvTqxqEcHUJGh+z1VJ31Yhu5B9PxfO0zbdg==} + peerDependencies: + react: '>=16' + dependencies: + '@iconify/types': 2.0.0 + react: 18.2.0 + dev: true + + /@iconify/types@2.0.0: + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + dev: true + + /@iconify/utils@2.1.7: + resolution: {integrity: sha512-P8S3z/L1LcV4Qem9AoCfVAaTFGySEMzFEY4CHZLkfRj0Fv9LiR+AwjDgrDrzyI93U2L2mg9JHsbTJ52mF8suNw==} + dependencies: + '@antfu/install-pkg': 0.1.1 + '@antfu/utils': 0.7.5 + '@iconify/types': 2.0.0 + debug: 4.3.4(supports-color@5.5.0) + kolorist: 1.8.0 + local-pkg: 0.4.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@isaacs/cliui@8.0.2: + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + dependencies: + string-width: 5.1.2 + string-width-cjs: /string-width@4.2.3 + strip-ansi: 7.0.1 + strip-ansi-cjs: /strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: /wrap-ansi@7.0.0 + dev: true + /@istanbuljs/load-nyc-config@1.1.0: resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} engines: {node: '>=8'} @@ -2914,7 +3515,7 @@ packages: chalk: 4.1.2 dev: true - /@joshwooding/vite-plugin-react-docgen-typescript@0.2.1(typescript@4.9.5)(vite@4.2.1): + /@joshwooding/vite-plugin-react-docgen-typescript@0.2.1(typescript@5.1.6)(vite@4.4.8): resolution: {integrity: sha512-ou4ZJSXMMWHqGS4g8uNRbC5TiTWxAgQZiVucoUrOCWuPrTbkpJbmVyIi9jU72SBry7gQtuMEDp4YR8EEXAg7VQ==} peerDependencies: typescript: '>= 4.3.x' @@ -2926,9 +3527,9 @@ packages: glob: 7.2.3 glob-promise: 4.2.2(glob@7.2.3) magic-string: 0.27.0 - react-docgen-typescript: 2.2.2(typescript@4.9.5) - typescript: 4.9.5 - vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3) + react-docgen-typescript: 2.2.2(typescript@5.1.6) + typescript: 5.1.6 + vite: 4.4.8(@types/node@20.4.6)(less@4.1.3)(sass@1.64.2) dev: true /@jridgewell/gen-mapping@0.1.1: @@ -2964,6 +3565,10 @@ packages: /@jridgewell/sourcemap-codec@1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + /@jridgewell/trace-mapping@0.3.17: resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} dependencies: @@ -3292,7 +3897,7 @@ packages: react: '>=16' dependencies: '@types/mdx': 2.0.3 - '@types/react': 18.0.28 + '@types/react': 18.2.18 react: 18.2.0 dev: true @@ -3369,30 +3974,6 @@ packages: resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} dev: true - /@mui/base@5.0.0-alpha.118(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-GAEpqhnuHjRaAZLdxFNuOf2GDTp9sUawM46oHZV4VnYPFjXJDkIYFWfIQLONb0nga92OiqS5DD/scGzVKCL0Mw==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@types/react': ^17.0.0 || ^18.0.0 - react: ^17.0.0 || ^18.0.0 - react-dom: ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@babel/runtime': 7.21.0 - '@emotion/is-prop-valid': 1.2.0 - '@mui/types': 7.2.3(@types/react@18.0.28) - '@mui/utils': 5.11.13(react@18.2.0) - '@popperjs/core': 2.11.6 - '@types/react': 18.0.28 - clsx: 1.2.1 - prop-types: 15.8.1 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-is: 18.2.0 - dev: false - /@mui/base@5.0.0-alpha.121(@types/react@18.0.28)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-8nJRY76UqlJV+q/Yzo0tgGfPWEOa+4N9rjO81fMmcJqP0I6m54hLDXsjvMg4tvelY5eKHXUK6Tb7en+GHfTqZA==} engines: {node: '>=12.0.0'} @@ -3491,22 +4072,6 @@ packages: react: 18.2.0 dev: false - /@mui/styled-engine-sc@5.11.11(@types/styled-components@5.1.26)(styled-components@5.3.9): - resolution: {integrity: sha512-6+HsfcKHlhjQklDoEup7Itl+Xgn+BCsqEpIdIIhlxED4YlOZ38xghxIKrx78XFZznTorbhAspUgDDKIaB5vDMg==} - engines: {node: '>=12.0.0'} - peerDependencies: - '@types/styled-components': ^5.1.14 - styled-components: ^5.3.1 - peerDependenciesMeta: - '@types/styled-components': - optional: true - dependencies: - '@babel/runtime': 7.21.0 - '@types/styled-components': 5.1.26 - prop-types: 15.8.1 - styled-components: 5.3.9(react-dom@18.2.0)(react-is@18.2.0)(react@18.2.0) - dev: false - /@mui/styled-engine@5.11.11(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(react@18.2.0): resolution: {integrity: sha512-wV0UgW4lN5FkDBXefN8eTYeuE9sjyQdg5h94vtwZCUamGQEzmCOtir4AakgmbWMy0x8OLjdEUESn9wnf5J9MOg==} engines: {node: '>=12.0.0'} @@ -4089,6 +4654,13 @@ packages: url: 0.11.0 dev: false + /@pkgjs/parseargs@0.11.0: + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + requiresBuild: true + dev: true + optional: true + /@popperjs/core@2.11.6: resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==} dev: false @@ -4131,24 +4703,457 @@ packages: '@babel/runtime': 7.21.0 dev: false - /@reactflow/background@11.1.0-next.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-OXCWt3rKz7/pctEqL2e82ziIJwfxGO9McC2a/JGso75rhCu+b7dWejhESNRS+9rgu1PdQpjDvB/wgQKIQqGoWA==} - peerDependencies: - react: '>=17' - react-dom: '>=17' + /@radix-ui/number@1.0.1: + resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} dependencies: '@babel/runtime': 7.21.0 - '@reactflow/core': 11.4.0-next.1(react-dom@18.2.0)(react@18.2.0) - classcat: 5.0.4 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - zustand: 4.3.6(immer@10.0.2)(react@18.2.0) - transitivePeerDependencies: - - immer - dev: false + dev: true - /@reactflow/background@11.2.0(immer@10.0.2)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-Fd8Few2JsLuE/2GaIM6fkxEBaAJvfzi2Lc106HKi/ddX+dZs8NUsSwMsJy1Ajs8b4GbiX8v8axfKpbK6qFMV8w==} + /@radix-ui/primitive@1.0.1: + resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} + dependencies: + '@babel/runtime': 7.21.0 + dev: true + + /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.18 + '@types/react-dom': 18.2.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.18)(react@18.2.0) + '@types/react': 18.2.18 + '@types/react-dom': 18.2.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-context@1.0.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-direction@1.0.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-dismissable-layer@1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.18)(react@18.2.0) + '@types/react': 18.2.18 + '@types/react-dom': 18.2.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-focus-scope@1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@types/react': 18.2.18 + '@types/react-dom': 18.2.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@radix-ui/react-id@1.0.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-popper@1.1.2(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-1CnGGfFi/bbqtJZZ0P/NQY20xdG3E0LALJaLUEoKwPLwl6PPPfbeiCqMVQnhoFRAxjJj4RpBRJzDmUgsex2tSg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@floating-ui/react-dom': 2.0.1(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.18 + '@types/react-dom': 18.2.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@radix-ui/react-portal@1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-xLYZeHrWoPmA5mEKEfZZevoVRK/Q43GfzRXkWV6qawIWWK8t6ifIiLQdd7rmQ4Vk1bmI21XhqF9BN3jWf+phpA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.18 + '@types/react-dom': 18.2.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.18)(react@18.2.0) + '@types/react': 18.2.18 + '@types/react-dom': 18.2.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@radix-ui/react-select@1.2.2(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-zI7McXr8fNaSrUY9mZe4x/HC0jTLY9fWNhO1oLWYMQGDXuV4UCivIGTxwioSzO0ZCYX9iSLyWmAh/1TOmX3Cnw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/number': 1.0.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-popper': 1.1.2(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.18 + '@types/react-dom': 18.2.7 + aria-hidden: 1.2.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-remove-scroll: 2.5.5(@types/react@18.2.18)(react@18.2.0) + dev: true + + /@radix-ui/react-slot@1.0.2(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-use-previous@1.0.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-use-rect@1.0.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-use-size@1.0.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.18)(react@18.2.0) + '@types/react': 18.2.18 + react: 18.2.0 + dev: true + + /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.21.0 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.18 + '@types/react-dom': 18.2.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@radix-ui/rect@1.0.1: + resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==} + dependencies: + '@babel/runtime': 7.21.0 + dev: true + + /@reactflow/background@11.1.0-next.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-OXCWt3rKz7/pctEqL2e82ziIJwfxGO9McC2a/JGso75rhCu+b7dWejhESNRS+9rgu1PdQpjDvB/wgQKIQqGoWA==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + dependencies: + '@babel/runtime': 7.21.0 + '@reactflow/core': 11.4.0-next.1(react-dom@18.2.0)(react@18.2.0) + classcat: 5.0.4 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.3.6(immer@10.0.2)(react@18.2.0) + transitivePeerDependencies: + - immer + dev: false + + /@reactflow/background@11.2.0(immer@10.0.2)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Fd8Few2JsLuE/2GaIM6fkxEBaAJvfzi2Lc106HKi/ddX+dZs8NUsSwMsJy1Ajs8b4GbiX8v8axfKpbK6qFMV8w==} peerDependencies: react: '>=17' react-dom: '>=17' @@ -4365,14 +5370,6 @@ packages: engines: {node: '>=14'} dev: false - /@rollup/pluginutils@4.2.1: - resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} - engines: {node: '>= 8.0.0'} - dependencies: - estree-walker: 2.0.2 - picomatch: 2.3.1 - dev: true - /@rollup/pluginutils@5.0.2: resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} engines: {node: '>=14.0.0'} @@ -4446,8 +5443,8 @@ packages: resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} dev: true - /@storybook/addon-actions@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-qEvhnGeFb9c2TXdSgcCm+LQsZC+8yj1xXv+xfXu/maEcf3DoFU7iF4pBQJRsmawLP+m/yNaXujUbg/aty4fSng==} + /@storybook/addon-actions@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-YUiKksgRIUm80eZacj/x14BEYCQY5iel1/Wo6mrTP7bVQrUNiCmnINSrup0DObg7lmIaq00h3ow7gKeYJ+x6zw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4457,14 +5454,14 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/components': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.0.0-rc.5 + '@storybook/client-logger': 7.2.1 + '@storybook/components': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.2.1 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.0-rc.5 - '@storybook/theming': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.0-rc.5 + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.2.1 + '@storybook/theming': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.2.1 dequal: 2.0.3 lodash: 4.17.21 polished: 4.2.2 @@ -4474,11 +5471,16 @@ packages: react-inspector: 6.0.1(react@18.2.0) telejson: 7.0.4 ts-dedent: 2.2.0 - uuid-browser: 3.1.0 + uuid: 9.0.0 + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - debug + - supports-color dev: true - /@storybook/addon-backgrounds@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-vjuPvgZjM1IFVCMSvbrAPO0piY+xgzh5433JqZuYGnIPOtqLuRpq1/xE7aSMNKC7bXIczukydo184p+rfqUUgw==} + /@storybook/addon-backgrounds@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-F+/eERFnCIjDaOkCbCS0erre1AbjsHoM0IdLu2sGIBwuroFwKYy/ijadSsJ1zk4eBqZFxdyN4CuMN6EsK1Xm+Q==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4488,22 +5490,27 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/components': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.0.0-rc.5 + '@storybook/client-logger': 7.2.1 + '@storybook/components': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.2.1 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.0-rc.5 - '@storybook/theming': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.0-rc.5 + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.2.1 + '@storybook/theming': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.2.1 memoizerific: 1.11.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - debug + - supports-color dev: true - /@storybook/addon-controls@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-dV7ljOjZsxtPJ4jlzurnEOQ15opPelKmcEAN6Tl0Id4gW0ouAkb7f++/TfSeI9+BDd0+JPvsw6w3SCCD0t+46A==} + /@storybook/addon-controls@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-ioILEP4wZo6n8ifr1b+o8xCdMVLWyhHqNWoQoBRixxWwpzR4/fHaKo7wBGSkOOWubkhen6wUMUuiJbDdoGyR7g==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4513,50 +5520,49 @@ packages: react-dom: optional: true dependencies: - '@storybook/blocks': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/components': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-common': 7.0.0-rc.5 - '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/node-logger': 7.0.0-rc.5 - '@storybook/preview-api': 7.0.0-rc.5 - '@storybook/theming': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.0-rc.5 + '@storybook/blocks': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 7.2.1 + '@storybook/components': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-common': 7.2.1 + '@storybook/core-events': 7.2.1 + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/node-logger': 7.2.1 + '@storybook/preview-api': 7.2.1 + '@storybook/theming': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.2.1 lodash: 4.17.21 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ts-dedent: 2.2.0 transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - debug + - encoding - supports-color dev: true - /@storybook/addon-docs@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-MhxJmZ/Pxi57+SGhpKhrNMxeP4Bj5UM1dmHYk49cwOZBIG0NuWr8lOvMvL8tRjvq7u0jHKqNSa0reSPCBZvvxg==} + /@storybook/addon-docs@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-QlUM22wK0cE9glMRt1auP3BccjafdRvcsAnaLvDIL12HRaUqMpH6vvNN3A3MXo6XuzbOmDwAov5mXdCenpz02A==} peerDependencies: - '@storybook/mdx1-csf': '>=1.0.0-0' react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - peerDependenciesMeta: - '@storybook/mdx1-csf': - optional: true dependencies: - '@babel/core': 7.21.3 - '@babel/plugin-transform-react-jsx': 7.21.0(@babel/core@7.21.3) '@jest/transform': 29.5.0 '@mdx-js/react': 2.3.0(react@18.2.0) - '@storybook/blocks': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/components': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/csf-plugin': 7.0.0-rc.5 - '@storybook/csf-tools': 7.0.0-rc.5 + '@storybook/blocks': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 7.2.1 + '@storybook/components': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/csf-plugin': 7.2.1 + '@storybook/csf-tools': 7.2.1 '@storybook/global': 5.0.0 - '@storybook/mdx2-csf': 1.1.0-next.1 - '@storybook/node-logger': 7.0.0-rc.5 - '@storybook/postinstall': 7.0.0-rc.5 - '@storybook/preview-api': 7.0.0-rc.5 - '@storybook/react-dom-shim': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/theming': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.0-rc.5 + '@storybook/mdx2-csf': 1.0.0 + '@storybook/node-logger': 7.2.1 + '@storybook/postinstall': 7.2.1 + '@storybook/preview-api': 7.2.1 + '@storybook/react-dom-shim': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.2.1 fs-extra: 11.1.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -4564,46 +5570,53 @@ packages: remark-slug: 6.1.0 ts-dedent: 2.2.0 transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - debug + - encoding - supports-color dev: true - /@storybook/addon-essentials@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-dfBOZ5odCzki6F7tMcbX9x6fpuGsz4Owxw5iIL7FUCjxUrlClwTMpvwqqZniHPFAEWnISLcKgkPX7D7oRrWCig==} + /@storybook/addon-essentials@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-+ICPYpuljKOoO1oTRfoax4n+3UD2/xAY8qQmAsRNN3xOBNJfdrsrCocrfY1j74xqoX+Zflvp5V481zq+MpP4XQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/addon-actions': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-backgrounds': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-controls': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-docs': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-highlight': 7.0.0-rc.5 - '@storybook/addon-measure': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-outline': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-toolbars': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/addon-viewport': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-common': 7.0.0-rc.5 - '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/node-logger': 7.0.0-rc.5 - '@storybook/preview-api': 7.0.0-rc.5 + '@storybook/addon-actions': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-backgrounds': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-controls': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-docs': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-highlight': 7.2.1 + '@storybook/addon-measure': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-outline': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-toolbars': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-viewport': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-common': 7.2.1 + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/node-logger': 7.2.1 + '@storybook/preview-api': 7.2.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ts-dedent: 2.2.0 transitivePeerDependencies: - - '@storybook/mdx1-csf' + - '@types/react' + - '@types/react-dom' + - debug + - encoding - supports-color dev: true - /@storybook/addon-highlight@7.0.0-rc.5: - resolution: {integrity: sha512-Dx4xObuDMQHJ/Et83HuzXI1g4LDJmw36Zgke09wdNta7CbvJG3eyDyiA+JrHRs+4eXYi1IWDhztpM5uQ/Chtaw==} + /@storybook/addon-highlight@7.2.1: + resolution: {integrity: sha512-6nNqpSMImn1mSGmEKF1o+C6o4lWJjduGYnCIO/ouXExaNLMrdcGKUEWrluABLOeDRPcNC9/EkuIEd8IsDnUX4A==} dependencies: - '@storybook/core-events': 7.0.0-rc.5 + '@storybook/core-events': 7.2.1 '@storybook/global': 5.0.0 - '@storybook/preview-api': 7.0.0-rc.5 + '@storybook/preview-api': 7.2.1 dev: true - /@storybook/addon-interactions@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-OPAp+0LS+vtFcBvfrY+5/xFyXfihLCWJauFmMI02g0tsHObB4Ua6juAnOYSwNSKdea0uW5GGTkVRxS7zEgqr3Q==} + /@storybook/addon-interactions@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-EuQMvigfEfQedNBojZhVs8x2mG8tL2n2yhtuYUsmHCmwAITcVxgPRV0xCgv676B8uRQvUru+cm9/nBIf2rUg/A==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4613,27 +5626,31 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/components': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-common': 7.0.0-rc.5 - '@storybook/core-events': 7.0.0-rc.5 + '@storybook/client-logger': 7.2.1 + '@storybook/components': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-common': 7.2.1 + '@storybook/core-events': 7.2.1 '@storybook/global': 5.0.0 - '@storybook/instrumenter': 7.0.0-rc.5 - '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.0-rc.5 - '@storybook/theming': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.0-rc.5 + '@storybook/instrumenter': 7.2.1 + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.2.1 + '@storybook/theming': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.2.1 jest-mock: 27.5.1 polished: 4.2.2 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ts-dedent: 2.2.0 transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - debug + - encoding - supports-color dev: true - /@storybook/addon-links@7.0.22(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-3kXBXAgPWIcy+bIFOxt6ZzFaO8bM4aTjtqN7Wdk3QtRY5Yrfpmfx/zmDByvmLZwj50HvvWq05rb/vE2ahtlm2A==} + /@storybook/addon-links@7.2.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3UQfOZ1+wGlPsHWWjXjPskq6nsDXuB+8QvOcpqy51mK+5Zv/EQe386hWj9VUpjLNMxXarWETa5CXGfoQdFzJTA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4643,22 +5660,22 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.0.22 - '@storybook/core-events': 7.0.22 + '@storybook/client-logger': 7.2.1 + '@storybook/core-events': 7.2.1 '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.0.22(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.22 - '@storybook/router': 7.0.22(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.22 + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.2.1 + '@storybook/router': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.2.1 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ts-dedent: 2.2.0 dev: true - /@storybook/addon-measure@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-m9CCcMpSrV7psZ9z6FaekdY0m7XNh+XRpiLLWn/TwQONHrUb0UBQGKloITNKE4QxCSDKpqCOUl/yJTxkCRCsrg==} + /@storybook/addon-measure@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3Rq/B3Iurbo5dZvUN735GHK+9EDm0xw+liK0PdeYvl21/RkXTV+a4aBcWyyeWwwu1S7pdK1B/0WEc9d5Lot8sA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4668,19 +5685,25 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/components': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.0.0-rc.5 + '@storybook/client-logger': 7.2.1 + '@storybook/components': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.2.1 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.0-rc.5 - '@storybook/types': 7.0.0-rc.5 + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.2.1 + '@storybook/types': 7.2.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + tiny-invariant: 1.3.1 + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - debug + - supports-color dev: true - /@storybook/addon-outline@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-CkwW6b9gzIqQFw68cdAYbaY15DzLhBSpCRsccl/Mnm83xxm2MeC3Z5yxvi+3fGyuV6iyJxDsyxn4y4MD/Zho9w==} + /@storybook/addon-outline@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-v2dYDhfSzV8Nsi1pmjcLEOHGJLlUnpnSXlQymb338YJEFKP2G5ylHzKAHG16MmzKeZZd3rthTB0246SFCyf0hg==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4690,19 +5713,24 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/components': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.0.0-rc.5 + '@storybook/client-logger': 7.2.1 + '@storybook/components': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.2.1 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.0-rc.5 - '@storybook/types': 7.0.0-rc.5 + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.2.1 + '@storybook/types': 7.2.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - debug + - supports-color dev: true - /@storybook/addon-styling@0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.0.22)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.2.2): + /@storybook/addon-styling@0.3.2(@storybook/addons@6.5.16)(@storybook/api@6.5.16)(@storybook/components@6.5.16)(@storybook/core-events@6.5.16)(@storybook/manager-api@7.2.1)(@storybook/theming@6.5.16)(react-dom@18.2.0)(react@18.2.0)(sass-loader@13.3.2): resolution: {integrity: sha512-ztKy9uU2yKBtvBp4/Km4LD1JCNNFHpXS33LjbeIfho0toRv100g8tUojrdnoRX1b2KVK6cqep5mJV0z2ak9hIQ==} peerDependencies: '@storybook/addons': ^6.5.8 @@ -4729,59 +5757,68 @@ packages: '@storybook/api': 6.5.16(react-dom@18.2.0)(react@18.2.0) '@storybook/components': 6.5.16(react-dom@18.2.0)(react@18.2.0) '@storybook/core-events': 6.5.16 - '@storybook/manager-api': 7.0.22(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) '@storybook/theming': 6.5.16(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - sass-loader: 13.2.2(sass@1.59.3)(webpack@5.77.0) + sass-loader: 13.3.2(sass@1.59.3)(webpack@5.77.0) dev: true - /@storybook/addon-styling@1.3.0(less@4.1.3)(postcss@8.4.21)(react-dom@18.2.0)(react@18.2.0)(sass@1.59.3)(webpack@5.77.0): - resolution: {integrity: sha512-+Ak9+SysMepRdXGlqDBlhR4cOSDCFEIfGuOW7nyA5eOgHi0IyTg9M+yfBgHVru7dEh+rq47XTVr44UhsWd4xgA==} + /@storybook/addon-styling@1.3.5(less@4.1.3)(postcss@8.4.27)(react-dom@18.2.0)(react@18.2.0)(sass@1.64.2)(webpack@5.77.0): + resolution: {integrity: sha512-W0oejixqUEd2yhy3ZAu9urKJZNCLrRFwpz7JD7OgN9HiUefLw3Rn2NHeP7v4Q1oznIxpYcsgYFzv10zX21Mq5w==} + hasBin: true peerDependencies: + less: ^3.5.0 || ^4.0.0 + postcss: ^7.0.0 || ^8.0.1 react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + webpack: ^5.0.0 peerDependenciesMeta: + less: + optional: true + postcss: + optional: true react: optional: true react-dom: optional: true + webpack: + optional: true dependencies: - '@babel/template': 7.20.7 + '@babel/template': 7.22.5 '@babel/types': 7.22.5 '@storybook/api': 7.0.22(react-dom@18.2.0)(react@18.2.0) '@storybook/components': 7.0.22(react-dom@18.2.0)(react@18.2.0) '@storybook/core-common': 7.0.22 '@storybook/core-events': 7.0.22 - '@storybook/csf-tools': 7.0.22 '@storybook/manager-api': 7.0.22(react-dom@18.2.0)(react@18.2.0) '@storybook/node-logger': 7.0.22 '@storybook/preview-api': 7.0.22 '@storybook/theming': 7.0.22(react-dom@18.2.0)(react@18.2.0) '@storybook/types': 7.0.22 css-loader: 6.7.3(webpack@5.77.0) + less: 4.1.3 less-loader: 11.1.0(less@4.1.3)(webpack@5.77.0) - postcss-loader: 7.3.0(postcss@8.4.21)(webpack@5.77.0) + postcss: 8.4.27 + postcss-loader: 7.3.0(postcss@8.4.27)(webpack@5.77.0) + prettier: 2.8.8 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - recast: 0.23.2 resolve-url-loader: 5.0.0 - sass-loader: 13.2.2(sass@1.59.3)(webpack@5.77.0) + sass-loader: 13.3.2(sass@1.64.2)(webpack@5.77.0) style-loader: 3.3.2(webpack@5.77.0) + webpack: 5.77.0(esbuild@0.18.17) transitivePeerDependencies: - encoding - fibers - - less - node-sass - - postcss - sass - sass-embedded - supports-color - - webpack dev: true - /@storybook/addon-toolbars@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-GErLxEBVh3HaQEvUNmKlNDcNuEYpGNVT1Nr1Tsc4J8EKG1ivEfQfVu6/5fduPZE8Vt1IUAzrVEp9NYzSELH49Q==} + /@storybook/addon-toolbars@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-SEDj9f0EgifPK/Eyh703N1tbk7SZ7yAZOnNUK8T0mwdKrMa7jskvYuift8iSnJA2ldp1siqwe1Obq+Oielp9hQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4791,17 +5828,22 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/components': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.0-rc.5 - '@storybook/theming': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 7.2.1 + '@storybook/components': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.2.1 + '@storybook/theming': 7.2.1(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - debug + - supports-color dev: true - /@storybook/addon-viewport@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-EzjGyi0s6VvwZvCuN6E8zgc6RcIOUz85G1Zt5U59as4GwhvezwiJdM9IjtX0/I17hdKS7vL36Gli67PJZKb/Bw==} + /@storybook/addon-viewport@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-aHl3rCh4MNByfWVtjBzkwMtz0iHQHFhatWXVt7mQoTQFBbZHpeynKvLfKBprp+2whK9RoDHqBUjqGTZrECdpRA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4811,17 +5853,22 @@ packages: react-dom: optional: true dependencies: - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/components': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.0.0-rc.5 + '@storybook/client-logger': 7.2.1 + '@storybook/components': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.2.1 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.0-rc.5 - '@storybook/theming': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.2.1 + '@storybook/theming': 7.2.1(react-dom@18.2.0)(react@18.2.0) memoizerific: 1.11.3 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - debug + - supports-color dev: true /@storybook/addons@6.5.16(react-dom@18.2.0)(react@18.2.0): @@ -4889,57 +5936,23 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/blocks@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-9ZGDExwA6DgR/BsFSk2aCe7p/AIIQAiCemV1W1Djp7lt6OOALWfLZ7r1sFUqY9ZgNkfD1N41JpmqJtPDLXejGQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - dependencies: - '@storybook/channels': 7.0.0-rc.5 - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/components': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.0.0-rc.5 - '@storybook/csf': 0.1.1-next.0 - '@storybook/docs-tools': 7.0.0-rc.5 - '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.0-rc.5 - '@storybook/theming': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.0-rc.5 - '@types/lodash': 4.14.191 - color-convert: 2.0.1 - dequal: 2.0.3 - lodash: 4.17.21 - markdown-to-jsx: 7.2.0(react@18.2.0) - memoizerific: 1.11.3 - polished: 4.2.2 - react: 18.2.0 - react-colorful: 5.6.1(react-dom@18.2.0)(react@18.2.0) - react-dom: 18.2.0(react@18.2.0) - telejson: 7.0.4 - ts-dedent: 2.2.0 - util-deprecate: 1.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@storybook/blocks@7.0.22(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-bVOouc2LCkfaQpymPX+PzVSGwlu7Nj52jnqZFBK84aRcX8JDhJdnZ4KCxyEfraBQRuywH36GIMrlhnZCf0w54A==} + /@storybook/blocks@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-1fPsFC6n9R267KwxGHiL80OuIdMDRC9QuIW4sRF0tF/G/yvucbofySYRQl/Y8LjsMJq8D4NpG5xLsneSxMP5cg==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/channels': 7.0.22 - '@storybook/client-logger': 7.0.22 - '@storybook/components': 7.0.22(react-dom@18.2.0)(react@18.2.0) - '@storybook/core-events': 7.0.22 + '@storybook/channels': 7.2.1 + '@storybook/client-logger': 7.2.1 + '@storybook/components': 7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.2.1 '@storybook/csf': 0.1.0 - '@storybook/docs-tools': 7.0.22 + '@storybook/docs-tools': 7.2.1 '@storybook/global': 5.0.0 - '@storybook/manager-api': 7.0.22(react-dom@18.2.0)(react@18.2.0) - '@storybook/preview-api': 7.0.22 - '@storybook/theming': 7.0.22(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.22 + '@storybook/manager-api': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.2.1 + '@storybook/theming': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.2.1 '@types/lodash': 4.14.191 color-convert: 2.0.1 dequal: 2.0.3 @@ -4951,26 +5964,30 @@ packages: react-colorful: 5.6.1(react-dom@18.2.0)(react@18.2.0) react-dom: 18.2.0(react@18.2.0) telejson: 7.0.4 + tocbot: 4.21.0 ts-dedent: 2.2.0 util-deprecate: 1.0.2 transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - debug - encoding - supports-color dev: true - /@storybook/builder-manager@7.0.22: - resolution: {integrity: sha512-90u1TP8Z53lbwMUm/JblPMmK8RJxRAWnJnAcVNuMmIxJjbW2EvQMGkNMhetk47kfiDyUJV0n90+wiMc+/DkxKQ==} + /@storybook/builder-manager@7.2.1: + resolution: {integrity: sha512-X8B1cUfDaTtsJY3xJNwPy6W4UN7LWXkKktJBoNUGESigQGKpAMvUAmABCZIjZD8GcdGMtU8y/fA7YimUpy/ZKQ==} dependencies: '@fal-works/esbuild-plugin-global-externals': 2.1.2 - '@storybook/core-common': 7.0.22 - '@storybook/manager': 7.0.22 - '@storybook/node-logger': 7.0.22 + '@storybook/core-common': 7.2.1 + '@storybook/manager': 7.2.1 + '@storybook/node-logger': 7.2.1 '@types/ejs': 3.1.2 '@types/find-cache-dir': 3.2.1 - '@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.17.12) + '@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.18.17) browser-assert: 1.2.1 ejs: 3.1.9 - esbuild: 0.17.12 + esbuild: 0.18.17 esbuild-plugin-alias: 0.2.1 express: 4.18.2 find-cache-dir: 3.3.2 @@ -4982,8 +5999,8 @@ packages: - supports-color dev: true - /@storybook/builder-vite@7.0.22(typescript@4.9.5)(vite@4.2.1): - resolution: {integrity: sha512-Il+JtE9TDHxPJ88BmkNBb0DAd1nNShM+tTy2scwDI2GlYQYFVSuo7V0ZqMxztKfS5Wm0mNAnFUvG50uVMwF1Iw==} + /@storybook/builder-vite@7.2.1(typescript@5.1.6)(vite@4.4.8): + resolution: {integrity: sha512-D/RNcH6WAxMAMmC3w9wwgDbYUJ9SjSwc6NPcxGrKk9o0SWDsKWWx4r6mM0W5FJ7Wh11Ca46LLnPC3cFfEg4YDQ==} peerDependencies: '@preact/preset-vite': '*' typescript: '>= 4.3.x' @@ -4997,28 +6014,27 @@ packages: vite-plugin-glimmerx: optional: true dependencies: - '@storybook/channel-postmessage': 7.0.22 - '@storybook/channel-websocket': 7.0.22 - '@storybook/client-logger': 7.0.22 - '@storybook/core-common': 7.0.22 - '@storybook/csf-plugin': 7.0.22 + '@storybook/channels': 7.2.1 + '@storybook/client-logger': 7.2.1 + '@storybook/core-common': 7.2.1 + '@storybook/csf-plugin': 7.2.1 '@storybook/mdx2-csf': 1.0.0 - '@storybook/node-logger': 7.0.22 - '@storybook/preview': 7.0.22 - '@storybook/preview-api': 7.0.22 - '@storybook/types': 7.0.22 + '@storybook/node-logger': 7.2.1 + '@storybook/preview': 7.2.1 + '@storybook/preview-api': 7.2.1 + '@storybook/types': 7.2.1 + '@types/find-cache-dir': 3.2.1 browser-assert: 1.2.1 es-module-lexer: 0.9.3 express: 4.18.2 + find-cache-dir: 3.3.2 fs-extra: 11.1.1 - glob: 8.1.0 - glob-promise: 6.0.2(glob@8.1.0) - magic-string: 0.27.0 + magic-string: 0.30.2 remark-external-links: 8.0.0 remark-slug: 6.1.0 rollup: 3.20.0 - typescript: 4.9.5 - vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3) + typescript: 5.1.6 + vite: 4.4.8(@types/node@20.4.6)(less@4.1.3)(sass@1.64.2) transitivePeerDependencies: - encoding - supports-color @@ -5046,26 +6062,6 @@ packages: telejson: 7.0.4 dev: true - /@storybook/channel-postmessage@7.0.7: - resolution: {integrity: sha512-XMtYfcaE0UoY/V7K1cTu9PcWETD4iyWb/Yswc4F9VrPw0Ui4UwGS1j4iaAu8DC06yyoJs4XvxYFBMlCQmKja6A==} - dependencies: - '@storybook/channels': 7.0.7 - '@storybook/client-logger': 7.0.7 - '@storybook/core-events': 7.0.7 - '@storybook/global': 5.0.0 - qs: 6.11.1 - telejson: 7.0.4 - dev: true - - /@storybook/channel-websocket@7.0.22: - resolution: {integrity: sha512-oxmUTWrwxzxBALuZhX84fgzc70oyjw2PC4s1OFT2mdm+wHfk72wKPBJxGnwPGFx+CSmDU4u6s+HUtkQYB6WYdw==} - dependencies: - '@storybook/channels': 7.0.22 - '@storybook/client-logger': 7.0.22 - '@storybook/global': 5.0.0 - telejson: 7.0.4 - dev: true - /@storybook/channels@6.5.16: resolution: {integrity: sha512-VylzaWQZaMozEwZPJdyJoz+0jpDa8GRyaqu9TGG6QGv+KU5POoZaGLDkRE7TzWkyyP0KQLo80K99MssZCpgSeg==} dependencies: @@ -5082,25 +6078,35 @@ packages: resolution: {integrity: sha512-8mR30xBotnhc24GQpBp14bflvagkOnBXUhCTyiljULvkyo/bK0NE8IeSSto1FAIzPl6+s5/A0sePvLNRuj3gqw==} dev: true - /@storybook/channels@7.0.7: - resolution: {integrity: sha512-Om4ovBLNw8pVrBu83MpOKgAuGO9Dpr1Coh2qp8t64WRPkejX1mxOY9IgH723//zH3igx8LCkf9rvBvcrsyaScQ==} + /@storybook/channels@7.2.1: + resolution: {integrity: sha512-3ZogzjwlFG+oarwnI7TTvWvHVOUtJbjrgZkM5QuLMlxNzIR1XuBY8f01yf4K8+VpdNy9DY+7Q/j6tBThfwYvpA==} + dependencies: + '@storybook/client-logger': 7.2.1 + '@storybook/core-events': 7.2.1 + '@storybook/global': 5.0.0 + qs: 6.11.1 + telejson: 7.0.4 + tiny-invariant: 1.3.1 dev: true - /@storybook/cli@7.0.22: - resolution: {integrity: sha512-tSThszrZjI4vffYn8qGImoyM6jtKYlftlJfmh/U55jA+0uMENKIN/3iQhiFhc2UgwSYLeg1dCd/RHNAwiK6Xaw==} + /@storybook/cli@7.2.1: + resolution: {integrity: sha512-rPZDUvM0FRHZU4Wcm0ASOr/0xZq/6uySulqpLgoSkeZIC0xLXh/bI6YoDrD9UJV6GIRiqHMWMdxWd1e+TH8XHg==} hasBin: true dependencies: - '@babel/core': 7.21.3 - '@babel/preset-env': 7.21.4(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/preset-env': 7.22.9(@babel/core@7.22.9) + '@babel/types': 7.22.5 '@ndelangen/get-tarball': 3.0.7 - '@storybook/codemod': 7.0.22 - '@storybook/core-common': 7.0.22 - '@storybook/core-server': 7.0.22 - '@storybook/csf-tools': 7.0.22 - '@storybook/node-logger': 7.0.22 - '@storybook/telemetry': 7.0.22 - '@storybook/types': 7.0.22 + '@storybook/codemod': 7.2.1 + '@storybook/core-common': 7.2.1 + '@storybook/core-server': 7.2.1 + '@storybook/csf-tools': 7.2.1 + '@storybook/node-logger': 7.2.1 + '@storybook/telemetry': 7.2.1 + '@storybook/types': 7.2.1 '@types/semver': 7.3.13 + '@yarnpkg/fslib': 2.10.3 + '@yarnpkg/libzip': 2.3.0 chalk: 4.1.2 commander: 6.2.1 cross-spawn: 7.0.3 @@ -5114,7 +6120,7 @@ packages: get-port: 5.1.1 giget: 1.1.2 globby: 11.1.0 - jscodeshift: 0.14.0(@babel/preset-env@7.21.4) + jscodeshift: 0.14.0(@babel/preset-env@7.22.9) leven: 3.1.0 ora: 5.4.1 prettier: 2.8.8 @@ -5122,8 +6128,7 @@ packages: puppeteer-core: 2.1.1 read-pkg-up: 7.0.1 semver: 7.3.8 - shelljs: 0.8.5 - simple-update-notifier: 1.1.0 + simple-update-notifier: 2.0.0 strip-json-comments: 3.1.1 tempy: 1.0.1 ts-dedent: 2.2.0 @@ -5154,25 +6159,26 @@ packages: '@storybook/global': 5.0.0 dev: true - /@storybook/client-logger@7.0.7: - resolution: {integrity: sha512-EclHjDs5HwHMKB4X2orn/KKA0DTIDmp4AXAUJGRfxb5ArpKEb7tXLHsgrRBlaoz1j5LAwKTmEyZOONh9G3etjg==} + /@storybook/client-logger@7.2.1: + resolution: {integrity: sha512-Lyht/lJg2S65CXRy9rXAZXP/Mgye7jbi/aqQL8z9VRMGChbL+k/3pSZnXTTrD1OVSpCEr4UWA+9bStzT4VjtYA==} dependencies: '@storybook/global': 5.0.0 dev: true - /@storybook/codemod@7.0.22: - resolution: {integrity: sha512-6saK3OtxSCtJEK2qwSBbzRne7VonpbPB4/PABNy431Ia8CHyk9wE2UbyK3g7WNpakkt06Y9yUpV3BGLD8FLa5g==} + /@storybook/codemod@7.2.1: + resolution: {integrity: sha512-R19fdPfslupxfbtyuGcRa2m1nCug2Zm8bS0GhnPtUl7eGBA4glcf4KKwP52pEqgJAsarfiL2cLSnN5wqQGQ/Sw==} dependencies: - '@babel/core': 7.21.3 - '@babel/preset-env': 7.21.4(@babel/core@7.21.3) - '@babel/types': 7.21.4 + '@babel/core': 7.22.9 + '@babel/preset-env': 7.22.9(@babel/core@7.22.9) + '@babel/types': 7.22.5 '@storybook/csf': 0.1.0 - '@storybook/csf-tools': 7.0.22 - '@storybook/node-logger': 7.0.22 - '@storybook/types': 7.0.22 + '@storybook/csf-tools': 7.2.1 + '@storybook/node-logger': 7.2.1 + '@storybook/types': 7.2.1 + '@types/cross-spawn': 6.0.2 cross-spawn: 7.0.3 globby: 11.1.0 - jscodeshift: 0.14.0(@babel/preset-env@7.21.4) + jscodeshift: 0.14.0(@babel/preset-env@7.22.9) lodash: 4.17.21 prettier: 2.8.8 recast: 0.23.2 @@ -5198,17 +6204,17 @@ packages: util-deprecate: 1.0.2 dev: true - /@storybook/components@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-zuKQ0+uOtRbmnF0trJ4LpWZ5w9Dzcs5dZjF3Uu4ka4F4vJ/fUWKL2spxAIsRalu2jyk2XVp6/mz/NiWQnrophw==} + /@storybook/components@7.0.22(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-4cPepDONPY5b7A52atQs2JD3gZ+DYCABWKL9VmNEJtKDVoMs/IKKstnnUQ5QbOGsEIttdheawmyZoa6IWUsoQg==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/csf': 0.1.1-next.0 + '@storybook/client-logger': 7.0.22 + '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/theming': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.0-rc.5 + '@storybook/theming': 7.0.22(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.22 memoizerific: 1.11.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -5216,22 +6222,29 @@ packages: util-deprecate: 1.0.2 dev: true - /@storybook/components@7.0.22(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-4cPepDONPY5b7A52atQs2JD3gZ+DYCABWKL9VmNEJtKDVoMs/IKKstnnUQ5QbOGsEIttdheawmyZoa6IWUsoQg==} + /@storybook/components@7.2.1(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-7JuMT2yK9FGPu9hFCo38tC3FDyr/hJ3CQwU6dSR6E5rT9E658dq31Xl3y/fM5OMzl8MX8Off7TWiybHSuwYJTA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/client-logger': 7.0.22 + '@radix-ui/react-select': 1.2.2(@types/react-dom@18.2.7)(@types/react@18.2.18)(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 7.2.1 '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/theming': 7.0.22(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.22 + '@storybook/icons': 1.1.2(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.2.1 memoizerific: 1.11.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) use-resize-observer: 9.1.0(react-dom@18.2.0)(react@18.2.0) util-deprecate: 1.0.2 + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + - debug + - supports-color dev: true /@storybook/core-client@7.0.0-rc.5: @@ -5248,6 +6261,13 @@ packages: '@storybook/preview-api': 7.0.22 dev: true + /@storybook/core-client@7.2.1: + resolution: {integrity: sha512-ujJdkaY6LXGCA8pqFBYTNMySmawm3GPcORYevkmM2edSbNKlu904+HvheRirajluzV7ropzGxUBZR9TMwgmDGg==} + dependencies: + '@storybook/client-logger': 7.2.1 + '@storybook/preview-api': 7.2.1 + dev: true + /@storybook/core-common@7.0.0-rc.5: resolution: {integrity: sha512-YlkcTcDx8bkOq3/STAuBkQOBQB5i0zLj2Zb0LUPzIDDBPZlGb3mJEla0UyJoMbP/E/QCq1K8pA1l9vtTK+ROJQ==} dependencies: @@ -5258,7 +6278,7 @@ packages: chalk: 4.1.2 esbuild: 0.16.17 esbuild-register: 3.4.2(esbuild@0.16.17) - file-system-cache: 2.0.2 + file-system-cache: 2.3.0 find-up: 5.0.0 fs-extra: 11.1.1 glob: 8.1.0 @@ -5286,7 +6306,7 @@ packages: chalk: 4.1.2 esbuild: 0.17.12 esbuild-register: 3.4.2(esbuild@0.17.12) - file-system-cache: 2.0.2 + file-system-cache: 2.3.0 find-up: 5.0.0 fs-extra: 11.1.1 glob: 8.1.0 @@ -5304,6 +6324,36 @@ packages: - supports-color dev: true + /@storybook/core-common@7.2.1: + resolution: {integrity: sha512-g1MQ04lgL16Ct89tPj6RSw72yd+a+ZJ4ceH3Ev+SmnU8efBLPmr6+G5Bx7+rY1W2c6NdpFgtSidjgOGqQ8gppw==} + dependencies: + '@storybook/node-logger': 7.2.1 + '@storybook/types': 7.2.1 + '@types/find-cache-dir': 3.2.1 + '@types/node': 16.18.16 + '@types/node-fetch': 2.6.4 + '@types/pretty-hrtime': 1.0.1 + chalk: 4.1.2 + esbuild: 0.18.17 + esbuild-register: 3.4.2(esbuild@0.18.17) + file-system-cache: 2.3.0 + find-cache-dir: 3.3.2 + find-up: 5.0.0 + fs-extra: 11.1.1 + glob: 10.3.3 + handlebars: 4.7.7 + lazy-universal-dotenv: 4.0.0 + node-fetch: 2.6.9 + picomatch: 2.3.1 + pkg-dir: 5.0.0 + pretty-hrtime: 1.0.3 + resolve-from: 5.0.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + /@storybook/core-events@6.5.16: resolution: {integrity: sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g==} dependencies: @@ -5318,33 +6368,33 @@ packages: resolution: {integrity: sha512-T7xiJTlNKrNxRCvJj/5RRukhFFJZqfmfF3DNi+P6YsLBE569GZ6y1eO58IalVzts4lB+LGYLAxkaWssNcZJ6Kg==} dev: true - /@storybook/core-events@7.0.7: - resolution: {integrity: sha512-XNsR2RgaL2vBwuqsu+KA1DzGmB1UFfrAhpxhmyWTKDCniwtTLlaXgfKbqwcrOrPu/o1YswgIup/9UHepRHaf4A==} + /@storybook/core-events@7.2.1: + resolution: {integrity: sha512-EUXYb3gyQ2EzpDAWkgfoDl1EPabj3OE6+zntsD/gwvzQU85BTocs10ksnRyS55bfrQpYbf+Z+gw2CZboyagLgg==} dev: true - /@storybook/core-server@7.0.22: - resolution: {integrity: sha512-RgMKAFtJ4rVUV8fBf1eWFtLliNW1x7T4nf9DzNCkeMkhWSi6hxGGB6WCRzNUIs0oibqul5FxWRGlvc3vJC39qw==} + /@storybook/core-server@7.2.1: + resolution: {integrity: sha512-jhS918Frl5j6LSB3x7qzHHuRL5e3RXqCkBQe5KtR2zXMgYlalSyGcX5uT8byWFznUsQIjGmUrf6ZIoKdRdslWg==} dependencies: - '@aw-web-design/x-default-browser': 1.4.88 + '@aw-web-design/x-default-browser': 1.4.126 '@discoveryjs/json-ext': 0.5.7 - '@storybook/builder-manager': 7.0.22 - '@storybook/core-common': 7.0.22 - '@storybook/core-events': 7.0.22 + '@storybook/builder-manager': 7.2.1 + '@storybook/channels': 7.2.1 + '@storybook/core-common': 7.2.1 + '@storybook/core-events': 7.2.1 '@storybook/csf': 0.1.0 - '@storybook/csf-tools': 7.0.22 + '@storybook/csf-tools': 7.2.1 '@storybook/docs-mdx': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/manager': 7.0.22 - '@storybook/node-logger': 7.0.22 - '@storybook/preview-api': 7.0.22 - '@storybook/telemetry': 7.0.22 - '@storybook/types': 7.0.22 + '@storybook/manager': 7.2.1 + '@storybook/node-logger': 7.2.1 + '@storybook/preview-api': 7.2.1 + '@storybook/telemetry': 7.2.1 + '@storybook/types': 7.2.1 '@types/detect-port': 1.3.2 '@types/node': 16.18.16 - '@types/node-fetch': 2.6.4 '@types/pretty-hrtime': 1.0.1 '@types/semver': 7.3.13 - better-opn: 2.1.1 + better-opn: 3.0.2 chalk: 4.1.2 cli-table3: 0.6.3 compression: 1.7.4 @@ -5354,7 +6404,6 @@ packages: globby: 11.1.0 ip: 2.0.0 lodash: 4.17.21 - node-fetch: 2.6.9 open: 8.4.2 pretty-hrtime: 1.0.3 prompts: 2.4.2 @@ -5362,7 +6411,9 @@ packages: semver: 7.3.8 serve-favicon: 2.5.0 telejson: 7.0.4 + tiny-invariant: 1.3.1 ts-dedent: 2.2.0 + util: 0.12.5 util-deprecate: 1.0.2 watchpack: 2.4.0 ws: 8.13.0 @@ -5373,50 +6424,26 @@ packages: - utf-8-validate dev: true - /@storybook/csf-plugin@7.0.0-rc.5: - resolution: {integrity: sha512-sgIEqV1MfhybvODcjtG0Ce/XlzWv2Sg5Prg5Qqsr5sMU7aET+yLHmr1umbM5L8ieRjsXS4CsxZCqZMrY9hDdNw==} - dependencies: - '@storybook/csf-tools': 7.0.0-rc.5 - unplugin: 0.10.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@storybook/csf-plugin@7.0.22: - resolution: {integrity: sha512-1AipSDkb2qEPXnXeU335nqKm1+po1T2J5MqA8eV7q62y3HOziRZuLKrR2k9XvVrwfzMn+fy/CLE7LVQurOSDBQ==} - dependencies: - '@storybook/csf-tools': 7.0.22 - unplugin: 0.10.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@storybook/csf-tools@7.0.0-rc.5: - resolution: {integrity: sha512-DvcAygIZMZIL30j7WxMXeJ6a+A2/Y/FuatZItmW+3sNv0FK1J9wH2SKw7QjzEw75LsgjvO07lU2cgcsPDFhXoA==} - dependencies: - '@babel/generator': 7.21.3 - '@babel/parser': 7.21.3 - '@babel/traverse': 7.21.3(supports-color@5.5.0) - '@babel/types': 7.21.4 - '@storybook/csf': 0.1.1-next.0 - '@storybook/types': 7.0.0-rc.5 - fs-extra: 11.1.1 - recast: 0.23.2 - ts-dedent: 2.2.0 + /@storybook/csf-plugin@7.2.1: + resolution: {integrity: sha512-qhxkKOsUjCS/hqsDgwgoM81ZXAXfTNrJJPHCs4Wa1dHoUVUn7rro7VANIO0GVNrRDnha3YR4fEmnD8kklLKmCQ==} + dependencies: + '@storybook/csf-tools': 7.2.1 + unplugin: 1.4.0 transitivePeerDependencies: - supports-color dev: true - /@storybook/csf-tools@7.0.22: - resolution: {integrity: sha512-rRlacX+h5HMXhizlDJy6+ILDZblxLo9uZR1CktlC+FOmbEWlB8WIK036I/t6H64AO0doahqaVwwVExULuHf0SA==} + /@storybook/csf-tools@7.2.1: + resolution: {integrity: sha512-QqZOBd6lmhPoIBLutyYYJ3wBwEZF+fUjiL8vhw3lgq+Mrer14lmKrImKDSjd1PsqVbbGQEJZ4TAJHZc3vdQs0w==} dependencies: - '@babel/generator': 7.21.3 - '@babel/parser': 7.21.3 - '@babel/traverse': 7.21.3(supports-color@5.5.0) - '@babel/types': 7.21.4 + '@babel/generator': 7.22.9 + '@babel/parser': 7.22.7 + '@babel/traverse': 7.22.8 + '@babel/types': 7.22.5 '@storybook/csf': 0.1.0 - '@storybook/types': 7.0.22 + '@storybook/types': 7.2.1 fs-extra: 11.1.1 + prettier: 2.8.8 recast: 0.23.2 ts-dedent: 2.2.0 transitivePeerDependencies: @@ -5474,44 +6501,70 @@ packages: - supports-color dev: true + /@storybook/docs-tools@7.2.1: + resolution: {integrity: sha512-snRdkqdaxAwlalIEtuElySzC68Lo/0KfrGRR6xSDxWIhjAPNqsRLPHEXlZrJ43Tn/V2oxCRU8eb21pP5/58krw==} + dependencies: + '@storybook/core-common': 7.2.1 + '@storybook/preview-api': 7.2.1 + '@storybook/types': 7.2.1 + '@types/doctrine': 0.0.3 + doctrine: 3.0.0 + lodash: 4.17.21 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + /@storybook/global@5.0.0: resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} dev: true - /@storybook/instrumenter@7.0.0-rc.5: - resolution: {integrity: sha512-e9AtV1hNTs4ppmqKfst/cInmRnhkK9VcGf3xB/d9Qqm0Sqo+sNXu6ywK5KpAURdCzsUEOPXbJ9H52yTrU4f74A==} + /@storybook/icons@1.1.2(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-rqbaVL2GoelYJzXWvZfAf8GAQw/IXEHM7baac1AzzsiabZv4ANlFImsWmT12GH8Q7v/B/4FJe0F2FQBd/1IX3w==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=17' + react-dom: '>=17' dependencies: - '@storybook/channels': 7.0.0-rc.5 - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/core-events': 7.0.0-rc.5 - '@storybook/global': 5.0.0 - '@storybook/preview-api': 7.0.0-rc.5 + '@svgr/core': 5.5.0 + '@svgr/plugin-prettier': 5.5.0 + '@svgr/plugin-svgo': 5.5.0 + axios: 1.4.0 + chalk: 4.1.2 + dotenv: 16.3.1 + figma-api-exporter: 0.0.2 + fs-extra: 11.1.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - debug + - supports-color dev: true - /@storybook/instrumenter@7.0.7: - resolution: {integrity: sha512-0zE5lM3laKvCT4GW/XKKw8kakvI4catqK8PObZolRhfxbtGufW4VJZ2E8vXLtgA/+K3zikypjuWE6d45NLbh9w==} + /@storybook/instrumenter@7.2.1: + resolution: {integrity: sha512-eA1xke6JWhqDNhrn/qK3KxeE9yXySyzK1gUhu1jtIt8npenebZsuG5Uu/IzJkSB8se1F419Pmbcpeq0V8GA1lQ==} dependencies: - '@storybook/channels': 7.0.7 - '@storybook/client-logger': 7.0.7 - '@storybook/core-events': 7.0.7 + '@storybook/channels': 7.2.1 + '@storybook/client-logger': 7.2.1 + '@storybook/core-events': 7.2.1 '@storybook/global': 5.0.0 - '@storybook/preview-api': 7.0.7 + '@storybook/preview-api': 7.2.1 dev: true - /@storybook/manager-api@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-MsNj/cPIOlL7HJ8ReYahUvJVfvZDtNfacUYSFuQjQwdnp0u3pbC5mGZPd32tAGj7lLaLzcqqo1yR+NAgwpZUBw==} + /@storybook/manager-api@7.0.22(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-7tvHZrrxp70zB4PyU+sIcBvBVq/dkhHkCsmuthRPW+OkZoolcXVU2xIbR62shOeaAobLbcJrlx5V2IFrLboZnA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/channels': 7.0.0-rc.5 - '@storybook/client-logger': 7.0.0-rc.5 - '@storybook/core-events': 7.0.0-rc.5 - '@storybook/csf': 0.1.1-next.0 + '@storybook/channels': 7.0.22 + '@storybook/client-logger': 7.0.22 + '@storybook/core-events': 7.0.22 + '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/router': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/theming': 7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.0-rc.5 + '@storybook/router': 7.0.22(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.0.22(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.22 dequal: 2.0.3 lodash: 4.17.21 memoizerific: 1.11.3 @@ -5523,20 +6576,20 @@ packages: ts-dedent: 2.2.0 dev: true - /@storybook/manager-api@7.0.22(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-7tvHZrrxp70zB4PyU+sIcBvBVq/dkhHkCsmuthRPW+OkZoolcXVU2xIbR62shOeaAobLbcJrlx5V2IFrLboZnA==} + /@storybook/manager-api@7.2.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-jRuYTrsNKq+g1u9kbQRvBsRKVITOdiNu9c633MeCH73oBVo8WNnZF/tW/ER86oTnru0H7EmRdgz3v9ft/wS2GQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/channels': 7.0.22 - '@storybook/client-logger': 7.0.22 - '@storybook/core-events': 7.0.22 + '@storybook/channels': 7.2.1 + '@storybook/client-logger': 7.2.1 + '@storybook/core-events': 7.2.1 '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/router': 7.0.22(react-dom@18.2.0)(react@18.2.0) - '@storybook/theming': 7.0.22(react-dom@18.2.0)(react@18.2.0) - '@storybook/types': 7.0.22 + '@storybook/router': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.2.1 dequal: 2.0.3 lodash: 4.17.21 memoizerific: 1.11.3 @@ -5548,18 +6601,14 @@ packages: ts-dedent: 2.2.0 dev: true - /@storybook/manager@7.0.22: - resolution: {integrity: sha512-5FXc5ordSWMVUcGNTWraCROJsA23gAUMraF2ns7KFnr15fMgJ9+/0UP/M7iYaZYZ5AcWwYO80efuogZyf5LrHQ==} + /@storybook/manager@7.2.1: + resolution: {integrity: sha512-wD2tRH8gLk2VNFMVcWmGZTXGTMNXdM3rnXiyKtmSVwFzacmOtLzEsCOprwI6WJpZv3v1vHY0s6idN9iadTVMhw==} dev: true /@storybook/mdx2-csf@1.0.0: resolution: {integrity: sha512-dBAnEL4HfxxJmv7LdEYUoZlQbWj9APZNIbOaq0tgF8XkxiIbzqvgB0jhL/9UOrysSDbQWBiCRTu2wOVxedGfmw==} dev: true - /@storybook/mdx2-csf@1.1.0-next.1: - resolution: {integrity: sha512-ONvFBZySHsBIkUYGrUM8FCG2tDKf663TIErztPSOghOpmBGyFLjSsXJHkNWiRi4c740PoemLqJd2XZZVlXRVLQ==} - dev: true - /@storybook/node-logger@7.0.0-rc.5: resolution: {integrity: sha512-3DpM988ndfbwc/03doFVP/HUJgoCp4eKVFMmSqnKVUd6qWx/dhsrTv+jqLt43wNZCgL/N/8QE+Q+FhVwefh6Tg==} dependencies: @@ -5578,11 +6627,15 @@ packages: pretty-hrtime: 1.0.3 dev: true - /@storybook/postinstall@7.0.0-rc.5: - resolution: {integrity: sha512-F23wxKEJ2XoVnHT7oAMjCXtANWvNq7M+FmIowgI98b3FT1dxt9fFPKKY+3Lcqp0Xa6Pzezd03KR9vAxXvvK/iQ==} + /@storybook/node-logger@7.2.1: + resolution: {integrity: sha512-Ywjqi8iAc26RYbZfmpzvzdKbaQZaD1T/IRNfVGReM/jTXnX0VSdsa6P/pfurbyHcQw//D3TSdqRHOMtbp0nIJg==} + dev: true + + /@storybook/postinstall@7.2.1: + resolution: {integrity: sha512-xOzX1MygQ+9xpku6FuODhXvfv/CcKlQPOGpZk8ejE/04Eow0JHluGI1cxdnpqGcCBygkw7DP+xrtQCv75c7Gjg==} dev: true - /@storybook/preset-scss@1.0.3(css-loader@6.7.3)(sass-loader@13.2.2)(style-loader@3.3.2): + /@storybook/preset-scss@1.0.3(css-loader@6.7.3)(sass-loader@13.3.2)(style-loader@3.3.2): resolution: {integrity: sha512-o9Iz6wxPeNENrQa2mKlsDKynBfqU2uWaRP80HeWp4TkGgf7/x3DVF2O7yi9N0x/PI1qzzTTpxlQ90D62XmpiTw==} peerDependencies: css-loader: '*' @@ -5590,7 +6643,7 @@ packages: style-loader: '*' dependencies: css-loader: 6.7.3(webpack@5.77.0) - sass-loader: 13.2.2(sass@1.59.3)(webpack@5.77.0) + sass-loader: 13.3.2(sass@1.59.3)(webpack@5.77.0) style-loader: 3.3.2(webpack@5.77.0) dev: true @@ -5635,16 +6688,15 @@ packages: util-deprecate: 1.0.2 dev: true - /@storybook/preview-api@7.0.7: - resolution: {integrity: sha512-R5pmGTodpu6hbwEg2RM2ulWtW3d426YzsisHrZJ+FT9lecWauN1y9xHCz7HdNzEFhT8r4YOa24L9ZS3mosZ7hA==} + /@storybook/preview-api@7.2.1: + resolution: {integrity: sha512-WKecuOdeh9+og6bPR9KoQf/JCeSRPCcfZv9uNfJzAp3IiTnS3UpfCz+HBZzZJQrisgbd7OulNY400HQUmxY2Ag==} dependencies: - '@storybook/channel-postmessage': 7.0.7 - '@storybook/channels': 7.0.7 - '@storybook/client-logger': 7.0.7 - '@storybook/core-events': 7.0.7 + '@storybook/channels': 7.2.1 + '@storybook/client-logger': 7.2.1 + '@storybook/core-events': 7.2.1 '@storybook/csf': 0.1.0 '@storybook/global': 5.0.0 - '@storybook/types': 7.0.7 + '@storybook/types': 7.2.1 '@types/qs': 6.9.7 dequal: 2.0.3 lodash: 4.17.21 @@ -5655,8 +6707,8 @@ packages: util-deprecate: 1.0.2 dev: true - /@storybook/preview@7.0.22: - resolution: {integrity: sha512-R33FM3t5UVkq++W3cLqnRNISnOc3CDpCd91wAzwCcnjZ9xCT1iGu/GvzD2NLWCmpdSRm8UHSB0x5xlxkF3pHBw==} + /@storybook/preview@7.2.1: + resolution: {integrity: sha512-5mLNhuaePx3Zv8mO93Y/M+U7ppqV5bS13rPfMHcVmSb7mQ/3hN7zkF6NhPOX6LoBUxetHiAJh5dA5McNE3adLQ==} dev: true /@storybook/react-dom-shim@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): @@ -5679,28 +6731,39 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/react-vite@7.0.22(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.2.1): - resolution: {integrity: sha512-qyfM4fng3UwSNVeERxFWHD6O9EXdCuds78aG5KON8fVHkfD1JKzdj6nAPI7nYaX0gn+7C20z7Y4GMtUdMAHHrw==} + /@storybook/react-dom-shim@7.2.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-QzQQN2nZkG7c0Mg5HvhfQuH10HjAJEnA8vDlENIFMj3XqtUAq4HE2n73gEcvdFJMXL4G16N58+TgR1e2cFdRKw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@storybook/react-vite@7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.1.6)(vite@4.4.8): + resolution: {integrity: sha512-sBMlrLf/zUDUk6bWQLu5/tERW82j9spGMD++O1mdum3eVfPwvsqjtGokTVx/eOLUYA9kqQFdUtjLSn0sS84bTQ==} engines: {node: '>=16'} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 vite: ^3.0.0 || ^4.0.0 dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.2.1(typescript@4.9.5)(vite@4.2.1) - '@rollup/pluginutils': 4.2.1 - '@storybook/builder-vite': 7.0.22(typescript@4.9.5)(vite@4.2.1) - '@storybook/react': 7.0.22(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5) - '@vitejs/plugin-react': 3.1.0(vite@4.2.1) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.2.1(typescript@5.1.6)(vite@4.4.8) + '@rollup/pluginutils': 5.0.2 + '@storybook/builder-vite': 7.2.1(typescript@5.1.6)(vite@4.4.8) + '@storybook/react': 7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.1.6) + '@vitejs/plugin-react': 3.1.0(vite@4.4.8) ast-types: 0.14.2 - magic-string: 0.27.0 + magic-string: 0.30.2 react: 18.2.0 react-docgen: 6.0.0-alpha.3 react-dom: 18.2.0(react@18.2.0) - vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3) + vite: 4.4.8(@types/node@20.4.6)(less@4.1.3)(sass@1.64.2) transitivePeerDependencies: - '@preact/preset-vite' - encoding + - rollup - supports-color - typescript - vite-plugin-glimmerx @@ -5785,6 +6848,46 @@ packages: - supports-color dev: true + /@storybook/react@7.2.1(react-dom@18.2.0)(react@18.2.0)(typescript@5.1.6): + resolution: {integrity: sha512-WRAVrSQKAtCoypUrrIXWGOvyGRVkrh73hSkKVC0gEqxWDmjZIZJ1uc3VrUd/yHJdLsqNphcAyU8Ahu52yozubg==} + engines: {node: '>=16.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@storybook/client-logger': 7.2.1 + '@storybook/core-client': 7.2.1 + '@storybook/docs-tools': 7.2.1 + '@storybook/global': 5.0.0 + '@storybook/preview-api': 7.2.1 + '@storybook/react-dom-shim': 7.2.1(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.2.1 + '@types/escodegen': 0.0.6 + '@types/estree': 0.0.51 + '@types/node': 16.18.16 + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + acorn-walk: 7.2.0 + escodegen: 2.0.0 + html-tags: 3.2.0 + lodash: 4.17.21 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-element-to-jsx-string: 15.0.0(react-dom@18.2.0)(react@18.2.0) + ts-dedent: 2.2.0 + type-fest: 2.19.0 + typescript: 5.1.6 + util-deprecate: 1.0.2 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + /@storybook/router@6.5.16(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ==} peerDependencies: @@ -5800,26 +6903,26 @@ packages: regenerator-runtime: 0.13.11 dev: true - /@storybook/router@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-s23O2OOQ4+CvySk3QC/PXhDJChc4jjyQu/h3gLMKF7bfWx0bd5KR4LnP3rCKLIMkxoJYFPUayPMgwEEeN/ENSw==} + /@storybook/router@7.0.22(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-yLKqpOm0zCF0EZcQn7aoV3EeDtg0DnhqBXLKXaiQpaPBV8AH6YJOQ3IiGY2CjeWhl2SIIH1glcQEDsF/6klD1g==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/client-logger': 7.0.0-rc.5 + '@storybook/client-logger': 7.0.22 memoizerific: 1.11.3 qs: 6.11.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/router@7.0.22(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-yLKqpOm0zCF0EZcQn7aoV3EeDtg0DnhqBXLKXaiQpaPBV8AH6YJOQ3IiGY2CjeWhl2SIIH1glcQEDsF/6klD1g==} + /@storybook/router@7.2.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-9Cn5boUS+7yhrKlSy1kt7ruNs/znk3555kclBD6+uuhH/dD84feGeiGYE4GUuLmcKrDFtNF185/Gr1huJ556tA==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - '@storybook/client-logger': 7.0.22 + '@storybook/client-logger': 7.2.1 memoizerific: 1.11.3 qs: 6.11.1 react: 18.2.0 @@ -5835,30 +6938,27 @@ packages: find-up: 4.1.0 dev: true - /@storybook/telemetry@7.0.22: - resolution: {integrity: sha512-629O0d3pEU8j7nwOqdBZhdRkV6KGN6FuaFOIRJdE+0rCQ78lBp6aqQZFDZ2wCwL9zqLcqY5WHbzCTh5OlccSwg==} + /@storybook/telemetry@7.2.1: + resolution: {integrity: sha512-ewYvX+ZzuTCl9a8DUbKkSPD6GhxUStl/+Eni1faE1OEnyduwbJFlse0EBpOa4YZTcghlngrHV3pulEW8qOgNFA==} dependencies: - '@storybook/client-logger': 7.0.22 - '@storybook/core-common': 7.0.22 + '@storybook/client-logger': 7.2.1 + '@storybook/core-common': 7.2.1 + '@storybook/csf-tools': 7.2.1 chalk: 4.1.2 detect-package-manager: 2.0.1 fetch-retry: 5.0.4 fs-extra: 11.1.1 - isomorphic-unfetch: 3.1.0 - nanoid: 3.3.4 read-pkg-up: 7.0.1 transitivePeerDependencies: - encoding - supports-color dev: true - /@storybook/testing-library@0.1.0: - resolution: {integrity: sha512-g947f4LJZw3IluBhysMKLJXByAFiSxnGuooENqU+ZPt/GTrz1I9GDBlhmoTJahuFkVbwHvziAl/8riY2Re921g==} + /@storybook/testing-library@0.2.0: + resolution: {integrity: sha512-Ff6jNnrsosmDshgCf0Eb5Cz7IA34p/1Ps5N3Kp3598kfXpBSccSkQQvVFUXC3kIHw/isIXWPqntZuKqnWUz7Gw==} dependencies: - '@storybook/client-logger': 7.0.7 - '@storybook/instrumenter': 7.0.7 - '@testing-library/dom': 8.20.0 - '@testing-library/user-event': 13.5.0(@testing-library/dom@8.20.0) + '@testing-library/dom': 9.0.1 + '@testing-library/user-event': 14.4.3(@testing-library/dom@9.0.1) ts-dedent: 2.2.0 dev: true @@ -5876,28 +6976,28 @@ packages: regenerator-runtime: 0.13.11 dev: true - /@storybook/theming@7.0.0-rc.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-OzwybDA2+4FWg85tcTNQkVI0JnHkwCRG9HM1qx9hOZJHNRfxmJFjJePOnBoXM6CjVlz0S1PJUwCmMHNH8OTvEw==} + /@storybook/theming@7.0.22(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-yNpjPW4NnJhrzTyYzqhzGK2bOB5AcW7V9NTdFmE5ZMgcoJLInHubWeCM2ODKE9/YzsKxo1gU8Io4qJ2IKZIoog==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: '@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0) - '@storybook/client-logger': 7.0.0-rc.5 + '@storybook/client-logger': 7.0.22 '@storybook/global': 5.0.0 memoizerific: 1.11.3 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: true - /@storybook/theming@7.0.22(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-yNpjPW4NnJhrzTyYzqhzGK2bOB5AcW7V9NTdFmE5ZMgcoJLInHubWeCM2ODKE9/YzsKxo1gU8Io4qJ2IKZIoog==} + /@storybook/theming@7.2.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-cfnNCLvKmzxjmoYKfLl7Q64gSTouLvd23CtvBAOlWcRYnMJ9v4/7A2tK3xQyVRlJYh9OuXiHFLL8AXbN58Hkzw==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: '@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0) - '@storybook/client-logger': 7.0.22 + '@storybook/client-logger': 7.2.1 '@storybook/global': 5.0.0 memoizerific: 1.11.3 react: 18.2.0 @@ -5907,28 +7007,254 @@ packages: /@storybook/types@7.0.0-rc.5: resolution: {integrity: sha512-gLKUY7EfPYenz0Y1jw90AUAUlKTHOj9p7J3d8GcI5x5buHdU+M7Q1jotPWzDwRFI24y3Ob31oyCBhysIw8S2Aw==} dependencies: - '@storybook/channels': 7.0.0-rc.5 - '@types/babel__core': 7.20.0 - '@types/express': 4.17.17 - file-system-cache: 2.0.2 + '@storybook/channels': 7.0.0-rc.5 + '@types/babel__core': 7.20.0 + '@types/express': 4.17.17 + file-system-cache: 2.3.0 + dev: true + + /@storybook/types@7.0.22: + resolution: {integrity: sha512-fzYD3fcgpQw3p0DLMQqlEvTw47qNwrPX8Wdv8pkS12RrM5ycmy6d6fVFVJOB9uWNXD1l34vWclEo6pbtEaBM9A==} + dependencies: + '@storybook/channels': 7.0.22 + '@types/babel__core': 7.20.0 + '@types/express': 4.17.17 + file-system-cache: 2.3.0 + dev: true + + /@storybook/types@7.2.1: + resolution: {integrity: sha512-YwlIY1uyxfJjijbB5x1d1QOKaUUDJnMX8BSb8oGqU4cyT76X/Is4CbGs+vccFsJo0tZu1GfuahYXl0EDT0nnSQ==} + dependencies: + '@storybook/channels': 7.2.1 + '@types/babel__core': 7.20.0 + '@types/express': 4.17.17 + file-system-cache: 2.3.0 + dev: true + + /@svgr/babel-plugin-add-jsx-attribute@5.4.0: + resolution: {integrity: sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==} + engines: {node: '>=10'} + dev: true + + /@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.21.3): + resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.3 + dev: true + + /@svgr/babel-plugin-remove-jsx-attribute@5.4.0: + resolution: {integrity: sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==} + engines: {node: '>=10'} + dev: true + + /@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.21.3): + resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.3 + dev: true + + /@svgr/babel-plugin-remove-jsx-empty-expression@5.0.1: + resolution: {integrity: sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==} + engines: {node: '>=10'} + dev: true + + /@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.21.3): + resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.3 + dev: true + + /@svgr/babel-plugin-replace-jsx-attribute-value@5.0.1: + resolution: {integrity: sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==} + engines: {node: '>=10'} + dev: true + + /@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.21.3): + resolution: {integrity: sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.3 + dev: true + + /@svgr/babel-plugin-svg-dynamic-title@5.4.0: + resolution: {integrity: sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==} + engines: {node: '>=10'} + dev: true + + /@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.21.3): + resolution: {integrity: sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.3 + dev: true + + /@svgr/babel-plugin-svg-em-dimensions@5.4.0: + resolution: {integrity: sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==} + engines: {node: '>=10'} + dev: true + + /@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.21.3): + resolution: {integrity: sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.3 + dev: true + + /@svgr/babel-plugin-transform-react-native-svg@5.4.0: + resolution: {integrity: sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==} + engines: {node: '>=10'} + dev: true + + /@svgr/babel-plugin-transform-react-native-svg@8.0.0(@babel/core@7.21.3): + resolution: {integrity: sha512-UKrY3860AQICgH7g+6h2zkoxeVEPLYwX/uAjmqo4PIq2FIHppwhIqZstIyTz0ZtlwreKR41O3W3BzsBBiJV2Aw==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.3 + dev: true + + /@svgr/babel-plugin-transform-svg-component@5.5.0: + resolution: {integrity: sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==} + engines: {node: '>=10'} + dev: true + + /@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.21.3): + resolution: {integrity: sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.3 + dev: true + + /@svgr/babel-preset@5.5.0: + resolution: {integrity: sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==} + engines: {node: '>=10'} + dependencies: + '@svgr/babel-plugin-add-jsx-attribute': 5.4.0 + '@svgr/babel-plugin-remove-jsx-attribute': 5.4.0 + '@svgr/babel-plugin-remove-jsx-empty-expression': 5.0.1 + '@svgr/babel-plugin-replace-jsx-attribute-value': 5.0.1 + '@svgr/babel-plugin-svg-dynamic-title': 5.4.0 + '@svgr/babel-plugin-svg-em-dimensions': 5.4.0 + '@svgr/babel-plugin-transform-react-native-svg': 5.4.0 + '@svgr/babel-plugin-transform-svg-component': 5.5.0 + dev: true + + /@svgr/babel-preset@8.0.0(@babel/core@7.21.3): + resolution: {integrity: sha512-KLcjiZychInVrhs86OvcYPLTFu9L5XV2vj0XAaE1HwE3J3jLmIzRY8ttdeAg/iFyp8nhavJpafpDZTt+1LIpkQ==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.3 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.21.3) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.21.3) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.21.3) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.21.3) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.21.3) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.21.3) + '@svgr/babel-plugin-transform-react-native-svg': 8.0.0(@babel/core@7.21.3) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.21.3) + dev: true + + /@svgr/core@5.5.0: + resolution: {integrity: sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==} + engines: {node: '>=10'} + dependencies: + '@svgr/plugin-jsx': 5.5.0 + camelcase: 6.3.0 + cosmiconfig: 7.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@svgr/core@8.0.0: + resolution: {integrity: sha512-aJKtc+Pie/rFYsVH/unSkDaZGvEeylNv/s2cP+ta9/rYWxRVvoV/S4Qw65Kmrtah4CBK5PM6ISH9qUH7IJQCng==} + engines: {node: '>=14'} + dependencies: + '@babel/core': 7.21.3 + '@svgr/babel-preset': 8.0.0(@babel/core@7.21.3) + camelcase: 6.3.0 + cosmiconfig: 8.1.3 + snake-case: 3.0.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@svgr/hast-util-to-babel-ast@5.5.0: + resolution: {integrity: sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==} + engines: {node: '>=10'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@svgr/hast-util-to-babel-ast@8.0.0: + resolution: {integrity: sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==} + engines: {node: '>=14'} + dependencies: + '@babel/types': 7.22.5 + entities: 4.4.0 + dev: true + + /@svgr/plugin-jsx@5.5.0: + resolution: {integrity: sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==} + engines: {node: '>=10'} + dependencies: + '@babel/core': 7.21.3 + '@svgr/babel-preset': 5.5.0 + '@svgr/hast-util-to-babel-ast': 5.5.0 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@svgr/plugin-jsx@8.0.1(@svgr/core@8.0.0): + resolution: {integrity: sha512-bfCFb+4ZsM3UuKP2t7KmDwn6YV8qVn9HIQJmau6xeQb/iV65Rpi7NBNBWA2hcCd4GKoCqG8hpaaDk5FDR0eH+g==} + engines: {node: '>=14'} + peerDependencies: + '@svgr/core': '*' + dependencies: + '@babel/core': 7.21.3 + '@svgr/babel-preset': 8.0.0(@babel/core@7.21.3) + '@svgr/core': 8.0.0 + '@svgr/hast-util-to-babel-ast': 8.0.0 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color dev: true - /@storybook/types@7.0.22: - resolution: {integrity: sha512-fzYD3fcgpQw3p0DLMQqlEvTw47qNwrPX8Wdv8pkS12RrM5ycmy6d6fVFVJOB9uWNXD1l34vWclEo6pbtEaBM9A==} + /@svgr/plugin-prettier@5.5.0: + resolution: {integrity: sha512-mVc+u+eKUmy8sW5UnFpes9NqVtizJfnhasF8Srbi3XdxVTWyU5lmhWlQAgHLhcrsZKowQ0b7xBa4qWHI5Ew/VQ==} + engines: {node: '>=10'} dependencies: - '@storybook/channels': 7.0.22 - '@types/babel__core': 7.20.0 - '@types/express': 4.17.17 - file-system-cache: 2.0.2 + deepmerge: 4.3.1 + prettier: 2.8.8 dev: true - /@storybook/types@7.0.7: - resolution: {integrity: sha512-v9piuwp8FvTiHXIOOi5lEyTEJKhnbcbhVxgJ3VFhhXYFd0DTz6Bst0XIIgkgs21ITb3xhkfPbCRUueMcbXO1MA==} + /@svgr/plugin-svgo@5.5.0: + resolution: {integrity: sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==} + engines: {node: '>=10'} dependencies: - '@storybook/channels': 7.0.7 - '@types/babel__core': 7.20.0 - '@types/express': 4.17.17 - file-system-cache: 2.0.2 + cosmiconfig: 7.1.0 + deepmerge: 4.3.1 + svgo: 1.3.2 dev: true /@swc/core-darwin-arm64@1.3.42: @@ -6044,25 +7370,23 @@ packages: tslib: 2.5.0 dev: false - /@testing-library/dom@8.20.0: - resolution: {integrity: sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA==} - engines: {node: '>=12'} + /@tailwindcss/typography@0.5.9(tailwindcss@3.3.1): + resolution: {integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' dependencies: - '@babel/code-frame': 7.18.6 - '@babel/runtime': 7.21.0 - '@types/aria-query': 5.0.1 - aria-query: 5.1.3 - chalk: 4.1.2 - dom-accessibility-api: 0.5.16 - lz-string: 1.5.0 - pretty-format: 27.5.1 + lodash.castarray: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + postcss-selector-parser: 6.0.10 + tailwindcss: 3.3.1(postcss@8.4.21)(ts-node@10.9.1) dev: true /@testing-library/dom@9.0.1: resolution: {integrity: sha512-fTOVsMY9QLFCCXRHG3Ese6cMH5qIWwSbgxZsgeF5TNsy81HKaZ4kgehnSF8FsR3OF+numlIV2YcU79MzbnhSig==} engines: {node: '>=14'} dependencies: - '@babel/code-frame': 7.18.6 + '@babel/code-frame': 7.22.5 '@babel/runtime': 7.21.0 '@types/aria-query': 5.0.1 aria-query: 5.1.3 @@ -6110,14 +7434,13 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true - /@testing-library/user-event@13.5.0(@testing-library/dom@8.20.0): - resolution: {integrity: sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==} - engines: {node: '>=10', npm: '>=6'} + /@testing-library/user-event@14.4.3(@testing-library/dom@9.0.1): + resolution: {integrity: sha512-kCUc5MEwaEMakkO5x7aoD+DLi02ehmEM2QCGWvNqAS1dV/fAvORWEjnjsEIvml59M7Y5kCkWN6fCCyPOe8OL6Q==} + engines: {node: '>=12', npm: '>=6'} peerDependencies: '@testing-library/dom': '>=7.21.4' dependencies: - '@babel/runtime': 7.21.0 - '@testing-library/dom': 8.20.0 + '@testing-library/dom': 9.0.1 dev: true /@tootallnate/once@2.0.0: @@ -6200,7 +7523,7 @@ packages: /@types/babel__core@7.20.0: resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==} dependencies: - '@babel/parser': 7.21.3 + '@babel/parser': 7.22.7 '@babel/types': 7.22.5 '@types/babel__generator': 7.6.4 '@types/babel__template': 7.4.1 @@ -6216,7 +7539,7 @@ packages: /@types/babel__template@7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: - '@babel/parser': 7.21.3 + '@babel/parser': 7.22.7 '@babel/types': 7.22.5 dev: true @@ -6269,6 +7592,12 @@ packages: resolution: {integrity: sha512-LKVP3cgXBT9RYj+t+9FDKwS5tdI+rPBXaNSkma7hvqy35lc7mAokC2zsqWJH0LaqIt3B962nuYI77hsJoT1gow==} dev: false + /@types/cross-spawn@6.0.2: + resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==} + dependencies: + '@types/node': 17.0.12 + dev: true + /@types/css-font-loading-module@0.0.7: resolution: {integrity: sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==} dev: false @@ -6441,6 +7770,10 @@ packages: resolution: {integrity: sha512-ZmiaE3wglXVWBM9fyVC17aGPkLo/UgaOjEiI2FXQfyczrCefORPxIe+2dVmnmk3zkVIbizjrlQzmPGhSYGXG5g==} dev: true + /@types/emscripten@1.39.7: + resolution: {integrity: sha512-tLqYV94vuqDrXh515F/FOGtBcRMTPGvVV1LzLbtYDcQmmhtpf/gLYf+hikBbQk8MzOHNz37wpFfJbYAuSn8HqA==} + dev: true + /@types/escodegen@0.0.6: resolution: {integrity: sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig==} dev: true @@ -6518,7 +7851,7 @@ packages: /@types/hoist-non-react-statics@3.3.1: resolution: {integrity: sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==} dependencies: - '@types/react': 18.0.28 + '@types/react': 18.2.18 hoist-non-react-statics: 3.3.2 /@types/is-function@1.0.1: @@ -6597,6 +7930,10 @@ packages: resolution: {integrity: sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg==} dev: true + /@types/node@20.4.6: + resolution: {integrity: sha512-q0RkvNgMweWWIvSMDiXhflGUKMdIxBo2M2tYM/0kEGDueQByFzK4KZAgu5YHGFNxziTlppNpTIBcqHQAxlfHdA==} + dev: true + /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true @@ -6611,7 +7948,6 @@ packages: /@types/parse-json@4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} - dev: false /@types/pretty-hrtime@1.0.1: resolution: {integrity: sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ==} @@ -6620,12 +7956,17 @@ packages: /@types/prop-types@15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + /@types/q@1.5.5: + resolution: {integrity: sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==} + dev: true + /@types/qs@6.9.7: resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} dev: true /@types/raf@3.4.0: resolution: {integrity: sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==} + requiresBuild: true dev: false optional: true @@ -6638,6 +7979,12 @@ packages: dependencies: '@types/react': 18.0.28 + /@types/react-dom@18.2.7: + resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==} + dependencies: + '@types/react': 18.2.18 + dev: true + /@types/react-grid-layout@1.3.2: resolution: {integrity: sha512-ZzpBEOC1JTQ7MGe1h1cPKSLP4jSWuxc+yvT4TsAlEW9+EFPzAf8nxQfFd7ea9gL17Em7PbwJZAsiwfQQBUklZQ==} dependencies: @@ -6646,13 +7993,13 @@ packages: /@types/react-is@17.0.3: resolution: {integrity: sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==} dependencies: - '@types/react': 18.0.28 + '@types/react': 18.2.18 dev: false /@types/react-transition-group@4.4.5: resolution: {integrity: sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==} dependencies: - '@types/react': 18.0.28 + '@types/react': 18.2.18 dev: false /@types/react-window@1.8.5: @@ -6668,6 +8015,13 @@ packages: '@types/scheduler': 0.16.2 csstype: 3.1.1 + /@types/react@18.2.18: + resolution: {integrity: sha512-da4NTSeBv/P34xoZPhtcLkmZuJ+oYaCxHmyHzwaDQo9RQPBeXV+06gEk2FpqEcsX9XrnNLvRpVh6bdavDSjtiQ==} + dependencies: + '@types/prop-types': 15.7.5 + '@types/scheduler': 0.16.2 + csstype: 3.1.1 + /@types/scheduler@0.16.2: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} @@ -6853,7 +8207,7 @@ packages: peerDependencies: vite: ^3.0.0 || ^4.0.0 dependencies: - vite: 4.2.1(@types/node@17.0.12)(sass@1.59.3) + vite: 4.2.1(@types/node@17.0.12)(sass@1.64.2) dev: true /@vitejs/plugin-react-swc@3.2.0(vite@4.2.1): @@ -6862,7 +8216,7 @@ packages: vite: ^4 dependencies: '@swc/core': 1.3.42 - vite: 4.2.1(@types/node@17.0.12)(sass@1.59.3) + vite: 4.2.1(@types/node@17.0.12)(sass@1.64.2) dev: true /@vitejs/plugin-react@3.1.0(vite@4.2.1): @@ -6876,7 +8230,38 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.21.3) magic-string: 0.27.0 react-refresh: 0.14.0 - vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3) + vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3) + transitivePeerDependencies: + - supports-color + dev: true + + /@vitejs/plugin-react@3.1.0(vite@4.4.8): + resolution: {integrity: sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.1.0-beta.0 + dependencies: + '@babel/core': 7.21.3 + '@babel/plugin-transform-react-jsx-self': 7.21.0(@babel/core@7.21.3) + '@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.21.3) + magic-string: 0.27.0 + react-refresh: 0.14.0 + vite: 4.4.8(@types/node@20.4.6)(less@4.1.3)(sass@1.64.2) + transitivePeerDependencies: + - supports-color + dev: true + + /@vitejs/plugin-react@4.0.4(vite@4.4.8): + resolution: {integrity: sha512-7wU921ABnNYkETiMaZy7XqpueMnpu5VxvVps13MjmCo+utBdD79sZzrApHawHtVX66cCJQQTXFcjH0y9dSUK8g==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 + dependencies: + '@babel/core': 7.22.9 + '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.22.9) + react-refresh: 0.14.0 + vite: 4.4.8(@types/node@20.4.6)(less@4.1.3)(sass@1.64.2) transitivePeerDependencies: - supports-color dev: true @@ -7026,16 +8411,32 @@ packages: resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} dev: true - /@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15(esbuild@0.17.12): + /@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15(esbuild@0.18.17): resolution: {integrity: sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA==} engines: {node: '>=14.15.0'} peerDependencies: esbuild: '>=0.10.0' dependencies: - esbuild: 0.17.12 + esbuild: 0.18.17 tslib: 2.5.0 dev: true + /@yarnpkg/fslib@2.10.3: + resolution: {integrity: sha512-41H+Ga78xT9sHvWLlFOZLIhtU6mTGZ20pZ29EiZa97vnxdohJD2AF42rCoAoWfqUz486xY6fhjMH+DYEM9r14A==} + engines: {node: '>=12 <14 || 14.2 - 14.9 || >14.10.0'} + dependencies: + '@yarnpkg/libzip': 2.3.0 + tslib: 1.14.1 + dev: true + + /@yarnpkg/libzip@2.3.0: + resolution: {integrity: sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg==} + engines: {node: '>=12 <14 || 14.2 - 14.9 || >14.10.0'} + dependencies: + '@types/emscripten': 1.39.7 + tslib: 1.14.1 + dev: true + /@yomguithereal/helpers@1.1.1: resolution: {integrity: sha512-UYvAq/XCA7xoh1juWDYsq3W0WywOB+pz8cgVnE1b45ZfdMhBvHDrgmSFG3jXeZSr2tMTYLGHFHON+ekG05Jebg==} dev: true @@ -7063,16 +8464,16 @@ packages: /acorn-globals@7.0.1: resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} dependencies: - acorn: 8.8.2 + acorn: 8.10.0 acorn-walk: 8.2.0 dev: true - /acorn-import-assertions@1.8.0(acorn@8.8.2): + /acorn-import-assertions@1.8.0(acorn@8.10.0): resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==} peerDependencies: acorn: ^8 dependencies: - acorn: 8.8.2 + acorn: 8.10.0 dev: true /acorn-jsx@5.3.2(acorn@7.4.1): @@ -7097,6 +8498,12 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + /acorn@8.8.2: resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} engines: {node: '>=0.4.0'} @@ -7241,6 +8648,13 @@ packages: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: true + /aria-hidden@1.2.3: + resolution: {integrity: sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==} + engines: {node: '>=10'} + dependencies: + tslib: 2.5.0 + dev: true + /aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} dependencies: @@ -7292,6 +8706,17 @@ packages: es-abstract: 1.21.2 es-shim-unscopables: 1.0.0 + /array.prototype.reduce@1.0.5: + resolution: {integrity: sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + es-array-method-boxes-properly: 1.0.0 + is-string: 1.0.7 + dev: true + /arrify@1.0.1: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} @@ -7376,6 +8801,22 @@ packages: postcss-value-parser: 4.2.0 dev: true + /autoprefixer@10.4.14(postcss@8.4.27): + resolution: {integrity: sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + dependencies: + browserslist: 4.21.5 + caniuse-lite: 1.0.30001466 + fraction.js: 4.2.0 + normalize-range: 0.1.2 + picocolors: 1.0.0 + postcss: 8.4.27 + postcss-value-parser: 4.2.0 + dev: true + /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} @@ -7390,17 +8831,44 @@ packages: resolution: {integrity: sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg==} engines: {node: '>=4'} + /axios@0.19.2: + resolution: {integrity: sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==} + deprecated: Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410 + dependencies: + follow-redirects: 1.5.10 + transitivePeerDependencies: + - supports-color + dev: true + + /axios@0.21.4: + resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} + dependencies: + follow-redirects: 1.15.2 + transitivePeerDependencies: + - debug + dev: true + + /axios@1.4.0: + resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==} + dependencies: + follow-redirects: 1.15.2 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: true + /axobject-query@3.1.1: resolution: {integrity: sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==} dependencies: deep-equal: 2.2.0 - /babel-core@7.0.0-bridge.0(@babel/core@7.21.3): + /babel-core@7.0.0-bridge.0(@babel/core@7.22.9): resolution: {integrity: sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.3 + '@babel/core': 7.22.9 dev: true /babel-plugin-istanbul@6.1.1: @@ -7425,38 +8893,38 @@ packages: resolve: 1.22.1 dev: false - /babel-plugin-polyfill-corejs2@0.3.3(@babel/core@7.21.3): - resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} + /babel-plugin-polyfill-corejs2@0.4.5(@babel/core@7.22.9): + resolution: {integrity: sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/compat-data': 7.21.4 - '@babel/core': 7.21.3 - '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.21.3) - semver: 6.3.0 + '@babel/compat-data': 7.22.9 + '@babel/core': 7.22.9 + '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.9) + semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-corejs3@0.6.0(@babel/core@7.21.3): - resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} + /babel-plugin-polyfill-corejs3@0.8.3(@babel/core@7.22.9): + resolution: {integrity: sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.21.3) - core-js-compat: 3.29.1 + '@babel/core': 7.22.9 + '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.9) + core-js-compat: 3.32.0 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-regenerator@0.4.1(@babel/core@7.21.3): - resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} + /babel-plugin-polyfill-regenerator@0.5.2(@babel/core@7.22.9): + resolution: {integrity: sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.21.3 - '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.9) transitivePeerDependencies: - supports-color dev: true @@ -7488,17 +8956,18 @@ packages: /base64-arraybuffer@1.0.2: resolution: {integrity: sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==} engines: {node: '>= 0.6.0'} + requiresBuild: true dev: false optional: true /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - /better-opn@2.1.1: - resolution: {integrity: sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA==} - engines: {node: '>8.0.0'} + /better-opn@3.0.2: + resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} + engines: {node: '>=12.0.0'} dependencies: - open: 7.4.2 + open: 8.4.2 dev: true /big-integer@1.6.51: @@ -7542,6 +9011,10 @@ packages: - supports-color dev: true + /boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + /bplist-parser@0.2.0: resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} engines: {node: '>= 5.10.0'} @@ -7577,6 +9050,17 @@ packages: pako: 0.2.9 dev: true + /browserslist@4.21.10: + resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001519 + electron-to-chromium: 1.4.482 + node-releases: 2.0.13 + update-browserslist-db: 1.0.11(browserslist@4.21.10) + dev: true + /browserslist@4.21.5: resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -7682,6 +9166,11 @@ packages: engines: {node: '>=6'} dev: true + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + /camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} dev: false @@ -7689,6 +9178,10 @@ packages: /caniuse-lite@1.0.30001466: resolution: {integrity: sha512-ewtFBSfWjEmxUgNBSZItFSmVtvk9zkwkl1OfRZlKA8slltRN+/C/tuGVrF9styXkN36Yu3+SeJ1qkXxDEyNZ5w==} + /caniuse-lite@1.0.30001519: + resolution: {integrity: sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==} + dev: true + /canvg@3.0.10: resolution: {integrity: sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==} engines: {node: '>=10.0.0'} @@ -7858,6 +9351,15 @@ packages: engines: {node: '>=6'} dev: false + /coa@2.0.2: + resolution: {integrity: sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==} + engines: {node: '>= 4.0'} + dependencies: + '@types/q': 1.5.5 + chalk: 2.4.2 + q: 1.5.1 + dev: true + /code-block-writer@11.0.3: resolution: {integrity: sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==} dev: true @@ -7905,7 +9407,6 @@ packages: /colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} - dev: false /colorette@2.0.19: resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} @@ -7977,7 +9478,7 @@ packages: dev: true /concat-map@0.0.1: - resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} /concat-stream@1.6.2: resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} @@ -8070,10 +9571,10 @@ packages: is-error: 2.2.2 dev: false - /core-js-compat@3.29.1: - resolution: {integrity: sha512-QmchCua884D8wWskMX8tW5ydINzd8oSJVx38lx/pVkFGqztxt73GYre3pm/hyYq8bPf+MW5In4I/uRShFDsbrA==} + /core-js-compat@3.32.0: + resolution: {integrity: sha512-7a9a3D1k4UCVKnLhrgALyFcP7YCsLOQIxPd0dKjf/6GuPcgyiGP70ewWdCGrSK7evyhymi0qO4EqCmSJofDeYw==} dependencies: - browserslist: 4.21.5 + browserslist: 4.21.10 dev: true /core-js@3.29.1: @@ -8120,7 +9621,6 @@ packages: parse-json: 5.2.0 path-type: 4.0.0 yaml: 1.10.2 - dev: false /cosmiconfig@8.1.3: resolution: {integrity: sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==} @@ -8164,6 +9664,7 @@ packages: /css-line-break@2.1.0: resolution: {integrity: sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==} + requiresBuild: true dependencies: utrie: 1.0.2 dev: false @@ -8175,17 +9676,37 @@ packages: peerDependencies: webpack: ^5.0.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.21) - postcss: 8.4.21 - postcss-modules-extract-imports: 3.0.0(postcss@8.4.21) - postcss-modules-local-by-default: 4.0.0(postcss@8.4.21) - postcss-modules-scope: 3.0.0(postcss@8.4.21) - postcss-modules-values: 4.0.0(postcss@8.4.21) + icss-utils: 5.1.0(postcss@8.4.27) + postcss: 8.4.27 + postcss-modules-extract-imports: 3.0.0(postcss@8.4.27) + postcss-modules-local-by-default: 4.0.0(postcss@8.4.27) + postcss-modules-scope: 3.0.0(postcss@8.4.27) + postcss-modules-values: 4.0.0(postcss@8.4.27) postcss-value-parser: 4.2.0 semver: 7.3.8 webpack: 5.77.0(esbuild@0.17.12) dev: true + /css-select-base-adapter@0.1.1: + resolution: {integrity: sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==} + dev: true + + /css-select@2.1.0: + resolution: {integrity: sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==} + dependencies: + boolbase: 1.0.0 + css-what: 3.4.2 + domutils: 1.7.0 + nth-check: 1.0.2 + dev: true + + /css-selector-tokenizer@0.8.0: + resolution: {integrity: sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==} + dependencies: + cssesc: 3.0.0 + fastparse: 1.1.2 + dev: true + /css-to-react-native@3.2.0: resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} dependencies: @@ -8194,6 +9715,27 @@ packages: postcss-value-parser: 4.2.0 dev: false + /css-tree@1.0.0-alpha.37: + resolution: {integrity: sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==} + engines: {node: '>=8.0.0'} + dependencies: + mdn-data: 2.0.4 + source-map: 0.6.1 + dev: true + + /css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + dev: true + + /css-what@3.4.2: + resolution: {integrity: sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==} + engines: {node: '>= 6'} + dev: true + /css.escape@1.5.1: resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} dev: true @@ -8204,6 +9746,13 @@ packages: hasBin: true dev: true + /csso@4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + dependencies: + css-tree: 1.1.3 + dev: true + /cssstyle@3.0.0: resolution: {integrity: sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==} engines: {node: '>=14'} @@ -8601,6 +10150,19 @@ packages: lodash: 4.17.21 dev: true + /daisyui@3.5.0(ts-node@10.9.1): + resolution: {integrity: sha512-wSaeXwaYdMv4yURv9wj7kKQQN9Jyumfh/skIpZfCNkCb2jLf/so+iNKSM8l4rDN0TRvB5OccMlAvsf2UAtk2gg==} + engines: {node: '>=16.9.0'} + dependencies: + colord: 2.9.3 + css-selector-tokenizer: 0.8.0 + postcss: 8.4.21 + postcss-js: 4.0.1(postcss@8.4.21) + tailwindcss: 3.3.1(postcss@8.4.21)(ts-node@10.9.1) + transitivePeerDependencies: + - ts-node + dev: true + /damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} @@ -8629,6 +10191,17 @@ packages: ms: 2.0.0 dev: true + /debug@3.1.0: + resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + /debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -8738,6 +10311,11 @@ packages: core-assert: 0.2.1 dev: false + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + /default-browser-id@3.0.0: resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} engines: {node: '>=12'} @@ -8815,6 +10393,10 @@ packages: engines: {node: '>=8'} dev: true + /detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + dev: true + /detect-package-manager@2.0.1: resolution: {integrity: sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==} engines: {node: '>=12'} @@ -8879,10 +10461,25 @@ packages: csstype: 3.1.1 dev: false + /dom-serializer@0.2.2: + resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} + dependencies: + domelementtype: 2.3.0 + entities: 2.2.0 + dev: true + /dom-walk@0.1.2: resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==} dev: true + /domelementtype@1.3.1: + resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} + dev: true + + /domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + dev: true + /domexception@4.0.0: resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} engines: {node: '>=12'} @@ -8896,6 +10493,20 @@ packages: dev: false optional: true + /domutils@1.7.0: + resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} + dependencies: + dom-serializer: 0.2.2 + domelementtype: 1.3.1 + dev: true + + /dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.5.0 + dev: true + /dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} @@ -8912,6 +10523,11 @@ packages: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} + /dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + dev: true + /draco3d@1.5.5: resolution: {integrity: sha512-JVuNV0EJzD3LBYhGyIXJLeBID/EVtmFO1ZNhAYflTgiMiAJlbhXQmRRda/azjc8MRVMHh0gqGhiqHUo5dIXM8Q==} dev: false @@ -8948,6 +10564,10 @@ packages: /electron-to-chromium@1.4.330: resolution: {integrity: sha512-PqyefhybrVdjAJ45HaPLtuVaehiSw7C3ya0aad+rvmV53IVyXmYRk3pwIOb2TxTDTnmgQdn46NjMMaysx79/6Q==} + /electron-to-chromium@1.4.482: + resolution: {integrity: sha512-h+UqpfmEr1Qkk0zp7ej/jid7CXoq4m4QzW6wNTb0ELJ/BZCpA4wgUylBIMGCe621tnr4l5VmoHjdoSx2lbnNJA==} + dev: true + /elkjs@0.8.2: resolution: {integrity: sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==} dev: true @@ -8988,6 +10608,10 @@ packages: dependencies: ansi-colors: 4.1.3 + /entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + dev: true + /entities@4.4.0: resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} engines: {node: '>=0.12'} @@ -9052,6 +10676,10 @@ packages: unbox-primitive: 1.0.2 which-typed-array: 1.1.9 + /es-array-method-boxes-properly@1.0.0: + resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} + dev: true + /es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} dependencies: @@ -9098,24 +10726,35 @@ packages: resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} dev: true - /esbuild-register@3.4.2(esbuild@0.16.17): + /esbuild-register@3.4.2(esbuild@0.16.17): + resolution: {integrity: sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==} + peerDependencies: + esbuild: '>=0.12 <1' + dependencies: + debug: 4.3.4(supports-color@5.5.0) + esbuild: 0.16.17 + transitivePeerDependencies: + - supports-color + dev: true + + /esbuild-register@3.4.2(esbuild@0.17.12): resolution: {integrity: sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==} peerDependencies: esbuild: '>=0.12 <1' dependencies: debug: 4.3.4(supports-color@5.5.0) - esbuild: 0.16.17 + esbuild: 0.17.12 transitivePeerDependencies: - supports-color dev: true - /esbuild-register@3.4.2(esbuild@0.17.12): + /esbuild-register@3.4.2(esbuild@0.18.17): resolution: {integrity: sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==} peerDependencies: esbuild: '>=0.12 <1' dependencies: debug: 4.3.4(supports-color@5.5.0) - esbuild: 0.17.12 + esbuild: 0.18.17 transitivePeerDependencies: - supports-color dev: true @@ -9180,6 +10819,36 @@ packages: '@esbuild/win32-x64': 0.17.12 dev: true + /esbuild@0.18.17: + resolution: {integrity: sha512-1GJtYnUxsJreHYA0Y+iQz2UEykonY66HNWOb0yXYZi9/kNrORUEHVg87eQsCtqh59PEJ5YVZJO98JHznMJSWjg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.17 + '@esbuild/android-arm64': 0.18.17 + '@esbuild/android-x64': 0.18.17 + '@esbuild/darwin-arm64': 0.18.17 + '@esbuild/darwin-x64': 0.18.17 + '@esbuild/freebsd-arm64': 0.18.17 + '@esbuild/freebsd-x64': 0.18.17 + '@esbuild/linux-arm': 0.18.17 + '@esbuild/linux-arm64': 0.18.17 + '@esbuild/linux-ia32': 0.18.17 + '@esbuild/linux-loong64': 0.18.17 + '@esbuild/linux-mips64el': 0.18.17 + '@esbuild/linux-ppc64': 0.18.17 + '@esbuild/linux-riscv64': 0.18.17 + '@esbuild/linux-s390x': 0.18.17 + '@esbuild/linux-x64': 0.18.17 + '@esbuild/netbsd-x64': 0.18.17 + '@esbuild/openbsd-x64': 0.18.17 + '@esbuild/sunos-x64': 0.18.17 + '@esbuild/win32-arm64': 0.18.17 + '@esbuild/win32-ia32': 0.18.17 + '@esbuild/win32-x64': 0.18.17 + dev: true + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -9241,13 +10910,13 @@ packages: dependencies: eslint: 7.32.0 - /eslint-config-turbo@1.10.9(eslint@7.32.0): - resolution: {integrity: sha512-YA5QWxWte/NiRJL0/Cv7aATfIvS5sUAuyD6ZuyTZEzwyU7E6FUXGo44amjf9INkyj96HrJ2nYWoFkCRx3vs6Ag==} + /eslint-config-turbo@1.10.12(eslint@7.32.0): + resolution: {integrity: sha512-z3jfh+D7UGYlzMWGh+Kqz++hf8LOE96q3o5R8X4HTjmxaBWlLAWG+0Ounr38h+JLR2TJno0hU9zfzoPNkR9BdA==} peerDependencies: eslint: '>6.6.0' dependencies: eslint: 7.32.0 - eslint-plugin-turbo: 1.10.9(eslint@7.32.0) + eslint-plugin-turbo: 1.10.12(eslint@7.32.0) /eslint-import-resolver-node@0.3.7: resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} @@ -9390,8 +11059,8 @@ packages: semver: 6.3.0 string.prototype.matchall: 4.0.8 - /eslint-plugin-turbo@1.10.9(eslint@7.32.0): - resolution: {integrity: sha512-o8Nga4WFMvzF0lo3d3UyjGli2JOUn/4SRtRdvcf4EA9/TPotU/NUHqO16Cp0SHZJG/tGYIy5LY1O/EO7Mxbd1A==} + /eslint-plugin-turbo@1.10.12(eslint@7.32.0): + resolution: {integrity: sha512-uNbdj+ohZaYo4tFJ6dStRXu2FZigwulR1b3URPXe0Q8YaE7thuekKNP+54CHtZPH9Zey9dmDx5btAQl9mfzGOw==} peerDependencies: eslint: '>6.6.0' dependencies: @@ -9518,7 +11187,7 @@ packages: resolution: {integrity: sha512-YNF+mZ/Wu2FU/gvmzuWtYc8rloubL7wfXCTgouFrnjGVXPA/EeYYA7pupXWrb3Iv1cTBeSSxxJIbK23l4MRNqg==} engines: {node: '>=8.3.0'} dependencies: - '@babel/traverse': 7.21.3(supports-color@5.5.0) + '@babel/traverse': 7.22.8 '@babel/types': 7.22.5 c8: 7.13.0 transitivePeerDependencies: @@ -9649,6 +11318,10 @@ packages: strnum: 1.0.5 dev: false + /fastparse@1.1.2: + resolution: {integrity: sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==} + dev: true + /fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} dependencies: @@ -9700,17 +11373,44 @@ packages: resolution: {integrity: sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==} dev: false + /figma-api-exporter@0.0.2: + resolution: {integrity: sha512-9cCPZPUKVuD0JetpAnp82wSmBQiYDQ0TTBc7+BFHXwPiW+KxirfiPuCPJY+p4rTplKPzn0hkfrCvGpAS9Rehhg==} + dependencies: + axios: 0.19.2 + figma-js: 1.16.0 + figma-transformer: 1.0.0 + fs: 0.0.1-security + ramda: 0.26.1 + rimraf: 3.0.2 + transitivePeerDependencies: + - debug + - supports-color + dev: true + + /figma-js@1.16.0: + resolution: {integrity: sha512-cImQT9DAJp1J0xr6FMUAswXKEnjwrDz4QKAgIBpUyydKAgDS/lm862stjweHp99uco5qLoNv+GbwQWBHyDvDQw==} + engines: {node: '>=8.9'} + dependencies: + axios: 0.21.4 + transitivePeerDependencies: + - debug + dev: true + + /figma-transformer@1.0.0: + resolution: {integrity: sha512-7iSOH1UkuRMAfP7jgmM7ca7v20FjxKgryVzd3qIvNBY2u0vrRLwIVMPqQC6PAy4G8iyJFqEDKX1ezHxrthPXbA==} + dev: true + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: flat-cache: 3.0.4 - /file-system-cache@2.0.2: - resolution: {integrity: sha512-lp4BHO4CWqvRyx88Tt3quZic9ZMf4cJyquYq7UI8sH42Bm2ArlBBjKQAalZOo+UfaBassb7X123Lik5qZ/tSAA==} + /file-system-cache@2.3.0: + resolution: {integrity: sha512-l4DMNdsIPsVnKrgEXbJwDJsA5mB8rGwHYERMgqQx/xAUtChPJMre1bXBzDEqqVbWv9AIbFezXMxeEkZDSrXUOQ==} dependencies: fs-extra: 11.1.1 - ramda: 0.28.0 + ramda: 0.29.0 dev: true /filelist@1.0.4: @@ -9812,6 +11512,25 @@ packages: - encoding dev: false + /follow-redirects@1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: true + + /follow-redirects@1.5.10: + resolution: {integrity: sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==} + engines: {node: '>=4.0'} + dependencies: + debug: 3.1.0 + transitivePeerDependencies: + - supports-color + dev: true + /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: @@ -9825,6 +11544,14 @@ packages: signal-exit: 3.0.7 dev: true + /foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + dev: true + /form-data@3.0.1: resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} engines: {node: '>= 6'} @@ -9898,6 +11625,10 @@ packages: /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + /fs@0.0.1-security: + resolution: {integrity: sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==} + dev: true + /fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -9958,6 +11689,11 @@ packages: has: 1.0.3 has-symbols: 1.0.3 + /get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + dev: true + /get-npm-tarball-url@2.0.3: resolution: {integrity: sha512-R/PW6RqyaBQNWYaSyfrh54/qtcnOp22FHCCiRhSSZj0FP3KQWCsxxt0DzIdVTbwTqe9CtQfvl/FPD4UIPt4pqw==} engines: {node: '>=12.17'} @@ -10057,6 +11793,18 @@ packages: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} dev: true + /glob@10.3.3: + resolution: {integrity: sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.2.2 + minimatch: 9.0.3 + minipass: 7.0.2 + path-scurry: 1.10.1 + dev: true + /glob@7.1.6: resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} dependencies: @@ -10492,13 +12240,13 @@ packages: safer-buffer: 2.1.2 dev: true - /icss-utils@5.1.0(postcss@8.4.21): + /icss-utils@5.1.0(postcss@8.4.27): resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.21 + postcss: 8.4.27 dev: true /ieee754@1.2.1: @@ -10583,9 +12331,10 @@ packages: resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} dev: false - /interpret@1.4.0: - resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} - engines: {node: '>= 0.10'} + /invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 dev: true /ip@2.0.0: @@ -10874,15 +12623,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /isomorphic-unfetch@3.1.0: - resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} - dependencies: - node-fetch: 2.6.9 - unfetch: 4.2.0 - transitivePeerDependencies: - - encoding - dev: true - /istanbul-lib-coverage@3.2.0: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} engines: {node: '>=8'} @@ -10893,7 +12633,7 @@ packages: engines: {node: '>=8'} dependencies: '@babel/core': 7.21.3 - '@babel/parser': 7.21.3 + '@babel/parser': 7.22.7 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.0 semver: 6.3.0 @@ -10918,6 +12658,15 @@ packages: istanbul-lib-report: 3.0.0 dev: true + /jackspeak@2.2.2: + resolution: {integrity: sha512-mgNtVv4vUuaKA97yxUHoA3+FkuhtxkjdXEWOyB/N76fjy0FjezEt34oy3epBtvCvS+7DyKwqCFWx/oJLV5+kCg==} + engines: {node: '>=14'} + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + dev: true + /jake@10.8.5: resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==} engines: {node: '>=10'} @@ -11022,23 +12771,23 @@ packages: argparse: 2.0.1 dev: true - /jscodeshift@0.14.0(@babel/preset-env@7.21.4): + /jscodeshift@0.14.0(@babel/preset-env@7.22.9): resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} hasBin: true peerDependencies: '@babel/preset-env': ^7.1.6 dependencies: - '@babel/core': 7.21.3 - '@babel/parser': 7.21.3 - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.21.3) - '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.3) - '@babel/plugin-transform-modules-commonjs': 7.21.2(@babel/core@7.21.3) - '@babel/preset-env': 7.21.4(@babel/core@7.21.3) - '@babel/preset-flow': 7.18.6(@babel/core@7.21.3) - '@babel/preset-typescript': 7.21.0(@babel/core@7.21.3) - '@babel/register': 7.21.0(@babel/core@7.21.3) - babel-core: 7.0.0-bridge.0(@babel/core@7.21.3) + '@babel/core': 7.22.9 + '@babel/parser': 7.22.7 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.22.9) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.22.9) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.22.9) + '@babel/plugin-transform-modules-commonjs': 7.21.2(@babel/core@7.22.9) + '@babel/preset-env': 7.22.9(@babel/core@7.22.9) + '@babel/preset-flow': 7.18.6(@babel/core@7.22.9) + '@babel/preset-typescript': 7.21.0(@babel/core@7.22.9) + '@babel/register': 7.21.0(@babel/core@7.22.9) + babel-core: 7.0.0-bridge.0(@babel/core@7.22.9) chalk: 4.1.2 flow-parser: 0.202.0 graceful-fs: 4.2.11 @@ -11209,6 +12958,10 @@ packages: resolution: {integrity: sha512-ymToLHqL02udwVdbkowNpzjFd6UzozMtshPQKVi5k1EjKRqKqBrOnE9QbLEb0/pV76SAiIT13hdL8R6suc+f3g==} dev: true + /kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + dev: true + /ktx-parse@0.0.4: resolution: {integrity: sha512-LY3nrmfXl+wZZdPxgJ3ZmLvG+wkOZZP3/dr4RbQj1Pk3Qwz44esOOSFFVQJcNWpXAtiNIC66WgXufX/SYgYz6A==} dev: false @@ -11234,7 +12987,7 @@ packages: engines: {node: '>=14.0.0'} dependencies: app-root-dir: 1.0.2 - dotenv: 16.0.3 + dotenv: 16.3.1 dotenv-expand: 10.0.0 dev: true @@ -11251,7 +13004,7 @@ packages: dependencies: klona: 2.0.6 less: 4.1.3 - webpack: 5.77.0(esbuild@0.17.12) + webpack: 5.77.0(esbuild@0.18.17) dev: true /less@4.1.3: @@ -11347,6 +13100,10 @@ packages: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: true + /lodash.castarray@4.4.0: + resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} + dev: true + /lodash.curry@4.1.1: resolution: {integrity: sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==} dev: false @@ -11436,6 +13193,17 @@ packages: get-func-name: 2.0.0 dev: true + /lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.5.0 + dev: true + + /lru-cache@10.0.0: + resolution: {integrity: sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==} + engines: {node: 14 || >=16.14} + dev: true + /lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} dependencies: @@ -11466,6 +13234,13 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true + /magic-string@0.30.2: + resolution: {integrity: sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + /make-dir@2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} @@ -11530,6 +13305,14 @@ packages: resolution: {integrity: sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==} dev: true + /mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + dev: true + + /mdn-data@2.0.4: + resolution: {integrity: sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==} + dev: true + /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -11638,6 +13421,13 @@ packages: brace-expansion: 2.0.1 dev: true + /minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimist-options@4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} engines: {node: '>= 6'} @@ -11662,6 +13452,11 @@ packages: engines: {node: '>=8'} dev: true + /minipass@7.0.2: + resolution: {integrity: sha512-eL79dXrE1q9dBbDCLg7xfn/vl7MS4F1gvJAgjJrQli/jbQWdUttuVawphqpffoIYfRdq78LHx6GP4bU/EQ2ATA==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true + /minizlib@2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} @@ -11698,7 +13493,7 @@ packages: /mlly@1.2.0: resolution: {integrity: sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww==} dependencies: - acorn: 8.8.2 + acorn: 8.10.0 pathe: 1.1.0 pkg-types: 1.0.2 ufo: 1.1.1 @@ -11751,6 +13546,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} dev: true @@ -11825,6 +13625,13 @@ packages: - babel-plugin-macros dev: false + /no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.5.0 + dev: true + /node-dir@0.1.17: resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} engines: {node: '>= 0.10.5'} @@ -11867,6 +13674,10 @@ packages: /node-releases@2.0.10: resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} + /node-releases@2.0.13: + resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + dev: true + /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} dependencies: @@ -11902,6 +13713,81 @@ packages: path-key: 3.1.1 dev: true + /npm@9.8.1: + resolution: {integrity: sha512-AfDvThQzsIXhYgk9zhbk5R+lh811lKkLAeQMMhSypf1BM7zUafeIIBzMzespeuVEJ0+LvY36oRQYf7IKLzU3rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + dev: true + bundledDependencies: + - '@isaacs/string-locale-compare' + - '@npmcli/arborist' + - '@npmcli/config' + - '@npmcli/fs' + - '@npmcli/map-workspaces' + - '@npmcli/package-json' + - '@npmcli/promise-spawn' + - '@npmcli/run-script' + - abbrev + - archy + - cacache + - chalk + - ci-info + - cli-columns + - cli-table3 + - columnify + - fastest-levenshtein + - fs-minipass + - glob + - graceful-fs + - hosted-git-info + - ini + - init-package-json + - is-cidr + - json-parse-even-better-errors + - libnpmaccess + - libnpmdiff + - libnpmexec + - libnpmfund + - libnpmhook + - libnpmorg + - libnpmpack + - libnpmpublish + - libnpmsearch + - libnpmteam + - libnpmversion + - make-fetch-happen + - minimatch + - minipass + - minipass-pipeline + - ms + - node-gyp + - nopt + - npm-audit-report + - npm-install-checks + - npm-package-arg + - npm-pick-manifest + - npm-profile + - npm-registry-fetch + - npm-user-validate + - npmlog + - p-map + - pacote + - parse-conflict-json + - proc-log + - qrcode-terminal + - read + - semver + - sigstore + - ssri + - supports-color + - tar + - text-table + - tiny-relative-date + - treeverse + - validate-npm-package-name + - which + - write-file-atomic + /npmlog@5.0.1: resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} dependencies: @@ -11911,6 +13797,12 @@ packages: set-blocking: 2.0.0 dev: true + /nth-check@1.0.2: + resolution: {integrity: sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==} + dependencies: + boolbase: 1.0.0 + dev: true + /nwsapi@2.2.2: resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==} dev: true @@ -11963,6 +13855,17 @@ packages: define-properties: 1.2.0 es-abstract: 1.21.2 + /object.getownpropertydescriptors@2.1.6: + resolution: {integrity: sha512-lq+61g26E/BgHv0ZTFgRvi7NMEPuAxLkFU7rukXjc/AlwH4Am5xXVnIXy3un1bg/JPbXHrixRkK1itUzzPiIjQ==} + engines: {node: '>= 0.8'} + dependencies: + array.prototype.reduce: 1.0.5 + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + safe-array-concat: 1.0.0 + dev: true + /object.hasown@1.1.2: resolution: {integrity: sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==} dependencies: @@ -12009,14 +13912,6 @@ packages: mimic-fn: 2.1.0 dev: true - /open@7.4.2: - resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} - engines: {node: '>=8'} - dependencies: - is-docker: 2.2.1 - is-wsl: 2.2.0 - dev: true - /open@8.4.2: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} @@ -12138,7 +14033,7 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.18.6 + '@babel/code-frame': 7.22.5 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -12184,6 +14079,14 @@ packages: /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + /path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + lru-cache: 10.0.0 + minipass: 7.0.2 + dev: true + /path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} dev: true @@ -12222,6 +14125,7 @@ packages: /performance-now@2.1.0: resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + requiresBuild: true dev: false optional: true @@ -12247,6 +14151,10 @@ packages: engines: {node: '>= 6'} dev: true + /pixi-viewport@5.0.2: + resolution: {integrity: sha512-U77KnCTl81xEgxEQRFEuI7MYVySWwCVkA41EnM8KiOYwgVOwdBUa7318O+u61IOnTwnoYLzaihy/kpoONKU13Q==} + dev: false + /pixi.js@7.2.1(@pixi/utils@7.2.1): resolution: {integrity: sha512-MDfXqHIazZa0FAcdHOcb9ix5Z6wYY+ruaJj38JwRYxWoVW/4u2LwAjTLabKbC0zKL/Y9xDPQiNNTZ8YkVOeG5g==} dependencies: @@ -12332,6 +14240,18 @@ packages: resolve: 1.22.1 dev: true + /postcss-import@15.1.0(postcss@8.4.27): + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + dependencies: + postcss: 8.4.27 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.2 + dev: true + /postcss-js@4.0.1(postcss@8.4.21): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} @@ -12342,6 +14262,16 @@ packages: postcss: 8.4.21 dev: true + /postcss-js@4.0.1(postcss@8.4.27): + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.27 + dev: true + /postcss-load-config@3.1.4(postcss@8.4.21)(ts-node@10.9.1): resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} @@ -12356,7 +14286,7 @@ packages: dependencies: lilconfig: 2.1.0 postcss: 8.4.21 - ts-node: 10.9.1(@types/node@17.0.12)(typescript@4.9.5) + ts-node: 10.9.1(@types/node@18.13.0)(typescript@4.9.5) yaml: 1.10.2 dev: true @@ -12378,7 +14308,25 @@ packages: yaml: 2.2.1 dev: true - /postcss-loader@7.3.0(postcss@8.4.21)(webpack@5.77.0): + /postcss-load-config@4.0.1(postcss@8.4.27)(ts-node@10.9.1): + resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.1.0 + postcss: 8.4.27 + ts-node: 10.9.1(@types/node@17.0.12)(typescript@4.9.5) + yaml: 2.2.1 + dev: true + + /postcss-loader@7.3.0(postcss@8.4.27)(webpack@5.77.0): resolution: {integrity: sha512-qLAFjvR2BFNz1H930P7mj1iuWJFjGey/nVhimfOAAQ1ZyPpcClAxP8+A55Sl8mBvM+K2a9Pjgdj10KpANWrNfw==} engines: {node: '>= 14.15.0'} peerDependencies: @@ -12388,50 +14336,50 @@ packages: cosmiconfig: 8.1.3 jiti: 1.18.2 klona: 2.0.6 - postcss: 8.4.21 + postcss: 8.4.27 semver: 7.3.8 - webpack: 5.77.0(esbuild@0.17.12) + webpack: 5.77.0(esbuild@0.18.17) dev: true - /postcss-modules-extract-imports@3.0.0(postcss@8.4.21): + /postcss-modules-extract-imports@3.0.0(postcss@8.4.27): resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.21 + postcss: 8.4.27 dev: true - /postcss-modules-local-by-default@4.0.0(postcss@8.4.21): + /postcss-modules-local-by-default@4.0.0(postcss@8.4.27): resolution: {integrity: sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.21) - postcss: 8.4.21 + icss-utils: 5.1.0(postcss@8.4.27) + postcss: 8.4.27 postcss-selector-parser: 6.0.11 postcss-value-parser: 4.2.0 dev: true - /postcss-modules-scope@3.0.0(postcss@8.4.21): + /postcss-modules-scope@3.0.0(postcss@8.4.27): resolution: {integrity: sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - postcss: 8.4.21 + postcss: 8.4.27 postcss-selector-parser: 6.0.11 dev: true - /postcss-modules-values@4.0.0(postcss@8.4.21): + /postcss-modules-values@4.0.0(postcss@8.4.27): resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} engines: {node: ^10 || ^12 || >= 14} peerDependencies: postcss: ^8.1.0 dependencies: - icss-utils: 5.1.0(postcss@8.4.21) - postcss: 8.4.21 + icss-utils: 5.1.0(postcss@8.4.27) + postcss: 8.4.27 dev: true /postcss-nested@6.0.0(postcss@8.4.21): @@ -12444,6 +14392,16 @@ packages: postcss-selector-parser: 6.0.11 dev: true + /postcss-nested@6.0.1(postcss@8.4.27): + resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + dependencies: + postcss: 8.4.27 + postcss-selector-parser: 6.0.11 + dev: true + /postcss-nesting@11.2.2(postcss@8.4.21): resolution: {integrity: sha512-aOTiUniAB1bcPE6GGiynWRa6PZFPhOTAm5q3q5cem6QeSijIHHkWr6gs65ukCZMXeak8yXeZVbBJET3VM+HlhA==} engines: {node: ^14 || ^16 || >=18} @@ -12455,6 +14413,17 @@ packages: postcss-selector-parser: 6.0.11 dev: true + /postcss-nesting@12.0.0(postcss@8.4.27): + resolution: {integrity: sha512-knqwW65kxssmyIFadRSimaiRyLVRd0MdwfabesKw6XvGLwSOCJ+4zfvNQQCOOYij5obwpZzDpODuGRv2PCyiUw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.4 + dependencies: + '@csstools/selector-specificity': 3.0.0(postcss-selector-parser@6.0.13) + postcss: 8.4.27 + postcss-selector-parser: 6.0.13 + dev: true + /postcss-plugin@1.0.0: resolution: {integrity: sha512-w0SKz9cKfp/wN8baHB/JXZUTBSrUP6/mqDiony+aAVlPXOhTkSXmJ8T5IuhZgHYdV4R/HA3P0N26rG1Sp0oP/A==} dependencies: @@ -12468,6 +14437,24 @@ packages: postcss: ^8.4.19 dependencies: postcss: 8.4.21 + dev: true + + /postcss-scss@4.0.6(postcss@8.4.27): + resolution: {integrity: sha512-rLDPhJY4z/i4nVFZ27j9GqLxj1pwxE80eAzUNRMXtcpipFYIeowerzBgG3yJhMtObGEXidtIgbUpQ3eLDsf5OQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.4.19 + dependencies: + postcss: 8.4.27 + dev: false + + /postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true /postcss-selector-parser@6.0.11: resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==} @@ -12477,6 +14464,14 @@ packages: util-deprecate: 1.0.2 dev: true + /postcss-selector-parser@6.0.13: + resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + /postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -12505,6 +14500,15 @@ packages: nanoid: 3.3.4 picocolors: 1.0.0 source-map-js: 1.0.2 + dev: true + + /postcss@8.4.27: + resolution: {integrity: sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 /prelude-ls@1.1.2: resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} @@ -12527,8 +14531,8 @@ packages: hasBin: true dev: true - /prettier@3.0.0: - resolution: {integrity: sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==} + /prettier@3.0.1: + resolution: {integrity: sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==} engines: {node: '>=14'} hasBin: true dev: true @@ -12599,6 +14603,7 @@ packages: /prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + requiresBuild: true dev: true optional: true @@ -12711,13 +14716,18 @@ packages: /raf@3.4.1: resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==} + requiresBuild: true dependencies: performance-now: 2.1.0 dev: false optional: true - /ramda@0.28.0: - resolution: {integrity: sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==} + /ramda@0.26.1: + resolution: {integrity: sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==} + dev: true + + /ramda@0.29.0: + resolution: {integrity: sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==} dev: true /randombytes@2.1.0: @@ -12771,12 +14781,12 @@ packages: universal-cookie: 4.0.4 dev: false - /react-docgen-typescript@2.2.2(typescript@4.9.5): + /react-docgen-typescript@2.2.2(typescript@5.1.6): resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==} peerDependencies: typescript: '>= 4.3.x' dependencies: - typescript: 4.9.5 + typescript: 5.1.6 dev: true /react-docgen@6.0.0-alpha.3: @@ -12785,7 +14795,7 @@ packages: hasBin: true dependencies: '@babel/core': 7.21.3 - '@babel/generator': 7.21.3 + '@babel/generator': 7.22.9 ast-types: 0.14.2 commander: 2.20.3 doctrine: 3.0.0 @@ -12938,6 +14948,41 @@ packages: engines: {node: '>=0.10.0'} dev: true + /react-remove-scroll-bar@2.3.4(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.18 + react: 18.2.0 + react-style-singleton: 2.2.1(@types/react@18.2.18)(react@18.2.0) + tslib: 2.5.0 + dev: true + + /react-remove-scroll@2.5.5(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.18 + react: 18.2.0 + react-remove-scroll-bar: 2.3.4(@types/react@18.2.18)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.18)(react@18.2.0) + tslib: 2.5.0 + use-callback-ref: 1.3.0(@types/react@18.2.18)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.18)(react@18.2.0) + dev: true + /react-resizable@3.0.4(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-StnwmiESiamNzdRHbSSvA65b0ZQJ7eVQpPusrSmcpyGKzC0gojhtO62xxH6YOBmepk9dQTBi9yxidL3W4s3EBA==} peerDependencies: @@ -12983,6 +15028,23 @@ packages: react-is: 18.2.0 dev: true + /react-style-singleton@2.2.1(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.18 + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 18.2.0 + tslib: 2.5.0 + dev: true + /react-test-renderer@18.2.0(react@18.2.0): resolution: {integrity: sha512-JWD+aQ0lh2gvh4NM3bBM42Kx+XybOxCpgYK7F8ugAlpaTSnWsX+39Z4XkOykGZAHrjwwTZT3x3KxswVWxHPUqA==} peerDependencies: @@ -13149,13 +15211,6 @@ packages: tslib: 2.5.0 dev: true - /rechoir@0.6.2: - resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} - engines: {node: '>= 0.10'} - dependencies: - resolve: 1.22.1 - dev: true - /redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -13296,7 +15351,7 @@ packages: adjust-sourcemap-loader: 4.0.0 convert-source-map: 1.9.0 loader-utils: 2.0.4 - postcss: 8.4.21 + postcss: 8.4.27 source-map: 0.6.1 dev: true @@ -13315,6 +15370,15 @@ packages: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + /resolve@1.22.2: + resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} + hasBin: true + dependencies: + is-core-module: 2.11.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + /resolve@2.0.0-next.4: resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} hasBin: true @@ -13338,6 +15402,7 @@ packages: /rgbcolor@1.0.1: resolution: {integrity: sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==} engines: {node: '>= 0.8.15'} + requiresBuild: true dev: false optional: true @@ -13369,6 +15434,14 @@ packages: fsevents: 2.3.2 dev: true + /rollup@3.27.1: + resolution: {integrity: sha512-tXNDFwOkN6C2w5Blj1g6ForKeFw6c1mDu5jxoeDO3/pmYjgt+8yvIFjKzH5FQUq70OKZBkOt0zzv0THXL7vwzQ==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + /rrweb-cssom@0.6.0: resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} dev: true @@ -13382,6 +15455,16 @@ packages: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} dev: false + /safe-array-concat@1.0.0: + resolution: {integrity: sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.0 + has-symbols: 1.0.3 + isarray: 2.0.5 + dev: true + /safe-buffer@5.1.1: resolution: {integrity: sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==} dev: true @@ -13404,12 +15487,12 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - /sass-loader@13.2.2(sass@1.59.3)(webpack@5.77.0): - resolution: {integrity: sha512-nrIdVAAte3B9icfBiGWvmMhT/D+eCDwnk+yA7VE/76dp/WkHX+i44Q/pfo71NYbwj0Ap+PGsn0ekOuU1WFJ2AA==} + /sass-loader@13.3.2(sass@1.59.3)(webpack@5.77.0): + resolution: {integrity: sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==} engines: {node: '>= 14.15.0'} peerDependencies: fibers: '>= 3.1.0' - node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 sass: ^1.3.0 sass-embedded: '*' webpack: ^5.0.0 @@ -13423,12 +15506,35 @@ packages: sass-embedded: optional: true dependencies: - klona: 2.0.6 neo-async: 2.6.2 sass: 1.59.3 webpack: 5.77.0(esbuild@0.17.12) dev: true + /sass-loader@13.3.2(sass@1.64.2)(webpack@5.77.0): + resolution: {integrity: sha512-CQbKl57kdEv+KDLquhC+gE3pXt74LEAzm+tzywcA0/aHZuub8wTErbjAoNI57rPUWRYRNC5WUnNl8eGJNbDdwg==} + engines: {node: '>= 14.15.0'} + peerDependencies: + fibers: '>= 3.1.0' + node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + sass: ^1.3.0 + sass-embedded: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + fibers: + optional: true + node-sass: + optional: true + sass: + optional: true + sass-embedded: + optional: true + dependencies: + neo-async: 2.6.2 + sass: 1.64.2 + webpack: 5.77.0(esbuild@0.18.17) + dev: true + /sass@1.59.3: resolution: {integrity: sha512-QCq98N3hX1jfTCoUAsF3eyGuXLsY7BCnCEg9qAact94Yc21npG2/mVOqoDvE0fCbWDqiM4WlcJQla0gWG2YlxQ==} engines: {node: '>=12.0.0'} @@ -13438,10 +15544,20 @@ packages: immutable: 4.3.0 source-map-js: 1.0.2 + /sass@1.64.2: + resolution: {integrity: sha512-TnDlfc+CRnUAgLO9D8cQLFu/GIjJIzJCGkE7o4ekIGQOH7T3GetiRR/PsTWJUHhkzcSPrARkPI+gNWn5alCzDg==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + chokidar: 3.5.3 + immutable: 4.3.0 + source-map-js: 1.0.2 + dev: true + /sax@1.2.4: resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + requiresBuild: true dev: true - optional: true /saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} @@ -13480,8 +15596,8 @@ packages: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} hasBin: true - /semver@7.0.0: - resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true dev: true @@ -13492,6 +15608,14 @@ packages: dependencies: lru-cache: 6.0.0 + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + /send@0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} engines: {node: '>= 0.8.0'} @@ -13575,16 +15699,6 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - /shelljs@0.8.5: - resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} - engines: {node: '>=4'} - hasBin: true - dependencies: - glob: 7.2.3 - interpret: 1.4.0 - rechoir: 0.6.2 - dev: true - /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: @@ -13600,17 +15714,22 @@ packages: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + /simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} dependencies: is-arrayish: 0.3.2 dev: false - /simple-update-notifier@1.1.0: - resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==} - engines: {node: '>=8.10.0'} + /simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} dependencies: - semver: 7.0.0 + semver: 7.5.4 dev: true /sisteransi@1.0.5: @@ -13637,6 +15756,13 @@ packages: is-fullwidth-code-point: 4.0.0 dev: true + /snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.5.0 + dev: true + /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -13693,6 +15819,11 @@ packages: /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + /stable@0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + dev: true + /stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true @@ -13700,6 +15831,7 @@ packages: /stackblur-canvas@2.5.0: resolution: {integrity: sha512-EeNzTVfj+1In7aSLPKDD03F/ly4RxEuF/EX0YcOG0cKoPXs+SLZxDawQbexQDBzwROs4VKLWTOaZQlZkGBFEIQ==} engines: {node: '>=0.1.14'} + requiresBuild: true dev: false optional: true @@ -13722,11 +15854,11 @@ packages: resolution: {integrity: sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==} dev: true - /storybook@7.0.22: - resolution: {integrity: sha512-d/pMpaVjTB1tSOpWYRpdCamfzg4zcVeOgz8O0k5OblJO8UOdq7numlynntaw4v+p6lusWXX8CSfE/MUUOgzQKw==} + /storybook@7.2.1: + resolution: {integrity: sha512-uNNqJrWUVaxdZdd3GpMTHt9h2EftoUKxtpAWeQlzx20DDvcliVC1yvLT54sLAzY8nlxxN+fBUuBbTSJ1Dx4TPg==} hasBin: true dependencies: - '@storybook/cli': 7.0.22 + '@storybook/cli': 7.2.1 transitivePeerDependencies: - bufferutil - encoding @@ -13842,7 +15974,7 @@ packages: /strip-literal@1.0.1: resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} dependencies: - acorn: 8.8.2 + acorn: 8.10.0 dev: true /strnum@1.0.5: @@ -13946,12 +16078,38 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + /svg-parser@2.0.4: + resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + dev: true + /svg-pathdata@6.0.3: resolution: {integrity: sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==} engines: {node: '>=12.0.0'} + requiresBuild: true dev: false optional: true + /svgo@1.3.2: + resolution: {integrity: sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==} + engines: {node: '>=4.0.0'} + deprecated: This SVGO version is no longer supported. Upgrade to v2.x.x. + hasBin: true + dependencies: + chalk: 2.4.2 + coa: 2.0.2 + css-select: 2.1.0 + css-select-base-adapter: 0.1.1 + css-tree: 1.0.0-alpha.37 + csso: 4.2.0 + js-yaml: 3.14.1 + mkdirp: 0.5.6 + object.values: 1.1.6 + sax: 1.2.4 + stable: 0.1.8 + unquote: 1.1.1 + util.promisify: 1.0.1 + dev: true + /symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} dev: true @@ -14005,6 +16163,37 @@ packages: - ts-node dev: true + /tailwindcss@3.3.3(ts-node@10.9.1): + resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.5.3 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.2.12 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.18.2 + lilconfig: 2.1.0 + micromatch: 4.0.5 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.0.0 + postcss: 8.4.27 + postcss-import: 15.1.0(postcss@8.4.27) + postcss-js: 4.0.1(postcss@8.4.27) + postcss-load-config: 4.0.1(postcss@8.4.27)(ts-node@10.9.1) + postcss-nested: 6.0.1(postcss@8.4.27) + postcss-selector-parser: 6.0.11 + resolve: 1.22.2 + sucrase: 3.32.0 + transitivePeerDependencies: + - ts-node + dev: true + /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} @@ -14109,13 +16298,38 @@ packages: webpack: 5.77.0(esbuild@0.17.12) dev: true + /terser-webpack-plugin@5.3.7(esbuild@0.18.17)(webpack@5.77.0): + resolution: {integrity: sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.17 + esbuild: 0.18.17 + jest-worker: 27.5.1 + schema-utils: 3.1.1 + serialize-javascript: 6.0.1 + terser: 5.16.8 + webpack: 5.77.0(esbuild@0.18.17) + dev: true + /terser@5.16.8: resolution: {integrity: sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA==} engines: {node: '>=10'} hasBin: true dependencies: '@jridgewell/source-map': 0.3.2 - acorn: 8.8.2 + acorn: 8.10.0 commander: 2.20.3 source-map-support: 0.5.21 dev: true @@ -14136,6 +16350,7 @@ packages: /text-segmentation@1.0.3: resolution: {integrity: sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==} + requiresBuild: true dependencies: utrie: 1.0.2 dev: false @@ -14187,6 +16402,10 @@ packages: deprecated: 'This module is now under the @mapbox namespace: install @mapbox/tilebelt instead' dev: false + /tiny-invariant@1.3.1: + resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==} + dev: true + /tinybench@2.4.0: resolution: {integrity: sha512-iyziEiyFxX4kyxSp+MtY1oCH/lvjH3PxFN8PGCDeqcZWAJ/i+9y+nL85w99PxVzrIvew/GSkSbDYtiGVa85Afg==} dev: true @@ -14215,6 +16434,10 @@ packages: dependencies: is-number: 7.0.0 + /tocbot@4.21.0: + resolution: {integrity: sha512-vXk8htr8mIl3hc2s2mDkaPTBfqmqZA2o0x7eXbxUibdrpEIPdpM0L9hH/RvEvlgSM+ZTgS34sGipk5+VrLJCLA==} + dev: true + /toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} @@ -14281,7 +16504,7 @@ packages: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.3 '@types/node': 17.0.12 - acorn: 8.8.2 + acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 create-require: 1.1.1 @@ -14336,6 +16559,19 @@ packages: typescript: 4.9.5 dev: true + /tsconfck@2.1.0(typescript@5.1.6): + resolution: {integrity: sha512-lztI9ohwclQHISVWrM/hlcgsRpphsii94DV9AQtAw2XJSVNiv+3ppdEsrL5J+xc5oTeHXe1qDqlOAGw8VSa9+Q==} + engines: {node: ^14.13.1 || ^16 || >=18} + hasBin: true + peerDependencies: + typescript: ^4.3.5 || ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + dependencies: + typescript: 5.1.6 + dev: true + /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} dependencies: @@ -14359,65 +16595,65 @@ packages: tslib: 1.14.1 typescript: 4.9.5 - /turbo-darwin-64@1.10.8: - resolution: {integrity: sha512-FOK3qrLZE2Yq7/2DkAnAzghisGQroZJs85Rui3IXM/2e7rTtBADmU9w36d4k0Yw7RHEiOo8U4eAYUl52OWRwJQ==} + /turbo-darwin-64@1.10.12: + resolution: {integrity: sha512-vmDfGVPl5/aFenAbOj3eOx3ePNcWVUyZwYr7taRl0ZBbmv2TzjRiFotO4vrKCiTVnbqjQqAFQWY2ugbqCI1kOQ==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.10.8: - resolution: {integrity: sha512-8mbgH8oBycusa8RnbHlvrpHxfZsgNrk6CXMu/KJECpajYT3nSOMK2Rrs+422HqLDTVUw4GAqmTr26nUx8yJoyA==} + /turbo-darwin-arm64@1.10.12: + resolution: {integrity: sha512-3JliEESLNX2s7g54SOBqqkqJ7UhcOGkS0ywMr5SNuvF6kWVTbuUq7uBU/sVbGq8RwvK1ONlhPvJne5MUqBCTCQ==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.10.8: - resolution: {integrity: sha512-eJ1ND3LuILw28gd+9f3Ews7Eika9WOxp+/PxJI+EPHseTrbLMLYqSPAunmZdOx840Pq0Sk5j4Nik7NCzuCWXkg==} + /turbo-linux-64@1.10.12: + resolution: {integrity: sha512-siYhgeX0DidIfHSgCR95b8xPee9enKSOjCzx7EjTLmPqPaCiVebRYvbOIYdQWRqiaKh9yfhUtFmtMOMScUf1gg==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.10.8: - resolution: {integrity: sha512-3+pVaOzGP/5GFvQakxuHDMsj43Y6bmaq5/84tvgGL0FgtKpsQvBfdaDs12HX5cb/zUnd2/jdQPNiGJwVeC/McA==} + /turbo-linux-arm64@1.10.12: + resolution: {integrity: sha512-K/ZhvD9l4SslclaMkTiIrnfcACgos79YcAo4kwc8bnMQaKuUeRpM15sxLpZp3xDjDg8EY93vsKyjaOhdFG2UbA==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.10.8: - resolution: {integrity: sha512-LdryI+ZQsVrW4hWZw5G5vJz0syjWxyc0tnieZRefy+d9Ti1du/qCYLP0KQRgL9Yuh1klbH/tzmx70upGARgWKQ==} + /turbo-windows-64@1.10.12: + resolution: {integrity: sha512-7FSgSwvktWDNOqV65l9AbZwcoueAILeE4L7JvjauNASAjjbuzXGCEq5uN8AQU3U5BOFj4TdXrVmO2dX+lLu8Zg==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.10.8: - resolution: {integrity: sha512-whHnhM84KIa2Ly/fcw2Ujw2Rr/9wh8ynAdZ9bdvZoZKAbOr3tXKft0tmy50jQ6IsNr6Cj0XD4cuSTKhvqoGtYA==} + /turbo-windows-arm64@1.10.12: + resolution: {integrity: sha512-gCNXF52dwom1HLY9ry/cneBPOKTBHhzpqhMylcyvJP0vp9zeMQQkt6yjYv+6QdnmELC92CtKNp2FsNZo+z0pyw==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.10.8: - resolution: {integrity: sha512-lmPKkeRMC/3gjTVxICt93A8zAzjGjbZINdekjzivn4g/rOjpHVNuOuVANU5L4H4R1bzQr8FFvZNQeQaElOjz/Q==} + /turbo@1.10.12: + resolution: {integrity: sha512-WM3+jTfQWnB9W208pmP4oeehZcC6JQNlydb/ZHMRrhmQa+htGhWLCzd6Q9rLe0MwZLPpSPFV2/bN5egCLyoKjQ==} hasBin: true requiresBuild: true optionalDependencies: - turbo-darwin-64: 1.10.8 - turbo-darwin-arm64: 1.10.8 - turbo-linux-64: 1.10.8 - turbo-linux-arm64: 1.10.8 - turbo-windows-64: 1.10.8 - turbo-windows-arm64: 1.10.8 + turbo-darwin-64: 1.10.12 + turbo-darwin-arm64: 1.10.12 + turbo-linux-64: 1.10.12 + turbo-linux-arm64: 1.10.12 + turbo-windows-64: 1.10.12 + turbo-windows-arm64: 1.10.12 dev: true /type-check@0.3.2: @@ -14497,6 +16733,12 @@ packages: engines: {node: '>=4.2.0'} hasBin: true + /typescript@5.1.6: + resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + /ua-parser-js@0.7.34: resolution: {integrity: sha512-cJMeh/eOILyGu0ejgTKB95yKT3zOenSe9UGE3vj6WfiOwgGYnmATUsnDixMFvdU+rNMvWih83hrUP8VwhF9yXQ==} dev: false @@ -14521,10 +16763,6 @@ packages: has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 - /unfetch@4.2.0: - resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} - dev: true - /unicode-canonical-property-names-ecmascript@2.0.0: resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} engines: {node: '>=4'} @@ -14601,13 +16839,48 @@ packages: engines: {node: '>= 0.8'} dev: true - /unplugin@0.10.2: - resolution: {integrity: sha512-6rk7GUa4ICYjae5PrAllvcDeuT8pA9+j5J5EkxbMFaV+SalHhxZ7X2dohMzu6C3XzsMT+6jwR/+pwPNR3uK9MA==} + /unplugin-icons@0.16.5: + resolution: {integrity: sha512-laCCqMWfng1XZgB9yowGfjBdDhtmz8t8zVnhzRNEMhBNdy26QrVewVmdXk/zsiAQYnEWvIxTjvW1nQXrxdd2+w==} + peerDependencies: + '@svgr/core': '>=7.0.0' + '@svgx/core': ^1.0.1 + '@vue/compiler-sfc': ^3.0.2 || ^2.7.0 + vue-template-compiler: ^2.6.12 + vue-template-es2015-compiler: ^1.9.0 + peerDependenciesMeta: + '@svgr/core': + optional: true + '@svgx/core': + optional: true + '@vue/compiler-sfc': + optional: true + vue-template-compiler: + optional: true + vue-template-es2015-compiler: + optional: true + dependencies: + '@antfu/install-pkg': 0.1.1 + '@antfu/utils': 0.7.5 + '@iconify/utils': 2.1.7 + debug: 4.3.4(supports-color@5.5.0) + kolorist: 1.8.0 + local-pkg: 0.4.3 + unplugin: 1.4.0 + transitivePeerDependencies: + - supports-color + dev: true + + /unplugin@1.4.0: + resolution: {integrity: sha512-5x4eIEL6WgbzqGtF9UV8VEC/ehKptPXDS6L2b0mv4FRMkJxRtjaJfOWDd6a8+kYbqsjklix7yWP0N3SUepjXcg==} dependencies: - acorn: 8.8.2 + acorn: 8.10.0 chokidar: 3.5.3 webpack-sources: 3.2.3 - webpack-virtual-modules: 0.4.6 + webpack-virtual-modules: 0.5.0 + dev: true + + /unquote@1.1.1: + resolution: {integrity: sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg==} dev: true /untildify@4.0.0: @@ -14625,6 +16898,17 @@ packages: escalade: 3.1.1 picocolors: 1.0.0 + /update-browserslist-db@1.0.11(browserslist@4.21.10): + resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.10 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: @@ -14660,6 +16944,21 @@ packages: querystring: 0.2.0 dev: false + /use-callback-ref@1.3.0(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.18 + react: 18.2.0 + tslib: 2.5.0 + dev: true + /use-composed-ref@1.3.0(react@18.2.0): resolution: {integrity: sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==} peerDependencies: @@ -14716,6 +17015,22 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: true + /use-sidecar@1.1.2(@types/react@18.2.18)(react@18.2.0): + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + dependencies: + '@types/react': 18.2.18 + detect-node-es: 1.1.0 + react: 18.2.0 + tslib: 2.5.0 + dev: true + /use-sync-external-store@1.2.0(react@18.2.0): resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: @@ -14727,6 +17042,15 @@ packages: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true + /util.promisify@1.0.1: + resolution: {integrity: sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==} + dependencies: + define-properties: 1.2.0 + es-abstract: 1.21.2 + has-symbols: 1.0.3 + object.getownpropertydescriptors: 2.1.6 + dev: true + /util@0.12.5: resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} dependencies: @@ -14744,14 +17068,15 @@ packages: /utrie@1.0.2: resolution: {integrity: sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==} + requiresBuild: true dependencies: base64-arraybuffer: 1.0.2 dev: false optional: true - /uuid-browser@3.1.0: - resolution: {integrity: sha512-dsNgbLaTrd6l3MMxTtouOCFw4CBFc/3a+GgYA2YyrJvyQ1u6q4pcu3ktLoUZ/VN/Aw9WsauazbgsgdfVWgAKQg==} - deprecated: Package no longer supported and required. Use the uuid package or crypto.randomUUID instead + /uuid@9.0.0: + resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true dev: true /v8-compile-cache-lib@3.0.1: @@ -14797,10 +17122,33 @@ packages: mlly: 1.2.0 pathe: 1.1.0 picocolors: 1.0.0 - vite: 4.2.1(@types/node@17.0.12)(sass@1.59.3) + vite: 4.4.8(@types/node@17.0.12)(sass@1.59.3) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vite-node@0.29.4(@types/node@17.0.12)(sass@1.64.2): + resolution: {integrity: sha512-sPhnCzGm3rCI1BMgOUHiGJN4MObLUOzdCjrNU5A2miNTat/7k96hmvVLxKXPLb0wjX160oG1ZhLVYBzF80UJlQ==} + engines: {node: '>=v14.16.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4(supports-color@5.5.0) + mlly: 1.2.0 + pathe: 1.1.0 + picocolors: 1.0.0 + vite: 4.4.8(@types/node@17.0.12)(sass@1.64.2) transitivePeerDependencies: - '@types/node' - less + - lightningcss - sass - stylus - sugarss @@ -14824,7 +17172,7 @@ packages: kolorist: 1.7.0 magic-string: 0.29.0 ts-morph: 17.0.1 - vite: 4.2.1(@types/node@17.0.12)(sass@1.59.3) + vite: 4.2.1(@types/node@17.0.12)(sass@1.64.2) transitivePeerDependencies: - '@types/node' - rollup @@ -14847,7 +17195,7 @@ packages: kolorist: 1.7.0 magic-string: 0.29.0 ts-morph: 17.0.1 - vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3) + vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3) transitivePeerDependencies: - '@types/node' - rollup @@ -14867,10 +17215,10 @@ packages: postcss-js: 4.0.1(postcss@8.4.21) prettier: 2.8.5 sass: 1.59.3 - vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3) + vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3) dev: true - /vite-plugin-sass-dts@1.3.2(postcss@8.4.21)(prettier@2.8.8)(sass@1.59.3)(vite@4.2.1): + /vite-plugin-sass-dts@1.3.2(postcss@8.4.21)(prettier@2.8.8)(sass@1.64.2)(vite@4.2.1): resolution: {integrity: sha512-zClOXVLQHKG//aZ+gsDXMnhLLVKJprrv3x+KQBf/8GD/dM4FHmlK4zMM5JcOr12oq3kTz+DUYCtCEYsFY8eDPQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -14882,12 +17230,45 @@ packages: postcss: 8.4.21 postcss-js: 4.0.1(postcss@8.4.21) prettier: 2.8.8 - sass: 1.59.3 - vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3) + sass: 1.64.2 + vite: 4.2.1(@types/node@17.0.12)(sass@1.64.2) + dev: true + + /vite-plugin-sass-dts@1.3.9(postcss@8.4.27)(prettier@2.8.8)(sass@1.64.2)(vite@4.4.8): + resolution: {integrity: sha512-v8+LJ8yeN+TexjWiJjv6XOIvT382ZEcFi9gY7OB1ydGNv50B+RE5I8/Xx5XJDkNXsDfhdatNMq02Zgu9ue/wXw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + postcss: ^8 + prettier: ^2.7 || ^3 + sass: '*' + vite: ^3 || ^4 + dependencies: + postcss: 8.4.27 + postcss-js: 4.0.1(postcss@8.4.27) + prettier: 2.8.8 + sass: 1.64.2 + vite: 4.4.8(@types/node@20.4.6)(less@4.1.3)(sass@1.64.2) + dev: true + + /vite-tsconfig-paths@4.0.7(typescript@4.9.5)(vite@4.2.1): + resolution: {integrity: sha512-MwIYaby6kcbQGZqMH+gAK6h0UYQGOkjsuAgw4q6bP/5vWkn8VKvnmLuCQHA2+IzHAJHnE8OFTO4lnJLFMf9+7Q==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + dependencies: + debug: 4.3.4(supports-color@5.5.0) + globrex: 0.1.2 + tsconfck: 2.1.0(typescript@4.9.5) + vite: 4.2.1(@types/node@18.13.0)(sass@1.59.3) + transitivePeerDependencies: + - supports-color + - typescript dev: true - /vite-tsconfig-paths@4.0.7(typescript@4.9.5)(vite@4.2.1): - resolution: {integrity: sha512-MwIYaby6kcbQGZqMH+gAK6h0UYQGOkjsuAgw4q6bP/5vWkn8VKvnmLuCQHA2+IzHAJHnE8OFTO4lnJLFMf9+7Q==} + /vite-tsconfig-paths@4.2.0(typescript@5.1.6)(vite@4.4.8): + resolution: {integrity: sha512-jGpus0eUy5qbbMVGiTxCL1iB9ZGN6Bd37VGLJU39kTDD6ZfULTTb1bcc5IeTWqWJKiWV5YihCaibeASPiGi8kw==} peerDependencies: vite: '*' peerDependenciesMeta: @@ -14896,14 +17277,14 @@ packages: dependencies: debug: 4.3.4(supports-color@5.5.0) globrex: 0.1.2 - tsconfck: 2.1.0(typescript@4.9.5) - vite: 4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3) + tsconfck: 2.1.0(typescript@5.1.6) + vite: 4.4.8(@types/node@20.4.6)(less@4.1.3)(sass@1.64.2) transitivePeerDependencies: - supports-color - typescript dev: true - /vite@4.2.1(@types/node@17.0.12)(sass@1.59.3): + /vite@4.2.1(@types/node@17.0.12)(sass@1.64.2): resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -14933,12 +17314,12 @@ packages: postcss: 8.4.21 resolve: 1.22.1 rollup: 3.20.0 - sass: 1.59.3 + sass: 1.64.2 optionalDependencies: fsevents: 2.3.2 dev: true - /vite@4.2.1(@types/node@18.13.0)(less@4.1.3)(sass@1.59.3): + /vite@4.2.1(@types/node@18.13.0)(sass@1.59.3): resolution: {integrity: sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -14965,7 +17346,6 @@ packages: dependencies: '@types/node': 18.13.0 esbuild: 0.17.12 - less: 4.1.3 postcss: 8.4.21 resolve: 1.22.1 rollup: 3.20.0 @@ -14974,6 +17354,180 @@ packages: fsevents: 2.3.2 dev: true + /vite@4.4.8(@types/node@17.0.12)(sass@1.59.3): + resolution: {integrity: sha512-LONawOUUjxQridNWGQlNizfKH89qPigK36XhMI7COMGztz8KNY0JHim7/xDd71CZwGT4HtSRgI7Hy+RlhG0Gvg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 17.0.12 + esbuild: 0.18.17 + postcss: 8.4.27 + rollup: 3.27.1 + sass: 1.59.3 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vite@4.4.8(@types/node@17.0.12)(sass@1.64.2): + resolution: {integrity: sha512-LONawOUUjxQridNWGQlNizfKH89qPigK36XhMI7COMGztz8KNY0JHim7/xDd71CZwGT4HtSRgI7Hy+RlhG0Gvg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 17.0.12 + esbuild: 0.18.17 + postcss: 8.4.27 + rollup: 3.27.1 + sass: 1.64.2 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vite@4.4.8(@types/node@20.4.6)(less@4.1.3)(sass@1.64.2): + resolution: {integrity: sha512-LONawOUUjxQridNWGQlNizfKH89qPigK36XhMI7COMGztz8KNY0JHim7/xDd71CZwGT4HtSRgI7Hy+RlhG0Gvg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.4.6 + esbuild: 0.18.17 + less: 4.1.3 + postcss: 8.4.27 + rollup: 3.27.1 + sass: 1.64.2 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitest@0.29.4: + resolution: {integrity: sha512-CJBD3K6klNMfrOoSWhpfKAhGLrQzFx+21QYuXZthUW7cuK9pC9o7yU8MpPs5vwkgKpqhaL62WyoDAS5zgqfm6g==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.4 + '@types/chai-subset': 1.3.3 + '@types/node': 17.0.12 + '@vitest/expect': 0.29.4 + '@vitest/runner': 0.29.4 + '@vitest/spy': 0.29.4 + '@vitest/utils': 0.29.4 + acorn: 8.8.2 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + debug: 4.3.4(supports-color@5.5.0) + local-pkg: 0.4.3 + pathe: 1.1.0 + picocolors: 1.0.0 + source-map: 0.6.1 + std-env: 3.3.2 + strip-literal: 1.0.1 + tinybench: 2.4.0 + tinypool: 0.4.0 + tinyspy: 1.1.1 + vite: 4.2.1(@types/node@17.0.12)(sass@1.64.2) + vite-node: 0.29.4(@types/node@17.0.12)(sass@1.59.3) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + /vitest@0.29.4(happy-dom@8.9.0)(jsdom@21.1.1)(sass@1.59.3): resolution: {integrity: sha512-CJBD3K6klNMfrOoSWhpfKAhGLrQzFx+21QYuXZthUW7cuK9pC9o7yU8MpPs5vwkgKpqhaL62WyoDAS5zgqfm6g==} engines: {node: '>=v14.16.0'} @@ -15025,11 +17579,74 @@ packages: tinybench: 2.4.0 tinypool: 0.4.0 tinyspy: 1.1.1 - vite: 4.2.1(@types/node@17.0.12)(sass@1.59.3) + vite: 4.4.8(@types/node@17.0.12)(sass@1.59.3) vite-node: 0.29.4(@types/node@17.0.12)(sass@1.59.3) why-is-node-running: 2.2.2 transitivePeerDependencies: - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vitest@0.29.4(sass@1.64.2): + resolution: {integrity: sha512-CJBD3K6klNMfrOoSWhpfKAhGLrQzFx+21QYuXZthUW7cuK9pC9o7yU8MpPs5vwkgKpqhaL62WyoDAS5zgqfm6g==} + engines: {node: '>=v14.16.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.4 + '@types/chai-subset': 1.3.3 + '@types/node': 17.0.12 + '@vitest/expect': 0.29.4 + '@vitest/runner': 0.29.4 + '@vitest/spy': 0.29.4 + '@vitest/utils': 0.29.4 + acorn: 8.8.2 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + debug: 4.3.4(supports-color@5.5.0) + local-pkg: 0.4.3 + pathe: 1.1.0 + picocolors: 1.0.0 + source-map: 0.6.1 + std-env: 3.3.2 + strip-literal: 1.0.1 + tinybench: 2.4.0 + tinypool: 0.4.0 + tinyspy: 1.1.1 + vite: 4.2.1(@types/node@17.0.12)(sass@1.64.2) + vite-node: 0.29.4(@types/node@17.0.12)(sass@1.64.2) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss - sass - stylus - sugarss @@ -15081,8 +17698,8 @@ packages: engines: {node: '>=10.13.0'} dev: true - /webpack-virtual-modules@0.4.6: - resolution: {integrity: sha512-5tyDlKLqPfMqjT3Q9TAqf2YqjwmnUleZwzJi1A5qXnlBCdj2AtOJ6wAWdglTIDOPgOiOrXeBeFcsQ8+aGQ6QbA==} + /webpack-virtual-modules@0.5.0: + resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==} dev: true /webpack@5.77.0(esbuild@0.17.12): @@ -15100,9 +17717,9 @@ packages: '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/wasm-edit': 1.11.1 '@webassemblyjs/wasm-parser': 1.11.1 - acorn: 8.8.2 - acorn-import-assertions: 1.8.0(acorn@8.8.2) - browserslist: 4.21.5 + acorn: 8.10.0 + acorn-import-assertions: 1.8.0(acorn@8.10.0) + browserslist: 4.21.10 chrome-trace-event: 1.0.3 enhanced-resolve: 5.12.0 es-module-lexer: 0.9.3 @@ -15125,6 +17742,46 @@ packages: - uglify-js dev: true + /webpack@5.77.0(esbuild@0.18.17): + resolution: {integrity: sha512-sbGNjBr5Ya5ss91yzjeJTLKyfiwo5C628AFjEa6WSXcZa4E+F57om3Cc8xLb1Jh0b243AWuSYRf3dn7HVeFQ9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.4 + '@types/estree': 0.0.51 + '@webassemblyjs/ast': 1.11.1 + '@webassemblyjs/wasm-edit': 1.11.1 + '@webassemblyjs/wasm-parser': 1.11.1 + acorn: 8.10.0 + acorn-import-assertions: 1.8.0(acorn@8.10.0) + browserslist: 4.21.10 + chrome-trace-event: 1.0.3 + enhanced-resolve: 5.12.0 + es-module-lexer: 0.9.3 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.1.1 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.7(esbuild@0.18.17)(webpack@5.77.0) + watchpack: 2.4.0 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + dev: true + /whatwg-encoding@2.0.0: resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} engines: {node: '>=12'} @@ -15218,6 +17875,15 @@ packages: strip-ansi: 6.0.1 dev: true + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.0.1 + dev: true + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}