aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-09-04 20:44:39 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-09-06 01:05:23 +0200
commit29919c02d86da10acf2b902fb9cab9998bb731a6 (patch)
treee4ac7dc9bc035327c720514363edee938248c14a
parentrefactor(frontend): add eslint-plugin-mobx (diff)
downloadrefinery-29919c02d86da10acf2b902fb9cab9998bb731a6.tar.gz
refinery-29919c02d86da10acf2b902fb9cab9998bb731a6.tar.zst
refinery-29919c02d86da10acf2b902fb9cab9998bb731a6.zip
feat(frontend): XState statecharts
Expressing logic in statecharts for complex stateful behaviours should improve maintainability We use @xstate/cli to statically analyze statcharts before typechecking
-rw-r--r--.gitignore1
-rw-r--r--.yarnrc.yml8
-rw-r--r--subprojects/frontend/.eslintrc.cjs2
-rw-r--r--subprojects/frontend/build.gradle29
-rw-r--r--subprojects/frontend/package.json30
-rw-r--r--subprojects/frontend/src/index.tsx1
-rw-r--r--subprojects/frontend/src/utils/CancelledError.ts4
-rw-r--r--subprojects/frontend/src/utils/Timer.ts33
-rw-r--r--subprojects/frontend/src/xtext/UpdateService.ts2
-rw-r--r--subprojects/frontend/src/xtext/XtextWebSocketClient.ts525
-rw-r--r--subprojects/frontend/src/xtext/webSocketMachine.ts215
-rw-r--r--subprojects/frontend/src/xtext/xtextMessages.ts8
-rw-r--r--yarn.lock507
13 files changed, 807 insertions, 558 deletions
diff --git a/.gitignore b/.gitignore
index 56961dd2..dc4d50b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,7 @@ bin/
17build/ 17build/
18dev-dist/ 18dev-dist/
19emf-gen/ 19emf-gen/
20*.typegen.ts
20xtend-gen/ 21xtend-gen/
21*.xtendbin 22*.xtendbin
22xtext-gen/ 23xtext-gen/
diff --git a/.yarnrc.yml b/.yarnrc.yml
index af8197e1..8cfe5aa0 100644
--- a/.yarnrc.yml
+++ b/.yarnrc.yml
@@ -2,6 +2,14 @@ enableTelemetry: 0
2 2
3nodeLinker: pnp 3nodeLinker: pnp
4 4
5packageExtensions:
6 "@xstate/cli@*":
7 peerDependencies:
8 prettier: "*"
9 "@xstate/tools-shared@*":
10 peerDependencies:
11 "@babel/core": "*"
12
5plugins: 13plugins:
6 - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs 14 - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
7 spec: "@yarnpkg/plugin-interactive-tools" 15 spec: "@yarnpkg/plugin-interactive-tools"
diff --git a/subprojects/frontend/.eslintrc.cjs b/subprojects/frontend/.eslintrc.cjs
index 1db67c11..0bf65c4f 100644
--- a/subprojects/frontend/.eslintrc.cjs
+++ b/subprojects/frontend/.eslintrc.cjs
@@ -37,7 +37,7 @@ module.exports = {
37 env: { 37 env: {
38 browser: true, 38 browser: true,
39 }, 39 },
40 ignorePatterns: ['build/**/*', 'dev-dist/**/*'], 40 ignorePatterns: ['build/**/*', 'dev-dist/**/*', 'src/**/*.typegen.ts'],
41 rules: { 41 rules: {
42 // In typescript, some class methods implementing an inderface do not use `this`: 42 // In typescript, some class methods implementing an inderface do not use `this`:
43 // https://github.com/typescript-eslint/typescript-eslint/issues/1103 43 // https://github.com/typescript-eslint/typescript-eslint/issues/1103
diff --git a/subprojects/frontend/build.gradle b/subprojects/frontend/build.gradle
index dd50860c..e57b2c4b 100644
--- a/subprojects/frontend/build.gradle
+++ b/subprojects/frontend/build.gradle
@@ -21,10 +21,15 @@ configurations {
21 21
22def installFrontend = tasks.named('installFrontend') 22def installFrontend = tasks.named('installFrontend')
23 23
24def sourcesWithoutTypegen = fileTree('src') {
25 exclude '**/*.typegen.ts'
26}
27
24def assembleFrontend = tasks.named('assembleFrontend') 28def assembleFrontend = tasks.named('assembleFrontend')
25assembleFrontend.configure { 29assembleFrontend.configure {
30 dependsOn generateXStateTypes
26 inputs.dir 'public' 31 inputs.dir 'public'
27 inputs.dir 'src' 32 inputs.files sourcesWithoutTypegen
28 inputs.file 'index.html' 33 inputs.file 'index.html'
29 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'vite.config.ts') 34 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'vite.config.ts')
30 inputs.file rootProject.file('yarn.lock') 35 inputs.file rootProject.file('yarn.lock')
@@ -37,9 +42,21 @@ artifacts {
37 } 42 }
38} 43}
39 44
45def generateXStateTypes = tasks.register('generateXStateTypes', RunYarn) {
46 dependsOn installFrontend
47 inputs.files sourcesWithoutTypegen
48 inputs.file 'package.json'
49 inputs.file rootProject.file('yarn.lock')
50 outputs.dir 'src'
51 script = 'run typegen'
52 description = 'Generate TypeScript typings for XState state machines.'
53}
54
40def typecheckFrontend = tasks.register('typecheckFrontend', RunYarn) { 55def typecheckFrontend = tasks.register('typecheckFrontend', RunYarn) {
41 dependsOn installFrontend 56 dependsOn installFrontend
57 dependsOn generateXStateTypes
42 inputs.dir 'src' 58 inputs.dir 'src'
59 inputs.dir 'types'
43 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'tsconfig.node.json') 60 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'tsconfig.node.json')
44 inputs.file rootProject.file('yarn.lock') 61 inputs.file rootProject.file('yarn.lock')
45 outputs.dir "${buildDir}/typescript" 62 outputs.dir "${buildDir}/typescript"
@@ -50,7 +67,9 @@ def typecheckFrontend = tasks.register('typecheckFrontend', RunYarn) {
50 67
51def lintFrontend = tasks.register('lintFrontend', RunYarn) { 68def lintFrontend = tasks.register('lintFrontend', RunYarn) {
52 dependsOn installFrontend 69 dependsOn installFrontend
70 dependsOn generateXStateTypes
53 inputs.dir 'src' 71 inputs.dir 'src'
72 inputs.dir 'types'
54 inputs.files('.eslintrc.cjs', 'prettier.config.cjs') 73 inputs.files('.eslintrc.cjs', 'prettier.config.cjs')
55 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'tsconfig.node.json') 74 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'tsconfig.node.json')
56 inputs.file rootProject.file('yarn.lock') 75 inputs.file rootProject.file('yarn.lock')
@@ -66,7 +85,9 @@ def lintFrontend = tasks.register('lintFrontend', RunYarn) {
66 85
67def prettier = tasks.register('fixFrontend', RunYarn) { 86def prettier = tasks.register('fixFrontend', RunYarn) {
68 dependsOn installFrontend 87 dependsOn installFrontend
88 dependsOn generateXStateTypes
69 inputs.dir 'src' 89 inputs.dir 'src'
90 inputs.dir 'types'
70 inputs.files('.eslintrc.cjs', 'prettier.config.cjs') 91 inputs.files('.eslintrc.cjs', 'prettier.config.cjs')
71 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'tsconfig.node.json') 92 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'tsconfig.node.json')
72 inputs.file rootProject.file('yarn.lock') 93 inputs.file rootProject.file('yarn.lock')
@@ -82,8 +103,9 @@ tasks.named('check') {
82 103
83tasks.register('serveFrontend', RunYarn) { 104tasks.register('serveFrontend', RunYarn) {
84 dependsOn installFrontend 105 dependsOn installFrontend
106 dependsOn generateXStateTypes
85 inputs.dir 'public' 107 inputs.dir 'public'
86 inputs.dir 'src' 108 inputs.files sourcesWithoutTypegen
87 inputs.file 'index.html' 109 inputs.file 'index.html'
88 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'vite.config.ts') 110 inputs.files('package.json', 'tsconfig.json', 'tsconfig.base.json', 'vite.config.ts')
89 inputs.file rootProject.file('yarn.lock') 111 inputs.file rootProject.file('yarn.lock')
@@ -95,6 +117,9 @@ tasks.register('serveFrontend', RunYarn) {
95 117
96tasks.named('clean') { 118tasks.named('clean') {
97 delete 'dev-dist' 119 delete 'dev-dist'
120 delete fileTree('src') {
121 include '**/*.typegen.ts'
122 }
98} 123}
99 124
100sonarqube.properties { 125sonarqube.properties {
diff --git a/subprojects/frontend/package.json b/subprojects/frontend/package.json
index b80e0561..9202542b 100644
--- a/subprojects/frontend/package.json
+++ b/subprojects/frontend/package.json
@@ -6,6 +6,7 @@
6 "scripts": { 6 "scripts": {
7 "build": "cross-env MODE=production vite build", 7 "build": "cross-env MODE=production vite build",
8 "serve": "cross-env MODE=development vite serve", 8 "serve": "cross-env MODE=development vite serve",
9 "typegen": "xstate typegen \"src/**/*.ts?(x)\"",
9 "typecheck": "tsc -p tsconfig.node.json && tsc -p tsconfig.json", 10 "typecheck": "tsc -p tsconfig.node.json && tsc -p tsconfig.json",
10 "lint": "eslint .", 11 "lint": "eslint .",
11 "lint:ci": "eslint -f json -o build/eslint.json .", 12 "lint:ci": "eslint -f json -o build/eslint.json .",
@@ -28,17 +29,17 @@
28 "@codemirror/lint": "^6.0.0", 29 "@codemirror/lint": "^6.0.0",
29 "@codemirror/search": "^6.2.0", 30 "@codemirror/search": "^6.2.0",
30 "@codemirror/state": "^6.1.1", 31 "@codemirror/state": "^6.1.1",
31 "@codemirror/view": "^6.2.1", 32 "@codemirror/view": "^6.2.2",
32 "@emotion/react": "^11.10.0", 33 "@emotion/react": "^11.10.4",
33 "@emotion/styled": "^11.10.0", 34 "@emotion/styled": "^11.10.4",
34 "@fontsource/jetbrains-mono": "^4.5.10", 35 "@fontsource/jetbrains-mono": "^4.5.10",
35 "@fontsource/roboto": "^4.5.8", 36 "@fontsource/roboto": "^4.5.8",
36 "@lezer/common": "^1.0.0", 37 "@lezer/common": "^1.0.1",
37 "@lezer/highlight": "^1.0.0", 38 "@lezer/highlight": "^1.0.0",
38 "@lezer/lr": "^1.2.3", 39 "@lezer/lr": "^1.2.3",
39 "@material-icons/svg": "^1.0.32", 40 "@material-icons/svg": "^1.0.33",
40 "@mui/icons-material": "5.10.2", 41 "@mui/icons-material": "5.10.3",
41 "@mui/material": "5.10.2", 42 "@mui/material": "5.10.3",
42 "ansi-styles": "^6.1.0", 43 "ansi-styles": "^6.1.0",
43 "escape-string-regexp": "^5.0.0", 44 "escape-string-regexp": "^5.0.0",
44 "lodash-es": "^4.17.21", 45 "lodash-es": "^4.17.21",
@@ -50,6 +51,7 @@
50 "notistack": "^2.0.5", 51 "notistack": "^2.0.5",
51 "react": "^18.2.0", 52 "react": "^18.2.0",
52 "react-dom": "^18.2.0", 53 "react-dom": "^18.2.0",
54 "xstate": "^4.33.5",
53 "zod": "^3.18.0" 55 "zod": "^3.18.0"
54 }, 56 },
55 "devDependencies": { 57 "devDependencies": {
@@ -57,13 +59,15 @@
57 "@types/eslint": "^8.4.6", 59 "@types/eslint": "^8.4.6",
58 "@types/html-minifier-terser": "^7.0.0", 60 "@types/html-minifier-terser": "^7.0.0",
59 "@types/lodash-es": "^4.17.6", 61 "@types/lodash-es": "^4.17.6",
60 "@types/node": "^18.7.13", 62 "@types/ms": "^0.7.31",
63 "@types/node": "^18.7.14",
61 "@types/prettier": "^2.7.0", 64 "@types/prettier": "^2.7.0",
62 "@types/react": "^18.0.17", 65 "@types/react": "^18.0.18",
63 "@types/react-dom": "^18.0.6", 66 "@types/react-dom": "^18.0.6",
64 "@typescript-eslint/eslint-plugin": "^5.35.1", 67 "@typescript-eslint/eslint-plugin": "^5.36.1",
65 "@typescript-eslint/parser": "^5.35.1", 68 "@typescript-eslint/parser": "^5.36.1",
66 "@vitejs/plugin-react": "^2.0.1", 69 "@vitejs/plugin-react": "^2.0.1",
70 "@xstate/cli": "^0.3.2",
67 "cross-env": "^7.0.3", 71 "cross-env": "^7.0.3",
68 "eslint": "^8.23.0", 72 "eslint": "^8.23.0",
69 "eslint-config-airbnb": "^19.0.4", 73 "eslint-config-airbnb": "^19.0.4",
@@ -74,14 +78,14 @@
74 "eslint-plugin-jsx-a11y": "^6.6.1", 78 "eslint-plugin-jsx-a11y": "^6.6.1",
75 "eslint-plugin-mobx": "^0.0.9", 79 "eslint-plugin-mobx": "^0.0.9",
76 "eslint-plugin-prettier": "^4.2.1", 80 "eslint-plugin-prettier": "^4.2.1",
77 "eslint-plugin-react": "^7.31.1", 81 "eslint-plugin-react": "^7.31.6",
78 "eslint-plugin-react-hooks": "^4.6.0", 82 "eslint-plugin-react-hooks": "^4.6.0",
79 "html-minifier-terser": "^7.0.0", 83 "html-minifier-terser": "^7.0.0",
80 "prettier": "^2.7.1", 84 "prettier": "^2.7.1",
81 "typescript": "~4.8.2", 85 "typescript": "~4.8.2",
82 "vite": "^3.0.9", 86 "vite": "^3.0.9",
83 "vite-plugin-inject-preload": "^1.1.0", 87 "vite-plugin-inject-preload": "^1.1.0",
84 "vite-plugin-pwa": "^0.12.3", 88 "vite-plugin-pwa": "^0.12.6",
85 "workbox-window": "^6.5.4" 89 "workbox-window": "^6.5.4"
86 } 90 }
87} 91}
diff --git a/subprojects/frontend/src/index.tsx b/subprojects/frontend/src/index.tsx
index 8436c7ae..9f413b85 100644
--- a/subprojects/frontend/src/index.tsx
+++ b/subprojects/frontend/src/index.tsx
@@ -63,7 +63,6 @@ scope Family = 1, Person += 5..10.
63 63
64configure({ 64configure({
65 enforceActions: 'always', 65 enforceActions: 'always',
66 reactionRequiresObservable: true,
67}); 66});
68 67
69const rootStore = new RootStore(initialValue); 68const rootStore = new RootStore(initialValue);
diff --git a/subprojects/frontend/src/utils/CancelledError.ts b/subprojects/frontend/src/utils/CancelledError.ts
index 8d3e55d8..ee23676f 100644
--- a/subprojects/frontend/src/utils/CancelledError.ts
+++ b/subprojects/frontend/src/utils/CancelledError.ts
@@ -1,5 +1,5 @@
1export default class CancelledError extends Error { 1export default class CancelledError extends Error {
2 constructor() { 2 constructor(message = 'Operation cancelled') {
3 super('Operation cancelled'); 3 super(message);
4 } 4 }
5} 5}
diff --git a/subprojects/frontend/src/utils/Timer.ts b/subprojects/frontend/src/utils/Timer.ts
deleted file mode 100644
index 4bb1bb9c..00000000
--- a/subprojects/frontend/src/utils/Timer.ts
+++ /dev/null
@@ -1,33 +0,0 @@
1export default class Timer {
2 private readonly callback: () => void;
3
4 private readonly defaultTimeout: number;
5
6 private timeout: number | undefined;
7
8 constructor(callback: () => void, defaultTimeout = 0) {
9 this.callback = () => {
10 this.timeout = undefined;
11 callback();
12 };
13 this.defaultTimeout = defaultTimeout;
14 }
15
16 schedule(timeout?: number | undefined): void {
17 if (this.timeout === undefined) {
18 this.timeout = setTimeout(this.callback, timeout ?? this.defaultTimeout);
19 }
20 }
21
22 reschedule(timeout?: number | undefined): void {
23 this.cancel();
24 this.schedule(timeout);
25 }
26
27 cancel(): void {
28 if (this.timeout !== undefined) {
29 clearTimeout(this.timeout);
30 this.timeout = undefined;
31 }
32 }
33}
diff --git a/subprojects/frontend/src/xtext/UpdateService.ts b/subprojects/frontend/src/xtext/UpdateService.ts
index f1abce52..d7471cdc 100644
--- a/subprojects/frontend/src/xtext/UpdateService.ts
+++ b/subprojects/frontend/src/xtext/UpdateService.ts
@@ -83,7 +83,7 @@ export default class UpdateService {
83 } 83 }
84 84
85 private idleUpdate(): void { 85 private idleUpdate(): void {
86 if (!this.webSocketClient.isOpen || !this.tracker.needsUpdate) { 86 if (!this.webSocketClient.opened || !this.tracker.needsUpdate) {
87 return; 87 return;
88 } 88 }
89 if (!this.tracker.lockedForUpdate) { 89 if (!this.tracker.lockedForUpdate) {
diff --git a/subprojects/frontend/src/xtext/XtextWebSocketClient.ts b/subprojects/frontend/src/xtext/XtextWebSocketClient.ts
index 60bf6ba9..eedfa365 100644
--- a/subprojects/frontend/src/xtext/XtextWebSocketClient.ts
+++ b/subprojects/frontend/src/xtext/XtextWebSocketClient.ts
@@ -1,34 +1,22 @@
1import { createAtom, makeAutoObservable, observable } from 'mobx';
1import { nanoid } from 'nanoid'; 2import { nanoid } from 'nanoid';
3import { interpret } from 'xstate';
2 4
5import CancelledError from '../utils/CancelledError';
3import PendingTask from '../utils/PendingTask'; 6import PendingTask from '../utils/PendingTask';
4import Timer from '../utils/Timer';
5import getLogger from '../utils/getLogger'; 7import getLogger from '../utils/getLogger';
6 8
9import webSocketMachine from './webSocketMachine';
7import { 10import {
8 XtextWebErrorResponse, 11 type XtextWebPushService,
9 XtextWebRequest, 12 XtextResponse,
10 XtextWebOkResponse, 13 type XtextWebRequest,
11 XtextWebPushMessage,
12 XtextWebPushService,
13} from './xtextMessages'; 14} from './xtextMessages';
14import { PongResult } from './xtextServiceResults'; 15import { PongResult } from './xtextServiceResults';
15 16
16const XTEXT_SUBPROTOCOL_V1 = 'tools.refinery.language.web.xtext.v1'; 17const XTEXT_SUBPROTOCOL_V1 = 'tools.refinery.language.web.xtext.v1';
17 18
18const WEBSOCKET_CLOSE_OK = 1000; 19const REQUEST_TIMEOUT = 1000;
19
20const WEBSOCKET_CLOSE_GOING_AWAY = 1001;
21
22const RECONNECT_DELAY_MS = [200, 1000, 5000, 30_000];
23
24const MAX_RECONNECT_DELAY_MS =
25 RECONNECT_DELAY_MS[RECONNECT_DELAY_MS.length - 1];
26
27const BACKGROUND_IDLE_TIMEOUT_MS = 5 * 60 * 1000;
28
29const PING_TIMEOUT_MS = 10 * 1000;
30
31const REQUEST_TIMEOUT_MS = 1000;
32 20
33const log = getLogger('xtext.XtextWebSocketClient'); 21const log = getLogger('xtext.XtextWebSocketClient');
34 22
@@ -41,351 +29,250 @@ export type PushHandler = (
41 data: unknown, 29 data: unknown,
42) => void; 30) => void;
43 31
44enum State {
45 Initial,
46 Opening,
47 TabVisible,
48 TabHiddenIdle,
49 TabHiddenWaitingToClose,
50 Error,
51 ClosedDueToInactivity,
52}
53
54export default class XtextWebSocketClient { 32export default class XtextWebSocketClient {
55 private nextMessageId = 0; 33 private readonly stateAtom = createAtom('state');
56 34
57 private connection!: WebSocket; 35 private webSocket: WebSocket | undefined;
58 36
59 private readonly pendingRequests = new Map<string, PendingTask<unknown>>(); 37 private readonly pendingRequests = new Map<string, PendingTask<unknown>>();
60 38
61 private readonly onReconnect: ReconnectHandler; 39 private readonly interpreter = interpret(
62 40 webSocketMachine
63 private readonly onPush: PushHandler; 41 .withContext({
64 42 ...webSocketMachine.context,
65 private state = State.Initial; 43 webSocketURL: `${window.location.origin.replace(
66 44 /^http/,
67 private reconnectTryCount = 0; 45 'ws',
68 46 )}/xtext-service`,
69 private readonly idleTimer = new Timer(() => { 47 })
70 this.handleIdleTimeout(); 48 .withConfig({
71 }, BACKGROUND_IDLE_TIMEOUT_MS); 49 actions: {
72 50 openWebSocket: ({ webSocketURL }) => this.openWebSocket(webSocketURL),
73 private readonly pingTimer = new Timer(() => { 51 closeWebSocket: () => this.closeWebSocket(),
74 this.sendPing(); 52 notifyReconnect: () => this.onReconnect(),
75 }, PING_TIMEOUT_MS); 53 cancelPendingRequests: () => this.cancelPendingRequests(),
54 },
55 services: {
56 pingService: () => this.sendPing(),
57 },
58 }),
59 {
60 logger: log.log.bind(log),
61 },
62 );
63
64 private readonly openListener = () => {
65 if (this.webSocket === undefined) {
66 throw new Error('Open listener called without a WebSocket');
67 }
68 const {
69 webSocket: { protocol },
70 } = this;
71 if (protocol === XTEXT_SUBPROTOCOL_V1) {
72 this.interpreter.send('OPENED');
73 } else {
74 this.interpreter.send({
75 type: 'ERROR',
76 message: `Unknown subprotocol ${protocol}`,
77 });
78 }
79 };
76 80
77 private readonly reconnectTimer = new Timer(() => { 81 private readonly errorListener = (event: Event) => {
78 this.handleReconnect(); 82 log.error('WebSocket error', event);
79 }); 83 this.interpreter.send({ type: 'ERROR', message: 'WebSocket error' });
84 };
80 85
81 constructor(onReconnect: ReconnectHandler, onPush: PushHandler) { 86 private readonly closeListener = ({ code, reason }: CloseEvent) =>
82 this.onReconnect = onReconnect; 87 this.interpreter.send({
83 this.onPush = onPush; 88 type: 'ERROR',
84 document.addEventListener('visibilitychange', () => { 89 message: `Socket closed unexpectedly: ${code} ${reason}`,
85 this.handleVisibilityChange();
86 }); 90 });
87 this.reconnect();
88 }
89 91
90 private get isLogicallyClosed(): boolean { 92 private readonly messageListener = ({ data }: MessageEvent) => {
91 return ( 93 if (typeof data !== 'string') {
92 this.state === State.Error || this.state === State.ClosedDueToInactivity 94 this.interpreter.send({
93 ); 95 type: 'ERROR',
94 } 96 message: 'Unexpected message format',
95 97 });
96 get isOpen(): boolean {
97 return (
98 this.state === State.TabVisible ||
99 this.state === State.TabHiddenIdle ||
100 this.state === State.TabHiddenWaitingToClose
101 );
102 }
103
104 private reconnect() {
105 if (this.isOpen || this.state === State.Opening) {
106 log.error('Trying to reconnect from', this.state);
107 return; 98 return;
108 } 99 }
109 this.state = State.Opening; 100 let json: unknown;
110 const webSocketServer = window.origin.replace(/^http/, 'ws'); 101 try {
111 const webSocketUrl = `${webSocketServer}/xtext-service`; 102 json = JSON.parse(data);
112 this.connection = new WebSocket(webSocketUrl, XTEXT_SUBPROTOCOL_V1); 103 } catch (error) {
113 this.connection.addEventListener('open', () => { 104 log.error('JSON parse error', error);
114 if (this.connection.protocol !== XTEXT_SUBPROTOCOL_V1) { 105 this.interpreter.send({ type: 'ERROR', message: 'Malformed message' });
115 log.error(
116 'Unknown subprotocol',
117 this.connection.protocol,
118 'selected by server',
119 );
120 this.forceReconnectOnError();
121 }
122 if (document.visibilityState === 'hidden') {
123 this.handleTabHidden();
124 } else {
125 this.handleTabVisibleConnected();
126 }
127 log.info('Connected to websocket');
128 this.nextMessageId = 0;
129 this.reconnectTryCount = 0;
130 this.pingTimer.schedule();
131 this.onReconnect();
132 });
133 this.connection.addEventListener('error', (event) => {
134 log.error('Unexpected websocket error', event);
135 this.forceReconnectOnError();
136 });
137 this.connection.addEventListener('message', (event) => {
138 this.handleMessage(event.data);
139 });
140 this.connection.addEventListener('close', (event) => {
141 const closedOnRequest =
142 this.isLogicallyClosed &&
143 event.code === WEBSOCKET_CLOSE_OK &&
144 this.pendingRequests.size === 0;
145 const closedOnNavigation = event.code === WEBSOCKET_CLOSE_GOING_AWAY;
146 if (closedOnNavigation) {
147 this.state = State.ClosedDueToInactivity;
148 }
149 if (closedOnRequest || closedOnNavigation) {
150 log.info('Websocket closed');
151 return;
152 }
153 log.error('Websocket closed unexpectedly', event.code, event.reason);
154 this.forceReconnectOnError();
155 });
156 }
157
158 private handleVisibilityChange() {
159 if (document.visibilityState === 'hidden') {
160 if (this.state === State.TabVisible) {
161 this.handleTabHidden();
162 }
163 return; 106 return;
164 } 107 }
165 this.idleTimer.cancel(); 108 const responseResult = XtextResponse.safeParse(json);
166 if ( 109 if (!responseResult.success) {
167 this.state === State.TabHiddenIdle || 110 log.error('Xtext response', json, 'is malformed:', responseResult.error);
168 this.state === State.TabHiddenWaitingToClose 111 this.interpreter.send({ type: 'ERROR', message: 'Malformed message' });
169 ) {
170 this.handleTabVisibleConnected();
171 return; 112 return;
172 } 113 }
173 if (this.state === State.ClosedDueToInactivity) { 114 const { data: response } = responseResult;
174 this.reconnect(); 115 if ('service' in response) {
116 // `XtextWebPushMessage.push` is optional, but `service` is not.
117 const { resource, stateId, service, push } = response;
118 this.onPush(resource, stateId, service, push);
119 return;
120 }
121 const { id } = response;
122 const task = this.pendingRequests.get(id);
123 if (task === undefined) {
124 log.warn('Task', id, 'has been already resolved');
125 return;
126 }
127 this.removeTask(id);
128 if ('error' in response) {
129 const formattedMessage = `${response.error} error: ${response.message}`;
130 log.error('Task', id, formattedMessage);
131 task.reject(new Error(formattedMessage));
132 } else {
133 task.resolve(response.response);
175 } 134 }
135 };
136
137 constructor(
138 private readonly onReconnect: ReconnectHandler,
139 private readonly onPush: PushHandler,
140 ) {
141 this.interpreter
142 .onTransition((state, event) => {
143 log.trace('WebSocke state transition', state.value, 'on event', event);
144 this.stateAtom.reportChanged();
145 })
146 .start();
147
148 this.updateVisibility();
149 document.addEventListener('visibilitychange', () =>
150 this.updateVisibility(),
151 );
152
153 this.interpreter.send('CONNECT');
154
155 makeAutoObservable<
156 XtextWebSocketClient,
157 | 'stateAtom'
158 | 'webSocket'
159 | 'interpreter'
160 | 'openListener'
161 | 'errorListener'
162 | 'closeListener'
163 | 'messageListener'
164 | 'sendPing'
165 >(this, {
166 stateAtom: false,
167 webSocket: observable.ref,
168 interpreter: false,
169 openListener: false,
170 errorListener: false,
171 closeListener: false,
172 messageListener: false,
173 sendPing: false,
174 });
176 } 175 }
177 176
178 private handleTabHidden() { 177 get state() {
179 log.debug('Tab hidden while websocket is connected'); 178 this.stateAtom.reportObserved();
180 this.state = State.TabHiddenIdle; 179 return this.interpreter.state;
181 this.idleTimer.schedule();
182 } 180 }
183 181
184 private handleTabVisibleConnected() { 182 get opened(): boolean {
185 log.debug('Tab visible while websocket is connected'); 183 return this.state.matches('connection.socketCreated.open.opened');
186 this.state = State.TabVisible;
187 } 184 }
188 185
189 private handleIdleTimeout() { 186 connect(): void {
190 log.trace('Waiting for pending tasks before disconnect'); 187 this.interpreter.send('CONNECT');
191 if (this.state === State.TabHiddenIdle) {
192 this.state = State.TabHiddenWaitingToClose;
193 this.handleWaitingForDisconnect();
194 }
195 } 188 }
196 189
197 private handleWaitingForDisconnect() { 190 disconnect(): void {
198 if (this.state !== State.TabHiddenWaitingToClose) { 191 this.interpreter.send('DISCONNECT');
199 return;
200 }
201 const pending = this.pendingRequests.size;
202 if (pending === 0) {
203 log.info('Closing idle websocket');
204 this.state = State.ClosedDueToInactivity;
205 this.closeConnection(1000, 'idle timeout');
206 return;
207 }
208 log.info(
209 'Waiting for',
210 pending,
211 'pending requests before closing websocket',
212 );
213 } 192 }
214 193
215 private sendPing() { 194 forceReconnectOnError(): void {
216 if (!this.isOpen) { 195 this.interpreter.send({
217 return; 196 type: 'ERROR',
218 } 197 message: 'Client error',
219 const ping = nanoid(); 198 });
220 log.trace('Ping', ping);
221 this.send({ ping })
222 .then((result) => {
223 const parsedPongResult = PongResult.safeParse(result);
224 if (parsedPongResult.success && parsedPongResult.data.pong === ping) {
225 log.trace('Pong', ping);
226 this.pingTimer.schedule();
227 } else {
228 log.error('Invalid pong:', parsedPongResult, 'expected:', ping);
229 this.forceReconnectOnError();
230 }
231 })
232 .catch((error) => {
233 log.error('Error while waiting for ping', error);
234 this.forceReconnectOnError();
235 });
236 } 199 }
237 200
238 send(request: unknown): Promise<unknown> { 201 send(request: unknown): Promise<unknown> {
239 if (!this.isOpen) { 202 if (!this.opened || this.webSocket === undefined) {
240 throw new Error('Not open'); 203 throw new Error('Not connected');
241 }
242 const messageId = this.nextMessageId.toString(16);
243 if (messageId in this.pendingRequests) {
244 log.error('Message id wraparound still pending', messageId);
245 this.rejectRequest(messageId, new Error('Message id wraparound'));
246 } 204 }
247 if (this.nextMessageId >= Number.MAX_SAFE_INTEGER) { 205
248 this.nextMessageId = 0; 206 const id = nanoid();
249 } else { 207
250 this.nextMessageId += 1; 208 const promise = new Promise((resolve, reject) => {
251 } 209 const task = new PendingTask(resolve, reject, REQUEST_TIMEOUT, () =>
252 const message = JSON.stringify({ 210 this.removeTask(id),
253 id: messageId, 211 );
254 request, 212 this.pendingRequests.set(id, task);
255 } as XtextWebRequest);
256 log.trace('Sending message', message);
257 return new Promise((resolve, reject) => {
258 const task = new PendingTask(resolve, reject, REQUEST_TIMEOUT_MS, () => {
259 this.removePendingRequest(messageId);
260 });
261 this.pendingRequests.set(messageId, task);
262 this.connection.send(message);
263 }); 213 });
214
215 const webRequest: XtextWebRequest = { id, request };
216 const json = JSON.stringify(webRequest);
217 this.webSocket.send(json);
218
219 return promise;
264 } 220 }
265 221
266 private handleMessage(messageStr: unknown) { 222 private updateVisibility(): void {
267 if (typeof messageStr !== 'string') { 223 this.interpreter.send(document.hidden ? 'TAB_HIDDEN' : 'TAB_VISIBLE');
268 log.error('Unexpected binary message', messageStr);
269 this.forceReconnectOnError();
270 return;
271 }
272 log.trace('Incoming websocket message', messageStr);
273 let message: unknown;
274 try {
275 message = JSON.parse(messageStr);
276 } catch (error) {
277 log.error('Json parse error', error);
278 this.forceReconnectOnError();
279 return;
280 }
281 const okResponse = XtextWebOkResponse.safeParse(message);
282 if (okResponse.success) {
283 const { id, response } = okResponse.data;
284 this.resolveRequest(id, response);
285 return;
286 }
287 const errorResponse = XtextWebErrorResponse.safeParse(message);
288 if (errorResponse.success) {
289 const { id, error, message: errorMessage } = errorResponse.data;
290 this.rejectRequest(id, new Error(`${error} error: ${errorMessage}`));
291 if (error === 'server') {
292 log.error('Reconnecting due to server error: ', errorMessage);
293 this.forceReconnectOnError();
294 }
295 return;
296 }
297 const pushMessage = XtextWebPushMessage.safeParse(message);
298 if (pushMessage.success) {
299 const { resource, stateId, service, push } = pushMessage.data;
300 this.onPush(resource, stateId, service, push);
301 } else {
302 log.error(
303 'Unexpected websocket message:',
304 message,
305 'not ok response because:',
306 okResponse.error,
307 'not error response because:',
308 errorResponse.error,
309 'not push message because:',
310 pushMessage.error,
311 );
312 this.forceReconnectOnError();
313 }
314 } 224 }
315 225
316 private resolveRequest(messageId: string, value: unknown) { 226 private openWebSocket(webSocketURL: string | undefined): void {
317 const pendingRequest = this.pendingRequests.get(messageId); 227 if (this.webSocket !== undefined) {
318 if (pendingRequest) { 228 throw new Error('WebSocket already open');
319 pendingRequest.resolve(value);
320 this.removePendingRequest(messageId);
321 return;
322 } 229 }
323 log.error('Trying to resolve unknown request', messageId, 'with', value);
324 }
325 230
326 private rejectRequest(messageId: string, reason?: unknown) { 231 if (webSocketURL === undefined) {
327 const pendingRequest = this.pendingRequests.get(messageId); 232 throw new Error('URL not configured');
328 if (pendingRequest) {
329 pendingRequest.reject(reason);
330 this.removePendingRequest(messageId);
331 return;
332 } 233 }
333 log.error('Trying to reject unknown request', messageId, 'with', reason);
334 }
335 234
336 private removePendingRequest(messageId: string) { 235 log.debug('Creating WebSocket');
337 this.pendingRequests.delete(messageId); 236
338 this.handleWaitingForDisconnect(); 237 this.webSocket = new WebSocket(webSocketURL, XTEXT_SUBPROTOCOL_V1);
238 this.webSocket.addEventListener('open', this.openListener);
239 this.webSocket.addEventListener('close', this.closeListener);
240 this.webSocket.addEventListener('error', this.errorListener);
241 this.webSocket.addEventListener('message', this.messageListener);
339 } 242 }
340 243
341 forceReconnectOnError(): void { 244 private closeWebSocket() {
342 if (this.isLogicallyClosed) { 245 if (this.webSocket === undefined) {
343 return; 246 throw new Error('WebSocket already closed');
344 }
345 this.pendingRequests.forEach((request) => {
346 request.reject(new Error('Websocket disconnect'));
347 });
348 this.pendingRequests.clear();
349 this.closeConnection(1000, 'reconnecting due to error');
350 if (this.state === State.Error) {
351 // We are already handling this error condition.
352 return;
353 } 247 }
354 if ( 248
355 this.state === State.TabHiddenIdle || 249 log.debug('Closing WebSocket');
356 this.state === State.TabHiddenWaitingToClose 250
357 ) { 251 this.webSocket.removeEventListener('open', this.openListener);
358 log.error('Will reconned due to error once the tab becomes visible'); 252 this.webSocket.removeEventListener('close', this.closeListener);
359 this.idleTimer.cancel(); 253 this.webSocket.removeEventListener('error', this.errorListener);
360 this.state = State.ClosedDueToInactivity; 254 this.webSocket.removeEventListener('message', this.messageListener);
361 return; 255 this.webSocket.close(1000, 'Closing connection');
362 } 256 this.webSocket = undefined;
363 log.error('Reconnecting after delay due to error');
364 this.state = State.Error;
365 this.reconnectTryCount += 1;
366 const delay =
367 RECONNECT_DELAY_MS[this.reconnectTryCount - 1] ?? MAX_RECONNECT_DELAY_MS;
368 log.info('Reconnecting in', delay, 'ms');
369 this.reconnectTimer.schedule(delay);
370 } 257 }
371 258
372 private closeConnection(code: number, reason: string) { 259 private removeTask(id: string): void {
373 this.pingTimer.cancel(); 260 this.pendingRequests.delete(id);
374 const { readyState } = this.connection;
375 if (readyState !== WebSocket.CLOSING && readyState !== WebSocket.CLOSED) {
376 this.connection.close(code, reason);
377 }
378 } 261 }
379 262
380 private handleReconnect() { 263 private cancelPendingRequests(): void {
381 if (this.state !== State.Error) { 264 this.pendingRequests.forEach((task) =>
382 log.error('Unexpected reconnect in', this.state); 265 task.reject(new CancelledError('Closing connection')),
383 return; 266 );
384 } 267 this.pendingRequests.clear();
385 if (document.visibilityState === 'hidden') { 268 }
386 this.state = State.ClosedDueToInactivity; 269
387 } else { 270 private async sendPing(): Promise<void> {
388 this.reconnect(); 271 const ping = nanoid();
272 const result = await this.send({ ping });
273 const { pong } = PongResult.parse(result);
274 if (ping !== pong) {
275 throw new Error(`Expected pong ${ping} but got ${pong} instead`);
389 } 276 }
390 } 277 }
391} 278}
diff --git a/subprojects/frontend/src/xtext/webSocketMachine.ts b/subprojects/frontend/src/xtext/webSocketMachine.ts
new file mode 100644
index 00000000..50eb36a0
--- /dev/null
+++ b/subprojects/frontend/src/xtext/webSocketMachine.ts
@@ -0,0 +1,215 @@
1import { actions, assign, createMachine, RaiseAction } from 'xstate';
2
3const { raise } = actions;
4
5const ERROR_WAIT_TIMES = [200, 1000, 5000, 30_000];
6
7export interface WebSocketContext {
8 webSocketURL: string | undefined;
9 errors: string[];
10 retryCount: number;
11}
12
13export type WebSocketEvent =
14 | { type: 'CONFIGURE'; webSocketURL: string }
15 | { type: 'CONNECT' }
16 | { type: 'DISCONNECT' }
17 | { type: 'OPENED' }
18 | { type: 'TAB_VISIBLE' }
19 | { type: 'TAB_HIDDEN' }
20 | { type: 'ERROR'; message: string };
21
22export default createMachine(
23 {
24 id: 'webSocket',
25 predictableActionArguments: true,
26 schema: {
27 context: {} as WebSocketContext,
28 events: {} as WebSocketEvent,
29 },
30 tsTypes: {} as import('./webSocketMachine.typegen').Typegen0,
31 context: {
32 webSocketURL: undefined,
33 errors: [],
34 retryCount: 0,
35 },
36 type: 'parallel',
37 states: {
38 connection: {
39 initial: 'disconnected',
40 states: {
41 disconnected: {
42 id: 'disconnected',
43 on: {
44 CONFIGURE: { actions: 'configure' },
45 },
46 },
47 timedOut: {
48 id: 'timedOut',
49 on: {
50 TAB_VISIBLE: 'socketCreated',
51 },
52 },
53 errorWait: {
54 id: 'errorWait',
55 after: {
56 ERROR_WAIT_TIME: [
57 { target: 'timedOut', in: '#tabHidden' },
58 { target: 'socketCreated' },
59 ],
60 },
61 },
62 socketCreated: {
63 type: 'parallel',
64 entry: 'openWebSocket',
65 exit: ['cancelPendingRequests', 'closeWebSocket'],
66 states: {
67 open: {
68 initial: 'opening',
69 states: {
70 opening: {
71 after: {
72 OPEN_TIMEOUT: {
73 actions: 'raiseTimeoutError',
74 },
75 },
76 on: {
77 OPENED: {
78 target: 'opened',
79 actions: ['clearError', 'notifyReconnect'],
80 },
81 },
82 },
83 opened: {
84 initial: 'pongReceived',
85 states: {
86 pongReceived: {
87 after: {
88 PING_PERIOD: 'pingSent',
89 },
90 },
91 pingSent: {
92 invoke: {
93 src: 'pingService',
94 onDone: 'pongReceived',
95 onError: {
96 actions: 'raisePromiseRejectionError',
97 },
98 },
99 },
100 },
101 },
102 },
103 },
104 idle: {
105 initial: 'getTabState',
106 states: {
107 getTabState: {
108 always: [
109 { target: 'inactive', in: '#tabHidden' },
110 'active',
111 ],
112 },
113 active: {
114 on: {
115 TAB_HIDDEN: 'inactive',
116 },
117 },
118 inactive: {
119 after: {
120 IDLE_TIMEOUT: '#timedOut',
121 },
122 on: {
123 TAB_VISIBLE: 'active',
124 },
125 },
126 },
127 },
128 },
129 on: {
130 CONNECT: undefined,
131 ERROR: {
132 target: '#errorWait',
133 actions: 'increaseRetryCount',
134 },
135 },
136 },
137 },
138 on: {
139 CONNECT: { target: '.socketCreated', cond: 'hasWebSocketURL' },
140 DISCONNECT: { target: '.disconnected', actions: 'clearError' },
141 },
142 },
143 tab: {
144 initial: 'visibleOrUnknown',
145 states: {
146 visibleOrUnknown: {
147 on: {
148 TAB_HIDDEN: 'hidden',
149 },
150 },
151 hidden: {
152 id: 'tabHidden',
153 on: {
154 TAB_VISIBLE: 'visibleOrUnknown',
155 },
156 },
157 },
158 },
159 error: {
160 initial: 'init',
161 states: {
162 init: {
163 on: {
164 ERROR: { actions: 'pushError' },
165 },
166 },
167 },
168 },
169 },
170 },
171 {
172 guards: {
173 hasWebSocketURL: ({ webSocketURL }) => webSocketURL !== undefined,
174 },
175 delays: {
176 IDLE_TIMEOUT: 300_000,
177 OPEN_TIMEOUT: 5000,
178 PING_PERIOD: 10_000,
179 ERROR_WAIT_TIME: ({ retryCount }) => {
180 const { length } = ERROR_WAIT_TIMES;
181 const index = retryCount < length ? retryCount : length - 1;
182 return ERROR_WAIT_TIMES[index];
183 },
184 },
185 actions: {
186 configure: assign((context, { webSocketURL }) => ({
187 ...context,
188 webSocketURL,
189 })),
190 pushError: assign((context, { message }) => ({
191 ...context,
192 errors: [...context.errors, message],
193 })),
194 increaseRetryCount: assign((context) => ({
195 ...context,
196 retryCount: context.retryCount + 1,
197 })),
198 clearError: assign((context) => ({
199 ...context,
200 errors: [],
201 retryCount: 0,
202 })),
203 // Workaround from https://github.com/statelyai/xstate/issues/1414#issuecomment-699972485
204 raiseTimeoutError: raise({
205 type: 'ERROR',
206 message: 'Open timeout',
207 }) as RaiseAction<WebSocketEvent>,
208 raisePromiseRejectionError: (_context, { data }) =>
209 raise({
210 type: 'ERROR',
211 message: data,
212 }) as RaiseAction<WebSocketEvent>,
213 },
214 },
215);
diff --git a/subprojects/frontend/src/xtext/xtextMessages.ts b/subprojects/frontend/src/xtext/xtextMessages.ts
index c4d0c676..ec7a2a31 100644
--- a/subprojects/frontend/src/xtext/xtextMessages.ts
+++ b/subprojects/frontend/src/xtext/xtextMessages.ts
@@ -40,3 +40,11 @@ export const XtextWebPushMessage = z.object({
40}); 40});
41 41
42export type XtextWebPushMessage = z.infer<typeof XtextWebPushMessage>; 42export type XtextWebPushMessage = z.infer<typeof XtextWebPushMessage>;
43
44export const XtextResponse = z.union([
45 XtextWebOkResponse,
46 XtextWebErrorResponse,
47 XtextWebPushMessage,
48]);
49
50export type XtextResponse = z.infer<typeof XtextResponse>;
diff --git a/yarn.lock b/yarn.lock
index 31c31f35..1bb04c59 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -44,37 +44,37 @@ __metadata:
44 languageName: node 44 languageName: node
45 linkType: hard 45 linkType: hard
46 46
47"@babel/core@npm:^7.11.1, @babel/core@npm:^7.18.10": 47"@babel/core@npm:^7.11.1, @babel/core@npm:^7.12.10, @babel/core@npm:^7.18.10":
48 version: 7.18.10 48 version: 7.18.13
49 resolution: "@babel/core@npm:7.18.10" 49 resolution: "@babel/core@npm:7.18.13"
50 dependencies: 50 dependencies:
51 "@ampproject/remapping": ^2.1.0 51 "@ampproject/remapping": ^2.1.0
52 "@babel/code-frame": ^7.18.6 52 "@babel/code-frame": ^7.18.6
53 "@babel/generator": ^7.18.10 53 "@babel/generator": ^7.18.13
54 "@babel/helper-compilation-targets": ^7.18.9 54 "@babel/helper-compilation-targets": ^7.18.9
55 "@babel/helper-module-transforms": ^7.18.9 55 "@babel/helper-module-transforms": ^7.18.9
56 "@babel/helpers": ^7.18.9 56 "@babel/helpers": ^7.18.9
57 "@babel/parser": ^7.18.10 57 "@babel/parser": ^7.18.13
58 "@babel/template": ^7.18.10 58 "@babel/template": ^7.18.10
59 "@babel/traverse": ^7.18.10 59 "@babel/traverse": ^7.18.13
60 "@babel/types": ^7.18.10 60 "@babel/types": ^7.18.13
61 convert-source-map: ^1.7.0 61 convert-source-map: ^1.7.0
62 debug: ^4.1.0 62 debug: ^4.1.0
63 gensync: ^1.0.0-beta.2 63 gensync: ^1.0.0-beta.2
64 json5: ^2.2.1 64 json5: ^2.2.1
65 semver: ^6.3.0 65 semver: ^6.3.0
66 checksum: 3a3fcd878430a9e1cb165f755c89fff45acc4efe4dd3a2ba356e89af331cb1947886b9782d56902a49af19ba3c24f08cf638a632699b9c5a4d8305c57c6a150d 66 checksum: c7ee5b2c10bc5b0325e31fb5da4cb4bc03f9d5f5c00ec3481a018917bcc6b7b040de0690c606a424f57e5fc26d218d64e7718d0e5d7d8614d39c8cd898fab9b3
67 languageName: node 67 languageName: node
68 linkType: hard 68 linkType: hard
69 69
70"@babel/generator@npm:^7.18.10": 70"@babel/generator@npm:^7.18.13":
71 version: 7.18.12 71 version: 7.18.13
72 resolution: "@babel/generator@npm:7.18.12" 72 resolution: "@babel/generator@npm:7.18.13"
73 dependencies: 73 dependencies:
74 "@babel/types": ^7.18.10 74 "@babel/types": ^7.18.13
75 "@jridgewell/gen-mapping": ^0.3.2 75 "@jridgewell/gen-mapping": ^0.3.2
76 jsesc: ^2.5.1 76 jsesc: ^2.5.1
77 checksum: 07dd71d255144bb703a80ab0156c35d64172ce81ddfb70ff24e2be687b052080233840c9a28d92fa2c33f7ecb8a8b30aef03b807518afc53b74c7908bf8859b1 77 checksum: 27f5e7eb774e4d76ee75dc96e3e1bd26cc0ee7cea13a8f7342b716319c0a4d4e26fc49aa8f19316f7c99383da55eeb2a866c6e034e9deacad58a9de9ed6004fb
78 languageName: node 78 languageName: node
79 linkType: hard 79 linkType: hard
80 80
@@ -350,12 +350,12 @@ __metadata:
350 languageName: node 350 languageName: node
351 linkType: hard 351 linkType: hard
352 352
353"@babel/parser@npm:^7.18.10, @babel/parser@npm:^7.18.11": 353"@babel/parser@npm:^7.18.10, @babel/parser@npm:^7.18.13":
354 version: 7.18.11 354 version: 7.18.13
355 resolution: "@babel/parser@npm:7.18.11" 355 resolution: "@babel/parser@npm:7.18.13"
356 bin: 356 bin:
357 parser: ./bin/babel-parser.js 357 parser: ./bin/babel-parser.js
358 checksum: 5ecc75b83e62ec53a947b1635a6ca75d6210d4a4f962f9f16f4239a6783f98e57f9662b598fa2fb1b8e12c0ad5c2bd86846ed0b97b85eb73dd7498b3a6d71a4b 358 checksum: 8b41c35607668495d67d9a7c5f61768aaab26acf887efdadc2781aed54046981480ef40aeda0b84d61aed02cf0c4ff4b028d5f83ab85e17e2ddff318f9243b8b
359 languageName: node 359 languageName: node
360 linkType: hard 360 linkType: hard
361 361
@@ -1286,7 +1286,7 @@ __metadata:
1286 languageName: node 1286 languageName: node
1287 linkType: hard 1287 linkType: hard
1288 1288
1289"@babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7": 1289"@babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7":
1290 version: 7.18.9 1290 version: 7.18.9
1291 resolution: "@babel/runtime@npm:7.18.9" 1291 resolution: "@babel/runtime@npm:7.18.9"
1292 dependencies: 1292 dependencies:
@@ -1306,32 +1306,32 @@ __metadata:
1306 languageName: node 1306 languageName: node
1307 linkType: hard 1307 linkType: hard
1308 1308
1309"@babel/traverse@npm:^7.18.10, @babel/traverse@npm:^7.18.11, @babel/traverse@npm:^7.18.9": 1309"@babel/traverse@npm:^7.18.11, @babel/traverse@npm:^7.18.13, @babel/traverse@npm:^7.18.9":
1310 version: 7.18.11 1310 version: 7.18.13
1311 resolution: "@babel/traverse@npm:7.18.11" 1311 resolution: "@babel/traverse@npm:7.18.13"
1312 dependencies: 1312 dependencies:
1313 "@babel/code-frame": ^7.18.6 1313 "@babel/code-frame": ^7.18.6
1314 "@babel/generator": ^7.18.10 1314 "@babel/generator": ^7.18.13
1315 "@babel/helper-environment-visitor": ^7.18.9 1315 "@babel/helper-environment-visitor": ^7.18.9
1316 "@babel/helper-function-name": ^7.18.9 1316 "@babel/helper-function-name": ^7.18.9
1317 "@babel/helper-hoist-variables": ^7.18.6 1317 "@babel/helper-hoist-variables": ^7.18.6
1318 "@babel/helper-split-export-declaration": ^7.18.6 1318 "@babel/helper-split-export-declaration": ^7.18.6
1319 "@babel/parser": ^7.18.11 1319 "@babel/parser": ^7.18.13
1320 "@babel/types": ^7.18.10 1320 "@babel/types": ^7.18.13
1321 debug: ^4.1.0 1321 debug: ^4.1.0
1322 globals: ^11.1.0 1322 globals: ^11.1.0
1323 checksum: 727409464d5cf27f33555010098ce9bb435f0648cc76e674f4fb7513522356655ba62be99c8df330982b391ccf5f0c0c23c7bd7453d4936d47e2181693fed14c 1323 checksum: 1a2ef738fac4968feba6385787a3f8f7357d08e7739ecc5b37d8ff5668935253a03290f700f02a85ccfd369d5898625f0722d7733bff2ef91504f6cd8b836f19
1324 languageName: node 1324 languageName: node
1325 linkType: hard 1325 linkType: hard
1326 1326
1327"@babel/types@npm:^7.18.10, @babel/types@npm:^7.18.6, @babel/types@npm:^7.18.9, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": 1327"@babel/types@npm:^7.18.10, @babel/types@npm:^7.18.13, @babel/types@npm:^7.18.6, @babel/types@npm:^7.18.9, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3":
1328 version: 7.18.10 1328 version: 7.18.13
1329 resolution: "@babel/types@npm:7.18.10" 1329 resolution: "@babel/types@npm:7.18.13"
1330 dependencies: 1330 dependencies:
1331 "@babel/helper-string-parser": ^7.18.10 1331 "@babel/helper-string-parser": ^7.18.10
1332 "@babel/helper-validator-identifier": ^7.18.6 1332 "@babel/helper-validator-identifier": ^7.18.6
1333 to-fast-properties: ^2.0.0 1333 to-fast-properties: ^2.0.0
1334 checksum: 11632c9b106e54021937a6498138014ebc9ad6c327a07b2af3ba8700773945aba4055fd136431cbe3a500d0f363cbf9c68eb4d6d38229897c5de9d06e14c85e8 1334 checksum: abc3ad1f3b6864df0ea0e778bcdf7d2c5ee2293811192962d50e8a8c05c1aeec90a48275f53b2a45aad882ed8bef9477ae1f8e70ac1d44d039e14930d1388dcc
1335 languageName: node 1335 languageName: node
1336 linkType: hard 1336 linkType: hard
1337 1337
@@ -1407,14 +1407,14 @@ __metadata:
1407 languageName: node 1407 languageName: node
1408 linkType: hard 1408 linkType: hard
1409 1409
1410"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.2.1": 1410"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.2.2":
1411 version: 6.2.1 1411 version: 6.2.2
1412 resolution: "@codemirror/view@npm:6.2.1" 1412 resolution: "@codemirror/view@npm:6.2.2"
1413 dependencies: 1413 dependencies:
1414 "@codemirror/state": ^6.0.0 1414 "@codemirror/state": ^6.0.0
1415 style-mod: ^4.0.0 1415 style-mod: ^4.0.0
1416 w3c-keyname: ^2.2.4 1416 w3c-keyname: ^2.2.4
1417 checksum: efa67b8b1cc921179e4e1f51bd0f5191b920e79be87a952bb2c90b933a79307adc15c4adcf8001d7e3b79fefafb2c822ddbce5bcafc6f82f359e7b7690b61673 1417 checksum: 6983c51362367d3885961fa233d302e75dfb103cd83ec78e6a044c2420e61466b5e94cfb73a9e840b04765577e8bbb269eb1ad45fa21abd28efda4ae780791db
1418 languageName: node 1418 languageName: node
1419 linkType: hard 1419 linkType: hard
1420 1420
@@ -1440,7 +1440,7 @@ __metadata:
1440 languageName: node 1440 languageName: node
1441 linkType: hard 1441 linkType: hard
1442 1442
1443"@emotion/cache@npm:^11.10.0, @emotion/cache@npm:^11.10.1": 1443"@emotion/cache@npm:^11.10.0, @emotion/cache@npm:^11.10.3":
1444 version: 11.10.3 1444 version: 11.10.3
1445 resolution: "@emotion/cache@npm:11.10.3" 1445 resolution: "@emotion/cache@npm:11.10.3"
1446 dependencies: 1446 dependencies:
@@ -1476,14 +1476,15 @@ __metadata:
1476 languageName: node 1476 languageName: node
1477 linkType: hard 1477 linkType: hard
1478 1478
1479"@emotion/react@npm:^11.10.0": 1479"@emotion/react@npm:^11.10.4":
1480 version: 11.10.0 1480 version: 11.10.4
1481 resolution: "@emotion/react@npm:11.10.0" 1481 resolution: "@emotion/react@npm:11.10.4"
1482 dependencies: 1482 dependencies:
1483 "@babel/runtime": ^7.18.3 1483 "@babel/runtime": ^7.18.3
1484 "@emotion/babel-plugin": ^11.10.0 1484 "@emotion/babel-plugin": ^11.10.0
1485 "@emotion/cache": ^11.10.0 1485 "@emotion/cache": ^11.10.0
1486 "@emotion/serialize": ^1.1.0 1486 "@emotion/serialize": ^1.1.0
1487 "@emotion/use-insertion-effect-with-fallbacks": ^1.0.0
1487 "@emotion/utils": ^1.2.0 1488 "@emotion/utils": ^1.2.0
1488 "@emotion/weak-memoize": ^0.3.0 1489 "@emotion/weak-memoize": ^0.3.0
1489 hoist-non-react-statics: ^3.3.1 1490 hoist-non-react-statics: ^3.3.1
@@ -1495,7 +1496,7 @@ __metadata:
1495 optional: true 1496 optional: true
1496 "@types/react": 1497 "@types/react":
1497 optional: true 1498 optional: true
1498 checksum: 6d692e43ff53fd3b87d4a000a9aec2ef080d66a0ebb7d0b9529c46d1e6bc1ac8a27c7dd74c27a8274ec1df1e3c960b78c035fca5d8a901a48eda445c6163b33b 1499 checksum: 7555f6a1840c71d841386be2ec98ebfd6399923bd6a61247c7b07283f9a056f57e83c4fdd9ea7a7fcc3d88e5e04bb03168b4f0557934bcd501c88af4db16e1e0
1499 languageName: node 1500 languageName: node
1500 linkType: hard 1501 linkType: hard
1501 1502
@@ -1519,14 +1520,15 @@ __metadata:
1519 languageName: node 1520 languageName: node
1520 linkType: hard 1521 linkType: hard
1521 1522
1522"@emotion/styled@npm:^11.10.0": 1523"@emotion/styled@npm:^11.10.4":
1523 version: 11.10.0 1524 version: 11.10.4
1524 resolution: "@emotion/styled@npm:11.10.0" 1525 resolution: "@emotion/styled@npm:11.10.4"
1525 dependencies: 1526 dependencies:
1526 "@babel/runtime": ^7.18.3 1527 "@babel/runtime": ^7.18.3
1527 "@emotion/babel-plugin": ^11.10.0 1528 "@emotion/babel-plugin": ^11.10.0
1528 "@emotion/is-prop-valid": ^1.2.0 1529 "@emotion/is-prop-valid": ^1.2.0
1529 "@emotion/serialize": ^1.1.0 1530 "@emotion/serialize": ^1.1.0
1531 "@emotion/use-insertion-effect-with-fallbacks": ^1.0.0
1530 "@emotion/utils": ^1.2.0 1532 "@emotion/utils": ^1.2.0
1531 peerDependencies: 1533 peerDependencies:
1532 "@babel/core": ^7.0.0 1534 "@babel/core": ^7.0.0
@@ -1537,7 +1539,7 @@ __metadata:
1537 optional: true 1539 optional: true
1538 "@types/react": 1540 "@types/react":
1539 optional: true 1541 optional: true
1540 checksum: f2a3e9798f807713d12771320cde9c2fa17ea6f008da605055496bd3522d81c120321240c8a1dae49c7272fea11361e1f47938ee069f678038b6836820c01243 1542 checksum: d56cbf48f30c5a36d618adf2c4d7d9440b5059373a96964fa2a6e832ce9b9ae8cee11b5292b444264b3acbfdd6a8f6c9050e197a35c8dea7e9b9cc78f55ac31c
1541 languageName: node 1543 languageName: node
1542 linkType: hard 1544 linkType: hard
1543 1545
@@ -1548,6 +1550,15 @@ __metadata:
1548 languageName: node 1550 languageName: node
1549 linkType: hard 1551 linkType: hard
1550 1552
1553"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.0":
1554 version: 1.0.0
1555 resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.0"
1556 peerDependencies:
1557 react: ">=16.8.0"
1558 checksum: 4f06a3b48258c832aa8022a262572061a31ff078d377e9164cccc99951309d70f4466e774fe704461b2f8715007a82ed625a54a5c7a127c89017d3ce3187d4f1
1559 languageName: node
1560 linkType: hard
1561
1551"@emotion/utils@npm:^1.2.0": 1562"@emotion/utils@npm:^1.2.0":
1552 version: 1.2.0 1563 version: 1.2.0
1553 resolution: "@emotion/utils@npm:1.2.0" 1564 resolution: "@emotion/utils@npm:1.2.0"
@@ -1701,10 +1712,10 @@ __metadata:
1701 languageName: node 1712 languageName: node
1702 linkType: hard 1713 linkType: hard
1703 1714
1704"@lezer/common@npm:^1.0.0": 1715"@lezer/common@npm:^1.0.0, @lezer/common@npm:^1.0.1":
1705 version: 1.0.0 1716 version: 1.0.1
1706 resolution: "@lezer/common@npm:1.0.0" 1717 resolution: "@lezer/common@npm:1.0.1"
1707 checksum: 0ba652b39f9ff073a6a8a3376a74279f2c2d2ccdd4d2bb57c7b607341dbdbf64baf9c23a196314f09349d175623bc73a6a0b6a0eeb2cc63f3a1190fd631f7c31 1718 checksum: 05bda2b0b90713a511502e1e0c67842996cb86415cd701c46eb49f8fa117552229a4bc7244f1e8e0025e3563294a52911eebd70d06a4bc987280fca5d148c34b
1708 languageName: node 1719 languageName: node
1709 linkType: hard 1720 linkType: hard
1710 1721
@@ -1738,21 +1749,21 @@ __metadata:
1738 languageName: node 1749 languageName: node
1739 linkType: hard 1750 linkType: hard
1740 1751
1741"@material-icons/svg@npm:^1.0.32": 1752"@material-icons/svg@npm:^1.0.33":
1742 version: 1.0.32 1753 version: 1.0.33
1743 resolution: "@material-icons/svg@npm:1.0.32" 1754 resolution: "@material-icons/svg@npm:1.0.33"
1744 checksum: ed3827a61834d92e70354b450212ff8c7a84ddb9ca148bf9bf096d265903da96f835edf1a7d5d83218951105592a42de70e6ba4c7f46013968e3b63a5a5b5185 1755 checksum: a5300f35b6dff085f38def8c3f2e7903784502333310d584d535cf45fd31c8b4573485dda2be6915658a0a252d3458e1c3d919f78fbe1a1e29c2ec79ece63144
1745 languageName: node 1756 languageName: node
1746 linkType: hard 1757 linkType: hard
1747 1758
1748"@mui/base@npm:5.0.0-alpha.94": 1759"@mui/base@npm:5.0.0-alpha.95":
1749 version: 5.0.0-alpha.94 1760 version: 5.0.0-alpha.95
1750 resolution: "@mui/base@npm:5.0.0-alpha.94" 1761 resolution: "@mui/base@npm:5.0.0-alpha.95"
1751 dependencies: 1762 dependencies:
1752 "@babel/runtime": ^7.17.2 1763 "@babel/runtime": ^7.18.9
1753 "@emotion/is-prop-valid": ^1.2.0 1764 "@emotion/is-prop-valid": ^1.2.0
1754 "@mui/types": ^7.1.5 1765 "@mui/types": ^7.2.0
1755 "@mui/utils": ^5.9.3 1766 "@mui/utils": ^5.10.3
1756 "@popperjs/core": ^2.11.6 1767 "@popperjs/core": ^2.11.6
1757 clsx: ^1.2.1 1768 clsx: ^1.2.1
1758 prop-types: ^15.8.1 1769 prop-types: ^15.8.1
@@ -1764,22 +1775,22 @@ __metadata:
1764 peerDependenciesMeta: 1775 peerDependenciesMeta:
1765 "@types/react": 1776 "@types/react":
1766 optional: true 1777 optional: true
1767 checksum: 877c7c1b53a555265332e1e677945de0415db187a7c5a7f088eaacb4f85aa20086a668915ad1885e77fa7ef4df5d35250e55f4aef2b4c5aa82f014406bbdaef3 1778 checksum: b05f18ed2f1fbb6e1ab1d58e54e38b09aa43ad10a0f5e8cf7c86da745a1feca298429c34d2437298b3125c3096cf8b32ee18ad4dbc616ac88d2bd6be57b5c21c
1768 languageName: node 1779 languageName: node
1769 linkType: hard 1780 linkType: hard
1770 1781
1771"@mui/core-downloads-tracker@npm:^5.10.2": 1782"@mui/core-downloads-tracker@npm:^5.10.3":
1772 version: 5.10.2 1783 version: 5.10.3
1773 resolution: "@mui/core-downloads-tracker@npm:5.10.2" 1784 resolution: "@mui/core-downloads-tracker@npm:5.10.3"
1774 checksum: 237d25f2cc8f63e4ee5f1cbe7944cb9818784535ed861ab3b8564ec4c7cbfdeb3c044596a2447c49feff987f268da30538fcb2ad194e3f7a0095d2e6edcdfdbd 1785 checksum: 07c7d3ddda9dfcd402633e7ab7b367505cbc097ac7ae59bb9232caa11896902e76241f5bf905b62b0c96429cb94009e1006492c172926390f1936fb6e5a1326d
1775 languageName: node 1786 languageName: node
1776 linkType: hard 1787 linkType: hard
1777 1788
1778"@mui/icons-material@npm:5.10.2": 1789"@mui/icons-material@npm:5.10.3":
1779 version: 5.10.2 1790 version: 5.10.3
1780 resolution: "@mui/icons-material@npm:5.10.2" 1791 resolution: "@mui/icons-material@npm:5.10.3"
1781 dependencies: 1792 dependencies:
1782 "@babel/runtime": ^7.17.2 1793 "@babel/runtime": ^7.18.9
1783 peerDependencies: 1794 peerDependencies:
1784 "@mui/material": ^5.0.0 1795 "@mui/material": ^5.0.0
1785 "@types/react": ^17.0.0 || ^18.0.0 1796 "@types/react": ^17.0.0 || ^18.0.0
@@ -1787,20 +1798,20 @@ __metadata:
1787 peerDependenciesMeta: 1798 peerDependenciesMeta:
1788 "@types/react": 1799 "@types/react":
1789 optional: true 1800 optional: true
1790 checksum: 9e694babaa69c52139b7cdd12f449a3464707ae12c3cdfd8af43bcbb1f9040dce08c6cde95ea7812e7b946f49fddbf4df05bc6cf44a30eaeb1c8701786fd309d 1801 checksum: 9c32f3e9fc2be61b6518418818ead346469fb4650852307291fe23e16909fc1c2f4bc3b09a524fb0e90920aa1a26a6a41e91815e0da1d15d7e26ccad4f6915fa
1791 languageName: node 1802 languageName: node
1792 linkType: hard 1803 linkType: hard
1793 1804
1794"@mui/material@npm:5.10.2": 1805"@mui/material@npm:5.10.3":
1795 version: 5.10.2 1806 version: 5.10.3
1796 resolution: "@mui/material@npm:5.10.2" 1807 resolution: "@mui/material@npm:5.10.3"
1797 dependencies: 1808 dependencies:
1798 "@babel/runtime": ^7.17.2 1809 "@babel/runtime": ^7.18.9
1799 "@mui/base": 5.0.0-alpha.94 1810 "@mui/base": 5.0.0-alpha.95
1800 "@mui/core-downloads-tracker": ^5.10.2 1811 "@mui/core-downloads-tracker": ^5.10.3
1801 "@mui/system": ^5.10.2 1812 "@mui/system": ^5.10.3
1802 "@mui/types": ^7.1.5 1813 "@mui/types": ^7.2.0
1803 "@mui/utils": ^5.9.3 1814 "@mui/utils": ^5.10.3
1804 "@types/react-transition-group": ^4.4.5 1815 "@types/react-transition-group": ^4.4.5
1805 clsx: ^1.2.1 1816 clsx: ^1.2.1
1806 csstype: ^3.1.0 1817 csstype: ^3.1.0
@@ -1820,16 +1831,16 @@ __metadata:
1820 optional: true 1831 optional: true
1821 "@types/react": 1832 "@types/react":
1822 optional: true 1833 optional: true
1823 checksum: 2d44933c28e25b112a18cdcee4ea4c71d6eeba6b91ee33e3b66ec636c05daf3a9b03715d0a86c34a5670a3e25e39d13b10fc57aac524d52631134db0daca88de 1834 checksum: af7502c5340bfd4a777daa986940a86664e3c3c724fe9e2821f95172cbc55e27e85bbad011f1c4e0554df93aed1d881d81d8fad16f8b8e011e7b2d2b31f34c9c
1824 languageName: node 1835 languageName: node
1825 linkType: hard 1836 linkType: hard
1826 1837
1827"@mui/private-theming@npm:^5.9.3": 1838"@mui/private-theming@npm:^5.10.3":
1828 version: 5.9.3 1839 version: 5.10.3
1829 resolution: "@mui/private-theming@npm:5.9.3" 1840 resolution: "@mui/private-theming@npm:5.10.3"
1830 dependencies: 1841 dependencies:
1831 "@babel/runtime": ^7.17.2 1842 "@babel/runtime": ^7.18.9
1832 "@mui/utils": ^5.9.3 1843 "@mui/utils": ^5.10.3
1833 prop-types: ^15.8.1 1844 prop-types: ^15.8.1
1834 peerDependencies: 1845 peerDependencies:
1835 "@types/react": ^17.0.0 || ^18.0.0 1846 "@types/react": ^17.0.0 || ^18.0.0
@@ -1837,16 +1848,16 @@ __metadata:
1837 peerDependenciesMeta: 1848 peerDependenciesMeta:
1838 "@types/react": 1849 "@types/react":
1839 optional: true 1850 optional: true
1840 checksum: baa144969e7839f4c74eba65f6518890942453c57992d9446c8ba8c1a5b1925400c392041cb5643bd3ca7f77894f94b72966b6ffdef659962b6105e5670c6cc4 1851 checksum: a089c0286d2a15bf8f01cf72d43e6be4fb66099028bc6be9712c9c7e39f4669f6875c722f98bcc10f1206ccc7d262e7a9521d7c6536b18d804dbe6d8fa5f7333
1841 languageName: node 1852 languageName: node
1842 linkType: hard 1853 linkType: hard
1843 1854
1844"@mui/styled-engine@npm:^5.10.2": 1855"@mui/styled-engine@npm:^5.10.3":
1845 version: 5.10.2 1856 version: 5.10.3
1846 resolution: "@mui/styled-engine@npm:5.10.2" 1857 resolution: "@mui/styled-engine@npm:5.10.3"
1847 dependencies: 1858 dependencies:
1848 "@babel/runtime": ^7.17.2 1859 "@babel/runtime": ^7.18.9
1849 "@emotion/cache": ^11.10.1 1860 "@emotion/cache": ^11.10.3
1850 csstype: ^3.1.0 1861 csstype: ^3.1.0
1851 prop-types: ^15.8.1 1862 prop-types: ^15.8.1
1852 peerDependencies: 1863 peerDependencies:
@@ -1858,19 +1869,19 @@ __metadata:
1858 optional: true 1869 optional: true
1859 "@emotion/styled": 1870 "@emotion/styled":
1860 optional: true 1871 optional: true
1861 checksum: 337455da69990ef83b10f7e0ee14720b991ae2dca9c616664931edbc17f209f3f9fc0abcad97c01d70cd72afbb0760f44c9aefe27c458fb6104d4a3f0078b812 1872 checksum: cc465991fb5f32fd56b7123183631c3c45e8c8f7a69d42a5050c461132ad5fb01f0e389488b9515b274506d92abcc8119da6289ea8652cf44f100a4d442ac8a5
1862 languageName: node 1873 languageName: node
1863 linkType: hard 1874 linkType: hard
1864 1875
1865"@mui/system@npm:^5.10.2": 1876"@mui/system@npm:^5.10.3":
1866 version: 5.10.2 1877 version: 5.10.3
1867 resolution: "@mui/system@npm:5.10.2" 1878 resolution: "@mui/system@npm:5.10.3"
1868 dependencies: 1879 dependencies:
1869 "@babel/runtime": ^7.17.2 1880 "@babel/runtime": ^7.18.9
1870 "@mui/private-theming": ^5.9.3 1881 "@mui/private-theming": ^5.10.3
1871 "@mui/styled-engine": ^5.10.2 1882 "@mui/styled-engine": ^5.10.3
1872 "@mui/types": ^7.1.5 1883 "@mui/types": ^7.2.0
1873 "@mui/utils": ^5.9.3 1884 "@mui/utils": ^5.10.3
1874 clsx: ^1.2.1 1885 clsx: ^1.2.1
1875 csstype: ^3.1.0 1886 csstype: ^3.1.0
1876 prop-types: ^15.8.1 1887 prop-types: ^15.8.1
@@ -1886,34 +1897,34 @@ __metadata:
1886 optional: true 1897 optional: true
1887 "@types/react": 1898 "@types/react":
1888 optional: true 1899 optional: true
1889 checksum: 07bdac55e8a29d5397579025a47258b885bd54b60cd9f7bc7214526960ba076ab975ba0a217b2420fd48960aaaec4bceea37ae404f7452cc2048c677fc91790a 1900 checksum: fee332cfb091c00d3b8fbdc020da1c5bc8a257fb38dafa72b7966a2b38f1d65aa27dcf113b9b016f9bfa82e5e974819e0d7a20f8c5c6ff18810eb5e2885541d0
1890 languageName: node 1901 languageName: node
1891 linkType: hard 1902 linkType: hard
1892 1903
1893"@mui/types@npm:^7.1.5": 1904"@mui/types@npm:^7.2.0":
1894 version: 7.1.5 1905 version: 7.2.0
1895 resolution: "@mui/types@npm:7.1.5" 1906 resolution: "@mui/types@npm:7.2.0"
1896 peerDependencies: 1907 peerDependencies:
1897 "@types/react": "*" 1908 "@types/react": "*"
1898 peerDependenciesMeta: 1909 peerDependenciesMeta:
1899 "@types/react": 1910 "@types/react":
1900 optional: true 1911 optional: true
1901 checksum: ce866083bfaef7c2231077b7d5db3db20e2a9b17758e4337aeac12bbae2063ea15b95f8384661dd4f260c51e6dfb098a0f768bf26daaad91e7e1233f794191f0 1912 checksum: a863140f2039c33fab7651e024f6ba277b282930b5b43e8a68c2339508a74fcedf15af2f0f46bafe276fb65ae0b44cd8a880e1f9a870d957f61457b59709ecba
1902 languageName: node 1913 languageName: node
1903 linkType: hard 1914 linkType: hard
1904 1915
1905"@mui/utils@npm:^5.9.3": 1916"@mui/utils@npm:^5.10.3":
1906 version: 5.9.3 1917 version: 5.10.3
1907 resolution: "@mui/utils@npm:5.9.3" 1918 resolution: "@mui/utils@npm:5.10.3"
1908 dependencies: 1919 dependencies:
1909 "@babel/runtime": ^7.17.2 1920 "@babel/runtime": ^7.18.9
1910 "@types/prop-types": ^15.7.5 1921 "@types/prop-types": ^15.7.5
1911 "@types/react-is": ^16.7.1 || ^17.0.0 1922 "@types/react-is": ^16.7.1 || ^17.0.0
1912 prop-types: ^15.8.1 1923 prop-types: ^15.8.1
1913 react-is: ^18.2.0 1924 react-is: ^18.2.0
1914 peerDependencies: 1925 peerDependencies:
1915 react: ^17.0.0 || ^18.0.0 1926 react: ^17.0.0 || ^18.0.0
1916 checksum: 745a9c5634a1b1104a64eb77341ed48dabf3afcc2bab6d67ce875d0fdd7c3ee5d115f0613a7782a8406b34e0e29e15c6293cac540711161ff9aba720b2478a60 1927 checksum: 591f45a31751092621af120f58a7116e87aa0ca616fb38ba5dc31f2a86534b90c10cc94ede5a7758d04a12c3fa0d4b3d878ebf4ca590b1531c32d4ee9227080a
1917 languageName: node 1928 languageName: node
1918 linkType: hard 1929 linkType: hard
1919 1930
@@ -1995,28 +2006,30 @@ __metadata:
1995 "@codemirror/lint": ^6.0.0 2006 "@codemirror/lint": ^6.0.0
1996 "@codemirror/search": ^6.2.0 2007 "@codemirror/search": ^6.2.0
1997 "@codemirror/state": ^6.1.1 2008 "@codemirror/state": ^6.1.1
1998 "@codemirror/view": ^6.2.1 2009 "@codemirror/view": ^6.2.2
1999 "@emotion/react": ^11.10.0 2010 "@emotion/react": ^11.10.4
2000 "@emotion/styled": ^11.10.0 2011 "@emotion/styled": ^11.10.4
2001 "@fontsource/jetbrains-mono": ^4.5.10 2012 "@fontsource/jetbrains-mono": ^4.5.10
2002 "@fontsource/roboto": ^4.5.8 2013 "@fontsource/roboto": ^4.5.8
2003 "@lezer/common": ^1.0.0 2014 "@lezer/common": ^1.0.1
2004 "@lezer/generator": ^1.1.1 2015 "@lezer/generator": ^1.1.1
2005 "@lezer/highlight": ^1.0.0 2016 "@lezer/highlight": ^1.0.0
2006 "@lezer/lr": ^1.2.3 2017 "@lezer/lr": ^1.2.3
2007 "@material-icons/svg": ^1.0.32 2018 "@material-icons/svg": ^1.0.33
2008 "@mui/icons-material": 5.10.2 2019 "@mui/icons-material": 5.10.3
2009 "@mui/material": 5.10.2 2020 "@mui/material": 5.10.3
2010 "@types/eslint": ^8.4.6 2021 "@types/eslint": ^8.4.6
2011 "@types/html-minifier-terser": ^7.0.0 2022 "@types/html-minifier-terser": ^7.0.0
2012 "@types/lodash-es": ^4.17.6 2023 "@types/lodash-es": ^4.17.6
2013 "@types/node": ^18.7.13 2024 "@types/ms": ^0.7.31
2025 "@types/node": ^18.7.14
2014 "@types/prettier": ^2.7.0 2026 "@types/prettier": ^2.7.0
2015 "@types/react": ^18.0.17 2027 "@types/react": ^18.0.18
2016 "@types/react-dom": ^18.0.6 2028 "@types/react-dom": ^18.0.6
2017 "@typescript-eslint/eslint-plugin": ^5.35.1 2029 "@typescript-eslint/eslint-plugin": ^5.36.1
2018 "@typescript-eslint/parser": ^5.35.1 2030 "@typescript-eslint/parser": ^5.36.1
2019 "@vitejs/plugin-react": ^2.0.1 2031 "@vitejs/plugin-react": ^2.0.1
2032 "@xstate/cli": ^0.3.2
2020 ansi-styles: ^6.1.0 2033 ansi-styles: ^6.1.0
2021 cross-env: ^7.0.3 2034 cross-env: ^7.0.3
2022 escape-string-regexp: ^5.0.0 2035 escape-string-regexp: ^5.0.0
@@ -2029,7 +2042,7 @@ __metadata:
2029 eslint-plugin-jsx-a11y: ^6.6.1 2042 eslint-plugin-jsx-a11y: ^6.6.1
2030 eslint-plugin-mobx: ^0.0.9 2043 eslint-plugin-mobx: ^0.0.9
2031 eslint-plugin-prettier: ^4.2.1 2044 eslint-plugin-prettier: ^4.2.1
2032 eslint-plugin-react: ^7.31.1 2045 eslint-plugin-react: ^7.31.6
2033 eslint-plugin-react-hooks: ^4.6.0 2046 eslint-plugin-react-hooks: ^4.6.0
2034 html-minifier-terser: ^7.0.0 2047 html-minifier-terser: ^7.0.0
2035 lodash-es: ^4.17.21 2048 lodash-es: ^4.17.21
@@ -2045,8 +2058,9 @@ __metadata:
2045 typescript: ~4.8.2 2058 typescript: ~4.8.2
2046 vite: ^3.0.9 2059 vite: ^3.0.9
2047 vite-plugin-inject-preload: ^1.1.0 2060 vite-plugin-inject-preload: ^1.1.0
2048 vite-plugin-pwa: ^0.12.3 2061 vite-plugin-pwa: ^0.12.6
2049 workbox-window: ^6.5.4 2062 workbox-window: ^6.5.4
2063 xstate: ^4.33.5
2050 zod: ^3.18.0 2064 zod: ^3.18.0
2051 languageName: unknown 2065 languageName: unknown
2052 linkType: soft 2066 linkType: soft
@@ -2198,10 +2212,17 @@ __metadata:
2198 languageName: node 2212 languageName: node
2199 linkType: hard 2213 linkType: hard
2200 2214
2201"@types/node@npm:*, @types/node@npm:^18.7.13": 2215"@types/ms@npm:^0.7.31":
2202 version: 18.7.13 2216 version: 0.7.31
2203 resolution: "@types/node@npm:18.7.13" 2217 resolution: "@types/ms@npm:0.7.31"
2204 checksum: 45431e7e89ecaf85c7d2c180d801c132a7c59e2f8ad578726b6d71cc74e3267c18f9ccdcad738bc0479790c078f0c79efb0e58da2c6be535c15995dbb19050c9 2218 checksum: daadd354aedde024cce6f5aa873fefe7b71b22cd0e28632a69e8b677aeb48ae8caa1c60e5919bb781df040d116b01cb4316335167a3fc0ef6a63fa3614c0f6da
2219 languageName: node
2220 linkType: hard
2221
2222"@types/node@npm:*, @types/node@npm:^18.7.14":
2223 version: 18.7.14
2224 resolution: "@types/node@npm:18.7.14"
2225 checksum: 99cf28ff854100158de875cca23c7acc3cc01dfee526a52b90b7f36767c821bcbaf2be0a98a70f06f3b78f3c60639168ff949d725b61e2e124f9f71f1fb8043d
2205 languageName: node 2226 languageName: node
2206 linkType: hard 2227 linkType: hard
2207 2228
@@ -2253,14 +2274,14 @@ __metadata:
2253 languageName: node 2274 languageName: node
2254 linkType: hard 2275 linkType: hard
2255 2276
2256"@types/react@npm:*, @types/react@npm:^18.0.17": 2277"@types/react@npm:*, @types/react@npm:^18.0.18":
2257 version: 18.0.17 2278 version: 18.0.18
2258 resolution: "@types/react@npm:18.0.17" 2279 resolution: "@types/react@npm:18.0.18"
2259 dependencies: 2280 dependencies:
2260 "@types/prop-types": "*" 2281 "@types/prop-types": "*"
2261 "@types/scheduler": "*" 2282 "@types/scheduler": "*"
2262 csstype: ^3.0.2 2283 csstype: ^3.0.2
2263 checksum: 18cae64f5bfd6bb58fbd8ee2ba52ec82de844f114254e26de7b513e4b86621f643f9b71d7066958cd571b0d78cb86cbceda449c5289f9349ca573df29ab69252 2284 checksum: 6d72d35ab3eecf382a5e0f225923f5a2c753045fce02e4e29713f36c99a24f0f770666a49dde96167f37c86271f93339d1b7e2b8969d011b137a9ebd24ee6806
2264 languageName: node 2285 languageName: node
2265 linkType: hard 2286 linkType: hard
2266 2287
@@ -2287,13 +2308,13 @@ __metadata:
2287 languageName: node 2308 languageName: node
2288 linkType: hard 2309 linkType: hard
2289 2310
2290"@typescript-eslint/eslint-plugin@npm:^5.35.1": 2311"@typescript-eslint/eslint-plugin@npm:^5.36.1":
2291 version: 5.35.1 2312 version: 5.36.1
2292 resolution: "@typescript-eslint/eslint-plugin@npm:5.35.1" 2313 resolution: "@typescript-eslint/eslint-plugin@npm:5.36.1"
2293 dependencies: 2314 dependencies:
2294 "@typescript-eslint/scope-manager": 5.35.1 2315 "@typescript-eslint/scope-manager": 5.36.1
2295 "@typescript-eslint/type-utils": 5.35.1 2316 "@typescript-eslint/type-utils": 5.36.1
2296 "@typescript-eslint/utils": 5.35.1 2317 "@typescript-eslint/utils": 5.36.1
2297 debug: ^4.3.4 2318 debug: ^4.3.4
2298 functional-red-black-tree: ^1.0.1 2319 functional-red-black-tree: ^1.0.1
2299 ignore: ^5.2.0 2320 ignore: ^5.2.0
@@ -2306,42 +2327,43 @@ __metadata:
2306 peerDependenciesMeta: 2327 peerDependenciesMeta:
2307 typescript: 2328 typescript:
2308 optional: true 2329 optional: true
2309 checksum: 073f4dffd863881f1c87e1c217ac13bda44aaa2db12ef260032b5e8eb6ffd6b9cf6f62c85132dbf84152f353c435c66dd4f75c3bcb86eb23e926737aa4fb66fa 2330 checksum: a4c555688d840c3ff0d3d71ceca583291e206cc523eade45c56fb8e1c8af84ae50ef8d344cdf8e3f9c38f430bc03c95eb8d49870094e0e5b57e0fa3e61c0ec91
2310 languageName: node 2331 languageName: node
2311 linkType: hard 2332 linkType: hard
2312 2333
2313"@typescript-eslint/parser@npm:^5.35.1": 2334"@typescript-eslint/parser@npm:^5.36.1":
2314 version: 5.35.1 2335 version: 5.36.1
2315 resolution: "@typescript-eslint/parser@npm:5.35.1" 2336 resolution: "@typescript-eslint/parser@npm:5.36.1"
2316 dependencies: 2337 dependencies:
2317 "@typescript-eslint/scope-manager": 5.35.1 2338 "@typescript-eslint/scope-manager": 5.36.1
2318 "@typescript-eslint/types": 5.35.1 2339 "@typescript-eslint/types": 5.36.1
2319 "@typescript-eslint/typescript-estree": 5.35.1 2340 "@typescript-eslint/typescript-estree": 5.36.1
2320 debug: ^4.3.4 2341 debug: ^4.3.4
2321 peerDependencies: 2342 peerDependencies:
2322 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 2343 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
2323 peerDependenciesMeta: 2344 peerDependenciesMeta:
2324 typescript: 2345 typescript:
2325 optional: true 2346 optional: true
2326 checksum: 57ea1a1da60b370f8d5c11c86155f7339359a90f2c59e34c89f626f1a79cb440248f07bd307a27ebbbcc997d2731cb9754cdbc37639770940521a938dd89870c 2347 checksum: 0f0f94e56ae1d55b6e7223ce5a2b0c93e5cc082ef2951a2b24ae4b22bb8ffbeb90d2d16682bfa8bc972ba2c7fb4703aedd79b7dbd09bcee397e1ab90d11506d9
2327 languageName: node 2348 languageName: node
2328 linkType: hard 2349 linkType: hard
2329 2350
2330"@typescript-eslint/scope-manager@npm:5.35.1": 2351"@typescript-eslint/scope-manager@npm:5.36.1":
2331 version: 5.35.1 2352 version: 5.36.1
2332 resolution: "@typescript-eslint/scope-manager@npm:5.35.1" 2353 resolution: "@typescript-eslint/scope-manager@npm:5.36.1"
2333 dependencies: 2354 dependencies:
2334 "@typescript-eslint/types": 5.35.1 2355 "@typescript-eslint/types": 5.36.1
2335 "@typescript-eslint/visitor-keys": 5.35.1 2356 "@typescript-eslint/visitor-keys": 5.36.1
2336 checksum: 5a969a081309bac5962f99ee6dfdfd9c68ea677bc79d9796592dce82a36217f67aa55c7bf421b2c97b46c5149d6a9401bb4c57829595e8c19f47cfa9e8c2dd86 2357 checksum: c46497226af75baed7458838ec0bfbddf19f8084115d78b915b46a8ceb4c05619ac61da127dfd3c8ee11bc916896d57bf8b9f936b0306ce69658160f910e3ad0
2337 languageName: node 2358 languageName: node
2338 linkType: hard 2359 linkType: hard
2339 2360
2340"@typescript-eslint/type-utils@npm:5.35.1": 2361"@typescript-eslint/type-utils@npm:5.36.1":
2341 version: 5.35.1 2362 version: 5.36.1
2342 resolution: "@typescript-eslint/type-utils@npm:5.35.1" 2363 resolution: "@typescript-eslint/type-utils@npm:5.36.1"
2343 dependencies: 2364 dependencies:
2344 "@typescript-eslint/utils": 5.35.1 2365 "@typescript-eslint/typescript-estree": 5.36.1
2366 "@typescript-eslint/utils": 5.36.1
2345 debug: ^4.3.4 2367 debug: ^4.3.4
2346 tsutils: ^3.21.0 2368 tsutils: ^3.21.0
2347 peerDependencies: 2369 peerDependencies:
@@ -2349,23 +2371,23 @@ __metadata:
2349 peerDependenciesMeta: 2371 peerDependenciesMeta:
2350 typescript: 2372 typescript:
2351 optional: true 2373 optional: true
2352 checksum: af317ba156f2767f76a7f97193873a00468370e157fdcc6ac19f664bc6c4c0a6836bd25028d17fdd54d339b6842fda68b82f1ce4142a222de6953625ea6c0a9c 2374 checksum: d2905289e253a83a9eacbad765cfba03440663086c8beb1b19345b46593c9053fb051ee13d3cc27ccd800fe95ffbf3be2b1273b0f0ac6a59452fc94e6460898b
2353 languageName: node 2375 languageName: node
2354 linkType: hard 2376 linkType: hard
2355 2377
2356"@typescript-eslint/types@npm:5.35.1": 2378"@typescript-eslint/types@npm:5.36.1":
2357 version: 5.35.1 2379 version: 5.36.1
2358 resolution: "@typescript-eslint/types@npm:5.35.1" 2380 resolution: "@typescript-eslint/types@npm:5.36.1"
2359 checksum: a4e1001867f43f3364b109fc5a07b91ae7a34b78ab191c6c5c4695dac9bb2b80b0a602651c0b807c1c7c1fc3656d2bbd47c637afa08a09e7b1c39eae3c489e00 2381 checksum: 10c8965c64e16bc6920dc0c62aae2b139062aca945d03df2ad6fe7c299d2faa684621d571f8d9807a67643d4e9fa5217c69d5f538f9936fc757f9df5ded57623
2360 languageName: node 2382 languageName: node
2361 linkType: hard 2383 linkType: hard
2362 2384
2363"@typescript-eslint/typescript-estree@npm:5.35.1": 2385"@typescript-eslint/typescript-estree@npm:5.36.1":
2364 version: 5.35.1 2386 version: 5.36.1
2365 resolution: "@typescript-eslint/typescript-estree@npm:5.35.1" 2387 resolution: "@typescript-eslint/typescript-estree@npm:5.36.1"
2366 dependencies: 2388 dependencies:
2367 "@typescript-eslint/types": 5.35.1 2389 "@typescript-eslint/types": 5.36.1
2368 "@typescript-eslint/visitor-keys": 5.35.1 2390 "@typescript-eslint/visitor-keys": 5.36.1
2369 debug: ^4.3.4 2391 debug: ^4.3.4
2370 globby: ^11.1.0 2392 globby: ^11.1.0
2371 is-glob: ^4.0.3 2393 is-glob: ^4.0.3
@@ -2374,33 +2396,33 @@ __metadata:
2374 peerDependenciesMeta: 2396 peerDependenciesMeta:
2375 typescript: 2397 typescript:
2376 optional: true 2398 optional: true
2377 checksum: a917ca4753a3f92c8d8555c96f5414383a9742761625476fa36a019401543aa74996159afa0f7fc7fae05fe0f904e3c6f4153a55412070c8a94e8171e81084c7 2399 checksum: acaf2938001673918dbbe690a353cf92e2cfabc79f74cd5946e303a8c24eb9c08ae2053dd261810ed0c9c471ebe879f386564c1b01dd2504dc84f4ce5f4dc696
2378 languageName: node 2400 languageName: node
2379 linkType: hard 2401 linkType: hard
2380 2402
2381"@typescript-eslint/utils@npm:5.35.1": 2403"@typescript-eslint/utils@npm:5.36.1":
2382 version: 5.35.1 2404 version: 5.36.1
2383 resolution: "@typescript-eslint/utils@npm:5.35.1" 2405 resolution: "@typescript-eslint/utils@npm:5.36.1"
2384 dependencies: 2406 dependencies:
2385 "@types/json-schema": ^7.0.9 2407 "@types/json-schema": ^7.0.9
2386 "@typescript-eslint/scope-manager": 5.35.1 2408 "@typescript-eslint/scope-manager": 5.36.1
2387 "@typescript-eslint/types": 5.35.1 2409 "@typescript-eslint/types": 5.36.1
2388 "@typescript-eslint/typescript-estree": 5.35.1 2410 "@typescript-eslint/typescript-estree": 5.36.1
2389 eslint-scope: ^5.1.1 2411 eslint-scope: ^5.1.1
2390 eslint-utils: ^3.0.0 2412 eslint-utils: ^3.0.0
2391 peerDependencies: 2413 peerDependencies:
2392 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 2414 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
2393 checksum: 2b04092583c3139dd090727c24fb9d7fdb1fb9f20f2e3f0141cab5b98b6a1934b0fc8cab948f7faae55588385b0f1fb7bbf91f52c705ce4528036a527c3119c6 2415 checksum: 77853d526af86ac508d7938916046ed4ad6374c7414981064c5122a2baa96fa234751137f481ac264a07387fd4dcec1cd26b33e29732cc58e855aae77a001d7c
2394 languageName: node 2416 languageName: node
2395 linkType: hard 2417 linkType: hard
2396 2418
2397"@typescript-eslint/visitor-keys@npm:5.35.1": 2419"@typescript-eslint/visitor-keys@npm:5.36.1":
2398 version: 5.35.1 2420 version: 5.36.1
2399 resolution: "@typescript-eslint/visitor-keys@npm:5.35.1" 2421 resolution: "@typescript-eslint/visitor-keys@npm:5.36.1"
2400 dependencies: 2422 dependencies:
2401 "@typescript-eslint/types": 5.35.1 2423 "@typescript-eslint/types": 5.36.1
2402 eslint-visitor-keys: ^3.3.0 2424 eslint-visitor-keys: ^3.3.0
2403 checksum: ef3c8377aac89935b5cc2fcf37bb3e42aa5f98848e7c22bdcbe5bb06c0fe8a1373a6897fd21109be8929b4708ad06c8874d2ef7bba17ff64911964203457330d 2425 checksum: 45ab7c2fd455a8e4beff418bed6c9e7e1f9f66bcaad3bfaed868f97a3f8cfec1fa4faa45948af1a1c32ce573a7b1c6d10427119c257622445b06b488fefd8b49
2404 languageName: node 2426 languageName: node
2405 linkType: hard 2427 linkType: hard
2406 2428
@@ -2421,6 +2443,44 @@ __metadata:
2421 languageName: node 2443 languageName: node
2422 linkType: hard 2444 linkType: hard
2423 2445
2446"@xstate/cli@npm:^0.3.2":
2447 version: 0.3.2
2448 resolution: "@xstate/cli@npm:0.3.2"
2449 dependencies:
2450 "@babel/core": ^7.12.10
2451 "@xstate/machine-extractor": 0.7.0
2452 "@xstate/tools-shared": 1.2.2
2453 chokidar: ^3.5.3
2454 commander: ^8.0.0
2455 xstate: ^4.29.0
2456 bin:
2457 xstate: bin/bin.js
2458 checksum: 78136a88a9357d676db09a18d726e1521b5284326a58cc75d4d6c0c86bf7e438c8b2f2d72562ef5133877fe9cbad1a91255600dca73aec7fab36980a2b8b9b7c
2459 languageName: node
2460 linkType: hard
2461
2462"@xstate/machine-extractor@npm:0.7.0":
2463 version: 0.7.0
2464 resolution: "@xstate/machine-extractor@npm:0.7.0"
2465 peerDependencies:
2466 "@babel/core": ^7
2467 xstate: ^4
2468 checksum: 139cba4217523034161d373d24e138c0d27e5527ca119f292dfc2c45a13d56cf72cb6ad4c94845b28192d9a908be3edf2d907c58cd35bac51cbacdefc9faefae
2469 languageName: node
2470 linkType: hard
2471
2472"@xstate/tools-shared@npm:1.2.2":
2473 version: 1.2.2
2474 resolution: "@xstate/tools-shared@npm:1.2.2"
2475 dependencies:
2476 "@xstate/machine-extractor": 0.7.0
2477 peerDependencies:
2478 prettier: ^2.3.1
2479 xstate: ^4
2480 checksum: a4e0dfb3bb8db9959cda415d0ee5fd4246fd6d803d602710737d947a382d68ea45887dac9ff51d8d1d8cff9acb1568e360babda4b02075b3d7a65ea241c58499
2481 languageName: node
2482 linkType: hard
2483
2424"abbrev@npm:1": 2484"abbrev@npm:1":
2425 version: 1.1.1 2485 version: 1.1.1
2426 resolution: "abbrev@npm:1.1.1" 2486 resolution: "abbrev@npm:1.1.1"
@@ -2532,6 +2592,16 @@ __metadata:
2532 languageName: node 2592 languageName: node
2533 linkType: hard 2593 linkType: hard
2534 2594
2595"anymatch@npm:~3.1.2":
2596 version: 3.1.2
2597 resolution: "anymatch@npm:3.1.2"
2598 dependencies:
2599 normalize-path: ^3.0.0
2600 picomatch: ^2.0.4
2601 checksum: 985163db2292fac9e5a1e072bf99f1b5baccf196e4de25a0b0b81865ebddeb3b3eb4480734ef0a2ac8c002845396b91aa89121f5b84f93981a4658164a9ec6e9
2602 languageName: node
2603 linkType: hard
2604
2535"aproba@npm:^1.0.3 || ^2.0.0": 2605"aproba@npm:^1.0.3 || ^2.0.0":
2536 version: 2.0.0 2606 version: 2.0.0
2537 resolution: "aproba@npm:2.0.0" 2607 resolution: "aproba@npm:2.0.0"
@@ -2707,6 +2777,13 @@ __metadata:
2707 languageName: node 2777 languageName: node
2708 linkType: hard 2778 linkType: hard
2709 2779
2780"binary-extensions@npm:^2.0.0":
2781 version: 2.2.0
2782 resolution: "binary-extensions@npm:2.2.0"
2783 checksum: ccd267956c58d2315f5d3ea6757cf09863c5fc703e50fbeb13a7dc849b812ef76e3cf9ca8f35a0c48498776a7478d7b4a0418e1e2b8cb9cb9731f2922aaad7f8
2784 languageName: node
2785 linkType: hard
2786
2710"brace-expansion@npm:^1.1.7": 2787"brace-expansion@npm:^1.1.7":
2711 version: 1.1.11 2788 version: 1.1.11
2712 resolution: "brace-expansion@npm:1.1.11" 2789 resolution: "brace-expansion@npm:1.1.11"
@@ -2726,7 +2803,7 @@ __metadata:
2726 languageName: node 2803 languageName: node
2727 linkType: hard 2804 linkType: hard
2728 2805
2729"braces@npm:^3.0.2": 2806"braces@npm:^3.0.2, braces@npm:~3.0.2":
2730 version: 3.0.2 2807 version: 3.0.2
2731 resolution: "braces@npm:3.0.2" 2808 resolution: "braces@npm:3.0.2"
2732 dependencies: 2809 dependencies:
@@ -2844,6 +2921,25 @@ __metadata:
2844 languageName: node 2921 languageName: node
2845 linkType: hard 2922 linkType: hard
2846 2923
2924"chokidar@npm:^3.5.3":
2925 version: 3.5.3
2926 resolution: "chokidar@npm:3.5.3"
2927 dependencies:
2928 anymatch: ~3.1.2
2929 braces: ~3.0.2
2930 fsevents: ~2.3.2
2931 glob-parent: ~5.1.2
2932 is-binary-path: ~2.1.0
2933 is-glob: ~4.0.1
2934 normalize-path: ~3.0.0
2935 readdirp: ~3.6.0
2936 dependenciesMeta:
2937 fsevents:
2938 optional: true
2939 checksum: b49fcde40176ba007ff361b198a2d35df60d9bb2a5aab228279eb810feae9294a6b4649ab15981304447afe1e6ffbf4788ad5db77235dc770ab777c6e771980c
2940 languageName: node
2941 linkType: hard
2942
2847"chownr@npm:^2.0.0": 2943"chownr@npm:^2.0.0":
2848 version: 2.0.0 2944 version: 2.0.0
2849 resolution: "chownr@npm:2.0.0" 2945 resolution: "chownr@npm:2.0.0"
@@ -2922,6 +3018,13 @@ __metadata:
2922 languageName: node 3018 languageName: node
2923 linkType: hard 3019 linkType: hard
2924 3020
3021"commander@npm:^8.0.0":
3022 version: 8.3.0
3023 resolution: "commander@npm:8.3.0"
3024 checksum: 0f82321821fc27b83bd409510bb9deeebcfa799ff0bf5d102128b500b7af22872c0c92cb6a0ebc5a4cf19c6b550fba9cedfa7329d18c6442a625f851377bacf0
3025 languageName: node
3026 linkType: hard
3027
2925"commander@npm:^9.4.0": 3028"commander@npm:^9.4.0":
2926 version: 9.4.0 3029 version: 9.4.0
2927 resolution: "commander@npm:9.4.0" 3030 resolution: "commander@npm:9.4.0"
@@ -3717,9 +3820,9 @@ __metadata:
3717 languageName: node 3820 languageName: node
3718 linkType: hard 3821 linkType: hard
3719 3822
3720"eslint-plugin-react@npm:^7.31.1": 3823"eslint-plugin-react@npm:^7.31.6":
3721 version: 7.31.1 3824 version: 7.31.6
3722 resolution: "eslint-plugin-react@npm:7.31.1" 3825 resolution: "eslint-plugin-react@npm:7.31.6"
3723 dependencies: 3826 dependencies:
3724 array-includes: ^3.1.5 3827 array-includes: ^3.1.5
3725 array.prototype.flatmap: ^1.3.0 3828 array.prototype.flatmap: ^1.3.0
@@ -3737,7 +3840,7 @@ __metadata:
3737 string.prototype.matchall: ^4.0.7 3840 string.prototype.matchall: ^4.0.7
3738 peerDependencies: 3841 peerDependencies:
3739 eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 3842 eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
3740 checksum: 6217d4c4e36c8fea24facd0cdcf22b2fd38a3603db94ec7c0a6f430046c8564b6c6884e0a9d4a4b8766201f66e8b18af594002210421bf9b6623b1fc32e15a3a 3843 checksum: fdcee460db2e01398b31dd75bb0597d6dfa2f29beda9c5ef641e6e3c72c8c2191cbaa952f7469a5e091bc2be959a1abc09761bdca70f12aa4a73090f48a98f6b
3741 languageName: node 3844 languageName: node
3742 linkType: hard 3845 linkType: hard
3743 3846
@@ -4151,7 +4254,7 @@ __metadata:
4151 languageName: node 4254 languageName: node
4152 linkType: hard 4255 linkType: hard
4153 4256
4154"glob-parent@npm:^5.1.2": 4257"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2":
4155 version: 5.1.2 4258 version: 5.1.2
4156 resolution: "glob-parent@npm:5.1.2" 4259 resolution: "glob-parent@npm:5.1.2"
4157 dependencies: 4260 dependencies:
@@ -4484,6 +4587,15 @@ __metadata:
4484 languageName: node 4587 languageName: node
4485 linkType: hard 4588 linkType: hard
4486 4589
4590"is-binary-path@npm:~2.1.0":
4591 version: 2.1.0
4592 resolution: "is-binary-path@npm:2.1.0"
4593 dependencies:
4594 binary-extensions: ^2.0.0
4595 checksum: 84192eb88cff70d320426f35ecd63c3d6d495da9d805b19bc65b518984b7c0760280e57dbf119b7e9be6b161784a5a673ab2c6abe83abb5198a432232ad5b35c
4596 languageName: node
4597 linkType: hard
4598
4487"is-boolean-object@npm:^1.1.0": 4599"is-boolean-object@npm:^1.1.0":
4488 version: 1.1.2 4600 version: 1.1.2
4489 resolution: "is-boolean-object@npm:1.1.2" 4601 resolution: "is-boolean-object@npm:1.1.2"
@@ -4542,7 +4654,7 @@ __metadata:
4542 languageName: node 4654 languageName: node
4543 linkType: hard 4655 linkType: hard
4544 4656
4545"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": 4657"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1":
4546 version: 4.0.3 4658 version: 4.0.3
4547 resolution: "is-glob@npm:4.0.3" 4659 resolution: "is-glob@npm:4.0.3"
4548 dependencies: 4660 dependencies:
@@ -5263,6 +5375,13 @@ __metadata:
5263 languageName: node 5375 languageName: node
5264 linkType: hard 5376 linkType: hard
5265 5377
5378"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0":
5379 version: 3.0.0
5380 resolution: "normalize-path@npm:3.0.0"
5381 checksum: 88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20
5382 languageName: node
5383 linkType: hard
5384
5266"notistack@npm:^2.0.5": 5385"notistack@npm:^2.0.5":
5267 version: 2.0.5 5386 version: 2.0.5
5268 resolution: "notistack@npm:2.0.5" 5387 resolution: "notistack@npm:2.0.5"
@@ -5548,7 +5667,7 @@ __metadata:
5548 languageName: node 5667 languageName: node
5549 linkType: hard 5668 linkType: hard
5550 5669
5551"picomatch@npm:^2.2.2, picomatch@npm:^2.3.1": 5670"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.3.1":
5552 version: 2.3.1 5671 version: 2.3.1
5553 resolution: "picomatch@npm:2.3.1" 5672 resolution: "picomatch@npm:2.3.1"
5554 checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf 5673 checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf
@@ -5724,6 +5843,15 @@ __metadata:
5724 languageName: node 5843 languageName: node
5725 linkType: hard 5844 linkType: hard
5726 5845
5846"readdirp@npm:~3.6.0":
5847 version: 3.6.0
5848 resolution: "readdirp@npm:3.6.0"
5849 dependencies:
5850 picomatch: ^2.2.1
5851 checksum: 1ced032e6e45670b6d7352d71d21ce7edf7b9b928494dcaba6f11fba63180d9da6cd7061ebc34175ffda6ff529f481818c962952004d273178acd70f7059b320
5852 languageName: node
5853 linkType: hard
5854
5727"regenerate-unicode-properties@npm:^10.0.1": 5855"regenerate-unicode-properties@npm:^10.0.1":
5728 version: 10.0.1 5856 version: 10.0.1
5729 resolution: "regenerate-unicode-properties@npm:10.0.1" 5857 resolution: "regenerate-unicode-properties@npm:10.0.1"
@@ -6605,9 +6733,9 @@ __metadata:
6605 languageName: node 6733 languageName: node
6606 linkType: hard 6734 linkType: hard
6607 6735
6608"vite-plugin-pwa@npm:^0.12.3": 6736"vite-plugin-pwa@npm:^0.12.6":
6609 version: 0.12.3 6737 version: 0.12.6
6610 resolution: "vite-plugin-pwa@npm:0.12.3" 6738 resolution: "vite-plugin-pwa@npm:0.12.6"
6611 dependencies: 6739 dependencies:
6612 debug: ^4.3.4 6740 debug: ^4.3.4
6613 fast-glob: ^3.2.11 6741 fast-glob: ^3.2.11
@@ -6619,7 +6747,7 @@ __metadata:
6619 vite: ^2.0.0 || ^3.0.0-0 6747 vite: ^2.0.0 || ^3.0.0-0
6620 workbox-build: ^6.4.0 6748 workbox-build: ^6.4.0
6621 workbox-window: ^6.4.0 6749 workbox-window: ^6.4.0
6622 checksum: 95cb06de0f4f9025462423fbaa7839f0197616082276d3ec4fd57fa3cc3b2bf47347a186c964594f18e230b2f07fcd18a065fc98f3b7be9a8980c3ca5abfe513 6750 checksum: b3577d401ede64c6937a940eca447e64f6f19f74f4588cdd8f201081ed73c1a87e1cb2defa47f7d6f33adb618f5dd7623e7b99d27fc5605ed175d678e64f8e71
6623 languageName: node 6751 languageName: node
6624 linkType: hard 6752 linkType: hard
6625 6753
@@ -6917,6 +7045,13 @@ __metadata:
6917 languageName: node 7045 languageName: node
6918 linkType: hard 7046 linkType: hard
6919 7047
7048"xstate@npm:^4.29.0, xstate@npm:^4.33.5":
7049 version: 4.33.5
7050 resolution: "xstate@npm:4.33.5"
7051 checksum: 124898d48547cdf46e9d26460fccd0632bd59505f5f1d968a9b21b04580eaa210ac289bb2dcd61a64f837fc4fba15ee20c3dc16b899dd637949c912b25fd0821
7052 languageName: node
7053 linkType: hard
7054
6920"yallist@npm:^4.0.0": 7055"yallist@npm:^4.0.0":
6921 version: 4.0.0 7056 version: 4.0.0
6922 resolution: "yallist@npm:4.0.0" 7057 resolution: "yallist@npm:4.0.0"