@apirtc/react-lib 1.2.1-rc.2 → 1.2.1-rc.3
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/README.md +1 -0
- package/dist/components/VideoStream/index.d.ts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/esm/components/VideoStream/index.d.ts +1 -1
- package/dist/esm/components/index.d.ts +1 -1
- package/dist/esm/hooks/index.d.ts +12 -12
- package/dist/esm/hooks/useTranscriptService.d.ts +2 -2
- package/dist/esm/hooks/useTranscriptService.spec.d.ts +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/hooks/index.d.ts +12 -12
- package/dist/hooks/useTranscriptService.d.ts +2 -2
- package/dist/hooks/useTranscriptService.spec.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/react-lib.production.min.js.map +1 -1
- package/package.json +1 -1
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export { useCameraStream } from
|
|
2
|
-
export { default as useConversation } from
|
|
3
|
-
export { default as useConversationContacts } from
|
|
4
|
-
export { default as useConversationMessages } from
|
|
5
|
-
export { default as useConversationModeration } from
|
|
6
|
-
export { default as useConversationStreams } from
|
|
7
|
-
export { default as usePresence } from
|
|
8
|
-
export { ApiKey, Credentials, default as useSession, LoginPassword, Token } from
|
|
9
|
-
export { default as useStreamApplyAudioProcessor } from
|
|
10
|
-
export { default as useStreamApplyVideoProcessor } from
|
|
11
|
-
export { default as useUserMediaDevices } from
|
|
12
|
-
export { default as useTranscriptService } from
|
|
1
|
+
export { useCameraStream } from './useCameraStream';
|
|
2
|
+
export { default as useConversation } from './useConversation';
|
|
3
|
+
export { default as useConversationContacts } from './useConversationContacts';
|
|
4
|
+
export { default as useConversationMessages } from './useConversationMessages';
|
|
5
|
+
export { default as useConversationModeration } from './useConversationModeration';
|
|
6
|
+
export { default as useConversationStreams } from './useConversationStreams';
|
|
7
|
+
export { default as usePresence } from './usePresence';
|
|
8
|
+
export { ApiKey, Credentials, default as useSession, LoginPassword, Token } from './useSession';
|
|
9
|
+
export { default as useStreamApplyAudioProcessor } from './useStreamApplyAudioProcessor';
|
|
10
|
+
export { default as useStreamApplyVideoProcessor } from './useStreamApplyVideoProcessor';
|
|
11
|
+
export { default as useUserMediaDevices } from './useUserMediaDevices';
|
|
12
|
+
export { default as useTranscriptService } from './useTranscriptService';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Conversation } from '@apirtc/apirtc';
|
|
2
2
|
/**
|
|
3
3
|
* A hook to start/stop and get messages from a transcriptService
|
|
4
4
|
* @param conversation an ApiRTC conversation
|
|
5
5
|
* @param autoStart boolean to automatically start transcription
|
|
6
6
|
*/
|
|
7
|
-
export default function useTranscriptService(conversation:
|
|
7
|
+
export default function useTranscriptService(conversation: Conversation | undefined, autoStart: boolean | undefined): {
|
|
8
8
|
transcriptService: import("@apizee/ia").TranscriptService | null;
|
|
9
9
|
hasStarted: boolean;
|
|
10
10
|
transcripts: import("@apizee/ia").Transcript[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import './getDisplayMedia.mock';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import * as react from 'react';
|
|
3
3
|
import react__default from 'react';
|
|
4
|
-
import { Stream, Session, CreateStreamOptions, GetOrCreateConversationOptions, JoinOptions, Conversation, Contact, ConversationMessage, PublishOptions, RegisterInformation, AudioProcessorType, VideoProcessorType, VideoProcessorOptions, MediaDeviceList, MediaDevice
|
|
4
|
+
import { Stream, Session, CreateStreamOptions, GetOrCreateConversationOptions, JoinOptions, Conversation, Contact, ConversationMessage, PublishOptions, RegisterInformation, AudioProcessorType, VideoProcessorType, VideoProcessorOptions, MediaDeviceList, MediaDevice } from '@apirtc/apirtc';
|
|
5
5
|
import * as _apizee_ia from '@apizee/ia';
|
|
6
6
|
|
|
7
7
|
type VideoStreamProps = {
|
|
@@ -150,7 +150,7 @@ declare function useUserMediaDevices(session: Session | undefined, storageKeyPre
|
|
|
150
150
|
* @param conversation an ApiRTC conversation
|
|
151
151
|
* @param autoStart boolean to automatically start transcription
|
|
152
152
|
*/
|
|
153
|
-
declare function useTranscriptService(conversation:
|
|
153
|
+
declare function useTranscriptService(conversation: Conversation | undefined, autoStart: boolean | undefined): {
|
|
154
154
|
transcriptService: _apizee_ia.TranscriptService | null;
|
|
155
155
|
hasStarted: boolean;
|
|
156
156
|
transcripts: _apizee_ia.Transcript[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react-lib.production.min.js","sources":["../src/hooks/useCameraStream.ts","../src/hooks/useConversation.ts","../src/hooks/useConversationContacts.ts","../src/hooks/useConversationMessages.ts","../src/hooks/useConversationModeration.ts","../src/hooks/useConversationStreams.ts","../src/hooks/usePresence.ts","../src/hooks/useSession.ts","../src/hooks/useStreamApplyAudioProcessor.ts","../src/hooks/useStreamApplyVideoProcessor.ts","../src/hooks/useUserMediaDevices.ts","../node_modules/tslib/tslib.es6.mjs","../src/hooks/useTranscriptService.ts","../src/index.ts","../src/components/VideoStream/VideoStream.tsx"],"sourcesContent":["import { CreateStreamOptions, Session, Stream, UserAgent } from '@apirtc/apirtc';\nimport { useEffect, useState } from 'react';\n\nconst EMPTY = {};\n\nconst HOOK_NAME = \"useCameraStream\";\nexport function useCameraStream(\n session: Session | undefined,\n options: CreateStreamOptions = EMPTY, // used to be = {} but this triggers infinite loop with useEffect\n errorCallback?: (error: any) => void\n) {\n const [stream, setStream] = useState<Stream>();\n const [grabbing, setGrabbing] = useState<boolean>(false);\n\n const [error, setError] = useState<any>();\n\n useEffect(() => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect`, session, options)\n }\n if (session) {\n const userAgent: UserAgent = session.getUserAgent();\n setGrabbing(true)\n userAgent.createStream(options).then((localStream: Stream) => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|createStream`, options, localStream)\n }\n setStream(localStream)\n setError(undefined)\n }).catch((error: any) => {\n console.error(`${HOOK_NAME}|createStream error`, options, error)\n setStream(undefined)\n if (errorCallback) {\n errorCallback(error)\n }\n setError(error)\n }).finally(() => {\n setGrabbing(false)\n })\n\n // DO NOT set out stream to undefined in the return, to prevent unnecessary refreshes\n // of other components with undefined stream, whereas we are expecting to change it\n // to another instance..\n // return () => { setStream(undefined) } // DON'T\n } else {\n setStream(undefined)\n setError(undefined)\n }\n }, [session, options, errorCallback])\n\n useEffect(() => {\n const l_stream = stream;\n if (l_stream) {\n return () => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|release stream`, l_stream)\n }\n l_stream.release()\n }\n }\n }, [stream])\n\n return {\n stream,\n grabbing,\n error\n }\n}","import { Conversation, GetOrCreateConversationOptions, JoinOptions, Session } from '@apirtc/apirtc';\nimport { useCallback, useEffect, useState } from 'react';\n\nconst HOOK_NAME = \"useConversation\";\n/**\n * A hook to getOrCreate a named conversation and manage join/leave\n * @param session an ApiRTC Session\n * @param name the conversation name\n * @param options getOrCreateConversation options\n * @param join true by default\n * @param joinOptions conversation.join options\n */\nexport default function useConversation(\n session: Session | undefined,\n name: string | undefined,\n options?: GetOrCreateConversationOptions,\n join: boolean = true,\n joinOptions?: JoinOptions\n) {\n const [conversation, setConversation] = useState<Conversation>();\n const [joined, setJoined] = useState<boolean>(false);\n const [joining, setJoining] = useState<boolean>(false);\n\n // Callbacks\n //\n // Offering Promised join/leave methods allows developer to act on then/catch\n //\n const o_join = useCallback((joinOptions: JoinOptions = {}) => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|join`, conversation, joinOptions)\n //JSON.stringify((apiRTC as any).session.apiCCWebRTCClient.webRTCClient.MCUClient.sessionMCUs))\n }\n return new Promise<void>((resolve, reject) => {\n if (!conversation) {\n reject(`${HOOK_NAME}|join|conversation not defined`)\n return\n }\n if (!conversation.isJoined()) {\n setJoining(true)\n conversation.join(joinOptions).then(() => {\n // successfully joined the conversation.\n setJoined(true)\n resolve()\n }).catch((error: any) => {\n // could not join the conversation.\n reject(error)\n }).finally(() => {\n setJoining(false)\n })\n } else {\n reject(`${HOOK_NAME}|join|conversation already joined`)\n }\n })\n }, [conversation]);\n\n const o_leave = useCallback(() => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|leave`, conversation)\n }\n return new Promise<void>((resolve, reject) => {\n if (!conversation) {\n reject(`${HOOK_NAME}|leave|conversation not defined`)\n return\n }\n if (conversation.isJoined()) {\n conversation.leave().then(() => {\n // local user successfully left the conversation.\n setJoined(false)\n resolve()\n }).catch((error: any) => {\n reject(error)\n })\n } else {\n reject(`${HOOK_NAME}|leave|conversation is not joined`)\n }\n })\n }, [conversation]);\n\n // Effects\n //\n useEffect(() => {\n if (session && name) {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|getOrCreateConversation`, name, options)\n }\n const l_conversation = session.getOrCreateConversation(name, options);\n setConversation(l_conversation)\n return () => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect cleanup`, name, options)\n }\n if (l_conversation.isJoined()) {\n l_conversation.leave()\n .then(() => { })\n .catch((error: any) => {\n if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|useEffect conversation.leave()`, error)\n }\n })\n .finally(() => {\n l_conversation.destroy()\n // SHOULD NOT touch the state here as this async and the conversation may have already changed\n })\n } else {\n // It is important to destroy the conversation.\n // Otherwise subsequent getOrCreateConversation with same name would get\n // previous handle, regardless of the potentially new options.\n // This also allows to cleanup memory\n l_conversation.destroy()\n }\n // In any cases, update state accordingly\n // Note: this is done here synchronously, this shall NOT be done in the leave().finally to prevent\n // overriding a potential conversation change\n setConversation(undefined)\n setJoined(false)\n }\n }\n }, [session, name, options])\n\n useEffect(() => {\n if (conversation && join) {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect`, conversation, join, joinOptions)\n }\n const l_conversation = conversation;\n const l_join = join;\n if (l_join) {\n setJoining(true)\n l_conversation.join(joinOptions).then(() => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|joined`, l_conversation)\n }\n setJoined(true)\n }).catch((error: any) => {\n if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|useEffect conversation.join() error`, l_conversation, joinOptions, error)\n }\n }).finally(() => {\n setJoining(false)\n })\n }\n return () => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect cleanup`, l_conversation, l_join)\n }\n if (l_conversation.isJoined()) {\n l_conversation.leave().then(() => {\n setJoined(false)\n }).catch((error: any) => {\n if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|useEffect conversation.leave() error`, l_conversation, error)\n }\n })\n }\n }\n }\n }, [conversation, options, join, joinOptions])\n\n return {\n conversation,\n joining,\n joined,\n join: o_join,\n leave: o_leave\n }\n}","import { Contact, Conversation } from '@apirtc/apirtc';\nimport { useEffect, useState } from 'react';\n\nconst HOOK_NAME = \"useConversationContacts\";\nexport default function useConversationContacts(\n conversation: Conversation | undefined,\n contactJoined?: (contact: Contact) => void,\n contactLeft?: (contact: Contact) => void\n) {\n const [contacts, setContacts] = useState<Array<Contact>>([]);\n\n useEffect(() => {\n if (conversation) {\n const onContactJoined = (contact: Contact) => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|on:contactJoined:`, conversation.getName(), contact)\n }\n setContacts((l_contacts) => [...l_contacts, contact])\n if (contactJoined) {\n contactJoined(contact)\n }\n };\n conversation.on('contactJoined', onContactJoined)\n\n const onContactLeft = (contact: Contact) => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|on:contactLeft:`, conversation.getName(), contact)\n }\n // filter out contact\n setContacts((l_contacts) => l_contacts.filter((l_contact) => l_contact !== contact))\n if (contactLeft) {\n contactLeft(contact)\n }\n };\n conversation.on('contactLeft', onContactLeft)\n\n return () => {\n conversation.removeListener('contactJoined', onContactJoined)\n conversation.removeListener('contactLeft', onContactLeft)\n setContacts(new Array<Contact>())\n }\n }\n }, [conversation, contactJoined, contactLeft])\n\n return {\n contacts\n }\n}","import { Contact, Conversation, ConversationMessage } from '@apirtc/apirtc';\nimport { useCallback, useEffect, useState } from 'react';\n\n// TODO : get and handle with pagination messages history\n// TODO : ask apirtc to include the uuid in ConversationMessage so that we can store it\n// into ConversationMessage when creating the local one, and we get it from conversation on:message\n// the uuid shall be the value used as a react child key when displaying list of messages\n\nconst HOOK_NAME = \"useConversationMessages\";\nexport default function useConversationMessages(\n conversation: Conversation | undefined,\n) {\n const [messages, setMessages] = useState<Array<ConversationMessage>>([]);\n\n useEffect(() => {\n if (conversation) {\n const onMessage = (message: ConversationMessage) => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|on:message:`, conversation.getName(), message)\n }\n setMessages((l_messages) => [...l_messages, message])\n };\n conversation.on('message', onMessage)\n\n return () => {\n conversation.removeListener('message', onMessage)\n setMessages(new Array<ConversationMessage>())\n }\n }\n }, [conversation])\n\n const sendMessage = useCallback((msgContent: string, sender: Contact) => {\n return new Promise<void>((resolve, reject) => {\n conversation?.sendMessage(msgContent)\n .then((uuid: number) => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|sentMessage`, conversation.getName(), uuid, msgContent)\n }\n setMessages((l_messages) => [...l_messages, { content: msgContent, sender: sender, time: new Date() }])\n resolve()\n })\n .catch((error: any) => {\n if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|sendMessage error`, error)\n }\n reject(error)\n })\n })\n }, [conversation]);\n\n return {\n messages,\n sendMessage\n }\n}","import { Contact, Conversation } from '@apirtc/apirtc';\nimport { useEffect, useState } from 'react';\n\nconst HOOK_NAME = \"useConversationModeration\";\nexport default function useConversationModeration(\n conversation: Conversation | undefined,\n onEjected?: (contact: Contact) => void,\n onEjectedSelf?: () => void) {\n\n const [candidates, setCandidates] = useState<Set<Contact>>(new Set<Contact>());\n\n useEffect(() => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect conversation`, conversation)\n }\n\n if (conversation) {\n const on_contactJoinedWaitingRoom = (contact: Contact) => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|on:contactJoinedWaitingRoom`, contact)\n }\n // A candidate joined the waiting room.\n setCandidates((prev) => new Set(prev.add(contact)))\n };\n const on_contactLeftWaitingRoom = (contact: Contact) => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|on:contactLeftWaitingRoom`, contact)\n }\n // A candidate left the waiting room.\n setCandidates((prev) => {\n prev.delete(contact)\n return new Set(prev)\n })\n };\n // TODO make apirtc.d.ts update to replace 'any'\n const on_participantEjected = (data: any) => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|on:participantEjected`, data)\n }\n if (data.self === true) {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|Self participant was ejected`)\n }\n if (onEjectedSelf) {\n onEjectedSelf()\n }\n } else {\n if (onEjected) {\n onEjected(data.contact)\n }\n }\n };\n\n conversation\n .on('contactJoinedWaitingRoom', on_contactJoinedWaitingRoom)\n .on('contactLeftWaitingRoom', on_contactLeftWaitingRoom)\n .on('participantEjected', on_participantEjected)\n\n return () => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|conversation clear`, conversation)\n }\n // remove listeners\n conversation\n .removeListener('contactJoinedWaitingRoom', on_contactJoinedWaitingRoom)\n .removeListener('contactLeftWaitingRoom', on_contactLeftWaitingRoom)\n .removeListener('participantEjected', on_participantEjected)\n setCandidates(new Set())\n }\n }\n }, [conversation, onEjected, onEjectedSelf])\n\n return {\n candidates\n }\n}","import { Conversation, PublishOptions, Stream, StreamInfo } from '@apirtc/apirtc';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\n// TODO?: add pagination ?\n// interface Options {\n// streamsSubscribePageSize: number\n// }\n\nfunction notEmpty<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined;\n}\n\nconst EMPTY: any[] = [];\n\nconst HOOK_NAME = \"useConversationStreams\";\nexport default function useConversationStreams(\n conversation: Conversation | undefined,\n /** fully managed list of Stream(s) to publish, with associated publish options */\n streamsToPublish: Array<{ stream: Stream, options?: PublishOptions } | undefined | null> = EMPTY,\n // TODO: streamIdsToSubscribeTo subscribe to all streams if undefined (default),\n // or subscribe only to the streamIds in the list. Subscribe to none if list is empty.\n // Note : the consumer will need to subscribe first to know the ids at least once,\n // => but this is not good as it would not know if those ids are no more published.. so we need to also output\n // the list of streams info if we go that way...\n // streamIdsToSubscribeTo?: Array<string>,\n errorCallback?: (error: any) => void\n) {\n\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|hook render|${conversation?.getName()}`, streamsToPublish.map((obj) => obj?.options))\n }\n\n // A cache to handle publication differences\n const publishedStreamsCache = useRef<Array<{ stream: Stream, options?: PublishOptions } | undefined | null>>([]);\n\n const [publishedStreams, setPublishedStreams] = useState<Array<Stream>>(new Array<Stream>());\n const [subscribedStreams, setSubscribedStreams] = useState<Array<Stream>>(new Array<Stream>());\n\n const publish: (localStream: Stream, options?: PublishOptions) => Promise<Stream> =\n useCallback((localStream: Stream, options?: PublishOptions) => {\n return new Promise<Stream>((resolve, reject) => {\n if (conversation) {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|publish|${conversation.getName()}`, localStream, options)\n }\n conversation.publish(localStream, options).then((stream: Stream) => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|published|${conversation.getName()}`, stream)\n }\n setPublishedStreams((l_streams) => [...l_streams, stream])\n resolve(stream)\n }).catch((error: any) => {\n reject(error)\n })\n }\n })\n }, [conversation]);\n\n const replacePublishedStream = useCallback((oldStream: Stream, newStream: Stream) => {\n return new Promise<Stream>((resolve, reject) => {\n if (conversation) {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|replacePublishedStream|${conversation.getName()}|${oldStream.getId()} -> ${newStream.getId()}`)\n }\n conversation.replacePublishedStream(oldStream, newStream).then((stream: Stream) => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|stream replaced|${conversation.getName()}`, oldStream, stream)\n }\n\n // replace old stream by new one at same position\n setPublishedStreams((l_streams) => {\n const index = l_streams.indexOf(oldStream);\n if (index >= 0) {\n l_streams.splice(index, 1, stream)\n }\n return Array.from(l_streams)\n })\n\n resolve(stream)\n }).catch((error: any) => {\n reject(error)\n })\n }\n })\n }, [conversation]);\n\n const unpublish: (localStream: Stream) => void = useCallback((localStream: Stream) => {\n if (conversation) {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|unpublish|${conversation.getName()}`, localStream.getId(), localStream)\n }\n conversation.unpublish(localStream)\n setPublishedStreams((l_streams) => l_streams.filter((l_stream) => l_stream !== localStream))\n }\n }, [conversation]);\n\n const doHandlePublication = useCallback(() => {\n const maxLength = Math.max(publishedStreamsCache.current.length, streamsToPublish.length);\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|doHandlePublication`, streamsToPublish,\n JSON.stringify(publishedStreamsCache.current.map(l_s => l_s?.stream.getId())),\n JSON.stringify(streamsToPublish.map(l_s => l_s?.stream.getId())),\n maxLength)\n }\n\n // make a copy of current cache\n const currentPublishedStreamsCache = [...publishedStreamsCache.current];\n\n // Strategy for publishedStreamsCache is to initialize it as it should be\n // and remove items if publication fails.\n // Need to do a real copy of options :\n const newPublishedStreamsCache = streamsToPublish.map(elt => {\n if (elt && elt.options) {\n return { stream: elt.stream, options: { ...elt.options } }\n } else {\n return elt\n }\n });\n // Replace cache\n publishedStreamsCache.current.length = 0;\n publishedStreamsCache.current.push(...newPublishedStreamsCache);\n\n // Prepare a set for Streams to publish, for further optimized check\n const streamsToPublishSet = new Set(streamsToPublish.filter(notEmpty).map((item) => item.stream));\n\n const doPublish = (index: number, obj: { stream: Stream, options?: PublishOptions }) => {\n publish(obj.stream, obj.options)\n .catch((error: Error) => {\n // Note that publishedStreamsCache is updated asynchronously here (catch)\n // Hence why publishedStreamsCache must always be the same array instance\n publishedStreamsCache.current.splice(index, 1, null)\n if (errorCallback) {\n errorCallback(error)\n } else if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|publish|error`, error)\n }\n })\n };\n\n // Loop on arrays index to publish new streams, or replace if necessary\n for (let i = 0; i < maxLength; i++) {\n const previous = currentPublishedStreamsCache[i];\n const next = streamsToPublish[i];\n\n if (previous && next) {\n\n const doUnpublishPublish = () => {\n unpublish(previous.stream)\n doPublish(i, next)\n };\n\n if (previous.stream === next.stream) {\n // Streams are the same, only replace if options are different\n if (JSON.stringify(previous.options) !== JSON.stringify(next.options)) {\n // replacePublishStream does not allow to change PublishOptions, so we need to\n // unpublish and republish\n doUnpublishPublish()\n }\n } else {\n // If position in both new and cached list are defined but are different:\n // replace if and only if stream to unpublish shall not be published (at other position)\n if (streamsToPublishSet.has(previous.stream)) { // previous shall be published\n // Previous shall actually be published (at another position), so don't do anything about it\n // But then we still have to publish new stream (if not already published)\n if (conversation && !conversation.isPublishedStream(next.stream)) {\n doPublish(i, next)\n }\n } else {\n if (conversation && !conversation.isPublishedStream(next.stream)) {\n // replacePublishStream does not allow to change PublishOptions, so we need to\n // unpublish and republish if options also change\n if (JSON.stringify(previous.options) === JSON.stringify(next.options)) {\n replacePublishedStream(previous.stream, next.stream)\n // eslint-disable-next-line no-loop-func\n .catch((error: Error) => {\n // Note that publishedStreamsCache is updated asynchronously here (catch)\n // Hence why publishedStreamsCache must always be the same array instance\n publishedStreamsCache.current.splice(i, 1, null)\n if (errorCallback) {\n errorCallback(error)\n } else if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|replacePublishedStream|error`, error)\n }\n })\n } else {\n doUnpublishPublish()\n }\n } else { // new stream is already published\n // So we shall not replace another stream by it, but we need to unpublish the previous\n unpublish(previous.stream)\n }\n }\n }\n } else if (previous && !next) {\n // If position in new list is now undefined(or null) while it was in cache:\n // unpublish if and only if stream to unpublish shall not be published (at other position)\n if (!streamsToPublishSet.has(previous.stream)) {\n unpublish(previous.stream)\n }\n } else if (!previous && next) {\n // If position in new list is valid : publish it whatever the position in cache.\n // Depending on the case the stream might be already published, or it might be not\n // (can happen if the cache was set while Conversation was not joined yet).\n // Note that we could try to publish without checking isPublishedStream, the call would\n // reject with a console error but this would not affect the behavior.\n if (conversation && !conversation.isPublishedStream(next.stream)) {\n doPublish(i, next)\n }\n }\n }\n\n }, [conversation,\n //streamsToPublish, change is captured by JSON.stringify below\n // JSON.stringify(streamsToPublish.map(l_s => `${l_s?.stream.getId()}-${JSON.stringify(l_s?.options)}`)),\n streamsToPublish,\n //publishedStreamsCache, // no need to put in dependency array as the instance shall never change\n publish, unpublish, replacePublishedStream,\n errorCallback]);\n\n const unpublishAll = useCallback(() => {\n if (conversation) {\n // Clear output arrays with new array so that parent gets notified of a change.\n setPublishedStreams((l_streams) => {\n // unpublish all published streams\n l_streams.forEach(stream => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|unpublish|${conversation.getName()}`, stream)\n }\n conversation.unpublish(stream)\n })\n return []\n })\n }\n // Clear cache\n publishedStreamsCache.current.length = 0;\n }, [conversation]);\n\n const unsubscribeAll = useCallback(() => {\n if (conversation) {\n setSubscribedStreams((l_streams) => {\n // make sure to unsubscribe to subscribed streams\n l_streams.forEach(stream => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|unsubscribeToStream|${conversation.getName()}`, stream)\n }\n conversation.unsubscribeToStream(stream.getId())\n })\n return []\n })\n }\n }, [conversation]);\n\n const unpublishAndUnsubscribeAll = useCallback(() => {\n unpublishAll()\n unsubscribeAll()\n }, [unpublishAll, unsubscribeAll]);\n\n // --------------------------------------------------------------------------\n // useEffect(s) - Order is important\n //\n useEffect(() => {\n if (conversation) {\n\n // make sure publishedStreamsCache is reinitialized empty\n publishedStreamsCache.current.length = 0;\n\n const on_streamAdded = (stream: Stream) => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|on_streamAdded|${conversation.getName()}`, stream)\n }\n setSubscribedStreams((l_streams) => [...l_streams, stream])\n };\n const on_streamRemoved = (stream: Stream) => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|on_streamRemoved|${conversation.getName()}`, stream)\n }\n setSubscribedStreams((l_streams) => l_streams.filter((l_stream) => l_stream !== stream))\n };\n const on_streamListChanged = (streamInfo: StreamInfo) => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|on_streamListChanged|${conversation.getName()}`, streamInfo)\n }\n const streamId = String(streamInfo.streamId);\n if (streamInfo.isRemote === true) {\n if (streamInfo.listEventType === 'added') {\n // a remote stream was published\n conversation.subscribeToStream(streamId)\n } else if (streamInfo.listEventType === 'removed') {\n // a remote stream is not published anymore\n conversation.unsubscribeToStream(streamId)\n }\n }\n };\n // Subscribe to incoming streams\n conversation.on('streamAdded', on_streamAdded)\n conversation.on('streamRemoved', on_streamRemoved)\n conversation.on('streamListChanged', on_streamListChanged)\n\n return () => {\n // remove listeners\n conversation.removeListener('streamListChanged', on_streamListChanged)\n conversation.removeListener('streamRemoved', on_streamRemoved)\n conversation.removeListener('streamAdded', on_streamAdded)\n\n unpublishAndUnsubscribeAll()\n }\n }\n }, [conversation, unpublishAndUnsubscribeAll])\n\n useEffect(() => {\n if (conversation) {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect doHandlePublication|${conversation.getName()}`, streamsToPublish)\n }\n\n const on_joined = () => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|on_joined|${conversation.getName()}`)\n }\n doHandlePublication()\n };\n const on_left = () => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|on_left|${conversation.getName()}`)\n }\n // Forcing unpublish will allow to republish if joining again\n unpublishAndUnsubscribeAll()\n };\n\n conversation.on('joined', on_joined)\n conversation.on('left', on_left)\n\n if (conversation.isJoined()) {\n doHandlePublication()\n }\n\n return () => {\n conversation.removeListener('joined', on_joined)\n conversation.removeListener('left', on_left)\n }\n }\n }, [conversation, streamsToPublish, doHandlePublication, unpublishAndUnsubscribeAll])\n\n return {\n publishedStreams,\n subscribedStreams,\n publish,\n unpublish,\n replacePublishedStream,\n unpublishAll,\n unsubscribeAll\n }\n}\n","import { Contact, Session } from '@apirtc/apirtc';\nimport { useEffect, useRef, useState } from 'react';\n\n/**\n * Subscribe to groups and returns contactsByGroup (of theses groups only) when updated.\n * If input groups list is updated, this hooks works diff with the previous set in order\n * to make as little as possible unsubscribe/subscribe calls.\n */\n\nconst HOOK_NAME = \"usePresence\";\nexport default function usePresence(session: Session | undefined, groups: Array<string>) {\n\n const m_groupsCache = useRef<Set<string>>(new Set());\n const m_contactsByGroup = useRef<Map<string, Set<Contact>>>(new Map());\n\n const [contactsByGroup, setContactsByGroup] = useState<Map<string, Set<Contact>>>(new Map());\n\n useEffect(() => {\n if (session) {\n const l_groupsCache = m_groupsCache.current;\n const l_contactsByGroup = m_contactsByGroup.current;\n return () => {\n l_groupsCache.clear()\n l_contactsByGroup.clear()\n setContactsByGroup(new Map())\n }\n }\n }, [session])\n\n const getOrCreateGroupSet = (group: string) => {\n const o_set = m_contactsByGroup.current.get(group) ?? new Set();\n if (!m_contactsByGroup.current.has(group)) {\n m_contactsByGroup.current.set(group, o_set)\n }\n return o_set\n };\n\n useEffect(() => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect session, groups`, groups)\n }\n if (session) {\n const l_session = session;\n const l_groupsSet = new Set(groups);\n\n // Diff update subscription to groups\n //\n l_groupsSet.forEach(group => {\n if (!m_groupsCache.current.has(group)) {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|subscribeToGroup`, group)\n }\n m_groupsCache.current.add(group)\n l_session.subscribeToGroup(group)\n }\n })\n\n let needsRefresh = false;\n m_groupsCache.current.forEach(group => {\n if (!l_groupsSet.has(group)) {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|unsubscribeToGroup`, group)\n }\n l_session.unsubscribeToGroup(group)\n m_groupsCache.current.delete(group)\n m_contactsByGroup.current.delete(group)\n needsRefresh = true;\n }\n })\n\n if (needsRefresh) {\n // contactsByGroup is exposed, so change the Map object to let client code detect a change.\n setContactsByGroup(new Map(m_contactsByGroup.current))\n }\n\n if (groups.length > 0) {\n const onContactListUpdate = (updatedContacts: any) => {\n\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|contactListUpdate`, updatedContacts)\n }\n\n let needsRefresh = false;\n\n // Maintain Map of Contacts per Group\n //\n for (const group of Object.keys(updatedContacts.joinedGroup)) {\n if (l_groupsSet.has(group)) {\n const l_set = getOrCreateGroupSet(group);\n for (const contact of updatedContacts.joinedGroup[group]) {\n l_set.add(contact)\n needsRefresh = true;\n }\n }\n }\n for (const group of Object.keys(updatedContacts.leftGroup)) {\n if (l_groupsSet.has(group)) {\n const l_set = getOrCreateGroupSet(group);\n for (const contact of updatedContacts.leftGroup[group]) {\n l_set.delete(contact)\n needsRefresh = true;\n\n // if set is empty, no need to keep the group as key in the map\n if (l_set.size === 0) {\n m_contactsByGroup.current.delete(group)\n }\n }\n }\n }\n\n // For data updates, trigger a refresh if and only if contact is part of managed groups\n for (const contact of updatedContacts.userDataChanged as Contact[]) {\n for (const l_contacts of m_contactsByGroup.current.values()) {\n if (l_contacts.has(contact)) {\n needsRefresh = true;\n break;\n }\n }\n }\n\n if (needsRefresh) {\n // contactsByGroup is exposed, so change the Map object to let client code detect a change.\n setContactsByGroup(new Map(m_contactsByGroup.current))\n }\n };\n l_session.on('contactListUpdate', onContactListUpdate)\n return () => {\n l_session.removeListener('contactListUpdate', onContactListUpdate)\n }\n }\n }\n }, [session, groups])\n\n return {\n contactsByGroup\n }\n}","import { RegisterInformation, Session, UserAgent } from '@apirtc/apirtc';\nimport { useEffect, useState } from 'react';\n\nexport type LoginPassword = {\n username: string\n password: string\n};\nfunction isInstanceOfLoginPassword(object: any): object is LoginPassword {\n if (typeof object !== 'object') return false;\n return 'username' in object;\n}\n\nexport type ApiKey = { apiKey: string };\nfunction isInstanceOfApiKey(object: any): object is ApiKey {\n if (typeof object !== 'object') return false;\n return 'apiKey' in object;\n}\n\nexport type Token = { token: string };\nfunction isInstanceOfToken(object: any): object is Token {\n if (typeof object !== 'object') return false;\n return 'token' in object;\n}\n\nexport type Credentials = LoginPassword | ApiKey | Token;\n\nconst HOOK_NAME = \"useSession\";\nexport default function useSession(credentials?: Credentials,\n options?: RegisterInformation,\n errorCallback?: (error: any) => void) {\n\n const [session, setSession] = useState<Session | undefined>();\n const [connecting, setConnecting] = useState<boolean>(false);\n\n useEffect(() => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect credentials, options`, credentials, options)\n }\n if (credentials) {\n // To fix errors like \"Warning: Can't perform a React state update on an unmounted component\"\n // https://stackoverflow.com/questions/53949393/cant-perform-a-react-state-update-on-an-unmounted-component\n //let isMounted = true;\n connect(credentials, options).catch((error: any) => {\n console.error(`${HOOK_NAME}|connection failed`, error)\n setSession(undefined)\n\n if (errorCallback) {\n errorCallback(error)\n } else if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|connect|error`, error)\n }\n })\n return () => {\n setSession(undefined)\n // Even though connecting is managed in connect(),\n // mark connecting to false when credentials are changed\n // as this shall be way to connect elsewhere or connect to\n // with other credentials. Note that to be perfect we should\n // cancel the potentially running connect : Is that possible with ApiRTC ?\n setConnecting(false)\n }\n }\n }, [credentials, options, errorCallback]) // JSON.stringify(credentials), JSON.stringify(options)\n\n useEffect(() => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect session`, session)\n }\n if (session) {\n const l_session = session;\n return () => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect session cleanup`, l_session)\n }\n l_session.disconnect().then(() => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|disconnected`, l_session)\n }\n }).catch((error: any) => {\n console.error(`${HOOK_NAME}|disconnect`, error)\n })\n }\n }\n }, [session])\n\n const connect = (credentials: Credentials | undefined, options?: RegisterInformation) => {\n return new Promise<void>((resolve, reject) => {\n const registerInformation: RegisterInformation = options ? options : {\n cloudUrl: 'https://cloud.apirtc.com',\n };\n\n let l_userAgent;\n\n if (isInstanceOfLoginPassword(credentials)) {\n registerInformation.password = credentials.password;\n l_userAgent = new UserAgent({\n uri: `apirtc:${credentials.username}`\n });\n } else if (isInstanceOfApiKey(credentials)) {\n l_userAgent = new UserAgent({\n uri: `apiKey:${credentials.apiKey}`\n });\n } else if (isInstanceOfToken(credentials)) {\n l_userAgent = new UserAgent({\n uri: `token:${credentials.token}`\n });\n } else {\n reject(\"credentials not recognized\")\n return\n }\n\n setConnecting(true)\n l_userAgent.register(registerInformation).then(l_session => {\n if (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n console.info(`${HOOK_NAME}|connected`, l_session)\n }\n setSession(l_session)\n resolve()\n }).catch((error: any) => {\n reject(error)\n }).finally(() => {\n setConnecting(false)\n })\n })\n };\n\n // const disconnect = useCallback(() => {\n // return new Promise<void>((resolve, reject) => {\n // if (session) {\n // const l_session = session;\n // l_session.disconnect().then(() => {\n // console.log(`${HOOK_NAME}|disconnected`, l_session)\n // setSession(undefined)\n // resolve()\n // }).catch((error: any) => {\n // console.error(`${HOOK_NAME}|disconnect`, error)\n // reject(error)\n // })\n // } else {\n // resolve()\n // }\n // })\n // }, [session])\n\n const disconnect = () => {\n setSession(undefined)\n };\n\n return {\n //userAgent: userAgent, // can get it from session\n session: session,\n connecting,\n connect,\n disconnect\n }\n}\n","import { AudioProcessorType, Stream } from '@apirtc/apirtc';\nimport { useEffect, useRef, useState } from 'react';\n\nconst HOOK_NAME = \"useStreamApplyAudioProcessor\";\n/**\n * This hook takes stream passed as parameter, and\n * returns either this stream or a stream with audio processor applied.\n * This is controlled by the audioProcessorType input attribute.\n * By default the output stream is the input stream.\n * The hook fully manages the output stream (applies 'none' if input stream is set to undefined).\n * The hook never releases the input stream.\n * \n * @param stream\n * @param audioProcessorType\n * @returns new stream with Audio processor applied (or original stream if no processor applied)\n */\nexport default function useStreamApplyAudioProcessor(\n stream: Stream | undefined,\n processorType: AudioProcessorType,\n errorCallback?: (error: any) => void) {\n //\n const appliedProcessor = useRef<AudioProcessorType>();\n const [outStream, setOutStream] = useState(stream);\n const [applying, setApplying] = useState(false);\n const [error, setError] = useState<any>();\n\n useEffect(() => {\n // Reset appliedProcessor.current when stream changes\n return () => {\n appliedProcessor.current = undefined;\n }\n }, [stream])\n\n useEffect(() => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect`, stream, processorType)\n }\n setOutStream(stream)\n const applied = appliedProcessor.current || stream?.audioAppliedFilter || 'none';\n if (stream && processorType !== applied) {\n setApplying(true)\n stream.applyAudioProcessor(processorType).then(l_stream => {\n setOutStream(l_stream)\n appliedProcessor.current = processorType;\n setError(undefined)\n }).catch(error => {\n setError(error)\n if (errorCallback) {\n errorCallback(error)\n } else if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|useEffect`, stream, processorType, error)\n }\n }).finally(() => {\n setApplying(false)\n })\n }\n return () => {\n setError(undefined)\n }\n }, [stream, processorType, errorCallback])\n\n return {\n stream: outStream,\n applying,\n applied: appliedProcessor.current || (stream as any)?.audioAppliedFilter || 'none',\n error\n }\n}","import { Stream, VideoProcessorOptions, VideoProcessorType } from '@apirtc/apirtc';\nimport { useEffect, useRef, useState } from 'react';\n\nconst HOOK_NAME = \"useStreamApplyVideoProcessor\";\n/**\n * This hook takes stream passed as parameter, and\n * returns either this stream or a stream with video processor applied.\n * This is controlled by the videoProcessorType input attribute.\n * By default the output stream is the input stream.\n * The hook fully manages the output stream (applies 'none' if input stream is set to undefined).\n * The hook never releases the input stream.\n * \n * @param stream\n * @param processorType\n * @param {VideoProcessorOptions} options\n * @returns new stream with video processor applied (or original stream if no processor applied)\n */\nexport default function useStreamApplyVideoProcessor(\n stream: Stream | undefined,\n processorType: VideoProcessorType, options?: VideoProcessorOptions,\n errorCallback?: (error: any) => void) {\n //\n const appliedProcessor = useRef<VideoProcessorType>();\n const [outStream, setOutStream] = useState(stream);\n const [applying, setApplying] = useState(false);\n const [error, setError] = useState<any>();\n\n useEffect(() => {\n // Reset appliedProcessor.current when stream changes\n return () => {\n appliedProcessor.current = undefined;\n }\n }, [stream])\n\n useEffect(() => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect`, stream, processorType, options)\n }\n setOutStream(stream)\n const applied = appliedProcessor.current || stream?.videoAppliedFilter || 'none';\n if (stream && processorType !== applied) {\n setApplying(true)\n stream.applyVideoProcessor(processorType, options).then(l_stream => {\n setOutStream(l_stream)\n appliedProcessor.current = processorType;\n setError(undefined)\n }).catch(error => {\n setError(error)\n if (errorCallback) {\n errorCallback(error)\n } else if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|useEffect`, stream, processorType, options, error)\n }\n }).finally(() => {\n setApplying(false)\n })\n }\n return () => {\n setError(undefined)\n }\n }, [stream, processorType, options, errorCallback])\n\n return {\n stream: outStream,\n applying,\n applied: appliedProcessor.current || (stream as any)?.videoAppliedFilter || 'none',\n error\n }\n}","import { MediaDevice, MediaDeviceList, Session, UserAgent } from '@apirtc/apirtc';\n\nimport { useEffect, useMemo, useState } from 'react';\n\nconst HOOK_NAME = \"useUserMediaDevices\";\n\nconst getMediaDeviceFromLocalStorage = (key: string) => {\n try {\n const value = localStorage.getItem(key);\n const obj = value ? JSON.parse(value) : null;\n return obj ? new MediaDevice(obj.id, obj.type, obj.label) : undefined;\n } catch (error) {\n console.warn(`${HOOK_NAME}|getMediaDeviceFromLocalStorage`, error)\n return undefined;\n }\n};\n\nconst setLocalStorage = (key: string, value: string) => {\n try {\n localStorage.setItem(key, value)\n } catch (error: any) { }\n};\n\n/**\n * useUserMediaDevices hook\n * @param session - a valid ApiRTC Session\n * @param storageKeyPrefix - do not set or set to undefined to NOT use local storage to get nor store devices ids.\n * @returns userMediaDevices,\n * selectedAudioIn, selectedAudioInId, setSelectedAudioIn,\n * selectedAudioOut, selectedAudioInId, setSelectedAudioOut,\n * selectedVideoIn, selectedVideoInId, setSelectedVideoIn\n */\nexport default function useUserMediaDevices(\n session: Session | undefined,\n storageKeyPrefix?: string\n) {\n const AUDIO_INPUT_KEY = useMemo(() => storageKeyPrefix ? `${storageKeyPrefix}.audioIn` : undefined, [storageKeyPrefix]);\n const AUDIO_OUTPUT_KEY = useMemo(() => storageKeyPrefix ? `${storageKeyPrefix}.audioOut` : undefined, [storageKeyPrefix]);\n const VIDEO_INPUT_KEY = useMemo(() => storageKeyPrefix ? `${storageKeyPrefix}.videoIn` : undefined, [storageKeyPrefix]);\n\n // Use lazy initialized useState to avoid calling getMediaDeviceFromLocalStorage (which is IO operation) at every render\n const [selectedAudioIn, setSelectedAudioIn] = useState<MediaDevice | undefined>(() => AUDIO_INPUT_KEY ? getMediaDeviceFromLocalStorage(AUDIO_INPUT_KEY) : undefined);\n const [selectedAudioOut, setSelectedAudioOut] = useState<MediaDevice | undefined>(() => AUDIO_OUTPUT_KEY ? getMediaDeviceFromLocalStorage(AUDIO_OUTPUT_KEY) : undefined);\n const [selectedVideoIn, setSelectedVideoIn] = useState<MediaDevice | undefined>(() => VIDEO_INPUT_KEY ? getMediaDeviceFromLocalStorage(VIDEO_INPUT_KEY) : undefined);\n\n const [userMediaDevices, setUserMediaDevices] = useState<MediaDeviceList>({\n audioinput: selectedAudioIn ? {\n [selectedAudioIn.getId()]: selectedAudioIn\n } : {},\n audiooutput: selectedAudioOut ? {\n [selectedAudioOut.getId()]: selectedAudioOut\n } : {},\n videoinput: selectedVideoIn ? {\n [selectedVideoIn.getId()]: selectedVideoIn\n } : {}\n });\n\n useEffect(() => {\n if (session) {\n const userAgent: UserAgent = session.getUserAgent();\n\n const on_mediaDeviceChanged = () => {\n const mediaDevices: MediaDeviceList = userAgent.getUserMediaDevices();\n\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|mediaDeviceChanged`, mediaDevices)\n }\n\n setUserMediaDevices(mediaDevices)\n setSelectedAudioIn((prev) => prev ? mediaDevices.audioinput[prev.getId()] : undefined)\n setSelectedAudioOut((prev) => prev ? mediaDevices.audiooutput[prev.getId()] : undefined)\n setSelectedVideoIn((prev) => prev ? mediaDevices.videoinput[prev.getId()] : undefined)\n };\n userAgent.on('mediaDeviceChanged', on_mediaDeviceChanged)\n\n return () => {\n userAgent.removeListener('mediaDeviceChanged', on_mediaDeviceChanged)\n }\n }\n }, [session])\n\n useEffect(() => {\n if (selectedAudioIn && AUDIO_INPUT_KEY) {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|Storing audioIn`, selectedAudioIn)\n }\n setLocalStorage(AUDIO_INPUT_KEY, JSON.stringify({\n id: selectedAudioIn.getId(), type: selectedAudioIn.getType(), label: selectedAudioIn.getLabel()\n }))\n }\n }, [AUDIO_INPUT_KEY, selectedAudioIn])\n\n useEffect(() => {\n if (selectedAudioOut && AUDIO_OUTPUT_KEY) {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|Storing audioOut`, selectedAudioOut)\n }\n setLocalStorage(AUDIO_OUTPUT_KEY, JSON.stringify({\n id: selectedAudioOut.getId(), type: selectedAudioOut.getType(), label: selectedAudioOut.getLabel()\n }))\n }\n }, [AUDIO_OUTPUT_KEY, selectedAudioOut])\n\n useEffect(() => {\n if (selectedVideoIn && VIDEO_INPUT_KEY) {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|Storing videoIn`, selectedVideoIn)\n }\n setLocalStorage(VIDEO_INPUT_KEY, JSON.stringify({\n id: selectedVideoIn.getId(), type: selectedVideoIn.getType(), label: selectedVideoIn.getLabel()\n }))\n }\n }, [VIDEO_INPUT_KEY, selectedVideoIn])\n\n return {\n userMediaDevices,\n selectedAudioIn, selectedAudioInId: selectedAudioIn?.getId(), setSelectedAudioIn,\n selectedAudioOut, selectedAudioOutId: selectedAudioOut?.getId(), setSelectedAudioOut,\n selectedVideoIn, selectedVideoInId: selectedVideoIn?.getId(), setSelectedVideoIn\n }\n}","/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n function next() {\n while (env.stack.length) {\n var rec = env.stack.pop();\n try {\n var result = rec.dispose && rec.dispose.call(rec.value);\n if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n catch (e) {\n fail(e);\n }\n }\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n};\n","import { useEffect, useState, useCallback } from \"react\"\nimport type { Conference } from \"@apirtc/apirtc\"\n\ntype TranscriptService = InstanceType<typeof import(\"@apizee/ia\")[\"TranscriptService\"]>\ntype Transcript = InstanceType<typeof import(\"@apizee/ia\")[\"Transcript\"]>\ntype EventTranscript = InstanceType<typeof import(\"@apizee/ia\")[\"EventTranscript\"]>\n\nconst HOOK_NAME = \"useTranscriptService\"\n/**\n * A hook to start/stop and get messages from a transcriptService\n * @param conversation an ApiRTC conversation\n * @param autoStart boolean to automatically start transcription\n */\nexport default function useTranscriptService(conversation: Conference | undefined, autoStart: boolean | undefined) {\n const [transcriptService, setTranscriptService] = useState<TranscriptService | null>(null)\n const [hasStarted, setHasStarted] = useState<boolean>(false)\n\n const [transcripts, setTranscripts] = useState<Transcript[]>([])\n\n // Instanciation\n useEffect(() => {\n if (transcriptService) return\n\n let mounted = true\n\n // Dynamic import @apizee/ia\n import(\"@apizee/ia\").then(({ TranscriptService }) => {\n if (!mounted) {\n if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|instanciation aborted - component unmounted`)\n }\n return\n }\n\n const service = new TranscriptService()\n setTranscriptService(service)\n })\n\n return () => {\n mounted = false\n }\n }, [transcriptService])\n\n // EventTranscript listener\n useEffect(() => {\n if (!transcriptService) {\n if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|useEffect transcript listener skipped - transcriptService not ready`)\n }\n return\n }\n\n const onTranscript = (event: EventTranscript) => {\n const { transcript } = event\n\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|onTranscript`, transcript)\n }\n\n setTranscripts((prev) => [...prev, transcript])\n }\n\n transcriptService.addEventListener(\"transcript\", onTranscript)\n\n return () => {\n transcriptService.removeEventListener(\"transcript\", onTranscript)\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect cleanup`, \"onTranscript\")\n }\n }\n }, [transcriptService])\n\n // Start\n const startTranscriptService = useCallback(async () => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|startTranscriptService transcriptService, hasStarted`, transcriptService, hasStarted)\n }\n\n if (!transcriptService) {\n if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|startTranscriptService aborted - transcriptService not initialized`)\n }\n return\n }\n\n if (hasStarted) {\n if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|startTranscriptService aborted - already started`)\n }\n return\n }\n\n if (!conversation) {\n console.warn(`${HOOK_NAME}|startTranscriptService aborted - conversation not provided`)\n return\n }\n\n await transcriptService\n .start(conversation)\n .then(() => {\n console.log(`${HOOK_NAME}|startTranscriptService - started`)\n setHasStarted(true)\n })\n .catch((error: string) => {\n console.error(`${HOOK_NAME}|startTranscriptService - failed`, error)\n })\n }, [transcriptService, hasStarted, conversation])\n\n // Stop\n const stopTranscriptService = useCallback(async () => {\n if (!transcriptService) {\n if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|stopTranscriptService aborted - transcriptService not initialized`)\n }\n return\n }\n\n if (!conversation) {\n console.warn(`${HOOK_NAME}|stopTranscriptService aborted - conversation not provided`)\n return\n }\n\n await transcriptService\n .stop(conversation)\n .then(() => {\n console.log(`${HOOK_NAME}|stopTranscriptService - stopped`)\n setHasStarted(false)\n })\n .catch((error: string) => {\n console.error(`${HOOK_NAME}|stopTranscriptService - failed`, error)\n })\n }, [transcriptService, conversation])\n\n // Auto-start\n useEffect(() => {\n if (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n console.debug(`${HOOK_NAME}|useEffect autoStartTranscriptService autoStart, conversation`, autoStart, conversation)\n }\n\n if (!autoStart) {\n if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|useEffect autoStart skipped - autoStart=false`)\n }\n return\n }\n\n if (!conversation) {\n if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n console.warn(`${HOOK_NAME}|useEffect - auto start transcription not possible if conversation not provided`)\n }\n return\n }\n\n startTranscriptService()\n }, [autoStart, conversation, startTranscriptService])\n\n return {\n transcriptService,\n hasStarted,\n transcripts,\n startTranscriptService,\n stopTranscriptService,\n }\n}\n","export * from './components'\nexport * from './hooks'\n\nexport type LogLevel = {\n level: 'debug' | 'info' | 'warn' | 'error'\n isDebugEnabled: boolean\n isInfoEnabled: boolean\n isWarnEnabled: boolean\n}\n\nconst INFO: LogLevel = { level: 'info', isDebugEnabled: false, isInfoEnabled: true, isWarnEnabled: true };\n\ndeclare global {\n var apirtcReactLibLogLevel: LogLevel;\n var setApirtcReactLibLogLevel: (logLevelText: 'debug' | 'info' | 'warn' | 'error') => void;\n}\n\n// a default value MUST be set in case application using the library does not override it\nglobalThis.apirtcReactLibLogLevel = INFO;\n\nexport function setLogLevel(logLevelText: 'debug' | 'info' | 'warn' | 'error') {\n switch (logLevelText) {\n case 'debug':\n globalThis.apirtcReactLibLogLevel = { level: 'debug', isDebugEnabled: true, isInfoEnabled: true, isWarnEnabled: true };\n break\n case 'info':\n globalThis.apirtcReactLibLogLevel = INFO;\n break\n case 'warn':\n globalThis.apirtcReactLibLogLevel = { level: 'warn', isDebugEnabled: false, isInfoEnabled: false, isWarnEnabled: true };\n break\n case 'error':\n globalThis.apirtcReactLibLogLevel = { level: 'error', isDebugEnabled: false, isInfoEnabled: false, isWarnEnabled: false };\n break\n default:\n // in case null is passed as input, default to 'info'\n globalThis.apirtcReactLibLogLevel = INFO;\n }\n return globalThis.apirtcReactLibLogLevel\n}\n\nglobalThis.setApirtcReactLibLogLevel = setLogLevel;\n","import React, { useEffect, useRef } from 'react';\n\nimport { Stream } from '@apirtc/apirtc';\n\nexport type VideoStreamProps = {\n stream: Stream,\n autoPlay?: boolean,\n muted?: boolean\n};\nexport default function VideoStream(props: VideoStreamProps) {\n\n const { autoPlay = true } = props;\n\n const videoRef = useRef<HTMLVideoElement>(null);\n\n useEffect(() => {\n const ref = videoRef.current;\n if (ref && props.stream) {\n props.stream.attachToElement(ref)\n return () => {\n ref.src = \"\";\n }\n }\n }, [props.stream])\n // No need to put videoRef.current because useRef does not trigger rerender anyways\n\n return <video id={props.stream.getId()} style={{ maxWidth: '100%' }}\n ref={videoRef}\n autoPlay={autoPlay}\n muted={props.muted}></video>\n}"],"names":["EMPTY","HOOK_NAME","notEmpty","value","getMediaDeviceFromLocalStorage","key","localStorage","getItem","obj","JSON","parse","MediaDevice","id","type","label","undefined","error","console","warn","setLocalStorage","setItem","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","next","e","rejected","result","done","then","apply","SuppressedError","INFO","level","isDebugEnabled","isInfoEnabled","isWarnEnabled","setLogLevel","logLevelText","globalThis","apirtcReactLibLogLevel","setApirtcReactLibLogLevel","props","autoPlay","videoRef","useRef","useEffect","ref","current","stream","attachToElement","src","React","createElement","getId","style","maxWidth","muted","session","options","errorCallback","setStream","useState","grabbing","setGrabbing","setError","debug","userAgent","getUserAgent","createStream","localStream","info","catch","finally","l_stream","release","name","join","joinOptions","conversation","setConversation","joined","setJoined","joining","setJoining","o_join","useCallback","isJoined","o_leave","leave","l_conversation","getOrCreateConversation","destroy","l_join","contactJoined","contactLeft","contacts","setContacts","onContactJoined","contact","getName","l_contacts","on","onContactLeft","filter","l_contact","removeListener","Array","messages","setMessages","onMessage","message","l_messages","sendMessage","msgContent","sender","uuid","content","time","Date","onEjected","onEjectedSelf","candidates","setCandidates","Set","on_contactJoinedWaitingRoom","prev","add","on_contactLeftWaitingRoom","delete","on_participantEjected","data","self","streamsToPublish","map","publishedStreamsCache","publishedStreams","setPublishedStreams","subscribedStreams","setSubscribedStreams","publish","l_streams","replacePublishedStream","oldStream","newStream","index","indexOf","splice","from","unpublish","doHandlePublication","maxLength","Math","max","length","stringify","l_s","currentPublishedStreamsCache","newPublishedStreamsCache","elt","Object","assign","push","streamsToPublishSet","item","doPublish","i","previous","doUnpublishPublish","has","isPublishedStream","unpublishAll","forEach","unsubscribeAll","unsubscribeToStream","unpublishAndUnsubscribeAll","on_streamAdded","on_streamRemoved","on_streamListChanged","streamInfo","streamId","String","isRemote","listEventType","subscribeToStream","on_joined","on_left","groups","m_groupsCache","m_contactsByGroup","Map","contactsByGroup","setContactsByGroup","l_groupsCache","l_contactsByGroup","clear","getOrCreateGroupSet","group","o_set","_a","get","set","l_session","l_groupsSet","subscribeToGroup","needsRefresh","unsubscribeToGroup","onContactListUpdate","updatedContacts","keys","joinedGroup","l_set","leftGroup","size","userDataChanged","values","credentials","setSession","connecting","setConnecting","connect","disconnect","registerInformation","cloudUrl","l_userAgent","object","password","UserAgent","uri","username","isInstanceOfApiKey","apiKey","isInstanceOfToken","token","register","processorType","appliedProcessor","outStream","setOutStream","applying","setApplying","applied","audioAppliedFilter","applyAudioProcessor","videoAppliedFilter","applyVideoProcessor","autoStart","transcriptService","setTranscriptService","hasStarted","setHasStarted","transcripts","setTranscripts","mounted","import","TranscriptService","service","onTranscript","event","transcript","addEventListener","removeEventListener","startTranscriptService","this","start","log","stopTranscriptService","stop","storageKeyPrefix","AUDIO_INPUT_KEY","useMemo","AUDIO_OUTPUT_KEY","VIDEO_INPUT_KEY","selectedAudioIn","setSelectedAudioIn","selectedAudioOut","setSelectedAudioOut","selectedVideoIn","setSelectedVideoIn","userMediaDevices","setUserMediaDevices","audioinput","audiooutput","videoinput","on_mediaDeviceChanged","mediaDevices","getUserMediaDevices","getType","getLabel","selectedAudioInId","selectedAudioOutId","selectedVideoInId"],"mappings":"kaAGA,MAAMA,EAAQ,CAAA,EAERC,EAAY,kBCFlB,MAAMA,EAAY,kBCAlB,MAAMA,EAAY,0BCKlB,MAAMA,EAAY,0BCLlB,MAAMA,EAAY,4BCKlB,SAASC,EAAYC,GACnB,OAAOA,OACT,CAEA,MAAMH,EAAe,GAEfC,EAAY,yBCLlB,MAAMA,EAAY,cCiBlB,MAAMA,EAAY,aCvBlB,MAAMA,EAAY,+BCAlB,MAAMA,EAAY,+BCClB,MAAMA,EAAY,sBAEZG,EAAkCC,IACpC,IACI,MAAMF,EAAQG,aAAaC,QAAQF,GAC7BG,EAAML,EAAQM,KAAKC,MAAMP,GAAS,KACxC,OAAOK,EAAM,IAAIG,cAAYH,EAAII,GAAIJ,EAAIK,KAAML,EAAIM,YAASC,CAC/D,CAAC,MAAOC,GAEL,YADAC,QAAQC,KAAK,GAAGjB,mCAA4Ce,EAE/D,GAGCG,EAAkB,CAACd,EAAaF,KAClC,IACIG,aAAac,QAAQf,EAAKF,EAC7B,CAAC,MAAOa,GAAe,GC8FrB,SAASK,EAAUC,EAASC,EAAYC,EAAGC,GAEhD,OAAO,IAAKD,IAAMA,EAAIE,WAAU,SAAUC,EAASC,GAC/C,SAASC,EAAU1B,GAAS,IAAM2B,EAAKL,EAAUM,KAAK5B,GAAQ,CAAG,MAAO6B,GAAKJ,EAAOI,GAAO,CAC3F,SAASC,EAAS9B,GAAS,IAAM2B,EAAKL,EAAiB,MAAEtB,GAAU,CAAC,MAAO6B,GAAKJ,EAAOI,GAAO,CAC9F,SAASF,EAAKI,GAJlB,IAAe/B,EAIa+B,EAAOC,KAAOR,EAAQO,EAAO/B,QAJ1CA,EAIyD+B,EAAO/B,MAJhDA,aAAiBqB,EAAIrB,EAAQ,IAAIqB,GAAE,SAAUG,GAAWA,EAAQxB,EAAO,KAIhBiC,KAAKP,EAAWI,EAAY,CAC9GH,GAAML,EAAYA,EAAUY,MAAMf,EAASC,GAAc,KAAKQ,OACpE,GACA,CAiMkD,mBAApBO,iBAAiCA,gBCpT/D,MAAMrC,EAAY,uBCGlB,MAAMsC,EAAiB,CAAEC,MAAO,OAAQC,gBAAgB,EAAOC,eAAe,EAAMC,eAAe,GAU7F,SAAUC,EAAYC,GACxB,OAAQA,GACJ,IAAK,QACDC,WAAWC,uBAAyB,CAAEP,MAAO,QAASC,gBAAgB,EAAMC,eAAe,EAAMC,eAAe,GAChH,MACJ,IAAK,OASL,QAEIG,WAAWC,uBAAyBR,QARxC,IAAK,OACDO,WAAWC,uBAAyB,CAAEP,MAAO,OAAQC,gBAAgB,EAAOC,eAAe,EAAOC,eAAe,GACjH,MACJ,IAAK,QACDG,WAAWC,uBAAyB,CAAEP,MAAO,QAASC,gBAAgB,EAAOC,eAAe,EAAOC,eAAe,GAM1H,OAAOG,WAAWC,sBACtB,CArBAD,WAAWC,uBAAyBR,EAuBpCO,WAAWE,0BAA4BJ,gBChCf,SAAYK,GAEhC,MAAMC,SAAEA,GAAW,GAASD,EAEtBE,EAAWC,SAAyB,MAa1C,OAXAC,EAAAA,WAAU,KACN,MAAMC,EAAMH,EAASI,QACrB,GAAID,GAAOL,EAAMO,OAEb,OADAP,EAAMO,OAAOC,gBAAgBH,GACtB,KACHA,EAAII,IAAM,EAAE,CAEnB,GACF,CAACT,EAAMO,SAGHG,EAAO,QAAAC,cAAA,QAAA,CAAAhD,GAAIqC,EAAMO,OAAOK,QAASC,MAAO,CAAEC,SAAU,QACvDT,IAAKH,EACLD,SAAUA,EACVc,MAAOf,EAAMe,OACrB,oCdxBM,SACFC,EACAC,EAA+BlE,EAC/BmE,GAEA,MAAOX,EAAQY,GAAaC,EAAQA,YAC7BC,EAAUC,GAAeF,EAAQA,UAAU,IAE3CrD,EAAOwD,GAAYH,EAAQA,WAgDlC,OA9CAhB,EAAAA,WAAU,KAIN,GAHIP,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,cAAuBgE,EAASC,GAEjDD,EAAS,CACT,MAAMS,EAAuBT,EAAQU,eACrCJ,GAAY,GACZG,EAAUE,aAAaV,GAAS9B,MAAMyC,IAC9B/B,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,iBAA0BiE,EAASW,GAEvDT,EAAUS,GACVL,OAASzD,EAAU,IACpBgE,OAAO/D,IACNC,QAAQD,MAAM,GAAGf,uBAAgCiE,EAASlD,GAC1DoD,OAAUrD,GACNoD,GACAA,EAAcnD,GAElBwD,EAASxD,EAAM,IAChBgE,SAAQ,KACPT,GAAY,EAAM,GAOzB,MACGH,OAAUrD,GACVyD,OAASzD,EACZ,GACF,CAACkD,EAASC,EAASC,IAEtBd,EAAAA,WAAU,KACN,MAAM4B,EAAWzB,EACjB,GAAIyB,EACA,MAAO,KACCnC,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,mBAA4BgF,GAEhDA,EAASC,SAAS,CAEzB,GACF,CAAC1B,IAEG,CACHA,SACAc,WACAtD,QAER,oBCvDwB,SACpBiD,EACAkB,EACAjB,EACAkB,GAAgB,EAChBC,GAEA,MAAOC,EAAcC,GAAmBlB,EAAQA,YACzCmB,EAAQC,GAAapB,EAAQA,UAAU,IACvCqB,EAASC,GAActB,EAAQA,UAAU,GAM1CuB,EAASC,EAAAA,aAAY,CAACR,EAA2B,CAAA,KAC/CvC,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,SAAkBqF,EAAcD,GAG9C,IAAI3D,SAAc,CAACC,EAASC,KAC1B0D,EAIAA,EAAaQ,WAadlE,EAAO,GAAG3B,uCAZV0F,GAAW,GACXL,EAAaF,KAAKC,GAAajD,MAAK,KAEhCqD,GAAU,GACV9D,GAAS,IACVoD,OAAO/D,IAENY,EAAOZ,EAAM,IACdgE,SAAQ,KACPW,GAAW,EAAM,KAbrB/D,EAAO,GAAG3B,kCAiBb,MAEN,CAACqF,IAEES,EAAUF,EAAAA,aAAY,KACpB/C,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,UAAmBqF,GAEjC,IAAI5D,SAAc,CAACC,EAASC,KAC1B0D,EAIDA,EAAaQ,WACbR,EAAaU,QAAQ5D,MAAK,KAEtBqD,GAAU,GACV9D,GAAS,IACVoD,OAAO/D,IACNY,EAAOZ,EAAM,IAGjBY,EAAO,GAAG3B,sCAZV2B,EAAO,GAAG3B,mCAab,MAEN,CAACqF,IAkFJ,OA9EAjC,EAAAA,WAAU,KACN,GAAIY,GAAWkB,EAAM,CACbrC,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,4BAAqCkF,EAAMjB,GAEhE,MAAM+B,EAAiBhC,EAAQiC,wBAAwBf,EAAMjB,GAE7D,OADAqB,EAAgBU,GACT,KACCnD,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,sBAA+BkF,EAAMjB,GAEtD+B,EAAeH,WACfG,EAAeD,QACV5D,MAAK,SACL2C,OAAO/D,IACA8B,WAAWC,uBAAuBJ,eAClC1B,QAAQC,KAAK,GAAGjB,mCAA4Ce,EAC/D,IAEJgE,SAAQ,KACLiB,EAAeE,SAAS,IAQhCF,EAAeE,UAKnBZ,OAAgBxE,GAChB0E,GAAU,EAAM,CAEvB,IACF,CAACxB,EAASkB,EAAMjB,IAEnBb,EAAAA,WAAU,KACN,GAAIiC,GAAgBF,EAAM,CAClBtC,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,cAAuBqF,EAAcF,EAAMC,GAEhE,MAAMY,EAAiBX,EACjBc,EAAShB,EAgBf,OAfIgB,IACAT,GAAW,GACXM,EAAeb,KAAKC,GAAajD,MAAK,KAC9BU,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,WAAoBgG,GAExCR,GAAU,EAAK,IAChBV,OAAO/D,IACF8B,WAAWC,uBAAuBJ,eAClC1B,QAAQC,KAAK,GAAGjB,wCAAiDgG,EAAgBZ,EAAarE,EACjG,IACFgE,SAAQ,KACPW,GAAW,EAAM,KAGlB,KACC7C,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,sBAA+BgG,EAAgBG,GAEhEH,EAAeH,YACfG,EAAeD,QAAQ5D,MAAK,KACxBqD,GAAU,EAAM,IACjBV,OAAO/D,IACF8B,WAAWC,uBAAuBJ,eAClC1B,QAAQC,KAAK,GAAGjB,yCAAkDgG,EAAgBjF,EACrF,GAER,CAER,IACF,CAACsE,EAAcpB,EAASkB,EAAMC,IAE1B,CACHC,eACAI,UACAF,SACAJ,KAAMQ,EACNI,MAAOD,EAEf,4BCjKwB,SACpBT,EACAe,EACAC,GAEA,MAAOC,EAAUC,GAAenC,EAAQA,SAAiB,IAmCzD,OAjCAhB,EAAAA,WAAU,KACN,GAAIiC,EAAc,CACd,MAAMmB,EAAmBC,IACjB5D,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,sBAA+BqF,EAAaqB,UAAWD,GAE5EF,GAAaI,GAAe,IAAIA,EAAYF,KACxCL,GACAA,EAAcK,EACjB,EAELpB,EAAauB,GAAG,gBAAiBJ,GAEjC,MAAMK,EAAiBJ,IACf5D,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,oBAA6BqF,EAAaqB,UAAWD,GAG1EF,GAAaI,GAAeA,EAAWG,QAAQC,GAAcA,IAAcN,MACvEJ,GACAA,EAAYI,EACf,EAIL,OAFApB,EAAauB,GAAG,cAAeC,GAExB,KACHxB,EAAa2B,eAAe,gBAAiBR,GAC7CnB,EAAa2B,eAAe,cAAeH,GAC3CN,EAAY,IAAIU,MAAiB,CAExC,IACF,CAAC5B,EAAce,EAAeC,IAE1B,CACHC,WAER,4BCtCwB,SACpBjB,GAEA,MAAO6B,EAAUC,GAAe/C,EAAQA,SAA6B,IAsCrE,OApCAhB,EAAAA,WAAU,KACN,GAAIiC,EAAc,CACd,MAAM+B,EAAaC,IACXxE,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,gBAAyBqF,EAAaqB,UAAWW,GAEtEF,GAAaG,GAAe,IAAIA,EAAYD,IAAS,EAIzD,OAFAhC,EAAauB,GAAG,UAAWQ,GAEpB,KACH/B,EAAa2B,eAAe,UAAWI,GACvCD,EAAY,IAAIF,MAA6B,CAEpD,IACF,CAAC5B,IAqBG,CACH6B,WACAK,YArBgB3B,EAAAA,aAAY,CAAC4B,EAAoBC,IAC1C,IAAIhG,SAAc,CAACC,EAASC,KAC/B0D,SAAAA,EAAckC,YAAYC,GACrBrF,MAAMuF,IACC7E,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,gBAAyBqF,EAAaqB,UAAWgB,EAAMF,GAE3EL,GAAaG,GAAe,IAAIA,EAAY,CAAEK,QAASH,EAAYC,OAAQA,EAAQG,KAAM,IAAIC,SAC7FnG,GAAS,IAEZoD,OAAO/D,IACA8B,WAAWC,uBAAuBJ,eAClC1B,QAAQC,KAAK,GAAGjB,sBAA+Be,GAEnDY,EAAOZ,EAAM,GACf,KAEX,CAACsE,IAMR,8BClDwB,SACpBA,EACAyC,EACAC,GAEA,MAAOC,EAAYC,GAAiB7D,EAAAA,SAAuB,IAAI8D,KA+D/D,OA7DA9E,EAAAA,WAAU,KAKN,GAJIP,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,2BAAoCqF,GAGrDA,EAAc,CACd,MAAM8C,EAA+B1B,IAC7B5D,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,gCAAyCyG,GAG7DwB,GAAeG,GAAS,IAAIF,IAAIE,EAAKC,IAAI5B,KAAU,EAEjD6B,EAA6B7B,IAC3B5D,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,8BAAuCyG,GAG3DwB,GAAeG,IACXA,EAAKG,OAAO9B,GACL,IAAIyB,IAAIE,KACjB,EAGAI,EAAyBC,IACvB5F,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,0BAAmCyI,IAErC,IAAdA,EAAKC,MACD7F,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,kCAEhB+H,GACAA,KAGAD,GACAA,EAAUW,EAAKhC,QAEtB,EAQL,OALApB,EACKuB,GAAG,2BAA4BuB,GAC/BvB,GAAG,yBAA0B0B,GAC7B1B,GAAG,qBAAsB4B,GAEvB,KACC3F,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,uBAAgCqF,GAGrDA,EACK2B,eAAe,2BAA4BmB,GAC3CnB,eAAe,yBAA0BsB,GACzCtB,eAAe,qBAAsBwB,GAC1CP,EAAc,IAAIC,IAAM,CAE/B,IACF,CAAC7C,EAAcyC,EAAWC,IAEtB,CACHC,aAER,2BC5DwB,SACtB3C,EAEAsD,EAA2F5I,EAO3FmE,GAGIrB,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,iBAAyBqF,eAAAA,EAAcqB,YAAaiC,EAAiBC,KAAKrI,GAAQA,eAAAA,EAAK0D,WAI1G,MAAM4E,EAAwB1F,SAA+E,KAEtG2F,EAAkBC,GAAuB3E,EAAAA,SAAwB,IAAI6C,QACrE+B,EAAmBC,GAAwB7E,EAAAA,SAAwB,IAAI6C,OAExEiC,EACJtD,EAAAA,aAAY,CAAChB,EAAqBX,IACzB,IAAIxC,SAAgB,CAACC,EAASC,KAC/B0D,IACExC,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,aAAqBqF,EAAaqB,YAAa9B,EAAaX,GAE/EoB,EAAa6D,QAAQtE,EAAaX,GAAS9B,MAAMoB,IAC3CV,WAAWC,uBAAuBL,eACpCzB,QAAQ6D,KAAK,GAAG7E,eAAuBqF,EAAaqB,YAAanD,GAEnEwF,GAAqBI,GAAc,IAAIA,EAAW5F,KAClD7B,EAAQ6B,EAAO,IACduB,OAAO/D,IACRY,EAAOZ,EAAM,IAEhB,KAEF,CAACsE,IAEA+D,EAAyBxD,EAAAA,aAAY,CAACyD,EAAmBC,IACtD,IAAI7H,SAAgB,CAACC,EAASC,KAC/B0D,IACExC,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,4BAAoCqF,EAAaqB,aAAa2C,EAAUzF,cAAc0F,EAAU1F,WAEnHyB,EAAa+D,uBAAuBC,EAAWC,GAAWnH,MAAMoB,IAC1DV,WAAWC,uBAAuBL,eACpCzB,QAAQ6D,KAAK,GAAG7E,qBAA6BqF,EAAaqB,YAAa2C,EAAW9F,GAIpFwF,GAAqBI,IACnB,MAAMI,EAAQJ,EAAUK,QAAQH,GAIhC,OAHIE,GAAS,GACXJ,EAAUM,OAAOF,EAAO,EAAGhG,GAEtB0D,MAAMyC,KAAKP,EAAU,IAG9BzH,EAAQ6B,EAAO,IACduB,OAAO/D,IACRY,EAAOZ,EAAM,IAEhB,KAEF,CAACsE,IAEEsE,EAA2C/D,eAAahB,IACxDS,IACExC,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,eAAuBqF,EAAaqB,YAAa9B,EAAYhB,QAASgB,GAEzFS,EAAasE,UAAU/E,GACvBmE,GAAqBI,GAAcA,EAAUrC,QAAQ9B,GAAaA,IAAaJ,MAChF,GACA,CAACS,IAEEuE,EAAsBhE,EAAAA,aAAY,KACtC,MAAMiE,EAAYC,KAAKC,IAAIlB,EAAsBvF,QAAQ0G,OAAQrB,EAAiBqB,QAC9EnH,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,wBAAiC2I,EAChDnI,KAAKyJ,UAAUpB,EAAsBvF,QAAQsF,KAAIsB,GAAOA,aAAA,EAAAA,EAAK3G,OAAOK,WACpEpD,KAAKyJ,UAAUtB,EAAiBC,KAAIsB,GAAOA,aAAG,EAAHA,EAAK3G,OAAOK,WACvDiG,GAIJ,MAAMM,EAA+B,IAAItB,EAAsBvF,SAKzD8G,EAA2BzB,EAAiBC,KAAIyB,GAChDA,GAAOA,EAAIpG,QACN,CAAEV,OAAQ8G,EAAI9G,OAAQU,QAAOqG,OAAAC,OAAA,CAAA,EAAOF,EAAIpG,UAExCoG,IAIXxB,EAAsBvF,QAAQ0G,OAAS,EACvCnB,EAAsBvF,QAAQkH,QAAQJ,GAGtC,MAAMK,EAAsB,IAAIvC,IAAIS,EAAiB7B,OAAO7G,GAAU2I,KAAK8B,GAASA,EAAKnH,UAEnFoH,EAAY,CAACpB,EAAehJ,KAChC2I,EAAQ3I,EAAIgD,OAAQhD,EAAI0D,SACrBa,OAAO/D,IAGN8H,EAAsBvF,QAAQmG,OAAOF,EAAO,EAAG,MAC3CrF,EACFA,EAAcnD,GACL8B,WAAWC,uBAAuBJ,eAC3C1B,QAAQC,KAAK,GAAGjB,kBAA2Be,EAC5C,GACD,EAIN,IAAK,IAAI6J,EAAI,EAAGA,EAAIf,EAAWe,IAAK,CAClC,MAAMC,EAAWV,EAA6BS,GACxC9I,EAAO6G,EAAiBiC,GAE9B,GAAIC,GAAY/I,EAAM,CAEpB,MAAMgJ,EAAqB,KACzBnB,EAAUkB,EAAStH,QACnBoH,EAAUC,EAAG9I,EAAK,EAGhB+I,EAAStH,SAAWzB,EAAKyB,OAEvB/C,KAAKyJ,UAAUY,EAAS5G,WAAazD,KAAKyJ,UAAUnI,EAAKmC,UAG3D6G,IAKEL,EAAoBM,IAAIF,EAAStH,QAG/B8B,IAAiBA,EAAa2F,kBAAkBlJ,EAAKyB,SACvDoH,EAAUC,EAAG9I,GAGXuD,IAAiBA,EAAa2F,kBAAkBlJ,EAAKyB,QAGnD/C,KAAKyJ,UAAUY,EAAS5G,WAAazD,KAAKyJ,UAAUnI,EAAKmC,SAC3DmF,EAAuByB,EAAStH,OAAQzB,EAAKyB,QAE1CuB,OAAO/D,IAGN8H,EAAsBvF,QAAQmG,OAAOmB,EAAG,EAAG,MACvC1G,EACFA,EAAcnD,GACL8B,WAAWC,uBAAuBJ,eAC3C1B,QAAQC,KAAK,GAAGjB,iCAA0Ce,EAC3D,IAGL+J,IAIFnB,EAAUkB,EAAStH,OAI1B,MAAUsH,IAAa/I,EAGjB2I,EAAoBM,IAAIF,EAAStH,SACpCoG,EAAUkB,EAAStH,SAEXsH,GAAY/I,GAMlBuD,IAAiBA,EAAa2F,kBAAkBlJ,EAAKyB,SACvDoH,EAAUC,EAAG9I,EAGlB,IAEA,CAACuD,EAGFsD,EAEAO,EAASS,EAAWP,EACpBlF,IAEI+G,EAAerF,EAAAA,aAAY,KAC3BP,GAEF0D,GAAqBI,IAEnBA,EAAU+B,SAAQ3H,IACZV,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,eAAuBqF,EAAaqB,YAAanD,GAEpE8B,EAAasE,UAAUpG,EAAO,IAEzB,MAIXsF,EAAsBvF,QAAQ0G,OAAS,CAAC,GACvC,CAAC3E,IAEE8F,EAAiBvF,EAAAA,aAAY,KAC7BP,GACF4D,GAAsBE,IAEpBA,EAAU+B,SAAQ3H,IACZV,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,yBAAiCqF,EAAaqB,YAAanD,GAE9E8B,EAAa+F,oBAAoB7H,EAAOK,QAAQ,IAE3C,KAEV,GACA,CAACyB,IAEEgG,EAA6BzF,EAAAA,aAAY,KAC7CqF,IACAE,GAAgB,GACf,CAACF,EAAcE,IAwFlB,OAnFA/H,EAAAA,WAAU,KACR,GAAIiC,EAAc,CAGhBwD,EAAsBvF,QAAQ0G,OAAS,EAEvC,MAAMsB,EAAkB/H,IAClBV,WAAWC,uBAAuBL,eACpCzB,QAAQ6D,KAAK,GAAG7E,oBAA4BqF,EAAaqB,YAAanD,GAExE0F,GAAsBE,GAAc,IAAIA,EAAW5F,IAAQ,EAEvDgI,EAAoBhI,IACpBV,WAAWC,uBAAuBL,eACpCzB,QAAQ6D,KAAK,GAAG7E,sBAA8BqF,EAAaqB,YAAanD,GAE1E0F,GAAsBE,GAAcA,EAAUrC,QAAQ9B,GAAaA,IAAazB,KAAQ,EAEpFiI,EAAwBC,IACxB5I,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,0BAAkCqF,EAAaqB,YAAa+E,GAE/E,MAAMC,EAAWC,OAAOF,EAAWC,WACP,IAAxBD,EAAWG,WACoB,UAA7BH,EAAWI,cAEbxG,EAAayG,kBAAkBJ,GACO,YAA7BD,EAAWI,eAEpBxG,EAAa+F,oBAAoBM,GAEpC,EAOH,OAJArG,EAAauB,GAAG,cAAe0E,GAC/BjG,EAAauB,GAAG,gBAAiB2E,GACjClG,EAAauB,GAAG,oBAAqB4E,GAE9B,KAELnG,EAAa2B,eAAe,oBAAqBwE,GACjDnG,EAAa2B,eAAe,gBAAiBuE,GAC7ClG,EAAa2B,eAAe,cAAesE,GAE3CD,GAA4B,CAE/B,IACA,CAAChG,EAAcgG,IAElBjI,EAAAA,WAAU,KACR,GAAIiC,EAAc,CACZxC,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,mCAA2CqF,EAAaqB,YAAaiC,GAGxF,MAAMoD,EAAY,KACZlJ,WAAWC,uBAAuBL,eACpCzB,QAAQ6D,KAAK,GAAG7E,eAAuBqF,EAAaqB,aAEtDkD,GAAqB,EAEjBoC,EAAU,KACVnJ,WAAWC,uBAAuBL,eACpCzB,QAAQ6D,KAAK,GAAG7E,aAAqBqF,EAAaqB,aAGpD2E,GAA4B,EAU9B,OAPAhG,EAAauB,GAAG,SAAUmF,GAC1B1G,EAAauB,GAAG,OAAQoF,GAEpB3G,EAAaQ,YACf+D,IAGK,KACLvE,EAAa2B,eAAe,SAAU+E,GACtC1G,EAAa2B,eAAe,OAAQgF,EAAQ,CAE/C,IACA,CAAC3G,EAAcsD,EAAkBiB,EAAqByB,IAElD,CACLvC,mBACAE,oBACAE,UACAS,YACAP,yBACA6B,eACAE,iBAEJ,gBCtVc,SAAsBnH,EAA8BiI,GAE9D,MAAMC,EAAgB/I,EAAAA,OAAoB,IAAI+E,KACxCiE,EAAoBhJ,EAAAA,OAAkC,IAAIiJ,MAEzDC,EAAiBC,GAAsBlI,EAAAA,SAAoC,IAAIgI,KAEtFhJ,EAAAA,WAAU,KACN,GAAIY,EAAS,CACT,MAAMuI,EAAgBL,EAAc5I,QAC9BkJ,EAAoBL,EAAkB7I,QAC5C,MAAO,KACHiJ,EAAcE,QACdD,EAAkBC,QAClBH,EAAmB,IAAIF,IAAM,CAEpC,IACF,CAACpI,IAEJ,MAAM0I,EAAuBC,UACzB,MAAMC,EAA4C,QAApCC,EAAAV,EAAkB7I,QAAQwJ,IAAIH,UAAM,IAAAE,EAAAA,EAAI,IAAI3E,IAI1D,OAHKiE,EAAkB7I,QAAQyH,IAAI4B,IAC/BR,EAAkB7I,QAAQyJ,IAAIJ,EAAOC,GAElCA,CAAK,EAmGhB,OAhGAxJ,EAAAA,WAAU,KAIN,GAHIP,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,8BAAuCiM,GAExDjI,EAAS,CACT,MAAMgJ,EAAYhJ,EACZiJ,EAAc,IAAI/E,IAAI+D,GAI5BgB,EAAY/B,SAAQyB,IACXT,EAAc5I,QAAQyH,IAAI4B,KACvB9J,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,qBAA8B2M,GAElDT,EAAc5I,QAAQ+E,IAAIsE,GAC1BK,EAAUE,iBAAiBP,GAC9B,IAGL,IAAIQ,GAAe,EAkBnB,GAjBAjB,EAAc5I,QAAQ4H,SAAQyB,IACrBM,EAAYlC,IAAI4B,KACb9J,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,uBAAgC2M,GAEpDK,EAAUI,mBAAmBT,GAC7BT,EAAc5I,QAAQiF,OAAOoE,GAC7BR,EAAkB7I,QAAQiF,OAAOoE,GACjCQ,GAAe,EAClB,IAGDA,GAEAb,EAAmB,IAAIF,IAAID,EAAkB7I,UAG7C2I,EAAOjC,OAAS,EAAG,CACnB,MAAMqD,EAAuBC,IAErBzK,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,sBAA+BsN,GAGpD,IAAIH,GAAe,EAInB,IAAK,MAAMR,KAASrC,OAAOiD,KAAKD,EAAgBE,aAC5C,GAAIP,EAAYlC,IAAI4B,GAAQ,CACxB,MAAMc,EAAQf,EAAoBC,GAClC,IAAK,MAAMlG,KAAW6G,EAAgBE,YAAYb,GAC9Cc,EAAMpF,IAAI5B,GACV0G,GAAe,CAEtB,CAEL,IAAK,MAAMR,KAASrC,OAAOiD,KAAKD,EAAgBI,WAC5C,GAAIT,EAAYlC,IAAI4B,GAAQ,CACxB,MAAMc,EAAQf,EAAoBC,GAClC,IAAK,MAAMlG,KAAW6G,EAAgBI,UAAUf,GAC5Cc,EAAMlF,OAAO9B,GACb0G,GAAe,EAGI,IAAfM,EAAME,MACNxB,EAAkB7I,QAAQiF,OAAOoE,EAG5C,CAIL,IAAK,MAAMlG,KAAW6G,EAAgBM,gBAClC,IAAK,MAAMjH,KAAcwF,EAAkB7I,QAAQuK,SAC/C,GAAIlH,EAAWoE,IAAItE,GAAU,CACzB0G,GAAe,EACf,KACH,CAILA,GAEAb,EAAmB,IAAIF,IAAID,EAAkB7I,SAChD,EAGL,OADA0J,EAAUpG,GAAG,oBAAqByG,GAC3B,KACHL,EAAUhG,eAAe,oBAAqBqG,EAAoB,CAEzE,CACJ,IACF,CAACrJ,EAASiI,IAEN,CACHI,kBAER,eC7GwB,SAAWyB,EAC/B7J,EACAC,GAEA,MAAOF,EAAS+J,GAAc3J,EAAQA,YAC/B4J,EAAYC,GAAiB7J,EAAQA,UAAU,GAEtDhB,EAAAA,WAAU,KAIN,GAHIP,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,mCAA4C8N,EAAa7J,GAE1E6J,EAcA,OAVAI,EAAQJ,EAAa7J,GAASa,OAAO/D,IACjCC,QAAQD,MAAM,GAAGf,sBAA+Be,GAChDgN,OAAWjN,GAEPoD,EACAA,EAAcnD,GACP8B,WAAWC,uBAAuBJ,eACzC1B,QAAQC,KAAK,GAAGjB,kBAA2Be,EAC9C,IAEE,KACHgN,OAAWjN,GAMXmN,GAAc,EAAM,CAE3B,GACF,CAACH,EAAa7J,EAASC,IAE1Bd,EAAAA,WAAU,KAIN,GAHIP,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,sBAA+BgE,GAEhDA,EAAS,CACT,MAAMgJ,EAAYhJ,EAClB,MAAO,KACCnB,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,8BAAuCgN,GAE5DA,EAAUmB,aAAahM,MAAK,KACpBU,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,iBAA0BgN,EAC7C,IACFlI,OAAO/D,IACNC,QAAQD,MAAM,GAAGf,eAAwBe,EAAM,GACjD,CAET,IACF,CAACiD,IAEJ,MAAMkK,EAAU,CAACJ,EAAsC7J,IAC5C,IAAIxC,SAAc,CAACC,EAASC,KAC/B,MAAMyM,EAA2CnK,GAAoB,CACjEoK,SAAU,4BAGd,IAAIC,EAEJ,GArFc,iBADSC,EAsFOT,IApF/B,aAAcS,EAqFTH,EAAoBI,SAAWV,EAAYU,SAC3CF,EAAc,IAAIG,EAAAA,UAAU,CACxBC,IAAK,UAAUZ,EAAYa,kBAE5B,GArFnB,SAA4BJ,GACxB,MAAsB,iBAAXA,GACJ,WAAYA,CACvB,CAkFuBK,CAAmBd,GAC1BQ,EAAc,IAAIG,EAAAA,UAAU,CACxBC,IAAK,UAAUZ,EAAYe,eAE5B,KAnFnB,SAA2BN,GACvB,MAAsB,iBAAXA,GACJ,UAAWA,CACtB,CAgFuBO,CAAkBhB,GAMzB,YADAnM,EAAO,8BAJP2M,EAAc,IAAIG,EAAAA,UAAU,CACxBC,IAAK,SAASZ,EAAYiB,SAKjC,CAtGb,IAAmCR,EAwGvBN,GAAc,GACdK,EAAYU,SAASZ,GAAqBjM,MAAK6K,IACvCnK,WAAWC,uBAAuBL,eAClCzB,QAAQ6D,KAAK,GAAG7E,cAAuBgN,GAE3Ce,EAAWf,GACXtL,GAAS,IACVoD,OAAO/D,IACNY,EAAOZ,EAAM,IACdgE,SAAQ,KACPkJ,GAAc,EAAM,GACtB,IA0BV,MAAO,CAEHjK,QAASA,EACTgK,aACAE,UACAC,WATe,KACfJ,OAAWjN,EAAU,EAU7B,iCC3IwB,SACpByC,EACA0L,EACA/K,GAEA,MAAMgL,EAAmB/L,EAAAA,UAClBgM,EAAWC,GAAgBhL,EAAQA,SAACb,IACpC8L,EAAUC,GAAelL,EAAQA,UAAC,IAClCrD,EAAOwD,GAAYH,EAAQA,WAqClC,OAnCAhB,EAAAA,WAAU,IAEC,KACH8L,EAAiB5L,aAAUxC,CAAS,GAEzC,CAACyC,IAEJH,EAAAA,WAAU,KACFP,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,cAAuBuD,EAAQ0L,GAEpDG,EAAa7L,GACb,MAAMgM,EAAUL,EAAiB5L,UAAWC,aAAM,EAANA,EAAQiM,qBAAsB,OAkB1E,OAjBIjM,GAAU0L,IAAkBM,IAC5BD,GAAY,GACZ/L,EAAOkM,oBAAoBR,GAAe9M,MAAK6C,IAC3CoK,EAAapK,GACbkK,EAAiB5L,QAAU2L,EAC3B1K,OAASzD,EAAU,IACpBgE,OAAM/D,IACLwD,EAASxD,GACLmD,EACAA,EAAcnD,GACP8B,WAAWC,uBAAuBJ,eACzC1B,QAAQC,KAAK,GAAGjB,cAAuBuD,EAAQ0L,EAAelO,EACjE,IACFgE,SAAQ,KACPuK,GAAY,EAAM,KAGnB,KACH/K,OAASzD,EAAU,CACtB,GACF,CAACyC,EAAQ0L,EAAe/K,IAEpB,CACHX,OAAQ4L,EACRE,WACAE,QAASL,EAAiB5L,UAAYC,aAAM,EAANA,EAAgBiM,qBAAsB,OAC5EzO,QAER,iCClDc,SACVwC,EACA0L,EAAmChL,EACnCC,GAEA,MAAMgL,EAAmB/L,EAAAA,UAClBgM,EAAWC,GAAgBhL,EAAQA,SAACb,IACpC8L,EAAUC,GAAelL,EAAQA,UAAC,IAClCrD,EAAOwD,GAAYH,EAAQA,WAqClC,OAnCAhB,EAAAA,WAAU,IAEC,KACH8L,EAAiB5L,aAAUxC,CAAS,GAEzC,CAACyC,IAEJH,EAAAA,WAAU,KACFP,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,cAAuBuD,EAAQ0L,EAAehL,GAEnEmL,EAAa7L,GACb,MAAMgM,EAAUL,EAAiB5L,UAAWC,aAAM,EAANA,EAAQmM,qBAAsB,OAkB1E,OAjBInM,GAAU0L,IAAkBM,IAC5BD,GAAY,GACZ/L,EAAOoM,oBAAoBV,EAAehL,GAAS9B,MAAK6C,IACpDoK,EAAapK,GACbkK,EAAiB5L,QAAU2L,EAC3B1K,OAASzD,EAAU,IACpBgE,OAAM/D,IACLwD,EAASxD,GACLmD,EACAA,EAAcnD,GACP8B,WAAWC,uBAAuBJ,eACzC1B,QAAQC,KAAK,GAAGjB,cAAuBuD,EAAQ0L,EAAehL,EAASlD,EAC1E,IACFgE,SAAQ,KACPuK,GAAY,EAAM,KAGnB,KACH/K,OAASzD,EAAU,CACtB,GACF,CAACyC,EAAQ0L,EAAehL,EAASC,IAE7B,CACHX,OAAQ4L,EACRE,WACAE,QAASL,EAAiB5L,UAAYC,aAAM,EAANA,EAAgBmM,qBAAsB,OAC5E3O,QAER,yBGvDc,SAA+BsE,EAAsCuK,GACjF,MAAOC,EAAmBC,GAAwB1L,EAAQA,SAA2B,OAC9E2L,EAAYC,GAAiB5L,EAAQA,UAAU,IAE/C6L,EAAaC,GAAkB9L,EAAQA,SAAe,IAG7DhB,EAAAA,WAAU,KACR,GAAIyM,EAAmB,OAEvB,IAAIM,GAAU,EAed,OAZAC,OAAO,cAAcjO,MAAK,EAAGkO,wBAC3B,IAAKF,EAIH,YAHItN,WAAWC,uBAAuBJ,eACpC1B,QAAQC,KAAK,GAAGjB,kDAKpB,MAAMsQ,EAAU,IAAID,EACpBP,EAAqBQ,EAAQ,IAGxB,KACLH,GAAU,CAAK,CAChB,GACA,CAACN,IAGJzM,EAAAA,WAAU,KACR,IAAKyM,EAIH,YAHIhN,WAAWC,uBAAuBJ,eACpC1B,QAAQC,KAAK,GAAGjB,0EAKpB,MAAMuQ,EAAgBC,IACpB,MAAMC,WAAEA,GAAeD,EAEnB3N,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,iBAA0ByQ,GAG7CP,GAAgB9H,GAAS,IAAIA,EAAMqI,IAAY,EAKjD,OAFAZ,EAAkBa,iBAAiB,aAAcH,GAE1C,KACLV,EAAkBc,oBAAoB,aAAcJ,GAChD1N,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,sBAA+B,eACjD,CACF,GACA,CAAC6P,IAGJ,MAAMe,EAAyBhL,EAAWA,aAAC,IAAWxE,EAAAyP,UAAA,OAAA,GAAA,YAChDhO,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,yDAAkE6P,EAAmBE,GAGnGF,EAODE,EACElN,WAAWC,uBAAuBJ,eACpC1B,QAAQC,KAAK,GAAGjB,sDAKfqF,QAKCwK,EACHiB,MAAMzL,GACNlD,MAAK,KACJnB,QAAQ+P,IAAI,GAAG/Q,sCACfgQ,GAAc,EAAK,IAEpBlL,OAAO/D,IACNC,QAAQD,MAAM,GAAGf,oCAA6Ce,EAAM,IAXtEC,QAAQC,KAAK,GAAGjB,gEAdZ6C,WAAWC,uBAAuBJ,eACpC1B,QAAQC,KAAK,GAAGjB,uEA0BrB,KAAE,CAAC6P,EAAmBE,EAAY1K,IAG7B2L,EAAwBpL,EAAWA,aAAC,IAAWxE,EAAAyP,UAAA,OAAA,GAAA,YAC9ChB,EAOAxK,QAKCwK,EACHoB,KAAK5L,GACLlD,MAAK,KACJnB,QAAQ+P,IAAI,GAAG/Q,qCACfgQ,GAAc,EAAM,IAErBlL,OAAO/D,IACNC,QAAQD,MAAM,GAAGf,mCAA4Ce,EAAM,IAXrEC,QAAQC,KAAK,GAAGjB,+DAPZ6C,WAAWC,uBAAuBJ,eACpC1B,QAAQC,KAAK,GAAGjB,sEAmBrB,KAAE,CAAC6P,EAAmBxK,IAyBvB,OAtBAjC,EAAAA,WAAU,KACJP,WAAWC,uBAAuBN,gBACpCxB,QAAQwD,MAAM,GAAGxE,iEAA0E4P,EAAWvK,GAGnGuK,EAOAvK,EAOLuL,IANM/N,WAAWC,uBAAuBJ,eACpC1B,QAAQC,KAAK,GAAGjB,oFARd6C,WAAWC,uBAAuBJ,eACpC1B,QAAQC,KAAK,GAAGjB,kDAYI,GACvB,CAAC4P,EAAWvK,EAAcuL,IAEtB,CACLf,oBACAE,aACAE,cACAW,yBACAI,wBAEJ,wBFnIc,SACVhN,EACAkN,GAEA,MAAMC,EAAkBC,EAAAA,SAAQ,IAAMF,EAAmB,GAAGA,iBAA6BpQ,GAAW,CAACoQ,IAC/FG,EAAmBD,EAAAA,SAAQ,IAAMF,EAAmB,GAAGA,kBAA8BpQ,GAAW,CAACoQ,IACjGI,EAAkBF,EAAAA,SAAQ,IAAMF,EAAmB,GAAGA,iBAA6BpQ,GAAW,CAACoQ,KAG9FK,EAAiBC,GAAsBpN,EAAQA,UAA0B,IAAM+M,EAAkBhR,EAA+BgR,QAAmBrQ,KACnJ2Q,EAAkBC,GAAuBtN,EAAQA,UAA0B,IAAMiN,EAAmBlR,EAA+BkR,QAAoBvQ,KACvJ6Q,EAAiBC,GAAsBxN,EAAQA,UAA0B,IAAMkN,EAAkBnR,EAA+BmR,QAAmBxQ,KAEnJ+Q,EAAkBC,GAAuB1N,WAA0B,CACtE2N,WAAYR,EAAkB,CAC1B,CAACA,EAAgB3N,SAAU2N,GAC3B,CAAE,EACNS,YAAaP,EAAmB,CAC5B,CAACA,EAAiB7N,SAAU6N,GAC5B,CAAE,EACNQ,WAAYN,EAAkB,CAC1B,CAACA,EAAgB/N,SAAU+N,GAC3B,CAAE,IA4DV,OAzDAvO,EAAAA,WAAU,KACN,GAAIY,EAAS,CACT,MAAMS,EAAuBT,EAAQU,eAE/BwN,EAAwB,KAC1B,MAAMC,EAAgC1N,EAAU2N,sBAE5CvP,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,uBAAgCmS,GAGrDL,EAAoBK,GACpBX,GAAoBpJ,GAASA,EAAO+J,EAAaJ,WAAW3J,EAAKxE,cAAW9C,IAC5E4Q,GAAqBtJ,GAASA,EAAO+J,EAAaH,YAAY5J,EAAKxE,cAAW9C,IAC9E8Q,GAAoBxJ,GAASA,EAAO+J,EAAaF,WAAW7J,EAAKxE,cAAW9C,GAAU,EAI1F,OAFA2D,EAAUmC,GAAG,qBAAsBsL,GAE5B,KACHzN,EAAUuC,eAAe,qBAAsBkL,EAAsB,CAE5E,IACF,CAAClO,IAEJZ,EAAAA,WAAU,KACFmO,GAAmBJ,IACftO,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,oBAA6BuR,GAElDrQ,EAAgBiQ,EAAiB3Q,KAAKyJ,UAAU,CAC5CtJ,GAAI4Q,EAAgB3N,QAAShD,KAAM2Q,EAAgBc,UAAWxR,MAAO0Q,EAAgBe,cAE5F,GACF,CAACnB,EAAiBI,IAErBnO,EAAAA,WAAU,KACFqO,GAAoBJ,IAChBxO,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,qBAA8ByR,GAEnDvQ,EAAgBmQ,EAAkB7Q,KAAKyJ,UAAU,CAC7CtJ,GAAI8Q,EAAiB7N,QAAShD,KAAM6Q,EAAiBY,UAAWxR,MAAO4Q,EAAiBa,cAE/F,GACF,CAACjB,EAAkBI,IAEtBrO,EAAAA,WAAU,KACFuO,GAAmBL,IACfzO,WAAWC,uBAAuBN,gBAClCxB,QAAQwD,MAAM,GAAGxE,oBAA6B2R,GAElDzQ,EAAgBoQ,EAAiB9Q,KAAKyJ,UAAU,CAC5CtJ,GAAIgR,EAAgB/N,QAAShD,KAAM+Q,EAAgBU,UAAWxR,MAAO8Q,EAAgBW,cAE5F,GACF,CAAChB,EAAiBK,IAEd,CACHE,mBACAN,kBAAiBgB,kBAAmBhB,aAAA,EAAAA,EAAiB3N,QAAS4N,qBAC9DC,mBAAkBe,mBAAoBf,aAAA,EAAAA,EAAkB7N,QAAS8N,sBACjEC,kBAAiBc,kBAAmBd,aAAA,EAAAA,EAAiB/N,QAASgO,qBAEtE"}
|
|
1
|
+
{"version":3,"file":"react-lib.production.min.js","sources":["../src/hooks/useCameraStream.ts","../src/hooks/useConversation.ts","../src/hooks/useConversationContacts.ts","../src/hooks/useConversationMessages.ts","../src/hooks/useConversationModeration.ts","../src/hooks/useConversationStreams.ts","../src/hooks/usePresence.ts","../src/hooks/useSession.ts","../src/hooks/useStreamApplyAudioProcessor.ts","../src/hooks/useStreamApplyVideoProcessor.ts","../src/hooks/useUserMediaDevices.ts","../node_modules/tslib/tslib.es6.mjs","../src/hooks/useTranscriptService.ts","../src/index.ts","../src/components/VideoStream/VideoStream.tsx"],"sourcesContent":["import { CreateStreamOptions, Session, Stream, UserAgent } from '@apirtc/apirtc';\nimport { useEffect, useState } from 'react';\n\nconst EMPTY = {};\n\nconst HOOK_NAME = 'useCameraStream';\nexport function useCameraStream(\n\tsession: Session | undefined,\n\toptions: CreateStreamOptions = EMPTY, // used to be = {} but this triggers infinite loop with useEffect\n\terrorCallback?: (error: any) => void\n) {\n\tconst [stream, setStream] = useState<Stream>();\n\tconst [grabbing, setGrabbing] = useState<boolean>(false);\n\n\tconst [error, setError] = useState<any>();\n\n\tuseEffect(() => {\n\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\tconsole.debug(`${HOOK_NAME}|useEffect`, session, options);\n\t\t}\n\t\tif (session) {\n\t\t\tconst userAgent: UserAgent = session.getUserAgent();\n\t\t\tsetGrabbing(true);\n\t\t\tuserAgent\n\t\t\t\t.createStream(options)\n\t\t\t\t.then((localStream: Stream) => {\n\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\t\tconsole.info(`${HOOK_NAME}|createStream`, options, localStream);\n\t\t\t\t\t}\n\t\t\t\t\tsetStream(localStream);\n\t\t\t\t\tsetError(undefined);\n\t\t\t\t})\n\t\t\t\t.catch((error: any) => {\n\t\t\t\t\tconsole.error(`${HOOK_NAME}|createStream error`, options, error);\n\t\t\t\t\tsetStream(undefined);\n\t\t\t\t\tif (errorCallback) {\n\t\t\t\t\t\terrorCallback(error);\n\t\t\t\t\t}\n\t\t\t\t\tsetError(error);\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tsetGrabbing(false);\n\t\t\t\t});\n\n\t\t\t// DO NOT set out stream to undefined in the return, to prevent unnecessary refreshes\n\t\t\t// of other components with undefined stream, whereas we are expecting to change it\n\t\t\t// to another instance..\n\t\t\t// return () => { setStream(undefined) } // DON'T\n\t\t} else {\n\t\t\tsetStream(undefined);\n\t\t\tsetError(undefined);\n\t\t}\n\t}, [session, options, errorCallback]);\n\n\tuseEffect(() => {\n\t\tconst l_stream = stream;\n\t\tif (l_stream) {\n\t\t\treturn () => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\tconsole.info(`${HOOK_NAME}|release stream`, l_stream);\n\t\t\t\t}\n\t\t\t\tl_stream.release();\n\t\t\t};\n\t\t}\n\t}, [stream]);\n\n\treturn {\n\t\tstream,\n\t\tgrabbing,\n\t\terror,\n\t};\n}\n","import { Conversation, GetOrCreateConversationOptions, JoinOptions, Session } from '@apirtc/apirtc';\nimport { useCallback, useEffect, useState } from 'react';\n\nconst HOOK_NAME = 'useConversation';\n/**\n * A hook to getOrCreate a named conversation and manage join/leave\n * @param session an ApiRTC Session\n * @param name the conversation name\n * @param options getOrCreateConversation options\n * @param join true by default\n * @param joinOptions conversation.join options\n */\nexport default function useConversation(\n\tsession: Session | undefined,\n\tname: string | undefined,\n\toptions?: GetOrCreateConversationOptions,\n\tjoin: boolean = true,\n\tjoinOptions?: JoinOptions\n) {\n\tconst [conversation, setConversation] = useState<Conversation>();\n\tconst [joined, setJoined] = useState<boolean>(false);\n\tconst [joining, setJoining] = useState<boolean>(false);\n\n\t// Callbacks\n\t//\n\t// Offering Promised join/leave methods allows developer to act on then/catch\n\t//\n\tconst o_join = useCallback(\n\t\t(joinOptions: JoinOptions = {}) => {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\tconsole.debug(`${HOOK_NAME}|join`, conversation, joinOptions);\n\t\t\t\t//JSON.stringify((apiRTC as any).session.apiCCWebRTCClient.webRTCClient.MCUClient.sessionMCUs))\n\t\t\t}\n\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\tif (!conversation) {\n\t\t\t\t\treject(`${HOOK_NAME}|join|conversation not defined`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!conversation.isJoined()) {\n\t\t\t\t\tsetJoining(true);\n\t\t\t\t\tconversation\n\t\t\t\t\t\t.join(joinOptions)\n\t\t\t\t\t\t.then(() => {\n\t\t\t\t\t\t\t// successfully joined the conversation.\n\t\t\t\t\t\t\tsetJoined(true);\n\t\t\t\t\t\t\tresolve();\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((error: any) => {\n\t\t\t\t\t\t\t// could not join the conversation.\n\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\t\tsetJoining(false);\n\t\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\treject(`${HOOK_NAME}|join|conversation already joined`);\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\t[conversation]\n\t);\n\n\tconst o_leave = useCallback(() => {\n\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\tconsole.debug(`${HOOK_NAME}|leave`, conversation);\n\t\t}\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\tif (!conversation) {\n\t\t\t\treject(`${HOOK_NAME}|leave|conversation not defined`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (conversation.isJoined()) {\n\t\t\t\tconversation\n\t\t\t\t\t.leave()\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\t// local user successfully left the conversation.\n\t\t\t\t\t\tsetJoined(false);\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t})\n\t\t\t\t\t.catch((error: any) => {\n\t\t\t\t\t\treject(error);\n\t\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treject(`${HOOK_NAME}|leave|conversation is not joined`);\n\t\t\t}\n\t\t});\n\t}, [conversation]);\n\n\t// Effects\n\t//\n\tuseEffect(() => {\n\t\tif (session && name) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\tconsole.debug(`${HOOK_NAME}|getOrCreateConversation`, name, options);\n\t\t\t}\n\t\t\tconst l_conversation = session.getOrCreateConversation(name, options);\n\t\t\tsetConversation(l_conversation);\n\t\t\treturn () => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\tconsole.debug(`${HOOK_NAME}|useEffect cleanup`, name, options);\n\t\t\t\t}\n\t\t\t\tif (l_conversation.isJoined()) {\n\t\t\t\t\tl_conversation\n\t\t\t\t\t\t.leave()\n\t\t\t\t\t\t.then(() => {})\n\t\t\t\t\t\t.catch((error: any) => {\n\t\t\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\t\t\t\t\tconsole.warn(`${HOOK_NAME}|useEffect conversation.leave()`, error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\t\tl_conversation.destroy();\n\t\t\t\t\t\t\t// SHOULD NOT touch the state here as this async and the conversation may have already changed\n\t\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// It is important to destroy the conversation.\n\t\t\t\t\t// Otherwise subsequent getOrCreateConversation with same name would get\n\t\t\t\t\t// previous handle, regardless of the potentially new options.\n\t\t\t\t\t// This also allows to cleanup memory\n\t\t\t\t\tl_conversation.destroy();\n\t\t\t\t}\n\t\t\t\t// In any cases, update state accordingly\n\t\t\t\t// Note: this is done here synchronously, this shall NOT be done in the leave().finally to prevent\n\t\t\t\t// overriding a potential conversation change\n\t\t\t\tsetConversation(undefined);\n\t\t\t\tsetJoined(false);\n\t\t\t};\n\t\t}\n\t}, [session, name, options]);\n\n\tuseEffect(() => {\n\t\tif (conversation && join) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\tconsole.debug(`${HOOK_NAME}|useEffect`, conversation, join, joinOptions);\n\t\t\t}\n\t\t\tconst l_conversation = conversation;\n\t\t\tconst l_join = join;\n\t\t\tif (l_join) {\n\t\t\t\tsetJoining(true);\n\t\t\t\tl_conversation\n\t\t\t\t\t.join(joinOptions)\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\t\t\tconsole.info(`${HOOK_NAME}|joined`, l_conversation);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetJoined(true);\n\t\t\t\t\t})\n\t\t\t\t\t.catch((error: any) => {\n\t\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\t`${HOOK_NAME}|useEffect conversation.join() error`,\n\t\t\t\t\t\t\t\tl_conversation,\n\t\t\t\t\t\t\t\tjoinOptions,\n\t\t\t\t\t\t\t\terror\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\tsetJoining(false);\n\t\t\t\t\t});\n\t\t\t}\n\t\t\treturn () => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\tconsole.debug(`${HOOK_NAME}|useEffect cleanup`, l_conversation, l_join);\n\t\t\t\t}\n\t\t\t\tif (l_conversation.isJoined()) {\n\t\t\t\t\tl_conversation\n\t\t\t\t\t\t.leave()\n\t\t\t\t\t\t.then(() => {\n\t\t\t\t\t\t\tsetJoined(false);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((error: any) => {\n\t\t\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\t\t`${HOOK_NAME}|useEffect conversation.leave() error`,\n\t\t\t\t\t\t\t\t\tl_conversation,\n\t\t\t\t\t\t\t\t\terror\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t}, [conversation, options, join, joinOptions]);\n\n\treturn {\n\t\tconversation,\n\t\tjoining,\n\t\tjoined,\n\t\tjoin: o_join,\n\t\tleave: o_leave,\n\t};\n}\n","import { Contact, Conversation } from '@apirtc/apirtc';\nimport { useEffect, useState } from 'react';\n\nconst HOOK_NAME = 'useConversationContacts';\nexport default function useConversationContacts(\n\tconversation: Conversation | undefined,\n\tcontactJoined?: (contact: Contact) => void,\n\tcontactLeft?: (contact: Contact) => void\n) {\n\tconst [contacts, setContacts] = useState<Array<Contact>>([]);\n\n\tuseEffect(() => {\n\t\tif (conversation) {\n\t\t\tconst onContactJoined = (contact: Contact) => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\tconsole.debug(\n\t\t\t\t\t\t`${HOOK_NAME}|on:contactJoined:`,\n\t\t\t\t\t\tconversation.getName(),\n\t\t\t\t\t\tcontact\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tsetContacts((l_contacts) => [...l_contacts, contact]);\n\t\t\t\tif (contactJoined) {\n\t\t\t\t\tcontactJoined(contact);\n\t\t\t\t}\n\t\t\t};\n\t\t\tconversation.on('contactJoined', onContactJoined);\n\n\t\t\tconst onContactLeft = (contact: Contact) => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\tconsole.debug(`${HOOK_NAME}|on:contactLeft:`, conversation.getName(), contact);\n\t\t\t\t}\n\t\t\t\t// filter out contact\n\t\t\t\tsetContacts((l_contacts) =>\n\t\t\t\t\tl_contacts.filter((l_contact) => l_contact !== contact)\n\t\t\t\t);\n\t\t\t\tif (contactLeft) {\n\t\t\t\t\tcontactLeft(contact);\n\t\t\t\t}\n\t\t\t};\n\t\t\tconversation.on('contactLeft', onContactLeft);\n\n\t\t\treturn () => {\n\t\t\t\tconversation.removeListener('contactJoined', onContactJoined);\n\t\t\t\tconversation.removeListener('contactLeft', onContactLeft);\n\t\t\t\tsetContacts(new Array<Contact>());\n\t\t\t};\n\t\t}\n\t}, [conversation, contactJoined, contactLeft]);\n\n\treturn {\n\t\tcontacts,\n\t};\n}\n","import { Contact, Conversation, ConversationMessage } from '@apirtc/apirtc';\nimport { useCallback, useEffect, useState } from 'react';\n\n// TODO : get and handle with pagination messages history\n// TODO : ask apirtc to include the uuid in ConversationMessage so that we can store it\n// into ConversationMessage when creating the local one, and we get it from conversation on:message\n// the uuid shall be the value used as a react child key when displaying list of messages\n\nconst HOOK_NAME = 'useConversationMessages';\nexport default function useConversationMessages(conversation: Conversation | undefined) {\n\tconst [messages, setMessages] = useState<Array<ConversationMessage>>([]);\n\n\tuseEffect(() => {\n\t\tif (conversation) {\n\t\t\tconst onMessage = (message: ConversationMessage) => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\tconsole.debug(`${HOOK_NAME}|on:message:`, conversation.getName(), message);\n\t\t\t\t}\n\t\t\t\tsetMessages((l_messages) => [...l_messages, message]);\n\t\t\t};\n\t\t\tconversation.on('message', onMessage);\n\n\t\t\treturn () => {\n\t\t\t\tconversation.removeListener('message', onMessage);\n\t\t\t\tsetMessages(new Array<ConversationMessage>());\n\t\t\t};\n\t\t}\n\t}, [conversation]);\n\n\tconst sendMessage = useCallback(\n\t\t(msgContent: string, sender: Contact) => {\n\t\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\t\tconversation\n\t\t\t\t\t?.sendMessage(msgContent)\n\t\t\t\t\t.then((uuid: number) => {\n\t\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\t\t\tconsole.info(\n\t\t\t\t\t\t\t\t`${HOOK_NAME}|sentMessage`,\n\t\t\t\t\t\t\t\tconversation.getName(),\n\t\t\t\t\t\t\t\tuuid,\n\t\t\t\t\t\t\t\tmsgContent\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsetMessages((l_messages) => [\n\t\t\t\t\t\t\t...l_messages,\n\t\t\t\t\t\t\t{ content: msgContent, sender: sender, time: new Date() },\n\t\t\t\t\t\t]);\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t})\n\t\t\t\t\t.catch((error: any) => {\n\t\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\t\t\t\tconsole.warn(`${HOOK_NAME}|sendMessage error`, error);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treject(error);\n\t\t\t\t\t});\n\t\t\t});\n\t\t},\n\t\t[conversation]\n\t);\n\n\treturn {\n\t\tmessages,\n\t\tsendMessage,\n\t};\n}\n","import { Contact, Conversation } from '@apirtc/apirtc';\nimport { useEffect, useState } from 'react';\n\nconst HOOK_NAME = 'useConversationModeration';\nexport default function useConversationModeration(\n\tconversation: Conversation | undefined,\n\tonEjected?: (contact: Contact) => void,\n\tonEjectedSelf?: () => void\n) {\n\tconst [candidates, setCandidates] = useState<Set<Contact>>(new Set<Contact>());\n\n\tuseEffect(() => {\n\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\tconsole.debug(`${HOOK_NAME}|useEffect conversation`, conversation);\n\t\t}\n\n\t\tif (conversation) {\n\t\t\tconst on_contactJoinedWaitingRoom = (contact: Contact) => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\tconsole.info(`${HOOK_NAME}|on:contactJoinedWaitingRoom`, contact);\n\t\t\t\t}\n\t\t\t\t// A candidate joined the waiting room.\n\t\t\t\tsetCandidates((prev) => new Set(prev.add(contact)));\n\t\t\t};\n\t\t\tconst on_contactLeftWaitingRoom = (contact: Contact) => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\tconsole.info(`${HOOK_NAME}|on:contactLeftWaitingRoom`, contact);\n\t\t\t\t}\n\t\t\t\t// A candidate left the waiting room.\n\t\t\t\tsetCandidates((prev) => {\n\t\t\t\t\tprev.delete(contact);\n\t\t\t\t\treturn new Set(prev);\n\t\t\t\t});\n\t\t\t};\n\t\t\t// TODO make apirtc.d.ts update to replace 'any'\n\t\t\tconst on_participantEjected = (data: any) => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\tconsole.info(`${HOOK_NAME}|on:participantEjected`, data);\n\t\t\t\t}\n\t\t\t\tif (data.self === true) {\n\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\t\tconsole.info(`${HOOK_NAME}|Self participant was ejected`);\n\t\t\t\t\t}\n\t\t\t\t\tif (onEjectedSelf) {\n\t\t\t\t\t\tonEjectedSelf();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (onEjected) {\n\t\t\t\t\t\tonEjected(data.contact);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tconversation\n\t\t\t\t.on('contactJoinedWaitingRoom', on_contactJoinedWaitingRoom)\n\t\t\t\t.on('contactLeftWaitingRoom', on_contactLeftWaitingRoom)\n\t\t\t\t.on('participantEjected', on_participantEjected);\n\n\t\t\treturn () => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\tconsole.debug(`${HOOK_NAME}|conversation clear`, conversation);\n\t\t\t\t}\n\t\t\t\t// remove listeners\n\t\t\t\tconversation\n\t\t\t\t\t.removeListener('contactJoinedWaitingRoom', on_contactJoinedWaitingRoom)\n\t\t\t\t\t.removeListener('contactLeftWaitingRoom', on_contactLeftWaitingRoom)\n\t\t\t\t\t.removeListener('participantEjected', on_participantEjected);\n\t\t\t\tsetCandidates(new Set());\n\t\t\t};\n\t\t}\n\t}, [conversation, onEjected, onEjectedSelf]);\n\n\treturn {\n\t\tcandidates,\n\t};\n}\n","import { Conversation, PublishOptions, Stream, StreamInfo } from '@apirtc/apirtc';\nimport { useCallback, useEffect, useRef, useState } from 'react';\n\n// TODO?: add pagination ?\n// interface Options {\n// streamsSubscribePageSize: number\n// }\n\nfunction notEmpty<T>(value: T | null | undefined): value is T {\n\treturn value !== null && value !== undefined;\n}\n\nconst EMPTY: any[] = [];\n\nconst HOOK_NAME = 'useConversationStreams';\nexport default function useConversationStreams(\n\tconversation: Conversation | undefined,\n\t/** fully managed list of Stream(s) to publish, with associated publish options */\n\tstreamsToPublish: Array<\n\t\t{ stream: Stream; options?: PublishOptions } | undefined | null\n\t> = EMPTY,\n\t// TODO: streamIdsToSubscribeTo subscribe to all streams if undefined (default),\n\t// or subscribe only to the streamIds in the list. Subscribe to none if list is empty.\n\t// Note : the consumer will need to subscribe first to know the ids at least once,\n\t// => but this is not good as it would not know if those ids are no more published.. so we need to also output\n\t// the list of streams info if we go that way...\n\t// streamIdsToSubscribeTo?: Array<string>,\n\terrorCallback?: (error: any) => void\n) {\n\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\tconsole.debug(\n\t\t\t`${HOOK_NAME}|hook render|${conversation?.getName()}`,\n\t\t\tstreamsToPublish.map((obj) => obj?.options)\n\t\t);\n\t}\n\n\t// A cache to handle publication differences\n\tconst publishedStreamsCache = useRef<\n\t\tArray<{ stream: Stream; options?: PublishOptions } | undefined | null>\n\t>([]);\n\n\tconst [publishedStreams, setPublishedStreams] = useState<Array<Stream>>(new Array<Stream>());\n\tconst [subscribedStreams, setSubscribedStreams] = useState<Array<Stream>>(new Array<Stream>());\n\n\tconst publish: (localStream: Stream, options?: PublishOptions) => Promise<Stream> = useCallback(\n\t\t(localStream: Stream, options?: PublishOptions) => {\n\t\t\treturn new Promise<Stream>((resolve, reject) => {\n\t\t\t\tif (conversation) {\n\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\t\tconsole.debug(\n\t\t\t\t\t\t\t`${HOOK_NAME}|publish|${conversation.getName()}`,\n\t\t\t\t\t\t\tlocalStream,\n\t\t\t\t\t\t\toptions\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconversation\n\t\t\t\t\t\t.publish(localStream, options)\n\t\t\t\t\t\t.then((stream: Stream) => {\n\t\t\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\t\t\t\tconsole.info(\n\t\t\t\t\t\t\t\t\t`${HOOK_NAME}|published|${conversation.getName()}`,\n\t\t\t\t\t\t\t\t\tstream\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsetPublishedStreams((l_streams) => [...l_streams, stream]);\n\t\t\t\t\t\t\tresolve(stream);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((error: any) => {\n\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\t[conversation]\n\t);\n\n\tconst replacePublishedStream = useCallback(\n\t\t(oldStream: Stream, newStream: Stream) => {\n\t\t\treturn new Promise<Stream>((resolve, reject) => {\n\t\t\t\tif (conversation) {\n\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\t\tconsole.debug(\n\t\t\t\t\t\t\t`${HOOK_NAME}|replacePublishedStream|${conversation.getName()}|${oldStream.getId()} -> ${newStream.getId()}`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconversation\n\t\t\t\t\t\t.replacePublishedStream(oldStream, newStream)\n\t\t\t\t\t\t.then((stream: Stream) => {\n\t\t\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\t\t\t\tconsole.info(\n\t\t\t\t\t\t\t\t\t`${HOOK_NAME}|stream replaced|${conversation.getName()}`,\n\t\t\t\t\t\t\t\t\toldStream,\n\t\t\t\t\t\t\t\t\tstream\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// replace old stream by new one at same position\n\t\t\t\t\t\t\tsetPublishedStreams((l_streams) => {\n\t\t\t\t\t\t\t\tconst index = l_streams.indexOf(oldStream);\n\t\t\t\t\t\t\t\tif (index >= 0) {\n\t\t\t\t\t\t\t\t\tl_streams.splice(index, 1, stream);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\treturn Array.from(l_streams);\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tresolve(stream);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((error: any) => {\n\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\t[conversation]\n\t);\n\n\tconst unpublish: (localStream: Stream) => void = useCallback(\n\t\t(localStream: Stream) => {\n\t\t\tif (conversation) {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\tconsole.debug(\n\t\t\t\t\t\t`${HOOK_NAME}|unpublish|${conversation.getName()}`,\n\t\t\t\t\t\tlocalStream.getId(),\n\t\t\t\t\t\tlocalStream\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconversation.unpublish(localStream);\n\t\t\t\tsetPublishedStreams((l_streams) =>\n\t\t\t\t\tl_streams.filter((l_stream) => l_stream !== localStream)\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[conversation]\n\t);\n\n\tconst doHandlePublication = useCallback(() => {\n\t\tconst maxLength = Math.max(publishedStreamsCache.current.length, streamsToPublish.length);\n\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\tconsole.debug(\n\t\t\t\t`${HOOK_NAME}|doHandlePublication`,\n\t\t\t\tstreamsToPublish,\n\t\t\t\tJSON.stringify(publishedStreamsCache.current.map((l_s) => l_s?.stream.getId())),\n\t\t\t\tJSON.stringify(streamsToPublish.map((l_s) => l_s?.stream.getId())),\n\t\t\t\tmaxLength\n\t\t\t);\n\t\t}\n\n\t\t// make a copy of current cache\n\t\tconst currentPublishedStreamsCache = [...publishedStreamsCache.current];\n\n\t\t// Strategy for publishedStreamsCache is to initialize it as it should be\n\t\t// and remove items if publication fails.\n\t\t// Need to do a real copy of options :\n\t\tconst newPublishedStreamsCache = streamsToPublish.map((elt) => {\n\t\t\tif (elt && elt.options) {\n\t\t\t\treturn { stream: elt.stream, options: { ...elt.options } };\n\t\t\t} else {\n\t\t\t\treturn elt;\n\t\t\t}\n\t\t});\n\t\t// Replace cache\n\t\tpublishedStreamsCache.current.length = 0;\n\t\tpublishedStreamsCache.current.push(...newPublishedStreamsCache);\n\n\t\t// Prepare a set for Streams to publish, for further optimized check\n\t\tconst streamsToPublishSet = new Set(\n\t\t\tstreamsToPublish.filter(notEmpty).map((item) => item.stream)\n\t\t);\n\n\t\tconst doPublish = (index: number, obj: { stream: Stream; options?: PublishOptions }) => {\n\t\t\tpublish(obj.stream, obj.options).catch((error: Error) => {\n\t\t\t\t// Note that publishedStreamsCache is updated asynchronously here (catch)\n\t\t\t\t// Hence why publishedStreamsCache must always be the same array instance\n\t\t\t\tpublishedStreamsCache.current.splice(index, 1, null);\n\t\t\t\tif (errorCallback) {\n\t\t\t\t\terrorCallback(error);\n\t\t\t\t} else if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\t\tconsole.warn(`${HOOK_NAME}|publish|error`, error);\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\t// Loop on arrays index to publish new streams, or replace if necessary\n\t\tfor (let i = 0; i < maxLength; i++) {\n\t\t\tconst previous = currentPublishedStreamsCache[i];\n\t\t\tconst next = streamsToPublish[i];\n\n\t\t\tif (previous && next) {\n\t\t\t\tconst doUnpublishPublish = () => {\n\t\t\t\t\tunpublish(previous.stream);\n\t\t\t\t\tdoPublish(i, next);\n\t\t\t\t};\n\n\t\t\t\tif (previous.stream === next.stream) {\n\t\t\t\t\t// Streams are the same, only replace if options are different\n\t\t\t\t\tif (JSON.stringify(previous.options) !== JSON.stringify(next.options)) {\n\t\t\t\t\t\t// replacePublishStream does not allow to change PublishOptions, so we need to\n\t\t\t\t\t\t// unpublish and republish\n\t\t\t\t\t\tdoUnpublishPublish();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// If position in both new and cached list are defined but are different:\n\t\t\t\t\t// replace if and only if stream to unpublish shall not be published (at other position)\n\t\t\t\t\tif (streamsToPublishSet.has(previous.stream)) {\n\t\t\t\t\t\t// previous shall be published\n\t\t\t\t\t\t// Previous shall actually be published (at another position), so don't do anything about it\n\t\t\t\t\t\t// But then we still have to publish new stream (if not already published)\n\t\t\t\t\t\tif (conversation && !conversation.isPublishedStream(next.stream)) {\n\t\t\t\t\t\t\tdoPublish(i, next);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (conversation && !conversation.isPublishedStream(next.stream)) {\n\t\t\t\t\t\t\t// replacePublishStream does not allow to change PublishOptions, so we need to\n\t\t\t\t\t\t\t// unpublish and republish if options also change\n\t\t\t\t\t\t\tif (JSON.stringify(previous.options) === JSON.stringify(next.options)) {\n\t\t\t\t\t\t\t\treplacePublishedStream(previous.stream, next.stream)\n\t\t\t\t\t\t\t\t\t// eslint-disable-next-line no-loop-func\n\t\t\t\t\t\t\t\t\t.catch((error: Error) => {\n\t\t\t\t\t\t\t\t\t\t// Note that publishedStreamsCache is updated asynchronously here (catch)\n\t\t\t\t\t\t\t\t\t\t// Hence why publishedStreamsCache must always be the same array instance\n\t\t\t\t\t\t\t\t\t\tpublishedStreamsCache.current.splice(i, 1, null);\n\t\t\t\t\t\t\t\t\t\tif (errorCallback) {\n\t\t\t\t\t\t\t\t\t\t\terrorCallback(error);\n\t\t\t\t\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\t\t\t\t\tglobalThis.apirtcReactLibLogLevel.isWarnEnabled\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\t\t\t\t\t`${HOOK_NAME}|replacePublishedStream|error`,\n\t\t\t\t\t\t\t\t\t\t\t\terror\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdoUnpublishPublish();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// new stream is already published\n\t\t\t\t\t\t\t// So we shall not replace another stream by it, but we need to unpublish the previous\n\t\t\t\t\t\t\tunpublish(previous.stream);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (previous && !next) {\n\t\t\t\t// If position in new list is now undefined(or null) while it was in cache:\n\t\t\t\t// unpublish if and only if stream to unpublish shall not be published (at other position)\n\t\t\t\tif (!streamsToPublishSet.has(previous.stream)) {\n\t\t\t\t\tunpublish(previous.stream);\n\t\t\t\t}\n\t\t\t} else if (!previous && next) {\n\t\t\t\t// If position in new list is valid : publish it whatever the position in cache.\n\t\t\t\t// Depending on the case the stream might be already published, or it might be not\n\t\t\t\t// (can happen if the cache was set while Conversation was not joined yet).\n\t\t\t\t// Note that we could try to publish without checking isPublishedStream, the call would\n\t\t\t\t// reject with a console error but this would not affect the behavior.\n\t\t\t\tif (conversation && !conversation.isPublishedStream(next.stream)) {\n\t\t\t\t\tdoPublish(i, next);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}, [\n\t\tconversation,\n\t\t//streamsToPublish, change is captured by JSON.stringify below\n\t\t// JSON.stringify(streamsToPublish.map(l_s => `${l_s?.stream.getId()}-${JSON.stringify(l_s?.options)}`)),\n\t\tstreamsToPublish,\n\t\t//publishedStreamsCache, // no need to put in dependency array as the instance shall never change\n\t\tpublish,\n\t\tunpublish,\n\t\treplacePublishedStream,\n\t\terrorCallback,\n\t]);\n\n\tconst unpublishAll = useCallback(() => {\n\t\tif (conversation) {\n\t\t\t// Clear output arrays with new array so that parent gets notified of a change.\n\t\t\tsetPublishedStreams((l_streams) => {\n\t\t\t\t// unpublish all published streams\n\t\t\t\tl_streams.forEach((stream) => {\n\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\t\tconsole.debug(`${HOOK_NAME}|unpublish|${conversation.getName()}`, stream);\n\t\t\t\t\t}\n\t\t\t\t\tconversation.unpublish(stream);\n\t\t\t\t});\n\t\t\t\treturn [];\n\t\t\t});\n\t\t}\n\t\t// Clear cache\n\t\tpublishedStreamsCache.current.length = 0;\n\t}, [conversation]);\n\n\tconst unsubscribeAll = useCallback(() => {\n\t\tif (conversation) {\n\t\t\tsetSubscribedStreams((l_streams) => {\n\t\t\t\t// make sure to unsubscribe to subscribed streams\n\t\t\t\tl_streams.forEach((stream) => {\n\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\t\tconsole.debug(\n\t\t\t\t\t\t\t`${HOOK_NAME}|unsubscribeToStream|${conversation.getName()}`,\n\t\t\t\t\t\t\tstream\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconversation.unsubscribeToStream(stream.getId());\n\t\t\t\t});\n\t\t\t\treturn [];\n\t\t\t});\n\t\t}\n\t}, [conversation]);\n\n\tconst unpublishAndUnsubscribeAll = useCallback(() => {\n\t\tunpublishAll();\n\t\tunsubscribeAll();\n\t}, [unpublishAll, unsubscribeAll]);\n\n\t// --------------------------------------------------------------------------\n\t// useEffect(s) - Order is important\n\t//\n\tuseEffect(() => {\n\t\tif (conversation) {\n\t\t\t// make sure publishedStreamsCache is reinitialized empty\n\t\t\tpublishedStreamsCache.current.length = 0;\n\n\t\t\tconst on_streamAdded = (stream: Stream) => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\tconsole.info(`${HOOK_NAME}|on_streamAdded|${conversation.getName()}`, stream);\n\t\t\t\t}\n\t\t\t\tsetSubscribedStreams((l_streams) => [...l_streams, stream]);\n\t\t\t};\n\t\t\tconst on_streamRemoved = (stream: Stream) => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\tconsole.info(`${HOOK_NAME}|on_streamRemoved|${conversation.getName()}`, stream);\n\t\t\t\t}\n\t\t\t\tsetSubscribedStreams((l_streams) =>\n\t\t\t\t\tl_streams.filter((l_stream) => l_stream !== stream)\n\t\t\t\t);\n\t\t\t};\n\t\t\tconst on_streamListChanged = (streamInfo: StreamInfo) => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\tconsole.debug(\n\t\t\t\t\t\t`${HOOK_NAME}|on_streamListChanged|${conversation.getName()}`,\n\t\t\t\t\t\tstreamInfo\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst streamId = String(streamInfo.streamId);\n\t\t\t\tif (streamInfo.isRemote === true) {\n\t\t\t\t\tif (streamInfo.listEventType === 'added') {\n\t\t\t\t\t\t// a remote stream was published\n\t\t\t\t\t\tconversation.subscribeToStream(streamId);\n\t\t\t\t\t} else if (streamInfo.listEventType === 'removed') {\n\t\t\t\t\t\t// a remote stream is not published anymore\n\t\t\t\t\t\tconversation.unsubscribeToStream(streamId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t\t// Subscribe to incoming streams\n\t\t\tconversation.on('streamAdded', on_streamAdded);\n\t\t\tconversation.on('streamRemoved', on_streamRemoved);\n\t\t\tconversation.on('streamListChanged', on_streamListChanged);\n\n\t\t\treturn () => {\n\t\t\t\t// remove listeners\n\t\t\t\tconversation.removeListener('streamListChanged', on_streamListChanged);\n\t\t\t\tconversation.removeListener('streamRemoved', on_streamRemoved);\n\t\t\t\tconversation.removeListener('streamAdded', on_streamAdded);\n\n\t\t\t\tunpublishAndUnsubscribeAll();\n\t\t\t};\n\t\t}\n\t}, [conversation, unpublishAndUnsubscribeAll]);\n\n\tuseEffect(() => {\n\t\tif (conversation) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\tconsole.debug(\n\t\t\t\t\t`${HOOK_NAME}|useEffect doHandlePublication|${conversation.getName()}`,\n\t\t\t\t\tstreamsToPublish\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst on_joined = () => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\tconsole.info(`${HOOK_NAME}|on_joined|${conversation.getName()}`);\n\t\t\t\t}\n\t\t\t\tdoHandlePublication();\n\t\t\t};\n\t\t\tconst on_left = () => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\tconsole.info(`${HOOK_NAME}|on_left|${conversation.getName()}`);\n\t\t\t\t}\n\t\t\t\t// Forcing unpublish will allow to republish if joining again\n\t\t\t\tunpublishAndUnsubscribeAll();\n\t\t\t};\n\n\t\t\tconversation.on('joined', on_joined);\n\t\t\tconversation.on('left', on_left);\n\n\t\t\tif (conversation.isJoined()) {\n\t\t\t\tdoHandlePublication();\n\t\t\t}\n\n\t\t\treturn () => {\n\t\t\t\tconversation.removeListener('joined', on_joined);\n\t\t\t\tconversation.removeListener('left', on_left);\n\t\t\t};\n\t\t}\n\t}, [conversation, streamsToPublish, doHandlePublication, unpublishAndUnsubscribeAll]);\n\n\treturn {\n\t\tpublishedStreams,\n\t\tsubscribedStreams,\n\t\tpublish,\n\t\tunpublish,\n\t\treplacePublishedStream,\n\t\tunpublishAll,\n\t\tunsubscribeAll,\n\t};\n}\n","import { Contact, Session } from '@apirtc/apirtc';\nimport { useEffect, useRef, useState } from 'react';\n\n/**\n * Subscribe to groups and returns contactsByGroup (of theses groups only) when updated.\n * If input groups list is updated, this hooks works diff with the previous set in order\n * to make as little as possible unsubscribe/subscribe calls.\n */\n\nconst HOOK_NAME = 'usePresence';\nexport default function usePresence(session: Session | undefined, groups: Array<string>) {\n\tconst m_groupsCache = useRef<Set<string>>(new Set());\n\tconst m_contactsByGroup = useRef<Map<string, Set<Contact>>>(new Map());\n\n\tconst [contactsByGroup, setContactsByGroup] = useState<Map<string, Set<Contact>>>(new Map());\n\n\tuseEffect(() => {\n\t\tif (session) {\n\t\t\tconst l_groupsCache = m_groupsCache.current;\n\t\t\tconst l_contactsByGroup = m_contactsByGroup.current;\n\t\t\treturn () => {\n\t\t\t\tl_groupsCache.clear();\n\t\t\t\tl_contactsByGroup.clear();\n\t\t\t\tsetContactsByGroup(new Map());\n\t\t\t};\n\t\t}\n\t}, [session]);\n\n\tconst getOrCreateGroupSet = (group: string) => {\n\t\tconst o_set = m_contactsByGroup.current.get(group) ?? new Set();\n\t\tif (!m_contactsByGroup.current.has(group)) {\n\t\t\tm_contactsByGroup.current.set(group, o_set);\n\t\t}\n\t\treturn o_set;\n\t};\n\n\tuseEffect(() => {\n\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\tconsole.debug(`${HOOK_NAME}|useEffect session, groups`, groups);\n\t\t}\n\t\tif (session) {\n\t\t\tconst l_session = session;\n\t\t\tconst l_groupsSet = new Set(groups);\n\n\t\t\t// Diff update subscription to groups\n\t\t\t//\n\t\t\tl_groupsSet.forEach((group) => {\n\t\t\t\tif (!m_groupsCache.current.has(group)) {\n\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\t\tconsole.info(`${HOOK_NAME}|subscribeToGroup`, group);\n\t\t\t\t\t}\n\t\t\t\t\tm_groupsCache.current.add(group);\n\t\t\t\t\tl_session.subscribeToGroup(group);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tlet needsRefresh = false;\n\t\t\tm_groupsCache.current.forEach((group) => {\n\t\t\t\tif (!l_groupsSet.has(group)) {\n\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\t\tconsole.info(`${HOOK_NAME}|unsubscribeToGroup`, group);\n\t\t\t\t\t}\n\t\t\t\t\tl_session.unsubscribeToGroup(group);\n\t\t\t\t\tm_groupsCache.current.delete(group);\n\t\t\t\t\tm_contactsByGroup.current.delete(group);\n\t\t\t\t\tneedsRefresh = true;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (needsRefresh) {\n\t\t\t\t// contactsByGroup is exposed, so change the Map object to let client code detect a change.\n\t\t\t\tsetContactsByGroup(new Map(m_contactsByGroup.current));\n\t\t\t}\n\n\t\t\tif (groups.length > 0) {\n\t\t\t\tconst onContactListUpdate = (updatedContacts: any) => {\n\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\t\tconsole.debug(`${HOOK_NAME}|contactListUpdate`, updatedContacts);\n\t\t\t\t\t}\n\n\t\t\t\t\tlet needsRefresh = false;\n\n\t\t\t\t\t// Maintain Map of Contacts per Group\n\t\t\t\t\t//\n\t\t\t\t\tfor (const group of Object.keys(updatedContacts.joinedGroup)) {\n\t\t\t\t\t\tif (l_groupsSet.has(group)) {\n\t\t\t\t\t\t\tconst l_set = getOrCreateGroupSet(group);\n\t\t\t\t\t\t\tfor (const contact of updatedContacts.joinedGroup[group]) {\n\t\t\t\t\t\t\t\tl_set.add(contact);\n\t\t\t\t\t\t\t\tneedsRefresh = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (const group of Object.keys(updatedContacts.leftGroup)) {\n\t\t\t\t\t\tif (l_groupsSet.has(group)) {\n\t\t\t\t\t\t\tconst l_set = getOrCreateGroupSet(group);\n\t\t\t\t\t\t\tfor (const contact of updatedContacts.leftGroup[group]) {\n\t\t\t\t\t\t\t\tl_set.delete(contact);\n\t\t\t\t\t\t\t\tneedsRefresh = true;\n\n\t\t\t\t\t\t\t\t// if set is empty, no need to keep the group as key in the map\n\t\t\t\t\t\t\t\tif (l_set.size === 0) {\n\t\t\t\t\t\t\t\t\tm_contactsByGroup.current.delete(group);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// For data updates, trigger a refresh if and only if contact is part of managed groups\n\t\t\t\t\tfor (const contact of updatedContacts.userDataChanged as Contact[]) {\n\t\t\t\t\t\tfor (const l_contacts of m_contactsByGroup.current.values()) {\n\t\t\t\t\t\t\tif (l_contacts.has(contact)) {\n\t\t\t\t\t\t\t\tneedsRefresh = true;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (needsRefresh) {\n\t\t\t\t\t\t// contactsByGroup is exposed, so change the Map object to let client code detect a change.\n\t\t\t\t\t\tsetContactsByGroup(new Map(m_contactsByGroup.current));\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tl_session.on('contactListUpdate', onContactListUpdate);\n\t\t\t\treturn () => {\n\t\t\t\t\tl_session.removeListener('contactListUpdate', onContactListUpdate);\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}, [session, groups]);\n\n\treturn {\n\t\tcontactsByGroup,\n\t};\n}\n","import { RegisterInformation, Session, UserAgent } from '@apirtc/apirtc';\nimport { useEffect, useState } from 'react';\n\nexport type LoginPassword = {\n\tusername: string;\n\tpassword: string;\n};\nfunction isInstanceOfLoginPassword(object: any): object is LoginPassword {\n\tif (typeof object !== 'object') return false;\n\treturn 'username' in object;\n}\n\nexport type ApiKey = { apiKey: string };\nfunction isInstanceOfApiKey(object: any): object is ApiKey {\n\tif (typeof object !== 'object') return false;\n\treturn 'apiKey' in object;\n}\n\nexport type Token = { token: string };\nfunction isInstanceOfToken(object: any): object is Token {\n\tif (typeof object !== 'object') return false;\n\treturn 'token' in object;\n}\n\nexport type Credentials = LoginPassword | ApiKey | Token;\n\nconst HOOK_NAME = 'useSession';\nexport default function useSession(\n\tcredentials?: Credentials,\n\toptions?: RegisterInformation,\n\terrorCallback?: (error: any) => void\n) {\n\tconst [session, setSession] = useState<Session | undefined>();\n\tconst [connecting, setConnecting] = useState<boolean>(false);\n\n\tuseEffect(() => {\n\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\tconsole.debug(`${HOOK_NAME}|useEffect credentials, options`, credentials, options);\n\t\t}\n\t\tif (credentials) {\n\t\t\t// To fix errors like \"Warning: Can't perform a React state update on an unmounted component\"\n\t\t\t// https://stackoverflow.com/questions/53949393/cant-perform-a-react-state-update-on-an-unmounted-component\n\t\t\t//let isMounted = true;\n\t\t\tconnect(credentials, options).catch((error: any) => {\n\t\t\t\tconsole.error(`${HOOK_NAME}|connection failed`, error);\n\t\t\t\tsetSession(undefined);\n\n\t\t\t\tif (errorCallback) {\n\t\t\t\t\terrorCallback(error);\n\t\t\t\t} else if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\t\tconsole.warn(`${HOOK_NAME}|connect|error`, error);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\tsetSession(undefined);\n\t\t\t\t// Even though connecting is managed in connect(),\n\t\t\t\t// mark connecting to false when credentials are changed\n\t\t\t\t// as this shall be way to connect elsewhere or connect to\n\t\t\t\t// with other credentials. Note that to be perfect we should\n\t\t\t\t// cancel the potentially running connect : Is that possible with ApiRTC ?\n\t\t\t\tsetConnecting(false);\n\t\t\t};\n\t\t}\n\t}, [credentials, options, errorCallback]); // JSON.stringify(credentials), JSON.stringify(options)\n\n\tuseEffect(() => {\n\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\tconsole.debug(`${HOOK_NAME}|useEffect session`, session);\n\t\t}\n\t\tif (session) {\n\t\t\tconst l_session = session;\n\t\t\treturn () => {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\tconsole.debug(`${HOOK_NAME}|useEffect session cleanup`, l_session);\n\t\t\t\t}\n\t\t\t\tl_session\n\t\t\t\t\t.disconnect()\n\t\t\t\t\t.then(() => {\n\t\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\t\t\tconsole.info(`${HOOK_NAME}|disconnected`, l_session);\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t\t.catch((error: any) => {\n\t\t\t\t\t\tconsole.error(`${HOOK_NAME}|disconnect`, error);\n\t\t\t\t\t});\n\t\t\t};\n\t\t}\n\t}, [session]);\n\n\tconst connect = (credentials: Credentials | undefined, options?: RegisterInformation) => {\n\t\treturn new Promise<void>((resolve, reject) => {\n\t\t\tconst registerInformation: RegisterInformation = options\n\t\t\t\t? options\n\t\t\t\t: {\n\t\t\t\t\t\tcloudUrl: 'https://cloud.apirtc.com',\n\t\t\t\t\t};\n\n\t\t\tlet l_userAgent;\n\n\t\t\tif (isInstanceOfLoginPassword(credentials)) {\n\t\t\t\tregisterInformation.password = credentials.password;\n\t\t\t\tl_userAgent = new UserAgent({\n\t\t\t\t\turi: `apirtc:${credentials.username}`,\n\t\t\t\t});\n\t\t\t} else if (isInstanceOfApiKey(credentials)) {\n\t\t\t\tl_userAgent = new UserAgent({\n\t\t\t\t\turi: `apiKey:${credentials.apiKey}`,\n\t\t\t\t});\n\t\t\t} else if (isInstanceOfToken(credentials)) {\n\t\t\t\tl_userAgent = new UserAgent({\n\t\t\t\t\turi: `token:${credentials.token}`,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\treject('credentials not recognized');\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsetConnecting(true);\n\t\t\tl_userAgent\n\t\t\t\t.register(registerInformation)\n\t\t\t\t.then((l_session) => {\n\t\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isInfoEnabled) {\n\t\t\t\t\t\tconsole.info(`${HOOK_NAME}|connected`, l_session);\n\t\t\t\t\t}\n\t\t\t\t\tsetSession(l_session);\n\t\t\t\t\tresolve();\n\t\t\t\t})\n\t\t\t\t.catch((error: any) => {\n\t\t\t\t\treject(error);\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tsetConnecting(false);\n\t\t\t\t});\n\t\t});\n\t};\n\n\t// const disconnect = useCallback(() => {\n\t// return new Promise<void>((resolve, reject) => {\n\t// if (session) {\n\t// const l_session = session;\n\t// l_session.disconnect().then(() => {\n\t// console.log(`${HOOK_NAME}|disconnected`, l_session)\n\t// setSession(undefined)\n\t// resolve()\n\t// }).catch((error: any) => {\n\t// console.error(`${HOOK_NAME}|disconnect`, error)\n\t// reject(error)\n\t// })\n\t// } else {\n\t// resolve()\n\t// }\n\t// })\n\t// }, [session])\n\n\tconst disconnect = () => {\n\t\tsetSession(undefined);\n\t};\n\n\treturn {\n\t\t//userAgent: userAgent, // can get it from session\n\t\tsession: session,\n\t\tconnecting,\n\t\tconnect,\n\t\tdisconnect,\n\t};\n}\n","import { AudioProcessorType, Stream } from '@apirtc/apirtc';\nimport { useEffect, useRef, useState } from 'react';\n\nconst HOOK_NAME = 'useStreamApplyAudioProcessor';\n/**\n * This hook takes stream passed as parameter, and\n * returns either this stream or a stream with audio processor applied.\n * This is controlled by the audioProcessorType input attribute.\n * By default the output stream is the input stream.\n * The hook fully manages the output stream (applies 'none' if input stream is set to undefined).\n * The hook never releases the input stream.\n *\n * @param stream\n * @param audioProcessorType\n * @returns new stream with Audio processor applied (or original stream if no processor applied)\n */\nexport default function useStreamApplyAudioProcessor(\n\tstream: Stream | undefined,\n\tprocessorType: AudioProcessorType,\n\terrorCallback?: (error: any) => void\n) {\n\t//\n\tconst appliedProcessor = useRef<AudioProcessorType>();\n\tconst [outStream, setOutStream] = useState(stream);\n\tconst [applying, setApplying] = useState(false);\n\tconst [error, setError] = useState<any>();\n\n\tuseEffect(() => {\n\t\t// Reset appliedProcessor.current when stream changes\n\t\treturn () => {\n\t\t\tappliedProcessor.current = undefined;\n\t\t};\n\t}, [stream]);\n\n\tuseEffect(() => {\n\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\tconsole.debug(`${HOOK_NAME}|useEffect`, stream, processorType);\n\t\t}\n\t\tsetOutStream(stream);\n\t\tconst applied = appliedProcessor.current || stream?.audioAppliedFilter || 'none';\n\t\tif (stream && processorType !== applied) {\n\t\t\tsetApplying(true);\n\t\t\tstream\n\t\t\t\t.applyAudioProcessor(processorType)\n\t\t\t\t.then((l_stream) => {\n\t\t\t\t\tsetOutStream(l_stream);\n\t\t\t\t\tappliedProcessor.current = processorType;\n\t\t\t\t\tsetError(undefined);\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tsetError(error);\n\t\t\t\t\tif (errorCallback) {\n\t\t\t\t\t\terrorCallback(error);\n\t\t\t\t\t} else if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\t\t\tconsole.warn(`${HOOK_NAME}|useEffect`, stream, processorType, error);\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tsetApplying(false);\n\t\t\t\t});\n\t\t}\n\t\treturn () => {\n\t\t\tsetError(undefined);\n\t\t};\n\t}, [stream, processorType, errorCallback]);\n\n\treturn {\n\t\tstream: outStream,\n\t\tapplying,\n\t\tapplied: appliedProcessor.current || (stream as any)?.audioAppliedFilter || 'none',\n\t\terror,\n\t};\n}\n","import { Stream, VideoProcessorOptions, VideoProcessorType } from '@apirtc/apirtc';\nimport { useEffect, useRef, useState } from 'react';\n\nconst HOOK_NAME = 'useStreamApplyVideoProcessor';\n/**\n * This hook takes stream passed as parameter, and\n * returns either this stream or a stream with video processor applied.\n * This is controlled by the videoProcessorType input attribute.\n * By default the output stream is the input stream.\n * The hook fully manages the output stream (applies 'none' if input stream is set to undefined).\n * The hook never releases the input stream.\n *\n * @param stream\n * @param processorType\n * @param {VideoProcessorOptions} options\n * @returns new stream with video processor applied (or original stream if no processor applied)\n */\nexport default function useStreamApplyVideoProcessor(\n\tstream: Stream | undefined,\n\tprocessorType: VideoProcessorType,\n\toptions?: VideoProcessorOptions,\n\terrorCallback?: (error: any) => void\n) {\n\t//\n\tconst appliedProcessor = useRef<VideoProcessorType>();\n\tconst [outStream, setOutStream] = useState(stream);\n\tconst [applying, setApplying] = useState(false);\n\tconst [error, setError] = useState<any>();\n\n\tuseEffect(() => {\n\t\t// Reset appliedProcessor.current when stream changes\n\t\treturn () => {\n\t\t\tappliedProcessor.current = undefined;\n\t\t};\n\t}, [stream]);\n\n\tuseEffect(() => {\n\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\tconsole.debug(`${HOOK_NAME}|useEffect`, stream, processorType, options);\n\t\t}\n\t\tsetOutStream(stream);\n\t\tconst applied = appliedProcessor.current || stream?.videoAppliedFilter || 'none';\n\t\tif (stream && processorType !== applied) {\n\t\t\tsetApplying(true);\n\t\t\tstream\n\t\t\t\t.applyVideoProcessor(processorType, options)\n\t\t\t\t.then((l_stream) => {\n\t\t\t\t\tsetOutStream(l_stream);\n\t\t\t\t\tappliedProcessor.current = processorType;\n\t\t\t\t\tsetError(undefined);\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tsetError(error);\n\t\t\t\t\tif (errorCallback) {\n\t\t\t\t\t\terrorCallback(error);\n\t\t\t\t\t} else if (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`${HOOK_NAME}|useEffect`,\n\t\t\t\t\t\t\tstream,\n\t\t\t\t\t\t\tprocessorType,\n\t\t\t\t\t\t\toptions,\n\t\t\t\t\t\t\terror\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tsetApplying(false);\n\t\t\t\t});\n\t\t}\n\t\treturn () => {\n\t\t\tsetError(undefined);\n\t\t};\n\t}, [stream, processorType, options, errorCallback]);\n\n\treturn {\n\t\tstream: outStream,\n\t\tapplying,\n\t\tapplied: appliedProcessor.current || (stream as any)?.videoAppliedFilter || 'none',\n\t\terror,\n\t};\n}\n","import { MediaDevice, MediaDeviceList, Session, UserAgent } from '@apirtc/apirtc';\n\nimport { useEffect, useMemo, useState } from 'react';\n\nconst HOOK_NAME = 'useUserMediaDevices';\n\nconst getMediaDeviceFromLocalStorage = (key: string) => {\n\ttry {\n\t\tconst value = localStorage.getItem(key);\n\t\tconst obj = value ? JSON.parse(value) : null;\n\t\treturn obj ? new MediaDevice(obj.id, obj.type, obj.label) : undefined;\n\t} catch (error) {\n\t\tconsole.warn(`${HOOK_NAME}|getMediaDeviceFromLocalStorage`, error);\n\t\treturn undefined;\n\t}\n};\n\nconst setLocalStorage = (key: string, value: string) => {\n\ttry {\n\t\tlocalStorage.setItem(key, value);\n\t} catch (error: any) {}\n};\n\n/**\n * useUserMediaDevices hook\n * @param session - a valid ApiRTC Session\n * @param storageKeyPrefix - do not set or set to undefined to NOT use local storage to get nor store devices ids.\n * @returns userMediaDevices,\n * selectedAudioIn, selectedAudioInId, setSelectedAudioIn,\n * selectedAudioOut, selectedAudioInId, setSelectedAudioOut,\n * selectedVideoIn, selectedVideoInId, setSelectedVideoIn\n */\nexport default function useUserMediaDevices(\n\tsession: Session | undefined,\n\tstorageKeyPrefix?: string\n) {\n\tconst AUDIO_INPUT_KEY = useMemo(\n\t\t() => (storageKeyPrefix ? `${storageKeyPrefix}.audioIn` : undefined),\n\t\t[storageKeyPrefix]\n\t);\n\tconst AUDIO_OUTPUT_KEY = useMemo(\n\t\t() => (storageKeyPrefix ? `${storageKeyPrefix}.audioOut` : undefined),\n\t\t[storageKeyPrefix]\n\t);\n\tconst VIDEO_INPUT_KEY = useMemo(\n\t\t() => (storageKeyPrefix ? `${storageKeyPrefix}.videoIn` : undefined),\n\t\t[storageKeyPrefix]\n\t);\n\n\t// Use lazy initialized useState to avoid calling getMediaDeviceFromLocalStorage (which is IO operation) at every render\n\tconst [selectedAudioIn, setSelectedAudioIn] = useState<MediaDevice | undefined>(() =>\n\t\tAUDIO_INPUT_KEY ? getMediaDeviceFromLocalStorage(AUDIO_INPUT_KEY) : undefined\n\t);\n\tconst [selectedAudioOut, setSelectedAudioOut] = useState<MediaDevice | undefined>(() =>\n\t\tAUDIO_OUTPUT_KEY ? getMediaDeviceFromLocalStorage(AUDIO_OUTPUT_KEY) : undefined\n\t);\n\tconst [selectedVideoIn, setSelectedVideoIn] = useState<MediaDevice | undefined>(() =>\n\t\tVIDEO_INPUT_KEY ? getMediaDeviceFromLocalStorage(VIDEO_INPUT_KEY) : undefined\n\t);\n\n\tconst [userMediaDevices, setUserMediaDevices] = useState<MediaDeviceList>({\n\t\taudioinput: selectedAudioIn\n\t\t\t? {\n\t\t\t\t\t[selectedAudioIn.getId()]: selectedAudioIn,\n\t\t\t\t}\n\t\t\t: {},\n\t\taudiooutput: selectedAudioOut\n\t\t\t? {\n\t\t\t\t\t[selectedAudioOut.getId()]: selectedAudioOut,\n\t\t\t\t}\n\t\t\t: {},\n\t\tvideoinput: selectedVideoIn\n\t\t\t? {\n\t\t\t\t\t[selectedVideoIn.getId()]: selectedVideoIn,\n\t\t\t\t}\n\t\t\t: {},\n\t});\n\n\tuseEffect(() => {\n\t\tif (session) {\n\t\t\tconst userAgent: UserAgent = session.getUserAgent();\n\n\t\t\tconst on_mediaDeviceChanged = () => {\n\t\t\t\tconst mediaDevices: MediaDeviceList = userAgent.getUserMediaDevices();\n\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\t\tconsole.debug(`${HOOK_NAME}|mediaDeviceChanged`, mediaDevices);\n\t\t\t\t}\n\n\t\t\t\tsetUserMediaDevices(mediaDevices);\n\t\t\t\tsetSelectedAudioIn((prev) =>\n\t\t\t\t\tprev ? mediaDevices.audioinput[prev.getId()] : undefined\n\t\t\t\t);\n\t\t\t\tsetSelectedAudioOut((prev) =>\n\t\t\t\t\tprev ? mediaDevices.audiooutput[prev.getId()] : undefined\n\t\t\t\t);\n\t\t\t\tsetSelectedVideoIn((prev) =>\n\t\t\t\t\tprev ? mediaDevices.videoinput[prev.getId()] : undefined\n\t\t\t\t);\n\t\t\t};\n\t\t\tuserAgent.on('mediaDeviceChanged', on_mediaDeviceChanged);\n\n\t\t\treturn () => {\n\t\t\t\tuserAgent.removeListener('mediaDeviceChanged', on_mediaDeviceChanged);\n\t\t\t};\n\t\t}\n\t}, [session]);\n\n\tuseEffect(() => {\n\t\tif (selectedAudioIn && AUDIO_INPUT_KEY) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\tconsole.debug(`${HOOK_NAME}|Storing audioIn`, selectedAudioIn);\n\t\t\t}\n\t\t\tsetLocalStorage(\n\t\t\t\tAUDIO_INPUT_KEY,\n\t\t\t\tJSON.stringify({\n\t\t\t\t\tid: selectedAudioIn.getId(),\n\t\t\t\t\ttype: selectedAudioIn.getType(),\n\t\t\t\t\tlabel: selectedAudioIn.getLabel(),\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\t}, [AUDIO_INPUT_KEY, selectedAudioIn]);\n\n\tuseEffect(() => {\n\t\tif (selectedAudioOut && AUDIO_OUTPUT_KEY) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\tconsole.debug(`${HOOK_NAME}|Storing audioOut`, selectedAudioOut);\n\t\t\t}\n\t\t\tsetLocalStorage(\n\t\t\t\tAUDIO_OUTPUT_KEY,\n\t\t\t\tJSON.stringify({\n\t\t\t\t\tid: selectedAudioOut.getId(),\n\t\t\t\t\ttype: selectedAudioOut.getType(),\n\t\t\t\t\tlabel: selectedAudioOut.getLabel(),\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\t}, [AUDIO_OUTPUT_KEY, selectedAudioOut]);\n\n\tuseEffect(() => {\n\t\tif (selectedVideoIn && VIDEO_INPUT_KEY) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\tconsole.debug(`${HOOK_NAME}|Storing videoIn`, selectedVideoIn);\n\t\t\t}\n\t\t\tsetLocalStorage(\n\t\t\t\tVIDEO_INPUT_KEY,\n\t\t\t\tJSON.stringify({\n\t\t\t\t\tid: selectedVideoIn.getId(),\n\t\t\t\t\ttype: selectedVideoIn.getType(),\n\t\t\t\t\tlabel: selectedVideoIn.getLabel(),\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\t}, [VIDEO_INPUT_KEY, selectedVideoIn]);\n\n\treturn {\n\t\tuserMediaDevices,\n\t\tselectedAudioIn,\n\t\tselectedAudioInId: selectedAudioIn?.getId(),\n\t\tsetSelectedAudioIn,\n\t\tselectedAudioOut,\n\t\tselectedAudioOutId: selectedAudioOut?.getId(),\n\t\tsetSelectedAudioOut,\n\t\tselectedVideoIn,\n\t\tselectedVideoInId: selectedVideoIn?.getId(),\n\t\tsetSelectedVideoIn,\n\t};\n}\n","/******************************************************************************\nCopyright (c) Microsoft Corporation.\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\nPERFORMANCE OF THIS SOFTWARE.\n***************************************************************************** */\n/* global Reflect, Promise, SuppressedError, Symbol */\n\nvar extendStatics = function(d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\n return extendStatics(d, b);\n};\n\nexport function __extends(d, b) {\n if (typeof b !== \"function\" && b !== null)\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n}\n\nexport var __assign = function() {\n __assign = Object.assign || function __assign(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n }\n return __assign.apply(this, arguments);\n}\n\nexport function __rest(s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\n t[p[i]] = s[p[i]];\n }\n return t;\n}\n\nexport function __decorate(decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n}\n\nexport function __param(paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n}\n\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\n var _, done = false;\n for (var i = decorators.length - 1; i >= 0; i--) {\n var context = {};\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\n if (kind === \"accessor\") {\n if (result === void 0) continue;\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\n if (_ = accept(result.get)) descriptor.get = _;\n if (_ = accept(result.set)) descriptor.set = _;\n if (_ = accept(result.init)) initializers.unshift(_);\n }\n else if (_ = accept(result)) {\n if (kind === \"field\") initializers.unshift(_);\n else descriptor[key] = _;\n }\n }\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\n done = true;\n};\n\nexport function __runInitializers(thisArg, initializers, value) {\n var useValue = arguments.length > 2;\n for (var i = 0; i < initializers.length; i++) {\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\n }\n return useValue ? value : void 0;\n};\n\nexport function __propKey(x) {\n return typeof x === \"symbol\" ? x : \"\".concat(x);\n};\n\nexport function __setFunctionName(f, name, prefix) {\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\n};\n\nexport function __metadata(metadataKey, metadataValue) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\n}\n\nexport function __awaiter(thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n}\n\nexport function __generator(thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [op[0] & 2, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n}\n\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\n\nexport function __exportStar(m, o) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\n}\n\nexport function __values(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n}\n\nexport function __read(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n}\n\n/** @deprecated */\nexport function __spread() {\n for (var ar = [], i = 0; i < arguments.length; i++)\n ar = ar.concat(__read(arguments[i]));\n return ar;\n}\n\n/** @deprecated */\nexport function __spreadArrays() {\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\n r[k] = a[j];\n return r;\n}\n\nexport function __spreadArray(to, from, pack) {\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\n if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n}\n\nexport function __await(v) {\n return this instanceof __await ? (this.v = v, this) : new __await(v);\n}\n\nexport function __asyncGenerator(thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n}\n\nexport function __asyncDelegator(o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\n}\n\nexport function __asyncValues(o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator], i;\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\n}\n\nexport function __makeTemplateObject(cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n};\n\nvar __setModuleDefault = Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n};\n\nexport function __importStar(mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n}\n\nexport function __importDefault(mod) {\n return (mod && mod.__esModule) ? mod : { default: mod };\n}\n\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n}\n\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n}\n\nexport function __classPrivateFieldIn(state, receiver) {\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\n}\n\nexport function __addDisposableResource(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n env.stack.push({ value: value, dispose: dispose, async: async });\n }\n else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n}\n\nvar _SuppressedError = typeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\n var e = new Error(message);\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\n};\n\nexport function __disposeResources(env) {\n function fail(e) {\n env.error = env.hasError ? new _SuppressedError(e, env.error, \"An error was suppressed during disposal.\") : e;\n env.hasError = true;\n }\n function next() {\n while (env.stack.length) {\n var rec = env.stack.pop();\n try {\n var result = rec.dispose && rec.dispose.call(rec.value);\n if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });\n }\n catch (e) {\n fail(e);\n }\n }\n if (env.hasError) throw env.error;\n }\n return next();\n}\n\nexport default {\n __extends,\n __assign,\n __rest,\n __decorate,\n __param,\n __metadata,\n __awaiter,\n __generator,\n __createBinding,\n __exportStar,\n __values,\n __read,\n __spread,\n __spreadArrays,\n __spreadArray,\n __await,\n __asyncGenerator,\n __asyncDelegator,\n __asyncValues,\n __makeTemplateObject,\n __importStar,\n __importDefault,\n __classPrivateFieldGet,\n __classPrivateFieldSet,\n __classPrivateFieldIn,\n __addDisposableResource,\n __disposeResources,\n};\n","import { useEffect, useState, useCallback } from 'react';\nimport type { Conversation } from '@apirtc/apirtc';\n\ntype TranscriptService = InstanceType<(typeof import('@apizee/ia'))['TranscriptService']>;\ntype Transcript = InstanceType<(typeof import('@apizee/ia'))['Transcript']>;\ntype EventTranscript = InstanceType<(typeof import('@apizee/ia'))['EventTranscript']>;\n\nconst HOOK_NAME = 'useTranscriptService';\n/**\n * A hook to start/stop and get messages from a transcriptService\n * @param conversation an ApiRTC conversation\n * @param autoStart boolean to automatically start transcription\n */\nexport default function useTranscriptService(\n\tconversation: Conversation | undefined,\n\tautoStart: boolean | undefined\n) {\n\tconst [transcriptService, setTranscriptService] = useState<TranscriptService | null>(null);\n\tconst [hasStarted, setHasStarted] = useState<boolean>(false);\n\n\tconst [transcripts, setTranscripts] = useState<Transcript[]>([]);\n\n\t// Instanciation\n\tuseEffect(() => {\n\t\tif (transcriptService) return;\n\n\t\tlet mounted = true;\n\n\t\t// Dynamic import @apizee/ia\n\t\timport('@apizee/ia').then(({ TranscriptService }) => {\n\t\t\tif (!mounted) {\n\t\t\t\tif (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\t\tconsole.warn(`${HOOK_NAME}|instanciation aborted - component unmounted`);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst service = new TranscriptService();\n\t\t\tsetTranscriptService(service);\n\t\t});\n\n\t\treturn () => {\n\t\t\tmounted = false;\n\t\t};\n\t}, [transcriptService]);\n\n\t// EventTranscript listener\n\tuseEffect(() => {\n\t\tif (!transcriptService) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`${HOOK_NAME}|useEffect transcript listener skipped - transcriptService not ready`\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tconst onTranscript = (event: EventTranscript) => {\n\t\t\tconst { transcript } = event;\n\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\tconsole.debug(`${HOOK_NAME}|onTranscript`, transcript);\n\t\t\t}\n\n\t\t\tsetTranscripts((prev) => [...prev, transcript]);\n\t\t};\n\n\t\ttranscriptService.addEventListener('transcript', onTranscript);\n\n\t\treturn () => {\n\t\t\ttranscriptService.removeEventListener('transcript', onTranscript);\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\t\tconsole.debug(`${HOOK_NAME}|useEffect cleanup`, 'onTranscript');\n\t\t\t}\n\t\t};\n\t}, [transcriptService]);\n\n\t// Start\n\tconst startTranscriptService = useCallback(async () => {\n\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\tconsole.debug(\n\t\t\t\t`${HOOK_NAME}|startTranscriptService transcriptService, hasStarted`,\n\t\t\t\ttranscriptService,\n\t\t\t\thasStarted\n\t\t\t);\n\t\t}\n\n\t\tif (!transcriptService) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`${HOOK_NAME}|startTranscriptService aborted - transcriptService not initialized`\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (hasStarted) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\tconsole.warn(`${HOOK_NAME}|startTranscriptService aborted - already started`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!conversation) {\n\t\t\tconsole.warn(`${HOOK_NAME}|startTranscriptService aborted - conversation not provided`);\n\t\t\treturn;\n\t\t}\n\n\t\tawait transcriptService\n\t\t\t.start(conversation)\n\t\t\t.then(() => {\n\t\t\t\tconsole.log(`${HOOK_NAME}|startTranscriptService - started`);\n\t\t\t\tsetHasStarted(true);\n\t\t\t})\n\t\t\t.catch((error: string) => {\n\t\t\t\tconsole.error(`${HOOK_NAME}|startTranscriptService - failed`, error);\n\t\t\t});\n\t}, [transcriptService, hasStarted, conversation]);\n\n\t// Stop\n\tconst stopTranscriptService = useCallback(async () => {\n\t\tif (!transcriptService) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`${HOOK_NAME}|stopTranscriptService aborted - transcriptService not initialized`\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!conversation) {\n\t\t\tconsole.warn(`${HOOK_NAME}|stopTranscriptService aborted - conversation not provided`);\n\t\t\treturn;\n\t\t}\n\n\t\tawait transcriptService\n\t\t\t.stop(conversation)\n\t\t\t.then(() => {\n\t\t\t\tconsole.log(`${HOOK_NAME}|stopTranscriptService - stopped`);\n\t\t\t\tsetHasStarted(false);\n\t\t\t})\n\t\t\t.catch((error: string) => {\n\t\t\t\tconsole.error(`${HOOK_NAME}|stopTranscriptService - failed`, error);\n\t\t\t});\n\t}, [transcriptService, conversation]);\n\n\t// Auto-start\n\tuseEffect(() => {\n\t\tif (globalThis.apirtcReactLibLogLevel.isDebugEnabled) {\n\t\t\tconsole.debug(\n\t\t\t\t`${HOOK_NAME}|useEffect autoStartTranscriptService autoStart, conversation`,\n\t\t\t\tautoStart,\n\t\t\t\tconversation\n\t\t\t);\n\t\t}\n\n\t\tif (!autoStart) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\tconsole.warn(`${HOOK_NAME}|useEffect autoStart skipped - autoStart=false`);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!conversation) {\n\t\t\tif (globalThis.apirtcReactLibLogLevel.isWarnEnabled) {\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`${HOOK_NAME}|useEffect - auto start transcription not possible if conversation not provided`\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tstartTranscriptService();\n\t}, [autoStart, conversation, startTranscriptService]);\n\n\treturn {\n\t\ttranscriptService,\n\t\thasStarted,\n\t\ttranscripts,\n\t\tstartTranscriptService,\n\t\tstopTranscriptService,\n\t};\n}\n","export * from './components';\nexport * from './hooks';\n\nexport type LogLevel = {\n\tlevel: 'debug' | 'info' | 'warn' | 'error';\n\tisDebugEnabled: boolean;\n\tisInfoEnabled: boolean;\n\tisWarnEnabled: boolean;\n};\n\nconst INFO: LogLevel = {\n\tlevel: 'info',\n\tisDebugEnabled: false,\n\tisInfoEnabled: true,\n\tisWarnEnabled: true,\n};\n\ndeclare global {\n\tvar apirtcReactLibLogLevel: LogLevel;\n\tvar setApirtcReactLibLogLevel: (logLevelText: 'debug' | 'info' | 'warn' | 'error') => void;\n}\n\n// a default value MUST be set in case application using the library does not override it\nglobalThis.apirtcReactLibLogLevel = INFO;\n\nexport function setLogLevel(logLevelText: 'debug' | 'info' | 'warn' | 'error') {\n\tswitch (logLevelText) {\n\t\tcase 'debug':\n\t\t\tglobalThis.apirtcReactLibLogLevel = {\n\t\t\t\tlevel: 'debug',\n\t\t\t\tisDebugEnabled: true,\n\t\t\t\tisInfoEnabled: true,\n\t\t\t\tisWarnEnabled: true,\n\t\t\t};\n\t\t\tbreak;\n\t\tcase 'info':\n\t\t\tglobalThis.apirtcReactLibLogLevel = INFO;\n\t\t\tbreak;\n\t\tcase 'warn':\n\t\t\tglobalThis.apirtcReactLibLogLevel = {\n\t\t\t\tlevel: 'warn',\n\t\t\t\tisDebugEnabled: false,\n\t\t\t\tisInfoEnabled: false,\n\t\t\t\tisWarnEnabled: true,\n\t\t\t};\n\t\t\tbreak;\n\t\tcase 'error':\n\t\t\tglobalThis.apirtcReactLibLogLevel = {\n\t\t\t\tlevel: 'error',\n\t\t\t\tisDebugEnabled: false,\n\t\t\t\tisInfoEnabled: false,\n\t\t\t\tisWarnEnabled: false,\n\t\t\t};\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t// in case null is passed as input, default to 'info'\n\t\t\tglobalThis.apirtcReactLibLogLevel = INFO;\n\t}\n\treturn globalThis.apirtcReactLibLogLevel;\n}\n\nglobalThis.setApirtcReactLibLogLevel = setLogLevel;\n","import React, { useEffect, useRef } from 'react';\n\nimport { Stream } from '@apirtc/apirtc';\n\nexport type VideoStreamProps = {\n\tstream: Stream;\n\tautoPlay?: boolean;\n\tmuted?: boolean;\n};\nexport default function VideoStream(props: VideoStreamProps) {\n\tconst { autoPlay = true } = props;\n\n\tconst videoRef = useRef<HTMLVideoElement>(null);\n\n\tuseEffect(() => {\n\t\tconst ref = videoRef.current;\n\t\tif (ref && props.stream) {\n\t\t\tprops.stream.attachToElement(ref);\n\t\t\treturn () => {\n\t\t\t\tref.src = '';\n\t\t\t};\n\t\t}\n\t}, [props.stream]);\n\t// No need to put videoRef.current because useRef does not trigger rerender anyways\n\n\treturn (\n\t\t<video\n\t\t\tid={props.stream.getId()}\n\t\t\tstyle={{ maxWidth: '100%' }}\n\t\t\tref={videoRef}\n\t\t\tautoPlay={autoPlay}\n\t\t\tmuted={props.muted}></video>\n\t);\n}\n"],"names":["EMPTY","HOOK_NAME","notEmpty","value","getMediaDeviceFromLocalStorage","key","localStorage","getItem","obj","JSON","parse","MediaDevice","id","type","label","undefined","error","console","warn","setLocalStorage","setItem","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","step","next","e","rejected","result","done","then","apply","SuppressedError","INFO","level","isDebugEnabled","isInfoEnabled","isWarnEnabled","setLogLevel","logLevelText","globalThis","apirtcReactLibLogLevel","setApirtcReactLibLogLevel","props","autoPlay","videoRef","useRef","useEffect","ref","current","stream","attachToElement","src","React","createElement","getId","style","maxWidth","muted","session","options","errorCallback","setStream","useState","grabbing","setGrabbing","setError","debug","userAgent","getUserAgent","createStream","localStream","info","catch","finally","l_stream","release","name","join","joinOptions","conversation","setConversation","joined","setJoined","joining","setJoining","o_join","useCallback","isJoined","o_leave","leave","l_conversation","getOrCreateConversation","destroy","l_join","contactJoined","contactLeft","contacts","setContacts","onContactJoined","contact","getName","l_contacts","on","onContactLeft","filter","l_contact","removeListener","Array","messages","setMessages","onMessage","message","l_messages","sendMessage","msgContent","sender","uuid","content","time","Date","onEjected","onEjectedSelf","candidates","setCandidates","Set","on_contactJoinedWaitingRoom","prev","add","on_contactLeftWaitingRoom","delete","on_participantEjected","data","self","streamsToPublish","map","publishedStreamsCache","publishedStreams","setPublishedStreams","subscribedStreams","setSubscribedStreams","publish","l_streams","replacePublishedStream","oldStream","newStream","index","indexOf","splice","from","unpublish","doHandlePublication","maxLength","Math","max","length","stringify","l_s","currentPublishedStreamsCache","newPublishedStreamsCache","elt","Object","assign","push","streamsToPublishSet","item","doPublish","i","previous","doUnpublishPublish","has","isPublishedStream","unpublishAll","forEach","unsubscribeAll","unsubscribeToStream","unpublishAndUnsubscribeAll","on_streamAdded","on_streamRemoved","on_streamListChanged","streamInfo","streamId","String","isRemote","listEventType","subscribeToStream","on_joined","on_left","groups","m_groupsCache","m_contactsByGroup","Map","contactsByGroup","setContactsByGroup","l_groupsCache","l_contactsByGroup","clear","getOrCreateGroupSet","group","o_set","_a","get","set","l_session","l_groupsSet","subscribeToGroup","needsRefresh","unsubscribeToGroup","onContactListUpdate","updatedContacts","keys","joinedGroup","l_set","leftGroup","size","userDataChanged","values","credentials","setSession","connecting","setConnecting","connect","disconnect","registerInformation","cloudUrl","l_userAgent","object","password","UserAgent","uri","username","isInstanceOfApiKey","apiKey","isInstanceOfToken","token","register","processorType","appliedProcessor","outStream","setOutStream","applying","setApplying","applied","audioAppliedFilter","applyAudioProcessor","videoAppliedFilter","applyVideoProcessor","autoStart","transcriptService","setTranscriptService","hasStarted","setHasStarted","transcripts","setTranscripts","mounted","import","TranscriptService","service","onTranscript","event","transcript","addEventListener","removeEventListener","startTranscriptService","this","start","log","stopTranscriptService","stop","storageKeyPrefix","AUDIO_INPUT_KEY","useMemo","AUDIO_OUTPUT_KEY","VIDEO_INPUT_KEY","selectedAudioIn","setSelectedAudioIn","selectedAudioOut","setSelectedAudioOut","selectedVideoIn","setSelectedVideoIn","userMediaDevices","setUserMediaDevices","audioinput","audiooutput","videoinput","on_mediaDeviceChanged","mediaDevices","getUserMediaDevices","getType","getLabel","selectedAudioInId","selectedAudioOutId","selectedVideoInId"],"mappings":"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"}
|