matt HOFFNER commited on
Commit
88cc829
β€’
1 Parent(s): d83366a

add voice chat

Browse files
app/constants.ts ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+
3
+ export default {
4
+ SAMPLING_RATE: 16000,
5
+ DEFAULT_MODEL: "Xenova/whisper-tiny",
6
+ DEFAULT_SUBTASK: "transcribe",
7
+ DEFAULT_LANGUAGE: "english",
8
+ DEFAULT_QUANTIZED: false,
9
+ DEFAULT_MULTILINGUAL: false,
10
+ };
app/hooks/useAudioManager.ts ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+
3
+ import { useState, useCallback } from 'react';
4
+ import constants from '../constants';
5
+
6
+ const useAudioManager = () => {
7
+ const [progress, setProgress] = useState<number | undefined>(undefined);
8
+ const [audioData, setAudioData] = useState<{
9
+ buffer: AudioBuffer;
10
+ url: string;
11
+ source: any;
12
+ mimeType: string;
13
+ } | undefined>(undefined);
14
+
15
+ // Reset the audio data
16
+ const resetAudio = useCallback(() => {
17
+ setAudioData(undefined);
18
+ }, []);
19
+
20
+ // Set audio from a Blob (e.g., from recording)
21
+ const setAudioFromRecording = useCallback(async (data: Blob) => {
22
+ resetAudio();
23
+ setProgress(0);
24
+ const blobUrl = URL.createObjectURL(data);
25
+ const audioCTX = new AudioContext({sampleRate: constants.SAMPLING_RATE, });
26
+ const arrayBuffer = await data.arrayBuffer();
27
+ const decoded = await audioCTX.decodeAudioData(arrayBuffer);
28
+ setProgress(undefined);
29
+ setAudioData({
30
+ buffer: decoded,
31
+ url: blobUrl,
32
+ source: "RECORDING",
33
+ mimeType: data.type,
34
+ });
35
+ }, [resetAudio]);
36
+
37
+ // Other functionalities (e.g., setAudioFromDownload, downloadAudioFromUrl)
38
+ // can be added similarly based on your requirements
39
+
40
+ return {
41
+ audioData,
42
+ progress,
43
+ setAudioFromRecording,
44
+ // Export other functions as needed
45
+ };
46
+ };
47
+
48
+ export default useAudioManager;
app/hooks/useSpeechRecognition.ts ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+
3
+ import { useState, useEffect, useCallback } from "react";
4
+ import { useTranscriber } from "./useTranscriber";
5
+
6
+ const useSpeechRecognition = () => {
7
+ const [recognizedText, setRecognizedText] = useState('');
8
+ const transcriber = useTranscriber();
9
+
10
+ const startListening = useCallback((audioData: any) => {
11
+ if (!transcriber.isBusy && !transcriber.isModelLoading) {
12
+ transcriber.start(audioData);
13
+ }
14
+ }, [transcriber]);
15
+
16
+ const stopListening = useCallback(() => {
17
+ console.log("Stopped listening...", recognizedText);
18
+ }, [recognizedText]); // Updated dependency array
19
+
20
+ useEffect(() => {
21
+ if (transcriber.output && !transcriber.isBusy) {
22
+ setRecognizedText(transcriber.output.text);
23
+ }
24
+ }, [transcriber.output, transcriber.isBusy]);
25
+
26
+ return { startListening, stopListening, recognizedText };
27
+ };
28
+
29
+ export default useSpeechRecognition;
app/hooks/useTranscriber.ts ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+
3
+ import { useCallback, useMemo, useState } from "react";
4
+ import { useWorker } from "./useWorker";
5
+ import Constants from "../constants";
6
+
7
+ interface ProgressItem {
8
+ file: string;
9
+ loaded: number;
10
+ progress: number;
11
+ total: number;
12
+ name: string;
13
+ status: string;
14
+ }
15
+
16
+ interface TranscriberUpdateData {
17
+ data: [
18
+ string,
19
+ { chunks: { text: string; timestamp: [number, number | null] }[] },
20
+ ];
21
+ text: string;
22
+ }
23
+
24
+ interface TranscriberCompleteData {
25
+ data: {
26
+ text: string;
27
+ chunks: { text: string; timestamp: [number, number | null] }[];
28
+ };
29
+ }
30
+
31
+ export interface TranscriberData {
32
+ isBusy: boolean;
33
+ text: string;
34
+ chunks: { text: string; timestamp: [number, number | null] }[];
35
+ }
36
+
37
+ export interface Transcriber {
38
+ onInputChange: () => void;
39
+ isBusy: boolean;
40
+ isModelLoading: boolean;
41
+ progressItems: ProgressItem[];
42
+ start: (audioData: AudioBuffer | undefined) => void;
43
+ output?: TranscriberData;
44
+ model: string;
45
+ setModel: (model: string) => void;
46
+ multilingual: boolean;
47
+ setMultilingual: (model: boolean) => void;
48
+ quantized: boolean;
49
+ setQuantized: (model: boolean) => void;
50
+ subtask: string;
51
+ setSubtask: (subtask: string) => void;
52
+ language?: string;
53
+ setLanguage: (language: string) => void;
54
+ }
55
+
56
+ export function useTranscriber(): Transcriber {
57
+ const [transcript, setTranscript] = useState<TranscriberData | undefined>(
58
+ undefined,
59
+ );
60
+ const [isBusy, setIsBusy] = useState(false);
61
+ const [isModelLoading, setIsModelLoading] = useState(false);
62
+
63
+ const [progressItems, setProgressItems] = useState<ProgressItem[]>([]);
64
+
65
+ const webWorker = useWorker((event) => {
66
+ const message = event.data;
67
+ // Update the state with the result
68
+ switch (message.status) {
69
+ case "progress":
70
+ // Model file progress: update one of the progress items.
71
+ setProgressItems((prev) =>
72
+ prev.map((item) => {
73
+ if (item.file === message.file) {
74
+ return { ...item, progress: message.progress };
75
+ }
76
+ return item;
77
+ }),
78
+ );
79
+ break;
80
+ case "update":
81
+ // Received partial update
82
+ // console.log("update", message);
83
+ // eslint-disable-next-line no-case-declarations
84
+ const updateMessage = message as TranscriberUpdateData;
85
+ setTranscript({
86
+ isBusy: true,
87
+ text: updateMessage.data[0],
88
+ chunks: updateMessage.data[1].chunks,
89
+ });
90
+ break;
91
+ case "complete":
92
+ // Received complete transcript
93
+ // console.log("complete", message);
94
+ // eslint-disable-next-line no-case-declarations
95
+ const completeMessage = message as TranscriberCompleteData;
96
+ setTranscript({
97
+ isBusy: false,
98
+ text: completeMessage.data.text,
99
+ chunks: completeMessage.data.chunks,
100
+ });
101
+ setIsBusy(false);
102
+ break;
103
+
104
+ case "initiate":
105
+ // Model file start load: add a new progress item to the list.
106
+ setIsModelLoading(true);
107
+ setProgressItems((prev) => [...prev, message]);
108
+ break;
109
+ case "ready":
110
+ setIsModelLoading(false);
111
+ break;
112
+ case "error":
113
+ setIsBusy(false);
114
+ alert(
115
+ `${message.data.message} This is most likely because you are using Safari on an M1/M2 Mac. Please try again from Chrome, Firefox, or Edge.\n\nIf this is not the case, please file a bug report.`,
116
+ );
117
+ break;
118
+ case "done":
119
+ // Model file loaded: remove the progress item from the list.
120
+ setProgressItems((prev) =>
121
+ prev.filter((item) => item.file !== message.file),
122
+ );
123
+ break;
124
+
125
+ default:
126
+ // initiate/download/done
127
+ break;
128
+ }
129
+ });
130
+
131
+ const [model, setModel] = useState<string>(Constants.DEFAULT_MODEL);
132
+ const [subtask, setSubtask] = useState<string>(Constants.DEFAULT_SUBTASK);
133
+ const [quantized, setQuantized] = useState<boolean>(
134
+ Constants.DEFAULT_QUANTIZED,
135
+ );
136
+ const [multilingual, setMultilingual] = useState<boolean>(
137
+ Constants.DEFAULT_MULTILINGUAL,
138
+ );
139
+ const [language, setLanguage] = useState<string>(
140
+ Constants.DEFAULT_LANGUAGE,
141
+ );
142
+
143
+ const onInputChange = useCallback(() => {
144
+ setTranscript(undefined);
145
+ }, []);
146
+
147
+ const postRequest = useCallback(
148
+ async (audioData: AudioBuffer | undefined) => {
149
+ if (audioData) {
150
+ setTranscript(undefined);
151
+ setIsBusy(true);
152
+
153
+ let audio;
154
+ if (audioData.numberOfChannels === 2) {
155
+ const SCALING_FACTOR = Math.sqrt(2);
156
+
157
+ let left = audioData.getChannelData(0);
158
+ let right = audioData.getChannelData(1);
159
+
160
+ audio = new Float32Array(left.length);
161
+ for (let i = 0; i < audioData.length; ++i) {
162
+ audio[i] = SCALING_FACTOR * (left[i] + right[i]) / 2;
163
+ }
164
+ } else {
165
+ // If the audio is not stereo, we can just use the first channel:
166
+ audio = audioData.getChannelData(0);
167
+ }
168
+
169
+ webWorker.postMessage({
170
+ audio,
171
+ model,
172
+ multilingual,
173
+ quantized,
174
+ subtask: multilingual ? subtask : null,
175
+ language:
176
+ multilingual && language !== "auto" ? language : null,
177
+ });
178
+ }
179
+ },
180
+ [webWorker, model, multilingual, quantized, subtask, language],
181
+ );
182
+
183
+ const transcriber = useMemo(() => {
184
+ return {
185
+ onInputChange,
186
+ isBusy,
187
+ isModelLoading,
188
+ progressItems,
189
+ start: postRequest,
190
+ output: transcript,
191
+ model,
192
+ setModel,
193
+ multilingual,
194
+ setMultilingual,
195
+ quantized,
196
+ setQuantized,
197
+ subtask,
198
+ setSubtask,
199
+ language,
200
+ setLanguage,
201
+ };
202
+ }, [
203
+ onInputChange,
204
+ isBusy,
205
+ isModelLoading,
206
+ progressItems,
207
+ postRequest,
208
+ transcript,
209
+ model,
210
+ multilingual,
211
+ quantized,
212
+ subtask,
213
+ language,
214
+ ]);
215
+
216
+ return transcriber;
217
+ }
app/hooks/useWorker.ts ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+
5
+ export interface MessageEventHandler {
6
+ (event: MessageEvent): void;
7
+ }
8
+
9
+ export function useWorker(messageEventHandler: MessageEventHandler): Worker | any {
10
+ // Create new worker once and never again
11
+ const [worker] = useState(() => createWorker(messageEventHandler));
12
+
13
+ return worker;
14
+ }
15
+
16
+
17
+ function createWorker(messageEventHandler: MessageEventHandler): Worker | null {
18
+ if (typeof window === 'undefined') {
19
+ // We're running in a non-browser environment (like the server side of Next.js)
20
+ return null;
21
+ }
22
+
23
+ const worker = new Worker(new URL("../worker.js", import.meta.url), {
24
+ type: "module",
25
+ });
26
+
27
+ worker.addEventListener("message", messageEventHandler);
28
+ return worker;
29
+ }
app/input.tsx ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+ import MicIcon from '@mui/icons-material/Mic';
3
+ import StopIcon from '@mui/icons-material/Stop';
4
+ import styles from './page.module.css';
5
+
6
+ import useSpeechRecognition from './hooks/useSpeechRecognition';
7
+ import useAudioManager from './hooks/useAudioManager';
8
+
9
+ const getMimeType = (): string | null => {
10
+ const types = ["audio/webm", "audio/mp4", "audio/ogg", "audio/wav", "audio/aac"];
11
+ for (let type of types) {
12
+ if (MediaRecorder.isTypeSupported(type)) {
13
+ return type;
14
+ }
15
+ }
16
+ return null;
17
+ };
18
+
19
+ interface VoiceInputFormProps {
20
+ handleSubmit: any;
21
+ input: string;
22
+ setInput: React.Dispatch<React.SetStateAction<string>>;
23
+ }
24
+
25
+ const VoiceInputForm: React.FC<VoiceInputFormProps> = ({ handleSubmit, input, setInput }) => {
26
+ const [isRecording, setIsRecording] = useState(false);
27
+ const { startListening, stopListening, recognizedText } = useSpeechRecognition();
28
+ const { setAudioFromRecording } = useAudioManager();
29
+
30
+ const mediaRecorderRef = useRef<MediaRecorder | null>(null);
31
+ const audioChunksRef = useRef<BlobPart[]>([]);
32
+
33
+ useEffect(() => {
34
+ if (recognizedText) {
35
+ setInput(recognizedText);
36
+ }
37
+ }, [recognizedText, setInput]);
38
+
39
+ const startRecording = async () => {
40
+ try {
41
+ const mimeType = getMimeType();
42
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
43
+ mediaRecorderRef.current = new MediaRecorder(stream, { mimeType: mimeType ?? undefined });
44
+ audioChunksRef.current = [];
45
+
46
+ mediaRecorderRef.current.ondataavailable = (event: BlobEvent) => {
47
+ audioChunksRef.current.push(event.data);
48
+ };
49
+
50
+ mediaRecorderRef.current.start();
51
+ } catch (err) {
52
+ console.error("Error accessing media devices:", err);
53
+ }
54
+ };
55
+
56
+ const stopRecording = async (): Promise<Blob> => {
57
+ return new Promise((resolve, reject) => {
58
+ const recorder = mediaRecorderRef.current;
59
+ if (recorder && recorder.state === "recording") {
60
+ recorder.onstop = () => {
61
+ const audioBlob = new Blob(audioChunksRef.current, { 'type': recorder.mimeType });
62
+ audioChunksRef.current = [];
63
+ resolve(audioBlob);
64
+ };
65
+ recorder.stop();
66
+ } else {
67
+ reject(new Error("MediaRecorder is not recording"));
68
+ }
69
+ });
70
+ };
71
+
72
+ const handleRecording = async () => {
73
+ if (isRecording) {
74
+ stopListening();
75
+ const recordedBlob = await stopRecording();
76
+ setAudioFromRecording(recordedBlob);
77
+ const audioBuffer = await convertBlobToAudioBuffer(recordedBlob);
78
+ startListening(audioBuffer);
79
+ } else {
80
+ startRecording();
81
+ }
82
+ setIsRecording(!isRecording);
83
+ };
84
+
85
+ return (
86
+ <div>
87
+ <form onSubmit={handleSubmit} className={styles.form}>
88
+ <input
89
+ type="text"
90
+ value={input}
91
+ className={styles.input}
92
+ onChange={(e) => setInput(e.target.value)}
93
+ placeholder="Speak or type..."
94
+ />
95
+ </form>
96
+ <button onClick={handleRecording} className={styles.button}>
97
+ {isRecording ? <StopIcon /> : <MicIcon />}
98
+ </button>
99
+ </div>
100
+ );
101
+ };
102
+
103
+ const convertBlobToAudioBuffer = async (blob: Blob): Promise<AudioBuffer> => {
104
+ const audioContext = new AudioContext();
105
+ const arrayBuffer = await blob.arrayBuffer();
106
+ return await audioContext.decodeAudioData(arrayBuffer);
107
+ };
108
+
109
+ export default VoiceInputForm;
app/page.tsx CHANGED
@@ -9,6 +9,7 @@ import { Bot, User } from "lucide-react";
9
  import { toast } from 'sonner';
