diff --git a/.husky/pre-commit b/.husky/pre-commit index 8790bc8b..46e51356 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,5 +1,5 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npm run ts-standard +npm run prod npm run test-ci diff --git a/dist/assets/assets/images/radio.svg b/dist/assets/assets/images/radio.svg new file mode 100644 index 00000000..4ce24fc8 --- /dev/null +++ b/dist/assets/assets/images/radio.svg @@ -0,0 +1,3 @@ + + + diff --git a/dist/assets/assets/images/radio_active.svg b/dist/assets/assets/images/radio_active.svg new file mode 100644 index 00000000..5edab1b4 --- /dev/null +++ b/dist/assets/assets/images/radio_active.svg @@ -0,0 +1,4 @@ + + + + diff --git a/dist/assets/assets/images/spinner.svg b/dist/assets/assets/images/spinner.svg new file mode 100644 index 00000000..ef958cc3 --- /dev/null +++ b/dist/assets/assets/images/spinner.svg @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/dist/assets/images/radio.svg b/dist/assets/images/radio.svg new file mode 100644 index 00000000..4ce24fc8 --- /dev/null +++ b/dist/assets/images/radio.svg @@ -0,0 +1,3 @@ + + + diff --git a/dist/assets/images/radio_active.svg b/dist/assets/images/radio_active.svg new file mode 100644 index 00000000..5edab1b4 --- /dev/null +++ b/dist/assets/images/radio_active.svg @@ -0,0 +1,4 @@ + + + + diff --git a/dist/assets/images/spinner.svg b/dist/assets/images/spinner.svg new file mode 100644 index 00000000..ef958cc3 --- /dev/null +++ b/dist/assets/images/spinner.svg @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/dist/framework/abstractions/processing_engine.d.ts b/dist/framework/abstractions/processing_engine.d.ts new file mode 100644 index 00000000..ce9f56a2 --- /dev/null +++ b/dist/framework/abstractions/processing_engine.d.ts @@ -0,0 +1,7 @@ +export default interface ProcessingEngine { + start: () => void; + loadScript: (script: any) => void; + firstRunCycle: () => void; + nextRunCycle: (response: any) => void; + terminate: () => void; +} diff --git a/dist/framework/abstractions/processing_engine.js b/dist/framework/abstractions/processing_engine.js new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/dist/framework/abstractions/processing_engine.js @@ -0,0 +1 @@ +export {}; diff --git a/dist/framework/abstractions/visualisation_engine.d.ts b/dist/framework/abstractions/visualisation_engine.d.ts new file mode 100644 index 00000000..e20f1b66 --- /dev/null +++ b/dist/framework/abstractions/visualisation_engine.d.ts @@ -0,0 +1,4 @@ +export default interface VisualisationEngine { + start: (script: string, rootElement: HTMLElement, locale: string) => Promise; + terminate: () => void; +} diff --git a/dist/framework/abstractions/visualisation_engine.js b/dist/framework/abstractions/visualisation_engine.js new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/dist/framework/abstractions/visualisation_engine.js @@ -0,0 +1 @@ +export {}; diff --git a/dist/framework/assembly.d.ts b/dist/framework/assembly.d.ts new file mode 100644 index 00000000..acc334ef --- /dev/null +++ b/dist/framework/assembly.d.ts @@ -0,0 +1,2 @@ +import VisualisationEngine from './abstractions/visualisation_engine'; +export declare const Assembly: (worker: Worker) => VisualisationEngine; diff --git a/dist/framework/assembly.js b/dist/framework/assembly.js new file mode 100644 index 00000000..315a6d98 --- /dev/null +++ b/dist/framework/assembly.js @@ -0,0 +1,9 @@ +import ReactEngine from './visualisation/react/engine'; +import ReactFactory from './visualisation/react/factory'; +import WorkerProcessingEngine from './processing/worker_engine'; +export const Assembly = (worker) => { + const processingEngine = new WorkerProcessingEngine(worker); + const visualisationEngine = new ReactEngine(new ReactFactory(), processingEngine); + processingEngine.eventListener = visualisationEngine.onEvent; + return visualisationEngine; +}; diff --git a/dist/framework/processing/python/worker.d.ts b/dist/framework/processing/python/worker.d.ts new file mode 100644 index 00000000..484861c8 --- /dev/null +++ b/dist/framework/processing/python/worker.d.ts @@ -0,0 +1,8 @@ +declare function runCycle(userInput: any): void; +declare function unwrap(response: any): Promise; +declare function copyFileToPyFS(file: any, resolve: any): void; +declare function initialise(): any; +declare function loadScript(script: any): void; +declare function pyWorker(): string; +declare let pyScript: any; +declare const pyPortApi: "\nclass Event:\n def toDict(self):\n return setType({}, \"Event\")\n\n\nclass EndOfFlow(Event):\n __slots__ = \"result\"\n def __init__(self, result):\n self.result = result\n def translate_result(self):\n print(\"translate\")\n data_output = []\n for data in self.result:\n df = data[\"data_frame\"]\n data_output.append({\"id\": data[\"id\"], \"data_frame\": df.to_json()})\n return {\n \"title\": data[\"title\"],\n \"data\": data_output,\n }\n def toDict(self):\n print(\"toDict2\")\n dict = toDict(super(), \"EndOfFlow\") \n dict = dict | self.translate_result()\n return dict\n \n\nclass Command(Event):\n def toDict(self):\n return toDict(super(), \"Command\")\n\n\nclass Prompt(Command):\n __slots__ = \"title\", \"description\"\n def __init__(self, title, description):\n self.title = title\n self.description = description\n def toDict(self):\n dict = toDict(super(), \"Prompt\")\n dict[\"title\"] = self.title.toDict()\n dict[\"description\"] = self.description.toDict()\n return dict\n\n\nclass FileInput(Prompt):\n __slots__ = \"extensions\"\n def __init__(self, title, description, extensions):\n super().__init__(title, description)\n self.extensions = extensions\n def toDict(self):\n dict = toDict(super(), \"FileInput\")\n dict[\"extensions\"] = self.extensions\n return dict\n\n\nclass RadioInput(Prompt):\n def __init__(self, title, description, items):\n super().__init__(title, description)\n self.items = items\n def toDict(self):\n dict = toDict(super(), \"RadioInput\")\n dict[\"items\"] = self.items\n return dict\n\n\nclass Translatable:\n __slots__ = \"translations\"\n def __init__(self):\n self.translations = {}\n def add(self, locale, text):\n self.translations[locale] = text\n return self\n def toDict(self):\n return setType(self.translations, \"Translatable\")\n\n\ndef toDict(zuper, type):\n return setType(zuper.toDict(), type)\n\n\ndef setType(dict, type):\n key = \"__type__\"\n seperator = \".\"\n\n path = [type]\n if key in dict:\n path.insert(0, dict[key])\n dict[key] = seperator.join(path)\n return dict\n"; diff --git a/dist/framework/processing/python/worker.js b/dist/framework/processing/python/worker.js new file mode 100644 index 00000000..9b9a39c3 --- /dev/null +++ b/dist/framework/processing/python/worker.js @@ -0,0 +1,186 @@ +let pyScript; +onmessage = (event) => { + const { eventType } = event.data; + switch (eventType) { + case 'initialise': + initialise().then(() => { + self.postMessage({ eventType: 'initialiseDone' }); + }); + break; + case 'loadScript': + loadScript(event.data.script); + self.postMessage({ eventType: 'loadScriptDone' }); + break; + case 'firstRunCycle': + pyScript = self.pyodide.runPython(pyWorker()); + runCycle(null); + break; + case 'nextRunCycle': + const { response } = event.data; + unwrap(response).then((userInput) => { + runCycle(userInput); + }); + break; + default: + console.log('[ProcessingWorker] Received unsupported event: ', eventType); + } +}; +function runCycle(userInput) { + scriptEvent = pyScript.send(userInput); + self.postMessage({ + eventType: 'runCycleDone', + scriptEvent: scriptEvent.toJs({ + create_proxies: false, + dict_converter: Object.fromEntries + }) + }); +} +function unwrap(response) { + return new Promise((resolve) => { + switch (response.prompt.__type__) { + case 'Event.Command.Prompt.FileInput': + copyFileToPyFS(response.userInput, resolve); + break; + default: + resolve(response.userInput); + } + }); +} +function copyFileToPyFS(file, resolve) { + const reader = file.stream().getReader(); + const pyFile = self.pyodide.FS.open(file.name, 'w'); + const writeToPyFS = ({ done, value }) => { + if (done) { + resolve(file.name); + } + else { + self.pyodide.FS.write(pyFile, value, 0, value.length); + reader.read().then(writeToPyFS); + } + }; + reader.read().then(writeToPyFS); +} +function initialise() { + importScripts('https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js'); + return loadPyodide({ + indexURL: 'https://cdn.jsdelivr.net/pyodide/v0.21.2/full/' + }).then((pyodide) => { + self.pyodide = pyodide; + return self.pyodide.loadPackage(['micropip', 'numpy', 'pandas']); + }); +} +function loadScript(script) { + console.log('[ProcessingWorker] loadScript'); + self.pyodide.runPython(pyPortApi); + self.pyodide.runPython(script); +} +const pyPortApi = ` +class Event: + def toDict(self): + return setType({}, "Event") + + +class EndOfFlow(Event): + __slots__ = "result" + def __init__(self, result): + self.result = result + def translate_result(self): + print("translate") + data_output = [] + for data in self.result: + df = data["data_frame"] + data_output.append({"id": data["id"], "data_frame": df.to_json()}) + return { + "title": data["title"], + "data": data_output, + } + def toDict(self): + print("toDict2") + dict = toDict(super(), "EndOfFlow") + dict = dict | self.translate_result() + return dict + + +class Command(Event): + def toDict(self): + return toDict(super(), "Command") + + +class Prompt(Command): + __slots__ = "title", "description" + def __init__(self, title, description): + self.title = title + self.description = description + def toDict(self): + dict = toDict(super(), "Prompt") + dict["title"] = self.title.toDict() + dict["description"] = self.description.toDict() + return dict + + +class FileInput(Prompt): + __slots__ = "extensions" + def __init__(self, title, description, extensions): + super().__init__(title, description) + self.extensions = extensions + def toDict(self): + dict = toDict(super(), "FileInput") + dict["extensions"] = self.extensions + return dict + + +class RadioInput(Prompt): + def __init__(self, title, description, items): + super().__init__(title, description) + self.items = items + def toDict(self): + dict = toDict(super(), "RadioInput") + dict["items"] = self.items + return dict + + +class Translatable: + __slots__ = "translations" + def __init__(self): + self.translations = {} + def add(self, locale, text): + self.translations[locale] = text + return self + def toDict(self): + return setType(self.translations, "Translatable") + + +def toDict(zuper, type): + return setType(zuper.toDict(), type) + + +def setType(dict, type): + key = "__type__" + seperator = "." + + path = [type] + if key in dict: + path.insert(0, dict[key]) + dict[key] = seperator.join(path) + return dict +`; +function pyWorker() { + return ` + from collections.abc import Generator + import json + import html + import pandas as pd + + class ScriptWrapper(Generator): + def __init__(self, script): + self.script = script + def send(self, data): + print("toDict") + event = self.script.send(data) + return event.toDict() + def throw(self, type=None, value=None, traceback=None): + raise StopIteration + script = process() + ScriptWrapper(script) + `; +} diff --git a/dist/framework/processing/worker_engine.d.ts b/dist/framework/processing/worker_engine.d.ts new file mode 100644 index 00000000..1fcc2ccd --- /dev/null +++ b/dist/framework/processing/worker_engine.d.ts @@ -0,0 +1,11 @@ +import ProcessingEngine from '../abstractions/processing_engine'; +export default class WorkerProcessingEngine implements ProcessingEngine { + eventListener: (event: any) => void; + worker: Worker; + constructor(worker: Worker); + start(): void; + loadScript(script: any): void; + firstRunCycle(): void; + nextRunCycle(response: any): void; + terminate(): void; +} diff --git a/dist/framework/processing/worker_engine.js b/dist/framework/processing/worker_engine.js new file mode 100644 index 00000000..bf0c299e --- /dev/null +++ b/dist/framework/processing/worker_engine.js @@ -0,0 +1,31 @@ +export default class WorkerProcessingEngine { + eventListener; + worker; + constructor(worker) { + this.eventListener = (event) => { + const eventString = JSON.stringify(event); + console.log('[ProcessingEngine] No event listener registered for event: ', eventString); + }; + this.worker = worker; + this.worker.onerror = console.log; + this.worker.onmessage = (event) => { + console.log('[ProcessingEngine] Received event from worker: ', event.data.eventType); + this.eventListener(event); + }; + } + start() { + this.worker.postMessage({ eventType: 'initialise' }); + } + loadScript(script) { + this.worker.postMessage({ eventType: 'loadScript', script }); + } + firstRunCycle() { + this.worker.postMessage({ eventType: 'firstRunCycle' }); + } + nextRunCycle(response) { + this.worker.postMessage({ eventType: 'nextRunCycle', response }); + } + terminate() { + this.worker.terminate(); + } +} diff --git a/dist/framework/translatable.d.ts b/dist/framework/translatable.d.ts new file mode 100644 index 00000000..ee5888c1 --- /dev/null +++ b/dist/framework/translatable.d.ts @@ -0,0 +1,9 @@ +export default class Translatable { + translations: { + [key: string]: string; + }; + defaultLocale: string; + add(locale: string, text: string): Translatable; + text(locale: string): string; + resolve(locale: string): string; +} diff --git a/dist/framework/translatable.js b/dist/framework/translatable.js new file mode 100644 index 00000000..7cc99051 --- /dev/null +++ b/dist/framework/translatable.js @@ -0,0 +1,26 @@ +import _ from 'lodash'; +export default class Translatable { + translations = {}; + defaultLocale = 'nl'; + add(locale, text) { + this.translations[locale] = text; + return this; + } + text(locale) { + return _.escape(this.resolve(locale)); + } + resolve(locale) { + const text = this.translations[locale]; + if (text !== null) { + return text; + } + const defaultText = this.translations[this.defaultLocale]; + if (defaultText !== null) { + return defaultText; + } + if (Object.values(this.translations).length > 0) { + return Object.values(this.translations)[0]; + } + return '?text?'; + } +} diff --git a/dist/framework/visualisation/element_ref.d.ts b/dist/framework/visualisation/element_ref.d.ts new file mode 100644 index 00000000..966c23fa --- /dev/null +++ b/dist/framework/visualisation/element_ref.d.ts @@ -0,0 +1,15 @@ +export default class ElementRef { + el: Element; + constructor(el: Element); + setInnerText(text: string): void; + setInnerHTML(html: string): void; + onClick(handle: () => void): void; + onChange(handle: () => void): void; + selectedFile(): File | null; + reset(): void; + click(): void; + hide(): void; + show(): void; + child(childId: string): ElementRef; + childs(className: string): ElementRef[]; +} diff --git a/dist/framework/visualisation/element_ref.js b/dist/framework/visualisation/element_ref.js new file mode 100644 index 00000000..3e70f998 --- /dev/null +++ b/dist/framework/visualisation/element_ref.js @@ -0,0 +1,70 @@ +export default class ElementRef { + el; + constructor(el) { + this.el = el; + if (el === null) { + throw new Error('Wrapped element is null'); + } + } + setInnerText(text) { + if (this.el instanceof HTMLElement) { + this.el.innerText = text; + } + } + setInnerHTML(html) { + if (this.el instanceof HTMLElement) { + this.el.innerHTML = html; + } + } + onClick(handle) { + this.el.addEventListener('click', () => { + handle(); + }); + } + onChange(handle) { + this.el.addEventListener('change', () => { + handle(); + }); + } + selectedFile() { + if (this.el instanceof HTMLInputElement) { + if (this.el.files !== null && this.el.files.length > 0) { + this.el.files.item(0); + } + } + return null; + } + reset() { + if (this.el instanceof HTMLInputElement) { + this.el.type = 'text'; + this.el.type = 'file'; + } + } + click() { + if (this.el instanceof HTMLElement) { + this.el.click(); + } + } + hide() { + if (!this.el.classList.contains('hidden')) { + this.el.classList.add('hidden'); + } + } + show() { + this.el.classList.remove('hidden'); + } + child(childId) { + const child = this.el.querySelector(`#${childId}`); + if (child === null) { + throw new Error(`Child not found: ${childId}`); + } + else { + return new ElementRef(child); + } + } + childs(className) { + const elements = this.el.getElementsByClassName(className); + const childs = Array.from(elements); + return childs.map((child) => new ElementRef(child)); + } +} diff --git a/dist/framework/visualisation/react/components/button.d.ts b/dist/framework/visualisation/react/components/button.d.ts new file mode 100644 index 00000000..edc00c46 --- /dev/null +++ b/dist/framework/visualisation/react/components/button.d.ts @@ -0,0 +1,16 @@ +/// +interface ButtonProps { + label: string; + color?: string; + onClick: () => void; +} +export declare const PrimaryButtonFactory: (props: ButtonProps) => JSX.Element; +export declare const PrimaryButton: ({ label, color, onClick }: ButtonProps) => JSX.Element; +interface ButtonProps { + label: string; + color?: string; + onClick: () => void; +} +export declare const SecondaryButtonFactory: (props: ButtonProps) => JSX.Element; +export declare const SecondaryButton: ({ label, color, onClick }: ButtonProps) => JSX.Element; +export {}; diff --git a/dist/framework/visualisation/react/components/button.js b/dist/framework/visualisation/react/components/button.js new file mode 100644 index 00000000..1a224126 --- /dev/null +++ b/dist/framework/visualisation/react/components/button.js @@ -0,0 +1,9 @@ +import { jsx as _jsx } from "react/jsx-runtime"; +export const PrimaryButtonFactory = (props) => _jsx(PrimaryButton, { ...props }); +export const PrimaryButton = ({ label, color = 'bg-primary text-white', onClick }) => { + return (_jsx("div", { className: `pt-15px pb-15px active:shadow-top4px active:pt-4 active:pb-14px leading-none font-button text-button rounded pr-4 pl-4 cursor-pointer ${color}`, onClick: onClick, children: _jsx("div", { id: 'confirm-button', className: 'flex-wrap', children: label }) })); +}; +export const SecondaryButtonFactory = (props) => _jsx(SecondaryButton, { ...props }); +export const SecondaryButton = ({ label, color = 'bg-delete text-delete', onClick }) => { + return (_jsx("div", { className: `pt-13px pb-13px active:pt-14px active:pb-3 active:shadow-top2px border-2 font-button text-button rounded bg-opacity-0 pr-4 pl-4 ${color}`, onClick: onClick, children: _jsx("div", { className: 'flex-wrap', children: label }) })); +}; diff --git a/dist/framework/visualisation/react/components/end_of_flow.d.ts b/dist/framework/visualisation/react/components/end_of_flow.d.ts new file mode 100644 index 00000000..6691a08a --- /dev/null +++ b/dist/framework/visualisation/react/components/end_of_flow.d.ts @@ -0,0 +1,9 @@ +/// +export interface EndOfFlowProps { + title: string; + data: any[]; + locale: string; + resolve: (value: any) => void; +} +export declare const EndOfFlowFactory: (props: EndOfFlowProps) => JSX.Element; +export declare const EndOfFlow: (props: EndOfFlowProps) => JSX.Element; diff --git a/dist/framework/visualisation/react/components/end_of_flow.js b/dist/framework/visualisation/react/components/end_of_flow.js new file mode 100644 index 00000000..47927f01 --- /dev/null +++ b/dist/framework/visualisation/react/components/end_of_flow.js @@ -0,0 +1,47 @@ +import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; +import Translatable from '../../../translatable'; +import { Table } from './table'; +import { PrimaryButton, SecondaryButton } from './button'; +import { Title2 } from './text'; +function prepareCopy({ locale }) { + return { + donateButton: donateButtonLabel().text(locale), + declineButton: declineButtonLabel().text(locale) + }; +} +const donateButtonLabel = () => { + return new Translatable() + .add('en', 'Yes, donate') + .add('nl', 'Ja, doneer'); +}; +const declineButtonLabel = () => { + return new Translatable() + .add('en', 'No') + .add('nl', 'Nee'); +}; +export const EndOfFlowFactory = (props) => _jsx(EndOfFlow, { ...props }); +export const EndOfFlow = (props) => { + const { title, data, resolve } = props; + const { donateButton, declineButton } = prepareCopy(props); + function handleDonate() { + resolve(JSON.stringify(data)); + } + function handleDecline() { + resolve(false); + } + function renderTable(table) { + const id = table.id; + const dataFrame = JSON.parse(table.data_frame); + const rowCount = Object.keys(dataFrame).length; + const header = { cells: Object.keys(dataFrame) }; + const rows = []; + for (let i = 0; i <= rowCount; i++) { + const cells = Object.keys(dataFrame).map((column) => dataFrame[column][`${i}`]); + rows.push({ cells: cells }); + } + const body = { rows: rows }; + return (_jsx(Table, { id: id, header: header, body: body }, id)); + } + const tables = data.map((table) => renderTable(table)); + return (_jsxs(_Fragment, { children: [_jsx(Title2, { text: title }), _jsxs("div", { className: 'flex flex-col gap-4', children: [_jsx("div", { className: 'mb-4', children: tables }), _jsxs("div", { className: 'flex flex-row gap-4', children: [_jsx(PrimaryButton, { label: donateButton, onClick: handleDonate }), _jsx(SecondaryButton, { label: declineButton, onClick: handleDecline })] })] })] })); +}; diff --git a/dist/framework/visualisation/react/components/file_input.d.ts b/dist/framework/visualisation/react/components/file_input.d.ts new file mode 100644 index 00000000..7b87bce2 --- /dev/null +++ b/dist/framework/visualisation/react/components/file_input.d.ts @@ -0,0 +1,9 @@ +/// +export interface FileInputProps { + title: any; + description: any; + extensions: string; + locale: string; + resolve: (value: any) => void; +} +export declare const FileInputFactory: (props: FileInputProps) => JSX.Element; diff --git a/dist/framework/visualisation/react/components/file_input.js b/dist/framework/visualisation/react/components/file_input.js new file mode 100644 index 00000000..1a9f6faf --- /dev/null +++ b/dist/framework/visualisation/react/components/file_input.js @@ -0,0 +1,53 @@ +import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; +import * as React from 'react'; +import Translatable from '../../../translatable'; +function prepareCopy({ title, description, extensions, locale }) { + return { + title: title.en, + description: description.en, + extensions: extensions, + selectButton: selectButtonLabel().text(locale), + continueButton: continueButtonLabel().text(locale), + resetButton: resetButtonLabel().text(locale) + }; +} +export const FileInputFactory = (props) => _jsx(FileInput, { ...props }); +const FileInput = (props) => { + const [selectedFile, setSelectedFile] = React.useState(); + const [confirmHidden, setConfirmHidden] = React.useState(true); + const input = React.useRef(null); + const { resolve } = props; + const { title, description, extensions, selectButton, continueButton, resetButton } = prepareCopy(props); + function handleClick() { + input.current?.click(); + } + function handleReset() { + handleClick(); + } + function handleSelect(event) { + const files = event.target.files; + if (files != null && files.length > 0) { + setSelectedFile(files[0]); + setConfirmHidden(false); + } + } + function handleConfirm() { + resolve(selectedFile); + } + return (_jsxs(_Fragment, { children: [_jsx("div", { className: 'text-title5 font-title5 sm:text-title4 sm:font-title4 lg:text-title3 lg:font-title3 text-grey1', children: title }), _jsx("div", { className: 'mt-8' }), _jsxs("div", { id: 'select-panel', children: [_jsx("div", { className: 'flex-wrap text-bodylarge font-body text-grey1 text-left', children: description }), _jsx("div", { className: 'mt-8' }), _jsx("div", { className: 'flex flex-row', children: _jsx("div", { className: 'flex-wrap cursor-pointer', children: _jsx("div", { id: 'select-button', className: 'pt-15px pb-15px active:shadow-top4px active:pt-4 active:pb-14px leading-none font-button text-button rounded pr-4 pl-4 bg-primary text-white', onClick: handleClick, children: selectButton }) }) }), _jsx("input", { ref: input, id: 'input', type: 'file', className: 'hidden', accept: extensions, onChange: handleSelect }), _jsx("div", { className: 'mt-8' })] }), _jsxs("div", { id: 'confirm-panel', className: confirmHidden ? 'hidden' : '', children: [_jsx("div", { className: 'flex flex-row', children: _jsx("div", { className: 'flex-wrap bg-grey5 rounded', children: _jsx("div", { className: 'flex flex-row h-14 px-5 items-center', children: _jsx("div", { id: 'selected-filename', className: 'flex-wrap text-subhead font-subhead text-grey1', children: selectedFile?.name }) }) }) }), _jsx("div", { className: 'mt-8' }), _jsx("div", { className: 'text-bodylarge font-body text-grey1 text-left', children: "Continue with the selected file, or select again?" }), _jsx("div", { className: 'mt-4' }), _jsxs("div", { className: 'flex flex-row gap-4', children: [_jsx("div", { id: 'confirm-button', className: 'flex-wrap cursor-pointer', children: _jsx("div", { className: 'pt-15px pb-15px active:shadow-top4px active:pt-4 active:pb-14px leading-none font-button text-button rounded pr-4 pl-4 bg-primary text-white', onClick: handleConfirm, children: continueButton }) }), _jsx("div", { id: 'reset-button', className: 'flex-wrap cursor-pointer', children: _jsx("div", { className: 'pt-13px pb-13px active:pt-14px active:pb-3 active:shadow-top2px border-2 font-button text-button rounded bg-opacity-0 pr-4 pl-4 bg-delete text-delete', onClick: handleReset, children: resetButton }) })] })] })] })); +}; +const continueButtonLabel = () => { + return new Translatable() + .add('en', 'Continue') + .add('nl', 'Doorgaan'); +}; +const selectButtonLabel = () => { + return new Translatable() + .add('en', 'Select file') + .add('nl', 'Selecteer bestand'); +}; +const resetButtonLabel = () => { + return new Translatable() + .add('en', 'Select again') + .add('nl', 'Opnieuw'); +}; diff --git a/dist/framework/visualisation/react/components/radio_input.d.ts b/dist/framework/visualisation/react/components/radio_input.d.ts new file mode 100644 index 00000000..64fcecb4 --- /dev/null +++ b/dist/framework/visualisation/react/components/radio_input.d.ts @@ -0,0 +1,17 @@ +/// +export interface RadioInputProps { + title: any; + description: any; + items: string[]; + locale: string; + resolve: (value: any) => void; +} +export declare const RadioInputFactory: (props: RadioInputProps) => JSX.Element; +export declare const RadioInput: (props: RadioInputProps) => JSX.Element; +export interface RadioItemProps { + id: number; + value: string; + selected: boolean; + onSelect: (id: number) => void; +} +export declare const RadioItem: ({ id, value, selected, onSelect }: RadioItemProps) => JSX.Element; diff --git a/dist/framework/visualisation/react/components/radio_input.js b/dist/framework/visualisation/react/components/radio_input.js new file mode 100644 index 00000000..d2ef33c1 --- /dev/null +++ b/dist/framework/visualisation/react/components/radio_input.js @@ -0,0 +1,36 @@ +import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; +import * as React from 'react'; +import Translatable from '../../../translatable'; +import RadioSvg from '../../../../assets/images/radio.svg'; +import RadioActiveSvg from '../../../../assets/images/radio_active.svg'; +function prepareCopy({ title, description, locale }) { + return { + title: title.en, + description: description.en, + continueButton: continueButtonLabel().text(locale) + }; +} +export const RadioInputFactory = (props) => _jsx(RadioInput, { ...props }); +export const RadioInput = (props) => { + const [selectedId, setSelectedId] = React.useState(-1); + const [confirmHidden, setConfirmHidden] = React.useState(true); + const { items, resolve } = props; + const { title, description, continueButton } = prepareCopy(props); + function handleSelect(id) { + setSelectedId(id); + setConfirmHidden(false); + } + function handleConfirm() { + const value = items.at(selectedId); + resolve(value); + } + return (_jsxs(_Fragment, { children: [_jsx("div", { className: 'text-title5 font-title5 sm:text-title4 sm:font-title4 lg:text-title3 lg:font-title3 text-grey1', children: title }), _jsx("div", { className: 'mt-8' }), _jsxs("div", { id: 'select-panel', children: [_jsx("div", { className: 'flex-wrap text-bodylarge font-body text-grey1 text-left', children: description }), _jsx("div", { className: 'mt-4' }), _jsx("div", { children: _jsx("div", { id: 'radio-group', className: 'flex flex-col gap-3', children: items.map((value, index) => _jsx(RadioItem, { onSelect: handleSelect, id: index, value: value, selected: selectedId === index }, index)) }) })] }), _jsx("div", { className: 'mt-8' }), _jsx("div", { className: `flex flex-row ${confirmHidden ? 'hidden' : ''}`, children: _jsx("div", { className: 'pt-15px pb-15px active:shadow-top4px active:pt-4 active:pb-14px leading-none font-button text-button rounded pr-4 pl-4 bg-primary text-white cursor-pointer', onClick: handleConfirm, children: _jsx("div", { id: 'confirm-button', className: 'flex-wrap', children: continueButton }) }) })] })); +}; +const continueButtonLabel = () => { + return new Translatable() + .add('en', 'Continue') + .add('nl', 'Doorgaan'); +}; +export const RadioItem = ({ id, value, selected, onSelect }) => { + return (_jsxs("div", { id: `${id}`, className: 'radio-item flex flex-row gap-3 items-center cursor-pointer', onClick: () => onSelect(id), children: [_jsxs("div", { children: [_jsx("img", { src: RadioSvg, id: `${id}-off`, className: selected ? 'hidden' : '' }), _jsx("img", { src: RadioActiveSvg, id: `${id}-on`, className: selected ? '' : 'hidden' })] }), _jsx("div", { className: 'text-grey1 text-label font-label select-none mt-1', children: value })] })); +}; diff --git a/dist/framework/visualisation/react/components/spinner.d.ts b/dist/framework/visualisation/react/components/spinner.d.ts new file mode 100644 index 00000000..01eefdeb --- /dev/null +++ b/dist/framework/visualisation/react/components/spinner.d.ts @@ -0,0 +1,6 @@ +/// +export interface SpinnerProps { + locale: string; +} +export declare const SpinnerFactory: (props: SpinnerProps) => JSX.Element; +export declare const Spinner: (props: SpinnerProps) => JSX.Element; diff --git a/dist/framework/visualisation/react/components/spinner.js b/dist/framework/visualisation/react/components/spinner.js new file mode 100644 index 00000000..913aa501 --- /dev/null +++ b/dist/framework/visualisation/react/components/spinner.js @@ -0,0 +1,18 @@ +import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; +import Translatable from '../../../translatable'; +import SpinnerSvg from '../../../../assets/images/spinner.svg'; +function prepareCopy({ texts, locale }) { + return { + text: texts.text(locale) + }; +} +const texts = () => { + return new Translatable() + .add('en', 'One moment please') + .add('nl', 'Een moment geduld'); +}; +export const SpinnerFactory = (props) => _jsx(Spinner, { ...props }); +export const Spinner = (props) => { + const { text } = prepareCopy({ texts: texts(), ...props }); + return (_jsxs("div", { id: 'spinner', className: 'flex flex-row items-center gap-4', children: [_jsx("div", { className: 'font-body text-bodymedium text-grey1', children: text }), _jsx("div", { className: 'w-10 h-10', children: _jsx("img", { src: SpinnerSvg }) })] })); +}; diff --git a/dist/framework/visualisation/react/components/table.d.ts b/dist/framework/visualisation/react/components/table.d.ts new file mode 100644 index 00000000..d4e9b3fb --- /dev/null +++ b/dist/framework/visualisation/react/components/table.d.ts @@ -0,0 +1,27 @@ +/// +interface TableProps { + id: string; + header: TableHeadProps; + body: TableBodyProps; +} +export declare const TableFactory: (props: TableProps) => JSX.Element; +export declare const Table: ({ id, header, body }: TableProps) => JSX.Element; +interface TableHeadProps { + cells: string[]; +} +export declare const TableHead: ({ cells }: TableHeadProps) => JSX.Element; +interface TableBodyProps { + rows: TableRowProps[]; +} +export declare const TableBody: ({ rows }: TableBodyProps) => JSX.Element; +interface TableRowProps { + header?: boolean; + cells: string[]; +} +export declare const TableRow: ({ header, cells }: TableRowProps) => JSX.Element; +interface TableCellProps { + header?: boolean; + cell: string; +} +export declare const TableCell: ({ header, cell }: TableCellProps) => JSX.Element; +export {}; diff --git a/dist/framework/visualisation/react/components/table.js b/dist/framework/visualisation/react/components/table.js new file mode 100644 index 00000000..28013cac --- /dev/null +++ b/dist/framework/visualisation/react/components/table.js @@ -0,0 +1,19 @@ +import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; +export const TableFactory = (props) => _jsx(Table, { ...props }); +export const Table = ({ id, header, body }) => { + return (_jsxs("table", { className: 'text-grey1 table-auto', children: [_jsx(TableHead, { ...header }), _jsx(TableBody, { ...body })] })); +}; +export const TableHead = ({ cells }) => { + return (_jsx("thead", { children: _jsx("tr", { children: cells.map((cell, index) => _jsx(TableCell, { header: true, cell: cell }, `${index}`)) }) })); +}; +export const TableBody = ({ rows }) => { + return (_jsx("tbody", { children: rows.map((row, index) => { return (_jsx(TableRow, { ...row }, `${index}`)); }) })); +}; +export const TableRow = ({ header = false, cells }) => { + return (_jsx("tr", { children: cells.map((cell, index) => _jsx(TableCell, { header: header, cell: cell }, `${index}`)) })); +}; +export const TableCell = ({ header = false, cell }) => { + return (header + ? _jsx("th", { className: 'px-2 pb-3 font-button text-button text-left', children: cell }) + : _jsx("td", { className: 'px-2 font-body text-body', children: cell })); +}; diff --git a/dist/framework/visualisation/react/components/text.d.ts b/dist/framework/visualisation/react/components/text.d.ts new file mode 100644 index 00000000..9ea5a266 --- /dev/null +++ b/dist/framework/visualisation/react/components/text.d.ts @@ -0,0 +1,13 @@ +/// +interface TextProps { + text: string; + color?: string; + margin?: string; +} +export declare const Title0Factory: (props: TextProps) => JSX.Element; +export declare const Title0: ({ text, color, margin }: TextProps) => JSX.Element; +export declare const Title1Factory: (props: TextProps) => JSX.Element; +export declare const Title1: ({ text, color, margin }: TextProps) => JSX.Element; +export declare const Title2Factory: (props: TextProps) => JSX.Element; +export declare const Title2: ({ text, color, margin }: TextProps) => JSX.Element; +export {}; diff --git a/dist/framework/visualisation/react/components/text.js b/dist/framework/visualisation/react/components/text.js new file mode 100644 index 00000000..83b2ef7c --- /dev/null +++ b/dist/framework/visualisation/react/components/text.js @@ -0,0 +1,13 @@ +import { jsx as _jsx } from "react/jsx-runtime"; +export const Title0Factory = (props) => _jsx(Title0, { ...props }); +export const Title0 = ({ text, color = 'text-grey1', margin = 'mb-6 md:mb-8 lg:mb-10' }) => { + return (_jsx("div", { className: `text-title4 font-title4 sm:text-title2 sm:font-title2 lg:text-title0 lg:font-title0 ${color} ${margin}`, children: text })); +}; +export const Title1Factory = (props) => _jsx(Title1, { ...props }); +export const Title1 = ({ text, color = 'text-grey1', margin = 'mb-6 md:mb-8 lg:mb-10' }) => { + return (_jsx("div", { className: `text-title3 font-title3 sm:text-title2 lg:text-title1 lg:font-title1 ${color} ${margin}`, children: text })); +}; +export const Title2Factory = (props) => _jsx(Title2, { ...props }); +export const Title2 = ({ text, color = 'text-grey1', margin = 'mb-6 md:mb-8 lg:mb-10' }) => { + return (_jsx("div", { className: `text-title4 font-title4 sm:text-title3 sm:font-title3 lg:text-title2 lg:font-title2 ${color} ${margin}`, children: text })); +}; diff --git a/dist/framework/visualisation/react/engine.d.ts b/dist/framework/visualisation/react/engine.d.ts new file mode 100644 index 00000000..ea128c77 --- /dev/null +++ b/dist/framework/visualisation/react/engine.d.ts @@ -0,0 +1,25 @@ +/// +import * as ReactDOM from 'react-dom/client'; +import VisualisationEngine from '../../abstractions/visualisation_engine'; +import ProcessingEngine from '../../abstractions/processing_engine'; +import VisualisationFactory from './factory'; +export default class ReactEngine implements VisualisationEngine { + factory: VisualisationFactory; + processingEngine: ProcessingEngine; + onEvent: (event: any) => void; + locale: string; + script: string; + root: ReactDOM.Root; + finishFlow: (value: unknown) => void; + constructor(factory: VisualisationFactory, processingEngine: ProcessingEngine); + start(script: string, rootElement: HTMLElement, locale: string): Promise; + terminate(): void; + renderPage(elements: JSX.Element[]): void; + showSpinner(): void; + showStartPage(): void; + showFinalPage(): void; + create(type: string, props?: any): JSX.Element; + handleEvent(event: any): void; + handleRunCycle(scriptEvent: any): void; + renderComponent(data: any): Promise; +} diff --git a/dist/framework/visualisation/react/engine.js b/dist/framework/visualisation/react/engine.js new file mode 100644 index 00000000..0282eef3 --- /dev/null +++ b/dist/framework/visualisation/react/engine.js @@ -0,0 +1,101 @@ +import { jsx as _jsx } from "react/jsx-runtime"; +import * as ReactDOM from 'react-dom/client'; +import { Main } from './main'; +export default class ReactEngine { + factory; + processingEngine; + onEvent; + locale; + script; + root; + finishFlow; + constructor(factory, processingEngine) { + this.factory = factory; + this.processingEngine = processingEngine; + this.onEvent = (event) => { + this.handleEvent(event); + }; + } + async start(script, rootElement, locale) { + console.log('[VisualisationEngine] started'); + this.script = script; + this.root = ReactDOM.createRoot(rootElement); + this.locale = locale; + this.showStartPage(); + this.processingEngine.start(); + return await new Promise((resolve) => { + this.finishFlow = resolve; + }); + } + terminate() { + this.processingEngine.terminate(); + } + renderPage(elements) { + this.root.render(_jsx(Main, { elements: elements })); + } + showSpinner() { + const spinner = this.create('Spinner'); + this.renderPage([spinner]); + } + showStartPage() { + const welcome = this.create('Title0', { text: 'Welcome' }); + const spinner = this.create('Spinner'); + this.renderPage([welcome, spinner]); + } + showFinalPage() { + const thanks = this.create('Title0', { text: 'Thank you' }); + this.renderPage([thanks]); + } + create(type, props = {}) { + return this.factory.createComponent({ __type__: type, ...props }, this.locale, () => { }); + } + handleEvent(event) { + const { eventType } = event.data; + console.log('[VisualisationEngine] received eventType: ', eventType); + switch (eventType) { + case 'initialiseDone': + console.log('[VisualisationEngine] received: initialiseDone'); + this.processingEngine.loadScript(this.script); + break; + case 'loadScriptDone': + console.log('[VisualisationEngine] Received: loadScriptDone'); + this.processingEngine.firstRunCycle(); + break; + case 'runCycleDone': + console.log('[VisualisationEngine] received: event', event.data.scriptEvent); + this.handleRunCycle(event.data.scriptEvent); + break; + default: + console.log('[VisualisationEngine] received unsupported flow event: ', eventType); + } + } + handleRunCycle(scriptEvent) { + console.log('scriptEvent', scriptEvent); + const type = scriptEvent.__type__; + if (type.startsWith('Event.EndOfFlow')) { + this.renderComponent(scriptEvent).then((result) => { + this.showFinalPage(); + this.finishFlow?.(result); + }, null); + return; + } + if (type.startsWith('Event.Command.Prompt')) { + this.renderComponent(scriptEvent).then((userInput) => { + this.showSpinner(); + this.processingEngine.nextRunCycle({ + prompt: scriptEvent, + userInput: userInput + }); + }, null); + return; + } + console.log('[VisualisationEngine] Received unsupported script event: ', type); + } + async renderComponent(data) { + const locale = this.locale; + return await new Promise((resolve) => { + const component = this.factory.createComponent(data, locale, resolve); + this.renderPage([component]); + }); + } +} diff --git a/dist/framework/visualisation/react/factory.d.ts b/dist/framework/visualisation/react/factory.d.ts new file mode 100644 index 00000000..e95b6e46 --- /dev/null +++ b/dist/framework/visualisation/react/factory.d.ts @@ -0,0 +1,9 @@ +/// +export default class ReactFactory { + mapping: { + [name: string]: (props: any) => JSX.Element; + }; + constructor(); + add(factory: (props: any) => JSX.Element, name: string): void; + createComponent(data: any, locale: string, resolve: (value: any) => void): JSX.Element; +} diff --git a/dist/framework/visualisation/react/factory.js b/dist/framework/visualisation/react/factory.js new file mode 100644 index 00000000..b8278699 --- /dev/null +++ b/dist/framework/visualisation/react/factory.js @@ -0,0 +1,33 @@ +import { TableFactory } from './components/table'; +import { SpinnerFactory } from './components/spinner'; +import { FileInputFactory } from './components/file_input'; +import { RadioInputFactory } from './components/radio_input'; +import { EndOfFlowFactory } from './components/end_of_flow'; +import { Title0Factory, Title1Factory, Title2Factory } from './components/text'; +export default class ReactFactory { + mapping = {}; + constructor() { + this.mapping.Table = TableFactory; + this.mapping.Spinner = SpinnerFactory; + this.mapping.FileInput = FileInputFactory; + this.mapping.RadioInput = RadioInputFactory; + this.mapping.EndOfFlow = EndOfFlowFactory; + this.mapping.Title0 = Title0Factory; + this.mapping.Title1 = Title1Factory; + this.mapping.Title2 = Title2Factory; + } + add(factory, name) { + this.mapping[name] = factory; + } + createComponent(data, locale, resolve) { + const type = data.__type__.split('.').pop(); + const props = { ...data, locale, resolve }; + if (this.mapping[type] !== null) { + const factoryMethod = this.mapping[type]; + return factoryMethod(props); + } + else { + throw new Error(`[VisualisationFactory] Received unsupported prompt: ${type}`); + } + } +} diff --git a/dist/framework/visualisation/react/main.d.ts b/dist/framework/visualisation/react/main.d.ts new file mode 100644 index 00000000..17ae6b1c --- /dev/null +++ b/dist/framework/visualisation/react/main.d.ts @@ -0,0 +1,6 @@ +/// +interface MainProps { + elements: JSX.Element[]; +} +export declare const Main: ({ elements }: MainProps) => JSX.Element; +export {}; diff --git a/dist/framework/visualisation/react/main.js b/dist/framework/visualisation/react/main.js new file mode 100644 index 00000000..137c230f --- /dev/null +++ b/dist/framework/visualisation/react/main.js @@ -0,0 +1,5 @@ +import { jsx as _jsx } from "react/jsx-runtime"; +export const Main = ({ elements }) => { + elements = elements.map((element, index) => { return { ...element, key: `${index}` }; }); + return (_jsx("div", { className: 'flex w-full', children: _jsx("div", { className: 'flex-grow m-6 md:8 lg:m-14 max-w-sheet', children: _jsx("div", { className: 'w-full', children: elements }) }) })); +}; diff --git a/dist/py_script.d.ts b/dist/py_script.d.ts new file mode 100644 index 00000000..22807575 --- /dev/null +++ b/dist/py_script.d.ts @@ -0,0 +1 @@ +export declare const PyScript: string; diff --git a/dist/py_script.js b/dist/py_script.js new file mode 100644 index 00000000..2f194769 --- /dev/null +++ b/dist/py_script.js @@ -0,0 +1,64 @@ +export const PyScript = ` +import pandas as pd + + +def process(): + chat_file_name = yield prompt_file() + usernames = extract_usernames(chat_file_name) + username = yield prompt_radio(usernames) + yield result(usernames, username) + + +def prompt_file(): + title = Translatable() + title.add("en", "Step 1: Select the chat file") + title.add("nl", "Stap 1: Selecteer het chat file") + + description = Translatable() + description.add("en", "We previously asked you to export a chat file from Whatsapp. Please select this file so we can extract relevant information for our research.") + description.add("nl", "We hebben je gevraagd een chat bestand te exporteren uit Whatsapp. Je kan deze file nu selecteren zodat wij er relevante informatie uit kunnen halen voor ons onderzoek.") + + extensions = "application/zip, text/plain" + + return FileInput(title, description, extensions) + + +def prompt_radio(usernames): + title = Translatable() + title.add("en", "Step 2: Select your username") + title.add("nl", "Stap 2: Selecteer je gebruikersnaam") + + description = Translatable() + description.add("en", "The following users are extracted from the chat file. Which one are you?") + description.add("nl", "De volgende gebruikers hebben we uit de chat file gehaald. Welke ben jij?") + + return RadioInput(title, description, usernames) + + +def extract_usernames(chat_file_name): + print(f"filename: {chat_file_name}") + + with open(chat_file_name) as chat_file: + while (line := chat_file.readline().rstrip()): + print(line) + + return ["emielvdveen", "a.m.mendrik", "9bitcat"] + + +def result(usernames, selected_username): + data = [] + for username in usernames: + description = "you" if username == selected_username else "-" + data.append((username, description)) + + data_frame = pd.DataFrame(data, columns=["username", "description"]) + + print(data_frame) + + result = [{ + "id": "overview", + "title": "The following usernames where extracted:", + "data_frame": data_frame + }] + return EndOfFlow(result) +`; diff --git a/dist/styles.css b/dist/styles.css new file mode 100644 index 00000000..76de01a4 --- /dev/null +++ b/dist/styles.css @@ -0,0 +1 @@ +/*! tailwindcss v3.1.8 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::-webkit-backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.m-6{margin:1.5rem}.mb-4{margin-bottom:1rem}.mt-8{margin-top:2rem}.mt-4{margin-top:1rem}.mt-1{margin-top:.25rem}.mb-6{margin-bottom:1.5rem}.flex{display:flex}.table{display:table}.hidden{display:none}.h-14{height:3.5rem}.h-10{height:2.5rem}.w-full{width:100%}.w-10{width:2.5rem}.max-w-sheet{max-width:760px}.flex-grow{flex-grow:1}.table-auto{table-layout:auto}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;user-select:none}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.gap-4{gap:1rem}.gap-3{gap:.75rem}.rounded{border-radius:.25rem}.border-2{border-width:2px}.bg-primary{--tw-bg-opacity:1;background-color:rgb(66 114 239/var(--tw-bg-opacity))}.bg-delete{--tw-bg-opacity:1;background-color:rgb(219 30 30/var(--tw-bg-opacity))}.bg-grey5{--tw-bg-opacity:1;background-color:rgb(246 246 246/var(--tw-bg-opacity))}.bg-opacity-0{--tw-bg-opacity:0}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.pt-15px{padding-top:15px}.pb-15px{padding-bottom:15px}.pr-4{padding-right:1rem}.pl-4{padding-left:1rem}.pt-13px{padding-top:13px}.pb-13px{padding-bottom:13px}.pb-3{padding-bottom:.75rem}.text-left{text-align:left}.font-button,.font-title5{font-family:Finador-Bold,sans-serif}.font-body{font-family:Finador-Light,sans-serif}.font-subhead{font-family:Finador-Medium,sans-serif}.font-label{font-family:Finador-Bold,sans-serif}.font-title3,.font-title4{font-family:Finador-Black,sans-serif}.text-button{font-size:18px;line-height:18px}.text-title5{font-size:24px;line-height:26px}.text-bodylarge{font-size:24px;line-height:36px}.text-subhead{font-size:20px;line-height:20px}.text-label{font-size:16px;line-height:16px}.text-bodymedium{font-size:20px;line-height:30px}.text-title4{font-size:28px;line-height:32px}.text-title3{font-size:32px;line-height:38px}.leading-none{line-height:1}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-delete{--tw-text-opacity:1;color:rgb(219 30 30/var(--tw-text-opacity))}.text-grey1{--tw-text-opacity:1;color:rgb(34 34 34/var(--tw-text-opacity))}.active\:pt-4:active{padding-top:1rem}.active\:pb-14px:active{padding-bottom:14px}.active\:pt-14px:active{padding-top:14px}.active\:pb-3:active{padding-bottom:.75rem}.active\:shadow-top4px:active{--tw-shadow:inset 0 4px 0 0 rgba(0,0,0,.15);--tw-shadow-colored:inset 0 4px 0 0 var(--tw-shadow-color)}.active\:shadow-top2px:active,.active\:shadow-top4px:active{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.active\:shadow-top2px:active{--tw-shadow:inset 0 2px 0 0 rgba(0,0,0,.15);--tw-shadow-colored:inset 0 2px 0 0 var(--tw-shadow-color)}@media (min-width:640px){.sm\:font-title2,.sm\:font-title3,.sm\:font-title4{font-family:Finador-Black,sans-serif}.sm\:text-title4{font-size:28px;line-height:32px}.sm\:text-title2{font-size:40px;line-height:44px}.sm\:text-title3{font-size:32px;line-height:38px}}@media (min-width:768px){.md\:mb-8{margin-bottom:2rem}}@media (min-width:1024px){.lg\:m-14{margin:3.5rem}.lg\:mb-10{margin-bottom:2.5rem}.lg\:font-title0,.lg\:font-title3{font-family:Finador-Black,sans-serif}.lg\:font-title1{font-family:Arial,sans-serif}.lg\:font-title2{font-family:Finador-Black,sans-serif}.lg\:text-title3{font-size:32px;line-height:38px}.lg\:text-title0{font-size:64px;line-height:68px}.lg\:text-title1{font-size:50px;line-height:50px}.lg\:text-title2{font-size:40px;line-height:44px}} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index abc1ad49..f894334d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@types/node": "^16.11.59", "@types/react": "^18.0.21", "@types/react-dom": "^18.0.6", + "lodash": "^4.17.21", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", @@ -22,8 +23,10 @@ "web-vitals": "^2.1.4" }, "devDependencies": { + "@types/lodash": "^4.14.185", "autoprefixer": "^10.4.12", "husky": "^8.0.1", + "npm-run-all": "^4.1.5", "postcss": "^8.4.16", "tailwindcss": "^3.1.8", "ts-standard": "^11.0.0" @@ -58,28 +61,28 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.1.tgz", - "integrity": "sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.3.tgz", + "integrity": "sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.1.tgz", - "integrity": "sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-compilation-targets": "^7.19.1", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", "@babel/helper-module-transforms": "^7.19.0", "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.1", + "@babel/parser": "^7.19.3", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -136,11 +139,11 @@ } }, "node_modules/@babel/generator": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz", - "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz", + "integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==", "dependencies": { - "@babel/types": "^7.19.0", + "@babel/types": "^7.19.3", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -185,11 +188,11 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz", - "integrity": "sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "dependencies": { - "@babel/compat-data": "^7.19.1", + "@babel/compat-data": "^7.19.3", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", "semver": "^6.3.0" @@ -563,9 +566,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.1.tgz", - "integrity": "sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.3.tgz", + "integrity": "sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -652,9 +655,9 @@ } }, "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.1.tgz", - "integrity": "sha512-LfIKNBBY7Q1OX5C4xAgRQffOg2OnhAo9fnbcOHgOC9Yytm2Sw+4XqHufRYU86tHomzepxtvuVaNO+3EVKR4ivw==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.3.tgz", + "integrity": "sha512-MbgXtNXqo7RTKYIXVchVJGPvaVufQH3pxvQyfbGvNw1DObIhph+PesYXJTcd8J4DdWibvf6Z2eanOyItX8WnJg==", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.19.0", "@babel/helper-plugin-utils": "^7.19.0", @@ -1676,9 +1679,9 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.1.tgz", - "integrity": "sha512-+ILcOU+6mWLlvCwnL920m2Ow3wWx3Wo8n2t5aROQmV55GZt+hOiLvBaa3DNzRjSEHa1aauRs4/YLmkCfFkhhRQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.3.tgz", + "integrity": "sha512-z6fnuK9ve9u/0X0rRvI9MY0xg+DOUaABDYOe+/SQTxtlptaBB/V9JIUxJn6xp3lMBeb9qe8xSFmHU35oZDXD+w==", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.19.0", "@babel/helper-plugin-utils": "^7.19.0", @@ -1721,12 +1724,12 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.1.tgz", - "integrity": "sha512-c8B2c6D16Lp+Nt6HcD+nHl0VbPKVnNPTpszahuxJJnurfMtKeZ80A+qUv48Y7wqvS+dTFuLuaM9oYxyNHbCLWA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.3.tgz", + "integrity": "sha512-ziye1OTc9dGFOAXSWKUqQblYHNlBOaDl8wzqf2iKXJAltYiR3hKHUKmkt+S9PppW7RQpq4fFCrwwpIDj/f5P4w==", "dependencies": { - "@babel/compat-data": "^7.19.1", - "@babel/helper-compilation-targets": "^7.19.1", + "@babel/compat-data": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", "@babel/helper-plugin-utils": "^7.19.0", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", @@ -1794,7 +1797,7 @@ "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.19.0", + "@babel/types": "^7.19.3", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -1903,18 +1906,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.1.tgz", - "integrity": "sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz", + "integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==", "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", + "@babel/generator": "^7.19.3", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.1", - "@babel/types": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/types": "^7.19.3", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1923,12 +1926,12 @@ } }, "node_modules/@babel/types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz", - "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.3.tgz", + "integrity": "sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==", "dependencies": { "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, "engines": { @@ -2275,9 +2278,9 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", - "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", @@ -2914,9 +2917,9 @@ "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" }, "node_modules/@sinclair/typebox": { - "version": "0.24.42", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.42.tgz", - "integrity": "sha512-d+2AtrHGyWek2u2ITF0lHRIv6Tt7X0dEHW+0rP+5aDCEjC3fiN2RBjrLD0yU0at52BcZbRGxLbAtXiR0hFCjYw==" + "version": "0.24.44", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.44.tgz", + "integrity": "sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg==" }, "node_modules/@sinonjs/commons": { "version": "1.8.3", @@ -3286,9 +3289,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.1.tgz", - "integrity": "sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", + "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", "dependencies": { "@babel/types": "^7.3.0" } @@ -3432,15 +3435,21 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/lodash": { + "version": "4.14.186", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.186.tgz", + "integrity": "sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==", + "dev": true + }, "node_modules/@types/mime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "node_modules/@types/node": { - "version": "16.11.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.60.tgz", - "integrity": "sha512-kYIYa1D1L+HDv5M5RXQeEu1o0FKA6yedZIoyugm/MBPROkLpX4L7HRxMrPVyo8bnvjpW/wDlqFNGzXNMb7AdRw==" + "version": "16.11.62", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.62.tgz", + "integrity": "sha512-K/ggecSdwAAy2NUW4WKmF4Rc03GKbsfP+k326UWgckoS+Rzd2PaWbjk76dSmqdLQvLTJAO9axiTUJ6488mFsYQ==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -3448,9 +3457,9 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "node_modules/@types/prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", - "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==" + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==" }, "node_modules/@types/prop-types": { "version": "15.7.5", @@ -3573,13 +3582,13 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.0.tgz", - "integrity": "sha512-GgHi/GNuUbTOeoJiEANi0oI6fF3gBQc3bGFYj40nnAPCbhrtEDf2rjBmefFadweBmO1Du1YovHeDP2h5JLhtTQ==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.1.tgz", + "integrity": "sha512-ky7EFzPhqz3XlhS7vPOoMDaQnQMn+9o5ICR9CPr/6bw8HrFkzhMSxuA3gRfiJVvs7geYrSeawGJjZoZQKCOglQ==", "dependencies": { - "@typescript-eslint/scope-manager": "5.38.0", - "@typescript-eslint/type-utils": "5.38.0", - "@typescript-eslint/utils": "5.38.0", + "@typescript-eslint/scope-manager": "5.38.1", + "@typescript-eslint/type-utils": "5.38.1", + "@typescript-eslint/utils": "5.38.1", "debug": "^4.3.4", "ignore": "^5.2.0", "regexpp": "^3.2.0", @@ -3603,12 +3612,26 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.38.0.tgz", - "integrity": "sha512-kzXBRfvGlicgGk4CYuRUqKvwc2s3wHXNssUWWJU18bhMRxriFm3BZWyQ6vEHBRpEIMKB6b7MIQHO+9lYlts19w==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.38.1.tgz", + "integrity": "sha512-Zv0EcU0iu64DiVG3pRZU0QYCgANO//U1fS3oEs3eqHD1eIVVcQsFd/T01ckaNbL2H2aCqRojY2xZuMAPcOArEA==", "dependencies": { - "@typescript-eslint/utils": "5.38.0" + "@typescript-eslint/utils": "5.38.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3622,13 +3645,13 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.38.0.tgz", - "integrity": "sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.38.1.tgz", + "integrity": "sha512-LDqxZBVFFQnQRz9rUZJhLmox+Ep5kdUmLatLQnCRR6523YV+XhRjfYzStQ4MheFA8kMAfUlclHSbu+RKdRwQKw==", "dependencies": { - "@typescript-eslint/scope-manager": "5.38.0", - "@typescript-eslint/types": "5.38.0", - "@typescript-eslint/typescript-estree": "5.38.0", + "@typescript-eslint/scope-manager": "5.38.1", + "@typescript-eslint/types": "5.38.1", + "@typescript-eslint/typescript-estree": "5.38.1", "debug": "^4.3.4" }, "engines": { @@ -3648,12 +3671,12 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.0.tgz", - "integrity": "sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz", + "integrity": "sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==", "dependencies": { - "@typescript-eslint/types": "5.38.0", - "@typescript-eslint/visitor-keys": "5.38.0" + "@typescript-eslint/types": "5.38.1", + "@typescript-eslint/visitor-keys": "5.38.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3664,12 +3687,12 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.38.0.tgz", - "integrity": "sha512-iZq5USgybUcj/lfnbuelJ0j3K9dbs1I3RICAJY9NZZpDgBYXmuUlYQGzftpQA9wC8cKgtS6DASTvF3HrXwwozA==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.38.1.tgz", + "integrity": "sha512-UU3j43TM66gYtzo15ivK2ZFoDFKKP0k03MItzLdq0zV92CeGCXRfXlfQX5ILdd4/DSpHkSjIgLLLh1NtkOJOAw==", "dependencies": { - "@typescript-eslint/typescript-estree": "5.38.0", - "@typescript-eslint/utils": "5.38.0", + "@typescript-eslint/typescript-estree": "5.38.1", + "@typescript-eslint/utils": "5.38.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -3690,9 +3713,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.0.tgz", - "integrity": "sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz", + "integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -3702,12 +3725,12 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.0.tgz", - "integrity": "sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz", + "integrity": "sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==", "dependencies": { - "@typescript-eslint/types": "5.38.0", - "@typescript-eslint/visitor-keys": "5.38.0", + "@typescript-eslint/types": "5.38.1", + "@typescript-eslint/visitor-keys": "5.38.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -3727,15 +3750,29 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@typescript-eslint/utils": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.0.tgz", - "integrity": "sha512-6sdeYaBgk9Fh7N2unEXGz+D+som2QCQGPAf1SxrkEr+Z32gMreQ0rparXTNGRRfYUWk/JzbGdcM8NSSd6oqnTA==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.1.tgz", + "integrity": "sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA==", "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.38.0", - "@typescript-eslint/types": "5.38.0", - "@typescript-eslint/typescript-estree": "5.38.0", + "@typescript-eslint/scope-manager": "5.38.1", + "@typescript-eslint/types": "5.38.1", + "@typescript-eslint/typescript-estree": "5.38.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -3771,11 +3808,11 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.0.tgz", - "integrity": "sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz", + "integrity": "sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==", "dependencies": { - "@typescript-eslint/types": "5.38.0", + "@typescript-eslint/types": "5.38.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -4848,9 +4885,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001410", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001410.tgz", - "integrity": "sha512-QoblBnuE+rG0lc3Ur9ltP5q47lbguipa/ncNMyyGuqPk44FxbScWAeEO+k5fSQ8WekdAK4mWqNs1rADDAiN5xQ==", + "version": "1.0.30001414", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz", + "integrity": "sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==", "funding": [ { "type": "opencollective", @@ -5255,9 +5292,9 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/core-js": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.2.tgz", - "integrity": "sha512-YB4IAT1bjEfxTJ1XYy11hJAKskO+qmhuDBM8/guIfMz4JvdsAQAqvyb97zXX7JgSrfPLG5mRGFWJwJD39ruq2A==", + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.3.tgz", + "integrity": "sha512-y1hvKXmPHvm5B7w4ln1S4uc9eV/O5+iFExSRUimnvIph11uaizFR8LFMdONN8hG3P2pipUfX4Y/fR8rAEtcHcQ==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5265,9 +5302,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.2.tgz", - "integrity": "sha512-TxfyECD4smdn3/CjWxczVtJqVLEEC2up7/82t7vC0AzNogr+4nQ8vyF7abxAuTXWvjTClSbvGhU0RgqA4ToQaQ==", + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.3.tgz", + "integrity": "sha512-xVtYpJQ5grszDHEUU9O7XbjjcZ0ccX3LgQsyqSvTnjX97ZqEgn9F5srmrwwwMtbKzDllyFPL+O+2OFMl1lU4TQ==", "dependencies": { "browserslist": "^4.21.4" }, @@ -5277,9 +5314,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.2.tgz", - "integrity": "sha512-ItD7YpW1cUB4jaqFLZXe1AXkyqIxz6GqPnsDV4uF4hVcWh/WAGIqSqw5p0/WdsILM0Xht9s3Koyw05R3K6RtiA==", + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.3.tgz", + "integrity": "sha512-T/7qvgv70MEvRkZ8p6BasLZmOVYKzOaWNBEHAU8FmveCJkl4nko2quqPQOmy6AJIp5MBanhz9no3A94NoRb0XA==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5307,16 +5344,19 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" }, "engines": { - "node": ">= 8" + "node": ">=4.8" } }, "node_modules/crypto-random-string": { @@ -5397,6 +5437,20 @@ "webpack": "^5.0.0" } }, + "node_modules/css-loader/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/css-minimizer-webpack-plugin": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", @@ -6081,9 +6135,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.258", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.258.tgz", - "integrity": "sha512-vutF4q0dTUXoAFI7Vbtdwen/BJVwPgj8GRg/SElOodfH7VTX+svUe62A5BG41QRQGk5HsZPB0M++KH1lAlOt0A==" + "version": "1.4.270", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.270.tgz", + "integrity": "sha512-KNhIzgLiJmDDC444dj9vEOpZEgsV96ult9Iff98Vanumn+ShJHd5se8aX6KeVxdc0YQeqdrezBZv89rleDbvSg==" }, "node_modules/emittery": { "version": "0.8.1", @@ -6338,12 +6392,12 @@ } }, "node_modules/eslint": { - "version": "8.23.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.1.tgz", - "integrity": "sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "dependencies": { "@eslint/eslintrc": "^1.3.2", - "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/config-array": "^0.10.5", "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", @@ -6929,6 +6983,19 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/eslint/node_modules/globals": { "version": "13.17.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", @@ -6954,6 +7021,33 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/eslint/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -6965,6 +7059,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/espree": { "version": "9.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", @@ -7079,6 +7187,60 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -7504,6 +7666,20 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -7764,17 +7940,6 @@ "node": ">=6" } }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -7915,6 +8080,12 @@ "node": ">= 6.0.0" } }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, "node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -8333,9 +8504,9 @@ } }, "node_modules/is-callable": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.6.tgz", - "integrity": "sha512-krO72EO2NptOGAX2KYyqbP9vYMlNAXdB53rq6f8LXY6RY7JdSR/3BD6wLUlPHSAesmY9vstNrjvqGaCiRK/91Q==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "engines": { "node": ">= 0.4" }, @@ -9186,6 +9357,20 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jest-util": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", @@ -9293,9 +9478,9 @@ } }, "node_modules/jest-watch-typeahead/node_modules/@types/yargs": { - "version": "17.0.12", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz", - "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==", + "version": "17.0.13", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", + "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", "dependencies": { "@types/yargs-parser": "*" } @@ -9537,9 +9722,9 @@ } }, "node_modules/js-sdsl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", - "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==" + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -9753,19 +9938,18 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/load-json-file": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, "dependencies": { - "graceful-fs": "^4.1.15", + "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0", - "type-fest": "^0.3.0" + "pify": "^3.0.0", + "strip-bom": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=4" } }, "node_modules/load-json-file/node_modules/parse-json": { @@ -9781,15 +9965,6 @@ "node": ">=4" } }, - "node_modules/load-json-file/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/load-json-file/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -9799,15 +9974,6 @@ "node": ">=4" } }, - "node_modules/load-json-file/node_modules/type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -9979,6 +10145,15 @@ "node": ">= 4.0.0" } }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -10208,6 +10383,12 @@ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -10235,6 +10416,18 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -10262,14 +10455,118 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, "dependencies": { - "path-key": "^3.0.0" + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" }, - "engines": { + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm-run-all/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/npm-run-all/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/npm-run-all/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/npm-run-all/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-all/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { "node": ">=8" } }, @@ -10614,11 +10911,12 @@ } }, "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/path-parse": { @@ -10660,12 +10958,25 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, "node_modules/pirates": { @@ -10701,6 +11012,22 @@ "node": ">=6" } }, + "node_modules/pkg-conf/node_modules/load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/pkg-conf/node_modules/locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -10741,6 +11068,19 @@ "node": ">=6" } }, + "node_modules/pkg-conf/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/pkg-conf/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -10750,6 +11090,33 @@ "node": ">=4" } }, + "node_modules/pkg-conf/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-conf/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-conf/node_modules/type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -10877,9 +11244,9 @@ } }, "node_modules/postcss": { - "version": "8.4.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", - "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "version": "8.4.17", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz", + "integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==", "funding": [ { "type": "opencollective", @@ -11377,6 +11744,20 @@ "webpack": "^5.0.0" } }, + "node_modules/postcss-loader/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/postcss-logical": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-5.0.4.tgz", @@ -12350,6 +12731,19 @@ "node": ">=14" } }, + "node_modules/react-dev-utils/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/react-dev-utils/node_modules/loader-utils": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", @@ -12358,6 +12752,47 @@ "node": ">= 12.13.0" } }, + "node_modules/react-dev-utils/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/react-dev-utils/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/react-dom": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", @@ -12460,6 +12895,20 @@ } } }, + "node_modules/react-scripts/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -12468,6 +12917,40 @@ "pify": "^2.3.0" } }, + "node_modules/read-cache/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -12992,17 +13475,12 @@ } }, "node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "semver": "bin/semver" } }, "node_modules/send": { @@ -13144,22 +13622,24 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, "dependencies": { - "shebang-regex": "^3.0.0" + "shebang-regex": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, "node_modules/shell-quote": { @@ -13288,6 +13768,38 @@ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "dev": true + }, "node_modules/spdy": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", @@ -13468,6 +13980,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/string.prototype.padend": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz", + "integrity": "sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.trimend": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", @@ -14322,6 +14851,20 @@ "node": ">=0.4.0" } }, + "node_modules/ts-standard/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/ts-standard/node_modules/eslint": { "version": "7.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", @@ -14573,6 +15116,51 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ts-standard/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-standard/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-standard/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-standard/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/ts-standard/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -14585,6 +15173,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ts-standard/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -14690,9 +15293,9 @@ } }, "node_modules/typescript": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", - "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==", + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -14893,6 +15496,16 @@ "node": ">=10.12.0" } }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -15333,17 +15946,14 @@ } }, "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dependencies": { "isexe": "^2.0.0" }, "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" + "which": "bin/which" } }, "node_modules/which-boxed-primitive": { @@ -15824,25 +16434,25 @@ } }, "@babel/compat-data": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.1.tgz", - "integrity": "sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==" + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.3.tgz", + "integrity": "sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==" }, "@babel/core": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.1.tgz", - "integrity": "sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-compilation-targets": "^7.19.1", + "@babel/generator": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", "@babel/helper-module-transforms": "^7.19.0", "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.1", + "@babel/parser": "^7.19.3", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0", + "@babel/traverse": "^7.19.3", + "@babel/types": "^7.19.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -15880,11 +16490,11 @@ } }, "@babel/generator": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz", - "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz", + "integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==", "requires": { - "@babel/types": "^7.19.0", + "@babel/types": "^7.19.3", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -15919,11 +16529,11 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz", - "integrity": "sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "requires": { - "@babel/compat-data": "^7.19.1", + "@babel/compat-data": "^7.19.3", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", "semver": "^6.3.0" @@ -16198,9 +16808,9 @@ } }, "@babel/parser": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.1.tgz", - "integrity": "sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==" + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.3.tgz", + "integrity": "sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", @@ -16251,9 +16861,9 @@ } }, "@babel/plugin-proposal-decorators": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.1.tgz", - "integrity": "sha512-LfIKNBBY7Q1OX5C4xAgRQffOg2OnhAo9fnbcOHgOC9Yytm2Sw+4XqHufRYU86tHomzepxtvuVaNO+3EVKR4ivw==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.3.tgz", + "integrity": "sha512-MbgXtNXqo7RTKYIXVchVJGPvaVufQH3pxvQyfbGvNw1DObIhph+PesYXJTcd8J4DdWibvf6Z2eanOyItX8WnJg==", "requires": { "@babel/helper-create-class-features-plugin": "^7.19.0", "@babel/helper-plugin-utils": "^7.19.0", @@ -16887,9 +17497,9 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.1.tgz", - "integrity": "sha512-+ILcOU+6mWLlvCwnL920m2Ow3wWx3Wo8n2t5aROQmV55GZt+hOiLvBaa3DNzRjSEHa1aauRs4/YLmkCfFkhhRQ==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.3.tgz", + "integrity": "sha512-z6fnuK9ve9u/0X0rRvI9MY0xg+DOUaABDYOe+/SQTxtlptaBB/V9JIUxJn6xp3lMBeb9qe8xSFmHU35oZDXD+w==", "requires": { "@babel/helper-create-class-features-plugin": "^7.19.0", "@babel/helper-plugin-utils": "^7.19.0", @@ -16914,12 +17524,12 @@ } }, "@babel/preset-env": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.1.tgz", - "integrity": "sha512-c8B2c6D16Lp+Nt6HcD+nHl0VbPKVnNPTpszahuxJJnurfMtKeZ80A+qUv48Y7wqvS+dTFuLuaM9oYxyNHbCLWA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.3.tgz", + "integrity": "sha512-ziye1OTc9dGFOAXSWKUqQblYHNlBOaDl8wzqf2iKXJAltYiR3hKHUKmkt+S9PppW7RQpq4fFCrwwpIDj/f5P4w==", "requires": { - "@babel/compat-data": "^7.19.1", - "@babel/helper-compilation-targets": "^7.19.1", + "@babel/compat-data": "^7.19.3", + "@babel/helper-compilation-targets": "^7.19.3", "@babel/helper-plugin-utils": "^7.19.0", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", @@ -16987,7 +17597,7 @@ "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.19.0", + "@babel/types": "^7.19.3", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -17065,29 +17675,29 @@ } }, "@babel/traverse": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.1.tgz", - "integrity": "sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz", + "integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==", "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", + "@babel/generator": "^7.19.3", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.1", - "@babel/types": "^7.19.0", + "@babel/parser": "^7.19.3", + "@babel/types": "^7.19.3", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.0.tgz", - "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==", + "version": "7.19.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.3.tgz", + "integrity": "sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==", "requires": { "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, @@ -17267,9 +17877,9 @@ } }, "@humanwhocodes/config-array": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", - "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz", + "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==", "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", @@ -17733,9 +18343,9 @@ "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" }, "@sinclair/typebox": { - "version": "0.24.42", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.42.tgz", - "integrity": "sha512-d+2AtrHGyWek2u2ITF0lHRIv6Tt7X0dEHW+0rP+5aDCEjC3fiN2RBjrLD0yU0at52BcZbRGxLbAtXiR0hFCjYw==" + "version": "0.24.44", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.44.tgz", + "integrity": "sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg==" }, "@sinonjs/commons": { "version": "1.8.3", @@ -17978,9 +18588,9 @@ } }, "@types/babel__traverse": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.1.tgz", - "integrity": "sha512-FSdLaZh2UxaMuLp9lixWaHq/golWTRWOnRsAXzDTDSDOQLuZb1nsdCt6pJSPWSEQt2eFZ2YVk3oYhn+1kLMeMA==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", + "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", "requires": { "@babel/types": "^7.3.0" } @@ -18124,15 +18734,21 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "@types/lodash": { + "version": "4.14.186", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.186.tgz", + "integrity": "sha512-eHcVlLXP0c2FlMPm56ITode2AgLMSa6aJ05JTTbYbI+7EMkCEE5qk2E41d5g2lCVTqRe0GnnRFurmlCsDODrPw==", + "dev": true + }, "@types/mime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==" }, "@types/node": { - "version": "16.11.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.60.tgz", - "integrity": "sha512-kYIYa1D1L+HDv5M5RXQeEu1o0FKA6yedZIoyugm/MBPROkLpX4L7HRxMrPVyo8bnvjpW/wDlqFNGzXNMb7AdRw==" + "version": "16.11.62", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.62.tgz", + "integrity": "sha512-K/ggecSdwAAy2NUW4WKmF4Rc03GKbsfP+k326UWgckoS+Rzd2PaWbjk76dSmqdLQvLTJAO9axiTUJ6488mFsYQ==" }, "@types/parse-json": { "version": "4.0.0", @@ -18140,9 +18756,9 @@ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, "@types/prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", - "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==" + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==" }, "@types/prop-types": { "version": "15.7.5", @@ -18265,87 +18881,107 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "@typescript-eslint/eslint-plugin": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.0.tgz", - "integrity": "sha512-GgHi/GNuUbTOeoJiEANi0oI6fF3gBQc3bGFYj40nnAPCbhrtEDf2rjBmefFadweBmO1Du1YovHeDP2h5JLhtTQ==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.1.tgz", + "integrity": "sha512-ky7EFzPhqz3XlhS7vPOoMDaQnQMn+9o5ICR9CPr/6bw8HrFkzhMSxuA3gRfiJVvs7geYrSeawGJjZoZQKCOglQ==", "requires": { - "@typescript-eslint/scope-manager": "5.38.0", - "@typescript-eslint/type-utils": "5.38.0", - "@typescript-eslint/utils": "5.38.0", + "@typescript-eslint/scope-manager": "5.38.1", + "@typescript-eslint/type-utils": "5.38.1", + "@typescript-eslint/utils": "5.38.1", "debug": "^4.3.4", "ignore": "^5.2.0", "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "@typescript-eslint/experimental-utils": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.38.0.tgz", - "integrity": "sha512-kzXBRfvGlicgGk4CYuRUqKvwc2s3wHXNssUWWJU18bhMRxriFm3BZWyQ6vEHBRpEIMKB6b7MIQHO+9lYlts19w==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.38.1.tgz", + "integrity": "sha512-Zv0EcU0iu64DiVG3pRZU0QYCgANO//U1fS3oEs3eqHD1eIVVcQsFd/T01ckaNbL2H2aCqRojY2xZuMAPcOArEA==", "requires": { - "@typescript-eslint/utils": "5.38.0" + "@typescript-eslint/utils": "5.38.1" } }, "@typescript-eslint/parser": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.38.0.tgz", - "integrity": "sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.38.1.tgz", + "integrity": "sha512-LDqxZBVFFQnQRz9rUZJhLmox+Ep5kdUmLatLQnCRR6523YV+XhRjfYzStQ4MheFA8kMAfUlclHSbu+RKdRwQKw==", "requires": { - "@typescript-eslint/scope-manager": "5.38.0", - "@typescript-eslint/types": "5.38.0", - "@typescript-eslint/typescript-estree": "5.38.0", + "@typescript-eslint/scope-manager": "5.38.1", + "@typescript-eslint/types": "5.38.1", + "@typescript-eslint/typescript-estree": "5.38.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.0.tgz", - "integrity": "sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz", + "integrity": "sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==", "requires": { - "@typescript-eslint/types": "5.38.0", - "@typescript-eslint/visitor-keys": "5.38.0" + "@typescript-eslint/types": "5.38.1", + "@typescript-eslint/visitor-keys": "5.38.1" } }, "@typescript-eslint/type-utils": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.38.0.tgz", - "integrity": "sha512-iZq5USgybUcj/lfnbuelJ0j3K9dbs1I3RICAJY9NZZpDgBYXmuUlYQGzftpQA9wC8cKgtS6DASTvF3HrXwwozA==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.38.1.tgz", + "integrity": "sha512-UU3j43TM66gYtzo15ivK2ZFoDFKKP0k03MItzLdq0zV92CeGCXRfXlfQX5ILdd4/DSpHkSjIgLLLh1NtkOJOAw==", "requires": { - "@typescript-eslint/typescript-estree": "5.38.0", - "@typescript-eslint/utils": "5.38.0", + "@typescript-eslint/typescript-estree": "5.38.1", + "@typescript-eslint/utils": "5.38.1", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.0.tgz", - "integrity": "sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA==" + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz", + "integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==" }, "@typescript-eslint/typescript-estree": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.0.tgz", - "integrity": "sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz", + "integrity": "sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==", "requires": { - "@typescript-eslint/types": "5.38.0", - "@typescript-eslint/visitor-keys": "5.38.0", + "@typescript-eslint/types": "5.38.1", + "@typescript-eslint/visitor-keys": "5.38.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", "semver": "^7.3.7", "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "@typescript-eslint/utils": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.0.tgz", - "integrity": "sha512-6sdeYaBgk9Fh7N2unEXGz+D+som2QCQGPAf1SxrkEr+Z32gMreQ0rparXTNGRRfYUWk/JzbGdcM8NSSd6oqnTA==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.1.tgz", + "integrity": "sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA==", "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.38.0", - "@typescript-eslint/types": "5.38.0", - "@typescript-eslint/typescript-estree": "5.38.0", + "@typescript-eslint/scope-manager": "5.38.1", + "@typescript-eslint/types": "5.38.1", + "@typescript-eslint/typescript-estree": "5.38.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -18367,11 +19003,11 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.38.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.0.tgz", - "integrity": "sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz", + "integrity": "sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==", "requires": { - "@typescript-eslint/types": "5.38.0", + "@typescript-eslint/types": "5.38.1", "eslint-visitor-keys": "^3.3.0" } }, @@ -19194,9 +19830,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001410", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001410.tgz", - "integrity": "sha512-QoblBnuE+rG0lc3Ur9ltP5q47lbguipa/ncNMyyGuqPk44FxbScWAeEO+k5fSQ8WekdAK4mWqNs1rADDAiN5xQ==" + "version": "1.0.30001414", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001414.tgz", + "integrity": "sha512-t55jfSaWjCdocnFdKQoO+d2ct9C59UZg4dY3OnUlSZ447r8pUtIKdp0hpAzrGFultmTC+Us+KpKi4GZl/LXlFg==" }, "case-sensitive-paths-webpack-plugin": { "version": "2.4.0", @@ -19500,22 +20136,22 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "core-js": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.2.tgz", - "integrity": "sha512-YB4IAT1bjEfxTJ1XYy11hJAKskO+qmhuDBM8/guIfMz4JvdsAQAqvyb97zXX7JgSrfPLG5mRGFWJwJD39ruq2A==" + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.25.3.tgz", + "integrity": "sha512-y1hvKXmPHvm5B7w4ln1S4uc9eV/O5+iFExSRUimnvIph11uaizFR8LFMdONN8hG3P2pipUfX4Y/fR8rAEtcHcQ==" }, "core-js-compat": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.2.tgz", - "integrity": "sha512-TxfyECD4smdn3/CjWxczVtJqVLEEC2up7/82t7vC0AzNogr+4nQ8vyF7abxAuTXWvjTClSbvGhU0RgqA4ToQaQ==", + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.3.tgz", + "integrity": "sha512-xVtYpJQ5grszDHEUU9O7XbjjcZ0ccX3LgQsyqSvTnjX97ZqEgn9F5srmrwwwMtbKzDllyFPL+O+2OFMl1lU4TQ==", "requires": { "browserslist": "^4.21.4" } }, "core-js-pure": { - "version": "3.25.2", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.2.tgz", - "integrity": "sha512-ItD7YpW1cUB4jaqFLZXe1AXkyqIxz6GqPnsDV4uF4hVcWh/WAGIqSqw5p0/WdsILM0Xht9s3Koyw05R3K6RtiA==" + "version": "3.25.3", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.25.3.tgz", + "integrity": "sha512-T/7qvgv70MEvRkZ8p6BasLZmOVYKzOaWNBEHAU8FmveCJkl4nko2quqPQOmy6AJIp5MBanhz9no3A94NoRb0XA==" }, "core-util-is": { "version": "1.0.3", @@ -19535,13 +20171,16 @@ } }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "crypto-random-string": { @@ -19584,6 +20223,16 @@ "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", "semver": "^7.3.5" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "css-minimizer-webpack-plugin": { @@ -20078,9 +20727,9 @@ } }, "electron-to-chromium": { - "version": "1.4.258", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.258.tgz", - "integrity": "sha512-vutF4q0dTUXoAFI7Vbtdwen/BJVwPgj8GRg/SElOodfH7VTX+svUe62A5BG41QRQGk5HsZPB0M++KH1lAlOt0A==" + "version": "1.4.270", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.270.tgz", + "integrity": "sha512-KNhIzgLiJmDDC444dj9vEOpZEgsV96ult9Iff98Vanumn+ShJHd5se8aX6KeVxdc0YQeqdrezBZv89rleDbvSg==" }, "emittery": { "version": "0.8.1", @@ -20271,12 +20920,12 @@ } }, "eslint": { - "version": "8.23.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.1.tgz", - "integrity": "sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg==", + "version": "8.24.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", + "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", "requires": { "@eslint/eslintrc": "^1.3.2", - "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/config-array": "^0.10.5", "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", @@ -20321,6 +20970,16 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "globals": { "version": "13.17.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", @@ -20337,10 +20996,36 @@ "argparse": "^2.0.1" } }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -20793,6 +21478,44 @@ "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + } } }, "exit": { @@ -21111,6 +21834,14 @@ "ajv-keywords": "^3.4.1" } }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + }, "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -21288,16 +22019,6 @@ "ini": "^1.3.5", "kind-of": "^6.0.2", "which": "^1.3.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - } } }, "globals": { @@ -21395,6 +22116,12 @@ "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==" }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, "hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -21696,9 +22423,9 @@ } }, "is-callable": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.6.tgz", - "integrity": "sha512-krO72EO2NptOGAX2KYyqbP9vYMlNAXdB53rq6f8LXY6RY7JdSR/3BD6wLUlPHSAesmY9vstNrjvqGaCiRK/91Q==" + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" }, "is-core-module": { "version": "2.10.0", @@ -22311,6 +23038,16 @@ "natural-compare": "^1.4.0", "pretty-format": "^27.5.1", "semver": "^7.3.2" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "jest-util": { @@ -22398,9 +23135,9 @@ } }, "@types/yargs": { - "version": "17.0.12", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.12.tgz", - "integrity": "sha512-Nz4MPhecOFArtm81gFQvQqdV7XYCrWKx5uUt6GNHredFHn1i2mtWqXTON7EPXMtNi1qjtjEM/VCHDhcHsAMLXQ==", + "version": "17.0.13", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", + "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", "requires": { "@types/yargs-parser": "*" } @@ -22579,9 +23316,9 @@ } }, "js-sdsl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", - "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==" + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz", + "integrity": "sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q==" }, "js-tokens": { "version": "4.0.0", @@ -22743,16 +23480,15 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "load-json-file": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", - "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "dev": true, "requires": { - "graceful-fs": "^4.1.15", + "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0", - "type-fest": "^0.3.0" + "pify": "^3.0.0", + "strip-bom": "^3.0.0" }, "dependencies": { "parse-json": { @@ -22765,23 +23501,11 @@ "json-parse-better-errors": "^1.0.1" } }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true - }, - "type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", - "dev": true } } }, @@ -22922,6 +23646,12 @@ "fs-monkey": "^1.0.3" } }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -23084,6 +23814,12 @@ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -23108,6 +23844,18 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -23123,12 +23871,94 @@ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "requires": { "path-key": "^3.0.0" + }, + "dependencies": { + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + } } }, "nth-check": { @@ -23370,9 +24200,10 @@ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true }, "path-parse": { "version": "1.0.7", @@ -23404,10 +24235,17 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, + "pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true + }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true }, "pirates": { "version": "4.0.5", @@ -23433,6 +24271,19 @@ "locate-path": "^3.0.0" } }, + "load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + } + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -23461,11 +24312,39 @@ "p-limit": "^2.0.0" } }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true } } }, @@ -23561,9 +24440,9 @@ } }, "postcss": { - "version": "8.4.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", - "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "version": "8.4.17", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz", + "integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==", "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -23810,6 +24689,16 @@ "cosmiconfig": "^7.0.0", "klona": "^2.0.5", "semver": "^7.3.5" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "postcss-logical": { @@ -24447,10 +25336,46 @@ "text-table": "^0.2.0" }, "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "loader-utils": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==" + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -24531,6 +25456,16 @@ "webpack-dev-server": "^4.6.0", "webpack-manifest-plugin": "^4.0.2", "workbox-webpack-plugin": "^6.4.1" + }, + "dependencies": { + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "read-cache": { @@ -24539,6 +25474,35 @@ "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", "requires": { "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + } + } + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + } } }, "readable-stream": { @@ -24902,12 +25866,10 @@ } }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "requires": { - "lru-cache": "^6.0.0" - } + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true }, "send": { "version": "0.18.0", @@ -25036,17 +25998,19 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, "requires": { - "shebang-regex": "^3.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true }, "shell-quote": { "version": "1.7.3", @@ -25145,6 +26109,38 @@ "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.12", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", + "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", + "dev": true + }, "spdy": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", @@ -25278,6 +26274,17 @@ "side-channel": "^1.0.4" } }, + "string.prototype.padend": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz", + "integrity": "sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, "string.prototype.trimend": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", @@ -25874,6 +26881,17 @@ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "eslint": { "version": "7.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", @@ -26037,11 +27055,50 @@ "type-fest": "^0.20.2" } }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -26127,9 +27184,9 @@ } }, "typescript": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", - "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==" + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" }, "unbox-primitive": { "version": "1.0.2", @@ -26267,6 +27324,16 @@ "source-map": "^0.7.3" } }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -26587,9 +27654,9 @@ } }, "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "requires": { "isexe": "^2.0.0" } diff --git a/package.json b/package.json index dbec370d..c12814dc 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@types/node": "^16.11.59", "@types/react": "^18.0.21", "@types/react-dom": "^18.0.6", + "lodash": "^4.17.21", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", @@ -17,13 +18,17 @@ "web-vitals": "^2.1.4" }, "scripts": { - "start": "react-scripts start", - "build": "react-scripts build", - "eject": "react-scripts eject", - "test": "react-scripts test", - "test-ci": "CI=true react-scripts test", - "ts-standard": "ts-standard --env jest --fix" - + "dev:fix": "ts-standard --env jest --fix", + "dev:build": "react-scripts build", + "dev:start": "react-scripts start", + "dev:test": "react-scripts test", + "prod:fix": "run-s dev:fix", + "prod:css": "NODE_ENV=production tailwindcss build -i ./src/framework/styles.css -o ./dist/styles.css --minify", + "prod:build": "tsc -d --project tsconfig.prod.json", + "prod:assets": "cp -R ./src/assets ./dist/assets", + "prod": "run-s prod:fix prod:build prod:assets prod:css", + "ci:fix": "run-s dev:fix", + "ci:test": "CI=true react-scripts test" }, "browserslist": { "production": [ @@ -38,13 +43,19 @@ ] }, "devDependencies": { + "@types/lodash": "^4.14.185", "autoprefixer": "^10.4.12", "husky": "^8.0.1", + "npm-run-all": "^4.1.5", "postcss": "^8.4.16", "tailwindcss": "^3.1.8", "ts-standard": "^11.0.0" }, "ts-standard": { - "project": "./tsconfig.json" + "project": "./tsconfig.json", + "ignore": [ + "dist", + "src/framework/processing/python/worker.js" + ] } } diff --git a/src/App.css b/src/App.css deleted file mode 100644 index 74b5e053..00000000 --- a/src/App.css +++ /dev/null @@ -1,38 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/src/App.test.tsx b/src/App.test.tsx deleted file mode 100644 index f3c4d434..00000000 --- a/src/App.test.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react' -import { render, screen } from '@testing-library/react' -import App from './App' - -test('renders hello world', () => { - render() - const element = screen.getByText(/Hello, world!/i) - expect(element).toBeInTheDocument() -}) diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index fdbc48ed..00000000 --- a/src/App.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import './App.css' - -function App (): any { - return ( -

