@pipecat-ai/client-react 0.4.0 → 0.4.1
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.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -18
- package/dist/index.js.map +1 -1
- package/dist/index.module.js +24 -18
- package/dist/index.module.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export const RTVIClientAudio: {
|
|
|
16
16
|
(): JSX.Element;
|
|
17
17
|
displayName: string;
|
|
18
18
|
};
|
|
19
|
+
export const useRTVIClientTransportState: () => TransportState;
|
|
19
20
|
/**
|
|
20
21
|
* Hook to control camera state
|
|
21
22
|
*/
|
|
@@ -116,7 +117,6 @@ export const useRTVIClientMediaDevices: () => {
|
|
|
116
117
|
updateMic: (id: string) => void;
|
|
117
118
|
updateSpeaker: (id: string) => void;
|
|
118
119
|
};
|
|
119
|
-
export const useRTVIClientTransportState: () => TransportState;
|
|
120
120
|
type _ParticipantType1 = Parameters<typeof useRTVIClientMediaTrack>[1];
|
|
121
121
|
interface _Props2 {
|
|
122
122
|
backgroundColor?: string;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;AAWA;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,cAAc,CAAC,eAAoB,CAAC,CAAC,OAAO,CAAC,CAAC;CAClE;AAMD,OAAO,MAAM,oBAAoB,MAAM,EAAE,CAAC,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAYvE,CAAC;ACtBF,OAAO,MAAM,2CAGZ,CAAC;ACFF,OAAO,MAAM,qBAAsB,CAAC,SAAS,SAAS,SAC7C,CAAC,WACC,iBAAiB,CAAC,CAAC,SAW7B,CAAC;ACTF,uBAAuB,MAAM,MAAM,CAAC;AACpC,iBAAiB,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;AA4BvC,OAAO,MAAM,qCACA,SAAS,mBACH,eAAe,4BA+DjC,CAAC;ACjGF,OAAO,MAAM;;;CA6BZ,CAAC;
|
|
1
|
+
{"mappings":"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","sources":["client-react/src/src/RTVIClientProvider.tsx","client-react/src/src/useRTVIClient.ts","client-react/src/src/useRTVIClientEvent.ts","client-react/src/src/useRTVIClientMediaTrack.ts","client-react/src/src/RTVIClientAudio.tsx","client-react/src/src/useRTVIClientTransportState.ts","client-react/src/src/useRTVIClientCamControl.ts","client-react/src/src/RTVIClientCamToggle.tsx","client-react/src/src/useRTVIClientMicControl.ts","client-react/src/src/RTVIClientMicToggle.tsx","client-react/src/src/useMergedRef.ts","client-react/src/src/RTVIClientVideo.tsx","client-react/src/src/useRTVIClientMediaDevices.ts","client-react/src/src/VoiceVisualizer.tsx","client-react/src/src/index.ts","client-react/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIClientAudio } from \"./RTVIClientAudio\";\nimport { RTVIClientCamToggle } from \"./RTVIClientCamToggle\";\nimport { RTVIClientMicToggle } from \"./RTVIClientMicToggle\";\nimport { RTVIClientProvider } from \"./RTVIClientProvider\";\nimport { RTVIClientVideo } from \"./RTVIClientVideo\";\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientCamControl } from \"./useRTVIClientCamControl\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { useRTVIClientMediaDevices } from \"./useRTVIClientMediaDevices\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\nimport { useRTVIClientMicControl } from \"./useRTVIClientMicControl\";\nimport { useRTVIClientTransportState } from \"./useRTVIClientTransportState\";\nimport { VoiceVisualizer } from \"./VoiceVisualizer\";\n\nexport {\n RTVIClientAudio,\n RTVIClientCamToggle,\n RTVIClientMicToggle,\n RTVIClientProvider,\n RTVIClientVideo,\n useRTVIClient,\n useRTVIClientCamControl,\n useRTVIClientEvent,\n useRTVIClientMediaDevices,\n useRTVIClientMediaTrack,\n useRTVIClientMicControl,\n useRTVIClientTransportState,\n VoiceVisualizer,\n};\n"],"names":[],"version":3,"file":"index.d.ts.map"}
|
package/dist/index.js
CHANGED
|
@@ -191,15 +191,32 @@ $e6a9aa6ceb34e585$export$ba1245f7cbf3ae02.displayName = "RTVIClientAudio";
|
|
|
191
191
|
|
|
192
192
|
|
|
193
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Copyright (c) 2024, Daily.
|
|
196
|
+
*
|
|
197
|
+
* SPDX-License-Identifier: BSD-2-Clause
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
const $6b6c1a9f794236bd$var$transportStateAtom = (0, $5Zyvw$jotai.atom)("disconnected");
|
|
202
|
+
const $6b6c1a9f794236bd$export$599fa01283bd4ece = ()=>{
|
|
203
|
+
const [transportState, setTransportState] = (0, $5Zyvw$jotai.useAtom)($6b6c1a9f794236bd$var$transportStateAtom);
|
|
204
|
+
(0, $8a6b68ebf0332682$export$33a6ac53b8f02625)((0, $5Zyvw$pipecataiclientjs.RTVIEvent).TransportStateChanged, setTransportState);
|
|
205
|
+
return transportState;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
|
|
194
209
|
const $affd351738e2f16c$export$46099a7ec2fe8ac5 = ()=>{
|
|
195
210
|
const client = (0, $8ee07494475a7fa7$export$31a5f6a22c9b8fba)();
|
|
196
211
|
const [isCamEnabled, setIsCamEnabled] = (0, $5Zyvw$react.useState)(client?.isCamEnabled ?? false);
|
|
212
|
+
const transportState = (0, $6b6c1a9f794236bd$export$599fa01283bd4ece)();
|
|
197
213
|
// Sync component state with client state initially
|
|
198
214
|
(0, $5Zyvw$react.useEffect)(()=>{
|
|
199
|
-
if (!client) return;
|
|
215
|
+
if (!client || transportState !== "initialized" || typeof client.isCamEnabled !== "boolean") return;
|
|
200
216
|
setIsCamEnabled(client.isCamEnabled);
|
|
201
217
|
}, [
|
|
202
|
-
client
|
|
218
|
+
client,
|
|
219
|
+
transportState
|
|
203
220
|
]);
|
|
204
221
|
const enableCam = (0, $5Zyvw$react.useCallback)((enabled)=>{
|
|
205
222
|
setIsCamEnabled(enabled);
|
|
@@ -242,15 +259,18 @@ var $e7a27a30474b270e$export$2e2bcd8739ae039 = $e7a27a30474b270e$export$156c26e1
|
|
|
242
259
|
|
|
243
260
|
|
|
244
261
|
|
|
262
|
+
|
|
245
263
|
const $b5946020fafb75c5$export$805915964ad7bc25 = ()=>{
|
|
246
264
|
const client = (0, $8ee07494475a7fa7$export$31a5f6a22c9b8fba)();
|
|
247
265
|
const [isMicEnabled, setIsMicEnabled] = (0, $5Zyvw$react.useState)(client?.isMicEnabled ?? false);
|
|
266
|
+
const transportState = (0, $6b6c1a9f794236bd$export$599fa01283bd4ece)();
|
|
248
267
|
// Sync component state with client state initially
|
|
249
268
|
(0, $5Zyvw$react.useEffect)(()=>{
|
|
250
|
-
if (!client) return;
|
|
269
|
+
if (!client || transportState !== "initialized" || typeof client.isMicEnabled !== "boolean") return;
|
|
251
270
|
setIsMicEnabled(client.isMicEnabled);
|
|
252
271
|
}, [
|
|
253
|
-
client
|
|
272
|
+
client,
|
|
273
|
+
transportState
|
|
254
274
|
]);
|
|
255
275
|
const enableMic = (0, $5Zyvw$react.useCallback)((enabled)=>{
|
|
256
276
|
setIsMicEnabled(enabled);
|
|
@@ -523,20 +543,6 @@ const $01bcacdf0a25e20c$export$652c54907b83a48d = ()=>{
|
|
|
523
543
|
|
|
524
544
|
|
|
525
545
|
|
|
526
|
-
/**
|
|
527
|
-
* Copyright (c) 2024, Daily.
|
|
528
|
-
*
|
|
529
|
-
* SPDX-License-Identifier: BSD-2-Clause
|
|
530
|
-
*/
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
const $6b6c1a9f794236bd$var$transportStateAtom = (0, $5Zyvw$jotai.atom)("disconnected");
|
|
534
|
-
const $6b6c1a9f794236bd$export$599fa01283bd4ece = ()=>{
|
|
535
|
-
const [transportState, setTransportState] = (0, $5Zyvw$jotai.useAtom)($6b6c1a9f794236bd$var$transportStateAtom);
|
|
536
|
-
(0, $8a6b68ebf0332682$export$33a6ac53b8f02625)((0, $5Zyvw$pipecataiclientjs.RTVIEvent).TransportStateChanged, setTransportState);
|
|
537
|
-
return transportState;
|
|
538
|
-
};
|
|
539
|
-
|
|
540
546
|
|
|
541
547
|
|
|
542
548
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;AEAA;;;;CAIG;ACJH;;;;CAIG;;;;;ACYH,MAAM,qCAAe,CAAA,GAAA,wBAAA;AAEd,MAAM,0DAAoB,CAAA,GAAA,0BAAA,EAAuC,CAAA;AAEjE,MAAM,2CAA+D,CAAC,YAC3E,QAAQ,UACR,MAAM,cACN,aAAa,oCACd;IACC,OACE,CAAA,GAAA,0BAAA,EAAC,CAAA,GAAA,0BAAA,GAAa;QAAC,OAAO;QAAU,UAC9B,CAAA,GAAA,0BAAA,EAAC,0CAAkB,QAAQ,EAAA;YAAC,OAAO;wBAAE;YAAM;YAAE,UAC1C;QAAQ;IACkB;AAGnC;AACA,yCAAmB,WAAW,GAAG;;;ADvB1B,MAAM,4CAAgB;IAC3B,MAAM,UAAE,MAAM,EAAE,GAAG,CAAA,GAAA,uBAAA,EAAW,CAAA,GAAA,yCAAA;IAC9B,OAAO;AACT;;;ADFO,MAAM,4CAAqB,CAChC,OACA;IAEA,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,CAAA,GAAA,sBAAA,EAAU;QACR,IAAI,CAAC,QAAQ;QACb,OAAO,EAAE,CAAC,OAAO;QACjB,OAAO;YACL,OAAO,GAAG,CAAC,OAAO;QACpB;IACF,GAAG;QAAC;QAAO;QAAS;KAAO;AAC7B;;;AGxBA;;;;CAIG;;;;;;AAcH,MAAM,4CAAsB,CAAA,GAAA,iBAAA,EAA8B;AAC1D,MAAM,4CAAsB,CAAA,GAAA,iBAAA,EAA8B;AAC1D,MAAM,kDAA4B,CAAA,GAAA,iBAAA,EAA8B;AAChE,MAAM,kDAA4B,CAAA,GAAA,iBAAA,EAA8B;AAChE,MAAM,0CAAoB,CAAA,GAAA,iBAAA,EAA8B;AACxD,MAAM,0CAAoB,CAAA,GAAA,iBAAA,EAA8B;AAExD,MAAM,kCAAY,CAAA,GAAA,4BAAA,EAGhB,CAAC,SAAE,KAAK,aAAE,SAAS,EAAE;IACrB,IAAI,OACF,OAAQ;QACN,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;IACX;IAEF,OAAO,cAAc,UAAU,0CAAoB;AACrD;AAEO,MAAM,4CAA0B,CACrC,WACA;IAEA,MAAM,SAAS,CAAA,GAAA,yCAAA;IACf,MAAM,QAAQ,CAAA,GAAA,yBAAA,EACZ,gCAAU;QAAE,OAAO,oBAAoB;mBAAS;IAAS;IAG3D,MAAM,cAAc,CAAA,GAAA,iCAAA,EAClB,CAAA,GAAA,wBAAA,EACE,CACE,KACA,KACA,OACA,WACA;QAEA,MAAM,OAAO,gCAAU;mBACrB;uBACA;QACD;QACD,MAAM,WAAW,IAAI;QACrB,IAAI,UAAU,OAAO,MAAM,EAAE,EAAE;QAC/B,IAAI,MAAM;IACZ,GACA,EAAE;IAIN,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,YAAY,EACtB,CAAA,GAAA,wBAAA,EACE,CAAC,OAAyB;QACxB,YACE,OACA,MAAM,IAAiB,EACvB,QAAQ,aAAa;IAEzB,GACA;QAAC;KAAY;IAIjB,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,kBAAkB,EAC5B,CAAA,GAAA,wBAAA,EACE,CAAC,OAAyB;QACxB,MAAM,YACJ,MAAM,IAAI,KAAK,UAAU,gBAAgB;QAC3C,YAAY,OAAO,WAAW,QAAQ,aAAa;IACrD,GACA;QAAC;KAAY;IAIjB,CAAA,GAAA,sBAAA,EAAU;QACR,IAAI,CAAC,QAAQ;QACb,MAAM,SAAS,OAAO,MAAM;QAC5B,MAAM,QAAQ,QAAQ,CAAC,gBAAgB,EAAE,CAAC,UAAU;QACpD,IAAI,CAAC,OAAO;QACZ,YAAY,OAAO,WAAW,oBAAoB;IACpD,GAAG;QAAC;QAAiB;QAAW;QAAa;KAAO;IAEpD,OAAO;AACT;;;AJjGO,MAAM,4CAAkB;IAC7B,MAAM,cAAc,CAAA,GAAA,mBAAA,EAAyB;IAC7C,MAAM,gBAAgB,CAAA,GAAA,yCAAA,EAAwB,SAAS;IAEvD,CAAA,GAAA,sBAAA,EAAU;QACR,IAAI,CAAC,YAAY,OAAO,IAAI,CAAC,eAAe;QAC5C,IAAI,YAAY,OAAO,CAAC,SAAS,EAAE;YACjC,MAAM,WACJ,YAAY,OAAO,CAAC,SACrB,CAAC,cAAc,EAAE,CAAC,EAAE;YACrB,IAAI,SAAS,EAAE,KAAK,cAAc,EAAE,EAAE;QACxC;QACA,YAAY,OAAO,CAAC,SAAS,GAAG,IAAI,YAAY;YAAC;SAAc;IACjE,GAAG;QAAC;KAAc;IAElB,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,cAAc,EACxB,CAAA,GAAA,wBAAA,EAAY,CAAC;QACX,IAAI,CAAC,YAAY,OAAO,EAAE;QAC1B,IAAI,OAAO,YAAY,OAAO,CAAC,SAAS,KAAK,YAAY;QACzD,YAAY,OAAO,CAAC,SAAS,CAAC,QAAQ,QAAQ;IAChD,GAAG,EAAE;IAGP,OACE,CAAA,GAAA,0BAAA,EAAA,CAAA,GAAA,+BAAA,GAAA;QAAA,UACE,CAAA,GAAA,0BAAA,EAAA,SAAA;YAAO,KAAK;YAAa,UAAQ;QAAA;IAAG;AAG1C;AACA,0CAAgB,WAAW,GAAG;;CDtC3B;;;;;AOGI,MAAM,4CAA0B;IACrC,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,MAAM,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,qBAAA,EACtC,QAAQ,gBAAgB;IAG1B,mDAAmD;IACnD,CAAA,GAAA,sBAAA,EAAU;QACR,IAAI,CAAC,QAAQ;QACb,gBAAgB,OAAO,YAAY;IACrC,GAAG;QAAC;KAAO;IAEX,MAAM,YAAY,CAAA,GAAA,wBAAA,EAChB,CAAC;QACC,gBAAgB;QAChB,QAAQ,YAAY;IACtB,GACA;QAAC;KAAO;IAGV,OAAO;mBACL;sBACA;IACD;AACH;;;ADFO,MAAM,4CAA0D,CAAC,uBACtE,mBAAmB,YACnB,WAAW,iBACX,QAAQ,EACT;IACC,MAAM,gBAAE,YAAY,aAAE,SAAS,EAAE,GAAG,CAAA,GAAA,yCAAA;IAEpC,MAAM,kBAAkB,CAAA,GAAA,wBAAA,EAAY;QAClC,IAAI,UAAU;QAEd,MAAM,kBAAkB,CAAC;QACzB,UAAU;QACV,sBAAsB;IACxB,GAAG;QAAC;QAAU;QAAW;QAAc;KAAoB;IAE3D,OACE,CAAA,GAAA,0BAAA,EAAA,CAAA,GAAA,+BAAA,GAAA;QAAA,UACG,SAAS;0BACR;YACA,SAAS;sBACT;QACD;IAAC;AAGR;IAEA,2CAAe;;;;;;;AGjDR,MAAM,4CAA0B;IACrC,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,MAAM,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,qBAAA,EACtC,QAAQ,gBAAgB;IAG1B,mDAAmD;IACnD,CAAA,GAAA,sBAAA,EAAU;QACR,IAAI,CAAC,QAAQ;QACb,gBAAgB,OAAO,YAAY;IACrC,GAAG;QAAC;KAAO;IAEX,MAAM,YAAY,CAAA,GAAA,wBAAA,EAChB,CAAC;QACC,gBAAgB;QAChB,QAAQ,YAAY;IACtB,GACA;QAAC;KAAO;IAGV,OAAO;mBACL;sBACA;IACD;AACH;;;ADFO,MAAM,4CAA0D,CAAC,uBACtE,mBAAmB,YACnB,WAAW,iBACX,QAAQ,EACT;IACC,MAAM,aAAE,SAAS,gBAAE,YAAY,EAAE,GAAG,CAAA,GAAA,yCAAA;IAEpC,MAAM,kBAAkB,CAAA,GAAA,wBAAA,EAAY;QAClC,IAAI,UAAU;QAEd,MAAM,kBAAkB,CAAC;QACzB,UAAU;QACV,sBAAsB;IACxB,GAAG;QAAC;QAAU;QAAW;QAAc;KAAoB;IAE3D,OACE,CAAA,GAAA,0BAAA,EAAA,CAAA,GAAA,+BAAA,GAAA;QAAA,UACG,SAAS;0BACR;YACA,SAAS;sBACT;QACD;IAAC;AAGR;IAEA,2CAAe;;;;;;AGxDf;;;;;;;;;CASG;AAIH,SAAS,mCAAgB,GAAG,IAAoB;IAC9C,OAAO,CAAA,GAAA,wBAAA,EACL,CAAC;QACC,IAAK,IAAI,IAAI,GAAG,IAAI,KAAK,MAAM,EAAE,IAAK;YACpC,MAAM,MAAM,IAAI,CAAC,EAAE;YACnB,IAAI,OAAO,QAAQ,YAAY,IAAI;iBAC9B,IAAI,OAAO,OAAO,QAAQ,UAC5B,IAAkC,OAAO,GAAG;QACjD;IACF,GACA,uDAAuD;IACvD;AAEJ;IAEA,2CAAe;;;;ADcR,MAAM,0DAAkB,CAAA,GAAA,uBAAA,EAC7B,SAAS,iBACP,eACE,cAAc,cACd,MAAM,mBACN,MAAM,YACN,QAAQ,SACR,QAAQ,CAAA,cACR,YAAY,SACZ,GAAG,OACJ,EACD,GAAG;IAEH,MAAM,aAAsC,CAAA,GAAA,yCAAA,EAC1C,WACA;IAGF,MAAM,UAAU,CAAA,GAAA,mBAAA,EAAyB;IACzC,MAAM,WAAW,CAAA,GAAA,wCAAA,EAA+B,SAAS;IAEzD;;KAEG,GACH,CAAA,GAAA,sBAAA,EAAU,SAAS;QACjB,MAAM,QAAQ,QAAQ,OAAO;QAC7B,IAAI,CAAC,OAAO;QAEZ,MAAM,YAAY;YAChB,MAAM,UAAU,MAAM,IAAI;YAC1B,IAAI,YAAY,WACd,QACG,IAAI,CAAC;gBACJ,8BAA8B;gBAC9B,MAAM,QAAQ,GAAG;YACnB,GACC,KAAK,CAAC,CAAC;gBACN,iFAAiF;gBACjF,MAAM,QAAQ,GAAG;gBACjB,QAAQ,IAAI,CAAC,wBAAwB;YACvC;QAEN;QAEA,MAAM,gBAAgB;YACpB,IAAI,CAAC,MAAM,MAAM,EAAE;YACnB;QACF;QACA,MAAM,iBAAiB;YACrB,MAAM,KAAK,CAAC,SAAS,GAAG;QAC1B;QACA,MAAM,iBAAiB;YACrB,MAAM,KAAK,CAAC,SAAS,GAAG;YACxB,WAAW;gBACT,IAAI,MAAM,MAAM,EAAE;YACpB,GAAG;QACL;QACA,MAAM,yBAAyB;YAC7B,IAAI,SAAS,eAAe,KAAK,UAAU;YAC3C,IAAI,CAAC,MAAM,MAAM,EAAE;YACnB;QACF;QACA,MAAM,gBAAgB,CAAC,WAAW;QAClC,MAAM,gBAAgB,CAAC,yBAAyB;QAChD,MAAM,gBAAgB,CAAC,yBAAyB;QAEhD,kEAAkE;QAClE,SAAS,gBAAgB,CAAC,oBAAoB;QAC9C,OAAO;YACL,MAAM,mBAAmB,CAAC,WAAW;YACrC,MAAM,mBAAmB,CAAC,yBAAyB;YACnD,MAAM,mBAAmB,CAAC,yBAAyB;YACnD,SAAS,mBAAmB,CAC1B,oBACA;QAEJ;IACF,GAAG,EAAE;IAEL;;KAEG,GACH,CAAA,GAAA,sBAAA,EACE,SAAS;QACP,MAAM,QAAQ,QAAQ,OAAO;QAC7B,IAAI,CAAC,SAAS,CAAC,YAAY;QAC3B,MAAM,SAAS,GAAG,IAAI,YAAY;YAAC;SAAW;QAC9C,MAAM,IAAI;QACV,OAAO;YACL,0BAA0B;YAC1B,MAAM,SAAS,GAAG;YAClB,MAAM,IAAI;QACZ;IACF,GACA;QAAC;QAAY,YAAY;KAAG;IAG9B;;;KAGG,GACH,CAAA,GAAA,sBAAA,EACE,SAAS;QACP,MAAM,QAAQ,QAAQ,OAAO;QAC7B,IAAI,CAAC,YAAY,CAAC,OAAO;QAEzB,IAAI;QACJ,SAAS;YACP,IAAI,OAAO,qBAAqB;YAChC,QAAQ,sBAAsB;gBAC5B,MAAM,QAAQ,QAAQ,OAAO;gBAC7B,IAAI,CAAC,SAAS,SAAS,MAAM,EAAE;gBAC/B,MAAM,aAAa,MAAM,UAAU;gBACnC,MAAM,cAAc,MAAM,WAAW;gBACrC,IAAI,cAAc,aAChB,WAAW;oBACT,aAAa,aAAa;oBAC1B,QAAQ;oBACR,OAAO;gBACR;YAEL;QACF;QAEA;QACA,MAAM,gBAAgB,CAAC,kBAAkB;QACzC,MAAM,gBAAgB,CAAC,UAAU;QAEjC,OAAO;YACL,IAAI,OAAO,qBAAqB;YAChC,MAAM,mBAAmB,CAAC,kBAAkB;YAC5C,MAAM,mBAAmB,CAAC,UAAU;QACtC;IACF,GACA;QAAC;KAAS;IAGZ,OACE,CAAA,GAAA,0BAAA,EAAA,SAAA;QACE,UAAQ;QACR,OAAK;QACL,aAAW;QACX,KAAK;QACL,OAAO;YACL,WAAW;YACX,WAAW,SAAS,iBAAiB;YACrC,GAAG,KAAK;QACT;QAAA,GACG,KAAK;IAAA;AAGf;AAEF,0CAAgB,WAAW,GAAG;;;;;;;;;;;;AEzL9B,MAAM,0CAAoB,CAAA,GAAA,iBAAA,EAAwB,EAAE;AACpD,MAAM,0CAAoB,CAAA,GAAA,iBAAA,EAAwB,EAAE;AACpD,MAAM,8CAAwB,CAAA,GAAA,iBAAA,EAAwB,EAAE;AACxD,MAAM,wCAAkB,CAAA,GAAA,iBAAA,EAA8B,CAAA;AACtD,MAAM,wCAAkB,CAAA,GAAA,iBAAA,EAA8B,CAAA;AACtD,MAAM,4CAAsB,CAAA,GAAA,iBAAA,EAA8B,CAAA;AAEnD,MAAM,4CAA4B;IACvC,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,MAAM,gBAAgB,CAAA,GAAA,yBAAA,EAAa;IACnC,MAAM,gBAAgB,CAAA,GAAA,yBAAA,EAAa;IACnC,MAAM,oBAAoB,CAAA,GAAA,yBAAA,EAAa;IACvC,MAAM,cAAc,CAAA,GAAA,yBAAA,EAAa;IACjC,MAAM,cAAc,CAAA,GAAA,yBAAA,EAAa;IACjC,MAAM,kBAAkB,CAAA,GAAA,yBAAA,EAAa;IAErC,MAAM,cAAc,CAAA,GAAA,iCAAA,EAClB,CAAA,GAAA,wBAAA,EACE,OAAO,MAAM;QACX,IAAI,CAAC,QAAQ;QAEb,MAAM,gBAAgB,MAAM,OAAO,UAAU;QAC7C,MAAM,gBAAgB,MAAM,OAAO,UAAU;QAC7C,MAAM,oBAAoB,MAAM,OAAO,cAAc;QAErD,IAAI,yCAAmB;QACvB,IAAI,yCAAmB;QACvB,IAAI,6CAAuB;QAE3B,IAAI,uCAAiB,OAAO,WAAW;QACvC,IAAI,uCAAiB,OAAO,WAAW;QACvC,IAAI,2CAAqB,OAAO,eAAe;IACjD,GACA;QAAC;KAAO;IAIZ,CAAA,GAAA,sBAAA,EAAU;QACR;IACF,GAAG;QAAC;KAAY;IAEhB,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,oBAAoB,EAC9B,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,yCAAmB;IACzB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,oBAAoB,EAC9B,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,yCAAmB;IACzB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,wBAAwB,EAClC,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,6CAAuB;IAC7B,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,UAAU,EACpB,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,uCAAiB;IACvB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,UAAU,EACpB,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,uCAAiB;IACvB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,cAAc,EACxB,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,2CAAqB;IAC3B,GAAG,EAAE;IAIT,MAAM,YAAY,CAAA,GAAA,wBAAA,EAChB,CAAC;QACC,QAAQ,UAAU;IACpB,GACA;QAAC;KAAO;IAEV,MAAM,YAAY,CAAA,GAAA,wBAAA,EAChB,CAAC;QACC,QAAQ,UAAU;IACpB,GACA;QAAC;KAAO;IAEV,MAAM,gBAAgB,CAAA,GAAA,wBAAA,EACpB,CAAC;QACC,QAAQ,cAAc;IACxB,GACA;QAAC;KAAO;IAGV,OAAO;uBACL;uBACA;2BACA;qBACA;qBACA;yBACA;mBACA;mBACA;uBACA;IACD;AACH;;;;;ACnIA;;;;CAIG;;;AAOH,MAAM,2CAAqB,CAAA,GAAA,iBAAA,EAAqB;AAEzC,MAAM,4CAA8B;IACzC,MAAM,CAAC,gBAAgB,kBAAkB,GAAG,CAAA,GAAA,oBAAA,EAAQ;IAEpD,CAAA,GAAA,yCAAA,EAAmB,CAAA,GAAA,kCAAA,EAAU,qBAAqB,EAAE;IAEpD,OAAO;AACT;;;;;;ACKO,MAAM,0DAAmC,CAAA,GAAA,sCAAA,EAAM,IAAI,CACxD,CAAC,mBACC,kBAAkB,yBAClB,WAAW,mBACX,WAAW,WACX,SAAS,gBACT,aAAa,uBACb,eAAe,gBACf,YAAY,oBACZ,WAAW,qBACX,eAAe,EAChB;IACC,MAAM,YAAY,CAAA,GAAA,mBAAA,EAA0B;IAE5C,MAAM,QAAiC,CAAA,GAAA,yCAAA,EACrC,SACA;IAGF,CAAA,GAAA,sBAAA,EAAU;QACR,IAAI,CAAC,UAAU,OAAO,EAAE;QAExB,MAAM,cAAc,WAAW,WAAW,AAAC,CAAA,WAAW,CAAA,IAAK;QAC3D,MAAM,eAAe;QAErB,MAAM,SAAS,UAAU,OAAO;QAEhC,MAAM,cAAc;QAEpB,yDAAyD;QACzD,MAAM,eAAe;YACnB,OAAO,KAAK,GAAG,cAAc;YAC7B,OAAO,MAAM,GAAG,eAAe;YAE/B,OAAO,KAAK,CAAC,KAAK,GAAG,GAAG,YAAW,EAAA,CAAI;YACvC,OAAO,KAAK,CAAC,MAAM,GAAG,GAAG,aAAY,EAAA,CAAI;YAEzC,UAAU,OAAO,GAAG;YACpB,UAAU,KAAK,CAAC,aAAa;QAC/B;QAEA,MAAM,YAAY,OAAO,UAAU,CAAC;QACpC;QAEA,IAAI,CAAC,OAAO;QAEZ,MAAM,eAAe,IAAI;QACzB,MAAM,SAAS,aAAa,uBAAuB,CACjD,IAAI,YAAY;YAAC;SAAM;QAEzB,MAAM,WAAW,aAAa,cAAc;QAE5C,SAAS,OAAO,GAAG;QAEnB,OAAO,OAAO,CAAC;QAEf,MAAM,gBAAgB,IAAI,WAAW,SAAS,iBAAiB;QAE/D,UAAU,OAAO,GAAG;QAEpB,2CAA2C;QAC3C,MAAM,QAAQ,MAAM,IAAI,CAAC;YAAE,QAAQ;QAAQ,GAAI,CAAC,GAAG;YACjD,mEAAmE;YACnE,MAAM,UAAU,WAAW,KAAK,MAAM,IAAI,0CAA0C;YACpF,MAAM,UAAU,OAAO,yCAAyC;YAEhE,6EAA6E;YAC7E,gFAAgF;YAChF,0CAA0C;YAC1C,MAAM,SAAS,OAAO,KAAK,KAAK,CAAC,IAAI,UAAU;YAC/C,MAAM,SAAS,OAAO,KAAK,KAAK,CAAC,IAAI,UAAU;YAC/C,MAAM,UAAU,AAAC,CAAA,SAAS,MAAA,IAAU;YAEpC,MAAM,WAAW,SAAS,IAAI;YAC9B,MAAM,YAAY,MAAO,CAAA,KAAK,GAAG,CAAC,IAAI,WAAW,QAAQ,CAAA;YACzD,MAAM,UAAU,MAAO,CAAA,KAAK,GAAG,CAAC,IAAI,AAAC,CAAA,WAAW,OAAA,IAAW,QAAQ,CAAA;YAEnE,OAAO;2BACL;yBACA;gBACA,aAAa;YACd;QACH;QAEA,MAAM,uBAAuB,CAAC;YAC5B,MAAM,UAAU,aAAa,UAAU,GAAG;YAC1C,OAAO,KAAK,KAAK,CACf,AAAC,YAAY,UAAY,CAAA,SAAS,iBAAiB,GAAG,CAAA;QAE1D;QAEA,SAAS;YACP,SAAS,oBAAoB,CAAC;YAC9B,UAAU,SAAS,CACjB,GACA,GACA,OAAO,KAAK,GAAG,aACf,OAAO,MAAM,GAAG;YAElB,UAAU,SAAS,GAAG;YACtB,UAAU,QAAQ,CAChB,GACA,GACA,OAAO,KAAK,GAAG,aACf,OAAO,MAAM,GAAG;YAGlB,IAAI,WAAW;YAEf,MAAM,iBACJ,MAAM,MAAM,GAAG,WAAW,AAAC,CAAA,MAAM,MAAM,GAAG,CAAA,IAAK;YACjD,MAAM,SAAS,AAAC,CAAA,OAAO,KAAK,GAAG,cAAc,cAAA,IAAkB,GAAG,cAAc;YAEhF,MAAM,uBAAuB,WAAW,GAAG,iCAAiC;YAE5E,MAAM,OAAO,CAAC,CAAC,MAAM;gBACnB,MAAM,aAAa,qBAAqB,KAAK,SAAS;gBACtD,MAAM,WAAW,qBAAqB,KAAK,OAAO;gBAClD,MAAM,WAAW,cAAc,KAAK,CAAC,YAAY;gBACjD,MAAM,YACJ,SAAS,MAAM,CAAC,CAAC,KAAK,MAAQ,MAAM,KAAK,KAAK,SAAS,MAAM;gBAE/D,MAAM,kBAAkB;gBAExB,IAAI,YAAY,GACd,KAAK,WAAW,GAAG,KAAK,GAAG,CACzB,KAAK,WAAW,GAAG,kBAAkB,GACrC;qBAEG;oBACL,KAAK,WAAW,GACd,KAAK,WAAW,GAChB,AAAC,CAAA,YAAY,KAAK,WAAW,AAAX,IAAe;oBACnC,WAAW;gBACb;gBAEA,MAAM,IAAI,SAAS,IAAK,CAAA,WAAW,MAAA;gBACnC,0CAA0C;gBAC1C,MAAM,YAAY;gBAClB,MAAM,YAAY,KAAK,GAAG,CACxB,WACA,KAAK,GAAG,CAAC,AAAC,KAAK,WAAW,GAAG,MAAO,cAAc;gBAGpD,IAAI,MAAM;gBACV,MAAM,eAAe,OAAO,MAAM,GAAG;gBAErC,OAAQ;oBACN,KAAK;wBACH,OAAO;wBACP,UAAU,KAAK,GAAG,CAChB,uBAAuB,WACvB,eAAe;wBAEjB;oBACF,KAAK;wBACH,UAAU,eAAe;wBACzB,OAAO,KAAK,GAAG,CAAC,UAAU,WAAW;wBACrC;oBACF,KAAK;oBACL;wBACE,OAAO,KAAK,GAAG,CACb,eAAe,IAAI,YAAY,GAC/B;wBAEF,UAAU,KAAK,GAAG,CAChB,eAAe,IAAI,YAAY,GAC/B,eAAe;wBAEjB;gBACJ;gBAEA,IAAI,KAAK,WAAW,GAAG,GAAG;oBACxB,UAAU,SAAS;oBACnB,UAAU,MAAM,CAAC,IAAI,WAAW,GAAG;oBACnC,UAAU,MAAM,CAAC,IAAI,WAAW,GAAG;oBACnC,UAAU,SAAS,GAAG;oBACtB,UAAU,WAAW,GAAG;oBACxB,UAAU,MAAM;gBAClB,OACE,mBAAmB,sBAAsB,UAAU,GAAG;YAE1D;YAEA,IAAI,CAAC,UACH,oBAAoB,sBAAsB;YAG5C,sBAAsB;QACxB;QAEA,SAAS,mBACP,YAAoB,EACpB,KAAa,EACb,CAAS,EACT,CAAS;YAET,OAAQ;gBACN,KAAK;oBACH,UAAU,SAAS,GAAG;oBACtB,UAAU,QAAQ,CAChB,IAAI,WAAW,IAAI,cACnB,IAAI,cACJ,eAAe,GACf,eAAe;oBAEjB;gBACF,KAAK;gBACL;oBACE,UAAU,SAAS;oBACnB,UAAU,GAAG,CAAC,IAAI,WAAW,GAAG,GAAG,cAAc,GAAG,IAAI,KAAK,EAAE;oBAC/D,UAAU,SAAS,GAAG;oBACtB,UAAU,IAAI;oBACd,UAAU,SAAS;oBACnB;YACJ;QACF;QAEA,SAAS,oBAAoB,YAAoB,EAAE,KAAa;YAC9D,MAAM,iBACJ,MAAM,MAAM,GAAG,WAAW,AAAC,CAAA,MAAM,MAAM,GAAG,CAAA,IAAK;YACjD,MAAM,SAAS,AAAC,CAAA,OAAO,KAAK,GAAG,cAAc,cAAA,IAAkB;YAC/D,MAAM,eAAe,OAAO,MAAM,GAAG;YAErC,IAAI;YACJ,OAAQ;gBACN,KAAK;oBACH,IAAI;oBACJ;gBACF,KAAK;oBACH,IAAI,eAAe;oBACnB;gBACF,KAAK;gBACL;oBACE,IAAI,eAAe;oBACnB;YACJ;YAEA,MAAM,OAAO,CAAC,CAAC,GAAG;gBAChB,MAAM,IAAI,SAAS,IAAK,CAAA,WAAW,MAAA;gBACnC,mBAAmB,cAAc,OAAO,GAAG;YAC7C;QACF;QAEA;QAEA,kBAAkB;QAClB,OAAO,gBAAgB,CAAC,UAAU;QAElC,OAAO;YACL,aAAa,KAAK;YAClB,OAAO,mBAAmB,CAAC,UAAU;QACvC;IACF,GAAG;QACD;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;KACD;IAED,OACE,CAAA,GAAA,0BAAA,EAAA,UAAA;QACE,KAAK;QACL,OAAO;YACL,SAAS;YACT,OAAO;YACP,QAAQ;QACT;IAAA;AAGP;AAGF,0CAAgB,WAAW,GAAG;","sources":["client-react/src/index.ts","client-react/src/RTVIClientAudio.tsx","client-react/src/useRTVIClientEvent.ts","client-react/src/useRTVIClient.ts","client-react/src/RTVIClientProvider.tsx","client-react/src/useRTVIClientMediaTrack.ts","client-react/src/RTVIClientCamToggle.tsx","client-react/src/useRTVIClientCamControl.ts","client-react/src/RTVIClientMicToggle.tsx","client-react/src/useRTVIClientMicControl.ts","client-react/src/RTVIClientVideo.tsx","client-react/src/useMergedRef.ts","client-react/src/useRTVIClientMediaDevices.ts","client-react/src/useRTVIClientTransportState.ts","client-react/src/VoiceVisualizer.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIClientAudio } from \"./RTVIClientAudio\";\nimport { RTVIClientCamToggle } from \"./RTVIClientCamToggle\";\nimport { RTVIClientMicToggle } from \"./RTVIClientMicToggle\";\nimport { RTVIClientProvider } from \"./RTVIClientProvider\";\nimport { RTVIClientVideo } from \"./RTVIClientVideo\";\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientCamControl } from \"./useRTVIClientCamControl\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { useRTVIClientMediaDevices } from \"./useRTVIClientMediaDevices\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\nimport { useRTVIClientMicControl } from \"./useRTVIClientMicControl\";\nimport { useRTVIClientTransportState } from \"./useRTVIClientTransportState\";\nimport { VoiceVisualizer } from \"./VoiceVisualizer\";\n\nexport {\n RTVIClientAudio,\n RTVIClientCamToggle,\n RTVIClientMicToggle,\n RTVIClientProvider,\n RTVIClientVideo,\n useRTVIClient,\n useRTVIClientCamControl,\n useRTVIClientEvent,\n useRTVIClientMediaDevices,\n useRTVIClientMediaTrack,\n useRTVIClientMicControl,\n useRTVIClientTransportState,\n VoiceVisualizer,\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { useCallback, useEffect, useRef } from \"react\";\n\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\nexport const RTVIClientAudio = () => {\n const botAudioRef = useRef<HTMLAudioElement>(null);\n const botAudioTrack = useRTVIClientMediaTrack(\"audio\", \"bot\");\n\n useEffect(() => {\n if (!botAudioRef.current || !botAudioTrack) return;\n if (botAudioRef.current.srcObject) {\n const oldTrack = (\n botAudioRef.current.srcObject as MediaStream\n ).getAudioTracks()[0];\n if (oldTrack.id === botAudioTrack.id) return;\n }\n botAudioRef.current.srcObject = new MediaStream([botAudioTrack]);\n }, [botAudioTrack]);\n\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useCallback((speaker: MediaDeviceInfo) => {\n if (!botAudioRef.current) return;\n if (typeof botAudioRef.current.setSinkId !== \"function\") return;\n botAudioRef.current.setSinkId(speaker.deviceId);\n }, [])\n );\n\n return (\n <>\n <audio ref={botAudioRef} autoPlay />\n </>\n );\n};\nRTVIClientAudio.displayName = \"RTVIClientAudio\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, RTVIEventHandler } from \"@pipecat-ai/client-js\";\nimport { useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\n\nexport const useRTVIClientEvent = <E extends RTVIEvent>(\n event: E,\n handler: RTVIEventHandler<E>\n) => {\n const client = useRTVIClient();\n\n useEffect(() => {\n if (!client) return;\n client.on(event, handler);\n return () => {\n client.off(event, handler);\n };\n }, [event, handler, client]);\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { RTVIClientContext } from \"./RTVIClientProvider\";\n\nexport const useRTVIClient = () => {\n const { client } = useContext(RTVIClientContext);\n return client;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIClient } from \"@pipecat-ai/client-js\";\nimport { createStore } from \"jotai\";\nimport { Provider as JotaiProvider } from \"jotai/react\";\nimport React, { createContext } from \"react\";\n\nexport interface Props {\n client: RTVIClient;\n jotaiStore?: React.ComponentProps<typeof JotaiProvider>[\"store\"];\n}\n\nconst defaultStore = createStore();\n\nexport const RTVIClientContext = createContext<{ client?: RTVIClient }>({});\n\nexport const RTVIClientProvider: React.FC<React.PropsWithChildren<Props>> = ({\n children,\n client,\n jotaiStore = defaultStore,\n}) => {\n return (\n <JotaiProvider store={jotaiStore}>\n <RTVIClientContext.Provider value={{ client }}>\n {children}\n </RTVIClientContext.Provider>\n </JotaiProvider>\n );\n};\nRTVIClientProvider.displayName = \"RTVIClientProvider\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { Participant, RTVIEvent, Tracks } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { atomFamily, useAtomCallback } from \"jotai/utils\";\nimport { PrimitiveAtom } from \"jotai/vanilla\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype ParticipantType = keyof Tracks;\ntype TrackType = keyof Tracks[\"local\"];\n\nconst localAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botVideoTrackAtom = atom<MediaStreamTrack | null>(null);\n\nconst trackAtom = atomFamily<\n { local: boolean; trackType: TrackType },\n PrimitiveAtom<MediaStreamTrack | null>\n>(({ local, trackType }) => {\n if (local) {\n switch (trackType) {\n case \"audio\":\n return localAudioTrackAtom;\n case \"screenAudio\":\n return localScreenAudioTrackAtom;\n case \"screenVideo\":\n return localScreenVideoTrackAtom;\n case \"video\":\n return localVideoTrackAtom;\n }\n }\n return trackType === \"audio\" ? botAudioTrackAtom : botVideoTrackAtom;\n});\n\nexport const useRTVIClientMediaTrack = (\n trackType: TrackType,\n participantType: ParticipantType\n) => {\n const client = useRTVIClient();\n const track = useAtomValue(\n trackAtom({ local: participantType === \"local\", trackType })\n );\n\n const updateTrack = useAtomCallback(\n useCallback(\n (\n get,\n set,\n track: MediaStreamTrack,\n trackType: TrackType,\n local: boolean\n ) => {\n const atom = trackAtom({\n local,\n trackType,\n });\n const oldTrack = get(atom);\n if (oldTrack?.id === track.id) return;\n set(atom, track);\n },\n []\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.TrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n updateTrack(\n track,\n track.kind as TrackType,\n Boolean(participant?.local)\n );\n },\n [updateTrack]\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.ScreenTrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n const trackType =\n track.kind === \"audio\" ? \"screenAudio\" : \"screenVideo\";\n updateTrack(track, trackType, Boolean(participant?.local));\n },\n [updateTrack]\n )\n );\n\n useEffect(() => {\n if (!client) return;\n const tracks = client.tracks();\n const track = tracks?.[participantType]?.[trackType];\n if (!track) return;\n updateTrack(track, trackType, participantType === \"local\");\n }, [participantType, trackType, updateTrack, client]);\n\n return track;\n};\n","import React, { useCallback } from \"react\";\n\nimport { useRTVIClientCamControl } from \"./useRTVIClientCamControl\";\n\nexport interface RTVIClientCamToggleProps {\n /**\n * Callback fired when camera state changes\n */\n onCamEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the cam toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isCamEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling camera state\n */\nexport const RTVIClientCamToggle: React.FC<RTVIClientCamToggleProps> = ({\n onCamEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { isCamEnabled, enableCam } = useRTVIClientCamControl();\n\n const handleToggleCam = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isCamEnabled;\n enableCam(newEnabledState);\n onCamEnabledChanged?.(newEnabledState);\n }, [disabled, enableCam, isCamEnabled, onCamEnabledChanged]);\n\n return (\n <>\n {children({\n isCamEnabled,\n onClick: handleToggleCam,\n disabled,\n })}\n </>\n );\n};\n\nexport default RTVIClientCamToggle;\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\n\n/**\n * Hook to control camera state\n */\nexport const useRTVIClientCamControl = () => {\n const client = useRTVIClient();\n\n const [isCamEnabled, setIsCamEnabled] = useState(\n client?.isCamEnabled ?? false\n );\n\n // Sync component state with client state initially\n useEffect(() => {\n if (!client) return;\n setIsCamEnabled(client.isCamEnabled);\n }, [client]);\n\n const enableCam = useCallback(\n (enabled: boolean) => {\n setIsCamEnabled(enabled);\n client?.enableCam?.(enabled);\n },\n [client]\n );\n\n return {\n enableCam,\n isCamEnabled,\n };\n};\n","import React, { useCallback } from \"react\";\n\nimport { useRTVIClientMicControl } from \"./useRTVIClientMicControl\";\n\nexport interface RTVIClientMicToggleProps {\n /**\n * Callback fired when microphone state changes\n */\n onMicEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the mic toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isMicEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling microphone state\n */\nexport const RTVIClientMicToggle: React.FC<RTVIClientMicToggleProps> = ({\n onMicEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { enableMic, isMicEnabled } = useRTVIClientMicControl();\n\n const handleToggleMic = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isMicEnabled;\n enableMic(newEnabledState);\n onMicEnabledChanged?.(newEnabledState);\n }, [disabled, enableMic, isMicEnabled, onMicEnabledChanged]);\n\n return (\n <>\n {children({\n isMicEnabled,\n onClick: handleToggleMic,\n disabled,\n })}\n </>\n );\n};\n\nexport default RTVIClientMicToggle;\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\n\n/**\n * Hook to control microphone state\n */\nexport const useRTVIClientMicControl = () => {\n const client = useRTVIClient();\n\n const [isMicEnabled, setIsMicEnabled] = useState(\n client?.isMicEnabled ?? false\n );\n\n // Sync component state with client state initially\n useEffect(() => {\n if (!client) return;\n setIsMicEnabled(client.isMicEnabled);\n }, [client]);\n\n const enableMic = useCallback(\n (enabled: boolean) => {\n setIsMicEnabled(enabled);\n client?.enableMic?.(enabled);\n },\n [client]\n );\n\n return {\n enableMic,\n isMicEnabled,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { forwardRef, useEffect, useRef } from \"react\";\n\nimport useMergedRef from \"./useMergedRef\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\ninterface RTVIClientVideoInterface {\n aspectRatio: number;\n height: number;\n width: number;\n}\n\nexport interface Props\n extends Omit<React.VideoHTMLAttributes<HTMLVideoElement>, \"onResize\"> {\n participant: \"local\" | \"bot\";\n\n /**\n * Defines the video track type to display. Default: 'video'.\n */\n trackType?: \"screenVideo\" | \"video\";\n\n /**\n * Defines whether the video should be fully contained or cover the box. Default: 'contain'.\n */\n fit?: \"contain\" | \"cover\";\n /**\n * Forces the video to be mirrored, if set.\n */\n mirror?: boolean;\n\n /**\n * Optional callback, which is triggered whenever the video's rendered width or height changes.\n * Returns the video's native width, height and aspectRatio.\n */\n onResize?(dimensions: RTVIClientVideoInterface): void;\n}\n\nexport const RTVIClientVideo = forwardRef<HTMLVideoElement, Props>(\n function VoiceClientVideo(\n {\n participant = \"local\",\n fit = \"contain\",\n mirror,\n onResize,\n style = {},\n trackType = \"video\",\n ...props\n },\n ref\n ) {\n const videoTrack: MediaStreamTrack | null = useRTVIClientMediaTrack(\n trackType,\n participant\n );\n\n const videoEl = useRef<HTMLVideoElement>(null);\n const videoRef = useMergedRef<HTMLVideoElement>(videoEl, ref);\n\n /**\n * Handle canplay & picture-in-picture events.\n */\n useEffect(function setupVideoEvents() {\n const video = videoEl.current;\n if (!video) return;\n\n const playVideo = () => {\n const promise = video.play();\n if (promise !== undefined) {\n promise\n .then(() => {\n // All good, playback started.\n video.controls = false;\n })\n .catch((error) => {\n // Auto-play was prevented. Show video controls, so user can play video manually.\n video.controls = true;\n console.warn(\"Failed to play video\", error);\n });\n }\n };\n\n const handleCanPlay = () => {\n if (!video.paused) return;\n playVideo();\n };\n const handleEnterPIP = () => {\n video.style.transform = \"scale(1)\";\n };\n const handleLeavePIP = () => {\n video.style.transform = \"\";\n setTimeout(() => {\n if (video.paused) playVideo();\n }, 100);\n };\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"hidden\") return;\n if (!video.paused) return;\n playVideo();\n };\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.addEventListener(\"leavepictureinpicture\", handleLeavePIP);\n\n // Videos can be paused if media was played in another app on iOS.\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n return () => {\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.removeEventListener(\"leavepictureinpicture\", handleLeavePIP);\n document.removeEventListener(\n \"visibilitychange\",\n handleVisibilityChange\n );\n };\n }, []);\n\n /**\n * Update srcObject.\n */\n useEffect(\n function updateSrcObject() {\n const video = videoEl.current;\n if (!video || !videoTrack) return;\n video.srcObject = new MediaStream([videoTrack]);\n video.load();\n return () => {\n // clean up when unmounted\n video.srcObject = null;\n video.load();\n };\n },\n [videoTrack, videoTrack?.id]\n );\n\n /**\n * Add optional event listener for resize event so the parent component\n * can know the video's native aspect ratio.\n */\n useEffect(\n function reportVideoDimensions() {\n const video = videoEl.current;\n if (!onResize || !video) return;\n\n let frame: ReturnType<typeof requestAnimationFrame>;\n function handleResize() {\n if (frame) cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n const video = videoEl.current;\n if (!video || document.hidden) return;\n const videoWidth = video.videoWidth;\n const videoHeight = video.videoHeight;\n if (videoWidth && videoHeight) {\n onResize?.({\n aspectRatio: videoWidth / videoHeight,\n height: videoHeight,\n width: videoWidth,\n });\n }\n });\n }\n\n handleResize();\n video.addEventListener(\"loadedmetadata\", handleResize);\n video.addEventListener(\"resize\", handleResize);\n\n return () => {\n if (frame) cancelAnimationFrame(frame);\n video.removeEventListener(\"loadedmetadata\", handleResize);\n video.removeEventListener(\"resize\", handleResize);\n };\n },\n [onResize]\n );\n\n return (\n <video\n autoPlay\n muted\n playsInline\n ref={videoRef}\n style={{\n objectFit: fit,\n transform: mirror ? \"scale(-1, 1)\" : \"\",\n ...style,\n }}\n {...props}\n />\n );\n }\n);\nRTVIClientVideo.displayName = \"RTVIClientVideo\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n *\n * This file contains code derived from:\n * https://github.com/jaredLunde/react-hook/blob/master/packages/merged-ref/src/index.tsx\n * Original author: Jared Lunde (https://github.com/jaredLunde)\n * Original license: MIT (https://github.com/jaredLunde/react-hook/blob/master/LICENSE)\n */\n\nimport React, { useCallback } from \"react\";\n\nfunction useMergedRef<T>(...refs: React.Ref<T>[]): React.RefCallback<T> {\n return useCallback(\n (element: T) => {\n for (let i = 0; i < refs.length; i++) {\n const ref = refs[i];\n if (typeof ref === \"function\") ref(element);\n else if (ref && typeof ref === \"object\")\n (ref as React.MutableRefObject<T>).current = element;\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n refs\n );\n}\n\nexport default useMergedRef;\n","import { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype OptionalMediaDeviceInfo = MediaDeviceInfo | Record<string, never>;\n\nconst availableMicsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableCamsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableSpeakersAtom = atom<MediaDeviceInfo[]>([]);\nconst selectedMicAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedCamAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedSpeakerAtom = atom<OptionalMediaDeviceInfo>({});\n\nexport const useRTVIClientMediaDevices = () => {\n const client = useRTVIClient();\n\n const availableCams = useAtomValue(availableCamsAtom);\n const availableMics = useAtomValue(availableMicsAtom);\n const availableSpeakers = useAtomValue(availableSpeakersAtom);\n const selectedCam = useAtomValue(selectedCamAtom);\n const selectedMic = useAtomValue(selectedMicAtom);\n const selectedSpeaker = useAtomValue(selectedSpeakerAtom);\n\n const initDevices = useAtomCallback(\n useCallback(\n async (_get, set) => {\n if (!client) return;\n\n const availableCams = await client.getAllCams();\n const availableMics = await client.getAllMics();\n const availableSpeakers = await client.getAllSpeakers();\n\n set(availableCamsAtom, availableCams);\n set(availableMicsAtom, availableMics);\n set(availableSpeakersAtom, availableSpeakers);\n\n set(selectedCamAtom, client.selectedCam);\n set(selectedMicAtom, client.selectedMic);\n set(selectedSpeakerAtom, client.selectedSpeaker);\n },\n [client]\n )\n );\n\n useEffect(() => {\n initDevices();\n }, [initDevices]);\n\n useRTVIClientEvent(\n RTVIEvent.AvailableCamsUpdated,\n useAtomCallback(\n useCallback((_get, set, cams) => {\n set(availableCamsAtom, cams);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableMicsUpdated,\n useAtomCallback(\n useCallback((_get, set, mics) => {\n set(availableMicsAtom, mics);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableSpeakersUpdated,\n useAtomCallback(\n useCallback((_get, set, speakers) => {\n set(availableSpeakersAtom, speakers);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.CamUpdated,\n useAtomCallback(\n useCallback((_get, set, cam) => {\n set(selectedCamAtom, cam);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.MicUpdated,\n useAtomCallback(\n useCallback((_get, set, mic) => {\n set(selectedMicAtom, mic);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useAtomCallback(\n useCallback((_get, set, speaker) => {\n set(selectedSpeakerAtom, speaker);\n }, [])\n )\n );\n\n const updateCam = useCallback(\n (id: string) => {\n client?.updateCam(id);\n },\n [client]\n );\n const updateMic = useCallback(\n (id: string) => {\n client?.updateMic(id);\n },\n [client]\n );\n const updateSpeaker = useCallback(\n (id: string) => {\n client?.updateSpeaker(id);\n },\n [client]\n );\n\n return {\n availableCams,\n availableMics,\n availableSpeakers,\n selectedCam,\n selectedMic,\n selectedSpeaker,\n updateCam,\n updateMic,\n updateSpeaker,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, TransportState } from \"@pipecat-ai/client-js\";\nimport { atom, useAtom } from \"jotai\";\n\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\nconst transportStateAtom = atom<TransportState>(\"disconnected\");\n\nexport const useRTVIClientTransportState = () => {\n const [transportState, setTransportState] = useAtom(transportStateAtom);\n\n useRTVIClientEvent(RTVIEvent.TransportStateChanged, setTransportState);\n\n return transportState;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { useEffect, useRef } from \"react\";\n\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\ntype ParticipantType = Parameters<typeof useRTVIClientMediaTrack>[1];\n\ninterface Props {\n backgroundColor?: string;\n barColor?: string;\n barCount?: number;\n barGap?: number;\n barLineCap?: \"round\" | \"square\";\n barMaxHeight?: number;\n barOrigin?: \"top\" | \"bottom\" | \"center\";\n barWidth?: number;\n participantType: ParticipantType;\n}\n\nexport const VoiceVisualizer: React.FC<Props> = React.memo(\n ({\n backgroundColor = \"transparent\",\n barColor = \"black\",\n barCount = 5,\n barGap = 12,\n barLineCap = \"round\",\n barMaxHeight = 120,\n barOrigin = \"center\",\n barWidth = 30,\n participantType,\n }) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const track: MediaStreamTrack | null = useRTVIClientMediaTrack(\n \"audio\",\n participantType\n );\n\n useEffect(() => {\n if (!canvasRef.current) return;\n\n const canvasWidth = barCount * barWidth + (barCount - 1) * barGap;\n const canvasHeight = barMaxHeight;\n\n const canvas = canvasRef.current;\n\n const scaleFactor = 2;\n\n // Make canvas fill the width and height of its container\n const resizeCanvas = () => {\n canvas.width = canvasWidth * scaleFactor;\n canvas.height = canvasHeight * scaleFactor;\n\n canvas.style.width = `${canvasWidth}px`;\n canvas.style.height = `${canvasHeight}px`;\n\n canvasCtx.lineCap = barLineCap;\n canvasCtx.scale(scaleFactor, scaleFactor);\n };\n\n const canvasCtx = canvas.getContext(\"2d\")!;\n resizeCanvas();\n\n if (!track) return;\n\n const audioContext = new AudioContext();\n const source = audioContext.createMediaStreamSource(\n new MediaStream([track])\n );\n const analyser = audioContext.createAnalyser();\n\n analyser.fftSize = 1024;\n\n source.connect(analyser);\n\n const frequencyData = new Uint8Array(analyser.frequencyBinCount);\n\n canvasCtx.lineCap = barLineCap;\n\n // Create frequency bands based on barCount\n const bands = Array.from({ length: barCount }, (_, i) => {\n // Use improved logarithmic scale for better frequency distribution\n const minFreq = barCount > 20 ? 200 : 80; // Adjust min frequency based on bar count\n const maxFreq = 10000; // Cover most important audio frequencies\n\n // Use Mel scale inspired approach for more perceptually uniform distribution\n // This helps with a large number of bars by placing fewer in the very low range\n // https://en.wikipedia.org/wiki/Mel_scale\n const melMin = 2595 * Math.log10(1 + minFreq / 700);\n const melMax = 2595 * Math.log10(1 + maxFreq / 700);\n const melStep = (melMax - melMin) / barCount;\n\n const melValue = melMin + i * melStep;\n const startFreq = 700 * (Math.pow(10, melValue / 2595) - 1);\n const endFreq = 700 * (Math.pow(10, (melValue + melStep) / 2595) - 1);\n\n return {\n startFreq,\n endFreq,\n smoothValue: 0,\n };\n });\n\n const getFrequencyBinIndex = (frequency: number) => {\n const nyquist = audioContext.sampleRate / 2;\n return Math.round(\n (frequency / nyquist) * (analyser.frequencyBinCount - 1)\n );\n };\n\n function drawSpectrum() {\n analyser.getByteFrequencyData(frequencyData);\n canvasCtx.clearRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n canvasCtx.fillStyle = backgroundColor;\n canvasCtx.fillRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n\n let isActive = false;\n\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2; // Center bars\n\n const adjustedCircleRadius = barWidth / 2; // Fixed radius for reset circles\n\n bands.forEach((band, i) => {\n const startIndex = getFrequencyBinIndex(band.startFreq);\n const endIndex = getFrequencyBinIndex(band.endFreq);\n const bandData = frequencyData.slice(startIndex, endIndex);\n const bandValue =\n bandData.reduce((acc, val) => acc + val, 0) / bandData.length;\n\n const smoothingFactor = 0.2;\n\n if (bandValue < 1) {\n band.smoothValue = Math.max(\n band.smoothValue - smoothingFactor * 5,\n 0\n );\n } else {\n band.smoothValue =\n band.smoothValue +\n (bandValue - band.smoothValue) * smoothingFactor;\n isActive = true;\n }\n\n const x = startX + i * (barWidth + barGap);\n // Calculate bar height with a maximum cap\n const minHeight = 0;\n const barHeight = Math.max(\n minHeight,\n Math.min((band.smoothValue / 255) * barMaxHeight, barMaxHeight)\n );\n\n let yTop, yBottom;\n const canvasHeight = canvas.height / scaleFactor;\n\n switch (barOrigin) {\n case \"top\":\n yTop = adjustedCircleRadius;\n yBottom = Math.min(\n adjustedCircleRadius + barHeight,\n canvasHeight - adjustedCircleRadius\n );\n break;\n case \"bottom\":\n yBottom = canvasHeight - adjustedCircleRadius;\n yTop = Math.max(yBottom - barHeight, adjustedCircleRadius);\n break;\n case \"center\":\n default:\n yTop = Math.max(\n canvasHeight / 2 - barHeight / 2,\n adjustedCircleRadius\n );\n yBottom = Math.min(\n canvasHeight / 2 + barHeight / 2,\n canvasHeight - adjustedCircleRadius\n );\n break;\n }\n\n if (band.smoothValue > 0) {\n canvasCtx.beginPath();\n canvasCtx.moveTo(x + barWidth / 2, yTop);\n canvasCtx.lineTo(x + barWidth / 2, yBottom);\n canvasCtx.lineWidth = barWidth;\n canvasCtx.strokeStyle = barColor;\n canvasCtx.stroke();\n } else {\n drawInactiveCircle(adjustedCircleRadius, barColor, x, yTop);\n }\n });\n\n if (!isActive) {\n drawInactiveCircles(adjustedCircleRadius, barColor);\n }\n\n requestAnimationFrame(drawSpectrum);\n }\n\n function drawInactiveCircle(\n circleRadius: number,\n color: string,\n x: number,\n y: number\n ) {\n switch (barLineCap) {\n case \"square\":\n canvasCtx.fillStyle = color;\n canvasCtx.fillRect(\n x + barWidth / 2 - circleRadius,\n y - circleRadius,\n circleRadius * 2,\n circleRadius * 2\n );\n break;\n case \"round\":\n default:\n canvasCtx.beginPath();\n canvasCtx.arc(x + barWidth / 2, y, circleRadius, 0, 2 * Math.PI);\n canvasCtx.fillStyle = color;\n canvasCtx.fill();\n canvasCtx.closePath();\n break;\n }\n }\n\n function drawInactiveCircles(circleRadius: number, color: string) {\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2;\n const canvasHeight = canvas.height / scaleFactor;\n\n let y;\n switch (barOrigin) {\n case \"top\":\n y = circleRadius;\n break;\n case \"bottom\":\n y = canvasHeight - circleRadius;\n break;\n case \"center\":\n default:\n y = canvasHeight / 2;\n break;\n }\n\n bands.forEach((_, i) => {\n const x = startX + i * (barWidth + barGap);\n drawInactiveCircle(circleRadius, color, x, y);\n });\n }\n\n drawSpectrum();\n\n // Handle resizing\n window.addEventListener(\"resize\", resizeCanvas);\n\n return () => {\n audioContext.close();\n window.removeEventListener(\"resize\", resizeCanvas);\n };\n }, [\n backgroundColor,\n barColor,\n barCount,\n barGap,\n barLineCap,\n barMaxHeight,\n barOrigin,\n barWidth,\n track,\n ]);\n\n return (\n <canvas\n ref={canvasRef}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n }}\n />\n );\n }\n);\n\nVoiceVisualizer.displayName = \"VoiceVisualizer\";\n"],"names":[],"version":3,"file":"index.js.map"}
|
|
1
|
+
{"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;AEAA;;;;CAIG;ACJH;;;;CAIG;;;;;ACYH,MAAM,qCAAe,CAAA,GAAA,wBAAA;AAEd,MAAM,0DAAoB,CAAA,GAAA,0BAAA,EAAuC,CAAA;AAEjE,MAAM,2CAA+D,CAAC,YAC3E,QAAQ,UACR,MAAM,cACN,aAAa,oCACd;IACC,OACE,CAAA,GAAA,0BAAA,EAAC,CAAA,GAAA,0BAAA,GAAa;QAAC,OAAO;QAAU,UAC9B,CAAA,GAAA,0BAAA,EAAC,0CAAkB,QAAQ,EAAA;YAAC,OAAO;wBAAE;YAAM;YAAE,UAC1C;QAAQ;IACkB;AAGnC;AACA,yCAAmB,WAAW,GAAG;;;ADvB1B,MAAM,4CAAgB;IAC3B,MAAM,UAAE,MAAM,EAAE,GAAG,CAAA,GAAA,uBAAA,EAAW,CAAA,GAAA,yCAAA;IAC9B,OAAO;AACT;;;ADFO,MAAM,4CAAqB,CAChC,OACA;IAEA,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,CAAA,GAAA,sBAAA,EAAU;QACR,IAAI,CAAC,QAAQ;QACb,OAAO,EAAE,CAAC,OAAO;QACjB,OAAO;YACL,OAAO,GAAG,CAAC,OAAO;QACpB;IACF,GAAG;QAAC;QAAO;QAAS;KAAO;AAC7B;;;AGxBA;;;;CAIG;;;;;;AAcH,MAAM,4CAAsB,CAAA,GAAA,iBAAA,EAA8B;AAC1D,MAAM,4CAAsB,CAAA,GAAA,iBAAA,EAA8B;AAC1D,MAAM,kDAA4B,CAAA,GAAA,iBAAA,EAA8B;AAChE,MAAM,kDAA4B,CAAA,GAAA,iBAAA,EAA8B;AAChE,MAAM,0CAAoB,CAAA,GAAA,iBAAA,EAA8B;AACxD,MAAM,0CAAoB,CAAA,GAAA,iBAAA,EAA8B;AAExD,MAAM,kCAAY,CAAA,GAAA,4BAAA,EAGhB,CAAC,SAAE,KAAK,aAAE,SAAS,EAAE;IACrB,IAAI,OACF,OAAQ;QACN,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;IACX;IAEF,OAAO,cAAc,UAAU,0CAAoB;AACrD;AAEO,MAAM,4CAA0B,CACrC,WACA;IAEA,MAAM,SAAS,CAAA,GAAA,yCAAA;IACf,MAAM,QAAQ,CAAA,GAAA,yBAAA,EACZ,gCAAU;QAAE,OAAO,oBAAoB;mBAAS;IAAS;IAG3D,MAAM,cAAc,CAAA,GAAA,iCAAA,EAClB,CAAA,GAAA,wBAAA,EACE,CACE,KACA,KACA,OACA,WACA;QAEA,MAAM,OAAO,gCAAU;mBACrB;uBACA;QACD;QACD,MAAM,WAAW,IAAI;QACrB,IAAI,UAAU,OAAO,MAAM,EAAE,EAAE;QAC/B,IAAI,MAAM;IACZ,GACA,EAAE;IAIN,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,YAAY,EACtB,CAAA,GAAA,wBAAA,EACE,CAAC,OAAyB;QACxB,YACE,OACA,MAAM,IAAiB,EACvB,QAAQ,aAAa;IAEzB,GACA;QAAC;KAAY;IAIjB,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,kBAAkB,EAC5B,CAAA,GAAA,wBAAA,EACE,CAAC,OAAyB;QACxB,MAAM,YACJ,MAAM,IAAI,KAAK,UAAU,gBAAgB;QAC3C,YAAY,OAAO,WAAW,QAAQ,aAAa;IACrD,GACA;QAAC;KAAY;IAIjB,CAAA,GAAA,sBAAA,EAAU;QACR,IAAI,CAAC,QAAQ;QACb,MAAM,SAAS,OAAO,MAAM;QAC5B,MAAM,QAAQ,QAAQ,CAAC,gBAAgB,EAAE,CAAC,UAAU;QACpD,IAAI,CAAC,OAAO;QACZ,YAAY,OAAO,WAAW,oBAAoB;IACpD,GAAG;QAAC;QAAiB;QAAW;QAAa;KAAO;IAEpD,OAAO;AACT;;;AJjGO,MAAM,4CAAkB;IAC7B,MAAM,cAAc,CAAA,GAAA,mBAAA,EAAyB;IAC7C,MAAM,gBAAgB,CAAA,GAAA,yCAAA,EAAwB,SAAS;IAEvD,CAAA,GAAA,sBAAA,EAAU;QACR,IAAI,CAAC,YAAY,OAAO,IAAI,CAAC,eAAe;QAC5C,IAAI,YAAY,OAAO,CAAC,SAAS,EAAE;YACjC,MAAM,WACJ,YAAY,OAAO,CAAC,SACrB,CAAC,cAAc,EAAE,CAAC,EAAE;YACrB,IAAI,SAAS,EAAE,KAAK,cAAc,EAAE,EAAE;QACxC;QACA,YAAY,OAAO,CAAC,SAAS,GAAG,IAAI,YAAY;YAAC;SAAc;IACjE,GAAG;QAAC;KAAc;IAElB,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,cAAc,EACxB,CAAA,GAAA,wBAAA,EAAY,CAAC;QACX,IAAI,CAAC,YAAY,OAAO,EAAE;QAC1B,IAAI,OAAO,YAAY,OAAO,CAAC,SAAS,KAAK,YAAY;QACzD,YAAY,OAAO,CAAC,SAAS,CAAC,QAAQ,QAAQ;IAChD,GAAG,EAAE;IAGP,OACE,CAAA,GAAA,0BAAA,EAAA,CAAA,GAAA,+BAAA,GAAA;QAAA,UACE,CAAA,GAAA,0BAAA,EAAA,SAAA;YAAO,KAAK;YAAa,UAAQ;QAAA;IAAG;AAG1C;AACA,0CAAgB,WAAW,GAAG;;CDtC3B;;;;;AQJH;;;;CAIG;;;AAOH,MAAM,2CAAqB,CAAA,GAAA,iBAAA,EAAqB;AAEzC,MAAM,4CAA8B;IACzC,MAAM,CAAC,gBAAgB,kBAAkB,GAAG,CAAA,GAAA,oBAAA,EAAQ;IAEpD,CAAA,GAAA,yCAAA,EAAmB,CAAA,GAAA,kCAAA,EAAU,qBAAqB,EAAE;IAEpD,OAAO;AACT;;;ADXO,MAAM,4CAA0B;IACrC,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,MAAM,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,qBAAA,EACtC,QAAQ,gBAAgB;IAG1B,MAAM,iBAAiB,CAAA,GAAA,yCAAA;IAEvB,mDAAmD;IACnD,CAAA,GAAA,sBAAA,EAAU;QACR,IACE,CAAC,UACD,mBAAmB,iBACnB,OAAO,OAAO,YAAY,KAAK,WAE/B;QACF,gBAAgB,OAAO,YAAY;IACrC,GAAG;QAAC;QAAQ;KAAe;IAE3B,MAAM,YAAY,CAAA,GAAA,wBAAA,EAChB,CAAC;QACC,gBAAgB;QAChB,QAAQ,YAAY;IACtB,GACA;QAAC;KAAO;IAGV,OAAO;mBACL;sBACA;IACD;AACH;;;ADVO,MAAM,4CAA0D,CAAC,uBACtE,mBAAmB,YACnB,WAAW,iBACX,QAAQ,EACT;IACC,MAAM,gBAAE,YAAY,aAAE,SAAS,EAAE,GAAG,CAAA,GAAA,yCAAA;IAEpC,MAAM,kBAAkB,CAAA,GAAA,wBAAA,EAAY;QAClC,IAAI,UAAU;QAEd,MAAM,kBAAkB,CAAC;QACzB,UAAU;QACV,sBAAsB;IACxB,GAAG;QAAC;QAAU;QAAW;QAAc;KAAoB;IAE3D,OACE,CAAA,GAAA,0BAAA,EAAA,CAAA,GAAA,+BAAA,GAAA;QAAA,UACG,SAAS;0BACR;YACA,SAAS;sBACT;QACD;IAAC;AAGR;IAEA,2CAAe;;;;;;;;AIhDR,MAAM,4CAA0B;IACrC,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,MAAM,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,qBAAA,EACtC,QAAQ,gBAAgB;IAG1B,MAAM,iBAAiB,CAAA,GAAA,yCAAA;IAEvB,mDAAmD;IACnD,CAAA,GAAA,sBAAA,EAAU;QACR,IACE,CAAC,UACD,mBAAmB,iBACnB,OAAO,OAAO,YAAY,KAAK,WAE/B;QACF,gBAAgB,OAAO,YAAY;IACrC,GAAG;QAAC;QAAQ;KAAe;IAE3B,MAAM,YAAY,CAAA,GAAA,wBAAA,EAChB,CAAC;QACC,gBAAgB;QAChB,QAAQ,YAAY;IACtB,GACA;QAAC;KAAO;IAGV,OAAO;mBACL;sBACA;IACD;AACH;;;ADVO,MAAM,4CAA0D,CAAC,uBACtE,mBAAmB,YACnB,WAAW,iBACX,QAAQ,EACT;IACC,MAAM,aAAE,SAAS,gBAAE,YAAY,EAAE,GAAG,CAAA,GAAA,yCAAA;IAEpC,MAAM,kBAAkB,CAAA,GAAA,wBAAA,EAAY;QAClC,IAAI,UAAU;QAEd,MAAM,kBAAkB,CAAC;QACzB,UAAU;QACV,sBAAsB;IACxB,GAAG;QAAC;QAAU;QAAW;QAAc;KAAoB;IAE3D,OACE,CAAA,GAAA,0BAAA,EAAA,CAAA,GAAA,+BAAA,GAAA;QAAA,UACG,SAAS;0BACR;YACA,SAAS;sBACT;QACD;IAAC;AAGR;IAEA,2CAAe;;;;;;AGxDf;;;;;;;;;CASG;AAIH,SAAS,mCAAgB,GAAG,IAAoB;IAC9C,OAAO,CAAA,GAAA,wBAAA,EACL,CAAC;QACC,IAAK,IAAI,IAAI,GAAG,IAAI,KAAK,MAAM,EAAE,IAAK;YACpC,MAAM,MAAM,IAAI,CAAC,EAAE;YACnB,IAAI,OAAO,QAAQ,YAAY,IAAI;iBAC9B,IAAI,OAAO,OAAO,QAAQ,UAC5B,IAAkC,OAAO,GAAG;QACjD;IACF,GACA,uDAAuD;IACvD;AAEJ;IAEA,2CAAe;;;;ADcR,MAAM,0DAAkB,CAAA,GAAA,uBAAA,EAC7B,SAAS,iBACP,eACE,cAAc,cACd,MAAM,mBACN,MAAM,YACN,QAAQ,SACR,QAAQ,CAAA,cACR,YAAY,SACZ,GAAG,OACJ,EACD,GAAG;IAEH,MAAM,aAAsC,CAAA,GAAA,yCAAA,EAC1C,WACA;IAGF,MAAM,UAAU,CAAA,GAAA,mBAAA,EAAyB;IACzC,MAAM,WAAW,CAAA,GAAA,wCAAA,EAA+B,SAAS;IAEzD;;KAEG,GACH,CAAA,GAAA,sBAAA,EAAU,SAAS;QACjB,MAAM,QAAQ,QAAQ,OAAO;QAC7B,IAAI,CAAC,OAAO;QAEZ,MAAM,YAAY;YAChB,MAAM,UAAU,MAAM,IAAI;YAC1B,IAAI,YAAY,WACd,QACG,IAAI,CAAC;gBACJ,8BAA8B;gBAC9B,MAAM,QAAQ,GAAG;YACnB,GACC,KAAK,CAAC,CAAC;gBACN,iFAAiF;gBACjF,MAAM,QAAQ,GAAG;gBACjB,QAAQ,IAAI,CAAC,wBAAwB;YACvC;QAEN;QAEA,MAAM,gBAAgB;YACpB,IAAI,CAAC,MAAM,MAAM,EAAE;YACnB;QACF;QACA,MAAM,iBAAiB;YACrB,MAAM,KAAK,CAAC,SAAS,GAAG;QAC1B;QACA,MAAM,iBAAiB;YACrB,MAAM,KAAK,CAAC,SAAS,GAAG;YACxB,WAAW;gBACT,IAAI,MAAM,MAAM,EAAE;YACpB,GAAG;QACL;QACA,MAAM,yBAAyB;YAC7B,IAAI,SAAS,eAAe,KAAK,UAAU;YAC3C,IAAI,CAAC,MAAM,MAAM,EAAE;YACnB;QACF;QACA,MAAM,gBAAgB,CAAC,WAAW;QAClC,MAAM,gBAAgB,CAAC,yBAAyB;QAChD,MAAM,gBAAgB,CAAC,yBAAyB;QAEhD,kEAAkE;QAClE,SAAS,gBAAgB,CAAC,oBAAoB;QAC9C,OAAO;YACL,MAAM,mBAAmB,CAAC,WAAW;YACrC,MAAM,mBAAmB,CAAC,yBAAyB;YACnD,MAAM,mBAAmB,CAAC,yBAAyB;YACnD,SAAS,mBAAmB,CAC1B,oBACA;QAEJ;IACF,GAAG,EAAE;IAEL;;KAEG,GACH,CAAA,GAAA,sBAAA,EACE,SAAS;QACP,MAAM,QAAQ,QAAQ,OAAO;QAC7B,IAAI,CAAC,SAAS,CAAC,YAAY;QAC3B,MAAM,SAAS,GAAG,IAAI,YAAY;YAAC;SAAW;QAC9C,MAAM,IAAI;QACV,OAAO;YACL,0BAA0B;YAC1B,MAAM,SAAS,GAAG;YAClB,MAAM,IAAI;QACZ;IACF,GACA;QAAC;QAAY,YAAY;KAAG;IAG9B;;;KAGG,GACH,CAAA,GAAA,sBAAA,EACE,SAAS;QACP,MAAM,QAAQ,QAAQ,OAAO;QAC7B,IAAI,CAAC,YAAY,CAAC,OAAO;QAEzB,IAAI;QACJ,SAAS;YACP,IAAI,OAAO,qBAAqB;YAChC,QAAQ,sBAAsB;gBAC5B,MAAM,QAAQ,QAAQ,OAAO;gBAC7B,IAAI,CAAC,SAAS,SAAS,MAAM,EAAE;gBAC/B,MAAM,aAAa,MAAM,UAAU;gBACnC,MAAM,cAAc,MAAM,WAAW;gBACrC,IAAI,cAAc,aAChB,WAAW;oBACT,aAAa,aAAa;oBAC1B,QAAQ;oBACR,OAAO;gBACR;YAEL;QACF;QAEA;QACA,MAAM,gBAAgB,CAAC,kBAAkB;QACzC,MAAM,gBAAgB,CAAC,UAAU;QAEjC,OAAO;YACL,IAAI,OAAO,qBAAqB;YAChC,MAAM,mBAAmB,CAAC,kBAAkB;YAC5C,MAAM,mBAAmB,CAAC,UAAU;QACtC;IACF,GACA;QAAC;KAAS;IAGZ,OACE,CAAA,GAAA,0BAAA,EAAA,SAAA;QACE,UAAQ;QACR,OAAK;QACL,aAAW;QACX,KAAK;QACL,OAAO;YACL,WAAW;YACX,WAAW,SAAS,iBAAiB;YACrC,GAAG,KAAK;QACT;QAAA,GACG,KAAK;IAAA;AAGf;AAEF,0CAAgB,WAAW,GAAG;;;;;;;;;;;;AEzL9B,MAAM,0CAAoB,CAAA,GAAA,iBAAA,EAAwB,EAAE;AACpD,MAAM,0CAAoB,CAAA,GAAA,iBAAA,EAAwB,EAAE;AACpD,MAAM,8CAAwB,CAAA,GAAA,iBAAA,EAAwB,EAAE;AACxD,MAAM,wCAAkB,CAAA,GAAA,iBAAA,EAA8B,CAAA;AACtD,MAAM,wCAAkB,CAAA,GAAA,iBAAA,EAA8B,CAAA;AACtD,MAAM,4CAAsB,CAAA,GAAA,iBAAA,EAA8B,CAAA;AAEnD,MAAM,4CAA4B;IACvC,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,MAAM,gBAAgB,CAAA,GAAA,yBAAA,EAAa;IACnC,MAAM,gBAAgB,CAAA,GAAA,yBAAA,EAAa;IACnC,MAAM,oBAAoB,CAAA,GAAA,yBAAA,EAAa;IACvC,MAAM,cAAc,CAAA,GAAA,yBAAA,EAAa;IACjC,MAAM,cAAc,CAAA,GAAA,yBAAA,EAAa;IACjC,MAAM,kBAAkB,CAAA,GAAA,yBAAA,EAAa;IAErC,MAAM,cAAc,CAAA,GAAA,iCAAA,EAClB,CAAA,GAAA,wBAAA,EACE,OAAO,MAAM;QACX,IAAI,CAAC,QAAQ;QAEb,MAAM,gBAAgB,MAAM,OAAO,UAAU;QAC7C,MAAM,gBAAgB,MAAM,OAAO,UAAU;QAC7C,MAAM,oBAAoB,MAAM,OAAO,cAAc;QAErD,IAAI,yCAAmB;QACvB,IAAI,yCAAmB;QACvB,IAAI,6CAAuB;QAE3B,IAAI,uCAAiB,OAAO,WAAW;QACvC,IAAI,uCAAiB,OAAO,WAAW;QACvC,IAAI,2CAAqB,OAAO,eAAe;IACjD,GACA;QAAC;KAAO;IAIZ,CAAA,GAAA,sBAAA,EAAU;QACR;IACF,GAAG;QAAC;KAAY;IAEhB,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,oBAAoB,EAC9B,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,yCAAmB;IACzB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,oBAAoB,EAC9B,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,yCAAmB;IACzB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,wBAAwB,EAClC,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,6CAAuB;IAC7B,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,UAAU,EACpB,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,uCAAiB;IACvB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,UAAU,EACpB,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,uCAAiB;IACvB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,kCAAA,EAAU,cAAc,EACxB,CAAA,GAAA,iCAAA,EACE,CAAA,GAAA,wBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,2CAAqB;IAC3B,GAAG,EAAE;IAIT,MAAM,YAAY,CAAA,GAAA,wBAAA,EAChB,CAAC;QACC,QAAQ,UAAU;IACpB,GACA;QAAC;KAAO;IAEV,MAAM,YAAY,CAAA,GAAA,wBAAA,EAChB,CAAC;QACC,QAAQ,UAAU;IACpB,GACA;QAAC;KAAO;IAEV,MAAM,gBAAgB,CAAA,GAAA,wBAAA,EACpB,CAAC;QACC,QAAQ,cAAc;IACxB,GACA;QAAC;KAAO;IAGV,OAAO;uBACL;uBACA;2BACA;qBACA;qBACA;yBACA;mBACA;mBACA;uBACA;IACD;AACH;;;;;;;;;AC3GO,MAAM,0DAAmC,CAAA,GAAA,sCAAA,EAAM,IAAI,CACxD,CAAC,mBACC,kBAAkB,yBAClB,WAAW,mBACX,WAAW,WACX,SAAS,gBACT,aAAa,uBACb,eAAe,gBACf,YAAY,oBACZ,WAAW,qBACX,eAAe,EAChB;IACC,MAAM,YAAY,CAAA,GAAA,mBAAA,EAA0B;IAE5C,MAAM,QAAiC,CAAA,GAAA,yCAAA,EACrC,SACA;IAGF,CAAA,GAAA,sBAAA,EAAU;QACR,IAAI,CAAC,UAAU,OAAO,EAAE;QAExB,MAAM,cAAc,WAAW,WAAW,AAAC,CAAA,WAAW,CAAA,IAAK;QAC3D,MAAM,eAAe;QAErB,MAAM,SAAS,UAAU,OAAO;QAEhC,MAAM,cAAc;QAEpB,yDAAyD;QACzD,MAAM,eAAe;YACnB,OAAO,KAAK,GAAG,cAAc;YAC7B,OAAO,MAAM,GAAG,eAAe;YAE/B,OAAO,KAAK,CAAC,KAAK,GAAG,GAAG,YAAW,EAAA,CAAI;YACvC,OAAO,KAAK,CAAC,MAAM,GAAG,GAAG,aAAY,EAAA,CAAI;YAEzC,UAAU,OAAO,GAAG;YACpB,UAAU,KAAK,CAAC,aAAa;QAC/B;QAEA,MAAM,YAAY,OAAO,UAAU,CAAC;QACpC;QAEA,IAAI,CAAC,OAAO;QAEZ,MAAM,eAAe,IAAI;QACzB,MAAM,SAAS,aAAa,uBAAuB,CACjD,IAAI,YAAY;YAAC;SAAM;QAEzB,MAAM,WAAW,aAAa,cAAc;QAE5C,SAAS,OAAO,GAAG;QAEnB,OAAO,OAAO,CAAC;QAEf,MAAM,gBAAgB,IAAI,WAAW,SAAS,iBAAiB;QAE/D,UAAU,OAAO,GAAG;QAEpB,2CAA2C;QAC3C,MAAM,QAAQ,MAAM,IAAI,CAAC;YAAE,QAAQ;QAAQ,GAAI,CAAC,GAAG;YACjD,mEAAmE;YACnE,MAAM,UAAU,WAAW,KAAK,MAAM,IAAI,0CAA0C;YACpF,MAAM,UAAU,OAAO,yCAAyC;YAEhE,6EAA6E;YAC7E,gFAAgF;YAChF,0CAA0C;YAC1C,MAAM,SAAS,OAAO,KAAK,KAAK,CAAC,IAAI,UAAU;YAC/C,MAAM,SAAS,OAAO,KAAK,KAAK,CAAC,IAAI,UAAU;YAC/C,MAAM,UAAU,AAAC,CAAA,SAAS,MAAA,IAAU;YAEpC,MAAM,WAAW,SAAS,IAAI;YAC9B,MAAM,YAAY,MAAO,CAAA,KAAK,GAAG,CAAC,IAAI,WAAW,QAAQ,CAAA;YACzD,MAAM,UAAU,MAAO,CAAA,KAAK,GAAG,CAAC,IAAI,AAAC,CAAA,WAAW,OAAA,IAAW,QAAQ,CAAA;YAEnE,OAAO;2BACL;yBACA;gBACA,aAAa;YACd;QACH;QAEA,MAAM,uBAAuB,CAAC;YAC5B,MAAM,UAAU,aAAa,UAAU,GAAG;YAC1C,OAAO,KAAK,KAAK,CACf,AAAC,YAAY,UAAY,CAAA,SAAS,iBAAiB,GAAG,CAAA;QAE1D;QAEA,SAAS;YACP,SAAS,oBAAoB,CAAC;YAC9B,UAAU,SAAS,CACjB,GACA,GACA,OAAO,KAAK,GAAG,aACf,OAAO,MAAM,GAAG;YAElB,UAAU,SAAS,GAAG;YACtB,UAAU,QAAQ,CAChB,GACA,GACA,OAAO,KAAK,GAAG,aACf,OAAO,MAAM,GAAG;YAGlB,IAAI,WAAW;YAEf,MAAM,iBACJ,MAAM,MAAM,GAAG,WAAW,AAAC,CAAA,MAAM,MAAM,GAAG,CAAA,IAAK;YACjD,MAAM,SAAS,AAAC,CAAA,OAAO,KAAK,GAAG,cAAc,cAAA,IAAkB,GAAG,cAAc;YAEhF,MAAM,uBAAuB,WAAW,GAAG,iCAAiC;YAE5E,MAAM,OAAO,CAAC,CAAC,MAAM;gBACnB,MAAM,aAAa,qBAAqB,KAAK,SAAS;gBACtD,MAAM,WAAW,qBAAqB,KAAK,OAAO;gBAClD,MAAM,WAAW,cAAc,KAAK,CAAC,YAAY;gBACjD,MAAM,YACJ,SAAS,MAAM,CAAC,CAAC,KAAK,MAAQ,MAAM,KAAK,KAAK,SAAS,MAAM;gBAE/D,MAAM,kBAAkB;gBAExB,IAAI,YAAY,GACd,KAAK,WAAW,GAAG,KAAK,GAAG,CACzB,KAAK,WAAW,GAAG,kBAAkB,GACrC;qBAEG;oBACL,KAAK,WAAW,GACd,KAAK,WAAW,GAChB,AAAC,CAAA,YAAY,KAAK,WAAW,AAAX,IAAe;oBACnC,WAAW;gBACb;gBAEA,MAAM,IAAI,SAAS,IAAK,CAAA,WAAW,MAAA;gBACnC,0CAA0C;gBAC1C,MAAM,YAAY;gBAClB,MAAM,YAAY,KAAK,GAAG,CACxB,WACA,KAAK,GAAG,CAAC,AAAC,KAAK,WAAW,GAAG,MAAO,cAAc;gBAGpD,IAAI,MAAM;gBACV,MAAM,eAAe,OAAO,MAAM,GAAG;gBAErC,OAAQ;oBACN,KAAK;wBACH,OAAO;wBACP,UAAU,KAAK,GAAG,CAChB,uBAAuB,WACvB,eAAe;wBAEjB;oBACF,KAAK;wBACH,UAAU,eAAe;wBACzB,OAAO,KAAK,GAAG,CAAC,UAAU,WAAW;wBACrC;oBACF,KAAK;oBACL;wBACE,OAAO,KAAK,GAAG,CACb,eAAe,IAAI,YAAY,GAC/B;wBAEF,UAAU,KAAK,GAAG,CAChB,eAAe,IAAI,YAAY,GAC/B,eAAe;wBAEjB;gBACJ;gBAEA,IAAI,KAAK,WAAW,GAAG,GAAG;oBACxB,UAAU,SAAS;oBACnB,UAAU,MAAM,CAAC,IAAI,WAAW,GAAG;oBACnC,UAAU,MAAM,CAAC,IAAI,WAAW,GAAG;oBACnC,UAAU,SAAS,GAAG;oBACtB,UAAU,WAAW,GAAG;oBACxB,UAAU,MAAM;gBAClB,OACE,mBAAmB,sBAAsB,UAAU,GAAG;YAE1D;YAEA,IAAI,CAAC,UACH,oBAAoB,sBAAsB;YAG5C,sBAAsB;QACxB;QAEA,SAAS,mBACP,YAAoB,EACpB,KAAa,EACb,CAAS,EACT,CAAS;YAET,OAAQ;gBACN,KAAK;oBACH,UAAU,SAAS,GAAG;oBACtB,UAAU,QAAQ,CAChB,IAAI,WAAW,IAAI,cACnB,IAAI,cACJ,eAAe,GACf,eAAe;oBAEjB;gBACF,KAAK;gBACL;oBACE,UAAU,SAAS;oBACnB,UAAU,GAAG,CAAC,IAAI,WAAW,GAAG,GAAG,cAAc,GAAG,IAAI,KAAK,EAAE;oBAC/D,UAAU,SAAS,GAAG;oBACtB,UAAU,IAAI;oBACd,UAAU,SAAS;oBACnB;YACJ;QACF;QAEA,SAAS,oBAAoB,YAAoB,EAAE,KAAa;YAC9D,MAAM,iBACJ,MAAM,MAAM,GAAG,WAAW,AAAC,CAAA,MAAM,MAAM,GAAG,CAAA,IAAK;YACjD,MAAM,SAAS,AAAC,CAAA,OAAO,KAAK,GAAG,cAAc,cAAA,IAAkB;YAC/D,MAAM,eAAe,OAAO,MAAM,GAAG;YAErC,IAAI;YACJ,OAAQ;gBACN,KAAK;oBACH,IAAI;oBACJ;gBACF,KAAK;oBACH,IAAI,eAAe;oBACnB;gBACF,KAAK;gBACL;oBACE,IAAI,eAAe;oBACnB;YACJ;YAEA,MAAM,OAAO,CAAC,CAAC,GAAG;gBAChB,MAAM,IAAI,SAAS,IAAK,CAAA,WAAW,MAAA;gBACnC,mBAAmB,cAAc,OAAO,GAAG;YAC7C;QACF;QAEA;QAEA,kBAAkB;QAClB,OAAO,gBAAgB,CAAC,UAAU;QAElC,OAAO;YACL,aAAa,KAAK;YAClB,OAAO,mBAAmB,CAAC,UAAU;QACvC;IACF,GAAG;QACD;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;KACD;IAED,OACE,CAAA,GAAA,0BAAA,EAAA,UAAA;QACE,KAAK;QACL,OAAO;YACL,SAAS;YACT,OAAO;YACP,QAAQ;QACT;IAAA;AAGP;AAGF,0CAAgB,WAAW,GAAG;;","sources":["client-react/src/index.ts","client-react/src/RTVIClientAudio.tsx","client-react/src/useRTVIClientEvent.ts","client-react/src/useRTVIClient.ts","client-react/src/RTVIClientProvider.tsx","client-react/src/useRTVIClientMediaTrack.ts","client-react/src/RTVIClientCamToggle.tsx","client-react/src/useRTVIClientCamControl.ts","client-react/src/useRTVIClientTransportState.ts","client-react/src/RTVIClientMicToggle.tsx","client-react/src/useRTVIClientMicControl.ts","client-react/src/RTVIClientVideo.tsx","client-react/src/useMergedRef.ts","client-react/src/useRTVIClientMediaDevices.ts","client-react/src/VoiceVisualizer.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIClientAudio } from \"./RTVIClientAudio\";\nimport { RTVIClientCamToggle } from \"./RTVIClientCamToggle\";\nimport { RTVIClientMicToggle } from \"./RTVIClientMicToggle\";\nimport { RTVIClientProvider } from \"./RTVIClientProvider\";\nimport { RTVIClientVideo } from \"./RTVIClientVideo\";\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientCamControl } from \"./useRTVIClientCamControl\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { useRTVIClientMediaDevices } from \"./useRTVIClientMediaDevices\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\nimport { useRTVIClientMicControl } from \"./useRTVIClientMicControl\";\nimport { useRTVIClientTransportState } from \"./useRTVIClientTransportState\";\nimport { VoiceVisualizer } from \"./VoiceVisualizer\";\n\nexport {\n RTVIClientAudio,\n RTVIClientCamToggle,\n RTVIClientMicToggle,\n RTVIClientProvider,\n RTVIClientVideo,\n useRTVIClient,\n useRTVIClientCamControl,\n useRTVIClientEvent,\n useRTVIClientMediaDevices,\n useRTVIClientMediaTrack,\n useRTVIClientMicControl,\n useRTVIClientTransportState,\n VoiceVisualizer,\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { useCallback, useEffect, useRef } from \"react\";\n\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\nexport const RTVIClientAudio = () => {\n const botAudioRef = useRef<HTMLAudioElement>(null);\n const botAudioTrack = useRTVIClientMediaTrack(\"audio\", \"bot\");\n\n useEffect(() => {\n if (!botAudioRef.current || !botAudioTrack) return;\n if (botAudioRef.current.srcObject) {\n const oldTrack = (\n botAudioRef.current.srcObject as MediaStream\n ).getAudioTracks()[0];\n if (oldTrack.id === botAudioTrack.id) return;\n }\n botAudioRef.current.srcObject = new MediaStream([botAudioTrack]);\n }, [botAudioTrack]);\n\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useCallback((speaker: MediaDeviceInfo) => {\n if (!botAudioRef.current) return;\n if (typeof botAudioRef.current.setSinkId !== \"function\") return;\n botAudioRef.current.setSinkId(speaker.deviceId);\n }, [])\n );\n\n return (\n <>\n <audio ref={botAudioRef} autoPlay />\n </>\n );\n};\nRTVIClientAudio.displayName = \"RTVIClientAudio\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, RTVIEventHandler } from \"@pipecat-ai/client-js\";\nimport { useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\n\nexport const useRTVIClientEvent = <E extends RTVIEvent>(\n event: E,\n handler: RTVIEventHandler<E>\n) => {\n const client = useRTVIClient();\n\n useEffect(() => {\n if (!client) return;\n client.on(event, handler);\n return () => {\n client.off(event, handler);\n };\n }, [event, handler, client]);\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { RTVIClientContext } from \"./RTVIClientProvider\";\n\nexport const useRTVIClient = () => {\n const { client } = useContext(RTVIClientContext);\n return client;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIClient } from \"@pipecat-ai/client-js\";\nimport { createStore } from \"jotai\";\nimport { Provider as JotaiProvider } from \"jotai/react\";\nimport React, { createContext } from \"react\";\n\nexport interface Props {\n client: RTVIClient;\n jotaiStore?: React.ComponentProps<typeof JotaiProvider>[\"store\"];\n}\n\nconst defaultStore = createStore();\n\nexport const RTVIClientContext = createContext<{ client?: RTVIClient }>({});\n\nexport const RTVIClientProvider: React.FC<React.PropsWithChildren<Props>> = ({\n children,\n client,\n jotaiStore = defaultStore,\n}) => {\n return (\n <JotaiProvider store={jotaiStore}>\n <RTVIClientContext.Provider value={{ client }}>\n {children}\n </RTVIClientContext.Provider>\n </JotaiProvider>\n );\n};\nRTVIClientProvider.displayName = \"RTVIClientProvider\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { Participant, RTVIEvent, Tracks } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { atomFamily, useAtomCallback } from \"jotai/utils\";\nimport { PrimitiveAtom } from \"jotai/vanilla\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype ParticipantType = keyof Tracks;\ntype TrackType = keyof Tracks[\"local\"];\n\nconst localAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botVideoTrackAtom = atom<MediaStreamTrack | null>(null);\n\nconst trackAtom = atomFamily<\n { local: boolean; trackType: TrackType },\n PrimitiveAtom<MediaStreamTrack | null>\n>(({ local, trackType }) => {\n if (local) {\n switch (trackType) {\n case \"audio\":\n return localAudioTrackAtom;\n case \"screenAudio\":\n return localScreenAudioTrackAtom;\n case \"screenVideo\":\n return localScreenVideoTrackAtom;\n case \"video\":\n return localVideoTrackAtom;\n }\n }\n return trackType === \"audio\" ? botAudioTrackAtom : botVideoTrackAtom;\n});\n\nexport const useRTVIClientMediaTrack = (\n trackType: TrackType,\n participantType: ParticipantType\n) => {\n const client = useRTVIClient();\n const track = useAtomValue(\n trackAtom({ local: participantType === \"local\", trackType })\n );\n\n const updateTrack = useAtomCallback(\n useCallback(\n (\n get,\n set,\n track: MediaStreamTrack,\n trackType: TrackType,\n local: boolean\n ) => {\n const atom = trackAtom({\n local,\n trackType,\n });\n const oldTrack = get(atom);\n if (oldTrack?.id === track.id) return;\n set(atom, track);\n },\n []\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.TrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n updateTrack(\n track,\n track.kind as TrackType,\n Boolean(participant?.local)\n );\n },\n [updateTrack]\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.ScreenTrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n const trackType =\n track.kind === \"audio\" ? \"screenAudio\" : \"screenVideo\";\n updateTrack(track, trackType, Boolean(participant?.local));\n },\n [updateTrack]\n )\n );\n\n useEffect(() => {\n if (!client) return;\n const tracks = client.tracks();\n const track = tracks?.[participantType]?.[trackType];\n if (!track) return;\n updateTrack(track, trackType, participantType === \"local\");\n }, [participantType, trackType, updateTrack, client]);\n\n return track;\n};\n","import React, { useCallback } from \"react\";\n\nimport { useRTVIClientCamControl } from \"./useRTVIClientCamControl\";\n\nexport interface RTVIClientCamToggleProps {\n /**\n * Callback fired when camera state changes\n */\n onCamEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the cam toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isCamEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling camera state\n */\nexport const RTVIClientCamToggle: React.FC<RTVIClientCamToggleProps> = ({\n onCamEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { isCamEnabled, enableCam } = useRTVIClientCamControl();\n\n const handleToggleCam = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isCamEnabled;\n enableCam(newEnabledState);\n onCamEnabledChanged?.(newEnabledState);\n }, [disabled, enableCam, isCamEnabled, onCamEnabledChanged]);\n\n return (\n <>\n {children({\n isCamEnabled,\n onClick: handleToggleCam,\n disabled,\n })}\n </>\n );\n};\n\nexport default RTVIClientCamToggle;\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientTransportState } from \"./useRTVIClientTransportState\";\n\n/**\n * Hook to control camera state\n */\nexport const useRTVIClientCamControl = () => {\n const client = useRTVIClient();\n\n const [isCamEnabled, setIsCamEnabled] = useState(\n client?.isCamEnabled ?? false\n );\n\n const transportState = useRTVIClientTransportState();\n\n // Sync component state with client state initially\n useEffect(() => {\n if (\n !client ||\n transportState !== \"initialized\" ||\n typeof client.isCamEnabled !== \"boolean\"\n )\n return;\n setIsCamEnabled(client.isCamEnabled);\n }, [client, transportState]);\n\n const enableCam = useCallback(\n (enabled: boolean) => {\n setIsCamEnabled(enabled);\n client?.enableCam?.(enabled);\n },\n [client]\n );\n\n return {\n enableCam,\n isCamEnabled,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, TransportState } from \"@pipecat-ai/client-js\";\nimport { atom, useAtom } from \"jotai\";\n\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\nconst transportStateAtom = atom<TransportState>(\"disconnected\");\n\nexport const useRTVIClientTransportState = () => {\n const [transportState, setTransportState] = useAtom(transportStateAtom);\n\n useRTVIClientEvent(RTVIEvent.TransportStateChanged, setTransportState);\n\n return transportState;\n};\n","import React, { useCallback } from \"react\";\n\nimport { useRTVIClientMicControl } from \"./useRTVIClientMicControl\";\n\nexport interface RTVIClientMicToggleProps {\n /**\n * Callback fired when microphone state changes\n */\n onMicEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the mic toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isMicEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling microphone state\n */\nexport const RTVIClientMicToggle: React.FC<RTVIClientMicToggleProps> = ({\n onMicEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { enableMic, isMicEnabled } = useRTVIClientMicControl();\n\n const handleToggleMic = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isMicEnabled;\n enableMic(newEnabledState);\n onMicEnabledChanged?.(newEnabledState);\n }, [disabled, enableMic, isMicEnabled, onMicEnabledChanged]);\n\n return (\n <>\n {children({\n isMicEnabled,\n onClick: handleToggleMic,\n disabled,\n })}\n </>\n );\n};\n\nexport default RTVIClientMicToggle;\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientTransportState } from \"./useRTVIClientTransportState\";\n\n/**\n * Hook to control microphone state\n */\nexport const useRTVIClientMicControl = () => {\n const client = useRTVIClient();\n\n const [isMicEnabled, setIsMicEnabled] = useState(\n client?.isMicEnabled ?? false\n );\n\n const transportState = useRTVIClientTransportState();\n\n // Sync component state with client state initially\n useEffect(() => {\n if (\n !client ||\n transportState !== \"initialized\" ||\n typeof client.isMicEnabled !== \"boolean\"\n )\n return;\n setIsMicEnabled(client.isMicEnabled);\n }, [client, transportState]);\n\n const enableMic = useCallback(\n (enabled: boolean) => {\n setIsMicEnabled(enabled);\n client?.enableMic?.(enabled);\n },\n [client]\n );\n\n return {\n enableMic,\n isMicEnabled,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { forwardRef, useEffect, useRef } from \"react\";\n\nimport useMergedRef from \"./useMergedRef\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\ninterface RTVIClientVideoInterface {\n aspectRatio: number;\n height: number;\n width: number;\n}\n\nexport interface Props\n extends Omit<React.VideoHTMLAttributes<HTMLVideoElement>, \"onResize\"> {\n participant: \"local\" | \"bot\";\n\n /**\n * Defines the video track type to display. Default: 'video'.\n */\n trackType?: \"screenVideo\" | \"video\";\n\n /**\n * Defines whether the video should be fully contained or cover the box. Default: 'contain'.\n */\n fit?: \"contain\" | \"cover\";\n /**\n * Forces the video to be mirrored, if set.\n */\n mirror?: boolean;\n\n /**\n * Optional callback, which is triggered whenever the video's rendered width or height changes.\n * Returns the video's native width, height and aspectRatio.\n */\n onResize?(dimensions: RTVIClientVideoInterface): void;\n}\n\nexport const RTVIClientVideo = forwardRef<HTMLVideoElement, Props>(\n function VoiceClientVideo(\n {\n participant = \"local\",\n fit = \"contain\",\n mirror,\n onResize,\n style = {},\n trackType = \"video\",\n ...props\n },\n ref\n ) {\n const videoTrack: MediaStreamTrack | null = useRTVIClientMediaTrack(\n trackType,\n participant\n );\n\n const videoEl = useRef<HTMLVideoElement>(null);\n const videoRef = useMergedRef<HTMLVideoElement>(videoEl, ref);\n\n /**\n * Handle canplay & picture-in-picture events.\n */\n useEffect(function setupVideoEvents() {\n const video = videoEl.current;\n if (!video) return;\n\n const playVideo = () => {\n const promise = video.play();\n if (promise !== undefined) {\n promise\n .then(() => {\n // All good, playback started.\n video.controls = false;\n })\n .catch((error) => {\n // Auto-play was prevented. Show video controls, so user can play video manually.\n video.controls = true;\n console.warn(\"Failed to play video\", error);\n });\n }\n };\n\n const handleCanPlay = () => {\n if (!video.paused) return;\n playVideo();\n };\n const handleEnterPIP = () => {\n video.style.transform = \"scale(1)\";\n };\n const handleLeavePIP = () => {\n video.style.transform = \"\";\n setTimeout(() => {\n if (video.paused) playVideo();\n }, 100);\n };\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"hidden\") return;\n if (!video.paused) return;\n playVideo();\n };\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.addEventListener(\"leavepictureinpicture\", handleLeavePIP);\n\n // Videos can be paused if media was played in another app on iOS.\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n return () => {\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.removeEventListener(\"leavepictureinpicture\", handleLeavePIP);\n document.removeEventListener(\n \"visibilitychange\",\n handleVisibilityChange\n );\n };\n }, []);\n\n /**\n * Update srcObject.\n */\n useEffect(\n function updateSrcObject() {\n const video = videoEl.current;\n if (!video || !videoTrack) return;\n video.srcObject = new MediaStream([videoTrack]);\n video.load();\n return () => {\n // clean up when unmounted\n video.srcObject = null;\n video.load();\n };\n },\n [videoTrack, videoTrack?.id]\n );\n\n /**\n * Add optional event listener for resize event so the parent component\n * can know the video's native aspect ratio.\n */\n useEffect(\n function reportVideoDimensions() {\n const video = videoEl.current;\n if (!onResize || !video) return;\n\n let frame: ReturnType<typeof requestAnimationFrame>;\n function handleResize() {\n if (frame) cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n const video = videoEl.current;\n if (!video || document.hidden) return;\n const videoWidth = video.videoWidth;\n const videoHeight = video.videoHeight;\n if (videoWidth && videoHeight) {\n onResize?.({\n aspectRatio: videoWidth / videoHeight,\n height: videoHeight,\n width: videoWidth,\n });\n }\n });\n }\n\n handleResize();\n video.addEventListener(\"loadedmetadata\", handleResize);\n video.addEventListener(\"resize\", handleResize);\n\n return () => {\n if (frame) cancelAnimationFrame(frame);\n video.removeEventListener(\"loadedmetadata\", handleResize);\n video.removeEventListener(\"resize\", handleResize);\n };\n },\n [onResize]\n );\n\n return (\n <video\n autoPlay\n muted\n playsInline\n ref={videoRef}\n style={{\n objectFit: fit,\n transform: mirror ? \"scale(-1, 1)\" : \"\",\n ...style,\n }}\n {...props}\n />\n );\n }\n);\nRTVIClientVideo.displayName = \"RTVIClientVideo\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n *\n * This file contains code derived from:\n * https://github.com/jaredLunde/react-hook/blob/master/packages/merged-ref/src/index.tsx\n * Original author: Jared Lunde (https://github.com/jaredLunde)\n * Original license: MIT (https://github.com/jaredLunde/react-hook/blob/master/LICENSE)\n */\n\nimport React, { useCallback } from \"react\";\n\nfunction useMergedRef<T>(...refs: React.Ref<T>[]): React.RefCallback<T> {\n return useCallback(\n (element: T) => {\n for (let i = 0; i < refs.length; i++) {\n const ref = refs[i];\n if (typeof ref === \"function\") ref(element);\n else if (ref && typeof ref === \"object\")\n (ref as React.MutableRefObject<T>).current = element;\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n refs\n );\n}\n\nexport default useMergedRef;\n","import { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype OptionalMediaDeviceInfo = MediaDeviceInfo | Record<string, never>;\n\nconst availableMicsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableCamsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableSpeakersAtom = atom<MediaDeviceInfo[]>([]);\nconst selectedMicAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedCamAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedSpeakerAtom = atom<OptionalMediaDeviceInfo>({});\n\nexport const useRTVIClientMediaDevices = () => {\n const client = useRTVIClient();\n\n const availableCams = useAtomValue(availableCamsAtom);\n const availableMics = useAtomValue(availableMicsAtom);\n const availableSpeakers = useAtomValue(availableSpeakersAtom);\n const selectedCam = useAtomValue(selectedCamAtom);\n const selectedMic = useAtomValue(selectedMicAtom);\n const selectedSpeaker = useAtomValue(selectedSpeakerAtom);\n\n const initDevices = useAtomCallback(\n useCallback(\n async (_get, set) => {\n if (!client) return;\n\n const availableCams = await client.getAllCams();\n const availableMics = await client.getAllMics();\n const availableSpeakers = await client.getAllSpeakers();\n\n set(availableCamsAtom, availableCams);\n set(availableMicsAtom, availableMics);\n set(availableSpeakersAtom, availableSpeakers);\n\n set(selectedCamAtom, client.selectedCam);\n set(selectedMicAtom, client.selectedMic);\n set(selectedSpeakerAtom, client.selectedSpeaker);\n },\n [client]\n )\n );\n\n useEffect(() => {\n initDevices();\n }, [initDevices]);\n\n useRTVIClientEvent(\n RTVIEvent.AvailableCamsUpdated,\n useAtomCallback(\n useCallback((_get, set, cams) => {\n set(availableCamsAtom, cams);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableMicsUpdated,\n useAtomCallback(\n useCallback((_get, set, mics) => {\n set(availableMicsAtom, mics);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableSpeakersUpdated,\n useAtomCallback(\n useCallback((_get, set, speakers) => {\n set(availableSpeakersAtom, speakers);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.CamUpdated,\n useAtomCallback(\n useCallback((_get, set, cam) => {\n set(selectedCamAtom, cam);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.MicUpdated,\n useAtomCallback(\n useCallback((_get, set, mic) => {\n set(selectedMicAtom, mic);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useAtomCallback(\n useCallback((_get, set, speaker) => {\n set(selectedSpeakerAtom, speaker);\n }, [])\n )\n );\n\n const updateCam = useCallback(\n (id: string) => {\n client?.updateCam(id);\n },\n [client]\n );\n const updateMic = useCallback(\n (id: string) => {\n client?.updateMic(id);\n },\n [client]\n );\n const updateSpeaker = useCallback(\n (id: string) => {\n client?.updateSpeaker(id);\n },\n [client]\n );\n\n return {\n availableCams,\n availableMics,\n availableSpeakers,\n selectedCam,\n selectedMic,\n selectedSpeaker,\n updateCam,\n updateMic,\n updateSpeaker,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { useEffect, useRef } from \"react\";\n\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\ntype ParticipantType = Parameters<typeof useRTVIClientMediaTrack>[1];\n\ninterface Props {\n backgroundColor?: string;\n barColor?: string;\n barCount?: number;\n barGap?: number;\n barLineCap?: \"round\" | \"square\";\n barMaxHeight?: number;\n barOrigin?: \"top\" | \"bottom\" | \"center\";\n barWidth?: number;\n participantType: ParticipantType;\n}\n\nexport const VoiceVisualizer: React.FC<Props> = React.memo(\n ({\n backgroundColor = \"transparent\",\n barColor = \"black\",\n barCount = 5,\n barGap = 12,\n barLineCap = \"round\",\n barMaxHeight = 120,\n barOrigin = \"center\",\n barWidth = 30,\n participantType,\n }) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const track: MediaStreamTrack | null = useRTVIClientMediaTrack(\n \"audio\",\n participantType\n );\n\n useEffect(() => {\n if (!canvasRef.current) return;\n\n const canvasWidth = barCount * barWidth + (barCount - 1) * barGap;\n const canvasHeight = barMaxHeight;\n\n const canvas = canvasRef.current;\n\n const scaleFactor = 2;\n\n // Make canvas fill the width and height of its container\n const resizeCanvas = () => {\n canvas.width = canvasWidth * scaleFactor;\n canvas.height = canvasHeight * scaleFactor;\n\n canvas.style.width = `${canvasWidth}px`;\n canvas.style.height = `${canvasHeight}px`;\n\n canvasCtx.lineCap = barLineCap;\n canvasCtx.scale(scaleFactor, scaleFactor);\n };\n\n const canvasCtx = canvas.getContext(\"2d\")!;\n resizeCanvas();\n\n if (!track) return;\n\n const audioContext = new AudioContext();\n const source = audioContext.createMediaStreamSource(\n new MediaStream([track])\n );\n const analyser = audioContext.createAnalyser();\n\n analyser.fftSize = 1024;\n\n source.connect(analyser);\n\n const frequencyData = new Uint8Array(analyser.frequencyBinCount);\n\n canvasCtx.lineCap = barLineCap;\n\n // Create frequency bands based on barCount\n const bands = Array.from({ length: barCount }, (_, i) => {\n // Use improved logarithmic scale for better frequency distribution\n const minFreq = barCount > 20 ? 200 : 80; // Adjust min frequency based on bar count\n const maxFreq = 10000; // Cover most important audio frequencies\n\n // Use Mel scale inspired approach for more perceptually uniform distribution\n // This helps with a large number of bars by placing fewer in the very low range\n // https://en.wikipedia.org/wiki/Mel_scale\n const melMin = 2595 * Math.log10(1 + minFreq / 700);\n const melMax = 2595 * Math.log10(1 + maxFreq / 700);\n const melStep = (melMax - melMin) / barCount;\n\n const melValue = melMin + i * melStep;\n const startFreq = 700 * (Math.pow(10, melValue / 2595) - 1);\n const endFreq = 700 * (Math.pow(10, (melValue + melStep) / 2595) - 1);\n\n return {\n startFreq,\n endFreq,\n smoothValue: 0,\n };\n });\n\n const getFrequencyBinIndex = (frequency: number) => {\n const nyquist = audioContext.sampleRate / 2;\n return Math.round(\n (frequency / nyquist) * (analyser.frequencyBinCount - 1)\n );\n };\n\n function drawSpectrum() {\n analyser.getByteFrequencyData(frequencyData);\n canvasCtx.clearRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n canvasCtx.fillStyle = backgroundColor;\n canvasCtx.fillRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n\n let isActive = false;\n\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2; // Center bars\n\n const adjustedCircleRadius = barWidth / 2; // Fixed radius for reset circles\n\n bands.forEach((band, i) => {\n const startIndex = getFrequencyBinIndex(band.startFreq);\n const endIndex = getFrequencyBinIndex(band.endFreq);\n const bandData = frequencyData.slice(startIndex, endIndex);\n const bandValue =\n bandData.reduce((acc, val) => acc + val, 0) / bandData.length;\n\n const smoothingFactor = 0.2;\n\n if (bandValue < 1) {\n band.smoothValue = Math.max(\n band.smoothValue - smoothingFactor * 5,\n 0\n );\n } else {\n band.smoothValue =\n band.smoothValue +\n (bandValue - band.smoothValue) * smoothingFactor;\n isActive = true;\n }\n\n const x = startX + i * (barWidth + barGap);\n // Calculate bar height with a maximum cap\n const minHeight = 0;\n const barHeight = Math.max(\n minHeight,\n Math.min((band.smoothValue / 255) * barMaxHeight, barMaxHeight)\n );\n\n let yTop, yBottom;\n const canvasHeight = canvas.height / scaleFactor;\n\n switch (barOrigin) {\n case \"top\":\n yTop = adjustedCircleRadius;\n yBottom = Math.min(\n adjustedCircleRadius + barHeight,\n canvasHeight - adjustedCircleRadius\n );\n break;\n case \"bottom\":\n yBottom = canvasHeight - adjustedCircleRadius;\n yTop = Math.max(yBottom - barHeight, adjustedCircleRadius);\n break;\n case \"center\":\n default:\n yTop = Math.max(\n canvasHeight / 2 - barHeight / 2,\n adjustedCircleRadius\n );\n yBottom = Math.min(\n canvasHeight / 2 + barHeight / 2,\n canvasHeight - adjustedCircleRadius\n );\n break;\n }\n\n if (band.smoothValue > 0) {\n canvasCtx.beginPath();\n canvasCtx.moveTo(x + barWidth / 2, yTop);\n canvasCtx.lineTo(x + barWidth / 2, yBottom);\n canvasCtx.lineWidth = barWidth;\n canvasCtx.strokeStyle = barColor;\n canvasCtx.stroke();\n } else {\n drawInactiveCircle(adjustedCircleRadius, barColor, x, yTop);\n }\n });\n\n if (!isActive) {\n drawInactiveCircles(adjustedCircleRadius, barColor);\n }\n\n requestAnimationFrame(drawSpectrum);\n }\n\n function drawInactiveCircle(\n circleRadius: number,\n color: string,\n x: number,\n y: number\n ) {\n switch (barLineCap) {\n case \"square\":\n canvasCtx.fillStyle = color;\n canvasCtx.fillRect(\n x + barWidth / 2 - circleRadius,\n y - circleRadius,\n circleRadius * 2,\n circleRadius * 2\n );\n break;\n case \"round\":\n default:\n canvasCtx.beginPath();\n canvasCtx.arc(x + barWidth / 2, y, circleRadius, 0, 2 * Math.PI);\n canvasCtx.fillStyle = color;\n canvasCtx.fill();\n canvasCtx.closePath();\n break;\n }\n }\n\n function drawInactiveCircles(circleRadius: number, color: string) {\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2;\n const canvasHeight = canvas.height / scaleFactor;\n\n let y;\n switch (barOrigin) {\n case \"top\":\n y = circleRadius;\n break;\n case \"bottom\":\n y = canvasHeight - circleRadius;\n break;\n case \"center\":\n default:\n y = canvasHeight / 2;\n break;\n }\n\n bands.forEach((_, i) => {\n const x = startX + i * (barWidth + barGap);\n drawInactiveCircle(circleRadius, color, x, y);\n });\n }\n\n drawSpectrum();\n\n // Handle resizing\n window.addEventListener(\"resize\", resizeCanvas);\n\n return () => {\n audioContext.close();\n window.removeEventListener(\"resize\", resizeCanvas);\n };\n }, [\n backgroundColor,\n barColor,\n barCount,\n barGap,\n barLineCap,\n barMaxHeight,\n barOrigin,\n barWidth,\n track,\n ]);\n\n return (\n <canvas\n ref={canvasRef}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n }}\n />\n );\n }\n);\n\nVoiceVisualizer.displayName = \"VoiceVisualizer\";\n"],"names":[],"version":3,"file":"index.js.map"}
|
package/dist/index.module.js
CHANGED
|
@@ -169,15 +169,32 @@ $f8b885726fc652c0$export$ba1245f7cbf3ae02.displayName = "RTVIClientAudio";
|
|
|
169
169
|
|
|
170
170
|
|
|
171
171
|
|
|
172
|
+
/**
|
|
173
|
+
* Copyright (c) 2024, Daily.
|
|
174
|
+
*
|
|
175
|
+
* SPDX-License-Identifier: BSD-2-Clause
|
|
176
|
+
*/
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
const $8376ffbc1b1f3c97$var$transportStateAtom = (0, $h9lXz$atom)("disconnected");
|
|
180
|
+
const $8376ffbc1b1f3c97$export$599fa01283bd4ece = ()=>{
|
|
181
|
+
const [transportState, setTransportState] = (0, $h9lXz$useAtom)($8376ffbc1b1f3c97$var$transportStateAtom);
|
|
182
|
+
(0, $824ea64b5f757259$export$33a6ac53b8f02625)((0, $h9lXz$RTVIEvent).TransportStateChanged, setTransportState);
|
|
183
|
+
return transportState;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
|
|
172
187
|
const $7662c16ae3a8c331$export$46099a7ec2fe8ac5 = ()=>{
|
|
173
188
|
const client = (0, $54a3c9f5bdbf0854$export$31a5f6a22c9b8fba)();
|
|
174
189
|
const [isCamEnabled, setIsCamEnabled] = (0, $h9lXz$useState)(client?.isCamEnabled ?? false);
|
|
190
|
+
const transportState = (0, $8376ffbc1b1f3c97$export$599fa01283bd4ece)();
|
|
175
191
|
// Sync component state with client state initially
|
|
176
192
|
(0, $h9lXz$useEffect)(()=>{
|
|
177
|
-
if (!client) return;
|
|
193
|
+
if (!client || transportState !== "initialized" || typeof client.isCamEnabled !== "boolean") return;
|
|
178
194
|
setIsCamEnabled(client.isCamEnabled);
|
|
179
195
|
}, [
|
|
180
|
-
client
|
|
196
|
+
client,
|
|
197
|
+
transportState
|
|
181
198
|
]);
|
|
182
199
|
const enableCam = (0, $h9lXz$useCallback)((enabled)=>{
|
|
183
200
|
setIsCamEnabled(enabled);
|
|
@@ -220,15 +237,18 @@ var $379da083c72543d5$export$2e2bcd8739ae039 = $379da083c72543d5$export$156c26e1
|
|
|
220
237
|
|
|
221
238
|
|
|
222
239
|
|
|
240
|
+
|
|
223
241
|
const $e6f5302cf8392476$export$805915964ad7bc25 = ()=>{
|
|
224
242
|
const client = (0, $54a3c9f5bdbf0854$export$31a5f6a22c9b8fba)();
|
|
225
243
|
const [isMicEnabled, setIsMicEnabled] = (0, $h9lXz$useState)(client?.isMicEnabled ?? false);
|
|
244
|
+
const transportState = (0, $8376ffbc1b1f3c97$export$599fa01283bd4ece)();
|
|
226
245
|
// Sync component state with client state initially
|
|
227
246
|
(0, $h9lXz$useEffect)(()=>{
|
|
228
|
-
if (!client) return;
|
|
247
|
+
if (!client || transportState !== "initialized" || typeof client.isMicEnabled !== "boolean") return;
|
|
229
248
|
setIsMicEnabled(client.isMicEnabled);
|
|
230
249
|
}, [
|
|
231
|
-
client
|
|
250
|
+
client,
|
|
251
|
+
transportState
|
|
232
252
|
]);
|
|
233
253
|
const enableMic = (0, $h9lXz$useCallback)((enabled)=>{
|
|
234
254
|
setIsMicEnabled(enabled);
|
|
@@ -501,20 +521,6 @@ const $c7d06534b21735c2$export$652c54907b83a48d = ()=>{
|
|
|
501
521
|
|
|
502
522
|
|
|
503
523
|
|
|
504
|
-
/**
|
|
505
|
-
* Copyright (c) 2024, Daily.
|
|
506
|
-
*
|
|
507
|
-
* SPDX-License-Identifier: BSD-2-Clause
|
|
508
|
-
*/
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
const $8376ffbc1b1f3c97$var$transportStateAtom = (0, $h9lXz$atom)("disconnected");
|
|
512
|
-
const $8376ffbc1b1f3c97$export$599fa01283bd4ece = ()=>{
|
|
513
|
-
const [transportState, setTransportState] = (0, $h9lXz$useAtom)($8376ffbc1b1f3c97$var$transportStateAtom);
|
|
514
|
-
(0, $824ea64b5f757259$export$33a6ac53b8f02625)((0, $h9lXz$RTVIEvent).TransportStateChanged, setTransportState);
|
|
515
|
-
return transportState;
|
|
516
|
-
};
|
|
517
|
-
|
|
518
524
|
|
|
519
525
|
|
|
520
526
|
|
package/dist/index.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":";;;;;;;AAAA;;;;;;;AEAA;;;;CAIG;ACJH;;;;CAIG;;;;;ACYH,MAAM,qCAAe,CAAA,GAAA,kBAAA;AAEd,MAAM,0DAAoB,CAAA,GAAA,oBAAA,EAAuC,CAAA;AAEjE,MAAM,2CAA+D,CAAC,YAC3E,QAAQ,UACR,MAAM,cACN,aAAa,oCACd;IACC,OACE,CAAA,GAAA,UAAA,EAAC,CAAA,GAAA,eAAA,GAAa;QAAC,OAAO;QAAU,UAC9B,CAAA,GAAA,UAAA,EAAC,0CAAkB,QAAQ,EAAA;YAAC,OAAO;wBAAE;YAAM;YAAE,UAC1C;QAAQ;IACkB;AAGnC;AACA,yCAAmB,WAAW,GAAG;;;ADvB1B,MAAM,4CAAgB;IAC3B,MAAM,UAAE,MAAM,EAAE,GAAG,CAAA,GAAA,iBAAA,EAAW,CAAA,GAAA,yCAAA;IAC9B,OAAO;AACT;;;ADFO,MAAM,4CAAqB,CAChC,OACA;IAEA,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,CAAA,GAAA,gBAAA,EAAU;QACR,IAAI,CAAC,QAAQ;QACb,OAAO,EAAE,CAAC,OAAO;QACjB,OAAO;YACL,OAAO,GAAG,CAAC,OAAO;QACpB;IACF,GAAG;QAAC;QAAO;QAAS;KAAO;AAC7B;;;AGxBA;;;;CAIG;;;;;;AAcH,MAAM,4CAAsB,CAAA,GAAA,WAAA,EAA8B;AAC1D,MAAM,4CAAsB,CAAA,GAAA,WAAA,EAA8B;AAC1D,MAAM,kDAA4B,CAAA,GAAA,WAAA,EAA8B;AAChE,MAAM,kDAA4B,CAAA,GAAA,WAAA,EAA8B;AAChE,MAAM,0CAAoB,CAAA,GAAA,WAAA,EAA8B;AACxD,MAAM,0CAAoB,CAAA,GAAA,WAAA,EAA8B;AAExD,MAAM,kCAAY,CAAA,GAAA,iBAAA,EAGhB,CAAC,SAAE,KAAK,aAAE,SAAS,EAAE;IACrB,IAAI,OACF,OAAQ;QACN,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;QACT,KAAK;YACH,OAAO;IACX;IAEF,OAAO,cAAc,UAAU,0CAAoB;AACrD;AAEO,MAAM,4CAA0B,CACrC,WACA;IAEA,MAAM,SAAS,CAAA,GAAA,yCAAA;IACf,MAAM,QAAQ,CAAA,GAAA,mBAAA,EACZ,gCAAU;QAAE,OAAO,oBAAoB;mBAAS;IAAS;IAG3D,MAAM,cAAc,CAAA,GAAA,sBAAA,EAClB,CAAA,GAAA,kBAAA,EACE,CACE,KACA,KACA,OACA,WACA;QAEA,MAAM,OAAO,gCAAU;mBACrB;uBACA;QACD;QACD,MAAM,WAAW,IAAI;QACrB,IAAI,UAAU,OAAO,MAAM,EAAE,EAAE;QAC/B,IAAI,MAAM;IACZ,GACA,EAAE;IAIN,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,gBAAA,EAAU,YAAY,EACtB,CAAA,GAAA,kBAAA,EACE,CAAC,OAAyB;QACxB,YACE,OACA,MAAM,IAAiB,EACvB,QAAQ,aAAa;IAEzB,GACA;QAAC;KAAY;IAIjB,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,gBAAA,EAAU,kBAAkB,EAC5B,CAAA,GAAA,kBAAA,EACE,CAAC,OAAyB;QACxB,MAAM,YACJ,MAAM,IAAI,KAAK,UAAU,gBAAgB;QAC3C,YAAY,OAAO,WAAW,QAAQ,aAAa;IACrD,GACA;QAAC;KAAY;IAIjB,CAAA,GAAA,gBAAA,EAAU;QACR,IAAI,CAAC,QAAQ;QACb,MAAM,SAAS,OAAO,MAAM;QAC5B,MAAM,QAAQ,QAAQ,CAAC,gBAAgB,EAAE,CAAC,UAAU;QACpD,IAAI,CAAC,OAAO;QACZ,YAAY,OAAO,WAAW,oBAAoB;IACpD,GAAG;QAAC;QAAiB;QAAW;QAAa;KAAO;IAEpD,OAAO;AACT;;;AJjGO,MAAM,4CAAkB;IAC7B,MAAM,cAAc,CAAA,GAAA,aAAA,EAAyB;IAC7C,MAAM,gBAAgB,CAAA,GAAA,yCAAA,EAAwB,SAAS;IAEvD,CAAA,GAAA,gBAAA,EAAU;QACR,IAAI,CAAC,YAAY,OAAO,IAAI,CAAC,eAAe;QAC5C,IAAI,YAAY,OAAO,CAAC,SAAS,EAAE;YACjC,MAAM,WACJ,YAAY,OAAO,CAAC,SACrB,CAAC,cAAc,EAAE,CAAC,EAAE;YACrB,IAAI,SAAS,EAAE,KAAK,cAAc,EAAE,EAAE;QACxC;QACA,YAAY,OAAO,CAAC,SAAS,GAAG,IAAI,YAAY;YAAC;SAAc;IACjE,GAAG;QAAC;KAAc;IAElB,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,gBAAA,EAAU,cAAc,EACxB,CAAA,GAAA,kBAAA,EAAY,CAAC;QACX,IAAI,CAAC,YAAY,OAAO,EAAE;QAC1B,IAAI,OAAO,YAAY,OAAO,CAAC,SAAS,KAAK,YAAY;QACzD,YAAY,OAAO,CAAC,SAAS,CAAC,QAAQ,QAAQ;IAChD,GAAG,EAAE;IAGP,OACE,CAAA,GAAA,UAAA,EAAA,CAAA,GAAA,eAAA,GAAA;QAAA,UACE,CAAA,GAAA,UAAA,EAAA,SAAA;YAAO,KAAK;YAAa,UAAQ;QAAA;IAAG;AAG1C;AACA,0CAAgB,WAAW,GAAG;;CDtC3B;;;;;AOGI,MAAM,4CAA0B;IACrC,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,MAAM,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,eAAA,EACtC,QAAQ,gBAAgB;IAG1B,mDAAmD;IACnD,CAAA,GAAA,gBAAA,EAAU;QACR,IAAI,CAAC,QAAQ;QACb,gBAAgB,OAAO,YAAY;IACrC,GAAG;QAAC;KAAO;IAEX,MAAM,YAAY,CAAA,GAAA,kBAAA,EAChB,CAAC;QACC,gBAAgB;QAChB,QAAQ,YAAY;IACtB,GACA;QAAC;KAAO;IAGV,OAAO;mBACL;sBACA;IACD;AACH;;;ADFO,MAAM,4CAA0D,CAAC,uBACtE,mBAAmB,YACnB,WAAW,iBACX,QAAQ,EACT;IACC,MAAM,gBAAE,YAAY,aAAE,SAAS,EAAE,GAAG,CAAA,GAAA,yCAAA;IAEpC,MAAM,kBAAkB,CAAA,GAAA,kBAAA,EAAY;QAClC,IAAI,UAAU;QAEd,MAAM,kBAAkB,CAAC;QACzB,UAAU;QACV,sBAAsB;IACxB,GAAG;QAAC;QAAU;QAAW;QAAc;KAAoB;IAE3D,OACE,CAAA,GAAA,UAAA,EAAA,CAAA,GAAA,eAAA,GAAA;QAAA,UACG,SAAS;0BACR;YACA,SAAS;sBACT;QACD;IAAC;AAGR;IAEA,2CAAe;;;;;;;AGjDR,MAAM,4CAA0B;IACrC,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,MAAM,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,eAAA,EACtC,QAAQ,gBAAgB;IAG1B,mDAAmD;IACnD,CAAA,GAAA,gBAAA,EAAU;QACR,IAAI,CAAC,QAAQ;QACb,gBAAgB,OAAO,YAAY;IACrC,GAAG;QAAC;KAAO;IAEX,MAAM,YAAY,CAAA,GAAA,kBAAA,EAChB,CAAC;QACC,gBAAgB;QAChB,QAAQ,YAAY;IACtB,GACA;QAAC;KAAO;IAGV,OAAO;mBACL;sBACA;IACD;AACH;;;ADFO,MAAM,4CAA0D,CAAC,uBACtE,mBAAmB,YACnB,WAAW,iBACX,QAAQ,EACT;IACC,MAAM,aAAE,SAAS,gBAAE,YAAY,EAAE,GAAG,CAAA,GAAA,yCAAA;IAEpC,MAAM,kBAAkB,CAAA,GAAA,kBAAA,EAAY;QAClC,IAAI,UAAU;QAEd,MAAM,kBAAkB,CAAC;QACzB,UAAU;QACV,sBAAsB;IACxB,GAAG;QAAC;QAAU;QAAW;QAAc;KAAoB;IAE3D,OACE,CAAA,GAAA,UAAA,EAAA,CAAA,GAAA,eAAA,GAAA;QAAA,UACG,SAAS;0BACR;YACA,SAAS;sBACT;QACD;IAAC;AAGR;IAEA,2CAAe;;;;;;AGxDf;;;;;;;;;CASG;AAIH,SAAS,mCAAgB,GAAG,IAAoB;IAC9C,OAAO,CAAA,GAAA,kBAAA,EACL,CAAC;QACC,IAAK,IAAI,IAAI,GAAG,IAAI,KAAK,MAAM,EAAE,IAAK;YACpC,MAAM,MAAM,IAAI,CAAC,EAAE;YACnB,IAAI,OAAO,QAAQ,YAAY,IAAI;iBAC9B,IAAI,OAAO,OAAO,QAAQ,UAC5B,IAAkC,OAAO,GAAG;QACjD;IACF,GACA,uDAAuD;IACvD;AAEJ;IAEA,2CAAe;;;;ADcR,MAAM,0DAAkB,CAAA,GAAA,iBAAA,EAC7B,SAAS,iBACP,eACE,cAAc,cACd,MAAM,mBACN,MAAM,YACN,QAAQ,SACR,QAAQ,CAAA,cACR,YAAY,SACZ,GAAG,OACJ,EACD,GAAG;IAEH,MAAM,aAAsC,CAAA,GAAA,yCAAA,EAC1C,WACA;IAGF,MAAM,UAAU,CAAA,GAAA,aAAA,EAAyB;IACzC,MAAM,WAAW,CAAA,GAAA,wCAAA,EAA+B,SAAS;IAEzD;;KAEG,GACH,CAAA,GAAA,gBAAA,EAAU,SAAS;QACjB,MAAM,QAAQ,QAAQ,OAAO;QAC7B,IAAI,CAAC,OAAO;QAEZ,MAAM,YAAY;YAChB,MAAM,UAAU,MAAM,IAAI;YAC1B,IAAI,YAAY,WACd,QACG,IAAI,CAAC;gBACJ,8BAA8B;gBAC9B,MAAM,QAAQ,GAAG;YACnB,GACC,KAAK,CAAC,CAAC;gBACN,iFAAiF;gBACjF,MAAM,QAAQ,GAAG;gBACjB,QAAQ,IAAI,CAAC,wBAAwB;YACvC;QAEN;QAEA,MAAM,gBAAgB;YACpB,IAAI,CAAC,MAAM,MAAM,EAAE;YACnB;QACF;QACA,MAAM,iBAAiB;YACrB,MAAM,KAAK,CAAC,SAAS,GAAG;QAC1B;QACA,MAAM,iBAAiB;YACrB,MAAM,KAAK,CAAC,SAAS,GAAG;YACxB,WAAW;gBACT,IAAI,MAAM,MAAM,EAAE;YACpB,GAAG;QACL;QACA,MAAM,yBAAyB;YAC7B,IAAI,SAAS,eAAe,KAAK,UAAU;YAC3C,IAAI,CAAC,MAAM,MAAM,EAAE;YACnB;QACF;QACA,MAAM,gBAAgB,CAAC,WAAW;QAClC,MAAM,gBAAgB,CAAC,yBAAyB;QAChD,MAAM,gBAAgB,CAAC,yBAAyB;QAEhD,kEAAkE;QAClE,SAAS,gBAAgB,CAAC,oBAAoB;QAC9C,OAAO;YACL,MAAM,mBAAmB,CAAC,WAAW;YACrC,MAAM,mBAAmB,CAAC,yBAAyB;YACnD,MAAM,mBAAmB,CAAC,yBAAyB;YACnD,SAAS,mBAAmB,CAC1B,oBACA;QAEJ;IACF,GAAG,EAAE;IAEL;;KAEG,GACH,CAAA,GAAA,gBAAA,EACE,SAAS;QACP,MAAM,QAAQ,QAAQ,OAAO;QAC7B,IAAI,CAAC,SAAS,CAAC,YAAY;QAC3B,MAAM,SAAS,GAAG,IAAI,YAAY;YAAC;SAAW;QAC9C,MAAM,IAAI;QACV,OAAO;YACL,0BAA0B;YAC1B,MAAM,SAAS,GAAG;YAClB,MAAM,IAAI;QACZ;IACF,GACA;QAAC;QAAY,YAAY;KAAG;IAG9B;;;KAGG,GACH,CAAA,GAAA,gBAAA,EACE,SAAS;QACP,MAAM,QAAQ,QAAQ,OAAO;QAC7B,IAAI,CAAC,YAAY,CAAC,OAAO;QAEzB,IAAI;QACJ,SAAS;YACP,IAAI,OAAO,qBAAqB;YAChC,QAAQ,sBAAsB;gBAC5B,MAAM,QAAQ,QAAQ,OAAO;gBAC7B,IAAI,CAAC,SAAS,SAAS,MAAM,EAAE;gBAC/B,MAAM,aAAa,MAAM,UAAU;gBACnC,MAAM,cAAc,MAAM,WAAW;gBACrC,IAAI,cAAc,aAChB,WAAW;oBACT,aAAa,aAAa;oBAC1B,QAAQ;oBACR,OAAO;gBACR;YAEL;QACF;QAEA;QACA,MAAM,gBAAgB,CAAC,kBAAkB;QACzC,MAAM,gBAAgB,CAAC,UAAU;QAEjC,OAAO;YACL,IAAI,OAAO,qBAAqB;YAChC,MAAM,mBAAmB,CAAC,kBAAkB;YAC5C,MAAM,mBAAmB,CAAC,UAAU;QACtC;IACF,GACA;QAAC;KAAS;IAGZ,OACE,CAAA,GAAA,UAAA,EAAA,SAAA;QACE,UAAQ;QACR,OAAK;QACL,aAAW;QACX,KAAK;QACL,OAAO;YACL,WAAW;YACX,WAAW,SAAS,iBAAiB;YACrC,GAAG,KAAK;QACT;QAAA,GACG,KAAK;IAAA;AAGf;AAEF,0CAAgB,WAAW,GAAG;;;;;;;;;;;;AEzL9B,MAAM,0CAAoB,CAAA,GAAA,WAAA,EAAwB,EAAE;AACpD,MAAM,0CAAoB,CAAA,GAAA,WAAA,EAAwB,EAAE;AACpD,MAAM,8CAAwB,CAAA,GAAA,WAAA,EAAwB,EAAE;AACxD,MAAM,wCAAkB,CAAA,GAAA,WAAA,EAA8B,CAAA;AACtD,MAAM,wCAAkB,CAAA,GAAA,WAAA,EAA8B,CAAA;AACtD,MAAM,4CAAsB,CAAA,GAAA,WAAA,EAA8B,CAAA;AAEnD,MAAM,4CAA4B;IACvC,MAAM,SAAS,CAAA,GAAA,yCAAA;IAEf,MAAM,gBAAgB,CAAA,GAAA,mBAAA,EAAa;IACnC,MAAM,gBAAgB,CAAA,GAAA,mBAAA,EAAa;IACnC,MAAM,oBAAoB,CAAA,GAAA,mBAAA,EAAa;IACvC,MAAM,cAAc,CAAA,GAAA,mBAAA,EAAa;IACjC,MAAM,cAAc,CAAA,GAAA,mBAAA,EAAa;IACjC,MAAM,kBAAkB,CAAA,GAAA,mBAAA,EAAa;IAErC,MAAM,cAAc,CAAA,GAAA,sBAAA,EAClB,CAAA,GAAA,kBAAA,EACE,OAAO,MAAM;QACX,IAAI,CAAC,QAAQ;QAEb,MAAM,gBAAgB,MAAM,OAAO,UAAU;QAC7C,MAAM,gBAAgB,MAAM,OAAO,UAAU;QAC7C,MAAM,oBAAoB,MAAM,OAAO,cAAc;QAErD,IAAI,yCAAmB;QACvB,IAAI,yCAAmB;QACvB,IAAI,6CAAuB;QAE3B,IAAI,uCAAiB,OAAO,WAAW;QACvC,IAAI,uCAAiB,OAAO,WAAW;QACvC,IAAI,2CAAqB,OAAO,eAAe;IACjD,GACA;QAAC;KAAO;IAIZ,CAAA,GAAA,gBAAA,EAAU;QACR;IACF,GAAG;QAAC;KAAY;IAEhB,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,gBAAA,EAAU,oBAAoB,EAC9B,CAAA,GAAA,sBAAA,EACE,CAAA,GAAA,kBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,yCAAmB;IACzB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,gBAAA,EAAU,oBAAoB,EAC9B,CAAA,GAAA,sBAAA,EACE,CAAA,GAAA,kBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,yCAAmB;IACzB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,gBAAA,EAAU,wBAAwB,EAClC,CAAA,GAAA,sBAAA,EACE,CAAA,GAAA,kBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,6CAAuB;IAC7B,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,gBAAA,EAAU,UAAU,EACpB,CAAA,GAAA,sBAAA,EACE,CAAA,GAAA,kBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,uCAAiB;IACvB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,gBAAA,EAAU,UAAU,EACpB,CAAA,GAAA,sBAAA,EACE,CAAA,GAAA,kBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,uCAAiB;IACvB,GAAG,EAAE;IAGT,CAAA,GAAA,yCAAA,EACE,CAAA,GAAA,gBAAA,EAAU,cAAc,EACxB,CAAA,GAAA,sBAAA,EACE,CAAA,GAAA,kBAAA,EAAY,CAAC,MAAM,KAAK;QACtB,IAAI,2CAAqB;IAC3B,GAAG,EAAE;IAIT,MAAM,YAAY,CAAA,GAAA,kBAAA,EAChB,CAAC;QACC,QAAQ,UAAU;IACpB,GACA;QAAC;KAAO;IAEV,MAAM,YAAY,CAAA,GAAA,kBAAA,EAChB,CAAC;QACC,QAAQ,UAAU;IACpB,GACA;QAAC;KAAO;IAEV,MAAM,gBAAgB,CAAA,GAAA,kBAAA,EACpB,CAAC;QACC,QAAQ,cAAc;IACxB,GACA;QAAC;KAAO;IAGV,OAAO;uBACL;uBACA;2BACA;qBACA;qBACA;yBACA;mBACA;mBACA;uBACA;IACD;AACH;;;;;ACnIA;;;;CAIG;;;AAOH,MAAM,2CAAqB,CAAA,GAAA,WAAA,EAAqB;AAEzC,MAAM,4CAA8B;IACzC,MAAM,CAAC,gBAAgB,kBAAkB,GAAG,CAAA,GAAA,cAAA,EAAQ;IAEpD,CAAA,GAAA,yCAAA,EAAmB,CAAA,GAAA,gBAAA,EAAU,qBAAqB,EAAE;IAEpD,OAAO;AACT;;;;;;ACKO,MAAM,0DAAmC,CAAA,GAAA,YAAA,EAAM,IAAI,CACxD,CAAC,mBACC,kBAAkB,yBAClB,WAAW,mBACX,WAAW,WACX,SAAS,gBACT,aAAa,uBACb,eAAe,gBACf,YAAY,oBACZ,WAAW,qBACX,eAAe,EAChB;IACC,MAAM,YAAY,CAAA,GAAA,aAAA,EAA0B;IAE5C,MAAM,QAAiC,CAAA,GAAA,yCAAA,EACrC,SACA;IAGF,CAAA,GAAA,gBAAA,EAAU;QACR,IAAI,CAAC,UAAU,OAAO,EAAE;QAExB,MAAM,cAAc,WAAW,WAAW,AAAC,CAAA,WAAW,CAAA,IAAK;QAC3D,MAAM,eAAe;QAErB,MAAM,SAAS,UAAU,OAAO;QAEhC,MAAM,cAAc;QAEpB,yDAAyD;QACzD,MAAM,eAAe;YACnB,OAAO,KAAK,GAAG,cAAc;YAC7B,OAAO,MAAM,GAAG,eAAe;YAE/B,OAAO,KAAK,CAAC,KAAK,GAAG,GAAG,YAAW,EAAA,CAAI;YACvC,OAAO,KAAK,CAAC,MAAM,GAAG,GAAG,aAAY,EAAA,CAAI;YAEzC,UAAU,OAAO,GAAG;YACpB,UAAU,KAAK,CAAC,aAAa;QAC/B;QAEA,MAAM,YAAY,OAAO,UAAU,CAAC;QACpC;QAEA,IAAI,CAAC,OAAO;QAEZ,MAAM,eAAe,IAAI;QACzB,MAAM,SAAS,aAAa,uBAAuB,CACjD,IAAI,YAAY;YAAC;SAAM;QAEzB,MAAM,WAAW,aAAa,cAAc;QAE5C,SAAS,OAAO,GAAG;QAEnB,OAAO,OAAO,CAAC;QAEf,MAAM,gBAAgB,IAAI,WAAW,SAAS,iBAAiB;QAE/D,UAAU,OAAO,GAAG;QAEpB,2CAA2C;QAC3C,MAAM,QAAQ,MAAM,IAAI,CAAC;YAAE,QAAQ;QAAQ,GAAI,CAAC,GAAG;YACjD,mEAAmE;YACnE,MAAM,UAAU,WAAW,KAAK,MAAM,IAAI,0CAA0C;YACpF,MAAM,UAAU,OAAO,yCAAyC;YAEhE,6EAA6E;YAC7E,gFAAgF;YAChF,0CAA0C;YAC1C,MAAM,SAAS,OAAO,KAAK,KAAK,CAAC,IAAI,UAAU;YAC/C,MAAM,SAAS,OAAO,KAAK,KAAK,CAAC,IAAI,UAAU;YAC/C,MAAM,UAAU,AAAC,CAAA,SAAS,MAAA,IAAU;YAEpC,MAAM,WAAW,SAAS,IAAI;YAC9B,MAAM,YAAY,MAAO,CAAA,KAAK,GAAG,CAAC,IAAI,WAAW,QAAQ,CAAA;YACzD,MAAM,UAAU,MAAO,CAAA,KAAK,GAAG,CAAC,IAAI,AAAC,CAAA,WAAW,OAAA,IAAW,QAAQ,CAAA;YAEnE,OAAO;2BACL;yBACA;gBACA,aAAa;YACd;QACH;QAEA,MAAM,uBAAuB,CAAC;YAC5B,MAAM,UAAU,aAAa,UAAU,GAAG;YAC1C,OAAO,KAAK,KAAK,CACf,AAAC,YAAY,UAAY,CAAA,SAAS,iBAAiB,GAAG,CAAA;QAE1D;QAEA,SAAS;YACP,SAAS,oBAAoB,CAAC;YAC9B,UAAU,SAAS,CACjB,GACA,GACA,OAAO,KAAK,GAAG,aACf,OAAO,MAAM,GAAG;YAElB,UAAU,SAAS,GAAG;YACtB,UAAU,QAAQ,CAChB,GACA,GACA,OAAO,KAAK,GAAG,aACf,OAAO,MAAM,GAAG;YAGlB,IAAI,WAAW;YAEf,MAAM,iBACJ,MAAM,MAAM,GAAG,WAAW,AAAC,CAAA,MAAM,MAAM,GAAG,CAAA,IAAK;YACjD,MAAM,SAAS,AAAC,CAAA,OAAO,KAAK,GAAG,cAAc,cAAA,IAAkB,GAAG,cAAc;YAEhF,MAAM,uBAAuB,WAAW,GAAG,iCAAiC;YAE5E,MAAM,OAAO,CAAC,CAAC,MAAM;gBACnB,MAAM,aAAa,qBAAqB,KAAK,SAAS;gBACtD,MAAM,WAAW,qBAAqB,KAAK,OAAO;gBAClD,MAAM,WAAW,cAAc,KAAK,CAAC,YAAY;gBACjD,MAAM,YACJ,SAAS,MAAM,CAAC,CAAC,KAAK,MAAQ,MAAM,KAAK,KAAK,SAAS,MAAM;gBAE/D,MAAM,kBAAkB;gBAExB,IAAI,YAAY,GACd,KAAK,WAAW,GAAG,KAAK,GAAG,CACzB,KAAK,WAAW,GAAG,kBAAkB,GACrC;qBAEG;oBACL,KAAK,WAAW,GACd,KAAK,WAAW,GAChB,AAAC,CAAA,YAAY,KAAK,WAAW,AAAX,IAAe;oBACnC,WAAW;gBACb;gBAEA,MAAM,IAAI,SAAS,IAAK,CAAA,WAAW,MAAA;gBACnC,0CAA0C;gBAC1C,MAAM,YAAY;gBAClB,MAAM,YAAY,KAAK,GAAG,CACxB,WACA,KAAK,GAAG,CAAC,AAAC,KAAK,WAAW,GAAG,MAAO,cAAc;gBAGpD,IAAI,MAAM;gBACV,MAAM,eAAe,OAAO,MAAM,GAAG;gBAErC,OAAQ;oBACN,KAAK;wBACH,OAAO;wBACP,UAAU,KAAK,GAAG,CAChB,uBAAuB,WACvB,eAAe;wBAEjB;oBACF,KAAK;wBACH,UAAU,eAAe;wBACzB,OAAO,KAAK,GAAG,CAAC,UAAU,WAAW;wBACrC;oBACF,KAAK;oBACL;wBACE,OAAO,KAAK,GAAG,CACb,eAAe,IAAI,YAAY,GAC/B;wBAEF,UAAU,KAAK,GAAG,CAChB,eAAe,IAAI,YAAY,GAC/B,eAAe;wBAEjB;gBACJ;gBAEA,IAAI,KAAK,WAAW,GAAG,GAAG;oBACxB,UAAU,SAAS;oBACnB,UAAU,MAAM,CAAC,IAAI,WAAW,GAAG;oBACnC,UAAU,MAAM,CAAC,IAAI,WAAW,GAAG;oBACnC,UAAU,SAAS,GAAG;oBACtB,UAAU,WAAW,GAAG;oBACxB,UAAU,MAAM;gBAClB,OACE,mBAAmB,sBAAsB,UAAU,GAAG;YAE1D;YAEA,IAAI,CAAC,UACH,oBAAoB,sBAAsB;YAG5C,sBAAsB;QACxB;QAEA,SAAS,mBACP,YAAoB,EACpB,KAAa,EACb,CAAS,EACT,CAAS;YAET,OAAQ;gBACN,KAAK;oBACH,UAAU,SAAS,GAAG;oBACtB,UAAU,QAAQ,CAChB,IAAI,WAAW,IAAI,cACnB,IAAI,cACJ,eAAe,GACf,eAAe;oBAEjB;gBACF,KAAK;gBACL;oBACE,UAAU,SAAS;oBACnB,UAAU,GAAG,CAAC,IAAI,WAAW,GAAG,GAAG,cAAc,GAAG,IAAI,KAAK,EAAE;oBAC/D,UAAU,SAAS,GAAG;oBACtB,UAAU,IAAI;oBACd,UAAU,SAAS;oBACnB;YACJ;QACF;QAEA,SAAS,oBAAoB,YAAoB,EAAE,KAAa;YAC9D,MAAM,iBACJ,MAAM,MAAM,GAAG,WAAW,AAAC,CAAA,MAAM,MAAM,GAAG,CAAA,IAAK;YACjD,MAAM,SAAS,AAAC,CAAA,OAAO,KAAK,GAAG,cAAc,cAAA,IAAkB;YAC/D,MAAM,eAAe,OAAO,MAAM,GAAG;YAErC,IAAI;YACJ,OAAQ;gBACN,KAAK;oBACH,IAAI;oBACJ;gBACF,KAAK;oBACH,IAAI,eAAe;oBACnB;gBACF,KAAK;gBACL;oBACE,IAAI,eAAe;oBACnB;YACJ;YAEA,MAAM,OAAO,CAAC,CAAC,GAAG;gBAChB,MAAM,IAAI,SAAS,IAAK,CAAA,WAAW,MAAA;gBACnC,mBAAmB,cAAc,OAAO,GAAG;YAC7C;QACF;QAEA;QAEA,kBAAkB;QAClB,OAAO,gBAAgB,CAAC,UAAU;QAElC,OAAO;YACL,aAAa,KAAK;YAClB,OAAO,mBAAmB,CAAC,UAAU;QACvC;IACF,GAAG;QACD;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;KACD;IAED,OACE,CAAA,GAAA,UAAA,EAAA,UAAA;QACE,KAAK;QACL,OAAO;YACL,SAAS;YACT,OAAO;YACP,QAAQ;QACT;IAAA;AAGP;AAGF,0CAAgB,WAAW,GAAG;","sources":["client-react/src/index.ts","client-react/src/RTVIClientAudio.tsx","client-react/src/useRTVIClientEvent.ts","client-react/src/useRTVIClient.ts","client-react/src/RTVIClientProvider.tsx","client-react/src/useRTVIClientMediaTrack.ts","client-react/src/RTVIClientCamToggle.tsx","client-react/src/useRTVIClientCamControl.ts","client-react/src/RTVIClientMicToggle.tsx","client-react/src/useRTVIClientMicControl.ts","client-react/src/RTVIClientVideo.tsx","client-react/src/useMergedRef.ts","client-react/src/useRTVIClientMediaDevices.ts","client-react/src/useRTVIClientTransportState.ts","client-react/src/VoiceVisualizer.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIClientAudio } from \"./RTVIClientAudio\";\nimport { RTVIClientCamToggle } from \"./RTVIClientCamToggle\";\nimport { RTVIClientMicToggle } from \"./RTVIClientMicToggle\";\nimport { RTVIClientProvider } from \"./RTVIClientProvider\";\nimport { RTVIClientVideo } from \"./RTVIClientVideo\";\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientCamControl } from \"./useRTVIClientCamControl\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { useRTVIClientMediaDevices } from \"./useRTVIClientMediaDevices\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\nimport { useRTVIClientMicControl } from \"./useRTVIClientMicControl\";\nimport { useRTVIClientTransportState } from \"./useRTVIClientTransportState\";\nimport { VoiceVisualizer } from \"./VoiceVisualizer\";\n\nexport {\n RTVIClientAudio,\n RTVIClientCamToggle,\n RTVIClientMicToggle,\n RTVIClientProvider,\n RTVIClientVideo,\n useRTVIClient,\n useRTVIClientCamControl,\n useRTVIClientEvent,\n useRTVIClientMediaDevices,\n useRTVIClientMediaTrack,\n useRTVIClientMicControl,\n useRTVIClientTransportState,\n VoiceVisualizer,\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { useCallback, useEffect, useRef } from \"react\";\n\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\nexport const RTVIClientAudio = () => {\n const botAudioRef = useRef<HTMLAudioElement>(null);\n const botAudioTrack = useRTVIClientMediaTrack(\"audio\", \"bot\");\n\n useEffect(() => {\n if (!botAudioRef.current || !botAudioTrack) return;\n if (botAudioRef.current.srcObject) {\n const oldTrack = (\n botAudioRef.current.srcObject as MediaStream\n ).getAudioTracks()[0];\n if (oldTrack.id === botAudioTrack.id) return;\n }\n botAudioRef.current.srcObject = new MediaStream([botAudioTrack]);\n }, [botAudioTrack]);\n\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useCallback((speaker: MediaDeviceInfo) => {\n if (!botAudioRef.current) return;\n if (typeof botAudioRef.current.setSinkId !== \"function\") return;\n botAudioRef.current.setSinkId(speaker.deviceId);\n }, [])\n );\n\n return (\n <>\n <audio ref={botAudioRef} autoPlay />\n </>\n );\n};\nRTVIClientAudio.displayName = \"RTVIClientAudio\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, RTVIEventHandler } from \"@pipecat-ai/client-js\";\nimport { useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\n\nexport const useRTVIClientEvent = <E extends RTVIEvent>(\n event: E,\n handler: RTVIEventHandler<E>\n) => {\n const client = useRTVIClient();\n\n useEffect(() => {\n if (!client) return;\n client.on(event, handler);\n return () => {\n client.off(event, handler);\n };\n }, [event, handler, client]);\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { RTVIClientContext } from \"./RTVIClientProvider\";\n\nexport const useRTVIClient = () => {\n const { client } = useContext(RTVIClientContext);\n return client;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIClient } from \"@pipecat-ai/client-js\";\nimport { createStore } from \"jotai\";\nimport { Provider as JotaiProvider } from \"jotai/react\";\nimport React, { createContext } from \"react\";\n\nexport interface Props {\n client: RTVIClient;\n jotaiStore?: React.ComponentProps<typeof JotaiProvider>[\"store\"];\n}\n\nconst defaultStore = createStore();\n\nexport const RTVIClientContext = createContext<{ client?: RTVIClient }>({});\n\nexport const RTVIClientProvider: React.FC<React.PropsWithChildren<Props>> = ({\n children,\n client,\n jotaiStore = defaultStore,\n}) => {\n return (\n <JotaiProvider store={jotaiStore}>\n <RTVIClientContext.Provider value={{ client }}>\n {children}\n </RTVIClientContext.Provider>\n </JotaiProvider>\n );\n};\nRTVIClientProvider.displayName = \"RTVIClientProvider\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { Participant, RTVIEvent, Tracks } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { atomFamily, useAtomCallback } from \"jotai/utils\";\nimport { PrimitiveAtom } from \"jotai/vanilla\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype ParticipantType = keyof Tracks;\ntype TrackType = keyof Tracks[\"local\"];\n\nconst localAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botVideoTrackAtom = atom<MediaStreamTrack | null>(null);\n\nconst trackAtom = atomFamily<\n { local: boolean; trackType: TrackType },\n PrimitiveAtom<MediaStreamTrack | null>\n>(({ local, trackType }) => {\n if (local) {\n switch (trackType) {\n case \"audio\":\n return localAudioTrackAtom;\n case \"screenAudio\":\n return localScreenAudioTrackAtom;\n case \"screenVideo\":\n return localScreenVideoTrackAtom;\n case \"video\":\n return localVideoTrackAtom;\n }\n }\n return trackType === \"audio\" ? botAudioTrackAtom : botVideoTrackAtom;\n});\n\nexport const useRTVIClientMediaTrack = (\n trackType: TrackType,\n participantType: ParticipantType\n) => {\n const client = useRTVIClient();\n const track = useAtomValue(\n trackAtom({ local: participantType === \"local\", trackType })\n );\n\n const updateTrack = useAtomCallback(\n useCallback(\n (\n get,\n set,\n track: MediaStreamTrack,\n trackType: TrackType,\n local: boolean\n ) => {\n const atom = trackAtom({\n local,\n trackType,\n });\n const oldTrack = get(atom);\n if (oldTrack?.id === track.id) return;\n set(atom, track);\n },\n []\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.TrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n updateTrack(\n track,\n track.kind as TrackType,\n Boolean(participant?.local)\n );\n },\n [updateTrack]\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.ScreenTrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n const trackType =\n track.kind === \"audio\" ? \"screenAudio\" : \"screenVideo\";\n updateTrack(track, trackType, Boolean(participant?.local));\n },\n [updateTrack]\n )\n );\n\n useEffect(() => {\n if (!client) return;\n const tracks = client.tracks();\n const track = tracks?.[participantType]?.[trackType];\n if (!track) return;\n updateTrack(track, trackType, participantType === \"local\");\n }, [participantType, trackType, updateTrack, client]);\n\n return track;\n};\n","import React, { useCallback } from \"react\";\n\nimport { useRTVIClientCamControl } from \"./useRTVIClientCamControl\";\n\nexport interface RTVIClientCamToggleProps {\n /**\n * Callback fired when camera state changes\n */\n onCamEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the cam toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isCamEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling camera state\n */\nexport const RTVIClientCamToggle: React.FC<RTVIClientCamToggleProps> = ({\n onCamEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { isCamEnabled, enableCam } = useRTVIClientCamControl();\n\n const handleToggleCam = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isCamEnabled;\n enableCam(newEnabledState);\n onCamEnabledChanged?.(newEnabledState);\n }, [disabled, enableCam, isCamEnabled, onCamEnabledChanged]);\n\n return (\n <>\n {children({\n isCamEnabled,\n onClick: handleToggleCam,\n disabled,\n })}\n </>\n );\n};\n\nexport default RTVIClientCamToggle;\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\n\n/**\n * Hook to control camera state\n */\nexport const useRTVIClientCamControl = () => {\n const client = useRTVIClient();\n\n const [isCamEnabled, setIsCamEnabled] = useState(\n client?.isCamEnabled ?? false\n );\n\n // Sync component state with client state initially\n useEffect(() => {\n if (!client) return;\n setIsCamEnabled(client.isCamEnabled);\n }, [client]);\n\n const enableCam = useCallback(\n (enabled: boolean) => {\n setIsCamEnabled(enabled);\n client?.enableCam?.(enabled);\n },\n [client]\n );\n\n return {\n enableCam,\n isCamEnabled,\n };\n};\n","import React, { useCallback } from \"react\";\n\nimport { useRTVIClientMicControl } from \"./useRTVIClientMicControl\";\n\nexport interface RTVIClientMicToggleProps {\n /**\n * Callback fired when microphone state changes\n */\n onMicEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the mic toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isMicEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling microphone state\n */\nexport const RTVIClientMicToggle: React.FC<RTVIClientMicToggleProps> = ({\n onMicEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { enableMic, isMicEnabled } = useRTVIClientMicControl();\n\n const handleToggleMic = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isMicEnabled;\n enableMic(newEnabledState);\n onMicEnabledChanged?.(newEnabledState);\n }, [disabled, enableMic, isMicEnabled, onMicEnabledChanged]);\n\n return (\n <>\n {children({\n isMicEnabled,\n onClick: handleToggleMic,\n disabled,\n })}\n </>\n );\n};\n\nexport default RTVIClientMicToggle;\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\n\n/**\n * Hook to control microphone state\n */\nexport const useRTVIClientMicControl = () => {\n const client = useRTVIClient();\n\n const [isMicEnabled, setIsMicEnabled] = useState(\n client?.isMicEnabled ?? false\n );\n\n // Sync component state with client state initially\n useEffect(() => {\n if (!client) return;\n setIsMicEnabled(client.isMicEnabled);\n }, [client]);\n\n const enableMic = useCallback(\n (enabled: boolean) => {\n setIsMicEnabled(enabled);\n client?.enableMic?.(enabled);\n },\n [client]\n );\n\n return {\n enableMic,\n isMicEnabled,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { forwardRef, useEffect, useRef } from \"react\";\n\nimport useMergedRef from \"./useMergedRef\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\ninterface RTVIClientVideoInterface {\n aspectRatio: number;\n height: number;\n width: number;\n}\n\nexport interface Props\n extends Omit<React.VideoHTMLAttributes<HTMLVideoElement>, \"onResize\"> {\n participant: \"local\" | \"bot\";\n\n /**\n * Defines the video track type to display. Default: 'video'.\n */\n trackType?: \"screenVideo\" | \"video\";\n\n /**\n * Defines whether the video should be fully contained or cover the box. Default: 'contain'.\n */\n fit?: \"contain\" | \"cover\";\n /**\n * Forces the video to be mirrored, if set.\n */\n mirror?: boolean;\n\n /**\n * Optional callback, which is triggered whenever the video's rendered width or height changes.\n * Returns the video's native width, height and aspectRatio.\n */\n onResize?(dimensions: RTVIClientVideoInterface): void;\n}\n\nexport const RTVIClientVideo = forwardRef<HTMLVideoElement, Props>(\n function VoiceClientVideo(\n {\n participant = \"local\",\n fit = \"contain\",\n mirror,\n onResize,\n style = {},\n trackType = \"video\",\n ...props\n },\n ref\n ) {\n const videoTrack: MediaStreamTrack | null = useRTVIClientMediaTrack(\n trackType,\n participant\n );\n\n const videoEl = useRef<HTMLVideoElement>(null);\n const videoRef = useMergedRef<HTMLVideoElement>(videoEl, ref);\n\n /**\n * Handle canplay & picture-in-picture events.\n */\n useEffect(function setupVideoEvents() {\n const video = videoEl.current;\n if (!video) return;\n\n const playVideo = () => {\n const promise = video.play();\n if (promise !== undefined) {\n promise\n .then(() => {\n // All good, playback started.\n video.controls = false;\n })\n .catch((error) => {\n // Auto-play was prevented. Show video controls, so user can play video manually.\n video.controls = true;\n console.warn(\"Failed to play video\", error);\n });\n }\n };\n\n const handleCanPlay = () => {\n if (!video.paused) return;\n playVideo();\n };\n const handleEnterPIP = () => {\n video.style.transform = \"scale(1)\";\n };\n const handleLeavePIP = () => {\n video.style.transform = \"\";\n setTimeout(() => {\n if (video.paused) playVideo();\n }, 100);\n };\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"hidden\") return;\n if (!video.paused) return;\n playVideo();\n };\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.addEventListener(\"leavepictureinpicture\", handleLeavePIP);\n\n // Videos can be paused if media was played in another app on iOS.\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n return () => {\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.removeEventListener(\"leavepictureinpicture\", handleLeavePIP);\n document.removeEventListener(\n \"visibilitychange\",\n handleVisibilityChange\n );\n };\n }, []);\n\n /**\n * Update srcObject.\n */\n useEffect(\n function updateSrcObject() {\n const video = videoEl.current;\n if (!video || !videoTrack) return;\n video.srcObject = new MediaStream([videoTrack]);\n video.load();\n return () => {\n // clean up when unmounted\n video.srcObject = null;\n video.load();\n };\n },\n [videoTrack, videoTrack?.id]\n );\n\n /**\n * Add optional event listener for resize event so the parent component\n * can know the video's native aspect ratio.\n */\n useEffect(\n function reportVideoDimensions() {\n const video = videoEl.current;\n if (!onResize || !video) return;\n\n let frame: ReturnType<typeof requestAnimationFrame>;\n function handleResize() {\n if (frame) cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n const video = videoEl.current;\n if (!video || document.hidden) return;\n const videoWidth = video.videoWidth;\n const videoHeight = video.videoHeight;\n if (videoWidth && videoHeight) {\n onResize?.({\n aspectRatio: videoWidth / videoHeight,\n height: videoHeight,\n width: videoWidth,\n });\n }\n });\n }\n\n handleResize();\n video.addEventListener(\"loadedmetadata\", handleResize);\n video.addEventListener(\"resize\", handleResize);\n\n return () => {\n if (frame) cancelAnimationFrame(frame);\n video.removeEventListener(\"loadedmetadata\", handleResize);\n video.removeEventListener(\"resize\", handleResize);\n };\n },\n [onResize]\n );\n\n return (\n <video\n autoPlay\n muted\n playsInline\n ref={videoRef}\n style={{\n objectFit: fit,\n transform: mirror ? \"scale(-1, 1)\" : \"\",\n ...style,\n }}\n {...props}\n />\n );\n }\n);\nRTVIClientVideo.displayName = \"RTVIClientVideo\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n *\n * This file contains code derived from:\n * https://github.com/jaredLunde/react-hook/blob/master/packages/merged-ref/src/index.tsx\n * Original author: Jared Lunde (https://github.com/jaredLunde)\n * Original license: MIT (https://github.com/jaredLunde/react-hook/blob/master/LICENSE)\n */\n\nimport React, { useCallback } from \"react\";\n\nfunction useMergedRef<T>(...refs: React.Ref<T>[]): React.RefCallback<T> {\n return useCallback(\n (element: T) => {\n for (let i = 0; i < refs.length; i++) {\n const ref = refs[i];\n if (typeof ref === \"function\") ref(element);\n else if (ref && typeof ref === \"object\")\n (ref as React.MutableRefObject<T>).current = element;\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n refs\n );\n}\n\nexport default useMergedRef;\n","import { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype OptionalMediaDeviceInfo = MediaDeviceInfo | Record<string, never>;\n\nconst availableMicsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableCamsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableSpeakersAtom = atom<MediaDeviceInfo[]>([]);\nconst selectedMicAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedCamAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedSpeakerAtom = atom<OptionalMediaDeviceInfo>({});\n\nexport const useRTVIClientMediaDevices = () => {\n const client = useRTVIClient();\n\n const availableCams = useAtomValue(availableCamsAtom);\n const availableMics = useAtomValue(availableMicsAtom);\n const availableSpeakers = useAtomValue(availableSpeakersAtom);\n const selectedCam = useAtomValue(selectedCamAtom);\n const selectedMic = useAtomValue(selectedMicAtom);\n const selectedSpeaker = useAtomValue(selectedSpeakerAtom);\n\n const initDevices = useAtomCallback(\n useCallback(\n async (_get, set) => {\n if (!client) return;\n\n const availableCams = await client.getAllCams();\n const availableMics = await client.getAllMics();\n const availableSpeakers = await client.getAllSpeakers();\n\n set(availableCamsAtom, availableCams);\n set(availableMicsAtom, availableMics);\n set(availableSpeakersAtom, availableSpeakers);\n\n set(selectedCamAtom, client.selectedCam);\n set(selectedMicAtom, client.selectedMic);\n set(selectedSpeakerAtom, client.selectedSpeaker);\n },\n [client]\n )\n );\n\n useEffect(() => {\n initDevices();\n }, [initDevices]);\n\n useRTVIClientEvent(\n RTVIEvent.AvailableCamsUpdated,\n useAtomCallback(\n useCallback((_get, set, cams) => {\n set(availableCamsAtom, cams);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableMicsUpdated,\n useAtomCallback(\n useCallback((_get, set, mics) => {\n set(availableMicsAtom, mics);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableSpeakersUpdated,\n useAtomCallback(\n useCallback((_get, set, speakers) => {\n set(availableSpeakersAtom, speakers);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.CamUpdated,\n useAtomCallback(\n useCallback((_get, set, cam) => {\n set(selectedCamAtom, cam);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.MicUpdated,\n useAtomCallback(\n useCallback((_get, set, mic) => {\n set(selectedMicAtom, mic);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useAtomCallback(\n useCallback((_get, set, speaker) => {\n set(selectedSpeakerAtom, speaker);\n }, [])\n )\n );\n\n const updateCam = useCallback(\n (id: string) => {\n client?.updateCam(id);\n },\n [client]\n );\n const updateMic = useCallback(\n (id: string) => {\n client?.updateMic(id);\n },\n [client]\n );\n const updateSpeaker = useCallback(\n (id: string) => {\n client?.updateSpeaker(id);\n },\n [client]\n );\n\n return {\n availableCams,\n availableMics,\n availableSpeakers,\n selectedCam,\n selectedMic,\n selectedSpeaker,\n updateCam,\n updateMic,\n updateSpeaker,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, TransportState } from \"@pipecat-ai/client-js\";\nimport { atom, useAtom } from \"jotai\";\n\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\nconst transportStateAtom = atom<TransportState>(\"disconnected\");\n\nexport const useRTVIClientTransportState = () => {\n const [transportState, setTransportState] = useAtom(transportStateAtom);\n\n useRTVIClientEvent(RTVIEvent.TransportStateChanged, setTransportState);\n\n return transportState;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { useEffect, useRef } from \"react\";\n\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\ntype ParticipantType = Parameters<typeof useRTVIClientMediaTrack>[1];\n\ninterface Props {\n backgroundColor?: string;\n barColor?: string;\n barCount?: number;\n barGap?: number;\n barLineCap?: \"round\" | \"square\";\n barMaxHeight?: number;\n barOrigin?: \"top\" | \"bottom\" | \"center\";\n barWidth?: number;\n participantType: ParticipantType;\n}\n\nexport const VoiceVisualizer: React.FC<Props> = React.memo(\n ({\n backgroundColor = \"transparent\",\n barColor = \"black\",\n barCount = 5,\n barGap = 12,\n barLineCap = \"round\",\n barMaxHeight = 120,\n barOrigin = \"center\",\n barWidth = 30,\n participantType,\n }) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const track: MediaStreamTrack | null = useRTVIClientMediaTrack(\n \"audio\",\n participantType\n );\n\n useEffect(() => {\n if (!canvasRef.current) return;\n\n const canvasWidth = barCount * barWidth + (barCount - 1) * barGap;\n const canvasHeight = barMaxHeight;\n\n const canvas = canvasRef.current;\n\n const scaleFactor = 2;\n\n // Make canvas fill the width and height of its container\n const resizeCanvas = () => {\n canvas.width = canvasWidth * scaleFactor;\n canvas.height = canvasHeight * scaleFactor;\n\n canvas.style.width = `${canvasWidth}px`;\n canvas.style.height = `${canvasHeight}px`;\n\n canvasCtx.lineCap = barLineCap;\n canvasCtx.scale(scaleFactor, scaleFactor);\n };\n\n const canvasCtx = canvas.getContext(\"2d\")!;\n resizeCanvas();\n\n if (!track) return;\n\n const audioContext = new AudioContext();\n const source = audioContext.createMediaStreamSource(\n new MediaStream([track])\n );\n const analyser = audioContext.createAnalyser();\n\n analyser.fftSize = 1024;\n\n source.connect(analyser);\n\n const frequencyData = new Uint8Array(analyser.frequencyBinCount);\n\n canvasCtx.lineCap = barLineCap;\n\n // Create frequency bands based on barCount\n const bands = Array.from({ length: barCount }, (_, i) => {\n // Use improved logarithmic scale for better frequency distribution\n const minFreq = barCount > 20 ? 200 : 80; // Adjust min frequency based on bar count\n const maxFreq = 10000; // Cover most important audio frequencies\n\n // Use Mel scale inspired approach for more perceptually uniform distribution\n // This helps with a large number of bars by placing fewer in the very low range\n // https://en.wikipedia.org/wiki/Mel_scale\n const melMin = 2595 * Math.log10(1 + minFreq / 700);\n const melMax = 2595 * Math.log10(1 + maxFreq / 700);\n const melStep = (melMax - melMin) / barCount;\n\n const melValue = melMin + i * melStep;\n const startFreq = 700 * (Math.pow(10, melValue / 2595) - 1);\n const endFreq = 700 * (Math.pow(10, (melValue + melStep) / 2595) - 1);\n\n return {\n startFreq,\n endFreq,\n smoothValue: 0,\n };\n });\n\n const getFrequencyBinIndex = (frequency: number) => {\n const nyquist = audioContext.sampleRate / 2;\n return Math.round(\n (frequency / nyquist) * (analyser.frequencyBinCount - 1)\n );\n };\n\n function drawSpectrum() {\n analyser.getByteFrequencyData(frequencyData);\n canvasCtx.clearRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n canvasCtx.fillStyle = backgroundColor;\n canvasCtx.fillRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n\n let isActive = false;\n\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2; // Center bars\n\n const adjustedCircleRadius = barWidth / 2; // Fixed radius for reset circles\n\n bands.forEach((band, i) => {\n const startIndex = getFrequencyBinIndex(band.startFreq);\n const endIndex = getFrequencyBinIndex(band.endFreq);\n const bandData = frequencyData.slice(startIndex, endIndex);\n const bandValue =\n bandData.reduce((acc, val) => acc + val, 0) / bandData.length;\n\n const smoothingFactor = 0.2;\n\n if (bandValue < 1) {\n band.smoothValue = Math.max(\n band.smoothValue - smoothingFactor * 5,\n 0\n );\n } else {\n band.smoothValue =\n band.smoothValue +\n (bandValue - band.smoothValue) * smoothingFactor;\n isActive = true;\n }\n\n const x = startX + i * (barWidth + barGap);\n // Calculate bar height with a maximum cap\n const minHeight = 0;\n const barHeight = Math.max(\n minHeight,\n Math.min((band.smoothValue / 255) * barMaxHeight, barMaxHeight)\n );\n\n let yTop, yBottom;\n const canvasHeight = canvas.height / scaleFactor;\n\n switch (barOrigin) {\n case \"top\":\n yTop = adjustedCircleRadius;\n yBottom = Math.min(\n adjustedCircleRadius + barHeight,\n canvasHeight - adjustedCircleRadius\n );\n break;\n case \"bottom\":\n yBottom = canvasHeight - adjustedCircleRadius;\n yTop = Math.max(yBottom - barHeight, adjustedCircleRadius);\n break;\n case \"center\":\n default:\n yTop = Math.max(\n canvasHeight / 2 - barHeight / 2,\n adjustedCircleRadius\n );\n yBottom = Math.min(\n canvasHeight / 2 + barHeight / 2,\n canvasHeight - adjustedCircleRadius\n );\n break;\n }\n\n if (band.smoothValue > 0) {\n canvasCtx.beginPath();\n canvasCtx.moveTo(x + barWidth / 2, yTop);\n canvasCtx.lineTo(x + barWidth / 2, yBottom);\n canvasCtx.lineWidth = barWidth;\n canvasCtx.strokeStyle = barColor;\n canvasCtx.stroke();\n } else {\n drawInactiveCircle(adjustedCircleRadius, barColor, x, yTop);\n }\n });\n\n if (!isActive) {\n drawInactiveCircles(adjustedCircleRadius, barColor);\n }\n\n requestAnimationFrame(drawSpectrum);\n }\n\n function drawInactiveCircle(\n circleRadius: number,\n color: string,\n x: number,\n y: number\n ) {\n switch (barLineCap) {\n case \"square\":\n canvasCtx.fillStyle = color;\n canvasCtx.fillRect(\n x + barWidth / 2 - circleRadius,\n y - circleRadius,\n circleRadius * 2,\n circleRadius * 2\n );\n break;\n case \"round\":\n default:\n canvasCtx.beginPath();\n canvasCtx.arc(x + barWidth / 2, y, circleRadius, 0, 2 * Math.PI);\n canvasCtx.fillStyle = color;\n canvasCtx.fill();\n canvasCtx.closePath();\n break;\n }\n }\n\n function drawInactiveCircles(circleRadius: number, color: string) {\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2;\n const canvasHeight = canvas.height / scaleFactor;\n\n let y;\n switch (barOrigin) {\n case \"top\":\n y = circleRadius;\n break;\n case \"bottom\":\n y = canvasHeight - circleRadius;\n break;\n case \"center\":\n default:\n y = canvasHeight / 2;\n break;\n }\n\n bands.forEach((_, i) => {\n const x = startX + i * (barWidth + barGap);\n drawInactiveCircle(circleRadius, color, x, y);\n });\n }\n\n drawSpectrum();\n\n // Handle resizing\n window.addEventListener(\"resize\", resizeCanvas);\n\n return () => {\n audioContext.close();\n window.removeEventListener(\"resize\", resizeCanvas);\n };\n }, [\n backgroundColor,\n barColor,\n barCount,\n barGap,\n barLineCap,\n barMaxHeight,\n barOrigin,\n barWidth,\n track,\n ]);\n\n return (\n <canvas\n ref={canvasRef}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n }}\n />\n );\n }\n);\n\nVoiceVisualizer.displayName = \"VoiceVisualizer\";\n"],"names":[],"version":3,"file":"index.module.js.map"}
|
|
1
|
+
{"mappings":"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","sources":["client-react/src/index.ts","client-react/src/RTVIClientAudio.tsx","client-react/src/useRTVIClientEvent.ts","client-react/src/useRTVIClient.ts","client-react/src/RTVIClientProvider.tsx","client-react/src/useRTVIClientMediaTrack.ts","client-react/src/RTVIClientCamToggle.tsx","client-react/src/useRTVIClientCamControl.ts","client-react/src/useRTVIClientTransportState.ts","client-react/src/RTVIClientMicToggle.tsx","client-react/src/useRTVIClientMicControl.ts","client-react/src/RTVIClientVideo.tsx","client-react/src/useMergedRef.ts","client-react/src/useRTVIClientMediaDevices.ts","client-react/src/VoiceVisualizer.tsx"],"sourcesContent":["/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIClientAudio } from \"./RTVIClientAudio\";\nimport { RTVIClientCamToggle } from \"./RTVIClientCamToggle\";\nimport { RTVIClientMicToggle } from \"./RTVIClientMicToggle\";\nimport { RTVIClientProvider } from \"./RTVIClientProvider\";\nimport { RTVIClientVideo } from \"./RTVIClientVideo\";\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientCamControl } from \"./useRTVIClientCamControl\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { useRTVIClientMediaDevices } from \"./useRTVIClientMediaDevices\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\nimport { useRTVIClientMicControl } from \"./useRTVIClientMicControl\";\nimport { useRTVIClientTransportState } from \"./useRTVIClientTransportState\";\nimport { VoiceVisualizer } from \"./VoiceVisualizer\";\n\nexport {\n RTVIClientAudio,\n RTVIClientCamToggle,\n RTVIClientMicToggle,\n RTVIClientProvider,\n RTVIClientVideo,\n useRTVIClient,\n useRTVIClientCamControl,\n useRTVIClientEvent,\n useRTVIClientMediaDevices,\n useRTVIClientMediaTrack,\n useRTVIClientMicControl,\n useRTVIClientTransportState,\n VoiceVisualizer,\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { useCallback, useEffect, useRef } from \"react\";\n\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\nexport const RTVIClientAudio = () => {\n const botAudioRef = useRef<HTMLAudioElement>(null);\n const botAudioTrack = useRTVIClientMediaTrack(\"audio\", \"bot\");\n\n useEffect(() => {\n if (!botAudioRef.current || !botAudioTrack) return;\n if (botAudioRef.current.srcObject) {\n const oldTrack = (\n botAudioRef.current.srcObject as MediaStream\n ).getAudioTracks()[0];\n if (oldTrack.id === botAudioTrack.id) return;\n }\n botAudioRef.current.srcObject = new MediaStream([botAudioTrack]);\n }, [botAudioTrack]);\n\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useCallback((speaker: MediaDeviceInfo) => {\n if (!botAudioRef.current) return;\n if (typeof botAudioRef.current.setSinkId !== \"function\") return;\n botAudioRef.current.setSinkId(speaker.deviceId);\n }, [])\n );\n\n return (\n <>\n <audio ref={botAudioRef} autoPlay />\n </>\n );\n};\nRTVIClientAudio.displayName = \"RTVIClientAudio\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, RTVIEventHandler } from \"@pipecat-ai/client-js\";\nimport { useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\n\nexport const useRTVIClientEvent = <E extends RTVIEvent>(\n event: E,\n handler: RTVIEventHandler<E>\n) => {\n const client = useRTVIClient();\n\n useEffect(() => {\n if (!client) return;\n client.on(event, handler);\n return () => {\n client.off(event, handler);\n };\n }, [event, handler, client]);\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { useContext } from \"react\";\n\nimport { RTVIClientContext } from \"./RTVIClientProvider\";\n\nexport const useRTVIClient = () => {\n const { client } = useContext(RTVIClientContext);\n return client;\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIClient } from \"@pipecat-ai/client-js\";\nimport { createStore } from \"jotai\";\nimport { Provider as JotaiProvider } from \"jotai/react\";\nimport React, { createContext } from \"react\";\n\nexport interface Props {\n client: RTVIClient;\n jotaiStore?: React.ComponentProps<typeof JotaiProvider>[\"store\"];\n}\n\nconst defaultStore = createStore();\n\nexport const RTVIClientContext = createContext<{ client?: RTVIClient }>({});\n\nexport const RTVIClientProvider: React.FC<React.PropsWithChildren<Props>> = ({\n children,\n client,\n jotaiStore = defaultStore,\n}) => {\n return (\n <JotaiProvider store={jotaiStore}>\n <RTVIClientContext.Provider value={{ client }}>\n {children}\n </RTVIClientContext.Provider>\n </JotaiProvider>\n );\n};\nRTVIClientProvider.displayName = \"RTVIClientProvider\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { Participant, RTVIEvent, Tracks } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { atomFamily, useAtomCallback } from \"jotai/utils\";\nimport { PrimitiveAtom } from \"jotai/vanilla\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype ParticipantType = keyof Tracks;\ntype TrackType = keyof Tracks[\"local\"];\n\nconst localAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst localScreenVideoTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botAudioTrackAtom = atom<MediaStreamTrack | null>(null);\nconst botVideoTrackAtom = atom<MediaStreamTrack | null>(null);\n\nconst trackAtom = atomFamily<\n { local: boolean; trackType: TrackType },\n PrimitiveAtom<MediaStreamTrack | null>\n>(({ local, trackType }) => {\n if (local) {\n switch (trackType) {\n case \"audio\":\n return localAudioTrackAtom;\n case \"screenAudio\":\n return localScreenAudioTrackAtom;\n case \"screenVideo\":\n return localScreenVideoTrackAtom;\n case \"video\":\n return localVideoTrackAtom;\n }\n }\n return trackType === \"audio\" ? botAudioTrackAtom : botVideoTrackAtom;\n});\n\nexport const useRTVIClientMediaTrack = (\n trackType: TrackType,\n participantType: ParticipantType\n) => {\n const client = useRTVIClient();\n const track = useAtomValue(\n trackAtom({ local: participantType === \"local\", trackType })\n );\n\n const updateTrack = useAtomCallback(\n useCallback(\n (\n get,\n set,\n track: MediaStreamTrack,\n trackType: TrackType,\n local: boolean\n ) => {\n const atom = trackAtom({\n local,\n trackType,\n });\n const oldTrack = get(atom);\n if (oldTrack?.id === track.id) return;\n set(atom, track);\n },\n []\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.TrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n updateTrack(\n track,\n track.kind as TrackType,\n Boolean(participant?.local)\n );\n },\n [updateTrack]\n )\n );\n\n useRTVIClientEvent(\n RTVIEvent.ScreenTrackStarted,\n useCallback(\n (track: MediaStreamTrack, participant?: Participant) => {\n const trackType =\n track.kind === \"audio\" ? \"screenAudio\" : \"screenVideo\";\n updateTrack(track, trackType, Boolean(participant?.local));\n },\n [updateTrack]\n )\n );\n\n useEffect(() => {\n if (!client) return;\n const tracks = client.tracks();\n const track = tracks?.[participantType]?.[trackType];\n if (!track) return;\n updateTrack(track, trackType, participantType === \"local\");\n }, [participantType, trackType, updateTrack, client]);\n\n return track;\n};\n","import React, { useCallback } from \"react\";\n\nimport { useRTVIClientCamControl } from \"./useRTVIClientCamControl\";\n\nexport interface RTVIClientCamToggleProps {\n /**\n * Callback fired when camera state changes\n */\n onCamEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the cam toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isCamEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling camera state\n */\nexport const RTVIClientCamToggle: React.FC<RTVIClientCamToggleProps> = ({\n onCamEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { isCamEnabled, enableCam } = useRTVIClientCamControl();\n\n const handleToggleCam = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isCamEnabled;\n enableCam(newEnabledState);\n onCamEnabledChanged?.(newEnabledState);\n }, [disabled, enableCam, isCamEnabled, onCamEnabledChanged]);\n\n return (\n <>\n {children({\n isCamEnabled,\n onClick: handleToggleCam,\n disabled,\n })}\n </>\n );\n};\n\nexport default RTVIClientCamToggle;\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientTransportState } from \"./useRTVIClientTransportState\";\n\n/**\n * Hook to control camera state\n */\nexport const useRTVIClientCamControl = () => {\n const client = useRTVIClient();\n\n const [isCamEnabled, setIsCamEnabled] = useState(\n client?.isCamEnabled ?? false\n );\n\n const transportState = useRTVIClientTransportState();\n\n // Sync component state with client state initially\n useEffect(() => {\n if (\n !client ||\n transportState !== \"initialized\" ||\n typeof client.isCamEnabled !== \"boolean\"\n )\n return;\n setIsCamEnabled(client.isCamEnabled);\n }, [client, transportState]);\n\n const enableCam = useCallback(\n (enabled: boolean) => {\n setIsCamEnabled(enabled);\n client?.enableCam?.(enabled);\n },\n [client]\n );\n\n return {\n enableCam,\n isCamEnabled,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport { RTVIEvent, TransportState } from \"@pipecat-ai/client-js\";\nimport { atom, useAtom } from \"jotai\";\n\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\nconst transportStateAtom = atom<TransportState>(\"disconnected\");\n\nexport const useRTVIClientTransportState = () => {\n const [transportState, setTransportState] = useAtom(transportStateAtom);\n\n useRTVIClientEvent(RTVIEvent.TransportStateChanged, setTransportState);\n\n return transportState;\n};\n","import React, { useCallback } from \"react\";\n\nimport { useRTVIClientMicControl } from \"./useRTVIClientMicControl\";\n\nexport interface RTVIClientMicToggleProps {\n /**\n * Callback fired when microphone state changes\n */\n onMicEnabledChanged?: (enabled: boolean) => void;\n\n /**\n * Optional prop to disable the mic toggle.\n * When disabled, changes are not applied to the client.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Render prop that provides state and handlers to the children\n */\n children: (props: {\n disabled?: boolean;\n isMicEnabled: boolean;\n onClick: () => void;\n }) => React.ReactNode;\n}\n\n/**\n * Headless component for controlling microphone state\n */\nexport const RTVIClientMicToggle: React.FC<RTVIClientMicToggleProps> = ({\n onMicEnabledChanged,\n disabled = false,\n children,\n}) => {\n const { enableMic, isMicEnabled } = useRTVIClientMicControl();\n\n const handleToggleMic = useCallback(() => {\n if (disabled) return;\n\n const newEnabledState = !isMicEnabled;\n enableMic(newEnabledState);\n onMicEnabledChanged?.(newEnabledState);\n }, [disabled, enableMic, isMicEnabled, onMicEnabledChanged]);\n\n return (\n <>\n {children({\n isMicEnabled,\n onClick: handleToggleMic,\n disabled,\n })}\n </>\n );\n};\n\nexport default RTVIClientMicToggle;\n","import { useCallback, useEffect, useState } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientTransportState } from \"./useRTVIClientTransportState\";\n\n/**\n * Hook to control microphone state\n */\nexport const useRTVIClientMicControl = () => {\n const client = useRTVIClient();\n\n const [isMicEnabled, setIsMicEnabled] = useState(\n client?.isMicEnabled ?? false\n );\n\n const transportState = useRTVIClientTransportState();\n\n // Sync component state with client state initially\n useEffect(() => {\n if (\n !client ||\n transportState !== \"initialized\" ||\n typeof client.isMicEnabled !== \"boolean\"\n )\n return;\n setIsMicEnabled(client.isMicEnabled);\n }, [client, transportState]);\n\n const enableMic = useCallback(\n (enabled: boolean) => {\n setIsMicEnabled(enabled);\n client?.enableMic?.(enabled);\n },\n [client]\n );\n\n return {\n enableMic,\n isMicEnabled,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { forwardRef, useEffect, useRef } from \"react\";\n\nimport useMergedRef from \"./useMergedRef\";\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\ninterface RTVIClientVideoInterface {\n aspectRatio: number;\n height: number;\n width: number;\n}\n\nexport interface Props\n extends Omit<React.VideoHTMLAttributes<HTMLVideoElement>, \"onResize\"> {\n participant: \"local\" | \"bot\";\n\n /**\n * Defines the video track type to display. Default: 'video'.\n */\n trackType?: \"screenVideo\" | \"video\";\n\n /**\n * Defines whether the video should be fully contained or cover the box. Default: 'contain'.\n */\n fit?: \"contain\" | \"cover\";\n /**\n * Forces the video to be mirrored, if set.\n */\n mirror?: boolean;\n\n /**\n * Optional callback, which is triggered whenever the video's rendered width or height changes.\n * Returns the video's native width, height and aspectRatio.\n */\n onResize?(dimensions: RTVIClientVideoInterface): void;\n}\n\nexport const RTVIClientVideo = forwardRef<HTMLVideoElement, Props>(\n function VoiceClientVideo(\n {\n participant = \"local\",\n fit = \"contain\",\n mirror,\n onResize,\n style = {},\n trackType = \"video\",\n ...props\n },\n ref\n ) {\n const videoTrack: MediaStreamTrack | null = useRTVIClientMediaTrack(\n trackType,\n participant\n );\n\n const videoEl = useRef<HTMLVideoElement>(null);\n const videoRef = useMergedRef<HTMLVideoElement>(videoEl, ref);\n\n /**\n * Handle canplay & picture-in-picture events.\n */\n useEffect(function setupVideoEvents() {\n const video = videoEl.current;\n if (!video) return;\n\n const playVideo = () => {\n const promise = video.play();\n if (promise !== undefined) {\n promise\n .then(() => {\n // All good, playback started.\n video.controls = false;\n })\n .catch((error) => {\n // Auto-play was prevented. Show video controls, so user can play video manually.\n video.controls = true;\n console.warn(\"Failed to play video\", error);\n });\n }\n };\n\n const handleCanPlay = () => {\n if (!video.paused) return;\n playVideo();\n };\n const handleEnterPIP = () => {\n video.style.transform = \"scale(1)\";\n };\n const handleLeavePIP = () => {\n video.style.transform = \"\";\n setTimeout(() => {\n if (video.paused) playVideo();\n }, 100);\n };\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"hidden\") return;\n if (!video.paused) return;\n playVideo();\n };\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.addEventListener(\"leavepictureinpicture\", handleLeavePIP);\n\n // Videos can be paused if media was played in another app on iOS.\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n return () => {\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"enterpictureinpicture\", handleEnterPIP);\n video.removeEventListener(\"leavepictureinpicture\", handleLeavePIP);\n document.removeEventListener(\n \"visibilitychange\",\n handleVisibilityChange\n );\n };\n }, []);\n\n /**\n * Update srcObject.\n */\n useEffect(\n function updateSrcObject() {\n const video = videoEl.current;\n if (!video || !videoTrack) return;\n video.srcObject = new MediaStream([videoTrack]);\n video.load();\n return () => {\n // clean up when unmounted\n video.srcObject = null;\n video.load();\n };\n },\n [videoTrack, videoTrack?.id]\n );\n\n /**\n * Add optional event listener for resize event so the parent component\n * can know the video's native aspect ratio.\n */\n useEffect(\n function reportVideoDimensions() {\n const video = videoEl.current;\n if (!onResize || !video) return;\n\n let frame: ReturnType<typeof requestAnimationFrame>;\n function handleResize() {\n if (frame) cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n const video = videoEl.current;\n if (!video || document.hidden) return;\n const videoWidth = video.videoWidth;\n const videoHeight = video.videoHeight;\n if (videoWidth && videoHeight) {\n onResize?.({\n aspectRatio: videoWidth / videoHeight,\n height: videoHeight,\n width: videoWidth,\n });\n }\n });\n }\n\n handleResize();\n video.addEventListener(\"loadedmetadata\", handleResize);\n video.addEventListener(\"resize\", handleResize);\n\n return () => {\n if (frame) cancelAnimationFrame(frame);\n video.removeEventListener(\"loadedmetadata\", handleResize);\n video.removeEventListener(\"resize\", handleResize);\n };\n },\n [onResize]\n );\n\n return (\n <video\n autoPlay\n muted\n playsInline\n ref={videoRef}\n style={{\n objectFit: fit,\n transform: mirror ? \"scale(-1, 1)\" : \"\",\n ...style,\n }}\n {...props}\n />\n );\n }\n);\nRTVIClientVideo.displayName = \"RTVIClientVideo\";\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n *\n * This file contains code derived from:\n * https://github.com/jaredLunde/react-hook/blob/master/packages/merged-ref/src/index.tsx\n * Original author: Jared Lunde (https://github.com/jaredLunde)\n * Original license: MIT (https://github.com/jaredLunde/react-hook/blob/master/LICENSE)\n */\n\nimport React, { useCallback } from \"react\";\n\nfunction useMergedRef<T>(...refs: React.Ref<T>[]): React.RefCallback<T> {\n return useCallback(\n (element: T) => {\n for (let i = 0; i < refs.length; i++) {\n const ref = refs[i];\n if (typeof ref === \"function\") ref(element);\n else if (ref && typeof ref === \"object\")\n (ref as React.MutableRefObject<T>).current = element;\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n refs\n );\n}\n\nexport default useMergedRef;\n","import { RTVIEvent } from \"@pipecat-ai/client-js\";\nimport { atom, useAtomValue } from \"jotai\";\nimport { useAtomCallback } from \"jotai/utils\";\nimport { useCallback, useEffect } from \"react\";\n\nimport { useRTVIClient } from \"./useRTVIClient\";\nimport { useRTVIClientEvent } from \"./useRTVIClientEvent\";\n\ntype OptionalMediaDeviceInfo = MediaDeviceInfo | Record<string, never>;\n\nconst availableMicsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableCamsAtom = atom<MediaDeviceInfo[]>([]);\nconst availableSpeakersAtom = atom<MediaDeviceInfo[]>([]);\nconst selectedMicAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedCamAtom = atom<OptionalMediaDeviceInfo>({});\nconst selectedSpeakerAtom = atom<OptionalMediaDeviceInfo>({});\n\nexport const useRTVIClientMediaDevices = () => {\n const client = useRTVIClient();\n\n const availableCams = useAtomValue(availableCamsAtom);\n const availableMics = useAtomValue(availableMicsAtom);\n const availableSpeakers = useAtomValue(availableSpeakersAtom);\n const selectedCam = useAtomValue(selectedCamAtom);\n const selectedMic = useAtomValue(selectedMicAtom);\n const selectedSpeaker = useAtomValue(selectedSpeakerAtom);\n\n const initDevices = useAtomCallback(\n useCallback(\n async (_get, set) => {\n if (!client) return;\n\n const availableCams = await client.getAllCams();\n const availableMics = await client.getAllMics();\n const availableSpeakers = await client.getAllSpeakers();\n\n set(availableCamsAtom, availableCams);\n set(availableMicsAtom, availableMics);\n set(availableSpeakersAtom, availableSpeakers);\n\n set(selectedCamAtom, client.selectedCam);\n set(selectedMicAtom, client.selectedMic);\n set(selectedSpeakerAtom, client.selectedSpeaker);\n },\n [client]\n )\n );\n\n useEffect(() => {\n initDevices();\n }, [initDevices]);\n\n useRTVIClientEvent(\n RTVIEvent.AvailableCamsUpdated,\n useAtomCallback(\n useCallback((_get, set, cams) => {\n set(availableCamsAtom, cams);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableMicsUpdated,\n useAtomCallback(\n useCallback((_get, set, mics) => {\n set(availableMicsAtom, mics);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.AvailableSpeakersUpdated,\n useAtomCallback(\n useCallback((_get, set, speakers) => {\n set(availableSpeakersAtom, speakers);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.CamUpdated,\n useAtomCallback(\n useCallback((_get, set, cam) => {\n set(selectedCamAtom, cam);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.MicUpdated,\n useAtomCallback(\n useCallback((_get, set, mic) => {\n set(selectedMicAtom, mic);\n }, [])\n )\n );\n useRTVIClientEvent(\n RTVIEvent.SpeakerUpdated,\n useAtomCallback(\n useCallback((_get, set, speaker) => {\n set(selectedSpeakerAtom, speaker);\n }, [])\n )\n );\n\n const updateCam = useCallback(\n (id: string) => {\n client?.updateCam(id);\n },\n [client]\n );\n const updateMic = useCallback(\n (id: string) => {\n client?.updateMic(id);\n },\n [client]\n );\n const updateSpeaker = useCallback(\n (id: string) => {\n client?.updateSpeaker(id);\n },\n [client]\n );\n\n return {\n availableCams,\n availableMics,\n availableSpeakers,\n selectedCam,\n selectedMic,\n selectedSpeaker,\n updateCam,\n updateMic,\n updateSpeaker,\n };\n};\n","/**\n * Copyright (c) 2024, Daily.\n *\n * SPDX-License-Identifier: BSD-2-Clause\n */\n\nimport React, { useEffect, useRef } from \"react\";\n\nimport { useRTVIClientMediaTrack } from \"./useRTVIClientMediaTrack\";\n\ntype ParticipantType = Parameters<typeof useRTVIClientMediaTrack>[1];\n\ninterface Props {\n backgroundColor?: string;\n barColor?: string;\n barCount?: number;\n barGap?: number;\n barLineCap?: \"round\" | \"square\";\n barMaxHeight?: number;\n barOrigin?: \"top\" | \"bottom\" | \"center\";\n barWidth?: number;\n participantType: ParticipantType;\n}\n\nexport const VoiceVisualizer: React.FC<Props> = React.memo(\n ({\n backgroundColor = \"transparent\",\n barColor = \"black\",\n barCount = 5,\n barGap = 12,\n barLineCap = \"round\",\n barMaxHeight = 120,\n barOrigin = \"center\",\n barWidth = 30,\n participantType,\n }) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const track: MediaStreamTrack | null = useRTVIClientMediaTrack(\n \"audio\",\n participantType\n );\n\n useEffect(() => {\n if (!canvasRef.current) return;\n\n const canvasWidth = barCount * barWidth + (barCount - 1) * barGap;\n const canvasHeight = barMaxHeight;\n\n const canvas = canvasRef.current;\n\n const scaleFactor = 2;\n\n // Make canvas fill the width and height of its container\n const resizeCanvas = () => {\n canvas.width = canvasWidth * scaleFactor;\n canvas.height = canvasHeight * scaleFactor;\n\n canvas.style.width = `${canvasWidth}px`;\n canvas.style.height = `${canvasHeight}px`;\n\n canvasCtx.lineCap = barLineCap;\n canvasCtx.scale(scaleFactor, scaleFactor);\n };\n\n const canvasCtx = canvas.getContext(\"2d\")!;\n resizeCanvas();\n\n if (!track) return;\n\n const audioContext = new AudioContext();\n const source = audioContext.createMediaStreamSource(\n new MediaStream([track])\n );\n const analyser = audioContext.createAnalyser();\n\n analyser.fftSize = 1024;\n\n source.connect(analyser);\n\n const frequencyData = new Uint8Array(analyser.frequencyBinCount);\n\n canvasCtx.lineCap = barLineCap;\n\n // Create frequency bands based on barCount\n const bands = Array.from({ length: barCount }, (_, i) => {\n // Use improved logarithmic scale for better frequency distribution\n const minFreq = barCount > 20 ? 200 : 80; // Adjust min frequency based on bar count\n const maxFreq = 10000; // Cover most important audio frequencies\n\n // Use Mel scale inspired approach for more perceptually uniform distribution\n // This helps with a large number of bars by placing fewer in the very low range\n // https://en.wikipedia.org/wiki/Mel_scale\n const melMin = 2595 * Math.log10(1 + minFreq / 700);\n const melMax = 2595 * Math.log10(1 + maxFreq / 700);\n const melStep = (melMax - melMin) / barCount;\n\n const melValue = melMin + i * melStep;\n const startFreq = 700 * (Math.pow(10, melValue / 2595) - 1);\n const endFreq = 700 * (Math.pow(10, (melValue + melStep) / 2595) - 1);\n\n return {\n startFreq,\n endFreq,\n smoothValue: 0,\n };\n });\n\n const getFrequencyBinIndex = (frequency: number) => {\n const nyquist = audioContext.sampleRate / 2;\n return Math.round(\n (frequency / nyquist) * (analyser.frequencyBinCount - 1)\n );\n };\n\n function drawSpectrum() {\n analyser.getByteFrequencyData(frequencyData);\n canvasCtx.clearRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n canvasCtx.fillStyle = backgroundColor;\n canvasCtx.fillRect(\n 0,\n 0,\n canvas.width / scaleFactor,\n canvas.height / scaleFactor\n );\n\n let isActive = false;\n\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2; // Center bars\n\n const adjustedCircleRadius = barWidth / 2; // Fixed radius for reset circles\n\n bands.forEach((band, i) => {\n const startIndex = getFrequencyBinIndex(band.startFreq);\n const endIndex = getFrequencyBinIndex(band.endFreq);\n const bandData = frequencyData.slice(startIndex, endIndex);\n const bandValue =\n bandData.reduce((acc, val) => acc + val, 0) / bandData.length;\n\n const smoothingFactor = 0.2;\n\n if (bandValue < 1) {\n band.smoothValue = Math.max(\n band.smoothValue - smoothingFactor * 5,\n 0\n );\n } else {\n band.smoothValue =\n band.smoothValue +\n (bandValue - band.smoothValue) * smoothingFactor;\n isActive = true;\n }\n\n const x = startX + i * (barWidth + barGap);\n // Calculate bar height with a maximum cap\n const minHeight = 0;\n const barHeight = Math.max(\n minHeight,\n Math.min((band.smoothValue / 255) * barMaxHeight, barMaxHeight)\n );\n\n let yTop, yBottom;\n const canvasHeight = canvas.height / scaleFactor;\n\n switch (barOrigin) {\n case \"top\":\n yTop = adjustedCircleRadius;\n yBottom = Math.min(\n adjustedCircleRadius + barHeight,\n canvasHeight - adjustedCircleRadius\n );\n break;\n case \"bottom\":\n yBottom = canvasHeight - adjustedCircleRadius;\n yTop = Math.max(yBottom - barHeight, adjustedCircleRadius);\n break;\n case \"center\":\n default:\n yTop = Math.max(\n canvasHeight / 2 - barHeight / 2,\n adjustedCircleRadius\n );\n yBottom = Math.min(\n canvasHeight / 2 + barHeight / 2,\n canvasHeight - adjustedCircleRadius\n );\n break;\n }\n\n if (band.smoothValue > 0) {\n canvasCtx.beginPath();\n canvasCtx.moveTo(x + barWidth / 2, yTop);\n canvasCtx.lineTo(x + barWidth / 2, yBottom);\n canvasCtx.lineWidth = barWidth;\n canvasCtx.strokeStyle = barColor;\n canvasCtx.stroke();\n } else {\n drawInactiveCircle(adjustedCircleRadius, barColor, x, yTop);\n }\n });\n\n if (!isActive) {\n drawInactiveCircles(adjustedCircleRadius, barColor);\n }\n\n requestAnimationFrame(drawSpectrum);\n }\n\n function drawInactiveCircle(\n circleRadius: number,\n color: string,\n x: number,\n y: number\n ) {\n switch (barLineCap) {\n case \"square\":\n canvasCtx.fillStyle = color;\n canvasCtx.fillRect(\n x + barWidth / 2 - circleRadius,\n y - circleRadius,\n circleRadius * 2,\n circleRadius * 2\n );\n break;\n case \"round\":\n default:\n canvasCtx.beginPath();\n canvasCtx.arc(x + barWidth / 2, y, circleRadius, 0, 2 * Math.PI);\n canvasCtx.fillStyle = color;\n canvasCtx.fill();\n canvasCtx.closePath();\n break;\n }\n }\n\n function drawInactiveCircles(circleRadius: number, color: string) {\n const totalBarsWidth =\n bands.length * barWidth + (bands.length - 1) * barGap;\n const startX = (canvas.width / scaleFactor - totalBarsWidth) / 2;\n const canvasHeight = canvas.height / scaleFactor;\n\n let y;\n switch (barOrigin) {\n case \"top\":\n y = circleRadius;\n break;\n case \"bottom\":\n y = canvasHeight - circleRadius;\n break;\n case \"center\":\n default:\n y = canvasHeight / 2;\n break;\n }\n\n bands.forEach((_, i) => {\n const x = startX + i * (barWidth + barGap);\n drawInactiveCircle(circleRadius, color, x, y);\n });\n }\n\n drawSpectrum();\n\n // Handle resizing\n window.addEventListener(\"resize\", resizeCanvas);\n\n return () => {\n audioContext.close();\n window.removeEventListener(\"resize\", resizeCanvas);\n };\n }, [\n backgroundColor,\n barColor,\n barCount,\n barGap,\n barLineCap,\n barMaxHeight,\n barOrigin,\n barWidth,\n track,\n ]);\n\n return (\n <canvas\n ref={canvasRef}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n }}\n />\n );\n }\n);\n\nVoiceVisualizer.displayName = \"VoiceVisualizer\";\n"],"names":[],"version":3,"file":"index.module.js.map"}
|