10
  import { FunctionIcon } from './icons';
11
  import { updateBackground } from './util';
 
12
 
13
  const Page: React.FC = () => {
14
  useEffect(() => {
@@ -164,18 +165,7 @@ const Page: React.FC = () => {
164
  })
165
  ) : null}
166
  </div>
167
- <form onSubmit={handleSubmit} className={styles.form}>
168
- <input
169
- type="text"
170
- value={input}
171
- onChange={(e) => setInput(e.target.value)}
172
- placeholder="Chat with Internet"
173
- className={styles.input}
174
- />
175
- <button type="submit" className={styles.button} disabled={isLoading}>
176
- {isLoading ? 'Loading...' : 'Send'}
177
- </button>
178
- </form>
179
  </main>
180
  );
181
  }
 
9
  import { toast } from 'sonner';
10
  import { FunctionIcon } from './icons';
11
  import { updateBackground } from './util';
12
+ import Input from './input';
13
 
14
  const Page: React.FC = () => {
15
  useEffect(() => {
 
165
  })
166
  ) : null}
167
  </div>
168
+ <Input handleSubmit={handleSubmit as any} setInput={setInput} input={input} />
 
 
 
 
 
 
 
 
 
 
 
169
  </main>
170
  );
171
  }
app/worker.js ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client"
2
+
3
+ /* eslint-disable camelcase */
4
+ import { pipeline, env } from "@xenova/transformers";
5
+
6
+ // Disable local models
7
+ env.allowLocalModels = false;
8
+
9
+ // Define model factories
10
+ // Ensures only one model is created of each type
11
+ class PipelineFactory {
12
+ static task = null;
13
+ static model = null;
14
+ static quantized = null;
15
+ static instance = null;
16
+
17
+ constructor(tokenizer, model, quantized) {
18
+ this.tokenizer = tokenizer;
19
+ this.model = model;
20
+ this.quantized = quantized;
21
+ }
22
+
23
+ static async getInstance(progress_callback = null) {
24
+ if (this.instance === null) {
25
+ this.instance = pipeline(this.task, this.model, {
26
+ quantized: this.quantized,
27
+ progress_callback,
28
+
29
+ // For medium models, we need to load the `no_attentions` revision to avoid running out of memory
30
+ revision: this.model.includes("/whisper-medium") ? "no_attentions" : "main"
31
+ });
32
+ }
33
+
34
+ return this.instance;
35
+ }
36
+ }
37
+
38
+ self.addEventListener("message", async (event) => {
39
+ const message = event.data;
40
+
41
+ // Do some work...
42
+ // TODO use message data
43
+ let transcript = await transcribe(
44
+ message.audio,
45
+ message.model,
46
+ message.multilingual,
47
+ message.quantized,
48
+ message.subtask,
49
+ message.language,
50
+ );
51
+ if (transcript === null) return;
52
+
53
+ // Send the result back to the main thread
54
+ self.postMessage({
55
+ status: "complete",
56
+ task: "automatic-speech-recognition",
57
+ data: transcript,
58
+ });
59
+ });
60
+
61
+ class AutomaticSpeechRecognitionPipelineFactory extends PipelineFactory {
62
+ static task = "automatic-speech-recognition";
63
+ static model = null;
64
+ static quantized = null;
65
+ }
66
+
67
+ const transcribe = async (
68
+ audio,
69
+ model,
70
+ multilingual,
71
+ quantized,
72
+ subtask,
73
+ language,
74
+ ) => {
75
+
76
+ const isDistilWhisper = model.startsWith("distil-whisper/");
77
+
78
+ let modelName = model;
79
+ if (!isDistilWhisper && !multilingual) {
80
+ modelName += ".en"
81
+ }
82
+
83
+ const p = AutomaticSpeechRecognitionPipelineFactory;
84
+ if (p.model !== modelName || p.quantized !== quantized) {
85
+ // Invalidate model if different
86
+ p.model = modelName;
87
+ p.quantized = quantized;
88
+
89
+ if (p.instance !== null) {
90
+ (await p.getInstance()).dispose();
91
+ p.instance = null;
92
+ }
93
+ }
94
+
95
+ // Load transcriber model
96
+ let transcriber = await p.getInstance((data) => {
97
+ self.postMessage(data);
98
+ });
99
+
100
+ const time_precision =
101
+ transcriber.processor.feature_extractor.config.chunk_length /
102
+ transcriber.model.config.max_source_positions;
103
+
104
+ // Storage for chunks to be processed. Initialise with an empty chunk.
105
+ let chunks_to_process = [
106
+ {
107
+ tokens: [],
108
+ finalised: false,
109
+ },
110
+ ];
111
+
112
+ // TODO: Storage for fully-processed and merged chunks
113
+ // let decoded_chunks = [];
114
+
115
+ function chunk_callback(chunk) {
116
+ let last = chunks_to_process[chunks_to_process.length - 1];
117
+
118
+ // Overwrite last chunk with new info
119
+ Object.assign(last, chunk);
120
+ last.finalised = true;
121
+
122
+ // Create an empty chunk after, if it not the last chunk
123
+ if (!chunk.is_last) {
124
+ chunks_to_process.push({
125
+ tokens: [],
126
+ finalised: false,
127
+ });
128
+ }
129
+ }
130
+
131
+ // Inject custom callback function to handle merging of chunks
132
+ function callback_function(item) {
133
+ let last = chunks_to_process[chunks_to_process.length - 1];
134
+
135
+ // Update tokens of last chunk
136
+ last.tokens = [...item[0].output_token_ids];
137
+
138
+ // Merge text chunks
139
+ // TODO optimise so we don't have to decode all chunks every time
140
+ let data = transcriber.tokenizer._decode_asr(chunks_to_process, {
141
+ time_precision: time_precision,
142
+ return_timestamps: true,
143
+ force_full_sequences: false,
144
+ });
145
+
146
+ self.postMessage({
147
+ status: "update",
148
+ task: "automatic-speech-recognition",
149
+ data: data,
150
+ });
151
+ }
152
+
153
+ // Actually run transcription
154
+ let output = await transcriber(audio, {
155
+ // Greedy
156
+ top_k: 0,
157
+ do_sample: false,
158
+
159
+ // Sliding window
160
+ chunk_length_s: isDistilWhisper ? 20 : 30,
161
+ stride_length_s: isDistilWhisper ? 3 : 5,
162
+
163
+ // Language and task
164
+ language: language,
165
+ task: subtask,
166
+
167
+ // Return timestamps
168
+ return_timestamps: true,
169
+ force_full_sequences: false,
170
+
171
+ // Callback functions
172
+ callback_function: callback_function, // after each generation step
173
+ chunk_callback: chunk_callback, // after each chunk is processed
174
+ }).catch((error) => {
175
+ self.postMessage({
176
+ status: "error",
177
+ task: "automatic-speech-recognition",
178
+ data: error,
179
+ });
180
+ return null;
181
+ });
182
+
183
+ return output;
184
+ };
next.config.js CHANGED
@@ -1,6 +1,17 @@
1
  /** @type {import('next').NextConfig} */
