@formant/data-sdk 1.13.1 → 1.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/data-sdk.cjs.js.map +1 -1
- package/dist/data-sdk.es.js.map +1 -1
- package/dist/types/data-sdk/src/main.d.ts +3 -0
- package/dist/types/data-sdk/src/stores/AuthenticationResult.d.ts +1 -1
- package/dist/types/data-sdk/src/stores/AuthenticationStore.d.ts +4 -1
- package/dist/types/data-sdk/src/stores/IAuthentication.d.ts +6 -0
- package/dist/types/data-sdk/src/stores/IAuthenticationStore.d.ts +7 -16
- package/dist/types/data-sdk/src/stores/IConfirmForgotPasswordRequest.d.ts +5 -0
- package/dist/types/data-sdk/src/stores/IRespondToNewPasswordRequiredChallengeRequest.d.ts +5 -0
- package/package.json +1 -1
package/dist/data-sdk.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-sdk.cjs.js","sources":["../src/config/whichFormantApiUrl.ts","../src/config/index.ts","../src/stores/AuthenticationErrors.ts","../src/stores/AuthenticationStore.ts","../src/utils/getCurrentModuleContext.ts","../src/message-bus/senders/sendAppMessage.ts","../src/message-bus/senders/refreshAuthToken.ts","../src/message-bus/listeners/addAccessTokenRefreshListener.ts","../src/Authentication.ts","../src/api/getModuleConfiguration.ts","../src/message-bus/senders/disableAnalyticsBottomBar.ts","../src/message-bus/senders/goToDevice.ts","../src/message-bus/senders/goToTime.ts","../src/message-bus/senders/requestModuleData.ts","../src/message-bus/senders/sendChannelData.ts","../src/message-bus/senders/setModuleDateTimeRange.ts","../src/message-bus/senders/setupModuleMenus.ts","../src/message-bus/senders/showMessage.ts","../src/message-bus/listeners/addChannelDataListener.ts","../src/message-bus/listeners/addMenuListener.ts","../src/message-bus/listeners/addModuleConfigurationListener.ts","../src/message-bus/listeners/addModuleDataListener.ts","../src/message-bus/listeners/addOverviewDeviceListener.ts","../../common/duration.ts","../src/cache/filterDataByType.ts","../src/cache/filterDataByTime.ts","../src/cache/StoreCache.ts","../src/api/queryTelemetry.ts","../src/cache/queryStore.ts","../src/message-bus/listeners/addStreamLIstener.ts","../src/message-bus/bidirectional/getDate.ts","../src/message-bus/bidirectional/prompt.ts","../src/App.ts","../../common/defined.ts","../src/model/SessionType.ts","../src/utils/RtcClientPool.ts","../src/AppRtcClientPools.ts","../src/CaptureStream.ts","../../common/delay.ts","../src/utils/isRtcPeer.ts","../src/DataChannel.ts","../src/Manipulator.ts","../src/RequestDataChannel.ts","../src/devices/BaseDevice.ts","../src/utils/serializeHash.ts","../src/api/getViews.ts","../src/api/createShareLink.ts","../src/utils/aggregateFunctionUtils.ts","../src/api/queryEvents.ts","../src/api/eventsCounter.ts","../src/api/getAnnotationCount.ts","../src/api/getAnnotationCountByIntervals.ts","../src/api/getTelemetry.ts","../src/api/getRealtimeSessions.ts","../src/api/getPeers.ts","../src/api/createDevice.ts","../src/api/patchDevice.ts","../src/api/getDevicesData.ts","../src/api/queryDevicesData.ts","../src/api/disableDevice.ts","../src/devices/Device.ts","../src/devices/PeerDevice.ts","../src/api/addDeviceToFleet.ts","../src/api/aggregateTelemetry.ts","../src/api/deleteFleet.ts","../src/api/getAnalyticsStreams.ts","../src/api/getAnalyticsModules.ts","../src/api/getAnalyticsRows.ts","../src/api/queryDevices.ts","../src/api/getCurrentGroup.ts","../src/api/getDevice.ts","../src/api/getDevices.ts","../src/api/getEvent.ts","../src/api/getFileUrl.ts","../src/api/getFleet.ts","../src/api/getFleetDevices.ts","../src/api/getInterventions.ts","../src/api/getLatestTelemetry.ts","../src/api/getOnlineDevices.ts","../src/api/getRealtimeDevices.ts","../src/api/getStreams.ts","../src/api/getTaskReportRows.ts","../src/api/getTaskreportTables.ts","../src/api/listFleets.ts","../src/api/patchFleet.ts","../src/api/patchStreams.ts","../src/api/patchView.ts","../src/api/queryAnalytics.ts","../src/api/createFleet.ts","../src/api/getAllEventTriggerGroup.ts","../src/api/getEventTriggerGroup.ts","../src/api/patchEventTriggerGroup.ts","../src/Fleet.ts","../src/KeyValue.ts","../src/utils/stringToArrayBuffer.ts","../../common/browser.ts","../src/AudioPlayer.ts","../src/Account.ts","../src/Role.ts","../src/User.ts","../src/model/accessLevels.ts","../src/model/AccessLevel.ts","../src/model/aggregateLevels.ts","../src/model/annotationTypes.ts","../src/model/eventTypes.ts","../src/model/healthStatuses.ts","../src/model/interventionTypes.ts","../src/model/severities.ts","../src/model/videoMimeTypes.ts","../src/utils/timeout.ts","../src/init.ts"],"sourcesContent":["const DEFAULT_FORMANT_API_URL = \"https://api.formant.io\";\n\ninterface IHasString {\n get(key: string): string | null;\n has(key: string): boolean;\n}\n\nexport function whichFormantApiUrl(global: any, urlParams: IHasString) {\n // url params may not be available when using react native\n try {\n if (urlParams.get(\"formant_stage\")) {\n return \"https://api-stage.formant.io\";\n }\n\n if (urlParams.get(\"formant_dev\")) {\n return \"https://api-dev.formant.io\";\n }\n\n if (urlParams.get(\"formant_local\")) {\n return \"https://api.formant.local\";\n }\n\n if (urlParams.get(\"formant_url\")) {\n const customUrl = urlParams.get(\"formant_url\");\n if (customUrl !== null) {\n try {\n return new URL(customUrl).origin;\n } catch {\n console.warn(\n `Ignoring malformed \\`formant_url\\` url parameter: ${customUrl}`\n );\n }\n }\n }\n } catch (_) {}\n\n if (\n typeof global !== \"undefined\" &&\n \"FORMANT_API_URL\" in global &&\n typeof global.FORMANT_API_URL === \"string\"\n ) {\n return global.FORMANT_API_URL;\n }\n\n return DEFAULT_FORMANT_API_URL;\n}\n","import { whichFormantApiUrl } from \"./whichFormantApiUrl\";\n\nexport const FORMANT_API_URL = whichFormantApiUrl(\n typeof window !== \"undefined\" ? window : globalThis,\n new URLSearchParams(\n typeof window !== \"undefined\" && window.location\n ? window.location.search\n : undefined\n )\n);\n","import { IChallenge } from \"../model/IChallenge\";\n\nexport class LoginFailureError extends Error {\n readonly reason: string;\n\n constructor(reason: string) {\n super(\"login failed\");\n this.reason = reason;\n this.name = \"LoginFailureError\";\n Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain\n }\n}\n\nexport class LoginChallengedError extends Error {\n readonly challenge: IChallenge;\n\n constructor(challenge: IChallenge) {\n super(\"login challenged\");\n this.challenge = challenge;\n this.name = \"LoginChallengedError\";\n Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain\n }\n}\n","import { decode } from \"base-64\";\n\nimport {\n IAuthentication,\n IAuthenticationStore,\n IConfirmForgotPasswordRequest,\n IRespondToNewPasswordRequiredChallengeRequest,\n} from \"./IAuthenticationStore\";\nimport { AuthenticationResult } from \"./AuthenticationResult\";\nimport {\n LoginFailureError,\n LoginChallengedError,\n} from \"./AuthenticationErrors\";\n\nimport { IUser } from \"../model/IUser\";\n\ninterface IAuthenticationStoreOptions {\n apiUrl: string;\n\n refreshAuthToken: () => void;\n addAccessTokenRefreshListener: (\n callback: (token: string) => void\n ) => () => void;\n}\n\nexport class AuthenticationStore implements IAuthenticationStore {\n private _refreshToken: string | undefined;\n private _isShareToken: boolean = false;\n private _currentOrganization: string | undefined;\n private _currentUser: IUser | undefined;\n private _defaultDeviceId: string | undefined;\n private _token: string | undefined;\n private _waitingForAuth: Set<(result: boolean) => void> = new Set();\n private _refreshTimer: ReturnType<typeof setTimeout> | undefined;\n\n private readonly _apiUrl: string;\n private readonly _refreshAuthToken: () => void;\n private readonly _addAccessTokenRefreshListener: (\n callback: (token: string) => void\n ) => () => void;\n\n constructor({\n apiUrl,\n refreshAuthToken,\n addAccessTokenRefreshListener,\n }: IAuthenticationStoreOptions) {\n this._apiUrl = apiUrl;\n this._refreshAuthToken = refreshAuthToken;\n this._addAccessTokenRefreshListener = addAccessTokenRefreshListener;\n }\n\n get token(): string | undefined {\n return this._token;\n }\n\n get currentUser(): IUser | undefined {\n return this._currentUser;\n }\n\n get currentOrganization(): string | undefined {\n return this._currentOrganization;\n }\n\n get defaultDeviceId(): string | undefined {\n return this._defaultDeviceId;\n }\n\n /**\n * @deprecated Do not use directly. This will be removed in future versions of the API\n */\n get refreshToken(): string | undefined {\n return this._refreshToken;\n }\n\n /**\n * @deprecated Do not use directly. This will be removed in future versions of the API\n */\n get isShareToken(): boolean {\n return this._isShareToken;\n }\n\n login(email: string, password: string): Promise<IAuthentication>;\n login(\n email: string,\n password: string,\n options: { advanced: true }\n ): Promise<AuthenticationResult>;\n async login(\n email: string,\n password: string,\n options: { advanced?: boolean } = {}\n ): Promise<IAuthentication | AuthenticationResult> {\n const { advanced = false } = options;\n\n try {\n const result = await fetch(`${this._apiUrl}/v1/admin/auth/login`, {\n method: \"POST\",\n body: JSON.stringify({ email, password }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n const auth = await result.json();\n if (result.status !== 200) {\n throw new LoginFailureError(auth.message);\n }\n\n if (\"challenge\" in auth) {\n throw new LoginChallengedError(auth.challenge);\n }\n\n const { authentication } = auth;\n await this.loginWithToken(\n authentication.accessToken as string,\n authentication.refreshToken as string\n );\n\n return !advanced\n ? authentication\n : {\n result: \"success\",\n authentication,\n };\n } catch (err: unknown) {\n if (!advanced) {\n console.error(\"login() failed\", { err });\n }\n\n this._waitingForAuth.forEach((_) => _(false));\n this._waitingForAuth.clear();\n\n if (!advanced) {\n throw err;\n }\n\n if (err instanceof LoginChallengedError) {\n return {\n result: \"challenged\",\n challenge: err.challenge,\n };\n }\n\n return {\n result: \"failure\",\n reason:\n err instanceof LoginFailureError\n ? err.reason\n : err instanceof Error\n ? err.message\n : String(err),\n };\n }\n }\n\n async loginWithToken(token: string, refreshToken?: string) {\n const tokenData = JSON.parse(decode(token.split(\".\")[1]));\n try {\n let userId: string | undefined;\n this._isShareToken =\n tokenData[\"formant:claims\"] &&\n tokenData[\"formant:claims\"].type == \"share\";\n\n if (tokenData[\"formant:claims\"]) {\n this._currentOrganization = tokenData[\"formant:claims\"].organizationId;\n }\n if (tokenData[\"custom:organization_id\"]) {\n this._currentOrganization = tokenData[\"custom:organization_id\"];\n }\n\n if (!this._isShareToken) {\n userId = tokenData.sub;\n }\n if (tokenData[\"formant:claims\"] && tokenData[\"formant:claims\"].userId) {\n userId = tokenData[\"formant:claims\"].userId;\n }\n\n if (userId && this._currentUser?.id !== userId) {\n const result = await fetch(`${this._apiUrl}/v1/admin/users/${userId}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + token,\n },\n });\n const data = await result.json();\n if (result.status !== 200) {\n throw new Error(data.message);\n }\n this._currentUser = data;\n }\n this._token = token;\n this._waitingForAuth.forEach((_) => _(true));\n } catch (err: unknown) {\n console.error(\"loginWithToken() failed\", { err });\n this._waitingForAuth.forEach((_) => _(false));\n } finally {\n this._waitingForAuth.clear();\n }\n\n if (refreshToken) {\n this._refreshToken = refreshToken;\n setInterval(async () => {\n if (this._refreshToken) {\n const result = await fetch(`${this._apiUrl}/v1/admin/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n refreshToken: this._refreshToken,\n }),\n });\n const refreshData = await result.json();\n this._token = refreshData.authentication.accessToken;\n }\n }, 1000 * 60 * 60);\n }\n }\n\n isAuthenticated(): boolean {\n return this._token !== undefined;\n }\n\n /**\n * @deprecated use currentUser property instead.\n */\n getCurrentUser(): IUser | undefined {\n return this._currentUser;\n }\n\n async waitTilAuthenticated(): Promise<boolean> {\n if (this.token !== undefined) {\n return true;\n } else {\n return new Promise((resolve) => {\n this._waitingForAuth.add(resolve);\n });\n }\n }\n\n async listenForRefresh() {\n // refresh token every hour\n const hour = 1000 * 60 * 60;\n const askForFreshToken = () => {\n this._refreshTimer = undefined;\n this._refreshAuthToken();\n };\n\n this._addAccessTokenRefreshListener((token: string) => {\n if (this._refreshTimer) {\n // unless I get a fresh token sooner\n clearTimeout(this._refreshTimer);\n }\n this._refreshTimer = setTimeout(askForFreshToken, hour);\n this.loginWithToken(token);\n });\n\n // refresh token every hour\n this._refreshTimer = setTimeout(askForFreshToken, hour);\n }\n\n async forgotPassword(email: string) {\n await fetch(`${this._apiUrl}/v1/admin/auth/forgot-password`, {\n method: \"POST\",\n body: JSON.stringify({ email }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n }\n\n /**\n * @example\n * // Body\n * await this.confirmForgotPassword({\n * email: \"joe@gmail.com\"\n * confirmationCode: \"1\",\n * newPassword: \"NewPassword\"\n * });\n */\n async confirmForgotPassword(request: IConfirmForgotPasswordRequest) {\n const response = await fetch(\n `${this._apiUrl}/v1/admin/auth/confirm-forgot-password`,\n {\n method: \"POST\",\n body: JSON.stringify(request),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n return response.ok;\n }\n\n async respondToNewPasswordRequiredChallenge(\n request: IRespondToNewPasswordRequiredChallengeRequest\n ) {\n const response = await fetch(\n `${this._apiUrl}/v1/admin/auth/respond-to-new-password-required-challenge`,\n {\n method: \"POST\",\n body: JSON.stringify(request),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n if (response.ok) {\n return await response.json();\n }\n\n throw new Error(\"respond-to-new-password-required-challenge failed\");\n }\n\n async loginWithGoogle(token: string) {\n const response = await fetch(`${this._apiUrl}/v1/admin/auth/login-google`, {\n method: \"POST\",\n body: JSON.stringify(token),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n return await response.json();\n }\n\n async refresh(token: string) {\n const result = await fetch(`${this._apiUrl}/v1/admin/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n refreshToken: token,\n }),\n });\n const refreshData = await result.json();\n await this.loginWithToken(refreshData.authentication.accessToken, token);\n }\n}\n","export function getCurrentModuleContext(): string | null {\n if (!(typeof window !== \"undefined\" && window.location)) {\n return null;\n }\n\n const urlParams = new URLSearchParams(window.location.search);\n return urlParams.get(\"module\");\n}\n","import { AppMessage } from \"./AppMessage\";\n\nexport function sendAppMessage(message: AppMessage) {\n if (!(window && window.parent)) {\n throw new Error(\"cannot send message to non-existent parent\");\n }\n window.parent.postMessage(message, \"*\");\n}\n","import { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\nimport { sendAppMessage } from \"./sendAppMessage\";\n\nexport function refreshAuthToken() {\n const moduleName = getCurrentModuleContext();\n if (!moduleName) {\n throw new Error(\"No module context\");\n }\n sendAppMessage({\n type: \"refresh_auth_token\",\n module: moduleName,\n });\n}\n","import { EmbeddedAppMessage } from \"./EmbeddedAppMessage\";\n\nexport function addAccessTokenRefreshListener(\n handler: (token: string) => void\n): () => void {\n function listener(event: MessageEvent<EmbeddedAppMessage>) {\n const msg = event.data;\n if (msg.type === \"auth_token\") {\n handler(msg.token);\n }\n }\n\n window.addEventListener(\"message\", listener);\n return () => {\n window.removeEventListener(\"message\", listener);\n };\n}\n","import { FORMANT_API_URL } from \"./config\";\nimport { IAuthenticationStore } from \"./stores/IAuthenticationStore\";\nimport { AuthenticationStore } from \"./stores/AuthenticationStore\";\nimport { refreshAuthToken } from \"./message-bus/senders/refreshAuthToken\";\nimport { addAccessTokenRefreshListener } from \"./message-bus/listeners/addAccessTokenRefreshListener\";\n\nexport const Authentication: IAuthenticationStore = new AuthenticationStore({\n apiUrl: FORMANT_API_URL,\n refreshAuthToken,\n addAccessTokenRefreshListener,\n});\n","import { FORMANT_API_URL } from \"../config\";\nimport { Authentication } from \"../Authentication\";\n\nexport async function getModuleConfiguration(\n id: string\n): Promise<string | undefined> {\n const response = await fetch(\n `${FORMANT_API_URL}/v1/admin/module-configurations/${id}`,\n {\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const moduleConfiguration = await response.json();\n return moduleConfiguration.configuration;\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\n\nexport function disableAnalyticsBottomBar() {\n sendAppMessage({\n type: \"hide_analytics_date_picker\",\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\n\nexport function goToDevice(deviceId: string) {\n sendAppMessage({\n type: \"go_to_device\",\n deviceId,\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\n\nexport function goToTime(date: Date): void {\n sendAppMessage({\n type: \"go_to_time\",\n time: date.getTime(),\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\nimport { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\n\nexport function requestModuleData() {\n const moduleName = getCurrentModuleContext();\n if (!moduleName) {\n throw new Error(\"No module context\");\n }\n sendAppMessage({\n type: \"request_module_data\",\n module: moduleName,\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\nimport { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\n\nexport function sendChannelData(channel: string, data: any) {\n const moduleName = getCurrentModuleContext();\n if (!moduleName) {\n throw new Error(\"No module context\");\n }\n\n sendAppMessage({\n type: \"send_channel_data\",\n source: moduleName,\n channel,\n data,\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\nimport { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\n\nexport function setModuleDateTimeRange(\n beforeInMilliseconds: number,\n afterInMilliseconds?: number\n) {\n const moduleName = getCurrentModuleContext();\n if (!moduleName) {\n throw new Error(\"No module context\");\n }\n sendAppMessage({\n type: \"set_module_data_time_range\",\n module: moduleName,\n before: beforeInMilliseconds,\n after: afterInMilliseconds || 0,\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\nimport { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\n\nexport function setupModuleMenus(menus: { label: string }[]) {\n const moduleName = getCurrentModuleContext();\n if (!moduleName) {\n throw new Error(\"No module context\");\n }\n sendAppMessage({\n type: \"setup_module_menus\",\n module: moduleName,\n menus,\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\n\nexport function showMessage(message: string) {\n sendAppMessage({ type: \"show_message\", message });\n}\n","import { EmbeddedAppMessage } from \"./EmbeddedAppMessage\";\n\nexport function addChannelDataListener(\n channel: string,\n handler: (e: { source: string; data: any }) => void\n) {\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"channel_data\" && msg.channel === channel) {\n handler({\n source: msg.source,\n data: msg.data,\n });\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","import { EmbeddedAppMessage } from \"./EmbeddedAppMessage\";\n\nexport function addMenuListener(handler: (label: string) => void) {\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"module_menu_item_clicked\") {\n handler(msg.menu);\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","import {\n EmbeddedAppMessage,\n ModuleConfigurationMessage,\n} from \"./EmbeddedAppMessage\";\n\nexport function addModuleConfigurationListener(\n handler: (event: ModuleConfigurationMessage) => void\n) {\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"module_configuration\") {\n handler(msg as ModuleConfigurationMessage);\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","import { sendAppMessage } from \"../senders/sendAppMessage\";\nimport { EmbeddedAppMessage } from \"./EmbeddedAppMessage\";\nimport { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\n\nexport interface ModuleData {\n queryRange: QueryRange;\n time: number;\n streams: { [stream_name: string]: Stream };\n}\n\nexport interface QueryRange {\n start: number;\n end: number;\n}\n\nexport interface Stream {\n data: StreamData[];\n loading: boolean;\n tooMuchData: boolean;\n type: string;\n}\n\nexport interface StreamData {\n points: DataPoint[];\n deviceId: string;\n agentId: string;\n name: string;\n tags: { [key: string]: string };\n type: string;\n}\n\nexport type DataPoint = [number, any];\n\nexport function addModuleDataListener(handler: (data: ModuleData) => void) {\n const moduleName = getCurrentModuleContext();\n if (moduleName) {\n sendAppMessage({ type: \"request_module_data\", module: moduleName });\n }\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"module_data\") {\n handler({\n streams: msg.streams,\n time: msg.time,\n queryRange: msg.queryRange,\n });\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","import { EmbeddedAppMessage, IDevice } from \"./EmbeddedAppMessage\";\nimport { sendAppMessage } from \"../senders/sendAppMessage\";\n\nexport function addOverviewDeviceListener(\n handler: (devices: IDevice[]) => void\n) {\n sendAppMessage({ type: \"request_devices\" });\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"overview_devices\") {\n handler(msg.data);\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","const millisecond = 1;\nconst second = 1000;\nconst minute = 60 * second;\nconst hour = 60 * minute;\nconst day = 24 * hour;\nconst week = 7 * day;\nconst month = 30 * day;\nconst year = 365 * day;\n\nexport const duration = {\n millisecond,\n second,\n minute,\n hour,\n day,\n week,\n month,\n year,\n} as const;\n","import { IStreamData } from \"../model/IStreamData\";\nimport { StreamType } from \"../model/StreamType\";\n\nexport function filterDataByType(\n datas: IStreamData[],\n type: StreamType[]\n): IStreamData[] {\n return datas.filter((_) => type.includes(_.type)) as IStreamData[];\n}\n","import { IStreamData } from \"../model/IStreamData\";\n\nexport function filterDataByTime(\n datas: IStreamData[],\n start: Date,\n end: Date\n): IStreamData[] {\n const startTime = start.getTime();\n const endTime = end.getTime();\n return datas\n .map((data) => ({\n ...data,\n points: data.points.filter(\n ([timestamp]) => timestamp >= startTime && timestamp < endTime\n ),\n }))\n .filter(({ points }) => points.length > 0);\n}\n","import { fork } from \"../../../common/fork\";\nimport { duration } from \"../../../common/duration\";\n\ninterface ICacheEntryMetadata<Value> {\n generating: boolean;\n expiration: Date;\n lastValue?: Value;\n}\n\ntype CacheKey = string;\n\nexport class StoreCache<Key, Value> {\n private entries = new Map<CacheKey, Value>();\n private metadata = new Map<CacheKey, ICacheEntryMetadata<Value>>();\n private capacity!: number;\n private timeout!: number;\n\n constructor({\n capacity,\n timeout,\n }: { capacity?: number; timeout?: number } = {}) {\n this.capacity = capacity || 10000;\n this.timeout = timeout || duration.minute;\n }\n\n public get(key: Key, generator?: () => Promise<Value>): Value | undefined {\n const cacheKey = this.keyToCacheKey(key);\n const entry = this.entries.get(cacheKey);\n const metadata = this.metadata.get(cacheKey);\n\n if (\n (entry === undefined ||\n (metadata && metadata?.expiration.getTime() < Date.now())) &&\n !metadata?.generating &&\n generator\n ) {\n this.generate(key, generator());\n }\n\n if (entry === undefined && metadata && metadata.lastValue !== undefined) {\n return metadata.lastValue;\n }\n\n return entry;\n }\n\n public set(key: Key, value: Value) {\n const cacheKey = this.keyToCacheKey(key);\n this.metadata.set(cacheKey, {\n generating: false,\n expiration: new Date(Date.now() + this.timeout),\n lastValue: value,\n });\n this.entries.set(cacheKey, value);\n\n if (this.metadata.size > this.capacity) {\n this.deleteOldestEntry();\n }\n }\n\n public clear() {\n this.entries.clear();\n [...this.metadata.values()].forEach((value) => (value.generating = false));\n }\n\n public clearKey(key: string): void {\n this.metadata.delete(key);\n this.entries.delete(key);\n }\n\n private keyToCacheKey(key: Key): CacheKey {\n return JSON.stringify(key);\n }\n\n private deleteOldestEntry() {\n if (this.metadata.size < 1) {\n return;\n }\n const [key] = [...this.metadata.entries()].reduce(\n ([oldestKey, oldestEntry], [thisKey, entry]) =>\n entry.expiration.getTime() < oldestEntry.expiration.getTime()\n ? [thisKey, entry]\n : [oldestKey, oldestEntry]\n );\n this.clearKey(key);\n }\n\n private generate(key: Key, promise: Promise<Value>) {\n const cacheKey = this.keyToCacheKey(key);\n const existingMetadata = this.metadata.get(cacheKey) || {};\n this.metadata.set(cacheKey, {\n ...existingMetadata,\n generating: true,\n expiration: new Date(Date.now() + this.timeout),\n });\n setTimeout(() => {\n fork(\n promise.then((value) => {\n const metadata = this.metadata.get(cacheKey);\n const canceled = !metadata?.generating;\n if (!canceled) {\n this.set(key, value);\n }\n })\n );\n }, 0);\n }\n}\n","import { IQuery } from \"../model/IQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IStreamData } from \"../model/IStreamData\";\n\nexport async function queryTelemetry(query: IQuery) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/queries/queries`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n\n return (await data.json()).items as IStreamData[];\n}\n","import { IQuery } from \"../model/IQuery\";\nimport { IStreamData } from \"../model/IStreamData\";\nimport { StreamType } from \"../model/StreamType\";\nimport { IFilter } from \"../model/IFilter\";\nimport {\n addMinutes,\n addSeconds,\n roundToNearestMinutes,\n startOfMinute,\n} from \"date-fns\";\nimport { duration } from \"../../../common/duration\";\nimport { filterDataByType } from \"./filterDataByType\";\nimport { filterDataByTime } from \"./filterDataByTime\";\nimport { StoreCache } from \"./StoreCache\";\nimport { queryTelemetry } from \"../api/queryTelemetry\";\n\nexport class QueryStore {\n private queryStoreCache = new StoreCache<\n IQuery,\n IStreamData[] | \"too much data\"\n >({\n capacity: 10_000,\n timeout: 20 * duration.second,\n });\n\n private liveQueryStoreCache = new StoreCache<\n IQuery,\n IStreamData[] | \"too much data\"\n >({\n capacity: 10_000,\n timeout: 200 * duration.millisecond,\n });\n\n public moduleQuery(\n filter: IFilter,\n name: string[],\n type: StreamType[],\n start: Date,\n end: Date,\n latestOnly: boolean = false\n ): IStreamData[] | \"too much data\" | undefined {\n const q: IFilter = {\n ...filter,\n names: [...name],\n types: [...type],\n };\n const data = this.query(q, start, end, latestOnly);\n if (data === undefined || data === \"too much data\") {\n return data as any;\n }\n return filterDataByType(data, type);\n }\n\n public query(\n filter: IFilter,\n start: Date,\n end: Date,\n latestOnly: boolean = false\n ): IStreamData[] | \"too much data\" | undefined {\n const q: IQuery = {\n ...filter,\n start: startOfMinute(start).toISOString(),\n end: latestOnly\n ? end.toISOString()\n : addMinutes(roundToNearestMinutes(end), 1).toISOString(),\n latestOnly,\n };\n const isLive = end > addSeconds(new Date(), -20);\n\n let data;\n if (isLive) {\n data = this.liveQueryCache(q);\n } else {\n data = this.queryCache(q);\n }\n\n if (!data || data === \"too much data\") {\n return data;\n }\n\n // return early because we might get data from near future that will be filtered out\n if (latestOnly) {\n return data;\n }\n\n return filterDataByTime(data, start, end);\n }\n\n private queryCache(\n query: IQuery\n ): IStreamData[] | \"too much data\" | undefined {\n return this.queryStoreCache.get(query, async () => {\n try {\n return await queryTelemetry(query);\n } catch (error) {\n throw error;\n }\n });\n }\n\n private liveQueryCache(\n query: IQuery\n ): IStreamData[] | \"too much data\" | undefined {\n return this.liveQueryStoreCache.get(query, async () => {\n try {\n return await queryTelemetry(query);\n } catch (error) {\n throw error;\n }\n });\n }\n}\n","import { StreamType } from \"../../model/StreamType\";\nimport { IStreamData } from \"../../model/IStreamData\";\nimport { EmbeddedAppMessage } from \"./EmbeddedAppMessage\";\nimport { QueryStore } from \"../../cache/queryStore\";\n\nconst queryStore = new QueryStore();\n\nexport function addStreamListener(\n streamNames: string[],\n streamTypes: StreamType[],\n handler: (response: IStreamData[] | \"too much data\" | undefined) => void\n): () => void {\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"module_data\") {\n const { start, end } = msg.queryRange;\n handler(\n queryStore.moduleQuery(\n {},\n streamNames,\n streamTypes,\n new Date(start),\n new Date(end),\n false\n )\n );\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","import { sendAppMessage } from \"../senders/sendAppMessage\";\nimport { EmbeddedAppMessage } from \"../listeners/EmbeddedAppMessage\";\n\nexport async function getDate(time?: Date, minTime?: Date, maxTime?: Date) {\n return new Promise((resolve) => {\n sendAppMessage({\n type: \"request_date\",\n minTime,\n maxTime,\n time,\n });\n const handler = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"date_response\") {\n window.removeEventListener(\"message\", handler);\n resolve(msg.data);\n }\n };\n window.addEventListener(\"message\", handler);\n });\n}\n","import { JsonSchema } from \"../../model/JsonSchema\";\nimport { sendAppMessage } from \"../senders/sendAppMessage\";\nimport { EmbeddedAppMessage } from \"../listeners/EmbeddedAppMessage\";\n\nexport async function prompt(\n schema: JsonSchema,\n options?: { okText?: string; cancelText?: string }\n): Promise<any> {\n return new Promise((resolve) => {\n const promptId = Math.random().toString();\n sendAppMessage({\n type: \"prompt\",\n promptId,\n schema,\n okText: options?.okText,\n cancelText: options?.cancelText,\n });\n const handler = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"prompt_response\" && msg.promptId === promptId) {\n resolve(msg.data);\n }\n window.removeEventListener(\"message\", handler);\n };\n window.addEventListener(\"message\", handler);\n });\n}\n","import { getModuleConfiguration } from \"./api/getModuleConfiguration\";\nimport { getCurrentModuleContext } from \"./utils/getCurrentModuleContext\";\nimport { disableAnalyticsBottomBar } from \"./message-bus/senders/disableAnalyticsBottomBar\";\nimport { goToDevice } from \"./message-bus/senders/goToDevice\";\nimport { goToTime } from \"./message-bus/senders/goToTime\";\nimport { refreshAuthToken } from \"./message-bus/senders/refreshAuthToken\";\nimport { requestModuleData } from \"./message-bus/senders/requestModuleData\";\nimport { sendAppMessage } from \"./message-bus/senders/sendAppMessage\";\nimport { sendChannelData } from \"./message-bus/senders/sendChannelData\";\nimport { setModuleDateTimeRange } from \"./message-bus/senders/setModuleDateTimeRange\";\nimport { setupModuleMenus } from \"./message-bus/senders/setupModuleMenus\";\nimport { showMessage } from \"./message-bus/senders/showMessage\";\nimport { EmbeddedAppMessage } from \"./message-bus/listeners/EmbeddedAppMessage\";\nimport { addAccessTokenRefreshListener } from \"./message-bus/listeners/addAccessTokenRefreshListener\";\nimport { addChannelDataListener } from \"./message-bus/listeners/addChannelDataListener\";\nimport { addMenuListener } from \"./message-bus/listeners/addMenuListener\";\nimport { addModuleConfigurationListener } from \"./message-bus/listeners/addModuleConfigurationListener\";\nimport { addModuleDataListener } from \"./message-bus/listeners/addModuleDataListener\";\nimport { addOverviewDeviceListener } from \"./message-bus/listeners/addOverviewDeviceListener\";\nimport { addStreamListener } from \"./message-bus/listeners/addStreamLIstener\";\nimport { getDate } from \"./message-bus/bidirectional/getDate\";\nimport { prompt } from \"./message-bus/bidirectional/prompt\";\n\nexport class App {\n static getCurrentModuleContext = getCurrentModuleContext;\n\n static isModule(): boolean {\n return getCurrentModuleContext() !== null;\n }\n\n static async getCurrentModuleConfiguration(): Promise<string | undefined> {\n let urlParams = new URLSearchParams(\"\");\n\n if (typeof window !== \"undefined\" && window.location) {\n urlParams = new URLSearchParams(window.location.search);\n }\n\n const configurationId = urlParams.get(\"configuration\");\n\n if (configurationId === null || configurationId.trim() === \"\") {\n return undefined;\n }\n\n return getModuleConfiguration(configurationId.trim());\n }\n\n // senders\n static disableAnalyticsBottomBar = disableAnalyticsBottomBar;\n static goToDevice = goToDevice;\n static goToTime = goToTime;\n static refreshAuthToken = refreshAuthToken;\n static requestModuleData = requestModuleData;\n static sendChannelData = sendChannelData;\n static setModuleDateTimeRange = setModuleDateTimeRange;\n static setupModuleMenus = setupModuleMenus;\n static showMessage = showMessage;\n\n // listeners\n static addAccessTokenRefreshListener = addAccessTokenRefreshListener;\n static addChannelDataListener = addChannelDataListener;\n static addMenuListener = addMenuListener;\n static addModuleConfigurationListener = addModuleConfigurationListener;\n static addModuleDataListener = addModuleDataListener;\n static addOverviewDeviceListener = addOverviewDeviceListener;\n static addStreamListener = addStreamListener;\n\n // bidirectional\n static getDate = getDate;\n static prompt = prompt;\n\n private static _isOnline: boolean | null = null;\n\n static get isOnline(): boolean | null {\n return App._isOnline;\n }\n\n static listenForConnectionEvents(): () => void {\n const listener = (e: MessageEvent<EmbeddedAppMessage>) => {\n const { data } = e;\n if (data.type === \"formant_online\") {\n this._isOnline = data.online;\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n }\n\n static checkConnection(deadlineMs: number = 1_000): Promise<boolean> {\n return new Promise((done, reject) => {\n const deadline = setTimeout(\n () => reject(new Error(\"deadline expired: took too long\")),\n deadlineMs\n );\n\n const handler = (e: MessageEvent<EmbeddedAppMessage>) => {\n window.removeEventListener(\"message\", handler);\n clearTimeout(deadline);\n\n const { data } = e;\n if (data.type === \"formant_online\") {\n this._isOnline = data.online;\n done(data.online);\n }\n };\n\n window.addEventListener(\"message\", handler);\n sendAppMessage({ type: \"formant_online\" });\n });\n }\n\n static waitForConnection(deadlineMs: number = 5_000): Promise<void> {\n let aborted = false;\n const deadline = new Promise<void>((_, reject) => {\n setTimeout(() => {\n aborted = true;\n reject(new Error(\"deadline expired: took too long\"));\n }, deadlineMs);\n });\n\n const delay = (ms: number) => new Promise((done) => setTimeout(done, ms));\n\n const loop = async (): Promise<void> => {\n await delay(50); // allow for initialization jitter to settle\n while (!aborted) {\n if (this.isOnline || (await this.checkConnection)) {\n break;\n }\n await delay(500);\n }\n };\n\n return Promise.race([deadline, loop()]);\n }\n}\n","export function defined<T>(value: T | undefined, errorMessage?: string): T {\n if (value !== undefined) {\n return value;\n }\n throw new Error(errorMessage || \"Value is undefined\");\n}\n\nexport function notNull<T>(value: T | null, errorMessage?: string): T {\n if (value !== null) {\n return value;\n }\n throw new Error(errorMessage || \"Value is null\");\n}\n\nexport function definedAndNotNull<T>(\n value: T | undefined | null,\n errorMessage?: string\n): T {\n return notNull(defined(value, errorMessage), errorMessage);\n}\n","import { IRtcClientConfiguration } from \"@formant/realtime-sdk\";\n\nexport type SessionType = NonNullable<IRtcClientConfiguration[\"sessionType\"]>;\n\nexport const SessionTypes = {\n UNKNOWN: 0,\n TELEOP: 1,\n PORT_FORWARD: 2,\n OBSERVE: 3,\n HEADLESS: 4,\n} as const satisfies Record<string, SessionType>;\n\n// For backwards-compatibility\nexport const SessionTypeConstants = {\n ...SessionTypes,\n\n Unknown: SessionTypes.UNKNOWN,\n Teleop: SessionTypes.TELEOP,\n PortForward: SessionTypes.PORT_FORWARD,\n Observe: SessionTypes.OBSERVE,\n Headless: SessionTypes.HEADLESS,\n\n unknown: SessionTypes.UNKNOWN,\n teleop: SessionTypes.TELEOP,\n portForward: SessionTypes.PORT_FORWARD,\n observe: SessionTypes.OBSERVE,\n headless: SessionTypes.HEADLESS,\n} as const satisfies Record<string, SessionType>;\n","import {\n RtcClient,\n RtcClientV1,\n IRtcClientConfiguration,\n} from \"@formant/realtime-sdk\";\n\ntype ReceiveFn = IRtcClientConfiguration[\"receive\"];\ntype CreateClientFn<T extends RtcClient | RtcClientV1> = (\n receive: ReceiveFn\n) => T;\n\nexport interface IRtcClientPoolOptions<T extends RtcClient | RtcClientV1> {\n createClient: CreateClientFn<T>;\n ttlMs?: number;\n}\n\nconst singleton = Symbol(\"RtcClientPool.instance\");\n\nexport class RtcClientPool<T extends RtcClient | RtcClientV1> {\n [singleton]: T | null = null;\n\n private readonly createClient: CreateClientFn<T>;\n private readonly ttlMs: number;\n private readonly proxyHandler: ProxyHandler<T>;\n private proxyReceivers: Map<T, ReceiveFn | null> = new Map();\n private teardownTimeout: ReturnType<typeof setTimeout> | null = null;\n\n constructor(options: IRtcClientPoolOptions<T>) {\n const { createClient, ttlMs = 0 } = options;\n this.createClient = createClient;\n this.ttlMs = Math.max(ttlMs, 0);\n this.proxyHandler = {\n get: (target, prop, receiver) => {\n switch (prop) {\n case \"shutdown\":\n return () => this.releaseInstance(receiver);\n default:\n return Reflect.get(target, prop, receiver);\n }\n },\n };\n }\n\n get isActive(): boolean {\n return this[singleton] !== null;\n }\n\n get size(): number {\n return this.proxyReceivers.size;\n }\n\n get(onReceive?: ReceiveFn): T {\n const proxy = new Proxy(this.allocate(), this.proxyHandler);\n this.proxyReceivers.set(proxy, onReceive ?? null);\n return proxy;\n }\n\n private allocate(): T {\n if (this[singleton]) {\n // cancel any outstanding teardown request/keep this singleton alive\n if (this.teardownTimeout) {\n clearTimeout(this.teardownTimeout);\n this.teardownTimeout = null;\n }\n\n return this[singleton];\n }\n\n const client = this.createClient(this.dispatch);\n this[singleton] = client;\n return client;\n }\n\n private async teardown() {\n const instance = this[singleton];\n if (!instance) {\n console.warn(\"singleton has already been shutdown!\");\n return;\n }\n\n try {\n await instance.shutdown();\n } finally {\n this[singleton] = null;\n }\n }\n\n private dispatch: ReceiveFn = (peerId, message) => {\n this.proxyReceivers.forEach((it) => it?.(peerId, message));\n };\n\n private async releaseInstance(proxy: T): Promise<boolean> {\n if (!this.proxyReceivers.delete(proxy)) {\n console.warn(\"this instance has already been released!\");\n return false;\n }\n\n if (this.proxyReceivers.size !== 0) {\n return false;\n }\n\n if (!this.teardownTimeout && Number.isFinite(this.ttlMs)) {\n if (this.ttlMs === 0) {\n await this.teardown();\n } else {\n this.teardownTimeout = setTimeout(() => {\n this.teardown()\n .catch((err) => console.error(\"teardown failed\", { err }))\n .finally(() => (this.teardownTimeout = null));\n }, this.ttlMs);\n }\n }\n return true;\n }\n}\n","import { RtcClient, SignalingPromiseClient } from \"@formant/realtime-sdk\";\n\nimport { SessionType, SessionTypes } from \"./model/SessionType\";\nimport { RtcClientPool } from \"./utils/RtcClientPool\";\nimport { FORMANT_API_URL } from \"./config\";\nimport { Authentication } from \"./Authentication\";\nimport { defined } from \"../../common/defined\";\n\nconst getToken = async () =>\n defined(Authentication.token, \"Realtime when user isn't authorized\");\n\nconst EnumRtcClientPools = {\n [SessionTypes.UNKNOWN]: new RtcClientPool({\n ttlMs: 2_500,\n createClient: (receiveFn) =>\n new RtcClient({\n signalingClient: new SignalingPromiseClient(FORMANT_API_URL),\n getToken,\n sessionType: SessionTypes.UNKNOWN,\n receive: receiveFn,\n }),\n }),\n [SessionTypes.TELEOP]: new RtcClientPool({\n ttlMs: 2_500,\n createClient: (receiveFn) =>\n new RtcClient({\n signalingClient: new SignalingPromiseClient(FORMANT_API_URL),\n getToken,\n sessionType: SessionTypes.TELEOP,\n receive: receiveFn,\n }),\n }),\n [SessionTypes.PORT_FORWARD]: new RtcClientPool({\n ttlMs: 2_500,\n createClient: (receiveFn) =>\n new RtcClient({\n signalingClient: new SignalingPromiseClient(FORMANT_API_URL),\n getToken,\n sessionType: SessionTypes.PORT_FORWARD,\n receive: receiveFn,\n }),\n }),\n [SessionTypes.OBSERVE]: new RtcClientPool({\n ttlMs: 2_500,\n createClient: (receiveFn) =>\n new RtcClient({\n signalingClient: new SignalingPromiseClient(FORMANT_API_URL),\n getToken,\n sessionType: SessionTypes.OBSERVE,\n receive: receiveFn,\n }),\n }),\n [SessionTypes.HEADLESS]: new RtcClientPool({\n ttlMs: 2_500,\n createClient: (receiveFn) =>\n new RtcClient({\n signalingClient: new SignalingPromiseClient(FORMANT_API_URL),\n getToken,\n sessionType: SessionTypes.HEADLESS,\n receive: receiveFn,\n }),\n }),\n} as const;\n\nexport const AppRtcClientPools = {\n ...EnumRtcClientPools,\n unknown: EnumRtcClientPools[SessionTypes.UNKNOWN],\n teleop: EnumRtcClientPools[SessionTypes.TELEOP],\n portForward: EnumRtcClientPools[SessionTypes.PORT_FORWARD],\n observe: EnumRtcClientPools[SessionTypes.OBSERVE],\n headless: EnumRtcClientPools[SessionTypes.HEADLESS],\n} as const;\n\nexport const defaultRtcClientPool = EnumRtcClientPools[SessionTypes.TELEOP];\n\nexport const getRtcClientPool = (options: { sessionType?: SessionType }) => {\n const { sessionType } = options;\n\n return sessionType ? AppRtcClientPools[sessionType] : defaultRtcClientPool;\n};\n\nexport function debug() {\n console.group(\"RtcClientPool Sizes\");\n console.table(\n ([\"unknown\", \"teleop\", \"portForward\", \"observe\"] as const).map((key) => {\n const pool = AppRtcClientPools[key];\n return {\n name: key,\n size: pool.size,\n active: pool.isActive ? \"🔥\" : \"🧊\",\n };\n })\n );\n\n console.groupEnd();\n}\n","import { FORMANT_API_URL } from \"./config\";\n\nexport interface CaptureSession {\n deviceId: string;\n streamName: string;\n tags: {};\n expiration: string;\n organizationId: string;\n userId: string;\n code: string;\n id: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport class CaptureStream {\n token: string | undefined;\n constructor(public captureSession: CaptureSession) {}\n\n async ingestJSON(value: {}) {\n if (!this.token) {\n const result = await fetch(\n `${FORMANT_API_URL}/v1/admin/capture-sessions/${this.captureSession.code}/authenticate`,\n {\n method: \"POST\",\n }\n );\n const authInfo = await result.json();\n this.token = authInfo.token;\n }\n\n await fetch(`${FORMANT_API_URL}/v1/ingest`, {\n method: \"POST\",\n body: JSON.stringify({\n deviceId: this.captureSession.deviceId,\n name: this.captureSession.streamName,\n type: \"json\",\n points: [[Date.now(), JSON.stringify(value)]],\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + this.token,\n },\n });\n }\n}\n","export function delay(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { IRtcPeer } from \"@formant/realtime-sdk\";\n\nexport const isRtcPeer = (peer: IRtcPeer | undefined): peer is IRtcPeer =>\n peer !== undefined &&\n peer.capabilities !== undefined &&\n peer.capabilitySet !== undefined;\n","export type DataChannelStringListener = (message: string) => void;\nexport type DataChannelBinaryListener = (message: Uint8Array) => void;\nexport type DataChannelListener = () => void;\nexport type DataChannelErrorListener = (ev: Event) => void;\nexport class DataChannel {\n ready = false;\n listeners: DataChannelStringListener[] = [];\n openListeners: DataChannelListener[] = [];\n closeListeners: DataChannelListener[] = [];\n errorListeners: DataChannelErrorListener[] = [];\n binaryListeners: DataChannelBinaryListener[] = [];\n error: string | undefined;\n decoder = new TextDecoder();\n\n constructor(private dataChannel: RTCDataChannel) {\n this.dataChannel.binaryType = \"arraybuffer\";\n this.dataChannel.onopen = () => {\n this.setReady();\n };\n this.dataChannel.onclose = () => {\n this.ready = false;\n this.closeListeners.forEach((listener) => listener());\n };\n this.dataChannel.onerror = (e) => {\n console.error(e);\n this.error = \"An error occurred in DataChannel\";\n this.errorListeners.forEach((listener) => listener(e));\n };\n this.dataChannel.onmessage = (m: MessageEvent) => {\n this.listeners.forEach((_) => {\n const d = new Uint8Array(m.data);\n const s = this.decoder.decode(d);\n _(s);\n });\n this.binaryListeners.forEach((_) => {\n _(new Uint8Array(m.data));\n });\n };\n }\n\n private setReady() {\n this.ready = true;\n this.openListeners.forEach((listener) => listener());\n }\n\n addOpenListener(listener: DataChannelListener) {\n this.openListeners.push(listener);\n }\n\n removeOpenListener(listener: DataChannelListener) {\n this.openListeners = this.openListeners.filter((_) => _ !== listener);\n }\n\n addCloseListener(listener: DataChannelListener) {\n this.closeListeners.push(listener);\n }\n\n removeCloseListener(listener: DataChannelListener) {\n this.closeListeners = this.closeListeners.filter((l) => l !== listener);\n }\n\n addErrorListener(listener: DataChannelErrorListener) {\n this.errorListeners.push(listener);\n }\n\n removeErrorListener(listener: DataChannelErrorListener) {\n this.errorListeners = this.errorListeners.filter((l) => l !== listener);\n }\n\n async waitTilReady(): Promise<boolean> {\n if (this.ready) {\n return true;\n }\n const p = new Promise<boolean>((resolve, reject) => {\n let a = setInterval(() => {\n if (this.dataChannel.readyState === \"open\") {\n this.setReady();\n }\n if (this.ready) {\n clearInterval(a);\n resolve(true);\n }\n if (this.error) {\n reject(this.error);\n }\n }, 10);\n });\n return p;\n }\n\n send(data: string) {\n if (!this.ready) {\n throw new Error(\"Connection has been closed\");\n }\n this.dataChannel.send(data);\n }\n\n sendBinary(data: Uint8Array) {\n if (!this.ready) {\n throw new Error(\"Connection has been closed\");\n }\n this.dataChannel.send(data);\n }\n\n addListener(listener: DataChannelStringListener) {\n this.listeners.push(listener);\n }\n\n removeListener(listener: DataChannelStringListener) {\n const i = this.listeners.indexOf(listener);\n if (i === -1) {\n throw new Error(\"Could not find data channel listener to remove\");\n }\n if (this.error) {\n throw new Error(this.error);\n }\n this.listeners.splice(i, 1);\n }\n\n addBinaryListener(listener: DataChannelBinaryListener) {\n this.binaryListeners.push(listener);\n }\n\n removeBinaryListener(listener: DataChannelBinaryListener) {\n const i = this.binaryListeners.indexOf(listener);\n if (i === -1) {\n throw new Error(\"Could not find data channel listener to remove\");\n }\n if (this.error) {\n throw new Error(this.error);\n }\n this.binaryListeners.splice(i, 1);\n }\n}\n","import {\n RealtimeDataStream,\n IJointState,\n RealtimeMessage,\n} from \"./devices/device.types\";\nimport { IRealtimeSubscriber } from \"./devices/IRealtimeSubscriber\";\n\nexport type RealtimeManipulatorConfig = {\n currentJointStateStream: RealtimeDataStream;\n plannedJointStateStream?: RealtimeDataStream;\n planValidStream?: RealtimeDataStream;\n endEffectorStream?: RealtimeDataStream;\n endEffectorLinkName?: string;\n baseReferenceFrame?: string;\n localFrame?: string;\n};\n\nexport class Manipulator {\n currentListeners: ((js: IJointState) => void)[] = [];\n constructor(\n private device: IRealtimeSubscriber,\n private config: RealtimeManipulatorConfig\n ) {}\n\n async synchronize() {\n this.device.addRealtimeListener(this.onRealtimeMessage);\n this.device.startListeningToRealtimeDataStream(\n this.config.currentJointStateStream\n );\n }\n\n async desynchronize() {\n this.device.removeRealtimeListener(this.onRealtimeMessage);\n this.device.stopListeningToRealtimeDataStream(\n this.config.currentJointStateStream\n );\n }\n\n onRealtimeMessage = (_peerId: string, message: RealtimeMessage) => {\n if (message.payload.jointState) {\n this.currentListeners.forEach((listener) => {\n if (message.payload.jointState) listener(message.payload.jointState);\n });\n }\n };\n\n async addCurrentJointStateListener(listener: (js: IJointState) => void) {\n this.currentListeners.push(listener);\n }\n}\n","import {\n DataChannel,\n DataChannelErrorListener,\n DataChannelListener,\n} from \"./DataChannel\";\nimport { delay } from \"../../common/delay\";\nimport { defined } from \"../../common/defined\";\nimport { ICustomDataChannelCreator } from \"./devices/ICustomDataChannelCreator\";\n\n// AdapterError -> An error occurred when handling the request on the adapter.\n// TimeoutError -> The request did not receive a response within the timeout period.\n\nabstract class RequestDataChannel {\n protected channel: undefined | DataChannel;\n protected requestIdToResponseMap = new Map<string, any>();\n constructor(\n protected device: ICustomDataChannelCreator,\n protected channel_name: string,\n protected timeout: number\n ) {}\n\n addOpenListener(listener: DataChannelListener) {\n defined(this.channel, \"channel not initalized\").addOpenListener(listener);\n }\n\n removeOpenListener(listener: DataChannelListener) {\n defined(this.channel, \"channel not initalized\").removeOpenListener(\n listener\n );\n }\n\n addCloseListener(listener: DataChannelListener) {\n defined(this.channel, \"channel not initalized\").addCloseListener(listener);\n }\n\n removeCloseListener(listener: DataChannelListener) {\n defined(this.channel, \"channel not initalized\").removeCloseListener(\n listener\n );\n }\n\n addErrorListener(listener: DataChannelErrorListener) {\n defined(this.channel, \"channel not initalized\").addErrorListener(listener);\n }\n\n removeErrorListener(listener: DataChannelErrorListener) {\n defined(this.channel, \"channel not initalized\").removeErrorListener(\n listener\n );\n }\n}\n\nexport class BinaryRequestDataChannel extends RequestDataChannel {\n private RESPONSE_SUCCESS_BYTE = 0;\n private decoder = new TextDecoder();\n\n /*\n Request binary payload layout:\n 16-bytes arbitrary-length\n [ ID ] [ PAYLOAD ]\n\n Response binary payload layout:\n 1-byte 16-bytes arbitrary-length\n [ SUCCESS OR ERROR BYTE ] [ ID ] [ PAYLOAD ]\n */\n\n generateBinaryId() {\n // attach binary ID as 16-byte header in binary messages\n const id = new Uint8Array(16);\n for (let i = 0; i < id.length; i++) {\n id[i] = Math.floor(Math.random() * 256);\n }\n return id;\n }\n\n async initialize() {\n this.channel = await this.device.createCustomDataChannel(this.channel_name);\n\n this.channel.addBinaryListener((message) => {\n const binaryId = message.slice(0, 16);\n\n const id = binaryId.toString();\n if (id.length === 0) {\n throw new Error(\"Invalid response\");\n }\n\n const response = message.slice(16);\n if (response.length === 0) {\n throw new Error(\"Invalid response\");\n }\n\n // only add to the map if there is an active request\n if (this.requestIdToResponseMap.has(id)) {\n this.requestIdToResponseMap.set(id, response);\n }\n });\n }\n\n async request(data: Uint8Array) {\n if (!this.channel) {\n await this.initialize();\n }\n if (!this.channel) {\n throw new Error(\"Failed to create channel\");\n }\n const { channel, requestIdToResponseMap, timeout } = this;\n await channel.waitTilReady();\n\n const binaryId = this.generateBinaryId();\n const id = binaryId.toString();\n requestIdToResponseMap.set(id, true); // true signifies an active request\n channel.sendBinary(new Uint8Array([...binaryId, ...data]));\n\n // Wait for the response to come back.\n const start = new Date().getTime();\n while (new Date().getTime() < start + timeout) {\n await delay(50);\n if (requestIdToResponseMap.has(id)) {\n const response = requestIdToResponseMap.get(id);\n if (response !== true) {\n requestIdToResponseMap.delete(id);\n const success = response[0] === this.RESPONSE_SUCCESS_BYTE;\n const payload = response.slice(1);\n if (success) {\n return payload;\n } else {\n console.error({\n name: \"AdapterError\",\n message: this.decoder.decode(payload),\n });\n throw new Error(\"Binary request datachannel adapter error\");\n }\n }\n }\n }\n\n requestIdToResponseMap.delete(id);\n console.error({\n name: \"TimeoutError\",\n message: `Request timed out after ${timeout / 1000.0} seconds`,\n });\n throw new Error(\"Binary request data channel request timed out\");\n }\n}\n\nexport class TextRequestDataChannel extends RequestDataChannel {\n generateTextId() {\n return (\n Math.random().toString(36).substring(2) +\n \"-\" +\n Math.random().toString(36).substring(2)\n );\n }\n\n async initialize() {\n this.channel = await this.device.createCustomDataChannel(this.channel_name);\n\n this.channel.addListener((message) => {\n const response = JSON.parse(message);\n const { id, data, error } = response;\n if (!id) {\n throw new Error(\"Invalid response\");\n }\n if (!data && !error) {\n throw new Error(\"Invalid response\");\n }\n // only add to the map if there is an active request\n if (this.requestIdToResponseMap.has(id)) {\n this.requestIdToResponseMap.set(id, response);\n }\n });\n }\n\n async request(data: string) {\n if (!this.channel) {\n await this.initialize();\n }\n if (!this.channel) {\n throw new Error(\"Failed to create channel\");\n }\n const { channel, requestIdToResponseMap, timeout } = this;\n await channel.waitTilReady();\n\n const id = this.generateTextId();\n requestIdToResponseMap.set(id, true); // true signifies an active request\n channel.send(\n JSON.stringify({\n id,\n data,\n })\n );\n\n // Wait for the response to come back.\n const start = new Date().getTime();\n while (new Date().getTime() < start + timeout) {\n await delay(50);\n if (requestIdToResponseMap.has(id)) {\n const response = requestIdToResponseMap.get(id);\n if (response !== true) {\n requestIdToResponseMap.delete(id);\n const { data, error } = response;\n if (data) {\n return data;\n }\n if (error) {\n console.error({\n name: \"AdapterError\",\n message: error,\n });\n throw new Error(\"Text request datachannel adapter error\");\n }\n }\n }\n }\n\n requestIdToResponseMap.delete(id);\n console.error({\n name: \"TimeoutError\",\n message: `Request timed out after ${timeout / 1000.0} seconds`,\n });\n throw new Error(\"Text request datachannel request timed out\");\n }\n}\n","import {\n IRtcSendConfiguration,\n IRtcStreamMessage,\n RtcClient,\n IRtcPeer,\n} from \"@formant/realtime-sdk\";\nimport { DataChannel } from \"../DataChannel\";\nimport { EventEmitter } from \"eventemitter3\";\nimport { Manipulator } from \"../Manipulator\";\nimport {\n BinaryRequestDataChannel,\n TextRequestDataChannel,\n} from \"../RequestDataChannel\";\nimport { defined } from \"../../../common/defined\";\nimport { IRealtimeSubscriber } from \"./IRealtimeSubscriber\";\nimport { ICustomDataChannelCreator } from \"./ICustomDataChannelCreator\";\nimport {\n ConfigurationDocument,\n RealtimeListener,\n RealtimeAudioStream,\n RealtimeVideoStream,\n RealtimeDataStream,\n} from \"./device.types\";\n\nexport abstract class BaseDevice\n extends EventEmitter\n implements IRealtimeSubscriber, ICustomDataChannelCreator\n{\n rtcClient: RtcClient | undefined;\n remoteDevicePeerId: string | null = null;\n\n protected realtimeListeners: RealtimeListener[] = [];\n\n protected connectionMonitorInterval:\n | ReturnType<typeof setInterval>\n | undefined;\n\n abstract getConfiguration(): Promise<ConfigurationDocument>;\n abstract startRealtimeConnection(sessionType?: number): Promise<void>;\n abstract getRemotePeer(): Promise<IRtcPeer>;\n\n protected handleMessage = (peerId: string, message: any) => {\n this.realtimeListeners.forEach((_) => _(peerId, message));\n };\n\n protected stopConnectionMonitoring() {\n clearInterval(this.connectionMonitorInterval);\n this.connectionMonitorInterval = undefined;\n }\n\n protected assertNotCancelled(cancelled: boolean): void {\n if (cancelled) throw new Error(\"Cancelled by deadline\");\n }\n\n getRealtimeStatus(): \"disconnected\" | \"connecting\" | \"connected\" {\n if (this.rtcClient && this.remoteDevicePeerId) {\n return this.rtcClient.getConnectionStatus(this.remoteDevicePeerId);\n } else {\n throw new Error(`Realtime connection hasn't been started`);\n }\n }\n\n getRealtimePing(): number | undefined {\n if (this.rtcClient && this.remoteDevicePeerId) {\n return this.rtcClient.getPing(this.remoteDevicePeerId);\n } else {\n throw new Error(`Realtime connection hasn't been started`);\n }\n }\n\n addRealtimeListener(listener: RealtimeListener) {\n this.realtimeListeners.push(listener);\n }\n\n removeRealtimeListener(listener: RealtimeListener) {\n const i = this.realtimeListeners.indexOf(listener);\n if (i === -1) {\n throw new Error(\"Could not find realtime listener to remove\");\n }\n this.realtimeListeners.splice(i, 1);\n }\n\n async getRealtimeManipulators(): Promise<Manipulator[]> {\n const document = (await this.getConfiguration()) as any;\n const manipulators = [];\n\n for (const _ of document.teleop.rosStreams ?? []) {\n if (_.topicType == \"sensor_msgs/JointState\") {\n manipulators.push(\n new Manipulator(this, {\n currentJointStateStream: { name: _.topicName },\n plannedJointStateStream: _.plannedTopic\n ? { name: _.plannedTopic }\n : undefined,\n planValidStream: _.planValidTopic\n ? { name: _.planValidTopic }\n : undefined,\n endEffectorStream: _.endEffectorTopic\n ? { name: _.endEffectorTopic }\n : undefined,\n endEffectorLinkName: _.endEffectorLinkName,\n baseReferenceFrame: _.baseReferenceFrame,\n localFrame: _.localFrame,\n })\n );\n }\n }\n return manipulators;\n }\n\n async getRealtimeVideoStreams(): Promise<RealtimeVideoStream[]> {\n const document = (await this.getConfiguration()) as any;\n const streams: { name: string }[] = [];\n\n for (const _ of document.teleop?.hardwareStreams ?? []) {\n if (_.rtcStreamType === \"h264-video-frame\") {\n streams.push({\n name: _.name,\n });\n }\n }\n for (const _ of document.teleop?.rosStreams ?? []) {\n if (_.topicType == \"formant/H264VideoFrame\") {\n streams.push({\n name: _.topicName,\n });\n }\n if (\n (_.topicType === \"sensor_msgs/Image\" ||\n _.topicType === \"sensor_msgs/CompressedImage\") &&\n _.encodeVideo\n ) {\n streams.push({\n name: _.topicName,\n });\n }\n }\n for (const _ of document.teleop?.customStreams ?? []) {\n if (_.rtcStreamType === \"h264-video-frame\") {\n streams.push({\n name: _.name,\n });\n }\n }\n return streams;\n }\n\n createCustomRequestDataChannel(\n channelName: string,\n timeout: number = 3000 // 3 seconds default timeout\n ): TextRequestDataChannel {\n return new TextRequestDataChannel(this, channelName, timeout);\n }\n\n createCustomBinaryRequestDataChannel(\n channelName: string,\n timeout: number = 3000 // 3 seconds default timeout\n ): BinaryRequestDataChannel {\n return new BinaryRequestDataChannel(this, channelName, timeout);\n }\n\n async startListeningToRealtimeVideo(stream: RealtimeVideoStream) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: stream.name,\n enable: true,\n pipeline: \"rtc\",\n });\n }\n\n async stopListeningToRealtimeVideo(stream: RealtimeVideoStream) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: stream.name,\n enable: false,\n pipeline: \"rtc\",\n });\n }\n\n async startListeningToRealtimeDataStream(stream: RealtimeDataStream) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: stream.name,\n enable: true,\n pipeline: \"rtc\",\n });\n }\n\n async stopListeningToRealtimeDataStream(stream: RealtimeDataStream) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: stream.name,\n enable: false,\n pipeline: \"rtc\",\n });\n }\n\n async enableRealtimeTelemetryPriorityIngestion(streamName: string) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: streamName,\n enablePriorityUpload: true,\n pipeline: \"telemetry\",\n });\n }\n\n async disableRealtimeTelemetryPriorityIngestion(streamName: string) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: streamName,\n enablePriorityUpload: false,\n pipeline: \"telemetry\",\n });\n }\n\n async changeStreamAudioType(streamName: string, newFormat: \"wav\" | \"opus\") {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName,\n setAudioFormat: newFormat,\n });\n }\n\n async createCustomDataChannel(\n channelName: string,\n rtcConfig?: RTCDataChannelInit\n ): Promise<DataChannel> {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n const p = await new Promise<DataChannel>((resolve) => {\n client.createCustomDataChannel(\n defined(devicePeer).id,\n channelName,\n {\n ordered: true,\n ...rtcConfig,\n },\n false,\n (_peerId, channel) => {\n const dataChannel = new DataChannel(channel);\n resolve(dataChannel);\n }\n );\n });\n await p.waitTilReady();\n return p;\n }\n\n async sendRealtimeMessage(\n message: IRtcStreamMessage,\n config: IRtcSendConfiguration = {\n channelLabel: \"stream.reliable\",\n }\n ) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.send(defined(devicePeer).id, message, config);\n }\n\n async getRealtimeAudioStreams(): Promise<RealtimeAudioStream[]> {\n const document = await this.getConfiguration();\n const streams: { name: string }[] = [];\n\n for (const _ of document.teleop?.hardwareStreams ?? []) {\n if (_.rtcStreamType === \"audio-chunk\") {\n streams.push({\n name: _.name,\n });\n }\n }\n for (const _ of document.teleop?.rosStreams ?? []) {\n if (_.topicType == \"audio_common_msgs/AudioData\") {\n streams.push({\n name: _.topicName,\n });\n }\n }\n for (const _ of document.teleop?.customStreams ?? []) {\n if (_.rtcStreamType === \"audio-chunk\") {\n streams.push({\n name: _.name,\n });\n }\n }\n return streams;\n }\n}\n","import { inflate, deflate } from \"pako\";\nimport { fromByteArray, toByteArray } from \"base64-js\";\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\nexport function serializeHash(value: any): string {\n const jsonValue = JSON.stringify(value);\n const encodedValue = encoder.encode(jsonValue);\n const compressedValue = deflate(encodedValue);\n return fromByteArray(compressedValue);\n}\n\nexport function deserializeHash(value: string): any {\n const a = toByteArray(value);\n const b = inflate(a);\n const c = decoder.decode(b);\n return JSON.parse(c);\n}\n","import { IView } from \"../model/IView\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getViews(): Promise<IView[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(`${FORMANT_API_URL}/v1/admin/views`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const views = await response.json();\n return views.items;\n}\n","import { IShare } from \"../model/IShare\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { serializeHash } from \"../utils/serializeHash\";\n\nimport { getViews } from \"./getViews\";\n\n/**\n * @param scope is required\n * @param time is required\n * @param view View name\n * @returns\n * Share link\n * @example\n * // Body\n * const link = await createShareLink({\n * delegateTeleop: false\n * message: \"See bot in action\",\n * scope: {\n * deviceIds: [\"d64520a6-a308-4a59-9267-b7f8a7bfc7ab\"],\n * start: \"2023-04-04T19:51:47.125Z\",\n * end: \"2023-04-04T20:51:47.125Z\"\n * },\n * time: \"2023-04-04T20:21:47.125Z\",\n * userName: \"User\",\n * });\n */\nexport async function createShareLink(share: IShare, view: string) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n\n const views = await getViews();\n\n const selectedView = views.filter((_) => _.name === view);\n\n if (selectedView.length === 0) {\n console.warn(\"View does not exist or it is misspell\");\n return null;\n }\n\n const response = await fetch(`${FORMANT_API_URL}/v1/admin/shares`, {\n method: \"POST\",\n body: JSON.stringify(share),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const origin = FORMANT_API_URL.replace(\"api\", \"app\");\n const { code } = await response.json();\n\n return `${origin}/shares/${code}#${serializeHash({\n viewId: selectedView[0].id,\n })}`;\n}\n","import { INumericAggregate } from \"../model/INumericAggregate\";\nimport * as dateFns from \"date-fns\";\nimport { AggregateLevel } from \"../model/AggregateLevel\";\n\nexport const vailableAggregationIntervals = [\n \"day\",\n \"week\",\n \"month\",\n \"year\",\n \"hour\",\n \"minute\",\n \"quarter\",\n] as const;\n\nexport type ValidAggregationInterval =\n (typeof vailableAggregationIntervals)[number];\n\nexport type IAggregateByDateFunctions = {\n [key in ValidAggregationInterval]: AggregateFunction;\n};\n\nexport const aggregateFunctions = [\n \"interval\",\n \"start\",\n \"end\",\n \"sub\",\n \"get\",\n] as const;\n\nexport type AggregateFunctions = (typeof aggregateFunctions)[number];\n\nexport type AggregateFunction = {\n [key in AggregateFunctions]: any;\n};\n\nexport function getVariance(a: INumericAggregate) {\n if (a.count < 2) {\n return 0;\n }\n return a.sumOfSquares / (a.count - 1);\n}\n\nexport function getStandardDeviation(a: INumericAggregate) {\n return Math.sqrt(getVariance(a));\n}\n\nexport function getMax(a: INumericAggregate) {\n return a.max;\n}\n\nexport function getMin(a: INumericAggregate) {\n return a.min;\n}\n\nexport function getAverage(a: INumericAggregate) {\n return a.count === 0 ? -1 : a.sum / a.count;\n}\n\nexport function getSum(a: INumericAggregate) {\n return a.sum;\n}\nexport function getCount(a: INumericAggregate) {\n return a.count;\n}\n\nexport const aggregateFunctionMap = {\n min: getMin,\n max: getMax,\n \"standard deviation\": getStandardDeviation,\n average: getAverage,\n sum: getSum,\n count: getCount,\n};\n\ninterface IAggregateFunctions {\n interval: (interval: dateFns.Interval) => Date[];\n start: (date: Date | number) => Date;\n end: (date: Date | number) => Date;\n sub: (date: Date | number, amount: number) => Date;\n get: (date: Date | number) => number;\n}\n\nexport const aggregateByDateFunctions: Record<\n AggregateLevel,\n IAggregateFunctions\n> = {\n day: {\n interval: dateFns.eachDayOfInterval,\n start: dateFns.startOfDay,\n end: dateFns.endOfDay,\n sub: dateFns.subDays,\n get: dateFns.getDay,\n },\n week: {\n interval: dateFns.eachWeekOfInterval,\n start: dateFns.startOfWeek,\n end: dateFns.endOfWeek,\n sub: dateFns.subWeeks,\n get: dateFns.getWeek,\n },\n month: {\n interval: dateFns.eachMonthOfInterval,\n start: dateFns.startOfMonth,\n end: dateFns.endOfMonth,\n sub: dateFns.subMonths,\n get: dateFns.getMonth,\n },\n year: {\n interval: dateFns.eachYearOfInterval,\n start: dateFns.startOfYear,\n end: dateFns.endOfYear,\n sub: dateFns.subYears,\n get: dateFns.getYear,\n },\n hour: {\n interval: dateFns.eachHourOfInterval,\n start: dateFns.startOfHour,\n end: dateFns.endOfHour,\n sub: dateFns.subHours,\n get: dateFns.getHours,\n },\n minute: {\n interval: dateFns.eachMinuteOfInterval,\n start: dateFns.startOfMinute,\n end: dateFns.endOfMinute,\n sub: dateFns.subMinutes,\n get: dateFns.getMinutes,\n },\n quarter: {\n interval: dateFns.eachQuarterOfInterval,\n start: dateFns.startOfQuarter,\n end: dateFns.endOfQuarter,\n sub: dateFns.subQuarters,\n get: dateFns.getQuarter,\n },\n};\n\nexport const formatTimeFrameText = (start: string, end: string) =>\n // FIXME this doesn't work for *a lot* locales, other than en-US\n // en-GB: 'dd/mm/YYYY'\n // ja-jp: 'YYYY/mm/dd'\n // bg-BG: 'dd.mm.YYYY'\n start.split(\"/\")[0] +\n \"/\" +\n start.split(\"/\")[1] +\n \"–\" +\n end.split(\"/\")[0] +\n \"/\" +\n end.split(\"/\")[1];\n","import { IEventQuery } from \"../model/IEventQuery\";\nimport { IEvent } from \"../model/IEvent\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function queryEvents(query: IEventQuery): Promise<IEvent[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/events/query`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n\n return (await data.json()).items as IEvent[];\n}\n","import { EventType } from \"../model/EventType\";\nimport { AggregateLevel } from \"../model/AggregateLevel\";\nimport { IEventQuery } from \"../model/IEventQuery\";\nimport {\n aggregateByDateFunctions,\n formatTimeFrameText,\n} from \"../utils/aggregateFunctionUtils\";\nimport { queryEvents } from \"./queryEvents\";\n\nexport async function eventsCounter(\n eventTypes: EventType[],\n timeFrame: AggregateLevel,\n range: number,\n time: number,\n query?: IEventQuery\n) {\n const dateFunctions = aggregateByDateFunctions[timeFrame];\n\n return await Promise.all(\n Array(range)\n .fill(0)\n .map(async (_, dateOffset) => {\n const activePointInTimeLine = new Date(time);\n\n const startDate: Date = dateFunctions.sub(\n dateFunctions.start(activePointInTimeLine),\n range - dateOffset - 1\n );\n const endDate: Date = dateFunctions.sub(\n dateFunctions.end(activePointInTimeLine),\n range - dateOffset - 1\n );\n const date = formatTimeFrameText(\n startDate.toLocaleDateString(),\n endDate.toLocaleDateString()\n );\n const events = await queryEvents({\n ...query,\n eventTypes,\n start: new Date(startDate).toISOString(),\n end: new Date(endDate).toISOString(),\n });\n return { date, events };\n })\n );\n}\n","import { IEventQuery } from \"../model/IEventQuery\";\n\nimport { queryEvents } from \"./queryEvents\";\n\nexport async function getAnnotationCount(query: IEventQuery, tagKey: string) {\n const annotations = await queryEvents({\n ...query,\n eventTypes: [\"annotation\"],\n });\n\n const validAnnotations = annotations.filter(\n (_) => !!_.tags && Object.keys(_.tags!).includes(tagKey)\n );\n const annotationCounter = validAnnotations.reduce<{\n [key: string]: number;\n }>((prev, current) => {\n const value = current.tags![tagKey];\n if (value in prev) {\n prev[value] += 1;\n return prev;\n }\n prev[value] = 1;\n return prev;\n }, {});\n\n return annotationCounter;\n}\n","import { IEventQuery } from \"../model/IEventQuery\";\nimport { AggregateLevel } from \"../model/AggregateLevel\";\nimport { aggregateByDateFunctions } from \"../utils/aggregateFunctionUtils\";\nimport { getAnnotationCount } from \"./getAnnotationCount\";\n\nexport async function getAnnotationCountByIntervals(\n query: IEventQuery,\n tagKey: string,\n aggregate: AggregateLevel\n) {\n const { end, start } = query;\n const dateFunctions = aggregateByDateFunctions[aggregate];\n const intervals: Date[] = dateFunctions.interval({\n start: new Date(start!),\n end: new Date(end!),\n });\n\n const annotationsQuery = intervals.map((_, idx) => {\n const startDate = new Date(_).toISOString();\n const endDate =\n idx === intervals.length - 1\n ? new Date(Date.now()).toISOString()\n : new Date(intervals[idx + 1]);\n return getAnnotationCount(\n {\n ...query,\n start: startDate,\n end: endDate as string,\n },\n tagKey\n );\n });\n const responses = await Promise.all(annotationsQuery);\n\n return intervals.map((_, idx) => ({\n date: new Date(_).toISOString(),\n annotations: responses[idx],\n }));\n}\n","import { FORMANT_API_URL } from \"../config\";\nimport { Authentication } from \"../Authentication\";\n\nimport { TelemetryResult } from \"../model/TelemetryResult\";\n\nexport async function getTelemetry(\n deviceIdOrDeviceIds: string | string[],\n streamNameOrStreamNames: string | string[],\n start: Date,\n end: Date,\n tags?: { [key in string]: string[] }\n): Promise<TelemetryResult[]> {\n let deviceIds = deviceIdOrDeviceIds;\n if (!Array.isArray(deviceIdOrDeviceIds)) {\n deviceIds = [deviceIdOrDeviceIds];\n }\n let streamNames = streamNameOrStreamNames;\n if (!Array.isArray(streamNameOrStreamNames)) {\n streamNames = [streamNameOrStreamNames];\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/queries/queries`, {\n method: \"POST\",\n body: JSON.stringify({\n deviceIds,\n end: end.toISOString(),\n names: streamNames,\n start: start.toISOString(),\n tags,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const telemetry = await data.json();\n return telemetry.items;\n}\n","import { Authentication } from \"../Authentication\";\nimport { defaultRtcClientPool } from \"../AppRtcClientPools\";\n\nexport async function getRealtimeSessions(): Promise<{\n [key in string]: string[];\n}> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const rtcClient = defaultRtcClientPool.get();\n try {\n return await rtcClient.getSessions();\n } finally {\n await rtcClient.shutdown();\n }\n}\n","import { IRtcPeer } from \"@formant/realtime-sdk\";\n\nimport { Authentication } from \"../Authentication\";\nimport { defaultRtcClientPool } from \"../AppRtcClientPools\";\n\nexport async function getPeers(): Promise<IRtcPeer[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const rtcClient = defaultRtcClientPool.get();\n try {\n return await rtcClient.getPeers();\n } finally {\n await rtcClient.shutdown();\n }\n}\n","import { IDevice } from \"../model/IDevice\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function createDevice(device: IDevice): Promise<IDevice> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices`, {\n method: \"POST\",\n body: JSON.stringify(device),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { IDevice } from \"../model/IDevice\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function patchDevice(\n id: string,\n device: Partial<IDevice>\n): Promise<IDevice> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify(device),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IDevice } from \"../model/IDevice\";\n\nexport async function getDevicesData(): Promise<IDevice[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/device-details/query`, {\n method: \"POST\",\n body: JSON.stringify({ enabled: true, type: \"default\" }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n return devices.items;\n}\n","import { IDeviceQuery } from \"../model/IDeviceQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IDevice } from \"../model/IDevice\";\n\nexport async function queryDevicesData(\n query: IDeviceQuery\n): Promise<IDevice[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices/query`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n\n return devices.items;\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IDevice } from \"../model/IDevice\";\n\nexport async function disableDevice(id: string): Promise<IDevice[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/devices/${id}/disable`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const response = await data.json();\n\n return response;\n}\n","import { RtcClient, IRtcPeer } from \"@formant/realtime-sdk\";\nimport { getRtcClientPool } from \"../AppRtcClientPools\";\nimport { Authentication } from \"../Authentication\";\nimport { CaptureStream } from \"../CaptureStream\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { delay } from \"../../../common/delay\";\nimport { defined } from \"../../../common/defined\";\nimport { InterventionType } from \"../model/InterventionType\";\nimport { IInterventionTypeMap } from \"../model/IInterventionTypeMap\";\nimport { IInterventionResponse } from \"../model/IInterventionResponse\";\nimport { IEventQuery } from \"../model/IEventQuery\";\nimport { AggregateLevel } from \"../model/AggregateLevel\";\nimport { EventType } from \"../model/EventType\";\nimport { IShare } from \"../model/IShare\";\nimport { SessionType } from \"../model/SessionType\";\nimport { isRtcPeer } from \"../utils/isRtcPeer\";\nimport {\n Command,\n ConfigurationDocument,\n IStartRealtimeConnectionOptions,\n TelemetryStream,\n} from \"./device.types\";\nimport { BaseDevice } from \"./BaseDevice\";\nimport { ITags } from \"../model/ITags\";\nimport { createShareLink } from \"../api/createShareLink\";\nimport { eventsCounter } from \"../api/eventsCounter\";\nimport { getAnnotationCount } from \"../api/getAnnotationCount\";\nimport { getAnnotationCountByIntervals } from \"../api/getAnnotationCountByIntervals\";\nimport { getTelemetry } from \"../api/getTelemetry\";\nimport { getRealtimeSessions } from \"../api/getRealtimeSessions\";\nimport { getPeers } from \"../api/getPeers\";\nimport { createDevice } from \"../api/createDevice\";\nimport { patchDevice } from \"../api/patchDevice\";\nimport { getDevicesData } from \"../api/getDevicesData\";\nimport { queryDevicesData } from \"../api/queryDevicesData\";\nimport { disableDevice } from \"../api/disableDevice\";\nexport class Device extends BaseDevice {\n constructor(\n public id: string,\n public name: string,\n private organizationId: string,\n public tags?: ITags\n ) {\n super();\n }\n\n static createDevice = createDevice;\n static patchDevice = patchDevice;\n static getDevicesData = getDevicesData;\n static queryDevicesData = queryDevicesData;\n static disableDevice = disableDevice;\n\n async getLatestTelemetry() {\n const data = await fetch(\n `${FORMANT_API_URL}/v1/queries/stream-current-value`,\n {\n method: \"POST\",\n body: JSON.stringify({\n deviceIds: [this.id],\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const telemetry = await data.json();\n return telemetry.items;\n }\n\n async getConfiguration(): Promise<ConfigurationDocument> {\n let result = await fetch(`${FORMANT_API_URL}/v1/admin/devices/${this.id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const device = await result.json();\n if (!device.state.reportedConfiguration) {\n throw new Error(\n \"Device has no configuration, has it ever been turned on?\"\n );\n }\n const version = device.state.reportedConfiguration.version;\n result = await fetch(\n `${FORMANT_API_URL}/v1/admin/devices/${this.id}/configurations/${version}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const config = await result.json();\n return config.document;\n }\n\n async getFileUrl(fileId: string): Promise<string[]> {\n const result = await fetch(`${FORMANT_API_URL}/v1/admin/files/query`, {\n method: \"POST\",\n body: JSON.stringify({\n fileIds: [fileId],\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const files = await result.json();\n return files.fileUrls;\n }\n\n /**\n * Starts a real-time connection with the remote device using WebRTC.\n * @param {number} [options] - Optional session type to be used for the connection.\n * @throws `Error` If the connection could not be established or if a connection already exists.\n * @returns {void}\n */\n async startRealtimeConnection(\n options: SessionType | IStartRealtimeConnectionOptions = {}\n ): Promise<void> {\n console.debug(`${new Date().toISOString()} :: Connection start requested`);\n\n if (this.rtcClient && this.connectionMonitorInterval !== undefined) {\n throw new Error(\n `Already created realtime connection to device ${this.id}`\n );\n }\n\n if (this.rtcClient) {\n console.warn(\n \"overwriting existing rtcClient due to missing connectionMonitorInterval\"\n );\n }\n\n const {\n sessionType,\n deadlineMs = 10_000,\n maxConnectRetries = 3,\n } = typeof options === \"number\"\n ? ({ sessionType: options } as IStartRealtimeConnectionOptions)\n : options;\n\n const pool = getRtcClientPool({\n sessionType,\n });\n const rtcClient = pool.get(this.handleMessage);\n\n let cancelled = false;\n const deadlinePromise = new Promise<never>((_, reject) =>\n setTimeout(() => {\n cancelled = true;\n reject(\n new Error(\n \"Connection timed out: the connection could not be finalized in time, \" +\n \"possibly due to network issues or misconfigured settings.\"\n )\n );\n }, deadlineMs)\n );\n\n const establishConnection = async (): Promise<string> => {\n if (\"isReady\" in rtcClient) {\n while (!rtcClient.isReady()) {\n this.assertNotCancelled(cancelled);\n await delay(100);\n }\n }\n\n // WebRTC requires a signaling phase when forming a new connection.\n const remoteDevicePeerId = await this.getRemoteDevicePeerId(rtcClient);\n this.assertNotCancelled(cancelled);\n\n let sessionId: string | undefined = undefined;\n\n // We can connect our real-time communication client to device peers by their ID\n for (let i = 0; i < maxConnectRetries; i++) {\n sessionId = await rtcClient.connect(remoteDevicePeerId);\n if (!!sessionId) break;\n delay(100);\n this.assertNotCancelled(cancelled);\n }\n\n if (!sessionId)\n throw new Error(\n `Session could not be created: exhausted ${maxConnectRetries} retries`\n );\n\n // Wait for the signaling process to complete...\n let retries = 0;\n while (!cancelled) {\n const connectionCompleted =\n rtcClient.getConnectionStatus(remoteDevicePeerId) === \"connected\";\n if (connectionCompleted) {\n break;\n }\n\n await delay(100);\n retries += 1;\n }\n this.assertNotCancelled(cancelled);\n\n console.debug(\n `${new Date().toISOString()} :: Connection completed after ${retries} retries`\n );\n\n return remoteDevicePeerId;\n };\n\n return Promise.race([establishConnection(), deadlinePromise])\n .then((remoteDevicePeerId) => {\n this.remoteDevicePeerId = remoteDevicePeerId;\n this.initConnectionMonitoring();\n this.rtcClient = rtcClient;\n this.emit(\"connect\");\n })\n .catch((err) => {\n console.debug(\n `${new Date().toISOString()} :: Connection failed: %o`,\n err\n );\n // cleanup on failure\n this.remoteDevicePeerId = null;\n rtcClient.shutdown().catch((shutdownErr: unknown) => {\n console.error(\"rtcClient cannot shutdown: %o\", shutdownErr);\n });\n this.emit(\"connection_failed\", err);\n throw err;\n });\n }\n\n private async getRemoteDevicePeerId(rtcClient: RtcClient) {\n // Each online device and user has a peer in the system\n const peers = await rtcClient.getPeers();\n\n // Find the device peer corresponding to the device's ID\n const devicePeer = peers.find((_) => _.deviceId === this.id);\n\n if (!isRtcPeer(devicePeer)) {\n // If the device is offline, we won't be able to find its peer.\n throw new Error(\"Cannot find peer, is the robot offline?\");\n }\n return devicePeer.id;\n }\n\n private initConnectionMonitoring() {\n this.connectionMonitorInterval = setInterval(async () => {\n let dataChannelClosed = false;\n\n if (this.rtcClient) {\n const rtcConnections = this.rtcClient.getConnections();\n const connection = rtcConnections.find(\n (_) => _.getRemotePeerId() === this.remoteDevicePeerId && _.isActive()\n );\n if (connection === undefined || !connection.isReady()) {\n console.debug(`${new Date().toISOString()} :: data channel closed`);\n dataChannelClosed = true;\n }\n }\n\n if (\n !this.rtcClient ||\n !this.remoteDevicePeerId ||\n (await this.rtcClient.getConnectionStatsInfo(\n this.remoteDevicePeerId\n )) === undefined ||\n dataChannelClosed\n ) {\n this.emit(\"disconnect\");\n this.stopRealtimeConnection().catch((err) => {\n console.error(err);\n });\n }\n }, 1000);\n }\n\n async getRemotePeer(): Promise<IRtcPeer> {\n // Each online device and user has a peer in the system\n const peers = await defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n ).getPeers();\n\n // Find the device peer corresponding to the device's ID\n const devicePeer = peers.find((_) => _.deviceId === this.id);\n return defined(\n devicePeer,\n \"Could not find remote peer for device \" + this.id\n );\n }\n\n async stopRealtimeConnection() {\n let throwNotStartedError = false;\n\n if (this.rtcClient) {\n this.stopConnectionMonitoring();\n\n if (this.remoteDevicePeerId) {\n await this.rtcClient.disconnect(this.remoteDevicePeerId);\n this.remoteDevicePeerId = null;\n } else {\n throwNotStartedError = true;\n }\n\n try {\n await this.rtcClient.shutdown();\n } finally {\n this.rtcClient = undefined;\n }\n }\n\n if (throwNotStartedError) {\n throw new Error(`Realtime connection hasn't been started for ${this.id}`);\n }\n }\n\n async isInRealtimeSession(): Promise<boolean> {\n const peers = await getPeers();\n const sessions = await getRealtimeSessions();\n const peer = peers.find((_) => _.deviceId === this.id);\n if (peer) {\n return sessions[peer.id].length > 0;\n }\n return false;\n }\n\n async getAvailableCommands(): Promise<Command[]> {\n const result = await fetch(\n `${FORMANT_API_URL}/v1/admin/command-templates/`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const commands = await result.json();\n return commands.items.map((i: any) => ({\n name: i.name,\n id: i.id,\n command: i.command,\n description: i.description,\n parameterEnabled: i.parameterEnabled,\n parameterValue: i.parameterValue,\n parameterMeta: i.parameterMeta,\n enabled: i.enabled,\n tags: i.tags,\n }));\n }\n\n async sendCommand(\n name: string,\n data?: string,\n time?: Date,\n metadata?: {}\n ): Promise<Response> {\n const commands = await this.getAvailableCommands();\n const command = commands.find((_) => _.name === name);\n if (!command) {\n throw new Error(`Could not find command with name \"${name}\"`);\n }\n\n let d: string = \"\";\n\n if (data === undefined) {\n if (command.parameterEnabled && command.parameterValue) {\n d = command.parameterValue;\n }\n } else {\n d = data;\n }\n\n let parameter = {\n value: d,\n scrubberTime: (time || new Date()).toISOString(),\n meta: {\n ...command.parameterMeta,\n ...metadata,\n },\n };\n\n const res = await fetch(`${FORMANT_API_URL}/v1/admin/commands`, {\n method: \"POST\",\n body: JSON.stringify({\n commandTemplateId: command.id,\n organizationId: this.organizationId,\n deviceId: this.id,\n command: command.command,\n parameter: parameter,\n userId: Authentication.currentUser?.id,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n\n return res;\n }\n\n async getCommand(id: string): Promise<Response> {\n const res = await fetch(`${FORMANT_API_URL}/v1/admin/commands/${id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return res;\n }\n\n async createCaptureStream(streamName: string) {\n const result = await fetch(`${FORMANT_API_URL}/v1/admin/capture-sessions`, {\n method: \"POST\",\n body: JSON.stringify({\n deviceId: this.id,\n streamName,\n tags: {},\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const captureSession = await result.json();\n return new CaptureStream(captureSession);\n }\n\n async getTelemetry(\n streamNameOrStreamNames: string | string[],\n start: Date,\n end: Date,\n tags?: { [key in string]: string[] }\n ) {\n return await getTelemetry(\n this.id,\n streamNameOrStreamNames,\n start,\n end,\n tags\n );\n }\n\n async getTelemetryStreams(): Promise<TelemetryStream[]> {\n const config = await this.getConfiguration();\n\n const result = await fetch(\n `${FORMANT_API_URL}/v1/queries/metadata/stream-names`,\n {\n method: \"POST\",\n body: JSON.stringify({\n deviceIds: [this.id],\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n const disabledList: string[] = [];\n const onDemandList: string[] = [];\n config.telemetry?.streams?.forEach((_) => {\n if (_.disabled !== true) {\n disabledList.push(_.name);\n }\n if (_.onDemand === true) {\n onDemandList.push(_.name);\n }\n });\n console.log(onDemandList);\n\n const data = await result.json();\n\n let streamNames = (data.items as string[])\n .filter((_) => !disabledList.includes(_))\n .map((_) => ({ name: _, onDemand: onDemandList.includes(_) }));\n\n return streamNames;\n }\n\n async createInterventionRequest<T extends InterventionType>(\n message: string,\n interventionType: InterventionType,\n interventionRequest: IInterventionTypeMap[T][\"request\"],\n tags?: { [key in string]: string[] }\n ): Promise<(id: string) => IInterventionTypeMap[T][\"response\"]> {\n const intervention = await fetch(\n `${FORMANT_API_URL}/v1/admin/intervention-requests`,\n {\n method: \"POST\",\n body: JSON.stringify({\n message,\n interventionType,\n time: new Date().toISOString(),\n deviceId: this.id,\n tags,\n data: interventionRequest,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n const interventionJson = await intervention.json();\n\n return interventionJson;\n }\n\n async addInterventionResponse<T extends InterventionType>(\n interventionId: string,\n interventionType: InterventionType,\n data: IInterventionTypeMap[T][\"response\"]\n ): Promise<IInterventionResponse> {\n const response = await fetch(\n `${FORMANT_API_URL}/v1/admin/intervention-responses`,\n {\n method: \"POST\",\n body: JSON.stringify({\n interventionId,\n interventionType,\n data,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const interventionResponse = await response.json();\n return interventionResponse;\n }\n\n async getAnnotationCount(query: IEventQuery, tagKey: string) {\n return await getAnnotationCount({ ...query, deviceIds: [this.id] }, tagKey);\n }\n\n async getAnnotationCountByIntervals(\n query: IEventQuery,\n tagKey: string,\n aggregate: AggregateLevel\n ) {\n return await getAnnotationCountByIntervals(\n { ...query, deviceIds: [this.id] },\n tagKey,\n aggregate\n );\n }\n\n async eventsCounter(\n eventTypes: EventType[],\n timeFrame: AggregateLevel,\n range: number,\n time: number,\n query?: IEventQuery\n ) {\n return await eventsCounter(eventTypes, timeFrame, range, time, {\n ...query,\n deviceIds: [this.id],\n });\n }\n\n async createShareLink(share: IShare, view: string) {\n share.scope.deviceIds = [this.id];\n return await createShareLink(share, view);\n }\n}\n","import { RtcClient, IRtcPeer } from \"@formant/realtime-sdk\";\nimport { delay } from \"../../../common/delay\";\nimport { IStreamCurrentValue } from \"../model/IStreamCurrentValue\";\nimport { ConfigurationDocument } from \"./device.types\";\nimport { BaseDevice } from \"./BaseDevice\";\n\nexport class PeerDevice extends BaseDevice {\n id!: string;\n\n private telemetryStreamActive = false;\n private streamTelemetry: { [key: string]: any } = {};\n\n constructor(public peerUrl: string) {\n super();\n }\n\n async getLatestTelemetry(): Promise<IStreamCurrentValue[]> {\n if (!this.telemetryStreamActive) {\n this.subscribeToTelemetry();\n }\n\n const telemetry = this.streamTelemetry as {\n [key in string]: { timestamp: string };\n };\n const entries = Object.entries(telemetry);\n return entries.map(([stream, latestValue]) => {\n const v: IStreamCurrentValue = {\n deviceId: this.id,\n streamName: stream,\n streamType: \"json\",\n currentValue: latestValue,\n currentValueTime: latestValue.timestamp,\n tags: {},\n };\n return v;\n });\n }\n\n private subscribeToTelemetry() {\n this.telemetryStreamActive = true;\n\n let previousBytesReceived = 0;\n\n // we use XHR because chunked encoding is broken in the react native fetch API\n const xhr = new XMLHttpRequest();\n xhr.responseType = \"text\";\n\n xhr.addEventListener(\"error\", (_) => {\n this.handleXHRError(\"error\");\n });\n xhr.addEventListener(\"abort\", (_) => {\n this.handleXHRError(\"abort\");\n });\n xhr.addEventListener(\"timeout\", (_) => {\n this.handleXHRError(\"timeout\");\n });\n xhr.addEventListener(\"readystatechange\", (_) => {\n if (xhr.readyState === XMLHttpRequest.DONE) {\n this.handleXHRError(\"closed\");\n }\n });\n\n // handle new data\n xhr.addEventListener(\"progress\", (event) => {\n const currentBytesReceived = event.loaded;\n const newBytesReceived = currentBytesReceived - previousBytesReceived;\n previousBytesReceived = currentBytesReceived;\n\n // Process the new data received\n const newData = xhr.responseText.substr(-newBytesReceived);\n\n const jsonObjects = newData.split(\"\\n\");\n jsonObjects.forEach((jsonObject) => {\n if (jsonObject.length > 0) {\n const parsedObject = JSON.parse(jsonObject);\n if (parsedObject.result?.datapoint) {\n const datapoint = parsedObject.result.datapoint;\n const stream = datapoint.stream;\n delete datapoint[\"stream\"];\n this.streamTelemetry[stream] = datapoint;\n }\n }\n });\n });\n\n xhr.open(\"POST\", `${this.peerUrl}/v1/telemetry`);\n\n xhr.send();\n }\n\n private handleXHRError(reason: string) {\n console.warn(`Telemetry stream ended: ${reason}`);\n this.telemetryStreamActive = false;\n }\n\n async getDeviceId(): Promise<string> {\n let result = await fetch(`${this.peerUrl}/v1/config`);\n const cfg = await result.json();\n return cfg.configuration.id;\n }\n\n async getConfiguration(): Promise<ConfigurationDocument> {\n let result = await fetch(`${this.peerUrl}/v1/config`);\n const cfg = await result.json();\n return cfg.configuration.document;\n }\n\n async startRealtimeConnection(sessionType?: number): Promise<void> {\n console.debug(`${new Date().toISOString()} :: Connection start requested`);\n\n if (this.rtcClient && this.connectionMonitorInterval !== undefined) {\n throw new Error(\n `Already created realtime connection to device ${this.id}`\n );\n }\n\n if (this.rtcClient) {\n console.warn(\n \"overwriting existing rtcClient due to missing connectionMonitorInterval\"\n );\n }\n\n const rtcClient = new RtcClient({\n lanOnlyMode: true,\n receive: this.handleMessage,\n sessionType,\n });\n\n await rtcClient.connectLan(this.peerUrl);\n\n // WebRTC requires a signaling phase when forming a new connection.\n // Wait for the signaling process to complete...\n while (rtcClient.getConnectionStatus(this.peerUrl) !== \"connected\") {\n await delay(100);\n }\n this.rtcClient = rtcClient;\n this.initConnectionMonitoring();\n }\n\n private initConnectionMonitoring() {\n this.connectionMonitorInterval = setInterval(async () => {\n let dataChannelClosed = false;\n\n if (this.rtcClient) {\n if (this.rtcClient.getConnectionStatus(this.peerUrl) !== \"connected\") {\n console.debug(`${new Date().toISOString()} :: data channel closed`);\n dataChannelClosed = true;\n }\n }\n\n if (!this.rtcClient || dataChannelClosed) {\n this.emit(\"disconnect\");\n this.stopRealtimeConnection().catch((err) => {\n console.error(err);\n });\n }\n }, 1000);\n }\n\n async getRemotePeer(): Promise<IRtcPeer> {\n return {\n id: this.peerUrl,\n organizationId: \"\",\n deviceId: this.id,\n capabilities: [],\n capabilitySet: {},\n };\n }\n\n async stopRealtimeConnection() {\n let throwNotStartedError = false;\n\n if (this.rtcClient) {\n this.stopConnectionMonitoring();\n\n if (this.id) {\n await this.rtcClient.disconnect(this.id);\n this.remoteDevicePeerId = null;\n } else {\n throwNotStartedError = true;\n }\n\n try {\n await this.rtcClient.shutdown();\n } finally {\n this.rtcClient = undefined;\n }\n }\n\n if (throwNotStartedError) {\n throw new Error(`Realtime connection hasn't been started for ${this.id}`);\n }\n }\n\n async sendCommand(\n name: string,\n data?: string,\n time?: Date,\n metadata?: {}\n ): Promise<Response> {\n const parameter = {\n value: data,\n scrubberTime: (time || new Date()).toISOString(),\n meta: metadata,\n };\n\n const res = await fetch(`${this.peerUrl}/v1/enqueue-command`, {\n method: \"POST\",\n body: JSON.stringify({\n command: name,\n parameter: parameter,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n return res;\n }\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function addDeviceToFleet(deviceId: string, fleetId: string) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices/${deviceId}`, {\n method: \"PATCH\",\n body: JSON.stringify({ fleetId }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { IQuery } from \"../model/IQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IStreamAggregateData } from \"../model/IStreamAggregateData\";\n\nexport async function aggregateTelemetry(query: IQuery) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/queries/queries`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n\n return (await data.json()).aggregates as IStreamAggregateData[];\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function deleteFleet(id: string): Promise<void> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n await fetch(`${FORMANT_API_URL}/v1/admin/fleets/${id}`, {\n method: \"DELETE\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IStreamColumn } from \"../model/IStreamColumn\";\n\n/**\n * retrieves a list of all available data streams that can be used for running analytics.\n * This function takes no arguments and returns a list of stream names that can be used for analyzing data.\n * @example\n * // Returns\n * [\n * {\n * streamName: \"$.agent.health\",\n streamType : \"health\"\n },\n {\n * streamName: \"up.hours\",\n streamType : \"numeric\"\n }\n ]\n */\nexport async function getAnalyticStreams() {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n\n const response = await fetch(\n `${FORMANT_API_URL}/v1/queries/analytics/streams`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return (await response.json()).items as IStreamColumn[];\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IAnalyticsModule } from \"../model/IAnalyticsModule\";\n\nexport async function getAnalyticsModules() {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n\n const response = await fetch(\n `${FORMANT_API_URL}/v1/admin/analytics-modules`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return (await response.json()).items as IAnalyticsModule;\n}\n","import { ISqlQuery } from \"../model/ISqlQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\n/**\n * Retrieves all rows\n * sqlQuery is required\n * @param query\n * @returns\n */\nexport async function getAnalyticsRows(query: ISqlQuery) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(`${FORMANT_API_URL}/v1/queries/analytics/rows`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await response.json();\n}\n","import { IDeviceQuery } from \"../model/IDeviceQuery\";\nimport { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function queryDevices(query: IDeviceQuery): Promise<Device[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices/query`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n\n return devices.items.map(\n (_: any) => new Device(_.id, _.name, _.organizationId, _.tags)\n );\n}\n","import { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { queryDevices } from \"./queryDevices\";\n\nexport async function getCurrentGroup(): Promise<Device[] | undefined> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n let urlParams = new URLSearchParams(\"\");\n\n if (typeof window !== \"undefined\" && window.location) {\n urlParams = new URLSearchParams(window.location.search);\n }\n\n const groupId = urlParams.get(\"group\");\n\n if (groupId === null || groupId.trim() === \"\") {\n return undefined;\n }\n const response = await fetch(\n `${FORMANT_API_URL}/v1/admin/groups/` + groupId,\n {\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n const { tagKey, tagValue } = await response.json();\n\n const devices = await queryDevices({\n tags: { [tagKey]: [tagValue] },\n enabled: true,\n type: \"default\",\n });\n\n return devices;\n}\n","import { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getDevice(deviceId: string): Promise<Device> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices/${deviceId}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const device = await data.json();\n const name = device.name as string;\n return new Device(deviceId, name, device.organizationId, device.tags);\n}\n","import { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getDevices(): Promise<Device[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/device-details/query`, {\n method: \"POST\",\n body: JSON.stringify({ enabled: true, type: \"default\" }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n devices.items;\n return devices.items.map(\n (_: any) =>\n new Device(\n _.id as string,\n _.name as string,\n _.organizationId as string,\n _.tags\n )\n );\n}\n","import { IEvent } from \"../model/IEvent\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getEvent(uuid: string): Promise<IEvent> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/events/query/id=${uuid}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n return (await data.json()).items as IEvent;\n}\n","import { FORMANT_API_URL } from \"../config\";\nimport { Authentication } from \"../Authentication\";\n\nexport async function getFileUrl(uuid: string) {\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/files/query`, {\n method: \"POST\",\n body: JSON.stringify({\n fileIds: [uuid],\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const result = await data.json();\n if (result.fileUrls.length === 0) {\n throw new Error(\"File not found\");\n }\n return result.fileUrls[0] as string;\n}\n","import { IFleet } from \"../model/IFleet\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getFleet(id: string): Promise<IFleet> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/fleets/${id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getFleetDevices(id: string): Promise<void> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/fleets/${id}/devices`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const fleets = await data.json();\n return fleets.items;\n}\n","import { IEvent } from \"../model/IEvent\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getInterventions(): Promise<IEvent[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const interventions = await fetch(\n `${FORMANT_API_URL}/v1/admin/intervention-requests`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return (await interventions.json()).items as IEvent[];\n}\n","import { IStreamCurrentValue } from \"../model/IStreamCurrentValue\";\nimport { IStreamTypeMap } from \"../model/IStreamTypeMap\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { Authentication } from \"../Authentication\";\n\nexport async function getLatestTelemetry(\n ...ids: (string | string[])[]\n): Promise<IStreamCurrentValue<keyof IStreamTypeMap>[]> {\n const deviceIds = ids.flat().filter((_) => !!_);\n\n if (deviceIds.length === 0) {\n return [];\n }\n\n const data = await fetch(\n `${FORMANT_API_URL}/v1/queries/stream-current-value`,\n {\n method: \"POST\",\n body: JSON.stringify({\n deviceIds,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const telemetry = await data.json();\n return telemetry.items;\n}\n","import { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { getDevices } from \"./getDevices\";\n\nexport async function getOnlineDevices(): Promise<Device[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/queries/online-devices`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n const onlineIds = devices.items as string[];\n const allDevices = await getDevices();\n return allDevices.filter((_) => onlineIds.includes(_.id));\n}\n","import { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { getDevices } from \"./getDevices\";\n\nexport async function getRealtimeDevices(): Promise<Device[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/signaling/peers`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n const onlineIds = devices.items.map(\n (_: { deviceId: string }) => _.deviceId\n ) as string[];\n const allDevices = await getDevices();\n return allDevices.filter((_) => onlineIds.includes(_.id));\n}\n","import { IStream } from \"../model/IStream\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getStreams(): Promise<IStream[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(`${FORMANT_API_URL}/v1/admin/streams`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const streams = await response.json();\n return streams.items.filter(\n (_: { enabled: boolean }) => _.enabled\n ) as IStream[];\n}\n","import { ISqlQuery } from \"../model/ISqlQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\n/**\n * @param taskColumns is required\n * @returns\n * All task reports\n * @example\n * // Body\n * const tasks = await getTaskReports({\n * taskColumns: [\n * {\n * columns: [\n * {\n * dataType: \"string\",\n * isNullable: true,\n * name: \"TYPE\",\n * tableName: \"custom\",\n * },\n * ],\n * name: \"DURATION_SECONDS\",\n * tableName: \"TASK_REPORTS_CLEANING_MODE\",\n * yAxis: \"DURATION_SECONDS\",\n * },\n * ],\n * });\n */\n\nexport async function getTaskReportRows(query: ISqlQuery) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(\n `${FORMANT_API_URL}/v1/queries/analytics/task-report-rows`,\n {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return await response.json();\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { ITaskReportColumn } from \"../model/ITaskReportColumn\";\n\n/**\n * retrieves a list of all available tables that can be used to create task reports.\n * This function takes no arguments and returns a list of table names that can be used for creating task reports.\n * @returns List all available tables\n * @example\n * // Returns\n *[\n * {\n * name: \"\",\n * tableName: \"TASK_REPORTS_CLEANING_MODE\",\n * columns: [\n * {\n * name: \"TYPE\",\n * isNullable: true,\n * dataType: \"string\",\n * tableName: \"custom\"\n * }\n * ]\n * }\n *]\n */\nexport async function getTaskReportTables() {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n\n const response = await fetch(\n `${FORMANT_API_URL}/v1/queries/analytics/task-reports`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return (await response.json()).items as ITaskReportColumn[];\n}\n","import { IFleet } from \"../model/IFleet\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function listFleets(): Promise<IFleet[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/fleets`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const fleets = await data.json();\n return fleets.items;\n}\n","import { IFleet } from \"../model/IFleet\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function patchFleet(\n id: string,\n role: Partial<IFleet>\n): Promise<IFleet> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/fleets/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify(role),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { IStream } from \"../model/IStream\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function patchStream(stream: IStream): Promise<IStream> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(\n `${FORMANT_API_URL}/v1/admin/streams/${stream.id}`,\n {\n method: \"PATCH\",\n body: JSON.stringify(stream),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return (await response.json()) as IStream;\n}\n","import { IView } from \"../model/IView\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function patchView(view: IView): Promise<IView> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(`${FORMANT_API_URL}/v1/admin/views/${view.id}`, {\n method: \"PATCH\",\n body: JSON.stringify(view),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return (await response.json()) as IView;\n}\n","import { ISqlQuery } from \"../model/ISqlQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { ISqlResult } from \"../model/ISqlResult\";\n\n/**\n *Retrieves all stream rows\n * @example\n * // Body\n * const analytics = await queryAnalytics({\n * aggregateLevel: \"day\",\n * orderByColumn: \"TIMESTAMP\",\n * streamColumns: [\n * {\n * streamName: \"consumables_residual_percentage\",\n * streamType: \"numeric set\",\n * },\n * ],\n * });\n * //Returns\n * {\n * aggregates: [],\n * columns: [\n * {\n * name: 'TIMESTAMP',\n * isNullable: true,\n * dataType: 'string',\n * tableName: 'NUMERIC_SET_MAIN'\n * }\n * ],\n * items: [\n * {\n * axisLabel: \"suction_blade\",\n * name: \"consumables_residual_percentage\",\n * tableName: \"NUMERIC_SET_TEST\",\n * time: \"2020-04-20T08:00:00.000Z\",\n * type: \"numeric set\",\n * unitLabel: \"percent\"\n * }\n * ],\n * rowCount: 14,\n * rows: []\n * sqlText: \"SELECT dateadd(day, dayofweek(TIMESTAMP), to_timestamp_tz('4/20/2020')) AS TIMESTAMP, SUM(VALUE)\"\n * }\n */\nexport async function queryAnalytics(query: ISqlQuery) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(`${FORMANT_API_URL}/v1/queries/analytics`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return (await response.json()) as ISqlResult;\n}\n","import { IFleet } from \"../model/IFleet\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function createFleet(fleet: IFleet): Promise<IFleet> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/fleets`, {\n method: \"POST\",\n body: JSON.stringify(fleet),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { IEventTriggerGroup } from \"../model/IEventTriggerGroup\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getAllEventTriggerGroup(): Promise<IEventTriggerGroup[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/event-trigger-groups`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n\n return (await data.json()).items as IEventTriggerGroup[];\n}\n","import { IEventTriggerGroup } from \"../model/IEventTriggerGroup\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getEventTriggerGroup(\n id: string\n): Promise<IEventTriggerGroup> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/event-trigger-groups/${id}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n return (await data.json()) as IEventTriggerGroup;\n}\n","import { IEventTriggerGroup } from \"../model/IEventTriggerGroup\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function patchEventTriggerGroup(\n id: string,\n eventTrigger: Partial<IEventTriggerGroup>\n): Promise<IEventTriggerGroup> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/event-trigger-groups/${id}`,\n {\n method: \"PATCH\",\n body: JSON.stringify(eventTrigger),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n return (await data.json()) as IEventTriggerGroup;\n}\n","import { defined } from \"../../common/defined\";\nimport { Authentication } from \"./Authentication\";\nimport { FORMANT_API_URL } from \"./config\";\nimport { Device } from \"./devices/Device\";\nimport { PeerDevice } from \"./devices/PeerDevice\";\nimport { addDeviceToFleet } from \"./api/addDeviceToFleet\";\nimport { aggregateTelemetry } from \"./api/aggregateTelemetry\";\nimport { createShareLink } from \"./api/createShareLink\";\nimport { deleteFleet } from \"./api/deleteFleet\";\nimport { eventsCounter } from \"./api/eventsCounter\";\nimport { getAnalyticStreams } from \"./api/getAnalyticsStreams\";\nimport { getAnalyticsModules } from \"./api/getAnalyticsModules\";\nimport { getAnalyticsRows } from \"./api/getAnalyticsRows\";\nimport { getAnnotationCount } from \"./api/getAnnotationCount\";\nimport { getAnnotationCountByIntervals } from \"./api/getAnnotationCountByIntervals\";\nimport { getCurrentGroup } from \"./api/getCurrentGroup\";\nimport { getDevice } from \"./api/getDevice\";\nimport { getDevices } from \"./api/getDevices\";\nimport { getEvent } from \"./api/getEvent\";\nimport { getFileUrl } from \"./api/getFileUrl\";\nimport { getFleet } from \"./api/getFleet\";\nimport { getFleetDevices } from \"./api/getFleetDevices\";\nimport { getInterventions } from \"./api/getInterventions\";\nimport { getLatestTelemetry } from \"./api/getLatestTelemetry\";\nimport { getOnlineDevices } from \"./api/getOnlineDevices\";\nimport { getPeers } from \"./api/getPeers\";\nimport { getRealtimeDevices } from \"./api/getRealtimeDevices\";\nimport { getRealtimeSessions } from \"./api/getRealtimeSessions\";\nimport { getStreams } from \"./api/getStreams\";\nimport { getTaskReportRows } from \"./api/getTaskReportRows\";\nimport { getTaskReportTables } from \"./api/getTaskreportTables\";\nimport { getTelemetry } from \"./api/getTelemetry\";\nimport { getViews } from \"./api/getViews\";\nimport { listFleets } from \"./api/listFleets\";\nimport { patchFleet } from \"./api/patchFleet\";\nimport { patchStream } from \"./api/patchStreams\";\nimport { patchView } from \"./api/patchView\";\nimport { queryAnalytics } from \"./api/queryAnalytics\";\nimport { queryDevices } from \"./api/queryDevices\";\nimport { queryEvents } from \"./api/queryEvents\";\nimport { queryTelemetry } from \"./api/queryTelemetry\";\nimport { createFleet } from \"./api/createFleet\";\nimport { getAllEventTriggerGroup } from \"./api/getAllEventTriggerGroup\";\nimport { getEventTriggerGroup } from \"./api/getEventTriggerGroup\";\nimport { patchEventTriggerGroup } from \"./api/patchEventTriggerGroup\";\n\nexport class Fleet {\n static defaultDeviceId: string | undefined;\n static knownContext: WeakRef<Device>[] = [];\n\n static createFleet = createFleet;\n static listFleets = listFleets;\n static getFleet = getFleet;\n static patchFleet = patchFleet;\n static deleteFleet = deleteFleet;\n static addDeviceToFleet = addDeviceToFleet;\n static getFleetDevices = getFleetDevices;\n\n static async setDefaultDevice(deviceId: string) {\n Fleet.defaultDeviceId = deviceId;\n }\n\n static async getCurrentDevice(): Promise<Device> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n if (!Fleet.defaultDeviceId) {\n throw new Error(\"No known default device\");\n }\n\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/device-details/query`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n const devices = await data.json();\n const device = devices.items.find(\n (_: { id: string }) => _.id === Fleet.defaultDeviceId\n );\n const name = device.name as string;\n const context = new Device(\n Fleet.defaultDeviceId,\n name,\n defined(Authentication.currentOrganization) as string,\n device.tags\n );\n Fleet.knownContext.push(new WeakRef(context));\n return context;\n }\n\n static async getPeerDevice(url: string): Promise<PeerDevice> {\n const peer = new PeerDevice(url);\n peer.id = await peer.getDeviceId();\n return peer;\n }\n\n static async getDevice(deviceId: string): Promise<Device> {\n const context = await getDevice(deviceId);\n Fleet.knownContext.push(new WeakRef(context));\n return context;\n }\n\n static aggregateTelemetry = aggregateTelemetry;\n static createShareLink = createShareLink;\n static eventsCounter = eventsCounter;\n static getAnalyticStreams = getAnalyticStreams;\n static getAnalyticsModules = getAnalyticsModules;\n static getAnalyticsRows = getAnalyticsRows;\n static getAnnotationCount = getAnnotationCount;\n static getAnnotationCountByIntervals = getAnnotationCountByIntervals;\n static getCurrentGroup = getCurrentGroup;\n static getDevices = getDevices;\n static getEvent = getEvent;\n static getFileUrl = getFileUrl;\n static getInterventions = getInterventions;\n static getLatestTelemetry = getLatestTelemetry;\n static getOnlineDevices = getOnlineDevices;\n static getPeers = getPeers;\n static getRealtimeDevices = getRealtimeDevices;\n static getRealtimeSessions = getRealtimeSessions;\n static getStreams = getStreams;\n static getTaskReportRows = getTaskReportRows;\n static getTaskReportTables = getTaskReportTables;\n static getTelemetry = getTelemetry;\n static getViews = getViews;\n static patchStream = patchStream;\n static patchView = patchView;\n static queryAnalytics = queryAnalytics;\n static queryDevices = queryDevices;\n static queryEvents = queryEvents;\n static queryTelemetry = queryTelemetry;\n static getAllEventTriggerGroup = getAllEventTriggerGroup;\n static getEventTriggerGroup = getEventTriggerGroup;\n static patchEventTriggergroup = patchEventTriggerGroup;\n}\n","import { FORMANT_API_URL } from \"./config\";\nimport { Authentication } from \"./Authentication\";\nimport { defined } from \"../../common/defined\";\nimport { ITags } from \"./model/ITags\";\n\nexport class KeyValue {\n public static async set(key: string, value: string, tags?: ITags) {\n try {\n const result = await fetch(FORMANT_API_URL + \"/v1/admin/key-value\", {\n method: \"POST\",\n body: JSON.stringify({\n organizationId: defined(Authentication.currentUser).organizationId,\n key,\n value,\n tags,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const keyValue = await result.json();\n if (result.status !== 200) {\n throw new Error(keyValue.message);\n }\n } catch (e: any) {\n throw e;\n }\n }\n\n public static async get(key: string): Promise<string> {\n try {\n const result = await fetch(\n FORMANT_API_URL + `/v1/admin/key-value/${key}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const keyValue = await result.json();\n if (result.status !== 200) {\n throw new Error(keyValue.message);\n }\n return keyValue.value;\n } catch (e: any) {\n throw e;\n }\n }\n\n public static async list(): Promise<string[]> {\n try {\n const result = await fetch(FORMANT_API_URL + \"/v1/admin/key-value\", {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const keyValueList = await result.json();\n if (result.status !== 200) {\n throw new Error(keyValueList.message);\n }\n return keyValueList.items;\n } catch (e: any) {\n throw e;\n }\n }\n\n public static async delete(key: string) {\n try {\n const result = await fetch(\n FORMANT_API_URL + `/v1/admin/key-value/${key}`,\n {\n method: \"DELETE\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n if (!result.ok) {\n throw new Error(\"Unable to handle request\");\n }\n return;\n } catch (e: any) {\n throw e;\n }\n }\n\n public static async query(keys: string[]) {\n try {\n const result = await fetch(\n FORMANT_API_URL + `/v1/admin/key-value/query`,\n {\n method: \"POST\",\n body: JSON.stringify({ keys }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n if (!result.ok) {\n throw new Error(\"Unable to handle request\");\n }\n const jsonResponse = await result.json();\n return jsonResponse.items;\n } catch (e: any) {\n throw e;\n }\n }\n}\n","import { decode } from \"base-64\";\n\nexport function stringToArrayBuffer(input: string): Uint8Array {\n return Uint8Array.from(decode(input), (_) => _.charCodeAt(0));\n}\n","export type BrowserType =\n | \"Firefox\"\n | \"Chrome\"\n | \"Edge\"\n | \"Safari\"\n | \"IE\"\n | \"Other\";\n\nexport function browser(): BrowserType {\n const { userAgent } = navigator;\n\n if (!userAgent) {\n return \"Other\";\n }\n\n if (userAgent.includes(\"Firefox/\")) {\n return \"Firefox\";\n } else if (userAgent.includes(\"Edg/\")) {\n return \"Edge\";\n } else if (userAgent.includes(\"Chrome/\")) {\n return \"Chrome\";\n } else if (userAgent.includes(\"Safari/\")) {\n return \"Safari\";\n } else if (userAgent.includes(\"MSIE/\") || userAgent.includes(\"Trident/\")) {\n return \"IE\";\n } else {\n return \"Other\";\n }\n}\n","import { IRtcStreamMessage } from \"@formant/realtime-sdk\";\nimport { Device } from \"./devices/Device\";\nimport { stringToArrayBuffer } from \"./utils/stringToArrayBuffer\";\nimport { fork } from \"../../common/fork\";\nimport { browser } from \"../../common/browser\";\nimport { RealtimeDataStream, RealtimeMessage } from \"./devices/device.types\";\n\nconst rtcAudioChunkStreamType = \"audio-chunk\";\n\nexport class AudioPlayer {\n private muted: boolean = false;\n\n public async play() {\n if (this.audioContext?.state === \"suspended\") {\n await this.audioContext?.resume();\n }\n this.muted = false;\n }\n\n public async pause() {\n await this.audioContext.suspend();\n this.muted = true;\n }\n\n private hasReceivedData: boolean = false;\n private audioContext: AudioContext;\n private chunks: Array<AudioBufferSourceNode> = [];\n private isPlaying: boolean = false;\n private startTime: number = 0;\n private lastChunkOffset: number = 0;\n private bufferSize: number = 3;\n\n public constructor(\n private device: Device,\n private stream: RealtimeDataStream\n ) {\n this.device.startListeningToRealtimeDataStream(stream);\n this.device.addRealtimeListener((_peerId: string, msg: RealtimeMessage) => {\n this.receive(msg);\n });\n\n if (browser() === \"Safari\" || browser() === \"IE\") {\n this.changeAudioWireFormat(\"wav\");\n } else {\n this.changeAudioWireFormat(\"opus\");\n }\n\n const AudioContext =\n window.AudioContext || (window as any).webkitAudioContext;\n\n this.audioContext = new AudioContext();\n }\n\n public destroy() {\n this.device.stopListeningToRealtimeDataStream(this.stream);\n }\n\n public receive = async (msg: IRtcStreamMessage) => {\n const data = msg.payload.audioChunk?.chunk_data;\n if (!data) {\n return;\n }\n\n if (!this.hasReceivedData) {\n this.hasReceivedData = true;\n }\n\n const { audioContext, muted } = this;\n if (\n !audioContext ||\n msg.header.stream.streamType !== rtcAudioChunkStreamType ||\n muted !== false\n ) {\n return;\n }\n const arrayBuffer = stringToArrayBuffer(data);\n try {\n await audioContext.decodeAudioData(\n arrayBuffer.buffer,\n this.scheduleChunk\n );\n } catch (error) {\n console.warn(\n \"Error decoding audio buffer, changing audioWireFormat on agent\",\n { error }\n );\n this.changeAudioWireFormat(\"wav\");\n }\n };\n\n private scheduleChunk = (buffer: AudioBuffer) => {\n const { audioContext } = this;\n\n if (!audioContext) {\n return;\n }\n if (this.chunks.length > this.bufferSize || this.isPlaying === false) {\n this.chunks.forEach((c) => {\n c.stop();\n });\n this.isPlaying = false;\n this.chunks = [];\n }\n const chunk = this.createChunk(buffer);\n if (!chunk) {\n return;\n }\n if (!chunk.buffer) {\n return;\n }\n if (this.isPlaying === false) {\n this.startTime = audioContext.currentTime;\n this.lastChunkOffset = 0;\n this.isPlaying = true;\n }\n chunk.start(this.startTime + this.lastChunkOffset, 0, buffer.duration);\n this.lastChunkOffset += chunk.buffer.duration;\n this.chunks.push(chunk);\n };\n\n private createChunk(buffer: AudioBuffer) {\n const { audioContext } = this;\n if (!audioContext) {\n return;\n }\n const source = audioContext.createBufferSource();\n source.buffer = buffer;\n source.connect(audioContext.destination);\n source.loop = false;\n source.onended = (_: Event) => {\n this.chunks.splice(this.chunks.indexOf(source), 1);\n if (this.chunks.length === 0) {\n this.isPlaying = false;\n }\n };\n\n return source;\n }\n\n private changeAudioWireFormat(newFormat: \"wav\" | \"opus\") {\n const { stream } = this;\n fork(\n (async () => {\n await this.device.changeStreamAudioType(stream.name, newFormat);\n })()\n );\n }\n}\n","import { FORMANT_API_URL } from \"./config\";\nimport { Authentication } from \"./Authentication\";\nimport { IAccount } from \"./model/IAccount\";\nimport { IAccountTree } from \"./model/IAccountTree\";\n\nexport class Account {\n static async listAccounts(): Promise<IAccount[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/accounts`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const accounts = await data.json();\n return accounts.items;\n }\n\n static async createAccounts(account: IAccount): Promise<IAccount> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/accounts`, {\n method: \"POST\",\n body: JSON.stringify(account),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async getAccount(id: string): Promise<IAccount> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/accounts/${id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async patchAccount(\n id: string,\n account: Partial<Account>\n ): Promise<IAccount> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/accounts/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify(account),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n static async deleteAccount(id: string): Promise<void> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n await fetch(`${FORMANT_API_URL}/v1/admin/accounts/${id}`, {\n method: \"DELETE\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n }\n\n static async getAccountTree(id: string): Promise<IAccountTree> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/accounts/${id}/tree`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return await data.json();\n }\n}\n","import { FORMANT_API_URL } from \"./config\";\nimport { Authentication } from \"./Authentication\";\nimport { IRole } from \"./model/IRole\";\n\nexport class Role {\n static async listRoles(): Promise<IRole[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/roles`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const roles = await data.json();\n return roles.items;\n }\n\n static async createRole(role: IRole): Promise<IRole> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/roles`, {\n method: \"POST\",\n body: JSON.stringify(role),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async getRole(id: string): Promise<IRole> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/roles/${id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async patchRole(id: string, role: Partial<IRole>): Promise<IRole> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/roles/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify(role),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async deleteRole(id: string): Promise<void> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n await fetch(`${FORMANT_API_URL}/v1/admin/roles/${id}`, {\n method: \"DELETE\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n }\n}\n","import { FORMANT_API_URL } from \"./config\";\nimport { Authentication } from \"./Authentication\";\nimport { IUser } from \"./model/IUser\";\n\nexport class User {\n static async listUsers(): Promise<IUser[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/users`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const users = await data.json();\n return users.items;\n }\n\n static async createUser(user: IUser): Promise<IUser> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/users`, {\n method: \"POST\",\n body: JSON.stringify(user),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async getUser(id: string): Promise<IUser> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/users/${id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async patchUser(id: string, user: Partial<IUser>): Promise<IUser> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/users/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify(user),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async deleteUser(id: string): Promise<void> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n await fetch(`${FORMANT_API_URL}/v1/admin/users/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify({ enabled: false, roleId: null, teamId: null }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n }\n}\n","export const accessLevels = [\"viewer\", \"operator\", \"administrator\"] as const;\n","import { accessLevels } from \"./accessLevels\";\n\nexport type AccessLevel = (typeof accessLevels)[number];\n\nexport const viewer = \"viewer\" as AccessLevel;\nexport const operator = \"operator\" as AccessLevel;\nexport const administrator = \"administrator\" as AccessLevel;\n","import { AggregateLevel } from \"./AggregateLevel\";\n\nexport const aggregateLevels: AggregateLevel[] = [\n \"year\",\n \"month\",\n \"week\",\n \"day\",\n \"hour\",\n \"minute\",\n];\n","export const annotationTypes = [\"tag\", \"sheet\", \"user\"];\n","export const eventTypes = [\n \"triggered-event\",\n \"intervention-request\",\n \"teleop-session-record\",\n \"port-forwarding-session-record\",\n \"command-request\",\n \"command-response\",\n \"command-delivery\",\n \"custom\",\n \"comment\",\n \"system\",\n \"annotation\",\n] as const;\n","export const healthStatuses = [\n \"unknown\",\n \"operational\",\n \"offline\",\n \"error\",\n] as const;\n","// NOTE: Also add an entry in IInterventionTypeMap\n\nexport const interventionTypes = [\"selection\", \"labeling\", \"teleop\"];\n","export const severities = [\"info\", \"warning\", \"error\", \"critical\"] as const;\n","export const videoMimeTypes = [\"video/mp4\"] as const;\n","export const timeout = (s: number) => {\n return new Promise((resolve) => setTimeout(resolve, s * 1000));\n};\n","// Application Initialization\nimport { App } from \"./App\";\nimport { Fleet } from \"./Fleet\";\nimport { Authentication } from \"./Authentication\";\n\ntry {\n const urlParams =\n typeof window !== \"undefined\" && window.location\n ? new URLSearchParams(window.location.search)\n : new URLSearchParams(\"\");\n\n const urlDevice = urlParams.get(\"device\");\n if (urlDevice) {\n Fleet.setDefaultDevice(urlDevice);\n }\n\n const urlAuth = urlParams.get(\"auth\");\n if (urlAuth) {\n Authentication.loginWithToken(urlAuth);\n }\n\n const moduleName = urlParams.get(\"module\");\n if (moduleName) {\n Authentication.listenForRefresh();\n }\n\n if (typeof window !== \"undefined\") {\n App.listenForConnectionEvents();\n }\n} catch (_) {}\n"],"names":["DEFAULT_FORMANT_API_URL","whichFormantApiUrl","global","urlParams","customUrl","FORMANT_API_URL","LoginFailureError","reason","__publicField","LoginChallengedError","challenge","AuthenticationStore","apiUrl","refreshAuthToken","addAccessTokenRefreshListener","email","password","options","advanced","result","auth","authentication","err","_","token","refreshToken","tokenData","decode","userId","_a","data","refreshData","resolve","askForFreshToken","request","response","getCurrentModuleContext","sendAppMessage","message","moduleName","handler","listener","event","msg","Authentication","getModuleConfiguration","id","disableAnalyticsBottomBar","goToDevice","deviceId","goToTime","date","requestModuleData","sendChannelData","channel","setModuleDateTimeRange","beforeInMilliseconds","afterInMilliseconds","setupModuleMenus","menus","showMessage","addChannelDataListener","addMenuListener","addModuleConfigurationListener","addModuleDataListener","addOverviewDeviceListener","millisecond","second","minute","hour","day","week","month","year","duration","filterDataByType","datas","type","filterDataByTime","start","end","startTime","endTime","timestamp","points","StoreCache","capacity","timeout","key","generator","cacheKey","entry","metadata","value","oldestKey","oldestEntry","thisKey","promise","existingMetadata","queryTelemetry","query","QueryStore","filter","name","latestOnly","q","startOfMinute","addMinutes","roundToNearestMinutes","isLive","addSeconds","error","queryStore","addStreamListener","streamNames","streamTypes","getDate","time","minTime","maxTime","prompt","schema","promptId","_App","configurationId","e","deadlineMs","done","reject","deadline","aborted","delay","ms","loop","App","defined","errorMessage","SessionTypes","SessionTypeConstants","singleton","RtcClientPool","peerId","it","createClient","ttlMs","target","prop","receiver","onReceive","proxy","client","instance","getToken","EnumRtcClientPools","receiveFn","RtcClient","SignalingPromiseClient","AppRtcClientPools","defaultRtcClientPool","getRtcClientPool","sessionType","CaptureStream","captureSession","authInfo","isRtcPeer","peer","DataChannel","dataChannel","m","d","s","l","a","i","Manipulator","device","config","_peerId","RequestDataChannel","channel_name","BinaryRequestDataChannel","requestIdToResponseMap","binaryId","success","payload","TextRequestDataChannel","BaseDevice","EventEmitter","cancelled","document","manipulators","streams","_b","_c","channelName","stream","devicePeer","streamName","newFormat","rtcConfig","p","encoder","serializeHash","jsonValue","encodedValue","compressedValue","deflate","fromByteArray","getViews","createShareLink","share","view","selectedView","origin","code","vailableAggregationIntervals","aggregateFunctions","getVariance","getStandardDeviation","getMax","getMin","getAverage","getSum","getCount","aggregateFunctionMap","aggregateByDateFunctions","dateFns","formatTimeFrameText","queryEvents","eventsCounter","eventTypes","timeFrame","range","dateFunctions","dateOffset","activePointInTimeLine","startDate","endDate","events","getAnnotationCount","tagKey","prev","current","getAnnotationCountByIntervals","aggregate","intervals","annotationsQuery","idx","responses","getTelemetry","deviceIdOrDeviceIds","streamNameOrStreamNames","tags","deviceIds","getRealtimeSessions","rtcClient","getPeers","createDevice","patchDevice","getDevicesData","queryDevicesData","disableDevice","Device","organizationId","version","fileId","maxConnectRetries","deadlinePromise","establishConnection","remoteDevicePeerId","sessionId","retries","shutdownErr","dataChannelClosed","connection","throwNotStartedError","peers","sessions","command","parameter","disabledList","onDemandList","interventionType","interventionRequest","interventionId","PeerDevice","peerUrl","telemetry","latestValue","previousBytesReceived","xhr","currentBytesReceived","newBytesReceived","jsonObject","parsedObject","datapoint","addDeviceToFleet","fleetId","aggregateTelemetry","deleteFleet","getAnalyticStreams","getAnalyticsModules","getAnalyticsRows","queryDevices","getCurrentGroup","groupId","tagValue","getDevice","getDevices","devices","getEvent","uuid","getFileUrl","getFleet","getFleetDevices","getInterventions","getLatestTelemetry","ids","getOnlineDevices","onlineIds","getRealtimeDevices","getStreams","getTaskReportRows","getTaskReportTables","listFleets","patchFleet","role","patchStream","patchView","queryAnalytics","createFleet","fleet","getAllEventTriggerGroup","getEventTriggerGroup","patchEventTriggerGroup","eventTrigger","_Fleet","context","url","Fleet","KeyValue","keyValue","keyValueList","keys","stringToArrayBuffer","input","browser","userAgent","rtcAudioChunkStreamType","AudioPlayer","audioContext","muted","arrayBuffer","buffer","c","chunk","AudioContext","source","Account","account","Role","User","user","accessLevels","viewer","operator","administrator","aggregateLevels","annotationTypes","healthStatuses","interventionTypes","severities","videoMimeTypes","urlDevice","urlAuth"],"mappings":"mrBAAMA,GAA0B,yBAOhB,SAAAC,GAAmBC,EAAaC,EAAuB,CAEjE,GAAA,CACE,GAAAA,EAAU,IAAI,eAAe,EACxB,MAAA,+BAGL,GAAAA,EAAU,IAAI,aAAa,EACtB,MAAA,6BAGL,GAAAA,EAAU,IAAI,eAAe,EACxB,MAAA,4BAGL,GAAAA,EAAU,IAAI,aAAa,EAAG,CAC1B,MAAAC,EAAYD,EAAU,IAAI,aAAa,EAC7C,GAAIC,IAAc,KACZ,GAAA,CACK,OAAA,IAAI,IAAIA,CAAS,EAAE,MAAA,MAC1B,CACQ,QAAA,KACN,qDAAqDA,GAAA,CAEzD,SAGO,CAGX,OAAA,OAAOF,EAAW,KAClB,oBAAqBA,GACrB,OAAOA,EAAO,iBAAoB,SAE3BA,EAAO,gBAGTF,EACT,CC3CO,MAAMK,EAAkBJ,GAC7B,OAAO,OAAW,IAAc,OAAS,WACzC,IAAI,gBACF,OAAO,OAAW,KAAe,OAAO,SACpC,OAAO,SAAS,OAChB,MACN,CACF,ECPO,MAAMK,UAA0B,KAAM,CAG3C,YAAYC,EAAgB,CAC1B,MAAM,cAAc,EAHbC,EAAA,eAIP,KAAK,OAASD,EACd,KAAK,KAAO,oBACL,OAAA,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,CAEO,MAAME,UAA6B,KAAM,CAG9C,YAAYC,EAAuB,CACjC,MAAM,kBAAkB,EAHjBF,EAAA,kBAIP,KAAK,UAAYE,EACjB,KAAK,KAAO,uBACL,OAAA,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,CCGO,MAAMC,EAAoD,CAgB/D,YAAY,CACV,OAAAC,EACA,iBAAAC,EACA,8BAAAC,CAAA,EAC8B,CAnBxBN,EAAA,sBACAA,EAAA,qBAAyB,IACzBA,EAAA,6BACAA,EAAA,qBACAA,EAAA,yBACAA,EAAA,eACAA,EAAA,2BAAsD,KACtDA,EAAA,sBAESA,EAAA,gBACAA,EAAA,0BACAA,EAAA,uCASf,KAAK,QAAUI,EACf,KAAK,kBAAoBC,EACzB,KAAK,+BAAiCC,CACxC,CAEA,IAAI,OAA4B,CAC9B,OAAO,KAAK,MACd,CAEA,IAAI,aAAiC,CACnC,OAAO,KAAK,YACd,CAEA,IAAI,qBAA0C,CAC5C,OAAO,KAAK,oBACd,CAEA,IAAI,iBAAsC,CACxC,OAAO,KAAK,gBACd,CAKA,IAAI,cAAmC,CACrC,OAAO,KAAK,aACd,CAKA,IAAI,cAAwB,CAC1B,OAAO,KAAK,aACd,CAQA,MAAM,MACJC,EACAC,EACAC,EAAkC,CAAA,EACe,CAC3C,KAAA,CAAE,SAAAC,EAAW,EAAU,EAAAD,EAEzB,GAAA,CACF,MAAME,EAAS,MAAM,MAAM,GAAG,KAAK,8BAA+B,CAChE,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,MAAAJ,EAAO,SAAAC,EAAU,EACxC,QAAS,CACP,eAAgB,kBAClB,CAAA,CACD,EAEKI,EAAO,MAAMD,EAAO,OACtB,GAAAA,EAAO,SAAW,IACd,MAAA,IAAIb,EAAkBc,EAAK,OAAO,EAG1C,GAAI,cAAeA,EACX,MAAA,IAAIX,EAAqBW,EAAK,SAAS,EAGzC,KAAA,CAAE,eAAAC,CAAmB,EAAAD,EAC3B,aAAM,KAAK,eACTC,EAAe,YACfA,EAAe,YAAA,EAGTH,EAEJ,CACE,OAAQ,UACR,eAAAG,CAAA,EAHFA,QAKGC,GAQP,GAPKJ,GACH,QAAQ,MAAM,iBAAkB,CAAE,IAAAI,CAAK,CAAA,EAGzC,KAAK,gBAAgB,QAASC,GAAMA,EAAE,EAAK,CAAC,EAC5C,KAAK,gBAAgB,QAEjB,CAACL,EACG,MAAAI,EAGR,OAAIA,aAAeb,EACV,CACL,OAAQ,aACR,UAAWa,EAAI,SAAA,EAIZ,CACL,OAAQ,UACR,OACEA,aAAehB,EACXgB,EAAI,OACJA,aAAe,MACfA,EAAI,QACJ,OAAOA,CAAG,CAAA,CAEpB,CACF,CAEA,MAAM,eAAeE,EAAeC,EAAuB,OACnD,MAAAC,EAAY,KAAK,MAAMC,SAAOH,EAAM,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,EACpD,GAAA,CACE,IAAAI,EAmBJ,GAlBA,KAAK,cACHF,EAAU,gBAAgB,GAC1BA,EAAU,gBAAgB,EAAE,MAAQ,QAElCA,EAAU,gBAAgB,IACvB,KAAA,qBAAuBA,EAAU,gBAAgB,EAAE,gBAEtDA,EAAU,wBAAwB,IAC/B,KAAA,qBAAuBA,EAAU,wBAAwB,GAG3D,KAAK,gBACRE,EAASF,EAAU,KAEjBA,EAAU,gBAAgB,GAAKA,EAAU,gBAAgB,EAAE,SACpDE,EAAAF,EAAU,gBAAgB,EAAE,QAGnCE,KAAUC,EAAA,KAAK,eAAL,YAAAA,EAAmB,MAAOD,EAAQ,CAC9C,MAAMT,EAAS,MAAM,MAAM,GAAG,KAAK,0BAA0BS,IAAU,CACrE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYJ,CAC7B,CAAA,CACD,EACKM,EAAO,MAAMX,EAAO,OACtB,GAAAA,EAAO,SAAW,IACd,MAAA,IAAI,MAAMW,EAAK,OAAO,EAE9B,KAAK,aAAeA,EAEtB,KAAK,OAASN,EACd,KAAK,gBAAgB,QAASD,GAAMA,EAAE,EAAI,CAAC,QACpCD,GACP,QAAQ,MAAM,0BAA2B,CAAE,IAAAA,CAAK,CAAA,EAChD,KAAK,gBAAgB,QAASC,GAAMA,EAAE,EAAK,CAAC,CAAA,QAC5C,CACA,KAAK,gBAAgB,OACvB,CAEIE,IACF,KAAK,cAAgBA,EACrB,YAAY,SAAY,CACtB,GAAI,KAAK,cAAe,CAUhB,MAAAM,EAAc,MATL,MAAM,MAAM,GAAG,KAAK,gCAAiC,CAClE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAClB,EACA,KAAM,KAAK,UAAU,CACnB,aAAc,KAAK,aAAA,CACpB,CAAA,CACF,GACgC,OAC5B,KAAA,OAASA,EAAY,eAAe,YAC3C,EACC,IAAO,GAAK,EAAE,EAErB,CAEA,iBAA2B,CACzB,OAAO,KAAK,SAAW,MACzB,CAKA,gBAAoC,CAClC,OAAO,KAAK,YACd,CAEA,MAAM,sBAAyC,CACzC,OAAA,KAAK,QAAU,OACV,GAEA,IAAI,QAASC,GAAY,CACzB,KAAA,gBAAgB,IAAIA,CAAO,CAAA,CACjC,CAEL,CAEA,MAAM,kBAAmB,CAGvB,MAAMC,EAAmB,IAAM,CAC7B,KAAK,cAAgB,OACrB,KAAK,kBAAkB,CAAA,EAGpB,KAAA,+BAAgCT,GAAkB,CACjD,KAAK,eAEP,aAAa,KAAK,aAAa,EAE5B,KAAA,cAAgB,WAAWS,EAAkB,IAAI,EACtD,KAAK,eAAeT,CAAK,CAAA,CAC1B,EAGI,KAAA,cAAgB,WAAWS,EAAkB,IAAI,CACxD,CAEA,MAAM,eAAelB,EAAe,CAC5B,MAAA,MAAM,GAAG,KAAK,wCAAyC,CAC3D,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,MAAAA,EAAO,EAC9B,QAAS,CACP,eAAgB,kBAClB,CAAA,CACD,CACH,CAWA,MAAM,sBAAsBmB,EAAwC,CAYlE,OAXiB,MAAM,MACrB,GAAG,KAAK,gDACR,CACE,OAAQ,OACR,KAAM,KAAK,UAAUA,CAAO,EAC5B,QAAS,CACP,eAAgB,kBAClB,CACF,CAAA,GAGc,EAClB,CAEA,MAAM,sCACJA,EACA,CACA,MAAMC,EAAW,MAAM,MACrB,GAAG,KAAK,mEACR,CACE,OAAQ,OACR,KAAM,KAAK,UAAUD,CAAO,EAC5B,QAAS,CACP,eAAgB,kBAClB,CACF,CAAA,EAGF,GAAIC,EAAS,GACJ,OAAA,MAAMA,EAAS,OAGlB,MAAA,IAAI,MAAM,mDAAmD,CACrE,CAEA,MAAM,gBAAgBX,EAAe,CAQ5B,OAAA,MAPU,MAAM,MAAM,GAAG,KAAK,qCAAsC,CACzE,OAAQ,OACR,KAAM,KAAK,UAAUA,CAAK,EAC1B,QAAS,CACP,eAAgB,kBAClB,CAAA,CACD,GACqB,MACxB,CAEA,MAAM,QAAQA,EAAe,CAUrB,MAAAO,EAAc,MATL,MAAM,MAAM,GAAG,KAAK,gCAAiC,CAClE,OAAQ,OACR,QAAS,CACP,eAAgB,kBAClB,EACA,KAAM,KAAK,UAAU,CACnB,aAAcP,CAAA,CACf,CAAA,CACF,GACgC,OACjC,MAAM,KAAK,eAAeO,EAAY,eAAe,YAAaP,CAAK,CACzE,CACF,CCrVO,SAASY,GAAyC,CACvD,OAAM,OAAO,OAAW,KAAe,OAAO,SAI5B,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAC3C,IAAI,QAAQ,EAJpB,IAKX,CCLO,SAASC,EAAeC,EAAqB,CAC9C,GAAA,EAAE,QAAU,OAAO,QACf,MAAA,IAAI,MAAM,4CAA4C,EAEvD,OAAA,OAAO,YAAYA,EAAS,GAAG,CACxC,CCJO,SAASzB,GAAmB,CACjC,MAAM0B,EAAaH,IACnB,GAAI,CAACG,EACG,MAAA,IAAI,MAAM,mBAAmB,EAEtBF,EAAA,CACb,KAAM,qBACN,OAAQE,CAAA,CACT,CACH,CCVO,SAASzB,EACd0B,EACY,CACZ,SAASC,EAASC,EAAyC,CACzD,MAAMC,EAAMD,EAAM,KACdC,EAAI,OAAS,cACfH,EAAQG,EAAI,KAAK,CAErB,CAEO,cAAA,iBAAiB,UAAWF,CAAQ,EACpC,IAAM,CACJ,OAAA,oBAAoB,UAAWA,CAAQ,CAAA,CAElD,CCVa,MAAAG,EAAuC,IAAIjC,GAAoB,CAC1E,OAAQN,EACR,iBAAAQ,EACA,8BAAAC,CACF,CAAC,ECPD,eAAsB+B,GACpBC,EAC6B,CAW7B,OAD4B,MATX,MAAM,MACrB,GAAGzC,oCAAkDyC,IACrD,CACE,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CACF,CAAA,GAEyC,QAChB,aAC7B,CCfO,SAASG,IAA4B,CAC3BV,EAAA,CACb,KAAM,4BAAA,CACP,CACH,CCJO,SAASW,GAAWC,EAAkB,CAC5BZ,EAAA,CACb,KAAM,eACN,SAAAY,CAAA,CACD,CACH,CCLO,SAASC,GAASC,EAAkB,CAC1Bd,EAAA,CACb,KAAM,aACN,KAAMc,EAAK,QAAQ,CAAA,CACpB,CACH,CCJO,SAASC,IAAoB,CAClC,MAAMb,EAAaH,IACnB,GAAI,CAACG,EACG,MAAA,IAAI,MAAM,mBAAmB,EAEtBF,EAAA,CACb,KAAM,sBACN,OAAQE,CAAA,CACT,CACH,CCTgB,SAAAc,GAAgBC,EAAiBxB,EAAW,CAC1D,MAAMS,EAAaH,IACnB,GAAI,CAACG,EACG,MAAA,IAAI,MAAM,mBAAmB,EAGtBF,EAAA,CACb,KAAM,oBACN,OAAQE,EACR,QAAAe,EACA,KAAAxB,CAAA,CACD,CACH,CCZgB,SAAAyB,GACdC,EACAC,EACA,CACA,MAAMlB,EAAaH,IACnB,GAAI,CAACG,EACG,MAAA,IAAI,MAAM,mBAAmB,EAEtBF,EAAA,CACb,KAAM,6BACN,OAAQE,EACR,OAAQiB,EACR,MAAOC,GAAuB,CAAA,CAC/B,CACH,CCdO,SAASC,GAAiBC,EAA4B,CAC3D,MAAMpB,EAAaH,IACnB,GAAI,CAACG,EACG,MAAA,IAAI,MAAM,mBAAmB,EAEtBF,EAAA,CACb,KAAM,qBACN,OAAQE,EACR,MAAAoB,CAAA,CACD,CACH,CCXO,SAASC,GAAYtB,EAAiB,CAC3CD,EAAe,CAAE,KAAM,eAAgB,QAAAC,CAAS,CAAA,CAClD,CCFgB,SAAAuB,GACdP,EACAd,EACA,CACM,MAAAC,EAAYC,GAA4C,CAC5D,MAAMC,EAAMD,EAAM,KACdC,EAAI,OAAS,gBAAkBA,EAAI,UAAYW,GACzCd,EAAA,CACN,OAAQG,EAAI,OACZ,KAAMA,EAAI,IAAA,CACX,CACH,EAGK,cAAA,iBAAiB,UAAWF,CAAQ,EACpC,IAAM,OAAO,oBAAoB,UAAWA,CAAQ,CAC7D,CChBO,SAASqB,GAAgBtB,EAAkC,CAC1D,MAAAC,EAAYC,GAA4C,CAC5D,MAAMC,EAAMD,EAAM,KACdC,EAAI,OAAS,4BACfH,EAAQG,EAAI,IAAI,CAClB,EAGK,cAAA,iBAAiB,UAAWF,CAAQ,EACpC,IAAM,OAAO,oBAAoB,UAAWA,CAAQ,CAC7D,CCPO,SAASsB,GACdvB,EACA,CACM,MAAAC,EAAYC,GAA4C,CAC5D,MAAMC,EAAMD,EAAM,KACdC,EAAI,OAAS,wBACfH,EAAQG,CAAiC,CAC3C,EAGK,cAAA,iBAAiB,UAAWF,CAAQ,EACpC,IAAM,OAAO,oBAAoB,UAAWA,CAAQ,CAC7D,CCgBO,SAASuB,GAAsBxB,EAAqC,CACzE,MAAMD,EAAaH,IACfG,GACFF,EAAe,CAAE,KAAM,sBAAuB,OAAQE,CAAY,CAAA,EAE9D,MAAAE,EAAYC,GAA4C,CAC5D,MAAMC,EAAMD,EAAM,KACdC,EAAI,OAAS,eACPH,EAAA,CACN,QAASG,EAAI,QACb,KAAMA,EAAI,KACV,WAAYA,EAAI,UAAA,CACjB,CACH,EAGK,cAAA,iBAAiB,UAAWF,CAAQ,EACpC,IAAM,OAAO,oBAAoB,UAAWA,CAAQ,CAC7D,CChDO,SAASwB,GACdzB,EACA,CACeH,EAAA,CAAE,KAAM,iBAAA,CAAmB,EACpC,MAAAI,EAAYC,GAA4C,CAC5D,MAAMC,EAAMD,EAAM,KACdC,EAAI,OAAS,oBACfH,EAAQG,EAAI,IAAI,CAClB,EAGK,cAAA,iBAAiB,UAAWF,CAAQ,EACpC,IAAM,OAAO,oBAAoB,UAAWA,CAAQ,CAC7D,CChBA,MAAMyB,GAAc,EACdC,EAAS,IACTC,EAAS,GAAKD,EACdE,EAAO,GAAKD,EACZE,EAAM,GAAKD,EACXE,GAAO,EAAID,EACXE,GAAQ,GAAKF,EACbG,GAAO,IAAMH,EAENI,EAAW,CACtB,YAAAR,GACA,OAAAC,EACA,OAAAC,EACA,KAAAC,EACA,IAAAC,EACA,KAAAC,GACA,MAAAC,GACA,KAAAC,EACF,ECfgB,SAAAE,GACdC,EACAC,EACe,CACR,OAAAD,EAAM,OAAQrD,GAAMsD,EAAK,SAAStD,EAAE,IAAI,CAAC,CAClD,CCNgB,SAAAuD,GACdF,EACAG,EACAC,EACe,CACT,MAAAC,EAAYF,EAAM,UAClBG,EAAUF,EAAI,UACb,OAAAJ,EACJ,IAAK9C,IAAU,CACd,GAAGA,EACH,OAAQA,EAAK,OAAO,OAClB,CAAC,CAACqD,CAAS,IAAMA,GAAaF,GAAaE,EAAYD,CACzD,CAAA,EACA,EACD,OAAO,CAAC,CAAE,OAAAE,CAAO,IAAMA,EAAO,OAAS,CAAC,CAC7C,CCNO,MAAMC,CAAuB,CAMlC,YAAY,CACV,SAAAC,EACA,QAAAC,CACF,EAA6C,GAAI,CARzC/E,EAAA,mBAAc,KACdA,EAAA,oBAAe,KACfA,EAAA,iBACAA,EAAA,gBAMN,KAAK,SAAW8E,GAAY,IACvB,KAAA,QAAUC,GAAWb,EAAS,MACrC,CAEO,IAAIc,EAAUC,EAAqD,CAClE,MAAAC,EAAW,KAAK,cAAcF,CAAG,EACjCG,EAAQ,KAAK,QAAQ,IAAID,CAAQ,EACjCE,EAAW,KAAK,SAAS,IAAIF,CAAQ,EAW3C,OARGC,IAAU,QACRC,IAAYA,GAAA,YAAAA,EAAU,WAAW,WAAY,KAAK,IAAI,IACzD,EAACA,GAAA,MAAAA,EAAU,aACXH,GAEK,KAAA,SAASD,EAAKC,EAAW,CAAA,EAG5BE,IAAU,QAAaC,GAAYA,EAAS,YAAc,OACrDA,EAAS,UAGXD,CACT,CAEO,IAAIH,EAAUK,EAAc,CAC3B,MAAAH,EAAW,KAAK,cAAcF,CAAG,EAClC,KAAA,SAAS,IAAIE,EAAU,CAC1B,WAAY,GACZ,WAAY,IAAI,KAAK,KAAK,IAAI,EAAI,KAAK,OAAO,EAC9C,UAAWG,CAAA,CACZ,EACI,KAAA,QAAQ,IAAIH,EAAUG,CAAK,EAE5B,KAAK,SAAS,KAAO,KAAK,UAC5B,KAAK,kBAAkB,CAE3B,CAEO,OAAQ,CACb,KAAK,QAAQ,QACZ,CAAA,GAAG,KAAK,SAAS,QAAQ,EAAE,QAASA,GAAWA,EAAM,WAAa,EAAM,CAC3E,CAEO,SAASL,EAAmB,CAC5B,KAAA,SAAS,OAAOA,CAAG,EACnB,KAAA,QAAQ,OAAOA,CAAG,CACzB,CAEQ,cAAcA,EAAoB,CACjC,OAAA,KAAK,UAAUA,CAAG,CAC3B,CAEQ,mBAAoB,CACtB,GAAA,KAAK,SAAS,KAAO,EACvB,OAEI,KAAA,CAACA,CAAG,EAAI,CAAC,GAAG,KAAK,SAAS,QAAS,CAAA,EAAE,OACzC,CAAC,CAACM,EAAWC,CAAW,EAAG,CAACC,EAASL,CAAK,IACxCA,EAAM,WAAW,QAAY,EAAAI,EAAY,WAAW,UAChD,CAACC,EAASL,CAAK,EACf,CAACG,EAAWC,CAAW,CAAA,EAE/B,KAAK,SAASP,CAAG,CACnB,CAEQ,SAASA,EAAUS,EAAyB,CAC5C,MAAAP,EAAW,KAAK,cAAcF,CAAG,EACjCU,EAAmB,KAAK,SAAS,IAAIR,CAAQ,GAAK,GACnD,KAAA,SAAS,IAAIA,EAAU,CAC1B,GAAGQ,EACH,WAAY,GACZ,WAAY,IAAI,KAAK,KAAK,IAAI,EAAI,KAAK,OAAO,CAAA,CAC/C,EACD,WAAW,IAAM,CAEbD,EAAQ,KAAMJ,GAAU,CACtB,MAAMD,EAAW,KAAK,SAAS,IAAIF,CAAQ,EAC1B,EAACE,GAAA,MAAAA,EAAU,aAErB,KAAA,IAAIJ,EAAKK,CAAK,CACrB,CACD,GAEF,CAAC,CACN,CACF,CCtGA,eAAsBM,EAAeC,EAAe,CAC9C,GAAA,CAACxD,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAW7B,OAAA,MATK,MAAM,MAAM,GAAGvC,uBAAsC,CAChE,OAAQ,OACR,KAAM,KAAK,UAAU+F,CAAK,EAC1B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYxD,EAAe,KAC5C,CAAA,CACD,GAEkB,KAAA,GAAQ,KAC7B,CCHO,MAAMyD,EAAW,CAAjB,cACG7F,EAAA,uBAAkB,IAAI6E,EAG5B,CACA,SAAU,IACV,QAAS,GAAKX,EAAS,MAAA,CACxB,GAEOlE,EAAA,2BAAsB,IAAI6E,EAGhC,CACA,SAAU,IACV,QAAS,IAAMX,EAAS,WAAA,CACzB,GAEM,YACL4B,EACAC,EACA1B,EACAE,EACAC,EACAwB,EAAsB,GACuB,CAC7C,MAAMC,EAAa,CACjB,GAAGH,EACH,MAAO,CAAC,GAAGC,CAAI,EACf,MAAO,CAAC,GAAG1B,CAAI,CAAA,EAEX/C,EAAO,KAAK,MAAM2E,EAAG1B,EAAOC,EAAKwB,CAAU,EAC7C,OAAA1E,IAAS,QAAaA,IAAS,gBAC1BA,EAEF6C,GAAiB7C,EAAM+C,CAAI,CACpC,CAEO,MACLyB,EACAvB,EACAC,EACAwB,EAAsB,GACuB,CAC7C,MAAMC,EAAY,CAChB,GAAGH,EACH,MAAOI,EAAA,cAAc3B,CAAK,EAAE,YAAY,EACxC,IAAKyB,EACDxB,EAAI,cACJ2B,EAAAA,WAAWC,EAAA,sBAAsB5B,CAAG,EAAG,CAAC,EAAE,YAAY,EAC1D,WAAAwB,CAAA,EAEIK,EAAS7B,EAAM8B,EAAA,WAAe,IAAA,KAAQ,GAAG,EAE3C,IAAAhF,EAYJ,OAXI+E,EACK/E,EAAA,KAAK,eAAe2E,CAAC,EAErB3E,EAAA,KAAK,WAAW2E,CAAC,EAGtB,CAAC3E,GAAQA,IAAS,iBAKlB0E,EACK1E,EAGFgD,GAAiBhD,EAAMiD,EAAOC,CAAG,CAC1C,CAEQ,WACNoB,EAC6C,CAC7C,OAAO,KAAK,gBAAgB,IAAIA,EAAO,SAAY,CAC7C,GAAA,CACK,OAAA,MAAMD,EAAeC,CAAK,QAC1BW,GACD,MAAAA,CACR,CAAA,CACD,CACH,CAEQ,eACNX,EAC6C,CAC7C,OAAO,KAAK,oBAAoB,IAAIA,EAAO,SAAY,CACjD,GAAA,CACK,OAAA,MAAMD,EAAeC,CAAK,QAC1BW,GACD,MAAAA,CACR,CAAA,CACD,CACH,CACF,CC1GA,MAAMC,GAAa,IAAIX,GAEP,SAAAY,GACdC,EACAC,EACA3E,EACY,CACN,MAAAC,EAAYC,GAA4C,CAC5D,MAAMC,EAAMD,EAAM,KACd,GAAAC,EAAI,OAAS,cAAe,CAC9B,KAAM,CAAE,MAAAoC,EAAO,IAAAC,GAAQrC,EAAI,WAC3BH,EACEwE,GAAW,YACT,CAAC,EACDE,EACAC,EACA,IAAI,KAAKpC,CAAK,EACd,IAAI,KAAKC,CAAG,EACZ,EACF,CAAA,EAEJ,EAGK,cAAA,iBAAiB,UAAWvC,CAAQ,EACpC,IAAM,OAAO,oBAAoB,UAAWA,CAAQ,CAC7D,CC5BsB,eAAA2E,GAAQC,EAAaC,EAAgBC,EAAgB,CAClE,OAAA,IAAI,QAASvF,GAAY,CACfK,EAAA,CACb,KAAM,eACN,QAAAiF,EACA,QAAAC,EACA,KAAAF,CAAA,CACD,EACK,MAAA7E,EAAWE,GAA4C,CAC3D,MAAMC,EAAMD,EAAM,KACdC,EAAI,OAAS,kBACR,OAAA,oBAAoB,UAAWH,CAAO,EAC7CR,EAAQW,EAAI,IAAI,EAClB,EAEK,OAAA,iBAAiB,UAAWH,CAAO,CAAA,CAC3C,CACH,CChBsB,eAAAgF,GACpBC,EACAxG,EACc,CACP,OAAA,IAAI,QAASe,GAAY,CAC9B,MAAM0F,EAAW,KAAK,OAAO,EAAE,SAAS,EACzBrF,EAAA,CACb,KAAM,SACN,SAAAqF,EACA,OAAAD,EACA,OAAQxG,GAAA,YAAAA,EAAS,OACjB,WAAYA,GAAA,YAAAA,EAAS,UAAA,CACtB,EACK,MAAAuB,EAAWE,GAA4C,CAC3D,MAAMC,EAAMD,EAAM,KACdC,EAAI,OAAS,mBAAqBA,EAAI,WAAa+E,GACrD1F,EAAQW,EAAI,IAAI,EAEX,OAAA,oBAAoB,UAAWH,CAAO,CAAA,EAExC,OAAA,iBAAiB,UAAWA,CAAO,CAAA,CAC3C,CACH,CCHO,MAAMmF,EAAN,KAAU,CAGf,OAAO,UAAoB,CACzB,OAAOvF,EAA8B,IAAA,IACvC,CAEA,aAAa,+BAA6D,CACpE,IAAAjC,EAAY,IAAI,gBAAgB,EAAE,EAElC,OAAO,OAAW,KAAe,OAAO,WAC1CA,EAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM,GAGlD,MAAAyH,EAAkBzH,EAAU,IAAI,eAAe,EAErD,GAAI,EAAAyH,IAAoB,MAAQA,EAAgB,KAAA,IAAW,IAIpD,OAAA/E,GAAuB+E,EAAgB,KAAA,CAAM,CACtD,CA4BA,WAAW,UAA2B,CACpC,OAAOD,EAAI,SACb,CAEA,OAAO,2BAAwC,CACvC,MAAAlF,EAAYoF,GAAwC,CAClD,KAAA,CAAE,KAAA/F,CAAS,EAAA+F,EACb/F,EAAK,OAAS,mBAChB,KAAK,UAAYA,EAAK,OACxB,EAGK,cAAA,iBAAiB,UAAWW,CAAQ,EACpC,IAAM,OAAO,oBAAoB,UAAWA,CAAQ,CAC7D,CAEA,OAAO,gBAAgBqF,EAAqB,IAAyB,CACnE,OAAO,IAAI,QAAQ,CAACC,EAAMC,IAAW,CACnC,MAAMC,EAAW,WACf,IAAMD,EAAO,IAAI,MAAM,iCAAiC,CAAC,EACzDF,CAAA,EAGItF,EAAWqF,GAAwC,CAChD,OAAA,oBAAoB,UAAWrF,CAAO,EAC7C,aAAayF,CAAQ,EAEf,KAAA,CAAE,KAAAnG,CAAS,EAAA+F,EACb/F,EAAK,OAAS,mBAChB,KAAK,UAAYA,EAAK,OACtBiG,EAAKjG,EAAK,MAAM,EAClB,EAGK,OAAA,iBAAiB,UAAWU,CAAO,EAC3BH,EAAA,CAAE,KAAM,gBAAA,CAAkB,CAAA,CAC1C,CACH,CAEA,OAAO,kBAAkByF,EAAqB,IAAsB,CAClE,IAAII,EAAU,GACd,MAAMD,EAAW,IAAI,QAAc,CAAC1G,EAAGyG,IAAW,CAChD,WAAW,IAAM,CACLE,EAAA,GACHF,EAAA,IAAI,MAAM,iCAAiC,CAAC,GAClDF,CAAU,CAAA,CACd,EAEKK,EAASC,GAAe,IAAI,QAASL,GAAS,WAAWA,EAAMK,CAAE,CAAC,EAElEC,EAAO,SAA2B,CAEtC,IADA,MAAMF,EAAM,EAAE,EACP,CAACD,GACF,OAAK,UAAa,MAAM,KAAK,kBAGjC,MAAMC,EAAM,GAAG,CACjB,EAGF,OAAO,QAAQ,KAAK,CAACF,EAAUI,EAAA,CAAM,CAAC,CACxC,CACF,EA/GO,IAAMC,EAANX,EACLnH,EADW8H,EACJ,0BAA0BlG,GAuBjC5B,EAxBW8H,EAwBJ,4BAA4BvF,IACnCvC,EAzBW8H,EAyBJ,aAAatF,IACpBxC,EA1BW8H,EA0BJ,WAAWpF,IAClB1C,EA3BW8H,EA2BJ,mBAAmBzH,GAC1BL,EA5BW8H,EA4BJ,oBAAoBlF,IAC3B5C,EA7BW8H,EA6BJ,kBAAkBjF,IACzB7C,EA9BW8H,EA8BJ,yBAAyB/E,IAChC/C,EA/BW8H,EA+BJ,mBAAmB5E,IAC1BlD,EAhCW8H,EAgCJ,cAAc1E,IAGrBpD,EAnCW8H,EAmCJ,gCAAgCxH,GACvCN,EApCW8H,EAoCJ,yBAAyBzE,IAChCrD,EArCW8H,EAqCJ,kBAAkBxE,IACzBtD,EAtCW8H,EAsCJ,iCAAiCvE,IACxCvD,EAvCW8H,EAuCJ,wBAAwBtE,IAC/BxD,EAxCW8H,EAwCJ,4BAA4BrE,IACnCzD,EAzCW8H,EAyCJ,oBAAoBrB,IAG3BzG,EA5CW8H,EA4CJ,UAAUlB,IACjB5G,EA7CW8H,EA6CJ,SAASd,IAEhBhH,EA/CW8H,EA+CI,YAA4B,MCtE7B,SAAAC,EAAW1C,EAAsB2C,EAA0B,CACzE,GAAI3C,IAAU,OACL,OAAAA,EAEH,MAAA,IAAI,MAAM2C,GAAgB,oBAAoB,CACtD,CCDO,MAAMC,EAAe,CAC1B,QAAS,EACT,OAAQ,EACR,aAAc,EACd,QAAS,EACT,SAAU,CACZ,EAGaC,GAAuB,CAClC,GAAGD,EAEH,QAASA,EAAa,QACtB,OAAQA,EAAa,OACrB,YAAaA,EAAa,aAC1B,QAASA,EAAa,QACtB,SAAUA,EAAa,SAEvB,QAASA,EAAa,QACtB,OAAQA,EAAa,OACrB,YAAaA,EAAa,aAC1B,QAASA,EAAa,QACtB,SAAUA,EAAa,QACzB,ECXME,EAAY,OAAO,wBAAwB,SAE1C,MAAMC,CAAiD,CAS5D,YAAY3H,EAAmC,CAR/CT,EAAA,KAACqB,GAAuB,MAEPrB,EAAA,qBACAA,EAAA,cACAA,EAAA,qBACTA,EAAA,0BAA+C,KAC/CA,EAAA,uBAAwD,MA8DxDA,EAAA,gBAAsB,CAACqI,EAAQvG,IAAY,CACjD,KAAK,eAAe,QAASwG,GAAOA,GAAA,YAAAA,EAAKD,EAAQvG,EAAQ,CAAA,GA5DzD,KAAM,CAAE,aAAAyG,EAAc,MAAAC,EAAQ,CAAA,EAAM/H,EACpC,KAAK,aAAe8H,EACpB,KAAK,MAAQ,KAAK,IAAIC,EAAO,CAAC,EAC9B,KAAK,aAAe,CAClB,IAAK,CAACC,EAAQC,EAAMC,IAAa,CAC/B,OAAQD,EAAM,CACZ,IAAK,WACI,MAAA,IAAM,KAAK,gBAAgBC,CAAQ,EAC5C,QACE,OAAO,QAAQ,IAAIF,EAAQC,EAAMC,CAAQ,CAC7C,CACF,CAAA,CAEJ,CAEA,IAAI,UAAoB,CACf,OAAA,KAAKR,CAAS,IAAM,IAC7B,CAEA,IAAI,MAAe,CACjB,OAAO,KAAK,eAAe,IAC7B,CAEA,IAAIS,EAA0B,CAC5B,MAAMC,EAAQ,IAAI,MAAM,KAAK,WAAY,KAAK,YAAY,EAC1D,YAAK,eAAe,IAAIA,EAAOD,GAAa,IAAI,EACzCC,CACT,CAEQ,UAAc,CAChB,GAAA,KAAKV,CAAS,EAEhB,OAAI,KAAK,kBACP,aAAa,KAAK,eAAe,EACjC,KAAK,gBAAkB,MAGlB,KAAKA,CAAS,EAGvB,MAAMW,EAAS,KAAK,aAAa,KAAK,QAAQ,EAC9C,YAAKX,CAAS,EAAIW,EACXA,CACT,CAEA,MAAc,UAAW,CACjB,MAAAC,EAAW,KAAKZ,CAAS,EAC/B,GAAI,CAACY,EAAU,CACb,QAAQ,KAAK,sCAAsC,EACnD,OAGE,GAAA,CACF,MAAMA,EAAS,UAAS,QACxB,CACA,KAAKZ,CAAS,EAAI,IACpB,CACF,CAMA,MAAc,gBAAgBU,EAA4B,CACxD,OAAK,KAAK,eAAe,OAAOA,CAAK,EAKjC,KAAK,eAAe,OAAS,EACxB,IAGL,CAAC,KAAK,iBAAmB,OAAO,SAAS,KAAK,KAAK,IACjD,KAAK,QAAU,EACjB,MAAM,KAAK,WAEN,KAAA,gBAAkB,WAAW,IAAM,CACtC,KAAK,WACF,MAAO/H,GAAQ,QAAQ,MAAM,kBAAmB,CAAE,IAAAA,CAAA,CAAK,CAAC,EACxD,QAAQ,IAAO,KAAK,gBAAkB,IAAK,CAAA,EAC7C,KAAK,KAAK,GAGV,KAnBL,QAAQ,KAAK,0CAA0C,EAChD,GAmBX,CACF,CA/FGO,GAAA8G,ECXH,MAAMa,EAAW,SACfjB,EAAQ3F,EAAe,MAAO,qCAAqC,EAE/D6G,EAAqB,CACzB,CAAChB,EAAa,OAAO,EAAG,IAAIG,EAAc,CACxC,MAAO,KACP,aAAec,GACb,IAAIC,YAAU,CACZ,gBAAiB,IAAIC,EAAA,uBAAuBvJ,CAAe,EAC3D,SAAAmJ,EACA,YAAaf,EAAa,QAC1B,QAASiB,CAAA,CACV,CAAA,CACJ,EACD,CAACjB,EAAa,MAAM,EAAG,IAAIG,EAAc,CACvC,MAAO,KACP,aAAec,GACb,IAAIC,YAAU,CACZ,gBAAiB,IAAIC,EAAA,uBAAuBvJ,CAAe,EAC3D,SAAAmJ,EACA,YAAaf,EAAa,OAC1B,QAASiB,CAAA,CACV,CAAA,CACJ,EACD,CAACjB,EAAa,YAAY,EAAG,IAAIG,EAAc,CAC7C,MAAO,KACP,aAAec,GACb,IAAIC,YAAU,CACZ,gBAAiB,IAAIC,EAAA,uBAAuBvJ,CAAe,EAC3D,SAAAmJ,EACA,YAAaf,EAAa,aAC1B,QAASiB,CAAA,CACV,CAAA,CACJ,EACD,CAACjB,EAAa,OAAO,EAAG,IAAIG,EAAc,CACxC,MAAO,KACP,aAAec,GACb,IAAIC,YAAU,CACZ,gBAAiB,IAAIC,EAAA,uBAAuBvJ,CAAe,EAC3D,SAAAmJ,EACA,YAAaf,EAAa,QAC1B,QAASiB,CAAA,CACV,CAAA,CACJ,EACD,CAACjB,EAAa,QAAQ,EAAG,IAAIG,EAAc,CACzC,MAAO,KACP,aAAec,GACb,IAAIC,YAAU,CACZ,gBAAiB,IAAIC,EAAA,uBAAuBvJ,CAAe,EAC3D,SAAAmJ,EACA,YAAaf,EAAa,SAC1B,QAASiB,CAAA,CACV,CAAA,CACJ,CACH,EAEaG,GAAoB,CAC/B,GAAGJ,EACH,QAASA,EAAmBhB,EAAa,OAAO,EAChD,OAAQgB,EAAmBhB,EAAa,MAAM,EAC9C,YAAagB,EAAmBhB,EAAa,YAAY,EACzD,QAASgB,EAAmBhB,EAAa,OAAO,EAChD,SAAUgB,EAAmBhB,EAAa,QAAQ,CACpD,EAEaqB,EAAuBL,EAAmBhB,EAAa,MAAM,EAE7DsB,GAAoB9I,GAA2C,CACpE,KAAA,CAAE,YAAA+I,CAAgB,EAAA/I,EAEjB,OAAA+I,EAAcH,GAAkBG,CAAW,EAAIF,CACxD,EChEO,MAAMG,CAAc,CAEzB,YAAmBC,EAAgC,CADnD1J,EAAA,cACmB,KAAA,eAAA0J,CAAiC,CAEpD,MAAM,WAAWrE,EAAW,CACtB,GAAA,CAAC,KAAK,MAAO,CAOT,MAAAsE,EAAW,MANF,MAAM,MACnB,GAAG9J,+BAA6C,KAAK,eAAe,oBACpE,CACE,OAAQ,MACV,CAAA,GAE4B,OAC9B,KAAK,MAAQ8J,EAAS,MAGlB,MAAA,MAAM,GAAG9J,cAA6B,CAC1C,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,SAAU,KAAK,eAAe,SAC9B,KAAM,KAAK,eAAe,WAC1B,KAAM,OACN,OAAQ,CAAC,CAAC,KAAK,IAAA,EAAO,KAAK,UAAUwF,CAAK,CAAC,CAAC,CAAA,CAC7C,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY,KAAK,KAClC,CAAA,CACD,CACH,CACF,CC7CO,SAASsC,EAAMC,EAAY,CAChC,OAAO,IAAI,QAASpG,GAAY,WAAWA,EAASoG,CAAE,CAAC,CACzD,CCAa,MAAAgC,GAAaC,GACxBA,IAAS,QACTA,EAAK,eAAiB,QACtBA,EAAK,gBAAkB,OCDlB,MAAMC,CAAY,CAUvB,YAAoBC,EAA6B,CATjD/J,EAAA,aAAQ,IACRA,EAAA,iBAAyC,CAAA,GACzCA,EAAA,qBAAuC,CAAA,GACvCA,EAAA,sBAAwC,CAAA,GACxCA,EAAA,sBAA6C,CAAA,GAC7CA,EAAA,uBAA+C,CAAA,GAC/CA,EAAA,cACAA,EAAA,eAAU,IAAI,aAEM,KAAA,YAAA+J,EAClB,KAAK,YAAY,WAAa,cACzB,KAAA,YAAY,OAAS,IAAM,CAC9B,KAAK,SAAS,CAAA,EAEX,KAAA,YAAY,QAAU,IAAM,CAC/B,KAAK,MAAQ,GACb,KAAK,eAAe,QAAS9H,GAAaA,EAAU,CAAA,CAAA,EAEjD,KAAA,YAAY,QAAWoF,GAAM,CAChC,QAAQ,MAAMA,CAAC,EACf,KAAK,MAAQ,mCACb,KAAK,eAAe,QAASpF,GAAaA,EAASoF,CAAC,CAAC,CAAA,EAElD,KAAA,YAAY,UAAa2C,GAAoB,CAC3C,KAAA,UAAU,QAASjJ,GAAM,CAC5B,MAAMkJ,EAAI,IAAI,WAAWD,EAAE,IAAI,EACzBE,EAAI,KAAK,QAAQ,OAAOD,CAAC,EAC/BlJ,EAAEmJ,CAAC,CAAA,CACJ,EACI,KAAA,gBAAgB,QAASnJ,GAAM,CAClCA,EAAE,IAAI,WAAWiJ,EAAE,IAAI,CAAC,CAAA,CACzB,CAAA,CAEL,CAEQ,UAAW,CACjB,KAAK,MAAQ,GACb,KAAK,cAAc,QAAS/H,GAAaA,EAAU,CAAA,CACrD,CAEA,gBAAgBA,EAA+B,CACxC,KAAA,cAAc,KAAKA,CAAQ,CAClC,CAEA,mBAAmBA,EAA+B,CAChD,KAAK,cAAgB,KAAK,cAAc,OAAQlB,GAAMA,IAAMkB,CAAQ,CACtE,CAEA,iBAAiBA,EAA+B,CACzC,KAAA,eAAe,KAAKA,CAAQ,CACnC,CAEA,oBAAoBA,EAA+B,CACjD,KAAK,eAAiB,KAAK,eAAe,OAAQkI,GAAMA,IAAMlI,CAAQ,CACxE,CAEA,iBAAiBA,EAAoC,CAC9C,KAAA,eAAe,KAAKA,CAAQ,CACnC,CAEA,oBAAoBA,EAAoC,CACtD,KAAK,eAAiB,KAAK,eAAe,OAAQkI,GAAMA,IAAMlI,CAAQ,CACxE,CAEA,MAAM,cAAiC,CACrC,OAAI,KAAK,MACA,GAEC,IAAI,QAAiB,CAACT,EAASgG,IAAW,CAC9C,IAAA4C,EAAI,YAAY,IAAM,CACpB,KAAK,YAAY,aAAe,QAClC,KAAK,SAAS,EAEZ,KAAK,QACP,cAAcA,CAAC,EACf5I,EAAQ,EAAI,GAEV,KAAK,OACPgG,EAAO,KAAK,KAAK,GAElB,EAAE,CAAA,CACN,CAEH,CAEA,KAAKlG,EAAc,CACb,GAAA,CAAC,KAAK,MACF,MAAA,IAAI,MAAM,4BAA4B,EAEzC,KAAA,YAAY,KAAKA,CAAI,CAC5B,CAEA,WAAWA,EAAkB,CACvB,GAAA,CAAC,KAAK,MACF,MAAA,IAAI,MAAM,4BAA4B,EAEzC,KAAA,YAAY,KAAKA,CAAI,CAC5B,CAEA,YAAYW,EAAqC,CAC1C,KAAA,UAAU,KAAKA,CAAQ,CAC9B,CAEA,eAAeA,EAAqC,CAClD,MAAMoI,EAAI,KAAK,UAAU,QAAQpI,CAAQ,EACzC,GAAIoI,IAAM,GACF,MAAA,IAAI,MAAM,gDAAgD,EAElE,GAAI,KAAK,MACD,MAAA,IAAI,MAAM,KAAK,KAAK,EAEvB,KAAA,UAAU,OAAOA,EAAG,CAAC,CAC5B,CAEA,kBAAkBpI,EAAqC,CAChD,KAAA,gBAAgB,KAAKA,CAAQ,CACpC,CAEA,qBAAqBA,EAAqC,CACxD,MAAMoI,EAAI,KAAK,gBAAgB,QAAQpI,CAAQ,EAC/C,GAAIoI,IAAM,GACF,MAAA,IAAI,MAAM,gDAAgD,EAElE,GAAI,KAAK,MACD,MAAA,IAAI,MAAM,KAAK,KAAK,EAEvB,KAAA,gBAAgB,OAAOA,EAAG,CAAC,CAClC,CACF,CCpHO,MAAMC,EAAY,CAEvB,YACUC,EACAC,EACR,CAJFxK,EAAA,wBAAkD,CAAA,GAoBlDA,EAAA,yBAAoB,CAACyK,EAAiB3I,IAA6B,CAC7DA,EAAQ,QAAQ,YACb,KAAA,iBAAiB,QAASG,GAAa,CACtCH,EAAQ,QAAQ,YAAqBG,EAAAH,EAAQ,QAAQ,UAAU,CAAA,CACpE,CACH,GAvBQ,KAAA,OAAAyI,EACA,KAAA,OAAAC,CACP,CAEH,MAAM,aAAc,CACb,KAAA,OAAO,oBAAoB,KAAK,iBAAiB,EACtD,KAAK,OAAO,mCACV,KAAK,OAAO,uBAAA,CAEhB,CAEA,MAAM,eAAgB,CACf,KAAA,OAAO,uBAAuB,KAAK,iBAAiB,EACzD,KAAK,OAAO,kCACV,KAAK,OAAO,uBAAA,CAEhB,CAUA,MAAM,6BAA6BvI,EAAqC,CACjE,KAAA,iBAAiB,KAAKA,CAAQ,CACrC,CACF,CCrCA,MAAeyI,EAAmB,CAGhC,YACYH,EACAI,EACA5F,EACV,CANQ/E,EAAA,gBACAA,EAAA,kCAA6B,KAE3B,KAAA,OAAAuK,EACA,KAAA,aAAAI,EACA,KAAA,QAAA5F,CACT,CAEH,gBAAgB9C,EAA+B,CAC7C8F,EAAQ,KAAK,QAAS,wBAAwB,EAAE,gBAAgB9F,CAAQ,CAC1E,CAEA,mBAAmBA,EAA+B,CACxC8F,EAAA,KAAK,QAAS,wBAAwB,EAAE,mBAC9C9F,CAAA,CAEJ,CAEA,iBAAiBA,EAA+B,CAC9C8F,EAAQ,KAAK,QAAS,wBAAwB,EAAE,iBAAiB9F,CAAQ,CAC3E,CAEA,oBAAoBA,EAA+B,CACzC8F,EAAA,KAAK,QAAS,wBAAwB,EAAE,oBAC9C9F,CAAA,CAEJ,CAEA,iBAAiBA,EAAoC,CACnD8F,EAAQ,KAAK,QAAS,wBAAwB,EAAE,iBAAiB9F,CAAQ,CAC3E,CAEA,oBAAoBA,EAAoC,CAC9C8F,EAAA,KAAK,QAAS,wBAAwB,EAAE,oBAC9C9F,CAAA,CAEJ,CACF,CAEO,MAAM2I,WAAiCF,EAAmB,CAA1D,kCACG1K,EAAA,6BAAwB,GACxBA,EAAA,eAAU,IAAI,aAYtB,kBAAmB,CAEX,MAAAsC,EAAK,IAAI,WAAW,EAAE,EAC5B,QAAS+H,EAAI,EAAGA,EAAI/H,EAAG,OAAQ+H,IAC7B/H,EAAG+H,CAAC,EAAI,KAAK,MAAM,KAAK,OAAA,EAAW,GAAG,EAEjC,OAAA/H,CACT,CAEA,MAAM,YAAa,CACjB,KAAK,QAAU,MAAM,KAAK,OAAO,wBAAwB,KAAK,YAAY,EAErE,KAAA,QAAQ,kBAAmBR,GAAY,CAGpC,MAAAQ,EAFWR,EAAQ,MAAM,EAAG,EAAE,EAEhB,WAChB,GAAAQ,EAAG,SAAW,EACV,MAAA,IAAI,MAAM,kBAAkB,EAG9B,MAAAX,EAAWG,EAAQ,MAAM,EAAE,EAC7B,GAAAH,EAAS,SAAW,EAChB,MAAA,IAAI,MAAM,kBAAkB,EAIhC,KAAK,uBAAuB,IAAIW,CAAE,GAC/B,KAAA,uBAAuB,IAAIA,EAAIX,CAAQ,CAC9C,CACD,CACH,CAEA,MAAM,QAAQL,EAAkB,CAI1B,GAHC,KAAK,SACR,MAAM,KAAK,aAET,CAAC,KAAK,QACF,MAAA,IAAI,MAAM,0BAA0B,EAE5C,KAAM,CAAE,QAAAwB,EAAS,uBAAA+H,EAAwB,QAAA9F,CAAA,EAAY,KACrD,MAAMjC,EAAQ,eAER,MAAAgI,EAAW,KAAK,mBAChBxI,EAAKwI,EAAS,WACGD,EAAA,IAAIvI,EAAI,EAAI,EAC3BQ,EAAA,WAAW,IAAI,WAAW,CAAC,GAAGgI,EAAU,GAAGxJ,CAAI,CAAC,CAAC,EAGzD,MAAMiD,EAAQ,IAAI,KAAK,EAAE,QAAQ,EACjC,SAAW,KAAK,EAAE,QAAQ,EAAIA,EAAQQ,GAEhC,GADJ,MAAM4C,EAAM,EAAE,EACVkD,EAAuB,IAAIvI,CAAE,EAAG,CAC5B,MAAAX,EAAWkJ,EAAuB,IAAIvI,CAAE,EAC9C,GAAIX,IAAa,GAAM,CACrBkJ,EAAuB,OAAOvI,CAAE,EAChC,MAAMyI,EAAUpJ,EAAS,CAAC,IAAM,KAAK,sBAC/BqJ,EAAUrJ,EAAS,MAAM,CAAC,EAChC,GAAIoJ,EACK,OAAAC,EAEP,cAAQ,MAAM,CACZ,KAAM,eACN,QAAS,KAAK,QAAQ,OAAOA,CAAO,CAAA,CACrC,EACK,IAAI,MAAM,0CAA0C,GAMlE,MAAAH,EAAuB,OAAOvI,CAAE,EAChC,QAAQ,MAAM,CACZ,KAAM,eACN,QAAS,2BAA2ByC,EAAU,aAAA,CAC/C,EACK,IAAI,MAAM,+CAA+C,CACjE,CACF,CAEO,MAAMkG,WAA+BP,EAAmB,CAC7D,gBAAiB,CACf,OACE,KAAK,SAAS,SAAS,EAAE,EAAE,UAAU,CAAC,EACtC,IACA,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,CAAC,CAE1C,CAEA,MAAM,YAAa,CACjB,KAAK,QAAU,MAAM,KAAK,OAAO,wBAAwB,KAAK,YAAY,EAErE,KAAA,QAAQ,YAAa5I,GAAY,CAC9B,MAAAH,EAAW,KAAK,MAAMG,CAAO,EAC7B,CAAE,GAAAQ,EAAI,KAAAhB,EAAM,MAAAiF,CAAA,EAAU5E,EAC5B,GAAI,CAACW,EACG,MAAA,IAAI,MAAM,kBAAkB,EAEhC,GAAA,CAAChB,GAAQ,CAACiF,EACN,MAAA,IAAI,MAAM,kBAAkB,EAGhC,KAAK,uBAAuB,IAAIjE,CAAE,GAC/B,KAAA,uBAAuB,IAAIA,EAAIX,CAAQ,CAC9C,CACD,CACH,CAEA,MAAM,QAAQL,EAAc,CAItB,GAHC,KAAK,SACR,MAAM,KAAK,aAET,CAAC,KAAK,QACF,MAAA,IAAI,MAAM,0BAA0B,EAE5C,KAAM,CAAE,QAAAwB,EAAS,uBAAA+H,EAAwB,QAAA9F,CAAA,EAAY,KACrD,MAAMjC,EAAQ,eAER,MAAAR,EAAK,KAAK,iBACOuI,EAAA,IAAIvI,EAAI,EAAI,EAC3BQ,EAAA,KACN,KAAK,UAAU,CACb,GAAAR,EACA,KAAAhB,CAAA,CACD,CAAA,EAIH,MAAMiD,EAAQ,IAAI,KAAK,EAAE,QAAQ,EACjC,SAAW,KAAK,EAAE,QAAQ,EAAIA,EAAQQ,GAEhC,GADJ,MAAM4C,EAAM,EAAE,EACVkD,EAAuB,IAAIvI,CAAE,EAAG,CAC5B,MAAAX,EAAWkJ,EAAuB,IAAIvI,CAAE,EAC9C,GAAIX,IAAa,GAAM,CACrBkJ,EAAuB,OAAOvI,CAAE,EAChC,KAAM,CAAE,KAAAhB,EAAM,MAAAiF,CAAA,EAAU5E,EACxB,GAAIL,EACKA,OAAAA,EAET,GAAIiF,EACF,cAAQ,MAAM,CACZ,KAAM,eACN,QAASA,CAAA,CACV,EACK,IAAI,MAAM,wCAAwC,GAMhE,MAAAsE,EAAuB,OAAOvI,CAAE,EAChC,QAAQ,MAAM,CACZ,KAAM,eACN,QAAS,2BAA2ByC,EAAU,aAAA,CAC/C,EACK,IAAI,MAAM,4CAA4C,CAC9D,CACF,CCtMO,MAAemG,WACZC,GAAAA,YAEV,CAHO,kCAILnL,EAAA,kBACAA,EAAA,0BAAoC,MAE1BA,EAAA,yBAAwC,CAAA,GAExCA,EAAA,kCAQAA,EAAA,qBAAgB,CAACqI,EAAgBvG,IAAiB,CAC1D,KAAK,kBAAkB,QAASf,GAAMA,EAAEsH,EAAQvG,CAAO,CAAC,CAAA,GAGhD,0BAA2B,CACnC,cAAc,KAAK,yBAAyB,EAC5C,KAAK,0BAA4B,MACnC,CAEU,mBAAmBsJ,EAA0B,CACjD,GAAAA,EAAiB,MAAA,IAAI,MAAM,uBAAuB,CACxD,CAEA,mBAAiE,CAC3D,GAAA,KAAK,WAAa,KAAK,mBACzB,OAAO,KAAK,UAAU,oBAAoB,KAAK,kBAAkB,EAE3D,MAAA,IAAI,MAAM,yCAAyC,CAE7D,CAEA,iBAAsC,CAChC,GAAA,KAAK,WAAa,KAAK,mBACzB,OAAO,KAAK,UAAU,QAAQ,KAAK,kBAAkB,EAE/C,MAAA,IAAI,MAAM,yCAAyC,CAE7D,CAEA,oBAAoBnJ,EAA4B,CACzC,KAAA,kBAAkB,KAAKA,CAAQ,CACtC,CAEA,uBAAuBA,EAA4B,CACjD,MAAMoI,EAAI,KAAK,kBAAkB,QAAQpI,CAAQ,EACjD,GAAIoI,IAAM,GACF,MAAA,IAAI,MAAM,4CAA4C,EAEzD,KAAA,kBAAkB,OAAOA,EAAG,CAAC,CACpC,CAEA,MAAM,yBAAkD,CAChD,MAAAgB,EAAY,MAAM,KAAK,mBACvBC,EAAe,CAAA,EAErB,UAAWvK,KAAKsK,EAAS,OAAO,YAAc,CAAA,EACxCtK,EAAE,WAAa,0BACJuK,EAAA,KACX,IAAIhB,GAAY,KAAM,CACpB,wBAAyB,CAAE,KAAMvJ,EAAE,SAAU,EAC7C,wBAAyBA,EAAE,aACvB,CAAE,KAAMA,EAAE,YACV,EAAA,OACJ,gBAAiBA,EAAE,eACf,CAAE,KAAMA,EAAE,cACV,EAAA,OACJ,kBAAmBA,EAAE,iBACjB,CAAE,KAAMA,EAAE,gBACV,EAAA,OACJ,oBAAqBA,EAAE,oBACvB,mBAAoBA,EAAE,mBACtB,WAAYA,EAAE,UAAA,CACf,CAAA,EAIA,OAAAuK,CACT,CAEA,MAAM,yBAA0D,WACxD,MAAAD,EAAY,MAAM,KAAK,mBACvBE,EAA8B,CAAA,EAEpC,UAAWxK,MAAKM,EAAAgK,EAAS,SAAT,YAAAhK,EAAiB,kBAAmB,CAAA,EAC9CN,EAAE,gBAAkB,oBACtBwK,EAAQ,KAAK,CACX,KAAMxK,EAAE,IAAA,CACT,EAGL,UAAWA,MAAKyK,EAAAH,EAAS,SAAT,YAAAG,EAAiB,aAAc,CAAA,EACzCzK,EAAE,WAAa,0BACjBwK,EAAQ,KAAK,CACX,KAAMxK,EAAE,SAAA,CACT,GAGAA,EAAE,YAAc,qBACfA,EAAE,YAAc,gCAClBA,EAAE,aAEFwK,EAAQ,KAAK,CACX,KAAMxK,EAAE,SAAA,CACT,EAGL,UAAWA,MAAK0K,EAAAJ,EAAS,SAAT,YAAAI,EAAiB,gBAAiB,CAAA,EAC5C1K,EAAE,gBAAkB,oBACtBwK,EAAQ,KAAK,CACX,KAAMxK,EAAE,IAAA,CACT,EAGE,OAAAwK,CACT,CAEA,+BACEG,EACA3G,EAAkB,IACM,CACxB,OAAO,IAAIkG,GAAuB,KAAMS,EAAa3G,CAAO,CAC9D,CAEA,qCACE2G,EACA3G,EAAkB,IACQ,CAC1B,OAAO,IAAI6F,GAAyB,KAAMc,EAAa3G,CAAO,CAChE,CAEA,MAAM,8BAA8B4G,EAA6B,CAC/D,MAAM7C,EAASf,EACb,KAAK,UACL,0CAAA,EAGI6D,EAAa,MAAM,KAAK,gBAC9B9C,EAAO,oBAAoBf,EAAQ6D,CAAU,EAAE,GAAI,CACjD,WAAYD,EAAO,KACnB,OAAQ,GACR,SAAU,KAAA,CACX,CACH,CAEA,MAAM,6BAA6BA,EAA6B,CAC9D,MAAM7C,EAASf,EACb,KAAK,UACL,0CAAA,EAEI6D,EAAa,MAAM,KAAK,gBAC9B9C,EAAO,oBAAoBf,EAAQ6D,CAAU,EAAE,GAAI,CACjD,WAAYD,EAAO,KACnB,OAAQ,GACR,SAAU,KAAA,CACX,CACH,CAEA,MAAM,mCAAmCA,EAA4B,CACnE,MAAM7C,EAASf,EACb,KAAK,UACL,0CAAA,EAGI6D,EAAa,MAAM,KAAK,gBAC9B9C,EAAO,oBAAoBf,EAAQ6D,CAAU,EAAE,GAAI,CACjD,WAAYD,EAAO,KACnB,OAAQ,GACR,SAAU,KAAA,CACX,CACH,CAEA,MAAM,kCAAkCA,EAA4B,CAClE,MAAM7C,EAASf,EACb,KAAK,UACL,0CAAA,EAEI6D,EAAa,MAAM,KAAK,gBAC9B9C,EAAO,oBAAoBf,EAAQ6D,CAAU,EAAE,GAAI,CACjD,WAAYD,EAAO,KACnB,OAAQ,GACR,SAAU,KAAA,CACX,CACH,CAEA,MAAM,yCAAyCE,EAAoB,CACjE,MAAM/C,EAASf,EACb,KAAK,UACL,0CAAA,EAGI6D,EAAa,MAAM,KAAK,gBAC9B9C,EAAO,oBAAoBf,EAAQ6D,CAAU,EAAE,GAAI,CACjD,WAAAC,EACA,qBAAsB,GACtB,SAAU,WAAA,CACX,CACH,CAEA,MAAM,0CAA0CA,EAAoB,CAClE,MAAM/C,EAASf,EACb,KAAK,UACL,0CAAA,EAGI6D,EAAa,MAAM,KAAK,gBAC9B9C,EAAO,oBAAoBf,EAAQ6D,CAAU,EAAE,GAAI,CACjD,WAAAC,EACA,qBAAsB,GACtB,SAAU,WAAA,CACX,CACH,CAEA,MAAM,sBAAsBA,EAAoBC,EAA2B,CACzE,MAAMhD,EAASf,EACb,KAAK,UACL,0CAAA,EAGI6D,EAAa,MAAM,KAAK,gBAC9B9C,EAAO,oBAAoBf,EAAQ6D,CAAU,EAAE,GAAI,CACjD,WAAAC,EACA,eAAgBC,CAAA,CACjB,CACH,CAEA,MAAM,wBACJJ,EACAK,EACsB,CACtB,MAAMjD,EAASf,EACb,KAAK,UACL,0CAAA,EAGI6D,EAAa,MAAM,KAAK,gBACxBI,EAAI,MAAM,IAAI,QAAsBxK,GAAY,CAC7CsH,EAAA,wBACLf,EAAQ6D,CAAU,EAAE,GACpBF,EACA,CACE,QAAS,GACT,GAAGK,CACL,EACA,GACA,CAACtB,EAAS3H,IAAY,CACd,MAAAiH,EAAc,IAAID,EAAYhH,CAAO,EAC3CtB,EAAQuI,CAAW,CACrB,CAAA,CACF,CACD,EACD,aAAMiC,EAAE,eACDA,CACT,CAEA,MAAM,oBACJlK,EACA0I,EAAgC,CAC9B,aAAc,iBAAA,EAEhB,CACA,MAAM1B,EAASf,EACb,KAAK,UACL,0CAAA,EAGI6D,EAAa,MAAM,KAAK,gBAC9B9C,EAAO,KAAKf,EAAQ6D,CAAU,EAAE,GAAI9J,EAAS0I,CAAM,CACrD,CAEA,MAAM,yBAA0D,WACxD,MAAAa,EAAW,MAAM,KAAK,mBACtBE,EAA8B,CAAA,EAEpC,UAAWxK,MAAKM,EAAAgK,EAAS,SAAT,YAAAhK,EAAiB,kBAAmB,CAAA,EAC9CN,EAAE,gBAAkB,eACtBwK,EAAQ,KAAK,CACX,KAAMxK,EAAE,IAAA,CACT,EAGL,UAAWA,MAAKyK,EAAAH,EAAS,SAAT,YAAAG,EAAiB,aAAc,CAAA,EACzCzK,EAAE,WAAa,+BACjBwK,EAAQ,KAAK,CACX,KAAMxK,EAAE,SAAA,CACT,EAGL,UAAWA,MAAK0K,EAAAJ,EAAS,SAAT,YAAAI,EAAiB,gBAAiB,CAAA,EAC5C1K,EAAE,gBAAkB,eACtBwK,EAAQ,KAAK,CACX,KAAMxK,EAAE,IAAA,CACT,EAGE,OAAAwK,CACT,CACF,CCpUA,MAAMU,GAAU,IAAI,YACJ,IAAI,YAEb,SAASC,GAAc7G,EAAoB,CAC1C,MAAA8G,EAAY,KAAK,UAAU9G,CAAK,EAChC+G,EAAeH,GAAQ,OAAOE,CAAS,EACvCE,EAAkBC,WAAQF,CAAY,EAC5C,OAAOG,GAAAA,cAAcF,CAAe,CACtC,CCPA,eAAsBG,IAA6B,CAC7C,GAAA,CAACpK,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAUrC,OADc,MAPG,MAAM,MAAM,GAAGvC,mBAAkC,CAChE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,GAC4B,QAChB,KACf,CCUsB,eAAAqK,GAAgBC,EAAeC,EAAc,CAC7D,GAAA,CAACvK,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAKrC,MAAMwK,GAFQ,MAAMJ,MAEO,OAAQzL,GAAMA,EAAE,OAAS4L,CAAI,EAEpD,GAAAC,EAAa,SAAW,EAC1B,eAAQ,KAAK,uCAAuC,EAC7C,KAGT,MAAMjL,EAAW,MAAM,MAAM,GAAG9B,oBAAmC,CACjE,OAAQ,OACR,KAAM,KAAK,UAAU6M,CAAK,EAC1B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYtK,EAAe,KAC5C,CAAA,CACD,EACKyK,EAAShN,EAAgB,QAAQ,MAAO,KAAK,EAC7C,CAAE,KAAAiN,CAAS,EAAA,MAAMnL,EAAS,KAAK,EAE9B,MAAA,GAAGkL,YAAiBC,KAAQZ,GAAc,CAC/C,OAAQU,EAAa,CAAC,EAAE,EACzB,CAAA,GACH,CCnDO,MAAMG,GAA+B,CAC1C,MACA,OACA,QACA,OACA,OACA,SACA,SACF,EASaC,GAAqB,CAChC,WACA,QACA,MACA,MACA,KACF,EAQO,SAASC,GAAY,EAAsB,CAC5C,OAAA,EAAE,MAAQ,EACL,EAEF,EAAE,cAAgB,EAAE,MAAQ,EACrC,CAEO,SAASC,GAAqB,EAAsB,CACzD,OAAO,KAAK,KAAKD,GAAY,CAAC,CAAC,CACjC,CAEO,SAASE,GAAO,EAAsB,CAC3C,OAAO,EAAE,GACX,CAEO,SAASC,GAAO,EAAsB,CAC3C,OAAO,EAAE,GACX,CAEO,SAASC,GAAW,EAAsB,CAC/C,OAAO,EAAE,QAAU,EAAI,GAAK,EAAE,IAAM,EAAE,KACxC,CAEO,SAASC,GAAO,EAAsB,CAC3C,OAAO,EAAE,GACX,CACO,SAASC,GAAS,EAAsB,CAC7C,OAAO,EAAE,KACX,CAEO,MAAMC,GAAuB,CAClC,IAAKJ,GACL,IAAKD,GACL,qBAAsBD,GACtB,QAASG,GACT,IAAKC,GACL,MAAOC,EACT,EAUaE,EAGT,CACF,IAAK,CACH,SAAUC,EAAQ,kBAClB,MAAOA,EAAQ,WACf,IAAKA,EAAQ,SACb,IAAKA,EAAQ,QACb,IAAKA,EAAQ,MACf,EACA,KAAM,CACJ,SAAUA,EAAQ,mBAClB,MAAOA,EAAQ,YACf,IAAKA,EAAQ,UACb,IAAKA,EAAQ,SACb,IAAKA,EAAQ,OACf,EACA,MAAO,CACL,SAAUA,EAAQ,oBAClB,MAAOA,EAAQ,aACf,IAAKA,EAAQ,WACb,IAAKA,EAAQ,UACb,IAAKA,EAAQ,QACf,EACA,KAAM,CACJ,SAAUA,EAAQ,mBAClB,MAAOA,EAAQ,YACf,IAAKA,EAAQ,UACb,IAAKA,EAAQ,SACb,IAAKA,EAAQ,OACf,EACA,KAAM,CACJ,SAAUA,EAAQ,mBAClB,MAAOA,EAAQ,YACf,IAAKA,EAAQ,UACb,IAAKA,EAAQ,SACb,IAAKA,EAAQ,QACf,EACA,OAAQ,CACN,SAAUA,EAAQ,qBAClB,MAAOA,EAAQ,cACf,IAAKA,EAAQ,YACb,IAAKA,EAAQ,WACb,IAAKA,EAAQ,UACf,EACA,QAAS,CACP,SAAUA,EAAQ,sBAClB,MAAOA,EAAQ,eACf,IAAKA,EAAQ,aACb,IAAKA,EAAQ,YACb,IAAKA,EAAQ,UACf,CACF,EAEaC,GAAsB,CAACpJ,EAAeC,IAKjDD,EAAM,MAAM,GAAG,EAAE,CAAC,EAClB,IACAA,EAAM,MAAM,GAAG,EAAE,CAAC,EAClB,IACAC,EAAI,MAAM,GAAG,EAAE,CAAC,EAChB,IACAA,EAAI,MAAM,GAAG,EAAE,CAAC,EC/IlB,eAAsBoJ,EAAYhI,EAAuC,CACnE,GAAA,CAACxD,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAY7B,OAAA,MATK,MAAM,MAAM,GAAGvC,0BAAyC,CACnE,OAAQ,OACR,KAAM,KAAK,UAAU+F,CAAK,EAC1B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYxD,EAAe,KAC5C,CAAA,CACD,GAEkB,KAAA,GAAQ,KAC7B,CCXA,eAAsByL,GACpBC,EACAC,EACAC,EACAnH,EACAjB,EACA,CACM,MAAAqI,EAAgBR,EAAyBM,CAAS,EAExD,OAAO,MAAM,QAAQ,IACnB,MAAMC,CAAK,EACR,KAAK,CAAC,EACN,IAAI,MAAOjN,EAAGmN,IAAe,CACtB,MAAAC,EAAwB,IAAI,KAAKtH,CAAI,EAErCuH,EAAkBH,EAAc,IACpCA,EAAc,MAAME,CAAqB,EACzCH,EAAQE,EAAa,CAAA,EAEjBG,EAAgBJ,EAAc,IAClCA,EAAc,IAAIE,CAAqB,EACvCH,EAAQE,EAAa,CAAA,EAEjBvL,EAAOgL,GACXS,EAAU,mBAAmB,EAC7BC,EAAQ,mBAAmB,CAAA,EAEvBC,EAAS,MAAMV,EAAY,CAC/B,GAAGhI,EACH,WAAAkI,EACA,MAAO,IAAI,KAAKM,CAAS,EAAE,YAAY,EACvC,IAAK,IAAI,KAAKC,CAAO,EAAE,YAAY,CAAA,CACpC,EACM,MAAA,CAAE,KAAA1L,EAAM,OAAA2L,EAAO,CACvB,CAAA,CAEP,CCzCsB,eAAAC,EAAmB3I,EAAoB4I,EAAgB,CAqBpE,OApBa,MAAMZ,EAAY,CACpC,GAAGhI,EACH,WAAY,CAAC,YAAY,CAAA,CAC1B,GAEoC,OAClC7E,GAAM,CAAC,CAACA,EAAE,MAAQ,OAAO,KAAKA,EAAE,IAAK,EAAE,SAASyN,CAAM,CAAA,EAEd,OAExC,CAACC,EAAMC,IAAY,CACd,MAAArJ,EAAQqJ,EAAQ,KAAMF,CAAM,EAClC,OAAInJ,KAASoJ,GACXA,EAAKpJ,CAAK,GAAK,EACRoJ,IAETA,EAAKpJ,CAAK,EAAI,EACPoJ,EACT,EAAG,CAAE,CAAA,CAGP,CCrBsB,eAAAE,GACpB/I,EACA4I,EACAI,EACA,CACM,KAAA,CAAE,IAAApK,EAAK,MAAAD,CAAU,EAAAqB,EAEjBiJ,EADgBpB,EAAyBmB,CAAS,EAChB,SAAS,CAC/C,MAAO,IAAI,KAAKrK,CAAM,EACtB,IAAK,IAAI,KAAKC,CAAI,CAAA,CACnB,EAEKsK,EAAmBD,EAAU,IAAI,CAAC9N,EAAGgO,IAAQ,CACjD,MAAMX,EAAY,IAAI,KAAKrN,CAAC,EAAE,YAAY,EACpCsN,EACJU,IAAQF,EAAU,OAAS,EACvB,IAAI,KAAK,KAAK,IAAA,CAAK,EAAE,cACrB,IAAI,KAAKA,EAAUE,EAAM,CAAC,CAAC,EAC1B,OAAAR,EACL,CACE,GAAG3I,EACH,MAAOwI,EACP,IAAKC,CACP,EACAG,CAAA,CACF,CACD,EACKQ,EAAY,MAAM,QAAQ,IAAIF,CAAgB,EAEpD,OAAOD,EAAU,IAAI,CAAC9N,EAAGgO,KAAS,CAChC,KAAM,IAAI,KAAKhO,CAAC,EAAE,YAAY,EAC9B,YAAaiO,EAAUD,CAAG,CAC1B,EAAA,CACJ,CCjCA,eAAsBE,GACpBC,EACAC,EACA5K,EACAC,EACA4K,EAC4B,CAC5B,IAAIC,EAAYH,EACX,MAAM,QAAQA,CAAmB,IACpCG,EAAY,CAACH,CAAmB,GAElC,IAAIxI,EAAcyI,EAClB,OAAK,MAAM,QAAQA,CAAuB,IACxCzI,EAAc,CAACyI,CAAuB,IAgBtB,MAdL,MAAM,MAAM,GAAGtP,uBAAsC,CAChE,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,UAAAwP,EACA,IAAK7K,EAAI,YAAY,EACrB,MAAOkC,EACP,MAAOnC,EAAM,YAAY,EACzB,KAAA6K,CAAA,CACD,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYhN,EAAe,KAC5C,CAAA,CACD,GAC4B,QACZ,KACnB,CCjCA,eAAsBkN,IAEnB,CACG,GAAA,CAAClN,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAE/B,MAAAmN,EAAYjG,EAAqB,MACnC,GAAA,CACK,OAAA,MAAMiG,EAAU,aAAY,QACnC,CACA,MAAMA,EAAU,UAClB,CACF,CCVA,eAAsBC,IAAgC,CAChD,GAAA,CAACpN,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAE/B,MAAAmN,EAAYjG,EAAqB,MACnC,GAAA,CACK,OAAA,MAAMiG,EAAU,UAAS,QAChC,CACA,MAAMA,EAAU,UAClB,CACF,CCXA,eAAsBE,GAAalF,EAAmC,CAChE,GAAA,CAACnI,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARM,MAAM,MAAM,GAAGvC,qBAAoC,CAC9D,OAAQ,OACR,KAAM,KAAK,UAAU0K,CAAM,EAC3B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYnI,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CCbsB,eAAAsN,GACpBpN,EACAiI,EACkB,CACd,GAAA,CAACnI,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARM,MAAM,MAAM,GAAGvC,sBAAoCyC,IAAM,CACpE,OAAQ,QACR,KAAM,KAAK,UAAUiI,CAAM,EAC3B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYnI,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CChBA,eAAsBuN,IAAqC,CACrD,GAAA,CAACvN,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAWrC,OADgB,MARH,MAAM,MAAM,GAAGvC,kCAAiD,CAC3E,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,QAAS,GAAM,KAAM,UAAW,EACvD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,GAC0B,QACZ,KACjB,CCbA,eAAsBwN,GACpBhK,EACoB,CAChB,GAAA,CAACxD,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAYrC,OAFgB,MARH,MAAM,MAAM,GAAGvC,2BAA0C,CACpE,OAAQ,OACR,KAAM,KAAK,UAAU+F,CAAK,EAC1B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYxD,EAAe,KAC5C,CAAA,CACD,GAC0B,QAEZ,KACjB,CClBA,eAAsByN,GAAcvN,EAAgC,CAC9D,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAc9B,OAFU,MAVJ,MAAM,MACjB,GAAGvC,sBAAoCyC,YACvC,CACE,OAAQ,OACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CACF,CAAA,GAE0B,MAG9B,CCeO,MAAM0N,UAAe5E,EAAW,CACrC,YACS5I,EACAyD,EACCgK,EACDX,EACP,CACM,QALC,KAAA,GAAA9M,EACA,KAAA,KAAAyD,EACC,KAAA,eAAAgK,EACD,KAAA,KAAAX,CAGT,CAQA,MAAM,oBAAqB,CAezB,OADkB,MAbL,MAAM,MACjB,GAAGvP,oCACH,CACE,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,UAAW,CAAC,KAAK,EAAE,CAAA,CACpB,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CACF,CAAA,GAE2B,QACZ,KACnB,CAEA,MAAM,kBAAmD,CACvD,IAAIzB,EAAS,MAAM,MAAM,GAAGd,sBAAoC,KAAK,KAAM,CACzE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,EACK,MAAAmI,EAAS,MAAM5J,EAAO,OACxB,GAAA,CAAC4J,EAAO,MAAM,sBAChB,MAAM,IAAI,MACR,0DAAA,EAGE,MAAAyF,EAAUzF,EAAO,MAAM,sBAAsB,QACnD,OAAA5J,EAAS,MAAM,MACb,GAAGd,sBAAoC,KAAK,qBAAqBmQ,IACjE,CACE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY5N,EAAe,KAC5C,CACF,CAAA,GAEa,MAAMzB,EAAO,QACd,QAChB,CAEA,MAAM,WAAWsP,EAAmC,CAYlD,OADc,MAVC,MAAM,MAAM,GAAGpQ,yBAAwC,CACpE,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,QAAS,CAACoQ,CAAM,CAAA,CACjB,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY7N,EAAe,KAC5C,CAAA,CACD,GAC0B,QACd,QACf,CAQA,MAAM,wBACJ3B,EAAyD,GAC1C,CAGf,GAFA,QAAQ,MAAM,GAAG,IAAI,KAAK,EAAE,6CAA6C,EAErE,KAAK,WAAa,KAAK,4BAA8B,OACvD,MAAM,IAAI,MACR,iDAAiD,KAAK,IAAA,EAItD,KAAK,WACC,QAAA,KACN,yEAAA,EAIE,KAAA,CACJ,YAAA+I,EACA,WAAAlC,EAAa,IACb,kBAAA4I,EAAoB,CAAA,EAClB,OAAOzP,GAAY,SAClB,CAAE,YAAaA,CAChB,EAAAA,EAKE8O,EAHOhG,GAAiB,CAC5B,YAAAC,CAAA,CACD,EACsB,IAAI,KAAK,aAAa,EAE7C,IAAI4B,EAAY,GAChB,MAAM+E,EAAkB,IAAI,QAAe,CAACpP,EAAGyG,IAC7C,WAAW,IAAM,CACH4D,EAAA,GACZ5D,EACE,IAAI,MACF,gIAEF,CAAA,GAEDF,CAAU,CAAA,EAGT8I,EAAsB,SAA6B,CACvD,GAAI,YAAab,EACR,KAAA,CAACA,EAAU,WAChB,KAAK,mBAAmBnE,CAAS,EACjC,MAAMzD,EAAM,GAAG,EAKnB,MAAM0I,EAAqB,MAAM,KAAK,sBAAsBd,CAAS,EACrE,KAAK,mBAAmBnE,CAAS,EAEjC,IAAIkF,EAGJ,QAASjG,EAAI,EAAGA,EAAI6F,IACNI,EAAA,MAAMf,EAAU,QAAQc,CAAkB,EAChD,CAAAC,GAF+BjG,IAGrC1C,EAAM,GAAG,EACT,KAAK,mBAAmByD,CAAS,EAGnC,GAAI,CAACkF,EACH,MAAM,IAAI,MACR,2CAA2CJ,WAAA,EAI/C,IAAIK,EAAU,EACd,KAAO,CAACnF,GAEJmE,EAAU,oBAAoBc,CAAkB,IAAM,aAKxD,MAAM1I,EAAM,GAAG,EACJ4I,GAAA,EAEb,YAAK,mBAAmBnF,CAAS,EAEzB,QAAA,MACN,GAAG,IAAI,KAAK,EAAE,+CAA+CmF,WAAA,EAGxDF,CAAA,EAGF,OAAA,QAAQ,KAAK,CAACD,EAAoB,EAAGD,CAAe,CAAC,EACzD,KAAME,GAAuB,CAC5B,KAAK,mBAAqBA,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,UAAYd,EACjB,KAAK,KAAK,SAAS,CAAA,CACpB,EACA,MAAOzO,GAAQ,CACN,cAAA,MACN,GAAG,IAAI,KAAK,EAAE,YAAY,6BAC1BA,CAAA,EAGF,KAAK,mBAAqB,KAC1ByO,EAAU,SAAS,EAAE,MAAOiB,GAAyB,CAC3C,QAAA,MAAM,gCAAiCA,CAAW,CAAA,CAC3D,EACI,KAAA,KAAK,oBAAqB1P,CAAG,EAC5BA,CAAA,CACP,CACL,CAEA,MAAc,sBAAsByO,EAAsB,CAKlD,MAAA3D,GAHQ,MAAM2D,EAAU,YAGL,KAAMxO,GAAMA,EAAE,WAAa,KAAK,EAAE,EAEvD,GAAA,CAAC6I,GAAUgC,CAAU,EAEjB,MAAA,IAAI,MAAM,yCAAyC,EAE3D,OAAOA,EAAW,EACpB,CAEQ,0BAA2B,CAC5B,KAAA,0BAA4B,YAAY,SAAY,CACvD,IAAI6E,EAAoB,GAExB,GAAI,KAAK,UAAW,CAElB,MAAMC,EADiB,KAAK,UAAU,eAAe,EACnB,KAC/B3P,GAAMA,EAAE,gBAAA,IAAsB,KAAK,oBAAsBA,EAAE,SAAS,CAAA,GAEnE2P,IAAe,QAAa,CAACA,EAAW,aAC1C,QAAQ,MAAM,GAAG,IAAI,KAAK,EAAE,sCAAsC,EAC9CD,EAAA,KAKtB,CAAC,KAAK,WACN,CAAC,KAAK,oBACL,MAAM,KAAK,UAAU,uBACpB,KAAK,kBAAA,IACA,QACPA,KAEA,KAAK,KAAK,YAAY,EACtB,KAAK,uBAAuB,EAAE,MAAO3P,GAAQ,CAC3C,QAAQ,MAAMA,CAAG,CAAA,CAClB,IAEF,GAAI,CACT,CAEA,MAAM,eAAmC,CAQjC,MAAA8K,GANQ,MAAM7D,EAClB,KAAK,UACL,4CACA,SAAS,GAGc,KAAMhH,GAAMA,EAAE,WAAa,KAAK,EAAE,EACpD,OAAAgH,EACL6D,EACA,yCAA2C,KAAK,EAAA,CAEpD,CAEA,MAAM,wBAAyB,CAC7B,IAAI+E,EAAuB,GAE3B,GAAI,KAAK,UAAW,CAClB,KAAK,yBAAyB,EAE1B,KAAK,oBACP,MAAM,KAAK,UAAU,WAAW,KAAK,kBAAkB,EACvD,KAAK,mBAAqB,MAEHA,EAAA,GAGrB,GAAA,CACI,MAAA,KAAK,UAAU,UAAS,QAC9B,CACA,KAAK,UAAY,MACnB,EAGF,GAAIA,EACF,MAAM,IAAI,MAAM,+CAA+C,KAAK,IAAI,CAE5E,CAEA,MAAM,qBAAwC,CACtC,MAAAC,EAAQ,MAAMpB,KACdqB,EAAW,MAAMvB,KACjBzF,EAAO+G,EAAM,KAAM7P,GAAMA,EAAE,WAAa,KAAK,EAAE,EACrD,OAAI8I,EACKgH,EAAShH,EAAK,EAAE,EAAE,OAAS,EAE7B,EACT,CAEA,MAAM,sBAA2C,CAY/C,OADiB,MAVF,MAAM,MACnB,GAAGhK,gCACH,CACE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CACF,CAAA,GAE4B,QACd,MAAM,IAAKiI,IAAY,CACrC,KAAMA,EAAE,KACR,GAAIA,EAAE,GACN,QAASA,EAAE,QACX,YAAaA,EAAE,YACf,iBAAkBA,EAAE,iBACpB,eAAgBA,EAAE,eAClB,cAAeA,EAAE,cACjB,QAASA,EAAE,QACX,KAAMA,EAAE,IACR,EAAA,CACJ,CAEA,MAAM,YACJtE,EACAzE,EACAuF,EACAzB,EACmB,OAEnB,MAAM0L,GADW,MAAM,KAAK,wBACH,KAAM/P,GAAMA,EAAE,OAASgF,CAAI,EACpD,GAAI,CAAC+K,EACG,MAAA,IAAI,MAAM,qCAAqC/K,IAAO,EAG9D,IAAI,EAAY,GAEZzE,IAAS,OACPwP,EAAQ,kBAAoBA,EAAQ,iBACtC,EAAIA,EAAQ,gBAGV,EAAAxP,EAGN,IAAIyP,EAAY,CACd,MAAO,EACP,cAAelK,GAAY,IAAA,MAAQ,YAAY,EAC/C,KAAM,CACJ,GAAGiK,EAAQ,cACX,GAAG1L,CACL,CAAA,EAmBK,OAhBK,MAAM,MAAM,GAAGvF,sBAAqC,CAC9D,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,kBAAmBiR,EAAQ,GAC3B,eAAgB,KAAK,eACrB,SAAU,KAAK,GACf,QAASA,EAAQ,QACjB,UAAAC,EACA,QAAQ1P,EAAAe,EAAe,cAAf,YAAAf,EAA4B,EAAA,CACrC,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYe,EAAe,KAC5C,CAAA,CACD,CAGH,CAEA,MAAM,WAAWE,EAA+B,CAQvC,OAPK,MAAM,MAAM,GAAGzC,uBAAqCyC,IAAM,CACpE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CAAA,CACD,CAEH,CAEA,MAAM,oBAAoByJ,EAAoB,CAatC,MAAAnC,EAAiB,MAZR,MAAM,MAAM,GAAG7J,8BAA6C,CACzE,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,SAAU,KAAK,GACf,WAAAgM,EACA,KAAM,CAAC,CAAA,CACR,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYzJ,EAAe,KAC5C,CAAA,CACD,GACmC,OAC7B,OAAA,IAAIqH,EAAcC,CAAc,CACzC,CAEA,MAAM,aACJyF,EACA5K,EACAC,EACA4K,EACA,CACA,OAAO,MAAMH,GACX,KAAK,GACLE,EACA5K,EACAC,EACA4K,CAAA,CAEJ,CAEA,MAAM,qBAAkD,SAChD,MAAA5E,EAAS,MAAM,KAAK,mBAEpB7J,EAAS,MAAM,MACnB,GAAGd,qCACH,CACE,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,UAAW,CAAC,KAAK,EAAE,CAAA,CACpB,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CACF,CAAA,EAGI4O,EAAyB,CAAA,EACzBC,EAAyB,CAAA,EAC/B,OAAAzF,GAAAnK,EAAAmJ,EAAO,YAAP,YAAAnJ,EAAkB,UAAlB,MAAAmK,EAA2B,QAASzK,GAAM,CACpCA,EAAE,WAAa,IACJiQ,EAAA,KAAKjQ,EAAE,IAAI,EAEtBA,EAAE,WAAa,IACJkQ,EAAA,KAAKlQ,EAAE,IAAI,CAC1B,GAEF,QAAQ,IAAIkQ,CAAY,GAEX,MAAMtQ,EAAO,QAEF,MACrB,OAAQI,GAAM,CAACiQ,EAAa,SAASjQ,CAAC,CAAC,EACvC,IAAKA,IAAO,CAAE,KAAMA,EAAG,SAAUkQ,EAAa,SAASlQ,CAAC,CAAI,EAAA,CAGjE,CAEA,MAAM,0BACJe,EACAoP,EACAC,EACA/B,EAC8D,CAsBvD,OAFkB,MAnBJ,MAAM,MACzB,GAAGvP,mCACH,CACE,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,QAAAiC,EACA,iBAAAoP,EACA,KAAM,IAAI,KAAK,EAAE,YAAY,EAC7B,SAAU,KAAK,GACf,KAAA9B,EACA,KAAM+B,CAAA,CACP,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY/O,EAAe,KAC5C,CACF,CAAA,GAG0C,MAG9C,CAEA,MAAM,wBACJgP,EACAF,EACA5P,EACgC,CAiBzB,OADsB,MAfZ,MAAM,MACrB,GAAGzB,oCACH,CACE,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,eAAAuR,EACA,iBAAAF,EACA,KAAA5P,CAAA,CACD,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYc,EAAe,KAC5C,CACF,CAAA,GAE0C,MAE9C,CAEA,MAAM,mBAAmBwD,EAAoB4I,EAAgB,CACpD,OAAA,MAAMD,EAAmB,CAAE,GAAG3I,EAAO,UAAW,CAAC,KAAK,EAAE,GAAK4I,CAAM,CAC5E,CAEA,MAAM,8BACJ5I,EACA4I,EACAI,EACA,CACA,OAAO,MAAMD,GACX,CAAE,GAAG/I,EAAO,UAAW,CAAC,KAAK,EAAE,CAAE,EACjC4I,EACAI,CAAA,CAEJ,CAEA,MAAM,cACJd,EACAC,EACAC,EACAnH,EACAjB,EACA,CACA,OAAO,MAAMiI,GAAcC,EAAYC,EAAWC,EAAOnH,EAAM,CAC7D,GAAGjB,EACH,UAAW,CAAC,KAAK,EAAE,CAAA,CACpB,CACH,CAEA,MAAM,gBAAgB8G,EAAeC,EAAc,CACjD,OAAAD,EAAM,MAAM,UAAY,CAAC,KAAK,EAAE,EACzB,MAAMD,GAAgBC,EAAOC,CAAI,CAC1C,CACF,CA7gBE3M,EAVW8P,EAUJ,eAAeL,IACtBzP,EAXW8P,EAWJ,cAAcJ,IACrB1P,EAZW8P,EAYJ,iBAAiBH,IACxB3P,EAbW8P,EAaJ,mBAAmBF,IAC1B5P,EAdW8P,EAcJ,gBAAgBD,IC5ClB,MAAMwB,WAAmBnG,EAAW,CAMzC,YAAmBoG,EAAiB,CAC5B,QANRtR,EAAA,WAEQA,EAAA,6BAAwB,IACxBA,EAAA,uBAA0C,CAAA,GAE/B,KAAA,QAAAsR,CAEnB,CAEA,MAAM,oBAAqD,CACpD,KAAK,uBACR,KAAK,qBAAqB,EAG5B,MAAMC,EAAY,KAAK,gBAIvB,OADgB,OAAO,QAAQA,CAAS,EACzB,IAAI,CAAC,CAAC5F,EAAQ6F,CAAW,KACP,CAC7B,SAAU,KAAK,GACf,WAAY7F,EACZ,WAAY,OACZ,aAAc6F,EACd,iBAAkBA,EAAY,UAC9B,KAAM,CAAC,CAAA,EAGV,CACH,CAEQ,sBAAuB,CAC7B,KAAK,sBAAwB,GAE7B,IAAIC,EAAwB,EAGtB,MAAAC,EAAM,IAAI,eAChBA,EAAI,aAAe,OAEfA,EAAA,iBAAiB,QAAU3Q,GAAM,CACnC,KAAK,eAAe,OAAO,CAAA,CAC5B,EACG2Q,EAAA,iBAAiB,QAAU3Q,GAAM,CACnC,KAAK,eAAe,OAAO,CAAA,CAC5B,EACG2Q,EAAA,iBAAiB,UAAY3Q,GAAM,CACrC,KAAK,eAAe,SAAS,CAAA,CAC9B,EACG2Q,EAAA,iBAAiB,mBAAqB3Q,GAAM,CAC1C2Q,EAAI,aAAe,eAAe,MACpC,KAAK,eAAe,QAAQ,CAC9B,CACD,EAGGA,EAAA,iBAAiB,WAAaxP,GAAU,CAC1C,MAAMyP,EAAuBzP,EAAM,OAC7B0P,EAAmBD,EAAuBF,EACxBA,EAAAE,EAGRD,EAAI,aAAa,OAAO,CAACE,CAAgB,EAE7B,MAAM;AAAA,CAAI,EAC1B,QAASC,GAAe,OAC9B,GAAAA,EAAW,OAAS,EAAG,CACnB,MAAAC,EAAe,KAAK,MAAMD,CAAU,EACtC,IAAAxQ,EAAAyQ,EAAa,SAAb,MAAAzQ,EAAqB,UAAW,CAC5B,MAAA0Q,EAAYD,EAAa,OAAO,UAChCnG,EAASoG,EAAU,OACzB,OAAOA,EAAU,OACZ,KAAA,gBAAgBpG,CAAM,EAAIoG,GAEnC,CACD,CAAA,CACF,EAEDL,EAAI,KAAK,OAAQ,GAAG,KAAK,sBAAsB,EAE/CA,EAAI,KAAK,CACX,CAEQ,eAAe3R,EAAgB,CAC7B,QAAA,KAAK,2BAA2BA,GAAQ,EAChD,KAAK,sBAAwB,EAC/B,CAEA,MAAM,aAA+B,CAGnC,OADY,MADC,MAAM,MAAM,GAAG,KAAK,mBAAmB,GAC3B,QACd,cAAc,EAC3B,CAEA,MAAM,kBAAmD,CAGvD,OADY,MADC,MAAM,MAAM,GAAG,KAAK,mBAAmB,GAC3B,QACd,cAAc,QAC3B,CAEA,MAAM,wBAAwByJ,EAAqC,CAGjE,GAFA,QAAQ,MAAM,GAAG,IAAI,KAAK,EAAE,6CAA6C,EAErE,KAAK,WAAa,KAAK,4BAA8B,OACvD,MAAM,IAAI,MACR,iDAAiD,KAAK,IAAA,EAItD,KAAK,WACC,QAAA,KACN,yEAAA,EAIE,MAAA+F,EAAY,IAAIpG,YAAU,CAC9B,YAAa,GACb,QAAS,KAAK,cACd,YAAAK,CAAA,CACD,EAMD,IAJM,MAAA+F,EAAU,WAAW,KAAK,OAAO,EAIhCA,EAAU,oBAAoB,KAAK,OAAO,IAAM,aACrD,MAAM5H,EAAM,GAAG,EAEjB,KAAK,UAAY4H,EACjB,KAAK,yBAAyB,CAChC,CAEQ,0BAA2B,CAC5B,KAAA,0BAA4B,YAAY,SAAY,CACvD,IAAIkB,EAAoB,GAEpB,KAAK,WACH,KAAK,UAAU,oBAAoB,KAAK,OAAO,IAAM,cACvD,QAAQ,MAAM,GAAG,IAAI,KAAK,EAAE,sCAAsC,EAC9CA,EAAA,KAIpB,CAAC,KAAK,WAAaA,KACrB,KAAK,KAAK,YAAY,EACtB,KAAK,uBAAuB,EAAE,MAAO3P,GAAQ,CAC3C,QAAQ,MAAMA,CAAG,CAAA,CAClB,IAEF,GAAI,CACT,CAEA,MAAM,eAAmC,CAChC,MAAA,CACL,GAAI,KAAK,QACT,eAAgB,GAChB,SAAU,KAAK,GACf,aAAc,CAAC,EACf,cAAe,CAAC,CAAA,CAEpB,CAEA,MAAM,wBAAyB,CAC7B,IAAI6P,EAAuB,GAE3B,GAAI,KAAK,UAAW,CAClB,KAAK,yBAAyB,EAE1B,KAAK,IACP,MAAM,KAAK,UAAU,WAAW,KAAK,EAAE,EACvC,KAAK,mBAAqB,MAEHA,EAAA,GAGrB,GAAA,CACI,MAAA,KAAK,UAAU,UAAS,QAC9B,CACA,KAAK,UAAY,MACnB,EAGF,GAAIA,EACF,MAAM,IAAI,MAAM,+CAA+C,KAAK,IAAI,CAE5E,CAEA,MAAM,YACJ5K,EACAzE,EACAuF,EACAzB,EACmB,CACnB,MAAM2L,EAAY,CAChB,MAAOzP,EACP,cAAeuF,GAAY,IAAA,MAAQ,YAAY,EAC/C,KAAMzB,CAAA,EAcD,OAXK,MAAM,MAAM,GAAG,KAAK,6BAA8B,CAC5D,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,QAASW,EACT,UAAAgL,CAAA,CACD,EACD,QAAS,CACP,eAAgB,kBAClB,CAAA,CACD,CAGH,CACF,CCxNsB,eAAAiB,GAAiBvP,EAAkBwP,EAAiB,CACpE,GAAA,CAAC7P,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARM,MAAM,MAAM,GAAGvC,sBAAoC4C,IAAY,CAC1E,OAAQ,QACR,KAAM,KAAK,UAAU,CAAE,QAAAwP,EAAS,EAChC,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY7P,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CCXA,eAAsB8P,GAAmBtM,EAAe,CAClD,GAAA,CAACxD,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAW7B,OAAA,MATK,MAAM,MAAM,GAAGvC,uBAAsC,CAChE,OAAQ,OACR,KAAM,KAAK,UAAU+F,CAAK,EAC1B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYxD,EAAe,KAC5C,CAAA,CACD,GAEkB,KAAA,GAAQ,UAC7B,CChBA,eAAsB+P,GAAY7P,EAA2B,CACvD,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAE/B,MAAA,MAAM,GAAGvC,qBAAmCyC,IAAM,CACtD,OAAQ,SACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CAAA,CACD,CACH,CCMA,eAAsBgQ,IAAqB,CACrC,GAAA,CAAChQ,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAa7B,OAAA,MAVS,MAAM,MACrB,GAAGvC,iCACH,CACE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CACF,CAAA,GAEqB,KAAA,GAAQ,KACjC,CChCA,eAAsBiQ,IAAsB,CACtC,GAAA,CAACjQ,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAa7B,OAAA,MAVS,MAAM,MACrB,GAAGvC,+BACH,CACE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CACF,CAAA,GAEqB,KAAA,GAAQ,KACjC,CCVA,eAAsBkQ,GAAiB1M,EAAkB,CACnD,GAAA,CAACxD,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARU,MAAM,MAAM,GAAGvC,8BAA6C,CAC3E,OAAQ,OACR,KAAM,KAAK,UAAU+F,CAAK,EAC1B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYxD,EAAe,KAC5C,CAAA,CACD,GACqB,MACxB,CClBA,eAAsBmQ,GAAa3M,EAAwC,CACrE,GAAA,CAACxD,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAYrC,OAFgB,MARH,MAAM,MAAM,GAAGvC,2BAA0C,CACpE,OAAQ,OACR,KAAM,KAAK,UAAU+F,CAAK,EAC1B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYxD,EAAe,KAC5C,CAAA,CACD,GAC0B,QAEZ,MAAM,IAClBrB,GAAW,IAAI+O,EAAO/O,EAAE,GAAIA,EAAE,KAAMA,EAAE,eAAgBA,EAAE,IAAI,CAAA,CAEjE,CCjBA,eAAsByR,IAAiD,CACjE,GAAA,CAACpQ,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAEjC,IAAAzC,EAAY,IAAI,gBAAgB,EAAE,EAElC,OAAO,OAAW,KAAe,OAAO,WAC1CA,EAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM,GAGlD,MAAA8S,EAAU9S,EAAU,IAAI,OAAO,EAErC,GAAI8S,IAAY,MAAQA,EAAQ,KAAA,IAAW,GAClC,OAET,MAAM9Q,EAAW,MAAM,MACrB,GAAG9B,qBAAqC4S,EACxC,CACE,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYrQ,EAAe,KAC5C,CACF,CAAA,EAGI,CAAE,OAAAoM,EAAQ,SAAAkE,CAAA,EAAa,MAAM/Q,EAAS,KAAK,EAQ1C,OANS,MAAM4Q,GAAa,CACjC,KAAM,CAAE,CAAC/D,CAAM,EAAG,CAACkE,CAAQ,CAAE,EAC7B,QAAS,GACT,KAAM,SAAA,CACP,CAGH,CCnCA,eAAsBC,GAAUlQ,EAAmC,CAC7D,GAAA,CAACL,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAS/B,MAAAmI,EAAS,MAPF,MAAM,MAAM,GAAG1K,sBAAoC4C,IAAY,CAC1E,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYL,EAAe,KAC5C,CAAA,CACD,GACyB,OACpB2D,EAAOwE,EAAO,KACpB,OAAO,IAAIuF,EAAOrN,EAAUsD,EAAMwE,EAAO,eAAgBA,EAAO,IAAI,CACtE,CCdA,eAAsBqI,GAAgC,CAChD,GAAA,CAACxQ,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU/B,MAAAyQ,EAAU,MARH,MAAM,MAAM,GAAGhT,kCAAiD,CAC3E,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,QAAS,GAAM,KAAM,UAAW,EACvD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,GAC0B,OACnB,OAAAyQ,EAAA,MACDA,EAAQ,MAAM,IAClB9R,GACC,IAAI+O,EACF/O,EAAE,GACFA,EAAE,KACFA,EAAE,eACFA,EAAE,IACJ,CAAA,CAEN,CCvBA,eAAsB+R,GAASC,EAA+B,CACxD,GAAA,CAAC3Q,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAa7B,OAAA,MAXK,MAAM,MACjB,GAAGvC,8BAA4CkT,IAC/C,CACE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY3Q,EAAe,KAC5C,CACF,CAAA,GAGiB,KAAA,GAAQ,KAC7B,CCjBA,eAAsB4Q,GAAWD,EAAc,CAWvC,MAAApS,EAAS,MAVF,MAAM,MAAM,GAAGd,yBAAwC,CAClE,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,QAAS,CAACkT,CAAI,CAAA,CACf,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY3Q,EAAe,KAC5C,CAAA,CACD,GACyB,OACtB,GAAAzB,EAAO,SAAS,SAAW,EACvB,MAAA,IAAI,MAAM,gBAAgB,EAE3B,OAAAA,EAAO,SAAS,CAAC,CAC1B,CCfA,eAAsBsS,GAAS3Q,EAA6B,CACtD,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAS9B,OAAA,MAPM,MAAM,MAAM,GAAGvC,qBAAmCyC,IAAM,CACnE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CCbA,eAAsB8Q,GAAgB5Q,EAA2B,CAC3D,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAUrC,OADe,MAPF,MAAM,MAAM,GAAGvC,qBAAmCyC,YAAc,CAC3E,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CAAA,CACD,GACyB,QACZ,KAChB,CCZA,eAAsB+Q,IAAsC,CACtD,GAAA,CAAC/Q,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAY7B,OAAA,MAVc,MAAM,MAC1B,GAAGvC,mCACH,CACE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CACF,CAAA,GAE0B,KAAA,GAAQ,KACtC,CCdA,eAAsBgR,MACjBC,EACmD,CAChD,MAAAhE,EAAYgE,EAAI,KAAK,EAAE,OAAQtS,GAAM,CAAC,CAACA,CAAC,EAE1C,OAAAsO,EAAU,SAAW,EAChB,IAgBS,MAbL,MAAM,MACjB,GAAGxP,oCACH,CACE,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,UAAAwP,CAAA,CACD,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYjN,EAAe,KAC5C,CACF,CAAA,GAE2B,QACZ,KACnB,CCxBA,eAAsBkR,IAAsC,CACtD,GAAA,CAAClR,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAUrC,MAAMmR,GADU,MAPH,MAAM,MAAM,GAAG1T,8BAA6C,CACvE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,GAC0B,QACD,MAEnB,OADY,MAAMwQ,KACP,OAAQ7R,GAAMwS,EAAU,SAASxS,EAAE,EAAE,CAAC,CAC1D,CCfA,eAAsByS,IAAwC,CACxD,GAAA,CAACpR,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU/B,MAAAmR,GADU,MAPH,MAAM,MAAM,GAAG1T,uBAAsC,CAChE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,GAC0B,QACD,MAAM,IAC7BrB,GAA4BA,EAAE,QAAA,EAG1B,OADY,MAAM6R,KACP,OAAQ7R,GAAMwS,EAAU,SAASxS,EAAE,EAAE,CAAC,CAC1D,CClBA,eAAsB0S,IAAiC,CACjD,GAAA,CAACrR,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAUrC,OADgB,MAPC,MAAM,MAAM,GAAGvC,qBAAoC,CAClE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,GAC8B,QAChB,MAAM,OAClBrB,GAA4BA,EAAE,OAAA,CAEnC,CCUA,eAAsB2S,GAAkB9N,EAAkB,CACpD,GAAA,CAACxD,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAa9B,OAAA,MAXU,MAAM,MACrB,GAAGvC,0CACH,CACE,OAAQ,OACR,KAAM,KAAK,UAAU+F,CAAK,EAC1B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYxD,EAAe,KAC5C,CACF,CAAA,GAEoB,MACxB,CCpBA,eAAsBuR,IAAsB,CACtC,GAAA,CAACvR,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAa7B,OAAA,MAVS,MAAM,MACrB,GAAGvC,sCACH,CACE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CACF,CAAA,GAEqB,KAAA,GAAQ,KACjC,CCrCA,eAAsBwR,IAAgC,CAChD,GAAA,CAACxR,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAUrC,OADe,MAPF,MAAM,MAAM,GAAGvC,oBAAmC,CAC7D,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,GACyB,QACZ,KAChB,CCbsB,eAAAyR,GACpBvR,EACAwR,EACiB,CACb,GAAA,CAAC1R,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARM,MAAM,MAAM,GAAGvC,qBAAmCyC,IAAM,CACnE,OAAQ,QACR,KAAM,KAAK,UAAUwR,CAAI,EACzB,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY1R,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CChBA,eAAsB2R,GAAYpI,EAAmC,CAC/D,GAAA,CAACvJ,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAa7B,OAAA,MAXS,MAAM,MACrB,GAAGvC,sBAAoC8L,EAAO,KAC9C,CACE,OAAQ,QACR,KAAM,KAAK,UAAUA,CAAM,EAC3B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYvJ,EAAe,KAC5C,CACF,CAAA,GAEqB,MACzB,CChBA,eAAsB4R,GAAUrH,EAA6B,CACvD,GAAA,CAACvK,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU7B,OAAA,MARS,MAAM,MAAM,GAAGvC,oBAAkC8M,EAAK,KAAM,CAC3E,OAAQ,QACR,KAAM,KAAK,UAAUA,CAAI,EACzB,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYvK,EAAe,KAC5C,CAAA,CACD,GACsB,MACzB,CC4BA,eAAsB6R,GAAerO,EAAkB,CACjD,GAAA,CAACxD,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU7B,OAAA,MARS,MAAM,MAAM,GAAGvC,yBAAwC,CACtE,OAAQ,OACR,KAAM,KAAK,UAAU+F,CAAK,EAC1B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYxD,EAAe,KAC5C,CAAA,CACD,GACsB,MACzB,CCtDA,eAAsB8R,GAAYC,EAAgC,CAC5D,GAAA,CAAC/R,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARM,MAAM,MAAM,GAAGvC,oBAAmC,CAC7D,OAAQ,OACR,KAAM,KAAK,UAAUsU,CAAK,EAC1B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY/R,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CCbA,eAAsBgS,IAAyD,CACzE,GAAA,CAAChS,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU7B,OAAA,MARK,MAAM,MAAM,GAAGvC,kCAAiD,CAC3E,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,GAEkB,KAAA,GAAQ,KAC7B,CCbA,eAAsBiS,GACpB/R,EAC6B,CACzB,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAa7B,OAAA,MAXK,MAAM,MACjB,GAAGvC,mCAAiDyC,IACpD,CACE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CACF,CAAA,GAGiB,MACrB,CClBsB,eAAAkS,GACpBhS,EACAiS,EAC6B,CACzB,GAAA,CAACnS,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAc7B,OAAA,MAZK,MAAM,MACjB,GAAGvC,mCAAiDyC,IACpD,CACE,OAAQ,QACR,KAAM,KAAK,UAAUiS,CAAY,EACjC,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYnS,EAAe,KAC5C,CACF,CAAA,GAGiB,MACrB,CCsBO,MAAMoS,EAAN,KAAY,CAYjB,aAAa,iBAAiB/R,EAAkB,CAC9C+R,EAAM,gBAAkB/R,CAC1B,CAEA,aAAa,kBAAoC,CAC3C,GAAA,CAACL,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAEjC,GAAA,CAACoS,EAAM,gBACH,MAAA,IAAI,MAAM,yBAAyB,EAerC,MAAAjK,GADU,MAXH,MAAM,MACjB,GAAG1K,kCACH,CACE,OAAQ,OACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CACF,CAAA,GAGyB,QACJ,MAAM,KAC1BrB,GAAsBA,EAAE,KAAOyT,EAAM,eAAA,EAElCzO,EAAOwE,EAAO,KACdkK,EAAU,IAAI3E,EAClB0E,EAAM,gBACNzO,EACAgC,EAAQ3F,EAAe,mBAAmB,EAC1CmI,EAAO,IAAA,EAET,OAAAiK,EAAM,aAAa,KAAK,IAAI,QAAQC,CAAO,CAAC,EACrCA,CACT,CAEA,aAAa,cAAcC,EAAkC,CACrD,MAAA7K,EAAO,IAAIwH,GAAWqD,CAAG,EAC1B,OAAA7K,EAAA,GAAK,MAAMA,EAAK,YAAY,EAC1BA,CACT,CAEA,aAAa,UAAUpH,EAAmC,CAClD,MAAAgS,EAAU,MAAM9B,GAAUlQ,CAAQ,EACxC,OAAA+R,EAAM,aAAa,KAAK,IAAI,QAAQC,CAAO,CAAC,EACrCA,CACT,CAkCF,EA9FO,IAAME,EAANH,EACLxU,EADW2U,EACJ,mBACP3U,EAFW2U,EAEJ,eAAkC,CAAA,GAEzC3U,EAJW2U,EAIJ,cAAcT,IACrBlU,EALW2U,EAKJ,aAAaf,IACpB5T,EANW2U,EAMJ,WAAW1B,IAClBjT,EAPW2U,EAOJ,aAAad,IACpB7T,EARW2U,EAQJ,cAAcxC,IACrBnS,EATW2U,EASJ,mBAAmB3C,IAC1BhS,EAVW2U,EAUJ,kBAAkBzB,IAoDzBlT,EA9DW2U,EA8DJ,qBAAqBzC,IAC5BlS,EA/DW2U,EA+DJ,kBAAkBlI,IACzBzM,EAhEW2U,EAgEJ,gBAAgB9G,IACvB7N,EAjEW2U,EAiEJ,qBAAqBvC,IAC5BpS,EAlEW2U,EAkEJ,sBAAsBtC,IAC7BrS,EAnEW2U,EAmEJ,mBAAmBrC,IAC1BtS,EApEW2U,EAoEJ,qBAAqBpG,GAC5BvO,EArEW2U,EAqEJ,gCAAgChG,IACvC3O,EAtEW2U,EAsEJ,kBAAkBnC,IACzBxS,EAvEW2U,EAuEJ,aAAa/B,GACpB5S,EAxEW2U,EAwEJ,WAAW7B,IAClB9S,EAzEW2U,EAyEJ,aAAa3B,IACpBhT,EA1EW2U,EA0EJ,mBAAmBxB,IAC1BnT,EA3EW2U,EA2EJ,qBAAqBvB,IAC5BpT,EA5EW2U,EA4EJ,mBAAmBrB,IAC1BtT,EA7EW2U,EA6EJ,WAAWnF,IAClBxP,EA9EW2U,EA8EJ,qBAAqBnB,IAC5BxT,EA/EW2U,EA+EJ,sBAAsBrF,IAC7BtP,EAhFW2U,EAgFJ,aAAalB,IACpBzT,EAjFW2U,EAiFJ,oBAAoBjB,IAC3B1T,EAlFW2U,EAkFJ,sBAAsBhB,IAC7B3T,EAnFW2U,EAmFJ,eAAe1F,IACtBjP,EApFW2U,EAoFJ,WAAWnI,IAClBxM,EArFW2U,EAqFJ,cAAcZ,IACrB/T,EAtFW2U,EAsFJ,YAAYX,IACnBhU,EAvFW2U,EAuFJ,iBAAiBV,IACxBjU,EAxFW2U,EAwFJ,eAAepC,IACtBvS,EAzFW2U,EAyFJ,cAAc/G,GACrB5N,EA1FW2U,EA0FJ,iBAAiBhP,GACxB3F,EA3FW2U,EA2FJ,0BAA0BP,IACjCpU,EA5FW2U,EA4FJ,uBAAuBN,IAC9BrU,EA7FW2U,EA6FJ,yBAAyBL,ICtI3B,MAAMM,EAAS,CACpB,aAAoB,IAAI5P,EAAaK,EAAe+J,EAAc,CAC5D,GAAA,CACF,MAAMzO,EAAS,MAAM,MAAMd,EAAkB,sBAAuB,CAClE,OAAQ,OACR,KAAM,KAAK,UAAU,CACnB,eAAgBkI,EAAQ3F,EAAe,WAAW,EAAE,eACpD,IAAA4C,EACA,MAAAK,EACA,KAAA+J,CAAA,CACD,EACD,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYhN,EAAe,KAC5C,CAAA,CACD,EACKyS,EAAW,MAAMlU,EAAO,OAC1B,GAAAA,EAAO,SAAW,IACd,MAAA,IAAI,MAAMkU,EAAS,OAAO,QAE3BxN,GACD,MAAAA,CACR,CACF,CAEA,aAAoB,IAAIrC,EAA8B,CAChD,GAAA,CACF,MAAMrE,EAAS,MAAM,MACnBd,EAAkB,uBAAuBmF,IACzC,CACE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY5C,EAAe,KAC5C,CACF,CAAA,EAEIyS,EAAW,MAAMlU,EAAO,OAC1B,GAAAA,EAAO,SAAW,IACd,MAAA,IAAI,MAAMkU,EAAS,OAAO,EAElC,OAAOA,EAAS,YACTxN,GACD,MAAAA,CACR,CACF,CAEA,aAAoB,MAA0B,CACxC,GAAA,CACF,MAAM1G,EAAS,MAAM,MAAMd,EAAkB,sBAAuB,CAClE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,EACK0S,EAAe,MAAMnU,EAAO,OAC9B,GAAAA,EAAO,SAAW,IACd,MAAA,IAAI,MAAMmU,EAAa,OAAO,EAEtC,OAAOA,EAAa,YACb,GACD,MAAA,CACR,CACF,CAEA,aAAoB,OAAO9P,EAAa,CAClC,GAAA,CAWE,GAAA,EAVW,MAAM,MACnBnF,EAAkB,uBAAuBmF,IACzC,CACE,OAAQ,SACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY5C,EAAe,KAC5C,CACF,CAAA,GAEU,GACJ,MAAA,IAAI,MAAM,0BAA0B,EAE5C,aACOiF,GACD,MAAAA,CACR,CACF,CAEA,aAAoB,MAAM0N,EAAgB,CACpC,GAAA,CACF,MAAMpU,EAAS,MAAM,MACnBd,EAAkB,4BAClB,CACE,OAAQ,OACR,KAAM,KAAK,UAAU,CAAE,KAAAkV,EAAM,EAC7B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY3S,EAAe,KAC5C,CACF,CAAA,EAEE,GAAA,CAACzB,EAAO,GACJ,MAAA,IAAI,MAAM,0BAA0B,EAG5C,OADqB,MAAMA,EAAO,QACd,YACb0G,GACD,MAAAA,CACR,CACF,CACF,CChHO,SAAS2N,GAAoBC,EAA2B,CACtD,OAAA,WAAW,KAAK9T,EAAA,OAAO8T,CAAK,EAAIlU,GAAMA,EAAE,WAAW,CAAC,CAAC,CAC9D,CCIO,SAASmU,GAAuB,CAC/B,KAAA,CAAE,UAAAC,CAAc,EAAA,UAEtB,OAAKA,EAIDA,EAAU,SAAS,UAAU,EACxB,UACEA,EAAU,SAAS,MAAM,EAC3B,OACEA,EAAU,SAAS,SAAS,EAC9B,SACEA,EAAU,SAAS,SAAS,EAC9B,SACEA,EAAU,SAAS,OAAO,GAAKA,EAAU,SAAS,UAAU,EAC9D,KAEA,QAdA,OAgBX,CCrBA,MAAMC,GAA0B,cAEzB,MAAMC,EAAY,CAuBhB,YACG9K,EACAoB,EACR,CAzBM3L,EAAA,aAAiB,IAcjBA,EAAA,uBAA2B,IAC3BA,EAAA,qBACAA,EAAA,cAAuC,CAAA,GACvCA,EAAA,iBAAqB,IACrBA,EAAA,iBAAoB,GACpBA,EAAA,uBAA0B,GAC1BA,EAAA,kBAAqB,GA2BtBA,EAAA,eAAU,MAAOmC,GAA2B,OAC3C,MAAAb,GAAOD,EAAAc,EAAI,QAAQ,aAAZ,YAAAd,EAAwB,WACrC,GAAI,CAACC,EACH,OAGG,KAAK,kBACR,KAAK,gBAAkB,IAGnB,KAAA,CAAE,aAAAgU,EAAc,MAAAC,CAAU,EAAA,KAE9B,GAAA,CAACD,GACDnT,EAAI,OAAO,OAAO,aAAeiT,IACjCG,IAAU,GAEV,OAEI,MAAAC,EAAcR,GAAoB1T,CAAI,EACxC,GAAA,CACF,MAAMgU,EAAa,gBACjBE,EAAY,OACZ,KAAK,aAAA,QAEAjP,GACC,QAAA,KACN,iEACA,CAAE,MAAAA,CAAM,CAAA,EAEV,KAAK,sBAAsB,KAAK,CAClC,CAAA,GAGMvG,EAAA,qBAAiByV,GAAwB,CACzC,KAAA,CAAE,aAAAH,CAAiB,EAAA,KAEzB,GAAI,CAACA,EACH,QAEE,KAAK,OAAO,OAAS,KAAK,YAAc,KAAK,YAAc,MACxD,KAAA,OAAO,QAASI,GAAM,CACzBA,EAAE,KAAK,CAAA,CACR,EACD,KAAK,UAAY,GACjB,KAAK,OAAS,IAEV,MAAAC,EAAQ,KAAK,YAAYF,CAAM,EAChCE,GAGAA,EAAM,SAGP,KAAK,YAAc,KACrB,KAAK,UAAYL,EAAa,YAC9B,KAAK,gBAAkB,EACvB,KAAK,UAAY,IAEnBK,EAAM,MAAM,KAAK,UAAY,KAAK,gBAAiB,EAAGF,EAAO,QAAQ,EAChE,KAAA,iBAAmBE,EAAM,OAAO,SAChC,KAAA,OAAO,KAAKA,CAAK,EAAA,GApFd,KAAA,OAAApL,EACA,KAAA,OAAAoB,EAEH,KAAA,OAAO,mCAAmCA,CAAM,EACrD,KAAK,OAAO,oBAAoB,CAAClB,EAAiBtI,IAAyB,CACzE,KAAK,QAAQA,CAAG,CAAA,CACjB,EAEG+S,EAAQ,IAAM,UAAYA,EAAA,IAAc,KAC1C,KAAK,sBAAsB,KAAK,EAEhC,KAAK,sBAAsB,MAAM,EAG7B,MAAAU,EACJ,OAAO,cAAiB,OAAe,mBAEpC,KAAA,aAAe,IAAIA,CAC1B,CAvCA,MAAa,MAAO,WACdvU,EAAA,KAAK,eAAL,YAAAA,EAAmB,SAAU,aACzB,OAAAmK,EAAA,KAAK,eAAL,YAAAA,EAAmB,UAE3B,KAAK,MAAQ,EACf,CAEA,MAAa,OAAQ,CACb,MAAA,KAAK,aAAa,UACxB,KAAK,MAAQ,EACf,CA+BO,SAAU,CACV,KAAA,OAAO,kCAAkC,KAAK,MAAM,CAC3D,CAiEQ,YAAYiK,EAAqB,CACjC,KAAA,CAAE,aAAAH,CAAiB,EAAA,KACzB,GAAI,CAACA,EACH,OAEI,MAAAO,EAASP,EAAa,qBAC5B,OAAAO,EAAO,OAASJ,EACTI,EAAA,QAAQP,EAAa,WAAW,EACvCO,EAAO,KAAO,GACPA,EAAA,QAAW9U,GAAa,CAC7B,KAAK,OAAO,OAAO,KAAK,OAAO,QAAQ8U,CAAM,EAAG,CAAC,EAC7C,KAAK,OAAO,SAAW,IACzB,KAAK,UAAY,GACnB,EAGKA,CACT,CAEQ,sBAAsB/J,EAA2B,CACjD,KAAA,CAAE,OAAAH,CAAW,EAAA,MAEhB,SACC,MAAM,KAAK,OAAO,sBAAsBA,EAAO,KAAMG,CAAS,IAGpE,CACF,CC9IO,MAAMgK,EAAQ,CACnB,aAAa,cAAoC,CAC3C,GAAA,CAAC1T,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAUrC,OADiB,MAPJ,MAAM,MAAM,GAAGvC,sBAAqC,CAC/D,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,GAC2B,QACZ,KAClB,CAEA,aAAa,eAAe2T,EAAsC,CAC5D,GAAA,CAAC3T,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARM,MAAM,MAAM,GAAGvC,sBAAqC,CAC/D,OAAQ,OACR,KAAM,KAAK,UAAUkW,CAAO,EAC5B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY3T,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CAEA,aAAa,WAAWE,EAA+B,CACjD,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAS9B,OAAA,MAPM,MAAM,MAAM,GAAGvC,uBAAqCyC,IAAM,CACrE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CAEA,aAAa,aACXE,EACAyT,EACmB,CACf,GAAA,CAAC3T,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARM,MAAM,MAAM,GAAGvC,uBAAqCyC,IAAM,CACrE,OAAQ,QACR,KAAM,KAAK,UAAUyT,CAAO,EAC5B,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY3T,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CACA,aAAa,cAAcE,EAA2B,CAChD,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAE/B,MAAA,MAAM,GAAGvC,uBAAqCyC,IAAM,CACxD,OAAQ,SACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CAAA,CACD,CACH,CAEA,aAAa,eAAeE,EAAmC,CACzD,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAY9B,OAAA,MAVM,MAAM,MACjB,GAAGvC,uBAAqCyC,SACxC,CACE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CACF,CAAA,GAEgB,MACpB,CACF,CC5FO,MAAM4T,EAAK,CAChB,aAAa,WAA8B,CACrC,GAAA,CAAC5T,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAUrC,OADc,MAPD,MAAM,MAAM,GAAGvC,mBAAkC,CAC5D,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,GACwB,QACZ,KACf,CAEA,aAAa,WAAW0R,EAA6B,CAC/C,GAAA,CAAC1R,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARM,MAAM,MAAM,GAAGvC,mBAAkC,CAC5D,OAAQ,OACR,KAAM,KAAK,UAAUiU,CAAI,EACzB,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY1R,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CAEA,aAAa,QAAQE,EAA4B,CAC3C,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAS9B,OAAA,MAPM,MAAM,MAAM,GAAGvC,oBAAkCyC,IAAM,CAClE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CAEA,aAAa,UAAUE,EAAYwR,EAAsC,CACnE,GAAA,CAAC1R,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARM,MAAM,MAAM,GAAGvC,oBAAkCyC,IAAM,CAClE,OAAQ,QACR,KAAM,KAAK,UAAUwR,CAAI,EACzB,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY1R,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CAEA,aAAa,WAAWE,EAA2B,CAC7C,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAE/B,MAAA,MAAM,GAAGvC,oBAAkCyC,IAAM,CACrD,OAAQ,SACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CAAA,CACD,CACH,CACF,CCxEO,MAAM6T,EAAK,CAChB,aAAa,WAA8B,CACrC,GAAA,CAAC7T,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAUrC,OADc,MAPD,MAAM,MAAM,GAAGvC,mBAAkC,CAC5D,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYuC,EAAe,KAC5C,CAAA,CACD,GACwB,QACZ,KACf,CAEA,aAAa,WAAW8T,EAA6B,CAC/C,GAAA,CAAC9T,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARM,MAAM,MAAM,GAAGvC,mBAAkC,CAC5D,OAAQ,OACR,KAAM,KAAK,UAAUqW,CAAI,EACzB,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY9T,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CAEA,aAAa,QAAQE,EAA4B,CAC3C,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAS9B,OAAA,MAPM,MAAM,MAAM,GAAGvC,oBAAkCyC,IAAM,CAClE,OAAQ,MACR,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CAEA,aAAa,UAAUE,EAAY4T,EAAsC,CACnE,GAAA,CAAC9T,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAU9B,OAAA,MARM,MAAM,MAAM,GAAGvC,oBAAkCyC,IAAM,CAClE,OAAQ,QACR,KAAM,KAAK,UAAU4T,CAAI,EACzB,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAY9T,EAAe,KAC5C,CAAA,CACD,GACiB,MACpB,CAEA,aAAa,WAAWE,EAA2B,CAC7C,GAAA,CAACF,EAAe,MACZ,MAAA,IAAI,MAAM,mBAAmB,EAE/B,MAAA,MAAM,GAAGvC,oBAAkCyC,IAAM,CACrD,OAAQ,QACR,KAAM,KAAK,UAAU,CAAE,QAAS,GAAO,OAAQ,KAAM,OAAQ,KAAM,EACnE,QAAS,CACP,eAAgB,mBAChB,cAAe,UAAYF,EAAe,KAC5C,CAAA,CACD,CACH,CACF,CC7EO,MAAM+T,GAAe,CAAC,SAAU,WAAY,eAAe,ECIrDC,GAAS,SACTC,GAAW,WACXC,GAAgB,gBCJhBC,GAAoC,CAC/C,OACA,QACA,OACA,MACA,OACA,QACF,ECTaC,GAAkB,CAAC,MAAO,QAAS,MAAM,ECAzC1I,GAAa,CACxB,kBACA,uBACA,wBACA,iCACA,kBACA,mBACA,mBACA,SACA,UACA,SACA,YACF,ECZa2I,GAAiB,CAC5B,UACA,cACA,UACA,OACF,ECHaC,GAAoB,CAAC,YAAa,WAAY,QAAQ,ECFtDC,GAAa,CAAC,OAAQ,UAAW,QAAS,UAAU,ECApDC,GAAiB,CAAC,WAAW,ECA7B7R,GAAWmF,GACf,IAAI,QAAS1I,GAAY,WAAWA,EAAS0I,EAAI,GAAI,CAAC,ECI/D,GAAI,CACF,MAAMvK,EACJ,OAAO,OAAW,KAAe,OAAO,SACpC,IAAI,gBAAgB,OAAO,SAAS,MAAM,EAC1C,IAAI,gBAAgB,EAAE,EAEtBkX,EAAYlX,EAAU,IAAI,QAAQ,EACpCkX,GACFlC,EAAM,iBAAiBkC,CAAS,EAG5B,MAAAC,EAAUnX,EAAU,IAAI,MAAM,EAChCmX,GACF1U,EAAe,eAAe0U,CAAO,EAGpBnX,EAAU,IAAI,QAAQ,GAEvCyC,EAAe,iBAAiB,EAG9B,OAAO,OAAW,KACpB0F,EAAI,0BAA0B,CAElC,MAAA,CAAa"}
|
|
1
|
+
{"version":3,"file":"data-sdk.cjs.js","sources":["../src/config/whichFormantApiUrl.ts","../src/config/index.ts","../src/stores/AuthenticationErrors.ts","../src/stores/AuthenticationStore.ts","../src/utils/getCurrentModuleContext.ts","../src/message-bus/senders/sendAppMessage.ts","../src/message-bus/senders/refreshAuthToken.ts","../src/message-bus/listeners/addAccessTokenRefreshListener.ts","../src/Authentication.ts","../src/api/getModuleConfiguration.ts","../src/message-bus/senders/disableAnalyticsBottomBar.ts","../src/message-bus/senders/goToDevice.ts","../src/message-bus/senders/goToTime.ts","../src/message-bus/senders/requestModuleData.ts","../src/message-bus/senders/sendChannelData.ts","../src/message-bus/senders/setModuleDateTimeRange.ts","../src/message-bus/senders/setupModuleMenus.ts","../src/message-bus/senders/showMessage.ts","../src/message-bus/listeners/addChannelDataListener.ts","../src/message-bus/listeners/addMenuListener.ts","../src/message-bus/listeners/addModuleConfigurationListener.ts","../src/message-bus/listeners/addModuleDataListener.ts","../src/message-bus/listeners/addOverviewDeviceListener.ts","../../common/duration.ts","../src/cache/filterDataByType.ts","../src/cache/filterDataByTime.ts","../src/cache/StoreCache.ts","../src/api/queryTelemetry.ts","../src/cache/queryStore.ts","../src/message-bus/listeners/addStreamLIstener.ts","../src/message-bus/bidirectional/getDate.ts","../src/message-bus/bidirectional/prompt.ts","../src/App.ts","../../common/defined.ts","../src/model/SessionType.ts","../src/utils/RtcClientPool.ts","../src/AppRtcClientPools.ts","../src/CaptureStream.ts","../../common/delay.ts","../src/utils/isRtcPeer.ts","../src/DataChannel.ts","../src/Manipulator.ts","../src/RequestDataChannel.ts","../src/devices/BaseDevice.ts","../src/utils/serializeHash.ts","../src/api/getViews.ts","../src/api/createShareLink.ts","../src/utils/aggregateFunctionUtils.ts","../src/api/queryEvents.ts","../src/api/eventsCounter.ts","../src/api/getAnnotationCount.ts","../src/api/getAnnotationCountByIntervals.ts","../src/api/getTelemetry.ts","../src/api/getRealtimeSessions.ts","../src/api/getPeers.ts","../src/api/createDevice.ts","../src/api/patchDevice.ts","../src/api/getDevicesData.ts","../src/api/queryDevicesData.ts","../src/api/disableDevice.ts","../src/devices/Device.ts","../src/devices/PeerDevice.ts","../src/api/addDeviceToFleet.ts","../src/api/aggregateTelemetry.ts","../src/api/deleteFleet.ts","../src/api/getAnalyticsStreams.ts","../src/api/getAnalyticsModules.ts","../src/api/getAnalyticsRows.ts","../src/api/queryDevices.ts","../src/api/getCurrentGroup.ts","../src/api/getDevice.ts","../src/api/getDevices.ts","../src/api/getEvent.ts","../src/api/getFileUrl.ts","../src/api/getFleet.ts","../src/api/getFleetDevices.ts","../src/api/getInterventions.ts","../src/api/getLatestTelemetry.ts","../src/api/getOnlineDevices.ts","../src/api/getRealtimeDevices.ts","../src/api/getStreams.ts","../src/api/getTaskReportRows.ts","../src/api/getTaskreportTables.ts","../src/api/listFleets.ts","../src/api/patchFleet.ts","../src/api/patchStreams.ts","../src/api/patchView.ts","../src/api/queryAnalytics.ts","../src/api/createFleet.ts","../src/api/getAllEventTriggerGroup.ts","../src/api/getEventTriggerGroup.ts","../src/api/patchEventTriggerGroup.ts","../src/Fleet.ts","../src/KeyValue.ts","../src/utils/stringToArrayBuffer.ts","../../common/browser.ts","../src/AudioPlayer.ts","../src/Account.ts","../src/Role.ts","../src/User.ts","../src/model/accessLevels.ts","../src/model/AccessLevel.ts","../src/model/aggregateLevels.ts","../src/model/annotationTypes.ts","../src/model/eventTypes.ts","../src/model/healthStatuses.ts","../src/model/interventionTypes.ts","../src/model/severities.ts","../src/model/videoMimeTypes.ts","../src/utils/timeout.ts","../src/init.ts"],"sourcesContent":["const DEFAULT_FORMANT_API_URL = \"https://api.formant.io\";\n\ninterface IHasString {\n get(key: string): string | null;\n has(key: string): boolean;\n}\n\nexport function whichFormantApiUrl(global: any, urlParams: IHasString) {\n // url params may not be available when using react native\n try {\n if (urlParams.get(\"formant_stage\")) {\n return \"https://api-stage.formant.io\";\n }\n\n if (urlParams.get(\"formant_dev\")) {\n return \"https://api-dev.formant.io\";\n }\n\n if (urlParams.get(\"formant_local\")) {\n return \"https://api.formant.local\";\n }\n\n if (urlParams.get(\"formant_url\")) {\n const customUrl = urlParams.get(\"formant_url\");\n if (customUrl !== null) {\n try {\n return new URL(customUrl).origin;\n } catch {\n console.warn(\n `Ignoring malformed \\`formant_url\\` url parameter: ${customUrl}`\n );\n }\n }\n }\n } catch (_) {}\n\n if (\n typeof global !== \"undefined\" &&\n \"FORMANT_API_URL\" in global &&\n typeof global.FORMANT_API_URL === \"string\"\n ) {\n return global.FORMANT_API_URL;\n }\n\n return DEFAULT_FORMANT_API_URL;\n}\n","import { whichFormantApiUrl } from \"./whichFormantApiUrl\";\n\nexport const FORMANT_API_URL = whichFormantApiUrl(\n typeof window !== \"undefined\" ? window : globalThis,\n new URLSearchParams(\n typeof window !== \"undefined\" && window.location\n ? window.location.search\n : undefined\n )\n);\n","import { IChallenge } from \"../model/IChallenge\";\n\nexport class LoginFailureError extends Error {\n readonly reason: string;\n\n constructor(reason: string) {\n super(\"login failed\");\n this.reason = reason;\n this.name = \"LoginFailureError\";\n Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain\n }\n}\n\nexport class LoginChallengedError extends Error {\n readonly challenge: IChallenge;\n\n constructor(challenge: IChallenge) {\n super(\"login challenged\");\n this.challenge = challenge;\n this.name = \"LoginChallengedError\";\n Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain\n }\n}\n","import { decode } from \"base-64\";\n\nimport { IAuthenticationStore } from \"./IAuthenticationStore\";\nimport { AuthenticationResult } from \"./AuthenticationResult\";\nimport {\n LoginFailureError,\n LoginChallengedError,\n} from \"./AuthenticationErrors\";\n\nimport { IUser } from \"../model/IUser\";\nimport { IAuthentication } from \"./IAuthentication\";\nimport { IConfirmForgotPasswordRequest } from \"./IConfirmForgotPasswordRequest\";\nimport { IRespondToNewPasswordRequiredChallengeRequest } from \"./IRespondToNewPasswordRequiredChallengeRequest\";\n\ninterface IAuthenticationStoreOptions {\n apiUrl: string;\n\n refreshAuthToken: () => void;\n addAccessTokenRefreshListener: (\n callback: (token: string) => void\n ) => () => void;\n}\n\nexport class AuthenticationStore implements IAuthenticationStore {\n private _refreshToken: string | undefined;\n private _isShareToken: boolean = false;\n private _currentOrganization: string | undefined;\n private _currentUser: IUser | undefined;\n private _defaultDeviceId: string | undefined;\n private _token: string | undefined;\n private _waitingForAuth: Set<(result: boolean) => void> = new Set();\n private _refreshTimer: ReturnType<typeof setTimeout> | undefined;\n\n private readonly _apiUrl: string;\n private readonly _refreshAuthToken: () => void;\n private readonly _addAccessTokenRefreshListener: (\n callback: (token: string) => void\n ) => () => void;\n\n constructor({\n apiUrl,\n refreshAuthToken,\n addAccessTokenRefreshListener,\n }: IAuthenticationStoreOptions) {\n this._apiUrl = apiUrl;\n this._refreshAuthToken = refreshAuthToken;\n this._addAccessTokenRefreshListener = addAccessTokenRefreshListener;\n }\n\n get token(): string | undefined {\n return this._token;\n }\n\n get currentUser(): IUser | undefined {\n return this._currentUser;\n }\n\n get currentOrganization(): string | undefined {\n return this._currentOrganization;\n }\n\n get defaultDeviceId(): string | undefined {\n return this._defaultDeviceId;\n }\n\n /**\n * @deprecated Do not use directly. This will be removed in future versions of the API\n */\n get refreshToken(): string | undefined {\n return this._refreshToken;\n }\n\n /**\n * @deprecated Do not use directly. This will be removed in future versions of the API\n */\n get isShareToken(): boolean {\n return this._isShareToken;\n }\n\n login(email: string, password: string): Promise<IAuthentication>;\n login(\n email: string,\n password: string,\n options: { advanced: true }\n ): Promise<AuthenticationResult>;\n async login(\n email: string,\n password: string,\n options: { advanced?: boolean } = {}\n ): Promise<IAuthentication | AuthenticationResult> {\n const { advanced = false } = options;\n\n try {\n const result = await fetch(`${this._apiUrl}/v1/admin/auth/login`, {\n method: \"POST\",\n body: JSON.stringify({ email, password }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n const auth = await result.json();\n if (result.status !== 200) {\n throw new LoginFailureError(auth.message);\n }\n\n if (\"challenge\" in auth) {\n throw new LoginChallengedError(auth.challenge);\n }\n\n const { authentication } = auth;\n await this.loginWithToken(\n authentication.accessToken as string,\n authentication.refreshToken as string\n );\n\n return !advanced\n ? authentication\n : {\n result: \"success\",\n authentication,\n };\n } catch (err: unknown) {\n if (!advanced) {\n console.error(\"login() failed\", { err });\n }\n\n this._waitingForAuth.forEach((_) => _(false));\n this._waitingForAuth.clear();\n\n if (!advanced) {\n throw err;\n }\n\n if (err instanceof LoginChallengedError) {\n return {\n result: \"challenged\",\n challenge: err.challenge,\n };\n }\n\n return {\n result: \"failure\",\n reason:\n err instanceof LoginFailureError\n ? err.reason\n : err instanceof Error\n ? err.message\n : String(err),\n };\n }\n }\n\n async loginWithToken(token: string, refreshToken?: string) {\n const tokenData = JSON.parse(decode(token.split(\".\")[1]));\n try {\n let userId: string | undefined;\n this._isShareToken =\n tokenData[\"formant:claims\"] &&\n tokenData[\"formant:claims\"].type == \"share\";\n\n if (tokenData[\"formant:claims\"]) {\n this._currentOrganization = tokenData[\"formant:claims\"].organizationId;\n }\n if (tokenData[\"custom:organization_id\"]) {\n this._currentOrganization = tokenData[\"custom:organization_id\"];\n }\n\n if (!this._isShareToken) {\n userId = tokenData.sub;\n }\n if (tokenData[\"formant:claims\"] && tokenData[\"formant:claims\"].userId) {\n userId = tokenData[\"formant:claims\"].userId;\n }\n\n if (userId && this._currentUser?.id !== userId) {\n const result = await fetch(`${this._apiUrl}/v1/admin/users/${userId}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + token,\n },\n });\n const data = await result.json();\n if (result.status !== 200) {\n throw new Error(data.message);\n }\n this._currentUser = data;\n }\n this._token = token;\n this._waitingForAuth.forEach((_) => _(true));\n } catch (err: unknown) {\n console.error(\"loginWithToken() failed\", { err });\n this._waitingForAuth.forEach((_) => _(false));\n } finally {\n this._waitingForAuth.clear();\n }\n\n if (refreshToken) {\n this._refreshToken = refreshToken;\n setInterval(async () => {\n if (this._refreshToken) {\n const result = await fetch(`${this._apiUrl}/v1/admin/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n refreshToken: this._refreshToken,\n }),\n });\n const refreshData = await result.json();\n this._token = refreshData.authentication.accessToken;\n }\n }, 1000 * 60 * 60);\n }\n }\n\n isAuthenticated(): boolean {\n return this._token !== undefined;\n }\n\n /**\n * @deprecated use currentUser property instead.\n */\n getCurrentUser(): IUser | undefined {\n return this._currentUser;\n }\n\n async waitTilAuthenticated(): Promise<boolean> {\n if (this.token !== undefined) {\n return true;\n } else {\n return new Promise((resolve) => {\n this._waitingForAuth.add(resolve);\n });\n }\n }\n\n async listenForRefresh() {\n // refresh token every hour\n const hour = 1000 * 60 * 60;\n const askForFreshToken = () => {\n this._refreshTimer = undefined;\n this._refreshAuthToken();\n };\n\n this._addAccessTokenRefreshListener((token: string) => {\n if (this._refreshTimer) {\n // unless I get a fresh token sooner\n clearTimeout(this._refreshTimer);\n }\n this._refreshTimer = setTimeout(askForFreshToken, hour);\n this.loginWithToken(token);\n });\n\n // refresh token every hour\n this._refreshTimer = setTimeout(askForFreshToken, hour);\n }\n\n async forgotPassword(email: string) {\n await fetch(`${this._apiUrl}/v1/admin/auth/forgot-password`, {\n method: \"POST\",\n body: JSON.stringify({ email }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n }\n\n /**\n * @example\n * // Body\n * await this.confirmForgotPassword({\n * email: \"joe@gmail.com\"\n * confirmationCode: \"1\",\n * newPassword: \"NewPassword\"\n * });\n */\n async confirmForgotPassword(request: IConfirmForgotPasswordRequest) {\n const response = await fetch(\n `${this._apiUrl}/v1/admin/auth/confirm-forgot-password`,\n {\n method: \"POST\",\n body: JSON.stringify(request),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n return response.ok;\n }\n\n async respondToNewPasswordRequiredChallenge(\n request: IRespondToNewPasswordRequiredChallengeRequest\n ) {\n const response = await fetch(\n `${this._apiUrl}/v1/admin/auth/respond-to-new-password-required-challenge`,\n {\n method: \"POST\",\n body: JSON.stringify(request),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }\n );\n\n if (response.ok) {\n return await response.json();\n }\n\n throw new Error(\"respond-to-new-password-required-challenge failed\");\n }\n\n async loginWithGoogle(token: string) {\n const response = await fetch(`${this._apiUrl}/v1/admin/auth/login-google`, {\n method: \"POST\",\n body: JSON.stringify(token),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n return await response.json();\n }\n\n async refresh(token: string) {\n const result = await fetch(`${this._apiUrl}/v1/admin/auth/refresh`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n refreshToken: token,\n }),\n });\n const refreshData = await result.json();\n await this.loginWithToken(refreshData.authentication.accessToken, token);\n }\n}\n","export function getCurrentModuleContext(): string | null {\n if (!(typeof window !== \"undefined\" && window.location)) {\n return null;\n }\n\n const urlParams = new URLSearchParams(window.location.search);\n return urlParams.get(\"module\");\n}\n","import { AppMessage } from \"./AppMessage\";\n\nexport function sendAppMessage(message: AppMessage) {\n if (!(window && window.parent)) {\n throw new Error(\"cannot send message to non-existent parent\");\n }\n window.parent.postMessage(message, \"*\");\n}\n","import { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\nimport { sendAppMessage } from \"./sendAppMessage\";\n\nexport function refreshAuthToken() {\n const moduleName = getCurrentModuleContext();\n if (!moduleName) {\n throw new Error(\"No module context\");\n }\n sendAppMessage({\n type: \"refresh_auth_token\",\n module: moduleName,\n });\n}\n","import { EmbeddedAppMessage } from \"./EmbeddedAppMessage\";\n\nexport function addAccessTokenRefreshListener(\n handler: (token: string) => void\n): () => void {\n function listener(event: MessageEvent<EmbeddedAppMessage>) {\n const msg = event.data;\n if (msg.type === \"auth_token\") {\n handler(msg.token);\n }\n }\n\n window.addEventListener(\"message\", listener);\n return () => {\n window.removeEventListener(\"message\", listener);\n };\n}\n","import { FORMANT_API_URL } from \"./config\";\nimport { IAuthenticationStore } from \"./stores/IAuthenticationStore\";\nimport { AuthenticationStore } from \"./stores/AuthenticationStore\";\nimport { refreshAuthToken } from \"./message-bus/senders/refreshAuthToken\";\nimport { addAccessTokenRefreshListener } from \"./message-bus/listeners/addAccessTokenRefreshListener\";\n\nexport const Authentication: IAuthenticationStore = new AuthenticationStore({\n apiUrl: FORMANT_API_URL,\n refreshAuthToken,\n addAccessTokenRefreshListener,\n});\n","import { FORMANT_API_URL } from \"../config\";\nimport { Authentication } from \"../Authentication\";\n\nexport async function getModuleConfiguration(\n id: string\n): Promise<string | undefined> {\n const response = await fetch(\n `${FORMANT_API_URL}/v1/admin/module-configurations/${id}`,\n {\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const moduleConfiguration = await response.json();\n return moduleConfiguration.configuration;\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\n\nexport function disableAnalyticsBottomBar() {\n sendAppMessage({\n type: \"hide_analytics_date_picker\",\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\n\nexport function goToDevice(deviceId: string) {\n sendAppMessage({\n type: \"go_to_device\",\n deviceId,\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\n\nexport function goToTime(date: Date): void {\n sendAppMessage({\n type: \"go_to_time\",\n time: date.getTime(),\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\nimport { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\n\nexport function requestModuleData() {\n const moduleName = getCurrentModuleContext();\n if (!moduleName) {\n throw new Error(\"No module context\");\n }\n sendAppMessage({\n type: \"request_module_data\",\n module: moduleName,\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\nimport { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\n\nexport function sendChannelData(channel: string, data: any) {\n const moduleName = getCurrentModuleContext();\n if (!moduleName) {\n throw new Error(\"No module context\");\n }\n\n sendAppMessage({\n type: \"send_channel_data\",\n source: moduleName,\n channel,\n data,\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\nimport { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\n\nexport function setModuleDateTimeRange(\n beforeInMilliseconds: number,\n afterInMilliseconds?: number\n) {\n const moduleName = getCurrentModuleContext();\n if (!moduleName) {\n throw new Error(\"No module context\");\n }\n sendAppMessage({\n type: \"set_module_data_time_range\",\n module: moduleName,\n before: beforeInMilliseconds,\n after: afterInMilliseconds || 0,\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\nimport { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\n\nexport function setupModuleMenus(menus: { label: string }[]) {\n const moduleName = getCurrentModuleContext();\n if (!moduleName) {\n throw new Error(\"No module context\");\n }\n sendAppMessage({\n type: \"setup_module_menus\",\n module: moduleName,\n menus,\n });\n}\n","import { sendAppMessage } from \"./sendAppMessage\";\n\nexport function showMessage(message: string) {\n sendAppMessage({ type: \"show_message\", message });\n}\n","import { EmbeddedAppMessage } from \"./EmbeddedAppMessage\";\n\nexport function addChannelDataListener(\n channel: string,\n handler: (e: { source: string; data: any }) => void\n) {\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"channel_data\" && msg.channel === channel) {\n handler({\n source: msg.source,\n data: msg.data,\n });\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","import { EmbeddedAppMessage } from \"./EmbeddedAppMessage\";\n\nexport function addMenuListener(handler: (label: string) => void) {\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"module_menu_item_clicked\") {\n handler(msg.menu);\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","import {\n EmbeddedAppMessage,\n ModuleConfigurationMessage,\n} from \"./EmbeddedAppMessage\";\n\nexport function addModuleConfigurationListener(\n handler: (event: ModuleConfigurationMessage) => void\n) {\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"module_configuration\") {\n handler(msg as ModuleConfigurationMessage);\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","import { sendAppMessage } from \"../senders/sendAppMessage\";\nimport { EmbeddedAppMessage } from \"./EmbeddedAppMessage\";\nimport { getCurrentModuleContext } from \"../../utils/getCurrentModuleContext\";\n\nexport interface ModuleData {\n queryRange: QueryRange;\n time: number;\n streams: { [stream_name: string]: Stream };\n}\n\nexport interface QueryRange {\n start: number;\n end: number;\n}\n\nexport interface Stream {\n data: StreamData[];\n loading: boolean;\n tooMuchData: boolean;\n type: string;\n}\n\nexport interface StreamData {\n points: DataPoint[];\n deviceId: string;\n agentId: string;\n name: string;\n tags: { [key: string]: string };\n type: string;\n}\n\nexport type DataPoint = [number, any];\n\nexport function addModuleDataListener(handler: (data: ModuleData) => void) {\n const moduleName = getCurrentModuleContext();\n if (moduleName) {\n sendAppMessage({ type: \"request_module_data\", module: moduleName });\n }\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"module_data\") {\n handler({\n streams: msg.streams,\n time: msg.time,\n queryRange: msg.queryRange,\n });\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","import { EmbeddedAppMessage, IDevice } from \"./EmbeddedAppMessage\";\nimport { sendAppMessage } from \"../senders/sendAppMessage\";\n\nexport function addOverviewDeviceListener(\n handler: (devices: IDevice[]) => void\n) {\n sendAppMessage({ type: \"request_devices\" });\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"overview_devices\") {\n handler(msg.data);\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","const millisecond = 1;\nconst second = 1000;\nconst minute = 60 * second;\nconst hour = 60 * minute;\nconst day = 24 * hour;\nconst week = 7 * day;\nconst month = 30 * day;\nconst year = 365 * day;\n\nexport const duration = {\n millisecond,\n second,\n minute,\n hour,\n day,\n week,\n month,\n year,\n} as const;\n","import { IStreamData } from \"../model/IStreamData\";\nimport { StreamType } from \"../model/StreamType\";\n\nexport function filterDataByType(\n datas: IStreamData[],\n type: StreamType[]\n): IStreamData[] {\n return datas.filter((_) => type.includes(_.type)) as IStreamData[];\n}\n","import { IStreamData } from \"../model/IStreamData\";\n\nexport function filterDataByTime(\n datas: IStreamData[],\n start: Date,\n end: Date\n): IStreamData[] {\n const startTime = start.getTime();\n const endTime = end.getTime();\n return datas\n .map((data) => ({\n ...data,\n points: data.points.filter(\n ([timestamp]) => timestamp >= startTime && timestamp < endTime\n ),\n }))\n .filter(({ points }) => points.length > 0);\n}\n","import { fork } from \"../../../common/fork\";\nimport { duration } from \"../../../common/duration\";\n\ninterface ICacheEntryMetadata<Value> {\n generating: boolean;\n expiration: Date;\n lastValue?: Value;\n}\n\ntype CacheKey = string;\n\nexport class StoreCache<Key, Value> {\n private entries = new Map<CacheKey, Value>();\n private metadata = new Map<CacheKey, ICacheEntryMetadata<Value>>();\n private capacity!: number;\n private timeout!: number;\n\n constructor({\n capacity,\n timeout,\n }: { capacity?: number; timeout?: number } = {}) {\n this.capacity = capacity || 10000;\n this.timeout = timeout || duration.minute;\n }\n\n public get(key: Key, generator?: () => Promise<Value>): Value | undefined {\n const cacheKey = this.keyToCacheKey(key);\n const entry = this.entries.get(cacheKey);\n const metadata = this.metadata.get(cacheKey);\n\n if (\n (entry === undefined ||\n (metadata && metadata?.expiration.getTime() < Date.now())) &&\n !metadata?.generating &&\n generator\n ) {\n this.generate(key, generator());\n }\n\n if (entry === undefined && metadata && metadata.lastValue !== undefined) {\n return metadata.lastValue;\n }\n\n return entry;\n }\n\n public set(key: Key, value: Value) {\n const cacheKey = this.keyToCacheKey(key);\n this.metadata.set(cacheKey, {\n generating: false,\n expiration: new Date(Date.now() + this.timeout),\n lastValue: value,\n });\n this.entries.set(cacheKey, value);\n\n if (this.metadata.size > this.capacity) {\n this.deleteOldestEntry();\n }\n }\n\n public clear() {\n this.entries.clear();\n [...this.metadata.values()].forEach((value) => (value.generating = false));\n }\n\n public clearKey(key: string): void {\n this.metadata.delete(key);\n this.entries.delete(key);\n }\n\n private keyToCacheKey(key: Key): CacheKey {\n return JSON.stringify(key);\n }\n\n private deleteOldestEntry() {\n if (this.metadata.size < 1) {\n return;\n }\n const [key] = [...this.metadata.entries()].reduce(\n ([oldestKey, oldestEntry], [thisKey, entry]) =>\n entry.expiration.getTime() < oldestEntry.expiration.getTime()\n ? [thisKey, entry]\n : [oldestKey, oldestEntry]\n );\n this.clearKey(key);\n }\n\n private generate(key: Key, promise: Promise<Value>) {\n const cacheKey = this.keyToCacheKey(key);\n const existingMetadata = this.metadata.get(cacheKey) || {};\n this.metadata.set(cacheKey, {\n ...existingMetadata,\n generating: true,\n expiration: new Date(Date.now() + this.timeout),\n });\n setTimeout(() => {\n fork(\n promise.then((value) => {\n const metadata = this.metadata.get(cacheKey);\n const canceled = !metadata?.generating;\n if (!canceled) {\n this.set(key, value);\n }\n })\n );\n }, 0);\n }\n}\n","import { IQuery } from \"../model/IQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IStreamData } from \"../model/IStreamData\";\n\nexport async function queryTelemetry(query: IQuery) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/queries/queries`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n\n return (await data.json()).items as IStreamData[];\n}\n","import { IQuery } from \"../model/IQuery\";\nimport { IStreamData } from \"../model/IStreamData\";\nimport { StreamType } from \"../model/StreamType\";\nimport { IFilter } from \"../model/IFilter\";\nimport {\n addMinutes,\n addSeconds,\n roundToNearestMinutes,\n startOfMinute,\n} from \"date-fns\";\nimport { duration } from \"../../../common/duration\";\nimport { filterDataByType } from \"./filterDataByType\";\nimport { filterDataByTime } from \"./filterDataByTime\";\nimport { StoreCache } from \"./StoreCache\";\nimport { queryTelemetry } from \"../api/queryTelemetry\";\n\nexport class QueryStore {\n private queryStoreCache = new StoreCache<\n IQuery,\n IStreamData[] | \"too much data\"\n >({\n capacity: 10_000,\n timeout: 20 * duration.second,\n });\n\n private liveQueryStoreCache = new StoreCache<\n IQuery,\n IStreamData[] | \"too much data\"\n >({\n capacity: 10_000,\n timeout: 200 * duration.millisecond,\n });\n\n public moduleQuery(\n filter: IFilter,\n name: string[],\n type: StreamType[],\n start: Date,\n end: Date,\n latestOnly: boolean = false\n ): IStreamData[] | \"too much data\" | undefined {\n const q: IFilter = {\n ...filter,\n names: [...name],\n types: [...type],\n };\n const data = this.query(q, start, end, latestOnly);\n if (data === undefined || data === \"too much data\") {\n return data as any;\n }\n return filterDataByType(data, type);\n }\n\n public query(\n filter: IFilter,\n start: Date,\n end: Date,\n latestOnly: boolean = false\n ): IStreamData[] | \"too much data\" | undefined {\n const q: IQuery = {\n ...filter,\n start: startOfMinute(start).toISOString(),\n end: latestOnly\n ? end.toISOString()\n : addMinutes(roundToNearestMinutes(end), 1).toISOString(),\n latestOnly,\n };\n const isLive = end > addSeconds(new Date(), -20);\n\n let data;\n if (isLive) {\n data = this.liveQueryCache(q);\n } else {\n data = this.queryCache(q);\n }\n\n if (!data || data === \"too much data\") {\n return data;\n }\n\n // return early because we might get data from near future that will be filtered out\n if (latestOnly) {\n return data;\n }\n\n return filterDataByTime(data, start, end);\n }\n\n private queryCache(\n query: IQuery\n ): IStreamData[] | \"too much data\" | undefined {\n return this.queryStoreCache.get(query, async () => {\n try {\n return await queryTelemetry(query);\n } catch (error) {\n throw error;\n }\n });\n }\n\n private liveQueryCache(\n query: IQuery\n ): IStreamData[] | \"too much data\" | undefined {\n return this.liveQueryStoreCache.get(query, async () => {\n try {\n return await queryTelemetry(query);\n } catch (error) {\n throw error;\n }\n });\n }\n}\n","import { StreamType } from \"../../model/StreamType\";\nimport { IStreamData } from \"../../model/IStreamData\";\nimport { EmbeddedAppMessage } from \"./EmbeddedAppMessage\";\nimport { QueryStore } from \"../../cache/queryStore\";\n\nconst queryStore = new QueryStore();\n\nexport function addStreamListener(\n streamNames: string[],\n streamTypes: StreamType[],\n handler: (response: IStreamData[] | \"too much data\" | undefined) => void\n): () => void {\n const listener = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"module_data\") {\n const { start, end } = msg.queryRange;\n handler(\n queryStore.moduleQuery(\n {},\n streamNames,\n streamTypes,\n new Date(start),\n new Date(end),\n false\n )\n );\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n}\n","import { sendAppMessage } from \"../senders/sendAppMessage\";\nimport { EmbeddedAppMessage } from \"../listeners/EmbeddedAppMessage\";\n\nexport async function getDate(time?: Date, minTime?: Date, maxTime?: Date) {\n return new Promise((resolve) => {\n sendAppMessage({\n type: \"request_date\",\n minTime,\n maxTime,\n time,\n });\n const handler = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"date_response\") {\n window.removeEventListener(\"message\", handler);\n resolve(msg.data);\n }\n };\n window.addEventListener(\"message\", handler);\n });\n}\n","import { JsonSchema } from \"../../model/JsonSchema\";\nimport { sendAppMessage } from \"../senders/sendAppMessage\";\nimport { EmbeddedAppMessage } from \"../listeners/EmbeddedAppMessage\";\n\nexport async function prompt(\n schema: JsonSchema,\n options?: { okText?: string; cancelText?: string }\n): Promise<any> {\n return new Promise((resolve) => {\n const promptId = Math.random().toString();\n sendAppMessage({\n type: \"prompt\",\n promptId,\n schema,\n okText: options?.okText,\n cancelText: options?.cancelText,\n });\n const handler = (event: MessageEvent<EmbeddedAppMessage>) => {\n const msg = event.data;\n if (msg.type === \"prompt_response\" && msg.promptId === promptId) {\n resolve(msg.data);\n }\n window.removeEventListener(\"message\", handler);\n };\n window.addEventListener(\"message\", handler);\n });\n}\n","import { getModuleConfiguration } from \"./api/getModuleConfiguration\";\nimport { getCurrentModuleContext } from \"./utils/getCurrentModuleContext\";\nimport { disableAnalyticsBottomBar } from \"./message-bus/senders/disableAnalyticsBottomBar\";\nimport { goToDevice } from \"./message-bus/senders/goToDevice\";\nimport { goToTime } from \"./message-bus/senders/goToTime\";\nimport { refreshAuthToken } from \"./message-bus/senders/refreshAuthToken\";\nimport { requestModuleData } from \"./message-bus/senders/requestModuleData\";\nimport { sendAppMessage } from \"./message-bus/senders/sendAppMessage\";\nimport { sendChannelData } from \"./message-bus/senders/sendChannelData\";\nimport { setModuleDateTimeRange } from \"./message-bus/senders/setModuleDateTimeRange\";\nimport { setupModuleMenus } from \"./message-bus/senders/setupModuleMenus\";\nimport { showMessage } from \"./message-bus/senders/showMessage\";\nimport { EmbeddedAppMessage } from \"./message-bus/listeners/EmbeddedAppMessage\";\nimport { addAccessTokenRefreshListener } from \"./message-bus/listeners/addAccessTokenRefreshListener\";\nimport { addChannelDataListener } from \"./message-bus/listeners/addChannelDataListener\";\nimport { addMenuListener } from \"./message-bus/listeners/addMenuListener\";\nimport { addModuleConfigurationListener } from \"./message-bus/listeners/addModuleConfigurationListener\";\nimport { addModuleDataListener } from \"./message-bus/listeners/addModuleDataListener\";\nimport { addOverviewDeviceListener } from \"./message-bus/listeners/addOverviewDeviceListener\";\nimport { addStreamListener } from \"./message-bus/listeners/addStreamLIstener\";\nimport { getDate } from \"./message-bus/bidirectional/getDate\";\nimport { prompt } from \"./message-bus/bidirectional/prompt\";\n\nexport class App {\n static getCurrentModuleContext = getCurrentModuleContext;\n\n static isModule(): boolean {\n return getCurrentModuleContext() !== null;\n }\n\n static async getCurrentModuleConfiguration(): Promise<string | undefined> {\n let urlParams = new URLSearchParams(\"\");\n\n if (typeof window !== \"undefined\" && window.location) {\n urlParams = new URLSearchParams(window.location.search);\n }\n\n const configurationId = urlParams.get(\"configuration\");\n\n if (configurationId === null || configurationId.trim() === \"\") {\n return undefined;\n }\n\n return getModuleConfiguration(configurationId.trim());\n }\n\n // senders\n static disableAnalyticsBottomBar = disableAnalyticsBottomBar;\n static goToDevice = goToDevice;\n static goToTime = goToTime;\n static refreshAuthToken = refreshAuthToken;\n static requestModuleData = requestModuleData;\n static sendChannelData = sendChannelData;\n static setModuleDateTimeRange = setModuleDateTimeRange;\n static setupModuleMenus = setupModuleMenus;\n static showMessage = showMessage;\n\n // listeners\n static addAccessTokenRefreshListener = addAccessTokenRefreshListener;\n static addChannelDataListener = addChannelDataListener;\n static addMenuListener = addMenuListener;\n static addModuleConfigurationListener = addModuleConfigurationListener;\n static addModuleDataListener = addModuleDataListener;\n static addOverviewDeviceListener = addOverviewDeviceListener;\n static addStreamListener = addStreamListener;\n\n // bidirectional\n static getDate = getDate;\n static prompt = prompt;\n\n private static _isOnline: boolean | null = null;\n\n static get isOnline(): boolean | null {\n return App._isOnline;\n }\n\n static listenForConnectionEvents(): () => void {\n const listener = (e: MessageEvent<EmbeddedAppMessage>) => {\n const { data } = e;\n if (data.type === \"formant_online\") {\n this._isOnline = data.online;\n }\n };\n\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n }\n\n static checkConnection(deadlineMs: number = 1_000): Promise<boolean> {\n return new Promise((done, reject) => {\n const deadline = setTimeout(\n () => reject(new Error(\"deadline expired: took too long\")),\n deadlineMs\n );\n\n const handler = (e: MessageEvent<EmbeddedAppMessage>) => {\n window.removeEventListener(\"message\", handler);\n clearTimeout(deadline);\n\n const { data } = e;\n if (data.type === \"formant_online\") {\n this._isOnline = data.online;\n done(data.online);\n }\n };\n\n window.addEventListener(\"message\", handler);\n sendAppMessage({ type: \"formant_online\" });\n });\n }\n\n static waitForConnection(deadlineMs: number = 5_000): Promise<void> {\n let aborted = false;\n const deadline = new Promise<void>((_, reject) => {\n setTimeout(() => {\n aborted = true;\n reject(new Error(\"deadline expired: took too long\"));\n }, deadlineMs);\n });\n\n const delay = (ms: number) => new Promise((done) => setTimeout(done, ms));\n\n const loop = async (): Promise<void> => {\n await delay(50); // allow for initialization jitter to settle\n while (!aborted) {\n if (this.isOnline || (await this.checkConnection)) {\n break;\n }\n await delay(500);\n }\n };\n\n return Promise.race([deadline, loop()]);\n }\n}\n","export function defined<T>(value: T | undefined, errorMessage?: string): T {\n if (value !== undefined) {\n return value;\n }\n throw new Error(errorMessage || \"Value is undefined\");\n}\n\nexport function notNull<T>(value: T | null, errorMessage?: string): T {\n if (value !== null) {\n return value;\n }\n throw new Error(errorMessage || \"Value is null\");\n}\n\nexport function definedAndNotNull<T>(\n value: T | undefined | null,\n errorMessage?: string\n): T {\n return notNull(defined(value, errorMessage), errorMessage);\n}\n","import { IRtcClientConfiguration } from \"@formant/realtime-sdk\";\n\nexport type SessionType = NonNullable<IRtcClientConfiguration[\"sessionType\"]>;\n\nexport const SessionTypes = {\n UNKNOWN: 0,\n TELEOP: 1,\n PORT_FORWARD: 2,\n OBSERVE: 3,\n HEADLESS: 4,\n} as const satisfies Record<string, SessionType>;\n\n// For backwards-compatibility\nexport const SessionTypeConstants = {\n ...SessionTypes,\n\n Unknown: SessionTypes.UNKNOWN,\n Teleop: SessionTypes.TELEOP,\n PortForward: SessionTypes.PORT_FORWARD,\n Observe: SessionTypes.OBSERVE,\n Headless: SessionTypes.HEADLESS,\n\n unknown: SessionTypes.UNKNOWN,\n teleop: SessionTypes.TELEOP,\n portForward: SessionTypes.PORT_FORWARD,\n observe: SessionTypes.OBSERVE,\n headless: SessionTypes.HEADLESS,\n} as const satisfies Record<string, SessionType>;\n","import {\n RtcClient,\n RtcClientV1,\n IRtcClientConfiguration,\n} from \"@formant/realtime-sdk\";\n\ntype ReceiveFn = IRtcClientConfiguration[\"receive\"];\ntype CreateClientFn<T extends RtcClient | RtcClientV1> = (\n receive: ReceiveFn\n) => T;\n\nexport interface IRtcClientPoolOptions<T extends RtcClient | RtcClientV1> {\n createClient: CreateClientFn<T>;\n ttlMs?: number;\n}\n\nconst singleton = Symbol(\"RtcClientPool.instance\");\n\nexport class RtcClientPool<T extends RtcClient | RtcClientV1> {\n [singleton]: T | null = null;\n\n private readonly createClient: CreateClientFn<T>;\n private readonly ttlMs: number;\n private readonly proxyHandler: ProxyHandler<T>;\n private proxyReceivers: Map<T, ReceiveFn | null> = new Map();\n private teardownTimeout: ReturnType<typeof setTimeout> | null = null;\n\n constructor(options: IRtcClientPoolOptions<T>) {\n const { createClient, ttlMs = 0 } = options;\n this.createClient = createClient;\n this.ttlMs = Math.max(ttlMs, 0);\n this.proxyHandler = {\n get: (target, prop, receiver) => {\n switch (prop) {\n case \"shutdown\":\n return () => this.releaseInstance(receiver);\n default:\n return Reflect.get(target, prop, receiver);\n }\n },\n };\n }\n\n get isActive(): boolean {\n return this[singleton] !== null;\n }\n\n get size(): number {\n return this.proxyReceivers.size;\n }\n\n get(onReceive?: ReceiveFn): T {\n const proxy = new Proxy(this.allocate(), this.proxyHandler);\n this.proxyReceivers.set(proxy, onReceive ?? null);\n return proxy;\n }\n\n private allocate(): T {\n if (this[singleton]) {\n // cancel any outstanding teardown request/keep this singleton alive\n if (this.teardownTimeout) {\n clearTimeout(this.teardownTimeout);\n this.teardownTimeout = null;\n }\n\n return this[singleton];\n }\n\n const client = this.createClient(this.dispatch);\n this[singleton] = client;\n return client;\n }\n\n private async teardown() {\n const instance = this[singleton];\n if (!instance) {\n console.warn(\"singleton has already been shutdown!\");\n return;\n }\n\n try {\n await instance.shutdown();\n } finally {\n this[singleton] = null;\n }\n }\n\n private dispatch: ReceiveFn = (peerId, message) => {\n this.proxyReceivers.forEach((it) => it?.(peerId, message));\n };\n\n private async releaseInstance(proxy: T): Promise<boolean> {\n if (!this.proxyReceivers.delete(proxy)) {\n console.warn(\"this instance has already been released!\");\n return false;\n }\n\n if (this.proxyReceivers.size !== 0) {\n return false;\n }\n\n if (!this.teardownTimeout && Number.isFinite(this.ttlMs)) {\n if (this.ttlMs === 0) {\n await this.teardown();\n } else {\n this.teardownTimeout = setTimeout(() => {\n this.teardown()\n .catch((err) => console.error(\"teardown failed\", { err }))\n .finally(() => (this.teardownTimeout = null));\n }, this.ttlMs);\n }\n }\n return true;\n }\n}\n","import { RtcClient, SignalingPromiseClient } from \"@formant/realtime-sdk\";\n\nimport { SessionType, SessionTypes } from \"./model/SessionType\";\nimport { RtcClientPool } from \"./utils/RtcClientPool\";\nimport { FORMANT_API_URL } from \"./config\";\nimport { Authentication } from \"./Authentication\";\nimport { defined } from \"../../common/defined\";\n\nconst getToken = async () =>\n defined(Authentication.token, \"Realtime when user isn't authorized\");\n\nconst EnumRtcClientPools = {\n [SessionTypes.UNKNOWN]: new RtcClientPool({\n ttlMs: 2_500,\n createClient: (receiveFn) =>\n new RtcClient({\n signalingClient: new SignalingPromiseClient(FORMANT_API_URL),\n getToken,\n sessionType: SessionTypes.UNKNOWN,\n receive: receiveFn,\n }),\n }),\n [SessionTypes.TELEOP]: new RtcClientPool({\n ttlMs: 2_500,\n createClient: (receiveFn) =>\n new RtcClient({\n signalingClient: new SignalingPromiseClient(FORMANT_API_URL),\n getToken,\n sessionType: SessionTypes.TELEOP,\n receive: receiveFn,\n }),\n }),\n [SessionTypes.PORT_FORWARD]: new RtcClientPool({\n ttlMs: 2_500,\n createClient: (receiveFn) =>\n new RtcClient({\n signalingClient: new SignalingPromiseClient(FORMANT_API_URL),\n getToken,\n sessionType: SessionTypes.PORT_FORWARD,\n receive: receiveFn,\n }),\n }),\n [SessionTypes.OBSERVE]: new RtcClientPool({\n ttlMs: 2_500,\n createClient: (receiveFn) =>\n new RtcClient({\n signalingClient: new SignalingPromiseClient(FORMANT_API_URL),\n getToken,\n sessionType: SessionTypes.OBSERVE,\n receive: receiveFn,\n }),\n }),\n [SessionTypes.HEADLESS]: new RtcClientPool({\n ttlMs: 2_500,\n createClient: (receiveFn) =>\n new RtcClient({\n signalingClient: new SignalingPromiseClient(FORMANT_API_URL),\n getToken,\n sessionType: SessionTypes.HEADLESS,\n receive: receiveFn,\n }),\n }),\n} as const;\n\nexport const AppRtcClientPools = {\n ...EnumRtcClientPools,\n unknown: EnumRtcClientPools[SessionTypes.UNKNOWN],\n teleop: EnumRtcClientPools[SessionTypes.TELEOP],\n portForward: EnumRtcClientPools[SessionTypes.PORT_FORWARD],\n observe: EnumRtcClientPools[SessionTypes.OBSERVE],\n headless: EnumRtcClientPools[SessionTypes.HEADLESS],\n} as const;\n\nexport const defaultRtcClientPool = EnumRtcClientPools[SessionTypes.TELEOP];\n\nexport const getRtcClientPool = (options: { sessionType?: SessionType }) => {\n const { sessionType } = options;\n\n return sessionType ? AppRtcClientPools[sessionType] : defaultRtcClientPool;\n};\n\nexport function debug() {\n console.group(\"RtcClientPool Sizes\");\n console.table(\n ([\"unknown\", \"teleop\", \"portForward\", \"observe\"] as const).map((key) => {\n const pool = AppRtcClientPools[key];\n return {\n name: key,\n size: pool.size,\n active: pool.isActive ? \"🔥\" : \"🧊\",\n };\n })\n );\n\n console.groupEnd();\n}\n","import { FORMANT_API_URL } from \"./config\";\n\nexport interface CaptureSession {\n deviceId: string;\n streamName: string;\n tags: {};\n expiration: string;\n organizationId: string;\n userId: string;\n code: string;\n id: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport class CaptureStream {\n token: string | undefined;\n constructor(public captureSession: CaptureSession) {}\n\n async ingestJSON(value: {}) {\n if (!this.token) {\n const result = await fetch(\n `${FORMANT_API_URL}/v1/admin/capture-sessions/${this.captureSession.code}/authenticate`,\n {\n method: \"POST\",\n }\n );\n const authInfo = await result.json();\n this.token = authInfo.token;\n }\n\n await fetch(`${FORMANT_API_URL}/v1/ingest`, {\n method: \"POST\",\n body: JSON.stringify({\n deviceId: this.captureSession.deviceId,\n name: this.captureSession.streamName,\n type: \"json\",\n points: [[Date.now(), JSON.stringify(value)]],\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + this.token,\n },\n });\n }\n}\n","export function delay(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { IRtcPeer } from \"@formant/realtime-sdk\";\n\nexport const isRtcPeer = (peer: IRtcPeer | undefined): peer is IRtcPeer =>\n peer !== undefined &&\n peer.capabilities !== undefined &&\n peer.capabilitySet !== undefined;\n","export type DataChannelStringListener = (message: string) => void;\nexport type DataChannelBinaryListener = (message: Uint8Array) => void;\nexport type DataChannelListener = () => void;\nexport type DataChannelErrorListener = (ev: Event) => void;\nexport class DataChannel {\n ready = false;\n listeners: DataChannelStringListener[] = [];\n openListeners: DataChannelListener[] = [];\n closeListeners: DataChannelListener[] = [];\n errorListeners: DataChannelErrorListener[] = [];\n binaryListeners: DataChannelBinaryListener[] = [];\n error: string | undefined;\n decoder = new TextDecoder();\n\n constructor(private dataChannel: RTCDataChannel) {\n this.dataChannel.binaryType = \"arraybuffer\";\n this.dataChannel.onopen = () => {\n this.setReady();\n };\n this.dataChannel.onclose = () => {\n this.ready = false;\n this.closeListeners.forEach((listener) => listener());\n };\n this.dataChannel.onerror = (e) => {\n console.error(e);\n this.error = \"An error occurred in DataChannel\";\n this.errorListeners.forEach((listener) => listener(e));\n };\n this.dataChannel.onmessage = (m: MessageEvent) => {\n this.listeners.forEach((_) => {\n const d = new Uint8Array(m.data);\n const s = this.decoder.decode(d);\n _(s);\n });\n this.binaryListeners.forEach((_) => {\n _(new Uint8Array(m.data));\n });\n };\n }\n\n private setReady() {\n this.ready = true;\n this.openListeners.forEach((listener) => listener());\n }\n\n addOpenListener(listener: DataChannelListener) {\n this.openListeners.push(listener);\n }\n\n removeOpenListener(listener: DataChannelListener) {\n this.openListeners = this.openListeners.filter((_) => _ !== listener);\n }\n\n addCloseListener(listener: DataChannelListener) {\n this.closeListeners.push(listener);\n }\n\n removeCloseListener(listener: DataChannelListener) {\n this.closeListeners = this.closeListeners.filter((l) => l !== listener);\n }\n\n addErrorListener(listener: DataChannelErrorListener) {\n this.errorListeners.push(listener);\n }\n\n removeErrorListener(listener: DataChannelErrorListener) {\n this.errorListeners = this.errorListeners.filter((l) => l !== listener);\n }\n\n async waitTilReady(): Promise<boolean> {\n if (this.ready) {\n return true;\n }\n const p = new Promise<boolean>((resolve, reject) => {\n let a = setInterval(() => {\n if (this.dataChannel.readyState === \"open\") {\n this.setReady();\n }\n if (this.ready) {\n clearInterval(a);\n resolve(true);\n }\n if (this.error) {\n reject(this.error);\n }\n }, 10);\n });\n return p;\n }\n\n send(data: string) {\n if (!this.ready) {\n throw new Error(\"Connection has been closed\");\n }\n this.dataChannel.send(data);\n }\n\n sendBinary(data: Uint8Array) {\n if (!this.ready) {\n throw new Error(\"Connection has been closed\");\n }\n this.dataChannel.send(data);\n }\n\n addListener(listener: DataChannelStringListener) {\n this.listeners.push(listener);\n }\n\n removeListener(listener: DataChannelStringListener) {\n const i = this.listeners.indexOf(listener);\n if (i === -1) {\n throw new Error(\"Could not find data channel listener to remove\");\n }\n if (this.error) {\n throw new Error(this.error);\n }\n this.listeners.splice(i, 1);\n }\n\n addBinaryListener(listener: DataChannelBinaryListener) {\n this.binaryListeners.push(listener);\n }\n\n removeBinaryListener(listener: DataChannelBinaryListener) {\n const i = this.binaryListeners.indexOf(listener);\n if (i === -1) {\n throw new Error(\"Could not find data channel listener to remove\");\n }\n if (this.error) {\n throw new Error(this.error);\n }\n this.binaryListeners.splice(i, 1);\n }\n}\n","import {\n RealtimeDataStream,\n IJointState,\n RealtimeMessage,\n} from \"./devices/device.types\";\nimport { IRealtimeSubscriber } from \"./devices/IRealtimeSubscriber\";\n\nexport type RealtimeManipulatorConfig = {\n currentJointStateStream: RealtimeDataStream;\n plannedJointStateStream?: RealtimeDataStream;\n planValidStream?: RealtimeDataStream;\n endEffectorStream?: RealtimeDataStream;\n endEffectorLinkName?: string;\n baseReferenceFrame?: string;\n localFrame?: string;\n};\n\nexport class Manipulator {\n currentListeners: ((js: IJointState) => void)[] = [];\n constructor(\n private device: IRealtimeSubscriber,\n private config: RealtimeManipulatorConfig\n ) {}\n\n async synchronize() {\n this.device.addRealtimeListener(this.onRealtimeMessage);\n this.device.startListeningToRealtimeDataStream(\n this.config.currentJointStateStream\n );\n }\n\n async desynchronize() {\n this.device.removeRealtimeListener(this.onRealtimeMessage);\n this.device.stopListeningToRealtimeDataStream(\n this.config.currentJointStateStream\n );\n }\n\n onRealtimeMessage = (_peerId: string, message: RealtimeMessage) => {\n if (message.payload.jointState) {\n this.currentListeners.forEach((listener) => {\n if (message.payload.jointState) listener(message.payload.jointState);\n });\n }\n };\n\n async addCurrentJointStateListener(listener: (js: IJointState) => void) {\n this.currentListeners.push(listener);\n }\n}\n","import {\n DataChannel,\n DataChannelErrorListener,\n DataChannelListener,\n} from \"./DataChannel\";\nimport { delay } from \"../../common/delay\";\nimport { defined } from \"../../common/defined\";\nimport { ICustomDataChannelCreator } from \"./devices/ICustomDataChannelCreator\";\n\n// AdapterError -> An error occurred when handling the request on the adapter.\n// TimeoutError -> The request did not receive a response within the timeout period.\n\nabstract class RequestDataChannel {\n protected channel: undefined | DataChannel;\n protected requestIdToResponseMap = new Map<string, any>();\n constructor(\n protected device: ICustomDataChannelCreator,\n protected channel_name: string,\n protected timeout: number\n ) {}\n\n addOpenListener(listener: DataChannelListener) {\n defined(this.channel, \"channel not initalized\").addOpenListener(listener);\n }\n\n removeOpenListener(listener: DataChannelListener) {\n defined(this.channel, \"channel not initalized\").removeOpenListener(\n listener\n );\n }\n\n addCloseListener(listener: DataChannelListener) {\n defined(this.channel, \"channel not initalized\").addCloseListener(listener);\n }\n\n removeCloseListener(listener: DataChannelListener) {\n defined(this.channel, \"channel not initalized\").removeCloseListener(\n listener\n );\n }\n\n addErrorListener(listener: DataChannelErrorListener) {\n defined(this.channel, \"channel not initalized\").addErrorListener(listener);\n }\n\n removeErrorListener(listener: DataChannelErrorListener) {\n defined(this.channel, \"channel not initalized\").removeErrorListener(\n listener\n );\n }\n}\n\nexport class BinaryRequestDataChannel extends RequestDataChannel {\n private RESPONSE_SUCCESS_BYTE = 0;\n private decoder = new TextDecoder();\n\n /*\n Request binary payload layout:\n 16-bytes arbitrary-length\n [ ID ] [ PAYLOAD ]\n\n Response binary payload layout:\n 1-byte 16-bytes arbitrary-length\n [ SUCCESS OR ERROR BYTE ] [ ID ] [ PAYLOAD ]\n */\n\n generateBinaryId() {\n // attach binary ID as 16-byte header in binary messages\n const id = new Uint8Array(16);\n for (let i = 0; i < id.length; i++) {\n id[i] = Math.floor(Math.random() * 256);\n }\n return id;\n }\n\n async initialize() {\n this.channel = await this.device.createCustomDataChannel(this.channel_name);\n\n this.channel.addBinaryListener((message) => {\n const binaryId = message.slice(0, 16);\n\n const id = binaryId.toString();\n if (id.length === 0) {\n throw new Error(\"Invalid response\");\n }\n\n const response = message.slice(16);\n if (response.length === 0) {\n throw new Error(\"Invalid response\");\n }\n\n // only add to the map if there is an active request\n if (this.requestIdToResponseMap.has(id)) {\n this.requestIdToResponseMap.set(id, response);\n }\n });\n }\n\n async request(data: Uint8Array) {\n if (!this.channel) {\n await this.initialize();\n }\n if (!this.channel) {\n throw new Error(\"Failed to create channel\");\n }\n const { channel, requestIdToResponseMap, timeout } = this;\n await channel.waitTilReady();\n\n const binaryId = this.generateBinaryId();\n const id = binaryId.toString();\n requestIdToResponseMap.set(id, true); // true signifies an active request\n channel.sendBinary(new Uint8Array([...binaryId, ...data]));\n\n // Wait for the response to come back.\n const start = new Date().getTime();\n while (new Date().getTime() < start + timeout) {\n await delay(50);\n if (requestIdToResponseMap.has(id)) {\n const response = requestIdToResponseMap.get(id);\n if (response !== true) {\n requestIdToResponseMap.delete(id);\n const success = response[0] === this.RESPONSE_SUCCESS_BYTE;\n const payload = response.slice(1);\n if (success) {\n return payload;\n } else {\n console.error({\n name: \"AdapterError\",\n message: this.decoder.decode(payload),\n });\n throw new Error(\"Binary request datachannel adapter error\");\n }\n }\n }\n }\n\n requestIdToResponseMap.delete(id);\n console.error({\n name: \"TimeoutError\",\n message: `Request timed out after ${timeout / 1000.0} seconds`,\n });\n throw new Error(\"Binary request data channel request timed out\");\n }\n}\n\nexport class TextRequestDataChannel extends RequestDataChannel {\n generateTextId() {\n return (\n Math.random().toString(36).substring(2) +\n \"-\" +\n Math.random().toString(36).substring(2)\n );\n }\n\n async initialize() {\n this.channel = await this.device.createCustomDataChannel(this.channel_name);\n\n this.channel.addListener((message) => {\n const response = JSON.parse(message);\n const { id, data, error } = response;\n if (!id) {\n throw new Error(\"Invalid response\");\n }\n if (!data && !error) {\n throw new Error(\"Invalid response\");\n }\n // only add to the map if there is an active request\n if (this.requestIdToResponseMap.has(id)) {\n this.requestIdToResponseMap.set(id, response);\n }\n });\n }\n\n async request(data: string) {\n if (!this.channel) {\n await this.initialize();\n }\n if (!this.channel) {\n throw new Error(\"Failed to create channel\");\n }\n const { channel, requestIdToResponseMap, timeout } = this;\n await channel.waitTilReady();\n\n const id = this.generateTextId();\n requestIdToResponseMap.set(id, true); // true signifies an active request\n channel.send(\n JSON.stringify({\n id,\n data,\n })\n );\n\n // Wait for the response to come back.\n const start = new Date().getTime();\n while (new Date().getTime() < start + timeout) {\n await delay(50);\n if (requestIdToResponseMap.has(id)) {\n const response = requestIdToResponseMap.get(id);\n if (response !== true) {\n requestIdToResponseMap.delete(id);\n const { data, error } = response;\n if (data) {\n return data;\n }\n if (error) {\n console.error({\n name: \"AdapterError\",\n message: error,\n });\n throw new Error(\"Text request datachannel adapter error\");\n }\n }\n }\n }\n\n requestIdToResponseMap.delete(id);\n console.error({\n name: \"TimeoutError\",\n message: `Request timed out after ${timeout / 1000.0} seconds`,\n });\n throw new Error(\"Text request datachannel request timed out\");\n }\n}\n","import {\n IRtcSendConfiguration,\n IRtcStreamMessage,\n RtcClient,\n IRtcPeer,\n} from \"@formant/realtime-sdk\";\nimport { DataChannel } from \"../DataChannel\";\nimport { EventEmitter } from \"eventemitter3\";\nimport { Manipulator } from \"../Manipulator\";\nimport {\n BinaryRequestDataChannel,\n TextRequestDataChannel,\n} from \"../RequestDataChannel\";\nimport { defined } from \"../../../common/defined\";\nimport { IRealtimeSubscriber } from \"./IRealtimeSubscriber\";\nimport { ICustomDataChannelCreator } from \"./ICustomDataChannelCreator\";\nimport {\n ConfigurationDocument,\n RealtimeListener,\n RealtimeAudioStream,\n RealtimeVideoStream,\n RealtimeDataStream,\n} from \"./device.types\";\n\nexport abstract class BaseDevice\n extends EventEmitter\n implements IRealtimeSubscriber, ICustomDataChannelCreator\n{\n rtcClient: RtcClient | undefined;\n remoteDevicePeerId: string | null = null;\n\n protected realtimeListeners: RealtimeListener[] = [];\n\n protected connectionMonitorInterval:\n | ReturnType<typeof setInterval>\n | undefined;\n\n abstract getConfiguration(): Promise<ConfigurationDocument>;\n abstract startRealtimeConnection(sessionType?: number): Promise<void>;\n abstract getRemotePeer(): Promise<IRtcPeer>;\n\n protected handleMessage = (peerId: string, message: any) => {\n this.realtimeListeners.forEach((_) => _(peerId, message));\n };\n\n protected stopConnectionMonitoring() {\n clearInterval(this.connectionMonitorInterval);\n this.connectionMonitorInterval = undefined;\n }\n\n protected assertNotCancelled(cancelled: boolean): void {\n if (cancelled) throw new Error(\"Cancelled by deadline\");\n }\n\n getRealtimeStatus(): \"disconnected\" | \"connecting\" | \"connected\" {\n if (this.rtcClient && this.remoteDevicePeerId) {\n return this.rtcClient.getConnectionStatus(this.remoteDevicePeerId);\n } else {\n throw new Error(`Realtime connection hasn't been started`);\n }\n }\n\n getRealtimePing(): number | undefined {\n if (this.rtcClient && this.remoteDevicePeerId) {\n return this.rtcClient.getPing(this.remoteDevicePeerId);\n } else {\n throw new Error(`Realtime connection hasn't been started`);\n }\n }\n\n addRealtimeListener(listener: RealtimeListener) {\n this.realtimeListeners.push(listener);\n }\n\n removeRealtimeListener(listener: RealtimeListener) {\n const i = this.realtimeListeners.indexOf(listener);\n if (i === -1) {\n throw new Error(\"Could not find realtime listener to remove\");\n }\n this.realtimeListeners.splice(i, 1);\n }\n\n async getRealtimeManipulators(): Promise<Manipulator[]> {\n const document = (await this.getConfiguration()) as any;\n const manipulators = [];\n\n for (const _ of document.teleop.rosStreams ?? []) {\n if (_.topicType == \"sensor_msgs/JointState\") {\n manipulators.push(\n new Manipulator(this, {\n currentJointStateStream: { name: _.topicName },\n plannedJointStateStream: _.plannedTopic\n ? { name: _.plannedTopic }\n : undefined,\n planValidStream: _.planValidTopic\n ? { name: _.planValidTopic }\n : undefined,\n endEffectorStream: _.endEffectorTopic\n ? { name: _.endEffectorTopic }\n : undefined,\n endEffectorLinkName: _.endEffectorLinkName,\n baseReferenceFrame: _.baseReferenceFrame,\n localFrame: _.localFrame,\n })\n );\n }\n }\n return manipulators;\n }\n\n async getRealtimeVideoStreams(): Promise<RealtimeVideoStream[]> {\n const document = (await this.getConfiguration()) as any;\n const streams: { name: string }[] = [];\n\n for (const _ of document.teleop?.hardwareStreams ?? []) {\n if (_.rtcStreamType === \"h264-video-frame\") {\n streams.push({\n name: _.name,\n });\n }\n }\n for (const _ of document.teleop?.rosStreams ?? []) {\n if (_.topicType == \"formant/H264VideoFrame\") {\n streams.push({\n name: _.topicName,\n });\n }\n if (\n (_.topicType === \"sensor_msgs/Image\" ||\n _.topicType === \"sensor_msgs/CompressedImage\") &&\n _.encodeVideo\n ) {\n streams.push({\n name: _.topicName,\n });\n }\n }\n for (const _ of document.teleop?.customStreams ?? []) {\n if (_.rtcStreamType === \"h264-video-frame\") {\n streams.push({\n name: _.name,\n });\n }\n }\n return streams;\n }\n\n createCustomRequestDataChannel(\n channelName: string,\n timeout: number = 3000 // 3 seconds default timeout\n ): TextRequestDataChannel {\n return new TextRequestDataChannel(this, channelName, timeout);\n }\n\n createCustomBinaryRequestDataChannel(\n channelName: string,\n timeout: number = 3000 // 3 seconds default timeout\n ): BinaryRequestDataChannel {\n return new BinaryRequestDataChannel(this, channelName, timeout);\n }\n\n async startListeningToRealtimeVideo(stream: RealtimeVideoStream) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: stream.name,\n enable: true,\n pipeline: \"rtc\",\n });\n }\n\n async stopListeningToRealtimeVideo(stream: RealtimeVideoStream) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: stream.name,\n enable: false,\n pipeline: \"rtc\",\n });\n }\n\n async startListeningToRealtimeDataStream(stream: RealtimeDataStream) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: stream.name,\n enable: true,\n pipeline: \"rtc\",\n });\n }\n\n async stopListeningToRealtimeDataStream(stream: RealtimeDataStream) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: stream.name,\n enable: false,\n pipeline: \"rtc\",\n });\n }\n\n async enableRealtimeTelemetryPriorityIngestion(streamName: string) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: streamName,\n enablePriorityUpload: true,\n pipeline: \"telemetry\",\n });\n }\n\n async disableRealtimeTelemetryPriorityIngestion(streamName: string) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName: streamName,\n enablePriorityUpload: false,\n pipeline: \"telemetry\",\n });\n }\n\n async changeStreamAudioType(streamName: string, newFormat: \"wav\" | \"opus\") {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.controlRemoteStream(defined(devicePeer).id, {\n streamName,\n setAudioFormat: newFormat,\n });\n }\n\n async createCustomDataChannel(\n channelName: string,\n rtcConfig?: RTCDataChannelInit\n ): Promise<DataChannel> {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n const p = await new Promise<DataChannel>((resolve) => {\n client.createCustomDataChannel(\n defined(devicePeer).id,\n channelName,\n {\n ordered: true,\n ...rtcConfig,\n },\n false,\n (_peerId, channel) => {\n const dataChannel = new DataChannel(channel);\n resolve(dataChannel);\n }\n );\n });\n await p.waitTilReady();\n return p;\n }\n\n async sendRealtimeMessage(\n message: IRtcStreamMessage,\n config: IRtcSendConfiguration = {\n channelLabel: \"stream.reliable\",\n }\n ) {\n const client = defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n );\n\n const devicePeer = await this.getRemotePeer();\n client.send(defined(devicePeer).id, message, config);\n }\n\n async getRealtimeAudioStreams(): Promise<RealtimeAudioStream[]> {\n const document = await this.getConfiguration();\n const streams: { name: string }[] = [];\n\n for (const _ of document.teleop?.hardwareStreams ?? []) {\n if (_.rtcStreamType === \"audio-chunk\") {\n streams.push({\n name: _.name,\n });\n }\n }\n for (const _ of document.teleop?.rosStreams ?? []) {\n if (_.topicType == \"audio_common_msgs/AudioData\") {\n streams.push({\n name: _.topicName,\n });\n }\n }\n for (const _ of document.teleop?.customStreams ?? []) {\n if (_.rtcStreamType === \"audio-chunk\") {\n streams.push({\n name: _.name,\n });\n }\n }\n return streams;\n }\n}\n","import { inflate, deflate } from \"pako\";\nimport { fromByteArray, toByteArray } from \"base64-js\";\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\nexport function serializeHash(value: any): string {\n const jsonValue = JSON.stringify(value);\n const encodedValue = encoder.encode(jsonValue);\n const compressedValue = deflate(encodedValue);\n return fromByteArray(compressedValue);\n}\n\nexport function deserializeHash(value: string): any {\n const a = toByteArray(value);\n const b = inflate(a);\n const c = decoder.decode(b);\n return JSON.parse(c);\n}\n","import { IView } from \"../model/IView\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getViews(): Promise<IView[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(`${FORMANT_API_URL}/v1/admin/views`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const views = await response.json();\n return views.items;\n}\n","import { IShare } from \"../model/IShare\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { serializeHash } from \"../utils/serializeHash\";\n\nimport { getViews } from \"./getViews\";\n\n/**\n * @param scope is required\n * @param time is required\n * @param view View name\n * @returns\n * Share link\n * @example\n * // Body\n * const link = await createShareLink({\n * delegateTeleop: false\n * message: \"See bot in action\",\n * scope: {\n * deviceIds: [\"d64520a6-a308-4a59-9267-b7f8a7bfc7ab\"],\n * start: \"2023-04-04T19:51:47.125Z\",\n * end: \"2023-04-04T20:51:47.125Z\"\n * },\n * time: \"2023-04-04T20:21:47.125Z\",\n * userName: \"User\",\n * });\n */\nexport async function createShareLink(share: IShare, view: string) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n\n const views = await getViews();\n\n const selectedView = views.filter((_) => _.name === view);\n\n if (selectedView.length === 0) {\n console.warn(\"View does not exist or it is misspell\");\n return null;\n }\n\n const response = await fetch(`${FORMANT_API_URL}/v1/admin/shares`, {\n method: \"POST\",\n body: JSON.stringify(share),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const origin = FORMANT_API_URL.replace(\"api\", \"app\");\n const { code } = await response.json();\n\n return `${origin}/shares/${code}#${serializeHash({\n viewId: selectedView[0].id,\n })}`;\n}\n","import { INumericAggregate } from \"../model/INumericAggregate\";\nimport * as dateFns from \"date-fns\";\nimport { AggregateLevel } from \"../model/AggregateLevel\";\n\nexport const vailableAggregationIntervals = [\n \"day\",\n \"week\",\n \"month\",\n \"year\",\n \"hour\",\n \"minute\",\n \"quarter\",\n] as const;\n\nexport type ValidAggregationInterval =\n (typeof vailableAggregationIntervals)[number];\n\nexport type IAggregateByDateFunctions = {\n [key in ValidAggregationInterval]: AggregateFunction;\n};\n\nexport const aggregateFunctions = [\n \"interval\",\n \"start\",\n \"end\",\n \"sub\",\n \"get\",\n] as const;\n\nexport type AggregateFunctions = (typeof aggregateFunctions)[number];\n\nexport type AggregateFunction = {\n [key in AggregateFunctions]: any;\n};\n\nexport function getVariance(a: INumericAggregate) {\n if (a.count < 2) {\n return 0;\n }\n return a.sumOfSquares / (a.count - 1);\n}\n\nexport function getStandardDeviation(a: INumericAggregate) {\n return Math.sqrt(getVariance(a));\n}\n\nexport function getMax(a: INumericAggregate) {\n return a.max;\n}\n\nexport function getMin(a: INumericAggregate) {\n return a.min;\n}\n\nexport function getAverage(a: INumericAggregate) {\n return a.count === 0 ? -1 : a.sum / a.count;\n}\n\nexport function getSum(a: INumericAggregate) {\n return a.sum;\n}\nexport function getCount(a: INumericAggregate) {\n return a.count;\n}\n\nexport const aggregateFunctionMap = {\n min: getMin,\n max: getMax,\n \"standard deviation\": getStandardDeviation,\n average: getAverage,\n sum: getSum,\n count: getCount,\n};\n\ninterface IAggregateFunctions {\n interval: (interval: dateFns.Interval) => Date[];\n start: (date: Date | number) => Date;\n end: (date: Date | number) => Date;\n sub: (date: Date | number, amount: number) => Date;\n get: (date: Date | number) => number;\n}\n\nexport const aggregateByDateFunctions: Record<\n AggregateLevel,\n IAggregateFunctions\n> = {\n day: {\n interval: dateFns.eachDayOfInterval,\n start: dateFns.startOfDay,\n end: dateFns.endOfDay,\n sub: dateFns.subDays,\n get: dateFns.getDay,\n },\n week: {\n interval: dateFns.eachWeekOfInterval,\n start: dateFns.startOfWeek,\n end: dateFns.endOfWeek,\n sub: dateFns.subWeeks,\n get: dateFns.getWeek,\n },\n month: {\n interval: dateFns.eachMonthOfInterval,\n start: dateFns.startOfMonth,\n end: dateFns.endOfMonth,\n sub: dateFns.subMonths,\n get: dateFns.getMonth,\n },\n year: {\n interval: dateFns.eachYearOfInterval,\n start: dateFns.startOfYear,\n end: dateFns.endOfYear,\n sub: dateFns.subYears,\n get: dateFns.getYear,\n },\n hour: {\n interval: dateFns.eachHourOfInterval,\n start: dateFns.startOfHour,\n end: dateFns.endOfHour,\n sub: dateFns.subHours,\n get: dateFns.getHours,\n },\n minute: {\n interval: dateFns.eachMinuteOfInterval,\n start: dateFns.startOfMinute,\n end: dateFns.endOfMinute,\n sub: dateFns.subMinutes,\n get: dateFns.getMinutes,\n },\n quarter: {\n interval: dateFns.eachQuarterOfInterval,\n start: dateFns.startOfQuarter,\n end: dateFns.endOfQuarter,\n sub: dateFns.subQuarters,\n get: dateFns.getQuarter,\n },\n};\n\nexport const formatTimeFrameText = (start: string, end: string) =>\n // FIXME this doesn't work for *a lot* locales, other than en-US\n // en-GB: 'dd/mm/YYYY'\n // ja-jp: 'YYYY/mm/dd'\n // bg-BG: 'dd.mm.YYYY'\n start.split(\"/\")[0] +\n \"/\" +\n start.split(\"/\")[1] +\n \"–\" +\n end.split(\"/\")[0] +\n \"/\" +\n end.split(\"/\")[1];\n","import { IEventQuery } from \"../model/IEventQuery\";\nimport { IEvent } from \"../model/IEvent\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function queryEvents(query: IEventQuery): Promise<IEvent[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/events/query`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n\n return (await data.json()).items as IEvent[];\n}\n","import { EventType } from \"../model/EventType\";\nimport { AggregateLevel } from \"../model/AggregateLevel\";\nimport { IEventQuery } from \"../model/IEventQuery\";\nimport {\n aggregateByDateFunctions,\n formatTimeFrameText,\n} from \"../utils/aggregateFunctionUtils\";\nimport { queryEvents } from \"./queryEvents\";\n\nexport async function eventsCounter(\n eventTypes: EventType[],\n timeFrame: AggregateLevel,\n range: number,\n time: number,\n query?: IEventQuery\n) {\n const dateFunctions = aggregateByDateFunctions[timeFrame];\n\n return await Promise.all(\n Array(range)\n .fill(0)\n .map(async (_, dateOffset) => {\n const activePointInTimeLine = new Date(time);\n\n const startDate: Date = dateFunctions.sub(\n dateFunctions.start(activePointInTimeLine),\n range - dateOffset - 1\n );\n const endDate: Date = dateFunctions.sub(\n dateFunctions.end(activePointInTimeLine),\n range - dateOffset - 1\n );\n const date = formatTimeFrameText(\n startDate.toLocaleDateString(),\n endDate.toLocaleDateString()\n );\n const events = await queryEvents({\n ...query,\n eventTypes,\n start: new Date(startDate).toISOString(),\n end: new Date(endDate).toISOString(),\n });\n return { date, events };\n })\n );\n}\n","import { IEventQuery } from \"../model/IEventQuery\";\n\nimport { queryEvents } from \"./queryEvents\";\n\nexport async function getAnnotationCount(query: IEventQuery, tagKey: string) {\n const annotations = await queryEvents({\n ...query,\n eventTypes: [\"annotation\"],\n });\n\n const validAnnotations = annotations.filter(\n (_) => !!_.tags && Object.keys(_.tags!).includes(tagKey)\n );\n const annotationCounter = validAnnotations.reduce<{\n [key: string]: number;\n }>((prev, current) => {\n const value = current.tags![tagKey];\n if (value in prev) {\n prev[value] += 1;\n return prev;\n }\n prev[value] = 1;\n return prev;\n }, {});\n\n return annotationCounter;\n}\n","import { IEventQuery } from \"../model/IEventQuery\";\nimport { AggregateLevel } from \"../model/AggregateLevel\";\nimport { aggregateByDateFunctions } from \"../utils/aggregateFunctionUtils\";\nimport { getAnnotationCount } from \"./getAnnotationCount\";\n\nexport async function getAnnotationCountByIntervals(\n query: IEventQuery,\n tagKey: string,\n aggregate: AggregateLevel\n) {\n const { end, start } = query;\n const dateFunctions = aggregateByDateFunctions[aggregate];\n const intervals: Date[] = dateFunctions.interval({\n start: new Date(start!),\n end: new Date(end!),\n });\n\n const annotationsQuery = intervals.map((_, idx) => {\n const startDate = new Date(_).toISOString();\n const endDate =\n idx === intervals.length - 1\n ? new Date(Date.now()).toISOString()\n : new Date(intervals[idx + 1]);\n return getAnnotationCount(\n {\n ...query,\n start: startDate,\n end: endDate as string,\n },\n tagKey\n );\n });\n const responses = await Promise.all(annotationsQuery);\n\n return intervals.map((_, idx) => ({\n date: new Date(_).toISOString(),\n annotations: responses[idx],\n }));\n}\n","import { FORMANT_API_URL } from \"../config\";\nimport { Authentication } from \"../Authentication\";\n\nimport { TelemetryResult } from \"../model/TelemetryResult\";\n\nexport async function getTelemetry(\n deviceIdOrDeviceIds: string | string[],\n streamNameOrStreamNames: string | string[],\n start: Date,\n end: Date,\n tags?: { [key in string]: string[] }\n): Promise<TelemetryResult[]> {\n let deviceIds = deviceIdOrDeviceIds;\n if (!Array.isArray(deviceIdOrDeviceIds)) {\n deviceIds = [deviceIdOrDeviceIds];\n }\n let streamNames = streamNameOrStreamNames;\n if (!Array.isArray(streamNameOrStreamNames)) {\n streamNames = [streamNameOrStreamNames];\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/queries/queries`, {\n method: \"POST\",\n body: JSON.stringify({\n deviceIds,\n end: end.toISOString(),\n names: streamNames,\n start: start.toISOString(),\n tags,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const telemetry = await data.json();\n return telemetry.items;\n}\n","import { Authentication } from \"../Authentication\";\nimport { defaultRtcClientPool } from \"../AppRtcClientPools\";\n\nexport async function getRealtimeSessions(): Promise<{\n [key in string]: string[];\n}> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const rtcClient = defaultRtcClientPool.get();\n try {\n return await rtcClient.getSessions();\n } finally {\n await rtcClient.shutdown();\n }\n}\n","import { IRtcPeer } from \"@formant/realtime-sdk\";\n\nimport { Authentication } from \"../Authentication\";\nimport { defaultRtcClientPool } from \"../AppRtcClientPools\";\n\nexport async function getPeers(): Promise<IRtcPeer[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const rtcClient = defaultRtcClientPool.get();\n try {\n return await rtcClient.getPeers();\n } finally {\n await rtcClient.shutdown();\n }\n}\n","import { IDevice } from \"../model/IDevice\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function createDevice(device: IDevice): Promise<IDevice> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices`, {\n method: \"POST\",\n body: JSON.stringify(device),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { IDevice } from \"../model/IDevice\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function patchDevice(\n id: string,\n device: Partial<IDevice>\n): Promise<IDevice> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify(device),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IDevice } from \"../model/IDevice\";\n\nexport async function getDevicesData(): Promise<IDevice[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/device-details/query`, {\n method: \"POST\",\n body: JSON.stringify({ enabled: true, type: \"default\" }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n return devices.items;\n}\n","import { IDeviceQuery } from \"../model/IDeviceQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IDevice } from \"../model/IDevice\";\n\nexport async function queryDevicesData(\n query: IDeviceQuery\n): Promise<IDevice[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices/query`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n\n return devices.items;\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IDevice } from \"../model/IDevice\";\n\nexport async function disableDevice(id: string): Promise<IDevice[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/devices/${id}/disable`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const response = await data.json();\n\n return response;\n}\n","import { RtcClient, IRtcPeer } from \"@formant/realtime-sdk\";\nimport { getRtcClientPool } from \"../AppRtcClientPools\";\nimport { Authentication } from \"../Authentication\";\nimport { CaptureStream } from \"../CaptureStream\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { delay } from \"../../../common/delay\";\nimport { defined } from \"../../../common/defined\";\nimport { InterventionType } from \"../model/InterventionType\";\nimport { IInterventionTypeMap } from \"../model/IInterventionTypeMap\";\nimport { IInterventionResponse } from \"../model/IInterventionResponse\";\nimport { IEventQuery } from \"../model/IEventQuery\";\nimport { AggregateLevel } from \"../model/AggregateLevel\";\nimport { EventType } from \"../model/EventType\";\nimport { IShare } from \"../model/IShare\";\nimport { SessionType } from \"../model/SessionType\";\nimport { isRtcPeer } from \"../utils/isRtcPeer\";\nimport {\n Command,\n ConfigurationDocument,\n IStartRealtimeConnectionOptions,\n TelemetryStream,\n} from \"./device.types\";\nimport { BaseDevice } from \"./BaseDevice\";\nimport { ITags } from \"../model/ITags\";\nimport { createShareLink } from \"../api/createShareLink\";\nimport { eventsCounter } from \"../api/eventsCounter\";\nimport { getAnnotationCount } from \"../api/getAnnotationCount\";\nimport { getAnnotationCountByIntervals } from \"../api/getAnnotationCountByIntervals\";\nimport { getTelemetry } from \"../api/getTelemetry\";\nimport { getRealtimeSessions } from \"../api/getRealtimeSessions\";\nimport { getPeers } from \"../api/getPeers\";\nimport { createDevice } from \"../api/createDevice\";\nimport { patchDevice } from \"../api/patchDevice\";\nimport { getDevicesData } from \"../api/getDevicesData\";\nimport { queryDevicesData } from \"../api/queryDevicesData\";\nimport { disableDevice } from \"../api/disableDevice\";\nexport class Device extends BaseDevice {\n constructor(\n public id: string,\n public name: string,\n private organizationId: string,\n public tags?: ITags\n ) {\n super();\n }\n\n static createDevice = createDevice;\n static patchDevice = patchDevice;\n static getDevicesData = getDevicesData;\n static queryDevicesData = queryDevicesData;\n static disableDevice = disableDevice;\n\n async getLatestTelemetry() {\n const data = await fetch(\n `${FORMANT_API_URL}/v1/queries/stream-current-value`,\n {\n method: \"POST\",\n body: JSON.stringify({\n deviceIds: [this.id],\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const telemetry = await data.json();\n return telemetry.items;\n }\n\n async getConfiguration(): Promise<ConfigurationDocument> {\n let result = await fetch(`${FORMANT_API_URL}/v1/admin/devices/${this.id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const device = await result.json();\n if (!device.state.reportedConfiguration) {\n throw new Error(\n \"Device has no configuration, has it ever been turned on?\"\n );\n }\n const version = device.state.reportedConfiguration.version;\n result = await fetch(\n `${FORMANT_API_URL}/v1/admin/devices/${this.id}/configurations/${version}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const config = await result.json();\n return config.document;\n }\n\n async getFileUrl(fileId: string): Promise<string[]> {\n const result = await fetch(`${FORMANT_API_URL}/v1/admin/files/query`, {\n method: \"POST\",\n body: JSON.stringify({\n fileIds: [fileId],\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const files = await result.json();\n return files.fileUrls;\n }\n\n /**\n * Starts a real-time connection with the remote device using WebRTC.\n * @param {number} [options] - Optional session type to be used for the connection.\n * @throws `Error` If the connection could not be established or if a connection already exists.\n * @returns {void}\n */\n async startRealtimeConnection(\n options: SessionType | IStartRealtimeConnectionOptions = {}\n ): Promise<void> {\n console.debug(`${new Date().toISOString()} :: Connection start requested`);\n\n if (this.rtcClient && this.connectionMonitorInterval !== undefined) {\n throw new Error(\n `Already created realtime connection to device ${this.id}`\n );\n }\n\n if (this.rtcClient) {\n console.warn(\n \"overwriting existing rtcClient due to missing connectionMonitorInterval\"\n );\n }\n\n const {\n sessionType,\n deadlineMs = 10_000,\n maxConnectRetries = 3,\n } = typeof options === \"number\"\n ? ({ sessionType: options } as IStartRealtimeConnectionOptions)\n : options;\n\n const pool = getRtcClientPool({\n sessionType,\n });\n const rtcClient = pool.get(this.handleMessage);\n\n let cancelled = false;\n const deadlinePromise = new Promise<never>((_, reject) =>\n setTimeout(() => {\n cancelled = true;\n reject(\n new Error(\n \"Connection timed out: the connection could not be finalized in time, \" +\n \"possibly due to network issues or misconfigured settings.\"\n )\n );\n }, deadlineMs)\n );\n\n const establishConnection = async (): Promise<string> => {\n if (\"isReady\" in rtcClient) {\n while (!rtcClient.isReady()) {\n this.assertNotCancelled(cancelled);\n await delay(100);\n }\n }\n\n // WebRTC requires a signaling phase when forming a new connection.\n const remoteDevicePeerId = await this.getRemoteDevicePeerId(rtcClient);\n this.assertNotCancelled(cancelled);\n\n let sessionId: string | undefined = undefined;\n\n // We can connect our real-time communication client to device peers by their ID\n for (let i = 0; i < maxConnectRetries; i++) {\n sessionId = await rtcClient.connect(remoteDevicePeerId);\n if (!!sessionId) break;\n delay(100);\n this.assertNotCancelled(cancelled);\n }\n\n if (!sessionId)\n throw new Error(\n `Session could not be created: exhausted ${maxConnectRetries} retries`\n );\n\n // Wait for the signaling process to complete...\n let retries = 0;\n while (!cancelled) {\n const connectionCompleted =\n rtcClient.getConnectionStatus(remoteDevicePeerId) === \"connected\";\n if (connectionCompleted) {\n break;\n }\n\n await delay(100);\n retries += 1;\n }\n this.assertNotCancelled(cancelled);\n\n console.debug(\n `${new Date().toISOString()} :: Connection completed after ${retries} retries`\n );\n\n return remoteDevicePeerId;\n };\n\n return Promise.race([establishConnection(), deadlinePromise])\n .then((remoteDevicePeerId) => {\n this.remoteDevicePeerId = remoteDevicePeerId;\n this.initConnectionMonitoring();\n this.rtcClient = rtcClient;\n this.emit(\"connect\");\n })\n .catch((err) => {\n console.debug(\n `${new Date().toISOString()} :: Connection failed: %o`,\n err\n );\n // cleanup on failure\n this.remoteDevicePeerId = null;\n rtcClient.shutdown().catch((shutdownErr: unknown) => {\n console.error(\"rtcClient cannot shutdown: %o\", shutdownErr);\n });\n this.emit(\"connection_failed\", err);\n throw err;\n });\n }\n\n private async getRemoteDevicePeerId(rtcClient: RtcClient) {\n // Each online device and user has a peer in the system\n const peers = await rtcClient.getPeers();\n\n // Find the device peer corresponding to the device's ID\n const devicePeer = peers.find((_) => _.deviceId === this.id);\n\n if (!isRtcPeer(devicePeer)) {\n // If the device is offline, we won't be able to find its peer.\n throw new Error(\"Cannot find peer, is the robot offline?\");\n }\n return devicePeer.id;\n }\n\n private initConnectionMonitoring() {\n this.connectionMonitorInterval = setInterval(async () => {\n let dataChannelClosed = false;\n\n if (this.rtcClient) {\n const rtcConnections = this.rtcClient.getConnections();\n const connection = rtcConnections.find(\n (_) => _.getRemotePeerId() === this.remoteDevicePeerId && _.isActive()\n );\n if (connection === undefined || !connection.isReady()) {\n console.debug(`${new Date().toISOString()} :: data channel closed`);\n dataChannelClosed = true;\n }\n }\n\n if (\n !this.rtcClient ||\n !this.remoteDevicePeerId ||\n (await this.rtcClient.getConnectionStatsInfo(\n this.remoteDevicePeerId\n )) === undefined ||\n dataChannelClosed\n ) {\n this.emit(\"disconnect\");\n this.stopRealtimeConnection().catch((err) => {\n console.error(err);\n });\n }\n }, 1000);\n }\n\n async getRemotePeer(): Promise<IRtcPeer> {\n // Each online device and user has a peer in the system\n const peers = await defined(\n this.rtcClient,\n \"Realtime connection has not been started\"\n ).getPeers();\n\n // Find the device peer corresponding to the device's ID\n const devicePeer = peers.find((_) => _.deviceId === this.id);\n return defined(\n devicePeer,\n \"Could not find remote peer for device \" + this.id\n );\n }\n\n async stopRealtimeConnection() {\n let throwNotStartedError = false;\n\n if (this.rtcClient) {\n this.stopConnectionMonitoring();\n\n if (this.remoteDevicePeerId) {\n await this.rtcClient.disconnect(this.remoteDevicePeerId);\n this.remoteDevicePeerId = null;\n } else {\n throwNotStartedError = true;\n }\n\n try {\n await this.rtcClient.shutdown();\n } finally {\n this.rtcClient = undefined;\n }\n }\n\n if (throwNotStartedError) {\n throw new Error(`Realtime connection hasn't been started for ${this.id}`);\n }\n }\n\n async isInRealtimeSession(): Promise<boolean> {\n const peers = await getPeers();\n const sessions = await getRealtimeSessions();\n const peer = peers.find((_) => _.deviceId === this.id);\n if (peer) {\n return sessions[peer.id].length > 0;\n }\n return false;\n }\n\n async getAvailableCommands(): Promise<Command[]> {\n const result = await fetch(\n `${FORMANT_API_URL}/v1/admin/command-templates/`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const commands = await result.json();\n return commands.items.map((i: any) => ({\n name: i.name,\n id: i.id,\n command: i.command,\n description: i.description,\n parameterEnabled: i.parameterEnabled,\n parameterValue: i.parameterValue,\n parameterMeta: i.parameterMeta,\n enabled: i.enabled,\n tags: i.tags,\n }));\n }\n\n async sendCommand(\n name: string,\n data?: string,\n time?: Date,\n metadata?: {}\n ): Promise<Response> {\n const commands = await this.getAvailableCommands();\n const command = commands.find((_) => _.name === name);\n if (!command) {\n throw new Error(`Could not find command with name \"${name}\"`);\n }\n\n let d: string = \"\";\n\n if (data === undefined) {\n if (command.parameterEnabled && command.parameterValue) {\n d = command.parameterValue;\n }\n } else {\n d = data;\n }\n\n let parameter = {\n value: d,\n scrubberTime: (time || new Date()).toISOString(),\n meta: {\n ...command.parameterMeta,\n ...metadata,\n },\n };\n\n const res = await fetch(`${FORMANT_API_URL}/v1/admin/commands`, {\n method: \"POST\",\n body: JSON.stringify({\n commandTemplateId: command.id,\n organizationId: this.organizationId,\n deviceId: this.id,\n command: command.command,\n parameter: parameter,\n userId: Authentication.currentUser?.id,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n\n return res;\n }\n\n async getCommand(id: string): Promise<Response> {\n const res = await fetch(`${FORMANT_API_URL}/v1/admin/commands/${id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return res;\n }\n\n async createCaptureStream(streamName: string) {\n const result = await fetch(`${FORMANT_API_URL}/v1/admin/capture-sessions`, {\n method: \"POST\",\n body: JSON.stringify({\n deviceId: this.id,\n streamName,\n tags: {},\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const captureSession = await result.json();\n return new CaptureStream(captureSession);\n }\n\n async getTelemetry(\n streamNameOrStreamNames: string | string[],\n start: Date,\n end: Date,\n tags?: { [key in string]: string[] }\n ) {\n return await getTelemetry(\n this.id,\n streamNameOrStreamNames,\n start,\n end,\n tags\n );\n }\n\n async getTelemetryStreams(): Promise<TelemetryStream[]> {\n const config = await this.getConfiguration();\n\n const result = await fetch(\n `${FORMANT_API_URL}/v1/queries/metadata/stream-names`,\n {\n method: \"POST\",\n body: JSON.stringify({\n deviceIds: [this.id],\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n const disabledList: string[] = [];\n const onDemandList: string[] = [];\n config.telemetry?.streams?.forEach((_) => {\n if (_.disabled !== true) {\n disabledList.push(_.name);\n }\n if (_.onDemand === true) {\n onDemandList.push(_.name);\n }\n });\n console.log(onDemandList);\n\n const data = await result.json();\n\n let streamNames = (data.items as string[])\n .filter((_) => !disabledList.includes(_))\n .map((_) => ({ name: _, onDemand: onDemandList.includes(_) }));\n\n return streamNames;\n }\n\n async createInterventionRequest<T extends InterventionType>(\n message: string,\n interventionType: InterventionType,\n interventionRequest: IInterventionTypeMap[T][\"request\"],\n tags?: { [key in string]: string[] }\n ): Promise<(id: string) => IInterventionTypeMap[T][\"response\"]> {\n const intervention = await fetch(\n `${FORMANT_API_URL}/v1/admin/intervention-requests`,\n {\n method: \"POST\",\n body: JSON.stringify({\n message,\n interventionType,\n time: new Date().toISOString(),\n deviceId: this.id,\n tags,\n data: interventionRequest,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n const interventionJson = await intervention.json();\n\n return interventionJson;\n }\n\n async addInterventionResponse<T extends InterventionType>(\n interventionId: string,\n interventionType: InterventionType,\n data: IInterventionTypeMap[T][\"response\"]\n ): Promise<IInterventionResponse> {\n const response = await fetch(\n `${FORMANT_API_URL}/v1/admin/intervention-responses`,\n {\n method: \"POST\",\n body: JSON.stringify({\n interventionId,\n interventionType,\n data,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const interventionResponse = await response.json();\n return interventionResponse;\n }\n\n async getAnnotationCount(query: IEventQuery, tagKey: string) {\n return await getAnnotationCount({ ...query, deviceIds: [this.id] }, tagKey);\n }\n\n async getAnnotationCountByIntervals(\n query: IEventQuery,\n tagKey: string,\n aggregate: AggregateLevel\n ) {\n return await getAnnotationCountByIntervals(\n { ...query, deviceIds: [this.id] },\n tagKey,\n aggregate\n );\n }\n\n async eventsCounter(\n eventTypes: EventType[],\n timeFrame: AggregateLevel,\n range: number,\n time: number,\n query?: IEventQuery\n ) {\n return await eventsCounter(eventTypes, timeFrame, range, time, {\n ...query,\n deviceIds: [this.id],\n });\n }\n\n async createShareLink(share: IShare, view: string) {\n share.scope.deviceIds = [this.id];\n return await createShareLink(share, view);\n }\n}\n","import { RtcClient, IRtcPeer } from \"@formant/realtime-sdk\";\nimport { delay } from \"../../../common/delay\";\nimport { IStreamCurrentValue } from \"../model/IStreamCurrentValue\";\nimport { ConfigurationDocument } from \"./device.types\";\nimport { BaseDevice } from \"./BaseDevice\";\n\nexport class PeerDevice extends BaseDevice {\n id!: string;\n\n private telemetryStreamActive = false;\n private streamTelemetry: { [key: string]: any } = {};\n\n constructor(public peerUrl: string) {\n super();\n }\n\n async getLatestTelemetry(): Promise<IStreamCurrentValue[]> {\n if (!this.telemetryStreamActive) {\n this.subscribeToTelemetry();\n }\n\n const telemetry = this.streamTelemetry as {\n [key in string]: { timestamp: string };\n };\n const entries = Object.entries(telemetry);\n return entries.map(([stream, latestValue]) => {\n const v: IStreamCurrentValue = {\n deviceId: this.id,\n streamName: stream,\n streamType: \"json\",\n currentValue: latestValue,\n currentValueTime: latestValue.timestamp,\n tags: {},\n };\n return v;\n });\n }\n\n private subscribeToTelemetry() {\n this.telemetryStreamActive = true;\n\n let previousBytesReceived = 0;\n\n // we use XHR because chunked encoding is broken in the react native fetch API\n const xhr = new XMLHttpRequest();\n xhr.responseType = \"text\";\n\n xhr.addEventListener(\"error\", (_) => {\n this.handleXHRError(\"error\");\n });\n xhr.addEventListener(\"abort\", (_) => {\n this.handleXHRError(\"abort\");\n });\n xhr.addEventListener(\"timeout\", (_) => {\n this.handleXHRError(\"timeout\");\n });\n xhr.addEventListener(\"readystatechange\", (_) => {\n if (xhr.readyState === XMLHttpRequest.DONE) {\n this.handleXHRError(\"closed\");\n }\n });\n\n // handle new data\n xhr.addEventListener(\"progress\", (event) => {\n const currentBytesReceived = event.loaded;\n const newBytesReceived = currentBytesReceived - previousBytesReceived;\n previousBytesReceived = currentBytesReceived;\n\n // Process the new data received\n const newData = xhr.responseText.substr(-newBytesReceived);\n\n const jsonObjects = newData.split(\"\\n\");\n jsonObjects.forEach((jsonObject) => {\n if (jsonObject.length > 0) {\n const parsedObject = JSON.parse(jsonObject);\n if (parsedObject.result?.datapoint) {\n const datapoint = parsedObject.result.datapoint;\n const stream = datapoint.stream;\n delete datapoint[\"stream\"];\n this.streamTelemetry[stream] = datapoint;\n }\n }\n });\n });\n\n xhr.open(\"POST\", `${this.peerUrl}/v1/telemetry`);\n\n xhr.send();\n }\n\n private handleXHRError(reason: string) {\n console.warn(`Telemetry stream ended: ${reason}`);\n this.telemetryStreamActive = false;\n }\n\n async getDeviceId(): Promise<string> {\n let result = await fetch(`${this.peerUrl}/v1/config`);\n const cfg = await result.json();\n return cfg.configuration.id;\n }\n\n async getConfiguration(): Promise<ConfigurationDocument> {\n let result = await fetch(`${this.peerUrl}/v1/config`);\n const cfg = await result.json();\n return cfg.configuration.document;\n }\n\n async startRealtimeConnection(sessionType?: number): Promise<void> {\n console.debug(`${new Date().toISOString()} :: Connection start requested`);\n\n if (this.rtcClient && this.connectionMonitorInterval !== undefined) {\n throw new Error(\n `Already created realtime connection to device ${this.id}`\n );\n }\n\n if (this.rtcClient) {\n console.warn(\n \"overwriting existing rtcClient due to missing connectionMonitorInterval\"\n );\n }\n\n const rtcClient = new RtcClient({\n lanOnlyMode: true,\n receive: this.handleMessage,\n sessionType,\n });\n\n await rtcClient.connectLan(this.peerUrl);\n\n // WebRTC requires a signaling phase when forming a new connection.\n // Wait for the signaling process to complete...\n while (rtcClient.getConnectionStatus(this.peerUrl) !== \"connected\") {\n await delay(100);\n }\n this.rtcClient = rtcClient;\n this.initConnectionMonitoring();\n }\n\n private initConnectionMonitoring() {\n this.connectionMonitorInterval = setInterval(async () => {\n let dataChannelClosed = false;\n\n if (this.rtcClient) {\n if (this.rtcClient.getConnectionStatus(this.peerUrl) !== \"connected\") {\n console.debug(`${new Date().toISOString()} :: data channel closed`);\n dataChannelClosed = true;\n }\n }\n\n if (!this.rtcClient || dataChannelClosed) {\n this.emit(\"disconnect\");\n this.stopRealtimeConnection().catch((err) => {\n console.error(err);\n });\n }\n }, 1000);\n }\n\n async getRemotePeer(): Promise<IRtcPeer> {\n return {\n id: this.peerUrl,\n organizationId: \"\",\n deviceId: this.id,\n capabilities: [],\n capabilitySet: {},\n };\n }\n\n async stopRealtimeConnection() {\n let throwNotStartedError = false;\n\n if (this.rtcClient) {\n this.stopConnectionMonitoring();\n\n if (this.id) {\n await this.rtcClient.disconnect(this.id);\n this.remoteDevicePeerId = null;\n } else {\n throwNotStartedError = true;\n }\n\n try {\n await this.rtcClient.shutdown();\n } finally {\n this.rtcClient = undefined;\n }\n }\n\n if (throwNotStartedError) {\n throw new Error(`Realtime connection hasn't been started for ${this.id}`);\n }\n }\n\n async sendCommand(\n name: string,\n data?: string,\n time?: Date,\n metadata?: {}\n ): Promise<Response> {\n const parameter = {\n value: data,\n scrubberTime: (time || new Date()).toISOString(),\n meta: metadata,\n };\n\n const res = await fetch(`${this.peerUrl}/v1/enqueue-command`, {\n method: \"POST\",\n body: JSON.stringify({\n command: name,\n parameter: parameter,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n\n return res;\n }\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function addDeviceToFleet(deviceId: string, fleetId: string) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices/${deviceId}`, {\n method: \"PATCH\",\n body: JSON.stringify({ fleetId }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { IQuery } from \"../model/IQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IStreamAggregateData } from \"../model/IStreamAggregateData\";\n\nexport async function aggregateTelemetry(query: IQuery) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/queries/queries`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n\n return (await data.json()).aggregates as IStreamAggregateData[];\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function deleteFleet(id: string): Promise<void> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n await fetch(`${FORMANT_API_URL}/v1/admin/fleets/${id}`, {\n method: \"DELETE\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IStreamColumn } from \"../model/IStreamColumn\";\n\n/**\n * retrieves a list of all available data streams that can be used for running analytics.\n * This function takes no arguments and returns a list of stream names that can be used for analyzing data.\n * @example\n * // Returns\n * [\n * {\n * streamName: \"$.agent.health\",\n streamType : \"health\"\n },\n {\n * streamName: \"up.hours\",\n streamType : \"numeric\"\n }\n ]\n */\nexport async function getAnalyticStreams() {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n\n const response = await fetch(\n `${FORMANT_API_URL}/v1/queries/analytics/streams`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return (await response.json()).items as IStreamColumn[];\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { IAnalyticsModule } from \"../model/IAnalyticsModule\";\n\nexport async function getAnalyticsModules() {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n\n const response = await fetch(\n `${FORMANT_API_URL}/v1/admin/analytics-modules`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return (await response.json()).items as IAnalyticsModule;\n}\n","import { ISqlQuery } from \"../model/ISqlQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\n/**\n * Retrieves all rows\n * sqlQuery is required\n * @param query\n * @returns\n */\nexport async function getAnalyticsRows(query: ISqlQuery) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(`${FORMANT_API_URL}/v1/queries/analytics/rows`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await response.json();\n}\n","import { IDeviceQuery } from \"../model/IDeviceQuery\";\nimport { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function queryDevices(query: IDeviceQuery): Promise<Device[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices/query`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n\n return devices.items.map(\n (_: any) => new Device(_.id, _.name, _.organizationId, _.tags)\n );\n}\n","import { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { queryDevices } from \"./queryDevices\";\n\nexport async function getCurrentGroup(): Promise<Device[] | undefined> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n let urlParams = new URLSearchParams(\"\");\n\n if (typeof window !== \"undefined\" && window.location) {\n urlParams = new URLSearchParams(window.location.search);\n }\n\n const groupId = urlParams.get(\"group\");\n\n if (groupId === null || groupId.trim() === \"\") {\n return undefined;\n }\n const response = await fetch(\n `${FORMANT_API_URL}/v1/admin/groups/` + groupId,\n {\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n const { tagKey, tagValue } = await response.json();\n\n const devices = await queryDevices({\n tags: { [tagKey]: [tagValue] },\n enabled: true,\n type: \"default\",\n });\n\n return devices;\n}\n","import { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getDevice(deviceId: string): Promise<Device> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/devices/${deviceId}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const device = await data.json();\n const name = device.name as string;\n return new Device(deviceId, name, device.organizationId, device.tags);\n}\n","import { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getDevices(): Promise<Device[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/device-details/query`, {\n method: \"POST\",\n body: JSON.stringify({ enabled: true, type: \"default\" }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n devices.items;\n return devices.items.map(\n (_: any) =>\n new Device(\n _.id as string,\n _.name as string,\n _.organizationId as string,\n _.tags\n )\n );\n}\n","import { IEvent } from \"../model/IEvent\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getEvent(uuid: string): Promise<IEvent> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/events/query/id=${uuid}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n return (await data.json()).items as IEvent;\n}\n","import { FORMANT_API_URL } from \"../config\";\nimport { Authentication } from \"../Authentication\";\n\nexport async function getFileUrl(uuid: string) {\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/files/query`, {\n method: \"POST\",\n body: JSON.stringify({\n fileIds: [uuid],\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const result = await data.json();\n if (result.fileUrls.length === 0) {\n throw new Error(\"File not found\");\n }\n return result.fileUrls[0] as string;\n}\n","import { IFleet } from \"../model/IFleet\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getFleet(id: string): Promise<IFleet> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/fleets/${id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getFleetDevices(id: string): Promise<void> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/fleets/${id}/devices`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const fleets = await data.json();\n return fleets.items;\n}\n","import { IEvent } from \"../model/IEvent\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getInterventions(): Promise<IEvent[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const interventions = await fetch(\n `${FORMANT_API_URL}/v1/admin/intervention-requests`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return (await interventions.json()).items as IEvent[];\n}\n","import { IStreamCurrentValue } from \"../model/IStreamCurrentValue\";\nimport { IStreamTypeMap } from \"../model/IStreamTypeMap\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { Authentication } from \"../Authentication\";\n\nexport async function getLatestTelemetry(\n ...ids: (string | string[])[]\n): Promise<IStreamCurrentValue<keyof IStreamTypeMap>[]> {\n const deviceIds = ids.flat().filter((_) => !!_);\n\n if (deviceIds.length === 0) {\n return [];\n }\n\n const data = await fetch(\n `${FORMANT_API_URL}/v1/queries/stream-current-value`,\n {\n method: \"POST\",\n body: JSON.stringify({\n deviceIds,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const telemetry = await data.json();\n return telemetry.items;\n}\n","import { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { getDevices } from \"./getDevices\";\n\nexport async function getOnlineDevices(): Promise<Device[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/queries/online-devices`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n const onlineIds = devices.items as string[];\n const allDevices = await getDevices();\n return allDevices.filter((_) => onlineIds.includes(_.id));\n}\n","import { Device } from \"../devices/Device\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { getDevices } from \"./getDevices\";\n\nexport async function getRealtimeDevices(): Promise<Device[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/signaling/peers`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const devices = await data.json();\n const onlineIds = devices.items.map(\n (_: { deviceId: string }) => _.deviceId\n ) as string[];\n const allDevices = await getDevices();\n return allDevices.filter((_) => onlineIds.includes(_.id));\n}\n","import { IStream } from \"../model/IStream\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getStreams(): Promise<IStream[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(`${FORMANT_API_URL}/v1/admin/streams`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const streams = await response.json();\n return streams.items.filter(\n (_: { enabled: boolean }) => _.enabled\n ) as IStream[];\n}\n","import { ISqlQuery } from \"../model/ISqlQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\n/**\n * @param taskColumns is required\n * @returns\n * All task reports\n * @example\n * // Body\n * const tasks = await getTaskReports({\n * taskColumns: [\n * {\n * columns: [\n * {\n * dataType: \"string\",\n * isNullable: true,\n * name: \"TYPE\",\n * tableName: \"custom\",\n * },\n * ],\n * name: \"DURATION_SECONDS\",\n * tableName: \"TASK_REPORTS_CLEANING_MODE\",\n * yAxis: \"DURATION_SECONDS\",\n * },\n * ],\n * });\n */\n\nexport async function getTaskReportRows(query: ISqlQuery) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(\n `${FORMANT_API_URL}/v1/queries/analytics/task-report-rows`,\n {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return await response.json();\n}\n","import { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { ITaskReportColumn } from \"../model/ITaskReportColumn\";\n\n/**\n * retrieves a list of all available tables that can be used to create task reports.\n * This function takes no arguments and returns a list of table names that can be used for creating task reports.\n * @returns List all available tables\n * @example\n * // Returns\n *[\n * {\n * name: \"\",\n * tableName: \"TASK_REPORTS_CLEANING_MODE\",\n * columns: [\n * {\n * name: \"TYPE\",\n * isNullable: true,\n * dataType: \"string\",\n * tableName: \"custom\"\n * }\n * ]\n * }\n *]\n */\nexport async function getTaskReportTables() {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n\n const response = await fetch(\n `${FORMANT_API_URL}/v1/queries/analytics/task-reports`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return (await response.json()).items as ITaskReportColumn[];\n}\n","import { IFleet } from \"../model/IFleet\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function listFleets(): Promise<IFleet[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/fleets`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const fleets = await data.json();\n return fleets.items;\n}\n","import { IFleet } from \"../model/IFleet\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function patchFleet(\n id: string,\n role: Partial<IFleet>\n): Promise<IFleet> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/fleets/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify(role),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { IStream } from \"../model/IStream\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function patchStream(stream: IStream): Promise<IStream> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(\n `${FORMANT_API_URL}/v1/admin/streams/${stream.id}`,\n {\n method: \"PATCH\",\n body: JSON.stringify(stream),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return (await response.json()) as IStream;\n}\n","import { IView } from \"../model/IView\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function patchView(view: IView): Promise<IView> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(`${FORMANT_API_URL}/v1/admin/views/${view.id}`, {\n method: \"PATCH\",\n body: JSON.stringify(view),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return (await response.json()) as IView;\n}\n","import { ISqlQuery } from \"../model/ISqlQuery\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\nimport { ISqlResult } from \"../model/ISqlResult\";\n\n/**\n *Retrieves all stream rows\n * @example\n * // Body\n * const analytics = await queryAnalytics({\n * aggregateLevel: \"day\",\n * orderByColumn: \"TIMESTAMP\",\n * streamColumns: [\n * {\n * streamName: \"consumables_residual_percentage\",\n * streamType: \"numeric set\",\n * },\n * ],\n * });\n * //Returns\n * {\n * aggregates: [],\n * columns: [\n * {\n * name: 'TIMESTAMP',\n * isNullable: true,\n * dataType: 'string',\n * tableName: 'NUMERIC_SET_MAIN'\n * }\n * ],\n * items: [\n * {\n * axisLabel: \"suction_blade\",\n * name: \"consumables_residual_percentage\",\n * tableName: \"NUMERIC_SET_TEST\",\n * time: \"2020-04-20T08:00:00.000Z\",\n * type: \"numeric set\",\n * unitLabel: \"percent\"\n * }\n * ],\n * rowCount: 14,\n * rows: []\n * sqlText: \"SELECT dateadd(day, dayofweek(TIMESTAMP), to_timestamp_tz('4/20/2020')) AS TIMESTAMP, SUM(VALUE)\"\n * }\n */\nexport async function queryAnalytics(query: ISqlQuery) {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const response = await fetch(`${FORMANT_API_URL}/v1/queries/analytics`, {\n method: \"POST\",\n body: JSON.stringify(query),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return (await response.json()) as ISqlResult;\n}\n","import { IFleet } from \"../model/IFleet\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function createFleet(fleet: IFleet): Promise<IFleet> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/fleets`, {\n method: \"POST\",\n body: JSON.stringify(fleet),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n}\n","import { IEventTriggerGroup } from \"../model/IEventTriggerGroup\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getAllEventTriggerGroup(): Promise<IEventTriggerGroup[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/event-trigger-groups`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n\n return (await data.json()).items as IEventTriggerGroup[];\n}\n","import { IEventTriggerGroup } from \"../model/IEventTriggerGroup\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function getEventTriggerGroup(\n id: string\n): Promise<IEventTriggerGroup> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/event-trigger-groups/${id}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n return (await data.json()) as IEventTriggerGroup;\n}\n","import { IEventTriggerGroup } from \"../model/IEventTriggerGroup\";\nimport { Authentication } from \"../Authentication\";\nimport { FORMANT_API_URL } from \"../config\";\n\nexport async function patchEventTriggerGroup(\n id: string,\n eventTrigger: Partial<IEventTriggerGroup>\n): Promise<IEventTriggerGroup> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/event-trigger-groups/${id}`,\n {\n method: \"PATCH\",\n body: JSON.stringify(eventTrigger),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n return (await data.json()) as IEventTriggerGroup;\n}\n","import { defined } from \"../../common/defined\";\nimport { Authentication } from \"./Authentication\";\nimport { FORMANT_API_URL } from \"./config\";\nimport { Device } from \"./devices/Device\";\nimport { PeerDevice } from \"./devices/PeerDevice\";\nimport { addDeviceToFleet } from \"./api/addDeviceToFleet\";\nimport { aggregateTelemetry } from \"./api/aggregateTelemetry\";\nimport { createShareLink } from \"./api/createShareLink\";\nimport { deleteFleet } from \"./api/deleteFleet\";\nimport { eventsCounter } from \"./api/eventsCounter\";\nimport { getAnalyticStreams } from \"./api/getAnalyticsStreams\";\nimport { getAnalyticsModules } from \"./api/getAnalyticsModules\";\nimport { getAnalyticsRows } from \"./api/getAnalyticsRows\";\nimport { getAnnotationCount } from \"./api/getAnnotationCount\";\nimport { getAnnotationCountByIntervals } from \"./api/getAnnotationCountByIntervals\";\nimport { getCurrentGroup } from \"./api/getCurrentGroup\";\nimport { getDevice } from \"./api/getDevice\";\nimport { getDevices } from \"./api/getDevices\";\nimport { getEvent } from \"./api/getEvent\";\nimport { getFileUrl } from \"./api/getFileUrl\";\nimport { getFleet } from \"./api/getFleet\";\nimport { getFleetDevices } from \"./api/getFleetDevices\";\nimport { getInterventions } from \"./api/getInterventions\";\nimport { getLatestTelemetry } from \"./api/getLatestTelemetry\";\nimport { getOnlineDevices } from \"./api/getOnlineDevices\";\nimport { getPeers } from \"./api/getPeers\";\nimport { getRealtimeDevices } from \"./api/getRealtimeDevices\";\nimport { getRealtimeSessions } from \"./api/getRealtimeSessions\";\nimport { getStreams } from \"./api/getStreams\";\nimport { getTaskReportRows } from \"./api/getTaskReportRows\";\nimport { getTaskReportTables } from \"./api/getTaskreportTables\";\nimport { getTelemetry } from \"./api/getTelemetry\";\nimport { getViews } from \"./api/getViews\";\nimport { listFleets } from \"./api/listFleets\";\nimport { patchFleet } from \"./api/patchFleet\";\nimport { patchStream } from \"./api/patchStreams\";\nimport { patchView } from \"./api/patchView\";\nimport { queryAnalytics } from \"./api/queryAnalytics\";\nimport { queryDevices } from \"./api/queryDevices\";\nimport { queryEvents } from \"./api/queryEvents\";\nimport { queryTelemetry } from \"./api/queryTelemetry\";\nimport { createFleet } from \"./api/createFleet\";\nimport { getAllEventTriggerGroup } from \"./api/getAllEventTriggerGroup\";\nimport { getEventTriggerGroup } from \"./api/getEventTriggerGroup\";\nimport { patchEventTriggerGroup } from \"./api/patchEventTriggerGroup\";\n\nexport class Fleet {\n static defaultDeviceId: string | undefined;\n static knownContext: WeakRef<Device>[] = [];\n\n static createFleet = createFleet;\n static listFleets = listFleets;\n static getFleet = getFleet;\n static patchFleet = patchFleet;\n static deleteFleet = deleteFleet;\n static addDeviceToFleet = addDeviceToFleet;\n static getFleetDevices = getFleetDevices;\n\n static async setDefaultDevice(deviceId: string) {\n Fleet.defaultDeviceId = deviceId;\n }\n\n static async getCurrentDevice(): Promise<Device> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n if (!Fleet.defaultDeviceId) {\n throw new Error(\"No known default device\");\n }\n\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/device-details/query`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n\n const devices = await data.json();\n const device = devices.items.find(\n (_: { id: string }) => _.id === Fleet.defaultDeviceId\n );\n const name = device.name as string;\n const context = new Device(\n Fleet.defaultDeviceId,\n name,\n defined(Authentication.currentOrganization) as string,\n device.tags\n );\n Fleet.knownContext.push(new WeakRef(context));\n return context;\n }\n\n static async getPeerDevice(url: string): Promise<PeerDevice> {\n const peer = new PeerDevice(url);\n peer.id = await peer.getDeviceId();\n return peer;\n }\n\n static async getDevice(deviceId: string): Promise<Device> {\n const context = await getDevice(deviceId);\n Fleet.knownContext.push(new WeakRef(context));\n return context;\n }\n\n static aggregateTelemetry = aggregateTelemetry;\n static createShareLink = createShareLink;\n static eventsCounter = eventsCounter;\n static getAnalyticStreams = getAnalyticStreams;\n static getAnalyticsModules = getAnalyticsModules;\n static getAnalyticsRows = getAnalyticsRows;\n static getAnnotationCount = getAnnotationCount;\n static getAnnotationCountByIntervals = getAnnotationCountByIntervals;\n static getCurrentGroup = getCurrentGroup;\n static getDevices = getDevices;\n static getEvent = getEvent;\n static getFileUrl = getFileUrl;\n static getInterventions = getInterventions;\n static getLatestTelemetry = getLatestTelemetry;\n static getOnlineDevices = getOnlineDevices;\n static getPeers = getPeers;\n static getRealtimeDevices = getRealtimeDevices;\n static getRealtimeSessions = getRealtimeSessions;\n static getStreams = getStreams;\n static getTaskReportRows = getTaskReportRows;\n static getTaskReportTables = getTaskReportTables;\n static getTelemetry = getTelemetry;\n static getViews = getViews;\n static patchStream = patchStream;\n static patchView = patchView;\n static queryAnalytics = queryAnalytics;\n static queryDevices = queryDevices;\n static queryEvents = queryEvents;\n static queryTelemetry = queryTelemetry;\n static getAllEventTriggerGroup = getAllEventTriggerGroup;\n static getEventTriggerGroup = getEventTriggerGroup;\n static patchEventTriggergroup = patchEventTriggerGroup;\n}\n","import { FORMANT_API_URL } from \"./config\";\nimport { Authentication } from \"./Authentication\";\nimport { defined } from \"../../common/defined\";\nimport { ITags } from \"./model/ITags\";\n\nexport class KeyValue {\n public static async set(key: string, value: string, tags?: ITags) {\n try {\n const result = await fetch(FORMANT_API_URL + \"/v1/admin/key-value\", {\n method: \"POST\",\n body: JSON.stringify({\n organizationId: defined(Authentication.currentUser).organizationId,\n key,\n value,\n tags,\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const keyValue = await result.json();\n if (result.status !== 200) {\n throw new Error(keyValue.message);\n }\n } catch (e: any) {\n throw e;\n }\n }\n\n public static async get(key: string): Promise<string> {\n try {\n const result = await fetch(\n FORMANT_API_URL + `/v1/admin/key-value/${key}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n const keyValue = await result.json();\n if (result.status !== 200) {\n throw new Error(keyValue.message);\n }\n return keyValue.value;\n } catch (e: any) {\n throw e;\n }\n }\n\n public static async list(): Promise<string[]> {\n try {\n const result = await fetch(FORMANT_API_URL + \"/v1/admin/key-value\", {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const keyValueList = await result.json();\n if (result.status !== 200) {\n throw new Error(keyValueList.message);\n }\n return keyValueList.items;\n } catch (e: any) {\n throw e;\n }\n }\n\n public static async delete(key: string) {\n try {\n const result = await fetch(\n FORMANT_API_URL + `/v1/admin/key-value/${key}`,\n {\n method: \"DELETE\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n if (!result.ok) {\n throw new Error(\"Unable to handle request\");\n }\n return;\n } catch (e: any) {\n throw e;\n }\n }\n\n public static async query(keys: string[]) {\n try {\n const result = await fetch(\n FORMANT_API_URL + `/v1/admin/key-value/query`,\n {\n method: \"POST\",\n body: JSON.stringify({ keys }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n if (!result.ok) {\n throw new Error(\"Unable to handle request\");\n }\n const jsonResponse = await result.json();\n return jsonResponse.items;\n } catch (e: any) {\n throw e;\n }\n }\n}\n","import { decode } from \"base-64\";\n\nexport function stringToArrayBuffer(input: string): Uint8Array {\n return Uint8Array.from(decode(input), (_) => _.charCodeAt(0));\n}\n","export type BrowserType =\n | \"Firefox\"\n | \"Chrome\"\n | \"Edge\"\n | \"Safari\"\n | \"IE\"\n | \"Other\";\n\nexport function browser(): BrowserType {\n const { userAgent } = navigator;\n\n if (!userAgent) {\n return \"Other\";\n }\n\n if (userAgent.includes(\"Firefox/\")) {\n return \"Firefox\";\n } else if (userAgent.includes(\"Edg/\")) {\n return \"Edge\";\n } else if (userAgent.includes(\"Chrome/\")) {\n return \"Chrome\";\n } else if (userAgent.includes(\"Safari/\")) {\n return \"Safari\";\n } else if (userAgent.includes(\"MSIE/\") || userAgent.includes(\"Trident/\")) {\n return \"IE\";\n } else {\n return \"Other\";\n }\n}\n","import { IRtcStreamMessage } from \"@formant/realtime-sdk\";\nimport { Device } from \"./devices/Device\";\nimport { stringToArrayBuffer } from \"./utils/stringToArrayBuffer\";\nimport { fork } from \"../../common/fork\";\nimport { browser } from \"../../common/browser\";\nimport { RealtimeDataStream, RealtimeMessage } from \"./devices/device.types\";\n\nconst rtcAudioChunkStreamType = \"audio-chunk\";\n\nexport class AudioPlayer {\n private muted: boolean = false;\n\n public async play() {\n if (this.audioContext?.state === \"suspended\") {\n await this.audioContext?.resume();\n }\n this.muted = false;\n }\n\n public async pause() {\n await this.audioContext.suspend();\n this.muted = true;\n }\n\n private hasReceivedData: boolean = false;\n private audioContext: AudioContext;\n private chunks: Array<AudioBufferSourceNode> = [];\n private isPlaying: boolean = false;\n private startTime: number = 0;\n private lastChunkOffset: number = 0;\n private bufferSize: number = 3;\n\n public constructor(\n private device: Device,\n private stream: RealtimeDataStream\n ) {\n this.device.startListeningToRealtimeDataStream(stream);\n this.device.addRealtimeListener((_peerId: string, msg: RealtimeMessage) => {\n this.receive(msg);\n });\n\n if (browser() === \"Safari\" || browser() === \"IE\") {\n this.changeAudioWireFormat(\"wav\");\n } else {\n this.changeAudioWireFormat(\"opus\");\n }\n\n const AudioContext =\n window.AudioContext || (window as any).webkitAudioContext;\n\n this.audioContext = new AudioContext();\n }\n\n public destroy() {\n this.device.stopListeningToRealtimeDataStream(this.stream);\n }\n\n public receive = async (msg: IRtcStreamMessage) => {\n const data = msg.payload.audioChunk?.chunk_data;\n if (!data) {\n return;\n }\n\n if (!this.hasReceivedData) {\n this.hasReceivedData = true;\n }\n\n const { audioContext, muted } = this;\n if (\n !audioContext ||\n msg.header.stream.streamType !== rtcAudioChunkStreamType ||\n muted !== false\n ) {\n return;\n }\n const arrayBuffer = stringToArrayBuffer(data);\n try {\n await audioContext.decodeAudioData(\n arrayBuffer.buffer,\n this.scheduleChunk\n );\n } catch (error) {\n console.warn(\n \"Error decoding audio buffer, changing audioWireFormat on agent\",\n { error }\n );\n this.changeAudioWireFormat(\"wav\");\n }\n };\n\n private scheduleChunk = (buffer: AudioBuffer) => {\n const { audioContext } = this;\n\n if (!audioContext) {\n return;\n }\n if (this.chunks.length > this.bufferSize || this.isPlaying === false) {\n this.chunks.forEach((c) => {\n c.stop();\n });\n this.isPlaying = false;\n this.chunks = [];\n }\n const chunk = this.createChunk(buffer);\n if (!chunk) {\n return;\n }\n if (!chunk.buffer) {\n return;\n }\n if (this.isPlaying === false) {\n this.startTime = audioContext.currentTime;\n this.lastChunkOffset = 0;\n this.isPlaying = true;\n }\n chunk.start(this.startTime + this.lastChunkOffset, 0, buffer.duration);\n this.lastChunkOffset += chunk.buffer.duration;\n this.chunks.push(chunk);\n };\n\n private createChunk(buffer: AudioBuffer) {\n const { audioContext } = this;\n if (!audioContext) {\n return;\n }\n const source = audioContext.createBufferSource();\n source.buffer = buffer;\n source.connect(audioContext.destination);\n source.loop = false;\n source.onended = (_: Event) => {\n this.chunks.splice(this.chunks.indexOf(source), 1);\n if (this.chunks.length === 0) {\n this.isPlaying = false;\n }\n };\n\n return source;\n }\n\n private changeAudioWireFormat(newFormat: \"wav\" | \"opus\") {\n const { stream } = this;\n fork(\n (async () => {\n await this.device.changeStreamAudioType(stream.name, newFormat);\n })()\n );\n }\n}\n","import { FORMANT_API_URL } from \"./config\";\nimport { Authentication } from \"./Authentication\";\nimport { IAccount } from \"./model/IAccount\";\nimport { IAccountTree } from \"./model/IAccountTree\";\n\nexport class Account {\n static async listAccounts(): Promise<IAccount[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/accounts`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const accounts = await data.json();\n return accounts.items;\n }\n\n static async createAccounts(account: IAccount): Promise<IAccount> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/accounts`, {\n method: \"POST\",\n body: JSON.stringify(account),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async getAccount(id: string): Promise<IAccount> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/accounts/${id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async patchAccount(\n id: string,\n account: Partial<Account>\n ): Promise<IAccount> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/accounts/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify(account),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n static async deleteAccount(id: string): Promise<void> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n await fetch(`${FORMANT_API_URL}/v1/admin/accounts/${id}`, {\n method: \"DELETE\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n }\n\n static async getAccountTree(id: string): Promise<IAccountTree> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(\n `${FORMANT_API_URL}/v1/admin/accounts/${id}/tree`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n }\n );\n return await data.json();\n }\n}\n","import { FORMANT_API_URL } from \"./config\";\nimport { Authentication } from \"./Authentication\";\nimport { IRole } from \"./model/IRole\";\n\nexport class Role {\n static async listRoles(): Promise<IRole[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/roles`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const roles = await data.json();\n return roles.items;\n }\n\n static async createRole(role: IRole): Promise<IRole> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/roles`, {\n method: \"POST\",\n body: JSON.stringify(role),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async getRole(id: string): Promise<IRole> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/roles/${id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async patchRole(id: string, role: Partial<IRole>): Promise<IRole> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/roles/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify(role),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async deleteRole(id: string): Promise<void> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n await fetch(`${FORMANT_API_URL}/v1/admin/roles/${id}`, {\n method: \"DELETE\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n }\n}\n","import { FORMANT_API_URL } from \"./config\";\nimport { Authentication } from \"./Authentication\";\nimport { IUser } from \"./model/IUser\";\n\nexport class User {\n static async listUsers(): Promise<IUser[]> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/users`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n const users = await data.json();\n return users.items;\n }\n\n static async createUser(user: IUser): Promise<IUser> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/users`, {\n method: \"POST\",\n body: JSON.stringify(user),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async getUser(id: string): Promise<IUser> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/users/${id}`, {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async patchUser(id: string, user: Partial<IUser>): Promise<IUser> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n const data = await fetch(`${FORMANT_API_URL}/v1/admin/users/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify(user),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n return await data.json();\n }\n\n static async deleteUser(id: string): Promise<void> {\n if (!Authentication.token) {\n throw new Error(\"Not authenticated\");\n }\n await fetch(`${FORMANT_API_URL}/v1/admin/users/${id}`, {\n method: \"PATCH\",\n body: JSON.stringify({ enabled: false, roleId: null, teamId: null }),\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + Authentication.token,\n },\n });\n }\n}\n","export const accessLevels = [\"viewer\", \"operator\", \"administrator\"] as const;\n","import { accessLevels } from \"./accessLevels\";\n\nexport type AccessLevel = (typeof accessLevels)[number];\n\nexport const viewer = \"viewer\" as AccessLevel;\nexport const operator = \"operator\" as AccessLevel;\nexport const administrator = \"administrator\" as AccessLevel;\n","import { AggregateLevel } from \"./AggregateLevel\";\n\nexport const aggregateLevels: AggregateLevel[] = [\n \"year\",\n \"month\",\n \"week\",\n \"day\",\n \"hour\",\n \"minute\",\n];\n","export const annotationTypes = [\"tag\", \"sheet\", \"user\"];\n","export const eventTypes = [\n \"triggered-event\",\n \"intervention-request\",\n \"teleop-session-record\",\n \"port-forwarding-session-record\",\n \"command-request\",\n \"command-response\",\n \"command-delivery\",\n \"custom\",\n \"comment\",\n \"system\",\n \"annotation\",\n] as const;\n","export const healthStatuses = [\n \"unknown\",\n \"operational\",\n \"offline\",\n \"error\",\n] as const;\n","// NOTE: Also add an entry in IInterventionTypeMap\n\nexport const interventionTypes = [\"selection\", \"labeling\", \"teleop\"];\n","export const severities = [\"info\", \"warning\", \"error\", \"critical\"] as const;\n","export const videoMimeTypes = [\"video/mp4\"] as const;\n","export const timeout = (s: number) => {\n return new Promise((resolve) => setTimeout(resolve, s * 1000));\n};\n","// Application Initialization\nimport { App } from \"./App\";\nimport { Fleet } from \"./Fleet\";\nimport { Authentication } from \"./Authentication\";\n\ntry {\n const urlParams =\n typeof window !== \"undefined\" && window.location\n ? new URLSearchParams(window.location.search)\n : new URLSearchParams(\"\");\n\n const urlDevice = urlParams.get(\"device\");\n if (urlDevice) {\n Fleet.setDefaultDevice(urlDevice);\n }\n\n const urlAuth = urlParams.get(\"auth\");\n if (urlAuth) {\n Authentication.loginWithToken(urlAuth);\n }\n\n const moduleName = urlParams.get(\"module\");\n if (moduleName) {\n Authentication.listenForRefresh();\n }\n\n if (typeof window !== \"undefined\") {\n App.listenForConnectionEvents();\n }\n} catch (_) {}\n"],"names":["DEFAULT_FORMANT_API_URL","whichFormantApiUrl","global","urlParams","customUrl","FORMANT_API_URL","LoginFailureError","reason","__publicField","LoginChallengedError","challenge","AuthenticationStore","apiUrl","refreshAuthToken","addAccessTokenRefreshListener","email","password","options","advanced","result","auth","authentication","err","_","token","refreshToken","tokenData","decode","userId","_a","data","refreshData","resolve","askForFreshToken","request","response","getCurrentModuleContext","sendAppMessage","message","moduleName","handler","listener","event","msg","Authentication","getModuleConfiguration","id","disableAnalyticsBottomBar","goToDevice","deviceId","goToTime","date","requestModuleData","sendChannelData","channel","setModuleDateTimeRange","beforeInMilliseconds","afterInMilliseconds","setupModuleMenus","menus","showMessage","addChannelDataListener","addMenuListener","addModuleConfigurationListener","addModuleDataListener","addOverviewDeviceListener","millisecond","second","minute","hour","day","week","month","year","duration","filterDataByType","datas","type","filterDataByTime","start","end","startTime","endTime","timestamp","points","StoreCache","capacity","timeout","key","generator","cacheKey","entry","metadata","value","oldestKey","oldestEntry","thisKey","promise","existingMetadata","queryTelemetry","query","QueryStore","filter","name","latestOnly","q","startOfMinute","addMinutes","roundToNearestMinutes","isLive","addSeconds","error","queryStore","addStreamListener","streamNames","streamTypes","getDate","time","minTime","maxTime","prompt","schema","promptId","_App","configurationId","e","deadlineMs","done","reject","deadline","aborted","delay","ms","loop","App","defined","errorMessage","SessionTypes","SessionTypeConstants","singleton","RtcClientPool","peerId","it","createClient","ttlMs","target","prop","receiver","onReceive","proxy","client","instance","getToken","EnumRtcClientPools","receiveFn","RtcClient","SignalingPromiseClient","AppRtcClientPools","defaultRtcClientPool","getRtcClientPool","sessionType","CaptureStream","captureSession","authInfo","isRtcPeer","peer","DataChannel","dataChannel","m","d","s","l","a","i","Manipulator","device","config","_peerId","RequestDataChannel","channel_name","BinaryRequestDataChannel","requestIdToResponseMap","binaryId","success","payload","TextRequestDataChannel","BaseDevice","EventEmitter","cancelled","document","manipulators","streams","_b","_c","channelName","stream","devicePeer","streamName","newFormat","rtcConfig","p","encoder","serializeHash","jsonValue","encodedValue","compressedValue","deflate","fromByteArray","getViews","createShareLink","share","view","selectedView","origin","code","vailableAggregationIntervals","aggregateFunctions","getVariance","getStandardDeviation","getMax","getMin","getAverage","getSum","getCount","aggregateFunctionMap","aggregateByDateFunctions","dateFns","formatTimeFrameText","queryEvents","eventsCounter","eventTypes","timeFrame","range","dateFunctions","dateOffset","activePointInTimeLine","startDate","endDate","events","getAnnotationCount","tagKey","prev","current","getAnnotationCountByIntervals","aggregate","intervals","annotationsQuery","idx","responses","getTelemetry","deviceIdOrDeviceIds","streamNameOrStreamNames","tags","deviceIds","getRealtimeSessions","rtcClient","getPeers","createDevice","patchDevice","getDevicesData","queryDevicesData","disableDevice","Device","organizationId","version","fileId","maxConnectRetries","deadlinePromise","establishConnection","remoteDevicePeerId","sessionId","retries","shutdownErr","dataChannelClosed","connection","throwNotStartedError","peers","sessions","command","parameter","disabledList","onDemandList","interventionType","interventionRequest","interventionId","PeerDevice","peerUrl","telemetry","latestValue","previousBytesReceived","xhr","currentBytesReceived","newBytesReceived","jsonObject","parsedObject","datapoint","addDeviceToFleet","fleetId","aggregateTelemetry","deleteFleet","getAnalyticStreams","getAnalyticsModules","getAnalyticsRows","queryDevices","getCurrentGroup","groupId","tagValue","getDevice","getDevices","devices","getEvent","uuid","getFileUrl","getFleet","getFleetDevices","getInterventions","getLatestTelemetry","ids","getOnlineDevices","onlineIds","getRealtimeDevices","getStreams","getTaskReportRows","getTaskReportTables","listFleets","patchFleet","role","patchStream","patchView","queryAnalytics","createFleet","fleet","getAllEventTriggerGroup","getEventTriggerGroup","patchEventTriggerGroup","eventTrigger","_Fleet","context","url","Fleet","KeyValue","keyValue","keyValueList","keys","stringToArrayBuffer","input","browser","userAgent","rtcAudioChunkStreamType","AudioPlayer","audioContext","muted","arrayBuffer","buffer","c","chunk","AudioContext","source","Account","account","Role","User","user","accessLevels","viewer","operator","administrator","aggregateLevels","annotationTypes","healthStatuses","interventionTypes","severities","videoMimeTypes","urlDevice","urlAuth"],"mappings":"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"}
|