- Hello, world! -

- ) -}; - -export default App diff --git a/src/assets/images/radio.svg b/src/assets/images/radio.svg new file mode 100644 index 00000000..4ce24fc8 --- /dev/null +++ b/src/assets/images/radio.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/radio_active.svg b/src/assets/images/radio_active.svg new file mode 100644 index 00000000..5edab1b4 --- /dev/null +++ b/src/assets/images/radio_active.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/spinner.svg b/src/assets/images/spinner.svg new file mode 100644 index 00000000..ef958cc3 --- /dev/null +++ b/src/assets/images/spinner.svg @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/src/fonts.css b/src/fonts.css new file mode 100644 index 00000000..e2c57954 --- /dev/null +++ b/src/fonts.css @@ -0,0 +1,69 @@ +@font-face { + font-family: 'Finador-Thin'; + src: url('./fonts/Finador-Thin.woff2') format('woff2'), url('./fonts/Finador-Thin.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-ThinOblique'; + src: url('./fonts/Finador-ThinOblique.woff2') format('woff2'), url('./fonts/Finador-ThinOblique.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-ExtraLight'; + src: url('./fonts/Finador-ExtraLight.woff2') format('woff2'), url('./fonts/Finador-ExtraLight.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-ExtraLightOblique'; + src: url('./fonts/Finador-ExtraLightOblique.woff2') format('woff2'), url('./fonts/Finador-ExtraLightOblique.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-Light'; + src: url('./fonts/Finador-Light.woff2') format('woff2'), url('./fonts/Finador-Light.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-LightOblique'; + src: url('./fonts/Finador-LightOblique.woff2') format('woff2'), url('./fonts/Finador-LightOblique.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-Regular'; + src: url('./fonts/Finador-Regular.woff2') format('woff2'), url('./fonts/Finador-Regular.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-RegularOblique'; + src: url('./fonts/Finador-RegularOblique.woff2') format('woff2'), url('./fonts/Finador-RegularOblique.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-Medium'; + src: url('./fonts/Finador-Medium.woff2') format('woff2'), url('./fonts/Finador-Medium.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-MediumOblique'; + src: url('./fonts/Finador-MediumOblique.woff2') format('woff2'),z url('./fonts/Finador-MediumOblique.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-Bold'; + src: url('./fonts/Finador-Bold.woff2') format('woff2'), url('./fonts/Finador-Bold.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-BoldOblique'; + src: url('./fonts/Finador-BoldOblique.woff2') format('woff2'), url('./fonts/Finador-BoldOblique.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-Black'; + src: url('./fonts/Finador-Black.woff2') format('woff2'), url('./fonts/Finador-Black.woff') format('woff'); +} + +@font-face { + font-family: 'Finador-BlackOblique'; + src: url('./fonts/Finador-BlackOblique.woff2') format('woff2'), url('./fonts/Finador-BlackOblique.woff') format('woff'); +} \ No newline at end of file diff --git a/src/fonts/Finador-Black.woff b/src/fonts/Finador-Black.woff new file mode 100644 index 00000000..764b131c Binary files /dev/null and b/src/fonts/Finador-Black.woff differ diff --git a/src/fonts/Finador-Black.woff2 b/src/fonts/Finador-Black.woff2 new file mode 100644 index 00000000..bff1a606 Binary files /dev/null and b/src/fonts/Finador-Black.woff2 differ diff --git a/src/fonts/Finador-BlackOblique.woff b/src/fonts/Finador-BlackOblique.woff new file mode 100644 index 00000000..465d5348 Binary files /dev/null and b/src/fonts/Finador-BlackOblique.woff differ diff --git a/src/fonts/Finador-BlackOblique.woff2 b/src/fonts/Finador-BlackOblique.woff2 new file mode 100644 index 00000000..b8417d2d Binary files /dev/null and b/src/fonts/Finador-BlackOblique.woff2 differ diff --git a/src/fonts/Finador-Bold.woff b/src/fonts/Finador-Bold.woff new file mode 100644 index 00000000..e5ab9203 Binary files /dev/null and b/src/fonts/Finador-Bold.woff differ diff --git a/src/fonts/Finador-Bold.woff2 b/src/fonts/Finador-Bold.woff2 new file mode 100644 index 00000000..3edd1497 Binary files /dev/null and b/src/fonts/Finador-Bold.woff2 differ diff --git a/src/fonts/Finador-BoldOblique.woff b/src/fonts/Finador-BoldOblique.woff new file mode 100644 index 00000000..fca8ba51 Binary files /dev/null and b/src/fonts/Finador-BoldOblique.woff differ diff --git a/src/fonts/Finador-BoldOblique.woff2 b/src/fonts/Finador-BoldOblique.woff2 new file mode 100644 index 00000000..3e13cbeb Binary files /dev/null and b/src/fonts/Finador-BoldOblique.woff2 differ diff --git a/src/fonts/Finador-ExtraLight.woff b/src/fonts/Finador-ExtraLight.woff new file mode 100644 index 00000000..65f69a7f Binary files /dev/null and b/src/fonts/Finador-ExtraLight.woff differ diff --git a/src/fonts/Finador-ExtraLight.woff2 b/src/fonts/Finador-ExtraLight.woff2 new file mode 100644 index 00000000..8135fd5c Binary files /dev/null and b/src/fonts/Finador-ExtraLight.woff2 differ diff --git a/src/fonts/Finador-ExtraLightOblique.woff b/src/fonts/Finador-ExtraLightOblique.woff new file mode 100644 index 00000000..200b536d Binary files /dev/null and b/src/fonts/Finador-ExtraLightOblique.woff differ diff --git a/src/fonts/Finador-ExtraLightOblique.woff2 b/src/fonts/Finador-ExtraLightOblique.woff2 new file mode 100644 index 00000000..f9ce100f Binary files /dev/null and b/src/fonts/Finador-ExtraLightOblique.woff2 differ diff --git a/src/fonts/Finador-Heavy.woff b/src/fonts/Finador-Heavy.woff new file mode 100644 index 00000000..8d2d1e8e Binary files /dev/null and b/src/fonts/Finador-Heavy.woff differ diff --git a/src/fonts/Finador-Heavy.woff2 b/src/fonts/Finador-Heavy.woff2 new file mode 100644 index 00000000..094f0a32 Binary files /dev/null and b/src/fonts/Finador-Heavy.woff2 differ diff --git a/src/fonts/Finador-HeavyOblique.woff b/src/fonts/Finador-HeavyOblique.woff new file mode 100644 index 00000000..d2e7be67 Binary files /dev/null and b/src/fonts/Finador-HeavyOblique.woff differ diff --git a/src/fonts/Finador-HeavyOblique.woff2 b/src/fonts/Finador-HeavyOblique.woff2 new file mode 100644 index 00000000..0330fc13 Binary files /dev/null and b/src/fonts/Finador-HeavyOblique.woff2 differ diff --git a/src/fonts/Finador-Light.woff b/src/fonts/Finador-Light.woff new file mode 100644 index 00000000..a078838b Binary files /dev/null and b/src/fonts/Finador-Light.woff differ diff --git a/src/fonts/Finador-Light.woff2 b/src/fonts/Finador-Light.woff2 new file mode 100644 index 00000000..6c9b9fd1 Binary files /dev/null and b/src/fonts/Finador-Light.woff2 differ diff --git a/src/fonts/Finador-LightOblique.woff b/src/fonts/Finador-LightOblique.woff new file mode 100644 index 00000000..c21f56c6 Binary files /dev/null and b/src/fonts/Finador-LightOblique.woff differ diff --git a/src/fonts/Finador-LightOblique.woff2 b/src/fonts/Finador-LightOblique.woff2 new file mode 100644 index 00000000..17256e96 Binary files /dev/null and b/src/fonts/Finador-LightOblique.woff2 differ diff --git a/src/fonts/Finador-Medium.woff b/src/fonts/Finador-Medium.woff new file mode 100644 index 00000000..2c7a5d7b Binary files /dev/null and b/src/fonts/Finador-Medium.woff differ diff --git a/src/fonts/Finador-Medium.woff2 b/src/fonts/Finador-Medium.woff2 new file mode 100644 index 00000000..17d07421 Binary files /dev/null and b/src/fonts/Finador-Medium.woff2 differ diff --git a/src/fonts/Finador-MediumOblique.woff b/src/fonts/Finador-MediumOblique.woff new file mode 100644 index 00000000..e3ed069c Binary files /dev/null and b/src/fonts/Finador-MediumOblique.woff differ diff --git a/src/fonts/Finador-MediumOblique.woff2 b/src/fonts/Finador-MediumOblique.woff2 new file mode 100644 index 00000000..11bf998b Binary files /dev/null and b/src/fonts/Finador-MediumOblique.woff2 differ diff --git a/src/fonts/Finador-Regular.woff b/src/fonts/Finador-Regular.woff new file mode 100644 index 00000000..4f32db27 Binary files /dev/null and b/src/fonts/Finador-Regular.woff differ diff --git a/src/fonts/Finador-Regular.woff2 b/src/fonts/Finador-Regular.woff2 new file mode 100644 index 00000000..57fb67da Binary files /dev/null and b/src/fonts/Finador-Regular.woff2 differ diff --git a/src/fonts/Finador-RegularOblique.woff b/src/fonts/Finador-RegularOblique.woff new file mode 100644 index 00000000..142eb9fc Binary files /dev/null and b/src/fonts/Finador-RegularOblique.woff differ diff --git a/src/fonts/Finador-RegularOblique.woff2 b/src/fonts/Finador-RegularOblique.woff2 new file mode 100644 index 00000000..7b1c9639 Binary files /dev/null and b/src/fonts/Finador-RegularOblique.woff2 differ diff --git a/src/fonts/Finador-Thin.woff b/src/fonts/Finador-Thin.woff new file mode 100644 index 00000000..592b1f51 Binary files /dev/null and b/src/fonts/Finador-Thin.woff differ diff --git a/src/fonts/Finador-Thin.woff2 b/src/fonts/Finador-Thin.woff2 new file mode 100644 index 00000000..6d6904d2 Binary files /dev/null and b/src/fonts/Finador-Thin.woff2 differ diff --git a/src/fonts/Finador-ThinOblique.woff b/src/fonts/Finador-ThinOblique.woff new file mode 100644 index 00000000..662d72b1 Binary files /dev/null and b/src/fonts/Finador-ThinOblique.woff differ diff --git a/src/fonts/Finador-ThinOblique.woff2 b/src/fonts/Finador-ThinOblique.woff2 new file mode 100644 index 00000000..8b97b6e2 Binary files /dev/null and b/src/fonts/Finador-ThinOblique.woff2 differ diff --git a/src/framework/abstractions/processing_engine.ts b/src/framework/abstractions/processing_engine.ts new file mode 100644 index 00000000..47f22fb5 --- /dev/null +++ b/src/framework/abstractions/processing_engine.ts @@ -0,0 +1,7 @@ +export default interface ProcessingEngine { + start: () => void + loadScript: (script: any) => void + firstRunCycle: () => void + nextRunCycle: (response: any) => void + terminate: () => void +} diff --git a/src/framework/abstractions/visualisation_engine.ts b/src/framework/abstractions/visualisation_engine.ts new file mode 100644 index 00000000..61e1344a --- /dev/null +++ b/src/framework/abstractions/visualisation_engine.ts @@ -0,0 +1,4 @@ +export default interface VisualisationEngine { + start: (script: string, rootElement: HTMLElement, locale: string) => Promise + terminate: () => void +} diff --git a/src/framework/assembly.ts b/src/framework/assembly.ts new file mode 100644 index 00000000..4c80bf82 --- /dev/null +++ b/src/framework/assembly.ts @@ -0,0 +1,14 @@ +import ReactEngine from './visualisation/react/engine' +import ReactFactory from './visualisation/react/factory' +import WorkerProcessingEngine from './processing/worker_engine' +import VisualisationEngine from './abstractions/visualisation_engine' + +export const Assembly = (worker: Worker): VisualisationEngine => { + const processingEngine = new WorkerProcessingEngine(worker) + const visualisationEngine = new ReactEngine( + new ReactFactory(), + processingEngine + ) + processingEngine.eventListener = visualisationEngine.onEvent + return visualisationEngine +} diff --git a/src/framework/custom.d.ts b/src/framework/custom.d.ts new file mode 100644 index 00000000..ec884c5e --- /dev/null +++ b/src/framework/custom.d.ts @@ -0,0 +1,6 @@ +declare module '*.svg' { + import React = require('react') + export const ReactComponent: React.FC> + const src: string + export default src +} diff --git a/src/framework/processing/python/worker.js b/src/framework/processing/python/worker.js new file mode 100755 index 00000000..9f73baca --- /dev/null +++ b/src/framework/processing/python/worker.js @@ -0,0 +1,200 @@ +let pyScript + +onmessage = (event) => { + const { eventType } = event.data + switch (eventType) { + case 'initialise': + initialise().then(() => { + self.postMessage({ eventType: 'initialiseDone' }) + }) + break + + case 'loadScript': + loadScript(event.data.script) + self.postMessage({ eventType: 'loadScriptDone' }) + break + + case 'firstRunCycle': + pyScript = self.pyodide.runPython(pyWorker()) + runCycle(null) + break + + case 'nextRunCycle': + const { response } = event.data + unwrap(response).then((userInput) => { + runCycle(userInput) + }) + break + + default: + console.log('[ProcessingWorker] Received unsupported event: ', eventType) + } +} + +function runCycle (userInput) { + scriptEvent = pyScript.send(userInput) + self.postMessage({ + eventType: 'runCycleDone', + scriptEvent: scriptEvent.toJs({ + create_proxies: false, + dict_converter: Object.fromEntries + }) + }) +} + +function unwrap (response) { + return new Promise((resolve) => { + switch (response.prompt.__type__) { + case 'Event.Command.Prompt.FileInput': + copyFileToPyFS(response.userInput, resolve) + break + + default: + resolve(response.userInput) + } + }) +} + +function copyFileToPyFS (file, resolve) { + const reader = file.stream().getReader() + const pyFile = self.pyodide.FS.open(file.name, 'w') + + const writeToPyFS = ({ done, value }) => { + if (done) { + resolve(file.name) + } else { + self.pyodide.FS.write(pyFile, value, 0, value.length) + reader.read().then(writeToPyFS) + } + } + reader.read().then(writeToPyFS) +} + +function initialise () { + importScripts('https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js') + + return loadPyodide({ + indexURL: 'https://cdn.jsdelivr.net/pyodide/v0.21.2/full/' + }).then((pyodide) => { + self.pyodide = pyodide + return self.pyodide.loadPackage(['micropip', 'numpy', 'pandas']) + }) +} + +function loadScript (script) { + console.log('[ProcessingWorker] loadScript') + self.pyodide.runPython(pyPortApi) + self.pyodide.runPython(script) +} + +const pyPortApi = ` +class Event: + def toDict(self): + return setType({}, "Event") + + +class EndOfFlow(Event): + __slots__ = "result" + def __init__(self, result): + self.result = result + def translate_result(self): + print("translate") + data_output = [] + for data in self.result: + df = data["data_frame"] + data_output.append({"id": data["id"], "data_frame": df.to_json()}) + return { + "title": data["title"], + "data": data_output, + } + def toDict(self): + print("toDict2") + dict = toDict(super(), "EndOfFlow") + dict = dict | self.translate_result() + return dict + + +class Command(Event): + def toDict(self): + return toDict(super(), "Command") + + +class Prompt(Command): + __slots__ = "title", "description" + def __init__(self, title, description): + self.title = title + self.description = description + def toDict(self): + dict = toDict(super(), "Prompt") + dict["title"] = self.title.toDict() + dict["description"] = self.description.toDict() + return dict + + +class FileInput(Prompt): + __slots__ = "extensions" + def __init__(self, title, description, extensions): + super().__init__(title, description) + self.extensions = extensions + def toDict(self): + dict = toDict(super(), "FileInput") + dict["extensions"] = self.extensions + return dict + + +class RadioInput(Prompt): + def __init__(self, title, description, items): + super().__init__(title, description) + self.items = items + def toDict(self): + dict = toDict(super(), "RadioInput") + dict["items"] = self.items + return dict + + +class Translatable: + __slots__ = "translations" + def __init__(self): + self.translations = {} + def add(self, locale, text): + self.translations[locale] = text + return self + def toDict(self): + return setType(self.translations, "Translatable") + + +def toDict(zuper, type): + return setType(zuper.toDict(), type) + + +def setType(dict, type): + key = "__type__" + seperator = "." + + path = [type] + if key in dict: + path.insert(0, dict[key]) + dict[key] = seperator.join(path) + return dict +` + +function pyWorker () { + return ` + from collections.abc import Generator + import json + import html + import pandas as pd + + class ScriptWrapper(Generator): + def __init__(self, script): + self.script = script + def send(self, data): + print("toDict") + event = self.script.send(data) + return event.toDict() + def throw(self, type=None, value=None, traceback=None): + raise StopIteration + script = process() + ScriptWrapper(script) + ` +} diff --git a/src/framework/processing/worker_engine.ts b/src/framework/processing/worker_engine.ts new file mode 100755 index 00000000..9d0ea3d9 --- /dev/null +++ b/src/framework/processing/worker_engine.ts @@ -0,0 +1,46 @@ +import ProcessingEngine from '../abstractions/processing_engine' + +export default class WorkerProcessingEngine implements ProcessingEngine { + eventListener: (event: any) => void + worker: Worker + + constructor (worker: Worker) { + this.eventListener = (event) => { + const eventString = JSON.stringify(event) + console.log( + '[ProcessingEngine] No event listener registered for event: ', + eventString + ) + } + + this.worker = worker + this.worker.onerror = console.log + this.worker.onmessage = (event) => { + console.log( + '[ProcessingEngine] Received event from worker: ', + event.data.eventType + ) + this.eventListener(event) + } + } + + start (): void { + this.worker.postMessage({ eventType: 'initialise' }) + } + + loadScript (script: any): void { + this.worker.postMessage({ eventType: 'loadScript', script }) + } + + firstRunCycle (): void { + this.worker.postMessage({ eventType: 'firstRunCycle' }) + } + + nextRunCycle (response: any): void { + this.worker.postMessage({ eventType: 'nextRunCycle', response }) + } + + terminate (): void { + this.worker.terminate() + } +} diff --git a/src/framework/styles.css b/src/framework/styles.css new file mode 100644 index 00000000..b5c61c95 --- /dev/null +++ b/src/framework/styles.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/src/framework/translatable.ts b/src/framework/translatable.ts new file mode 100644 index 00000000..6cb51906 --- /dev/null +++ b/src/framework/translatable.ts @@ -0,0 +1,33 @@ +import _ from 'lodash' + +export default class Translatable { + translations: { [key: string]: string } = {} + defaultLocale: string = 'nl' + + add (locale: string, text: string): Translatable { + this.translations[locale] = text + return this + } + + text (locale: string): string { + return _.escape(this.resolve(locale)) + } + + resolve (locale: string): string { + const text = this.translations[locale] + if (text !== null) { + return text + } + + const defaultText = this.translations[this.defaultLocale] + if (defaultText !== null) { + return defaultText + } + + if (Object.values(this.translations).length > 0) { + return Object.values(this.translations)[0] + } + + return '?text?' + } +} diff --git a/src/framework/visualisation/element_ref.ts b/src/framework/visualisation/element_ref.ts new file mode 100644 index 00000000..f8b00c5b --- /dev/null +++ b/src/framework/visualisation/element_ref.ts @@ -0,0 +1,82 @@ +export default class ElementRef { + el: Element + + constructor (el: Element) { + this.el = el + + if (el === null) { + throw new Error('Wrapped element is null') + } + } + + setInnerText (text: string): void { + if (this.el instanceof HTMLElement) { + this.el.innerText = text + } + } + + setInnerHTML (html: string): void { + if (this.el instanceof HTMLElement) { + this.el.innerHTML = html + } + } + + onClick (handle: () => void): void { + this.el.addEventListener('click', () => { + handle() + }) + } + + onChange (handle: () => void): void { + this.el.addEventListener('change', () => { + handle() + }) + } + + selectedFile (): File | null { + if (this.el instanceof HTMLInputElement) { + if (this.el.files !== null && this.el.files.length > 0) { + this.el.files.item(0) + } + } + return null + } + + reset (): void { + if (this.el instanceof HTMLInputElement) { + this.el.type = 'text' + this.el.type = 'file' + } + } + + click (): void { + if (this.el instanceof HTMLElement) { + this.el.click() + } + } + + hide (): void { + if (!this.el.classList.contains('hidden')) { + this.el.classList.add('hidden') + } + } + + show (): void { + this.el.classList.remove('hidden') + } + + child (childId: string): ElementRef { + const child = this.el.querySelector(`#${childId}`) + if (child === null) { + throw new Error(`Child not found: ${childId}`) + } else { + return new ElementRef(child) + } + } + + childs (className: string): ElementRef[] { + const elements = this.el.getElementsByClassName(className) + const childs = Array.from(elements) + return childs.map((child) => new ElementRef(child)) + } +} diff --git a/src/framework/visualisation/react/components/button.tsx b/src/framework/visualisation/react/components/button.tsx new file mode 100644 index 00000000..f06bd52d --- /dev/null +++ b/src/framework/visualisation/react/components/button.tsx @@ -0,0 +1,35 @@ +interface ButtonProps { + label: string + color?: string + onClick: () => void +} + +export const PrimaryButtonFactory = (props: ButtonProps): JSX.Element => + +export const PrimaryButton = ({ label, color = 'bg-primary text-white', onClick }: ButtonProps): JSX.Element => { + return ( +
+
+ {label} +
+
+ ) +} + +interface ButtonProps { + label: string + color?: string + onClick: () => void +} + +export const SecondaryButtonFactory = (props: ButtonProps): JSX.Element => + +export const SecondaryButton = ({ label, color = 'bg-delete text-delete', onClick }: ButtonProps): JSX.Element => { + return ( +
+
+ {label} +
+
+ ) +} diff --git a/src/framework/visualisation/react/components/end_of_flow.tsx b/src/framework/visualisation/react/components/end_of_flow.tsx new file mode 100644 index 00000000..816e738f --- /dev/null +++ b/src/framework/visualisation/react/components/end_of_flow.tsx @@ -0,0 +1,85 @@ +import Translatable from '../../../translatable' +import { Table } from './table' +import { PrimaryButton, SecondaryButton } from './button' +import { Title2 } from './text' + +export interface EndOfFlowProps { + title: string + data: any[] + locale: string + resolve: (value: any) => void +} + +interface Copy { + donateButton: string + declineButton: string +} + +function prepareCopy ({ locale }: EndOfFlowProps): Copy { + return { + donateButton: donateButtonLabel().text(locale), + declineButton: declineButtonLabel().text(locale) + } +} + +const donateButtonLabel = (): Translatable => { + return new Translatable() + .add('en', 'Yes, donate') + .add('nl', 'Ja, doneer') +} + +const declineButtonLabel = (): Translatable => { + return new Translatable() + .add('en', 'No') + .add('nl', 'Nee') +} + +export const EndOfFlowFactory = (props: EndOfFlowProps): JSX.Element => + +export const EndOfFlow = (props: EndOfFlowProps): JSX.Element => { + const { title, data, resolve } = props + const { donateButton, declineButton } = prepareCopy(props) + + function handleDonate (): void { + resolve(JSON.stringify(data)) + } + + function handleDecline (): void { + resolve(false) + } + + function renderTable (table: any): JSX.Element { + const id = table.id as string + const dataFrame = JSON.parse(table.data_frame) + const rowCount = Object.keys(dataFrame).length + + const header = { cells: Object.keys(dataFrame) } + const rows = [] + for (let i = 0; i <= rowCount; i++) { + const cells = Object.keys(dataFrame).map((column: any) => dataFrame[column][`${i}`]) + rows.push({ cells: cells }) + } + const body = { rows: rows } + + return ( + + ) + } + + const tables = data.map((table) => renderTable(table)) + + return ( + <> + +
+
+ {tables} +
+
+ + +
+
+ + ) +} diff --git a/src/framework/visualisation/react/components/file_input.tsx b/src/framework/visualisation/react/components/file_input.tsx new file mode 100644 index 00000000..886d5b7b --- /dev/null +++ b/src/framework/visualisation/react/components/file_input.tsx @@ -0,0 +1,131 @@ +import * as React from 'react' +import Translatable from '../../../translatable' + +export interface FileInputProps { + title: any + description: any + extensions: string + locale: string + resolve: (value: any) => void +} + +interface Copy { + title: string + description: string + extensions: string + selectButton: string + continueButton: string + resetButton: string +} + +function prepareCopy ({ title, description, extensions, locale }: any): Copy { + return { + title: title.en, + description: description.en, + extensions: extensions, + selectButton: selectButtonLabel().text(locale), + continueButton: continueButtonLabel().text(locale), + resetButton: resetButtonLabel().text(locale) + } +} + +export const FileInputFactory = (props: FileInputProps): JSX.Element => + +const FileInput = (props: FileInputProps): JSX.Element => { + const [selectedFile, setSelectedFile] = React.useState() + const [confirmHidden, setConfirmHidden] = React.useState(true) + const input = React.useRef(null) + + const { resolve } = props + const { title, description, extensions, selectButton, continueButton, resetButton } = prepareCopy(props) + + function handleClick (): void { + input.current?.click() + } + + function handleReset (): void { + handleClick() + } + + function handleSelect (event: React.ChangeEvent): void { + const files = event.target.files + if (files != null && files.length > 0) { + setSelectedFile(files[0]) + setConfirmHidden(false) + } + } + + function handleConfirm (): void { + resolve(selectedFile) + } + + return ( + <> +
+ {title} +
+
+ +
+
+ {description} +
+
+
+
+
+ {selectButton} +
+
+
+ +
+
+ +
+
+
+
+
{selectedFile?.name}
+
+
+
+
+
+ Continue with the selected file, or select again? +
+
+
+
+
+ {continueButton} +
+
+
+
+ {resetButton} +
+
+
+
+ + ) +} + +const continueButtonLabel = (): Translatable => { + return new Translatable() + .add('en', 'Continue') + .add('nl', 'Doorgaan') +} + +const selectButtonLabel = (): Translatable => { + return new Translatable() + .add('en', 'Select file') + .add('nl', 'Selecteer bestand') +} + +const resetButtonLabel = (): Translatable => { + return new Translatable() + .add('en', 'Select again') + .add('nl', 'Opnieuw') +} diff --git a/src/framework/visualisation/react/components/radio_input.tsx b/src/framework/visualisation/react/components/radio_input.tsx new file mode 100644 index 00000000..682930ed --- /dev/null +++ b/src/framework/visualisation/react/components/radio_input.tsx @@ -0,0 +1,101 @@ +import * as React from 'react' +import Translatable from '../../../translatable' +import RadioSvg from '../../../../assets/images/radio.svg' +import RadioActiveSvg from '../../../../assets/images/radio_active.svg' + +export interface RadioInputProps { + title: any + description: any + items: string[] + locale: string + resolve: (value: any) => void +} + +interface Copy { + title: string + description: string + continueButton: string +} + +function prepareCopy ({ title, description, locale }: RadioInputProps): Copy { + return { + title: title.en, + description: description.en, + continueButton: continueButtonLabel().text(locale) + } +} + +export const RadioInputFactory = (props: RadioInputProps): JSX.Element => + +export const RadioInput = (props: RadioInputProps): JSX.Element => { + const [selectedId, setSelectedId] = React.useState(-1) + const [confirmHidden, setConfirmHidden] = React.useState(true) + + const { items, resolve } = props + const { title, description, continueButton } = prepareCopy(props) + + function handleSelect (id: number): void { + setSelectedId(id) + setConfirmHidden(false) + } + + function handleConfirm (): void { + const value = items.at(selectedId) + resolve(value) + } + + return ( + <> +
+ {title} +
+
+
+
+ {description} +
+
+
+
+ {items.map((value, index) => )} +
+
+
+
+
+
+
+ {continueButton} +
+
+
+ + ) +} + +const continueButtonLabel = (): Translatable => { + return new Translatable() + .add('en', 'Continue') + .add('nl', 'Doorgaan') +} + +export interface RadioItemProps { + id: number + value: string + selected: boolean + onSelect: (id: number) => void +} + +export const RadioItem = ({ id, value, selected, onSelect }: RadioItemProps): JSX.Element => { + return ( +
onSelect(id)}> +
+ + +
+
+ {value} +
+
+ ) +} diff --git a/src/framework/visualisation/react/components/spinner.tsx b/src/framework/visualisation/react/components/spinner.tsx new file mode 100644 index 00000000..43e9f7a0 --- /dev/null +++ b/src/framework/visualisation/react/components/spinner.tsx @@ -0,0 +1,37 @@ +import Translatable from '../../../translatable' +import SpinnerSvg from '../../../../assets/images/spinner.svg' + +export interface SpinnerProps { + locale: string +} + +interface Copy { + text: string +} + +function prepareCopy ({ texts, locale }: any): Copy { + return { + text: texts.text(locale) + } +} + +const texts = (): Translatable => { + return new Translatable() + .add('en', 'One moment please') + .add('nl', 'Een moment geduld') +} + +export const SpinnerFactory = (props: SpinnerProps): JSX.Element => + +export const Spinner = (props: SpinnerProps): JSX.Element => { + const { text } = prepareCopy({ texts: texts(), ...props }) + + return ( +
+
{text}
+
+ +
+
+ ) +} diff --git a/src/framework/visualisation/react/components/table.tsx b/src/framework/visualisation/react/components/table.tsx new file mode 100644 index 00000000..8e963c1a --- /dev/null +++ b/src/framework/visualisation/react/components/table.tsx @@ -0,0 +1,62 @@ +interface TableProps { + id: string + header: TableHeadProps + body: TableBodyProps +} + +export const TableFactory = (props: TableProps): JSX.Element =>
+ +export const Table = ({ id, header, body }: TableProps): JSX.Element => { + return ( +
+ + +
+ ) +} + +interface TableHeadProps { + cells: string[] +} + +export const TableHead = ({ cells }: TableHeadProps): JSX.Element => { + return ( + {cells.map((cell, index) => )} + ) +} + +interface TableBodyProps { + rows: TableRowProps[] +} + +export const TableBody = ({ rows }: TableBodyProps): JSX.Element => { + return ( + + {rows.map((row, index) => { return () })} + + ) +} + +interface TableRowProps { + header?: boolean + cells: string[] +} + +export const TableRow = ({ header = false, cells }: TableRowProps): JSX.Element => { + return ( + {cells.map((cell, index) => )} + ) +} + +interface TableCellProps { + header?: boolean + cell: string +} + +export const TableCell = ({ header = false, cell }: TableCellProps): JSX.Element => { + return ( + header + ? {cell} + : {cell} + ) +} diff --git a/src/framework/visualisation/react/components/text.tsx b/src/framework/visualisation/react/components/text.tsx new file mode 100644 index 00000000..d88dcc46 --- /dev/null +++ b/src/framework/visualisation/react/components/text.tsx @@ -0,0 +1,33 @@ + +interface TextProps { + text: string + color?: string + margin?: string +} + +export const Title0Factory = (props: TextProps): JSX.Element => +export const Title0 = ({ text, color = 'text-grey1', margin = 'mb-6 md:mb-8 lg:mb-10' }: TextProps): JSX.Element => { + return ( +
+ {text} +
+ ) +} + +export const Title1Factory = (props: TextProps): JSX.Element => +export const Title1 = ({ text, color = 'text-grey1', margin = 'mb-6 md:mb-8 lg:mb-10' }: TextProps): JSX.Element => { + return ( +
+ {text} +
+ ) +} + +export const Title2Factory = (props: TextProps): JSX.Element => +export const Title2 = ({ text, color = 'text-grey1', margin = 'mb-6 md:mb-8 lg:mb-10' }: TextProps): JSX.Element => { + return ( +
+ {text} +
+ ) +} diff --git a/src/framework/visualisation/react/engine.tsx b/src/framework/visualisation/react/engine.tsx new file mode 100644 index 00000000..8989d8c7 --- /dev/null +++ b/src/framework/visualisation/react/engine.tsx @@ -0,0 +1,131 @@ +import * as ReactDOM from 'react-dom/client' +import VisualisationEngine from '../../abstractions/visualisation_engine' +import ProcessingEngine from '../../abstractions/processing_engine' +import VisualisationFactory from './factory' +import { Main } from './main' + +export default class ReactEngine implements VisualisationEngine { + factory: VisualisationFactory + processingEngine: ProcessingEngine + onEvent: (event: any) => void + + locale!: string + script!: string + root!: ReactDOM.Root + + finishFlow!: (value: unknown) => void + + constructor (factory: VisualisationFactory, processingEngine: ProcessingEngine) { + this.factory = factory + this.processingEngine = processingEngine + this.onEvent = (event) => { + this.handleEvent(event) + } + } + + async start (script: string, rootElement: HTMLElement, locale: string): Promise { + console.log('[VisualisationEngine] started') + this.script = script + this.root = ReactDOM.createRoot(rootElement) + this.locale = locale + this.showStartPage() + this.processingEngine.start() + return await new Promise((resolve) => { + this.finishFlow = resolve + }) + } + + terminate (): void { + this.processingEngine.terminate() + } + + renderPage (elements: JSX.Element[]): void { + this.root.render(
) + } + + showSpinner (): void { + const spinner = this.create('Spinner') + this.renderPage([spinner]) + } + + showStartPage (): void { + const welcome = this.create('Title0', { text: 'Welcome' }) + const spinner = this.create('Spinner') + this.renderPage([welcome, spinner]) + } + + showFinalPage (): void { + const thanks = this.create('Title0', { text: 'Thank you' }) + this.renderPage([thanks]) + } + + create (type: string, props: any = {}): JSX.Element { + return this.factory.createComponent({ __type__: type, ...props }, this.locale, () => {}) + } + + handleEvent (event: any): void { + const { eventType } = event.data + console.log('[VisualisationEngine] received eventType: ', eventType) + switch (eventType) { + case 'initialiseDone': + console.log('[VisualisationEngine] received: initialiseDone') + this.processingEngine.loadScript(this.script) + break + + case 'loadScriptDone': + console.log('[VisualisationEngine] Received: loadScriptDone') + this.processingEngine.firstRunCycle() + break + + case 'runCycleDone': + console.log('[VisualisationEngine] received: event', event.data.scriptEvent) + this.handleRunCycle(event.data.scriptEvent) + break + default: + console.log( + '[VisualisationEngine] received unsupported flow event: ', + eventType + ) + } + } + + handleRunCycle (scriptEvent: any): void { + console.log('scriptEvent', scriptEvent) + const type = scriptEvent.__type__ as string + if (type.startsWith('Event.EndOfFlow')) { + this.renderComponent(scriptEvent).then( + (result) => { + this.showFinalPage() + this.finishFlow?.(result) + }, + null) + return + } + + if (type.startsWith('Event.Command.Prompt')) { + this.renderComponent(scriptEvent).then( + (userInput) => { + this.showSpinner() + this.processingEngine.nextRunCycle({ + prompt: scriptEvent, + userInput: userInput + }) + }, + null) + return + } + + console.log( + '[VisualisationEngine] Received unsupported script event: ', + type + ) + } + + async renderComponent (data: any): Promise { + const locale = this.locale + return await new Promise((resolve) => { + const component = this.factory.createComponent(data, locale, resolve) + this.renderPage([component]) + }) + } +} diff --git a/src/framework/visualisation/react/factory.tsx b/src/framework/visualisation/react/factory.tsx new file mode 100644 index 00000000..4ec2a3cf --- /dev/null +++ b/src/framework/visualisation/react/factory.tsx @@ -0,0 +1,38 @@ + +import { TableFactory } from './components/table' +import { SpinnerFactory } from './components/spinner' +import { FileInputFactory } from './components/file_input' +import { RadioInputFactory } from './components/radio_input' +import { EndOfFlowFactory } from './components/end_of_flow' +import { Title0Factory, Title1Factory, Title2Factory } from './components/text' + +export default class ReactFactory { + mapping: { [name: string]: (props: any) => JSX.Element} = {} + + constructor () { + this.mapping.Table = TableFactory + this.mapping.Spinner = SpinnerFactory + this.mapping.FileInput = FileInputFactory + this.mapping.RadioInput = RadioInputFactory + this.mapping.EndOfFlow = EndOfFlowFactory + this.mapping.Title0 = Title0Factory + this.mapping.Title1 = Title1Factory + this.mapping.Title2 = Title2Factory + } + + add (factory: (props: any) => JSX.Element, name: string): void { + this.mapping[name] = factory + } + + createComponent (data: any, locale: string, resolve: (value: any) => void): JSX.Element { + const type = data.__type__.split('.').pop() as string + const props = { ...data, locale, resolve } + + if (this.mapping[type] !== null) { + const factoryMethod = this.mapping[type] + return factoryMethod(props) + } else { + throw new Error(`[VisualisationFactory] Received unsupported prompt: ${type}`) + } + } +} diff --git a/src/framework/visualisation/react/main.tsx b/src/framework/visualisation/react/main.tsx new file mode 100644 index 00000000..04f048a8 --- /dev/null +++ b/src/framework/visualisation/react/main.tsx @@ -0,0 +1,19 @@ +import * as React from 'react' + +interface MainProps { + elements: JSX.Element[] +} + +export const Main = ({ elements }: MainProps): JSX.Element => { + elements = elements.map((element, index) => { return { ...element, key: `${index}` } }) + + return ( +
+
+
+ {elements} +
+
+
+ ) +} diff --git a/src/index.css b/src/index.css deleted file mode 100644 index 17df0e7e..00000000 --- a/src/index.css +++ /dev/null @@ -1,17 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} diff --git a/src/index.tsx b/src/index.tsx index 0b3c0a62..7ba408b5 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,19 +1,14 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import './index.css' -import App from './App' -import reportWebVitals from './reportWebVitals' +import './fonts.css' +import './framework/styles.css' +import { Assembly } from './framework/assembly' +import { PyScript } from './py_script' -const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement -) -root.render( - - - -) +const workerFile = new URL('./framework/processing/python/worker.js', import.meta.url) +const worker = new Worker(workerFile) -// If you want to start measuring performance in your app, pass a function -// to log results (for example: reportWebVitals(console.log)) -// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals() +const rootElement = document.getElementById('root') as HTMLElement +const visualisationEngine = Assembly(worker) +visualisationEngine.start(PyScript, rootElement, 'en').then( + () => {}, + () => {} +) diff --git a/src/logo.svg b/src/logo.svg deleted file mode 100644 index 9dfc1c05..00000000 --- a/src/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/py_script.ts b/src/py_script.ts new file mode 100644 index 00000000..a2bc957a --- /dev/null +++ b/src/py_script.ts @@ -0,0 +1,64 @@ +export const PyScript: string = ` +import pandas as pd + + +def process(): + chat_file_name = yield prompt_file() + usernames = extract_usernames(chat_file_name) + username = yield prompt_radio(usernames) + yield result(usernames, username) + + +def prompt_file(): + title = Translatable() + title.add("en", "Step 1: Select the chat file") + title.add("nl", "Stap 1: Selecteer het chat file") + + description = Translatable() + description.add("en", "We previously asked you to export a chat file from Whatsapp. Please select this file so we can extract relevant information for our research.") + description.add("nl", "We hebben je gevraagd een chat bestand te exporteren uit Whatsapp. Je kan deze file nu selecteren zodat wij er relevante informatie uit kunnen halen voor ons onderzoek.") + + extensions = "application/zip, text/plain" + + return FileInput(title, description, extensions) + + +def prompt_radio(usernames): + title = Translatable() + title.add("en", "Step 2: Select your username") + title.add("nl", "Stap 2: Selecteer je gebruikersnaam") + + description = Translatable() + description.add("en", "The following users are extracted from the chat file. Which one are you?") + description.add("nl", "De volgende gebruikers hebben we uit de chat file gehaald. Welke ben jij?") + + return RadioInput(title, description, usernames) + + +def extract_usernames(chat_file_name): + print(f"filename: {chat_file_name}") + + with open(chat_file_name) as chat_file: + while (line := chat_file.readline().rstrip()): + print(line) + + return ["emielvdveen", "a.m.mendrik", "9bitcat"] + + +def result(usernames, selected_username): + data = [] + for username in usernames: + description = "you" if username == selected_username else "-" + data.append((username, description)) + + data_frame = pd.DataFrame(data, columns=["username", "description"]) + + print(data_frame) + + result = [{ + "id": "overview", + "title": "The following usernames where extracted:", + "data_frame": data_frame + }] + return EndOfFlow(result) +` diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/src/reportWebVitals.ts b/src/reportWebVitals.ts deleted file mode 100644 index fed31e26..00000000 --- a/src/reportWebVitals.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ReportHandler } from 'web-vitals' - -const reportWebVitals = (onPerfEntry?: ReportHandler): void => { - if ((onPerfEntry != null) && onPerfEntry instanceof Function) { - void import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { - getCLS(onPerfEntry) - getFID(onPerfEntry) - getFCP(onPerfEntry) - getLCP(onPerfEntry) - getTTFB(onPerfEntry) - }) - } -} - -export default reportWebVitals diff --git a/src/test/visualisationEngine.test.tsx b/src/test/visualisationEngine.test.tsx new file mode 100644 index 00000000..74e917a2 --- /dev/null +++ b/src/test/visualisationEngine.test.tsx @@ -0,0 +1,7 @@ +import { render } from '@testing-library/react' + +test('renders hello world', () => { + render(
) + // const element = screen.getByText(/Hello, world!/i) + // expect(element).toBeInTheDocument() +}) diff --git a/tailwind.config.js b/tailwind.config.js index 963600ca..41f6f350 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,10 +1,172 @@ /** @type {import('tailwindcss').Config} */ + module.exports = { content: [ './src/**/*.{js,jsx,ts,tsx}' ], + + darkMode: 'media', theme: { - extend: {} + boxShadow: { + top4px: 'inset 0 4px 0 0 rgba(0, 0, 0, 0.15)', + top2px: 'inset 0 2px 0 0 rgba(0, 0, 0, 0.15)', + '2xl': '0 5px 20px 0px rgba(0, 0, 0, 0.10)' + }, + colors: { + primary: '#4272EF', + primarylight: '#E3EAFD', + secondary: '#FF5E5E', + tertiary: '#FFCF60', + success: '#6FCA37', + successlight: '#EBFFDF', + warning: '#F28D15', + warninglight: '#FFEFDC', + delete: '#DB1E1E', + deletelight: '#FFECEC', + error: '#DB1E1E', + errorlight: '#FFECEC', + black: '#000000', + grey1: '#222222', + grey2: '#999999', + grey3: '#CCCCCC', + grey4: '#EEEEEE', + grey5: '#F6F6F6', + grey6: '#FAFAFA', + white: '#FFFFFF' + }, + extend: { + opacity: { + shadow: '.15' + }, + spacing: { + '1px': '1px', + '2px': '2px', + '3px': '3px', + '5px': '5px', + '6px': '6px', + '7px': '7px', + '9px': '9px', + '10px': '10px', + '11px': '11px', + '13px': '13px', + '14px': '14px', + '15px': '15px', + '17px': '17px', + '18px': '18px', + '19px': '19px', + '48px': '48px', + '44px': '44px', + '84px': '84px', + '200px': '200px', + '224px': '224px', + 30: '120px', + 34: '136px', + 35: '140px' + }, + width: { + logo: '23px', + 'logo-sm': '48px', + sheet: '760px', + form: '400px', + card: '376px', + 'image-preview': '120px', + 'image-preview-sm': '200px', + 'image-preview-circle': '120px', + 'image-preview-circle-sm': '150px', + 'button-sm': '14px', + popup: '480px', + 'popup-sm': '520px', + 'popup-md': '730px', + 'popup-lg': '1228px' + }, + height: { + logo: '32px', + 'logo-sm': '48px', + 'image-card': '200px', + 'image-preview': '90px', + 'image-preview-sm': '150px', + 'image-preview-circle': '120px', + 'image-preview-circle-sm': '150px', + 'button-sm': '14px' + }, + fontFamily: { + title0: ['Finador-Black', 'sans-serif'], + title1: ['Arial', 'sans-serif'], + title2: ['Finador-Black', 'sans-serif'], + title3: ['Finador-Black', 'sans-serif'], + title4: ['Finador-Black', 'sans-serif'], + title5: ['Finador-Bold', 'sans-serif'], + title6: ['Finador-Bold', 'sans-serif'], + title7: ['Finador-Bold', 'sans-serif'], + caption: ['Finador-Medium', 'sans-serif'], + link: ['Finador-Medium', 'sans-serif'], + subhead: ['Finador-Medium', 'sans-serif'], + button: ['Finador-Bold', 'sans-serif'], + intro: ['Finador-Medium', 'sans-serif'], + label: ['Finador-Bold', 'sans-serif'], + body: ['Finador-Light', 'sans-serif'] + }, + fontSize: { + title0: ['64px', '68px'], + title1: ['50px', '50px'], + title2: ['40px', '44px'], + title3: ['32px', '38px'], + title4: ['28px', '32px'], + title5: ['24px', '26px'], + title6: ['20px', '22px'], + title7: ['16px', '20px'], + caption: ['14px', '18px'], + captionsmall: ['12px', '14px'], + subhead: ['20px', '20px'], + label: ['16px', '16px'], + labelsmall: ['14px', '14px'], + button: ['18px', '18px'], + buttonsmall: ['16px', '16px'], + intro: ['20px', '30px'], + introdesktop: ['24px', '36px'], + bodylarge: ['24px', '36px'], + bodymedium: ['20px', '30px'], + bodysmall: ['16px', '24px'], + bodylinklarge: ['24px', '36px'], + bodylinkmedium: ['30px', '30px'], + link: ['16px', '24px'] + }, + minWidth: { + '1/2': '50%', + '3/4': '75%' + }, + maxWidth: { + card: '376px', + form: '400px', + sheet: '760px', + popup: '480px', + 'popup-sm': '520px', + 'popup-md': '730px', + 'popup-lg': '1228px', + '3/4': '75%', + '9/10': '90%' + }, + maxHeight: { + dropdown: '317px', + header1: '376px', + form: '400px', + mailto: '128px' + } + } + }, + variants: { + extend: { + borderColor: ['active', 'hover', 'disabled'], + borderWidth: ['active', 'hover', 'disabled'], + ringColor: ['hover'], + ringWidth: ['hover'], + ringOpacity: ['hover'], + ringOffsetColor: ['hover'], + ringOffsetWidth: ['hover'], + opacity: ['active', 'disabled'], + padding: ['active'], + boxShadow: ['active'] + } }, plugins: [] } diff --git a/tsconfig.json b/tsconfig.json index a273b0cf..ffe6f2c7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,8 @@ "lib": [ "dom", "dom.iterable", - "esnext" + "esnext", + "webworker" ], "allowJs": true, "skipLibCheck": true, diff --git a/tsconfig.prod.json b/tsconfig.prod.json new file mode 100644 index 00000000..8ee82aa3 --- /dev/null +++ b/tsconfig.prod.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "jsx": "react-jsx", + "target": "esnext", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "module": "esnext", + "moduleResolution": "node", + "esModuleInterop": true, + "resolveJsonModule": true, + "isolatedModules": true, + "outDir": "./dist" + }, + "include": [ + "src/framework", + "src/py_script.ts" + ] +}