2
  const nextConfig = {
3
- output: "standalone"
 
 
 
 
 
 
 
 
 
 
 
4
  }
5
 
6
  module.exports = nextConfig
 
1
  /** @type {import('next').NextConfig} */
2
  const nextConfig = {
3
+ output: "standalone",
4
+ // Custom Webpack configuration
5
+ webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
6
+ // Add the node-loader for handling .node files
7
+ config.module.rules.push({
8
+ test: /\.node$/,
9
+ loader: 'node-loader',
10
+ });
11
+
12
+ // Return the modified config
13
+ return config;
14
+ },
15
  }
16
 
17
  module.exports = nextConfig
package-lock.json CHANGED
@@ -10,6 +10,7 @@
10
  "dependencies": {
11
  "@emotion/react": "^11.11.1",
12
  "@emotion/styled": "^11.11.0",
 
13
  "@mui/material": "^5.14.16",
14
  "@upstash/ratelimit": "^0.4.4",
15
  "@vercel/kv": "^0.2.4",
@@ -43,6 +44,7 @@
43
  "@types/react-dom": "^18",
44
  "eslint": "^8",
45
  "eslint-config-next": "14.0.1",
 
46
  "typescript": "^5"
47
  }
48
  },
@@ -323,9 +325,9 @@
323
  }
