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/[email protected]":
|
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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/[email protected]":
|
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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 | |
| 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==
|