sera-ai 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2852,6 +2852,7 @@ var useAudioRecorder = ({
2852
2852
  speciality,
2853
2853
  patientId,
2854
2854
  patientName,
2855
+ patientHistory,
2855
2856
  selectedFormat = "json",
2856
2857
  skipDiarization = true,
2857
2858
  silenceRemoval = true,
@@ -3233,6 +3234,7 @@ var useAudioRecorder = ({
3233
3234
  formData.append("model", selectedModelRef.current);
3234
3235
  formData.append("doctorName", doctorName);
3235
3236
  formData.append("patientName", patientName || "");
3237
+ if (patientHistory) formData.append("patientHistory", patientHistory);
3236
3238
  if (patientId) formData.append("patientId", patientId.toString());
3237
3239
  formData.append("removeSilence", removeSilenceRef.current.toString());
3238
3240
  formData.append("skipDiarization", skipDiarizationRef.current.toString());
@@ -3414,6 +3416,7 @@ var useAudioRecorder = ({
3414
3416
  skipDiarization,
3415
3417
  selectedFormat,
3416
3418
  patientName,
3419
+ patientHistory,
3417
3420
  onTranscriptionComplete,
3418
3421
  speciality,
3419
3422
  removeSilence,
@@ -3472,6 +3475,7 @@ var useAudioRecorder = ({
3472
3475
  await createSession(localSessionId, {
3473
3476
  patientId,
3474
3477
  patientName: patientName || void 0,
3478
+ patientHistory: patientHistory || void 0,
3475
3479
  speciality
3476
3480
  });
3477
3481
  }
@@ -3570,6 +3574,7 @@ var useAudioRecorder = ({
3570
3574
  createSession,
3571
3575
  patientId,
3572
3576
  patientName,
3577
+ patientHistory,
3573
3578
  speciality,
3574
3579
  currentDeviceId
3575
3580
  ]);
@@ -4360,6 +4365,7 @@ var AudioRecorder = ({
4360
4365
  speciality,
4361
4366
  patientId,
4362
4367
  patientName,
4368
+ patientHistory,
4363
4369
  onTranscriptionUpdate,
4364
4370
  onTranscriptionComplete,
4365
4371
  onSuccess,
@@ -4394,6 +4400,7 @@ var AudioRecorder = ({
4394
4400
  speciality,
4395
4401
  patientName,
4396
4402
  patientId,
4403
+ patientHistory,
4397
4404
  onTranscriptionUpdate: (text, sessionId) => {
4398
4405
  console.log("onTranscriptionUpdate called with text:", text, "sessionId:", sessionId);
4399
4406
  if (text.length > 0) {
@@ -5095,7 +5102,886 @@ var AudioDictation = ({
5095
5102
  ) });
5096
5103
  };
5097
5104
  var AudioDictation_default = AudioDictation;
5105
+ var createAudioCaptureWorker = () => {
5106
+ const workerCode = `
5107
+ class AudioCaptureProcessor extends AudioWorkletProcessor {
5108
+ constructor() {
5109
+ super();
5110
+ this._buffer = [];
5111
+ this._isStopped = false;
5112
+ this._isPaused = false;
5113
+ this._chunkReady = false;
5114
+ this._processingChunk = false;
5115
+
5116
+ this._audioLevelCheckInterval = 0;
5117
+ this._audioLevelCheckFrequency = 128;
5118
+ this._silentSampleCount = 0;
5119
+ this._maxSilentSamples = 44100 * 30;
5120
+ this._audioThreshold = 0.002;
5121
+ this._hasDetectedAudio = false;
5122
+ this._lastAudioTime = 0;
5123
+ this._recordingStartTime = Date.now();
5124
+ this._initialSilenceThreshold = 44100 * 10;
5125
+ this._isInitialPhase = true;
5126
+ this._bufferSize = 0;
5127
+
5128
+ this.port.onmessage = (event) => {
5129
+ if (event.data.command === "stop") {
5130
+ this._isStopped = true;
5131
+ this._sendFinalChunk();
5132
+ }
5133
+
5134
+ if (event.data.command === "getChunk") {
5135
+ this._chunkReady = true;
5136
+ }
5137
+
5138
+ if (event.data.command === "resetChunk") {
5139
+ this._chunkReady = false;
5140
+ this._processingChunk = false;
5141
+ this._buffer = [];
5142
+ this._bufferSize = 0;
5143
+ }
5144
+
5145
+ if (event.data.command === "pause") {
5146
+ this._isPaused = true;
5147
+ }
5148
+
5149
+ if (event.data.command === "resume") {
5150
+ this._isPaused = false;
5151
+ }
5152
+ };
5153
+ }
5154
+
5155
+ _sendFinalChunk() {
5156
+ if (this._buffer.length > 0) {
5157
+ const flat = this._flattenBuffer();
5158
+ this.port.postMessage({
5159
+ command: "finalChunk",
5160
+ audioBuffer: flat.buffer,
5161
+ duration: this._bufferSize / 44100
5162
+ }, [flat.buffer]);
5163
+ } else {
5164
+ // Send empty final chunk
5165
+ const emptyBuffer = new Float32Array(1000);
5166
+ this.port.postMessage({
5167
+ command: "finalChunk",
5168
+ audioBuffer: emptyBuffer.buffer,
5169
+ duration: 0
5170
+ }, [emptyBuffer.buffer]);
5171
+ }
5172
+ this._buffer = [];
5173
+ this._bufferSize = 0;
5174
+ }
5175
+
5176
+ _flattenBuffer() {
5177
+ let totalLength = 0;
5178
+ for (let i = 0; i < this._buffer.length; i++) {
5179
+ totalLength += this._buffer[i].length;
5180
+ }
5181
+
5182
+ const flat = new Float32Array(totalLength);
5183
+ let offset = 0;
5184
+ for (let i = 0; i < this._buffer.length; i++) {
5185
+ flat.set(this._buffer[i], offset);
5186
+ offset += this._buffer[i].length;
5187
+ }
5188
+ return flat;
5189
+ }
5190
+
5191
+ process(inputs, outputs) {
5192
+ if (this._isStopped || this._isPaused) {
5193
+ return true;
5194
+ }
5195
+
5196
+ const input = inputs[0];
5197
+ if (input && input.length > 0) {
5198
+ const samples = input[0];
5199
+
5200
+ // Calculate audio level
5201
+ let audioLevel = 0;
5202
+ for (let i = 0; i < samples.length; i++) {
5203
+ audioLevel += Math.abs(samples[i]);
5204
+ }
5205
+ audioLevel /= samples.length;
5206
+
5207
+ // Send audio level updates
5208
+ this._audioLevelCheckInterval++;
5209
+ if (this._audioLevelCheckInterval >= this._audioLevelCheckFrequency) {
5210
+ this.port.postMessage({
5211
+ command: "audioLevel",
5212
+ level: audioLevel,
5213
+ });
5214
+ this._audioLevelCheckInterval = 0;
5215
+ }
5216
+
5217
+ // Check for audio activity
5218
+ if (audioLevel > this._audioThreshold) {
5219
+ this._hasDetectedAudio = true;
5220
+ this._isInitialPhase = false;
5221
+ this._silentSampleCount = 0;
5222
+ this._lastAudioTime = Date.now();
5223
+ } else {
5224
+ this._silentSampleCount += samples.length;
5225
+
5226
+ if (this._isInitialPhase && this._silentSampleCount > this._initialSilenceThreshold) {
5227
+ this.port.postMessage({
5228
+ command: "noAudioDetected",
5229
+ message: "No audio input detected after 10 seconds. Please check your microphone."
5230
+ });
5231
+ return true;
5232
+ }
5233
+ }
5234
+
5235
+ // Buffer the audio
5236
+ this._buffer.push(new Float32Array(samples));
5237
+ this._bufferSize += samples.length;
5238
+
5239
+ // Send chunk if ready
5240
+ if (this._chunkReady && !this._processingChunk) {
5241
+ this._processingChunk = true;
5242
+
5243
+ const flat = this._flattenBuffer();
5244
+ this.port.postMessage({
5245
+ command: "chunk",
5246
+ audioBuffer: flat.buffer,
5247
+ duration: this._bufferSize / 44100,
5248
+ hasActivity: audioLevel > this._audioThreshold
5249
+ }, [flat.buffer]);
5250
+
5251
+ this._buffer = [];
5252
+ this._bufferSize = 0;
5253
+ this._chunkReady = false;
5254
+ this._processingChunk = false;
5255
+ }
5256
+ }
5257
+
5258
+ return true;
5259
+ }
5260
+ }
5261
+
5262
+ registerProcessor("audio-capture-processor", AudioCaptureProcessor);
5263
+ `;
5264
+ const blob = new Blob([workerCode], { type: "application/javascript" });
5265
+ return URL.createObjectURL(blob);
5266
+ };
5267
+ var useAudioCapture = ({
5268
+ onAudioChunk,
5269
+ onAudioComplete,
5270
+ onAudioFile,
5271
+ silenceRemoval = false,
5272
+ chunkDuration = 30,
5273
+ // Default 30 seconds per chunk
5274
+ format = "raw"
5275
+ }) => {
5276
+ const [isRecording, setIsRecording] = React3.useState(false);
5277
+ const [isPaused, setIsPaused] = React3.useState(false);
5278
+ const [isProcessing, setIsProcessing] = React3.useState(false);
5279
+ const [error, setError] = React3.useState(null);
5280
+ const [currentDeviceId, setCurrentDeviceId] = React3.useState(null);
5281
+ const [availableDevices, setAvailableDevices] = React3.useState([]);
5282
+ const [audioLevel, setAudioLevel] = React3.useState(0);
5283
+ const [noAudioDetected, setNoAudioDetected] = React3.useState(false);
5284
+ const [recordingDuration, setRecordingDuration] = React3.useState(0);
5285
+ const [totalChunks, setTotalChunks] = React3.useState(0);
5286
+ const mediaStreamRef = React3.useRef(null);
5287
+ const processorRef = React3.useRef(null);
5288
+ const audioContextRef = React3.useRef(null);
5289
+ const chunkIntervalRef = React3.useRef(null);
5290
+ const recordingStartTimeRef = React3.useRef(0);
5291
+ const durationIntervalRef = React3.useRef(null);
5292
+ const sequenceCounterRef = React3.useRef(0);
5293
+ const allAudioChunksRef = React3.useRef([]);
5294
+ const {
5295
+ removeSilence,
5296
+ isLoaded,
5297
+ isConverting,
5298
+ progress,
5299
+ statusMessage,
5300
+ convertToWav
5301
+ } = useFFmpegConverter_default();
5302
+ const validateMicrophoneAccess = React3.useCallback(async () => {
5303
+ try {
5304
+ const devices = await navigator.mediaDevices.enumerateDevices();
5305
+ const audioInputDevices = devices.filter((device) => device.kind === "audioinput");
5306
+ setAvailableDevices(audioInputDevices);
5307
+ if (audioInputDevices.length === 0) {
5308
+ throw new Error("No microphone devices detected. Please connect a microphone.");
5309
+ }
5310
+ const testStream = await navigator.mediaDevices.getUserMedia({
5311
+ audio: {
5312
+ deviceId: currentDeviceId ? { exact: currentDeviceId } : void 0
5313
+ }
5314
+ });
5315
+ const audioTracks = testStream.getAudioTracks();
5316
+ if (audioTracks.length > 0) {
5317
+ const track = audioTracks[0];
5318
+ const settings = track.getSettings();
5319
+ setCurrentDeviceId(settings.deviceId || null);
5320
+ }
5321
+ testStream.getTracks().forEach((track) => track.stop());
5322
+ return true;
5323
+ } catch (error2) {
5324
+ console.error("Microphone validation failed:", error2);
5325
+ if (error2 instanceof Error) {
5326
+ let errorMessage = "";
5327
+ if (error2.name === "NotFoundError" || error2.name === "DevicesNotFoundError") {
5328
+ errorMessage = "No microphone devices found. Please connect a microphone.";
5329
+ } else if (error2.name === "NotAllowedError" || error2.name === "PermissionDeniedError") {
5330
+ errorMessage = "Microphone permission denied. Please allow access and try again.";
5331
+ } else if (error2.name === "NotReadableError" || error2.name === "TrackStartError") {
5332
+ errorMessage = "Microphone is busy or unavailable. Please close other applications using the microphone.";
5333
+ } else if (error2.name === "OverconstrainedError") {
5334
+ errorMessage = "Selected microphone device is not available. Please select a different device.";
5335
+ } else {
5336
+ errorMessage = `Microphone error: ${error2.message}`;
5337
+ }
5338
+ setError(errorMessage);
5339
+ } else {
5340
+ setError("Microphone access error occurred.");
5341
+ }
5342
+ return false;
5343
+ }
5344
+ }, [currentDeviceId]);
5345
+ const processAudioChunk = React3.useCallback(async (audioData, sequence, isFinal) => {
5346
+ try {
5347
+ setIsProcessing(true);
5348
+ let processedAudio = audioData;
5349
+ if (silenceRemoval && isLoaded && typeof removeSilence === "function") {
5350
+ console.log("Applying silence removal to audio chunk...");
5351
+ const tempFile = float32ToWavFile(audioData);
5352
+ const processedFile = await removeSilence(tempFile);
5353
+ if (processedFile) {
5354
+ const arrayBuffer = await processedFile.arrayBuffer();
5355
+ const dataView = new DataView(arrayBuffer);
5356
+ const samples = new Float32Array((arrayBuffer.byteLength - 44) / 2);
5357
+ for (let i = 0; i < samples.length; i++) {
5358
+ const int16 = dataView.getInt16(44 + i * 2, true);
5359
+ samples[i] = int16 / (int16 < 0 ? 32768 : 32767);
5360
+ }
5361
+ processedAudio = samples;
5362
+ }
5363
+ }
5364
+ if (!isFinal) {
5365
+ allAudioChunksRef.current.push(processedAudio);
5366
+ }
5367
+ if (onAudioChunk) {
5368
+ onAudioChunk(processedAudio, sequence, isFinal);
5369
+ }
5370
+ if (isFinal) {
5371
+ const totalLength = allAudioChunksRef.current.reduce((sum, chunk) => sum + chunk.length, 0);
5372
+ const finalAudio = new Float32Array(totalLength);
5373
+ let offset = 0;
5374
+ for (const chunk of allAudioChunksRef.current) {
5375
+ finalAudio.set(chunk, offset);
5376
+ offset += chunk.length;
5377
+ }
5378
+ if (onAudioComplete) {
5379
+ onAudioComplete(finalAudio);
5380
+ }
5381
+ if (onAudioFile && format === "wav") {
5382
+ const wavFile = await createWavFile(finalAudio);
5383
+ onAudioFile(wavFile);
5384
+ } else if (onAudioFile && format === "raw") {
5385
+ const rawFile = createRawFile(finalAudio);
5386
+ onAudioFile(rawFile);
5387
+ }
5388
+ allAudioChunksRef.current = [];
5389
+ }
5390
+ } catch (error2) {
5391
+ console.error("Error processing audio chunk:", error2);
5392
+ setError(`Audio processing failed: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
5393
+ } finally {
5394
+ setIsProcessing(false);
5395
+ }
5396
+ }, [silenceRemoval, isLoaded, removeSilence, onAudioChunk, onAudioComplete, onAudioFile, format]);
5397
+ const createWavFile = React3.useCallback(async (samples) => {
5398
+ if (isLoaded && typeof convertToWav === "function") {
5399
+ const result = await convertToWav(samples);
5400
+ return result || float32ToWavFile(samples);
5401
+ } else {
5402
+ return float32ToWavFile(samples);
5403
+ }
5404
+ }, [isLoaded, convertToWav]);
5405
+ const createRawFile = React3.useCallback((samples) => {
5406
+ const timestamp = Date.now();
5407
+ const filename = `audio-recording-${timestamp}.raw`;
5408
+ const buffer = new ArrayBuffer(samples.byteLength);
5409
+ const uint8Array = new Uint8Array(buffer);
5410
+ const sourceArray = new Uint8Array(samples.buffer, samples.byteOffset, samples.byteLength);
5411
+ uint8Array.set(sourceArray);
5412
+ return new File([buffer], filename, {
5413
+ type: "application/octet-stream",
5414
+ lastModified: timestamp
5415
+ });
5416
+ }, []);
5417
+ const float32ToWavFile = (samples) => {
5418
+ const sampleRate = audioContextRef.current?.sampleRate || 44100;
5419
+ const buffer = new ArrayBuffer(44 + samples.length * 2);
5420
+ const view = new DataView(buffer);
5421
+ const writeString = (offset2, str) => {
5422
+ for (let i = 0; i < str.length; i++) {
5423
+ view.setUint8(offset2 + i, str.charCodeAt(i));
5424
+ }
5425
+ };
5426
+ writeString(0, "RIFF");
5427
+ view.setUint32(4, 36 + samples.length * 2, true);
5428
+ writeString(8, "WAVE");
5429
+ writeString(12, "fmt ");
5430
+ view.setUint32(16, 16, true);
5431
+ view.setUint16(20, 1, true);
5432
+ view.setUint16(22, 1, true);
5433
+ view.setUint32(24, sampleRate, true);
5434
+ view.setUint32(28, sampleRate * 2, true);
5435
+ view.setUint16(32, 2, true);
5436
+ view.setUint16(34, 16, true);
5437
+ writeString(36, "data");
5438
+ view.setUint32(40, samples.length * 2, true);
5439
+ let offset = 44;
5440
+ for (let i = 0; i < samples.length; i++) {
5441
+ const sample = Math.max(-1, Math.min(1, samples[i]));
5442
+ view.setInt16(offset, sample < 0 ? sample * 32768 : sample * 32767, true);
5443
+ offset += 2;
5444
+ }
5445
+ const timestamp = Date.now();
5446
+ const filename = `audio-recording-${timestamp}.wav`;
5447
+ return new File([view], filename, {
5448
+ type: "audio/wav",
5449
+ lastModified: timestamp
5450
+ });
5451
+ };
5452
+ const startRecording = React3.useCallback(async () => {
5453
+ try {
5454
+ setError(null);
5455
+ setNoAudioDetected(false);
5456
+ const micValid = await validateMicrophoneAccess();
5457
+ if (!micValid) return;
5458
+ sequenceCounterRef.current = 0;
5459
+ allAudioChunksRef.current = [];
5460
+ setTotalChunks(0);
5461
+ setRecordingDuration(0);
5462
+ recordingStartTimeRef.current = Date.now();
5463
+ const stream = await navigator.mediaDevices.getUserMedia({
5464
+ audio: {
5465
+ deviceId: currentDeviceId ? { exact: currentDeviceId } : void 0,
5466
+ echoCancellation: true,
5467
+ noiseSuppression: true,
5468
+ autoGainControl: true
5469
+ }
5470
+ });
5471
+ mediaStreamRef.current = stream;
5472
+ const audioContext = new (window.AudioContext || window.webkitAudioContext)();
5473
+ const processorUrl = createAudioCaptureWorker();
5474
+ await audioContext.audioWorklet.addModule(processorUrl);
5475
+ URL.revokeObjectURL(processorUrl);
5476
+ const processor = new AudioWorkletNode(audioContext, "audio-capture-processor");
5477
+ processor.port.onmessage = (event) => {
5478
+ if (event.data.command === "chunk") {
5479
+ const audioData = new Float32Array(event.data.audioBuffer);
5480
+ const sequence = sequenceCounterRef.current++;
5481
+ setTotalChunks(sequence + 1);
5482
+ processAudioChunk(audioData, sequence, false);
5483
+ } else if (event.data.command === "finalChunk") {
5484
+ const audioData = new Float32Array(event.data.audioBuffer);
5485
+ const sequence = sequenceCounterRef.current++;
5486
+ processAudioChunk(audioData, sequence, true);
5487
+ } else if (event.data.command === "audioLevel") {
5488
+ setAudioLevel(event.data.level);
5489
+ } else if (event.data.command === "noAudioDetected") {
5490
+ setNoAudioDetected(true);
5491
+ setError(event.data.message);
5492
+ }
5493
+ };
5494
+ const source = audioContext.createMediaStreamSource(stream);
5495
+ source.connect(processor);
5496
+ audioContextRef.current = audioContext;
5497
+ processorRef.current = processor;
5498
+ setIsRecording(true);
5499
+ const chunkIntervalId = window.setInterval(() => {
5500
+ processor.port.postMessage({ command: "getChunk" });
5501
+ }, chunkDuration * 1e3);
5502
+ chunkIntervalRef.current = chunkIntervalId;
5503
+ const durationIntervalId = window.setInterval(() => {
5504
+ const elapsed = (Date.now() - recordingStartTimeRef.current) / 1e3;
5505
+ setRecordingDuration(elapsed);
5506
+ }, 100);
5507
+ durationIntervalRef.current = durationIntervalId;
5508
+ } catch (err) {
5509
+ console.error("Recording start failed:", err);
5510
+ setError(err instanceof Error ? err.message : "Failed to start recording");
5511
+ }
5512
+ }, [validateMicrophoneAccess, currentDeviceId, chunkDuration, processAudioChunk]);
5513
+ const stopRecording = React3.useCallback(() => {
5514
+ console.log("Stopping recording...");
5515
+ if (chunkIntervalRef.current) {
5516
+ clearInterval(chunkIntervalRef.current);
5517
+ chunkIntervalRef.current = null;
5518
+ }
5519
+ if (durationIntervalRef.current) {
5520
+ clearInterval(durationIntervalRef.current);
5521
+ durationIntervalRef.current = null;
5522
+ }
5523
+ if (processorRef.current) {
5524
+ processorRef.current.port.postMessage({ command: "stop" });
5525
+ }
5526
+ if (mediaStreamRef.current) {
5527
+ mediaStreamRef.current.getTracks().forEach((track) => track.stop());
5528
+ mediaStreamRef.current = null;
5529
+ }
5530
+ if (audioContextRef.current) {
5531
+ audioContextRef.current.close();
5532
+ audioContextRef.current = null;
5533
+ }
5534
+ processorRef.current = null;
5535
+ setIsRecording(false);
5536
+ }, []);
5537
+ const pauseRecording = React3.useCallback(() => {
5538
+ if (!isRecording || isPaused) return;
5539
+ if (chunkIntervalRef.current) {
5540
+ clearInterval(chunkIntervalRef.current);
5541
+ chunkIntervalRef.current = null;
5542
+ }
5543
+ if (durationIntervalRef.current) {
5544
+ clearInterval(durationIntervalRef.current);
5545
+ durationIntervalRef.current = null;
5546
+ }
5547
+ setIsPaused(true);
5548
+ if (processorRef.current) {
5549
+ processorRef.current.port.postMessage({ command: "pause" });
5550
+ }
5551
+ setIsRecording(false);
5552
+ }, [isRecording, isPaused]);
5553
+ const resumeRecording = React3.useCallback(() => {
5554
+ if (!isPaused) return;
5555
+ setIsPaused(false);
5556
+ setIsRecording(true);
5557
+ setNoAudioDetected(false);
5558
+ if (processorRef.current) {
5559
+ processorRef.current.port.postMessage({ command: "resume" });
5560
+ }
5561
+ const chunkIntervalId = window.setInterval(() => {
5562
+ processorRef.current?.port.postMessage({ command: "getChunk" });
5563
+ }, chunkDuration * 1e3);
5564
+ chunkIntervalRef.current = chunkIntervalId;
5565
+ const durationIntervalId = window.setInterval(() => {
5566
+ const elapsed = (Date.now() - recordingStartTimeRef.current) / 1e3;
5567
+ setRecordingDuration(elapsed);
5568
+ }, 100);
5569
+ durationIntervalRef.current = durationIntervalId;
5570
+ }, [isPaused, chunkDuration]);
5571
+ const selectMicrophone = React3.useCallback(async (deviceId) => {
5572
+ try {
5573
+ setCurrentDeviceId(deviceId);
5574
+ if (isRecording) {
5575
+ await stopRecording();
5576
+ await startRecording();
5577
+ }
5578
+ } catch (error2) {
5579
+ console.error("Device selection failed:", error2);
5580
+ setError("Failed to switch to selected microphone.");
5581
+ }
5582
+ }, [isRecording, stopRecording, startRecording]);
5583
+ return {
5584
+ mediaStreamRef,
5585
+ startRecording,
5586
+ stopRecording,
5587
+ pauseRecording,
5588
+ resumeRecording,
5589
+ isRecording,
5590
+ isPaused,
5591
+ isProcessing,
5592
+ error,
5593
+ availableDevices,
5594
+ currentDeviceId,
5595
+ selectMicrophone,
5596
+ validateMicrophoneAccess,
5597
+ audioLevel,
5598
+ noAudioDetected,
5599
+ isConverting,
5600
+ progress,
5601
+ statusMessage,
5602
+ recordingDuration,
5603
+ totalChunks
5604
+ };
5605
+ };
5606
+ var useAudioCapture_default = useAudioCapture;
5607
+ var tailwindStyles2 = `
5608
+ .space-y-4 > :not([hidden]) ~ :not([hidden]) { margin-top: 1rem; }
5609
+ .bg-orange-50 { background-color: rgb(255 247 237); }
5610
+ .bg-blue-900 { background-color: rgb(30 58 138); }
5611
+ .text-yellow-200 { color: rgb(254 240 138); }
5612
+ .hover\\:bg-blue-700:hover { background-color: rgb(29 78 216); }
5613
+ .dark .dark\\:bg-orange-900\\/20 { background-color: rgb(194 65 12 / 0.2); }
5614
+ .border { border-width: 1px; }
5615
+ .border-orange-200 { border-color: rgb(254 215 170); }
5616
+ .dark .dark\\:border-orange-800 { border-color: rgb(154 52 18); }
5617
+ .rounded-lg { border-radius: 0.5rem; }
5618
+ .p-4 { padding: 1rem; }
5619
+ .flex { display: flex; }
5620
+ .items-start { align-items: flex-start; }
5621
+ .items-center { align-items: center; }
5622
+ .justify-center { justify-content: center; }
5623
+ .justify-between { justify-content: space-between; }
5624
+ .flex-shrink-0 { flex-shrink: 0; }
5625
+ .h-5 { height: 1.25rem; }
5626
+ .w-5 { width: 1.25rem; }
5627
+ .text-orange-400 { color: rgb(251 146 60); }
5628
+ .ml-3 { margin-left: 0.75rem; }
5629
+ .mr-2 { margin-right: 0.5rem; }
5630
+ .flex-1 { flex: 1 1 0%; }
5631
+ .text-sm { font-size: 0.875rem; line-height: 1.25rem; }
5632
+ .font-medium { font-weight: 500; }
5633
+ .text-orange-800 { color: rgb(154 52 18); }
5634
+ .dark .dark\\:text-orange-200 { color: rgb(254 215 170); }
5635
+ .mt-2 { margin-top: 0.5rem; }
5636
+ .text-orange-700 { color: rgb(194 65 12); }
5637
+ .dark .dark\\:text-orange-300 { color: rgb(253 186 116); }
5638
+ .list-disc { list-style-type: disc; }
5639
+ .list-inside { list-style-position: inside; }
5640
+ .bg-red-50 { background-color: rgb(254 242 242); }
5641
+ .dark .dark\\:bg-red-900\\/20 { background-color: rgb(127 29 29 / 0.2); }
5642
+ .border-red-200 { border-color: rgb(254 202 202); }
5643
+ .dark .dark\\:border-red-800 { border-color: rgb(153 27 27); }
5644
+ .text-red-400 { color: rgb(248 113 113); }
5645
+ .text-red-800 { color: rgb(153 27 27); }
5646
+ .dark .dark\\:text-red-200 { color: rgb(254 202 202); }
5647
+ .text-red-700 { color: rgb(185 28 28); }
5648
+ .dark .dark\\:text-red-300 { color: rgb(252 165 165); }
5649
+ .mt-4 { margin-top: 1rem; }
5650
+ .bg-red-600 { background-color: rgb(220 38 38); }
5651
+ .hover\\:bg-red-700:hover { background-color: rgb(185 28 28); }
5652
+ .text-white { color: rgb(255 255 255); }
5653
+ .px-3 { padding-left: 0.75rem; padding-right: 0.75rem; }
5654
+ .py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem; }
5655
+ .py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem; }
5656
+ .px-4 { padding-left: 1rem; padding-right: 1rem; }
5657
+ .rounded { border-radius: 0.25rem; }
5658
+ .rounded-full { border-radius: 9999px; }
5659
+ .transition-colors { transition-property: color, background-color, border-color, text-decoration-color, fill, stroke; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; }
5660
+ .bg-yellow-50 { background-color: rgb(254 252 232); }
5661
+ .dark .dark\\:bg-yellow-900\\/20 { background-color: rgb(133 77 14 / 0.2); }
5662
+ .border-yellow-200 { border-color: rgb(254 240 138); }
5663
+ .dark .dark\\:border-yellow-800 { border-color: rgb(133 77 14); }
5664
+ .text-yellow-400 { color: rgb(250 204 21); }
5665
+ .text-yellow-800 { color: rgb(133 77 14); }
5666
+ .dark .dark\\:text-yellow-200 { color: rgb(254 240 138); }
5667
+ .text-yellow-700 { color: rgb(161 98 7); }
5668
+ .dark .dark\\:text-yellow-300 { color: rgb(253 224 71); }
5669
+ .space-x-3 > :not([hidden]) ~ :not([hidden]) { margin-left: 0.75rem; }
5670
+ .space-x-1 > :not([hidden]) ~ :not([hidden]) { margin-left: 0.25rem; }
5671
+ .space-x-2 > :not([hidden]) ~ :not([hidden]) { margin-left: 0.5rem; }
5672
+ .bg-yellow-600 { background-color: rgb(202 138 4); }
5673
+ .hover\\:bg-yellow-700:hover { background-color: rgb(161 98 7); }
5674
+ .disabled\\:opacity-50:disabled { opacity: 0.5; }
5675
+ .h-3 { height: 0.75rem; }
5676
+ .w-3 { width: 0.75rem; }
5677
+ .animate-spin { animation: spin 1s linear infinite; }
5678
+ @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
5679
+ .bg-gray-600 { background-color: rgb(75 85 99); }
5680
+ .hover\\:bg-gray-700:hover { background-color: rgb(55 65 81); }
5681
+ .bg-blue-50 { background-color: rgb(239 246 255); }
5682
+ .dark .dark\\:bg-blue-900\\/20 { background-color: rgb(30 58 138 / 0.2); }
5683
+ .border-blue-200 { border-color: rgb(191 219 254); }
5684
+ .dark .dark\\:border-blue-800 { border-color: rgb(30 64 175); }
5685
+ .text-blue-600 { color: rgb(37 99 235); }
5686
+ .block { display: block; }
5687
+ .text-blue-700 { color: rgb(29 78 216); }
5688
+ .dark .dark\\:text-blue-300 { color: rgb(147 197 253); }
5689
+ .text-xs { font-size: 0.75rem; line-height: 1rem; }
5690
+ .dark .dark\\:text-blue-400 { color: rgb(96 165 250); }
5691
+ .mt-1 { margin-top: 0.25rem; }
5692
+ .bg-teal-600 { background-color: rgb(13 148 136); }
5693
+ .hover\\:bg-teal-700:hover { background-color: rgb(15 118 110); }
5694
+ .bg-green-600 { background-color: rgb(22 163 74); }
5695
+ .hover\\:bg-green-700:hover { background-color: rgb(21 128 61); }
5696
+ .bg-yellow-500 { background-color: rgb(234 179 8); }
5697
+ .hover\\:bg-yellow-600:hover { background-color: rgb(202 138 4); }
5698
+ .bg-gradient-to-r { background-image: linear-gradient(to right, var(--tw-gradient-stops)); }
5699
+ .from-purple-400 { --tw-gradient-from: #c084fc; --tw-gradient-to: rgb(192 132 252 / 0); --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); }
5700
+ .to-blue-500 { --tw-gradient-to: #3b82f6; }
5701
+ .hover\\:from-purple-500:hover { --tw-gradient-from: #a855f7; --tw-gradient-to: rgb(168 85 247 / 0); --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); }
5702
+ .hover\\:to-blue-600:hover { --tw-gradient-to: #2563eb; }
5703
+ .opacity-50 { opacity: 0.5; }
5704
+ .cursor-not-allowed { cursor: not-allowed; }
5705
+ .text-gray-600 { color: rgb(75 85 99); }
5706
+ .dark .dark\\:text-gray-300 { color: rgb(209 213 219); }
5707
+ .bg-gray-100 { background-color: rgb(243 244 246); }
5708
+ .dark .dark\\:bg-gray-800 { background-color: rgb(31 41 55); }
5709
+ .border-gray-200 { border-color: rgb(229 231 235); }
5710
+ .dark .dark\\:border-gray-700 { border-color: rgb(55 65 81); }
5711
+ .cursor-pointer { cursor: pointer; }
5712
+ .hover\\:bg-gray-200:hover { background-color: rgb(229 231 235); }
5713
+ .dark .dark\\:hover\\:bg-gray-700:hover { background-color: rgb(55 65 81); }
5714
+ `;
5715
+ var stylesInjected2 = false;
5716
+ var injectTailwindStyles2 = () => {
5717
+ if (!stylesInjected2 && typeof document !== "undefined") {
5718
+ const styleElement = document.createElement("style");
5719
+ styleElement.textContent = tailwindStyles2;
5720
+ document.head.appendChild(styleElement);
5721
+ stylesInjected2 = true;
5722
+ }
5723
+ };
5724
+ var AudioCapture = ({
5725
+ onAudioChunk,
5726
+ onAudioComplete,
5727
+ onAudioFile,
5728
+ silenceRemoval = false,
5729
+ chunkDuration = 30,
5730
+ format = "raw",
5731
+ showDownload = false,
5732
+ className = "",
5733
+ style
5734
+ }) => {
5735
+ React3__namespace.useEffect(() => {
5736
+ injectTailwindStyles2();
5737
+ }, []);
5738
+ const {
5739
+ mediaStreamRef,
5740
+ startRecording,
5741
+ stopRecording,
5742
+ pauseRecording,
5743
+ resumeRecording,
5744
+ isRecording,
5745
+ isPaused,
5746
+ isProcessing,
5747
+ error,
5748
+ availableDevices,
5749
+ currentDeviceId,
5750
+ selectMicrophone,
5751
+ validateMicrophoneAccess,
5752
+ noAudioDetected,
5753
+ isConverting,
5754
+ progress,
5755
+ statusMessage,
5756
+ recordingDuration,
5757
+ totalChunks
5758
+ } = useAudioCapture_default({
5759
+ onAudioChunk,
5760
+ onAudioComplete,
5761
+ onAudioFile,
5762
+ silenceRemoval,
5763
+ chunkDuration,
5764
+ format
5765
+ });
5766
+ const [isDisabled, setIsDisabled] = React3__namespace.useState(false);
5767
+ const [lastAudioFile, setLastAudioFile] = React3__namespace.useState(null);
5768
+ const [toast, setToast] = React3__namespace.useState({
5769
+ show: false,
5770
+ message: "",
5771
+ type: "success"
5772
+ });
5773
+ React3__namespace.useEffect(() => {
5774
+ if (onAudioFile) {
5775
+ const originalCallback = onAudioFile;
5776
+ onAudioFile = (file) => {
5777
+ setLastAudioFile(file);
5778
+ originalCallback(file);
5779
+ };
5780
+ }
5781
+ }, [onAudioFile]);
5782
+ const handleStopClick = () => {
5783
+ setIsDisabled(true);
5784
+ stopRecording();
5785
+ };
5786
+ const handleStartRecording = () => {
5787
+ setIsDisabled(false);
5788
+ setLastAudioFile(null);
5789
+ startRecording();
5790
+ };
5791
+ const handleDownload = () => {
5792
+ if (lastAudioFile) {
5793
+ const url = URL.createObjectURL(lastAudioFile);
5794
+ const a = document.createElement("a");
5795
+ a.href = url;
5796
+ a.download = lastAudioFile.name;
5797
+ document.body.appendChild(a);
5798
+ a.click();
5799
+ document.body.removeChild(a);
5800
+ URL.revokeObjectURL(url);
5801
+ setToast({
5802
+ show: true,
5803
+ message: `Downloaded ${lastAudioFile.name}`,
5804
+ type: "success"
5805
+ });
5806
+ }
5807
+ };
5808
+ React3__namespace.useEffect(() => {
5809
+ if (error) {
5810
+ setToast({ show: true, message: error, type: "error" });
5811
+ }
5812
+ }, [error]);
5813
+ const closeToast = () => {
5814
+ setToast({ ...toast, show: false });
5815
+ };
5816
+ const formatDuration = (seconds) => {
5817
+ const minutes = Math.floor(seconds / 60);
5818
+ const secs = Math.floor(seconds % 60);
5819
+ return `${minutes}:${secs.toString().padStart(2, "0")}`;
5820
+ };
5821
+ const isMicrophoneError = error && (error.toLowerCase().includes("microphone") || error.toLowerCase().includes("not found") || error.toLowerCase().includes("no audio") || error.toLowerCase().includes("devices not found") || error.toLowerCase().includes("access denied") || error.toLowerCase().includes("permission") || error.toLowerCase().includes("not allowed") || error.toLowerCase().includes("busy") || error.toLowerCase().includes("media devices not supported") || availableDevices.length === 0 || noAudioDetected);
5822
+ if (noAudioDetected || error && error.includes("No audio input detected")) {
5823
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-800 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start", children: [
5824
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-5 w-5 text-orange-400" }) }),
5825
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-3 flex-1", children: [
5826
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-orange-800 dark:text-orange-200", children: "No Audio Input Detected" }),
5827
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 text-sm text-orange-700 dark:text-orange-300", children: [
5828
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: error }),
5829
+ /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "mt-2 list-disc list-inside", children: [
5830
+ /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Check if your microphone is properly connected" }),
5831
+ /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Ensure you're speaking close enough to the microphone" }),
5832
+ /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Try adjusting your microphone volume settings" }),
5833
+ /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Test your microphone in other applications" }),
5834
+ /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Make sure your browser has microphone permissions" }),
5835
+ /* @__PURE__ */ jsxRuntime.jsx("li", { children: "Please reload the page and try again" })
5836
+ ] })
5837
+ ] })
5838
+ ] })
5839
+ ] }) });
5840
+ }
5841
+ if (isMicrophoneError) {
5842
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start", children: [
5843
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-5 w-5 text-red-400" }) }),
5844
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-3 flex-1", children: [
5845
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-sm font-medium text-red-800 dark:text-red-200", children: "Audio Input Issue" }),
5846
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 text-sm text-red-700 dark:text-red-300", children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: error }) }),
5847
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: /* @__PURE__ */ jsxRuntime.jsx(
5848
+ "button",
5849
+ {
5850
+ onClick: () => {
5851
+ validateMicrophoneAccess();
5852
+ },
5853
+ className: "bg-red-600 hover:bg-red-700 text-white px-3 py-1 rounded text-sm transition-colors",
5854
+ children: "Check Again"
5855
+ }
5856
+ ) })
5857
+ ] })
5858
+ ] }) });
5859
+ }
5860
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
5861
+ toast.show && /* @__PURE__ */ jsxRuntime.jsx(Toast, { message: toast.message, type: toast.type, onClose: closeToast, duration: 3 }),
5862
+ (isRecording || isPaused || recordingDuration > 0) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center", children: [
5863
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-gray-600 dark:text-gray-300", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex space-x-4", children: [
5864
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
5865
+ "Duration: ",
5866
+ formatDuration(recordingDuration)
5867
+ ] }),
5868
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
5869
+ "Chunks: ",
5870
+ totalChunks
5871
+ ] }),
5872
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
5873
+ "Format: ",
5874
+ format.toUpperCase()
5875
+ ] }),
5876
+ silenceRemoval && /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Silence Removal: ON" })
5877
+ ] }) }),
5878
+ showDownload && lastAudioFile && /* @__PURE__ */ jsxRuntime.jsxs(
5879
+ "button",
5880
+ {
5881
+ onClick: handleDownload,
5882
+ className: "flex items-center space-x-1 bg-blue-600 hover:bg-blue-700 text-white px-3 py-1 rounded text-sm transition-colors",
5883
+ children: [
5884
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Download, { className: "h-3 w-3" }),
5885
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Download" })
5886
+ ]
5887
+ }
5888
+ )
5889
+ ] }) }),
5890
+ (isProcessing || isConverting) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center space-x-2 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4", children: [
5891
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "animate-spin h-5 w-5 text-blue-600" }),
5892
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
5893
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-sm font-medium text-blue-700 dark:text-blue-300", children: isConverting ? `Processing Audio... ${Math.round(progress)}%` : "Processing audio chunk..." }),
5894
+ statusMessage && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-blue-600 dark:text-blue-400 mt-1", children: statusMessage })
5895
+ ] })
5896
+ ] }),
5897
+ isRecording && !isPaused && mediaStreamRef.current && /* @__PURE__ */ jsxRuntime.jsxs(
5898
+ "div",
5899
+ {
5900
+ className: `audio-recorder-container ${isRecording && !isPaused ? "glow-active" : ""}`,
5901
+ children: [
5902
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "edge-container", children: [
5903
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "edge edge-top" }),
5904
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "edge edge-right" }),
5905
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "edge edge-bottom" }),
5906
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "edge edge-left" })
5907
+ ] }),
5908
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
5909
+ AudioVisualizerImproved,
5910
+ {
5911
+ mediaStream: mediaStreamRef.current,
5912
+ isRecording: isRecording && !isPaused,
5913
+ forceLight: false
5914
+ }
5915
+ ) })
5916
+ ]
5917
+ }
5918
+ ),
5919
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center", children: isProcessing ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center space-x-2 bg-teal-600 hover:bg-teal-700 text-white py-2 px-4 rounded-full", children: [
5920
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "animate-spin h-5 w-5" }),
5921
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Processing..." })
5922
+ ] }) : isRecording || isPaused ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex space-x-2", children: [
5923
+ /* @__PURE__ */ jsxRuntime.jsxs(
5924
+ "button",
5925
+ {
5926
+ className: `flex items-center justify-center space-x-2 bg-red-600 hover:bg-red-700 text-white py-2 px-4 rounded-full transition-colors ${isDisabled ? "opacity-50 cursor-not-allowed" : ""}`,
5927
+ onClick: handleStopClick,
5928
+ disabled: isDisabled,
5929
+ children: [
5930
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Square, { className: "h-5 w-5" }),
5931
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Stop" })
5932
+ ]
5933
+ }
5934
+ ),
5935
+ !isPaused ? /* @__PURE__ */ jsxRuntime.jsxs(
5936
+ "button",
5937
+ {
5938
+ className: "flex items-center justify-center space-x-2 bg-yellow-500 hover:bg-yellow-600 text-white py-2 px-4 rounded-full transition-colors",
5939
+ onClick: pauseRecording,
5940
+ children: [
5941
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pause, { className: "h-5 w-5" }),
5942
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Pause" })
5943
+ ]
5944
+ }
5945
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
5946
+ "button",
5947
+ {
5948
+ className: "flex items-center justify-center space-x-2 bg-green-600 hover:bg-green-700 text-white py-2 px-4 rounded-full transition-colors",
5949
+ onClick: resumeRecording,
5950
+ children: [
5951
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Play, { className: "h-5 w-5" }),
5952
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Resume" })
5953
+ ]
5954
+ }
5955
+ )
5956
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(
5957
+ "button",
5958
+ {
5959
+ className: className ? `flex items-center justify-center space-x-2 py-2 px-4 rounded-full transition-colors ${className}` : "flex items-center justify-center space-x-2 bg-gradient-to-r from-purple-400 to-blue-500 hover:bg-gradient-to-r hover:from-purple-500 hover:to-blue-600 text-white py-2 px-4 rounded-full transition-colors",
5960
+ onClick: handleStartRecording,
5961
+ children: [
5962
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Mic, { className: "h-5 w-5" }),
5963
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Start Recording" })
5964
+ ]
5965
+ }
5966
+ ) }),
5967
+ availableDevices.length > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4", children: [
5968
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: "Select Microphone:" }),
5969
+ /* @__PURE__ */ jsxRuntime.jsx(
5970
+ "select",
5971
+ {
5972
+ value: currentDeviceId || "",
5973
+ onChange: (e) => selectMicrophone(e.target.value),
5974
+ className: "w-full p-2 border border-gray-200 dark:border-gray-700 rounded bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100",
5975
+ disabled: isRecording,
5976
+ children: availableDevices.map((device) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: device.deviceId, children: device.label || `Microphone ${device.deviceId.slice(0, 8)}` }, device.deviceId))
5977
+ }
5978
+ )
5979
+ ] })
5980
+ ] });
5981
+ };
5982
+ var AudioCapture_default = AudioCapture;
5098
5983
 
5984
+ exports.AudioCapture = AudioCapture_default;
5099
5985
  exports.AudioDictation = AudioDictation_default;
5100
5986
  exports.AudioRecorder = AudioRecorder_default;
5101
5987
  //# sourceMappingURL=index.js.map