324
  },
325
  "node_modules/@babel/runtime": {
326
- "version": "7.23.2",
327
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
328
- "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
329
  "dependencies": {
330
  "regenerator-runtime": "^0.14.0"
331
  },
@@ -634,6 +636,17 @@
634
  "node": ">=6.0.0"
635
  }
636
  },
 
 
 
 
 
 
 
 
 
 
 
637
  "node_modules/@jridgewell/sourcemap-codec": {
638
  "version": "1.4.15",
639
  "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
@@ -690,6 +703,31 @@
690
  "url": "https://opencollective.com/mui"
691
  }
692
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
693
  "node_modules/@mui/material": {
694
  "version": "5.14.16",
695
  "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.16.tgz",
@@ -1186,6 +1224,28 @@
1186
  "@types/ms": "*"
1187
  }
1188
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1189
  "node_modules/@types/estree": {
1190
  "version": "1.0.4",
1191
  "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.4.tgz",
@@ -1211,6 +1271,13 @@
1211
  "parse5": "^7.0.0"
1212
  }
1213
  },
 
 
 
 
 
 
 
1214
  "node_modules/@types/json5": {
1215
  "version": "0.0.29",
1216
  "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@@ -1615,6 +1682,167 @@
1615
  "integrity": "sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg==",
1616
  "peer": true
1617
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1618
  "node_modules/@xenova/transformers": {
1619
  "version": "2.7.0",
1620
  "resolved": "https://registry.npmjs.org/@xenova/transformers/-/transformers-2.7.0.tgz",
@@ -1627,6 +1855,20 @@
1627
  "onnxruntime-node": "1.14.0"
1628
  }
1629
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1630
  "node_modules/abab": {
1631
  "version": "2.0.6",
1632
  "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -1654,6 +1896,16 @@
1654
  "node": ">=0.4.0"
1655
  }
1656
  },
 
 
 
 
 
 
 
 
 
 
1657
  "node_modules/acorn-jsx": {
1658
  "version": "5.3.2",
1659
  "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
@@ -1738,6 +1990,16 @@
1738
  "url": "https://github.com/sponsors/epoberezkin"
1739
  }
1740
  },
 
 
 
 
 
 
 
 
 
 
1741
  "node_modules/ansi-regex": {
1742
  "version": "5.0.1",
1743
  "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -2041,6 +2303,15 @@
2041
  }
2042
  ]
2043
  },
 
 
 
 
 
 
 
 
 
2044
  "node_modules/binary-extensions": {
2045
  "version": "2.2.0",
2046
  "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -2091,6 +2362,39 @@
2091
  "node": ">=8"
2092
  }
2093
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2094
  "node_modules/buffer": {
2095
  "version": "5.7.1",
2096
  "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
@@ -2122,6 +2426,13 @@
2122
  "node": "*"
2123
  }
2124
  },
 
 
 
 
 
 
 
2125
  "node_modules/busboy": {
2126
  "version": "1.6.0",
2127
  "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -2259,6 +2570,16 @@
2259
  "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
2260
  "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
2261
  },
 
 
 
 
 
 
 
 
 
 
2262
  "node_modules/chromium-bidi": {
2263
  "version": "0.4.7",
2264
  "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.7.tgz",
@@ -2802,12 +3123,28 @@
2802
  "url": "https://github.com/fb55/domutils?sponsor=1"
2803
  }
2804
  },
 
 
 
 
 
 
 
2805
  "node_modules/emoji-regex": {
2806
  "version": "9.2.2",
2807
  "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
2808
  "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
2809
  "dev": true
2810
  },
 
 
 
 
 
 
 
 
 
2811
  "node_modules/end-of-stream": {
2812
  "version": "1.4.4",
2813
  "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -2923,6 +3260,13 @@
2923
  "safe-array-concat": "^1.0.1"
2924
  }
2925
  },
 
 
 
 
 
 
 
2926
  "node_modules/es-set-tostringtag": {
2927
  "version": "2.0.2",
2928
  "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz",
@@ -3426,6 +3770,16 @@
3426
  "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
3427
  "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
3428
  },
 
 
 
 
 
 
 
 
 
 
3429
  "node_modules/eventsource-parser": {
3430
  "version": "1.0.0",
3431
  "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-1.0.0.tgz",
@@ -4626,6 +4980,37 @@
4626
  "set-function-name": "^2.0.1"
4627
  }
4628
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4629
  "node_modules/js-tiktoken": {
4630
  "version": "1.0.7",
4631
  "resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.7.tgz",
@@ -5313,6 +5698,42 @@
5313
  "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
5314
  "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
5315
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5316
  "node_modules/locate-character": {
5317
  "version": "3.0.0",
5318
  "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
@@ -5457,6 +5878,13 @@
5457
  "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
5458
  "peer": true
5459
  },
 
 
 
 
 
 
 
5460
  "node_modules/merge2": {
5461
  "version": "1.4.1",
5462
  "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -6052,6 +6480,13 @@
6052
  "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
6053
  "dev": true
6054
  },
 
 
 
 
 
 
 
6055
  "node_modules/next": {
6056
  "version": "14.0.1",
6057
  "resolved": "https://registry.npmjs.org/next/-/next-14.0.1.tgz",
@@ -6153,6 +6588,32 @@
6153
  "url": "https://opencollective.com/node-fetch"
6154
  }
6155
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6156
  "node_modules/nth-check": {
6157
  "version": "2.1.1",
6158
  "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
@@ -6865,6 +7326,16 @@
6865
  "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
6866
  "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
6867
  },
 
 
 
 
 
 
 
 
 
 
6868
  "node_modules/rc": {
6869
  "version": "1.2.8",
6870
  "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@@ -7224,6 +7695,25 @@
7224
  "loose-envify": "^1.1.0"
7225
  }
7226
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7227
  "node_modules/semver": {
7228
  "version": "7.5.4",
7229
  "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
@@ -7238,6 +7728,16 @@
7238
  "node": ">=10"
7239
  }
7240
  },
 
 
 
 
 
 
 
 
 
 
7241
  "node_modules/seroval": {
7242
  "version": "0.12.3",
7243
  "resolved": "https://registry.npmjs.org/seroval/-/seroval-0.12.3.tgz",
@@ -7470,6 +7970,27 @@
7470
  "node": ">=0.10.0"
7471
  }
7472
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7473
  "node_modules/space-separated-tokens": {
7474
  "version": "2.0.2",
7475
  "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
@@ -7787,6 +8308,67 @@
7787
  "node": ">=6"
7788
  }
7789
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7790
  "node_modules/text-table": {
7791
  "version": "0.2.0",
7792
  "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -8167,6 +8749,37 @@
8167
  "node": ">= 4.0.0"
8168
  }
8169
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8170
  "node_modules/uri-js": {
8171
  "version": "4.4.1",
8172
  "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -8297,6 +8910,88 @@
8297
  "node": ">=12"
8298
  }
