@arbidocs/react 0.3.173 → 0.3.175
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/chunk-7IOCMCC5.cjs +99 -0
- package/dist/chunk-7IOCMCC5.cjs.map +1 -0
- package/dist/{chunk-5DV7FW6T.cjs → chunk-FIPS3VPH.cjs} +497 -8
- package/dist/chunk-FIPS3VPH.cjs.map +1 -0
- package/dist/{chunk-PAJGQHFM.js → chunk-I256BUCX.js} +492 -11
- package/dist/chunk-I256BUCX.js.map +1 -0
- package/dist/chunk-JKO3NR5L.js +93 -0
- package/dist/chunk-JKO3NR5L.js.map +1 -0
- package/dist/index.cjs +723 -543
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +228 -2
- package/dist/index.d.ts +228 -2
- package/dist/index.js +372 -223
- package/dist/index.js.map +1 -1
- package/dist/ui/index.cjs +115 -107
- package/dist/ui/index.d.cts +216 -154
- package/dist/ui/index.d.ts +216 -154
- package/dist/ui/index.js +1 -1
- package/dist/viewers/index.cjs +14 -58
- package/dist/viewers/index.cjs.map +1 -1
- package/dist/viewers/index.js +3 -53
- package/dist/viewers/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-5DV7FW6T.cjs.map +0 -1
- package/dist/chunk-PAJGQHFM.js.map +0 -1
- package/dist/chunk-Q6XAXIT3.js +0 -43
- package/dist/chunk-Q6XAXIT3.js.map +0 -1
- package/dist/chunk-RWCMW36I.cjs +0 -47
- package/dist/chunk-RWCMW36I.cjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
1
|
+
import { cn, Avatar, AvatarFallback, AvatarImage, Tooltip, TooltipTrigger, TooltipContent, Popover, PopoverTrigger, PopoverContent, AiMarkdown, Card, Button, Badge, MarkdownRenderer, Input, DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, ScrollArea, DropdownMenuItem, Textarea, Slider, Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DropdownMenuLabel, DropdownMenuSeparator, Checkbox, useAudioRecorder, MicWaveformIndicator, IconToggle, classifyMediaError, formatElapsed } from './chunk-I256BUCX.js';
|
|
2
|
+
export { AiMarkdown, Avatar, AvatarFallback, AvatarImage, Badge, Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DictateProvider, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, HoverCard, HoverCardContent, HoverCardTrigger, IconToggle, InlineMicButton, Input, Label, MarkdownRenderer, MarkdownStreamingContext, MicRecordingOverlay, MicWaveformIndicator, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Slider, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, badgeVariants, buttonVariants, cardVariants, cn, formatElapsed, markdownBaseComponents, splitMarkdownBlocks, toggleVariants, useAudioRecorder } from './chunk-I256BUCX.js';
|
|
3
|
+
import { useArbi, ArbiProvider, AudioViewer, ImageViewer, VideoViewer } from './chunk-JKO3NR5L.js';
|
|
4
|
+
export { ArbiProvider, useArbi } from './chunk-JKO3NR5L.js';
|
|
5
5
|
import React2, { memo, useState, createContext, forwardRef, useMemo, useCallback, useId, useRef, useContext, useEffect, Fragment as Fragment$1 } from 'react';
|
|
6
6
|
import { useQuery, useMutation, useQueries, QueryClient, QueryClientProvider, useQueryClient } from '@tanstack/react-query';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import { connectWithReconnect, resolveCitations, summarizeCitations } from '@arbidocs/sdk/browser';
|
|
9
9
|
export { Arbi, ArbiError } from '@arbidocs/sdk/browser';
|
|
10
|
-
import { Link, Trash2, CheckCheck, Check, MessageCircleMore, MoreVertical, MessageSquareLock, Info, FileQuestion, BookOpen, Upload, LogOut, LayoutGrid, Bell, MessageSquare, CircleUserRound, Wrench, CreditCard, ClipboardList, UserPlus, UserStar, Settings2, Users, User, NotebookPen, NotebookText, StickyNote, FolderPlus, Hash, EyeOff, Eye, CaptionsOff, FolderOpen, MessageSquareMore, MessageSquarePlus, MessageSquareText, MessageSquareOff, MessagesSquare, Columns3Cog, SquarePlus, SquareM, ChevronsDown, Bot, Calendar, Search, Folder, List, SquareCheckBig, Loader2, AlertTriangle, ShieldCheck, Copy, Sparkles, FileText, GitCompareArrows, Download, Image as Image$1, CornerDownLeft, X, ArrowLeft, Send, Tags, Crown, Activity, Gauge, Gift, PartyPopper, UserCheck, FileX2, FileCheck2, Pencil, SquareArrowOutUpRight, BellOff, XCircle, CheckCircle2, ArrowRight, ChevronDown, MoreHorizontal, SquarePen, Mic, Pause, Play, Square, RotateCcw, FileX, SkipForward, CheckCircle } from 'lucide-react';
|
|
10
|
+
import { Link, Trash2, CheckCheck, Check, MessageCircleMore, MoreVertical, MessageSquareLock, Info, FileQuestion, BookOpen, Upload, LogOut, LayoutGrid, Bell, MessageSquare, CircleUserRound, Wrench, CreditCard, ClipboardList, UserPlus, UserStar, Settings2, Users, User, NotebookPen, NotebookText, StickyNote, FolderPlus, Hash, EyeOff, Eye, CaptionsOff, FolderOpen, MessageSquareMore, MessageSquarePlus, MessageSquareText, MessageSquareOff, MessagesSquare, Columns3Cog, SquarePlus, SquareM, ChevronsDown, Bot, Calendar, Search, Folder, List, SquareCheckBig, Loader2, AlertTriangle, ShieldCheck, Copy, Sparkles, FileText, GitCompareArrows, Download, Image as Image$1, CornerDownLeft, X, ArrowLeft, Send, Tags, Crown, Activity, Gauge, Gift, PartyPopper, UserCheck, FileX2, FileCheck2, Pencil, SquareArrowOutUpRight, BellOff, XCircle, CheckCircle2, ArrowRight, ChevronDown, MoreHorizontal, SquarePen, Mic, Pause, Play, Square, RotateCcw, Camera, Circle, FileX, SkipForward, CheckCircle } from 'lucide-react';
|
|
11
11
|
import { isMessageType } from '@arbidocs/client';
|
|
12
12
|
export { isMessageType } from '@arbidocs/client';
|
|
13
13
|
import { create } from 'zustand';
|
|
@@ -7160,227 +7160,11 @@ function DocumentGallery({
|
|
|
7160
7160
|
}
|
|
7161
7161
|
);
|
|
7162
7162
|
}
|
|
7163
|
-
var LEVEL_UPDATE_INTERVAL_MS = 50;
|
|
7164
|
-
function classifyMicError(err) {
|
|
7165
|
-
const name = err instanceof DOMException ? err.name : void 0;
|
|
7166
|
-
if (name === "NotAllowedError" || name === "SecurityError") {
|
|
7167
|
-
return "Microphone access is blocked. Allow microphone permission in your browser settings to use voice input.";
|
|
7168
|
-
}
|
|
7169
|
-
if (name === "NotFoundError" || name === "DevicesNotFoundError") {
|
|
7170
|
-
return "No microphone found on this device.";
|
|
7171
|
-
}
|
|
7172
|
-
if (!navigator.mediaDevices?.getUserMedia) {
|
|
7173
|
-
return "Voice input is not supported in this browser.";
|
|
7174
|
-
}
|
|
7175
|
-
return "Could not start recording. Please try again.";
|
|
7176
|
-
}
|
|
7177
|
-
function useAudioRecorder() {
|
|
7178
|
-
const [state, setState] = useState("idle");
|
|
7179
|
-
const [level, setLevel] = useState(0);
|
|
7180
|
-
const [elapsedMs, setElapsedMs] = useState(0);
|
|
7181
|
-
const [blob, setBlob] = useState(null);
|
|
7182
|
-
const [mimeType, setMimeType] = useState(null);
|
|
7183
|
-
const [error, setError] = useState(null);
|
|
7184
|
-
const mediaRecorderRef = useRef(null);
|
|
7185
|
-
const chunksRef = useRef([]);
|
|
7186
|
-
const streamRef = useRef(null);
|
|
7187
|
-
const stateRef = useRef("idle");
|
|
7188
|
-
stateRef.current = state;
|
|
7189
|
-
const segmentStartRef = useRef(0);
|
|
7190
|
-
const accumulatedMsRef = useRef(0);
|
|
7191
|
-
const audioContextRef = useRef(null);
|
|
7192
|
-
const analyserRef = useRef(null);
|
|
7193
|
-
const levelRafRef = useRef(null);
|
|
7194
|
-
const stopMeter = useCallback(() => {
|
|
7195
|
-
if (levelRafRef.current !== null) cancelAnimationFrame(levelRafRef.current);
|
|
7196
|
-
levelRafRef.current = null;
|
|
7197
|
-
analyserRef.current = null;
|
|
7198
|
-
void audioContextRef.current?.close().catch(() => {
|
|
7199
|
-
});
|
|
7200
|
-
audioContextRef.current = null;
|
|
7201
|
-
}, []);
|
|
7202
|
-
const startMeter = useCallback((stream) => {
|
|
7203
|
-
const audioContext = new AudioContext();
|
|
7204
|
-
const source = audioContext.createMediaStreamSource(stream);
|
|
7205
|
-
const analyser = audioContext.createAnalyser();
|
|
7206
|
-
analyser.fftSize = 256;
|
|
7207
|
-
source.connect(analyser);
|
|
7208
|
-
audioContextRef.current = audioContext;
|
|
7209
|
-
analyserRef.current = analyser;
|
|
7210
|
-
const data = new Uint8Array(analyser.frequencyBinCount);
|
|
7211
|
-
let lastUpdate = 0;
|
|
7212
|
-
const tick = (t) => {
|
|
7213
|
-
const active = analyserRef.current;
|
|
7214
|
-
if (!active) return;
|
|
7215
|
-
if (t - lastUpdate >= LEVEL_UPDATE_INTERVAL_MS) {
|
|
7216
|
-
lastUpdate = t;
|
|
7217
|
-
active.getByteTimeDomainData(data);
|
|
7218
|
-
let sumSquares = 0;
|
|
7219
|
-
for (let i = 0; i < data.length; i++) {
|
|
7220
|
-
const centered = (data[i] - 128) / 128;
|
|
7221
|
-
sumSquares += centered * centered;
|
|
7222
|
-
}
|
|
7223
|
-
const rms = Math.sqrt(sumSquares / data.length);
|
|
7224
|
-
setLevel(Math.sqrt(Math.min(1, rms * 8)));
|
|
7225
|
-
setElapsedMs(accumulatedMsRef.current + (t - segmentStartRef.current));
|
|
7226
|
-
}
|
|
7227
|
-
levelRafRef.current = requestAnimationFrame(tick);
|
|
7228
|
-
};
|
|
7229
|
-
levelRafRef.current = requestAnimationFrame(tick);
|
|
7230
|
-
}, []);
|
|
7231
|
-
const stopTracks = useCallback(() => {
|
|
7232
|
-
streamRef.current?.getTracks().forEach((t) => t.stop());
|
|
7233
|
-
streamRef.current = null;
|
|
7234
|
-
}, []);
|
|
7235
|
-
useEffect(
|
|
7236
|
-
() => () => {
|
|
7237
|
-
stopTracks();
|
|
7238
|
-
stopMeter();
|
|
7239
|
-
},
|
|
7240
|
-
[stopTracks, stopMeter]
|
|
7241
|
-
);
|
|
7242
|
-
const start = useCallback(async () => {
|
|
7243
|
-
if (stateRef.current === "recording" || stateRef.current === "paused") return;
|
|
7244
|
-
setError(null);
|
|
7245
|
-
try {
|
|
7246
|
-
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
7247
|
-
streamRef.current = stream;
|
|
7248
|
-
const mt = MediaRecorder.isTypeSupported("audio/webm") ? "audio/webm" : "audio/mp4";
|
|
7249
|
-
const recorder = new MediaRecorder(stream, { mimeType: mt });
|
|
7250
|
-
chunksRef.current = [];
|
|
7251
|
-
recorder.ondataavailable = (e) => {
|
|
7252
|
-
if (e.data.size > 0) chunksRef.current.push(e.data);
|
|
7253
|
-
};
|
|
7254
|
-
mediaRecorderRef.current = recorder;
|
|
7255
|
-
setMimeType(mt);
|
|
7256
|
-
setBlob(null);
|
|
7257
|
-
accumulatedMsRef.current = 0;
|
|
7258
|
-
segmentStartRef.current = performance.now();
|
|
7259
|
-
recorder.start();
|
|
7260
|
-
setState("recording");
|
|
7261
|
-
startMeter(stream);
|
|
7262
|
-
} catch (err) {
|
|
7263
|
-
stopTracks();
|
|
7264
|
-
setError(classifyMicError(err));
|
|
7265
|
-
}
|
|
7266
|
-
}, [startMeter, stopTracks]);
|
|
7267
|
-
const pause = useCallback(() => {
|
|
7268
|
-
const recorder = mediaRecorderRef.current;
|
|
7269
|
-
if (!recorder || recorder.state !== "recording") return;
|
|
7270
|
-
recorder.pause();
|
|
7271
|
-
accumulatedMsRef.current += performance.now() - segmentStartRef.current;
|
|
7272
|
-
stopMeter();
|
|
7273
|
-
setLevel(0);
|
|
7274
|
-
setState("paused");
|
|
7275
|
-
}, [stopMeter]);
|
|
7276
|
-
const resume = useCallback(() => {
|
|
7277
|
-
const recorder = mediaRecorderRef.current;
|
|
7278
|
-
if (!recorder || recorder.state !== "paused") return;
|
|
7279
|
-
recorder.resume();
|
|
7280
|
-
segmentStartRef.current = performance.now();
|
|
7281
|
-
setState("recording");
|
|
7282
|
-
if (streamRef.current) startMeter(streamRef.current);
|
|
7283
|
-
}, [startMeter]);
|
|
7284
|
-
const stop = useCallback(() => {
|
|
7285
|
-
const recorder = mediaRecorderRef.current;
|
|
7286
|
-
if (!recorder || recorder.state === "inactive") return;
|
|
7287
|
-
const finalElapsed = recorder.state === "paused" ? accumulatedMsRef.current : accumulatedMsRef.current + (performance.now() - segmentStartRef.current);
|
|
7288
|
-
stopMeter();
|
|
7289
|
-
recorder.onstop = () => {
|
|
7290
|
-
stopTracks();
|
|
7291
|
-
const finalBlob = chunksRef.current.length ? new Blob(chunksRef.current, { type: recorder.mimeType }) : null;
|
|
7292
|
-
setBlob(finalBlob);
|
|
7293
|
-
setElapsedMs(finalElapsed);
|
|
7294
|
-
setLevel(0);
|
|
7295
|
-
setState("stopped");
|
|
7296
|
-
};
|
|
7297
|
-
recorder.stop();
|
|
7298
|
-
}, [stopMeter, stopTracks]);
|
|
7299
|
-
const reset = useCallback(() => {
|
|
7300
|
-
setState("idle");
|
|
7301
|
-
setBlob(null);
|
|
7302
|
-
setElapsedMs(0);
|
|
7303
|
-
setLevel(0);
|
|
7304
|
-
setMimeType(null);
|
|
7305
|
-
setError(null);
|
|
7306
|
-
}, []);
|
|
7307
|
-
return { state, level, elapsedMs, blob, mimeType, error, start, pause, resume, stop, reset };
|
|
7308
|
-
}
|
|
7309
|
-
|
|
7310
|
-
// src/documents/format-elapsed.ts
|
|
7311
|
-
function formatElapsed(ms) {
|
|
7312
|
-
const totalSeconds = Math.max(0, Math.floor(ms / 1e3));
|
|
7313
|
-
const minutes = Math.floor(totalSeconds / 60);
|
|
7314
|
-
const seconds = totalSeconds % 60;
|
|
7315
|
-
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
|
|
7316
|
-
}
|
|
7317
|
-
var BAR_WEIGHTS = [
|
|
7318
|
-
0.25,
|
|
7319
|
-
0.32,
|
|
7320
|
-
0.48,
|
|
7321
|
-
0.62,
|
|
7322
|
-
0.82,
|
|
7323
|
-
0.56,
|
|
7324
|
-
0.92,
|
|
7325
|
-
0.72,
|
|
7326
|
-
1,
|
|
7327
|
-
0.86,
|
|
7328
|
-
0.62,
|
|
7329
|
-
0.96,
|
|
7330
|
-
0.76,
|
|
7331
|
-
0.5,
|
|
7332
|
-
0.84,
|
|
7333
|
-
0.66,
|
|
7334
|
-
0.42,
|
|
7335
|
-
0.56,
|
|
7336
|
-
0.36,
|
|
7337
|
-
0.28,
|
|
7338
|
-
0.22
|
|
7339
|
-
];
|
|
7340
|
-
var MIN_BAR_PX = 3;
|
|
7341
|
-
var MAX_BAR_PX = 40;
|
|
7342
|
-
function MicWaveformIndicator({
|
|
7343
|
-
level,
|
|
7344
|
-
elapsedMs,
|
|
7345
|
-
paused = false
|
|
7346
|
-
}) {
|
|
7347
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3", "data-testid": "mic-waveform-indicator", children: [
|
|
7348
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
7349
|
-
/* @__PURE__ */ jsxs("span", { className: "relative flex h-2 w-2", children: [
|
|
7350
|
-
!paused && /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-red-500 opacity-75" }),
|
|
7351
|
-
/* @__PURE__ */ jsx(
|
|
7352
|
-
"span",
|
|
7353
|
-
{
|
|
7354
|
-
className: `relative inline-flex h-2 w-2 rounded-full ${paused ? "bg-muted-foreground" : "bg-red-500"}`
|
|
7355
|
-
}
|
|
7356
|
-
)
|
|
7357
|
-
] }),
|
|
7358
|
-
/* @__PURE__ */ jsx(
|
|
7359
|
-
"span",
|
|
7360
|
-
{
|
|
7361
|
-
className: `text-xs font-semibold uppercase tracking-wide ${paused ? "text-muted-foreground" : "text-red-500"}`,
|
|
7362
|
-
children: paused ? "Paused" : "Rec"
|
|
7363
|
-
}
|
|
7364
|
-
),
|
|
7365
|
-
/* @__PURE__ */ jsx("span", { className: "font-mono text-xs tabular-nums text-muted-foreground", children: formatElapsed(elapsedMs) })
|
|
7366
|
-
] }),
|
|
7367
|
-
/* @__PURE__ */ jsx("div", { className: "flex h-10 items-end gap-[3px]", "data-testid": "mic-waveform-indicator-bars", children: BAR_WEIGHTS.map((weight, i) => /* @__PURE__ */ jsx(
|
|
7368
|
-
"span",
|
|
7369
|
-
{
|
|
7370
|
-
className: "w-1 rounded-full bg-secondary transition-[height] duration-75 ease-out",
|
|
7371
|
-
style: {
|
|
7372
|
-
height: Math.min(MAX_BAR_PX, Math.max(MIN_BAR_PX, level * weight * MAX_BAR_PX))
|
|
7373
|
-
}
|
|
7374
|
-
},
|
|
7375
|
-
i
|
|
7376
|
-
)) })
|
|
7377
|
-
] });
|
|
7378
|
-
}
|
|
7379
7163
|
function VoiceNoteRecorder({
|
|
7380
7164
|
onSave,
|
|
7381
7165
|
onDiscard,
|
|
7382
7166
|
onError,
|
|
7383
|
-
title = "Voice
|
|
7167
|
+
title = "Voice Memo",
|
|
7384
7168
|
isSaving = false,
|
|
7385
7169
|
transcribe
|
|
7386
7170
|
}) {
|
|
@@ -7531,6 +7315,371 @@ function VoiceNoteRecorder({
|
|
|
7531
7315
|
] })
|
|
7532
7316
|
] });
|
|
7533
7317
|
}
|
|
7318
|
+
var AUTO_RENAME_COLORS = { text: "text-amber-700", bg: "bg-amber-500" };
|
|
7319
|
+
function DraftTitleControls({
|
|
7320
|
+
title,
|
|
7321
|
+
onTitleChange,
|
|
7322
|
+
placeholder,
|
|
7323
|
+
autoRename,
|
|
7324
|
+
onAutoRenameChange
|
|
7325
|
+
}) {
|
|
7326
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-shrink-0 items-center gap-1.5", children: [
|
|
7327
|
+
/* @__PURE__ */ jsx(
|
|
7328
|
+
"input",
|
|
7329
|
+
{
|
|
7330
|
+
type: "text",
|
|
7331
|
+
value: title,
|
|
7332
|
+
onChange: (e) => onTitleChange(e.target.value),
|
|
7333
|
+
placeholder,
|
|
7334
|
+
className: "min-w-0 max-w-[220px] rounded-md bg-muted px-2 py-1 text-sm font-medium outline-none focus-visible:ring-1 focus-visible:ring-primary",
|
|
7335
|
+
"data-testid": "draft-title-input"
|
|
7336
|
+
}
|
|
7337
|
+
),
|
|
7338
|
+
/* @__PURE__ */ jsx(
|
|
7339
|
+
IconToggle,
|
|
7340
|
+
{
|
|
7341
|
+
icon: Sparkles,
|
|
7342
|
+
isActive: autoRename,
|
|
7343
|
+
onToggle: onAutoRenameChange,
|
|
7344
|
+
colors: AUTO_RENAME_COLORS,
|
|
7345
|
+
tooltipActive: "Auto-name from content is on \u2014 generates a title once saved",
|
|
7346
|
+
tooltipInactive: "Auto-name from content is off \u2014 uses the name typed above",
|
|
7347
|
+
"data-testid": "draft-auto-rename-toggle"
|
|
7348
|
+
}
|
|
7349
|
+
)
|
|
7350
|
+
] });
|
|
7351
|
+
}
|
|
7352
|
+
function useCameraStream(constraints = { video: true, audio: false }) {
|
|
7353
|
+
const [stream, setStream] = useState(null);
|
|
7354
|
+
const [isStarting, setIsStarting] = useState(false);
|
|
7355
|
+
const [error, setError] = useState(null);
|
|
7356
|
+
const streamRef = useRef(null);
|
|
7357
|
+
const stop = useCallback(() => {
|
|
7358
|
+
streamRef.current?.getTracks().forEach((t) => t.stop());
|
|
7359
|
+
streamRef.current = null;
|
|
7360
|
+
setStream(null);
|
|
7361
|
+
}, []);
|
|
7362
|
+
const constraintsRef = useRef(constraints);
|
|
7363
|
+
constraintsRef.current = constraints;
|
|
7364
|
+
const start = useCallback(async () => {
|
|
7365
|
+
if (streamRef.current) return;
|
|
7366
|
+
setError(null);
|
|
7367
|
+
setIsStarting(true);
|
|
7368
|
+
try {
|
|
7369
|
+
const media = await navigator.mediaDevices.getUserMedia(constraintsRef.current);
|
|
7370
|
+
streamRef.current = media;
|
|
7371
|
+
setStream(media);
|
|
7372
|
+
} catch (err) {
|
|
7373
|
+
setError(classifyMediaError(err, "camera"));
|
|
7374
|
+
} finally {
|
|
7375
|
+
setIsStarting(false);
|
|
7376
|
+
}
|
|
7377
|
+
}, []);
|
|
7378
|
+
useEffect(() => () => stop(), [stop]);
|
|
7379
|
+
return { stream, isStarting, error, start, stop };
|
|
7380
|
+
}
|
|
7381
|
+
var ELAPSED_TICK_MS = 200;
|
|
7382
|
+
function useVideoRecorder(stream) {
|
|
7383
|
+
const [state, setState] = useState("idle");
|
|
7384
|
+
const [elapsedMs, setElapsedMs] = useState(0);
|
|
7385
|
+
const [blob, setBlob] = useState(null);
|
|
7386
|
+
const [mimeType, setMimeType] = useState(null);
|
|
7387
|
+
const mediaRecorderRef = useRef(null);
|
|
7388
|
+
const chunksRef = useRef([]);
|
|
7389
|
+
const startedAtRef = useRef(0);
|
|
7390
|
+
const tickRef = useRef(null);
|
|
7391
|
+
const stateRef = useRef("idle");
|
|
7392
|
+
stateRef.current = state;
|
|
7393
|
+
const stopTicking = useCallback(() => {
|
|
7394
|
+
if (tickRef.current !== null) clearInterval(tickRef.current);
|
|
7395
|
+
tickRef.current = null;
|
|
7396
|
+
}, []);
|
|
7397
|
+
useEffect(() => stopTicking, [stopTicking]);
|
|
7398
|
+
const start = useCallback(() => {
|
|
7399
|
+
if (!stream || stateRef.current === "recording") return;
|
|
7400
|
+
const mt = MediaRecorder.isTypeSupported("video/webm") ? "video/webm" : "video/mp4";
|
|
7401
|
+
const recorder = new MediaRecorder(stream, { mimeType: mt });
|
|
7402
|
+
chunksRef.current = [];
|
|
7403
|
+
recorder.ondataavailable = (e) => {
|
|
7404
|
+
if (e.data.size > 0) chunksRef.current.push(e.data);
|
|
7405
|
+
};
|
|
7406
|
+
mediaRecorderRef.current = recorder;
|
|
7407
|
+
setMimeType(mt);
|
|
7408
|
+
setBlob(null);
|
|
7409
|
+
startedAtRef.current = performance.now();
|
|
7410
|
+
setElapsedMs(0);
|
|
7411
|
+
recorder.start();
|
|
7412
|
+
setState("recording");
|
|
7413
|
+
tickRef.current = setInterval(() => {
|
|
7414
|
+
setElapsedMs(performance.now() - startedAtRef.current);
|
|
7415
|
+
}, ELAPSED_TICK_MS);
|
|
7416
|
+
}, [stream]);
|
|
7417
|
+
const stop = useCallback(() => {
|
|
7418
|
+
const recorder = mediaRecorderRef.current;
|
|
7419
|
+
if (!recorder || recorder.state === "inactive") return;
|
|
7420
|
+
const finalElapsed = performance.now() - startedAtRef.current;
|
|
7421
|
+
stopTicking();
|
|
7422
|
+
recorder.onstop = () => {
|
|
7423
|
+
const finalBlob = chunksRef.current.length ? new Blob(chunksRef.current, { type: recorder.mimeType }) : null;
|
|
7424
|
+
setBlob(finalBlob);
|
|
7425
|
+
setElapsedMs(finalElapsed);
|
|
7426
|
+
setState("stopped");
|
|
7427
|
+
};
|
|
7428
|
+
recorder.stop();
|
|
7429
|
+
}, [stopTicking]);
|
|
7430
|
+
const reset = useCallback(() => {
|
|
7431
|
+
setState("idle");
|
|
7432
|
+
setBlob(null);
|
|
7433
|
+
setElapsedMs(0);
|
|
7434
|
+
setMimeType(null);
|
|
7435
|
+
}, []);
|
|
7436
|
+
return { state, elapsedMs, blob, mimeType, start, stop, reset };
|
|
7437
|
+
}
|
|
7438
|
+
|
|
7439
|
+
// src/documents/capture-frame.ts
|
|
7440
|
+
function captureFrameAsBlob(video, mimeType = "image/png") {
|
|
7441
|
+
return new Promise((resolve, reject) => {
|
|
7442
|
+
const canvas = document.createElement("canvas");
|
|
7443
|
+
canvas.width = video.videoWidth;
|
|
7444
|
+
canvas.height = video.videoHeight;
|
|
7445
|
+
const ctx = canvas.getContext("2d");
|
|
7446
|
+
if (!ctx) {
|
|
7447
|
+
reject(new Error("Canvas 2D context is not available"));
|
|
7448
|
+
return;
|
|
7449
|
+
}
|
|
7450
|
+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
7451
|
+
canvas.toBlob((blob) => {
|
|
7452
|
+
if (blob) resolve(blob);
|
|
7453
|
+
else reject(new Error("Failed to capture the photo"));
|
|
7454
|
+
}, mimeType);
|
|
7455
|
+
});
|
|
7456
|
+
}
|
|
7457
|
+
function PhotoCapture({ onSave, onDiscard, onError, isSaving = false }) {
|
|
7458
|
+
const camera = useCameraStream({ video: true, audio: false });
|
|
7459
|
+
const videoRef = useRef(null);
|
|
7460
|
+
const [capturedBlob, setCapturedBlob] = useState(null);
|
|
7461
|
+
const [captureError, setCaptureError] = useState(null);
|
|
7462
|
+
useEffect(() => {
|
|
7463
|
+
void camera.start();
|
|
7464
|
+
}, []);
|
|
7465
|
+
useEffect(() => {
|
|
7466
|
+
if (camera.error) onError?.(camera.error);
|
|
7467
|
+
}, [camera.error]);
|
|
7468
|
+
useEffect(() => {
|
|
7469
|
+
const video = videoRef.current;
|
|
7470
|
+
if (!video) return;
|
|
7471
|
+
video.srcObject = camera.stream;
|
|
7472
|
+
if (camera.stream) void video.play().catch(() => {
|
|
7473
|
+
});
|
|
7474
|
+
}, [camera.stream]);
|
|
7475
|
+
const handleShutter = () => {
|
|
7476
|
+
const video = videoRef.current;
|
|
7477
|
+
if (!video) return;
|
|
7478
|
+
setCaptureError(null);
|
|
7479
|
+
captureFrameAsBlob(video).then(setCapturedBlob).catch((err) => {
|
|
7480
|
+
const message = err instanceof Error ? err.message : "Failed to capture the photo";
|
|
7481
|
+
setCaptureError(message);
|
|
7482
|
+
onError?.(message);
|
|
7483
|
+
});
|
|
7484
|
+
};
|
|
7485
|
+
const handleRetake = () => setCapturedBlob(null);
|
|
7486
|
+
const handleSave = () => {
|
|
7487
|
+
if (!capturedBlob) return;
|
|
7488
|
+
void onSave(capturedBlob, "image/png");
|
|
7489
|
+
};
|
|
7490
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-6 p-8", children: [
|
|
7491
|
+
!capturedBlob && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7492
|
+
/* @__PURE__ */ jsx("div", { className: "w-full max-w-md overflow-hidden rounded-lg bg-muted/30", children: /* @__PURE__ */ jsx(
|
|
7493
|
+
"video",
|
|
7494
|
+
{
|
|
7495
|
+
ref: videoRef,
|
|
7496
|
+
autoPlay: true,
|
|
7497
|
+
muted: true,
|
|
7498
|
+
playsInline: true,
|
|
7499
|
+
className: "w-full max-h-[60vh] object-contain",
|
|
7500
|
+
"data-testid": "photo-capture-preview"
|
|
7501
|
+
}
|
|
7502
|
+
) }),
|
|
7503
|
+
/* @__PURE__ */ jsx(
|
|
7504
|
+
Button,
|
|
7505
|
+
{
|
|
7506
|
+
type: "button",
|
|
7507
|
+
size: "lg",
|
|
7508
|
+
className: "h-16 w-16 rounded-full p-0",
|
|
7509
|
+
onClick: handleShutter,
|
|
7510
|
+
disabled: !camera.stream,
|
|
7511
|
+
"data-testid": "photo-capture-shutter-button",
|
|
7512
|
+
children: /* @__PURE__ */ jsx(Camera, { className: "h-6 w-6" })
|
|
7513
|
+
}
|
|
7514
|
+
),
|
|
7515
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: camera.isStarting ? "Starting camera\u2026" : camera.stream ? "Press to take a photo" : "Waiting for camera access\u2026" }),
|
|
7516
|
+
captureError && /* @__PURE__ */ jsx("p", { className: "text-sm text-red-text", children: captureError })
|
|
7517
|
+
] }),
|
|
7518
|
+
capturedBlob && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7519
|
+
/* @__PURE__ */ jsx("div", { className: "w-full max-w-md", children: /* @__PURE__ */ jsx(ImageViewer, { blob: capturedBlob, alt: "Captured photo" }) }),
|
|
7520
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
7521
|
+
/* @__PURE__ */ jsxs(
|
|
7522
|
+
Button,
|
|
7523
|
+
{
|
|
7524
|
+
type: "button",
|
|
7525
|
+
variant: "outline",
|
|
7526
|
+
onClick: onDiscard,
|
|
7527
|
+
disabled: isSaving,
|
|
7528
|
+
"data-testid": "photo-capture-discard-button",
|
|
7529
|
+
children: [
|
|
7530
|
+
/* @__PURE__ */ jsx(Trash2, { className: "mr-1.5 h-4 w-4" }),
|
|
7531
|
+
"Discard"
|
|
7532
|
+
]
|
|
7533
|
+
}
|
|
7534
|
+
),
|
|
7535
|
+
/* @__PURE__ */ jsxs(
|
|
7536
|
+
Button,
|
|
7537
|
+
{
|
|
7538
|
+
type: "button",
|
|
7539
|
+
variant: "outline",
|
|
7540
|
+
onClick: handleRetake,
|
|
7541
|
+
disabled: isSaving,
|
|
7542
|
+
"data-testid": "photo-capture-retake-button",
|
|
7543
|
+
children: [
|
|
7544
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "mr-1.5 h-4 w-4" }),
|
|
7545
|
+
"Retake"
|
|
7546
|
+
]
|
|
7547
|
+
}
|
|
7548
|
+
),
|
|
7549
|
+
/* @__PURE__ */ jsxs(
|
|
7550
|
+
Button,
|
|
7551
|
+
{
|
|
7552
|
+
type: "button",
|
|
7553
|
+
onClick: handleSave,
|
|
7554
|
+
disabled: isSaving,
|
|
7555
|
+
"data-testid": "photo-capture-save-button",
|
|
7556
|
+
children: [
|
|
7557
|
+
isSaving ? /* @__PURE__ */ jsx(Loader2, { className: "mr-1.5 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Check, { className: "mr-1.5 h-4 w-4" }),
|
|
7558
|
+
isSaving ? "Saving\u2026" : "Save"
|
|
7559
|
+
]
|
|
7560
|
+
}
|
|
7561
|
+
)
|
|
7562
|
+
] })
|
|
7563
|
+
] })
|
|
7564
|
+
] });
|
|
7565
|
+
}
|
|
7566
|
+
function VideoCapture({ onSave, onDiscard, onError, isSaving = false }) {
|
|
7567
|
+
const camera = useCameraStream({ video: true, audio: true });
|
|
7568
|
+
const recorder = useVideoRecorder(camera.stream);
|
|
7569
|
+
const videoRef = useRef(null);
|
|
7570
|
+
useEffect(() => {
|
|
7571
|
+
void camera.start();
|
|
7572
|
+
}, []);
|
|
7573
|
+
useEffect(() => {
|
|
7574
|
+
if (camera.error) onError?.(camera.error);
|
|
7575
|
+
}, [camera.error]);
|
|
7576
|
+
useEffect(() => {
|
|
7577
|
+
const video = videoRef.current;
|
|
7578
|
+
if (!video || recorder.state === "stopped") return;
|
|
7579
|
+
video.srcObject = camera.stream;
|
|
7580
|
+
if (camera.stream) void video.play().catch(() => {
|
|
7581
|
+
});
|
|
7582
|
+
}, [camera.stream, recorder.state]);
|
|
7583
|
+
const handleRetake = () => {
|
|
7584
|
+
recorder.reset();
|
|
7585
|
+
};
|
|
7586
|
+
const handleSave = () => {
|
|
7587
|
+
if (!recorder.blob) return;
|
|
7588
|
+
void onSave(recorder.blob, recorder.mimeType);
|
|
7589
|
+
};
|
|
7590
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-6 p-8", children: [
|
|
7591
|
+
recorder.state !== "stopped" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7592
|
+
/* @__PURE__ */ jsx("div", { className: "w-full max-w-md overflow-hidden rounded-lg bg-muted/30", children: /* @__PURE__ */ jsx(
|
|
7593
|
+
"video",
|
|
7594
|
+
{
|
|
7595
|
+
ref: videoRef,
|
|
7596
|
+
autoPlay: true,
|
|
7597
|
+
muted: true,
|
|
7598
|
+
playsInline: true,
|
|
7599
|
+
className: "w-full max-h-[60vh] object-contain",
|
|
7600
|
+
"data-testid": "video-capture-preview"
|
|
7601
|
+
}
|
|
7602
|
+
) }),
|
|
7603
|
+
recorder.state === "recording" && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", "data-testid": "video-capture-rec-indicator", children: [
|
|
7604
|
+
/* @__PURE__ */ jsxs("span", { className: "relative flex h-2 w-2", children: [
|
|
7605
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-red-500 opacity-75" }),
|
|
7606
|
+
/* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-red-500" })
|
|
7607
|
+
] }),
|
|
7608
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-wide text-red-500", children: "Rec" }),
|
|
7609
|
+
/* @__PURE__ */ jsx("span", { className: "font-mono text-xs tabular-nums text-muted-foreground", children: formatElapsed(recorder.elapsedMs) })
|
|
7610
|
+
] }),
|
|
7611
|
+
recorder.state === "recording" ? /* @__PURE__ */ jsx(
|
|
7612
|
+
Button,
|
|
7613
|
+
{
|
|
7614
|
+
type: "button",
|
|
7615
|
+
size: "lg",
|
|
7616
|
+
className: "h-16 w-16 rounded-full p-0",
|
|
7617
|
+
onClick: recorder.stop,
|
|
7618
|
+
"data-testid": "video-capture-stop-button",
|
|
7619
|
+
children: /* @__PURE__ */ jsx(Square, { className: "h-5 w-5 fill-current" })
|
|
7620
|
+
}
|
|
7621
|
+
) : /* @__PURE__ */ jsx(
|
|
7622
|
+
Button,
|
|
7623
|
+
{
|
|
7624
|
+
type: "button",
|
|
7625
|
+
size: "lg",
|
|
7626
|
+
className: "h-16 w-16 rounded-full p-0",
|
|
7627
|
+
onClick: recorder.start,
|
|
7628
|
+
disabled: !camera.stream,
|
|
7629
|
+
"data-testid": "video-capture-record-button",
|
|
7630
|
+
children: /* @__PURE__ */ jsx(Circle, { className: "h-6 w-6 fill-current" })
|
|
7631
|
+
}
|
|
7632
|
+
),
|
|
7633
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: recorder.state === "recording" ? "Tap to stop recording" : camera.isStarting ? "Starting camera\u2026" : camera.stream ? "Tap to start recording" : "Waiting for camera access\u2026" })
|
|
7634
|
+
] }),
|
|
7635
|
+
recorder.state === "stopped" && recorder.blob && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7636
|
+
/* @__PURE__ */ jsx("div", { className: "w-full max-w-md", children: /* @__PURE__ */ jsx(VideoViewer, { blob: recorder.blob, title: "Captured video" }) }),
|
|
7637
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
7638
|
+
/* @__PURE__ */ jsxs(
|
|
7639
|
+
Button,
|
|
7640
|
+
{
|
|
7641
|
+
type: "button",
|
|
7642
|
+
variant: "outline",
|
|
7643
|
+
onClick: onDiscard,
|
|
7644
|
+
disabled: isSaving,
|
|
7645
|
+
"data-testid": "video-capture-discard-button",
|
|
7646
|
+
children: [
|
|
7647
|
+
/* @__PURE__ */ jsx(Trash2, { className: "mr-1.5 h-4 w-4" }),
|
|
7648
|
+
"Discard"
|
|
7649
|
+
]
|
|
7650
|
+
}
|
|
7651
|
+
),
|
|
7652
|
+
/* @__PURE__ */ jsxs(
|
|
7653
|
+
Button,
|
|
7654
|
+
{
|
|
7655
|
+
type: "button",
|
|
7656
|
+
variant: "outline",
|
|
7657
|
+
onClick: handleRetake,
|
|
7658
|
+
disabled: isSaving,
|
|
7659
|
+
"data-testid": "video-capture-retake-button",
|
|
7660
|
+
children: [
|
|
7661
|
+
/* @__PURE__ */ jsx(RotateCcw, { className: "mr-1.5 h-4 w-4" }),
|
|
7662
|
+
"Record again"
|
|
7663
|
+
]
|
|
7664
|
+
}
|
|
7665
|
+
),
|
|
7666
|
+
/* @__PURE__ */ jsxs(
|
|
7667
|
+
Button,
|
|
7668
|
+
{
|
|
7669
|
+
type: "button",
|
|
7670
|
+
onClick: handleSave,
|
|
7671
|
+
disabled: isSaving,
|
|
7672
|
+
"data-testid": "video-capture-save-button",
|
|
7673
|
+
children: [
|
|
7674
|
+
isSaving ? /* @__PURE__ */ jsx(Loader2, { className: "mr-1.5 h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Check, { className: "mr-1.5 h-4 w-4" }),
|
|
7675
|
+
isSaving ? "Saving\u2026" : "Save"
|
|
7676
|
+
]
|
|
7677
|
+
}
|
|
7678
|
+
)
|
|
7679
|
+
] })
|
|
7680
|
+
] })
|
|
7681
|
+
] });
|
|
7682
|
+
}
|
|
7534
7683
|
|
|
7535
7684
|
// src/documents/has-video-track.ts
|
|
7536
7685
|
function hasVideoTrack(blob) {
|
|
@@ -7556,6 +7705,6 @@ function hasVideoTrack(blob) {
|
|
|
7556
7705
|
});
|
|
7557
7706
|
}
|
|
7558
7707
|
|
|
7559
|
-
export { ActivityFeed, AgentBadge, AiActionCard, AiAnswer, AppleIcon, ArbiBotHeadIcon, ArbiBotIcon, ArbiChat, ArbiChatPanel, ArbiIcon, ArbiWebSocketProvider, ArtifactCanvas, AudIcon, BASE_COLORS2 as BASE_COLORS, ChatBubble, CitationRenderer, ClaudeIcon, CommandPalette, CommandPaletteProvider, ConversationList, DEFAULT_ASPECT_OPTIONS, DEFAULT_NOTIFY_TONE, DateSeparator, DirectMessages, DmAvatar, DmComposer, DocIcon, DocQaPanel, DocSearch, DocumentCard, DocumentCardMenu, DocumentEntity, DocumentGallery, DocumentReview, DocumentTable, ENTITY_MAPPINGS, EmlIcon, EntityIcon, EntityPill, FILE_TYPE_COLORS, FileIcon, FireworksIcon, GeminiIcon, GitHubIcon, GoogleIcon, HtmlIcon, ImageCropModal, ImageCropper, ImgIcon, LinkedInIcon, MessageArtifactCard, MessageBubble2 as MessageBubble, MessageThread,
|
|
7708
|
+
export { ActivityFeed, AgentBadge, AiActionCard, AiAnswer, AppleIcon, ArbiBotHeadIcon, ArbiBotIcon, ArbiChat, ArbiChatPanel, ArbiIcon, ArbiWebSocketProvider, ArtifactCanvas, AudIcon, BASE_COLORS2 as BASE_COLORS, ChatBubble, CitationRenderer, ClaudeIcon, CommandPalette, CommandPaletteProvider, ConversationList, DEFAULT_ASPECT_OPTIONS, DEFAULT_NOTIFY_TONE, DateSeparator, DirectMessages, DmAvatar, DmComposer, DocIcon, DocQaPanel, DocSearch, DocumentCard, DocumentCardMenu, DocumentEntity, DocumentGallery, DocumentReview, DocumentTable, DraftTitleControls, ENTITY_MAPPINGS, EmlIcon, EntityIcon, EntityPill, FILE_TYPE_COLORS, FileIcon, FireworksIcon, GeminiIcon, GitHubIcon, GoogleIcon, HtmlIcon, ImageCropModal, ImageCropper, ImgIcon, LinkedInIcon, MessageArtifactCard, MessageBubble2 as MessageBubble, MessageThread, NEUTRAL_GRAY2 as NEUTRAL_GRAY, NotificationBell, OpenAIIcon, PLACEHOLDER_COLOR, PassageCard, PdfIcon, PhotoCapture, PresenceLabel, ProjectEntity, ProviderIcon, RUN_WINDOW_MS, RagDot, RelevanceDot, SemanticSearch, StatusPill, TAG_TYPE_ICONS, TAG_TYPE_LABELS, TagEntity, Toaster, TxtIcon, TypingIndicator, UserEntity, UserMenu, VISIBILITY_ICONS, VidIcon, VideoCapture, VisibilityIcon, VoiceNoteRecorder, XlsIcon, annotateThread, arbiQueryKeys, captureFrameAsBlob, configureEntityRegistry, configureRagLabels, configureStatusRegistry, cropImage, dayKey, describeActivity, formatRelativeTime, getDocIcon, getEntityColor2 as getEntityColor, getEntityColorStyles, getEntityIcon, getEntityLabel, getNotificationTypeMeta, getStatusVariant, getTagTypeIcon, getTagTypeLabel, getWorkspaceActionText, getWorkspaceColor, getWorkspaceSentPhrase, hasVideoTrack, isWorkspaceNotificationType, notify, parseActivityContent, redlineStats, seedNotifications, selectUnread, textToArtifact, toRedlineMarkdown, useActivity, useAgents, useAiTask, useArbiConnected, useArbiDocumentSync, useArbiUiStore, useArbiWebSocket, useArbiWsContext, useArbiWsMessage, useArbiWsStatus, useArbiWsStore, useArbiWsTask, useArbiWsTasks, useAssistantQuery, useCameraStream, useCommandPalette, useConfigs, useConversations, useDeleteAgents, useDirectMessages, useDocuments, useFacts, useHealth, useNotify, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSemanticSearch, useSessions, useTags, useTasks, useThumbnails, useUserUsageToday, useVideoRecorder, useWorkspaceDocs, useWorkspaces, userDisplayName, userInitials };
|
|
7560
7709
|
//# sourceMappingURL=index.js.map
|
|
7561
7710
|
//# sourceMappingURL=index.js.map
|