sip-connector 16.2.0 → 18.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -45
- package/dist/@SipConnector-CFYT0HQB.cjs +1 -0
- package/dist/{@SipConnector-D1YBDd7g.js → @SipConnector-UTHCoMXw.js} +880 -800
- package/dist/ApiManager/__tests-utils__/helpers.d.ts +2 -4
- package/dist/ApiManager/constants.d.ts +1 -2
- package/dist/ApiManager/eventNames.d.ts +1 -2
- package/dist/ApiManager/index.d.ts +1 -0
- package/dist/CallManager/@CallManager.d.ts +7 -6
- package/dist/CallManager/AbstractCallStrategy.d.ts +5 -1
- package/dist/CallManager/MCUCallStrategy.d.ts +1 -0
- package/dist/CallManager/eventNames.d.ts +42 -2
- package/dist/CallManager/index.d.ts +2 -1
- package/dist/CallManager/types.d.ts +5 -4
- package/dist/PresentationManager/types.d.ts +1 -1
- package/dist/SipConnector/@SipConnector.d.ts +4 -1
- package/dist/SipConnector/eventNames.d.ts +1 -1
- package/dist/SipConnectorFacade/index.d.ts +1 -1
- package/dist/StatsPeerConnection/index.d.ts +1 -1
- package/dist/TransceiverManager/@TransceiverManager.d.ts +70 -0
- package/dist/TransceiverManager/index.d.ts +1 -0
- package/dist/TransceiverManager/types.d.ts +11 -0
- package/dist/VideoSendingBalancer/index.d.ts +1 -1
- package/dist/__fixtures__/RTCPeerConnectionMock.d.ts +2 -1
- package/dist/__fixtures__/RTCRtpTransceiverMock.d.ts +16 -0
- package/dist/__fixtures__/eventNames.d.ts +1 -1
- package/dist/doMock.cjs +1 -1
- package/dist/doMock.js +166 -143
- package/dist/index.cjs +1 -1
- package/dist/index.js +83 -83
- package/package.json +12 -12
- package/dist/@SipConnector-B5FFHZzJ.cjs +0 -1
- /package/dist/SipConnectorFacade/{SipConnectorFacade.d.ts → @SipConnectorFacade.d.ts} +0 -0
- /package/dist/StatsPeerConnection/{StatsPeerConnection.d.ts → @StatsPeerConnection.d.ts} +0 -0
- /package/dist/VideoSendingBalancer/{VideoSendingBalancer.d.ts → @VideoSendingBalancer.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -9,16 +9,20 @@
|
|
|
9
9
|
|
|
10
10
|
**sip-connector** — это TypeScript SDK для интеграции WebRTC-приложений с платформой Vinteo через SIP-протокол. Библиотека построена на базе `@krivega/jssip` и предоставляет высокоуровневый API для создания полнофункциональных видеоконференций.
|
|
11
11
|
|
|
12
|
-
###
|
|
13
|
-
|
|
14
|
-
**Важные изменения, требующие обновления кода:**
|
|
12
|
+
### 🎯 Основные возможности
|
|
15
13
|
|
|
16
|
-
|
|
17
|
-
- **Удален параметр `simulcastEncodings`**: Вместо него используется `sendEncodings` для настройки кодировок
|
|
18
|
-
- **Автоматический запуск балансировки**: VideoSendingBalancer теперь автоматически запускается через 10 секунд после начала звонка
|
|
19
|
-
- **Новые события балансировки**: Добавлены события `video-balancer:*` для мониторинга состояния балансировки
|
|
14
|
+
SDK предоставляет комплексное решение для:
|
|
20
15
|
|
|
21
|
-
|
|
16
|
+
| Категория | Возможности |
|
|
17
|
+
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
|
18
|
+
| **SIP-подключения** | Регистрация на сервере (SIP REGISTER), управление сессиями |
|
|
19
|
+
| **WebRTC-коммуникации** | Исходящие/входящие звонки (SIP INVITE/200 OK), медиа-потоки, управление transceiver'ами, автоматический перезапуск ICE |
|
|
20
|
+
| **Презентации** | Отправка второго потока (screen sharing, демонстрация экрана) |
|
|
21
|
+
| **Системные сообщения** | DTMF, SIP INFO, синхронизация медиа-состояния |
|
|
22
|
+
| **Событийная архитектура** | Подписка на события платформы в реальном времени |
|
|
23
|
+
| **Мониторинг** | WebRTC-статистика (RTCRtpStats, ICE candidate stats) |
|
|
24
|
+
| **Управление конференциями** | Перемещение участников между ролями (участник/зритель) |
|
|
25
|
+
| **Лицензирование** | Мониторинг использования лицензий и состояния презентаций |
|
|
22
26
|
|
|
23
27
|
- **Адаптивный polling**: Улучшенная система опроса для мониторинга изменений видеотреков
|
|
24
28
|
- **Поддержка maxBitrate в PresentationManager**: Автоматическое управление битрейтом для презентаций
|
|
@@ -26,21 +30,9 @@
|
|
|
26
30
|
- **Обработка смены треков**: Автоматическая адаптация балансировки при изменении видеотреков
|
|
27
31
|
- **Улучшенная статистика**: Расширенные возможности сбора и анализа WebRTC статистики
|
|
28
32
|
- **Автоматический перезапуск ICE**: Обработка событий `restart` от сервера с автоматическим вызовом `restartIce`
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
SDK предоставляет комплексное решение для:
|
|
33
|
-
|
|
34
|
-
| Категория | Возможности |
|
|
35
|
-
| ---------------------------- | ------------------------------------------------------------------------------------------ |
|
|
36
|
-
| **SIP-подключения** | Регистрация на сервере (SIP REGISTER), управление сессиями |
|
|
37
|
-
| **WebRTC-коммуникации** | Исходящие/входящие звонки (SIP INVITE/200 OK), медиа-потоки, автоматический перезапуск ICE |
|
|
38
|
-
| **Презентации** | Отправка второго потока (screen sharing, демонстрация экрана) |
|
|
39
|
-
| **Системные сообщения** | DTMF, SIP INFO, синхронизация медиа-состояния |
|
|
40
|
-
| **Событийная архитектура** | Подписка на события платформы в реальном времени |
|
|
41
|
-
| **Мониторинг** | WebRTC-статистика (RTCRtpStats, ICE candidate stats) |
|
|
42
|
-
| **Управление конференциями** | Перемещение участников между ролями (участник/зритель) |
|
|
43
|
-
| **Лицензирование** | Мониторинг использования лицензий и состояния презентаций |
|
|
33
|
+
- **Управление transceiver'ами**: Новый `TransceiverManager` для отслеживания и управления RTCRtpTransceiver'ами
|
|
34
|
+
- **Автоматическое добавление transceiver'ов**: Умное добавление презентационных transceiver'ов при событиях restart
|
|
35
|
+
|
|
|
44
36
|
|
|
45
37
|
### 🏗️ Архитектура
|
|
46
38
|
|
|
@@ -67,23 +59,6 @@ yarn add sip-connector
|
|
|
67
59
|
pnpm add sip-connector
|
|
68
60
|
```
|
|
69
61
|
|
|
70
|
-
### 📋 Системные требования
|
|
71
|
-
|
|
72
|
-
#### Обязательные зависимости
|
|
73
|
-
|
|
74
|
-
| Компонент | Требование | Описание |
|
|
75
|
-
| ------------------ | -------------------- | ------------------------------ |
|
|
76
|
-
| `@krivega/jssip` | peer dependency | Для SIP-функциональности |
|
|
77
|
-
| WebRTC API | Поддержка в браузере | Стандартные WebRTC возможности |
|
|
78
|
-
| JavaScript runtime | ES2017+ | Современный синтаксис |
|
|
79
|
-
|
|
80
|
-
#### Рекомендуемые зависимости
|
|
81
|
-
|
|
82
|
-
| Компонент | Версия | Назначение |
|
|
83
|
-
| ---------- | ------ | ------------------- |
|
|
84
|
-
| TypeScript | 4.5+ | Полная типизация |
|
|
85
|
-
| Node.js | 16+ | Сборка и разработка |
|
|
86
|
-
|
|
87
62
|
---
|
|
88
63
|
|
|
89
64
|
## 🎯 Быстрый старт
|
|
@@ -398,11 +373,13 @@ try {
|
|
|
398
373
|
|
|
399
374
|
#### Автоматический перезапуск по событию сервера
|
|
400
375
|
|
|
401
|
-
SDK автоматически обрабатывает события `restart` от сервера и инициирует перезапуск ICE
|
|
376
|
+
SDK автоматически обрабатывает события `restart` от сервера и инициирует перезапуск ICE-соединения с интеллектуальным управлением transceiver'ами:
|
|
402
377
|
|
|
403
378
|
```typescript
|
|
404
379
|
// SDK автоматически подписывается на события restart от ApiManager
|
|
405
|
-
// и
|
|
380
|
+
// и выполняет следующие действия:
|
|
381
|
+
// 1. Проверяет необходимость добавления презентационного transceiver'а
|
|
382
|
+
// 2. Вызывает callManager.restartIce()
|
|
406
383
|
|
|
407
384
|
// Мониторинг событий restart (опционально)
|
|
408
385
|
sipConnector.on('api:restart', (data) => {
|
|
@@ -412,8 +389,14 @@ sipConnector.on('api:restart', (data) => {
|
|
|
412
389
|
videoTrackCount: data.videoTrackCount,
|
|
413
390
|
});
|
|
414
391
|
|
|
415
|
-
// SDK
|
|
392
|
+
// SDK автоматически:
|
|
393
|
+
// - Добавит презентационный transceiver если videoTrackCount === 2
|
|
394
|
+
// - Вызовет restartIce()
|
|
416
395
|
console.log('ICE будет перезапущен автоматически');
|
|
396
|
+
|
|
397
|
+
if (data.videoTrackCount === 2) {
|
|
398
|
+
console.log('Может быть добавлен презентационный transceiver');
|
|
399
|
+
}
|
|
417
400
|
});
|
|
418
401
|
```
|
|
419
402
|
|
|
@@ -429,6 +412,100 @@ sipConnector.on('api:restart', (data) => {
|
|
|
429
412
|
|
|
430
413
|
---
|
|
431
414
|
|
|
415
|
+
## 🎛️ Управление RTCRtpTransceiver'ами
|
|
416
|
+
|
|
417
|
+
### Обзор TransceiverManager
|
|
418
|
+
|
|
419
|
+
SDK автоматически отслеживает и управляет RTCRtpTransceiver'ами через новый класс `TransceiverManager`:
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
// Получение текущих transceiver'ов
|
|
423
|
+
const transceivers = sipConnector.callManager.getTransceivers();
|
|
424
|
+
|
|
425
|
+
console.log('Основной аудио transceiver:', transceivers.mainAudio);
|
|
426
|
+
console.log('Основной видео transceiver:', transceivers.mainVideo);
|
|
427
|
+
console.log('Презентационный видео transceiver:', transceivers.presentationVideo);
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Типы transceiver'ов
|
|
431
|
+
|
|
432
|
+
SDK автоматически классифицирует transceiver'ы по их `mid` значению:
|
|
433
|
+
|
|
434
|
+
| Тип transceiver'а | mid | Назначение |
|
|
435
|
+
| ------------------- | --- | --------------------------- |
|
|
436
|
+
| `mainAudio` | '0' | Основной аудио поток |
|
|
437
|
+
| `mainVideo` | '1' | Основной видео поток |
|
|
438
|
+
| `presentationVideo` | '2' | Презентационный видео поток |
|
|
439
|
+
|
|
440
|
+
### Автоматическое добавление transceiver'ов
|
|
441
|
+
|
|
442
|
+
При получении события `restart` с `videoTrackCount === 2`, SDK автоматически добавляет презентационный transceiver если он отсутствует:
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// SDK автоматически обрабатывает события restart
|
|
446
|
+
sipConnector.on('api:restart', (data) => {
|
|
447
|
+
if (data.videoTrackCount === 2) {
|
|
448
|
+
// SDK проверит наличие presentationVideo transceiver'а
|
|
449
|
+
// и добавит его автоматически если необходимо
|
|
450
|
+
console.log('Будет добавлен презентационный transceiver');
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Ручное управление transceiver'ами
|
|
456
|
+
|
|
457
|
+
```typescript
|
|
458
|
+
// Добавление нового transceiver'а
|
|
459
|
+
try {
|
|
460
|
+
const audioTransceiver = await sipConnector.callManager.addTransceiver('audio', {
|
|
461
|
+
direction: 'sendrecv',
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
const videoTransceiver = await sipConnector.callManager.addTransceiver('video', {
|
|
465
|
+
direction: 'sendonly',
|
|
466
|
+
sendEncodings: [
|
|
467
|
+
{ rid: 'low', maxBitrate: 500_000, scaleResolutionDownBy: 4 },
|
|
468
|
+
{ rid: 'high', maxBitrate: 2_000_000, scaleResolutionDownBy: 1 },
|
|
469
|
+
],
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
console.log('Transceiver'ы добавлены:', { audioTransceiver, videoTransceiver });
|
|
473
|
+
} catch (error) {
|
|
474
|
+
console.error('Ошибка добавления transceiver'а:', error);
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
### Мониторинг transceiver'ов
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
// Проверка состояния transceiver'ов
|
|
482
|
+
const checkTransceivers = () => {
|
|
483
|
+
const transceivers = sipConnector.callManager.getTransceivers();
|
|
484
|
+
|
|
485
|
+
console.log('Статус transceiver'ов:', {
|
|
486
|
+
hasAudio: transceivers.mainAudio !== undefined,
|
|
487
|
+
hasVideo: transceivers.mainVideo !== undefined,
|
|
488
|
+
hasPresentation: transceivers.presentationVideo !== undefined,
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
// Детальная информация
|
|
492
|
+
if (transceivers.mainVideo) {
|
|
493
|
+
console.log('Основное видео:', {
|
|
494
|
+
mid: transceivers.mainVideo.mid,
|
|
495
|
+
direction: transceivers.mainVideo.direction,
|
|
496
|
+
currentDirection: transceivers.mainVideo.currentDirection,
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
|
|
501
|
+
// Проверка после установки соединения
|
|
502
|
+
sipConnector.on('call:confirmed', () => {
|
|
503
|
+
checkTransceivers();
|
|
504
|
+
});
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
432
509
|
## 📡 События и их обработка
|
|
433
510
|
|
|
434
511
|
### Архитектура событий
|
|
@@ -494,7 +571,7 @@ const roomData = await sipConnector.wait('api:enterRoom');
|
|
|
494
571
|
console.log('Данные комнаты:', roomData);
|
|
495
572
|
```
|
|
496
573
|
|
|
497
|
-
### События балансировки видео
|
|
574
|
+
### События балансировки видео
|
|
498
575
|
|
|
499
576
|
```typescript
|
|
500
577
|
// Мониторинг автоматической балансировки видео
|
|
@@ -644,7 +721,7 @@ monitor.subscribe(videoSender, () => {
|
|
|
644
721
|
|
|
645
722
|
### Автоматическая балансировка
|
|
646
723
|
|
|
647
|
-
|
|
724
|
+
`VideoSendingBalancer` интегрирован в `SipConnector` и запускается автоматически:
|
|
648
725
|
|
|
649
726
|
```typescript
|
|
650
727
|
const sipConnector = new SipConnector(
|
|
@@ -753,6 +830,7 @@ import {
|
|
|
753
830
|
SipConnector, // Низкоуровневый API
|
|
754
831
|
SipConnectorFacade, // Высокоуровневый фасад
|
|
755
832
|
StatsPeerConnection, // Сбор статистики
|
|
833
|
+
TransceiverManager, // Управление transceiver'ами
|
|
756
834
|
// ... другие экспорты
|
|
757
835
|
} from 'sip-connector';
|
|
758
836
|
```
|
|
@@ -769,6 +847,10 @@ await facade.replaceMediaStream(mediaStream, options);
|
|
|
769
847
|
// Получение удаленных потоков
|
|
770
848
|
const streams = facade.getRemoteStreams();
|
|
771
849
|
|
|
850
|
+
// Управление transceiver'ами (низкоуровневый API)
|
|
851
|
+
const transceivers = sipConnector.callManager.getTransceivers();
|
|
852
|
+
await sipConnector.callManager.addTransceiver('video', { direction: 'sendrecv' });
|
|
853
|
+
|
|
772
854
|
// Перезапуск ICE-соединения (низкоуровневый API)
|
|
773
855
|
await sipConnector.callManager.restartIce(options);
|
|
774
856
|
```
|
|
@@ -791,6 +873,7 @@ import {
|
|
|
791
873
|
type TInboundStats, // Входящая статистика
|
|
792
874
|
type TOutboundStats, // Исходящая статистика
|
|
793
875
|
type TRestartData, // Данные события restart
|
|
876
|
+
type ITransceiverStorage, // Интерфейс хранения transceiver'ов
|
|
794
877
|
} from 'sip-connector';
|
|
795
878
|
```
|
|
796
879
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const O=require("events-constructor"),H=require("debug"),x=require("repeated-calls"),j=require("xstate"),Z=require("stack-promises"),me=require("@krivega/cancelable-promise"),ee=require("@krivega/timeout-requester");require("ua-parser-js");require("sequent-promises");const q="sip-connector",E=H(q),Me=()=>{H.enable(q)},pe=()=>{H.enable(`-${q}`)},Pe="Error decline with 603",ve=1006,fe=n=>typeof n=="object"&&n!==null&&"code"in n&&n.code===ve,Oe=n=>n.message===Pe;var h=(n=>(n.CONTENT_TYPE="content-type",n.CONTENT_ENTER_ROOM="x-webrtc-enter-room",n.CONTENT_USE_LICENSE="X-WEBRTC-USE-LICENSE",n.PARTICIPANT_NAME="X-WEBRTC-PARTICIPANT-NAME",n.INPUT_CHANNELS="X-WEBRTC-INPUT-CHANNELS",n.OUTPUT_CHANNELS="X-WEBRTC-OUTPUT-CHANNELS",n.MAIN_CAM="X-WEBRTC-MAINCAM",n.MIC="X-WEBRTC-MIC",n.MEDIA_SYNC="X-WEBRTC-SYNC",n.MAIN_CAM_RESOLUTION="X-WEBRTC-MAINCAM-RESOLUTION",n.MEDIA_STATE="X-WEBRTC-MEDIA-STATE",n.MEDIA_TYPE="X-Vinteo-Media-Type",n.MAIN_CAM_STATE="X-Vinteo-MainCam-State",n.MIC_STATE="X-Vinteo-Mic-State",n.CONTENT_PARTICIPANT_STATE="X-WEBRTC-PARTSTATE",n.NOTIFY="X-VINTEO-NOTIFY",n.CONTENT_ENABLE_MEDIA_DEVICE="X-WEBRTC-REQUEST-ENABLE-MEDIA-DEVICE",n.CONTENT_SHARE_STATE="x-webrtc-share-state",n.MUST_STOP_PRESENTATION_P2P="x-webrtc-share-state: YOUMUSTSTOPSENDCONTENT",n.START_PRESENTATION_P2P="x-webrtc-share-state: YOUCANRECEIVECONTENT",n.STOP_PRESENTATION_P2P="x-webrtc-share-state: CONTENTEND",n.STOP_PRESENTATION="x-webrtc-share-state: STOPPRESENTATION",n.START_PRESENTATION="x-webrtc-share-state: LETMESTARTPRESENTATION",n.ENABLE_MAIN_CAM="X-WEBRTC-REQUEST-ENABLE-MEDIA-DEVICE: LETMESTARTMAINCAM",n.AVAILABLE_INCOMING_BITRATE="X-WEBRTC-AVAILABLE-INCOMING-BITRATE",n.AUDIO_TRACK_COUNT="X-WEBRTC-AUDIO-TRACK-COUNT",n.VIDEO_TRACK_COUNT="X-WEBRTC-VIDEO-TRACK-COUNT",n.TRACKS_DIRECTION="X-WEBRTC-TRACKS-DIRECTION",n))(h||{}),B=(n=>(n.AVAILABLE_SECOND_REMOTE_STREAM="YOUCANRECEIVECONTENT",n.NOT_AVAILABLE_SECOND_REMOTE_STREAM="CONTENTEND",n.MUST_STOP_PRESENTATION="YOUMUSTSTOPSENDCONTENT",n))(B||{}),$=(n=>(n.SPECTATOR="SPECTATOR",n.PARTICIPANT="PARTICIPANT",n))($||{}),v=(n=>(n.ENTER_ROOM="application/vinteo.webrtc.roomname",n.MIC="application/vinteo.webrtc.mic",n.USE_LICENSE="application/vinteo.webrtc.uselic",n.PARTICIPANT_STATE="application/vinteo.webrtc.partstate",n.NOTIFY="application/vinteo.webrtc.notify",n.SHARE_STATE="application/vinteo.webrtc.sharedesktop",n.MAIN_CAM="application/vinteo.webrtc.maincam",n.RESTART="application/vinteo.webrtc.restart",n))(v||{}),M=(n=>(n.CHANNELS="application/vinteo.webrtc.channels",n.MEDIA_STATE="application/vinteo.webrtc.mediastate",n.REFUSAL="application/vinteo.webrtc.refusal",n.SHARE_STATE="application/vinteo.webrtc.sharedesktop",n.MAIN_CAM="application/vinteo.webrtc.maincam",n.STATS="application/vinteo.webrtc.stats",n))(M||{}),P=(n=>(n.PAUSE_MAIN_CAM="PAUSEMAINCAM",n.RESUME_MAIN_CAM="RESUMEMAINCAM",n.MAX_MAIN_CAM_RESOLUTION="MAXMAINCAMRESOLUTION",n.ADMIN_STOP_MAIN_CAM="ADMINSTOPMAINCAM",n.ADMIN_START_MAIN_CAM="ADMINSTARTMAINCAM",n))(P||{}),V=(n=>(n.ADMIN_STOP_MIC="ADMINSTOPMIC",n.ADMIN_START_MIC="ADMINSTARTMIC",n))(V||{}),W=(n=>(n.ADMIN_SYNC_FORCED="1",n.ADMIN_SYNC_NOT_FORCED="0",n))(W||{}),te=(n=>(n.AUDIO="AUDIO",n.VIDEO="VIDEO",n.AUDIOPLUSPRESENTATION="AUDIOPLUSPRESENTATION",n))(te||{}),g=(n=>(n.CHANNELS_NOTIFY="channels:notify",n.PARTICIPANT_ADDED_TO_LIST_MODERATORS="participant:added-to-list-moderators",n.PARTICIPANT_REMOVED_FROM_LIST_MODERATORS="participant:removed-from-list-moderators",n.PARTICIPANT_MOVE_REQUEST_TO_STREAM="participant:move-request-to-stream",n.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS="participant:move-request-to-spectators",n.PARTICIPANT_MOVE_REQUEST_TO_PARTICIPANTS="participant:move-request-to-participants",n.PARTICIPATION_ACCEPTING_WORD_REQUEST="participation:accepting-word-request",n.PARTICIPATION_CANCELLING_WORD_REQUEST="participation:cancelling-word-request",n.WEBCAST_STARTED="webcast:started",n.WEBCAST_STOPPED="webcast:stopped",n.ACCOUNT_CHANGED="account:changed",n.ACCOUNT_DELETED="account:deleted",n.CONFERENCE_PARTICIPANT_TOKEN_ISSUED="conference:participant-token-issued",n.CHANNELS="channels",n.ENTER_ROOM="enterRoom",n.SHARE_STATE="shareState",n.MAIN_CAM_CONTROL="main-cam-control",n.USE_LICENSE="useLicense",n.ADMIN_START_MAIN_CAM="admin-start-main-cam",n.ADMIN_STOP_MAIN_CAM="admin-stop-main-cam",n.ADMIN_START_MIC="admin-start-mic",n.ADMIN_STOP_MIC="admin-stop-mic",n.ADMIN_FORCE_SYNC_MEDIA_STATE="admin-force-sync-media-state",n.AVAILABLE_SECOND_REMOTE_STREAM="availableSecondRemoteStream",n.NOT_AVAILABLE_SECOND_REMOTE_STREAM="notAvailableSecondRemoteStream",n.MUST_STOP_PRESENTATION="mustStopPresentation",n.NEW_DTMF="newDTMF",n.RESTART="restart",n))(g||{});const ne=["participation:accepting-word-request","participation:cancelling-word-request","participant:move-request-to-stream","channels:notify","conference:participant-token-issued","account:changed","account:deleted","webcast:started","webcast:stopped","participant:added-to-list-moderators","participant:removed-from-list-moderators","participant:move-request-to-spectators","participant:move-request-to-participants","channels","enterRoom","shareState","main-cam-control","useLicense","admin-start-main-cam","admin-stop-main-cam","admin-start-mic","admin-stop-mic","admin-force-sync-media-state","availableSecondRemoteStream","notAvailableSecondRemoteStream","mustStopPresentation","newDTMF","restart"];var _=(n=>(n.CHANNELS="channels",n.WEBCAST_STARTED="WebcastStarted",n.WEBCAST_STOPPED="WebcastStopped",n.ACCOUNT_CHANGED="accountChanged",n.ACCOUNT_DELETED="accountDeleted",n.ADDED_TO_LIST_MODERATORS="addedToListModerators",n.REMOVED_FROM_LIST_MODERATORS="removedFromListModerators",n.ACCEPTING_WORD_REQUEST="ParticipationRequestAccepted",n.CANCELLING_WORD_REQUEST="ParticipationRequestRejected",n.MOVE_REQUEST_TO_STREAM="ParticipantMovedToWebcast",n.CONFERENCE_PARTICIPANT_TOKEN_ISSUED="ConferenceParticipantTokenIssued",n))(_||{});class De{events;connectionManager;callManager;constructor({connectionManager:e,callManager:t}){this.connectionManager=e,this.callManager=t,this.events=new O.Events(ne),this.subscribe()}async waitChannels(){return this.wait(g.CHANNELS)}async waitSyncMediaState(){return this.wait(g.ADMIN_FORCE_SYNC_MEDIA_STATE)}async sendDTMF(e){return new Promise((t,s)=>{let r;try{r=this.getEstablishedRTCSessionProtected()}catch(i){s(i)}r&&(this.callManager.once("newDTMF",({originator:i})=>{i==="local"&&t()}),r.sendDTMF(e,{duration:120,interToneGap:600}))})}async sendChannels({inputChannels:e,outputChannels:t}){const s=this.getEstablishedRTCSessionProtected(),r=`${h.INPUT_CHANNELS}: ${e}`,i=`${h.OUTPUT_CHANNELS}: ${t}`,a=[r,i];return s.sendInfo(M.CHANNELS,void 0,{extraHeaders:a})}async sendMediaState({cam:e,mic:t},s={}){const r=this.getEstablishedRTCSessionProtected(),i=`${h.MEDIA_STATE}: currentstate`,a=`${h.MAIN_CAM_STATE}: ${Number(e)}`,o=`${h.MIC_STATE}: ${Number(t)}`,c=[i,a,o];return r.sendInfo(M.MEDIA_STATE,void 0,{noTerminateWhenError:!0,...s,extraHeaders:c})}async sendStats({availableIncomingBitrate:e}){const t=this.getEstablishedRTCSessionProtected(),r=[`${h.AVAILABLE_INCOMING_BITRATE}: ${e}`];return t.sendInfo(M.STATS,void 0,{noTerminateWhenError:!0,extraHeaders:r})}async sendRefusalToTurnOn(e,t={}){const s=this.getEstablishedRTCSessionProtected(),a=e==="mic"?0:1,c=[`${h.MEDIA_TYPE}: ${a}`];return s.sendInfo(M.REFUSAL,void 0,{noTerminateWhenError:!0,...t,extraHeaders:c})}async sendRefusalToTurnOnMic(e={}){return this.sendRefusalToTurnOn("mic",{noTerminateWhenError:!0,...e})}async sendRefusalToTurnOnCam(e={}){return this.sendRefusalToTurnOn("cam",{noTerminateWhenError:!0,...e})}async sendMustStopPresentationP2P(){await this.getEstablishedRTCSessionProtected().sendInfo(M.SHARE_STATE,void 0,{extraHeaders:[h.MUST_STOP_PRESENTATION_P2P]})}async sendStoppedPresentationP2P(){await this.getEstablishedRTCSessionProtected().sendInfo(M.SHARE_STATE,void 0,{extraHeaders:[h.STOP_PRESENTATION_P2P]})}async sendStoppedPresentation(){await this.getEstablishedRTCSessionProtected().sendInfo(M.SHARE_STATE,void 0,{extraHeaders:[h.STOP_PRESENTATION]})}async askPermissionToStartPresentationP2P(){await this.getEstablishedRTCSessionProtected().sendInfo(M.SHARE_STATE,void 0,{extraHeaders:[h.START_PRESENTATION_P2P]})}async askPermissionToStartPresentation(){await this.getEstablishedRTCSessionProtected().sendInfo(M.SHARE_STATE,void 0,{extraHeaders:[h.START_PRESENTATION]})}async askPermissionToEnableCam(e={}){const t=this.getEstablishedRTCSessionProtected(),s=[h.ENABLE_MAIN_CAM];return t.sendInfo(M.MAIN_CAM,void 0,{noTerminateWhenError:!0,...e,extraHeaders:s}).catch(r=>{if(Oe(r))throw r})}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}getEstablishedRTCSessionProtected=()=>{const e=this.callManager.getEstablishedRTCSession();if(!e)throw new Error("No rtcSession established");return e};subscribe(){this.connectionManager.on("sipEvent",this.handleSipEvent),this.callManager.on("newInfo",this.handleNewInfo),this.callManager.on("newDTMF",e=>{this.events.trigger("newDTMF",e)})}handleSipEvent=({request:e})=>{this.maybeHandleNotify(e)};maybeHandleNotify=e=>{try{const t=e.getHeader(h.NOTIFY);if(t){const s=JSON.parse(t);this.handleNotify(s)}}catch(t){E("error parse notify",t)}};handleNotify=e=>{switch(e.cmd){case _.CHANNELS:{const t=e;this.triggerChannelsNotify(t);break}case _.WEBCAST_STARTED:{const t=e;this.triggerWebcastStartedNotify(t);break}case _.WEBCAST_STOPPED:{const t=e;this.triggerWebcastStoppedNotify(t);break}case _.ADDED_TO_LIST_MODERATORS:{const t=e;this.triggerAddedToListModeratorsNotify(t);break}case _.REMOVED_FROM_LIST_MODERATORS:{const t=e;this.triggerRemovedFromListModeratorsNotify(t);break}case _.ACCEPTING_WORD_REQUEST:{const t=e;this.triggerParticipationAcceptingWordRequest(t);break}case _.CANCELLING_WORD_REQUEST:{const t=e;this.triggerParticipationCancellingWordRequest(t);break}case _.MOVE_REQUEST_TO_STREAM:{const t=e;this.triggerParticipantMoveRequestToStream(t);break}case _.ACCOUNT_CHANGED:{this.triggerAccountChangedNotify();break}case _.ACCOUNT_DELETED:{this.triggerAccountDeletedNotify();break}case _.CONFERENCE_PARTICIPANT_TOKEN_ISSUED:{const t=e;this.triggerConferenceParticipantTokenIssued(t);break}default:E("unknown cmd",e)}};handleNewInfo=e=>{const{originator:t}=e;if(t!=="remote")return;const{request:s}=e,r=s,i=r.getHeader(h.CONTENT_TYPE);if(i!==void 0)switch(i){case v.ENTER_ROOM:{this.triggerEnterRoom(r),this.maybeTriggerChannels(r);break}case v.NOTIFY:{this.maybeHandleNotify(r);break}case v.SHARE_STATE:{this.triggerShareState(r);break}case v.MAIN_CAM:{this.triggerMainCamControl(r);break}case v.MIC:{this.triggerMicControl(r);break}case v.USE_LICENSE:{this.triggerUseLicense(r);break}case v.PARTICIPANT_STATE:{this.maybeTriggerParticipantMoveRequest(r);break}case v.RESTART:{this.triggerRestart(r);break}}};triggerChannelsNotify=e=>{const t=e.input,s=e.output,r={inputChannels:t,outputChannels:s};this.events.trigger(g.CHANNELS_NOTIFY,r)};triggerWebcastStartedNotify=({body:{conference:e,type:t}})=>{const s={conference:e,type:t};this.events.trigger(g.WEBCAST_STARTED,s)};triggerWebcastStoppedNotify=({body:{conference:e,type:t}})=>{const s={conference:e,type:t};this.events.trigger(g.WEBCAST_STOPPED,s)};triggerAddedToListModeratorsNotify=({conference:e})=>{const t={conference:e};this.events.trigger(g.PARTICIPANT_ADDED_TO_LIST_MODERATORS,t)};triggerRemovedFromListModeratorsNotify=({conference:e})=>{const t={conference:e};this.events.trigger(g.PARTICIPANT_REMOVED_FROM_LIST_MODERATORS,t)};triggerParticipationAcceptingWordRequest=({body:{conference:e}})=>{const t={conference:e};this.events.trigger(g.PARTICIPATION_ACCEPTING_WORD_REQUEST,t)};triggerParticipationCancellingWordRequest=({body:{conference:e}})=>{const t={conference:e};this.events.trigger(g.PARTICIPATION_CANCELLING_WORD_REQUEST,t)};triggerParticipantMoveRequestToStream=({body:{conference:e}})=>{const t={conference:e};this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_STREAM,t)};triggerAccountChangedNotify=()=>{this.events.trigger(g.ACCOUNT_CHANGED,void 0)};triggerAccountDeletedNotify=()=>{this.events.trigger(g.ACCOUNT_DELETED,void 0)};triggerConferenceParticipantTokenIssued=({body:{conference:e,participant:t,jwt:s}})=>{const r={conference:e,participant:t,jwt:s};this.events.trigger(g.CONFERENCE_PARTICIPANT_TOKEN_ISSUED,r)};maybeTriggerChannels=e=>{const t=e.getHeader(h.INPUT_CHANNELS),s=e.getHeader(h.OUTPUT_CHANNELS);if(t&&s){const r={inputChannels:t,outputChannels:s};this.events.trigger(g.CHANNELS,r)}};triggerEnterRoom=e=>{const t=e.getHeader(h.CONTENT_ENTER_ROOM),s=e.getHeader(h.PARTICIPANT_NAME);this.events.trigger(g.ENTER_ROOM,{room:t,participantName:s})};triggerShareState=e=>{const t=e.getHeader(h.CONTENT_SHARE_STATE);if(t!==void 0)switch(t){case B.AVAILABLE_SECOND_REMOTE_STREAM:{this.events.trigger(g.AVAILABLE_SECOND_REMOTE_STREAM,void 0);break}case B.NOT_AVAILABLE_SECOND_REMOTE_STREAM:{this.events.trigger(g.NOT_AVAILABLE_SECOND_REMOTE_STREAM,void 0);break}case B.MUST_STOP_PRESENTATION:{this.events.trigger(g.MUST_STOP_PRESENTATION,void 0);break}}};maybeTriggerParticipantMoveRequest=e=>{const t=e.getHeader(h.CONTENT_PARTICIPANT_STATE);t===$.SPECTATOR&&this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_SPECTATORS,void 0),t===$.PARTICIPANT&&this.events.trigger(g.PARTICIPANT_MOVE_REQUEST_TO_PARTICIPANTS,void 0)};triggerMainCamControl=e=>{const t=e.getHeader(h.MAIN_CAM),s=e.getHeader(h.MEDIA_SYNC),r=s===W.ADMIN_SYNC_FORCED;if(t===P.ADMIN_START_MAIN_CAM){this.events.trigger(g.ADMIN_START_MAIN_CAM,{isSyncForced:r});return}if(t===P.ADMIN_STOP_MAIN_CAM){this.events.trigger(g.ADMIN_STOP_MAIN_CAM,{isSyncForced:r});return}(t===P.RESUME_MAIN_CAM||t===P.PAUSE_MAIN_CAM)&&s!==void 0&&this.events.trigger(g.ADMIN_FORCE_SYNC_MEDIA_STATE,{isSyncForced:r});const i=e.getHeader(h.MAIN_CAM_RESOLUTION);this.events.trigger(g.MAIN_CAM_CONTROL,{mainCam:t,resolutionMainCam:i})};triggerMicControl=e=>{const t=e.getHeader(h.MIC),r=e.getHeader(h.MEDIA_SYNC)===W.ADMIN_SYNC_FORCED;t===V.ADMIN_START_MIC?this.events.trigger(g.ADMIN_START_MIC,{isSyncForced:r}):t===V.ADMIN_STOP_MIC&&this.events.trigger(g.ADMIN_STOP_MIC,{isSyncForced:r})};triggerUseLicense=e=>{const t=e.getHeader(h.CONTENT_USE_LICENSE);this.events.trigger(g.USE_LICENSE,t)};triggerRestart=e=>{const t=e.getHeader(h.TRACKS_DIRECTION),s=Number(e.getHeader(h.AUDIO_TRACK_COUNT)),r=Number(e.getHeader(h.VIDEO_TRACK_COUNT)),i={tracksDirection:t,audioTrackCount:s,videoTrackCount:r};this.events.trigger(g.RESTART,i)}}var N=(n=>(n.PEER_CONNECTION="peerconnection",n.CONNECTING="connecting",n.SENDING="sending",n.PROGRESS="progress",n.ACCEPTED="accepted",n.CONFIRMED="confirmed",n.ENDED="ended",n.FAILED="failed",n.NEW_DTMF="newDTMF",n.NEW_INFO="newInfo",n.HOLD="hold",n.UNHOLD="unhold",n.MUTED="muted",n.UNMUTED="unmuted",n.REINVITE="reinvite",n.UPDATE="update",n.REFER="refer",n.REPLACES="replaces",n.SDP="sdp",n.ICE_CANDIDATE="icecandidate",n.GET_USER_MEDIA_FAILED="getusermediafailed",n.PEER_CONNECTION_CREATE_OFFER_FAILED="peerconnection:createofferfailed",n.PEER_CONNECTION_CREATE_ANSWER_FAILED="peerconnection:createanswerfailed",n.PEER_CONNECTION_SET_LOCAL_DESCRIPTION_FAILED="peerconnection:setlocaldescriptionfailed",n.PEER_CONNECTION_SET_REMOTE_DESCRIPTION_FAILED="peerconnection:setremotedescriptionfailed",n.START_PRESENTATION="presentation:start",n.STARTED_PRESENTATION="presentation:started",n.END_PRESENTATION="presentation:end",n.ENDED_PRESENTATION="presentation:ended",n.FAILED_PRESENTATION="presentation:failed",n.PEER_CONNECTION_CONFIRMED="peerconnection:confirmed",n.PEER_CONNECTION_ONTRACK="peerconnection:ontrack",n.ENDED_FROM_SERVER="ended:fromserver",n))(N||{}),se=(n=>(n.LOCAL="local",n.REMOTE="remote",n.SYSTEM="system",n))(se||{});const re=["peerconnection","connecting","sending","progress","accepted","confirmed","ended","failed","newInfo","newDTMF","presentation:start","presentation:started","presentation:end","presentation:ended","presentation:failed","reinvite","update","refer","replaces","sdp","icecandidate","getusermediafailed","peerconnection:createofferfailed","peerconnection:createanswerfailed","peerconnection:setlocaldescriptionfailed","peerconnection:setremotedescriptionfailed"],ye=["peerconnection:confirmed","peerconnection:ontrack","ended:fromserver"],ie=[...re,...ye],be=(n,e)=>{n.getVideoTracks().forEach(s=>{"contentHint"in s&&s.contentHint!==e&&(s.contentHint=e)})},U=(n,{directionVideo:e,directionAudio:t,contentHint:s}={})=>{if(!n||e==="recvonly"&&t==="recvonly")return;const r=t==="recvonly"?[]:n.getAudioTracks(),i=e==="recvonly"?[]:n.getVideoTracks(),a=[...r,...i],o=new MediaStream(a);return o.getTracks=()=>[...o.getAudioTracks(),...o.getVideoTracks()],s&&s!=="none"&&be(o,s),o};function we(n){return e=>`sip:${e}@${n}`}const Ue=(n,e)=>()=>Math.floor(Math.random()*(e-n))+n,ae=n=>n.trim().replaceAll(" ","_"),Le=Ue(1e5,99999999),Be=n=>n.some(t=>{const{kind:s}=t;return s==="video"});class ke{isPendingCall=!1;isPendingAnswer=!1;rtcSession;remoteStreams={};events;callConfiguration={};constructor(e){this.events=e}}var G=(n=>(n.BYE="Terminated",n.WEBRTC_ERROR="WebRTC Error",n.CANCELED="Canceled",n.REQUEST_TIMEOUT="Request Timeout",n.REJECTED="Rejected",n.REDIRECTED="Redirected",n.UNAVAILABLE="Unavailable",n.NOT_FOUND="Not Found",n.ADDRESS_INCOMPLETE="Address Incomplete",n.INCOMPATIBLE_SDP="Incompatible SDP",n.BAD_MEDIA_DESCRIPTION="Bad Media Description",n))(G||{});class Fe{remoteStreams={};reset(){this.remoteStreams={}}generateStream(e,t){const{id:s}=e,r=this.remoteStreams[s]??new MediaStream;return t&&r.addTrack(t),r.addTrack(e),this.remoteStreams[s]=r,r}generateAudioStream(e){const{id:t}=e,s=this.remoteStreams[t]??new MediaStream;return s.addTrack(e),this.remoteStreams[t]=s,s}generateStreams(e){const t=[];return e.forEach((s,r)=>{if(s.kind==="audio")return;const i=s,a=e[r-1];let o;a?.kind==="audio"&&(o=a);const c=this.generateStream(i,o);t.push(c)}),t}generateAudioStreams(e){return e.map(t=>this.generateAudioStream(t))}}class $e extends ke{remoteStreamsManager=new Fe;disposers=new Set;constructor(e){super(e),e.on(N.FAILED,this.handleEnded),e.on(N.ENDED,this.handleEnded)}get requested(){return this.isPendingCall||this.isPendingAnswer}get connection(){return this.rtcSession?.connection}get isCallActive(){return this.rtcSession?.isEstablished()===!0}get establishedRTCSession(){return this.rtcSession?.isEstablished()===!0?this.rtcSession:void 0}startCall=async(e,t,{number:s,mediaStream:r,extraHeaders:i=[],ontrack:a,iceServers:o,directionVideo:c,directionAudio:d,contentHint:u,offerToReceiveAudio:T=!0,offerToReceiveVideo:l=!0,degradationPreference:C,sendEncodings:m,onAddedTransceiver:I})=>(this.isPendingCall=!0,new Promise((R,y)=>{this.callConfiguration.number=s,this.callConfiguration.answer=!1,this.handleCall({ontrack:a}).then(R).catch(k=>{y(k)}),this.rtcSession=e.call(t(s),{mediaStream:U(r,{directionVideo:c,directionAudio:d,contentHint:u}),pcConfig:{iceServers:o},rtcOfferConstraints:{offerToReceiveAudio:T,offerToReceiveVideo:l},eventHandlers:this.events.triggers,extraHeaders:i,directionVideo:c,directionAudio:d,degradationPreference:C,sendEncodings:m,onAddedTransceiver:I})}).finally(()=>{this.isPendingCall=!1}));async endCall(){const{rtcSession:e}=this;if(e&&!e.isEnded())return e.terminateAsync({cause:G.CANCELED}).finally(()=>{this.reset()});this.reset()}answerToIncomingCall=async(e,{mediaStream:t,ontrack:s,extraHeaders:r=[],iceServers:i,directionVideo:a,directionAudio:o,offerToReceiveAudio:c,offerToReceiveVideo:d,contentHint:u,degradationPreference:T,sendEncodings:l,onAddedTransceiver:C})=>(this.isPendingAnswer=!0,new Promise((m,I)=>{try{const R=e();this.rtcSession=R,this.subscribeToSessionEvents(R),this.callConfiguration.answer=!0,this.callConfiguration.number=R.remote_identity.uri.user,this.handleCall({ontrack:s}).then(m).catch(y=>{I(y)}),R.answer({pcConfig:{iceServers:i},rtcOfferConstraints:{offerToReceiveAudio:c,offerToReceiveVideo:d},mediaStream:U(t,{directionVideo:a,directionAudio:o,contentHint:u}),extraHeaders:r,directionVideo:a,directionAudio:o,degradationPreference:T,sendEncodings:l,onAddedTransceiver:C})}catch(R){I(R)}}).finally(()=>{this.isPendingAnswer=!1}));getEstablishedRTCSession(){return this.rtcSession?.isEstablished()===!0?this.rtcSession:void 0}getCallConfiguration(){return{...this.callConfiguration}}getRemoteStreams(){if(!this.connection)return;const t=this.connection.getReceivers().map(({track:s})=>s);return Be(t)?this.remoteStreamsManager.generateStreams(t):this.remoteStreamsManager.generateAudioStreams(t)}async replaceMediaStream(e,t){if(!this.rtcSession)throw new Error("No rtcSession established");const{contentHint:s}=t??{},r=U(e,{contentHint:s});if(r===void 0)throw new Error("No preparedMediaStream");return this.rtcSession.replaceMediaStream(r,t)}async restartIce(e){if(!this.rtcSession)throw new Error("No rtcSession established");return this.rtcSession.restartIce(e)}async addTransceiver(e,t){if(!this.rtcSession)throw new Error("No rtcSession established");return this.rtcSession.addTransceiver(e,t)}handleCall=async({ontrack:e})=>new Promise((t,s)=>{const r=()=>{this.events.on(N.PEER_CONNECTION,u),this.events.on(N.CONFIRMED,T)},i=()=>{this.events.off(N.PEER_CONNECTION,u),this.events.off(N.CONFIRMED,T)},a=()=>{this.events.on(N.FAILED,c),this.events.on(N.ENDED,c)},o=()=>{this.events.off(N.FAILED,c),this.events.off(N.ENDED,c)},c=l=>{i(),o(),s(l)};let d;const u=({peerconnection:l})=>{d=l;const C=m=>{this.events.trigger(N.PEER_CONNECTION_ONTRACK,m),e&&e(m)};l.addEventListener("track",C),this.disposers.add(()=>{l.removeEventListener("track",C)})},T=()=>{d!==void 0&&this.events.trigger(N.PEER_CONNECTION_CONFIRMED,d),i(),o(),t(d)};r(),a()});subscribeToSessionEvents(e){this.events.eachTriggers((t,s)=>{const r=re.find(i=>i===s);r&&(e.on(r,t),this.disposers.add(()=>{e.off(r,t)}))})}unsubscribeFromSessionEvents(){this.disposers.forEach(e=>{e()}),this.disposers.clear()}handleEnded=e=>{const{originator:t}=e;t==="remote"&&this.events.trigger(N.ENDED_FROM_SERVER,e),this.reset()};reset=()=>{delete this.rtcSession,this.remoteStreamsManager.reset(),this.unsubscribeFromSessionEvents(),this.callConfiguration.number=void 0,this.callConfiguration.answer=!1}}class Ve{events;strategy;constructor(e){this.events=new O.TypedEvents(ie),this.strategy=e??new $e(this.events)}get requested(){return this.strategy.requested}get connection(){return this.strategy.connection}get establishedRTCSession(){return this.strategy.establishedRTCSession}get isCallActive(){return this.strategy.isCallActive}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}setStrategy(e){this.strategy=e}startCall=async(...e)=>this.strategy.startCall(...e);endCall=async()=>this.strategy.endCall();answerToIncomingCall=async(...e)=>this.strategy.answerToIncomingCall(...e);getEstablishedRTCSession=()=>this.strategy.getEstablishedRTCSession();getCallConfiguration=()=>this.strategy.getCallConfiguration();getRemoteStreams=()=>this.strategy.getRemoteStreams();addTransceiver=async(...e)=>this.strategy.addTransceiver(...e);replaceMediaStream=async(...e)=>this.strategy.replaceMediaStream(...e);restartIce=async e=>this.strategy.restartIce(e)}const We=(n,e)=>(n.degradationPreference=e.degradationPreference,n),He=(n,e)=>{n.encodings??=[];for(let t=n.encodings.length;t<e;t+=1)n.encodings.push({});return n},oe=n=>(e,t)=>t!==void 0&&e!==t||t===void 0&&e!==n,xe=oe(),qe=(n,e)=>{if(xe(n,e))return n},Ge=(n,e)=>{const t=n.maxBitrate,s=qe(e,t);return s!==void 0&&(n.maxBitrate=s),n},ce=1,Qe=oe(ce),Ye=(n,e)=>{const t=n===void 0?void 0:Math.max(n,ce);if(t!==void 0&&Qe(t,e))return t},ze=(n,e)=>{const t=n.scaleResolutionDownBy,s=Ye(e,t);return s!==void 0&&(n.scaleResolutionDownBy=s),n},Xe=(n,e)=>{const t=e.encodings?.length??0;return He(n,t),n.encodings.forEach((s,r)=>{const i=(e?.encodings??[])[r],a=i?.maxBitrate,o=i?.scaleResolutionDownBy;Ge(s,a),ze(s,o)}),n},Je=(n,e)=>{if(n.codecs?.length!==e.codecs?.length)return!0;for(let t=0;t<(n.codecs?.length??0);t++)if(JSON.stringify(n.codecs[t])!==JSON.stringify(e.codecs[t]))return!0;if(n.headerExtensions?.length!==e.headerExtensions?.length)return!0;for(let t=0;t<(n.headerExtensions?.length??0);t++)if(JSON.stringify(n.headerExtensions[t])!==JSON.stringify(e.headerExtensions[t]))return!0;if(n.encodings?.length!==e.encodings?.length)return!0;for(let t=0;t<(n.encodings?.length??0);t++)if(JSON.stringify(n.encodings[t])!==JSON.stringify(e.encodings[t]))return!0;return n.rtcp?.cname!==e.rtcp?.cname||n.rtcp?.reducedSize!==e.rtcp?.reducedSize||n.degradationPreference!==e.degradationPreference},de=async(n,e)=>{const t=n.getParameters(),s=JSON.parse(JSON.stringify(t));Xe(t,e),We(t,e);const r=Je(s,t);return r&&await n.setParameters(t),{parameters:t,isChanged:r}},Q=async(n,e,t)=>{const{isChanged:s,parameters:r}=await de(n,{encodings:[{scaleResolutionDownBy:e.scaleResolutionDownBy,maxBitrate:e.maxBitrate}]});return s&&t&&t(r),{isChanged:s,parameters:r}},Ke=(n,e)=>n.find(t=>t.track!==null&&e.getTracks().includes(t.track)),je=async(n,e,t)=>{const s=Ke(n,e);if(s)return Q(s,{maxBitrate:t})};var f=(n=>(n.START_PRESENTATION="presentation:start",n.STARTED_PRESENTATION="presentation:started",n.END_PRESENTATION="presentation:end",n.ENDED_PRESENTATION="presentation:ended",n.FAILED_PRESENTATION="presentation:failed",n))(f||{});const he=["presentation:start","presentation:started","presentation:end","presentation:ended","presentation:failed"],Ze=1,et=n=>x.hasCanceledError(n);class tt{events;promisePendingStartPresentation;promisePendingStopPresentation;streamPresentationCurrent;maxBitrate;cancelableSendPresentationWithRepeatedCalls;callManager;constructor({callManager:e,maxBitrate:t}){this.callManager=e,this.maxBitrate=t,this.events=new O.Events(he),this.subscribe()}get isPendingPresentation(){return!!this.promisePendingStartPresentation||!!this.promisePendingStopPresentation}async startPresentation(e,t,{isNeedReinvite:s,contentHint:r,sendEncodings:i,onAddedTransceiver:a}={},o){const c=this.getRtcSessionProtected();if(this.streamPresentationCurrent)throw new Error("Presentation is already started");return this.sendPresentationWithDuplicatedCalls(e,{rtcSession:c,stream:t,presentationOptions:{isNeedReinvite:s,contentHint:r,sendEncodings:i,onAddedTransceiver:a},options:o})}async stopPresentation(e){this.cancelSendPresentationWithRepeatedCalls();const t=this.streamPresentationCurrent;let s=this.promisePendingStartPresentation??Promise.resolve(void 0);this.promisePendingStartPresentation&&await this.promisePendingStartPresentation.catch(()=>{});const r=this.callManager.getEstablishedRTCSession();return r&&t?s=e().then(async()=>r.stopPresentation(t)).catch(i=>{throw this.events.trigger(f.FAILED_PRESENTATION,i),i}):t&&this.events.trigger(f.ENDED_PRESENTATION,t),this.promisePendingStopPresentation=s,s.finally(()=>{this.resetPresentation()})}async updatePresentation(e,t,{contentHint:s,sendEncodings:r,onAddedTransceiver:i}={}){const a=this.getRtcSessionProtected();if(!this.streamPresentationCurrent)throw new Error("Presentation has not started yet");return this.promisePendingStartPresentation&&await this.promisePendingStartPresentation,this.sendPresentation(e,a,t,{contentHint:s,isNeedReinvite:!1,sendEncodings:r,onAddedTransceiver:i}).then(async o=>(await this.setMaxBitrate(),o))}cancelSendPresentationWithRepeatedCalls(){this.cancelableSendPresentationWithRepeatedCalls?.stopRepeatedCalls()}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}subscribe(){this.callManager.on("presentation:start",e=>{this.events.trigger(f.START_PRESENTATION,e)}),this.callManager.on("presentation:started",e=>{this.events.trigger(f.STARTED_PRESENTATION,e)}),this.callManager.on("presentation:end",e=>{this.events.trigger(f.END_PRESENTATION,e)}),this.callManager.on("presentation:ended",e=>{this.events.trigger(f.ENDED_PRESENTATION,e)}),this.callManager.on("presentation:failed",e=>{this.events.trigger(f.FAILED_PRESENTATION,e)}),this.callManager.on("failed",this.handleEnded),this.callManager.on("ended",this.handleEnded)}async sendPresentationWithDuplicatedCalls(e,{rtcSession:t,stream:s,presentationOptions:r,options:i={callLimit:Ze}}){const a=async()=>this.sendPresentation(e,t,s,r),o=()=>!!this.streamPresentationCurrent;return this.cancelableSendPresentationWithRepeatedCalls=x.repeatedCallsAsync({targetFunction:a,isComplete:o,isRejectAsValid:!0,...i}),this.cancelableSendPresentationWithRepeatedCalls.then(c=>c)}async sendPresentation(e,t,s,{isNeedReinvite:r=!0,contentHint:i="detail",degradationPreference:a,sendEncodings:o,onAddedTransceiver:c}){const d=U(s,{contentHint:i});if(d===void 0)throw new Error("No streamPresentationTarget");this.streamPresentationCurrent=d;const u=e().then(async()=>t.startPresentation(d,r,{degradationPreference:a,sendEncodings:o,onAddedTransceiver:c})).then(this.setMaxBitrate).then(()=>s).catch(T=>{throw this.removeStreamPresentationCurrent(),this.events.trigger(f.FAILED_PRESENTATION,T),T});return this.promisePendingStartPresentation=u,u.finally(()=>{this.promisePendingStartPresentation=void 0})}setMaxBitrate=async()=>{const{connection:e}=this.callManager,{streamPresentationCurrent:t}=this,{maxBitrate:s}=this;if(!e||!t||s===void 0)return;const r=e.getSenders();await je(r,t,s)};getRtcSessionProtected=()=>{const e=this.callManager.getEstablishedRTCSession();if(!e)throw new Error("No rtcSession established");return e};handleEnded=()=>{this.reset()};reset(){this.cancelSendPresentationWithRepeatedCalls(),this.resetPresentation()}resetPresentation(){this.removeStreamPresentationCurrent(),this.promisePendingStartPresentation=void 0,this.promisePendingStopPresentation=void 0}removeStreamPresentationCurrent(){delete this.streamPresentationCurrent}}class nt{data={};getUa;constructor(e){this.getUa=e.getUa}isConfigured(){return this.getUa()!==void 0}get(){return{...this.data}}set(e){this.data={...e}}update(e,t){this.data[e]=t}clear(){this.data={}}isRegister(){return this.data.register===!0}getSipServerUrl(){return this.data.sipServerUrl}getDisplayName(){return this.data.displayName}getUser(){return this.data.user}getPassword(){return this.data.password}isRegisterEnabled(){return this.data.register===!0}}var A=(n=>(n.CONNECTING="connecting",n.CONNECTED="connected",n.DISCONNECTED="disconnected",n.NEW_RTC_SESSION="newRTCSession",n.REGISTERED="registered",n.UNREGISTERED="unregistered",n.REGISTRATION_FAILED="registrationFailed",n.NEW_MESSAGE="newMessage",n.SIP_EVENT="sipEvent",n))(A||{});const le=["connecting","connected","disconnected","newRTCSession","registered","unregistered","registrationFailed","newMessage","sipEvent"],ge=[...le],st=3;class rt{cancelableConnectWithRepeatedCalls;JsSIP;events;uaFactory;stateMachine;registrationManager;getUa;setUa;getConnectionConfiguration;setConnectionConfiguration;updateConnectionConfiguration;setSipServerUrl;setSocket;constructor(e){this.JsSIP=e.JsSIP,this.events=e.events,this.uaFactory=e.uaFactory,this.stateMachine=e.stateMachine,this.registrationManager=e.registrationManager,this.getUa=e.getUa,this.setUa=e.setUa,this.getConnectionConfiguration=e.getConnectionConfiguration,this.setConnectionConfiguration=e.setConnectionConfiguration,this.updateConnectionConfiguration=e.updateConnectionConfiguration,this.setSipServerUrl=e.setSipServerUrl,this.setSocket=e.setSocket}connect=async(e,t)=>(this.cancelRequests(),this.connectWithDuplicatedCalls(e,t));set=async({displayName:e})=>new Promise((t,s)=>{const r=this.getUa();if(!r){s(new Error("this.ua is not initialized"));return}let i=!1;const a=this.getConnectionConfiguration();e!==void 0&&e!==a.displayName&&(i=r.set("display_name",ae(e)),this.updateConnectionConfiguration("displayName",e));const o=i;o?t(o):s(new Error("nothing changed"))});disconnect=async()=>{const e=new Promise(s=>{this.events.once(A.DISCONNECTED,()=>{s()})}),t=this.getUa();return t?t.stop():this.events.trigger(A.DISCONNECTED,void 0),e.finally(()=>{this.setUa(void 0),this.stateMachine.reset()})};cancelRequests(){this.cancelConnectWithRepeatedCalls()}connectWithDuplicatedCalls=async(e,{callLimit:t=st}={})=>{const s=async()=>this.connectInner(e),r=i=>{const c=this.getUa()?.isConnected()===!0&&this.hasEqualConnectionConfiguration(e),d=i!=null&&!fe(i);return c||d};return this.stateMachine.startConnect(),this.cancelableConnectWithRepeatedCalls=x.repeatedCallsAsync({targetFunction:s,isComplete:r,callLimit:t,isRejectAsValid:!0,isCheckBeforeCall:!1}),this.cancelableConnectWithRepeatedCalls.then(i=>{if(i instanceof this.JsSIP.UA)return i;throw i})};hasEqualConnectionConfiguration(e){const{configuration:t}=this.uaFactory.createConfiguration(e),r=this.getUa()?.configuration;return r?r.password===t.password&&r.register===t.register&&r.uri.toString()===t.uri&&r.display_name===t.display_name&&r.user_agent===t.user_agent&&r.sockets===t.sockets&&r.session_timers===t.session_timers&&r.register_expires===t.register_expires&&r.connection_recovery_min_interval===t.connection_recovery_min_interval&&r.connection_recovery_max_interval===t.connection_recovery_max_interval:!1}connectInner=async e=>this.initUa(e).then(async()=>this.start());initUa=async({user:e,password:t,sipServerUrl:s,sipWebSocketServerURL:r,remoteAddress:i,sessionTimers:a,registerExpires:o,connectionRecoveryMinInterval:c,connectionRecoveryMaxInterval:d,userAgent:u,displayName:T="",register:l=!1,extraHeaders:C=[]})=>{this.stateMachine.startInitUa(),this.setConnectionConfiguration({sipServerUrl:s,displayName:T,register:l,user:e,password:t}),this.getUa()&&await this.disconnect();const{ua:I,helpers:R}=this.uaFactory.createUAWithConfiguration({user:e,password:t,sipServerUrl:s,sipWebSocketServerURL:r,displayName:T,register:l,sessionTimers:a,registerExpires:o,connectionRecoveryMinInterval:c,connectionRecoveryMaxInterval:d,userAgent:u,remoteAddress:i,extraHeaders:C},this.events);return this.setUa(I),this.setSipServerUrl(R.getSipServerUrl),this.setSocket(R.socket),I};start=async()=>new Promise((e,t)=>{const s=this.getUa();if(!s){t(new Error("this.ua is not initialized"));return}let r;r=((c,d)=>{if(this.getConnectionConfiguration().register===!0)return this.registrationManager.subscribeToStartEvents(c,d);const T=A.CONNECTED,l=[A.DISCONNECTED];return this.events.on(T,c),l.forEach(C=>{this.events.on(C,d)}),()=>{this.events.off(T,c),l.forEach(C=>{this.events.off(C,d)})}})(()=>{r?.(),e(s)},c=>{r?.(),t(c)}),s.start()});cancelConnectWithRepeatedCalls(){this.cancelableConnectWithRepeatedCalls?.cancel()}}var ue=(n=>(n.START_CONNECT="START_CONNECT",n.START_INIT_UA="START_INIT_UA",n.UA_CONNECTED="UA_CONNECTED",n.UA_REGISTERED="UA_REGISTERED",n.UA_UNREGISTERED="UA_UNREGISTERED",n.UA_DISCONNECTED="UA_DISCONNECTED",n.CONNECTION_FAILED="CONNECTION_FAILED",n.RESET="RESET",n))(ue||{});const it=j.setup({types:{context:{},events:{}},actions:{logTransition:(n,e)=>{E(`State transition: ${e.from} -> ${e.to} (${e.event})`)},logStateChange:(n,e)=>{E("ConnectionStateMachine state changed",e.state)}}}).createMachine({id:"connection",initial:"idle",context:{},states:{idle:{entry:{type:"logStateChange",params:{state:"idle"}},on:{START_CONNECT:{target:"connecting",actions:{type:"logTransition",params:{from:"idle",to:"connecting",event:"START_CONNECT"}}}}},connecting:{entry:{type:"logStateChange",params:{state:"connecting"}},on:{START_INIT_UA:{target:"initializing",actions:{type:"logTransition",params:{from:"connecting",to:"initializing",event:"START_INIT_UA"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"connecting",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"connecting",to:"failed",event:"CONNECTION_FAILED"}}}}},initializing:{entry:{type:"logStateChange",params:{state:"initializing"}},on:{UA_CONNECTED:{target:"connected",actions:{type:"logTransition",params:{from:"initializing",to:"connected",event:"UA_CONNECTED"}}},UA_REGISTERED:{target:"registered",actions:{type:"logTransition",params:{from:"initializing",to:"registered",event:"UA_REGISTERED"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"initializing",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"initializing",to:"failed",event:"CONNECTION_FAILED"}}}}},connected:{entry:{type:"logStateChange",params:{state:"connected"}},on:{UA_REGISTERED:{target:"registered",actions:{type:"logTransition",params:{from:"connected",to:"registered",event:"UA_REGISTERED"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"connected",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"connected",to:"failed",event:"CONNECTION_FAILED"}}}}},registered:{entry:{type:"logStateChange",params:{state:"registered"}},on:{UA_UNREGISTERED:{target:"connected",actions:{type:"logTransition",params:{from:"registered",to:"connected",event:"UA_UNREGISTERED"}}},UA_DISCONNECTED:{target:"disconnected",actions:{type:"logTransition",params:{from:"registered",to:"disconnected",event:"UA_DISCONNECTED"}}},CONNECTION_FAILED:{target:"failed",actions:{type:"logTransition",params:{from:"registered",to:"failed",event:"CONNECTION_FAILED"}}}}},disconnected:{entry:{type:"logStateChange",params:{state:"disconnected"}},on:{RESET:{target:"idle",actions:{type:"logTransition",params:{from:"disconnected",to:"idle",event:"RESET"}}},START_CONNECT:{target:"connecting",actions:{type:"logTransition",params:{from:"disconnected",to:"connecting",event:"START_CONNECT"}}}}},failed:{entry:{type:"logStateChange",params:{state:"failed"}},on:{RESET:{target:"idle",actions:{type:"logTransition",params:{from:"failed",to:"idle",event:"RESET"}}},START_CONNECT:{target:"connecting",actions:{type:"logTransition",params:{from:"failed",to:"connecting",event:"START_CONNECT"}}}}}}});class at{actor;stateChangeListeners=new Set;events;unsubscribeFromEvents;actorSubscription;constructor(e){this.events=e,this.actor=j.createActor(it),this.actorSubscription=this.actor.subscribe(t=>{const s=t.value;this.stateChangeListeners.forEach(r=>{r(s)})}),this.actor.start(),this.subscribeToEvents()}get state(){return this.actor.getSnapshot().value}get isIdle(){return this.hasState("idle")}get isConnecting(){return this.hasState("connecting")}get isInitializing(){return this.hasState("initializing")}get isConnected(){return this.hasState("connected")}get isRegistered(){return this.hasState("registered")}get isDisconnected(){return this.hasState("disconnected")}get isFailed(){return this.hasState("failed")}get isPending(){return this.isConnecting||this.isInitializing}get isPendingConnect(){return this.isConnecting}get isPendingInitUa(){return this.isInitializing}get isActiveConnection(){return this.isConnected||this.isRegistered}startConnect(){this.toStartConnect()}startInitUa(){this.toStartInitUa()}reset(){this.toIdle()}destroy(){this.unsubscribeFromEvents?.(),this.actorSubscription?.unsubscribe(),this.actor.stop()}onStateChange(e){return this.stateChangeListeners.add(e),()=>{this.stateChangeListeners.delete(e)}}canTransition(e){return this.actor.getSnapshot().can({type:e})}getValidEvents(){return Object.values(ue).filter(e=>this.canTransition(e))}hasState(e){return this.actor.getSnapshot().matches(e)}sendEvent(e){const t=this.actor.getSnapshot(),s={type:e};if(!t.can(s)){E(`Invalid transition: ${s.type} from ${this.state}. Event cannot be processed in current state.`);return}this.actor.send(s)}toStartConnect=()=>{this.sendEvent("START_CONNECT")};toStartInitUa=()=>{this.sendEvent("START_INIT_UA")};toConnected=()=>{this.sendEvent("UA_CONNECTED")};toRegistered=()=>{this.sendEvent("UA_REGISTERED")};toUnregistered=()=>{this.sendEvent("UA_UNREGISTERED")};toDisconnected=()=>{this.sendEvent("UA_DISCONNECTED")};toFailed=()=>{this.sendEvent("CONNECTION_FAILED")};toIdle=()=>{this.sendEvent("RESET")};subscribeToEvents(){this.events.on("connected",this.toConnected),this.events.on("registered",this.toRegistered),this.events.on("unregistered",this.toUnregistered),this.events.on("disconnected",this.toDisconnected),this.events.on("registrationFailed",this.toFailed),this.unsubscribeFromEvents=()=>{this.events.off("connected",this.toConnected),this.events.off("registered",this.toRegistered),this.events.off("unregistered",this.toUnregistered),this.events.off("disconnected",this.toDisconnected),this.events.off("registrationFailed",this.toFailed)}}}class ot{events;getUaProtected;constructor(e){this.events=e.events,this.getUaProtected=e.getUaProtected}async register(){const e=this.getUaProtected();return new Promise((t,s)=>{e.on(A.REGISTERED,t),e.on(A.REGISTRATION_FAILED,s),e.register()})}async unregister(){const e=this.getUaProtected();return new Promise(t=>{e.on(A.UNREGISTERED,t),e.unregister()})}async tryRegister(){try{await this.unregister()}catch(e){E("tryRegister",e)}return this.register()}subscribeToStartEvents(e,t){const s=A.REGISTERED,r=[A.REGISTRATION_FAILED,A.DISCONNECTED];return this.events.on(s,e),r.forEach(i=>{this.events.on(i,t)}),()=>{this.events.off(s,e),r.forEach(i=>{this.events.off(i,t)})}}}class ct{uaFactory;getUaProtected;constructor(e){this.uaFactory=e.uaFactory,this.getUaProtected=e.getUaProtected}async sendOptions(e,t,s){const r=this.getUaProtected();return new Promise((i,a)=>{try{r.sendOptions(e,t,{extraHeaders:s,eventHandlers:{succeeded:()=>{i()},failed:a}})}catch(o){a(o)}})}async ping(e,t){const r=this.getUaProtected().configuration.uri;return this.sendOptions(r,e,t)}async checkTelephony({userAgent:e,displayName:t,sipServerUrl:s,sipWebSocketServerURL:r,remoteAddress:i,extraHeaders:a}){return new Promise((o,c)=>{const{configuration:d}=this.uaFactory.createConfiguration({sipWebSocketServerURL:r,displayName:t,userAgent:e,sipServerUrl:s}),u=this.uaFactory.createUA({...d,remoteAddress:i,extraHeaders:a}),T=()=>{const C=new Error("Telephony is not available");c(C)};u.once(A.DISCONNECTED,T);const l=()=>{u.removeAllListeners(),u.once(A.DISCONNECTED,()=>{o()}),u.stop()};u.once(A.CONNECTED,l),u.start()})}}const dt=n=>{const e=[];return n!==void 0&&n!==""&&e.push(`X-Vinteo-Remote: ${n}`),e};class D{JsSIP;constructor(e){this.JsSIP=e}static isRegisteredUA(e){return!!e&&e.isRegistered()}static validateConfiguration({register:e,password:t,user:s,sipServerUrl:r,sipWebSocketServerURL:i}){if(!r)throw new Error("sipServerUrl is required");if(!i)throw new Error("sipWebSocketServerURL is required");if(e&&(t===void 0||t===""))throw new Error("password is required for authorized connection");if(e&&(s===void 0||s===""))throw new Error("user is required for authorized connection")}static resolveAuthorizationUser(e,t){return e&&t!==void 0&&t.trim()!==""?t.trim():`${Le()}`}static buildExtraHeaders(e,t){const s=e!==void 0&&e!==""?dt(e):[];return t===void 0?s:[...s,...t]}createConfiguration({user:e,password:t,sipWebSocketServerURL:s,displayName:r="",sipServerUrl:i,register:a=!1,sessionTimers:o=!1,registerExpires:c=300,connectionRecoveryMinInterval:d=2,connectionRecoveryMaxInterval:u=6,userAgent:T}){D.validateConfiguration({register:a,password:t,user:e,sipServerUrl:i,sipWebSocketServerURL:s});const l=D.resolveAuthorizationUser(a,e),C=we(i),m=C(l),I=new this.JsSIP.WebSocketInterface(s);return{configuration:{password:t,register:a,uri:m,display_name:ae(r),user_agent:T,sdpSemantics:"unified-plan",sockets:[I],session_timers:o,register_expires:c,connection_recovery_min_interval:d,connection_recovery_max_interval:u},helpers:{socket:I,getSipServerUrl:C}}}createUA({remoteAddress:e,extraHeaders:t,...s}){const r=new this.JsSIP.UA(s),i=D.buildExtraHeaders(e,t);return i.length>0&&r.registrator().setExtraHeaders(i),r}createUAWithConfiguration(e,t){const{configuration:s,helpers:r}=this.createConfiguration(e),i=this.createUA({...s,remoteAddress:e.remoteAddress,extraHeaders:e.extraHeaders});return t.eachTriggers((a,o)=>{const c=le.find(d=>d===o);c&&i.on(c,a)}),{ua:i,helpers:r}}}class ht{events;ua;socket;uaFactory;registrationManager;stateMachine;connectionFlow;sipOperations;configurationManager;JsSIP;constructor({JsSIP:e}){this.JsSIP=e,this.events=new O.Events(ge),this.uaFactory=new D(e),this.registrationManager=new ot({events:this.events,getUaProtected:this.getUaProtected}),this.stateMachine=new at(this.events),this.configurationManager=new nt({getUa:this.getUa}),this.sipOperations=new ct({uaFactory:this.uaFactory,getUaProtected:this.getUaProtected}),this.connectionFlow=new rt({JsSIP:this.JsSIP,events:this.events,uaFactory:this.uaFactory,stateMachine:this.stateMachine,registrationManager:this.registrationManager,getUa:this.getUa,getConnectionConfiguration:this.getConnectionConfiguration,setConnectionConfiguration:t=>{this.configurationManager.set(t)},updateConnectionConfiguration:(t,s)=>{this.configurationManager.update(t,s)},setUa:t=>{this.ua=t},setSipServerUrl:t=>{this.getSipServerUrl=t},setSocket:t=>{this.socket=t}})}get requested(){return this.stateMachine.isPending}get isPendingConnect(){return this.stateMachine.isPendingConnect}get isPendingInitUa(){return this.stateMachine.isPendingInitUa}get connectionState(){return this.stateMachine.state}get isRegistered(){return D.isRegisteredUA(this.ua)}get isRegisterConfig(){return this.configurationManager.isRegister()}connect=async(e,t)=>this.connectionFlow.connect(e,t);set=async({displayName:e})=>this.connectionFlow.set({displayName:e});disconnect=async()=>this.connectionFlow.disconnect();async register(){return this.registrationManager.register()}async unregister(){return this.registrationManager.unregister()}tryRegister=async()=>this.registrationManager.tryRegister();sendOptions=async(e,t,s)=>this.sipOperations.sendOptions(e,t,s);ping=async(e,t)=>this.sipOperations.ping(e,t);checkTelephony=async e=>this.sipOperations.checkTelephony(e);on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}isConfigured(){return this.configurationManager.isConfigured()}getConnectionConfiguration=()=>this.configurationManager.get();destroy(){this.stateMachine.destroy()}getSipServerUrl=e=>e;getUaProtected=()=>{if(!this.ua)throw new Error("UA not initialized");return this.ua};getUa=()=>this.ua}class lt{connectionManager;stackPromises=Z.createStackPromises({noRunIsNotActual:!0});constructor({connectionManager:e}){this.connectionManager=e}connect=async(...e)=>this.stackPromises.run(async()=>this.connectionManager.connect(...e));disconnect=async()=>this.stackPromises.run(async()=>this.connectionManager.disconnect());register=async()=>this.stackPromises.run(async()=>this.connectionManager.register());unregister=async()=>this.stackPromises.run(async()=>this.connectionManager.unregister());tryRegister=async()=>this.stackPromises.run(async()=>this.connectionManager.tryRegister());checkTelephony=async(...e)=>this.stackPromises.run(async()=>this.connectionManager.checkTelephony(...e));sendOptions=async(...e)=>this.stackPromises.run(async()=>this.connectionManager.sendOptions(...e));ping=async(...e)=>this.stackPromises.run(async()=>this.connectionManager.ping(...e));set=async(...e)=>this.stackPromises.run(async()=>this.connectionManager.set(...e))}var w=(n=>(n.INCOMING_CALL="incomingCall",n.DECLINED_INCOMING_CALL="declinedIncomingCall",n.TERMINATED_INCOMING_CALL="terminatedIncomingCall",n.FAILED_INCOMING_CALL="failedIncomingCall",n))(w||{});const Te=["incomingCall","declinedIncomingCall","terminatedIncomingCall","failedIncomingCall"],gt=486,ut=487;class Tt{events;incomingRTCSession;connectionManager;constructor(e){this.connectionManager=e,this.events=new O.Events(Te),this.start()}get remoteCallerData(){return{displayName:this.incomingRTCSession?.remote_identity.display_name,host:this.incomingRTCSession?.remote_identity.uri.host,incomingNumber:this.incomingRTCSession?.remote_identity.uri.user,rtcSession:this.incomingRTCSession}}get isAvailableIncomingCall(){return!!this.incomingRTCSession}start(){this.subscribe()}stop(){this.unsubscribe(),this.removeIncomingSession()}getIncomingRTCSession=()=>{const{incomingRTCSession:e}=this;if(!e)throw new Error("No incomingRTCSession");return e};extractIncomingRTCSession=()=>{const e=this.getIncomingRTCSession();return this.removeIncomingSession(),e};async declineToIncomingCall({statusCode:e=ut}={}){return new Promise((t,s)=>{try{const r=this.getIncomingRTCSession(),i=this.remoteCallerData;this.removeIncomingSession(),this.events.trigger(w.DECLINED_INCOMING_CALL,i),r.terminate({status_code:e}),t()}catch(r){s(r)}})}async busyIncomingCall(){return this.declineToIncomingCall({statusCode:gt})}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}subscribe(){this.connectionManager.on("newRTCSession",this.handleNewRTCSession)}unsubscribe(){this.connectionManager.off("newRTCSession",this.handleNewRTCSession)}handleNewRTCSession=({originator:e,session:t})=>{e==="remote"&&this.setIncomingSession(t)};setIncomingSession(e){this.incomingRTCSession=e;const t=this.remoteCallerData;e.on("failed",s=>{this.removeIncomingSession(),s.originator==="local"?this.events.trigger(w.TERMINATED_INCOMING_CALL,t):this.events.trigger(w.FAILED_INCOMING_CALL,t)}),this.events.trigger(w.INCOMING_CALL,t)}removeIncomingSession(){delete this.incomingRTCSession}}const b=1e3;var S=(n=>(n.INBOUND_RTP="inbound-rtp",n.REMOTE_OUTBOUND_RTP="remote-outbound-rtp",n.MEDIA_SOURCE="media-source",n.OUTBOUND_RTP="outbound-rtp",n.REMOTE_INBOUND_RTP="remote-inbound-rtp",n.CODEC="codec",n.CANDIDATE_PAIR="candidate-pair",n.CERTIFICATE="certificate",n.TRANSPORT="transport",n.LOCAL_CANDIDATE="local-candidate",n.REMOTE_CANDIDATE="remote-candidate",n))(S||{});const Se=["collected"],z=()=>"performance"in window?performance.now():Date.now(),L=n=>[...n.keys()].reduce((e,t)=>{const s=n.get(t);return s===void 0?e:{...e,[s.type]:s}},{}),St=n=>{if(!n)return{outboundRtp:void 0,codec:void 0,mediaSource:void 0,remoteInboundRtp:void 0};const e=L(n);return{outboundRtp:e[S.OUTBOUND_RTP],codec:e[S.CODEC],mediaSource:e[S.MEDIA_SOURCE],remoteInboundRtp:e[S.REMOTE_INBOUND_RTP]}},X=n=>{if(!n)return{outboundRtp:void 0,codec:void 0,mediaSource:void 0,remoteInboundRtp:void 0};const e=L(n);return{outboundRtp:e[S.OUTBOUND_RTP],codec:e[S.CODEC],mediaSource:e[S.MEDIA_SOURCE],remoteInboundRtp:e[S.REMOTE_INBOUND_RTP]}},J=({videoReceiversStats:n,synchronizationSourcesVideo:e})=>{if(!n)return{inboundRtp:void 0,codec:void 0,synchronizationSources:e};const t=L(n);return{inboundRtp:t[S.INBOUND_RTP],codec:t[S.CODEC],synchronizationSources:e}},Ct=({audioReceiverStats:n,synchronizationSourcesAudio:e})=>{if(!n)return{inboundRtp:void 0,codec:void 0,remoteOutboundRtp:void 0,synchronizationSources:e};const t=L(n);return{inboundRtp:t[S.INBOUND_RTP],codec:t[S.CODEC],remoteOutboundRtp:t[S.REMOTE_OUTBOUND_RTP],synchronizationSources:e}},Ce=n=>{if(!n)return{candidatePair:void 0,certificate:void 0,localCandidate:void 0,remoteCandidate:void 0,transport:void 0};const e=L(n);return{candidatePair:e[S.CANDIDATE_PAIR],certificate:e[S.CERTIFICATE],localCandidate:e[S.LOCAL_CANDIDATE],remoteCandidate:e[S.REMOTE_CANDIDATE],transport:e[S.TRANSPORT]}},Et=({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t})=>({video:X(e),secondVideo:X(t),audio:St(n),additional:Ce(n??e??t)}),Nt=({audioReceiverStats:n,videoReceiverFirstStats:e,videoReceiverSecondStats:t,synchronizationSources:s})=>({video:J({videoReceiversStats:e,synchronizationSourcesVideo:s.video}),secondVideo:J({videoReceiversStats:t,synchronizationSourcesVideo:s.video}),audio:Ct({audioReceiverStats:n,synchronizationSourcesAudio:s.audio}),additional:Ce(n??e??t)}),At=({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t,audioReceiverStats:s,videoReceiverFirstStats:r,videoReceiverSecondStats:i,synchronizationSources:a})=>{const o=Et({audioSenderStats:n,videoSenderFirstStats:e,videoSenderSecondStats:t}),c=Nt({audioReceiverStats:s,videoReceiverFirstStats:r,videoReceiverSecondStats:i,synchronizationSources:a});return{outbound:o,inbound:c}},Rt=async n=>{const e="audio",t="video",s=n.getSenders(),r=s.find(l=>l.track?.kind===e),i=s.filter(l=>l.track?.kind===t),a=n.getReceivers(),o=a.find(l=>l.track.kind===e),c=a.filter(l=>l.track.kind===t),d={trackIdentifier:o?.track.id,item:o?.getSynchronizationSources()[0]},u={trackIdentifier:c[0]?.track.id,item:c[0]?.getSynchronizationSources()[0]},T={audio:d,video:u};return Promise.all([r?.getStats()??Promise.resolve(void 0),i[0]?.getStats()??Promise.resolve(void 0),i[1]?.getStats()??Promise.resolve(void 0),o?.getStats()??Promise.resolve(void 0),c[0]?.getStats()??Promise.resolve(void 0),c[1]?.getStats()??Promise.resolve(void 0)]).then(l=>{const[C,m,I,R,y,k]=l;return{synchronizationSources:T,audioSenderStats:C,videoSenderFirstStats:m,videoSenderSecondStats:I,audioReceiverStats:R,videoReceiverFirstStats:y,videoReceiverSecondStats:k}})},It=n=>{E(String(n))};class Ee{events;setTimeoutRequest;requesterAllStatistics=new me.CancelableRequest(Rt);constructor(){this.events=new O.TypedEvents(Se),this.setTimeoutRequest=new ee.SetTimeoutRequest}get requested(){return this.setTimeoutRequest.requested}start(e,{interval:t=b,onError:s=It}={}){this.stop(),this.setTimeoutRequest.request(()=>{this.collectStatistics(e,{onError:s})},t)}stop(){this.setTimeoutRequest.cancelRequest(),this.requesterAllStatistics.cancelRequest()}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}collectStatistics=(e,{onError:t})=>{const s=z();this.requesterAllStatistics.request(e).then(r=>{this.events.trigger("collected",At(r));const a=z()-s;let o=b;a>48?o=b*4:a>32?o=b*3:a>16&&(o=b*2),this.start(e,{onError:t,interval:o})}).catch(r=>{t&&t(r)})}}class _t{availableIncomingBitrate;statsPeerConnection;callManager;apiManager;previousAvailableIncomingBitrate;constructor({callManager:e,apiManager:t}){this.callManager=e,this.apiManager=t,this.statsPeerConnection=new Ee,this.subscribe()}get events(){return this.statsPeerConnection.events}on(e,t){return this.statsPeerConnection.on(e,t)}once(e,t){return this.statsPeerConnection.once(e,t)}onceRace(e,t){return this.statsPeerConnection.onceRace(e,t)}async wait(e){return this.statsPeerConnection.wait(e)}off(e,t){this.statsPeerConnection.off(e,t)}hasAvailableIncomingBitrateChangedQuarter(){const e=this.previousAvailableIncomingBitrate,t=this.availableIncomingBitrate;return e===void 0||t===void 0?!1:e===0?t>0:Math.abs(t-e)/e>=.25}subscribe(){this.callManager.on("peerconnection:confirmed",this.handleStarted),this.callManager.on("failed",this.handleEnded),this.callManager.on("ended",this.handleEnded),this.statsPeerConnection.on("collected",this.handleStatsCollected)}handleStatsCollected=e=>{this.previousAvailableIncomingBitrate=this.availableIncomingBitrate,this.availableIncomingBitrate=e.inbound.additional.candidatePair?.availableIncomingBitrate,this.maybeSendStats()};handleStarted=e=>{this.statsPeerConnection.start(e)};handleEnded=()=>{this.statsPeerConnection.stop(),this.availableIncomingBitrate=void 0,this.previousAvailableIncomingBitrate=void 0};maybeSendStats(){this.availableIncomingBitrate!==void 0&&this.hasAvailableIncomingBitrateChangedQuarter()&&this.apiManager.sendStats({availableIncomingBitrate:this.availableIncomingBitrate}).catch(e=>{E("Failed to send stats",e)})}}const mt=(n,e)=>n.filter(s=>e.some(r=>r.clockRate===s.clockRate&&r.mimeType===s.mimeType&&r.channels===s.channels&&r.sdpFmtpLine===s.sdpFmtpLine)),Mt=n=>{const e=RTCRtpSender.getCapabilities(n),t=RTCRtpReceiver.getCapabilities(n),s=e===null?[]:e.codecs,r=t===null?[]:t.codecs;return mt(s,r)},pt=(n,e)=>e===void 0||e.length===0?n:n.sort((t,s)=>{const r=e.indexOf(t.mimeType),i=e.indexOf(s.mimeType),a=r===-1?Number.MAX_VALUE:r,o=i===-1?Number.MAX_VALUE:i;return a-o}),Pt=(n,e)=>e===void 0||e.length===0?n:n.filter(t=>!e.includes(t.mimeType)),vt=(n,{preferredMimeTypesVideoCodecs:e,excludeMimeTypesVideoCodecs:t})=>{try{if(typeof n.setCodecPreferences=="function"&&n.sender.track?.kind==="video"&&(e!==void 0&&e.length>0||t!==void 0&&t.length>0)){const s=Mt("video"),r=Pt(s,t),i=pt(r,e);n.setCodecPreferences(i)}}catch(s){E("setCodecPreferences error",s)}};class ft{transceivers={};callManager;apiManager;constructor({callManager:e,apiManager:t}){this.callManager=e,this.apiManager=t,this.subscribe()}storeTransceiver(e,t){const{kind:s}=t;if(s==="audio")this.transceivers.mainAudio??=e;else{const{mid:r}=e;r==="2"?this.transceivers.presentationVideo??=e:this.transceivers.mainVideo??=e}}getTransceivers(){return{...this.transceivers}}getMainAudioTransceiver(){return this.transceivers.mainAudio}getMainVideoTransceiver(){return this.transceivers.mainVideo}getPresentationVideoTransceiver(){return this.transceivers.presentationVideo}hasTransceiver(e){return this.transceivers[e]!==void 0}clear(){this.transceivers.mainVideo=void 0,this.transceivers.mainAudio=void 0,this.transceivers.presentationVideo=void 0}getCount(){let e=0;return this.transceivers.mainAudio&&(e+=1),this.transceivers.mainVideo&&(e+=1),this.transceivers.presentationVideo&&(e+=1),e}isEmpty(){return this.getCount()===0}handleRestart=e=>{this.updateTransceivers(e).catch(t=>{E("Failed to update transceivers",t)}).finally(()=>{this.callManager.restartIce().catch(t=>{E("Failed to restart ICE",t)})})};updateTransceivers=async e=>{const{videoTrackCount:t}=e;t===2&&(this.getTransceivers().presentationVideo!==void 0||await this.callManager.addTransceiver("video",{direction:"recvonly"}).catch(i=>{E("Failed to add presentation video transceiver",i)}))};subscribe(){this.callManager.on("peerconnection:ontrack",this.handleTrack),this.callManager.on("failed",this.handleEnded),this.callManager.on("ended",this.handleEnded),this.apiManager.on("restart",this.handleRestart)}handleTrack=e=>{this.storeTransceiver(e.transceiver,e.track)};handleEnded=()=>{this.clear()}}const Ot=n=>[...n.keys()].map(e=>n.get(e)),Dt=(n,e)=>Ot(n).find(t=>t?.type===e),Ne=async n=>n.getStats().then(e=>Dt(e,"codec")?.mimeType);class yt{async getCodecFromSender(e){return await Ne(e)??""}}class bt{stackPromises=Z.createStackPromises({noRunIsNotActual:!0});async add(e){return this.stackPromises.add(e),this.run()}stop(){this.stackPromises.stop()}async run(){return this.stackPromises().catch(e=>{E("TaskQueue: error",e)})}}class wt{taskQueue;onSetParameters;constructor(e){this.onSetParameters=e,this.taskQueue=new bt}async setEncodingsToSender(e,t){return this.taskQueue.add(async()=>Q(e,t,this.onSetParameters))}stop(){this.taskQueue.stop()}}const Ae=(n,e)=>n!==void 0&&e!==void 0&&n.toLowerCase().includes(e.toLowerCase()),Ut=1e6,p=n=>n*Ut,Re=p(.06),Ie=p(4),Lt=n=>n<=64?Re:n<=128?p(.12):n<=256?p(.25):n<=384?p(.32):n<=426?p(.38):n<=640?p(.5):n<=848?p(.7):n<=1280?p(1):n<=1920?p(2):Ie,Bt="av1",kt=n=>Ae(n,Bt),Ft=.6,Y=(n,e)=>kt(e)?n*Ft:n,$t=n=>Y(Re,n),Vt=n=>Y(Ie,n),K=(n,e)=>{const t=Lt(n);return Y(t,e)},F=1,Wt=({videoTrack:n,targetSize:e})=>{const t=n.getSettings(),s=t.width,r=t.height,i=s===void 0?F:s/e.width,a=r===void 0?F:r/e.height;return Math.max(i,a,F)};class Ht{ignoreForCodec;senderFinder;codecProvider;parametersSetter;resultNoChanged={isChanged:!1,parameters:{encodings:[{}],transactionId:"0",codecs:[],headerExtensions:[],rtcp:{}}};constructor({senderFinder:e,codecProvider:t,parametersSetter:s},r){this.senderFinder=e,this.codecProvider=t,this.parametersSetter=s,this.ignoreForCodec=r.ignoreForCodec}async balance(e,t){const s=e.getSenders(),r=this.senderFinder.findVideoSender(s);if(!r?.track)return{...this.resultNoChanged,sender:r};const i=await this.codecProvider.getCodecFromSender(r);if(Ae(i,this.ignoreForCodec))return{...this.resultNoChanged,sender:r};const{mainCam:a,resolutionMainCam:o}=t??{};return this.processSender({mainCam:a,resolutionMainCam:o},{sender:r,codec:i,videoTrack:r.track}).then(c=>({...c,sender:r}))}async processSender(e,t){const{mainCam:s,resolutionMainCam:r}=e;switch(s){case P.PAUSE_MAIN_CAM:return this.downgradeResolutionSender(t);case P.RESUME_MAIN_CAM:return this.setBitrateByTrackResolution(t);case P.MAX_MAIN_CAM_RESOLUTION:return r!==void 0?this.setResolutionSender(r,t):this.setBitrateByTrackResolution(t);case P.ADMIN_STOP_MAIN_CAM:case P.ADMIN_START_MAIN_CAM:case void 0:return this.setBitrateByTrackResolution(t);default:return this.setBitrateByTrackResolution(t)}}async downgradeResolutionSender(e){const{sender:t,codec:s}=e,r={scaleResolutionDownBy:200,maxBitrate:$t(s)};return this.parametersSetter.setEncodingsToSender(t,r)}async setBitrateByTrackResolution(e){const{sender:t,videoTrack:s,codec:r}=e,a=s.getSettings().width,o=a===void 0?Vt(r):K(a,r);return this.parametersSetter.setEncodingsToSender(t,{scaleResolutionDownBy:1,maxBitrate:o})}async setResolutionSender(e,t){const[s,r]=e.split("x"),{sender:i,videoTrack:a,codec:o}=t,c={width:Number(s),height:Number(r)},d=Wt({videoTrack:a,targetSize:c}),u=K(c.width,o),T={scaleResolutionDownBy:d,maxBitrate:u};return this.parametersSetter.setEncodingsToSender(i,T)}}const xt=n=>n.find(e=>e.track?.kind==="video");class qt{findVideoSender(e){return xt(e)}}class Gt{currentSender;originalReplaceTrack;lastWidth;lastHeight;maxPollIntervalMs;currentPollIntervalMs;pollIntervalMs;setTimeoutRequest;constructor({pollIntervalMs:e=1e3,maxPollIntervalMs:t}){this.pollIntervalMs=e,this.maxPollIntervalMs=t??e*16,this.currentPollIntervalMs=this.pollIntervalMs,this.setTimeoutRequest=new ee.SetTimeoutRequest}subscribe(e,t){if(!e){this.detachSender();return}this.currentSender!==e&&(this.detachSender(),this.attachSender(e,t))}unsubscribe(){this.detachSender()}attachSender(e,t){this.currentSender=e;const s=e.replaceTrack.bind(e);this.originalReplaceTrack=s,e.replaceTrack=async r=>{await s(r),this.attachTrack(t,r??void 0),t()},this.attachTrack(t,e.track)}detachSender(){this.currentSender&&this.originalReplaceTrack&&(this.currentSender.replaceTrack=this.originalReplaceTrack),this.originalReplaceTrack=void 0,this.currentSender=void 0,this.detachTrack()}attachTrack(e,t){if(this.detachTrack(),!t)return;const{width:s,height:r}=t.getSettings();this.lastWidth=s,this.lastHeight=r,this.currentPollIntervalMs=this.pollIntervalMs,this.schedulePoll(t,e)}schedulePoll(e,t){const s=()=>{const{width:r,height:i}=e.getSettings();r!==this.lastWidth||i!==this.lastHeight?(this.lastWidth=r,this.lastHeight=i,this.currentPollIntervalMs=this.pollIntervalMs,t()):this.currentPollIntervalMs=Math.min(this.currentPollIntervalMs*2,this.maxPollIntervalMs),this.setTimeoutRequest.request(s,this.currentPollIntervalMs)};this.setTimeoutRequest.request(s,this.currentPollIntervalMs)}detachTrack(){this.setTimeoutRequest.cancelRequest(),this.lastWidth=void 0,this.lastHeight=void 0}}class Qt{apiManager;currentHandler;constructor(e){this.apiManager=e}subscribe(e){this.currentHandler=e,this.apiManager.on("main-cam-control",e)}unsubscribe(){this.currentHandler&&(this.apiManager.off("main-cam-control",this.currentHandler),this.currentHandler=void 0)}}class Yt{eventHandler;senderBalancer;parametersSetterWithQueue;getConnection;serverHeaders;trackMonitor;constructor(e,t,{ignoreForCodec:s,onSetParameters:r,pollIntervalMs:i}={}){this.getConnection=t,this.eventHandler=new Qt(e),this.parametersSetterWithQueue=new wt(r),this.senderBalancer=new Ht({senderFinder:new qt,codecProvider:new yt,parametersSetter:this.parametersSetterWithQueue},{ignoreForCodec:s}),this.trackMonitor=new Gt({pollIntervalMs:i})}subscribe(){this.eventHandler.subscribe(this.handleMainCamControl)}unsubscribe(){this.eventHandler.unsubscribe(),this.parametersSetterWithQueue.stop(),this.reset()}reset(){delete this.serverHeaders,this.trackMonitor.unsubscribe()}async balance(){const e=this.getConnection();if(!e)throw new Error("connection is not exist");const t=await this.senderBalancer.balance(e,this.serverHeaders);return this.trackMonitor.subscribe(t.sender,()=>{this.balance().catch(s=>{E("balance on track change: error",s)})}),t}handleMainCamControl=e=>{this.serverHeaders=e,this.balance().catch(t=>{E("handleMainCamControl: error",t)})}}const _e=["balancing-scheduled","balancing-started","balancing-stopped","parameters-updated"];class zt{isBalancingActive=!1;events;callManager;balancingStartDelay;videoSendingBalancer;startBalancingTimer;constructor(e,t,s={}){this.events=new O.TypedEvents(_e),this.callManager=e,this.balancingStartDelay=s.balancingStartDelay??1e4,this.videoSendingBalancer=new Yt(t,()=>e.connection,{...s,onSetParameters:r=>{this.events.trigger("parameters-updated",r),s.onSetParameters?.(r)}}),this.subscribe()}get isBalancingScheduled(){return this.startBalancingTimer!==void 0}async startBalancing(){this.isBalancingActive||(this.clearStartTimer(),await this.videoSendingBalancer.balance(),this.videoSendingBalancer.subscribe(),this.isBalancingActive=!0,this.events.trigger("balancing-started",{delay:this.balancingStartDelay}))}stopBalancing(){this.clearStartTimer(),this.videoSendingBalancer.unsubscribe(),this.isBalancingActive=!1,this.events.trigger("balancing-stopped",{})}async balance(){return this.videoSendingBalancer.balance()}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}subscribe(){this.callManager.on("peerconnection:confirmed",this.handleCallStarted),this.callManager.on("ended",this.handleCallEnded),this.callManager.on("failed",this.handleCallEnded)}handleCallStarted=()=>{this.scheduleBalancingStart()};handleCallEnded=()=>{this.stopBalancing()};scheduleBalancingStart(){this.clearStartTimer(),this.startBalancingTimer=setTimeout(()=>{this.startBalancingTimer=void 0,this.startBalancing().catch(e=>{E("startBalancing: error",e)})},this.balancingStartDelay),this.events.trigger("balancing-scheduled",{delay:this.balancingStartDelay})}clearStartTimer(){this.startBalancingTimer&&(clearTimeout(this.startBalancingTimer),this.startBalancingTimer=void 0)}}const Xt=1e6,Jt=ge.map(n=>`connection:${n}`),Kt=ie.map(n=>`call:${n}`),jt=ne.map(n=>`api:${n}`),Zt=Te.map(n=>`incoming-call:${n}`),en=he.map(n=>`presentation:${n}`),tn=Se.map(n=>`stats:${n}`),nn=_e.map(n=>`video-balancer:${n}`),sn=[...Jt,...Kt,...jt,...Zt,...en,...tn,...nn];class rn{events;connectionManager;connectionQueueManager;callManager;apiManager;incomingCallManager;presentationManager;statsManager;videoSendingBalancerManager;transceiverManager;preferredMimeTypesVideoCodecs;excludeMimeTypesVideoCodecs;constructor({JsSIP:e},{preferredMimeTypesVideoCodecs:t,excludeMimeTypesVideoCodecs:s,videoBalancerOptions:r}={}){this.preferredMimeTypesVideoCodecs=t,this.excludeMimeTypesVideoCodecs=s,this.events=new O.Events(sn),this.connectionManager=new ht({JsSIP:e}),this.connectionQueueManager=new lt({connectionManager:this.connectionManager}),this.callManager=new Ve,this.apiManager=new De({connectionManager:this.connectionManager,callManager:this.callManager}),this.incomingCallManager=new Tt(this.connectionManager),this.presentationManager=new tt({callManager:this.callManager,maxBitrate:Xt}),this.statsManager=new _t({callManager:this.callManager,apiManager:this.apiManager}),this.transceiverManager=new ft({callManager:this.callManager,apiManager:this.apiManager}),this.videoSendingBalancerManager=new zt(this.callManager,this.apiManager,r),this.subscribe()}get requestedConnection(){return this.connectionManager.requested}get isPendingConnect(){return this.connectionManager.isPendingConnect}get isPendingInitUa(){return this.connectionManager.isPendingInitUa}get connectionState(){return this.connectionManager.connectionState}get isRegistered(){return this.connectionManager.isRegistered}get isRegisterConfig(){return this.connectionManager.isRegisterConfig}get socket(){return this.connectionManager.socket}get requestedCall(){return this.callManager.requested}get connection(){return this.callManager.connection}get establishedRTCSession(){return this.callManager.establishedRTCSession}get isCallActive(){return this.callManager.isCallActive}get remoteCallerData(){return this.incomingCallManager.remoteCallerData}get isAvailableIncomingCall(){return this.incomingCallManager.isAvailableIncomingCall}on(e,t){return this.events.on(e,t)}once(e,t){return this.events.once(e,t)}onceRace(e,t){return this.events.onceRace(e,t)}async wait(e){return this.events.wait(e)}off(e,t){this.events.off(e,t)}connect=async(...e)=>this.connectionQueueManager.connect(...e);set=async(...e)=>this.connectionQueueManager.set(...e);disconnect=async()=>this.connectionQueueManager.disconnect();register=async()=>this.connectionQueueManager.register();unregister=async()=>this.connectionQueueManager.unregister();tryRegister=async()=>this.connectionQueueManager.tryRegister();sendOptions=async(e,t,s)=>this.connectionQueueManager.sendOptions(e,t,s);ping=async(e,t)=>this.connectionQueueManager.ping(e,t);checkTelephony=async e=>this.connectionQueueManager.checkTelephony(e);isConfigured=()=>this.connectionManager.isConfigured();getConnectionConfiguration=()=>this.connectionManager.getConnectionConfiguration();getSipServerUrl=e=>this.connectionManager.getSipServerUrl(e);call=async e=>{const{onAddedTransceiver:t,...s}=e;return this.callManager.startCall(this.connectionManager.getUaProtected(),this.getSipServerUrl,{...s,onAddedTransceiver:this.resolveHandleAddTransceiver(t)})};hangUp=async()=>this.callManager.endCall();answerToIncomingCall=async e=>{const{onAddedTransceiver:t,...s}=e;return this.callManager.answerToIncomingCall(this.incomingCallManager.extractIncomingRTCSession,{...s,onAddedTransceiver:this.resolveHandleAddTransceiver(t)})};declineToIncomingCall=async(...e)=>this.incomingCallManager.declineToIncomingCall(...e);getEstablishedRTCSession=()=>this.callManager.getEstablishedRTCSession();getCallConfiguration=()=>this.callManager.getCallConfiguration();getRemoteStreams=()=>this.callManager.getRemoteStreams();replaceMediaStream=async(...e)=>this.callManager.replaceMediaStream(...e);async startPresentation(e,t={}){const{isP2P:s,callLimit:r,onAddedTransceiver:i,...a}=t;return this.presentationManager.startPresentation(async()=>{s===!0?(await this.apiManager.sendMustStopPresentationP2P(),await this.apiManager.askPermissionToStartPresentationP2P()):await this.apiManager.askPermissionToStartPresentation()},e,{...a,onAddedTransceiver:this.resolveHandleAddTransceiver(i)},r===void 0?void 0:{callLimit:r})}async stopPresentation(e={}){const{isP2P:t}=e;return this.presentationManager.stopPresentation(async()=>{await(t===!0?this.apiManager.sendMustStopPresentationP2P():this.apiManager.sendStoppedPresentation())})}async updatePresentation(e,t={}){const{isP2P:s,onAddedTransceiver:r,...i}=t;return this.presentationManager.updatePresentation(async()=>{s===!0?(await this.apiManager.sendMustStopPresentationP2P(),await this.apiManager.askPermissionToStartPresentationP2P()):await this.apiManager.askPermissionToStartPresentation()},e,{...i,onAddedTransceiver:this.resolveHandleAddTransceiver(r)})}async waitChannels(...e){return this.apiManager.waitChannels(...e)}async waitSyncMediaState(...e){return this.apiManager.waitSyncMediaState(...e)}async sendDTMF(...e){return this.apiManager.sendDTMF(...e)}async sendChannels(...e){return this.apiManager.sendChannels(...e)}async sendMediaState(...e){return this.apiManager.sendMediaState(...e)}async sendRefusalToTurnOn(...e){return this.apiManager.sendRefusalToTurnOn(...e)}async sendRefusalToTurnOnMic(...e){return this.apiManager.sendRefusalToTurnOnMic(...e)}async sendRefusalToTurnOnCam(...e){return this.apiManager.sendRefusalToTurnOnCam(...e)}async sendMustStopPresentationP2P(...e){return this.apiManager.sendMustStopPresentationP2P(...e)}async sendStoppedPresentationP2P(...e){return this.apiManager.sendStoppedPresentationP2P(...e)}async sendStoppedPresentation(...e){return this.apiManager.sendStoppedPresentation(...e)}async askPermissionToStartPresentationP2P(...e){return this.apiManager.askPermissionToStartPresentationP2P(...e)}async askPermissionToStartPresentation(...e){return this.apiManager.askPermissionToStartPresentation(...e)}async askPermissionToEnableCam(...e){return this.apiManager.askPermissionToEnableCam(...e)}setCodecPreferences(e){vt(e,{preferredMimeTypesVideoCodecs:this.preferredMimeTypesVideoCodecs,excludeMimeTypesVideoCodecs:this.excludeMimeTypesVideoCodecs})}subscribe(){this.bridgeEvents("connection",this.connectionManager),this.bridgeEvents("call",this.callManager),this.bridgeEvents("api",this.apiManager),this.bridgeEvents("incoming-call",this.incomingCallManager),this.bridgeEvents("presentation",this.presentationManager),this.bridgeEvents("stats",this.statsManager),this.bridgeEvents("video-balancer",this.videoSendingBalancerManager)}bridgeEvents=(e,t)=>{t.events.eachTriggers((s,r)=>{t.on(r,i=>{this.events.trigger(`${e}:${r}`,i)})})};resolveHandleAddTransceiver=e=>async(t,s,r)=>{this.setCodecPreferences(t),await e?.(t,s,r)}}exports.ECallCause=G;exports.EStatsTypes=S;exports.EUseLicense=te;exports.Originator=se;exports.SipConnector=rn;exports.StatsPeerConnection=Ee;exports.disableDebug=pe;exports.enableDebug=Me;exports.getCodecFromSender=Ne;exports.hasCanceledStartPresentationError=et;exports.logger=E;exports.prepareMediaStream=U;exports.setEncodingsToSender=Q;exports.setParametersToSender=de;
|