8299
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8300
  "node_modules/whatwg-encoding": {
8301
  "version": "2.0.0",
8302
  "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
 
10
  "dependencies": {
11
  "@emotion/react": "^11.11.1",
12
  "@emotion/styled": "^11.11.0",
13
+ "@mui/icons-material": "^5.14.19",
14
  "@mui/material": "^5.14.16",
15
  "@upstash/ratelimit": "^0.4.4",
16
  "@vercel/kv": "^0.2.4",
 
44
  "@types/react-dom": "^18",
45
  "eslint": "^8",
46
  "eslint-config-next": "14.0.1",
47
+ "node-loader": "^2.0.0",
48
  "typescript": "^5"
49
  }
50
  },
 
325
  }
326
  },
327
  "node_modules/@babel/runtime": {
328
+ "version": "7.23.5",
329
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.5.tgz",
330
+ "integrity": "sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==",
331
  "dependencies": {
332
  "regenerator-runtime": "^0.14.0"
333
  },
 
636
  "node": ">=6.0.0"
637
  }
638
  },
639
+ "node_modules/@jridgewell/source-map": {
640
+ "version": "0.3.5",
641
+ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz",
642
+ "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==",
643
+ "dev": true,
644
+ "peer": true,
645
+ "dependencies": {
646
+ "@jridgewell/gen-mapping": "^0.3.0",
647
+ "@jridgewell/trace-mapping": "^0.3.9"
648
+ }
649
+ },
650
  "node_modules/@jridgewell/sourcemap-codec": {
651
  "version": "1.4.15",
652
  "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
 
703
  "url": "https://opencollective.com/mui"
704
  }
705
  },
706
+ "node_modules/@mui/icons-material": {
707
+ "version": "5.14.19",
708
+ "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.19.tgz",
709
+ "integrity": "sha512-yjP8nluXxZGe3Y7pS+yxBV+hWZSsSBampCxkZwaw+1l+feL+rfP74vbEFbMrX/Kil9I/Y1tWfy5bs/eNvwNpWw==",
710
+ "dependencies": {
711
+ "@babel/runtime": "^7.23.4"
712
+ },
713
+ "engines": {
714
+ "node": ">=12.0.0"
715
+ },
716
+ "funding": {
717
+ "type": "opencollective",
718
+ "url": "https://opencollective.com/mui-org"
719
+ },
720
+ "peerDependencies": {
721
+ "@mui/material": "^5.0.0",
722
+ "@types/react": "^17.0.0 || ^18.0.0",
723
+ "react": "^17.0.0 || ^18.0.0"
724
+ },
725
+ "peerDependenciesMeta": {
726
+ "@types/react": {
727
+ "optional": true
728
+ }
729
+ }
730
+ },
731
  "node_modules/@mui/material": {
732
  "version": "5.14.16",
733
  "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.16.tgz",
 
1224
  "@types/ms": "*"
1225
  }
1226
  },
1227
+ "node_modules/@types/eslint": {
1228
+ "version": "8.44.8",
1229
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.8.tgz",
1230
+ "integrity": "sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw==",
1231
+ "dev": true,
1232
+ "peer": true,
1233
+ "dependencies": {
1234
+ "@types/estree": "*",
1235
+ "@types/json-schema": "*"
1236
+ }
1237
+ },
1238
+ "node_modules/@types/eslint-scope": {
1239
+ "version": "3.7.7",
1240
+ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz",
1241
+ "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==",
1242
+ "dev": true,
1243
+ "peer": true,
1244
+ "dependencies": {
1245
+ "@types/eslint": "*",
1246
+ "@types/estree": "*"
1247
+ }
1248
+ },
1249
  "node_modules/@types/estree": {
1250
  "version": "1.0.4",
1251
  "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.4.tgz",
 
1271
  "parse5": "^7.0.0"
1272
  }
1273
  },
1274
+ "node_modules/@types/json-schema": {
1275
+ "version": "7.0.15",
1276
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
1277
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
1278
+ "dev": true,
1279
+ "peer": true
1280
+ },
1281
  "node_modules/@types/json5": {
1282
  "version": "0.0.29",
1283
  "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
 
1682
  "integrity": "sha512-N/tbkINRUDExgcPTBvxNkvHGu504k8lzlNQRITVnm6YjOjwa4r0nnbd4Jb01sNpur5hAllyRJzSK5PvB9PPwRg==",
1683
  "peer": true
1684
  },
1685
+ "node_modules/@webassemblyjs/ast": {
1686
+ "version": "1.11.6",
1687
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
1688
+ "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==",
1689
+ "dev": true,
1690
+ "peer": true,
1691
+ "dependencies": {
1692
+ "@webassemblyjs/helper-numbers": "1.11.6",
1693
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
1694
+ }
1695
+ },
1696
+ "node_modules/@webassemblyjs/floating-point-hex-parser": {
1697
+ "version": "1.11.6",
1698
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
1699
+ "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
1700
+ "dev": true,
1701
+ "peer": true
1702
+ },
1703
+ "node_modules/@webassemblyjs/helper-api-error": {
1704
+ "version": "1.11.6",
1705
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
1706
+ "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
1707
+ "dev": true,
1708
+ "peer": true
1709
+ },
1710
+ "node_modules/@webassemblyjs/helper-buffer": {
1711
+ "version": "1.11.6",
1712
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz",
1713
+ "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==",
1714
+ "dev": true,
1715
+ "peer": true
1716
+ },
1717
+ "node_modules/@webassemblyjs/helper-numbers": {
1718
+ "version": "1.11.6",
1719
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
1720
+ "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
1721
+ "dev": true,
1722
+ "peer": true,
1723
+ "dependencies": {
1724
+ "@webassemblyjs/floating-point-hex-parser": "1.11.6",
1725
+ "@webassemblyjs/helper-api-error": "1.11.6",
1726
+ "@xtuc/long": "4.2.2"
1727
+ }
1728
+ },
1729
+ "node_modules/@webassemblyjs/helper-wasm-bytecode": {
1730
+ "version": "1.11.6",
1731
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
1732
+ "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
1733
+ "dev": true,
1734
+ "peer": true
1735
+ },
1736
+ "node_modules/@webassemblyjs/helper-wasm-section": {
1737
+ "version": "1.11.6",
1738
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz",
1739
+ "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==",
1740
+ "dev": true,
1741
+ "peer": true,
1742
+ "dependencies": {
1743
+ "@webassemblyjs/ast": "1.11.6",
1744
+ "@webassemblyjs/helper-buffer": "1.11.6",
1745
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
1746
+ "@webassemblyjs/wasm-gen": "1.11.6"
1747
+ }
1748
+ },
1749
+ "node_modules/@webassemblyjs/ieee754": {
1750
+ "version": "1.11.6",
1751
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
1752
+ "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
1753
+ "dev": true,
1754
+ "peer": true,
1755
+ "dependencies": {
1756
+ "@xtuc/ieee754": "^1.2.0"
1757
+ }
1758
+ },
1759
+ "node_modules/@webassemblyjs/leb128": {
1760
+ "version": "1.11.6",
1761
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
1762
+ "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
1763
+ "dev": true,
1764
+ "peer": true,
1765
+ "dependencies": {
1766
+ "@xtuc/long": "4.2.2"
1767
+ }
1768
+ },
1769
+ "node_modules/@webassemblyjs/utf8": {
1770
+ "version": "1.11.6",
1771
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
1772
+ "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
1773
+ "dev": true,
1774
+ "peer": true
1775
+ },
1776
+ "node_modules/@webassemblyjs/wasm-edit": {
1777
+ "version": "1.11.6",
1778
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz",
1779
+ "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==",
1780
+ "dev": true,
1781
+ "peer": true,
1782
+ "dependencies": {
1783
+ "@webassemblyjs/ast": "1.11.6",
1784
+ "@webassemblyjs/helper-buffer": "1.11.6",
1785
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
1786
+ "@webassemblyjs/helper-wasm-section": "1.11.6",
1787
+ "@webassemblyjs/wasm-gen": "1.11.6",
1788
+ "@webassemblyjs/wasm-opt": "1.11.6",
1789
+ "@webassemblyjs/wasm-parser": "1.11.6",
1790
+ "@webassemblyjs/wast-printer": "1.11.6"
1791
+ }
1792
+ },
1793
+ "node_modules/@webassemblyjs/wasm-gen": {
1794
+ "version": "1.11.6",
1795
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz",
1796
+ "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==",
1797
+ "dev": true,
1798
+ "peer": true,
1799
+ "dependencies": {
1800
+ "@webassemblyjs/ast": "1.11.6",
1801
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
1802
+ "@webassemblyjs/ieee754": "1.11.6",
1803
+ "@webassemblyjs/leb128": "1.11.6",
1804
+ "@webassemblyjs/utf8": "1.11.6"
1805
+ }
1806
+ },
1807
+ "node_modules/@webassemblyjs/wasm-opt": {
1808
+ "version": "1.11.6",
1809
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz",
1810
+ "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==",
1811
+ "dev": true,
1812
+ "peer": true,
1813
+ "dependencies": {
1814
+ "@webassemblyjs/ast": "1.11.6",
1815
+ "@webassemblyjs/helper-buffer": "1.11.6",
1816
+ "@webassemblyjs/wasm-gen": "1.11.6",
1817
+ "@webassemblyjs/wasm-parser": "1.11.6"
1818
+ }
1819
+ },
1820
+ "node_modules/@webassemblyjs/wasm-parser": {
1821
+ "version": "1.11.6",
1822
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz",
1823
+ "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==",
1824
+ "dev": true,
1825
+ "peer": true,
1826
+ "dependencies": {
1827
+ "@webassemblyjs/ast": "1.11.6",
1828
+ "@webassemblyjs/helper-api-error": "1.11.6",
1829
+ "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
1830
+ "@webassemblyjs/ieee754": "1.11.6",
1831
+ "@webassemblyjs/leb128": "1.11.6",
1832
+ "@webassemblyjs/utf8": "1.11.6"
1833
+ }
1834
+ },
1835
+ "node_modules/@webassemblyjs/wast-printer": {
1836
+ "version": "1.11.6",
1837
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz",
1838
+ "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==",
1839
+ "dev": true,
1840
+ "peer": true,
1841
+ "dependencies": {
1842
+ "@webassemblyjs/ast": "1.11.6",
1843
+ "@xtuc/long": "4.2.2"
1844
+ }
1845
+ },
1846
  "node_modules/@xenova/transformers": {
1847
  "version": "2.7.0",
1848
  "resolved": "https://registry.npmjs.org/@xenova/transformers/-/transformers-2.7.0.tgz",
 
1855
  "onnxruntime-node": "1.14.0"
1856
  }
