Spaces:
Running
on
T4
Running
on
T4
Mark Duppenthaler
commited on
Commit
•
34021fc
1
Parent(s):
7505741
Port over VR performance fixes and cleanup
Browse files- streaming-react-app/src/StreamingInterface.tsx +37 -7
- streaming-react-app/src/URLParams.ts +2 -2
- streaming-react-app/src/react-xr/ARButton.tsx +89 -0
- streaming-react-app/src/react-xr/XRDialog.css +6 -0
- streaming-react-app/src/react-xr/XRDialog.tsx +85 -28
- streaming-react-app/src/react-xr/XRRendering.ts +402 -0
- streaming-react-app/src/react-xr/supportedCharSet.ts +20 -0
- streaming-react-app/src/types/StreamingTypes.ts +8 -8
- streaming-react-app/src/types/URLParamsTypes.ts +4 -4
- streaming-react-app/yarn.lock +152 -97
streaming-react-app/src/StreamingInterface.tsx
CHANGED
@@ -64,19 +64,19 @@ const AUDIO_STREAM_DEFAULTS: {
|
|
64 |
[key in SupportedInputSource]: BrowserAudioStreamConfig;
|
65 |
} = {
|
66 |
userMedia: {
|
67 |
-
noiseSuppression: true,
|
68 |
echoCancellation: false,
|
|
|
69 |
},
|
70 |
displayMedia: {
|
71 |
-
noiseSuppression: false,
|
72 |
echoCancellation: false,
|
|
|
73 |
},
|
74 |
};
|
75 |
|
76 |
async function requestUserMediaAudioStream(
|
77 |
config: BrowserAudioStreamConfig = {
|
78 |
-
noiseSuppression: true,
|
79 |
echoCancellation: false,
|
|
|
80 |
},
|
81 |
) {
|
82 |
const stream = await navigator.mediaDevices.getUserMedia({
|
@@ -91,8 +91,8 @@ async function requestUserMediaAudioStream(
|
|
91 |
|
92 |
async function requestDisplayMediaAudioStream(
|
93 |
config: BrowserAudioStreamConfig = {
|
94 |
-
noiseSuppression: false,
|
95 |
echoCancellation: false,
|
|
|
96 |
},
|
97 |
) {
|
98 |
const stream = await navigator.mediaDevices.getDisplayMedia({
|
@@ -130,7 +130,9 @@ export const TYPING_ANIMATION_DELAY_MS = 6;
|
|
130 |
export default function StreamingInterface() {
|
131 |
const urlParams = getURLParams();
|
132 |
const debugParam = urlParams.debug;
|
133 |
-
const animateTextDisplay =
|
|
|
|
|
134 |
|
135 |
const socketObject = useSocket();
|
136 |
const {socket, clientID} = socketObject;
|
@@ -165,6 +167,9 @@ export default function StreamingInterface() {
|
|
165 |
const [enableNoiseSuppression, setEnableNoiseSuppression] = useState<
|
166 |
boolean | null
|
167 |
>(null);
|
|
|
|
|
|
|
168 |
|
169 |
// Dynamic Params:
|
170 |
const [targetLang, setTargetLang] = useState<string | null>(null);
|
@@ -358,14 +363,18 @@ export default function StreamingInterface() {
|
|
358 |
noiseSuppression:
|
359 |
enableNoiseSuppression ??
|
360 |
AUDIO_STREAM_DEFAULTS['userMedia'].noiseSuppression,
|
361 |
-
echoCancellation:
|
|
|
|
|
362 |
});
|
363 |
} else if (inputSource === 'displayMedia') {
|
364 |
stream = await requestDisplayMediaAudioStream({
|
365 |
noiseSuppression:
|
366 |
enableNoiseSuppression ??
|
367 |
AUDIO_STREAM_DEFAULTS['displayMedia'].noiseSuppression,
|
368 |
-
echoCancellation:
|
|
|
|
|
369 |
});
|
370 |
} else {
|
371 |
throw new Error(`Unsupported input source requested: ${inputSource}`);
|
@@ -733,6 +742,10 @@ export default function StreamingInterface() {
|
|
733 |
startStreaming={startStreaming}
|
734 |
stopStreaming={stopStreaming}
|
735 |
debugParam={debugParam}
|
|
|
|
|
|
|
|
|
736 |
/>
|
737 |
);
|
738 |
|
@@ -980,6 +993,23 @@ export default function StreamingInterface() {
|
|
980 |
}
|
981 |
label="Noise Suppression (Browser)"
|
982 |
/>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
983 |
<FormControlLabel
|
984 |
control={
|
985 |
<Checkbox
|
|
|
64 |
[key in SupportedInputSource]: BrowserAudioStreamConfig;
|
65 |
} = {
|
66 |
userMedia: {
|
|
|
67 |
echoCancellation: false,
|
68 |
+
noiseSuppression: true,
|
69 |
},
|
70 |
displayMedia: {
|
|
|
71 |
echoCancellation: false,
|
72 |
+
noiseSuppression: false,
|
73 |
},
|
74 |
};
|
75 |
|
76 |
async function requestUserMediaAudioStream(
|
77 |
config: BrowserAudioStreamConfig = {
|
|
|
78 |
echoCancellation: false,
|
79 |
+
noiseSuppression: true,
|
80 |
},
|
81 |
) {
|
82 |
const stream = await navigator.mediaDevices.getUserMedia({
|
|
|
91 |
|
92 |
async function requestDisplayMediaAudioStream(
|
93 |
config: BrowserAudioStreamConfig = {
|
|
|
94 |
echoCancellation: false,
|
95 |
+
noiseSuppression: false,
|
96 |
},
|
97 |
) {
|
98 |
const stream = await navigator.mediaDevices.getDisplayMedia({
|
|
|
130 |
export default function StreamingInterface() {
|
131 |
const urlParams = getURLParams();
|
132 |
const debugParam = urlParams.debug;
|
133 |
+
const [animateTextDisplay, setAnimateTextDisplay] = useState<boolean>(
|
134 |
+
urlParams.animateTextDisplay,
|
135 |
+
);
|
136 |
|
137 |
const socketObject = useSocket();
|
138 |
const {socket, clientID} = socketObject;
|
|
|
167 |
const [enableNoiseSuppression, setEnableNoiseSuppression] = useState<
|
168 |
boolean | null
|
169 |
>(null);
|
170 |
+
const [enableEchoCancellation, setEnableEchoCancellation] = useState<
|
171 |
+
boolean | null
|
172 |
+
>(null);
|
173 |
|
174 |
// Dynamic Params:
|
175 |
const [targetLang, setTargetLang] = useState<string | null>(null);
|
|
|
363 |
noiseSuppression:
|
364 |
enableNoiseSuppression ??
|
365 |
AUDIO_STREAM_DEFAULTS['userMedia'].noiseSuppression,
|
366 |
+
echoCancellation:
|
367 |
+
enableEchoCancellation ??
|
368 |
+
AUDIO_STREAM_DEFAULTS['userMedia'].echoCancellation,
|
369 |
});
|
370 |
} else if (inputSource === 'displayMedia') {
|
371 |
stream = await requestDisplayMediaAudioStream({
|
372 |
noiseSuppression:
|
373 |
enableNoiseSuppression ??
|
374 |
AUDIO_STREAM_DEFAULTS['displayMedia'].noiseSuppression,
|
375 |
+
echoCancellation:
|
376 |
+
enableEchoCancellation ??
|
377 |
+
AUDIO_STREAM_DEFAULTS['displayMedia'].echoCancellation,
|
378 |
});
|
379 |
} else {
|
380 |
throw new Error(`Unsupported input source requested: ${inputSource}`);
|
|
|
742 |
startStreaming={startStreaming}
|
743 |
stopStreaming={stopStreaming}
|
744 |
debugParam={debugParam}
|
745 |
+
onARHidden={() => {
|
746 |
+
setAnimateTextDisplay(urlParams.animateTextDisplay);
|
747 |
+
}}
|
748 |
+
onARVisible={() => setAnimateTextDisplay(false)}
|
749 |
/>
|
750 |
);
|
751 |
|
|
|
993 |
}
|
994 |
label="Noise Suppression (Browser)"
|
995 |
/>
|
996 |
+
<FormControlLabel
|
997 |
+
control={
|
998 |
+
<Checkbox
|
999 |
+
checked={
|
1000 |
+
enableEchoCancellation ??
|
1001 |
+
AUDIO_STREAM_DEFAULTS[inputSource]
|
1002 |
+
.echoCancellation
|
1003 |
+
}
|
1004 |
+
onChange={(
|
1005 |
+
event: React.ChangeEvent<HTMLInputElement>,
|
1006 |
+
) =>
|
1007 |
+
setEnableEchoCancellation(event.target.checked)
|
1008 |
+
}
|
1009 |
+
/>
|
1010 |
+
}
|
1011 |
+
label="Echo Cancellation (Browser)"
|
1012 |
+
/>
|
1013 |
<FormControlLabel
|
1014 |
control={
|
1015 |
<Checkbox
|
streaming-react-app/src/URLParams.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
-
import {getBooleanParamFlag, getStringParamFlag} from './getParamFlag';
|
2 |
-
import {URLParamsObject} from './types/URLParamsTypes';
|
3 |
|
4 |
/**
|
5 |
* These are the URL parameters you can provide to the app to change its behavior.
|
|
|
1 |
+
import { getBooleanParamFlag, getStringParamFlag } from './getParamFlag';
|
2 |
+
import { URLParamsObject } from './types/URLParamsTypes';
|
3 |
|
4 |
/**
|
5 |
* These are the URL parameters you can provide to the app to change its behavior.
|
streaming-react-app/src/react-xr/ARButton.tsx
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import * as THREE from 'three';
|
2 |
+
import {Button} from '@mui/material';
|
3 |
+
import {useCallback, useEffect, useState} from 'react';
|
4 |
+
import {BufferedSpeechPlayer} from '../createBufferedSpeechPlayer';
|
5 |
+
|
6 |
+
type Props = {
|
7 |
+
bufferedSpeechPlayer: BufferedSpeechPlayer;
|
8 |
+
renderer: THREE.WebGLRenderer | null;
|
9 |
+
onARVisible?: () => void;
|
10 |
+
onARHidden?: () => void;
|
11 |
+
};
|
12 |
+
|
13 |
+
export default function ARButton({
|
14 |
+
bufferedSpeechPlayer,
|
15 |
+
renderer,
|
16 |
+
onARVisible,
|
17 |
+
onARHidden,
|
18 |
+
}: Props) {
|
19 |
+
const [session, setSession] = useState<XRSession | null>(null);
|
20 |
+
const [supported, setSupported] = useState<boolean>(true);
|
21 |
+
|
22 |
+
useEffect(() => {
|
23 |
+
if (!navigator.xr) {
|
24 |
+
setSupported(false);
|
25 |
+
return;
|
26 |
+
}
|
27 |
+
navigator.xr.isSessionSupported('immersive-ar').then((supported) => {
|
28 |
+
setSupported(supported);
|
29 |
+
});
|
30 |
+
}, []);
|
31 |
+
|
32 |
+
const resetBuffers = useCallback(
|
33 |
+
(event: XRSessionEvent) => {
|
34 |
+
const session = event.target;
|
35 |
+
if (!(session instanceof XRSession)) {
|
36 |
+
return;
|
37 |
+
}
|
38 |
+
switch (session.visibilityState) {
|
39 |
+
case 'visible':
|
40 |
+
console.log('Restarting speech player, device is visible');
|
41 |
+
bufferedSpeechPlayer.stop();
|
42 |
+
bufferedSpeechPlayer.start();
|
43 |
+
onARVisible?.();
|
44 |
+
break;
|
45 |
+
case 'hidden':
|
46 |
+
console.log('Stopping speech player, device is hidden');
|
47 |
+
bufferedSpeechPlayer.stop();
|
48 |
+
bufferedSpeechPlayer.start();
|
49 |
+
onARHidden?.();
|
50 |
+
break;
|
51 |
+
}
|
52 |
+
},
|
53 |
+
[bufferedSpeechPlayer],
|
54 |
+
);
|
55 |
+
|
56 |
+
async function onSessionStarted(session: XRSession) {
|
57 |
+
setSession(session);
|
58 |
+
|
59 |
+
session.onvisibilitychange = resetBuffers;
|
60 |
+
session.onend = onSessionEnded;
|
61 |
+
|
62 |
+
await renderer.xr.setSession(session);
|
63 |
+
}
|
64 |
+
|
65 |
+
function onSessionEnded() {
|
66 |
+
setSession(null);
|
67 |
+
}
|
68 |
+
|
69 |
+
const onClick = () => {
|
70 |
+
if (session === null) {
|
71 |
+
navigator.xr!.requestSession('immersive-ar').then(onSessionStarted);
|
72 |
+
} else {
|
73 |
+
session.end();
|
74 |
+
}
|
75 |
+
};
|
76 |
+
return (
|
77 |
+
<Button
|
78 |
+
variant="contained"
|
79 |
+
onClick={onClick}
|
80 |
+
disabled={!supported || renderer == null}
|
81 |
+
sx={{mt: 1}}>
|
82 |
+
{supported
|
83 |
+
? renderer != null
|
84 |
+
? 'Enter AR'
|
85 |
+
: 'Initializing AR...'
|
86 |
+
: 'AR Not Supported'}
|
87 |
+
</Button>
|
88 |
+
);
|
89 |
+
}
|
streaming-react-app/src/react-xr/XRDialog.css
CHANGED
@@ -11,3 +11,9 @@
|
|
11 |
.xr-dialog-text-center {
|
12 |
text-align: center;
|
13 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
.xr-dialog-text-center {
|
12 |
text-align: center;
|
13 |
}
|
14 |
+
|
15 |
+
.xr-dialog-canvas-container {
|
16 |
+
display: flex;
|
17 |
+
align-items: center;
|
18 |
+
justify-content: center;
|
19 |
+
}
|
streaming-react-app/src/react-xr/XRDialog.tsx
CHANGED
@@ -1,3 +1,4 @@
|
|
|
|
1 |
import {
|
2 |
Button,
|
3 |
Dialog,
|
@@ -7,43 +8,99 @@ import {
|
|
7 |
Typography,
|
8 |
} from '@mui/material';
|
9 |
import CloseIcon from '@mui/icons-material/Close';
|
10 |
-
import
|
11 |
-
import {useState} from 'react';
|
12 |
import './XRDialog.css';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
export default function XRDialog(props: XRConfigProps) {
|
15 |
const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);
|
|
|
16 |
return (
|
17 |
<>
|
18 |
<Button variant="contained" onClick={() => setIsDialogOpen(true)}>
|
19 |
Enter AR Experience
|
20 |
</Button>
|
21 |
-
|
22 |
-
<
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
Welcome to the Seamless team streaming demo experience! In this demo
|
41 |
-
you will experience AI powered text and audio translation in real
|
42 |
-
time.
|
43 |
-
</Typography>
|
44 |
-
<XRConfig {...props} />
|
45 |
-
</DialogContent>
|
46 |
-
</Dialog>
|
47 |
</>
|
48 |
);
|
49 |
}
|
|
|
1 |
+
import * as THREE from 'three';
|
2 |
import {
|
3 |
Button,
|
4 |
Dialog,
|
|
|
8 |
Typography,
|
9 |
} from '@mui/material';
|
10 |
import CloseIcon from '@mui/icons-material/Close';
|
11 |
+
import {useEffect, useRef, useState} from 'react';
|
|
|
12 |
import './XRDialog.css';
|
13 |
+
import {getRenderer, init, updatetranslationText} from './XRRendering';
|
14 |
+
import ARButton from './ARButton';
|
15 |
+
import {getURLParams} from '../URLParams';
|
16 |
+
import { BufferedSpeechPlayer } from '../createBufferedSpeechPlayer';
|
17 |
+
import { TranslationSentences } from '../types/StreamingTypes';
|
18 |
+
import { RoomState } from '../types/RoomState';
|
19 |
+
|
20 |
+
type XRConfigProps = {
|
21 |
+
animateTextDisplay: boolean;
|
22 |
+
bufferedSpeechPlayer: BufferedSpeechPlayer;
|
23 |
+
translationSentences: TranslationSentences;
|
24 |
+
roomState: RoomState | null;
|
25 |
+
roomID: string | null;
|
26 |
+
startStreaming: () => Promise<void>;
|
27 |
+
stopStreaming: () => Promise<void>;
|
28 |
+
debugParam: boolean | null;
|
29 |
+
onARVisible?: () => void;
|
30 |
+
onARHidden?: () => void;
|
31 |
+
};
|
32 |
+
|
33 |
+
function XRContent(props: XRConfigProps) {
|
34 |
+
const debugParam = getURLParams().debug;
|
35 |
+
const {translationSentences} = props;
|
36 |
+
useEffect(() => {
|
37 |
+
updatetranslationText(translationSentences);
|
38 |
+
}, [translationSentences]);
|
39 |
+
|
40 |
+
const [renderer, setRenderer] = useState<THREE.WebGLRenderer | null>(null);
|
41 |
+
const canvasRef = useRef<HTMLDivElement | null>(null);
|
42 |
+
useEffect(() => {
|
43 |
+
if (canvasRef.current != null || debugParam === false) {
|
44 |
+
const existingRenderer = getRenderer();
|
45 |
+
if (existingRenderer) {
|
46 |
+
setRenderer(existingRenderer);
|
47 |
+
} else {
|
48 |
+
const newRenderer = init(
|
49 |
+
400,
|
50 |
+
300,
|
51 |
+
debugParam ? canvasRef.current : null,
|
52 |
+
);
|
53 |
+
setRenderer(newRenderer);
|
54 |
+
}
|
55 |
+
}
|
56 |
+
}, [canvasRef.current]);
|
57 |
+
|
58 |
+
return (
|
59 |
+
<DialogContent
|
60 |
+
dividers
|
61 |
+
className="xr-dialog-container xr-dialog-text-center">
|
62 |
+
<Typography gutterBottom>
|
63 |
+
Welcome to the Seamless team streaming demo experience! In this demo you
|
64 |
+
will experience AI powered text and audio translation in real time.
|
65 |
+
</Typography>
|
66 |
+
<div ref={canvasRef} className="xr-dialog-canvas-container" />
|
67 |
+
<ARButton
|
68 |
+
bufferedSpeechPlayer={props.bufferedSpeechPlayer}
|
69 |
+
renderer={renderer}
|
70 |
+
onARHidden={props.onARHidden}
|
71 |
+
onARVisible={props.onARVisible}
|
72 |
+
/>
|
73 |
+
</DialogContent>
|
74 |
+
);
|
75 |
+
}
|
76 |
|
77 |
export default function XRDialog(props: XRConfigProps) {
|
78 |
const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false);
|
79 |
+
|
80 |
return (
|
81 |
<>
|
82 |
<Button variant="contained" onClick={() => setIsDialogOpen(true)}>
|
83 |
Enter AR Experience
|
84 |
</Button>
|
85 |
+
{isDialogOpen && (
|
86 |
+
<Dialog onClose={() => setIsDialogOpen(false)} open={true}>
|
87 |
+
<DialogTitle sx={{m: 0, p: 2}} className="xr-dialog-text-center">
|
88 |
+
FAIR Seamless Streaming Demo
|
89 |
+
</DialogTitle>
|
90 |
+
<IconButton
|
91 |
+
aria-label="close"
|
92 |
+
onClick={() => setIsDialogOpen(false)}
|
93 |
+
sx={{
|
94 |
+
position: 'absolute',
|
95 |
+
right: 8,
|
96 |
+
top: 8,
|
97 |
+
color: (theme) => theme.palette.grey[500],
|
98 |
+
}}>
|
99 |
+
<CloseIcon />
|
100 |
+
</IconButton>
|
101 |
+
<XRContent {...props} />
|
102 |
+
</Dialog>
|
103 |
+
)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
</>
|
105 |
);
|
106 |
}
|
streaming-react-app/src/react-xr/XRRendering.ts
ADDED
@@ -0,0 +1,402 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import * as THREE from 'three';
|
2 |
+
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';
|
3 |
+
|
4 |
+
import ThreeMeshUI, {Block, Text} from 'three-mesh-ui';
|
5 |
+
|
6 |
+
import FontJSON from '../assets/RobotoMono-Regular-msdf.json?url';
|
7 |
+
import FontImage from '../assets/RobotoMono-Regular.png';
|
8 |
+
import {TranslationSentences} from '../types/StreamingTypes';
|
9 |
+
import supportedCharSet from './supportedCharSet';
|
10 |
+
|
11 |
+
// Augment three-mesh-ui types which aren't implemented
|
12 |
+
declare module 'three-mesh-ui' {
|
13 |
+
interface Block {
|
14 |
+
add(any: any);
|
15 |
+
set(props: BlockOptions);
|
16 |
+
position: {
|
17 |
+
x: number;
|
18 |
+
y: number;
|
19 |
+
z: number;
|
20 |
+
set: (x: number, y: number, z: number) => void;
|
21 |
+
};
|
22 |
+
}
|
23 |
+
interface Text {
|
24 |
+
set(props: {content: string});
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
// Various configuration parameters
|
29 |
+
const INITIAL_PROMPT = 'Listening...\n';
|
30 |
+
const NUM_LINES = 3;
|
31 |
+
const CHARS_PER_LINE = 37;
|
32 |
+
const CHARS_PER_SECOND = 15;
|
33 |
+
|
34 |
+
const MAX_WIDTH = 0.89;
|
35 |
+
const CHAR_WIDTH = 0.0233;
|
36 |
+
const Y_COORD_START = -0.38;
|
37 |
+
const Z_COORD = -1.3;
|
38 |
+
const LINE_HEIGHT = 0.062;
|
39 |
+
const BLOCK_SPACING = 0.02;
|
40 |
+
const FONT_SIZE = 0.038;
|
41 |
+
|
42 |
+
// Speed of scrolling of text lines
|
43 |
+
const SCROLL_Y_DELTA = 0.01;
|
44 |
+
|
45 |
+
// Overlay an extra block for padding due to inflexibilities of native padding
|
46 |
+
const OFFSET = 0.01;
|
47 |
+
const OFFSET_WIDTH = OFFSET * 3;
|
48 |
+
|
49 |
+
// The tick interval
|
50 |
+
const CURSOR_BLINK_INTERVAL_MS = 500;
|
51 |
+
|
52 |
+
type TranscriptState = {
|
53 |
+
translationText: string;
|
54 |
+
textBlocksProps: TextBlockProps[];
|
55 |
+
lastTranslationStringIndex: number;
|
56 |
+
lastTranslationLineStartIndex: number;
|
57 |
+
transcriptLines: string[];
|
58 |
+
lastUpdateTime: number;
|
59 |
+
};
|
60 |
+
|
61 |
+
type TextBlockProps = {
|
62 |
+
content: string;
|
63 |
+
// The end position when animating
|
64 |
+
targetY: number;
|
65 |
+
// Current scroll position that caps at targetY
|
66 |
+
currentY: number;
|
67 |
+
textOpacity: number;
|
68 |
+
backgroundOpacity: number;
|
69 |
+
index: number;
|
70 |
+
isBottomLine: boolean;
|
71 |
+
};
|
72 |
+
|
73 |
+
function initialTextBlockProps(count: number): TextBlockProps[] {
|
74 |
+
return Array.from({length: count}).map(() => {
|
75 |
+
// Push in non display blocks because mesh UI crashes if elements are add / removed from screen.
|
76 |
+
|
77 |
+
return {
|
78 |
+
// key: textBlocksProps.length,
|
79 |
+
targetY: Y_COORD_START,
|
80 |
+
currentY: Y_COORD_START,
|
81 |
+
index: 0,
|
82 |
+
textOpacity: 0,
|
83 |
+
backgroundOpacity: 0,
|
84 |
+
width: MAX_WIDTH,
|
85 |
+
height: LINE_HEIGHT,
|
86 |
+
content: '',
|
87 |
+
isBottomLine: true,
|
88 |
+
};
|
89 |
+
});
|
90 |
+
}
|
91 |
+
|
92 |
+
function initialState(): TranscriptState {
|
93 |
+
return {
|
94 |
+
translationText: '',
|
95 |
+
textBlocksProps: initialTextBlockProps(NUM_LINES),
|
96 |
+
lastTranslationStringIndex: 0,
|
97 |
+
lastTranslationLineStartIndex: 0,
|
98 |
+
transcriptLines: [],
|
99 |
+
lastUpdateTime: new Date().getTime(),
|
100 |
+
};
|
101 |
+
}
|
102 |
+
|
103 |
+
let transcriptState: TranscriptState = initialState();
|
104 |
+
|
105 |
+
let scene: THREE.Scene | null;
|
106 |
+
let camera: THREE.PerspectiveCamera | null;
|
107 |
+
let renderer: THREE.WebGLRenderer | null;
|
108 |
+
let controls: THREE.OrbitControls | null;
|
109 |
+
|
110 |
+
let cursorBlinkOn: boolean = false;
|
111 |
+
|
112 |
+
setInterval(() => {
|
113 |
+
cursorBlinkOn = !cursorBlinkOn;
|
114 |
+
}, CURSOR_BLINK_INTERVAL_MS);
|
115 |
+
|
116 |
+
type TextBlock = {
|
117 |
+
textBlockOuterContainer: Block;
|
118 |
+
textBlockInnerContainer: Block;
|
119 |
+
text: Text;
|
120 |
+
};
|
121 |
+
const textBlocks: TextBlock[] = [];
|
122 |
+
|
123 |
+
export function getRenderer(): THREE.WebGLRenderer | null {
|
124 |
+
return renderer;
|
125 |
+
}
|
126 |
+
|
127 |
+
export function init(
|
128 |
+
width: number,
|
129 |
+
height: number,
|
130 |
+
parentElement: HTMLDivElement | null,
|
131 |
+
): THREE.WebGLRenderer {
|
132 |
+
scene = new THREE.Scene();
|
133 |
+
scene.background = new THREE.Color(0x505050);
|
134 |
+
|
135 |
+
camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 1000);
|
136 |
+
camera.position.z = 1;
|
137 |
+
|
138 |
+
renderer = new THREE.WebGLRenderer({
|
139 |
+
antialias: true,
|
140 |
+
});
|
141 |
+
renderer.setPixelRatio(window.devicePixelRatio);
|
142 |
+
renderer.setSize(width, height);
|
143 |
+
renderer.xr.enabled = true;
|
144 |
+
|
145 |
+
renderer.xr.setReferenceSpaceType('local');
|
146 |
+
|
147 |
+
parentElement?.appendChild(renderer.domElement);
|
148 |
+
|
149 |
+
controls = new OrbitControls(camera, renderer.domElement);
|
150 |
+
controls.update();
|
151 |
+
|
152 |
+
scene.add(camera);
|
153 |
+
|
154 |
+
textBlocks.push(
|
155 |
+
...initialTextBlockProps(NUM_LINES).map((props) => makeTextBlock(props)),
|
156 |
+
);
|
157 |
+
|
158 |
+
renderer.setAnimationLoop(loop);
|
159 |
+
return renderer;
|
160 |
+
}
|
161 |
+
|
162 |
+
export function updatetranslationText(
|
163 |
+
translationSentences: TranslationSentences,
|
164 |
+
): void {
|
165 |
+
const newText = INITIAL_PROMPT + translationSentences.join('\n');
|
166 |
+
if (transcriptState.translationText === newText) {
|
167 |
+
return;
|
168 |
+
}
|
169 |
+
transcriptState.translationText = newText;
|
170 |
+
}
|
171 |
+
|
172 |
+
export function resetState(): void {
|
173 |
+
transcriptState = initialState();
|
174 |
+
}
|
175 |
+
|
176 |
+
function makeTextBlock({
|
177 |
+
content,
|
178 |
+
backgroundOpacity,
|
179 |
+
}: TextBlockProps): TextBlock {
|
180 |
+
const width = MAX_WIDTH;
|
181 |
+
const height = LINE_HEIGHT;
|
182 |
+
|
183 |
+
const fontProps = {
|
184 |
+
fontSize: FONT_SIZE,
|
185 |
+
textAlign: 'left',
|
186 |
+
// TODO: support more language charsets
|
187 |
+
// This renders using MSDF format supported in WebGL. Renderable characters are defined in the "charset" json
|
188 |
+
// Currently supports most default keyboard inputs but this would exclude many non latin charset based languages.
|
189 |
+
// You can use https://msdf-bmfont.donmccurdy.com/ for easily generating these files
|
190 |
+
fontFamily: FontJSON,
|
191 |
+
fontTexture: FontImage,
|
192 |
+
};
|
193 |
+
|
194 |
+
const textBlockOuterContainer = new Block({
|
195 |
+
backgroundOpacity,
|
196 |
+
width: width + OFFSET_WIDTH,
|
197 |
+
height: height,
|
198 |
+
borderRadius: 0,
|
199 |
+
...fontProps,
|
200 |
+
});
|
201 |
+
|
202 |
+
const text = new Text({content});
|
203 |
+
const textBlockInnerContainer = new Block({
|
204 |
+
padding: 0,
|
205 |
+
backgroundOpacity: 0,
|
206 |
+
width,
|
207 |
+
height,
|
208 |
+
});
|
209 |
+
|
210 |
+
// Adding it to the camera makes the UI follow it.
|
211 |
+
camera.add(textBlockOuterContainer);
|
212 |
+
textBlockOuterContainer.add(textBlockInnerContainer);
|
213 |
+
textBlockInnerContainer.add(text);
|
214 |
+
|
215 |
+
return {
|
216 |
+
textBlockOuterContainer,
|
217 |
+
textBlockInnerContainer,
|
218 |
+
text,
|
219 |
+
};
|
220 |
+
}
|
221 |
+
|
222 |
+
// Updates the position and text of a text block from its props
|
223 |
+
function updateTextBlock(
|
224 |
+
id: number,
|
225 |
+
{content, targetY, currentY, backgroundOpacity, isBottomLine}: TextBlockProps,
|
226 |
+
): void {
|
227 |
+
const {textBlockOuterContainer, textBlockInnerContainer, text} =
|
228 |
+
textBlocks[id];
|
229 |
+
|
230 |
+
const {lastTranslationStringIndex, translationText} = transcriptState;
|
231 |
+
|
232 |
+
// Add blinking cursor if we don't have any new input to render
|
233 |
+
const numChars = content.length;
|
234 |
+
|
235 |
+
if (
|
236 |
+
isBottomLine &&
|
237 |
+
cursorBlinkOn &&
|
238 |
+
lastTranslationStringIndex >= translationText.length
|
239 |
+
) {
|
240 |
+
content = content + '|';
|
241 |
+
}
|
242 |
+
|
243 |
+
// Accounting for potential cursor for block width (the +1)
|
244 |
+
const width =
|
245 |
+
(numChars + (isBottomLine ? 1.1 : 0) + (numChars < 10 ? 1 : 0)) *
|
246 |
+
CHAR_WIDTH;
|
247 |
+
const height = LINE_HEIGHT;
|
248 |
+
|
249 |
+
// Width starts from 0 and goes 1/2 in each direction so offset x
|
250 |
+
const xPosition = width / 2 - MAX_WIDTH / 2 + OFFSET_WIDTH;
|
251 |
+
textBlockOuterContainer?.set({
|
252 |
+
backgroundOpacity,
|
253 |
+
width: width + 2 * OFFSET_WIDTH,
|
254 |
+
height: height + OFFSET / 3,
|
255 |
+
borderRadius: 0,
|
256 |
+
});
|
257 |
+
|
258 |
+
// Scroll up line toward target
|
259 |
+
const y = isBottomLine
|
260 |
+
? targetY
|
261 |
+
: Math.min(currentY + SCROLL_Y_DELTA, targetY);
|
262 |
+
transcriptState.textBlocksProps[id].currentY = y;
|
263 |
+
|
264 |
+
textBlockOuterContainer.position.set(-OFFSET_WIDTH + xPosition, y, Z_COORD);
|
265 |
+
textBlockInnerContainer.set({
|
266 |
+
padding: 0,
|
267 |
+
backgroundOpacity: 0,
|
268 |
+
width,
|
269 |
+
height,
|
270 |
+
});
|
271 |
+
text.set({content});
|
272 |
+
}
|
273 |
+
|
274 |
+
// We split the text so it fits line by line into the UI
|
275 |
+
function chunkTranslationTextIntoLines(
|
276 |
+
translationText: string,
|
277 |
+
nextTranslationStringIndex: number,
|
278 |
+
): string[] {
|
279 |
+
// Ideally we continue where we left off but this is complicated when we have mid-words. Recalculating for now
|
280 |
+
const newSentences = translationText
|
281 |
+
.substring(0, nextTranslationStringIndex)
|
282 |
+
.split('\n');
|
283 |
+
const transcriptLines = [''];
|
284 |
+
newSentences.forEach((newSentence, sentenceIdx) => {
|
285 |
+
const words = newSentence.split(/\s+/);
|
286 |
+
words.forEach((word) => {
|
287 |
+
const filteredWord = [...word]
|
288 |
+
.filter((c) => {
|
289 |
+
if (supportedCharSet().has(c)) {
|
290 |
+
return true;
|
291 |
+
}
|
292 |
+
console.error(
|
293 |
+
`Unsupported char ${c} - make sure this is supported in the font family msdf file`,
|
294 |
+
);
|
295 |
+
return false;
|
296 |
+
})
|
297 |
+
.join('')
|
298 |
+
// Filter out unknown symbol
|
299 |
+
.replace('<unk>', '');
|
300 |
+
|
301 |
+
const lastLineSoFar = transcriptLines[0];
|
302 |
+
const charCount = lastLineSoFar.length + filteredWord.length + 1;
|
303 |
+
|
304 |
+
if (charCount <= CHARS_PER_LINE) {
|
305 |
+
transcriptLines[0] = lastLineSoFar + ' ' + filteredWord;
|
306 |
+
} else {
|
307 |
+
transcriptLines.unshift(filteredWord);
|
308 |
+
}
|
309 |
+
});
|
310 |
+
|
311 |
+
if (sentenceIdx < newSentences.length - 1) {
|
312 |
+
transcriptLines.unshift('\n');
|
313 |
+
transcriptLines.unshift('');
|
314 |
+
}
|
315 |
+
});
|
316 |
+
return transcriptLines;
|
317 |
+
}
|
318 |
+
|
319 |
+
// The main loop,
|
320 |
+
function updateTextBlocksProps(): void {
|
321 |
+
const {translationText, lastTranslationStringIndex, lastUpdateTime} =
|
322 |
+
transcriptState;
|
323 |
+
|
324 |
+
const currentTime = new Date().getTime();
|
325 |
+
const charsToRender = Math.round(
|
326 |
+
((currentTime - lastUpdateTime) * CHARS_PER_SECOND) / 1000,
|
327 |
+
);
|
328 |
+
|
329 |
+
if (charsToRender < 1) {
|
330 |
+
// Wait some more until we render more characters
|
331 |
+
return;
|
332 |
+
}
|
333 |
+
|
334 |
+
const nextTranslationStringIndex = Math.min(
|
335 |
+
lastTranslationStringIndex + charsToRender,
|
336 |
+
translationText.length,
|
337 |
+
);
|
338 |
+
if (nextTranslationStringIndex === lastTranslationStringIndex) {
|
339 |
+
// No new characters to render
|
340 |
+
transcriptState.lastUpdateTime = currentTime;
|
341 |
+
return;
|
342 |
+
}
|
343 |
+
|
344 |
+
// Ideally we continue where we left off but this is complicated when we have mid-words. Recalculating for now
|
345 |
+
const transcriptLines = chunkTranslationTextIntoLines(
|
346 |
+
translationText,
|
347 |
+
nextTranslationStringIndex,
|
348 |
+
);
|
349 |
+
transcriptState.transcriptLines = transcriptLines;
|
350 |
+
transcriptState.lastTranslationStringIndex = nextTranslationStringIndex;
|
351 |
+
|
352 |
+
// Compute the new props for each text block
|
353 |
+
const newTextBlocksProps: TextBlockProps[] = [];
|
354 |
+
// We start with the most recent line and increment the y coordinate for older lines.
|
355 |
+
// If it is a new sentence we increment the y coordinate a little more to leave a visible space
|
356 |
+
let y = Y_COORD_START;
|
357 |
+
transcriptLines.forEach((line, i) => {
|
358 |
+
if (newTextBlocksProps.length == NUM_LINES) {
|
359 |
+
return;
|
360 |
+
}
|
361 |
+
|
362 |
+
if (line === '\n') {
|
363 |
+
y += BLOCK_SPACING;
|
364 |
+
return;
|
365 |
+
}
|
366 |
+
|
367 |
+
const isBottomLine = newTextBlocksProps.length === 0;
|
368 |
+
|
369 |
+
const textOpacity = 1 - 0.1 * newTextBlocksProps.length;
|
370 |
+
|
371 |
+
const previousProps = transcriptState.textBlocksProps.find(
|
372 |
+
(props) => props.index === i,
|
373 |
+
);
|
374 |
+
const props = {
|
375 |
+
targetY: y + LINE_HEIGHT / 2,
|
376 |
+
currentY: isBottomLine ? y : previousProps?.currentY || y,
|
377 |
+
index: i,
|
378 |
+
textOpacity,
|
379 |
+
backgroundOpacity: 1,
|
380 |
+
content: line,
|
381 |
+
isBottomLine,
|
382 |
+
};
|
383 |
+
newTextBlocksProps.push(props);
|
384 |
+
|
385 |
+
y += LINE_HEIGHT;
|
386 |
+
});
|
387 |
+
|
388 |
+
transcriptState.textBlocksProps = newTextBlocksProps;
|
389 |
+
transcriptState.lastUpdateTime = currentTime;
|
390 |
+
}
|
391 |
+
|
392 |
+
// The main render loop, everything gets rendered here.
|
393 |
+
function loop() {
|
394 |
+
updateTextBlocksProps();
|
395 |
+
|
396 |
+
transcriptState.textBlocksProps.map((props, i) => updateTextBlock(i, props));
|
397 |
+
|
398 |
+
ThreeMeshUI.update();
|
399 |
+
|
400 |
+
controls.update();
|
401 |
+
renderer.render(scene, camera);
|
402 |
+
}
|
streaming-react-app/src/react-xr/supportedCharSet.ts
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import robotoFontFamilyJson from '../assets/RobotoMono-Regular-msdf.json?url';
|
2 |
+
|
3 |
+
async function fetchSupportedCharSet(): Promise<Set<string>> {
|
4 |
+
try {
|
5 |
+
const response = await fetch(robotoFontFamilyJson);
|
6 |
+
const fontFamily = await response.json();
|
7 |
+
|
8 |
+
return new Set(fontFamily.info.charset);
|
9 |
+
} catch (e) {
|
10 |
+
console.error('Failed to fetch supported XR charset', e);
|
11 |
+
return new Set();
|
12 |
+
}
|
13 |
+
}
|
14 |
+
|
15 |
+
let charSet = new Set<string>();
|
16 |
+
fetchSupportedCharSet().then((result) => (charSet = result));
|
17 |
+
|
18 |
+
export default function supportedCharSet(): Set<string> {
|
19 |
+
return charSet;
|
20 |
+
}
|
streaming-react-app/src/types/StreamingTypes.ts
CHANGED
@@ -49,10 +49,10 @@ export const SUPPORTED_OUTPUT_MODES: Array<{
|
|
49 |
value: (typeof SUPPORTED_OUTPUT_MODE_VALUES)[number];
|
50 |
label: string;
|
51 |
}> = [
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
];
|
56 |
|
57 |
export const SUPPORTED_INPUT_SOURCE_VALUES = [
|
58 |
'userMedia',
|
@@ -66,9 +66,9 @@ export const SUPPORTED_INPUT_SOURCES: Array<{
|
|
66 |
value: SupportedInputSource;
|
67 |
label: string;
|
68 |
}> = [
|
69 |
-
|
70 |
-
|
71 |
-
];
|
72 |
|
73 |
export type StartStreamEventConfig = {
|
74 |
event: 'config';
|
@@ -100,7 +100,7 @@ export type ServerLockObject = {
|
|
100 |
export type ServerState = ServerStateItem & {
|
101 |
agentsCapabilities: Array<AgentCapabilities>;
|
102 |
statusByRoom: {
|
103 |
-
[key: string]: {activeConnections: number; activeTranscoders: number};
|
104 |
};
|
105 |
totalActiveConnections: number;
|
106 |
totalActiveTranscoders: number;
|
|
|
49 |
value: (typeof SUPPORTED_OUTPUT_MODE_VALUES)[number];
|
50 |
label: string;
|
51 |
}> = [
|
52 |
+
{ value: 's2s&t', label: 'Text & Speech' },
|
53 |
+
{ value: 's2t', label: 'Text' },
|
54 |
+
{ value: 's2s', label: 'Speech' },
|
55 |
+
];
|
56 |
|
57 |
export const SUPPORTED_INPUT_SOURCE_VALUES = [
|
58 |
'userMedia',
|
|
|
66 |
value: SupportedInputSource;
|
67 |
label: string;
|
68 |
}> = [
|
69 |
+
{ value: 'userMedia', label: 'Microphone' },
|
70 |
+
{ value: 'displayMedia', label: 'Browser Tab' },
|
71 |
+
];
|
72 |
|
73 |
export type StartStreamEventConfig = {
|
74 |
event: 'config';
|
|
|
100 |
export type ServerState = ServerStateItem & {
|
101 |
agentsCapabilities: Array<AgentCapabilities>;
|
102 |
statusByRoom: {
|
103 |
+
[key: string]: { activeConnections: number; activeTranscoders: number };
|
104 |
};
|
105 |
totalActiveConnections: number;
|
106 |
totalActiveTranscoders: number;
|
streaming-react-app/src/types/URLParamsTypes.ts
CHANGED
@@ -7,10 +7,10 @@ export type URLParamsObject = {
|
|
7 |
serverURL: string | null;
|
8 |
skipARIntro: boolean;
|
9 |
ARTranscriptionType:
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
};
|
15 |
|
16 |
export type URLParamNames = keyof URLParamsObject;
|
|
|
7 |
serverURL: string | null;
|
8 |
skipARIntro: boolean;
|
9 |
ARTranscriptionType:
|
10 |
+
| 'single_block'
|
11 |
+
| 'lines'
|
12 |
+
| 'lines_with_background'
|
13 |
+
| string;
|
14 |
};
|
15 |
|
16 |
export type URLParamNames = keyof URLParamsObject;
|
streaming-react-app/yarn.lock
CHANGED
@@ -61,7 +61,7 @@
|
|
61 |
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz"
|
62 |
integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==
|
63 |
|
64 |
-
"@babel/core@^7.
|
65 |
version "7.22.10"
|
66 |
resolved "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz"
|
67 |
integrity sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==
|
@@ -298,7 +298,7 @@
|
|
298 |
resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz"
|
299 |
integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
|
300 |
|
301 |
-
"@emotion/react
|
302 |
version "11.11.1"
|
303 |
resolved "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz"
|
304 |
integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==
|
@@ -328,7 +328,7 @@
|
|
328 |
resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz"
|
329 |
integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==
|
330 |
|
331 |
-
"@emotion/styled
|
332 |
version "11.11.0"
|
333 |
resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz"
|
334 |
integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==
|
@@ -360,11 +360,116 @@
|
|
360 |
resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz"
|
361 |
integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==
|
362 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
363 |
"@esbuild/linux-x64@0.18.20":
|
364 |
version "0.18.20"
|
365 |
resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz"
|
366 |
integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==
|
367 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
368 |
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
|
369 |
version "4.4.0"
|
370 |
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
|
@@ -479,7 +584,7 @@
|
|
479 |
dependencies:
|
480 |
"@babel/runtime" "^7.22.6"
|
481 |
|
482 |
-
"@mui/material
|
483 |
version "5.14.5"
|
484 |
resolved "https://registry.npmjs.org/@mui/material/-/material-5.14.5.tgz"
|
485 |
integrity sha512-4qa4GMfuZH0Ai3mttk5ccXP8a3sf7aPlAJwyMrUSz6h9hPri6BPou94zeu3rENhhmKLby9S/W1y+pmficy8JKA==
|
@@ -554,7 +659,7 @@
|
|
554 |
"@nodelib/fs.stat" "2.0.5"
|
555 |
run-parallel "^1.1.9"
|
556 |
|
557 |
-
"@nodelib/fs.stat
|
558 |
version "2.0.5"
|
559 |
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
|
560 |
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
|
@@ -647,7 +752,7 @@
|
|
647 |
utility-types "^3.10.0"
|
648 |
zustand "^3.5.13"
|
649 |
|
650 |
-
"@react-three/fiber@^8.14.1"
|
651 |
version "8.14.1"
|
652 |
resolved "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.14.1.tgz"
|
653 |
integrity sha512-Ky/FiCyJiyaI8bd+vckzgkHgKDSQDOcSSUVFOHCuCO9XOLb7Ebs6lof2hPpFa1HkaeE5ZIbTWIprvN0QqdPF0w==
|
@@ -693,7 +798,7 @@
|
|
693 |
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz"
|
694 |
integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==
|
695 |
|
696 |
-
"@types/node@^20.5.3"
|
697 |
version "20.5.3"
|
698 |
resolved "https://registry.npmjs.org/@types/node/-/node-20.5.3.tgz"
|
699 |
integrity sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA==
|
@@ -748,7 +853,7 @@
|
|
748 |
dependencies:
|
749 |
"@types/react" "*"
|
750 |
|
751 |
-
"@types/react@*", "@types/react@^
|
752 |
version "18.2.20"
|
753 |
resolved "https://registry.npmjs.org/@types/react/-/react-18.2.20.tgz"
|
754 |
integrity sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==
|
@@ -767,21 +872,6 @@
|
|
767 |
resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz"
|
768 |
integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==
|
769 |
|
770 |
-
"@types/stats.js@*":
|
771 |
-
version "0.17.3"
|
772 |
-
resolved "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz"
|
773 |
-
integrity sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==
|
774 |
-
|
775 |
-
"@types/three@>=0.144.0":
|
776 |
-
version "0.158.3"
|
777 |
-
resolved "https://registry.npmjs.org/@types/three/-/three-0.158.3.tgz"
|
778 |
-
integrity sha512-6Qs1rUvLSbkJ4hlIe6/rdwIf61j1x2UKvGJg7s8KjswYsz1C1qDTs6voVXXB8kYaI0hgklgZgbZUupfL1l9xdA==
|
779 |
-
dependencies:
|
780 |
-
"@types/stats.js" "*"
|
781 |
-
"@types/webxr" "*"
|
782 |
-
fflate "~0.6.10"
|
783 |
-
meshoptimizer "~0.18.1"
|
784 |
-
|
785 |
"@types/uuid@^9.0.2":
|
786 |
version "9.0.2"
|
787 |
resolved "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz"
|
@@ -809,7 +899,7 @@
|
|
809 |
semver "^7.5.4"
|
810 |
ts-api-utils "^1.0.1"
|
811 |
|
812 |
-
"@typescript-eslint/parser@^6.0.0"
|
813 |
version "6.4.0"
|
814 |
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.0.tgz"
|
815 |
integrity sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg==
|
@@ -904,7 +994,7 @@ acorn-jsx@^5.3.2:
|
|
904 |
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
|
905 |
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
906 |
|
907 |
-
|
908 |
version "8.10.0"
|
909 |
resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz"
|
910 |
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
|
@@ -942,14 +1032,7 @@ ansi-styles@^3.2.1:
|
|
942 |
dependencies:
|
943 |
color-convert "^1.9.0"
|
944 |
|
945 |
-
ansi-styles@^4.0.0:
|
946 |
-
version "4.3.0"
|
947 |
-
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
|
948 |
-
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
949 |
-
dependencies:
|
950 |
-
color-convert "^2.0.1"
|
951 |
-
|
952 |
-
ansi-styles@^4.1.0:
|
953 |
version "4.3.0"
|
954 |
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
|
955 |
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
@@ -1033,7 +1116,7 @@ braces@^3.0.2:
|
|
1033 |
dependencies:
|
1034 |
fill-range "^7.0.1"
|
1035 |
|
1036 |
-
browserslist@^4.21.9
|
1037 |
version "4.21.10"
|
1038 |
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz"
|
1039 |
integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==
|
@@ -1084,15 +1167,7 @@ chalk@^2.4.2:
|
|
1084 |
escape-string-regexp "^1.0.5"
|
1085 |
supports-color "^5.3.0"
|
1086 |
|
1087 |
-
chalk@^4.0.0:
|
1088 |
-
version "4.1.2"
|
1089 |
-
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
|
1090 |
-
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
1091 |
-
dependencies:
|
1092 |
-
ansi-styles "^4.1.0"
|
1093 |
-
supports-color "^7.1.0"
|
1094 |
-
|
1095 |
-
chalk@^4.1.2:
|
1096 |
version "4.1.2"
|
1097 |
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
|
1098 |
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
@@ -1128,16 +1203,16 @@ color-convert@^2.0.1:
|
|
1128 |
dependencies:
|
1129 |
color-name "~1.1.4"
|
1130 |
|
1131 |
-
color-name@~1.1.4:
|
1132 |
-
version "1.1.4"
|
1133 |
-
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
|
1134 |
-
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
1135 |
-
|
1136 |
color-name@1.1.3:
|
1137 |
version "1.1.3"
|
1138 |
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
|
1139 |
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
|
1140 |
|
|
|
|
|
|
|
|
|
|
|
1141 |
concat-map@0.0.1:
|
1142 |
version "0.0.1"
|
1143 |
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
@@ -1352,7 +1427,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4
|
|
1352 |
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz"
|
1353 |
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
|
1354 |
|
1355 |
-
|
1356 |
version "8.47.0"
|
1357 |
resolved "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz"
|
1358 |
integrity sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==
|
@@ -1471,7 +1546,7 @@ fastq@^1.6.0:
|
|
1471 |
dependencies:
|
1472 |
reusify "^1.0.4"
|
1473 |
|
1474 |
-
fflate@^0.6.9
|
1475 |
version "0.6.10"
|
1476 |
resolved "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz"
|
1477 |
integrity sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==
|
@@ -1528,6 +1603,11 @@ fs.realpath@^1.0.0:
|
|
1528 |
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
|
1529 |
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
|
1530 |
|
|
|
|
|
|
|
|
|
|
|
1531 |
function-bind@^1.1.1:
|
1532 |
version "1.1.1"
|
1533 |
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
|
@@ -1661,7 +1741,7 @@ hoist-non-react-statics@^3.3.1:
|
|
1661 |
dependencies:
|
1662 |
react-is "^16.7.0"
|
1663 |
|
1664 |
-
ieee754
|
1665 |
version "1.1.13"
|
1666 |
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz"
|
1667 |
integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
|
@@ -1692,7 +1772,7 @@ inflight@^1.0.4:
|
|
1692 |
once "^1.3.0"
|
1693 |
wrappy "1"
|
1694 |
|
1695 |
-
inherits@^2.0.3
|
1696 |
version "2.0.4"
|
1697 |
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
|
1698 |
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
@@ -1890,7 +1970,7 @@ lodash.pick@^4.4.0:
|
|
1890 |
resolved "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz"
|
1891 |
integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==
|
1892 |
|
1893 |
-
lodash
|
1894 |
version "4.17.21"
|
1895 |
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
|
1896 |
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
@@ -1931,11 +2011,6 @@ meshline@^3.1.6:
|
|
1931 |
resolved "https://registry.npmjs.org/meshline/-/meshline-3.1.6.tgz"
|
1932 |
integrity sha512-8JZJOdaL5oz3PI/upG8JvP/5FfzYUOhrkJ8np/WKvXzl0/PZ2V9pqTvCIjSKv+w9ccg2xb+yyBhXAwt6ier3ug==
|
1933 |
|
1934 |
-
meshoptimizer@~0.18.1:
|
1935 |
-
version "0.18.1"
|
1936 |
-
resolved "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz"
|
1937 |
-
integrity sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==
|
1938 |
-
|
1939 |
micromatch@^4.0.4:
|
1940 |
version "4.0.5"
|
1941 |
resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz"
|
@@ -2109,16 +2184,16 @@ prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.8.1:
|
|
2109 |
object-assign "^4.1.1"
|
2110 |
react-is "^16.13.1"
|
2111 |
|
2112 |
-
punycode@^2.1.0:
|
2113 |
-
version "2.3.0"
|
2114 |
-
resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz"
|
2115 |
-
integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
|
2116 |
-
|
2117 |
punycode@1.3.2:
|
2118 |
version "1.3.2"
|
2119 |
resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz"
|
2120 |
integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==
|
2121 |
|
|
|
|
|
|
|
|
|
|
|
2122 |
querystring@0.2.0:
|
2123 |
version "0.2.0"
|
2124 |
resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz"
|
@@ -2136,7 +2211,7 @@ react-composer@^5.0.3:
|
|
2136 |
dependencies:
|
2137 |
prop-types "^15.6.0"
|
2138 |
|
2139 |
-
|
2140 |
version "18.2.0"
|
2141 |
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
|
2142 |
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
|
@@ -2149,12 +2224,7 @@ react-google-charts@^4.0.1:
|
|
2149 |
resolved "https://registry.npmjs.org/react-google-charts/-/react-google-charts-4.0.1.tgz"
|
2150 |
integrity sha512-V/hcMcNuBgD5w49BYTUDye+bUKaPmsU5vy/9W/Nj2xEeGn+6/AuH9IvBkbDcNBsY00cV9OeexdmgfI5RFHgsXQ==
|
2151 |
|
2152 |
-
react-is@^16.13.1:
|
2153 |
-
version "16.13.1"
|
2154 |
-
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
2155 |
-
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
2156 |
-
|
2157 |
-
react-is@^16.7.0:
|
2158 |
version "16.13.1"
|
2159 |
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
2160 |
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
@@ -2199,7 +2269,7 @@ react-use-measure@^2.1.1:
|
|
2199 |
dependencies:
|
2200 |
debounce "^1.2.1"
|
2201 |
|
2202 |
-
|
2203 |
version "18.2.0"
|
2204 |
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
2205 |
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
|
@@ -2268,7 +2338,7 @@ rxjs@^7.8.1:
|
|
2268 |
dependencies:
|
2269 |
tslib "^2.1.0"
|
2270 |
|
2271 |
-
sax
|
2272 |
version "1.2.1"
|
2273 |
resolved "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz"
|
2274 |
integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==
|
@@ -2457,7 +2527,7 @@ three-stdlib@^2.21.1, three-stdlib@^2.25.1:
|
|
2457 |
potpack "^1.0.1"
|
2458 |
zstddec "^0.0.2"
|
2459 |
|
2460 |
-
three@^0.156.1
|
2461 |
version "0.156.1"
|
2462 |
resolved "https://registry.npmjs.org/three/-/three-0.156.1.tgz"
|
2463 |
integrity sha512-kP7H0FK9d/k6t/XvQ9FO6i+QrePoDcNhwl0I02+wmUJRNSLCUIDMcfObnzQvxb37/0Uc9TDT0T1HgsRRrO6SYQ==
|
@@ -2519,17 +2589,7 @@ tslib@^1.11.1:
|
|
2519 |
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
|
2520 |
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
2521 |
|
2522 |
-
tslib@^2.1.0:
|
2523 |
-
version "2.6.2"
|
2524 |
-
resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz"
|
2525 |
-
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
2526 |
-
|
2527 |
-
tslib@^2.3.1:
|
2528 |
-
version "2.6.2"
|
2529 |
-
resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz"
|
2530 |
-
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
2531 |
-
|
2532 |
-
tslib@^2.5.0:
|
2533 |
version "2.6.2"
|
2534 |
resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz"
|
2535 |
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
@@ -2546,7 +2606,7 @@ type-fest@^0.20.2:
|
|
2546 |
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz"
|
2547 |
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
|
2548 |
|
2549 |
-
typescript
|
2550 |
version "5.1.6"
|
2551 |
resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz"
|
2552 |
integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
|
@@ -2600,17 +2660,17 @@ utility-types@^3.10.0:
|
|
2600 |
resolved "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz"
|
2601 |
integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==
|
2602 |
|
2603 |
-
uuid@^9.0.0:
|
2604 |
-
version "9.0.0"
|
2605 |
-
resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz"
|
2606 |
-
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
|
2607 |
-
|
2608 |
uuid@8.0.0:
|
2609 |
version "8.0.0"
|
2610 |
resolved "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz"
|
2611 |
integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==
|
2612 |
|
2613 |
-
|
|
|
|
|
|
|
|
|
|
|
2614 |
version "4.4.9"
|
2615 |
resolved "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz"
|
2616 |
integrity sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==
|
@@ -2747,12 +2807,7 @@ zstddec@^0.0.2:
|
|
2747 |
resolved "https://registry.npmjs.org/zstddec/-/zstddec-0.0.2.tgz"
|
2748 |
integrity sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA==
|
2749 |
|
2750 |
-
zustand@^3.5.13:
|
2751 |
-
version "3.7.2"
|
2752 |
-
resolved "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz"
|
2753 |
-
integrity sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==
|
2754 |
-
|
2755 |
-
zustand@^3.7.1:
|
2756 |
version "3.7.2"
|
2757 |
resolved "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz"
|
2758 |
integrity sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==
|
|
|
61 |
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz"
|
62 |
integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==
|
63 |
|
64 |
+
"@babel/core@^7.22.9":
|
65 |
version "7.22.10"
|
66 |
resolved "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz"
|
67 |
integrity sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==
|
|
|
298 |
resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz"
|
299 |
integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
|
300 |
|
301 |
+
"@emotion/react@11.11.1":
|
302 |
version "11.11.1"
|
303 |
resolved "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz"
|
304 |
integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==
|
|
|
328 |
resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz"
|
329 |
integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==
|
330 |
|
331 |
+
"@emotion/styled@11.11.0":
|
332 |
version "11.11.0"
|
333 |
resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz"
|
334 |
integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==
|
|
|
360 |
resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz"
|
361 |
integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==
|
362 |
|
363 |
+
"@esbuild/android-arm64@0.18.20":
|
364 |
+
version "0.18.20"
|
365 |
+
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz#984b4f9c8d0377443cc2dfcef266d02244593622"
|
366 |
+
integrity sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==
|
367 |
+
|
368 |
+
"@esbuild/android-arm@0.18.20":
|
369 |
+
version "0.18.20"
|
370 |
+
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.20.tgz#fedb265bc3a589c84cc11f810804f234947c3682"
|
371 |
+
integrity sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==
|
372 |
+
|
373 |
+
"@esbuild/android-x64@0.18.20":
|
374 |
+
version "0.18.20"
|
375 |
+
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.20.tgz#35cf419c4cfc8babe8893d296cd990e9e9f756f2"
|
376 |
+
integrity sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==
|
377 |
+
|
378 |
+
"@esbuild/darwin-arm64@0.18.20":
|
379 |
+
version "0.18.20"
|
380 |
+
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz#08172cbeccf95fbc383399a7f39cfbddaeb0d7c1"
|
381 |
+
integrity sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==
|
382 |
+
|
383 |
+
"@esbuild/darwin-x64@0.18.20":
|
384 |
+
version "0.18.20"
|
385 |
+
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz#d70d5790d8bf475556b67d0f8b7c5bdff053d85d"
|
386 |
+
integrity sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==
|
387 |
+
|
388 |
+
"@esbuild/freebsd-arm64@0.18.20":
|
389 |
+
version "0.18.20"
|
390 |
+
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz#98755cd12707f93f210e2494d6a4b51b96977f54"
|
391 |
+
integrity sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==
|
392 |
+
|
393 |
+
"@esbuild/freebsd-x64@0.18.20":
|
394 |
+
version "0.18.20"
|
395 |
+
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz#c1eb2bff03915f87c29cece4c1a7fa1f423b066e"
|
396 |
+
integrity sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==
|
397 |
+
|
398 |
+
"@esbuild/linux-arm64@0.18.20":
|
399 |
+
version "0.18.20"
|
400 |
+
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz#bad4238bd8f4fc25b5a021280c770ab5fc3a02a0"
|
401 |
+
integrity sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==
|
402 |
+
|
403 |
+
"@esbuild/linux-arm@0.18.20":
|
404 |
+
version "0.18.20"
|
405 |
+
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz#3e617c61f33508a27150ee417543c8ab5acc73b0"
|
406 |
+
integrity sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==
|
407 |
+
|
408 |
+
"@esbuild/linux-ia32@0.18.20":
|
409 |
+
version "0.18.20"
|
410 |
+
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz#699391cccba9aee6019b7f9892eb99219f1570a7"
|
411 |
+
integrity sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==
|
412 |
+
|
413 |
+
"@esbuild/linux-loong64@0.18.20":
|
414 |
+
version "0.18.20"
|
415 |
+
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz#e6fccb7aac178dd2ffb9860465ac89d7f23b977d"
|
416 |
+
integrity sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==
|
417 |
+
|
418 |
+
"@esbuild/linux-mips64el@0.18.20":
|
419 |
+
version "0.18.20"
|
420 |
+
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz#eeff3a937de9c2310de30622a957ad1bd9183231"
|
421 |
+
integrity sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==
|
422 |
+
|
423 |
+
"@esbuild/linux-ppc64@0.18.20":
|
424 |
+
version "0.18.20"
|
425 |
+
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz#2f7156bde20b01527993e6881435ad79ba9599fb"
|
426 |
+
integrity sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==
|
427 |
+
|
428 |
+
"@esbuild/linux-riscv64@0.18.20":
|
429 |
+
version "0.18.20"
|
430 |
+
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz#6628389f210123d8b4743045af8caa7d4ddfc7a6"
|
431 |
+
integrity sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==
|
432 |
+
|
433 |
+
"@esbuild/linux-s390x@0.18.20":
|
434 |
+
version "0.18.20"
|
435 |
+
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz#255e81fb289b101026131858ab99fba63dcf0071"
|
436 |
+
integrity sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==
|
437 |
+
|
438 |
"@esbuild/linux-x64@0.18.20":
|
439 |
version "0.18.20"
|
440 |
resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz"
|
441 |
integrity sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==
|
442 |
|
443 |
+
"@esbuild/netbsd-x64@0.18.20":
|
444 |
+
version "0.18.20"
|
445 |
+
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz#30e8cd8a3dded63975e2df2438ca109601ebe0d1"
|
446 |
+
integrity sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==
|
447 |
+
|
448 |
+
"@esbuild/openbsd-x64@0.18.20":
|
449 |
+
version "0.18.20"
|
450 |
+
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz#7812af31b205055874c8082ea9cf9ab0da6217ae"
|
451 |
+
integrity sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==
|
452 |
+
|
453 |
+
"@esbuild/sunos-x64@0.18.20":
|
454 |
+
version "0.18.20"
|
455 |
+
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz#d5c275c3b4e73c9b0ecd38d1ca62c020f887ab9d"
|
456 |
+
integrity sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==
|
457 |
+
|
458 |
+
"@esbuild/win32-arm64@0.18.20":
|
459 |
+
version "0.18.20"
|
460 |
+
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz#73bc7f5a9f8a77805f357fab97f290d0e4820ac9"
|
461 |
+
integrity sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==
|
462 |
+
|
463 |
+
"@esbuild/win32-ia32@0.18.20":
|
464 |
+
version "0.18.20"
|
465 |
+
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz#ec93cbf0ef1085cc12e71e0d661d20569ff42102"
|
466 |
+
integrity sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==
|
467 |
+
|
468 |
+
"@esbuild/win32-x64@0.18.20":
|
469 |
+
version "0.18.20"
|
470 |
+
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz#786c5f41f043b07afb1af37683d7c33668858f6d"
|
471 |
+
integrity sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==
|
472 |
+
|
473 |
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
|
474 |
version "4.4.0"
|
475 |
resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz"
|
|
|
584 |
dependencies:
|
585 |
"@babel/runtime" "^7.22.6"
|
586 |
|
587 |
+
"@mui/material@5.14.5":
|
588 |
version "5.14.5"
|
589 |
resolved "https://registry.npmjs.org/@mui/material/-/material-5.14.5.tgz"
|
590 |
integrity sha512-4qa4GMfuZH0Ai3mttk5ccXP8a3sf7aPlAJwyMrUSz6h9hPri6BPou94zeu3rENhhmKLby9S/W1y+pmficy8JKA==
|
|
|
659 |
"@nodelib/fs.stat" "2.0.5"
|
660 |
run-parallel "^1.1.9"
|
661 |
|
662 |
+
"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
|
663 |
version "2.0.5"
|
664 |
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
|
665 |
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
|
|
|
752 |
utility-types "^3.10.0"
|
753 |
zustand "^3.5.13"
|
754 |
|
755 |
+
"@react-three/fiber@^8.14.1":
|
756 |
version "8.14.1"
|
757 |
resolved "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.14.1.tgz"
|
758 |
integrity sha512-Ky/FiCyJiyaI8bd+vckzgkHgKDSQDOcSSUVFOHCuCO9XOLb7Ebs6lof2hPpFa1HkaeE5ZIbTWIprvN0QqdPF0w==
|
|
|
798 |
resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz"
|
799 |
integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==
|
800 |
|
801 |
+
"@types/node@^20.5.3":
|
802 |
version "20.5.3"
|
803 |
resolved "https://registry.npmjs.org/@types/node/-/node-20.5.3.tgz"
|
804 |
integrity sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA==
|
|
|
853 |
dependencies:
|
854 |
"@types/react" "*"
|
855 |
|
856 |
+
"@types/react@*", "@types/react@^18.2.15":
|
857 |
version "18.2.20"
|
858 |
resolved "https://registry.npmjs.org/@types/react/-/react-18.2.20.tgz"
|
859 |
integrity sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==
|
|
|
872 |
resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz"
|
873 |
integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==
|
874 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
875 |
"@types/uuid@^9.0.2":
|
876 |
version "9.0.2"
|
877 |
resolved "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz"
|
|
|
899 |
semver "^7.5.4"
|
900 |
ts-api-utils "^1.0.1"
|
901 |
|
902 |
+
"@typescript-eslint/parser@^6.0.0":
|
903 |
version "6.4.0"
|
904 |
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.0.tgz"
|
905 |
integrity sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg==
|
|
|
994 |
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
|
995 |
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
996 |
|
997 |
+
acorn@^8.9.0:
|
998 |
version "8.10.0"
|
999 |
resolved "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz"
|
1000 |
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
|
|
|
1032 |
dependencies:
|
1033 |
color-convert "^1.9.0"
|
1034 |
|
1035 |
+
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1036 |
version "4.3.0"
|
1037 |
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
|
1038 |
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
|
|
1116 |
dependencies:
|
1117 |
fill-range "^7.0.1"
|
1118 |
|
1119 |
+
browserslist@^4.21.9:
|
1120 |
version "4.21.10"
|
1121 |
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz"
|
1122 |
integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==
|
|
|
1167 |
escape-string-regexp "^1.0.5"
|
1168 |
supports-color "^5.3.0"
|
1169 |
|
1170 |
+
chalk@^4.0.0, chalk@^4.1.2:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1171 |
version "4.1.2"
|
1172 |
resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz"
|
1173 |
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
|
|
1203 |
dependencies:
|
1204 |
color-name "~1.1.4"
|
1205 |
|
|
|
|
|
|
|
|
|
|
|
1206 |
color-name@1.1.3:
|
1207 |
version "1.1.3"
|
1208 |
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
|
1209 |
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
|
1210 |
|
1211 |
+
color-name@~1.1.4:
|
1212 |
+
version "1.1.4"
|
1213 |
+
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
|
1214 |
+
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
1215 |
+
|
1216 |
concat-map@0.0.1:
|
1217 |
version "0.0.1"
|
1218 |
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
|
|
|
1427 |
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz"
|
1428 |
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
|
1429 |
|
1430 |
+
eslint@^8.45.0:
|
1431 |
version "8.47.0"
|
1432 |
resolved "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz"
|
1433 |
integrity sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==
|
|
|
1546 |
dependencies:
|
1547 |
reusify "^1.0.4"
|
1548 |
|
1549 |
+
fflate@^0.6.9:
|
1550 |
version "0.6.10"
|
1551 |
resolved "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz"
|
1552 |
integrity sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==
|
|
|
1603 |
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
|
1604 |
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
|
1605 |
|
1606 |
+
fsevents@~2.3.2:
|
1607 |
+
version "2.3.3"
|
1608 |
+
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
|
1609 |
+
integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
|
1610 |
+
|
1611 |
function-bind@^1.1.1:
|
1612 |
version "1.1.1"
|
1613 |
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
|
|
|
1741 |
dependencies:
|
1742 |
react-is "^16.7.0"
|
1743 |
|
1744 |
+
ieee754@1.1.13, ieee754@^1.1.4:
|
1745 |
version "1.1.13"
|
1746 |
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz"
|
1747 |
integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
|
|
|
1772 |
once "^1.3.0"
|
1773 |
wrappy "1"
|
1774 |
|
1775 |
+
inherits@2, inherits@^2.0.3:
|
1776 |
version "2.0.4"
|
1777 |
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
|
1778 |
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
|
|
1970 |
resolved "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz"
|
1971 |
integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==
|
1972 |
|
1973 |
+
lodash@4.17.21, lodash@^4.17.21:
|
1974 |
version "4.17.21"
|
1975 |
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
|
1976 |
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
|
|
2011 |
resolved "https://registry.npmjs.org/meshline/-/meshline-3.1.6.tgz"
|
2012 |
integrity sha512-8JZJOdaL5oz3PI/upG8JvP/5FfzYUOhrkJ8np/WKvXzl0/PZ2V9pqTvCIjSKv+w9ccg2xb+yyBhXAwt6ier3ug==
|
2013 |
|
|
|
|
|
|
|
|
|
|
|
2014 |
micromatch@^4.0.4:
|
2015 |
version "4.0.5"
|
2016 |
resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz"
|
|
|
2184 |
object-assign "^4.1.1"
|
2185 |
react-is "^16.13.1"
|
2186 |
|
|
|
|
|
|
|
|
|
|
|
2187 |
punycode@1.3.2:
|
2188 |
version "1.3.2"
|
2189 |
resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz"
|
2190 |
integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==
|
2191 |
|
2192 |
+
punycode@^2.1.0:
|
2193 |
+
version "2.3.0"
|
2194 |
+
resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz"
|
2195 |
+
integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
|
2196 |
+
|
2197 |
querystring@0.2.0:
|
2198 |
version "0.2.0"
|
2199 |
resolved "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz"
|
|
|
2211 |
dependencies:
|
2212 |
prop-types "^15.6.0"
|
2213 |
|
2214 |
+
react-dom@^18.2.0:
|
2215 |
version "18.2.0"
|
2216 |
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
|
2217 |
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
|
|
|
2224 |
resolved "https://registry.npmjs.org/react-google-charts/-/react-google-charts-4.0.1.tgz"
|
2225 |
integrity sha512-V/hcMcNuBgD5w49BYTUDye+bUKaPmsU5vy/9W/Nj2xEeGn+6/AuH9IvBkbDcNBsY00cV9OeexdmgfI5RFHgsXQ==
|
2226 |
|
2227 |
+
react-is@^16.13.1, react-is@^16.7.0:
|
|
|
|
|
|
|
|
|
|
|
2228 |
version "16.13.1"
|
2229 |
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
|
2230 |
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
|
|
2269 |
dependencies:
|
2270 |
debounce "^1.2.1"
|
2271 |
|
2272 |
+
react@^18.2.0:
|
2273 |
version "18.2.0"
|
2274 |
resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz"
|
2275 |
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
|
|
|
2338 |
dependencies:
|
2339 |
tslib "^2.1.0"
|
2340 |
|
2341 |
+
sax@1.2.1, sax@>=0.6.0:
|
2342 |
version "1.2.1"
|
2343 |
resolved "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz"
|
2344 |
integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==
|
|
|
2527 |
potpack "^1.0.1"
|
2528 |
zstddec "^0.0.2"
|
2529 |
|
2530 |
+
three@^0.156.1:
|
2531 |
version "0.156.1"
|
2532 |
resolved "https://registry.npmjs.org/three/-/three-0.156.1.tgz"
|
2533 |
integrity sha512-kP7H0FK9d/k6t/XvQ9FO6i+QrePoDcNhwl0I02+wmUJRNSLCUIDMcfObnzQvxb37/0Uc9TDT0T1HgsRRrO6SYQ==
|
|
|
2589 |
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
|
2590 |
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
2591 |
|
2592 |
+
tslib@^2.1.0, tslib@^2.3.1, tslib@^2.5.0:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2593 |
version "2.6.2"
|
2594 |
resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz"
|
2595 |
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
|
|
|
2606 |
resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz"
|
2607 |
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
|
2608 |
|
2609 |
+
typescript@5.1.6:
|
2610 |
version "5.1.6"
|
2611 |
resolved "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz"
|
2612 |
integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
|
|
|
2660 |
resolved "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz"
|
2661 |
integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==
|
2662 |
|
|
|
|
|
|
|
|
|
|
|
2663 |
uuid@8.0.0:
|
2664 |
version "8.0.0"
|
2665 |
resolved "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz"
|
2666 |
integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==
|
2667 |
|
2668 |
+
uuid@^9.0.0:
|
2669 |
+
version "9.0.0"
|
2670 |
+
resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz"
|
2671 |
+
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
|
2672 |
+
|
2673 |
+
vite@^4.4.5:
|
2674 |
version "4.4.9"
|
2675 |
resolved "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz"
|
2676 |
integrity sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==
|
|
|
2807 |
resolved "https://registry.npmjs.org/zstddec/-/zstddec-0.0.2.tgz"
|
2808 |
integrity sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA==
|
2809 |
|
2810 |
+
zustand@^3.5.13, zustand@^3.7.1:
|
|
|
|
|
|
|
|
|
|
|
2811 |
version "3.7.2"
|
2812 |
resolved "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz"
|
2813 |
integrity sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==
|