1857
  },
1858
+ "node_modules/@xtuc/ieee754": {
1859
+ "version": "1.2.0",
1860
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
1861
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
1862
+ "dev": true,
1863
+ "peer": true
1864
+ },
1865
+ "node_modules/@xtuc/long": {
1866
+ "version": "4.2.2",
1867
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
1868
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
1869
+ "dev": true,
1870
+ "peer": true
1871
+ },
1872
  "node_modules/abab": {
1873
  "version": "2.0.6",
1874
  "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
 
1896
  "node": ">=0.4.0"
1897
  }
1898
  },
1899
+ "node_modules/acorn-import-assertions": {
1900
+ "version": "1.9.0",
1901
+ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz",
1902
+ "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==",
1903
+ "dev": true,
1904
+ "peer": true,
1905
+ "peerDependencies": {
1906
+ "acorn": "^8"
1907
+ }
1908
+ },
1909
  "node_modules/acorn-jsx": {
1910
  "version": "5.3.2",
1911
  "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
 
1990
  "url": "https://github.com/sponsors/epoberezkin"
1991
  }
1992
  },
1993
+ "node_modules/ajv-keywords": {
1994
+ "version": "3.5.2",
1995
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
1996
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
1997
+ "dev": true,
1998
+ "peer": true,
1999
+ "peerDependencies": {
2000
+ "ajv": "^6.9.1"
2001
+ }
2002
+ },
2003
  "node_modules/ansi-regex": {
2004
  "version": "5.0.1",
2005
  "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
 
2303
  }
2304
  ]
2305
  },
2306
+ "node_modules/big.js": {
2307
+ "version": "5.2.2",
2308
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
2309
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
2310
+ "dev": true,
2311
+ "engines": {
2312
+ "node": "*"
2313
+ }
2314
+ },
2315
  "node_modules/binary-extensions": {
2316
  "version": "2.2.0",
2317
  "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
 
2362
  "node": ">=8"
2363
  }
2364
  },
2365
+ "node_modules/browserslist": {
2366
+ "version": "4.22.1",
2367
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
2368
+ "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
2369
+ "dev": true,
2370
+ "funding": [
2371
+ {
2372
+ "type": "opencollective",
2373
+ "url": "https://opencollective.com/browserslist"
2374
+ },
2375
+ {
2376
+ "type": "tidelift",
2377
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
2378
+ },
2379
+ {
2380
+ "type": "github",
2381
+ "url": "https://github.com/sponsors/ai"
2382
+ }
2383
+ ],
2384
+ "peer": true,
2385
+ "dependencies": {
2386
+ "caniuse-lite": "^1.0.30001541",
2387
+ "electron-to-chromium": "^1.4.535",
2388
+ "node-releases": "^2.0.13",
2389
+ "update-browserslist-db": "^1.0.13"
2390
+ },
2391
+ "bin": {
2392
+ "browserslist": "cli.js"
2393
+ },
2394
+ "engines": {
2395
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
2396
+ }
2397
+ },
2398
  "node_modules/buffer": {
2399
  "version": "5.7.1",
2400
  "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
 
2426
  "node": "*"
2427
  }
2428
  },
2429
+ "node_modules/buffer-from": {
2430
+ "version": "1.1.2",
2431
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
2432
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
2433
+ "dev": true,
2434
+ "peer": true
2435
+ },
2436
  "node_modules/busboy": {
2437
  "version": "1.6.0",
2438
  "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
 
2570
  "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
2571
  "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
2572
  },
2573
+ "node_modules/chrome-trace-event": {
2574
+ "version": "1.0.3",
2575
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
2576
+ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
2577
+ "dev": true,
2578
+ "peer": true,
2579
+ "engines": {
2580
+ "node": ">=6.0"
2581
+ }
2582
+ },
2583
  "node_modules/chromium-bidi": {
2584
  "version": "0.4.7",
2585
  "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.7.tgz",
 
3123
  "url": "https://github.com/fb55/domutils?sponsor=1"
3124
  }
3125
  },
3126
+ "node_modules/electron-to-chromium": {
3127
+ "version": "1.4.601",
3128
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.601.tgz",
3129
+ "integrity": "sha512-SpwUMDWe9tQu8JX5QCO1+p/hChAi9AE9UpoC3rcHVc+gdCGlbT3SGb5I1klgb952HRIyvt9wZhSz9bNBYz9swA==",
3130
+ "dev": true,
3131
+ "peer": true
3132
+ },
3133
  "node_modules/emoji-regex": {
3134
  "version": "9.2.2",
3135
  "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
3136
  "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
3137
  "dev": true
3138
  },
3139
+ "node_modules/emojis-list": {
3140
+ "version": "3.0.0",
3141
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
3142
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
3143
+ "dev": true,
3144
+ "engines": {
3145
+ "node": ">= 4"
3146
+ }
3147
+ },
3148
  "node_modules/end-of-stream": {
3149
  "version": "1.4.4",
3150
  "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
 
3260
  "safe-array-concat": "^1.0.1"
3261
  }
3262
  },
3263
+ "node_modules/es-module-lexer": {
3264
+ "version": "1.4.1",
3265
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz",
3266
+ "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==",
3267
+ "dev": true,
3268
+ "peer": true
3269
+ },
3270
  "node_modules/es-set-tostringtag": {
3271
  "version": "2.0.2",
3272
  "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz",
 
3770
  "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
3771
  "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw=="
3772
  },
3773
+ "node_modules/events": {
3774
+ "version": "3.3.0",
3775
+ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
3776
+ "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
3777
+ "dev": true,
3778
+ "peer": true,
3779
+ "engines": {
3780
+ "node": ">=0.8.x"
3781
+ }
3782
+ },
3783
  "node_modules/eventsource-parser": {
3784
  "version": "1.0.0",
3785
  "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-1.0.0.tgz",
 
4980
  "set-function-name": "^2.0.1"
4981
  }
4982
  },
4983
+ "node_modules/jest-worker": {
4984
+ "version": "27.5.1",
4985
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
4986
+ "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
4987
+ "dev": true,
4988
+ "peer": true,
4989
+ "dependencies": {
4990
+ "@types/node": "*",
4991
+ "merge-stream": "^2.0.0",
4992
+ "supports-color": "^8.0.0"
4993
+ },
4994
+ "engines": {
4995
+ "node": ">= 10.13.0"
4996
+ }
4997
+ },
4998
+ "node_modules/jest-worker/node_modules/supports-color": {
4999
+ "version": "8.1.1",
5000
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
5001
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
5002
+ "dev": true,
5003
+ "peer": true,
5004
+ "dependencies": {
5005
+ "has-flag": "^4.0.0"
5006
+ },
5007
+ "engines": {
5008
+ "node": ">=10"
5009
+ },
5010
+ "funding": {
5011
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
5012
+ }
5013
+ },
5014
  "node_modules/js-tiktoken": {
5015
  "version": "1.0.7",
5016
  "resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.7.tgz",
 
5698
  "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
5699
  "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
5700
  },
5701
+ "node_modules/loader-runner": {
5702
+ "version": "4.3.0",
5703
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
5704
+ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==",
5705
+ "dev": true,
5706
+ "peer": true,
5707
+ "engines": {
5708
+ "node": ">=6.11.5"
5709
+ }
5710
+ },
5711
+ "node_modules/loader-utils": {
5712
+ "version": "2.0.4",
5713
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
5714
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
5715
+ "dev": true,
5716
+ "dependencies": {
5717
+ "big.js": "^5.2.2",
5718
+ "emojis-list": "^3.0.0",
5719
+ "json5": "^2.1.2"
5720
+ },
5721
+ "engines": {
5722
+ "node": ">=8.9.0"
5723
+ }
5724
+ },
5725
+ "node_modules/loader-utils/node_modules/json5": {
5726
+ "version": "2.2.3",
5727
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
5728
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
5729
+ "dev": true,
5730
+ "bin": {
5731
+ "json5": "lib/cli.js"
5732
+ },
5733
+ "engines": {
5734
+ "node": ">=6"
5735
+ }
5736
+ },
5737
  "node_modules/locate-character": {
5738
  "version": "3.0.0",
5739
  "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
 
5878
  "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
5879
  "peer": true
5880
  },
5881
+ "node_modules/merge-stream": {
5882
+ "version": "2.0.0",
5883
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
5884
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
5885
+ "dev": true,
5886
+ "peer": true
5887
+ },
5888
  "node_modules/merge2": {
5889
  "version": "1.4.1",
5890
  "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
 
6480
  "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
6481
  "dev": true
6482
  },
6483
+ "node_modules/neo-async": {
6484
+ "version": "2.6.2",
6485
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
6486
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
6487
+ "dev": true,
6488
+ "peer": true
6489
+ },
6490
  "node_modules/next": {
6491
  "version": "14.0.1",
6492
  "resolved": "https://registry.npmjs.org/next/-/next-14.0.1.tgz",
 
6588
  "url": "https://opencollective.com/node-fetch"
6589
  }
6590
  },
6591
+ "node_modules/node-loader": {
6592
+ "version": "2.0.0",
6593
+ "resolved": "https://registry.npmjs.org/node-loader/-/node-loader-2.0.0.tgz",
6594
+ "integrity": "sha512-I5VN34NO4/5UYJaUBtkrODPWxbobrE4hgDqPrjB25yPkonFhCmZ146vTH+Zg417E9Iwoh1l/MbRs1apc5J295Q==",
6595
+ "dev": true,
6596
+ "dependencies": {
6597
+ "loader-utils": "^2.0.0"
6598
+ },
6599
+ "engines": {
6600
+ "node": ">= 10.13.0"
6601
+ },
6602
+ "funding": {
6603
+ "type": "opencollective",
6604
+ "url": "https://opencollective.com/webpack"
6605
+ },
6606
+ "peerDependencies": {
6607
+ "webpack": "^5.0.0"
6608
+ }
6609
+ },
6610
+ "node_modules/node-releases": {
6611
+ "version": "2.0.14",
6612
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
6613
+ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
6614
+ "dev": true,
6615
+ "peer": true
6616
+ },
6617
  "node_modules/nth-check": {
6618
  "version": "2.1.1",
6619
  "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
 
7326
  "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
7327
  "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
7328
  },
7329
+ "node_modules/randombytes": {
7330
+ "version": "2.1.0",
7331
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
7332
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
7333
+ "dev": true,
7334
+ "peer": true,
7335
+ "dependencies": {
7336
+ "safe-buffer": "^5.1.0"
7337
+ }
7338
+ },
7339
  "node_modules/rc": {
7340
  "version": "1.2.8",
7341
  "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
 
7695
  "loose-envify": "^1.1.0"
7696
  }
7697
  },
7698
+ "node_modules/schema-utils": {
7699
+ "version": "3.3.0",
7700
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
7701
+ "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
7702
+ "dev": true,
7703
+ "peer": true,
7704
+ "dependencies": {
7705
+ "@types/json-schema": "^7.0.8",
7706
+ "ajv": "^6.12.5",
7707
+ "ajv-keywords": "^3.5.2"
7708
+ },
7709
+ "engines": {
7710
+ "node": ">= 10.13.0"
7711
+ },
7712
+ "funding": {
7713
+ "type": "opencollective",
7714
+ "url": "https://opencollective.com/webpack"
7715
+ }
7716
+ },
7717
  "node_modules/semver": {
7718
  "version": "7.5.4",
7719
  "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
 
7728
  "node": ">=10"
7729
  }
7730
  },
7731
+ "node_modules/serialize-javascript": {
7732
+ "version": "6.0.1",
7733
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz",
7734
+ "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==",
7735
+ "dev": true,
7736
+ "peer": true,
7737
+ "dependencies": {
7738
+ "randombytes": "^2.1.0"
7739
+ }
7740
+ },
7741
  "node_modules/seroval": {
7742
  "version": "0.12.3",
7743
  "resolved": "https://registry.npmjs.org/seroval/-/seroval-0.12.3.tgz",
 
7970
  "node": ">=0.10.0"
7971
  }
7972
  },
7973
+ "node_modules/source-map-support": {
7974
+ "version": "0.5.21",
7975
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
7976
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
7977
+ "dev": true,
7978
+ "peer": true,
7979
+ "dependencies": {
7980
+ "buffer-from": "^1.0.0",
7981
+ "source-map": "^0.6.0"
7982
+ }
7983
+ },
7984
+ "node_modules/source-map-support/node_modules/source-map": {
7985
+ "version": "0.6.1",
7986
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
7987
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
7988
+ "dev": true,
7989
+ "peer": true,
7990
+ "engines": {
7991
+ "node": ">=0.10.0"
7992
+ }
7993
+ },
7994
  "node_modules/space-separated-tokens": {
7995
  "version": "2.0.2",
7996
  "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
 
8308
  "node": ">=6"
8309
  }
8310
  },
8311
+ "node_modules/terser": {
8312
+ "version": "5.24.0",
8313
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.24.0.tgz",
8314
+ "integrity": "sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==",
8315
+ "dev": true,
8316
+ "peer": true,
8317
+ "dependencies": {
8318
+ "@jridgewell/source-map": "^0.3.3",
8319
+ "acorn": "^8.8.2",
8320
+ "commander": "^2.20.0",
8321
+ "source-map-support": "~0.5.20"
8322
+ },
8323
+ "bin": {
8324
+ "terser": "bin/terser"
8325
+ },
8326
+ "engines": {
8327
+ "node": ">=10"
8328
+ }
8329
+ },
8330
+ "node_modules/terser-webpack-plugin": {
8331
+ "version": "5.3.9",
8332
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz",
8333
+ "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==",
8334
+ "dev": true,
8335
+ "peer": true,
8336
+ "dependencies": {
8337
+ "@jridgewell/trace-mapping": "^0.3.17",
8338
+ "jest-worker": "^27.4.5",
8339
+ "schema-utils": "^3.1.1",
8340
+ "serialize-javascript": "^6.0.1",
8341
+ "terser": "^5.16.8"
8342
+ },
8343
+ "engines": {
8344
+ "node": ">= 10.13.0"
8345
+ },
8346
+ "funding": {
8347
+ "type": "opencollective",
8348
+ "url": "https://opencollective.com/webpack"
8349
+ },
8350
+ "peerDependencies": {
8351
+ "webpack": "^5.1.0"
8352
+ },
8353
+ "peerDependenciesMeta": {
8354
+ "@swc/core": {
8355
+ "optional": true
8356
+ },
8357
+ "esbuild": {
8358
+ "optional": true
8359
+ },
8360
+ "uglify-js": {
8361
+ "optional": true
8362
+ }
8363
+ }
8364
+ },
8365
+ "node_modules/terser/node_modules/commander": {
8366
+ "version": "2.20.3",
8367
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
8368
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
8369
+ "dev": true,
8370
+ "peer": true
8371
+ },
8372
  "node_modules/text-table": {
8373
  "version": "0.2.0",
8374
  "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
 
8749
  "node": ">= 4.0.0"
8750
  }
8751
  },
8752
+ "node_modules/update-browserslist-db": {
8753
+ "version": "1.0.13",
8754
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
8755
+ "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
8756
+ "dev": true,
8757
+ "funding": [
8758
+ {
8759
+ "type": "opencollective",
8760
+ "url": "https://opencollective.com/browserslist"
8761
+ },
8762
+ {
8763
+ "type": "tidelift",
8764
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
8765
+ },
8766
+ {
8767
+ "type": "github",
8768
+ "url": "https://github.com/sponsors/ai"
8769
+ }
8770
+ ],
8771
+ "peer": true,
8772
+ "dependencies": {
8773
+ "escalade": "^3.1.1",
8774
+ "picocolors": "^1.0.0"
8775
+ },
8776
+ "bin": {
8777
+ "update-browserslist-db": "cli.js"
8778
+ },
8779
+ "peerDependencies": {
8780
+ "browserslist": ">= 4.21.0"
8781
+ }
8782
+ },
8783
  "node_modules/uri-js": {
8784
  "version": "4.4.1",
8785
  "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
 
8910
  "node": ">=12"
8911
  }
8912
  },
8913
+ "node_modules/webpack": {
8914
+ "version": "5.89.0",
8915
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz",
8916
+ "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==",
8917
+ "dev": true,
8918
+ "peer": true,
8919
+ "dependencies": {
8920
+ "@types/eslint-scope": "^3.7.3",
8921
+ "@types/estree": "^1.0.0",
8922
+ "@webassemblyjs/ast": "^1.11.5",
8923
+ "@webassemblyjs/wasm-edit": "^1.11.5",
8924
+ "@webassemblyjs/wasm-parser": "^1.11.5",
8925
+ "acorn": "^8.7.1",
8926
+ "acorn-import-assertions": "^1.9.0",
8927
+ "browserslist": "^4.14.5",
8928
+ "chrome-trace-event": "^1.0.2",
8929
+ "enhanced-resolve": "^5.15.0",
8930
+ "es-module-lexer": "^1.2.1",
8931
+ "eslint-scope": "5.1.1",
8932
+ "events": "^3.2.0",
8933
+ "glob-to-regexp": "^0.4.1",
8934
+ "graceful-fs": "^4.2.9",
8935
+ "json-parse-even-better-errors": "^2.3.1",
8936
+ "loader-runner": "^4.2.0",
8937
+ "mime-types": "^2.1.27",
8938
+ "neo-async": "^2.6.2",
8939
+ "schema-utils": "^3.2.0",
8940
+ "tapable": "^2.1.1",
8941
+ "terser-webpack-plugin": "^5.3.7",
8942
+ "watchpack": "^2.4.0",
8943
+ "webpack-sources": "^3.2.3"
8944
+ },
8945
+ "bin": {
8946
+ "webpack": "bin/webpack.js"
8947
+ },
8948
+ "engines": {
8949
+ "node": ">=10.13.0"
8950
+ },
8951
+ "funding": {
8952
+ "type": "opencollective",
8953
+ "url": "https://opencollective.com/webpack"
8954
+ },
8955
+ "peerDependenciesMeta": {
8956
+ "webpack-cli": {
8957
+ "optional": true
8958
+ }
8959
+ }
8960
+ },
8961
+ "node_modules/webpack-sources": {
8962
+ "version": "3.2.3",
8963
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
8964
+ "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
8965
+ "dev": true,
8966
+ "peer": true,
8967
+ "engines": {
8968
+ "node": ">=10.13.0"
8969
+ }
8970
+ },
8971
+ "node_modules/webpack/node_modules/eslint-scope": {
8972
+ "version": "5.1.1",
8973
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
8974
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
8975
+ "dev": true,
8976
+ "peer": true,
8977
+ "dependencies": {
8978
+ "esrecurse": "^4.3.0",
8979
+ "estraverse": "^4.1.1"
8980
+ },
8981
+ "engines": {
8982
+ "node": ">=8.0.0"
8983
+ }
8984
+ },
8985
+ "node_modules/webpack/node_modules/estraverse": {
8986
+ "version": "4.3.0",
8987
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
8988
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
8989
+ "dev": true,
8990
+ "peer": true,
8991
+ "engines": {
8992
+ "node": ">=4.0"
8993
+ }
8994
+ },
8995
  "node_modules/whatwg-encoding": {
8996
  "version": "2.0.0",
8997
  "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
package.json CHANGED
@@ -11,6 +11,7 @@
11
  "dependencies": {
12
  "@emotion/react": "^11.11.1",
13
  "@emotion/styled": "^11.11.0",
 
14
  "@mui/material": "^5.14.16",
15
  "@upstash/ratelimit": "^0.4.4",
16
  "@vercel/kv": "^0.2.4",
@@ -44,6 +45,7 @@
44
  "@types/react-dom": "^18",
45
  "eslint": "^8",
46
  "eslint-config-next": "14.0.1",
 
47
  "typescript": "^5"
48
  }
49
  }
 
11
  "dependencies": {
12
  "@emotion/react": "^11.11.1",
13
  "@emotion/styled": "^11.11.0",
14
+ "@mui/icons-material": "^5.14.19",
15
  "@mui/material": "^5.14.16",
16
  "@upstash/ratelimit": "^0.4.4",
17
  "@vercel/kv": "^0.2.4",
 
45
  "@types/react-dom": "^18",
46
  "eslint": "^8",
47
  "eslint-config-next": "14.0.1",
48
+ "node-loader": "^2.0.0",
49
  "typescript": "^5"
50
  }
51
  }
tsconfig.json CHANGED
@@ -22,6 +22,6 @@
22
  "@/*": ["./*"]
23
  }
24
  },
25
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26
  "exclude": ["node_modules"]
27
  }
 
22
  "@/*": ["./*"]
23
  }
24
  },
25
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "app/worker.js"],
26
  "exclude": ["node_modules"]
27
  }