{ "version": 3, "sources": [ "webpack://JitsiMeetJS/webpack/universalModuleDefinition", "webpack://JitsiMeetJS/webpack/bootstrap", "webpack://JitsiMeetJS/./service/xmpp/XMPPEvents.js", "webpack://JitsiMeetJS/./node_modules/strophe.js/dist/strophe.umd.js", "webpack://JitsiMeetJS/./JitsiConferenceEvents.js", "webpack://JitsiMeetJS/./modules/browser/index.js", "webpack://JitsiMeetJS/./node_modules/jitsi-meet-logger/lib/index.js", "webpack://JitsiMeetJS/./modules/statistics/statistics.js", "webpack://JitsiMeetJS/./modules/xmpp/SDPUtil.js", "webpack://JitsiMeetJS/./service/statistics/AnalyticsEvents.js", "webpack://JitsiMeetJS/./service/RTC/RTCEvents.js", "webpack://JitsiMeetJS/./service/RTC/MediaType.js", "webpack://JitsiMeetJS/./modules/RTC/RTCUtils.js", "webpack://JitsiMeetJS/./modules/util/GlobalOnErrorHandler.js", "webpack://JitsiMeetJS/./modules/RTC/RTC.js", "webpack://JitsiMeetJS/./JitsiTrackErrors.js", "webpack://JitsiMeetJS/./service/RTC/VideoType.js", "webpack://JitsiMeetJS/./JitsiTrackEvents.js", "webpack://JitsiMeetJS/./JitsiTrackError.js", "webpack://JitsiMeetJS/./modules/xmpp/SDP.js", "webpack://JitsiMeetJS/./JitsiConferenceErrors.js", "webpack://JitsiMeetJS/./node_modules/events/events.js", "webpack://JitsiMeetJS/./modules/detection/DetectionEvents.js", "webpack://JitsiMeetJS/./node_modules/sdp-transform/lib/index.js", "webpack://JitsiMeetJS/./modules/videosipgw/VideoSIPGWConstants.js", "webpack://JitsiMeetJS/./node_modules/js-utils/browser-detection/browsers.js", "webpack://JitsiMeetJS/./node_modules/js-utils/browser-detection/BrowserDetection.js", "webpack://JitsiMeetJS/./node_modules/js-utils/index.js", "webpack://JitsiMeetJS/./modules/util/Listenable.js", "webpack://JitsiMeetJS/./JitsiConnectionEvents.js", "webpack://JitsiMeetJS/./service/statistics/Events.js", "webpack://JitsiMeetJS/./modules/xmpp/SdpTransformUtil.js", "webpack://JitsiMeetJS/./service/connectivity/ConnectionQualityEvents.js", "webpack://JitsiMeetJS/./modules/util/MathUtil.js", "webpack://JitsiMeetJS/./modules/proxyconnection/constants.js", "webpack://JitsiMeetJS/./service/RTC/Resolutions.js", "webpack://JitsiMeetJS/./modules/xmpp/JingleSessionState.js", "webpack://JitsiMeetJS/./modules/statistics/CallStats.js", "webpack://JitsiMeetJS/./modules/settings/Settings.js", "webpack://JitsiMeetJS/./modules/util/RandomUtil.js", "webpack://JitsiMeetJS/./modules/xmpp/ConnectionPlugin.js", "webpack://JitsiMeetJS/./modules/xmpp/xmpp.js", "webpack://JitsiMeetJS/./service/RTC/SignalingEvents.js", "webpack://JitsiMeetJS/./JitsiConnectionErrors.js", "webpack://JitsiMeetJS/./modules/xmpp/XmppConnection.js", "webpack://JitsiMeetJS/./service/RTC/CameraFacingMode.js", "webpack://JitsiMeetJS/./modules/RTC/ScreenObtainer.js", "webpack://JitsiMeetJS/(webpack)/buildin/global.js", "webpack://JitsiMeetJS/./modules/connectivity/ParticipantConnectionStatus.js", "webpack://JitsiMeetJS/./node_modules/sdp/sdp.js", "webpack://JitsiMeetJS/./modules/recording/recordingXMLUtils.js", "webpack://JitsiMeetJS/./modules/xmpp/JingleSessionPC.js", "webpack://JitsiMeetJS/./JitsiMediaDevicesEvents.js", "webpack://JitsiMeetJS/./node_modules/lodash.clonedeep/index.js", "webpack://JitsiMeetJS/./modules/xmpp/SDPDiffer.js", "webpack://JitsiMeetJS/./node_modules/process/browser.js", "webpack://JitsiMeetJS/./modules/statistics/LocalStatsCollector.js", "webpack://JitsiMeetJS/./modules/util/ScriptUtil.js", "webpack://JitsiMeetJS/./modules/RTC/JitsiTrack.js", "webpack://JitsiMeetJS/./modules/webaudio/WebAudioUtils.js", "webpack://JitsiMeetJS/./modules/detection/TrackVADEmitter.js", "webpack://JitsiMeetJS/./service/e2eping/E2ePingEvents.js", "webpack://JitsiMeetJS/./node_modules/lodash.isequal/index.js", "webpack://JitsiMeetJS/./modules/xmpp/Caps.js", "webpack://JitsiMeetJS/./JitsiTranscriptionStatus.js", "webpack://JitsiMeetJS/./modules/RTC/TPCUtils.js", "webpack://JitsiMeetJS/./modules/statistics/SpeakerStats.js", "webpack://JitsiMeetJS/./service/authentication/AuthenticationEvents.js", "webpack://JitsiMeetJS/./node_modules/js-md5/src/md5.js", "webpack://JitsiMeetJS/./modules/RTC/JitsiLocalTrack.js", "webpack://JitsiMeetJS/./modules/detection/VADAudioAnalyser.js", "webpack://JitsiMeetJS/./modules/recording/JibriSession.js", "webpack://JitsiMeetJS/./JitsiMediaDevices.js", "webpack://JitsiMeetJS/./node_modules/jitsi-meet-logger/lib/Logger.js", "webpack://JitsiMeetJS/(webpack)/buildin/module.js", "webpack://JitsiMeetJS/./node_modules/sdp-transform/lib/grammar.js", "webpack://JitsiMeetJS/./modules/transcription/audioRecorder.js", "webpack://JitsiMeetJS/./modules/detection/ActiveDeviceDetector.js", "webpack://JitsiMeetJS/./modules/RTC/BridgeChannel.js", "webpack://JitsiMeetJS/./modules/statistics/AnalyticsAdapter.js", "webpack://JitsiMeetJS/./modules/browser/BrowserCapabilities.js", "webpack://JitsiMeetJS/./node_modules/bowser/es5.js", "webpack://JitsiMeetJS/./modules/statistics/RTPStatsCollector.js", "webpack://JitsiMeetJS/./node_modules/rtcpeerconnection-shim/rtcpeerconnection.js", "webpack://JitsiMeetJS/./modules/RTC/TraceablePeerConnection.js", "webpack://JitsiMeetJS/./modules/RTC/JitsiRemoteTrack.js", "webpack://JitsiMeetJS/./modules/RTC/LocalSdpMunger.js", "webpack://JitsiMeetJS/./modules/xmpp/RtxModifier.js", "webpack://JitsiMeetJS/./modules/xmpp/SdpConsistency.js", "webpack://JitsiMeetJS/./modules/webaudio/AudioMixer.js", "webpack://JitsiMeetJS/./modules/util/AuthUtil.js", "webpack://JitsiMeetJS/./JitsiConnection.js", "webpack://JitsiMeetJS/./JitsiConference.js", "webpack://JitsiMeetJS/./JitsiConferenceEventManager.js", "webpack://JitsiMeetJS/./modules/util/EventEmitterForwarder.js", "webpack://JitsiMeetJS/./JitsiParticipant.js", "webpack://JitsiMeetJS/./authenticateAndUpgradeRole.js", "webpack://JitsiMeetJS/./modules/xmpp/strophe.emuc.js", "webpack://JitsiMeetJS/./modules/xmpp/ChatRoom.js", "webpack://JitsiMeetJS/./modules/xmpp/moderator.js", "webpack://JitsiMeetJS/./modules/util/UsernameGenerator.js", "webpack://JitsiMeetJS/./modules/util/Retry.js", "webpack://JitsiMeetJS/./modules/xmpp/StropheLastSuccess.js", "webpack://JitsiMeetJS/./modules/xmpp/strophe.jingle.js", "webpack://JitsiMeetJS/./modules/util/StringUtils.js", "webpack://JitsiMeetJS/./modules/xmpp/JingleSession.js", "webpack://JitsiMeetJS/./modules/xmpp/SignalingLayerImpl.js", "webpack://JitsiMeetJS/./service/RTC/SignalingLayer.js", "webpack://JitsiMeetJS/./modules/util/AsyncQueue.js", "webpack://JitsiMeetJS/./node_modules/async/lib/async.js", "webpack://JitsiMeetJS/./modules/xmpp/strophe.util.js", "webpack://JitsiMeetJS/./modules/xmpp/strophe.ping.js", "webpack://JitsiMeetJS/./modules/xmpp/strophe.rayo.js", "webpack://JitsiMeetJS/./modules/xmpp/strophe.logger.js", "webpack://JitsiMeetJS/./modules/detection/P2PDominantSpeakerDetection.js", "webpack://JitsiMeetJS/./modules/detection/TalkMutedDetection.js", "webpack://JitsiMeetJS/./modules/detection/VADTalkMutedDetection.js", "webpack://JitsiMeetJS/./modules/detection/VADNoiseDetection.js", "webpack://JitsiMeetJS/./modules/detection/NoAudioSignalDetection.js", "webpack://JitsiMeetJS/./modules/connectivity/ConnectionQuality.js", "webpack://JitsiMeetJS/./modules/connectivity/IceFailedNotification.js", "webpack://JitsiMeetJS/./modules/e2ee/E2EEContext.js", "webpack://JitsiMeetJS/./modules/e2eping/e2eping.js", "webpack://JitsiMeetJS/./modules/event/Jvb121EventGenerator.js", "webpack://JitsiMeetJS/./modules/recording/RecordingManager.js", "webpack://JitsiMeetJS/./modules/rttmonitor/rttmonitor.js", "webpack://JitsiMeetJS/./modules/statistics/AvgRTPStatsReporter.js", "webpack://JitsiMeetJS/./modules/statistics/AudioOutputProblemDetector.js", "webpack://JitsiMeetJS/./modules/statistics/SpeakerStatsCollector.js", "webpack://JitsiMeetJS/./modules/transcription/transcriber.js", "webpack://JitsiMeetJS/./modules/version/ComponentsVersions.js", "webpack://JitsiMeetJS/./modules/videosipgw/VideoSIPGW.js", "webpack://JitsiMeetJS/./modules/videosipgw/JitsiVideoSIPGWSession.js", "webpack://JitsiMeetJS/./modules/recording/recordingConstants.js", "webpack://JitsiMeetJS/./modules/proxyconnection/ProxyConnectionService.js", "webpack://JitsiMeetJS/./modules/proxyconnection/ProxyConnectionPC.js", "webpack://JitsiMeetJS/./node_modules/@jitsi/sdp-interop/lib/transform.js", "webpack://JitsiMeetJS/./node_modules/@jitsi/sdp-interop/lib/interop.js", "webpack://JitsiMeetJS/./node_modules/@jitsi/sdp-interop/lib/index.js", "webpack://JitsiMeetJS/./index.js", "webpack://JitsiMeetJS/./JitsiMeetJS.js", "webpack://JitsiMeetJS/./node_modules/jitsi-meet-logger/lib/LogCollector.js", "webpack://JitsiMeetJS/(webpack)/buildin/amd-options.js", "webpack://JitsiMeetJS/./node_modules/current-executing-script/dist/currentExecutingScript.js", "webpack://JitsiMeetJS/./service/statistics/constants.js", "webpack://JitsiMeetJS/./node_modules/sdp-transform/lib/parser.js", "webpack://JitsiMeetJS/./node_modules/sdp-transform/lib/writer.js", "webpack://JitsiMeetJS/./node_modules/@jitsi/sdp-simulcast/lib/index.js", "webpack://JitsiMeetJS/./node_modules/@jitsi/sdp-simulcast/lib/transform-utils.js", "webpack://JitsiMeetJS/./node_modules/strophejs-plugin-disco/lib/strophe.disco.js", "webpack://JitsiMeetJS/./node_modules/strophejs-plugin-stream-management/lib/strophe.stream-management.js", "webpack://JitsiMeetJS/./node_modules/timers-browserify/main.js", "webpack://JitsiMeetJS/./node_modules/setimmediate/setImmediate.js", "webpack://JitsiMeetJS/./modules/transcription/recordingResult.js", "webpack://JitsiMeetJS/./modules/transcription/transcriptionServices/SphinxTranscriptionService.js", "webpack://JitsiMeetJS/./modules/transcription/transcriptionServices/AbstractTranscriptionService.js", "webpack://JitsiMeetJS/./modules/transcription/word.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/utils.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/chrome/getusermedia.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/chrome/getdisplaymedia.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/chrome/chrome_shim.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/edge/getusermedia.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/edge/getdisplaymedia.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/edge/edge_shim.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/edge/filtericeservers.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/firefox/getusermedia.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/firefox/getdisplaymedia.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/firefox/firefox_shim.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/safari/safari_shim.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/common_shim.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/adapter_core.js", "webpack://JitsiMeetJS/./node_modules/webrtc-adapter/src/js/adapter_factory.js" ], "names": [ "root", "factory", "exports", "module", "define", "amd", "window", "installedModules", "__webpack_require__", "moduleId", "i", "l", "modules", "call", "m", "c", "d", "name", "getter", "o", "Object", "defineProperty", "enumerable", "get", "r", "Symbol", "toStringTag", "value", "t", "mode", "__esModule", "ns", "create", "key", "bind", "n", "object", "property", "prototype", "hasOwnProperty", "p", "s", "ADD_ICE_CANDIDATE_FAILED", "AUDIO_MUTED_BY_FOCUS", "AUTHENTICATION_REQUIRED", "BRIDGE_DOWN", "CALL_ACCEPTED", "CALL_INCOMING", "CALL_ENDED", "CHAT_ERROR_RECEIVED", "CONFERENCE_PROPERTIES_CHANGED", "CONNECTION_ESTABLISHED", "CONNECTION_FAILED", "CONNECTION_INTERRUPTED", "CONNECTION_RESTORED", "CONNECTION_ICE_FAILED", "CONNECTION_STATUS_CHANGED", "DISPLAY_NAME_CHANGED", "EMUC_ROOM_ADDED", "EMUC_ROOM_REMOVED", "ETHERPAD", "FOCUS_DISCONNECTED", "FOCUS_LEFT", "GRACEFUL_SHUTDOWN", "ICE_RESTARTING", "ICE_RESTART_SUCCESS", "KICKED", "LOCAL_ROLE_CHANGED", "MEETING_ID_SET", "MESSAGE_RECEIVED", "PRIVATE_MESSAGE_RECEIVED", "MUC_MEMBER_BOT_TYPE_CHANGED", "MUC_DESTROYED", "MUC_JOINED", "MUC_MEMBER_JOINED", "MUC_MEMBER_LEFT", "MUC_LEFT", "MUC_ROLE_CHANGED", "MUC_LOCK_CHANGED", "PARTICIPANT_AUDIO_MUTED", "PARTICIPANT_VIDEO_MUTED", "PARTICIPANT_VIDEO_TYPE_CHANGED", "PARTCIPANT_FEATURES_CHANGED", "PASSWORD_REQUIRED", "PEERCONNECTION_READY", "PHONE_NUMBER_CHANGED", "PRESENCE_RECEIVED", "PRESENCE_STATUS", "PROMPT_FOR_LOGIN", "READY_TO_JOIN", "RECORDER_STATE_CHANGED", "REMOTE_STATS", "RENEGOTIATION_FAILED", "RESERVATION_ERROR", "ROOM_CONNECT_ERROR", "ROOM_CONNECT_NOT_ALLOWED_ERROR", "ROOM_JOIN_ERROR", "ROOM_MAX_USERS_ERROR", "SENDING_CHAT_MESSAGE", "SENDING_PRIVATE_CHAT_MESSAGE", "SESSION_ACCEPT_TIMEOUT", "SPEAKER_STATS_RECEIVED", "CONFERENCE_TIMESTAMP_RECEIVED", "START_MUTED_FROM_FOCUS", "SUBJECT_CHANGED", "SUSPEND_DETECTED", "TRANSCRIPTION_STATUS_CHANGED", "TRANSPORT_INFO", "VIDEO_SIP_GW_AVAILABILITY_CHANGED", "VIDEO_SIP_GW_SESSION_STATE_CHANGED", "ICE_CONNECTION_STATE_CHANGED", "JSON_MESSAGE_RECEIVED", "global", "global$1", "self", "_typeof", "obj", "iterator", "constructor", "_toConsumableArray", "arr", "Array", "isArray", "arr2", "length", "_arrayWithoutHoles", "iter", "toString", "from", "_iterableToArray", "TypeError", "_nonIterableSpread", "safe_add", "x", "y", "lsw", "str2binl", "str", "Error", "bin", "charCodeAt", "md5_cmn", "q", "a", "b", "num", "cnt", "md5_ff", "md5_gg", "md5_hh", "md5_ii", "core_md5", "len", "olda", "oldb", "oldc", "oldd", "MD5", "hexdigest", "binarray", "charAt", "binl2hex", "hash", "String", "fromCharCode", "binl2str", "core_sha1", "j", "olde", "w", "e", "rol", "safe_add$1", "sha1_ft", "sha1_kt", "core_hmac_sha1", "data", "bkey", "str2binb", "ipad", "opad", "concat", "binb2b64", "triplet", "binb2str", "SHA1", "b64_hmac_sha1", "b64_sha1", "str_hmac_sha1", "str_sha1", "utils", "out", "cookies", "cookieName", "expires", "domain", "path", "cookieObj", "isObj", "cookieValue", "escape", "unescape", "document", "cookie", "$build", "attrs", "Strophe", "Builder", "$iq", "$pres", "VERSION", "NS", "HTTPBIND", "BOSH", "CLIENT", "AUTH", "ROSTER", "PROFILE", "DISCO_INFO", "DISCO_ITEMS", "MUC", "SASL", "STREAM", "FRAMING", "BIND", "SESSION", "STANZAS", "XHTML_IM", "XHTML", "tags", "attributes", "blockquote", "br", "cite", "em", "img", "li", "ol", "span", "strong", "ul", "body", "css", "validTag", "tag", "validAttribute", "attribute", "validCSS", "style", "Status", "ERROR", "CONNECTING", "CONNFAIL", "AUTHENTICATING", "AUTHFAIL", "CONNECTED", "DISCONNECTED", "DISCONNECTING", "ATTACHED", "REDIRECT", "CONNTIMEOUT", "BINDREQUIRED", "ErrorCondition", "BAD_FORMAT", "CONFLICT", "MISSING_JID_NODE", "NO_AUTH_MECH", "UNKNOWN_REASON", "LogLevel", "DEBUG", "INFO", "WARN", "FATAL", "ElementType", "NORMAL", "TEXT", "CDATA", "FRAGMENT", "TIMEOUT", "SECONDARY_TIMEOUT", "addNamespace", "forEachChild", "elem", "elemName", "func", "childNodes", "childNode", "nodeType", "this", "isTagEqual", "el", "tagName", "_xmlGenerator", "_makeGenerator", "doc", "undefined", "implementation", "createDocument", "documentMode", "_getIEXmlDom", "appendChild", "createElement", "xmlGenerator", "docStrings", "ActiveXObject", "xmlElement", "node", "arguments", "arg", "xmlTextNode", "sort", "attr", "setAttribute", "k", "xmlescape", "text", "replace", "xmlunescape", "createTextNode", "xmlHtmlNode", "html", "DOMParser", "parseFromString", "async", "loadXML", "getText", "nodeValue", "copyElement", "nodeName", "_i", "createHtml", "toLowerCase", "getAttribute", "cssText", "cssAttrs", "split", "cssName", "cssValue", "push", "join", "_i2", "createDocumentFragment", "_i3", "_i4", "escapeNode", "unescapeNode", "getNodeFromJid", "jid", "indexOf", "getDomainFromJid", "bare", "getBareJidFromJid", "parts", "splice", "getResourceFromJid", "_handleError", "stack", "fatal", "sourceURL", "handler", "line", "message", "fileName", "lineNumber", "log", "level", "msg", "console", "error", "debug", "info", "warn", "serialize", "tree", "names", "keys", "map", "result", "reduce", "getNamedItem", "child", "_requestId", "_connectionPlugins", "addConnectionPlugin", "ptype", "xmlns", "nodeTree", "up", "parentNode", "moreattrs", "removeAttribute", "cnode", "impNode", "xmlGen", "importNode", "newElem", "h", "fragment", "innerHTML", "xhtml", "Handler", "type", "id", "options", "matchBareFromJid", "ignoreNamespaceFragment", "matchBare", "user", "getNamespace", "elNamespace", "namespaceMatch", "_this", "nsMatch", "isMatch", "elem_type", "run", "TimedHandler", "period", "lastCalled", "Date", "getTime", "reset", "Connection", "service", "_this2", "proto", "protocol", "_proto", "Websocket", "Bosh", "features", "_sasl_data", "do_session", "do_bind", "timedHandlers", "handlers", "removeTimeds", "removeHandlers", "addTimeds", "addHandlers", "protocolErrorHandlers", "HTTP", "websocket", "_idleTimeout", "_disconnectTimeout", "authenticated", "connected", "disconnecting", "do_authentication", "paused", "restored", "_data", "_uniqueId", "_sasl_success_handler", "_sasl_failure_handler", "_sasl_challenge_handler", "maxRetries", "setTimeout", "_onIdle", "registerSASLMechanisms", "mechanisms", "F", "init", "_reset", "_requests", "pause", "resume", "getUniqueId", "suffix", "uuid", "Math", "random", "addProtocolErrorHandler", "status_code", "callback", "connect", "pass", "wait", "hold", "route", "authcid", "authzid", "servtype", "connect_callback", "_changeConnectStatus", "_connect", "attach", "sid", "rid", "wind", "_attach", "restore", "_sessionCachingSupported", "_restore", "JSON", "sessionStorage", "setItem", "removeItem", "xmlInput", "xmlOutput", "rawInput", "rawOutput", "nextValidRid", "send", "_queueData", "_send", "flush", "clearTimeout", "sendPresence", "errback", "timeout", "_this3", "timeoutHandler", "addHandler", "stanza", "deleteTimedHandler", "addTimedHandler", "deleteHandler", "sendIQ", "_this4", "iqtype", "element", "_sendRestart", "_this5", "thand", "handRef", "hand", "SASLAnonymous", "SASLExternal", "SASLMD5", "SASLOAuthBearer", "SASLXOAuth2", "SASLPlain", "SASLSHA1", "forEach", "registerSASLMechanism", "mechanism", "disconnect", "reason", "pres", "_addSysTimedHandler", "_onDisconnectTimeout", "_disconnect", "_abortAllRequests", "_doDisconnect", "status", "condition", "plugin", "statusChanged", "err", "_dataRecv", "req", "raw", "_this6", "_reqToData", "strip", "pop", "_emptyQueue", "cond", "conflict", "getElementsByTagName", "UNKOWN_REASON", "newList", "_i5", "_hand", "_connect_cb", "_callback", "bodyWrap", "getElementsByTagNameNS", "matched", "mech", "authenticate", "_no_auth_received", "sortMechanismsByPriority", "higher", "priority", "swap", "_attemptSASLAuth", "_attemptLegacyAuth", "mechanism_found", "test", "_addSysHandler", "_sasl_success_cb", "_sasl_failure_cb", "_sasl_challenge_cb", "_sasl_mechanism", "onStart", "request_auth_exchange", "isClientFirst", "response", "onChallenge", "btoa", "challenge", "atob", "_onLegacyAuthIQResult", "to", "iq", "_auth2_cb", "_this7", "serverSignature", "matches", "match", "onSuccess", "streamfeature_handlers", "wrapper", "_onStreamFeaturesAfterSASL", "explicitResourceBinding", "_onResourceBindResultIQ", "resource", "jidNode", "_establishSession", "_onSessionResultIQ", "onFailure", "_this8", "now", "_i6", "_thand", "SASLMechanism", "connection", "_connection", "auth_str", "test_cnonce", "cnonce", "nonce", "salt", "Hi", "U", "U_old", "responseText", "authMessage", "attribMatch", "substr", "clientKey", "serverKey", "clientSignature", "_quote", "realm", "host", "digest_uri", "cred", "A1", "A2", "core", "$msg", "Strophe$1", "$build$1", "Request", "sends", "xmlData", "origFunc", "date", "NaN", "abort", "dead", "age", "timeDead", "xhr", "_newXHR", "getResponse", "responseXML", "documentElement", "querySelector", "textContent", "XMLHttpRequest", "overrideMimeType", "onreadystatechange", "_conn", "floor", "errors", "inactivity", "lastResponseHeaders", "_buildBody", "keepalive", "_cacheSession", "xml:lang", "content", "ver", "xmpp:version", "xmlns:xmpp", "_onRequestStateChange", "_throttledRequestHandler", "session", "parse", "getItem", "stringify", "typ", "parseInt", "_sendTerminate", "_callProtocolErrorHandlers", "reqStatus", "_getRequestStatus", "err_callback", "_hitError", "xmpp:restart", "time_elapsed", "def", "readyState", "getAllResponseHeaders", "valid_request", "too_many_retries", "_removeRequest", "reqIs0", "_restartRequest", "Number", "_processRequest", "primary_timeout", "isNaN", "secondary_timeout", "server_error", "content_type", "contentType", "open", "sync", "setRequestHeader", "withCredentials", "e2", "sendFunc", "customHeaders", "headers", "header", "backoff", "min", "pow", "abs", "Strophe$2", "$build$2", "new_service", "location", "pathname", "_buildStream", "version", "_check_streamerror", "connectstatus", "errorString", "_closeSocket", "socket", "WebSocket", "onopen", "_onOpen", "onerror", "_onError", "onclose", "_onClose", "onmessage", "_connect_cb_wrapper", "_handleStreamStart", "streamStart", "parsedMessage", "see_uri", "string", "_streamWrap", "_onMessage", "CLOSED", "close", "closeString", "code", "rawStanza", "search", "firstChild", "start", "startString", "__webpack_exports__", "AUDIO_INPUT_STATE_CHANGE", "AUTH_STATUS_CHANGED", "AVATAR_CHANGED", "BEFORE_STATISTICS_DISPOSED", "CONFERENCE_ERROR", "CONFERENCE_FAILED", "CONFERENCE_JOINED", "CONFERENCE_LEFT", "DATA_CHANNEL_OPENED", "DOMINANT_SPEAKER_CHANGED", "CONFERENCE_CREATED_TIMESTAMP", "DTMF_SUPPORT_CHANGED", "ENDPOINT_MESSAGE_RECEIVED", "JVB121_STATUS", "PARTICIPANT_KICKED", "LAST_N_ENDPOINTS_CHANGED", "LOCK_STATE_CHANGED", "SERVER_REGION_CHANGED", "NO_AUDIO_INPUT", "NOISY_MIC", "PARTICIPANT_CONN_STATUS_CHANGED", "PARTICIPANT_PROPERTY_CHANGED", "P2P_STATUS", "PROPERTIES_CHANGED", "START_MUTED_POLICY_CHANGED", "STARTED_MUTED", "TALK_WHILE_MUTED", "TRACK_ADDED", "TRACK_AUDIO_LEVEL_CHANGED", "TRACK_MUTE_CHANGED", "TRACK_REMOVED", "USER_JOINED", "USER_LEFT", "USER_ROLE_CHANGED", "USER_STATUS_CHANGED", "BOT_TYPE_CHANGED", "_BrowserCapabilities__WEBPACK_IMPORTED_MODULE_0__", "BrowserCapabilities", "Logger", "LogCollector", "idLoggers", "loggers", "curLevel", "levels", "TRACE", "addGlobalTransport", "transport", "removeGlobalTransport", "setGlobalOptions", "getLogger", "transports", "logger", "setLogLevelById", "setLevel", "setLogLevel", "__filename", "Statistics", "events__WEBPACK_IMPORTED_MODULE_0__", "events__WEBPACK_IMPORTED_MODULE_0___default", "_service_statistics_AnalyticsEvents__WEBPACK_IMPORTED_MODULE_1__", "_AnalyticsAdapter__WEBPACK_IMPORTED_MODULE_2__", "_CallStats__WEBPACK_IMPORTED_MODULE_3__", "_LocalStatsCollector__WEBPACK_IMPORTED_MODULE_4__", "_RTPStatsCollector__WEBPACK_IMPORTED_MODULE_5__", "_browser__WEBPACK_IMPORTED_MODULE_6__", "_util_ScriptUtil__WEBPACK_IMPORTED_MODULE_7__", "_util_ScriptUtil__WEBPACK_IMPORTED_MODULE_7___default", "_JitsiTrackError__WEBPACK_IMPORTED_MODULE_8__", "_service_statistics_Events__WEBPACK_IMPORTED_MODULE_9__", "require", "_instances", "isCallstatsLoaded", "_initCallStatsBackend", "CallStats", "isBackendInitialized", "initBackend", "callStatsID", "callStatsSecret", "userName", "aliasName", "applicationName", "getWiFiStatsMethod", "confID", "xmpp", "rtpStatsMap", "Map", "eventEmitter", "EventEmitter", "callStatsIntegrationEnabled", "disableThirdPartyRequests", "callStatsApplicationLogsDisabled", "browser", "isReactNative", "ScriptUtil", "loadScript", "customScriptUrl", "loadCallStatsAPI", "callStatsConfIDNamespace", "callsStatsInstances", "instances", "add", "audioLevelsEnabled", "disableAudioLevels", "pcStatsInterval", "audioLevelsInterval", "analytics", "Set", "startRemoteStats", "peerconnection", "stopRemoteStats", "rtpStats", "RTPStats", "set", "localStats", "startLocalStats", "stream", "LocalStats", "addAudioLevelListener", "listener", "on", "StatisticsEvents", "removeAudioLevelListener", "removeListener", "addBeforeDisposedListener", "removeBeforeDisposedListener", "addConnectionStatsListener", "removeConnectionStatsListener", "addByteSentStatsListener", "removeByteSentStatsListener", "dispose", "size", "emit", "callStats", "values", "stopCallStats", "tpc", "tpcId", "_stopRemoteStats", "removeAllListeners", "delete", "stopLocalStats", "stop", "startCallStats", "remoteUserID", "has", "newInstance", "_getCallStatsConfID", "_getAllCallStatsInstances", "csInstances", "statistics", "cs", "roomName", "callStatsInstance", "sendTerminateEvent", "isCallstatsEnabled", "sendConnectionResumeOrHoldEvent", "isResume", "instance", "sendResumeOrHoldEvent", "sendIceConnectionFailedEvent", "sendMuteEvent", "muted", "sendScreenSharingEvent", "ssrc", "sendDominantSpeakerEvent", "roomJid", "sendActiveDeviceListEvent", "devicesData", "globalSet", "associateStreamWithVideoTag", "isLocal", "userId", "usageLabel", "containerId", "sendGetUserMediaFailed", "JitsiTrackError", "gum", "constraintName", "constraints", "formatJitsiTrackErrorForCallStats", "sendCreateOfferFailed", "sendCreateAnswerFailed", "sendSetLocalDescFailed", "sendSetRemoteDescFailed", "sendAddIceCandidateFailed", "sendLog", "globalSubSet", "stats", "next", "csPerStats", "sendApplicationLog", "sendFeedback", "overall", "comment", "sendEvent", "FEEDBACK", "rating", "LOCAL_JID", "reportGlobalError", "sendAnalyticsAndLog", "event", "properties", "eventToLog", "sendAnalytics", "eventName", "jitsi_meet_logger__WEBPACK_IMPORTED_MODULE_0__", "_util_RandomUtil__WEBPACK_IMPORTED_MODULE_1__", "_util_RandomUtil__WEBPACK_IMPORTED_MODULE_1___default", "_browser__WEBPACK_IMPORTED_MODULE_2__", "SDPUtil", "filterSpecialChars", "iceparams", "mediadesc", "sessiondesc", "pwd", "ufrag", "findLine", "parseICEUfrag", "parseICEPwd", "substring", "buildICEUfrag", "frag", "buildICEPwd", "parseMID", "parseMLine", "media", "shift", "port", "fmt", "buildMLine", "mline", "parseRTPMap", "clockrate", "channels", "parseSCTPMap", "buildRTPMap", "parseCrypto", "parseFingerprint", "fingerprint", "parseFmtp", "parseICECandidate", "candidate", "elems", "foundation", "component", "ip", "generation", "tcptype", "network", "buildICECandidate", "cand", "hasOwnAttribute", "parseSSRC", "desc", "lines", "parseRTCPFB", "pt", "params", "parseExtmap", "direction", "uri", "haystack", "needle", "sessionpart", "findLines", "needles", "candidateToJingle", "candidateFromJingle", "isFirefox", "parsePrimaryVideoSsrc", "videoMLine", "numSsrcs", "ssrcs", "ssrcInfo", "filter", "index", "array", "numGroups", "ssrcGroups", "primarySsrc", "fidGroup", "find", "group", "semantics", "simGroup", "generateSsrc", "RandomUtil", "randomInt", "getSsrcAttribute", "mLine", "attributeName", "ssrcLine", "parseGroupSsrcs", "ssrcGroup", "ssrcStr", "getMedia", "sdp", "getUfrag", "ufragLines", "startsWith", "preferVideoCodec", "codecName", "payloadType", "rtp", "codec", "payload", "payloadTypes", "payloads", "payloadIndex", "unshift", "stripVideoCodec", "removePts", "rtxApts", "item", "rtxPts", "fmtp", "config", "keepPts", "rtcpFb", "TYPE_OPERATIONAL", "TYPE_PAGE", "TYPE_TRACK", "TYPE_UI", "ACTION_JINGLE_RESTART", "ACTION_JINGLE_SA_TIMEOUT", "ACTION_JINGLE_SI_RECEIVED", "ACTION_JINGLE_SI_TIMEOUT", "ACTION_JINGLE_TERMINATE", "ACTION_JINGLE_TR_RECEIVED", "ACTION_JINGLE_TR_SUCCESS", "ACTION_P2P_DECLINED", "ACTION_P2P_ESTABLISHED", "ACTION_P2P_FAILED", "ACTION_P2P_SWITCH_TO_JVB", "AVAILABLE_DEVICE", "CONNECTION_DISCONNECTED", "ICE_DURATION", "ICE_ESTABLISHMENT_DURATION_DIFF", "ICE_STATE_CHANGED", "NO_BYTES_SENT", "TRACK_UNMUTED", "createBridgeDownEvent", "action", "actionSubject", "createConnectionFailedEvent", "errorType", "errorMessage", "details", "_objectSpread", "error_type", "error_message", "createConferenceEvent", "source", "createConnectionStageReachedEvent", "stage", "createE2eRttEvent", "participantId", "region", "rtt", "participant_id", "createFocusLeftEvent", "createGetUserMediaEvent", "createParticipantConnectionStatusEvent", "createJingleEvent", "createNoDataFromSourceEvent", "mediaType", "media_type", "createP2PEvent", "createRemotelyMutedEvent", "createRtpStatsEvent", "createRttByRegionEvent", "createTransportStatsEvent", "createAudioOutputProblemEvent", "userID", "localAudioLevels", "remoteAudioLevels", "createBridgeChannelClosedEvent", "createTtfmEvent", "CREATE_ANSWER_FAILED", "CREATE_OFFER_FAILED", "DATA_CHANNEL_OPEN", "ENDPOINT_CONN_STATUS_CHANGED", "LASTN_ENDPOINT_CHANGED", "GRANTED_PERMISSIONS", "IS_SELECTED_CHANGED", "LASTN_VALUE_CHANGED", "LOCAL_TRACK_SSRC_UPDATED", "TRACK_ATTACHED", "REMOTE_TRACK_ADDED", "REMOTE_TRACK_MUTE", "REMOTE_TRACK_REMOVED", "REMOTE_TRACK_UNMUTE", "SET_LOCAL_DESCRIPTION_FAILED", "SET_REMOTE_DESCRIPTION_FAILED", "AUDIO_OUTPUT_DEVICE_CHANGED", "DEVICE_LIST_CHANGED", "DEVICE_LIST_WILL_CHANGE", "DEVICE_LIST_AVAILABLE", "LOCAL_UFRAG_CHANGED", "REMOTE_UFRAG_CHANGED", "AUDIO", "PRESENTER", "VIDEO", "usesAdapter", "AVAILABLE_DEVICES_POLL_INTERVAL_TIME", "OLD_GUM_DEFAULT_RESOLUTION", "OLD_GUM_DEFAULT_DEVICES", "DEFAULT_CONSTRAINTS", "video", "height", "ideal", "max", "SS_DEFAULT_FRAME_RATE", "audioOutputDeviceId", "audioOutputChanged", "disableAP", "disableAEC", "disableNS", "disableAGC", "disableHPF", "featureDetectionAudioEl", "isAudioOutputDeviceChangeAvailable", "setSinkId", "availableDevices", "availableDevicesPollTimer", "getConstraints", "um", "audio", "isNewStyleConstraintsSupported", "isSafari", "mandatory", "optional", "cameraDeviceId", "deviceId", "sourceId", "facingMode", "CameraFacingMode", "USER", "minFps", "maxFps", "fps", "minFrameRate", "maxFrameRate", "resolution", "Resolutions", "width", "minWidth", "minHeight", "maxWidth", "maxHeight", "setResolutionConstraints", "micDeviceId", "echoCancellation", "googEchoCancellation", "googAutoGainControl", "googNoiseSuppression", "googHighpassFilter", "googNoiseSuppression2", "googEchoCancellation2", "googAutoGainControl2", "isChrome", "getSSConstraints", "mozMediaSource", "mediaSource", "frameRate", "errmsg", "GlobalOnErrorHandler", "callErrorHandler", "isElectron", "screenShareAudio", "desktopStream", "chromeMediaSource", "chromeMediaSourceId", "bandwidth", "firefox_fake_device", "fake", "screen", "getTrackSSConstraints", "desktopSharingFrameRate", "updateGrantedPermissions", "audioTracksReceived", "Boolean", "getAudioTracks", "videoTracksReceived", "getVideoTracks", "grantedPermissions", "RTCEvents", "sendDeviceListToAnalytics", "deviceList", "audioInputDeviceCount", "kind", "audioOutputDeviceCount", "videoInputDeviceCount", "videoOutputDeviceCount", "device", "audio_input_device_count", "audio_output_device_count", "video_input_device_count", "video_output_device_count", "device_id", "device_group_id", "groupId", "device_kind", "device_label", "label", "rtcUtils", "Listenable", "super", "clearInterval", "enumerateDevices", "navigator", "mediaDevices", "then", "initEnumerateDevicesWithCallback", "usesNewGumFlow", "RTCPeerConnectionType", "RTCPeerConnection", "attachMediaStream", "wrapAttachMediaStream", "srcObject", "getStreamID", "getTrackID", "isChromiumBased", "src", "srcObjectPropertyName", "jitsiObjectURL", "URL", "createObjectURL", "defaultSetVideoSrc", "MediaStream", "videoTracks", "audioTracks", "_initPCConstraints", "screenObtainer", "getUserMediaWithConstraints", "isDeviceListAvailable", "ds", "updateKnownDevices", "pds", "newDevices", "mediaDeviceInfoToJSON", "facing", "compareAvailableMediaDevices", "devicesReceived", "slice", "onMediaDevicesListChanged", "supportsDeviceChangeEvent", "addEventListener", "setInterval", "pcConstraints", "googHighStartBitrate", "googPayloadPadding", "googScreencastMinBitrate", "googCpuOveruseDetection", "googCpuOveruseEncodeUsage", "googCpuUnderuseThreshold", "googCpuOveruseThreshold", "useIPv6", "googIPv6", "p2pPcConstraints", "Promise", "resolve", "reject", "getUserMedia", "catch", "_newGetUserMediaWithConstraints", "umDevices", "_newGetDesktopMedia", "isSupported", "supportsVideo", "obtainStream", "_parseDesktopSharingOptions", "obtainAudioAndVideoPermissions", "devices", "includes", "_getAudioAndVideoStreams", "streams", "audioStream", "videoStream", "res", "audioVideo", "addTrack", "desktop", "sourceType", "track", "MediaType", "videoType", "VideoType", "DESKTOP", "CAMERA", "handleLocalStream", "requestingDesktop", "avStream", "missingTracks", "_getMissingTracks", "stopMediaStream", "desktopSharingSourceDevice", "requestedDevices", "missingDevices", "audioDeviceRequested", "videoDeviceRequested", "desktopSharingExtensionExternalInstallation", "desktopSharingSources", "gumOptions", "trackOptions", "newObtainAudioAndVideoPermissions", "mediaStreamsMetaData", "maybeRequestDesktopDevice", "matchingDevice", "getTracks", "applyConstraints", "maybeRequestCaptureDevices", "requestedCaptureDevices", "newGetConstraints", "desktopAudioTracks", "desktopAudioStream", "desktopVideoTracks", "desktopVideoStream", "effects", "isDeviceChangeAvailable", "deviceType", "mediaStream", "release", "url", "revokeObjectURL", "isDesktopSharingEnabled", "setAudioOutputDevice", "getAudioOutputDevice", "getCurrentlyAvailableMediaDevices", "getEventDataForActiveDevice", "deviceData", "setSuspendVideo", "enable", "googSuspendBelowMinBitrate", "origAttachMediaStream", "apply", "ex", "callUnhandledRejectionHandler", "promise", "oldOnErrorHandler", "oldOnUnhandledRejection", "onunhandledrejection", "args", "errHandler", "peerConnectionIdCounter", "rtcTrackIdCounter", "createLocalTracks", "tracksInfo", "newTracks", "trackInfo", "safeCounterIncrement", "localTrack", "JitsiLocalTrack", "rtcId", "_newCreateLocalTracks", "mediaStreamMetaData", "metaData", "getSettings", "RTC", "conference", "peerConnections", "localTracks", "_channel", "_channelOpen", "_lastN", "_lastNEndpoints", "_maxFrameHeight", "_pinnedEndpoint", "_selectedEndpoints", "_lastNChangeListener", "_onLastNChanged", "_onDeviceListChanged", "_updateAudioOutputForAudioTracks", "RTCUtils", "addListener", "destroy", "_channelOpenListener", "[object Object]", "initializeBridgeChannel", "wsUrl", "BridgeChannel", "sendPinnedEndpointMessage", "sendSelectedEndpointsMessage", "sendReceiverVideoConstraintMessage", "_selectedEndpoint", "sendSetLastNMessage", "lastNEndpoints", "oldLastNEndpoints", "leavingLastNEndpoints", "enteringLastNEndpoints", "isInLastN", "JitsiConferenceEvents", "onCallEnded", "setReceiverVideoConstraint", "maxFrameHeight", "selectEndpoints", "ids", "pinEndpoint", "eventType", "createPeerConnection", "signaling", "iceConfig", "isP2P", "getPCConstraints", "abtestSuspendVideo", "addPermanentProperties", "supportsInsertableStreams", "forceEncodedAudioInsertableStreams", "forceEncodedVideoInsertableStreams", "supportsSdpSemantics", "sdpSemantics", "bundlePolicy", "newConnection", "TraceablePeerConnection", "_removePeerConnection", "traceablePeerConnection", "addLocalTrack", "getLastN", "getLocalVideoTrack", "localVideo", "getLocalTracks", "getLocalAudioTrack", "localAudio", "tracks", "getType", "getRemoteTracks", "remoteTracks", "pcRemoteTracks", "setAudioMute", "mutePromises", "audioTrack", "mute", "unmute", "all", "removeLocalTrack", "pos", "removeRemoteTracks", "owner", "removedTracks", "pcRemovedTracks", "elSelector", "isUserStreamById", "streamId", "closeBridgeChannel", "setAudioLevel", "audioLevel", "getTrackBySSRC", "isAudioTrack", "sendChannelMessage", "sendMessage", "setLastN", "remoteAudioTracks", "setAudioOutput", "CHROME_EXTENSION_GENERIC_ERROR", "CHROME_EXTENSION_INSTALLATION_ERROR", "CHROME_EXTENSION_USER_GESTURE_REQUIRED", "CHROME_EXTENSION_USER_CANCELED", "CONSTRAINT_FAILED", "ELECTRON_DESKTOP_PICKER_ERROR", "ELECTRON_DESKTOP_PICKER_NOT_FOUND", "FIREFOX_EXTENSION_NEEDED", "GENERAL", "NOT_FOUND", "PERMISSION_DENIED", "TRACK_IS_DISPOSED", "TRACK_NO_STREAM_FOUND", "UNSUPPORTED_RESOLUTION", "LOCAL_TRACK_STOPPED", "TRACK_AUDIO_OUTPUT_CHANGED", "TRACK_VIDEOTYPE_CHANGED", "NO_DATA_FROM_SOURCE", "_JitsiTrackErrors__WEBPACK_IMPORTED_MODULE_0__", "TRACK_ERROR_TO_MESSAGE_MAP", "JitsiTrackErrors", "constraint", "failedConstraintName", "getResolutionFromFailedConstraint", "SDP", "_browser__WEBPACK_IMPORTED_MODULE_0__", "_SDPUtil__WEBPACK_IMPORTED_MODULE_1__", "mediaI", "failICE", "removeTcpCandidates", "removeUdpCandidates", "getMediaSsrcMap", "mediaSSRCs", "tmp", "mediaindex", "mid", "linessrc", "idx", "containsSSRC", "medias", "mangle", "newdesc", "rtpmap", "removeSessionLines", "prefix", "removeMediaLines", "toJingle", "thecreator", "assrcline", "creator", "amidline", "afmtpline", "rtcpFbToJingle", "crypto", "required", "ssrcMap", "availableSsrc", "ssrcParameters", "ssrcSdpLine", "kv", "v", "ridLines", "usesRidsForSimulcast", "rids", "ridLine", "ridInfo", "senders", "transportToJingle", "sctpmap", "sctpAttrs", "number", "setup", "payloadtype", "subtype", "rtcpFbFromJingle", "each", "$", "fromJingle", "jingle", "sessionId", "groups", "contents", "_", "jingle2media", "sctp", "streamCount", "CHAT_ERROR", "CONFERENCE_DESTROYED", "CONFERENCE_MAX_USERS", "CONNECTION_ERROR", "NOT_ALLOWED_ERROR", "INCOMPATIBLE_SERVER_VERSIONS", "OFFER_ANSWER_FAILED", "PASSWORD_NOT_SUPPORTED", "SETUP_FAILED", "VIDEOBRIDGE_NOT_AVAILABLE", "_events", "_maxListeners", "isFunction", "isObject", "isUndefined", "defaultMaxListeners", "setMaxListeners", "er", "listeners", "context", "newListener", "warned", "trace", "once", "fired", "g", "list", "position", "listenerCount", "evlistener", "emitter", "DETECTOR_STATE_CHANGE", "VAD_NOISY_DEVICE", "VAD_REPORT_PUBLISHED", "VAD_SCORE_PUBLISHED", "VAD_TALK_WHILE_MUTED", "parser", "writer", "write", "parseFmtpConfig", "parseParams", "parsePayloads", "parseRemoteCandidates", "parseImageAttributes", "parseSimulcastStreamList", "STATUS_AVAILABLE", "STATUS_UNDEFINED", "STATUS_BUSY", "STATE_ON", "STATE_OFF", "STATE_PENDING", "STATE_RETRYING", "STATE_FAILED", "ERROR_NO_CONNECTION", "ERROR_SESSION_EXISTS", "CHROME", "OPERA", "FIREFOX", "INTERNET_EXPLORER", "SAFARI", "NWJS", "ELECTRON", "REACT_NATIVE", "UNKNOWN", "bowserNameToJitsiName", "Chrome", "Chromium", "Opera", "Firefox", "Internet Explorer", "Safari", "_detectElectron", "userAgent", "_detectNWJS", "_detectReactNative", "product", "_detect", "bowser", "browserInfo", "detectors", "getBrowserName", "getBrowserVersion", "_detectChromiumBased", "BrowserDetection", "_bowser", "Bowser", "getParser", "detectedBrowserInfo", "_name", "_version", "getName", "isOpera", "isIExplorer", "isNWJS", "getVersion", "_checkCondition", "checkTree", "satisfies", "isVersionGreaterThan", "isVersionLessThan", "isVersionEqualTo", "BrowserDetection_BrowserDetection", "browsers_namespaceObject", "removeEventListener", "off", "WRONG_STATE", "AUDIO_LEVEL", "BEFORE_DISPOSED", "BYTE_SENT_STATS", "CONNECTION_STATS", "parsePrimarySSRC", "parseSecondarySSRC", "SdpTransformWrap", "sdp_transform__WEBPACK_IMPORTED_MODULE_0__", "_getSSRCCount", "MLineWrap", "getSSRCAttrValue", "ssrcNumber", "attrName", "ssrcObj", "removeSSRC", "ssrcNum", "addSSRCAttribute", "findGroup", "findGroups", "findGroupByPrimarySSRC", "primarySSRC", "findSSRCByMSID", "msid", "getSSRCCount", "containsAnySSRCGroups", "getPrimaryVideoSsrc", "fecGroup", "getRtxSSRC", "getSSRCs", "getPrimaryVideoSSRCs", "videoSSRCs", "ssrcGroupInfo", "secondarySsrc", "dumpSSRCGroups", "removeGroupsWithSSRC", "groupInfo", "removeGroupsBySemantics", "replaceSSRC", "oldSSRC", "newSSRC", "addSSRCGroup", "rawSDP", "parsedSDP", "transform", "selectMedia", "selectedMLine", "toRawSDP", "LOCAL_STATS_UPDATED", "REMOTE_STATS_UPDATED", "nextValue", "MAX_SAFE_INTEGER", "calculateAverage", "valueArray", "filterPositiveValues", "ACTIONS", "ACCEPT", "INITIATE", "TERMINATE", "UNAVAILABLE", "1080", "order", "fullhd", "720", "hd", "960", "540", "qhd", "360", "640", "vga", "180", "320", "PENDING", "ACTIVE", "ENDED", "_util_GlobalOnErrorHandler__WEBPACK_IMPORTED_MODULE_1__", "_util_GlobalOnErrorHandler__WEBPACK_IMPORTED_MODULE_1___default", "wrtcFuncNames", "createOffer", "createAnswer", "setLocalDescription", "setRemoteDescription", "addIceCandidate", "iceConnectionFailure", "signalingError", "applicationLog", "fabricEvent", "fabricHold", "fabricResume", "audioMute", "audioUnmute", "videoPause", "videoResume", "fabricUsageEvent", "fabricStats", "fabricTerminated", "screenShareStart", "screenShareStop", "dominantSpeaker", "activeDeviceList", "DEFAULT_REMOTE_USER", "reportType", "EVENT", "MST_WITH_USERID", "_fabrics", "backend", "backendInitialized", "atLeastOneFabric", "defaultInstance", "fabrics", "hasFabric", "_addNewFabric", "_emptyReportQueue", "csInstance", "defaultConfID", "defaultPC", "report", "reportsQueue", "errorData", "_reportError", "pc", "eventData", "sendFabricEvent", "associateMstWithUserID", "callStatsId", "_error", "reportError", "theBackend", "tryCatchMethods", "methodName", "originalMethod", "theArguments", "debugMethods", "originalReportError", "exception", "CallStatsBackend", "callstats", "configParams", "_traceAndCatchBackendCalls", "applicationVersion", "siteID", "initialize", "_initCallback", "attachWifiStatsHandler", "addresses", "_reportEvent", "conferenceID", "sendUserFeedback", "fabricAttributes", "remoteEndpointType", "endpointType", "peer", "server", "ret", "addNewFabric", "fabricUsage", "multiplex", "_addNewFabricCallback", "success", "streamEndpointId", "_util_UsernameGenerator__WEBPACK_IMPORTED_MODULE_1__", "_util_UsernameGenerator__WEBPACK_IMPORTED_MODULE_1___default", "_callStatsUserName", "_machineId", "getLocalStorage", "storage", "localStorage", "_p8", "callStatsUserName", "username", "UsernameGenerator", "generateUsername", "generateCallStatsUserName", "machineId", "jitsiMeetId", "generateJitsiMeetId", "ALPHANUM", "randomElement", "randomHexDigit", "randomHexString", "randomAlphanumStr", "ConnectionPluginListenable", "_util_Listenable__WEBPACK_IMPORTED_MODULE_0__", "getConnectionPluginDefinition", "base", "DEFAULT_STUN_SERVERS", "JITSI_MEET_MUC_TYPE", "XMPP", "strophe_js__WEBPACK_IMPORTED_MODULE_1__", "_util_RandomUtil__WEBPACK_IMPORTED_MODULE_3__", "_util_RandomUtil__WEBPACK_IMPORTED_MODULE_3___default", "_JitsiConnectionErrors__WEBPACK_IMPORTED_MODULE_4__", "_JitsiConnectionEvents__WEBPACK_IMPORTED_MODULE_5__", "_strophe_emuc__WEBPACK_IMPORTED_MODULE_7__", "_strophe_jingle__WEBPACK_IMPORTED_MODULE_8__", "_strophe_util__WEBPACK_IMPORTED_MODULE_9__", "_strophe_ping__WEBPACK_IMPORTED_MODULE_10__", "_strophe_rayo__WEBPACK_IMPORTED_MODULE_11__", "_strophe_logger__WEBPACK_IMPORTED_MODULE_12__", "_util_Listenable__WEBPACK_IMPORTED_MODULE_13__", "_Caps__WEBPACK_IMPORTED_MODULE_14__", "_util_GlobalOnErrorHandler__WEBPACK_IMPORTED_MODULE_15__", "_util_GlobalOnErrorHandler__WEBPACK_IMPORTED_MODULE_15___default", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_16__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_16___default", "_XmppConnection__WEBPACK_IMPORTED_MODULE_17__", "urls", "token", "disconnectInProgress", "connectionTimes", "authenticatedUser", "initStropheUtil", "initStropheLogger", "enableWebsocketResume", "serviceUrl", "websocketKeepAlive", "XmppConnection", "createConnection", "bosh", "_initStrophePlugins", "caps", "Caps", "clientNode", "initFeaturesList", "ev", "addFeature", "disableRtx", "supportsRtx", "enableLipSync", "rayo", "isPingSupported", "_pingSupported", "getConnection", "connectionHandler", "credentials", "performance", "statusStr", "getStatusString", "XMPPEvents", "useStunTurn", "p2p", "getStunAndTurnCredentials", "_resetState", "pingJid", "getFeaturesAndIdentities", "identities", "PING", "ping", "startInterval", "identity", "speakerStatsComponentAddress", "conferenceDurationComponentAddress", "_onPrivateMessage", "password", "JitsiConnectionEvents", "anonymousConnectionFailed", "connectionFailed", "lastErrorMsg", "JitsiConnectionErrors", "stopInterval", "wasIntentionalDisconnect", "errMsg", "_getConnectionFailedReasonDetails", "lastErrorStatus", "getLastErrorStatus", "attaching", "anonymousdomain", "hosts", "configDomain", "hostname", "createRoom", "onCreateResource", "roomjid", "muc", "mucNickname", "emuc", "getJid", "getJingleLog", "getLog", "getXmppLog", "dial", "getSessions", "sessions", "disconnectListener", "_cleanupXmppConnection", "isUsingWebSocket", "evType", "sendUnavailableBeacon", "jvb", "iceServers", "p2pStunServers", "stunServers", "iceTransportPolicy", "MucConnectionPlugin", "JingleConnectionPlugin", "PingConnectionPlugin", "RayoConnectionPlugin", "deploymentInfo", "shard", "headersArr", "trim", "shard_changed", "suspend_time", "getPingSuspendTime", "time_since_last_success", "getTimeSinceLastSuccess", "room", "tryParseJSONAndVerify", "jsonString", "json", "jsonMessage", "parsedJson", "users", "created_timestamp", "PEER_MUTED_CHANGED", "PEER_VIDEO_TYPE_CHANGED", "CONNECTION_DROPPED_ERROR", "OTHER_ERROR", "SERVER_ERROR", "_util_Listenable__WEBPACK_IMPORTED_MODULE_3__", "_util_Retry__WEBPACK_IMPORTED_MODULE_4__", "_StropheLastSuccess__WEBPACK_IMPORTED_MODULE_5__", "Events", "CONN_STATUS_CHANGED", "_options", "_resumeRetryN", "_stropheConn", "_usesWebsocket", "_lastSuccessTracker", "LastSuccessTracker", "startTracking", "_status", "disco", "_stropheConnectionCb", "targetCallback", "blockCallback", "_maybeEnableStreamResume", "_maybeStartWSKeepAlive", "_tryResumingConnection", "_wsKeepAlive", "closeWebsocket", "_resumeTimeout", "streamManagement", "getResumeToken", "intervalWithJitter", "fetch", "sendBeacon", "resumeToken", "retryTimeout", "getJitterDelay", "ENVIRONMENT", "chromeExtInstalled", "chromeExtUpdateRequired", "gumFunction", "ScreenObtainer", "intChromeExtPromise", "desktopSharingChromeDisabled", "desktopSharingChromeExtId", "desktopSharingFirefoxDisabled", "_createObtainStreamMethod", "JitsiMeetNW", "obtainDesktopStream", "jitsiError", "obtainScreenOnElectron", "supportsGetDisplayMedia", "obtainScreenFromGetDisplayMedia", "append", "getWebStoreInstallUrl", "initInlineInstalls", "checkChromeExtInstalled", "installed", "updateRequired", "initChromeExtension", "obtainScreenFromExtension", "obtainScreenOnFirefox", "errorCallback", "streamCallback", "failCallback", "obtainWebRTCScreen", "JitsiMeetScreenObtainer", "openDesktopPicker", "desktopSharingChromeSources", "streamType", "onGetStreamResponse", "doGetStreamFromExtensionOptions", "chrome", "runtime", "getStream", "sources", "lastError", "doGetStreamFromExtension", "alert", "handleExternalInstall", "webStoreInstallUrl", "checkForChromeExtensionOnInterval", "checkAgain", "waitInterval", "retries", "currentRetries", "interval", "waitForExtensionAfterInstall", "getDisplayMedia", "applyConstraintsPromise", "videoTrack", "extVersion", "minVersion", "s1", "s2", "n1", "n2", "isUpdateRequired", "desktopSharingChromeMinExtVersion", "Function", "DEFAULT_NOT_IN_LAST_N_TIMEOUT", "DEFAULT_RTC_MUTE_TIMEOUT", "DEFAULT_RESTORING_TIMEOUT", "ParticipantConnectionStatus", "INACTIVE", "INTERRUPTED", "RESTORING", "ParticipantConnectionStatusHandler", "isConnectionActiveByJvb", "isRestoringTimedout", "isVideoMuted", "isVideoTrackFrozen", "supportsVideoMuteOnConnInterrupted", "rtc", "trackTimers", "connStatusFromJvb", "outOfLastNTimeout", "rtcMuteTimeout", "rtcMutedTimestamp", "enteredLastNTimestamp", "restoringTimers", "connectionStatusMap", "_getVideoFrozenTimeout", "_onEndpointConnStatusChanged", "onEndpointConnStatusChanged", "_onP2PStatus", "refreshConnectionStatusForAll", "_onUserLeft", "onUserLeft", "_onTrackRtcMuted", "onTrackRtcMuted", "_onTrackRtcUnmuted", "onTrackRtcUnmuted", "_onRemoteTrackAdded", "onRemoteTrackAdded", "_onRemoteTrackRemoved", "onRemoteTrackRemoved", "_onSignallingMuteChanged", "onSignallingMuteChanged", "_onTrackVideoTypeChanged", "onTrackVideoTypeChanged", "_onLastNValueChanged", "participantIds", "clearRtcMutedTimestamp", "endpointId", "isActive", "myUserId", "figureOutConnectionStatus", "_changeConnectionStatus", "participant", "newStatus", "getConnectionStatus", "getId", "_setConnectionStatus", "remoteTrack", "getParticipantId", "JitsiTrackEvents", "hasAnyVideoRTCMuted", "hasAnyVideoTrackWebRTCMuted", "participants", "getParticipants", "getParticipantById", "inP2PMode", "isP2PActive", "isRestoringTimedOut", "_isRestoringTimedout", "audioOnlyMode", "isConnActiveByJvb", "newState", "_getNewStateForP2PMode", "_getNewStateForJvbMode", "_clearRestoringTimer", "oldConnectionStatus", "connectionStatus", "nowMs", "maybeSendParticipantConnectionStatusEvent", "startedMs", "getTracksByMediaType", "participantConnectionStatus", "leavingLastN", "enteringLastN", "rTimer", "isMuted", "SDPUtils", "generateIdentifier", "localCName", "splitLines", "blob", "splitSections", "part", "getDescription", "sections", "getMediaSections", "matchPrefix", "parseCandidate", "address", "relatedAddress", "relatedPort", "tcpType", "usernameFragment", "writeCandidate", "toUpperCase", "parseIceOptions", "parseRtpMap", "parsed", "clockRate", "numChannels", "writeRtpMap", "preferredPayloadType", "writeExtmap", "headerExtension", "preferredId", "writeFmtp", "parameters", "param", "parseRtcpFb", "parameter", "writeRtcpFb", "rtcpFeedback", "fb", "parseSsrcMedia", "sp", "colon", "parseSsrcGroup", "getMid", "mediaSection", "algorithm", "getDtlsParameters", "role", "fingerprints", "writeDtlsParameters", "setupType", "fp", "parseCryptoLine", "cryptoSuite", "keyParams", "sessionParams", "writeCryptoLine", "writeCryptoKeyParams", "parseCryptoKeyParams", "keyMethod", "keySalt", "lifeTime", "mkiValue", "mkiLength", "getCryptoParameters", "getIceParameters", "writeIceParameters", "parseRtpParameters", "description", "codecs", "headerExtensions", "fecMechanisms", "rtcp", "rtpmapline", "fmtps", "writeRtpDescription", "maxptime", "extension", "parseRtpEncodingParameters", "encodingParameters", "hasRed", "hasUlpfec", "flows", "apt", "encParam", "codecPayloadType", "rtx", "fec", "maxBitrate", "parseRtcpParameters", "rtcpParameters", "remoteSsrc", "cname", "rsize", "reducedSize", "compound", "mux", "parseMsid", "spec", "planB", "msidParts", "parseSctpDescription", "maxMessageSize", "maxSizeLine", "sctpPort", "writeSctpDescription", "output", "generateSessionId", "writeSessionBoilerplate", "sessId", "sessVer", "sessUser", "writeMediaSection", "transceiver", "iceGatherer", "getLocalParameters", "dtlsTransport", "rtpSender", "rtpReceiver", "sendEncodingParameters", "getDirection", "getKind", "isRejected", "parseOLine", "sessionVersion", "netType", "addressType", "isValidSDP", "getFocusRecordingUpdate", "presence", "jibriStatus", "initiator", "recordingMode", "sessionID", "getHiddenDomainUpdate", "liveStreamViewURLContainer", "liveStreamViewURL", "modeContainer", "sessionIDContainer", "getSessionIdFromIq", "jibri", "getSessionId", "sessionIdContainer", "isFromFocus", "JingleSessionPC", "_service_statistics_AnalyticsEvents__WEBPACK_IMPORTED_MODULE_0__", "jitsi_meet_logger__WEBPACK_IMPORTED_MODULE_1__", "strophe_js__WEBPACK_IMPORTED_MODULE_2__", "_util_StringUtils__WEBPACK_IMPORTED_MODULE_3__", "_browser__WEBPACK_IMPORTED_MODULE_4__", "_JingleSession__WEBPACK_IMPORTED_MODULE_5__", "_JingleSessionState__WEBPACK_IMPORTED_MODULE_6__", "_SDP__WEBPACK_IMPORTED_MODULE_7__", "_SDPDiffer__WEBPACK_IMPORTED_MODULE_8__", "_SDPUtil__WEBPACK_IMPORTED_MODULE_9__", "_SignalingLayerImpl__WEBPACK_IMPORTED_MODULE_10__", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_11__", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_11___default", "_statistics_statistics__WEBPACK_IMPORTED_MODULE_12__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_13__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_13___default", "_util_AsyncQueue__WEBPACK_IMPORTED_MODULE_14__", "_XmppConnection__WEBPACK_IMPORTED_MODULE_16__", "IQ_TIMEOUT", "DEFAULT_MAX_STATS", "JingleSession", "jingleContents", "videoContents", "localJid", "remoteJid", "mediaConstraints", "isInitiator", "_bridgeSessionId", "_cachedOldLocalSdp", "_cachedNewLocalSdp", "_iceCheckingStartedTimestamp", "_gatheringStartedTimestamp", "_localVideoActive", "_remoteVideoActive", "_gatheringReported", "lasticecandidate", "closed", "signalingLayer", "SignalingLayerImpl", "modificationQueue", "AsyncQueue", "wasConnected", "establishmentDuration", "_xmppListeners", "onXmppStatusChanged", "_assertNotEnded", "state", "JingleSessionState", "doInitialize", "isReconnect", "wasstable", "webrtcIceUdpDisable", "webrtcIceTcpDisable", "pcOptions", "gatherStats", "maxstats", "capScreenshareBitrate", "disableSimulcast", "disableH264", "preferH264", "_abtestSuspendVideoEnabled", "enableLayerSuspension", "testing", "startSilent", "onicecandidate", "phase", "sendIceCandidate", "onsignalingstatechange", "signalingState", "connectionState", "oniceconnectionstatechange", "iceConnectionState", "signaling_state", "reconnect", "iceStarted", "onnegotiationneeded", "remoteDescription", "usesUnifiedPlan", "workFunction", "finishedCallback", "oldSdp", "localDescription", "_renegotiate", "newSdp", "notifyMySSRCUpdate", "setChatRoom", "isSelected", "setIsSelected", "localSDP", "ice", "sdpMLineIndex", "jcand", "errorMesssage", "usedrip", "dripContainer", "sendIceCandidates", "candidates", "initiatorJid", "cands", "sdpMid", "fingerprintLine", "newJingleErrorHandler", "sendIceFailedNotification", "sessionInfo", "addIceCandidates", "iceCandidates", "rtcCandidate", "RTCIceCandidate", "outerHTML", "iceCandidate", "readSsrcInfo", "ssrcElement", "setSSRCOwner", "i3", "ssrcInfoElement", "generateRecvonlySsrc", "acceptOffer", "jingleOffer", "failure", "setOfferAnswerCycle", "sendSessionAccept", "invite", "offerSdp", "sendSessionInitiate", "setAnswer", "jingleAnswer", "jingleOfferAnswerIq", "newRemoteSdp", "_processNewJingleOfferIq", "oldLocalSdp", "bridgeSessionId", "sendContentModify", "newLocalSdp", "replaceTransport", "jingleOfferElem", "originalOffer", "clone", "remove", "newFingerprint", "sendTransportAccept", "accept", "responder", "responderJid", "videoTransferActive", "newSendersValue", "sessionModify", "transportAccept", "medialines", "sendTransportReject", "transportReject", "terminate", "sendSessionTerminate", "sessionTerminate", "reasonDescription", "onTerminated", "reasonCondition", "reasonText", "_parseSsrcInfoFromSourceAdd", "sourceAddElem", "currentRemoteSdp", "addSsrcInfo", "i1", "i2", "addRemoteStream", "_addOrRemoveRemoteStream", "removeRemoteStream", "isAdd", "logPrefix", "addOrRemoveSsrcInfo", "_parseSsrcInfoFromSourceRemove", "_processRemoteAddSource", "_processRemoteRemoveSource", "offerIq", "remoteSdp", "removeSsrcInfo", "usesPlanB", "findIndex", "optionalRemoteSdp", "RTCSessionDescription", "_initiatorRenegotiate", "_responderRenegotiate", "answer", "offer", "replaceTrack", "oldTrack", "newTrack", "isVideoTrack", "clearRecvonlySsrc", "shouldRenegotiate", "newLocalSDP", "setMaxBitRate", "sourceRemoveElem", "ssrcLines", "_verifyNoSSRCChanged", "operationName", "oldSDP", "currentLocalSDP", "sdpDiff", "SDPDiffer", "addedMedia", "getNewMedia", "removedMedia", "addTrackAsUnmute", "_addRemoveTrackAsMuteUnmute", "removeTrackAsMute", "isMute", "oldLocalSDP", "removeTrackMute", "addTrackUnmute", "setMediaTransferActive", "audioActive", "videoActive", "logAudioStr", "logVideoStr", "isSessionActive", "audioActiveChanged", "setAudioTransferActive", "pcVideoActiveChanged", "setVideoTransferActive", "modifyContents", "newVideoSenders", "parseVideoSenders", "_modifyRemoteVideoActive", "remoteVideoSenders", "isRemoteVideoActive", "newSDP", "sdpDiffer", "request", "failureCb", "errResponse", "errorElSel", "errorReasonSel", "errorMsgSel", "getIceConnectionState", "clear", "finishCallback", "shutdown", "abTesting", "enableSuspendVideoTest", "_getInitiatorJid", "integerHash", "PERMISSION_PROMPT_IS_SHOWN", "LARGE_ARRAY_SIZE", "HASH_UNDEFINED", "argsTag", "boolTag", "dateTag", "funcTag", "genTag", "mapTag", "numberTag", "objectTag", "regexpTag", "setTag", "stringTag", "symbolTag", "arrayBufferTag", "dataViewTag", "float32Tag", "float64Tag", "int8Tag", "int16Tag", "int32Tag", "uint8Tag", "uint8ClampedTag", "uint16Tag", "uint32Tag", "reFlags", "reIsHostCtor", "reIsUint", "cloneableTags", "freeGlobal", "freeSelf", "freeExports", "freeModule", "moduleExports", "addMapEntry", "pair", "addSetEntry", "arrayReduce", "iteratee", "accumulator", "initAccum", "isHostObject", "mapToArray", "overArg", "setToArray", "uid", "arrayProto", "funcProto", "objectProto", "coreJsData", "maskSrcKey", "exec", "IE_PROTO", "funcToString", "objectToString", "reIsNative", "RegExp", "Buffer", "Uint8Array", "getPrototype", "getPrototypeOf", "objectCreate", "propertyIsEnumerable", "nativeGetSymbols", "getOwnPropertySymbols", "nativeIsBuffer", "isBuffer", "nativeKeys", "DataView", "getNative", "WeakMap", "nativeCreate", "dataViewCtorString", "toSource", "mapCtorString", "promiseCtorString", "setCtorString", "weakMapCtorString", "symbolProto", "symbolValueOf", "valueOf", "Hash", "entries", "entry", "ListCache", "MapCache", "Stack", "__data__", "arrayLikeKeys", "inherited", "isObjectLike", "isArrayLike", "isArrayLikeObject", "isArguments", "baseTimes", "skipIndexes", "isIndex", "assignValue", "objValue", "eq", "assocIndexOf", "baseClone", "isDeep", "isFull", "customizer", "isArr", "input", "initCloneArray", "copyArray", "getTag", "isFunc", "buffer", "copy", "cloneBuffer", "isPrototype", "initCloneObject", "copyObject", "getSymbols", "copySymbols", "baseAssign", "cloneFunc", "Ctor", "cloneArrayBuffer", "dataView", "byteOffset", "byteLength", "cloneDataView", "typedArray", "cloneTypedArray", "cloneMap", "regexp", "lastIndex", "cloneSet", "symbol", "initCloneByTag", "stacked", "props", "keysFunc", "symbolsFunc", "offset", "arrayPush", "baseGetAllKeys", "getAllKeys", "arrayEach", "subValue", "baseIsNative", "arrayBuffer", "newValue", "getMapData", "getValue", "cache", "pairs", "other", "ArrayBuffer", "ctorString", "isLength", "baseKeys", "_SDPUtil__WEBPACK_IMPORTED_MODULE_0__", "arrayEquals", "array1", "array2", "equals", "mySDP", "otherSDP", "myMedias", "othersMedias", "newMedia", "othersMediaIdx", "myMedia", "othersMedia", "otherSsrcGroup", "mySsrcGroup", "modify", "sdpMediaSsrcs", "modified", "mediaSsrc", "nv", "cachedSetTimeout", "cachedClearTimeout", "process", "defaultSetTimout", "defaultClearTimeout", "runTimeout", "fun", "currentQueue", "queue", "draining", "queueIndex", "cleanUpNextTick", "drainQueue", "marker", "runClearTimeout", "Item", "noop", "nextTick", "title", "env", "argv", "versions", "prependListener", "prependOnceListener", "binding", "cwd", "chdir", "dir", "umask", "LocalStatsCollector", "AudioContext", "webkitAudioContext", "intervalId", "intervalMilis", "suspend", "isLocalStatsSupported", "analyser", "createAnalyser", "smoothingTimeConstant", "fftSize", "createMediaStreamSource", "frequencyBinCount", "getByteTimeDomainData", "samples", "maxVolume", "parseFloat", "toFixed", "timeDomainDataToAudioLevel", "newLevel", "lastLevel", "diff", "animateLevel", "currentExecutingScript", "prepend", "relativeURL", "loadCallback", "script", "referenceNode", "scriptEl", "scriptSrc", "baseScriptSrc", "lastIndexOf", "onload", "insertBefore", "JitsiTrack", "_JitsiTrackEvents__WEBPACK_IMPORTED_MODULE_2__", "_service_RTC_MediaType__WEBPACK_IMPORTED_MODULE_3__", "_RTCUtils__WEBPACK_IMPORTED_MODULE_4__", "trackHandler2Prop", "track_mute", "track_unmute", "track_ended", "addMediaStreamInactiveHandler", "oninactive", "streamInactiveHandler", "trackMediaType", "containers", "disposed", "_streamInactiveHandler", "_setStream", "_setHandler", "_unregisterHandlers", "isWebRTCTrackMuted", "isLocalAudioTrack", "getOriginalStream", "getStreamId", "getTrack", "getTrackLabel", "getTrackId", "getUsageLabel", "_maybeFireTrackAttached", "container", "_onTrackAttach", "_attachTTFMTracker", "detach", "_onTrackDetach", "isScreenSharing", "active", "getMSID", "trackId", "createAudioContext", "AudioContextImpl", "TrackVADEmitter", "_RTC_RTC__WEBPACK_IMPORTED_MODULE_1__", "_webaudio_WebAudioUtils__WEBPACK_IMPORTED_MODULE_2__", "_DetectionEvents__WEBPACK_IMPORTED_MODULE_3__", "procNodeSampleRate", "vadProcessor", "jitsiLocalTrack", "_procNodeSampleRate", "_vadProcessor", "_localTrack", "_bufferResidue", "Float32Array", "_audioContext", "sampleRate", "getRequiredPCMFrequency", "_vadSampleSize", "getSampleLength", "_onAudioProcess", "_initializeAudioContext", "_audioSource", "_audioProcessingNode", "createScriptProcessor", "audioEvent", "inData", "inputBuffer", "getChannelData", "completeInData", "sampleTimestamp", "pcmSample", "vadScore", "calculateAudioFrameVAD", "timestamp", "score", "pcmData", "getDeviceId", "_connectAudioGraph", "onaudioprocess", "destination", "_disconnectAudioGraph", "_cleanupResources", "stopStream", "getDeviceLabel", "_destroyed", "E2E_RTT_CHANGED", "COMPARE_PARTIAL_FLAG", "COMPARE_UNORDERED_FLAG", "arrayTag", "asyncTag", "errorTag", "nullTag", "proxyTag", "undefinedTag", "typedArrayTags", "freeProcess", "nodeUtil", "nodeIsTypedArray", "isTypedArray", "arraySome", "predicate", "nativeObjectToString", "symToStringTag", "SetCache", "isArg", "isBuff", "isType", "baseGetTag", "isOwn", "unmasked", "getRawTag", "baseIsArguments", "baseIsEqual", "bitmask", "equalFunc", "objIsArr", "othIsArr", "objTag", "othTag", "objIsObj", "othIsObj", "isSameTag", "equalArrays", "convert", "isPartial", "equalByTag", "objIsWrapped", "othIsWrapped", "objUnwrapped", "othUnwrapped", "objProps", "objLength", "othLength", "skipCtor", "othValue", "compared", "objCtor", "othCtor", "equalObjects", "baseIsEqualDeep", "arrLength", "seen", "arrValue", "othIndex", "resIndex", "arrayFilter", "baseUnary", "ERROR_FEATURE_VERSION_MISMATCH", "strophe_js__WEBPACK_IMPORTED_MODULE_0__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_1__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_1___default", "_util_Listenable__WEBPACK_IMPORTED_MODULE_2__", "IDENTITY_PROPERTIES", "IDENTITY_PROPERTIES_FOR_COMPARE", "HASH", "compareIdentities", "some", "generateSha", "sortedIdentities", "accumulatedValue", "sortedFeatures", "feature", "versionToCapabilities", "jidToVersion", "rooms", "_addChatRoom", "_removeChatRoom", "CAPS", "_handleCaps", "_onMucMemberLeft", "_removeJidToVersionEntry", "submit", "_generateVersion", "removeFeature", "getFeatures", "_getDiscoInfo", "sha", "receivedNode", "category", "_fixChatRoomPresenceMap", "addToPresence", "_notifyVersionChanged", "_identities", "_features", "oldVersion", "ON", "OFF", "SIM_LAYER_RIDS", "TPCUtils", "sdp_transform__WEBPACK_IMPORTED_MODULE_1__", "sdp_transform__WEBPACK_IMPORTED_MODULE_1___default", "_browser__WEBPACK_IMPORTED_MODULE_3__", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_4__", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_4___default", "SIM_LAYER_1_RID", "SIM_LAYER_2_RID", "SIM_LAYER_3_RID", "simulcastEncodings", "scaleResolutionDownBy", "_ensureCorrectOrderOfSsrcs", "parsedSdp", "reorderedSsrcs", "_getStreamEncodings", "isSimulcastOn", "_insertUnifiedPlanSimulcastReceive", "usesSdpMungingForSimulcast", "simulcast_03", "simulcast", "simulcastLine", "transceiverInit", "sendEncodings", "addTransceiver", "getTransceivers", "receiver", "addStream", "setEncodings", "sender", "stopped", "localSSRCs", "_addedStreams", "_extractPrimarySSRC", "getParameters", "encodings", "setParameters", "transceivers", "encoding", "displayName", "isLocalStats", "_userId", "setDisplayName", "_isLocalStats", "setDominantSpeaker", "totalDominantSpeakerTime", "_dominantSpeakerStart", "_hasLeft", "getUserId", "getDisplayName", "newName", "isDominantSpeaker", "isNowDominantSpeaker", "timeElapsed", "getTotalDominantSpeakerTime", "total", "hasLeft", "markAsHasLeft", "IDENTITY_UPDATED", "__WEBPACK_AMD_DEFINE_RESULT__", "WINDOW", "JS_MD5_NO_WINDOW", "WEB_WORKER", "NODE_JS", "JS_MD5_NO_NODE_JS", "COMMON_JS", "JS_MD5_NO_COMMON_JS", "AMD", "ARRAY_BUFFER", "JS_MD5_NO_ARRAY_BUFFER", "HEX_CHARS", "EXTRA", "SHIFT", "OUTPUT_TYPES", "BASE64_ENCODE_CHAR", "blocks", "buffer8", "Uint32Array", "JS_MD5_NO_ARRAY_BUFFER_IS_VIEW", "isView", "createOutputMethod", "outputType", "Md5", "update", "createMethod", "method", "nodeWrap", "eval", "nodeMethod", "createHash", "digest", "sharedMemory", "h0", "h1", "h2", "h3", "bytes", "hBytes", "finalized", "hashed", "first", "notString", "lastByteIndex", "finalize", "bc", "da", "hex", "base64", "v1", "v2", "v3", "base64Str", "md5", "_JitsiTrack__WEBPACK_IMPORTED_MODULE_1__", "_JitsiTrackError__WEBPACK_IMPORTED_MODULE_2__", "_JitsiTrackErrors__WEBPACK_IMPORTED_MODULE_3__", "_JitsiTrackEvents__WEBPACK_IMPORTED_MODULE_4__", "_browser__WEBPACK_IMPORTED_MODULE_5__", "_RTCUtils__WEBPACK_IMPORTED_MODULE_6__", "_service_RTC_CameraFacingMode__WEBPACK_IMPORTED_MODULE_7__", "_service_RTC_CameraFacingMode__WEBPACK_IMPORTED_MODULE_7___default", "_service_RTC_MediaType__WEBPACK_IMPORTED_MODULE_8__", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_9__", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_9___default", "_service_RTC_VideoType__WEBPACK_IMPORTED_MODULE_10__", "_service_RTC_VideoType__WEBPACK_IMPORTED_MODULE_10___default", "_service_statistics_AnalyticsEvents__WEBPACK_IMPORTED_MODULE_11__", "_setEffectInProgress", "effect", "isEnabled", "_startStreamEffect", "_constraints", "_prevSetMuted", "_facingMode", "_trackEnded", "_hasSentData", "_testDataSent", "_realDeviceId", "_trackMutedTS", "_onDeviceListWillChange", "oldRealDeviceId", "_setRealDeviceIdFromDeviceList", "_onAudioOutputDeviceChanged", "_initNoDataFromSourceHandlers", "isEnded", "_isNoDataFromSourceEventsEnabled", "_fireNoDataFromSourceEvent", "track_type", "isReceivingData", "storedMSID", "_streamEffect", "_originalStream", "startEffect", "_stopStreamEffect", "stopEffect", "_switchStreamEffect", "setEffect", "cont", "removeTrack", "_queueSetMuted", "setMuted", "_setMuted", "logMuteInfo", "doesVideoMuteByStreamRemove", "enabled", "_removeStreamFromConferenceAsMute", "streamOptions", "getCameraFacingMode", "assign", "streamsInfo", "streamInfo", "_addStreamToConferenceAsUnmute", "_sendMuteStatus", "_addLocalTrackAsUnmute", "successCallback", "_removeLocalTrackAsMute", "_setConference", "_onByteSentStatsReceived", "bytesSent", "getConnectionState", "trackSettings", "_stopStreamInProgress", "_switchCamera", "_effectEnabled", "VADAudioAnalyser", "_JitsiConferenceEvents__WEBPACK_IMPORTED_MODULE_2__", "_TrackVADEmitter__WEBPACK_IMPORTED_MODULE_4__", "VAD_EMITTER_SAMPLE_RATE", "createVADProcessor", "_createVADProcessor", "_vadEmitter", "_isVADEmitterRunning", "_detectionServices", "_vadInitTracker", "_processVADScore", "_trackAdded", "_trackRemoved", "_trackMuteChanged", "addVADDetectionService", "vadService", "detector", "_stopVADEmitter", "_startVADEmitter", "processVADScore", "_changeDetectorsMuteState", "changeMuteState", "vadEmitter", "JibriSession", "_recordingXMLUtils__WEBPACK_IMPORTED_MODULE_1__", "_mode", "_setSessionID", "setStatus", "getError", "getID", "_sessionID", "getInitiator", "_initiator", "getLiveStreamViewURL", "_liveStreamViewURL", "getStatus", "getTerminator", "_terminator", "getMode", "setError", "setLiveStreamViewURL", "setInitiator", "setTerminator", "appData", "broadcastId", "focusMucJid", "_createIQ", "recordingXMLUtils", "_setErrorFromIq", "app_data", "recording_mode", "streamid", "you_tube_broadcast_id", "errorIq", "children", "AUDIO_PERMISSION_NAME", "PERMISSION_GRANTED_STATUS", "VIDEO_PERMISSION_NAME", "_eventEmitter", "_grantedPermissions", "JitsiMediaDevicesEvents", "_logOutputDevice", "_handleGrantedPermissions", "_permissionsApiSupported", "permissions", "query", "deviceID", "isDevicePermissionGranted", "supported", "promises", "results", "every", "permissionStatus", "isMultipleAudioInputSupported", "emitEvent", "consoleTransport", "globalTransports", "transportIdx", "globalOptions", "callerInfo", "disableCallerInfo", "fileLocation", "column", "getCallerInfo", "logPrefixes", "toISOString", "fullLogParts", "methods", "LOG", "webpackPolyfill", "deprecate", "paths", "grammar", "reg", "format", "u", "z", "rate", "sessionConfig", "raddr", "dir2", "RecordingResult", "AUDIO_WEBM", "AUDIO_OGG", "TrackRecorder", "recorder", "startTime", "startRecorder", "trackRecorder", "stopRecorder", "determineCorrectFileType", "MediaRecorder", "isTypeSupported", "AudioRecorder", "jitsiConference", "recorders", "fileType", "isRecording", "instantiateTrackRecorder", "updateNames", "originalStream", "createEmptyStream", "mimeType", "ondataavailable", "dataEvent", "recorderToRemove", "download", "Blob", "href", "click", "getRecordingResults", "getFileType", "getActiveAudioDevice", "_JitsiTrackEvents__WEBPACK_IMPORTED_MODULE_1__", "_RTC_RTC__WEBPACK_IMPORTED_MODULE_2__", "_statistics_statistics__WEBPACK_IMPORTED_MODULE_3__", "DETECTION_TIMEOUT", "audioDevices", "devicePromiseArray", "micDevice", "devicePromise", "allSettled", "outcomeArray", "successfulPromises", "rejectedPromises", "rejectReasons", "stopActiveDevices", "deviceLabel", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_1__", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_1___default", "_service_statistics_AnalyticsEvents__WEBPACK_IMPORTED_MODULE_2__", "_util_GlobalOnErrorHandler__WEBPACK_IMPORTED_MODULE_4__", "_util_GlobalOnErrorHandler__WEBPACK_IMPORTED_MODULE_4___default", "_areRetriesEnabled", "_closedFromClient", "datachannel", "createDataChannel", "_handleChannel", "_wsUrl", "_initWebSocket", "ws", "_startConnectionRetries", "timeoutS", "reload", "isOpen", "_retryTimeout", "_stopConnectionRetries", "_retryWebSocketConnection", "closeEvent", "OPEN", "colibriClass", "msgPayload", "jsonObject", "lastN", "pinnedEndpoint", "endpointIds", "selectedEndpoints", "maxFrameHeightPixels", "channel", "dominantSpeakerEndpoint", "endpoint", "MAX_CACHE_SIZE", "analyticsHandlers", "permanentProperties", "conferenceName", "user_agent", "browser_name", "setAnalyticsHandlers", "_setUserProperties", "_sendEvent", "setUserProperties", "setConferenceName", "conference_name", "_verifyRequiredFields", "objectType", "containerType", "objectId", "_maybeCacheEvent", "js_utils__WEBPACK_IMPORTED_MODULE_1__", "supportsP2P", "isUserInteractionRequiredForUnmute", "supportsBandwidthStatistics", "ondevicechange", "supportsLocalCandidateRttStatistics", "supportsRTTStatistics", "supportsRtpSender", "RTCRtpTransceiver", "_getChromiumBasedVersion", "RTCRtpSender", "createEncodedVideoStreams", "chromium", "ua", "default", "17", "getFirstMatch", "getSecondMatch", "matchAndReturnConst", "getWindowsVersionName", "getMacOSVersionName", "getAndroidVersionName", "getVersionPrecision", "compareVersions", "reverse", "getBrowserAlias", "BROWSER_ALIASES_MAP", "getBrowserTypeByAlias", "BROWSER_MAP", "18", "ENGINE_MAP", "OS_MAP", "PLATFORMS_MAP", "Amazon Silk", "Android Browser", "Bada", "BlackBerry", "Epiphany", "Focus", "Generic", "Google Search", "Googlebot", "K-Meleon", "Maxthon", "Microsoft Edge", "MZ Browser", "NAVER Whale Browser", "Opera Coast", "PhantomJS", "Puffin", "QupZilla", "QQ", "QQLite", "Sailfish", "Samsung Internet for Android", "SeaMonkey", "Sleipnir", "Swing", "Tizen", "UC Browser", "Vivaldi", "WebOS Browser", "WeChat", "Yandex Browser", "Roku", "amazon_silk", "android", "bada", "blackberry", "epiphany", "firefox", "focus", "generic", "googlebot", "google_search", "ie", "k_meleon", "maxthon", "edge", "mz", "naver", "opera", "opera_coast", "phantomjs", "puffin", "qupzilla", "qq", "qqlite", "safari", "sailfish", "samsung_internet", "seamonkey", "sleipnir", "swing", "tizen", "uc", "vivaldi", "webos", "wechat", "yandex", "tablet", "mobile", "tv", "WindowsPhone", "Windows", "MacOS", "iOS", "Android", "WebOS", "Linux", "ChromeOS", "PlayStation4", "EdgeHTML", "Blink", "Trident", "Presto", "Gecko", "WebKit", "90", "configurable", "writable", "getResult", "91", "_ua", "parsedResult", "getUA", "parseBrowser", "describe", "getBrowser", "getOS", "os", "parseOS", "getOSName", "getOSVersion", "getPlatform", "platform", "parsePlatform", "getPlatformType", "getEngine", "engine", "parseEngine", "getEngineName", "isOS", "isPlatform", "f", "isBrowser", "compareVersion", "isEngine", "is", "92", "93", "versionName", "94", "vendor", "model", "95", "StatsCollector", "_service_statistics_Events__WEBPACK_IMPORTED_MODULE_2__", "KEYS_BY_BROWSER_TYPE", "calculatePacketLoss", "lostPackets", "totalPackets", "round", "SsrcStats", "loss", "bitrate", "upload", "framerate", "ConferenceStats", "packetLoss", "statsInterval", "_browserType", "_usesPromiseGetStats", "_getStatValue", "_defineNewGetStatValueMethod", "_defineGetStatValueMethod", "baselineAudioLevelsReport", "currentAudioLevelsReport", "currentStatsReport", "previousStatsReport", "audioLevelReportHistory", "audioLevelsIntervalId", "conferenceStats", "audioLevelsIntervalMilis", "statsIntervalId", "statsIntervalMilis", "ssrc2stats", "browsers", "packetsReceived", "packetsLost", "packetsSent", "bytesReceived", "framerateMean", "receiveBandwidth", "sendBandwidth", "remoteAddress", "transportType", "localAddress", "activeConnection", "googFrameHeightReceived", "googFrameWidthReceived", "googFrameHeightSent", "googFrameWidthSent", "googFrameRateReceived", "googFrameRateSent", "audioInputLevel", "audioOutputLevel", "currentRoundTripTime", "remoteCandidateType", "localCandidateType", "setLoss", "setResolution", "addBitrate", "resetBitrate", "setFramerate", "startAudioLevelStats", "getStats", "processNewAudioLevelReport", "processAudioLevelReport", "processNewStatsReport", "processStatsReport", "itemStatByKey", "stat", "keyFromName", "getNonNegativeStat", "getStatValue", "byteSentStats", "localip", "conferenceStatsTransport", "selected", "local", "localCandidateId", "remote", "remoteCandidateId", "ipAddress", "portNumber", "candidateType", "before", "ssrcIds", "isRemote", "remoteSource", "ssrcStats", "isDownloadStream", "packetsNow", "packetsBefore", "packetsDiff", "packetsLostNow", "packetsLostBefore", "packetsLostDiff", "packetsTotal", "bytesReceivedNow", "bytesReceivedBefore", "nowBytesTransmitted", "timeMs", "bitrateReceivedKbps", "bitrateSentKbps", "_processAndEmitReport", "bitrateDownload", "bitrateUpload", "resolutions", "framerates", "audioBitrateDownload", "audioBitrateUpload", "videoBitrateDownload", "videoBitrateUpload", "userResolutions", "userFramerates", "avgAudioLevels", "localAvgAudioLevels", "avgAudioLevel", "sum", "currentValue", "getNonNegativeValue", "_calculateBitrate", "fieldName", "bytesNow", "bytesBefore", "bytesProcessed", "bitrateKbps", "nominated", "availableIncomingBitrate", "availableOutgoingBitrate", "remoteUsedCandidate", "localUsedCandidate", "localIp", "networkType", "frameHeight", "frameWidth", "framesPerSecond", "framesSent", "trackIdentifier", "getSsrcByTrackId", "getLocalSSRC", "dtlsRole", "_initialTrackId", "getCommonCapabilities", "localCapabilities", "remoteCapabilities", "commonCapabilities", "findCodecByPayloadType", "rtxCapabilityMatches", "lRtx", "rRtx", "lCodecs", "rCodecs", "lCodec", "rCodec", "lHeaderExtension", "rHeaderExtension", "isActionAllowedInSignalingState", "maybeAddCandidate", "iceTransport", "alreadyAdded", "getRemoteCandidates", "remoteCandidate", "addRemoteCandidate", "makeError", "NotSupportedError", "InvalidStateError", "InvalidAccessError", "OperationError", "edgeVersion", "addTrackToStreamAndFireEvent", "dispatchEvent", "MediaStreamTrackEvent", "fireAddTrack", "trackEvent", "Event", "_dispatchEvent", "_eventTarget", "canTrickleIceCandidates", "needNegotiation", "localStreams", "remoteStreams", "_localDescription", "_remoteDescription", "iceGatheringState", "usingBundle", "rtcpMuxPolicy", "hasTurn", "isString", "filterIceServers", "_iceGatherers", "iceCandidatePoolSize", "RTCIceGatherer", "gatherPolicy", "_config", "_sdpSessionId", "_sdpSessionVersion", "_dtlsRole", "_isClosed", "onaddstream", "ontrack", "onremovestream", "onconnectionstatechange", "onicegatheringstatechange", "ondatachannel", "_emitGatheringStateChange", "getConfiguration", "getLocalStreams", "getRemoteStreams", "_createTransceiver", "doNotAdd", "hasBundleTransport", "recvEncodingParameters", "associatedRemoteMediaStreams", "wantReceive", "_createIceAndDtlsTransports", "_maybeFireNegotiationNeeded", "clonedStream", "clonedTrack", "removeStream", "getSenders", "getReceivers", "_createIceGatherer", "bufferedCandidateEvents", "bufferCandidates", "end", "_gather", "onlocalcandidate", "evt", "serializedCandidate", "toJSON", "complete", "RTCIceTransport", "onicestatechange", "_updateIceConnectionState", "_updateConnectionState", "RTCDtlsTransport", "ondtlsstatechange", "_disposeIceAndDtlsTransports", "_transceive", "recv", "receive", "isIceLite", "rejected", "remoteIceParameters", "remoteDtlsParameters", "_updateSignalingState", "receiverList", "iceOptions", "remoteMsid", "isComplete", "setTransport", "setRemoteCandidates", "RTCRtpReceiver", "getCapabilities", "isNewTrack", "nativeTrack", "states", "new", "checking", "completed", "disconnected", "failed", "connecting", "numAudioTracks", "numVideoTracks", "offerOptions", "offerToReceiveAudio", "offerToReceiveVideo", "remoteCodec", "hdrExt", "rHdrExt", "getLocalCandidates", "mediaSectionsInOffer", "candidateString", "selector", "MediaStreamTrack", "senderOrReceiver", "allStats", "ortcObjectName", "nativeGetstats", "nativeStats", "mapStats", "inboundrtp", "outboundrtp", "candidatepair", "localcandidate", "remotecandidate", "nativeMethod", "_jitsi_sdp_interop__WEBPACK_IMPORTED_MODULE_1__", "sdp_transform__WEBPACK_IMPORTED_MODULE_2__", "sdp_transform__WEBPACK_IMPORTED_MODULE_2___default", "_util_GlobalOnErrorHandler__WEBPACK_IMPORTED_MODULE_3__", "_JitsiRemoteTrack__WEBPACK_IMPORTED_MODULE_4__", "_service_RTC_MediaType__WEBPACK_IMPORTED_MODULE_5__", "_LocalSdpMunger__WEBPACK_IMPORTED_MODULE_6__", "_RTC__WEBPACK_IMPORTED_MODULE_7__", "_RTCUtils__WEBPACK_IMPORTED_MODULE_8__", "_browser__WEBPACK_IMPORTED_MODULE_9__", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_10__", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_10___default", "_xmpp_RtxModifier__WEBPACK_IMPORTED_MODULE_11__", "_TPCUtils__WEBPACK_IMPORTED_MODULE_12__", "_xmpp_SDP__WEBPACK_IMPORTED_MODULE_13__", "_xmpp_SdpConsistency__WEBPACK_IMPORTED_MODULE_14__", "_xmpp_SdpTransformUtil__WEBPACK_IMPORTED_MODULE_15__", "_xmpp_SDPUtil__WEBPACK_IMPORTED_MODULE_16__", "_service_RTC_SignalingEvents__WEBPACK_IMPORTED_MODULE_17__", "audioTransferActive", "_dtmfSender", "_dtmfTonesQueue", "localUfrag", "remoteUfrag", "_peerVideoTypeChanged", "SignalingEvents", "_peerMutedChanged", "tpcUtils", "updateLog", "statsinterval", "interop", "Interop", "Simulcast", "numOfLayers", "explodeRemoteSimulcast", "sdpConsistency", "SdpConsistency", "localSdpMunger", "LocalSdpMunger", "rtxModifier", "RtxModifier", "what", "time", "_remoteStreamAdded", "_remoteStreamRemoved", "_remoteTrackAdded", "onremovetrack", "_remoteTrackRemoved", "_processStat", "statValue", "endTime", "times", "dumpSDP", "_getDesiredMediaDirection", "mediaTransferActive", "hasAnyTracksOfType", "_setVideoType", "setMute", "endpoints", "endpointTrackMap", "mediaTrack", "getSSRC", "findTrackById", "onaddtrack", "streamAudioTracks", "streamVideoTracks", "remoteSDP", "mediaLines", "mls", "trackSsrc", "ownerEndpointId", "getSSRCOwner", "peerMediaInfo", "getPeerMediaInfo", "_createRemoteTrack", "remoteTracksMap", "existingTrack", "JitsiRemoteTrack", "isUserStream", "_removeRemoteTrackById", "_getRemoteTrackById", "removedAudioTrack", "removedVideoTrack", "_removeRemoteTrack", "toBeRemoved", "normalizePlanB", "firstSsrcs", "newSsrcLines", "filteredLines", "ssrcId", "cnameLine", "replaceDefaultUnifiedPlanMsid", "resStr", "_getSSRC", "_injectSsrcGroupForUnifiedSimulcast", "getters", "toPlanB", "maybeAddMutedLocalVideoTracksToSDP", "transformer", "audioMedia", "changed", "videoMedia", "enforceSendRecv", "transformStreamIdentifiers", "prop", "webrtcStream", "_addStream", "generateNewStreamSSRCInfo", "setPrimarySsrc", "setSsrcCache", "fidGroups", "rtxSsrcMapping", "rtxSsrc", "_assertTrackBelongs", "webRtcStream", "_removeStream", "_handleSenderRemoveStream", "doesBelong", "isMediaStreamInPc", "findSenderByKind", "findSenderByStream", "findReceiverForTrack", "findSenderForTrack", "opts", "_ensureSimulcastGroupIsLast", "localSdp", "sdpStr", "videoStartIndex", "simStartIndex", "otherStartIndex", "simEndIndex", "simStr", "otherEndIndex", "sdpHead", "simStrTrimmed", "sdpTail", "_adjustLocalMediaDirection", "modifiedDirection", "desiredAudioDirection", "desiredVideoDirection", "toUnifiedPlan", "mungeRemoteDescription", "currentDescription", "sendTones", "tones", "duration", "interToneGap", "dtmf", "localAudioTrack", "createDTMFSender", "ontonechange", "_onToneChange", "toneBuffer", "insertDTMF", "tone", "clearVideoSsrcCache", "peerTracks", "hasCameraTrack", "peerConnection", "_createOfferOrAnswer", "isOffer", "logName", "handleSuccess", "resultSdp", "resolveFn", "rejectFn", "hasPrimarySsrcCached", "makeVideoPrimarySsrcsConsistent", "mungeLocalDescription", "modifyRtxSsrcs", "_fixAnswerRFC4145Setup", "groupsMap", "groupSSRCs", "extractSSRCMap", "_processLocalSSRCsMap", "handleFailure", "oaPromise", "trackMSID", "newSSRCNum", "oldSSRCNum", "currNumSsrcs", "videoSender", "simIndex", "handleLayerSuspension", "ttfmTrackerAudioAttached", "ttfmTrackerVideoAttached", "containerEvents", "hasBeenMuted", "_bindTrackHandlers", "_containerHandlers", "_containerEventHandler", "_onTrackMute", "_onTrackUnmute", "_playCallback", "getConnectionTimes", "gumStart", "gumEnd", "gumDuration", "ttfm", "_getStatus", "_service_RTC_MediaType__WEBPACK_IMPORTED_MODULE_1__", "_xmpp_SdpTransformUtil__WEBPACK_IMPORTED_MODULE_2__", "_addMutedLocalVideoTracksToSDP", "localVideos", "isInPeerConnection", "shouldFakeSdp", "requiredSSRCs", "ssrcCache", "cachedPrimarySsrc", "primaryCname", "modifyRtxSsrcs2", "_transformMediaIdentifiers", "pcId", "streamAndTrackIDs", "sessionDesc", "audioMLine", "_SdpTransformUtil__WEBPACK_IMPORTED_MODULE_1__", "_SDPUtil__WEBPACK_IMPORTED_MODULE_2__", "updateAssociatedRtxStream", "primarySsrcInfo", "primarySsrcMsid", "primarySsrcCname", "previousRtxSSRC", "correspondingRtxSsrcs", "clearSsrcCache", "ssrcMapping", "sdpTransformer", "primaryVideoSsrcs", "correspondingRtxSsrc", "previousAssociatedRtxStream", "stripRtx", "injectRecvOnly", "newPrimarySsrc", "AudioMixer", "_WebAudioUtils__WEBPACK_IMPORTED_MODULE_1__", "_started", "_streamsToMix", "_streamMSSArray", "addMediaStream", "_mixedMSD", "createMediaStreamDestination", "streamMSS", "AuthUtil", "getTokenAuthUrl", "urlPattern", "roleUpgrade", "JitsiConnection", "_JitsiConference__WEBPACK_IMPORTED_MODULE_1__", "_JitsiConnectionEvents__WEBPACK_IMPORTED_MODULE_2__", "_modules_statistics_statistics__WEBPACK_IMPORTED_MODULE_3__", "_modules_xmpp_xmpp__WEBPACK_IMPORTED_MODULE_4__", "appID", "errType", "ANALYTICS_CONNECTION_DISCONNECTED", "setToken", "initJitsiConference", "JitsiConference", "eventManager", "JitsiConferenceEventManager", "_init", "componentsVersions", "ComponentsVersions", "jvbJingleSession", "lastDominantSpeaker", "dtmfManager", "somebodySupportsDTMF", "authEnabled", "startAudioMuted", "startVideoMuted", "startMutedPolicy", "isMutedByFocus", "mutedByFocusActor", "wasStopped", "connectionQuality", "ConnectionQuality", "avgRtpStatsReporter", "AvgRTPStatsReporter", "avgRtpStatsN", "_audioOutputProblemDetector", "AudioOutputProblemDetector", "isJvbConnectionInterrupted", "speakerStatsCollector", "SpeakerStatsCollector", "deferredStartP2PTask", "delay", "backToP2PDelay", "isP2PConnectionInterrupted", "p2pJingleSession", "videoSIPGWHandler", "VideoSIPGW", "recordingManager", "RecordingManager", "_conferenceJoinAnalyticsEventSent", "_e2eeCtx", "E2EEContext", "resourceCreator", "isAuthenticatedUser", "setupXMPPListeners", "_statsCurrentId", "statisticsId", "Settings", "statsId", "_onIceConnectionInterrupted", "_onIceConnectionRestored", "_onIceConnectionEstablished", "_updateProperties", "_sendConferenceJoinAnalyticsEvent", "rttMonitor", "RttMonitor", "e2eping", "E2ePing", "setupRTCListeners", "_peerConnStatusRtcMuteTimeout", "_peerConnStatusOutOfLastNTimeout", "statisticsDisplayName", "callStatsCustomScriptUrl", "callstats_name", "setupChatRoomListeners", "setupStatisticsListeners", "enableTalkWhileMuted", "_audioAnalyser", "vadTalkMutedDetection", "VADTalkMutedDetection", "DetectionEvents", "_talkWhileMutedDetection", "TalkMutedDetection", "enableNoisyMicDetection", "vadNoiseDetection", "VADNoiseDetection", "enableNoAudioDetection", "_noAudioSignalDetection", "NoAudioSignalDetection", "hasAudioSignal", "channelLastN", "jvb121Status", "Jvb121EventGenerator", "p2pDominantSpeakerDetection", "P2PDominantSpeakerDetection", "userRegion", "setLocalParticipantProperty", "_maybeSetSITimeout", "authenticateAndUpgradeRole", "isJoined", "joined", "isP2PEnabled", "isP2PTestModeEnabled", "p2pTestMode", "leave", "onLocalTrackRemoved", "_delayedIceFailed", "cancel", "removeXMPPListeners", "onMemberLeft", "isAuthEnabled", "isLoggedIn", "authIdentity", "getAuthLogin", "isExternalAuthEnabled", "moderator", "getExternalAuthUrl", "urlForPopup", "getPopupLoginUrl", "getLoginUrl", "eventId", "addCommandListener", "command", "addPresenceListener", "removeCommandListener", "removePresenceListener", "sendTextMessage", "elementName", "getFromPresence", "sendPrivateTextMessage", "sendPrivateMessage", "sendCommand", "sendCommandOnce", "removeCommand", "removeFromPresence", "setSubject", "subject", "isModerator", "getTranscriber", "transcriber", "Transcriber", "localAudioTracks", "getTranscriptionStatus", "transcriptionStatus", "localVideoTrack", "_fireAudioLevelChangeEvent", "activeTpc", "getActivePeerConnection", "_fireMuteChangeEvent", "actorParticipant", "muteParticipant", "myroomjid", "actorId", "muteHandler", "audioLevelHandler", "_doReplaceTrack", "_setupNewTrack", "replaceTrackPromises", "setVideoMute", "addAsUnmutePromises", "removeAsMutePromises", "getRole", "isHidden", "hiddenDomain", "lock", "lockRoom", "JitsiConferenceErrors", "unlock", "selectParticipant", "selectParticipants", "pinParticipant", "isInteger", "RangeError", "isVideoActive", "getParticipantCount", "countHidden", "kickParticipant", "kick", "_maybeClearSITimeout", "_sessionInitiateTimeout", "onMemberJoined", "nick", "statsID", "botType", "JitsiParticipant", "_role", "_botType", "_updateFeatures", "_maybeStartOrStopP2P", "_supportsDTMF", "updateDTMFSupport", "setProperty", "_onMemberBotTypeChanged", "botParticipant", "onMemberKicked", "isSelfPresence", "kickedParticipantId", "kickedParticipant", "onLocalRoleChanged", "onUserRoleChanged", "onDisplayNameChanged", "_displayName", "_setupReceiverE2EEForTrack", "_tracks", "onCallAccepted", "_setupSenderE2EEForTrack", "onTransportInfo", "transportInfo", "removedTrack", "_onIncomingCallP2P", "jingleSession", "rejectReason", "errorMsg", "_shouldBeInP2PMode", "_rejectIncomingCall", "_acceptP2PIncomingCall", "onIncomingCall", "isFocus", "_acceptJvbIncomingCall", "serverRegion", "_setBridgeChannel", "_suspendMediaTransferForJvbConnection", "webSocket", "bridgeChannelType", "openBridgeChannel", "forceJvb121", "p2pFailed", "_stopP2PSession", "onSuspendDetected", "supportsDTMF", "isDTMFSupported", "startRecording", "stopRecording", "isSIPCallingSupported", "hangup", "startTranscriber", "stopTranscriber", "getPhoneNumber", "getPhonePin", "getMeetingUniqueId", "getMeetingId", "setStartMutedPolicy", "policy", "getStartMutedPolicy", "isStartAudioMuted", "isStartVideoMuted", "getLogs", "metadata", "removeLocalParticipantProperty", "getLocalParticipantProperty", "presMap", "nodes", "overallFeedback", "detailedFeedback", "remoteUserId", "_isFocus", "mucJid", "_fireIncompatibleVersionsEvent", "sendEndpointMessage", "broadcastEndpointMessage", "sendThroughVideobridge", "messageType", "messageToSend", "isConnectionInterrupted", "_onIceConnectionFailed", "IceFailedNotification", "remoteID", "getStatsID", "_addRemoteJVBTracks", "_addRemoteTracks", "_addRemoteP2PTracks", "p2pEstablishmentDuration", "jvbEstablishmentDuration", "done", "forceJVB121Ratio", "establishmentDurationDiff", "_setP2PStatus", "_removeRemoteJVBTracks", "isEqual", "getProperty", "_maybeClearDeferredStartP2P", "_removeRemoteTracks", "_removeRemoteP2PTracks", "sessionNickname", "_resumeMediaTransferForJvbConnection", "_startP2PSession", "newP2PJingleSession", "userLeftEvent", "peers", "peerCount", "shouldBeInP2P", "myId", "peersId", "hasBotPeer", "wasP2PEstablished", "getP2PConnectionState", "startP2PSession", "peerJid", "stopP2PSession", "getSpeakerStats", "createVideoSIPGWSession", "sipAddress", "VideoSIPGWConstants", "meetingId", "isE2EESupported", "setE2EEKey", "setKey", "handleSender", "handleReceiver", "_service_authentication_AuthenticationEvents__WEBPACK_IMPORTED_MODULE_2__", "_service_authentication_AuthenticationEvents__WEBPACK_IMPORTED_MODULE_2___default", "_modules_util_EventEmitterForwarder__WEBPACK_IMPORTED_MODULE_3__", "_modules_util_EventEmitterForwarder__WEBPACK_IMPORTED_MODULE_3___default", "jitsi_meet_logger__WEBPACK_IMPORTED_MODULE_4__", "_JitsiConferenceErrors__WEBPACK_IMPORTED_MODULE_5__", "_JitsiConferenceEvents__WEBPACK_IMPORTED_MODULE_6__", "_service_RTC_MediaType__WEBPACK_IMPORTED_MODULE_7__", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_8__", "_service_RTC_RTCEvents__WEBPACK_IMPORTED_MODULE_8___default", "_service_RTC_VideoType__WEBPACK_IMPORTED_MODULE_9__", "_service_RTC_VideoType__WEBPACK_IMPORTED_MODULE_9___default", "_modules_statistics_statistics__WEBPACK_IMPORTED_MODULE_10__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_11__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_11___default", "xmppListeners", "chatRoom", "chatRoomForwarder", "EventEmitterForwarder", "actor", "forward", "setParticipantPropertyListener", "recorderSession", "logObject", "AuthenticationEvents", "txt", "myJid", "ts", "updated", "featuresChangedListener", "_addConferenceXMPPListener", "audioMuted", "videoMuted", "ignoreStartMuted", "createdTimestamp", "dest", "srcEvent", "_modules_connectivity_ParticipantConnectionStatus__WEBPACK_IMPORTED_MODULE_3__", "_modules_xmpp_Caps__WEBPACK_IMPORTED_MODULE_4__", "hidden", "_jid", "_id", "_conference", "_hidden", "_statsID", "_connectionStatus", "_properties", "_identity", "getConference", "jitsiTrack", "oldValue", "isAudioMuted", "_isMediaTypeMuted", "_getFeaturesPromise", "getBotType", "_JitsiConnectionEvents__WEBPACK_IMPORTED_MODULE_0__", "_modules_xmpp_xmpp__WEBPACK_IMPORTED_MODULE_1__", "onLoginSuccessful", "roomPassword", "rejectPromise", "canceled", "authenticationError", "connectionError", "_ChatRoom__WEBPACK_IMPORTED_MODULE_2__", "_ConnectionPlugin__WEBPACK_IMPORTED_MODULE_3__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_4__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_4___default", "onPresence", "onPresenceUnavailable", "onPresenceError", "onMessage", "onMute", "ChatRoom", "doLeave", "createNonAnonymousRoom", "_util_GlobalOnErrorHandler__WEBPACK_IMPORTED_MODULE_2__", "_util_GlobalOnErrorHandler__WEBPACK_IMPORTED_MODULE_2___default", "_JitsiTranscriptionStatus__WEBPACK_IMPORTED_MODULE_3__", "_util_Listenable__WEBPACK_IMPORTED_MODULE_4__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_6__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_6___default", "_moderator__WEBPACK_IMPORTED_MODULE_7__", "_XmppConnection__WEBPACK_IMPORTED_MODULE_8__", "packet2JSON", "json2packet", "packet", "filterNodeFromPresenceJSON", "members", "presHandlers", "_removeConnListeners", "noBridgeAvailable", "Moderator", "initPresenceMap", "lastPresences", "phoneNumber", "phonePin", "participantPropertyListener", "locked", "JitsiTranscriptionStatus", "xns", "addVideoInfoToPresence", "disableFocus", "allocateConferenceFocus", "onConnStatusChanged", "fromJoin", "discoRoomInfo", "getInfo", "meetingIdValEl", "setMeetingId", "getForm", "form", "formSubmit", "var", "member", "statusEl", "hasStatusUpdate", "hasVersionUpdate", "xElement", "mucUserItem", "affiliation", "getFocusUserJid", "isHiddenDomain", "fromHiddenDomain", "xEl", "extractIdentityInformation", "userInfo", "newRole", "_initFocus", "memberOfThis", "displayJids", "att", "phone", "pin", "processNode", "tagHandlers", "nickname", "onParticipantLeft", "skipEvents", "onMucMemberLeft", "reasonSelect", "isKick", "membersKeys", "actorSelect", "actorNick", "subjectText", "stamp", "dateParts", "kickIQ", "onError", "onNotSupported", "formsubmit", "handlerIdx", "getMemberRole", "sendVideoInfoPresence", "sendAudioInfoPresence", "addAudioInfoToPresence", "getMediaPresenceInfo", "mutedNode", "videoTypeNode", "isSipGatewayEnabled", "iqToFocus", "onMucLeft", "doReject", "_settings_Settings__WEBPACK_IMPORTED_MODULE_1__", "createExpBackoffTimer", "step", "count", "origin", "xmppService", "getNextTimeout", "getNextErrorTimeout", "externalAuthEnabled", "sipGatewayEnabled", "call_control", "attachEvent", "setFocusUserJid", "focusJid", "focusUserJid", "getFocusComponent", "focusComponent", "createConferenceIq", "machineUID", "openSctp", "machine-uid", "session-id", "enforcedBridge", "enableTcc", "enableRemb", "minParticipants", "audioPacketDelay", "startBitrate", "minBitrate", "octo", "probability", "stereo", "useRoomAsSharedDocumentName", "parseSessionId", "resultIq", "parseConfigOptions", "authenticationEnabled", "_allocateConferenceFocusSuccess", "_allocateConferenceFocusError", "invalidSession", "reservationErr", "errorCode", "errorTextNode", "waitMs", "retrySec", "urlCallback", "failureCallback", "_getLoginUrl", "popup", "urlCb", "decodeURIComponent", "logout", "logoutUrl", "retry", "minDelay", "LastRequestTracker", "_lastSuccess", "stropheConnection", "originalRawInput", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_3__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_3___default", "_util_RandomUtil__WEBPACK_IMPORTED_MODULE_5__", "_util_RandomUtil__WEBPACK_IMPORTED_MODULE_5___default", "_statistics_statistics__WEBPACK_IMPORTED_MODULE_6__", "_JingleSessionPC__WEBPACK_IMPORTED_MODULE_7__", "_ConnectionPlugin__WEBPACK_IMPORTED_MODULE_8__", "ConnectionPlugin", "jvbIceConfig", "p2pIceConfig", "onJingle", "fromJid", "ack", "sess", "startMuted", "successTime", "me", "iceservers", "dict", "credential", "char", "_JingleSessionState__WEBPACK_IMPORTED_MODULE_1__", "getState", "addSources", "removeSources", "_service_RTC_SignalingEvents__WEBPACK_IMPORTED_MODULE_2__", "_service_RTC_SignalingLayer__WEBPACK_IMPORTED_MODULE_3__", "SignalingLayer", "ssrcOwners", "oldChatRoom", "_audioMuteHandler", "_videoMuteHandler", "_videoTypeHandler", "_modules_util_Listenable__WEBPACK_IMPORTED_MODULE_0__", "async__WEBPACK_IMPORTED_MODULE_0__", "async__WEBPACK_IMPORTED_MODULE_0___default", "_queue", "_processQueueTasks", "_stopped", "kill", "task", "setImmediate", "previous_async", "only_once", "fn", "called", "noConflict", "_toString", "_isArray", "_each", "_map", "_keys", "eachSeries", "iterate", "forEachSeries", "eachLimit", "limit", "_eachLimit", "forEachLimit", "started", "running", "replenish", "doParallel", "doSeries", "_asyncMap", "eachfn", "mapSeries", "mapLimit", "_mapLimit", "doParallelLimit", "memo", "inject", "foldl", "reduceRight", "reversed", "foldr", "_filter", "filterSeries", "select", "selectSeries", "_reject", "rejectSeries", "main_callback", "detect", "detectSeries", "any", "sortBy", "criteria", "left", "right", "auto", "tasks", "remainingTasks", "taskComplete", "theCallback", "taskCallback", "safeResults", "rkey", "requires", "ready", "attempts", "wrappedTask", "wrappedCallback", "wrappedResults", "retryAttempt", "finalAttempt", "seriesCallback", "series", "waterfall", "wrapIterator", "_parallel", "parallel", "parallelLimit", "makeCallback", "_concat", "cb", "concatSeries", "whilst", "doWhilst", "until", "doUntil", "worker", "concurrency", "_insert", "drain", "saturated", "workers", "empty", "idle", "priorityQueue", "_compareTasks", "sequence", "compare", "beg", "_binarySearch", "cargo", "working", "drained", "_console_fn", "memoize", "hasher", "queues", "memoized", "unmemoized", "unmemoize", "counter", "timesSeries", "seq", "fns", "that", "newargs", "nextargs", "compose", "_applyEach", "go", "applyEach", "applyEachSeries", "forever", "resetLastErrorStatusRegExpr", "lastErrorStatusRegExpr", "errStatusCapture", "PING_INTERVAL", "PING_TIMEOUT", "PING_THRESHOLD", "PING_TIMESTAMPS_TO_KEEP", "failedPings", "pingExecIntervals", "_addPingExecutionTimestamp", "pingIntervals", "maxInterval", "previousTS", "currentInterval", "_ConnectionPlugin__WEBPACK_IMPORTED_MODULE_2__", "RAYO_XMLNS", "onRayo", "roomPass", "callResource", "_ConnectionPlugin__WEBPACK_IMPORTED_MODULE_1__", "StropheLogger", "logIncoming", "logOutgoing", "_JitsiConferenceEvents__WEBPACK_IMPORTED_MODULE_0__", "SPEECH_DETECT_THRESHOLD", "_audioLevel", "myUserID", "_eventFired", "_isLocalAudioTrack", "_util_MathUtil__WEBPACK_IMPORTED_MODULE_1__", "_DetectionEvents__WEBPACK_IMPORTED_MODULE_2__", "VAD_AVG_THRESHOLD", "VAD_VOICE_LEVEL", "PROCESS_TIME_FRAME_SPAN_MS", "_processing", "_scoreArray", "_active", "_calculateVADScore", "_setActiveState", "_processTimeout", "VAD_NOISE_AVG_THRESHOLD", "NOISY_AUDIO_LEVEL_THRESHOLD", "VAD_SCORE_TRIGGER", "AUDIO_LEVEL_SCORE_TRIGGER", "_audioLvlArray", "_calculateNoisyScore", "scoreAvg", "audioLevelAvg", "_recordValues", "avgAudioLvl", "posAudioLevels", "_JitsiConferenceEvents__WEBPACK_IMPORTED_MODULE_1__", "SILENCE_PERIOD_MS", "_timeoutTrigger", "_hasAudioInput", "_clearTriggerTimeout", "_handleAudioInputStateChange", "_handleNoAudioInputDetection", "_audioTrack", "_service_connectivity_ConnectionQualityEvents__WEBPACK_IMPORTED_MODULE_0__", "jitsi_meet_logger__WEBPACK_IMPORTED_MODULE_2__", "STATS_MESSAGE_TYPE", "kSimulcastFormats", "layers", "target", "MAX_TARGET_BITRATE", "videoBitrateCap", "getTarget", "millisSinceStart", "simulcastFormat", "targetHeight", "pixels", "rampUp", "_localStats", "jvbRTT", "_lastConnectionQualityUpdate", "_remoteStats", "_timeIceConnected", "_timeVideoUnmuted", "_timeLastBwCapRemoved", "ConferenceEvents", "_updateLocalConnectionQuality", "ConnectionQualityEvents", "_broadcastLocalStats", "_updateRemoteStats", "_updateLocalStats", "_maybeUpdateUnmuteTime", "bridgeCount", "_calculateConnectionQuality", "resolutionName", "quality", "activeTPC", "newVideoBitrateCap", "bandwidthLimiter", "getBandwidthLimit", "maxIncreasePerSecond", "prevConnectionQuality", "diffSeconds", "updateLocalConnectionQuality", "_canceled", "_iceFailedTimeout", "E2EEcontext", "keyRingSize", "ivLength", "unencryptedBytes", "delta", "kJitsiE2EE", "_cryptoKeyRing", "_currentKeyIndex", "_sendCounts", "encoder", "TextEncoder", "_salt", "encode", "receiverStreams", "createEncodedAudioStreams", "TransformStream", "_decodeFunction", "readableStream", "pipeThrough", "pipeTo", "writableStream", "senderStreams", "_encodeFunction", "_deriveKey", "keyBytes", "material", "subtle", "importKey", "deriveKey", "iterations", "_makeIV", "synchronizationSource", "iv", "ivView", "sendCount", "setUint32", "encodedFrame", "controller", "keyIndex", "encrypt", "additionalData", "cipherText", "newData", "newUint8", "enqueue", "cipherTextStart", "cipherTextLength", "decrypt", "plainText", "_service_e2eping_E2ePingEvents__WEBPACK_IMPORTED_MODULE_2__", "_JitsiConferenceEvents__WEBPACK_IMPORTED_MODULE_3__", "_statistics_statistics__WEBPACK_IMPORTED_MODULE_4__", "E2E_PING_REQUEST", "E2E_PING_RESPONSE", "ParticipantWrapper", "requests", "lastRequestId", "clearIntervals", "sendRequest", "handleResponse", "maybeSendAnalytics", "isDataChannelOpen", "pingInterval", "pingIntervalMs", "analyticsInterval", "analyticsIntervalMs", "requestId", "requestMessage", "timeSent", "E2ePingEvents", "Infinity", "participantJoined", "participantLeft", "messageReceived", "dataChannelOpened", "participantWrapper", "handleRequest", "_jvb121", "evaluateStatus", "oldStatus", "_sessions", "_chatRoom", "getSession", "_handleFocusPresence", "_handleJibriPresence", "_addSession", "_emitSessionUpdate", "_createSession", "_RTC_RTCUtils__WEBPACK_IMPORTED_MODULE_3__", "stunKeepAliveIntervalMs", "PCMonitor", "getStatsIntervalMs", "getStatsInterval", "rtts", "startStatsInterval", "handleCandidateRtt", "rttTotal", "candidateKey", "responsesReceived", "requestsSent", "rttTotalDiff", "responsesReceivedDiff", "requestsResponsesDiff", "pcMonitors", "startPCMonitors", "initialDelay", "lodash_isequal__WEBPACK_IMPORTED_MODULE_0__", "lodash_isequal__WEBPACK_IMPORTED_MODULE_0___default", "_service_connectivity_ConnectionQualityEvents__WEBPACK_IMPORTED_MODULE_3__", "_JitsiConferenceEvents__WEBPACK_IMPORTED_MODULE_4__", "_statistics__WEBPACK_IMPORTED_MODULE_7__", "_service_RTC_VideoType__WEBPACK_IMPORTED_MODULE_8__", "AverageStatReport", "addNext", "calculate", "appendReport", "ConnectionAvgStats", "_n", "_sampleIdx", "_avgRTT", "_avgRemoteRTTMap", "_avgRtpStatsReporter", "_avgEnd2EndRTT", "_onConnectionStats", "_calculateAvgStats", "_onRemoteStatsUpdated", "_processRemoteStats", "batchReport", "conference_size", "local_candidate_type", "remote_candidate_type", "transport_type", "jvbEnd2EndRTT", "jvbStatsMonitor", "avgRemoteRTT", "_calculateAvgRemoteRTT", "avgLocalRTT", "_resetAvgStats", "remoteAvg", "avg", "validData", "rttAvg", "_avgAudioBitrateUp", "_avgAudioBitrateDown", "_avgVideoBitrateUp", "_avgVideoBitrateDown", "_avgBandwidthUp", "_avgBandwidthDown", "_avgPacketLossTotal", "_avgPacketLossUp", "_avgPacketLossDown", "_avgRemoteFPS", "_avgRemoteScreenFPS", "_avgLocalFPS", "_avgLocalScreenFPS", "_avgRemoteCameraPixels", "_avgRemoteScreenPixels", "_avgLocalCameraPixels", "_avgLocalScreenPixels", "_avgCQ", "_cachedTransportStats", "_onLocalStatsUpdated", "_maybeSendTransportAnalyticsEvent", "_onP2PStatusChanged", "p2pStatsMonitor", "_onJvb121StatusChanged", "_resetAvgJvbStats", "confSize", "_calculateAvgVideoFps", "_calculateAvgVideoPixels", "peerResolutions", "peerPixelsSum", "myID", "peerID", "videosResolution", "peerAvgPixels", "_calculatePeerAvgVideoPixels", "videos", "peerSsrcCount", "peerSsrcPixels", "peerFpsSum", "videosFps", "peerAvgFPS", "_calculatePeerAvgVideoFps", "peerSsrcFps", "transportStats", "_service_connectivity_ConnectionQualityEvents__WEBPACK_IMPORTED_MODULE_2__", "_service_statistics_AnalyticsEvents__WEBPACK_IMPORTED_MODULE_4__", "_statistics__WEBPACK_IMPORTED_MODULE_5__", "NUMBER_OF_LOCAL_SAMPLES", "_localAudioLevelCache", "_reportedParticipants", "_audioProblemCandidates", "_numberOfRemoteAudioLevelsReceived", "_onLocalAudioLevelsReport", "_onRemoteAudioLevelReceived", "_clearUserData", "numberOfReports", "localAudioLevelsString", "_SpeakerStats__WEBPACK_IMPORTED_MODULE_1__", "_SpeakerStats__WEBPACK_IMPORTED_MODULE_1___default", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_2__", "_service_xmpp_XMPPEvents__WEBPACK_IMPORTED_MODULE_2___default", "dominantSpeakerId", "SpeakerStats", "_onDominantSpeaker", "_onUserJoin", "_onUserLeave", "_onDisplayNameChange", "_updateStats", "oldDominantSpeaker", "newDominantSpeaker", "savedUser", "newStats", "speakerStatsToUpdate", "newParticipant", "SphinxService", "BEFORE_STATE", "audioRecorder", "transcriptionService", "transcription", "lineLength", "hasPopulatedArrays", "twoDimensionalArray", "callBack", "wordArray", "getUTCMilliseconds", "wordObject", "begin", "word", "maybeMerge", "recordingResult", "merge", "arrays", "potentialWords", "pushWordToSortedArray", "lowestWordArray", "wordToAdd", "updateTranscription", "foundSmaller", "wordToCompare", "getTranscription", "_statistics_statistics__WEBPACK_IMPORTED_MODULE_0__", "processVersions", "mucResource", "getComponentVersion", "componentName", "_JitsiVideoSIPGWSession__WEBPACK_IMPORTED_MODULE_1__", "_VideoSIPGWConstants__WEBPACK_IMPORTED_MODULE_2__", "sessionStateChangeListener", "sessionStateChanged", "handleJibriSIPState", "Constants", "sipaddress", "setState", "failure_reason", "JitsiVideoSIPGWSession", "addStateListener", "removeStateListener", "_VideoSIPGWConstants__WEBPACK_IMPORTED_MODULE_3__", "STATE_CHANGED", "_sendJibriIQ", "failureReason", "oldState", "displayname", "BUSY", "RESOURCE_CONSTRAINT", "SERVICE_UNAVAILABLE", "FILE", "ProxyConnectionService", "jitsiConnection", "otherOptions", "_objectWithoutProperties", "_peerConnection", "_onFatalError", "_onSendMessage", "_onRemoteStream", "processMessage", "getPeerJid", "_convertStringToXML", "$jingle", "_createPeerConnection", "receiveVideo", "_selfCloseConnection", "xml", "xmlDom", "onRemoteStream", "onSendMessage", "ProxyConnectionPC", "jitsiRemoteTrack", "isVideo", "convertVideoToDesktop", "jitsiLocalTracks", "newCreateLocalTracks", "stringifiedIq", "XMLSerializer", "serializeToString", "onConnectionClosed", "receiveAudio", "_onSessionAccept", "_onSessionInitiate", "_onSessionTerminate", "_onTransportInfo", "connectionStub", "iceConfigStub", "roomStub", "_rtc", "lib_default", "found", "PLAN_B_MIDS", "findSimGroup", "grp", "findFidGroup", "addSimGroupSources", "sourceGroups", "sourceList", "findSourcebyId", "relatedFidGroup", "relatedSsrc", "addSourcesToMline", "otherSsrc", "simGroup2", "checkIfMlineForSsrcExists", "mlines", "interop_Interop", "sessionMedia", "bLine", "lodash_clonedeep_default", "bundle", "mids", "msidSemantic", "semantic", "current", "currentDesc", "newMline", "mLineForData", "ssrc2group", "createSourceGroupMap", "bundleOnly", "inactiveMid", "cmLine", "_modules_detection_ActiveDeviceDetector__WEBPACK_IMPORTED_MODULE_0__", "_modules_webaudio_AudioMixer__WEBPACK_IMPORTED_MODULE_1__", "_modules_detection_DetectionEvents__WEBPACK_IMPORTED_MODULE_2__", "_modules_detection_TrackVADEmitter__WEBPACK_IMPORTED_MODULE_3__", "_modules_util_AuthUtil__WEBPACK_IMPORTED_MODULE_5__", "_modules_util_AuthUtil__WEBPACK_IMPORTED_MODULE_5___default", "_service_connectivity_ConnectionQualityEvents__WEBPACK_IMPORTED_MODULE_6__", "_service_e2eping_E2ePingEvents__WEBPACK_IMPORTED_MODULE_7__", "_modules_util_GlobalOnErrorHandler__WEBPACK_IMPORTED_MODULE_8__", "_modules_util_GlobalOnErrorHandler__WEBPACK_IMPORTED_MODULE_8___default", "_JitsiConferenceErrors__WEBPACK_IMPORTED_MODULE_9__", "_JitsiConferenceEvents__WEBPACK_IMPORTED_MODULE_10__", "_JitsiConnection__WEBPACK_IMPORTED_MODULE_11__", "_JitsiConnectionErrors__WEBPACK_IMPORTED_MODULE_12__", "_JitsiConnectionEvents__WEBPACK_IMPORTED_MODULE_13__", "_JitsiMediaDevices__WEBPACK_IMPORTED_MODULE_14__", "_JitsiMediaDevicesEvents__WEBPACK_IMPORTED_MODULE_15__", "_JitsiTrackError__WEBPACK_IMPORTED_MODULE_16__", "_JitsiTrackErrors__WEBPACK_IMPORTED_MODULE_17__", "_JitsiTrackEvents__WEBPACK_IMPORTED_MODULE_18__", "_JitsiTranscriptionStatus__WEBPACK_IMPORTED_MODULE_19__", "_modules_statistics_LocalStatsCollector__WEBPACK_IMPORTED_MODULE_20__", "jitsi_meet_logger__WEBPACK_IMPORTED_MODULE_21__", "jitsi_meet_logger__WEBPACK_IMPORTED_MODULE_21___default", "_service_RTC_MediaType__WEBPACK_IMPORTED_MODULE_22__", "_service_RTC_Resolutions__WEBPACK_IMPORTED_MODULE_23__", "_service_RTC_Resolutions__WEBPACK_IMPORTED_MODULE_23___default", "_modules_connectivity_ParticipantConnectionStatus__WEBPACK_IMPORTED_MODULE_24__", "_modules_RTC_RTC__WEBPACK_IMPORTED_MODULE_25__", "_modules_browser__WEBPACK_IMPORTED_MODULE_26__", "_modules_util_ScriptUtil__WEBPACK_IMPORTED_MODULE_27__", "_modules_util_ScriptUtil__WEBPACK_IMPORTED_MODULE_27___default", "_modules_recording_recordingConstants__WEBPACK_IMPORTED_MODULE_28__", "_modules_proxyconnection_ProxyConnectionService__WEBPACK_IMPORTED_MODULE_29__", "_modules_statistics_statistics__WEBPACK_IMPORTED_MODULE_30__", "_modules_videosipgw_VideoSIPGWConstants__WEBPACK_IMPORTED_MODULE_31__", "getAnalyticsAttributesFromOptions", "audio_requested", "video_requested", "screen_sharing_requested", "_mergeNamespaceAndModule", "constants", "recording", "recordingConstants", "sipVideoGW", "events", "detection", "errorTypes", "logLevels", "JitsiMediaDevices", "enableAnalyticsLogging", "enableWindowOnErrorHandler", "getGlobalOnErrorHandler", "aprops", "isWebRtcSupported", "addGlobalLogTransport", "globalTransport", "removeGlobalLogTransport", "setGlobalLogOptions", "firePermissionPromptIsShownEvent", "originalOptions", "promiseFulfilled", "mStream", "currentlyAvailableMediaDevices", "setVideoTrackContentHints", "oldResolution", "newResolution", "resName", "getLowerResolution", "old_resolution", "new_resolution", "createTrackVADEmitter", "localAudioDeviceId", "createAudioMixer", "isCollectingLocalStats", "lineno", "colno", "hint", "contentHint", "util", "JitsiMeetJS", "logStorage", "stringifyObjects", "storeInterval", "maxEntryLength", "logLevel", "_log", "storeLogsIntervalID", "totalLen", "outputCache", "someObject", "formatLogMessage", "prevMessage", "_flush", "_reschedulePublishInterval", "force", "reschedule", "isReady", "cachedQueue", "storeLogs", "__webpack_amd_options__", "__WEBPACK_AMD_DEFINE_FACTORY__", "__WEBPACK_AMD_DEFINE_ARRAY__", "scriptReadyRegex", "fullPageUrl", "pageUrl", "scripts", "supportsScriptReadyState", "isNotOpera", "hasNativeCurrentScriptAccessor", "stackTraceLimit", "hasStackBeforeThrowing", "hasStackAfterThrowing", "_nearestExecutingScript", "eligibleScripts", "skipStackDepth", "getScriptUrlFromStack", "remainingStack", "ignoreMessage", "getScriptFromUrl", "hasAttribute", "getSoleInlineScript", "currentScript", "thrownErr", "near", "far", "toIntIfInt", "parseReg", "needsBlank", "keyLocation", "rawName", "attachProperties", "validLine", "paramReducer", "acc", "expr", "scid", "formatRegExp", "makeLine", "formatStr", "defaultOuterOrder", "defaultInnerOrder", "outerOrder", "innerOrder", "transformUtils", "parseSsrcs", "writeSsrcs", "DEFAULT_NUM_OF_LAYERS", "processVideo", "validateDescription", "_parseSimLayers", "_buildNewToOldSsrcMap", "newSsrcList", "oldSsrcList", "newSsrc", "oldSsrc", "_fillInSourceDataFromCache", "newSimSsrcs", "newMsid", "newCname", "ssrcsToReplace", "ssrcsToAdd", "_generateSourceData", "addAssociatedStream", "simSsrcs", "simSsrc", "_restoreSimulcast", "simulcastSsrcs", "relatedGroup", "relatedSsrcs", "relatedSSRC", "simulcastGroup", "nuke", "implodeRemoteSimulcast", "invalid", "assertGoogConference", "strophe_js", "_items", "conn", "_onDiscoInfo", "_onDiscoItems", "addIdentity", "lang", "var_name", "addItem", "call_back", "items", "_buildIQResult", "query_attrs", "iqresult", "logging", "autoSendCountOnEveryIncomingStanza", "requestResponseInterval", "_c", "_NS", "_isStreamManagementEnabled", "_serverProcesssedStanzasCounter", "_clientProcessedStanzasCounter", "_clientSentStanzasCounter", "_originalXMLOutput", "_requestHandler", "_incomingHandler", "_requestResponseIntervalCount", "_isSupported", "_unacknowledgedStanzas", "_acknowledgedStanzaListeners", "addAcknowledgedStanzaListener", "_resumeToken", "_resuming", "_originalConnect", "_connectArgs", "requestAcknowledgement", "getOutgoingCounter", "getIncomingCounter", "_interceptConnectArgs", "_originalOnStreamFeaturesAfterSASL", "_originalDoDisconnect", "_interceptDoDisconnect", "_originalDisconnect", "_interceptDisconnect", "_resumeState", "_storedJid", "previd", "_handleServerRequestHandler", "_ackHandler", "_handleServerAck", "_incomingStanzaHandler", "_enabledHandler", "_handleEnabled", "_resumeFailedHandler", "_handleResumeFailed", "_resumedHandler", "_handleResumed", "_increaseSentStanzasCounter", "firstElementChild", "handledCount", "_handleAcknowledgedStanzas", "_increaseReceivedStanzasCounter", "_answerProcessedStanzas", "reportedHandledCount", "lastKnownHandledCount", "_throwError", "scope", "Timeout", "clearFn", "_clearFn", "unref", "ref", "enroll", "msecs", "_idleTimeoutId", "unenroll", "_unrefActive", "_onTimeout", "clearImmediate", "registerImmediate", "messagePrefix", "onGlobalMessage", "nextHandle", "tasksByHandle", "currentlyRunningATask", "attachTo", "handle", "runIfPresent", "postMessage", "importScripts", "postMessageIsAsynchronous", "oldOnMessage", "canUsePostMessage", "MessageChannel", "port1", "port2", "removeChild", "TranscriptionService", "Word", "sphinxURL", "toReturn", "getURL", "audioFileBlob", "DONE", "formatResponse", "objects", "filler", "verify", "audioBlob", "getWord", "getBeginTime", "getEndTime", "logDisabled_", "deprecationWarnings_", "extractVersion", "uastring", "wrapPeerConnectionEvent", "eventNameToWrap", "nativeAddEventListener", "nativeEventName", "modifiedEvent", "_eventMap", "nativeRemoveEventListener", "unwrappedCb", "disableLog", "bool", "disableWarnings", "deprecated", "oldMethod", "newMethod", "detectBrowser", "mozGetUserMedia", "webkitGetUserMedia", "isSecureContext", "webkitRTCPeerConnection", "supportsUnifiedPlan", "val", "compactObject", "isEmptyObject", "filterStats", "outbound", "streamStatsType", "filteredResult", "trackStats", "trackStat", "walkStats", "resultSet", "endsWith", "getusermedia_logging", "shimGetUserMedia", "browserDetails", "constraintsToChrome_", "cc", "exact", "oldname_", "oc", "mix", "advanced", "shimConstraints_", "remap", "face", "getSupportedFacingModeLies", "getSupportedConstraints", "dev", "shimError_", "PermissionDeniedError", "PermissionDismissedError", "DevicesNotFoundError", "ConstraintNotSatisfiedError", "TrackStartError", "MediaDeviceFailedDueToShutdown", "MediaDeviceKillSwitchOn", "TabCaptureError", "ScreenCaptureError", "DeviceCaptureError", "origGetUserMedia", "DOMException", "shimGetDisplayMedia", "getSourceId", "widthSpecified", "heightSpecified", "frameRateSpecified", "shimMediaStream", "webkitMediaStream", "shimOnTrack", "_ontrack", "origSetRemoteDescription", "_ontrackpoly", "te", "shimGetSendersWithDtmf", "shimSenderWithDtmf", "_dtmf", "_pc", "_senders", "origAddTrack", "origRemoveTrack", "origAddStream", "origRemoveStream", "origGetSenders", "shimGetStats", "origGetStats", "onSucc", "onErr", "fixChromeStats_", "standardReport", "standardStats", "makeMapStats", "successCallbackWrapper_", "shimSenderReceiverGetStats", "origGetReceivers", "receivers", "srcElement", "shimAddTrackRemoveTrackWithNative", "_shimmedLocalStreams", "existingSenders", "newSenders", "newSender", "shimAddTrackRemoveTrack", "origGetLocalStreams", "nativeStreams", "_reverseStreams", "_streams", "newStream", "replaceInternalStreamId", "internalId", "externalStream", "internalStream", "oldStream", "methodObj", "origSetLocalDescription", "replaceExternalStreamId", "origLocalDescription", "getOwnPropertyDescriptor", "shimPeerConnection", "addIceCandidateNullSupported", "nativeAddIceCandidate", "fixNegotiationNeeded", "getusermedia_shimGetUserMedia", "getdisplaymedia_shimGetDisplayMedia", "edge_shim_shimPeerConnection", "origMSTEnabled", "RTCDtmfSender", "RTCDTMFSender", "RTCPeerConnectionShim", "rtcpeerconnection_default", "validTurn", "shimReplaceTrack", "setTrack", "firefox_getusermedia_shimGetUserMedia", "nativeGetUserMedia", "nativeGetSettings", "nativeApplyConstraints", "firefox_getdisplaymedia_shimGetDisplayMedia", "preferredMediaSource", "firefox_shim_shimOnTrack", "RTCTrackEvent", "firefox_shim_shimPeerConnection", "mozRTCPeerConnection", "modernStatsTypes", "nativeGetStats", "shimSenderGetStats", "shimReceiverGetStats", "shimRemoveStream", "shimRTCDataChannel", "DataChannel", "RTCDataChannel", "shimAddTransceiver", "origAddTransceiver", "setParametersPromises", "initParameters", "shouldPerformCheck", "encodingParam", "maxFramerate", "shimCreateOffer", "origCreateOffer", "finally", "shimCreateAnswer", "origCreateAnswer", "shimLocalStreamsAPI", "_localStreams", "_addTrack", "shimRemoteStreamsAPI", "_remoteStreams", "_onaddstream", "_onaddstreampoly", "shimCallbacksAPI", "withCallback", "safari_shim_shimGetUserMedia", "_getUserMedia", "shimConstraints", "errcb", "shimRTCIceServerUrls", "OrigPeerConnection", "pcConfig", "newIceServers", "generateCertificate", "shimTrackEventTransceiver", "shimCreateOfferLegacy", "audioTransceiver", "setDirection", "videoTransceiver", "shimRTCIceCandidate", "NativeRTCIceCandidate", "nativeCandidate", "parsedCandidate", "sdp_default", "augmentedCandidate", "shimMaxMessageSize", "_sctp", "sctpInDescription", "getRemoteFirefoxVersion", "canSendMMS", "remoteIsFirefox", "canSendMaxMessageSize", "getCanSendMaxMessageSize", "remoteMMS", "getMaxMessageSize", "POSITIVE_INFINITY", "shimSendThrowTypeError", "wrapDcSend", "dc", "origDataChannelSend", "origCreateDataChannel", "dataChannel", "shimConnectionState", "_onconnectionstatechange", "origMethod", "_connectionstatechangepoly", "_lastConnectionState", "newEvent", "removeAllowExtmapMixed", "nativeSRD", "adapter_core_adapter", "shimChrome", "shimFirefox", "shimEdge", "shimSafari", "adapter", "commonShim", "common_shim_namespaceObject", "chrome_shim_namespaceObject", "browserShim", "firefox_shim_namespaceObject", "edge_shim_namespaceObject", "safari_shim_namespaceObject", "adapterFactory" ], "mappings": "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", "file": "lib-jitsi-meet.min.js", "sourcesContent": [ "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"JitsiMeetJS\"] = factory();\n\telse\n\t\troot[\"JitsiMeetJS\"] = factory();\n})(window, function() {\nreturn ", " \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 133);\n", "const XMPPEvents = {\n /**\n * Indicates error while adding ice candidate.\n */\n ADD_ICE_CANDIDATE_FAILED: 'xmpp.add_ice_candidate_failed',\n\n // Designates an event indicating that the focus has asked us to mute our\n // audio.\n AUDIO_MUTED_BY_FOCUS: 'xmpp.audio_muted_by_focus',\n AUTHENTICATION_REQUIRED: 'xmpp.authentication_required',\n BRIDGE_DOWN: 'xmpp.bridge_down',\n\n /**\n * Triggered when 'session-accept' is received from the responder.\n */\n CALL_ACCEPTED: 'xmpp.callaccepted.jingle',\n\n // Designates an event indicating that an offer (e.g. Jingle\n // session-initiate) was received.\n CALL_INCOMING: 'xmpp.callincoming.jingle',\n\n // Triggered when Jicofo kills our media session, this can happen while\n // we're still in the MUC, when it decides to terminate the media session.\n // For example when the session is idle for too long, because we're the only\n // person in the conference room.\n CALL_ENDED: 'xmpp.callended.jingle',\n CHAT_ERROR_RECEIVED: 'xmpp.chat_error_received',\n\n // The conference properties (as advertised by jicofo) have changed\n CONFERENCE_PROPERTIES_CHANGED: 'xmpp.conference_properties_changed',\n\n /**\n * This event is triggered when the ICE connects for the first time.\n */\n CONNECTION_ESTABLISHED: 'xmpp.connection.connected',\n\n // Designates an event indicating that the connection to the XMPP server\n // failed.\n CONNECTION_FAILED: 'xmpp.connection.failed',\n\n // Designates an event indicating that the media (ICE) connection was\n // interrupted. This should go to the RTC module.\n CONNECTION_INTERRUPTED: 'xmpp.connection.interrupted',\n\n // Designates an event indicating that the media (ICE) connection was\n // restored. This should go to the RTC module.\n CONNECTION_RESTORED: 'xmpp.connection.restored',\n\n // Designates an event indicating that the media (ICE) connection failed.\n // This should go to the RTC module.\n CONNECTION_ICE_FAILED: 'xmpp.connection.ice.failed',\n\n /**\n * Designates an event indicating connection status changes.\n */\n CONNECTION_STATUS_CHANGED: 'xmpp.connection.status.changed',\n\n // Designates an event indicating that the display name of a participant\n // has changed.\n DISPLAY_NAME_CHANGED: 'xmpp.display_name_changed',\n\n /**\n * Chat room instance have been added to Strophe.emuc plugin.\n */\n EMUC_ROOM_ADDED: 'xmpp.emuc_room_added',\n\n /**\n * Chat room instance have been removed from Strophe.emuc plugin.\n */\n EMUC_ROOM_REMOVED: 'xmpp.emuc_room_removed',\n ETHERPAD: 'xmpp.etherpad',\n FOCUS_DISCONNECTED: 'xmpp.focus_disconnected',\n FOCUS_LEFT: 'xmpp.focus_left',\n GRACEFUL_SHUTDOWN: 'xmpp.graceful_shutdown',\n\n /**\n * Event fired when 'transport-replace' Jingle message has been received,\n * before the new offer is set on the PeerConnection.\n */\n ICE_RESTARTING: 'rtc.ice_restarting',\n\n /**\n * Event fired after the 'transport-replace' message has been processed\n * and the new offer has been set successfully.\n */\n ICE_RESTART_SUCCESS: 'rtc.ice_restart_success',\n\n /**\n * Designates an event indicating that we were kicked from the XMPP MUC.\n * @param {boolean} isSelfPresence - whether it is for local participant\n * or another participant.\n * @param {string} actorJid - the jid of the participant who was initator\n * of the kick.\n * @param {?string} participantJid - when it is not a kick for local participant,\n * this is the jid of the participant which was kicked.\n */\n KICKED: 'xmpp.kicked',\n\n // Designates an event indicating that our role in the XMPP MUC has changed.\n LOCAL_ROLE_CHANGED: 'xmpp.localrole_changed',\n\n /**\n * Event fired when the unique meeting id is set.\n */\n MEETING_ID_SET: 'xmpp.meeting_id_set',\n\n // Designates an event indicating that an XMPP message in the MUC was\n // received.\n MESSAGE_RECEIVED: 'xmpp.message_received',\n\n // Designates an event indicating that a private XMPP message in the MUC was\n // received.\n PRIVATE_MESSAGE_RECEIVED: 'xmpp.private_message_received',\n\n // Designates an event indicating that a bot participant type had changed\n MUC_MEMBER_BOT_TYPE_CHANGED: 'xmpp.muc_member_bot_type_changed',\n\n // Designates an event indicating that the XMPP MUC was destroyed.\n MUC_DESTROYED: 'xmpp.muc_destroyed',\n\n // Designates an event indicating that we have joined the XMPP MUC.\n MUC_JOINED: 'xmpp.muc_joined',\n\n // Designates an event indicating that a participant joined the XMPP MUC.\n MUC_MEMBER_JOINED: 'xmpp.muc_member_joined',\n\n // Designates an event indicating that a participant left the XMPP MUC.\n MUC_MEMBER_LEFT: 'xmpp.muc_member_left',\n\n // Designates an event indicating that local participant left the muc\n MUC_LEFT: 'xmpp.muc_left',\n\n // Designates an event indicating that the MUC role of a participant has\n // changed.\n MUC_ROLE_CHANGED: 'xmpp.muc_role_changed',\n\n // Designates an event indicating that the MUC has been locked or unlocked.\n MUC_LOCK_CHANGED: 'xmpp.muc_lock_changed',\n\n // Designates an event indicating that a participant in the XMPP MUC has\n // advertised that they have audio muted (or unmuted).\n PARTICIPANT_AUDIO_MUTED: 'xmpp.audio_muted',\n\n // Designates an event indicating that a participant in the XMPP MUC has\n // advertised that they have video muted (or unmuted).\n PARTICIPANT_VIDEO_MUTED: 'xmpp.video_muted',\n\n // Designates an event indicating that the video type (e.g. 'camera' or\n // 'screen') for a participant has changed.\n // Note: currently this event fires every time we receive presence from\n // someone (regardless of whether or not the \"video type\" changed).\n PARTICIPANT_VIDEO_TYPE_CHANGED: 'xmpp.video_type',\n\n /**\n * Indicates that the features of the participant has been changed.\n */\n PARTCIPANT_FEATURES_CHANGED: 'xmpp.partcipant_features_changed',\n PASSWORD_REQUIRED: 'xmpp.password_required',\n PEERCONNECTION_READY: 'xmpp.peerconnection_ready',\n\n /**\n * Indicates that phone number changed.\n */\n PHONE_NUMBER_CHANGED: 'conference.phoneNumberChanged',\n PRESENCE_RECEIVED: 'xmpp.presence_received',\n PRESENCE_STATUS: 'xmpp.presence_status',\n PROMPT_FOR_LOGIN: 'xmpp.prompt_for_login',\n\n // xmpp is connected and obtained user media\n READY_TO_JOIN: 'xmpp.ready_to_join',\n\n /**\n * Indicates that recording state changed.\n */\n RECORDER_STATE_CHANGED: 'xmpp.recorderStateChanged',\n\n // Designates an event indicating that we received statistics from a\n // participant in the MUC.\n REMOTE_STATS: 'xmpp.remote_stats',\n\n /**\n * Indicates that the offer / answer renegotiation has failed.\n */\n RENEGOTIATION_FAILED: 'xmpp.renegotiation_failed',\n RESERVATION_ERROR: 'xmpp.room_reservation_error',\n ROOM_CONNECT_ERROR: 'xmpp.room_connect_error',\n ROOM_CONNECT_NOT_ALLOWED_ERROR: 'xmpp.room_connect_error.not_allowed',\n ROOM_JOIN_ERROR: 'xmpp.room_join_error',\n\n /**\n * Indicates that max users limit has been reached.\n */\n ROOM_MAX_USERS_ERROR: 'xmpp.room_max_users_error',\n\n // Designates an event indicating that we sent an XMPP message to the MUC.\n SENDING_CHAT_MESSAGE: 'xmpp.sending_chat_message',\n\n // Designates an event indicating that we sent a private XMPP message to\n // a specific user of the muc.\n SENDING_PRIVATE_CHAT_MESSAGE: 'xmpp.sending_private_chat_message',\n\n /**\n * Event fired when we do not get our 'session-accept' acknowledged by\n * Jicofo. It most likely means that there is serious problem with our\n * connection or XMPP server and we should reload the conference.\n *\n * We have seen that to happen in BOSH requests race condition when the BOSH\n * request table containing the 'session-accept' was discarded by Prosody.\n * Jicofo does send the RESULT immediately without any condition, so missing\n * packets means that most likely it has never seen our IQ.\n */\n SESSION_ACCEPT_TIMEOUT: 'xmpp.session_accept_timeout',\n\n /**\n * Event fired when speaker stats update message is received.\n */\n SPEAKER_STATS_RECEIVED: 'xmpp.speaker_stats_received',\n\n /**\n * Event fired when conference creation timestamp is received.\n */\n CONFERENCE_TIMESTAMP_RECEIVED: 'xmpp.conference_timestamp_received',\n\n // Designates an event indicating that we should join the conference with\n // audio and/or video muted.\n START_MUTED_FROM_FOCUS: 'xmpp.start_muted_from_focus',\n\n // Designates an event indicating that the subject of the XMPP MUC has\n // changed.\n SUBJECT_CHANGED: 'xmpp.subject_changed',\n\n // FIXME: how does it belong to XMPP ? - it's detected by the PeerConnection\n // suspending detected\n SUSPEND_DETECTED: 'xmpp.suspend_detected',\n\n /**\n * Notifies for transcription status changes. The event provides the\n * following parameters to its listeners:\n *\n * @param {String} status - The new status.\n */\n TRANSCRIPTION_STATUS_CHANGED: 'xmpp.transcription_status_changed',\n\n /**\n * Event fired when 'transport-info' with new ICE candidates is received.\n */\n TRANSPORT_INFO: 'xmpp.transportinfo.jingle',\n\n /**\n * Indicates that video SIP GW state changed.\n *\n * @param {VideoSIPGWConstants} status - Any of the following statuses:\n * STATUS_BUSY, STATUS_AVAILABLE or STATUS_UNDEFINED.\n */\n VIDEO_SIP_GW_AVAILABILITY_CHANGED: 'xmpp.videoSIPGWAvailabilityChanged',\n\n /**\n * Indicates that video SIP GW Session state changed.\n * The statuses are any of the following statuses:\n * STATE_ON, STATE_OFF, STATE_PENDING, STATE_RETRYING, STATE_FAILED.\n * {@see VideoSIPGWConstants}\n *\n * @param {options} event - {address, oldState, newState, displayName}.\n */\n VIDEO_SIP_GW_SESSION_STATE_CHANGED:\n 'xmpp.videoSIPGWSessionStateChanged',\n\n // Designates an event indicating that the local ICE connection state has\n // changed.\n ICE_CONNECTION_STATE_CHANGED: 'xmpp.ice_connection_state_changed',\n\n /**\n * Event which is emitted when the body in an XMPP message in the MUC\n * contains JSON\n */\n JSON_MESSAGE_RECEIVED: 'xmmp.json_message_received'\n};\n\nmodule.exports = XMPPEvents;\n", "(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (global = global || self, global.strophe = factory());\n}(this, function () { 'use strict';\n\n var global$1 = (typeof global !== \"undefined\" ? global :\n typeof self !== \"undefined\" ? self :\n typeof window !== \"undefined\" ? window : {});\n\n function _typeof(obj) {\n if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n _typeof = function (obj) {\n return typeof obj;\n };\n } else {\n _typeof = function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n }\n\n return _typeof(obj);\n }\n\n function _toConsumableArray(arr) {\n return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();\n }\n\n function _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) {\n for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];\n\n return arr2;\n }\n }\n\n function _iterableToArray(iter) {\n if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter);\n }\n\n function _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance\");\n }\n\n /*\n * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\n * Digest Algorithm, as defined in RFC 1321.\n * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.\n * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n * Distributed under the BSD License\n * See http://pajhome.org.uk/crypt/md5 for more info.\n */\n\n /*\n * Everything that isn't used by Strophe has been stripped here!\n */\n\n /*\n * Add integers, wrapping at 2^32. This uses 16-bit operations internally\n * to work around bugs in some JS interpreters.\n */\n var safe_add = function safe_add(x, y) {\n var lsw = (x & 0xFFFF) + (y & 0xFFFF);\n var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n return msw << 16 | lsw & 0xFFFF;\n };\n /*\n * Bitwise rotate a 32-bit number to the left.\n */\n\n\n var bit_rol = function bit_rol(num, cnt) {\n return num << cnt | num >>> 32 - cnt;\n };\n /*\n * Convert a string to an array of little-endian words\n */\n\n\n var str2binl = function str2binl(str) {\n if (typeof str !== \"string\") {\n throw new Error(\"str2binl was passed a non-string\");\n }\n\n var bin = [];\n\n for (var i = 0; i < str.length * 8; i += 8) {\n bin[i >> 5] |= (str.charCodeAt(i / 8) & 255) << i % 32;\n }\n\n return bin;\n };\n /*\n * Convert an array of little-endian words to a string\n */\n\n\n var binl2str = function binl2str(bin) {\n var str = \"\";\n\n for (var i = 0; i < bin.length * 32; i += 8) {\n str += String.fromCharCode(bin[i >> 5] >>> i % 32 & 255);\n }\n\n return str;\n };\n /*\n * Convert an array of little-endian words to a hex string.\n */\n\n\n var binl2hex = function binl2hex(binarray) {\n var hex_tab = \"0123456789abcdef\";\n var str = \"\";\n\n for (var i = 0; i < binarray.length * 4; i++) {\n str += hex_tab.charAt(binarray[i >> 2] >> i % 4 * 8 + 4 & 0xF) + hex_tab.charAt(binarray[i >> 2] >> i % 4 * 8 & 0xF);\n }\n\n return str;\n };\n /*\n * These functions implement the four basic operations the algorithm uses.\n */\n\n\n var md5_cmn = function md5_cmn(q, a, b, x, s, t) {\n return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);\n };\n\n var md5_ff = function md5_ff(a, b, c, d, x, s, t) {\n return md5_cmn(b & c | ~b & d, a, b, x, s, t);\n };\n\n var md5_gg = function md5_gg(a, b, c, d, x, s, t) {\n return md5_cmn(b & d | c & ~d, a, b, x, s, t);\n };\n\n var md5_hh = function md5_hh(a, b, c, d, x, s, t) {\n return md5_cmn(b ^ c ^ d, a, b, x, s, t);\n };\n\n var md5_ii = function md5_ii(a, b, c, d, x, s, t) {\n return md5_cmn(c ^ (b | ~d), a, b, x, s, t);\n };\n /*\n * Calculate the MD5 of an array of little-endian words, and a bit length\n */\n\n\n var core_md5 = function core_md5(x, len) {\n /* append padding */\n x[len >> 5] |= 0x80 << len % 32;\n x[(len + 64 >>> 9 << 4) + 14] = len;\n var a = 1732584193;\n var b = -271733879;\n var c = -1732584194;\n var d = 271733878;\n var olda, oldb, oldc, oldd;\n\n for (var i = 0; i < x.length; i += 16) {\n olda = a;\n oldb = b;\n oldc = c;\n oldd = d;\n a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);\n d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);\n c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);\n b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);\n a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);\n d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);\n c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);\n b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);\n a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);\n d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);\n c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);\n b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);\n a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);\n d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);\n c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);\n b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);\n a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);\n d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);\n c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);\n b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);\n a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);\n d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);\n c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);\n b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);\n a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);\n d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);\n c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);\n b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);\n a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);\n d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);\n c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);\n b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);\n a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);\n d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);\n c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);\n b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);\n a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);\n d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);\n c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);\n b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);\n a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);\n d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);\n c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);\n b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);\n a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);\n d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);\n c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);\n b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);\n a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);\n d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);\n c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);\n b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);\n a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);\n d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);\n c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);\n b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);\n a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);\n d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);\n c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);\n b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);\n a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);\n d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);\n c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);\n b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);\n a = safe_add(a, olda);\n b = safe_add(b, oldb);\n c = safe_add(c, oldc);\n d = safe_add(d, oldd);\n }\n\n return [a, b, c, d];\n };\n /*\n * These are the functions you'll usually want to call.\n * They take string arguments and return either hex or base-64 encoded\n * strings.\n */\n\n\n var MD5 = {\n hexdigest: function hexdigest(s) {\n return binl2hex(core_md5(str2binl(s), s.length * 8));\n },\n hash: function hash(s) {\n return binl2str(core_md5(str2binl(s), s.length * 8));\n }\n };\n\n /*\n * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined\n * in FIPS PUB 180-1\n * Version 2.1a Copyright Paul Johnston 2000 - 2002.\n * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n * Distributed under the BSD License\n * See http://pajhome.org.uk/crypt/md5 for details.\n */\n\n /* global define */\n\n /* Some functions and variables have been stripped for use with Strophe */\n\n /*\n * Calculate the SHA-1 of an array of big-endian words, and a bit length\n */\n function core_sha1(x, len) {\n /* append padding */\n x[len >> 5] |= 0x80 << 24 - len % 32;\n x[(len + 64 >> 9 << 4) + 15] = len;\n var w = new Array(80);\n var a = 1732584193;\n var b = -271733879;\n var c = -1732584194;\n var d = 271733878;\n var e = -1009589776;\n var i, j, t, olda, oldb, oldc, oldd, olde;\n\n for (i = 0; i < x.length; i += 16) {\n olda = a;\n oldb = b;\n oldc = c;\n oldd = d;\n olde = e;\n\n for (j = 0; j < 80; j++) {\n if (j < 16) {\n w[j] = x[i + j];\n } else {\n w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);\n }\n\n t = safe_add$1(safe_add$1(rol(a, 5), sha1_ft(j, b, c, d)), safe_add$1(safe_add$1(e, w[j]), sha1_kt(j)));\n e = d;\n d = c;\n c = rol(b, 30);\n b = a;\n a = t;\n }\n\n a = safe_add$1(a, olda);\n b = safe_add$1(b, oldb);\n c = safe_add$1(c, oldc);\n d = safe_add$1(d, oldd);\n e = safe_add$1(e, olde);\n }\n\n return [a, b, c, d, e];\n }\n /*\n * Perform the appropriate triplet combination function for the current\n * iteration\n */\n\n\n function sha1_ft(t, b, c, d) {\n if (t < 20) {\n return b & c | ~b & d;\n }\n\n if (t < 40) {\n return b ^ c ^ d;\n }\n\n if (t < 60) {\n return b & c | b & d | c & d;\n }\n\n return b ^ c ^ d;\n }\n /*\n * Determine the appropriate additive constant for the current iteration\n */\n\n\n function sha1_kt(t) {\n return t < 20 ? 1518500249 : t < 40 ? 1859775393 : t < 60 ? -1894007588 : -899497514;\n }\n /*\n * Calculate the HMAC-SHA1 of a key and some data\n */\n\n\n function core_hmac_sha1(key, data) {\n var bkey = str2binb(key);\n\n if (bkey.length > 16) {\n bkey = core_sha1(bkey, key.length * 8);\n }\n\n var ipad = new Array(16),\n opad = new Array(16);\n\n for (var i = 0; i < 16; i++) {\n ipad[i] = bkey[i] ^ 0x36363636;\n opad[i] = bkey[i] ^ 0x5C5C5C5C;\n }\n\n var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * 8);\n return core_sha1(opad.concat(hash), 512 + 160);\n }\n /*\n * Add integers, wrapping at 2^32. This uses 16-bit operations internally\n * to work around bugs in some JS interpreters.\n */\n\n\n function safe_add$1(x, y) {\n var lsw = (x & 0xFFFF) + (y & 0xFFFF);\n var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n return msw << 16 | lsw & 0xFFFF;\n }\n /*\n * Bitwise rotate a 32-bit number to the left.\n */\n\n\n function rol(num, cnt) {\n return num << cnt | num >>> 32 - cnt;\n }\n /*\n * Convert an 8-bit or 16-bit string to an array of big-endian words\n * In 8-bit function, characters >255 have their hi-byte silently ignored.\n */\n\n\n function str2binb(str) {\n var bin = [];\n var mask = 255;\n\n for (var i = 0; i < str.length * 8; i += 8) {\n bin[i >> 5] |= (str.charCodeAt(i / 8) & mask) << 24 - i % 32;\n }\n\n return bin;\n }\n /*\n * Convert an array of big-endian words to a base-64 string\n */\n\n\n function binb2b64(binarray) {\n var tab = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n var str = \"\";\n var triplet, j;\n\n for (var i = 0; i < binarray.length * 4; i += 3) {\n triplet = (binarray[i >> 2] >> 8 * (3 - i % 4) & 0xFF) << 16 | (binarray[i + 1 >> 2] >> 8 * (3 - (i + 1) % 4) & 0xFF) << 8 | binarray[i + 2 >> 2] >> 8 * (3 - (i + 2) % 4) & 0xFF;\n\n for (j = 0; j < 4; j++) {\n if (i * 8 + j * 6 > binarray.length * 32) {\n str += \"=\";\n } else {\n str += tab.charAt(triplet >> 6 * (3 - j) & 0x3F);\n }\n }\n }\n\n return str;\n }\n /*\n * Convert an array of big-endian words to a string\n */\n\n\n function binb2str(bin) {\n var str = \"\";\n var mask = 255;\n\n for (var i = 0; i < bin.length * 32; i += 8) {\n str += String.fromCharCode(bin[i >> 5] >>> 24 - i % 32 & mask);\n }\n\n return str;\n }\n /*\n * These are the functions you'll usually want to call\n * They take string arguments and return either hex or base-64 encoded strings\n */\n\n\n var SHA1 = {\n b64_hmac_sha1: function b64_hmac_sha1(key, data) {\n return binb2b64(core_hmac_sha1(key, data));\n },\n b64_sha1: function b64_sha1(s) {\n return binb2b64(core_sha1(str2binb(s), s.length * 8));\n },\n binb2str: binb2str,\n core_hmac_sha1: core_hmac_sha1,\n str_hmac_sha1: function str_hmac_sha1(key, data) {\n return binb2str(core_hmac_sha1(key, data));\n },\n str_sha1: function str_sha1(s) {\n return binb2str(core_sha1(str2binb(s), s.length * 8));\n }\n };\n\n var utils = {\n utf16to8: function utf16to8(str) {\n var i, c;\n var out = \"\";\n var len = str.length;\n\n for (i = 0; i < len; i++) {\n c = str.charCodeAt(i);\n\n if (c >= 0x0000 && c <= 0x007F) {\n out += str.charAt(i);\n } else if (c > 0x07FF) {\n out += String.fromCharCode(0xE0 | c >> 12 & 0x0F);\n out += String.fromCharCode(0x80 | c >> 6 & 0x3F);\n out += String.fromCharCode(0x80 | c >> 0 & 0x3F);\n } else {\n out += String.fromCharCode(0xC0 | c >> 6 & 0x1F);\n out += String.fromCharCode(0x80 | c >> 0 & 0x3F);\n }\n }\n\n return out;\n },\n addCookies: function addCookies(cookies) {\n /* Parameters:\n * (Object) cookies - either a map of cookie names\n * to string values or to maps of cookie values.\n *\n * For example:\n * { \"myCookie\": \"1234\" }\n *\n * or:\n * { \"myCookie\": {\n * \"value\": \"1234\",\n * \"domain\": \".example.org\",\n * \"path\": \"/\",\n * \"expires\": expirationDate\n * }\n * }\n *\n * These values get passed to Strophe.Connection via\n * options.cookies\n */\n cookies = cookies || {};\n\n for (var cookieName in cookies) {\n if (Object.prototype.hasOwnProperty.call(cookies, cookieName)) {\n var expires = '';\n var domain = '';\n var path = '';\n var cookieObj = cookies[cookieName];\n var isObj = _typeof(cookieObj) === \"object\";\n var cookieValue = escape(unescape(isObj ? cookieObj.value : cookieObj));\n\n if (isObj) {\n expires = cookieObj.expires ? \";expires=\" + cookieObj.expires : '';\n domain = cookieObj.domain ? \";domain=\" + cookieObj.domain : '';\n path = cookieObj.path ? \";path=\" + cookieObj.path : '';\n }\n\n document.cookie = cookieName + '=' + cookieValue + expires + domain + path;\n }\n }\n }\n };\n\n /** Function: $build\n * Create a Strophe.Builder.\n * This is an alias for 'new Strophe.Builder(name, attrs)'.\n *\n * Parameters:\n * (String) name - The root element name.\n * (Object) attrs - The attributes for the root element in object notation.\n *\n * Returns:\n * A new Strophe.Builder object.\n */\n\n function $build(name, attrs) {\n return new Strophe.Builder(name, attrs);\n }\n /** Function: $msg\n * Create a Strophe.Builder with a element as the root.\n *\n * Parameters:\n * (Object) attrs - The element attributes in object notation.\n *\n * Returns:\n * A new Strophe.Builder object.\n */\n\n\n function $msg(attrs) {\n return new Strophe.Builder(\"message\", attrs);\n }\n /** Function: $iq\n * Create a Strophe.Builder with an element as the root.\n *\n * Parameters:\n * (Object) attrs - The element attributes in object notation.\n *\n * Returns:\n * A new Strophe.Builder object.\n */\n\n\n function $iq(attrs) {\n return new Strophe.Builder(\"iq\", attrs);\n }\n /** Function: $pres\n * Create a Strophe.Builder with a element as the root.\n *\n * Parameters:\n * (Object) attrs - The element attributes in object notation.\n *\n * Returns:\n * A new Strophe.Builder object.\n */\n\n\n function $pres(attrs) {\n return new Strophe.Builder(\"presence\", attrs);\n }\n /** Class: Strophe\n * An object container for all Strophe library functions.\n *\n * This class is just a container for all the objects and constants\n * used in the library. It is not meant to be instantiated, but to\n * provide a namespace for library objects, constants, and functions.\n */\n\n\n var Strophe = {\n /** Constant: VERSION */\n VERSION: \"@VERSION@\",\n\n /** Constants: XMPP Namespace Constants\n * Common namespace constants from the XMPP RFCs and XEPs.\n *\n * NS.HTTPBIND - HTTP BIND namespace from XEP 124.\n * NS.BOSH - BOSH namespace from XEP 206.\n * NS.CLIENT - Main XMPP client namespace.\n * NS.AUTH - Legacy authentication namespace.\n * NS.ROSTER - Roster operations namespace.\n * NS.PROFILE - Profile namespace.\n * NS.DISCO_INFO - Service discovery info namespace from XEP 30.\n * NS.DISCO_ITEMS - Service discovery items namespace from XEP 30.\n * NS.MUC - Multi-User Chat namespace from XEP 45.\n * NS.SASL - XMPP SASL namespace from RFC 3920.\n * NS.STREAM - XMPP Streams namespace from RFC 3920.\n * NS.BIND - XMPP Binding namespace from RFC 3920 and RFC 6120.\n * NS.SESSION - XMPP Session namespace from RFC 3920.\n * NS.XHTML_IM - XHTML-IM namespace from XEP 71.\n * NS.XHTML - XHTML body namespace from XEP 71.\n */\n NS: {\n HTTPBIND: \"http://jabber.org/protocol/httpbind\",\n BOSH: \"urn:xmpp:xbosh\",\n CLIENT: \"jabber:client\",\n AUTH: \"jabber:iq:auth\",\n ROSTER: \"jabber:iq:roster\",\n PROFILE: \"jabber:iq:profile\",\n DISCO_INFO: \"http://jabber.org/protocol/disco#info\",\n DISCO_ITEMS: \"http://jabber.org/protocol/disco#items\",\n MUC: \"http://jabber.org/protocol/muc\",\n SASL: \"urn:ietf:params:xml:ns:xmpp-sasl\",\n STREAM: \"http://etherx.jabber.org/streams\",\n FRAMING: \"urn:ietf:params:xml:ns:xmpp-framing\",\n BIND: \"urn:ietf:params:xml:ns:xmpp-bind\",\n SESSION: \"urn:ietf:params:xml:ns:xmpp-session\",\n VERSION: \"jabber:iq:version\",\n STANZAS: \"urn:ietf:params:xml:ns:xmpp-stanzas\",\n XHTML_IM: \"http://jabber.org/protocol/xhtml-im\",\n XHTML: \"http://www.w3.org/1999/xhtml\"\n },\n\n /** Constants: XHTML_IM Namespace\n * contains allowed tags, tag attributes, and css properties.\n * Used in the createHtml function to filter incoming html into the allowed XHTML-IM subset.\n * See http://xmpp.org/extensions/xep-0071.html#profile-summary for the list of recommended\n * allowed tags and their attributes.\n */\n XHTML: {\n tags: ['a', 'blockquote', 'br', 'cite', 'em', 'img', 'li', 'ol', 'p', 'span', 'strong', 'ul', 'body'],\n attributes: {\n 'a': ['href'],\n 'blockquote': ['style'],\n 'br': [],\n 'cite': ['style'],\n 'em': [],\n 'img': ['src', 'alt', 'style', 'height', 'width'],\n 'li': ['style'],\n 'ol': ['style'],\n 'p': ['style'],\n 'span': ['style'],\n 'strong': [],\n 'ul': ['style'],\n 'body': []\n },\n css: ['background-color', 'color', 'font-family', 'font-size', 'font-style', 'font-weight', 'margin-left', 'margin-right', 'text-align', 'text-decoration'],\n\n /** Function: XHTML.validTag\n *\n * Utility method to determine whether a tag is allowed\n * in the XHTML_IM namespace.\n *\n * XHTML tag names are case sensitive and must be lower case.\n */\n validTag: function validTag(tag) {\n for (var i = 0; i < Strophe.XHTML.tags.length; i++) {\n if (tag === Strophe.XHTML.tags[i]) {\n return true;\n }\n }\n\n return false;\n },\n\n /** Function: XHTML.validAttribute\n *\n * Utility method to determine whether an attribute is allowed\n * as recommended per XEP-0071\n *\n * XHTML attribute names are case sensitive and must be lower case.\n */\n validAttribute: function validAttribute(tag, attribute) {\n if (typeof Strophe.XHTML.attributes[tag] !== 'undefined' && Strophe.XHTML.attributes[tag].length > 0) {\n for (var i = 0; i < Strophe.XHTML.attributes[tag].length; i++) {\n if (attribute === Strophe.XHTML.attributes[tag][i]) {\n return true;\n }\n }\n }\n\n return false;\n },\n validCSS: function validCSS(style) {\n for (var i = 0; i < Strophe.XHTML.css.length; i++) {\n if (style === Strophe.XHTML.css[i]) {\n return true;\n }\n }\n\n return false;\n }\n },\n\n /** Constants: Connection Status Constants\n * Connection status constants for use by the connection handler\n * callback.\n *\n * Status.ERROR - An error has occurred\n * Status.CONNECTING - The connection is currently being made\n * Status.CONNFAIL - The connection attempt failed\n * Status.AUTHENTICATING - The connection is authenticating\n * Status.AUTHFAIL - The authentication attempt failed\n * Status.CONNECTED - The connection has succeeded\n * Status.DISCONNECTED - The connection has been terminated\n * Status.DISCONNECTING - The connection is currently being terminated\n * Status.ATTACHED - The connection has been attached\n * Status.REDIRECT - The connection has been redirected\n * Status.CONNTIMEOUT - The connection has timed out\n */\n Status: {\n ERROR: 0,\n CONNECTING: 1,\n CONNFAIL: 2,\n AUTHENTICATING: 3,\n AUTHFAIL: 4,\n CONNECTED: 5,\n DISCONNECTED: 6,\n DISCONNECTING: 7,\n ATTACHED: 8,\n REDIRECT: 9,\n CONNTIMEOUT: 10,\n BINDREQUIRED: 11\n },\n ErrorCondition: {\n BAD_FORMAT: \"bad-format\",\n CONFLICT: \"conflict\",\n MISSING_JID_NODE: \"x-strophe-bad-non-anon-jid\",\n NO_AUTH_MECH: \"no-auth-mech\",\n UNKNOWN_REASON: \"unknown\"\n },\n\n /** Constants: Log Level Constants\n * Logging level indicators.\n *\n * LogLevel.DEBUG - Debug output\n * LogLevel.INFO - Informational output\n * LogLevel.WARN - Warnings\n * LogLevel.ERROR - Errors\n * LogLevel.FATAL - Fatal errors\n */\n LogLevel: {\n DEBUG: 0,\n INFO: 1,\n WARN: 2,\n ERROR: 3,\n FATAL: 4\n },\n\n /** PrivateConstants: DOM Element Type Constants\n * DOM element types.\n *\n * ElementType.NORMAL - Normal element.\n * ElementType.TEXT - Text data element.\n * ElementType.FRAGMENT - XHTML fragment element.\n */\n ElementType: {\n NORMAL: 1,\n TEXT: 3,\n CDATA: 4,\n FRAGMENT: 11\n },\n\n /** PrivateConstants: Timeout Values\n * Timeout values for error states. These values are in seconds.\n * These should not be changed unless you know exactly what you are\n * doing.\n *\n * TIMEOUT - Timeout multiplier. A waiting request will be considered\n * failed after Math.floor(TIMEOUT * wait) seconds have elapsed.\n * This defaults to 1.1, and with default wait, 66 seconds.\n * SECONDARY_TIMEOUT - Secondary timeout multiplier. In cases where\n * Strophe can detect early failure, it will consider the request\n * failed if it doesn't return after\n * Math.floor(SECONDARY_TIMEOUT * wait) seconds have elapsed.\n * This defaults to 0.1, and with default wait, 6 seconds.\n */\n TIMEOUT: 1.1,\n SECONDARY_TIMEOUT: 0.1,\n\n /** Function: addNamespace\n * This function is used to extend the current namespaces in\n * Strophe.NS. It takes a key and a value with the key being the\n * name of the new namespace, with its actual value.\n * For example:\n * Strophe.addNamespace('PUBSUB', \"http://jabber.org/protocol/pubsub\");\n *\n * Parameters:\n * (String) name - The name under which the namespace will be\n * referenced under Strophe.NS\n * (String) value - The actual namespace.\n */\n addNamespace: function addNamespace(name, value) {\n Strophe.NS[name] = value;\n },\n\n /** Function: forEachChild\n * Map a function over some or all child elements of a given element.\n *\n * This is a small convenience function for mapping a function over\n * some or all of the children of an element. If elemName is null, all\n * children will be passed to the function, otherwise only children\n * whose tag names match elemName will be passed.\n *\n * Parameters:\n * (XMLElement) elem - The element to operate on.\n * (String) elemName - The child element tag name filter.\n * (Function) func - The function to apply to each child. This\n * function should take a single argument, a DOM element.\n */\n forEachChild: function forEachChild(elem, elemName, func) {\n for (var i = 0; i < elem.childNodes.length; i++) {\n var childNode = elem.childNodes[i];\n\n if (childNode.nodeType === Strophe.ElementType.NORMAL && (!elemName || this.isTagEqual(childNode, elemName))) {\n func(childNode);\n }\n }\n },\n\n /** Function: isTagEqual\n * Compare an element's tag name with a string.\n *\n * This function is case sensitive.\n *\n * Parameters:\n * (XMLElement) el - A DOM element.\n * (String) name - The element name.\n *\n * Returns:\n * true if the element's tag name matches _el_, and false\n * otherwise.\n */\n isTagEqual: function isTagEqual(el, name) {\n return el.tagName === name;\n },\n\n /** PrivateVariable: _xmlGenerator\n * _Private_ variable that caches a DOM document to\n * generate elements.\n */\n _xmlGenerator: null,\n\n /** PrivateFunction: _makeGenerator\n * _Private_ function that creates a dummy XML DOM document to serve as\n * an element and text node generator.\n */\n _makeGenerator: function _makeGenerator() {\n var doc; // IE9 does implement createDocument(); however, using it will cause the browser to leak memory on page unload.\n // Here, we test for presence of createDocument() plus IE's proprietary documentMode attribute, which would be\n // less than 10 in the case of IE9 and below.\n\n if (document.implementation.createDocument === undefined || document.implementation.createDocument && document.documentMode && document.documentMode < 10) {\n doc = this._getIEXmlDom();\n doc.appendChild(doc.createElement('strophe'));\n } else {\n doc = document.implementation.createDocument('jabber:client', 'strophe', null);\n }\n\n return doc;\n },\n\n /** Function: xmlGenerator\n * Get the DOM document to generate elements.\n *\n * Returns:\n * The currently used DOM document.\n */\n xmlGenerator: function xmlGenerator() {\n if (!Strophe._xmlGenerator) {\n Strophe._xmlGenerator = Strophe._makeGenerator();\n }\n\n return Strophe._xmlGenerator;\n },\n\n /** PrivateFunction: _getIEXmlDom\n * Gets IE xml doc object\n *\n * Returns:\n * A Microsoft XML DOM Object\n * See Also:\n * http://msdn.microsoft.com/en-us/library/ms757837%28VS.85%29.aspx\n */\n _getIEXmlDom: function _getIEXmlDom() {\n var doc = null;\n var docStrings = [\"Msxml2.DOMDocument.6.0\", \"Msxml2.DOMDocument.5.0\", \"Msxml2.DOMDocument.4.0\", \"MSXML2.DOMDocument.3.0\", \"MSXML2.DOMDocument\", \"MSXML.DOMDocument\", \"Microsoft.XMLDOM\"];\n\n for (var d = 0; d < docStrings.length; d++) {\n if (doc === null) {\n try {\n doc = new ActiveXObject(docStrings[d]);\n } catch (e) {\n doc = null;\n }\n } else {\n break;\n }\n }\n\n return doc;\n },\n\n /** Function: xmlElement\n * Create an XML DOM element.\n *\n * This function creates an XML DOM element correctly across all\n * implementations. Note that these are not HTML DOM elements, which\n * aren't appropriate for XMPP stanzas.\n *\n * Parameters:\n * (String) name - The name for the element.\n * (Array|Object) attrs - An optional array or object containing\n * key/value pairs to use as element attributes. The object should\n * be in the format {'key': 'value'} or {key: 'value'}. The array\n * should have the format [['key1', 'value1'], ['key2', 'value2']].\n * (String) text - The text child data for the element.\n *\n * Returns:\n * A new XML DOM element.\n */\n xmlElement: function xmlElement(name) {\n if (!name) {\n return null;\n }\n\n var node = Strophe.xmlGenerator().createElement(name); // FIXME: this should throw errors if args are the wrong type or\n // there are more than two optional args\n\n for (var a = 1; a < arguments.length; a++) {\n var arg = arguments[a];\n\n if (!arg) {\n continue;\n }\n\n if (typeof arg === \"string\" || typeof arg === \"number\") {\n node.appendChild(Strophe.xmlTextNode(arg));\n } else if (_typeof(arg) === \"object\" && typeof arg.sort === \"function\") {\n for (var i = 0; i < arg.length; i++) {\n var attr = arg[i];\n\n if (_typeof(attr) === \"object\" && typeof attr.sort === \"function\" && attr[1] !== undefined && attr[1] !== null) {\n node.setAttribute(attr[0], attr[1]);\n }\n }\n } else if (_typeof(arg) === \"object\") {\n for (var k in arg) {\n if (Object.prototype.hasOwnProperty.call(arg, k) && arg[k] !== undefined && arg[k] !== null) {\n node.setAttribute(k, arg[k]);\n }\n }\n }\n }\n\n return node;\n },\n\n /* Function: xmlescape\n * Excapes invalid xml characters.\n *\n * Parameters:\n * (String) text - text to escape.\n *\n * Returns:\n * Escaped text.\n */\n xmlescape: function xmlescape(text) {\n text = text.replace(/\\&/g, \"&\");\n text = text.replace(//g, \">\");\n text = text.replace(/'/g, \"'\");\n text = text.replace(/\"/g, \""\");\n return text;\n },\n\n /* Function: xmlunescape\n * Unexcapes invalid xml characters.\n *\n * Parameters:\n * (String) text - text to unescape.\n *\n * Returns:\n * Unescaped text.\n */\n xmlunescape: function xmlunescape(text) {\n text = text.replace(/\\&/g, \"&\");\n text = text.replace(/</g, \"<\");\n text = text.replace(/>/g, \">\");\n text = text.replace(/'/g, \"'\");\n text = text.replace(/"/g, \"\\\"\");\n return text;\n },\n\n /** Function: xmlTextNode\n * Creates an XML DOM text node.\n *\n * Provides a cross implementation version of document.createTextNode.\n *\n * Parameters:\n * (String) text - The content of the text node.\n *\n * Returns:\n * A new XML DOM text node.\n */\n xmlTextNode: function xmlTextNode(text) {\n return Strophe.xmlGenerator().createTextNode(text);\n },\n\n /** Function: xmlHtmlNode\n * Creates an XML DOM html node.\n *\n * Parameters:\n * (String) html - The content of the html node.\n *\n * Returns:\n * A new XML DOM text node.\n */\n xmlHtmlNode: function xmlHtmlNode(html) {\n var node; //ensure text is escaped\n\n if (DOMParser) {\n var parser = new DOMParser();\n node = parser.parseFromString(html, \"text/xml\");\n } else {\n node = new ActiveXObject(\"Microsoft.XMLDOM\");\n node.async = \"false\";\n node.loadXML(html);\n }\n\n return node;\n },\n\n /** Function: getText\n * Get the concatenation of all text children of an element.\n *\n * Parameters:\n * (XMLElement) elem - A DOM element.\n *\n * Returns:\n * A String with the concatenated text of all text element children.\n */\n getText: function getText(elem) {\n if (!elem) {\n return null;\n }\n\n var str = \"\";\n\n if (elem.childNodes.length === 0 && elem.nodeType === Strophe.ElementType.TEXT) {\n str += elem.nodeValue;\n }\n\n for (var i = 0; i < elem.childNodes.length; i++) {\n if (elem.childNodes[i].nodeType === Strophe.ElementType.TEXT) {\n str += elem.childNodes[i].nodeValue;\n }\n }\n\n return Strophe.xmlescape(str);\n },\n\n /** Function: copyElement\n * Copy an XML DOM element.\n *\n * This function copies a DOM element and all its descendants and returns\n * the new copy.\n *\n * Parameters:\n * (XMLElement) elem - A DOM element.\n *\n * Returns:\n * A new, copied DOM element tree.\n */\n copyElement: function copyElement(elem) {\n var el;\n\n if (elem.nodeType === Strophe.ElementType.NORMAL) {\n el = Strophe.xmlElement(elem.tagName);\n\n for (var i = 0; i < elem.attributes.length; i++) {\n el.setAttribute(elem.attributes[i].nodeName, elem.attributes[i].value);\n }\n\n for (var _i = 0; _i < elem.childNodes.length; _i++) {\n el.appendChild(Strophe.copyElement(elem.childNodes[_i]));\n }\n } else if (elem.nodeType === Strophe.ElementType.TEXT) {\n el = Strophe.xmlGenerator().createTextNode(elem.nodeValue);\n }\n\n return el;\n },\n\n /** Function: createHtml\n * Copy an HTML DOM element into an XML DOM.\n *\n * This function copies a DOM element and all its descendants and returns\n * the new copy.\n *\n * Parameters:\n * (HTMLElement) elem - A DOM element.\n *\n * Returns:\n * A new, copied DOM element tree.\n */\n createHtml: function createHtml(elem) {\n var el;\n\n if (elem.nodeType === Strophe.ElementType.NORMAL) {\n var tag = elem.nodeName.toLowerCase(); // XHTML tags must be lower case.\n\n if (Strophe.XHTML.validTag(tag)) {\n try {\n el = Strophe.xmlElement(tag);\n\n for (var i = 0; i < Strophe.XHTML.attributes[tag].length; i++) {\n var attribute = Strophe.XHTML.attributes[tag][i];\n var value = elem.getAttribute(attribute);\n\n if (typeof value === 'undefined' || value === null || value === '' || value === false || value === 0) {\n continue;\n }\n\n if (attribute === 'style' && _typeof(value) === 'object' && typeof value.cssText !== 'undefined') {\n value = value.cssText; // we're dealing with IE, need to get CSS out\n } // filter out invalid css styles\n\n\n if (attribute === 'style') {\n var css = [];\n var cssAttrs = value.split(';');\n\n for (var j = 0; j < cssAttrs.length; j++) {\n var attr = cssAttrs[j].split(':');\n var cssName = attr[0].replace(/^\\s*/, \"\").replace(/\\s*$/, \"\").toLowerCase();\n\n if (Strophe.XHTML.validCSS(cssName)) {\n var cssValue = attr[1].replace(/^\\s*/, \"\").replace(/\\s*$/, \"\");\n css.push(cssName + ': ' + cssValue);\n }\n }\n\n if (css.length > 0) {\n value = css.join('; ');\n el.setAttribute(attribute, value);\n }\n } else {\n el.setAttribute(attribute, value);\n }\n }\n\n for (var _i2 = 0; _i2 < elem.childNodes.length; _i2++) {\n el.appendChild(Strophe.createHtml(elem.childNodes[_i2]));\n }\n } catch (e) {\n // invalid elements\n el = Strophe.xmlTextNode('');\n }\n } else {\n el = Strophe.xmlGenerator().createDocumentFragment();\n\n for (var _i3 = 0; _i3 < elem.childNodes.length; _i3++) {\n el.appendChild(Strophe.createHtml(elem.childNodes[_i3]));\n }\n }\n } else if (elem.nodeType === Strophe.ElementType.FRAGMENT) {\n el = Strophe.xmlGenerator().createDocumentFragment();\n\n for (var _i4 = 0; _i4 < elem.childNodes.length; _i4++) {\n el.appendChild(Strophe.createHtml(elem.childNodes[_i4]));\n }\n } else if (elem.nodeType === Strophe.ElementType.TEXT) {\n el = Strophe.xmlTextNode(elem.nodeValue);\n }\n\n return el;\n },\n\n /** Function: escapeNode\n * Escape the node part (also called local part) of a JID.\n *\n * Parameters:\n * (String) node - A node (or local part).\n *\n * Returns:\n * An escaped node (or local part).\n */\n escapeNode: function escapeNode(node) {\n if (typeof node !== \"string\") {\n return node;\n }\n\n return node.replace(/^\\s+|\\s+$/g, '').replace(/\\\\/g, \"\\\\5c\").replace(/ /g, \"\\\\20\").replace(/\\\"/g, \"\\\\22\").replace(/\\&/g, \"\\\\26\").replace(/\\'/g, \"\\\\27\").replace(/\\//g, \"\\\\2f\").replace(/:/g, \"\\\\3a\").replace(//g, \"\\\\3e\").replace(/@/g, \"\\\\40\");\n },\n\n /** Function: unescapeNode\n * Unescape a node part (also called local part) of a JID.\n *\n * Parameters:\n * (String) node - A node (or local part).\n *\n * Returns:\n * An unescaped node (or local part).\n */\n unescapeNode: function unescapeNode(node) {\n if (typeof node !== \"string\") {\n return node;\n }\n\n return node.replace(/\\\\20/g, \" \").replace(/\\\\22/g, '\"').replace(/\\\\26/g, \"&\").replace(/\\\\27/g, \"'\").replace(/\\\\2f/g, \"/\").replace(/\\\\3a/g, \":\").replace(/\\\\3c/g, \"<\").replace(/\\\\3e/g, \">\").replace(/\\\\40/g, \"@\").replace(/\\\\5c/g, \"\\\\\");\n },\n\n /** Function: getNodeFromJid\n * Get the node portion of a JID String.\n *\n * Parameters:\n * (String) jid - A JID.\n *\n * Returns:\n * A String containing the node.\n */\n getNodeFromJid: function getNodeFromJid(jid) {\n if (jid.indexOf(\"@\") < 0) {\n return null;\n }\n\n return jid.split(\"@\")[0];\n },\n\n /** Function: getDomainFromJid\n * Get the domain portion of a JID String.\n *\n * Parameters:\n * (String) jid - A JID.\n *\n * Returns:\n * A String containing the domain.\n */\n getDomainFromJid: function getDomainFromJid(jid) {\n var bare = Strophe.getBareJidFromJid(jid);\n\n if (bare.indexOf(\"@\") < 0) {\n return bare;\n } else {\n var parts = bare.split(\"@\");\n parts.splice(0, 1);\n return parts.join('@');\n }\n },\n\n /** Function: getResourceFromJid\n * Get the resource portion of a JID String.\n *\n * Parameters:\n * (String) jid - A JID.\n *\n * Returns:\n * A String containing the resource.\n */\n getResourceFromJid: function getResourceFromJid(jid) {\n if (!jid) {\n return null;\n }\n\n var s = jid.split(\"/\");\n\n if (s.length < 2) {\n return null;\n }\n\n s.splice(0, 1);\n return s.join('/');\n },\n\n /** Function: getBareJidFromJid\n * Get the bare JID from a JID String.\n *\n * Parameters:\n * (String) jid - A JID.\n *\n * Returns:\n * A String containing the bare JID.\n */\n getBareJidFromJid: function getBareJidFromJid(jid) {\n return jid ? jid.split(\"/\")[0] : null;\n },\n\n /** PrivateFunction: _handleError\n * _Private_ function that properly logs an error to the console\n */\n _handleError: function _handleError(e) {\n if (typeof e.stack !== \"undefined\") {\n Strophe.fatal(e.stack);\n }\n\n if (e.sourceURL) {\n Strophe.fatal(\"error: \" + this.handler + \" \" + e.sourceURL + \":\" + e.line + \" - \" + e.name + \": \" + e.message);\n } else if (e.fileName) {\n Strophe.fatal(\"error: \" + this.handler + \" \" + e.fileName + \":\" + e.lineNumber + \" - \" + e.name + \": \" + e.message);\n } else {\n Strophe.fatal(\"error: \" + e.message);\n }\n },\n\n /** Function: log\n * User overrideable logging function.\n *\n * This function is called whenever the Strophe library calls any\n * of the logging functions. The default implementation of this\n * function logs only fatal errors. If client code wishes to handle the logging\n * messages, it should override this with\n * > Strophe.log = function (level, msg) {\n * > (user code here)\n * > };\n *\n * Please note that data sent and received over the wire is logged\n * via Strophe.Connection.rawInput() and Strophe.Connection.rawOutput().\n *\n * The different levels and their meanings are\n *\n * DEBUG - Messages useful for debugging purposes.\n * INFO - Informational messages. This is mostly information like\n * 'disconnect was called' or 'SASL auth succeeded'.\n * WARN - Warnings about potential problems. This is mostly used\n * to report transient connection errors like request timeouts.\n * ERROR - Some error occurred.\n * FATAL - A non-recoverable fatal error occurred.\n *\n * Parameters:\n * (Integer) level - The log level of the log message. This will\n * be one of the values in Strophe.LogLevel.\n * (String) msg - The log message.\n */\n log: function log(level, msg) {\n if (level === this.LogLevel.FATAL && _typeof(window.console) === 'object' && typeof window.console.error === 'function') {\n window.console.error(msg);\n }\n },\n\n /** Function: debug\n * Log a message at the Strophe.LogLevel.DEBUG level.\n *\n * Parameters:\n * (String) msg - The log message.\n */\n debug: function debug(msg) {\n this.log(this.LogLevel.DEBUG, msg);\n },\n\n /** Function: info\n * Log a message at the Strophe.LogLevel.INFO level.\n *\n * Parameters:\n * (String) msg - The log message.\n */\n info: function info(msg) {\n this.log(this.LogLevel.INFO, msg);\n },\n\n /** Function: warn\n * Log a message at the Strophe.LogLevel.WARN level.\n *\n * Parameters:\n * (String) msg - The log message.\n */\n warn: function warn(msg) {\n this.log(this.LogLevel.WARN, msg);\n },\n\n /** Function: error\n * Log a message at the Strophe.LogLevel.ERROR level.\n *\n * Parameters:\n * (String) msg - The log message.\n */\n error: function error(msg) {\n this.log(this.LogLevel.ERROR, msg);\n },\n\n /** Function: fatal\n * Log a message at the Strophe.LogLevel.FATAL level.\n *\n * Parameters:\n * (String) msg - The log message.\n */\n fatal: function fatal(msg) {\n this.log(this.LogLevel.FATAL, msg);\n },\n\n /** Function: serialize\n * Render a DOM element and all descendants to a String.\n *\n * Parameters:\n * (XMLElement) elem - A DOM element.\n *\n * Returns:\n * The serialized element tree as a String.\n */\n serialize: function serialize(elem) {\n if (!elem) {\n return null;\n }\n\n if (typeof elem.tree === \"function\") {\n elem = elem.tree();\n }\n\n var names = _toConsumableArray(Array(elem.attributes.length).keys()).map(function (i) {\n return elem.attributes[i].nodeName;\n });\n\n names.sort();\n var result = names.reduce(function (a, n) {\n return \"\".concat(a, \" \").concat(n, \"=\\\"\").concat(Strophe.xmlescape(elem.attributes.getNamedItem(n).value), \"\\\"\");\n }, \"<\".concat(elem.nodeName));\n\n if (elem.childNodes.length > 0) {\n result += \">\";\n\n for (var i = 0; i < elem.childNodes.length; i++) {\n var child = elem.childNodes[i];\n\n switch (child.nodeType) {\n case Strophe.ElementType.NORMAL:\n // normal element, so recurse\n result += Strophe.serialize(child);\n break;\n\n case Strophe.ElementType.TEXT:\n // text element to escape values\n result += Strophe.xmlescape(child.nodeValue);\n break;\n\n case Strophe.ElementType.CDATA:\n // cdata section so don't escape values\n result += \"\";\n }\n }\n\n result += \"\";\n } else {\n result += \"/>\";\n }\n\n return result;\n },\n\n /** PrivateVariable: _requestId\n * _Private_ variable that keeps track of the request ids for\n * connections.\n */\n _requestId: 0,\n\n /** PrivateVariable: Strophe.connectionPlugins\n * _Private_ variable Used to store plugin names that need\n * initialization on Strophe.Connection construction.\n */\n _connectionPlugins: {},\n\n /** Function: addConnectionPlugin\n * Extends the Strophe.Connection object with the given plugin.\n *\n * Parameters:\n * (String) name - The name of the extension.\n * (Object) ptype - The plugin's prototype.\n */\n addConnectionPlugin: function addConnectionPlugin(name, ptype) {\n Strophe._connectionPlugins[name] = ptype;\n }\n };\n /** Class: Strophe.Builder\n * XML DOM builder.\n *\n * This object provides an interface similar to JQuery but for building\n * DOM elements easily and rapidly. All the functions except for toString()\n * and tree() return the object, so calls can be chained. Here's an\n * example using the $iq() builder helper.\n * > $iq({to: 'you', from: 'me', type: 'get', id: '1'})\n * > .c('query', {xmlns: 'strophe:example'})\n * > .c('example')\n * > .toString()\n *\n * The above generates this XML fragment\n * > \n * > \n * > \n * > \n * > \n * The corresponding DOM manipulations to get a similar fragment would be\n * a lot more tedious and probably involve several helper variables.\n *\n * Since adding children makes new operations operate on the child, up()\n * is provided to traverse up the tree. To add two children, do\n * > builder.c('child1', ...).up().c('child2', ...)\n * The next operation on the Builder will be relative to the second child.\n */\n\n /** Constructor: Strophe.Builder\n * Create a Strophe.Builder object.\n *\n * The attributes should be passed in object notation. For example\n * > let b = new Builder('message', {to: 'you', from: 'me'});\n * or\n * > let b = new Builder('messsage', {'xml:lang': 'en'});\n *\n * Parameters:\n * (String) name - The name of the root element.\n * (Object) attrs - The attributes for the root element in object notation.\n *\n * Returns:\n * A new Strophe.Builder.\n */\n\n Strophe.Builder = function (name, attrs) {\n // Set correct namespace for jabber:client elements\n if (name === \"presence\" || name === \"message\" || name === \"iq\") {\n if (attrs && !attrs.xmlns) {\n attrs.xmlns = Strophe.NS.CLIENT;\n } else if (!attrs) {\n attrs = {\n xmlns: Strophe.NS.CLIENT\n };\n }\n } // Holds the tree being built.\n\n\n this.nodeTree = Strophe.xmlElement(name, attrs); // Points to the current operation node.\n\n this.node = this.nodeTree;\n };\n\n Strophe.Builder.prototype = {\n /** Function: tree\n * Return the DOM tree.\n *\n * This function returns the current DOM tree as an element object. This\n * is suitable for passing to functions like Strophe.Connection.send().\n *\n * Returns:\n * The DOM tree as a element object.\n */\n tree: function tree() {\n return this.nodeTree;\n },\n\n /** Function: toString\n * Serialize the DOM tree to a String.\n *\n * This function returns a string serialization of the current DOM\n * tree. It is often used internally to pass data to a\n * Strophe.Request object.\n *\n * Returns:\n * The serialized DOM tree in a String.\n */\n toString: function toString() {\n return Strophe.serialize(this.nodeTree);\n },\n\n /** Function: up\n * Make the current parent element the new current element.\n *\n * This function is often used after c() to traverse back up the tree.\n * For example, to add two children to the same element\n * > builder.c('child1', {}).up().c('child2', {});\n *\n * Returns:\n * The Stophe.Builder object.\n */\n up: function up() {\n this.node = this.node.parentNode;\n return this;\n },\n\n /** Function: root\n * Make the root element the new current element.\n *\n * When at a deeply nested element in the tree, this function can be used\n * to jump back to the root of the tree, instead of having to repeatedly\n * call up().\n *\n * Returns:\n * The Stophe.Builder object.\n */\n root: function root() {\n this.node = this.nodeTree;\n return this;\n },\n\n /** Function: attrs\n * Add or modify attributes of the current element.\n *\n * The attributes should be passed in object notation. This function\n * does not move the current element pointer.\n *\n * Parameters:\n * (Object) moreattrs - The attributes to add/modify in object notation.\n *\n * Returns:\n * The Strophe.Builder object.\n */\n attrs: function attrs(moreattrs) {\n for (var k in moreattrs) {\n if (Object.prototype.hasOwnProperty.call(moreattrs, k)) {\n if (moreattrs[k] === undefined) {\n this.node.removeAttribute(k);\n } else {\n this.node.setAttribute(k, moreattrs[k]);\n }\n }\n }\n\n return this;\n },\n\n /** Function: c\n * Add a child to the current element and make it the new current\n * element.\n *\n * This function moves the current element pointer to the child,\n * unless text is provided. If you need to add another child, it\n * is necessary to use up() to go back to the parent in the tree.\n *\n * Parameters:\n * (String) name - The name of the child.\n * (Object) attrs - The attributes of the child in object notation.\n * (String) text - The text to add to the child.\n *\n * Returns:\n * The Strophe.Builder object.\n */\n c: function c(name, attrs, text) {\n var child = Strophe.xmlElement(name, attrs, text);\n this.node.appendChild(child);\n\n if (typeof text !== \"string\" && typeof text !== \"number\") {\n this.node = child;\n }\n\n return this;\n },\n\n /** Function: cnode\n * Add a child to the current element and make it the new current\n * element.\n *\n * This function is the same as c() except that instead of using a\n * name and an attributes object to create the child it uses an\n * existing DOM element object.\n *\n * Parameters:\n * (XMLElement) elem - A DOM element.\n *\n * Returns:\n * The Strophe.Builder object.\n */\n cnode: function cnode(elem) {\n var impNode;\n var xmlGen = Strophe.xmlGenerator();\n\n try {\n impNode = xmlGen.importNode !== undefined;\n } catch (e) {\n impNode = false;\n }\n\n var newElem = impNode ? xmlGen.importNode(elem, true) : Strophe.copyElement(elem);\n this.node.appendChild(newElem);\n this.node = newElem;\n return this;\n },\n\n /** Function: t\n * Add a child text element.\n *\n * This *does not* make the child the new current element since there\n * are no children of text elements.\n *\n * Parameters:\n * (String) text - The text data to append to the current element.\n *\n * Returns:\n * The Strophe.Builder object.\n */\n t: function t(text) {\n var child = Strophe.xmlTextNode(text);\n this.node.appendChild(child);\n return this;\n },\n\n /** Function: h\n * Replace current element contents with the HTML passed in.\n *\n * This *does not* make the child the new current element\n *\n * Parameters:\n * (String) html - The html to insert as contents of current element.\n *\n * Returns:\n * The Strophe.Builder object.\n */\n h: function h(html) {\n var fragment = document.createElement('body'); // force the browser to try and fix any invalid HTML tags\n\n fragment.innerHTML = html; // copy cleaned html into an xml dom\n\n var xhtml = Strophe.createHtml(fragment);\n\n while (xhtml.childNodes.length > 0) {\n this.node.appendChild(xhtml.childNodes[0]);\n }\n\n return this;\n }\n };\n /** PrivateClass: Strophe.Handler\n * _Private_ helper class for managing stanza handlers.\n *\n * A Strophe.Handler encapsulates a user provided callback function to be\n * executed when matching stanzas are received by the connection.\n * Handlers can be either one-off or persistant depending on their\n * return value. Returning true will cause a Handler to remain active, and\n * returning false will remove the Handler.\n *\n * Users will not use Strophe.Handler objects directly, but instead they\n * will use Strophe.Connection.addHandler() and\n * Strophe.Connection.deleteHandler().\n */\n\n /** PrivateConstructor: Strophe.Handler\n * Create and initialize a new Strophe.Handler.\n *\n * Parameters:\n * (Function) handler - A function to be executed when the handler is run.\n * (String) ns - The namespace to match.\n * (String) name - The element name to match.\n * (String) type - The element type to match.\n * (String) id - The element id attribute to match.\n * (String) from - The element from attribute to match.\n * (Object) options - Handler options\n *\n * Returns:\n * A new Strophe.Handler object.\n */\n\n Strophe.Handler = function (handler, ns, name, type, id, from, options) {\n this.handler = handler;\n this.ns = ns;\n this.name = name;\n this.type = type;\n this.id = id;\n this.options = options || {\n 'matchBareFromJid': false,\n 'ignoreNamespaceFragment': false\n }; // BBB: Maintain backward compatibility with old `matchBare` option\n\n if (this.options.matchBare) {\n Strophe.warn('The \"matchBare\" option is deprecated, use \"matchBareFromJid\" instead.');\n this.options.matchBareFromJid = this.options.matchBare;\n delete this.options.matchBare;\n }\n\n if (this.options.matchBareFromJid) {\n this.from = from ? Strophe.getBareJidFromJid(from) : null;\n } else {\n this.from = from;\n } // whether the handler is a user handler or a system handler\n\n\n this.user = true;\n };\n\n Strophe.Handler.prototype = {\n /** PrivateFunction: getNamespace\n * Returns the XML namespace attribute on an element.\n * If `ignoreNamespaceFragment` was passed in for this handler, then the\n * URL fragment will be stripped.\n *\n * Parameters:\n * (XMLElement) elem - The XML element with the namespace.\n *\n * Returns:\n * The namespace, with optionally the fragment stripped.\n */\n getNamespace: function getNamespace(elem) {\n var elNamespace = elem.getAttribute(\"xmlns\");\n\n if (elNamespace && this.options.ignoreNamespaceFragment) {\n elNamespace = elNamespace.split('#')[0];\n }\n\n return elNamespace;\n },\n\n /** PrivateFunction: namespaceMatch\n * Tests if a stanza matches the namespace set for this Strophe.Handler.\n *\n * Parameters:\n * (XMLElement) elem - The XML element to test.\n *\n * Returns:\n * true if the stanza matches and false otherwise.\n */\n namespaceMatch: function namespaceMatch(elem) {\n var _this = this;\n\n var nsMatch = false;\n\n if (!this.ns) {\n return true;\n } else {\n Strophe.forEachChild(elem, null, function (elem) {\n if (_this.getNamespace(elem) === _this.ns) {\n nsMatch = true;\n }\n });\n return nsMatch || this.getNamespace(elem) === this.ns;\n }\n },\n\n /** PrivateFunction: isMatch\n * Tests if a stanza matches the Strophe.Handler.\n *\n * Parameters:\n * (XMLElement) elem - The XML element to test.\n *\n * Returns:\n * true if the stanza matches and false otherwise.\n */\n isMatch: function isMatch(elem) {\n var from = elem.getAttribute('from');\n\n if (this.options.matchBareFromJid) {\n from = Strophe.getBareJidFromJid(from);\n }\n\n var elem_type = elem.getAttribute(\"type\");\n\n if (this.namespaceMatch(elem) && (!this.name || Strophe.isTagEqual(elem, this.name)) && (!this.type || (Array.isArray(this.type) ? this.type.indexOf(elem_type) !== -1 : elem_type === this.type)) && (!this.id || elem.getAttribute(\"id\") === this.id) && (!this.from || from === this.from)) {\n return true;\n }\n\n return false;\n },\n\n /** PrivateFunction: run\n * Run the callback on a matching stanza.\n *\n * Parameters:\n * (XMLElement) elem - The DOM element that triggered the\n * Strophe.Handler.\n *\n * Returns:\n * A boolean indicating if the handler should remain active.\n */\n run: function run(elem) {\n var result = null;\n\n try {\n result = this.handler(elem);\n } catch (e) {\n Strophe._handleError(e);\n\n throw e;\n }\n\n return result;\n },\n\n /** PrivateFunction: toString\n * Get a String representation of the Strophe.Handler object.\n *\n * Returns:\n * A String.\n */\n toString: function toString() {\n return \"{Handler: \" + this.handler + \"(\" + this.name + \",\" + this.id + \",\" + this.ns + \")}\";\n }\n };\n /** PrivateClass: Strophe.TimedHandler\n * _Private_ helper class for managing timed handlers.\n *\n * A Strophe.TimedHandler encapsulates a user provided callback that\n * should be called after a certain period of time or at regular\n * intervals. The return value of the callback determines whether the\n * Strophe.TimedHandler will continue to fire.\n *\n * Users will not use Strophe.TimedHandler objects directly, but instead\n * they will use Strophe.Connection.addTimedHandler() and\n * Strophe.Connection.deleteTimedHandler().\n */\n\n /** PrivateConstructor: Strophe.TimedHandler\n * Create and initialize a new Strophe.TimedHandler object.\n *\n * Parameters:\n * (Integer) period - The number of milliseconds to wait before the\n * handler is called.\n * (Function) handler - The callback to run when the handler fires. This\n * function should take no arguments.\n *\n * Returns:\n * A new Strophe.TimedHandler object.\n */\n\n Strophe.TimedHandler = function (period, handler) {\n this.period = period;\n this.handler = handler;\n this.lastCalled = new Date().getTime();\n this.user = true;\n };\n\n Strophe.TimedHandler.prototype = {\n /** PrivateFunction: run\n * Run the callback for the Strophe.TimedHandler.\n *\n * Returns:\n * true if the Strophe.TimedHandler should be called again, and false\n * otherwise.\n */\n run: function run() {\n this.lastCalled = new Date().getTime();\n return this.handler();\n },\n\n /** PrivateFunction: reset\n * Reset the last called time for the Strophe.TimedHandler.\n */\n reset: function reset() {\n this.lastCalled = new Date().getTime();\n },\n\n /** PrivateFunction: toString\n * Get a string representation of the Strophe.TimedHandler object.\n *\n * Returns:\n * The string representation.\n */\n toString: function toString() {\n return \"{TimedHandler: \" + this.handler + \"(\" + this.period + \")}\";\n }\n };\n /** Class: Strophe.Connection\n * XMPP Connection manager.\n *\n * This class is the main part of Strophe. It manages a BOSH or websocket\n * connection to an XMPP server and dispatches events to the user callbacks\n * as data arrives. It supports SASL PLAIN, SASL DIGEST-MD5, SASL SCRAM-SHA1\n * and legacy authentication.\n *\n * After creating a Strophe.Connection object, the user will typically\n * call connect() with a user supplied callback to handle connection level\n * events like authentication failure, disconnection, or connection\n * complete.\n *\n * The user will also have several event handlers defined by using\n * addHandler() and addTimedHandler(). These will allow the user code to\n * respond to interesting stanzas or do something periodically with the\n * connection. These handlers will be active once authentication is\n * finished.\n *\n * To send data to the connection, use send().\n */\n\n /** Constructor: Strophe.Connection\n * Create and initialize a Strophe.Connection object.\n *\n * The transport-protocol for this connection will be chosen automatically\n * based on the given service parameter. URLs starting with \"ws://\" or\n * \"wss://\" will use WebSockets, URLs starting with \"http://\", \"https://\"\n * or without a protocol will use BOSH.\n *\n * To make Strophe connect to the current host you can leave out the protocol\n * and host part and just pass the path, e.g.\n *\n * > let conn = new Strophe.Connection(\"/http-bind/\");\n *\n * Options common to both Websocket and BOSH:\n * ------------------------------------------\n *\n * cookies:\n *\n * The *cookies* option allows you to pass in cookies to be added to the\n * document. These cookies will then be included in the BOSH XMLHttpRequest\n * or in the websocket connection.\n *\n * The passed in value must be a map of cookie names and string values.\n *\n * > { \"myCookie\": {\n * > \"value\": \"1234\",\n * > \"domain\": \".example.org\",\n * > \"path\": \"/\",\n * > \"expires\": expirationDate\n * > }\n * > }\n *\n * Note that cookies can't be set in this way for other domains (i.e. cross-domain).\n * Those cookies need to be set under those domains, for example they can be\n * set server-side by making a XHR call to that domain to ask it to set any\n * necessary cookies.\n *\n * mechanisms:\n *\n * The *mechanisms* option allows you to specify the SASL mechanisms that this\n * instance of Strophe.Connection (and therefore your XMPP client) will\n * support.\n *\n * The value must be an array of objects with Strophe.SASLMechanism\n * prototypes.\n *\n * If nothing is specified, then the following mechanisms (and their\n * priorities) are registered:\n *\n * SCRAM-SHA1 - 70\n * DIGEST-MD5 - 60\n * PLAIN - 50\n * OAUTH-BEARER - 40\n * OAUTH-2 - 30\n * ANONYMOUS - 20\n * EXTERNAL - 10\n *\n * explicitResourceBinding:\n *\n * If `explicitResourceBinding` is set to a truthy value, then the XMPP client\n * needs to explicitly call `Strophe.Connection.prototype.bind` once the XMPP\n * server has advertised the \"urn:ietf:params:xml:ns:xmpp-bind\" feature.\n *\n * Making this step explicit allows client authors to first finish other\n * stream related tasks, such as setting up an XEP-0198 Stream Management\n * session, before binding the JID resource for this session.\n *\n * WebSocket options:\n * ------------------\n *\n * If you want to connect to the current host with a WebSocket connection you\n * can tell Strophe to use WebSockets through a \"protocol\" attribute in the\n * optional options parameter. Valid values are \"ws\" for WebSocket and \"wss\"\n * for Secure WebSocket.\n * So to connect to \"wss://CURRENT_HOSTNAME/xmpp-websocket\" you would call\n *\n * > let conn = new Strophe.Connection(\"/xmpp-websocket/\", {protocol: \"wss\"});\n *\n * Note that relative URLs _NOT_ starting with a \"/\" will also include the path\n * of the current site.\n *\n * Also because downgrading security is not permitted by browsers, when using\n * relative URLs both BOSH and WebSocket connections will use their secure\n * variants if the current connection to the site is also secure (https).\n *\n * BOSH options:\n * -------------\n *\n * By adding \"sync\" to the options, you can control if requests will\n * be made synchronously or not. The default behaviour is asynchronous.\n * If you want to make requests synchronous, make \"sync\" evaluate to true.\n * > let conn = new Strophe.Connection(\"/http-bind/\", {sync: true});\n *\n * You can also toggle this on an already established connection.\n * > conn.options.sync = true;\n *\n * The *customHeaders* option can be used to provide custom HTTP headers to be\n * included in the XMLHttpRequests made.\n *\n * The *keepalive* option can be used to instruct Strophe to maintain the\n * current BOSH session across interruptions such as webpage reloads.\n *\n * It will do this by caching the sessions tokens in sessionStorage, and when\n * \"restore\" is called it will check whether there are cached tokens with\n * which it can resume an existing session.\n *\n * The *withCredentials* option should receive a Boolean value and is used to\n * indicate wether cookies should be included in ajax requests (by default\n * they're not).\n * Set this value to true if you are connecting to a BOSH service\n * and for some reason need to send cookies to it.\n * In order for this to work cross-domain, the server must also enable\n * credentials by setting the Access-Control-Allow-Credentials response header\n * to \"true\". For most usecases however this setting should be false (which\n * is the default).\n * Additionally, when using Access-Control-Allow-Credentials, the\n * Access-Control-Allow-Origin header can't be set to the wildcard \"*\", but\n * instead must be restricted to actual domains.\n *\n * The *contentType* option can be set to change the default Content-Type\n * of \"text/xml; charset=utf-8\", which can be useful to reduce the amount of\n * CORS preflight requests that are sent to the server.\n *\n * Parameters:\n * (String) service - The BOSH or WebSocket service URL.\n * (Object) options - A hash of configuration options\n *\n * Returns:\n * A new Strophe.Connection object.\n */\n\n Strophe.Connection = function (service, options) {\n var _this2 = this;\n\n // The service URL\n this.service = service; // Configuration options\n\n this.options = options || {};\n var proto = this.options.protocol || \"\"; // Select protocal based on service or options\n\n if (service.indexOf(\"ws:\") === 0 || service.indexOf(\"wss:\") === 0 || proto.indexOf(\"ws\") === 0) {\n this._proto = new Strophe.Websocket(this);\n } else {\n this._proto = new Strophe.Bosh(this);\n }\n /* The connected JID. */\n\n\n this.jid = \"\";\n /* the JIDs domain */\n\n this.domain = null;\n /* stream:features */\n\n this.features = null; // SASL\n\n this._sasl_data = {};\n this.do_session = false;\n this.do_bind = false; // handler lists\n\n this.timedHandlers = [];\n this.handlers = [];\n this.removeTimeds = [];\n this.removeHandlers = [];\n this.addTimeds = [];\n this.addHandlers = [];\n this.protocolErrorHandlers = {\n 'HTTP': {},\n 'websocket': {}\n };\n this._idleTimeout = null;\n this._disconnectTimeout = null;\n this.authenticated = false;\n this.connected = false;\n this.disconnecting = false;\n this.do_authentication = true;\n this.paused = false;\n this.restored = false;\n this._data = [];\n this._uniqueId = 0;\n this._sasl_success_handler = null;\n this._sasl_failure_handler = null;\n this._sasl_challenge_handler = null; // Max retries before disconnecting\n\n this.maxRetries = 5; // Call onIdle callback every 1/10th of a second\n\n this._idleTimeout = setTimeout(function () {\n return _this2._onIdle();\n }, 100);\n utils.addCookies(this.options.cookies);\n this.registerSASLMechanisms(this.options.mechanisms); // initialize plugins\n\n for (var k in Strophe._connectionPlugins) {\n if (Object.prototype.hasOwnProperty.call(Strophe._connectionPlugins, k)) {\n var F = function F() {};\n\n F.prototype = Strophe._connectionPlugins[k];\n this[k] = new F();\n this[k].init(this);\n }\n }\n };\n\n Strophe.Connection.prototype = {\n /** Function: reset\n * Reset the connection.\n *\n * This function should be called after a connection is disconnected\n * before that connection is reused.\n */\n reset: function reset() {\n this._proto._reset(); // SASL\n\n\n this.do_session = false;\n this.do_bind = false; // handler lists\n\n this.timedHandlers = [];\n this.handlers = [];\n this.removeTimeds = [];\n this.removeHandlers = [];\n this.addTimeds = [];\n this.addHandlers = [];\n this.authenticated = false;\n this.connected = false;\n this.disconnecting = false;\n this.restored = false;\n this._data = [];\n this._requests = [];\n this._uniqueId = 0;\n },\n\n /** Function: pause\n * Pause the request manager.\n *\n * This will prevent Strophe from sending any more requests to the\n * server. This is very useful for temporarily pausing\n * BOSH-Connections while a lot of send() calls are happening quickly.\n * This causes Strophe to send the data in a single request, saving\n * many request trips.\n */\n pause: function pause() {\n this.paused = true;\n },\n\n /** Function: resume\n * Resume the request manager.\n *\n * This resumes after pause() has been called.\n */\n resume: function resume() {\n this.paused = false;\n },\n\n /** Function: getUniqueId\n * Generate a unique ID for use in elements.\n *\n * All stanzas are required to have unique id attributes. This\n * function makes creating these easy. Each connection instance has\n * a counter which starts from zero, and the value of this counter\n * plus a colon followed by the suffix becomes the unique id. If no\n * suffix is supplied, the counter is used as the unique id.\n *\n * Suffixes are used to make debugging easier when reading the stream\n * data, and their use is recommended. The counter resets to 0 for\n * every new connection for the same reason. For connections to the\n * same server that authenticate the same way, all the ids should be\n * the same, which makes it easy to see changes. This is useful for\n * automated testing as well.\n *\n * Parameters:\n * (String) suffix - A optional suffix to append to the id.\n *\n * Returns:\n * A unique string to be used for the id attribute.\n */\n getUniqueId: function getUniqueId(suffix) {\n var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n var r = Math.random() * 16 | 0,\n v = c === 'x' ? r : r & 0x3 | 0x8;\n return v.toString(16);\n });\n\n if (typeof suffix === \"string\" || typeof suffix === \"number\") {\n return uuid + \":\" + suffix;\n } else {\n return uuid + \"\";\n }\n },\n\n /** Function: addProtocolErrorHandler\n * Register a handler function for when a protocol (websocker or HTTP)\n * error occurs.\n *\n * NOTE: Currently only HTTP errors for BOSH requests are handled.\n * Patches that handle websocket errors would be very welcome.\n *\n * Parameters:\n * (String) protocol - 'HTTP' or 'websocket'\n * (Integer) status_code - Error status code (e.g 500, 400 or 404)\n * (Function) callback - Function that will fire on Http error\n *\n * Example:\n * function onError(err_code){\n * //do stuff\n * }\n *\n * let conn = Strophe.connect('http://example.com/http-bind');\n * conn.addProtocolErrorHandler('HTTP', 500, onError);\n * // Triggers HTTP 500 error and onError handler will be called\n * conn.connect('user_jid@incorrect_jabber_host', 'secret', onConnect);\n */\n addProtocolErrorHandler: function addProtocolErrorHandler(protocol, status_code, callback) {\n this.protocolErrorHandlers[protocol][status_code] = callback;\n },\n\n /** Function: connect\n * Starts the connection process.\n *\n * As the connection process proceeds, the user supplied callback will\n * be triggered multiple times with status updates. The callback\n * should take two arguments - the status code and the error condition.\n *\n * The status code will be one of the values in the Strophe.Status\n * constants. The error condition will be one of the conditions\n * defined in RFC 3920 or the condition 'strophe-parsererror'.\n *\n * The Parameters _wait_, _hold_ and _route_ are optional and only relevant\n * for BOSH connections. Please see XEP 124 for a more detailed explanation\n * of the optional parameters.\n *\n * Parameters:\n * (String) jid - The user's JID. This may be a bare JID,\n * or a full JID. If a node is not supplied, SASL OAUTHBEARER or\n * SASL ANONYMOUS authentication will be attempted (OAUTHBEARER will\n * process the provided password value as an access token).\n * (String) pass - The user's password.\n * (Function) callback - The connect callback function.\n * (Integer) wait - The optional HTTPBIND wait value. This is the\n * time the server will wait before returning an empty result for\n * a request. The default setting of 60 seconds is recommended.\n * (Integer) hold - The optional HTTPBIND hold value. This is the\n * number of connections the server will hold at one time. This\n * should almost always be set to 1 (the default).\n * (String) route - The optional route value.\n * (String) authcid - The optional alternative authentication identity\n * (username) if intending to impersonate another user.\n * When using the SASL-EXTERNAL authentication mechanism, for example\n * with client certificates, then the authcid value is used to\n * determine whether an authorization JID (authzid) should be sent to\n * the server. The authzid should not be sent to the server if the\n * authzid and authcid are the same. So to prevent it from being sent\n * (for example when the JID is already contained in the client\n * certificate), set authcid to that same JID. See XEP-178 for more\n * details.\n */\n connect: function connect(jid, pass, callback, wait, hold, route, authcid) {\n this.jid = jid;\n /** Variable: authzid\n * Authorization identity.\n */\n\n this.authzid = Strophe.getBareJidFromJid(this.jid);\n /** Variable: authcid\n * Authentication identity (User name).\n */\n\n this.authcid = authcid || Strophe.getNodeFromJid(this.jid);\n /** Variable: pass\n * Authentication identity (User password).\n */\n\n this.pass = pass;\n /** Variable: servtype\n * Digest MD5 compatibility.\n */\n\n this.servtype = \"xmpp\";\n this.connect_callback = callback;\n this.disconnecting = false;\n this.connected = false;\n this.authenticated = false;\n this.restored = false; // parse jid for domain\n\n this.domain = Strophe.getDomainFromJid(this.jid);\n\n this._changeConnectStatus(Strophe.Status.CONNECTING, null);\n\n this._proto._connect(wait, hold, route);\n },\n\n /** Function: attach\n * Attach to an already created and authenticated BOSH session.\n *\n * This function is provided to allow Strophe to attach to BOSH\n * sessions which have been created externally, perhaps by a Web\n * application. This is often used to support auto-login type features\n * without putting user credentials into the page.\n *\n * Parameters:\n * (String) jid - The full JID that is bound by the session.\n * (String) sid - The SID of the BOSH session.\n * (String) rid - The current RID of the BOSH session. This RID\n * will be used by the next request.\n * (Function) callback The connect callback function.\n * (Integer) wait - The optional HTTPBIND wait value. This is the\n * time the server will wait before returning an empty result for\n * a request. The default setting of 60 seconds is recommended.\n * Other settings will require tweaks to the Strophe.TIMEOUT value.\n * (Integer) hold - The optional HTTPBIND hold value. This is the\n * number of connections the server will hold at one time. This\n * should almost always be set to 1 (the default).\n * (Integer) wind - The optional HTTBIND window value. This is the\n * allowed range of request ids that are valid. The default is 5.\n */\n attach: function attach(jid, sid, rid, callback, wait, hold, wind) {\n if (this._proto instanceof Strophe.Bosh) {\n this._proto._attach(jid, sid, rid, callback, wait, hold, wind);\n } else {\n var error = new Error('The \"attach\" method can only be used with a BOSH connection.');\n error.name = 'StropheSessionError';\n throw error;\n }\n },\n\n /** Function: restore\n * Attempt to restore a cached BOSH session.\n *\n * This function is only useful in conjunction with providing the\n * \"keepalive\":true option when instantiating a new Strophe.Connection.\n *\n * When \"keepalive\" is set to true, Strophe will cache the BOSH tokens\n * RID (Request ID) and SID (Session ID) and then when this function is\n * called, it will attempt to restore the session from those cached\n * tokens.\n *\n * This function must therefore be called instead of connect or attach.\n *\n * For an example on how to use it, please see examples/restore.js\n *\n * Parameters:\n * (String) jid - The user's JID. This may be a bare JID or a full JID.\n * (Function) callback - The connect callback function.\n * (Integer) wait - The optional HTTPBIND wait value. This is the\n * time the server will wait before returning an empty result for\n * a request. The default setting of 60 seconds is recommended.\n * (Integer) hold - The optional HTTPBIND hold value. This is the\n * number of connections the server will hold at one time. This\n * should almost always be set to 1 (the default).\n * (Integer) wind - The optional HTTBIND window value. This is the\n * allowed range of request ids that are valid. The default is 5.\n */\n restore: function restore(jid, callback, wait, hold, wind) {\n if (this._sessionCachingSupported()) {\n this._proto._restore(jid, callback, wait, hold, wind);\n } else {\n var error = new Error('The \"restore\" method can only be used with a BOSH connection.');\n error.name = 'StropheSessionError';\n throw error;\n }\n },\n\n /** PrivateFunction: _sessionCachingSupported\n * Checks whether sessionStorage and JSON are supported and whether we're\n * using BOSH.\n */\n _sessionCachingSupported: function _sessionCachingSupported() {\n if (this._proto instanceof Strophe.Bosh) {\n if (!JSON) {\n return false;\n }\n\n try {\n sessionStorage.setItem('_strophe_', '_strophe_');\n sessionStorage.removeItem('_strophe_');\n } catch (e) {\n return false;\n }\n\n return true;\n }\n\n return false;\n },\n\n /** Function: xmlInput\n * User overrideable function that receives XML data coming into the\n * connection.\n *\n * The default function does nothing. User code can override this with\n * > Strophe.Connection.xmlInput = function (elem) {\n * > (user code)\n * > };\n *\n * Due to limitations of current Browsers' XML-Parsers the opening and closing\n * tag for WebSocket-Connoctions will be passed as selfclosing here.\n *\n * BOSH-Connections will have all stanzas wrapped in a tag. See\n * if you want to strip this tag.\n *\n * Parameters:\n * (XMLElement) elem - The XML data received by the connection.\n */\n xmlInput: function xmlInput(elem) {\n return;\n },\n\n /** Function: xmlOutput\n * User overrideable function that receives XML data sent to the\n * connection.\n *\n * The default function does nothing. User code can override this with\n * > Strophe.Connection.xmlOutput = function (elem) {\n * > (user code)\n * > };\n *\n * Due to limitations of current Browsers' XML-Parsers the opening and closing\n * tag for WebSocket-Connoctions will be passed as selfclosing here.\n *\n * BOSH-Connections will have all stanzas wrapped in a tag. See\n * if you want to strip this tag.\n *\n * Parameters:\n * (XMLElement) elem - The XMLdata sent by the connection.\n */\n xmlOutput: function xmlOutput(elem) {\n return;\n },\n\n /** Function: rawInput\n * User overrideable function that receives raw data coming into the\n * connection.\n *\n * The default function does nothing. User code can override this with\n * > Strophe.Connection.rawInput = function (data) {\n * > (user code)\n * > };\n *\n * Parameters:\n * (String) data - The data received by the connection.\n */\n rawInput: function rawInput(data) {\n return;\n },\n\n /** Function: rawOutput\n * User overrideable function that receives raw data sent to the\n * connection.\n *\n * The default function does nothing. User code can override this with\n * > Strophe.Connection.rawOutput = function (data) {\n * > (user code)\n * > };\n *\n * Parameters:\n * (String) data - The data sent by the connection.\n */\n rawOutput: function rawOutput(data) {\n return;\n },\n\n /** Function: nextValidRid\n * User overrideable function that receives the new valid rid.\n *\n * The default function does nothing. User code can override this with\n * > Strophe.Connection.nextValidRid = function (rid) {\n * > (user code)\n * > };\n *\n * Parameters:\n * (Number) rid - The next valid rid\n */\n nextValidRid: function nextValidRid(rid) {\n return;\n },\n\n /** Function: send\n * Send a stanza.\n *\n * This function is called to push data onto the send queue to\n * go out over the wire. Whenever a request is sent to the BOSH\n * server, all pending data is sent and the queue is flushed.\n *\n * Parameters:\n * (XMLElement |\n * [XMLElement] |\n * Strophe.Builder) elem - The stanza to send.\n */\n send: function send(elem) {\n if (elem === null) {\n return;\n }\n\n if (typeof elem.sort === \"function\") {\n for (var i = 0; i < elem.length; i++) {\n this._queueData(elem[i]);\n }\n } else if (typeof elem.tree === \"function\") {\n this._queueData(elem.tree());\n } else {\n this._queueData(elem);\n }\n\n this._proto._send();\n },\n\n /** Function: flush\n * Immediately send any pending outgoing data.\n *\n * Normally send() queues outgoing data until the next idle period\n * (100ms), which optimizes network use in the common cases when\n * several send()s are called in succession. flush() can be used to\n * immediately send all pending data.\n */\n flush: function flush() {\n // cancel the pending idle period and run the idle function\n // immediately\n clearTimeout(this._idleTimeout);\n\n this._onIdle();\n },\n\n /** Function: sendPresence\n * Helper function to send presence stanzas. The main benefit is for\n * sending presence stanzas for which you expect a responding presence\n * stanza with the same id (for example when leaving a chat room).\n *\n * Parameters:\n * (XMLElement) elem - The stanza to send.\n * (Function) callback - The callback function for a successful request.\n * (Function) errback - The callback function for a failed or timed\n * out request. On timeout, the stanza will be null.\n * (Integer) timeout - The time specified in milliseconds for a\n * timeout to occur.\n *\n * Returns:\n * The id used to send the presence.\n */\n sendPresence: function sendPresence(elem, callback, errback, timeout) {\n var _this3 = this;\n\n var timeoutHandler = null;\n\n if (typeof elem.tree === \"function\") {\n elem = elem.tree();\n }\n\n var id = elem.getAttribute('id');\n\n if (!id) {\n // inject id if not found\n id = this.getUniqueId(\"sendPresence\");\n elem.setAttribute(\"id\", id);\n }\n\n if (typeof callback === \"function\" || typeof errback === \"function\") {\n var handler = this.addHandler(function (stanza) {\n // remove timeout handler if there is one\n if (timeoutHandler) {\n _this3.deleteTimedHandler(timeoutHandler);\n }\n\n if (stanza.getAttribute('type') === 'error') {\n if (errback) {\n errback(stanza);\n }\n } else if (callback) {\n callback(stanza);\n }\n }, null, 'presence', null, id); // if timeout specified, set up a timeout handler.\n\n if (timeout) {\n timeoutHandler = this.addTimedHandler(timeout, function () {\n // get rid of normal handler\n _this3.deleteHandler(handler); // call errback on timeout with null stanza\n\n\n if (errback) {\n errback(null);\n }\n\n return false;\n });\n }\n }\n\n this.send(elem);\n return id;\n },\n\n /** Function: sendIQ\n * Helper function to send IQ stanzas.\n *\n * Parameters:\n * (XMLElement) elem - The stanza to send.\n * (Function) callback - The callback function for a successful request.\n * (Function) errback - The callback function for a failed or timed\n * out request. On timeout, the stanza will be null.\n * (Integer) timeout - The time specified in milliseconds for a\n * timeout to occur.\n *\n * Returns:\n * The id used to send the IQ.\n */\n sendIQ: function sendIQ(elem, callback, errback, timeout) {\n var _this4 = this;\n\n var timeoutHandler = null;\n\n if (typeof elem.tree === \"function\") {\n elem = elem.tree();\n }\n\n var id = elem.getAttribute('id');\n\n if (!id) {\n // inject id if not found\n id = this.getUniqueId(\"sendIQ\");\n elem.setAttribute(\"id\", id);\n }\n\n if (typeof callback === \"function\" || typeof errback === \"function\") {\n var handler = this.addHandler(function (stanza) {\n // remove timeout handler if there is one\n if (timeoutHandler) {\n _this4.deleteTimedHandler(timeoutHandler);\n }\n\n var iqtype = stanza.getAttribute('type');\n\n if (iqtype === 'result') {\n if (callback) {\n callback(stanza);\n }\n } else if (iqtype === 'error') {\n if (errback) {\n errback(stanza);\n }\n } else {\n var error = new Error(\"Got bad IQ type of \".concat(iqtype));\n error.name = \"StropheError\";\n throw error;\n }\n }, null, 'iq', ['error', 'result'], id); // if timeout specified, set up a timeout handler.\n\n if (timeout) {\n timeoutHandler = this.addTimedHandler(timeout, function () {\n // get rid of normal handler\n _this4.deleteHandler(handler); // call errback on timeout with null stanza\n\n\n if (errback) {\n errback(null);\n }\n\n return false;\n });\n }\n }\n\n this.send(elem);\n return id;\n },\n\n /** PrivateFunction: _queueData\n * Queue outgoing data for later sending. Also ensures that the data\n * is a DOMElement.\n */\n _queueData: function _queueData(element) {\n if (element === null || !element.tagName || !element.childNodes) {\n var error = new Error(\"Cannot queue non-DOMElement.\");\n error.name = \"StropheError\";\n throw error;\n }\n\n this._data.push(element);\n },\n\n /** PrivateFunction: _sendRestart\n * Send an xmpp:restart stanza.\n */\n _sendRestart: function _sendRestart() {\n var _this5 = this;\n\n this._data.push(\"restart\");\n\n this._proto._sendRestart();\n\n this._idleTimeout = setTimeout(function () {\n return _this5._onIdle();\n }, 100);\n },\n\n /** Function: addTimedHandler\n * Add a timed handler to the connection.\n *\n * This function adds a timed handler. The provided handler will\n * be called every period milliseconds until it returns false,\n * the connection is terminated, or the handler is removed. Handlers\n * that wish to continue being invoked should return true.\n *\n * Because of method binding it is necessary to save the result of\n * this function if you wish to remove a handler with\n * deleteTimedHandler().\n *\n * Note that user handlers are not active until authentication is\n * successful.\n *\n * Parameters:\n * (Integer) period - The period of the handler.\n * (Function) handler - The callback function.\n *\n * Returns:\n * A reference to the handler that can be used to remove it.\n */\n addTimedHandler: function addTimedHandler(period, handler) {\n var thand = new Strophe.TimedHandler(period, handler);\n this.addTimeds.push(thand);\n return thand;\n },\n\n /** Function: deleteTimedHandler\n * Delete a timed handler for a connection.\n *\n * This function removes a timed handler from the connection. The\n * handRef parameter is *not* the function passed to addTimedHandler(),\n * but is the reference returned from addTimedHandler().\n *\n * Parameters:\n * (Strophe.TimedHandler) handRef - The handler reference.\n */\n deleteTimedHandler: function deleteTimedHandler(handRef) {\n // this must be done in the Idle loop so that we don't change\n // the handlers during iteration\n this.removeTimeds.push(handRef);\n },\n\n /** Function: addHandler\n * Add a stanza handler for the connection.\n *\n * This function adds a stanza handler to the connection. The\n * handler callback will be called for any stanza that matches\n * the parameters. Note that if multiple parameters are supplied,\n * they must all match for the handler to be invoked.\n *\n * The handler will receive the stanza that triggered it as its argument.\n * *The handler should return true if it is to be invoked again;\n * returning false will remove the handler after it returns.*\n *\n * As a convenience, the ns parameters applies to the top level element\n * and also any of its immediate children. This is primarily to make\n * matching /iq/query elements easy.\n *\n * Options\n * ~~~~~~~\n * With the options argument, you can specify boolean flags that affect how\n * matches are being done.\n *\n * Currently two flags exist:\n *\n * - matchBareFromJid:\n * When set to true, the from parameter and the\n * from attribute on the stanza will be matched as bare JIDs instead\n * of full JIDs. To use this, pass {matchBareFromJid: true} as the\n * value of options. The default value for matchBareFromJid is false.\n *\n * - ignoreNamespaceFragment:\n * When set to true, a fragment specified on the stanza's namespace\n * URL will be ignored when it's matched with the one configured for\n * the handler.\n *\n * This means that if you register like this:\n * > connection.addHandler(\n * > handler,\n * > 'http://jabber.org/protocol/muc',\n * > null, null, null, null,\n * > {'ignoreNamespaceFragment': true}\n * > );\n *\n * Then a stanza with XML namespace of\n * 'http://jabber.org/protocol/muc#user' will also be matched. If\n * 'ignoreNamespaceFragment' is false, then only stanzas with\n * 'http://jabber.org/protocol/muc' will be matched.\n *\n * Deleting the handler\n * ~~~~~~~~~~~~~~~~~~~~\n * The return value should be saved if you wish to remove the handler\n * with deleteHandler().\n *\n * Parameters:\n * (Function) handler - The user callback.\n * (String) ns - The namespace to match.\n * (String) name - The stanza name to match.\n * (String|Array) type - The stanza type (or types if an array) to match.\n * (String) id - The stanza id attribute to match.\n * (String) from - The stanza from attribute to match.\n * (String) options - The handler options\n *\n * Returns:\n * A reference to the handler that can be used to remove it.\n */\n addHandler: function addHandler(handler, ns, name, type, id, from, options) {\n var hand = new Strophe.Handler(handler, ns, name, type, id, from, options);\n this.addHandlers.push(hand);\n return hand;\n },\n\n /** Function: deleteHandler\n * Delete a stanza handler for a connection.\n *\n * This function removes a stanza handler from the connection. The\n * handRef parameter is *not* the function passed to addHandler(),\n * but is the reference returned from addHandler().\n *\n * Parameters:\n * (Strophe.Handler) handRef - The handler reference.\n */\n deleteHandler: function deleteHandler(handRef) {\n // this must be done in the Idle loop so that we don't change\n // the handlers during iteration\n this.removeHandlers.push(handRef); // If a handler is being deleted while it is being added,\n // prevent it from getting added\n\n var i = this.addHandlers.indexOf(handRef);\n\n if (i >= 0) {\n this.addHandlers.splice(i, 1);\n }\n },\n\n /** Function: registerSASLMechanisms\n *\n * Register the SASL mechanisms which will be supported by this instance of\n * Strophe.Connection (i.e. which this XMPP client will support).\n *\n * Parameters:\n * (Array) mechanisms - Array of objects with Strophe.SASLMechanism prototypes\n *\n */\n registerSASLMechanisms: function registerSASLMechanisms(mechanisms) {\n this.mechanisms = {};\n mechanisms = mechanisms || [Strophe.SASLAnonymous, Strophe.SASLExternal, Strophe.SASLMD5, Strophe.SASLOAuthBearer, Strophe.SASLXOAuth2, Strophe.SASLPlain, Strophe.SASLSHA1];\n mechanisms.forEach(this.registerSASLMechanism.bind(this));\n },\n\n /** Function: registerSASLMechanism\n *\n * Register a single SASL mechanism, to be supported by this client.\n *\n * Parameters:\n * (Object) mechanism - Object with a Strophe.SASLMechanism prototype\n *\n */\n registerSASLMechanism: function registerSASLMechanism(mechanism) {\n this.mechanisms[mechanism.prototype.name] = mechanism;\n },\n\n /** Function: disconnect\n * Start the graceful disconnection process.\n *\n * This function starts the disconnection process. This process starts\n * by sending unavailable presence and sending BOSH body of type\n * terminate. A timeout handler makes sure that disconnection happens\n * even if the BOSH server does not respond.\n * If the Connection object isn't connected, at least tries to abort all pending requests\n * so the connection object won't generate successful requests (which were already opened).\n *\n * The user supplied connection callback will be notified of the\n * progress as this process happens.\n *\n * Parameters:\n * (String) reason - The reason the disconnect is occuring.\n */\n disconnect: function disconnect(reason) {\n this._changeConnectStatus(Strophe.Status.DISCONNECTING, reason);\n\n Strophe.warn(\"Disconnect was called because: \" + reason);\n\n if (this.connected) {\n var pres = false;\n this.disconnecting = true;\n\n if (this.authenticated) {\n pres = $pres({\n 'xmlns': Strophe.NS.CLIENT,\n 'type': 'unavailable'\n });\n } // setup timeout handler\n\n\n this._disconnectTimeout = this._addSysTimedHandler(3000, this._onDisconnectTimeout.bind(this));\n\n this._proto._disconnect(pres);\n } else {\n Strophe.warn(\"Disconnect was called before Strophe connected to the server\");\n\n this._proto._abortAllRequests();\n\n this._doDisconnect();\n }\n },\n\n /** PrivateFunction: _changeConnectStatus\n * _Private_ helper function that makes sure plugins and the user's\n * callback are notified of connection status changes.\n *\n * Parameters:\n * (Integer) status - the new connection status, one of the values\n * in Strophe.Status\n * (String) condition - the error condition or null\n * (XMLElement) elem - The triggering stanza.\n */\n _changeConnectStatus: function _changeConnectStatus(status, condition, elem) {\n // notify all plugins listening for status changes\n for (var k in Strophe._connectionPlugins) {\n if (Object.prototype.hasOwnProperty.call(Strophe._connectionPlugins, k)) {\n var plugin = this[k];\n\n if (plugin.statusChanged) {\n try {\n plugin.statusChanged(status, condition);\n } catch (err) {\n Strophe.error(\"\".concat(k, \" plugin caused an exception changing status: \").concat(err));\n }\n }\n }\n } // notify the user's callback\n\n\n if (this.connect_callback) {\n try {\n this.connect_callback(status, condition, elem);\n } catch (e) {\n Strophe._handleError(e);\n\n Strophe.error(\"User connection callback caused an exception: \".concat(e));\n }\n }\n },\n\n /** PrivateFunction: _doDisconnect\n * _Private_ function to disconnect.\n *\n * This is the last piece of the disconnection logic. This resets the\n * connection and alerts the user's connection callback.\n */\n _doDisconnect: function _doDisconnect(condition) {\n if (typeof this._idleTimeout === \"number\") {\n clearTimeout(this._idleTimeout);\n } // Cancel Disconnect Timeout\n\n\n if (this._disconnectTimeout !== null) {\n this.deleteTimedHandler(this._disconnectTimeout);\n this._disconnectTimeout = null;\n }\n\n Strophe.debug(\"_doDisconnect was called\");\n\n this._proto._doDisconnect();\n\n this.authenticated = false;\n this.disconnecting = false;\n this.restored = false; // delete handlers\n\n this.handlers = [];\n this.timedHandlers = [];\n this.removeTimeds = [];\n this.removeHandlers = [];\n this.addTimeds = [];\n this.addHandlers = []; // tell the parent we disconnected\n\n this._changeConnectStatus(Strophe.Status.DISCONNECTED, condition);\n\n this.connected = false;\n },\n\n /** PrivateFunction: _dataRecv\n * _Private_ handler to processes incoming data from the the connection.\n *\n * Except for _connect_cb handling the initial connection request,\n * this function handles the incoming data for all requests. This\n * function also fires stanza handlers that match each incoming\n * stanza.\n *\n * Parameters:\n * (Strophe.Request) req - The request that has data ready.\n * (string) req - The stanza a raw string (optiona).\n */\n _dataRecv: function _dataRecv(req, raw) {\n var _this6 = this;\n\n Strophe.debug(\"_dataRecv called\");\n\n var elem = this._proto._reqToData(req);\n\n if (elem === null) {\n return;\n }\n\n if (this.xmlInput !== Strophe.Connection.prototype.xmlInput) {\n if (elem.nodeName === this._proto.strip && elem.childNodes.length) {\n this.xmlInput(elem.childNodes[0]);\n } else {\n this.xmlInput(elem);\n }\n }\n\n if (this.rawInput !== Strophe.Connection.prototype.rawInput) {\n if (raw) {\n this.rawInput(raw);\n } else {\n this.rawInput(Strophe.serialize(elem));\n }\n } // remove handlers scheduled for deletion\n\n\n while (this.removeHandlers.length > 0) {\n var hand = this.removeHandlers.pop();\n var i = this.handlers.indexOf(hand);\n\n if (i >= 0) {\n this.handlers.splice(i, 1);\n }\n } // add handlers scheduled for addition\n\n\n while (this.addHandlers.length > 0) {\n this.handlers.push(this.addHandlers.pop());\n } // handle graceful disconnect\n\n\n if (this.disconnecting && this._proto._emptyQueue()) {\n this._doDisconnect();\n\n return;\n }\n\n var type = elem.getAttribute(\"type\");\n\n if (type !== null && type === \"terminate\") {\n // Don't process stanzas that come in after disconnect\n if (this.disconnecting) {\n return;\n } // an error occurred\n\n\n var cond = elem.getAttribute(\"condition\");\n var conflict = elem.getElementsByTagName(\"conflict\");\n\n if (cond !== null) {\n if (cond === \"remote-stream-error\" && conflict.length > 0) {\n cond = \"conflict\";\n }\n\n this._changeConnectStatus(Strophe.Status.CONNFAIL, cond);\n } else {\n this._changeConnectStatus(Strophe.Status.CONNFAIL, Strophe.ErrorCondition.UNKOWN_REASON);\n }\n\n this._doDisconnect(cond);\n\n return;\n } // send each incoming stanza through the handler chain\n\n\n Strophe.forEachChild(elem, null, function (child) {\n // process handlers\n var newList = _this6.handlers;\n _this6.handlers = [];\n\n for (var _i5 = 0; _i5 < newList.length; _i5++) {\n var _hand = newList[_i5]; // encapsulate 'handler.run' not to lose the whole handler list if\n // one of the handlers throws an exception\n\n try {\n if (_hand.isMatch(child) && (_this6.authenticated || !_hand.user)) {\n if (_hand.run(child)) {\n _this6.handlers.push(_hand);\n }\n } else {\n _this6.handlers.push(_hand);\n }\n } catch (e) {\n // if the handler throws an exception, we consider it as false\n Strophe.warn('Removing Strophe handlers due to uncaught exception: ' + e.message);\n }\n }\n });\n },\n\n /** Attribute: mechanisms\n * SASL Mechanisms available for Connection.\n */\n mechanisms: {},\n\n /** PrivateFunction: _connect_cb\n * _Private_ handler for initial connection request.\n *\n * This handler is used to process the initial connection request\n * response from the BOSH server. It is used to set up authentication\n * handlers and start the authentication process.\n *\n * SASL authentication will be attempted if available, otherwise\n * the code will fall back to legacy authentication.\n *\n * Parameters:\n * (Strophe.Request) req - The current request.\n * (Function) _callback - low level (xmpp) connect callback function.\n * Useful for plugins with their own xmpp connect callback (when they\n * want to do something special).\n */\n _connect_cb: function _connect_cb(req, _callback, raw) {\n Strophe.debug(\"_connect_cb was called\");\n this.connected = true;\n var bodyWrap;\n\n try {\n bodyWrap = this._proto._reqToData(req);\n } catch (e) {\n if (e.name !== Strophe.ErrorCondition.BAD_FORMAT) {\n throw e;\n }\n\n this._changeConnectStatus(Strophe.Status.CONNFAIL, Strophe.ErrorCondition.BAD_FORMAT);\n\n this._doDisconnect(Strophe.ErrorCondition.BAD_FORMAT);\n }\n\n if (!bodyWrap) {\n return;\n }\n\n if (this.xmlInput !== Strophe.Connection.prototype.xmlInput) {\n if (bodyWrap.nodeName === this._proto.strip && bodyWrap.childNodes.length) {\n this.xmlInput(bodyWrap.childNodes[0]);\n } else {\n this.xmlInput(bodyWrap);\n }\n }\n\n if (this.rawInput !== Strophe.Connection.prototype.rawInput) {\n if (raw) {\n this.rawInput(raw);\n } else {\n this.rawInput(Strophe.serialize(bodyWrap));\n }\n }\n\n var conncheck = this._proto._connect_cb(bodyWrap);\n\n if (conncheck === Strophe.Status.CONNFAIL) {\n return;\n } // Check for the stream:features tag\n\n\n var hasFeatures;\n\n if (bodyWrap.getElementsByTagNameNS) {\n hasFeatures = bodyWrap.getElementsByTagNameNS(Strophe.NS.STREAM, \"features\").length > 0;\n } else {\n hasFeatures = bodyWrap.getElementsByTagName(\"stream:features\").length > 0 || bodyWrap.getElementsByTagName(\"features\").length > 0;\n }\n\n if (!hasFeatures) {\n this._proto._no_auth_received(_callback);\n\n return;\n }\n\n var matched = [];\n var mechanisms = bodyWrap.getElementsByTagName(\"mechanism\");\n\n if (mechanisms.length > 0) {\n for (var i = 0; i < mechanisms.length; i++) {\n var mech = Strophe.getText(mechanisms[i]);\n if (this.mechanisms[mech]) matched.push(this.mechanisms[mech]);\n }\n }\n\n if (matched.length === 0) {\n if (bodyWrap.getElementsByTagName(\"auth\").length === 0) {\n // There are no matching SASL mechanisms and also no legacy\n // auth available.\n this._proto._no_auth_received(_callback);\n\n return;\n }\n }\n\n if (this.do_authentication !== false) {\n this.authenticate(matched);\n }\n },\n\n /** Function: sortMechanismsByPriority\n *\n * Sorts an array of objects with prototype SASLMechanism according to\n * their priorities.\n *\n * Parameters:\n * (Array) mechanisms - Array of SASL mechanisms.\n *\n */\n sortMechanismsByPriority: function sortMechanismsByPriority(mechanisms) {\n // Sorting mechanisms according to priority.\n for (var i = 0; i < mechanisms.length - 1; ++i) {\n var higher = i;\n\n for (var j = i + 1; j < mechanisms.length; ++j) {\n if (mechanisms[j].prototype.priority > mechanisms[higher].prototype.priority) {\n higher = j;\n }\n }\n\n if (higher !== i) {\n var swap = mechanisms[i];\n mechanisms[i] = mechanisms[higher];\n mechanisms[higher] = swap;\n }\n }\n\n return mechanisms;\n },\n\n /** Function: authenticate\n * Set up authentication\n *\n * Continues the initial connection request by setting up authentication\n * handlers and starting the authentication process.\n *\n * SASL authentication will be attempted if available, otherwise\n * the code will fall back to legacy authentication.\n *\n * Parameters:\n * (Array) matched - Array of SASL mechanisms supported.\n *\n */\n authenticate: function authenticate(matched) {\n if (!this._attemptSASLAuth(matched)) {\n this._attemptLegacyAuth();\n }\n },\n\n /** PrivateFunction: _attemptSASLAuth\n *\n * Iterate through an array of SASL mechanisms and attempt authentication\n * with the highest priority (enabled) mechanism.\n *\n * Parameters:\n * (Array) mechanisms - Array of SASL mechanisms.\n *\n * Returns:\n * (Boolean) mechanism_found - true or false, depending on whether a\n * valid SASL mechanism was found with which authentication could be\n * started.\n */\n _attemptSASLAuth: function _attemptSASLAuth(mechanisms) {\n mechanisms = this.sortMechanismsByPriority(mechanisms || []);\n var mechanism_found = false;\n\n for (var i = 0; i < mechanisms.length; ++i) {\n if (!mechanisms[i].prototype.test(this)) {\n continue;\n }\n\n this._sasl_success_handler = this._addSysHandler(this._sasl_success_cb.bind(this), null, \"success\", null, null);\n this._sasl_failure_handler = this._addSysHandler(this._sasl_failure_cb.bind(this), null, \"failure\", null, null);\n this._sasl_challenge_handler = this._addSysHandler(this._sasl_challenge_cb.bind(this), null, \"challenge\", null, null);\n this._sasl_mechanism = new mechanisms[i]();\n\n this._sasl_mechanism.onStart(this);\n\n var request_auth_exchange = $build(\"auth\", {\n 'xmlns': Strophe.NS.SASL,\n 'mechanism': this._sasl_mechanism.name\n });\n\n if (this._sasl_mechanism.isClientFirst) {\n var response = this._sasl_mechanism.onChallenge(this, null);\n\n request_auth_exchange.t(btoa(response));\n }\n\n this.send(request_auth_exchange.tree());\n mechanism_found = true;\n break;\n }\n\n return mechanism_found;\n },\n\n /** PrivateFunction: _sasl_challenge_cb\n * _Private_ handler for the SASL challenge\n *\n */\n _sasl_challenge_cb: function _sasl_challenge_cb(elem) {\n var challenge = atob(Strophe.getText(elem));\n\n var response = this._sasl_mechanism.onChallenge(this, challenge);\n\n var stanza = $build('response', {\n 'xmlns': Strophe.NS.SASL\n });\n\n if (response !== \"\") {\n stanza.t(btoa(response));\n }\n\n this.send(stanza.tree());\n return true;\n },\n\n /** PrivateFunction: _attemptLegacyAuth\n *\n * Attempt legacy (i.e. non-SASL) authentication.\n */\n _attemptLegacyAuth: function _attemptLegacyAuth() {\n if (Strophe.getNodeFromJid(this.jid) === null) {\n // we don't have a node, which is required for non-anonymous\n // client connections\n this._changeConnectStatus(Strophe.Status.CONNFAIL, Strophe.ErrorCondition.MISSING_JID_NODE);\n\n this.disconnect(Strophe.ErrorCondition.MISSING_JID_NODE);\n } else {\n // Fall back to legacy authentication\n this._changeConnectStatus(Strophe.Status.AUTHENTICATING, null);\n\n this._addSysHandler(this._onLegacyAuthIQResult.bind(this), null, null, null, \"_auth_1\");\n\n this.send($iq({\n 'type': \"get\",\n 'to': this.domain,\n 'id': \"_auth_1\"\n }).c(\"query\", {\n xmlns: Strophe.NS.AUTH\n }).c(\"username\", {}).t(Strophe.getNodeFromJid(this.jid)).tree());\n }\n },\n\n /** PrivateFunction: _onLegacyAuthIQResult\n * _Private_ handler for legacy authentication.\n *\n * This handler is called in response to the initial \n * for legacy authentication. It builds an authentication and\n * sends it, creating a handler (calling back to _auth2_cb()) to\n * handle the result\n *\n * Parameters:\n * (XMLElement) elem - The stanza that triggered the callback.\n *\n * Returns:\n * false to remove the handler.\n */\n _onLegacyAuthIQResult: function _onLegacyAuthIQResult(elem) {\n // build plaintext auth iq\n var iq = $iq({\n type: \"set\",\n id: \"_auth_2\"\n }).c('query', {\n xmlns: Strophe.NS.AUTH\n }).c('username', {}).t(Strophe.getNodeFromJid(this.jid)).up().c('password').t(this.pass);\n\n if (!Strophe.getResourceFromJid(this.jid)) {\n // since the user has not supplied a resource, we pick\n // a default one here. unlike other auth methods, the server\n // cannot do this for us.\n this.jid = Strophe.getBareJidFromJid(this.jid) + '/strophe';\n }\n\n iq.up().c('resource', {}).t(Strophe.getResourceFromJid(this.jid));\n\n this._addSysHandler(this._auth2_cb.bind(this), null, null, null, \"_auth_2\");\n\n this.send(iq.tree());\n return false;\n },\n\n /** PrivateFunction: _sasl_success_cb\n * _Private_ handler for succesful SASL authentication.\n *\n * Parameters:\n * (XMLElement) elem - The matching stanza.\n *\n * Returns:\n * false to remove the handler.\n */\n _sasl_success_cb: function _sasl_success_cb(elem) {\n var _this7 = this;\n\n if (this._sasl_data[\"server-signature\"]) {\n var serverSignature;\n var success = atob(Strophe.getText(elem));\n var attribMatch = /([a-z]+)=([^,]+)(,|$)/;\n var matches = success.match(attribMatch);\n\n if (matches[1] === \"v\") {\n serverSignature = matches[2];\n }\n\n if (serverSignature !== this._sasl_data[\"server-signature\"]) {\n // remove old handlers\n this.deleteHandler(this._sasl_failure_handler);\n this._sasl_failure_handler = null;\n\n if (this._sasl_challenge_handler) {\n this.deleteHandler(this._sasl_challenge_handler);\n this._sasl_challenge_handler = null;\n }\n\n this._sasl_data = {};\n return this._sasl_failure_cb(null);\n }\n }\n\n Strophe.info(\"SASL authentication succeeded.\");\n\n if (this._sasl_mechanism) {\n this._sasl_mechanism.onSuccess();\n } // remove old handlers\n\n\n this.deleteHandler(this._sasl_failure_handler);\n this._sasl_failure_handler = null;\n\n if (this._sasl_challenge_handler) {\n this.deleteHandler(this._sasl_challenge_handler);\n this._sasl_challenge_handler = null;\n }\n\n var streamfeature_handlers = [];\n\n var wrapper = function wrapper(handlers, elem) {\n while (handlers.length) {\n _this7.deleteHandler(handlers.pop());\n }\n\n _this7._onStreamFeaturesAfterSASL(elem);\n\n return false;\n };\n\n streamfeature_handlers.push(this._addSysHandler(function (elem) {\n return wrapper(streamfeature_handlers, elem);\n }, null, \"stream:features\", null, null));\n streamfeature_handlers.push(this._addSysHandler(function (elem) {\n return wrapper(streamfeature_handlers, elem);\n }, Strophe.NS.STREAM, \"features\", null, null)); // we must send an xmpp:restart now\n\n this._sendRestart();\n\n return false;\n },\n\n /** PrivateFunction: _onStreamFeaturesAfterSASL\n * Parameters:\n * (XMLElement) elem - The matching stanza.\n *\n * Returns:\n * false to remove the handler.\n */\n _onStreamFeaturesAfterSASL: function _onStreamFeaturesAfterSASL(elem) {\n // save stream:features for future usage\n this.features = elem;\n\n for (var i = 0; i < elem.childNodes.length; i++) {\n var child = elem.childNodes[i];\n\n if (child.nodeName === 'bind') {\n this.do_bind = true;\n }\n\n if (child.nodeName === 'session') {\n this.do_session = true;\n }\n }\n\n if (!this.do_bind) {\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, null);\n\n return false;\n } else if (!this.options.explicitResourceBinding) {\n this.bind();\n } else {\n this._changeConnectStatus(Strophe.Status.BINDREQUIRED, null);\n }\n\n return false;\n },\n\n /** Function: bind\n *\n * Sends an IQ to the XMPP server to bind a JID resource for this session.\n *\n * https://tools.ietf.org/html/rfc6120#section-7.5\n *\n * If `explicitResourceBinding` was set to a truthy value in the options\n * passed to the Strophe.Connection constructor, then this function needs\n * to be called explicitly by the client author.\n *\n * Otherwise it'll be called automatically as soon as the XMPP server\n * advertises the \"urn:ietf:params:xml:ns:xmpp-bind\" stream feature.\n */\n bind: function bind() {\n if (!this.do_bind) {\n Strophe.log(Strophe.LogLevel.INFO, \"Strophe.Connection.prototype.bind called but \\\"do_bind\\\" is false\");\n return;\n }\n\n this._addSysHandler(this._onResourceBindResultIQ.bind(this), null, null, null, \"_bind_auth_2\");\n\n var resource = Strophe.getResourceFromJid(this.jid);\n\n if (resource) {\n this.send($iq({\n type: \"set\",\n id: \"_bind_auth_2\"\n }).c('bind', {\n xmlns: Strophe.NS.BIND\n }).c('resource', {}).t(resource).tree());\n } else {\n this.send($iq({\n type: \"set\",\n id: \"_bind_auth_2\"\n }).c('bind', {\n xmlns: Strophe.NS.BIND\n }).tree());\n }\n },\n\n /** PrivateFunction: _onResourceBindIQ\n * _Private_ handler for binding result and session start.\n *\n * Parameters:\n * (XMLElement) elem - The matching stanza.\n *\n * Returns:\n * false to remove the handler.\n */\n _onResourceBindResultIQ: function _onResourceBindResultIQ(elem) {\n if (elem.getAttribute(\"type\") === \"error\") {\n Strophe.warn(\"Resource binding failed.\");\n var conflict = elem.getElementsByTagName(\"conflict\");\n var condition;\n\n if (conflict.length > 0) {\n condition = Strophe.ErrorCondition.CONFLICT;\n }\n\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, condition, elem);\n\n return false;\n } // TODO - need to grab errors\n\n\n var bind = elem.getElementsByTagName(\"bind\");\n\n if (bind.length > 0) {\n var jidNode = bind[0].getElementsByTagName(\"jid\");\n\n if (jidNode.length > 0) {\n this.jid = Strophe.getText(jidNode[0]);\n\n if (this.do_session) {\n this._establishSession();\n } else {\n this.authenticated = true;\n\n this._changeConnectStatus(Strophe.Status.CONNECTED, null);\n }\n }\n } else {\n Strophe.warn(\"Resource binding failed.\");\n\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);\n\n return false;\n }\n },\n\n /** PrivateFunction: _establishSession\n * Send IQ request to establish a session with the XMPP server.\n *\n * See https://xmpp.org/rfcs/rfc3921.html#session\n *\n * Note: The protocol for session establishment has been determined as\n * unnecessary and removed in RFC-6121.\n */\n _establishSession: function _establishSession() {\n if (!this.do_session) {\n throw new Error(\"Strophe.Connection.prototype._establishSession \" + \"called but apparently \".concat(Strophe.NS.SESSION, \" wasn't advertised by the server\"));\n }\n\n this._addSysHandler(this._onSessionResultIQ.bind(this), null, null, null, \"_session_auth_2\");\n\n this.send($iq({\n type: \"set\",\n id: \"_session_auth_2\"\n }).c('session', {\n xmlns: Strophe.NS.SESSION\n }).tree());\n },\n\n /** PrivateFunction: _onSessionResultIQ\n * _Private_ handler for the server's IQ response to a client's session\n * request.\n *\n * This sets Connection.authenticated to true on success, which\n * starts the processing of user handlers.\n *\n * See https://xmpp.org/rfcs/rfc3921.html#session\n *\n * Note: The protocol for session establishment has been determined as\n * unnecessary and removed in RFC-6121.\n *\n * Parameters:\n * (XMLElement) elem - The matching stanza.\n *\n * Returns:\n * false to remove the handler.\n */\n _onSessionResultIQ: function _onSessionResultIQ(elem) {\n if (elem.getAttribute(\"type\") === \"result\") {\n this.authenticated = true;\n\n this._changeConnectStatus(Strophe.Status.CONNECTED, null);\n } else if (elem.getAttribute(\"type\") === \"error\") {\n Strophe.warn(\"Session creation failed.\");\n\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);\n\n return false;\n }\n\n return false;\n },\n\n /** PrivateFunction: _sasl_failure_cb\n * _Private_ handler for SASL authentication failure.\n *\n * Parameters:\n * (XMLElement) elem - The matching stanza.\n *\n * Returns:\n * false to remove the handler.\n */\n _sasl_failure_cb: function _sasl_failure_cb(elem) {\n // delete unneeded handlers\n if (this._sasl_success_handler) {\n this.deleteHandler(this._sasl_success_handler);\n this._sasl_success_handler = null;\n }\n\n if (this._sasl_challenge_handler) {\n this.deleteHandler(this._sasl_challenge_handler);\n this._sasl_challenge_handler = null;\n }\n\n if (this._sasl_mechanism) this._sasl_mechanism.onFailure();\n\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);\n\n return false;\n },\n\n /** PrivateFunction: _auth2_cb\n * _Private_ handler to finish legacy authentication.\n *\n * This handler is called when the result from the jabber:iq:auth\n * stanza is returned.\n *\n * Parameters:\n * (XMLElement) elem - The stanza that triggered the callback.\n *\n * Returns:\n * false to remove the handler.\n */\n _auth2_cb: function _auth2_cb(elem) {\n if (elem.getAttribute(\"type\") === \"result\") {\n this.authenticated = true;\n\n this._changeConnectStatus(Strophe.Status.CONNECTED, null);\n } else if (elem.getAttribute(\"type\") === \"error\") {\n this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);\n\n this.disconnect('authentication failed');\n }\n\n return false;\n },\n\n /** PrivateFunction: _addSysTimedHandler\n * _Private_ function to add a system level timed handler.\n *\n * This function is used to add a Strophe.TimedHandler for the\n * library code. System timed handlers are allowed to run before\n * authentication is complete.\n *\n * Parameters:\n * (Integer) period - The period of the handler.\n * (Function) handler - The callback function.\n */\n _addSysTimedHandler: function _addSysTimedHandler(period, handler) {\n var thand = new Strophe.TimedHandler(period, handler);\n thand.user = false;\n this.addTimeds.push(thand);\n return thand;\n },\n\n /** PrivateFunction: _addSysHandler\n * _Private_ function to add a system level stanza handler.\n *\n * This function is used to add a Strophe.Handler for the\n * library code. System stanza handlers are allowed to run before\n * authentication is complete.\n *\n * Parameters:\n * (Function) handler - The callback function.\n * (String) ns - The namespace to match.\n * (String) name - The stanza name to match.\n * (String) type - The stanza type attribute to match.\n * (String) id - The stanza id attribute to match.\n */\n _addSysHandler: function _addSysHandler(handler, ns, name, type, id) {\n var hand = new Strophe.Handler(handler, ns, name, type, id);\n hand.user = false;\n this.addHandlers.push(hand);\n return hand;\n },\n\n /** PrivateFunction: _onDisconnectTimeout\n * _Private_ timeout handler for handling non-graceful disconnection.\n *\n * If the graceful disconnect process does not complete within the\n * time allotted, this handler finishes the disconnect anyway.\n *\n * Returns:\n * false to remove the handler.\n */\n _onDisconnectTimeout: function _onDisconnectTimeout() {\n Strophe.debug(\"_onDisconnectTimeout was called\");\n\n this._changeConnectStatus(Strophe.Status.CONNTIMEOUT, null);\n\n this._proto._onDisconnectTimeout(); // actually disconnect\n\n\n this._doDisconnect();\n\n return false;\n },\n\n /** PrivateFunction: _onIdle\n * _Private_ handler to process events during idle cycle.\n *\n * This handler is called every 100ms to fire timed handlers that\n * are ready and keep poll requests going.\n */\n _onIdle: function _onIdle() {\n var _this8 = this;\n\n // add timed handlers scheduled for addition\n // NOTE: we add before remove in the case a timed handler is\n // added and then deleted before the next _onIdle() call.\n while (this.addTimeds.length > 0) {\n this.timedHandlers.push(this.addTimeds.pop());\n } // remove timed handlers that have been scheduled for deletion\n\n\n while (this.removeTimeds.length > 0) {\n var thand = this.removeTimeds.pop();\n var i = this.timedHandlers.indexOf(thand);\n\n if (i >= 0) {\n this.timedHandlers.splice(i, 1);\n }\n } // call ready timed handlers\n\n\n var now = new Date().getTime();\n var newList = [];\n\n for (var _i6 = 0; _i6 < this.timedHandlers.length; _i6++) {\n var _thand = this.timedHandlers[_i6];\n\n if (this.authenticated || !_thand.user) {\n var since = _thand.lastCalled + _thand.period;\n\n if (since - now <= 0) {\n if (_thand.run()) {\n newList.push(_thand);\n }\n } else {\n newList.push(_thand);\n }\n }\n }\n\n this.timedHandlers = newList;\n clearTimeout(this._idleTimeout);\n\n this._proto._onIdle(); // reactivate the timer only if connected\n\n\n if (this.connected) {\n this._idleTimeout = setTimeout(function () {\n return _this8._onIdle();\n }, 100);\n }\n }\n };\n /** Class: Strophe.SASLMechanism\n *\n * encapsulates SASL authentication mechanisms.\n *\n * User code may override the priority for each mechanism or disable it completely.\n * See for information about changing priority and for informatian on\n * how to disable a mechanism.\n *\n * By default, all mechanisms are enabled and the priorities are\n *\n * OAUTHBEARER - 60\n * SCRAM-SHA1 - 50\n * DIGEST-MD5 - 40\n * PLAIN - 30\n * ANONYMOUS - 20\n * EXTERNAL - 10\n *\n * See: Strophe.Connection.addSupportedSASLMechanisms\n */\n\n /**\n * PrivateConstructor: Strophe.SASLMechanism\n * SASL auth mechanism abstraction.\n *\n * Parameters:\n * (String) name - SASL Mechanism name.\n * (Boolean) isClientFirst - If client should send response first without challenge.\n * (Number) priority - Priority.\n *\n * Returns:\n * A new Strophe.SASLMechanism object.\n */\n\n Strophe.SASLMechanism = function (name, isClientFirst, priority) {\n /** PrivateVariable: name\n * Mechanism name.\n */\n this.name = name;\n /** PrivateVariable: isClientFirst\n * If client sends response without initial server challenge.\n */\n\n this.isClientFirst = isClientFirst;\n /** Variable: priority\n * Determines which is chosen for authentication (Higher is better).\n * Users may override this to prioritize mechanisms differently.\n *\n * In the default configuration the priorities are\n *\n * SCRAM-SHA1 - 40\n * DIGEST-MD5 - 30\n * Plain - 20\n *\n * Example: (This will cause Strophe to choose the mechanism that the server sent first)\n *\n * > Strophe.SASLMD5.priority = Strophe.SASLSHA1.priority;\n *\n * See for a list of available mechanisms.\n *\n */\n\n this.priority = priority;\n };\n\n Strophe.SASLMechanism.prototype = {\n /**\n * Function: test\n * Checks if mechanism able to run.\n * To disable a mechanism, make this return false;\n *\n * To disable plain authentication run\n * > Strophe.SASLPlain.test = function() {\n * > return false;\n * > }\n *\n * See for a list of available mechanisms.\n *\n * Parameters:\n * (Strophe.Connection) connection - Target Connection.\n *\n * Returns:\n * (Boolean) If mechanism was able to run.\n */\n test: function test(connection) {\n return true;\n },\n\n /** PrivateFunction: onStart\n * Called before starting mechanism on some connection.\n *\n * Parameters:\n * (Strophe.Connection) connection - Target Connection.\n */\n onStart: function onStart(connection) {\n this._connection = connection;\n },\n\n /** PrivateFunction: onChallenge\n * Called by protocol implementation on incoming challenge. If client is\n * first (isClientFirst === true) challenge will be null on the first call.\n *\n * Parameters:\n * (Strophe.Connection) connection - Target Connection.\n * (String) challenge - current challenge to handle.\n *\n * Returns:\n * (String) Mechanism response.\n */\n onChallenge: function onChallenge(connection, challenge) {\n throw new Error(\"You should implement challenge handling!\");\n },\n\n /** PrivateFunction: onFailure\n * Protocol informs mechanism implementation about SASL failure.\n */\n onFailure: function onFailure() {\n this._connection = null;\n },\n\n /** PrivateFunction: onSuccess\n * Protocol informs mechanism implementation about SASL success.\n */\n onSuccess: function onSuccess() {\n this._connection = null;\n }\n };\n /** Constants: SASL mechanisms\n * Available authentication mechanisms\n *\n * Strophe.SASLAnonymous - SASL ANONYMOUS authentication.\n * Strophe.SASLPlain - SASL PLAIN authentication.\n * Strophe.SASLMD5 - SASL DIGEST-MD5 authentication\n * Strophe.SASLSHA1 - SASL SCRAM-SHA1 authentication\n * Strophe.SASLOAuthBearer - SASL OAuth Bearer authentication\n * Strophe.SASLExternal - SASL EXTERNAL authentication\n * Strophe.SASLXOAuth2 - SASL X-OAuth2 authentication\n */\n // Building SASL callbacks\n\n /** PrivateConstructor: SASLAnonymous\n * SASL ANONYMOUS authentication.\n */\n\n Strophe.SASLAnonymous = function () {};\n\n Strophe.SASLAnonymous.prototype = new Strophe.SASLMechanism(\"ANONYMOUS\", false, 20);\n\n Strophe.SASLAnonymous.prototype.test = function (connection) {\n return connection.authcid === null;\n };\n /** PrivateConstructor: SASLPlain\n * SASL PLAIN authentication.\n */\n\n\n Strophe.SASLPlain = function () {};\n\n Strophe.SASLPlain.prototype = new Strophe.SASLMechanism(\"PLAIN\", true, 50);\n\n Strophe.SASLPlain.prototype.test = function (connection) {\n return connection.authcid !== null;\n };\n\n Strophe.SASLPlain.prototype.onChallenge = function (connection) {\n var auth_str = connection.authzid;\n auth_str = auth_str + \"\\0\";\n auth_str = auth_str + connection.authcid;\n auth_str = auth_str + \"\\0\";\n auth_str = auth_str + connection.pass;\n return utils.utf16to8(auth_str);\n };\n /** PrivateConstructor: SASLSHA1\n * SASL SCRAM SHA 1 authentication.\n */\n\n\n Strophe.SASLSHA1 = function () {};\n\n Strophe.SASLSHA1.prototype = new Strophe.SASLMechanism(\"SCRAM-SHA-1\", true, 70);\n\n Strophe.SASLSHA1.prototype.test = function (connection) {\n return connection.authcid !== null;\n };\n\n Strophe.SASLSHA1.prototype.onChallenge = function (connection, challenge, test_cnonce) {\n var cnonce = test_cnonce || MD5.hexdigest(\"\" + Math.random() * 1234567890);\n var auth_str = \"n=\" + utils.utf16to8(connection.authcid);\n auth_str += \",r=\";\n auth_str += cnonce;\n connection._sasl_data.cnonce = cnonce;\n connection._sasl_data[\"client-first-message-bare\"] = auth_str;\n auth_str = \"n,,\" + auth_str;\n\n this.onChallenge = function (connection, challenge) {\n var nonce, salt, iter, Hi, U, U_old, i, k;\n var responseText = \"c=biws,\";\n var authMessage = \"\".concat(connection._sasl_data[\"client-first-message-bare\"], \",\").concat(challenge, \",\");\n var cnonce = connection._sasl_data.cnonce;\n var attribMatch = /([a-z]+)=([^,]+)(,|$)/;\n\n while (challenge.match(attribMatch)) {\n var matches = challenge.match(attribMatch);\n challenge = challenge.replace(matches[0], \"\");\n\n switch (matches[1]) {\n case \"r\":\n nonce = matches[2];\n break;\n\n case \"s\":\n salt = matches[2];\n break;\n\n case \"i\":\n iter = matches[2];\n break;\n }\n }\n\n if (nonce.substr(0, cnonce.length) !== cnonce) {\n connection._sasl_data = {};\n return connection._sasl_failure_cb();\n }\n\n responseText += \"r=\" + nonce;\n authMessage += responseText;\n salt = atob(salt);\n salt += \"\\x00\\x00\\x00\\x01\";\n var pass = utils.utf16to8(connection.pass);\n Hi = U_old = SHA1.core_hmac_sha1(pass, salt);\n\n for (i = 1; i < iter; i++) {\n U = SHA1.core_hmac_sha1(pass, SHA1.binb2str(U_old));\n\n for (k = 0; k < 5; k++) {\n Hi[k] ^= U[k];\n }\n\n U_old = U;\n }\n\n Hi = SHA1.binb2str(Hi);\n var clientKey = SHA1.core_hmac_sha1(Hi, \"Client Key\");\n var serverKey = SHA1.str_hmac_sha1(Hi, \"Server Key\");\n var clientSignature = SHA1.core_hmac_sha1(SHA1.str_sha1(SHA1.binb2str(clientKey)), authMessage);\n connection._sasl_data[\"server-signature\"] = SHA1.b64_hmac_sha1(serverKey, authMessage);\n\n for (k = 0; k < 5; k++) {\n clientKey[k] ^= clientSignature[k];\n }\n\n responseText += \",p=\" + btoa(SHA1.binb2str(clientKey));\n return responseText;\n };\n\n return auth_str;\n };\n /** PrivateConstructor: SASLMD5\n * SASL DIGEST MD5 authentication.\n */\n\n\n Strophe.SASLMD5 = function () {};\n\n Strophe.SASLMD5.prototype = new Strophe.SASLMechanism(\"DIGEST-MD5\", false, 60);\n\n Strophe.SASLMD5.prototype.test = function (connection) {\n return connection.authcid !== null;\n };\n /** PrivateFunction: _quote\n * _Private_ utility function to backslash escape and quote strings.\n *\n * Parameters:\n * (String) str - The string to be quoted.\n *\n * Returns:\n * quoted string\n */\n\n\n Strophe.SASLMD5.prototype._quote = function (str) {\n return '\"' + str.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"') + '\"'; //\" end string workaround for emacs\n };\n\n Strophe.SASLMD5.prototype.onChallenge = function (connection, challenge, test_cnonce) {\n var attribMatch = /([a-z]+)=(\"[^\"]+\"|[^,\"]+)(?:,|$)/;\n var cnonce = test_cnonce || MD5.hexdigest(\"\" + Math.random() * 1234567890);\n var realm = \"\";\n var host = null;\n var nonce = \"\";\n var qop = \"\";\n\n while (challenge.match(attribMatch)) {\n var matches = challenge.match(attribMatch);\n challenge = challenge.replace(matches[0], \"\");\n matches[2] = matches[2].replace(/^\"(.+)\"$/, \"$1\");\n\n switch (matches[1]) {\n case \"realm\":\n realm = matches[2];\n break;\n\n case \"nonce\":\n nonce = matches[2];\n break;\n\n case \"qop\":\n qop = matches[2];\n break;\n\n case \"host\":\n host = matches[2];\n break;\n }\n }\n\n var digest_uri = connection.servtype + \"/\" + connection.domain;\n\n if (host !== null) {\n digest_uri = digest_uri + \"/\" + host;\n }\n\n var cred = utils.utf16to8(connection.authcid + \":\" + realm + \":\" + this._connection.pass);\n var A1 = MD5.hash(cred) + \":\" + nonce + \":\" + cnonce;\n var A2 = 'AUTHENTICATE:' + digest_uri;\n var responseText = \"\";\n responseText += 'charset=utf-8,';\n responseText += 'username=' + this._quote(utils.utf16to8(connection.authcid)) + ',';\n responseText += 'realm=' + this._quote(realm) + ',';\n responseText += 'nonce=' + this._quote(nonce) + ',';\n responseText += 'nc=00000001,';\n responseText += 'cnonce=' + this._quote(cnonce) + ',';\n responseText += 'digest-uri=' + this._quote(digest_uri) + ',';\n responseText += 'response=' + MD5.hexdigest(MD5.hexdigest(A1) + \":\" + nonce + \":00000001:\" + cnonce + \":auth:\" + MD5.hexdigest(A2)) + \",\";\n responseText += 'qop=auth';\n\n this.onChallenge = function () {\n return \"\";\n };\n\n return responseText;\n };\n /** PrivateConstructor: SASLOAuthBearer\n * SASL OAuth Bearer authentication.\n */\n\n\n Strophe.SASLOAuthBearer = function () {};\n\n Strophe.SASLOAuthBearer.prototype = new Strophe.SASLMechanism(\"OAUTHBEARER\", true, 40);\n\n Strophe.SASLOAuthBearer.prototype.test = function (connection) {\n return connection.pass !== null;\n };\n\n Strophe.SASLOAuthBearer.prototype.onChallenge = function (connection) {\n var auth_str = 'n,';\n\n if (connection.authcid !== null) {\n auth_str = auth_str + 'a=' + connection.authzid;\n }\n\n auth_str = auth_str + ',';\n auth_str = auth_str + \"\\x01\";\n auth_str = auth_str + 'auth=Bearer ';\n auth_str = auth_str + connection.pass;\n auth_str = auth_str + \"\\x01\";\n auth_str = auth_str + \"\\x01\";\n return utils.utf16to8(auth_str);\n };\n /** PrivateConstructor: SASLExternal\n * SASL EXTERNAL authentication.\n *\n * The EXTERNAL mechanism allows a client to request the server to use\n * credentials established by means external to the mechanism to\n * authenticate the client. The external means may be, for instance,\n * TLS services.\n */\n\n\n Strophe.SASLExternal = function () {};\n\n Strophe.SASLExternal.prototype = new Strophe.SASLMechanism(\"EXTERNAL\", true, 10);\n\n Strophe.SASLExternal.prototype.onChallenge = function (connection) {\n /** According to XEP-178, an authzid SHOULD NOT be presented when the\n * authcid contained or implied in the client certificate is the JID (i.e.\n * authzid) with which the user wants to log in as.\n *\n * To NOT send the authzid, the user should therefore set the authcid equal\n * to the JID when instantiating a new Strophe.Connection object.\n */\n return connection.authcid === connection.authzid ? '' : connection.authzid;\n };\n /** PrivateConstructor: SASLXOAuth2\n * SASL X-OAuth2 authentication.\n */\n\n\n Strophe.SASLXOAuth2 = function () {};\n\n Strophe.SASLXOAuth2.prototype = new Strophe.SASLMechanism(\"X-OAUTH2\", true, 30);\n\n Strophe.SASLXOAuth2.prototype.test = function (connection) {\n return connection.pass !== null;\n };\n\n Strophe.SASLXOAuth2.prototype.onChallenge = function (connection) {\n var auth_str = \"\\0\";\n\n if (connection.authcid !== null) {\n auth_str = auth_str + connection.authzid;\n }\n\n auth_str = auth_str + \"\\0\";\n auth_str = auth_str + connection.pass;\n return utils.utf16to8(auth_str);\n };\n var core = {\n 'Strophe': Strophe,\n '$build': $build,\n '$iq': $iq,\n '$msg': $msg,\n '$pres': $pres,\n 'SHA1': SHA1,\n 'MD5': MD5,\n 'b64_hmac_sha1': SHA1.b64_hmac_sha1,\n 'b64_sha1': SHA1.b64_sha1,\n 'str_hmac_sha1': SHA1.str_hmac_sha1,\n 'str_sha1': SHA1.str_sha1\n };\n\n /*\n This program is distributed under the terms of the MIT license.\n Please see the LICENSE file for details.\n\n Copyright 2006-2008, OGG, LLC\n */\n var Strophe$1 = core.Strophe;\n var $build$1 = core.$build;\n /** PrivateClass: Strophe.Request\n * _Private_ helper class that provides a cross implementation abstraction\n * for a BOSH related XMLHttpRequest.\n *\n * The Strophe.Request class is used internally to encapsulate BOSH request\n * information. It is not meant to be used from user's code.\n */\n\n /** PrivateConstructor: Strophe.Request\n * Create and initialize a new Strophe.Request object.\n *\n * Parameters:\n * (XMLElement) elem - The XML data to be sent in the request.\n * (Function) func - The function that will be called when the\n * XMLHttpRequest readyState changes.\n * (Integer) rid - The BOSH rid attribute associated with this request.\n * (Integer) sends - The number of times this same request has been sent.\n */\n\n Strophe$1.Request = function (elem, func, rid, sends) {\n this.id = ++Strophe$1._requestId;\n this.xmlData = elem;\n this.data = Strophe$1.serialize(elem); // save original function in case we need to make a new request\n // from this one.\n\n this.origFunc = func;\n this.func = func;\n this.rid = rid;\n this.date = NaN;\n this.sends = sends || 0;\n this.abort = false;\n this.dead = null;\n\n this.age = function () {\n if (!this.date) {\n return 0;\n }\n\n var now = new Date();\n return (now - this.date) / 1000;\n };\n\n this.timeDead = function () {\n if (!this.dead) {\n return 0;\n }\n\n var now = new Date();\n return (now - this.dead) / 1000;\n };\n\n this.xhr = this._newXHR();\n };\n\n Strophe$1.Request.prototype = {\n /** PrivateFunction: getResponse\n * Get a response from the underlying XMLHttpRequest.\n *\n * This function attempts to get a response from the request and checks\n * for errors.\n *\n * Throws:\n * \"parsererror\" - A parser error occured.\n * \"bad-format\" - The entity has sent XML that cannot be processed.\n *\n * Returns:\n * The DOM element tree of the response.\n */\n getResponse: function getResponse() {\n var node = null;\n\n if (this.xhr.responseXML && this.xhr.responseXML.documentElement) {\n node = this.xhr.responseXML.documentElement;\n\n if (node.tagName === \"parsererror\") {\n Strophe$1.error(\"invalid response received\");\n Strophe$1.error(\"responseText: \" + this.xhr.responseText);\n Strophe$1.error(\"responseXML: \" + Strophe$1.serialize(this.xhr.responseXML));\n throw new Error(\"parsererror\");\n }\n } else if (this.xhr.responseText) {\n // In React Native, we may get responseText but no responseXML. We can try to parse it manually.\n Strophe$1.debug(\"Got responseText but no responseXML; attempting to parse it with DOMParser...\");\n node = new DOMParser().parseFromString(this.xhr.responseText, 'application/xml').documentElement;\n\n if (!node) {\n throw new Error('Parsing produced null node');\n } else if (node.querySelector('parsererror')) {\n Strophe$1.error(\"invalid response received: \" + node.querySelector('parsererror').textContent);\n Strophe$1.error(\"responseText: \" + this.xhr.responseText);\n var error = new Error();\n error.name = Strophe$1.ErrorCondition.BAD_FORMAT;\n throw error;\n }\n }\n\n return node;\n },\n\n /** PrivateFunction: _newXHR\n * _Private_ helper function to create XMLHttpRequests.\n *\n * This function creates XMLHttpRequests across all implementations.\n *\n * Returns:\n * A new XMLHttpRequest.\n */\n _newXHR: function _newXHR() {\n var xhr = null;\n\n if (window.XMLHttpRequest) {\n xhr = new XMLHttpRequest();\n\n if (xhr.overrideMimeType) {\n xhr.overrideMimeType(\"text/xml; charset=utf-8\");\n }\n } else if (window.ActiveXObject) {\n xhr = new ActiveXObject(\"Microsoft.XMLHTTP\");\n } // use Function.bind() to prepend ourselves as an argument\n\n\n xhr.onreadystatechange = this.func.bind(null, this);\n return xhr;\n }\n };\n /** Class: Strophe.Bosh\n * _Private_ helper class that handles BOSH Connections\n *\n * The Strophe.Bosh class is used internally by Strophe.Connection\n * to encapsulate BOSH sessions. It is not meant to be used from user's code.\n */\n\n /** File: bosh.js\n * A JavaScript library to enable BOSH in Strophejs.\n *\n * this library uses Bidirectional-streams Over Synchronous HTTP (BOSH)\n * to emulate a persistent, stateful, two-way connection to an XMPP server.\n * More information on BOSH can be found in XEP 124.\n */\n\n /** PrivateConstructor: Strophe.Bosh\n * Create and initialize a Strophe.Bosh object.\n *\n * Parameters:\n * (Strophe.Connection) connection - The Strophe.Connection that will use BOSH.\n *\n * Returns:\n * A new Strophe.Bosh object.\n */\n\n Strophe$1.Bosh = function (connection) {\n this._conn = connection;\n /* request id for body tags */\n\n this.rid = Math.floor(Math.random() * 4294967295);\n /* The current session ID. */\n\n this.sid = null; // default BOSH values\n\n this.hold = 1;\n this.wait = 60;\n this.window = 5;\n this.errors = 0;\n this.inactivity = null;\n this.lastResponseHeaders = null;\n this._requests = [];\n };\n\n Strophe$1.Bosh.prototype = {\n /** Variable: strip\n *\n * BOSH-Connections will have all stanzas wrapped in a tag when\n * passed to or .\n * To strip this tag, User code can set to \"body\":\n *\n * > Strophe.Bosh.prototype.strip = \"body\";\n *\n * This will enable stripping of the body tag in both\n * and .\n */\n strip: null,\n\n /** PrivateFunction: _buildBody\n * _Private_ helper function to generate the wrapper for BOSH.\n *\n * Returns:\n * A Strophe.Builder with a element.\n */\n _buildBody: function _buildBody() {\n var bodyWrap = $build$1('body', {\n 'rid': this.rid++,\n 'xmlns': Strophe$1.NS.HTTPBIND\n });\n\n if (this.sid !== null) {\n bodyWrap.attrs({\n 'sid': this.sid\n });\n }\n\n if (this._conn.options.keepalive && this._conn._sessionCachingSupported()) {\n this._cacheSession();\n }\n\n return bodyWrap;\n },\n\n /** PrivateFunction: _reset\n * Reset the connection.\n *\n * This function is called by the reset function of the Strophe Connection\n */\n _reset: function _reset() {\n this.rid = Math.floor(Math.random() * 4294967295);\n this.sid = null;\n this.errors = 0;\n\n if (this._conn._sessionCachingSupported()) {\n window.sessionStorage.removeItem('strophe-bosh-session');\n }\n\n this._conn.nextValidRid(this.rid);\n },\n\n /** PrivateFunction: _connect\n * _Private_ function that initializes the BOSH connection.\n *\n * Creates and sends the Request that initializes the BOSH connection.\n */\n _connect: function _connect(wait, hold, route) {\n this.wait = wait || this.wait;\n this.hold = hold || this.hold;\n this.errors = 0;\n\n var body = this._buildBody().attrs({\n \"to\": this._conn.domain,\n \"xml:lang\": \"en\",\n \"wait\": this.wait,\n \"hold\": this.hold,\n \"content\": \"text/xml; charset=utf-8\",\n \"ver\": \"1.6\",\n \"xmpp:version\": \"1.0\",\n \"xmlns:xmpp\": Strophe$1.NS.BOSH\n });\n\n if (route) {\n body.attrs({\n 'route': route\n });\n }\n\n var _connect_cb = this._conn._connect_cb;\n\n this._requests.push(new Strophe$1.Request(body.tree(), this._onRequestStateChange.bind(this, _connect_cb.bind(this._conn)), body.tree().getAttribute(\"rid\")));\n\n this._throttledRequestHandler();\n },\n\n /** PrivateFunction: _attach\n * Attach to an already created and authenticated BOSH session.\n *\n * This function is provided to allow Strophe to attach to BOSH\n * sessions which have been created externally, perhaps by a Web\n * application. This is often used to support auto-login type features\n * without putting user credentials into the page.\n *\n * Parameters:\n * (String) jid - The full JID that is bound by the session.\n * (String) sid - The SID of the BOSH session.\n * (String) rid - The current RID of the BOSH session. This RID\n * will be used by the next request.\n * (Function) callback The connect callback function.\n * (Integer) wait - The optional HTTPBIND wait value. This is the\n * time the server will wait before returning an empty result for\n * a request. The default setting of 60 seconds is recommended.\n * Other settings will require tweaks to the Strophe.TIMEOUT value.\n * (Integer) hold - The optional HTTPBIND hold value. This is the\n * number of connections the server will hold at one time. This\n * should almost always be set to 1 (the default).\n * (Integer) wind - The optional HTTBIND window value. This is the\n * allowed range of request ids that are valid. The default is 5.\n */\n _attach: function _attach(jid, sid, rid, callback, wait, hold, wind) {\n this._conn.jid = jid;\n this.sid = sid;\n this.rid = rid;\n this._conn.connect_callback = callback;\n this._conn.domain = Strophe$1.getDomainFromJid(this._conn.jid);\n this._conn.authenticated = true;\n this._conn.connected = true;\n this.wait = wait || this.wait;\n this.hold = hold || this.hold;\n this.window = wind || this.window;\n\n this._conn._changeConnectStatus(Strophe$1.Status.ATTACHED, null);\n },\n\n /** PrivateFunction: _restore\n * Attempt to restore a cached BOSH session\n *\n * Parameters:\n * (String) jid - The full JID that is bound by the session.\n * This parameter is optional but recommended, specifically in cases\n * where prebinded BOSH sessions are used where it's important to know\n * that the right session is being restored.\n * (Function) callback The connect callback function.\n * (Integer) wait - The optional HTTPBIND wait value. This is the\n * time the server will wait before returning an empty result for\n * a request. The default setting of 60 seconds is recommended.\n * Other settings will require tweaks to the Strophe.TIMEOUT value.\n * (Integer) hold - The optional HTTPBIND hold value. This is the\n * number of connections the server will hold at one time. This\n * should almost always be set to 1 (the default).\n * (Integer) wind - The optional HTTBIND window value. This is the\n * allowed range of request ids that are valid. The default is 5.\n */\n _restore: function _restore(jid, callback, wait, hold, wind) {\n var session = JSON.parse(window.sessionStorage.getItem('strophe-bosh-session'));\n\n if (typeof session !== \"undefined\" && session !== null && session.rid && session.sid && session.jid && (typeof jid === \"undefined\" || jid === null || Strophe$1.getBareJidFromJid(session.jid) === Strophe$1.getBareJidFromJid(jid) || // If authcid is null, then it's an anonymous login, so\n // we compare only the domains:\n Strophe$1.getNodeFromJid(jid) === null && Strophe$1.getDomainFromJid(session.jid) === jid)) {\n this._conn.restored = true;\n\n this._attach(session.jid, session.sid, session.rid, callback, wait, hold, wind);\n } else {\n var error = new Error(\"_restore: no restoreable session.\");\n error.name = \"StropheSessionError\";\n throw error;\n }\n },\n\n /** PrivateFunction: _cacheSession\n * _Private_ handler for the beforeunload event.\n *\n * This handler is used to process the Bosh-part of the initial request.\n * Parameters:\n * (Strophe.Request) bodyWrap - The received stanza.\n */\n _cacheSession: function _cacheSession() {\n if (this._conn.authenticated) {\n if (this._conn.jid && this.rid && this.sid) {\n window.sessionStorage.setItem('strophe-bosh-session', JSON.stringify({\n 'jid': this._conn.jid,\n 'rid': this.rid,\n 'sid': this.sid\n }));\n }\n } else {\n window.sessionStorage.removeItem('strophe-bosh-session');\n }\n },\n\n /** PrivateFunction: _connect_cb\n * _Private_ handler for initial connection request.\n *\n * This handler is used to process the Bosh-part of the initial request.\n * Parameters:\n * (Strophe.Request) bodyWrap - The received stanza.\n */\n _connect_cb: function _connect_cb(bodyWrap) {\n var typ = bodyWrap.getAttribute(\"type\");\n\n if (typ !== null && typ === \"terminate\") {\n // an error occurred\n var cond = bodyWrap.getAttribute(\"condition\");\n Strophe$1.error(\"BOSH-Connection failed: \" + cond);\n var conflict = bodyWrap.getElementsByTagName(\"conflict\");\n\n if (cond !== null) {\n if (cond === \"remote-stream-error\" && conflict.length > 0) {\n cond = \"conflict\";\n }\n\n this._conn._changeConnectStatus(Strophe$1.Status.CONNFAIL, cond);\n } else {\n this._conn._changeConnectStatus(Strophe$1.Status.CONNFAIL, \"unknown\");\n }\n\n this._conn._doDisconnect(cond);\n\n return Strophe$1.Status.CONNFAIL;\n } // check to make sure we don't overwrite these if _connect_cb is\n // called multiple times in the case of missing stream:features\n\n\n if (!this.sid) {\n this.sid = bodyWrap.getAttribute(\"sid\");\n }\n\n var wind = bodyWrap.getAttribute('requests');\n\n if (wind) {\n this.window = parseInt(wind, 10);\n }\n\n var hold = bodyWrap.getAttribute('hold');\n\n if (hold) {\n this.hold = parseInt(hold, 10);\n }\n\n var wait = bodyWrap.getAttribute('wait');\n\n if (wait) {\n this.wait = parseInt(wait, 10);\n }\n\n var inactivity = bodyWrap.getAttribute('inactivity');\n\n if (inactivity) {\n this.inactivity = parseInt(inactivity, 10);\n }\n },\n\n /** PrivateFunction: _disconnect\n * _Private_ part of Connection.disconnect for Bosh\n *\n * Parameters:\n * (Request) pres - This stanza will be sent before disconnecting.\n */\n _disconnect: function _disconnect(pres) {\n this._sendTerminate(pres);\n },\n\n /** PrivateFunction: _doDisconnect\n * _Private_ function to disconnect.\n *\n * Resets the SID and RID.\n */\n _doDisconnect: function _doDisconnect() {\n this.sid = null;\n this.rid = Math.floor(Math.random() * 4294967295);\n\n if (this._conn._sessionCachingSupported()) {\n window.sessionStorage.removeItem('strophe-bosh-session');\n }\n\n this._conn.nextValidRid(this.rid);\n },\n\n /** PrivateFunction: _emptyQueue\n * _Private_ function to check if the Request queue is empty.\n *\n * Returns:\n * True, if there are no Requests queued, False otherwise.\n */\n _emptyQueue: function _emptyQueue() {\n return this._requests.length === 0;\n },\n\n /** PrivateFunction: _callProtocolErrorHandlers\n * _Private_ function to call error handlers registered for HTTP errors.\n *\n * Parameters:\n * (Strophe.Request) req - The request that is changing readyState.\n */\n _callProtocolErrorHandlers: function _callProtocolErrorHandlers(req) {\n var reqStatus = this._getRequestStatus(req);\n\n var err_callback = this._conn.protocolErrorHandlers.HTTP[reqStatus];\n\n if (err_callback) {\n err_callback.call(this, reqStatus);\n }\n },\n\n /** PrivateFunction: _hitError\n * _Private_ function to handle the error count.\n *\n * Requests are resent automatically until their error count reaches\n * 5. Each time an error is encountered, this function is called to\n * increment the count and disconnect if the count is too high.\n *\n * Parameters:\n * (Integer) reqStatus - The request status.\n */\n _hitError: function _hitError(reqStatus) {\n this.errors++;\n Strophe$1.warn(\"request errored, status: \" + reqStatus + \", number of errors: \" + this.errors);\n\n if (this.errors > 4) {\n this._conn._onDisconnectTimeout();\n }\n },\n\n /** PrivateFunction: _no_auth_received\n *\n * Called on stream start/restart when no stream:features\n * has been received and sends a blank poll request.\n */\n _no_auth_received: function _no_auth_received(callback) {\n Strophe$1.warn(\"Server did not yet offer a supported authentication \" + \"mechanism. Sending a blank poll request.\");\n\n if (callback) {\n callback = callback.bind(this._conn);\n } else {\n callback = this._conn._connect_cb.bind(this._conn);\n }\n\n var body = this._buildBody();\n\n this._requests.push(new Strophe$1.Request(body.tree(), this._onRequestStateChange.bind(this, callback), body.tree().getAttribute(\"rid\")));\n\n this._throttledRequestHandler();\n },\n\n /** PrivateFunction: _onDisconnectTimeout\n * _Private_ timeout handler for handling non-graceful disconnection.\n *\n * Cancels all remaining Requests and clears the queue.\n */\n _onDisconnectTimeout: function _onDisconnectTimeout() {\n this._abortAllRequests();\n },\n\n /** PrivateFunction: _abortAllRequests\n * _Private_ helper function that makes sure all pending requests are aborted.\n */\n _abortAllRequests: function _abortAllRequests() {\n while (this._requests.length > 0) {\n var req = this._requests.pop();\n\n req.abort = true;\n req.xhr.abort();\n\n req.xhr.onreadystatechange = function () {};\n }\n },\n\n /** PrivateFunction: _onIdle\n * _Private_ handler called by Strophe.Connection._onIdle\n *\n * Sends all queued Requests or polls with empty Request if there are none.\n */\n _onIdle: function _onIdle() {\n var data = this._conn._data; // if no requests are in progress, poll\n\n if (this._conn.authenticated && this._requests.length === 0 && data.length === 0 && !this._conn.disconnecting) {\n Strophe$1.debug(\"no requests during idle cycle, sending blank request\");\n data.push(null);\n }\n\n if (this._conn.paused) {\n return;\n }\n\n if (this._requests.length < 2 && data.length > 0) {\n var body = this._buildBody();\n\n for (var i = 0; i < data.length; i++) {\n if (data[i] !== null) {\n if (data[i] === \"restart\") {\n body.attrs({\n \"to\": this._conn.domain,\n \"xml:lang\": \"en\",\n \"xmpp:restart\": \"true\",\n \"xmlns:xmpp\": Strophe$1.NS.BOSH\n });\n } else {\n body.cnode(data[i]).up();\n }\n }\n }\n\n delete this._conn._data;\n this._conn._data = [];\n\n this._requests.push(new Strophe$1.Request(body.tree(), this._onRequestStateChange.bind(this, this._conn._dataRecv.bind(this._conn)), body.tree().getAttribute(\"rid\")));\n\n this._throttledRequestHandler();\n }\n\n if (this._requests.length > 0) {\n var time_elapsed = this._requests[0].age();\n\n if (this._requests[0].dead !== null) {\n if (this._requests[0].timeDead() > Math.floor(Strophe$1.SECONDARY_TIMEOUT * this.wait)) {\n this._throttledRequestHandler();\n }\n }\n\n if (time_elapsed > Math.floor(Strophe$1.TIMEOUT * this.wait)) {\n Strophe$1.warn(\"Request \" + this._requests[0].id + \" timed out, over \" + Math.floor(Strophe$1.TIMEOUT * this.wait) + \" seconds since last activity\");\n\n this._throttledRequestHandler();\n }\n }\n },\n\n /** PrivateFunction: _getRequestStatus\n *\n * Returns the HTTP status code from a Strophe.Request\n *\n * Parameters:\n * (Strophe.Request) req - The Strophe.Request instance.\n * (Integer) def - The default value that should be returned if no\n * status value was found.\n */\n _getRequestStatus: function _getRequestStatus(req, def) {\n var reqStatus;\n\n if (req.xhr.readyState === 4) {\n try {\n reqStatus = req.xhr.status;\n } catch (e) {\n // ignore errors from undefined status attribute. Works\n // around a browser bug\n Strophe$1.error(\"Caught an error while retrieving a request's status, \" + \"reqStatus: \" + reqStatus);\n }\n }\n\n if (typeof reqStatus === \"undefined\") {\n reqStatus = typeof def === 'number' ? def : 0;\n }\n\n return reqStatus;\n },\n\n /** PrivateFunction: _onRequestStateChange\n * _Private_ handler for Strophe.Request state changes.\n *\n * This function is called when the XMLHttpRequest readyState changes.\n * It contains a lot of error handling logic for the many ways that\n * requests can fail, and calls the request callback when requests\n * succeed.\n *\n * Parameters:\n * (Function) func - The handler for the request.\n * (Strophe.Request) req - The request that is changing readyState.\n */\n _onRequestStateChange: function _onRequestStateChange(func, req) {\n Strophe$1.debug(\"request id \" + req.id + \".\" + req.sends + \" state changed to \" + req.xhr.readyState);\n\n if (req.abort) {\n req.abort = false;\n return;\n }\n\n if (req.xhr.readyState !== 4) {\n // The request is not yet complete\n return;\n }\n\n var reqStatus = this._getRequestStatus(req);\n\n this.lastResponseHeaders = req.xhr.getAllResponseHeaders();\n\n if (this.disconnecting && reqStatus >= 400) {\n this._hitError(reqStatus);\n\n this._callProtocolErrorHandlers(req);\n\n return;\n }\n\n var valid_request = reqStatus > 0 && reqStatus < 500;\n var too_many_retries = req.sends > this._conn.maxRetries;\n\n if (valid_request || too_many_retries) {\n // remove from internal queue\n this._removeRequest(req);\n\n Strophe$1.debug(\"request id \" + req.id + \" should now be removed\");\n }\n\n if (reqStatus === 200) {\n // request succeeded\n var reqIs0 = this._requests[0] === req;\n var reqIs1 = this._requests[1] === req; // if request 1 finished, or request 0 finished and request\n // 1 is over Strophe.SECONDARY_TIMEOUT seconds old, we need to\n // restart the other - both will be in the first spot, as the\n // completed request has been removed from the queue already\n\n if (reqIs1 || reqIs0 && this._requests.length > 0 && this._requests[0].age() > Math.floor(Strophe$1.SECONDARY_TIMEOUT * this.wait)) {\n this._restartRequest(0);\n }\n\n this._conn.nextValidRid(Number(req.rid) + 1);\n\n Strophe$1.debug(\"request id \" + req.id + \".\" + req.sends + \" got 200\");\n func(req); // call handler\n\n this.errors = 0;\n } else if (reqStatus === 0 || reqStatus >= 400 && reqStatus < 600 || reqStatus >= 12000) {\n // request failed\n Strophe$1.error(\"request id \" + req.id + \".\" + req.sends + \" error \" + reqStatus + \" happened\");\n\n this._hitError(reqStatus);\n\n this._callProtocolErrorHandlers(req);\n\n if (reqStatus >= 400 && reqStatus < 500) {\n this._conn._changeConnectStatus(Strophe$1.Status.DISCONNECTING, null);\n\n this._conn._doDisconnect();\n }\n } else {\n Strophe$1.error(\"request id \" + req.id + \".\" + req.sends + \" error \" + reqStatus + \" happened\");\n }\n\n if (!valid_request && !too_many_retries) {\n this._throttledRequestHandler();\n } else if (too_many_retries && !this._conn.connected) {\n this._conn._changeConnectStatus(Strophe$1.Status.CONNFAIL, \"giving-up\");\n }\n },\n\n /** PrivateFunction: _processRequest\n * _Private_ function to process a request in the queue.\n *\n * This function takes requests off the queue and sends them and\n * restarts dead requests.\n *\n * Parameters:\n * (Integer) i - The index of the request in the queue.\n */\n _processRequest: function _processRequest(i) {\n var _this = this;\n\n var req = this._requests[i];\n\n var reqStatus = this._getRequestStatus(req, -1); // make sure we limit the number of retries\n\n\n if (req.sends > this._conn.maxRetries) {\n this._conn._onDisconnectTimeout();\n\n return;\n }\n\n var time_elapsed = req.age();\n var primary_timeout = !isNaN(time_elapsed) && time_elapsed > Math.floor(Strophe$1.TIMEOUT * this.wait);\n var secondary_timeout = req.dead !== null && req.timeDead() > Math.floor(Strophe$1.SECONDARY_TIMEOUT * this.wait);\n var server_error = req.xhr.readyState === 4 && (reqStatus < 1 || reqStatus >= 500);\n\n if (primary_timeout || secondary_timeout || server_error) {\n if (secondary_timeout) {\n Strophe$1.error(\"Request \".concat(this._requests[i].id, \" timed out (secondary), restarting\"));\n }\n\n req.abort = true;\n req.xhr.abort(); // setting to null fails on IE6, so set to empty function\n\n req.xhr.onreadystatechange = function () {};\n\n this._requests[i] = new Strophe$1.Request(req.xmlData, req.origFunc, req.rid, req.sends);\n req = this._requests[i];\n }\n\n if (req.xhr.readyState === 0) {\n Strophe$1.debug(\"request id \" + req.id + \".\" + req.sends + \" posting\");\n\n try {\n var content_type = this._conn.options.contentType || \"text/xml; charset=utf-8\";\n req.xhr.open(\"POST\", this._conn.service, this._conn.options.sync ? false : true);\n\n if (typeof req.xhr.setRequestHeader !== 'undefined') {\n // IE9 doesn't have setRequestHeader\n req.xhr.setRequestHeader(\"Content-Type\", content_type);\n }\n\n if (this._conn.options.withCredentials) {\n req.xhr.withCredentials = true;\n }\n } catch (e2) {\n Strophe$1.error(\"XHR open failed: \" + e2.toString());\n\n if (!this._conn.connected) {\n this._conn._changeConnectStatus(Strophe$1.Status.CONNFAIL, \"bad-service\");\n }\n\n this._conn.disconnect();\n\n return;\n } // Fires the XHR request -- may be invoked immediately\n // or on a gradually expanding retry window for reconnects\n\n\n var sendFunc = function sendFunc() {\n req.date = new Date();\n\n if (_this._conn.options.customHeaders) {\n var headers = _this._conn.options.customHeaders;\n\n for (var header in headers) {\n if (Object.prototype.hasOwnProperty.call(headers, header)) {\n req.xhr.setRequestHeader(header, headers[header]);\n }\n }\n }\n\n req.xhr.send(req.data);\n }; // Implement progressive backoff for reconnects --\n // First retry (send === 1) should also be instantaneous\n\n\n if (req.sends > 1) {\n // Using a cube of the retry number creates a nicely\n // expanding retry window\n var backoff = Math.min(Math.floor(Strophe$1.TIMEOUT * this.wait), Math.pow(req.sends, 3)) * 1000;\n setTimeout(function () {\n // XXX: setTimeout should be called only with function expressions (23974bc1)\n sendFunc();\n }, backoff);\n } else {\n sendFunc();\n }\n\n req.sends++;\n\n if (this._conn.xmlOutput !== Strophe$1.Connection.prototype.xmlOutput) {\n if (req.xmlData.nodeName === this.strip && req.xmlData.childNodes.length) {\n this._conn.xmlOutput(req.xmlData.childNodes[0]);\n } else {\n this._conn.xmlOutput(req.xmlData);\n }\n }\n\n if (this._conn.rawOutput !== Strophe$1.Connection.prototype.rawOutput) {\n this._conn.rawOutput(req.data);\n }\n } else {\n Strophe$1.debug(\"_processRequest: \" + (i === 0 ? \"first\" : \"second\") + \" request has readyState of \" + req.xhr.readyState);\n }\n },\n\n /** PrivateFunction: _removeRequest\n * _Private_ function to remove a request from the queue.\n *\n * Parameters:\n * (Strophe.Request) req - The request to remove.\n */\n _removeRequest: function _removeRequest(req) {\n Strophe$1.debug(\"removing request\");\n\n for (var i = this._requests.length - 1; i >= 0; i--) {\n if (req === this._requests[i]) {\n this._requests.splice(i, 1);\n }\n } // IE6 fails on setting to null, so set to empty function\n\n\n req.xhr.onreadystatechange = function () {};\n\n this._throttledRequestHandler();\n },\n\n /** PrivateFunction: _restartRequest\n * _Private_ function to restart a request that is presumed dead.\n *\n * Parameters:\n * (Integer) i - The index of the request in the queue.\n */\n _restartRequest: function _restartRequest(i) {\n var req = this._requests[i];\n\n if (req.dead === null) {\n req.dead = new Date();\n }\n\n this._processRequest(i);\n },\n\n /** PrivateFunction: _reqToData\n * _Private_ function to get a stanza out of a request.\n *\n * Tries to extract a stanza out of a Request Object.\n * When this fails the current connection will be disconnected.\n *\n * Parameters:\n * (Object) req - The Request.\n *\n * Returns:\n * The stanza that was passed.\n */\n _reqToData: function _reqToData(req) {\n try {\n return req.getResponse();\n } catch (e) {\n if (e.message !== \"parsererror\") {\n throw e;\n }\n\n this._conn.disconnect(\"strophe-parsererror\");\n }\n },\n\n /** PrivateFunction: _sendTerminate\n * _Private_ function to send initial disconnect sequence.\n *\n * This is the first step in a graceful disconnect. It sends\n * the BOSH server a terminate body and includes an unavailable\n * presence if authentication has completed.\n */\n _sendTerminate: function _sendTerminate(pres) {\n Strophe$1.debug(\"_sendTerminate was called\");\n\n var body = this._buildBody().attrs({\n type: \"terminate\"\n });\n\n if (pres) {\n body.cnode(pres.tree());\n }\n\n var req = new Strophe$1.Request(body.tree(), this._onRequestStateChange.bind(this, this._conn._dataRecv.bind(this._conn)), body.tree().getAttribute(\"rid\"));\n\n this._requests.push(req);\n\n this._throttledRequestHandler();\n },\n\n /** PrivateFunction: _send\n * _Private_ part of the Connection.send function for BOSH\n *\n * Just triggers the RequestHandler to send the messages that are in the queue\n */\n _send: function _send() {\n var _this2 = this;\n\n clearTimeout(this._conn._idleTimeout);\n\n this._throttledRequestHandler();\n\n this._conn._idleTimeout = setTimeout(function () {\n return _this2._conn._onIdle();\n }, 100);\n },\n\n /** PrivateFunction: _sendRestart\n *\n * Send an xmpp:restart stanza.\n */\n _sendRestart: function _sendRestart() {\n this._throttledRequestHandler();\n\n clearTimeout(this._conn._idleTimeout);\n },\n\n /** PrivateFunction: _throttledRequestHandler\n * _Private_ function to throttle requests to the connection window.\n *\n * This function makes sure we don't send requests so fast that the\n * request ids overflow the connection window in the case that one\n * request died.\n */\n _throttledRequestHandler: function _throttledRequestHandler() {\n if (!this._requests) {\n Strophe$1.debug(\"_throttledRequestHandler called with \" + \"undefined requests\");\n } else {\n Strophe$1.debug(\"_throttledRequestHandler called with \" + this._requests.length + \" requests\");\n }\n\n if (!this._requests || this._requests.length === 0) {\n return;\n }\n\n if (this._requests.length > 0) {\n this._processRequest(0);\n }\n\n if (this._requests.length > 1 && Math.abs(this._requests[0].rid - this._requests[1].rid) < this.window) {\n this._processRequest(1);\n }\n }\n };\n\n /*\n This program is distributed under the terms of the MIT license.\n Please see the LICENSE file for details.\n\n Copyright 2006-2008, OGG, LLC\n */\n var Strophe$2 = core.Strophe;\n var $build$2 = core.$build;\n /** Class: Strophe.WebSocket\n * _Private_ helper class that handles WebSocket Connections\n *\n * The Strophe.WebSocket class is used internally by Strophe.Connection\n * to encapsulate WebSocket sessions. It is not meant to be used from user's code.\n */\n\n /** File: websocket.js\n * A JavaScript library to enable XMPP over Websocket in Strophejs.\n *\n * This file implements XMPP over WebSockets for Strophejs.\n * If a Connection is established with a Websocket url (ws://...)\n * Strophe will use WebSockets.\n * For more information on XMPP-over-WebSocket see RFC 7395:\n * http://tools.ietf.org/html/rfc7395\n *\n * WebSocket support implemented by Andreas Guth (andreas.guth@rwth-aachen.de)\n */\n\n /** PrivateConstructor: Strophe.Websocket\n * Create and initialize a Strophe.WebSocket object.\n * Currently only sets the connection Object.\n *\n * Parameters:\n * (Strophe.Connection) connection - The Strophe.Connection that will use WebSockets.\n *\n * Returns:\n * A new Strophe.WebSocket object.\n */\n\n Strophe$2.Websocket = function (connection) {\n this._conn = connection;\n this.strip = \"wrapper\";\n var service = connection.service;\n\n if (service.indexOf(\"ws:\") !== 0 && service.indexOf(\"wss:\") !== 0) {\n // If the service is not an absolute URL, assume it is a path and put the absolute\n // URL together from options, current URL and the path.\n var new_service = \"\";\n\n if (connection.options.protocol === \"ws\" && window.location.protocol !== \"https:\") {\n new_service += \"ws\";\n } else {\n new_service += \"wss\";\n }\n\n new_service += \"://\" + window.location.host;\n\n if (service.indexOf(\"/\") !== 0) {\n new_service += window.location.pathname + service;\n } else {\n new_service += service;\n }\n\n connection.service = new_service;\n }\n };\n\n Strophe$2.Websocket.prototype = {\n /** PrivateFunction: _buildStream\n * _Private_ helper function to generate the start tag for WebSockets\n *\n * Returns:\n * A Strophe.Builder with a element.\n */\n _buildStream: function _buildStream() {\n return $build$2(\"open\", {\n \"xmlns\": Strophe$2.NS.FRAMING,\n \"to\": this._conn.domain,\n \"version\": '1.0'\n });\n },\n\n /** PrivateFunction: _check_streamerror\n * _Private_ checks a message for stream:error\n *\n * Parameters:\n * (Strophe.Request) bodyWrap - The received stanza.\n * connectstatus - The ConnectStatus that will be set on error.\n * Returns:\n * true if there was a streamerror, false otherwise.\n */\n _check_streamerror: function _check_streamerror(bodyWrap, connectstatus) {\n var errors;\n\n if (bodyWrap.getElementsByTagNameNS) {\n errors = bodyWrap.getElementsByTagNameNS(Strophe$2.NS.STREAM, \"error\");\n } else {\n errors = bodyWrap.getElementsByTagName(\"stream:error\");\n }\n\n if (errors.length === 0) {\n return false;\n }\n\n var error = errors[0];\n var condition = \"\";\n var text = \"\";\n var ns = \"urn:ietf:params:xml:ns:xmpp-streams\";\n\n for (var i = 0; i < error.childNodes.length; i++) {\n var e = error.childNodes[i];\n\n if (e.getAttribute(\"xmlns\") !== ns) {\n break;\n }\n\n if (e.nodeName === \"text\") {\n text = e.textContent;\n } else {\n condition = e.nodeName;\n }\n }\n\n var errorString = \"WebSocket stream error: \";\n\n if (condition) {\n errorString += condition;\n } else {\n errorString += \"unknown\";\n }\n\n if (text) {\n errorString += \" - \" + text;\n }\n\n Strophe$2.error(errorString); // close the connection on stream_error\n\n this._conn._changeConnectStatus(connectstatus, condition);\n\n this._conn._doDisconnect();\n\n return true;\n },\n\n /** PrivateFunction: _reset\n * Reset the connection.\n *\n * This function is called by the reset function of the Strophe Connection.\n * Is not needed by WebSockets.\n */\n _reset: function _reset() {\n return;\n },\n\n /** PrivateFunction: _connect\n * _Private_ function called by Strophe.Connection.connect\n *\n * Creates a WebSocket for a connection and assigns Callbacks to it.\n * Does nothing if there already is a WebSocket.\n */\n _connect: function _connect() {\n // Ensure that there is no open WebSocket from a previous Connection.\n this._closeSocket(); // Create the new WobSocket\n\n\n this.socket = new WebSocket(this._conn.service, \"xmpp\");\n this.socket.onopen = this._onOpen.bind(this);\n this.socket.onerror = this._onError.bind(this);\n this.socket.onclose = this._onClose.bind(this);\n this.socket.onmessage = this._connect_cb_wrapper.bind(this);\n },\n\n /** PrivateFunction: _connect_cb\n * _Private_ function called by Strophe.Connection._connect_cb\n *\n * checks for stream:error\n *\n * Parameters:\n * (Strophe.Request) bodyWrap - The received stanza.\n */\n _connect_cb: function _connect_cb(bodyWrap) {\n var error = this._check_streamerror(bodyWrap, Strophe$2.Status.CONNFAIL);\n\n if (error) {\n return Strophe$2.Status.CONNFAIL;\n }\n },\n\n /** PrivateFunction: _handleStreamStart\n * _Private_ function that checks the opening tag for errors.\n *\n * Disconnects if there is an error and returns false, true otherwise.\n *\n * Parameters:\n * (Node) message - Stanza containing the tag.\n */\n _handleStreamStart: function _handleStreamStart(message) {\n var error = false; // Check for errors in the tag\n\n var ns = message.getAttribute(\"xmlns\");\n\n if (typeof ns !== \"string\") {\n error = \"Missing xmlns in \";\n } else if (ns !== Strophe$2.NS.FRAMING) {\n error = \"Wrong xmlns in : \" + ns;\n }\n\n var ver = message.getAttribute(\"version\");\n\n if (typeof ver !== \"string\") {\n error = \"Missing version in \";\n } else if (ver !== \"1.0\") {\n error = \"Wrong version in : \" + ver;\n }\n\n if (error) {\n this._conn._changeConnectStatus(Strophe$2.Status.CONNFAIL, error);\n\n this._conn._doDisconnect();\n\n return false;\n }\n\n return true;\n },\n\n /** PrivateFunction: _connect_cb_wrapper\n * _Private_ function that handles the first connection messages.\n *\n * On receiving an opening stream tag this callback replaces itself with the real\n * message handler. On receiving a stream error the connection is terminated.\n */\n _connect_cb_wrapper: function _connect_cb_wrapper(message) {\n if (message.data.indexOf(\"\\s*)*/, \"\");\n if (data === '') return;\n var streamStart = new DOMParser().parseFromString(data, \"text/xml\").documentElement;\n\n this._conn.xmlInput(streamStart);\n\n this._conn.rawInput(message.data); //_handleStreamSteart will check for XML errors and disconnect on error\n\n\n if (this._handleStreamStart(streamStart)) {\n //_connect_cb will check for stream:error and disconnect on error\n this._connect_cb(streamStart);\n }\n } else if (message.data.indexOf(\"\n // Parse the raw string to an XML element\n var parsedMessage = new DOMParser().parseFromString(message.data, \"text/xml\").documentElement; // Report this input to the raw and xml handlers\n\n this._conn.xmlInput(parsedMessage);\n\n this._conn.rawInput(message.data);\n\n var see_uri = parsedMessage.getAttribute(\"see-other-uri\");\n\n if (see_uri) {\n var service = this._conn.service; // Valid scenarios: WSS->WSS, WS->ANY\n\n var isSecureRedirect = service.indexOf(\"wss:\") >= 0 && see_uri.indexOf(\"wss:\") >= 0 || service.indexOf(\"ws:\") >= 0;\n\n if (isSecureRedirect) {\n this._conn._changeConnectStatus(Strophe$2.Status.REDIRECT, \"Received see-other-uri, resetting connection\");\n\n this._conn.reset();\n\n this._conn.service = see_uri;\n\n this._connect();\n }\n } else {\n this._conn._changeConnectStatus(Strophe$2.Status.CONNFAIL, \"Received closing stream\");\n\n this._conn._doDisconnect();\n }\n } else {\n var string = this._streamWrap(message.data);\n\n var elem = new DOMParser().parseFromString(string, \"text/xml\").documentElement;\n this.socket.onmessage = this._onMessage.bind(this);\n\n this._conn._connect_cb(elem, null, message.data);\n }\n },\n\n /** PrivateFunction: _disconnect\n * _Private_ function called by Strophe.Connection.disconnect\n *\n * Disconnects and sends a last stanza if one is given\n *\n * Parameters:\n * (Request) pres - This stanza will be sent before disconnecting.\n */\n _disconnect: function _disconnect(pres) {\n if (this.socket && this.socket.readyState !== WebSocket.CLOSED) {\n if (pres) {\n this._conn.send(pres);\n }\n\n var close = $build$2(\"close\", {\n \"xmlns\": Strophe$2.NS.FRAMING\n });\n\n this._conn.xmlOutput(close.tree());\n\n var closeString = Strophe$2.serialize(close);\n\n this._conn.rawOutput(closeString);\n\n try {\n this.socket.send(closeString);\n } catch (e) {\n Strophe$2.warn(\"Couldn't send tag.\");\n }\n }\n\n this._conn._doDisconnect();\n },\n\n /** PrivateFunction: _doDisconnect\n * _Private_ function to disconnect.\n *\n * Just closes the Socket for WebSockets\n */\n _doDisconnect: function _doDisconnect() {\n Strophe$2.debug(\"WebSockets _doDisconnect was called\");\n\n this._closeSocket();\n },\n\n /** PrivateFunction _streamWrap\n * _Private_ helper function to wrap a stanza in a tag.\n * This is used so Strophe can process stanzas from WebSockets like BOSH\n */\n _streamWrap: function _streamWrap(stanza) {\n return \"\" + stanza + '';\n },\n\n /** PrivateFunction: _closeSocket\n * _Private_ function to close the WebSocket.\n *\n * Closes the socket if it is still open and deletes it\n */\n _closeSocket: function _closeSocket() {\n if (this.socket) {\n try {\n this.socket.onclose = null;\n this.socket.onerror = null;\n this.socket.onmessage = null;\n this.socket.close();\n } catch (e) {\n Strophe$2.debug(e.message);\n }\n }\n\n this.socket = null;\n },\n\n /** PrivateFunction: _emptyQueue\n * _Private_ function to check if the message queue is empty.\n *\n * Returns:\n * True, because WebSocket messages are send immediately after queueing.\n */\n _emptyQueue: function _emptyQueue() {\n return true;\n },\n\n /** PrivateFunction: _onClose\n * _Private_ function to handle websockets closing.\n *\n * Nothing to do here for WebSockets\n */\n _onClose: function _onClose(e) {\n if (this._conn.connected && !this._conn.disconnecting) {\n Strophe$2.error(\"Websocket closed unexpectedly\");\n\n this._conn._doDisconnect();\n } else if (e && e.code === 1006 && !this._conn.connected && this.socket) {\n // in case the onError callback was not called (Safari 10 does not\n // call onerror when the initial connection fails) we need to\n // dispatch a CONNFAIL status update to be consistent with the\n // behavior on other browsers.\n Strophe$2.error(\"Websocket closed unexcectedly\");\n\n this._conn._changeConnectStatus(Strophe$2.Status.CONNFAIL, \"The WebSocket connection could not be established or was disconnected.\");\n\n this._conn._doDisconnect();\n } else {\n Strophe$2.debug(\"Websocket closed\");\n }\n },\n\n /** PrivateFunction: _no_auth_received\n *\n * Called on stream start/restart when no stream:features\n * has been received.\n */\n _no_auth_received: function _no_auth_received(callback) {\n Strophe$2.error(\"Server did not offer a supported authentication mechanism\");\n\n this._conn._changeConnectStatus(Strophe$2.Status.CONNFAIL, Strophe$2.ErrorCondition.NO_AUTH_MECH);\n\n if (callback) {\n callback.call(this._conn);\n }\n\n this._conn._doDisconnect();\n },\n\n /** PrivateFunction: _onDisconnectTimeout\n * _Private_ timeout handler for handling non-graceful disconnection.\n *\n * This does nothing for WebSockets\n */\n _onDisconnectTimeout: function _onDisconnectTimeout() {},\n\n /** PrivateFunction: _abortAllRequests\n * _Private_ helper function that makes sure all pending requests are aborted.\n */\n _abortAllRequests: function _abortAllRequests() {},\n\n /** PrivateFunction: _onError\n * _Private_ function to handle websockets errors.\n *\n * Parameters:\n * (Object) error - The websocket error.\n */\n _onError: function _onError(error) {\n Strophe$2.error(\"Websocket error \" + error);\n\n this._conn._changeConnectStatus(Strophe$2.Status.CONNFAIL, \"The WebSocket connection could not be established or was disconnected.\");\n\n this._disconnect();\n },\n\n /** PrivateFunction: _onIdle\n * _Private_ function called by Strophe.Connection._onIdle\n *\n * sends all queued stanzas\n */\n _onIdle: function _onIdle() {\n var data = this._conn._data;\n\n if (data.length > 0 && !this._conn.paused) {\n for (var i = 0; i < data.length; i++) {\n if (data[i] !== null) {\n var stanza = void 0;\n\n if (data[i] === \"restart\") {\n stanza = this._buildStream().tree();\n } else {\n stanza = data[i];\n }\n\n var rawStanza = Strophe$2.serialize(stanza);\n\n this._conn.xmlOutput(stanza);\n\n this._conn.rawOutput(rawStanza);\n\n this.socket.send(rawStanza);\n }\n }\n\n this._conn._data = [];\n }\n },\n\n /** PrivateFunction: _onMessage\n * _Private_ function to handle websockets messages.\n *\n * This function parses each of the messages as if they are full documents.\n * [TODO : We may actually want to use a SAX Push parser].\n *\n * Since all XMPP traffic starts with\n * \n *\n * The first stanza will always fail to be parsed.\n *\n * Additionally, the seconds stanza will always be with\n * the stream NS defined in the previous stanza, so we need to 'force'\n * the inclusion of the NS in this stanza.\n *\n * Parameters:\n * (string) message - The websocket message.\n */\n _onMessage: function _onMessage(message) {\n var elem; // check for closing stream\n\n var close = '';\n\n if (message.data === close) {\n this._conn.rawInput(close);\n\n this._conn.xmlInput(message);\n\n if (!this._conn.disconnecting) {\n this._conn._doDisconnect();\n }\n\n return;\n } else if (message.data.search(\" tag before we close the connection\n\n\n return;\n }\n\n this._conn._dataRecv(elem, message.data);\n },\n\n /** PrivateFunction: _onOpen\n * _Private_ function to handle websockets connection setup.\n *\n * The opening stream tag is sent here.\n */\n _onOpen: function _onOpen() {\n Strophe$2.debug(\"Websocket open\");\n\n var start = this._buildStream();\n\n this._conn.xmlOutput(start.tree());\n\n var startString = Strophe$2.serialize(start);\n\n this._conn.rawOutput(startString);\n\n this.socket.send(startString);\n },\n\n /** PrivateFunction: _reqToData\n * _Private_ function to get a stanza out of a request.\n *\n * WebSockets don't use requests, so the passed argument is just returned.\n *\n * Parameters:\n * (Object) stanza - The stanza.\n *\n * Returns:\n * The stanza that was passed.\n */\n _reqToData: function _reqToData(stanza) {\n return stanza;\n },\n\n /** PrivateFunction: _send\n * _Private_ part of the Connection.send function for WebSocket\n *\n * Just flushes the messages that are in the queue\n */\n _send: function _send() {\n this._conn.flush();\n },\n\n /** PrivateFunction: _sendRestart\n *\n * Send an xmpp:restart stanza.\n */\n _sendRestart: function _sendRestart() {\n clearTimeout(this._conn._idleTimeout);\n\n this._conn._onIdle.bind(this._conn)();\n }\n };\n\n global$1.Strophe = core.Strophe;\n global$1.$build = core.$build;\n global$1.$iq = core.$iq;\n global$1.$msg = core.$msg;\n global$1.$pres = core.$pres;\n\n return core;\n\n}));\n", "/**\n * The events for the conference.\n */\n\n/**\n * Event indicates that the current conference audio input switched between audio\n * input states,i.e. with or without audio input.\n */\nexport const AUDIO_INPUT_STATE_CHANGE = 'conference.audio_input_state_changed';\n\n/**\n * Indicates that authentication status changed.\n */\nexport const AUTH_STATUS_CHANGED = 'conference.auth_status_changed';\n\n/**\n * A participant avatar has changed.\n */\nexport const AVATAR_CHANGED = 'conference.avatarChanged';\n\n/**\n * Fired just before the statistics module is disposed and it's the last chance\n * to submit some logs to the statistics service (ex. CallStats if enabled),\n * before it's disconnected.\n */\nexport const BEFORE_STATISTICS_DISPOSED = 'conference.beforeStatisticsDisposed';\n\n/**\n * Indicates that an error occured.\n */\nexport const CONFERENCE_ERROR = 'conference.error';\n\n/**\n * Indicates that conference failed.\n */\nexport const CONFERENCE_FAILED = 'conference.failed';\n\n/**\n * Indicates that conference has been joined. The event does NOT provide any\n * parameters to its listeners.\n */\nexport const CONFERENCE_JOINED = 'conference.joined';\n\n/**\n * Indicates that conference has been left.\n */\nexport const CONFERENCE_LEFT = 'conference.left';\n\n/**\n * Indicates that the connection to the conference has been established\n * XXX This is currently fired whenVthe *ICE* connection enters 'connected'\n * state for the first time.\n */\nexport const CONNECTION_ESTABLISHED = 'conference.connectionEstablished';\n\n/**\n * Indicates that the connection to the conference has been interrupted for some\n * reason.\n * XXX This is currently fired when the *ICE* connection is interrupted.\n */\nexport const CONNECTION_INTERRUPTED = 'conference.connectionInterrupted';\n\n/**\n * Indicates that the connection to the conference has been restored.\n * XXX This is currently fired when the *ICE* connection is restored.\n */\nexport const CONNECTION_RESTORED = 'conference.connectionRestored';\n\n/**\n * A connection to the video bridge's data channel has been established.\n */\nexport const DATA_CHANNEL_OPENED = 'conference.dataChannelOpened';\n\n/**\n * A user has changed it display name\n */\nexport const DISPLAY_NAME_CHANGED = 'conference.displayNameChanged';\n\n/**\n * The dominant speaker was changed.\n */\nexport const DOMINANT_SPEAKER_CHANGED = 'conference.dominantSpeaker';\n\n/**\n * UTC conference timestamp when first participant joined.\n */\nexport const CONFERENCE_CREATED_TIMESTAMP = 'conference.createdTimestamp';\n\n/**\n * Indicates that DTMF support changed.\n */\nexport const DTMF_SUPPORT_CHANGED = 'conference.dtmfSupportChanged';\n\n/**\n * Indicates that a message from another participant is received on data\n * channel.\n */\nexport const ENDPOINT_MESSAGE_RECEIVED = 'conference.endpoint_message_received';\n\n/**\n * NOTE This is lib-jitsi-meet internal event and can be removed at any time !\n *\n * Event emitted when conference transits, between one to one and multiparty JVB\n * conference. If the conference switches to P2P it's neither one to one nor\n * a multiparty JVB conference, but P2P (the status argument of this event will\n * be false).\n *\n * The first argument is a boolean which carries the previous value and\n * the seconds argument is a boolean with the new status. The event is emitted\n * only if the previous and the new values are different.\n *\n * @type {string}\n */\nexport const JVB121_STATUS = 'conference.jvb121Status';\n\n/**\n * You are kicked from the conference.\n * @param {JitsiParticipant} the participant that initiated the kick.\n */\nexport const KICKED = 'conference.kicked';\n\n/**\n * Participant was kicked from the conference.\n * @param {JitsiParticipant} the participant that initiated the kick.\n * @param {JitsiParticipant} the participant that was kicked.\n */\nexport const PARTICIPANT_KICKED = 'conference.participant_kicked';\n\n/**\n * The Last N set is changed.\n *\n * @param {Array|null} leavingEndpointIds the ids of all the endpoints\n * which are leaving Last N\n * @param {Array|null} enteringEndpointIds the ids of all the endpoints\n * which are entering Last N\n */\nexport const LAST_N_ENDPOINTS_CHANGED = 'conference.lastNEndpointsChanged';\n\n/**\n * Indicates that the room has been locked or unlocked.\n */\nexport const LOCK_STATE_CHANGED = 'conference.lock_state_changed';\n\n/**\n * Indicates that the region of the media server (jitsi-videobridge) that we\n * are connected to changed (or was initially set).\n * @type {string} the region.\n */\nexport const SERVER_REGION_CHANGED = 'conference.server_region_changed';\n\n/**\n * New text message was received.\n */\nexport const MESSAGE_RECEIVED = 'conference.messageReceived';\n\n/**\n * Event indicates that the current selected input device has no signal\n */\nexport const NO_AUDIO_INPUT = 'conference.no_audio_input';\n\n/**\n * Event indicates that the current microphone used by the conference is noisy.\n */\nexport const NOISY_MIC = 'conference.noisy_mic';\n\n/**\n * New private text message was received.\n */\nexport const PRIVATE_MESSAGE_RECEIVED = 'conference.privateMessageReceived';\n\n/**\n * Event fired when JVB sends notification about interrupted/restored user's\n * ICE connection status or we detect local problem with the video track.\n * First argument is the ID of the participant and\n * the seconds is a string indicating if the connection is currently\n * - active - the connection is active\n * - inactive - the connection is inactive, was intentionally interrupted by\n * the bridge\n * - interrupted - a network problem occurred\n * - restoring - the connection was inactive and is restoring now\n *\n * The current status value can be obtained by calling\n * JitsiParticipant.getConnectionStatus().\n */\nexport const PARTICIPANT_CONN_STATUS_CHANGED\n = 'conference.participant_conn_status_changed';\n\n/**\n * Indicates that the features of the participant has been changed.\n */\nexport const PARTCIPANT_FEATURES_CHANGED\n = 'conference.partcipant_features_changed';\n\n/**\n * Indicates that a the value of a specific property of a specific participant\n * has changed.\n */\nexport const PARTICIPANT_PROPERTY_CHANGED\n = 'conference.participant_property_changed';\n\n/**\n * Indicates that the conference has switched between JVB and P2P connections.\n * The first argument of this event is a boolean which when set to\n * true means that the conference is running on the P2P connection.\n */\nexport const P2P_STATUS = 'conference.p2pStatus';\n\n/**\n * Indicates that phone number changed.\n */\nexport const PHONE_NUMBER_CHANGED = 'conference.phoneNumberChanged';\n\n/**\n * The conference properties changed.\n * @type {string}\n */\nexport const PROPERTIES_CHANGED = 'conference.propertiesChanged';\n\n/**\n * Indicates that recording state changed.\n */\nexport const RECORDER_STATE_CHANGED = 'conference.recorderStateChanged';\n\n/**\n * Indicates that video SIP GW state changed.\n * @param {VideoSIPGWConstants} status.\n */\nexport const VIDEO_SIP_GW_AVAILABILITY_CHANGED\n = 'conference.videoSIPGWAvailabilityChanged';\n\n/**\n * Indicates that video SIP GW Session state changed.\n * @param {options} event - {\n * {string} address,\n * {VideoSIPGWConstants} oldState,\n * {VideoSIPGWConstants} newState,\n * {string} displayName}\n * }.\n */\nexport const VIDEO_SIP_GW_SESSION_STATE_CHANGED\n = 'conference.videoSIPGWSessionStateChanged';\n\n/**\n * Indicates that start muted settings changed.\n */\nexport const START_MUTED_POLICY_CHANGED\n = 'conference.start_muted_policy_changed';\n\n/**\n * Indicates that the local user has started muted.\n */\nexport const STARTED_MUTED = 'conference.started_muted';\n\n/**\n * Indicates that subject of the conference has changed.\n */\nexport const SUBJECT_CHANGED = 'conference.subjectChanged';\n\n/**\n * Indicates that DTMF support changed.\n */\nexport const SUSPEND_DETECTED = 'conference.suspendDetected';\n\n/**\n * Event indicates that local user is talking while he muted himself\n */\nexport const TALK_WHILE_MUTED = 'conference.talk_while_muted';\n\n/**\n * A new media track was added to the conference. The event provides the\n * following parameters to its listeners:\n *\n * @param {JitsiTrack} track the added JitsiTrack\n */\nexport const TRACK_ADDED = 'conference.trackAdded';\n\n/**\n * Audio levels of a media track ( attached to the conference) was changed.\n */\nexport const TRACK_AUDIO_LEVEL_CHANGED = 'conference.audioLevelsChanged';\n\n/**\n * A media track ( attached to the conference) mute status was changed.\n * @param {JitsiParticipant|null} the participant that initiated the mute\n * if it is a remote mute.\n */\nexport const TRACK_MUTE_CHANGED = 'conference.trackMuteChanged';\n\n/**\n * The media track was removed from the conference. The event provides the\n * following parameters to its listeners:\n *\n * @param {JitsiTrack} track the removed JitsiTrack\n */\nexport const TRACK_REMOVED = 'conference.trackRemoved';\n\n/**\n * Notifies for transcription status changes. The event provides the\n * following parameters to its listeners:\n *\n * @param {String} status - The new status.\n */\nexport const TRANSCRIPTION_STATUS_CHANGED\n = 'conference.transcriptionStatusChanged';\n\n\n/**\n * A new user joined the conference.\n */\nexport const USER_JOINED = 'conference.userJoined';\n\n/**\n * A user has left the conference.\n */\nexport const USER_LEFT = 'conference.userLeft';\n\n/**\n * User role changed.\n */\nexport const USER_ROLE_CHANGED = 'conference.roleChanged';\n\n/**\n * User status changed.\n */\nexport const USER_STATUS_CHANGED = 'conference.statusChanged';\n\n/**\n * Event indicates that the bot participant type changed.\n */\nexport const BOT_TYPE_CHANGED = 'conference.bot_type_changed';\n", "import BrowserCapabilities from './BrowserCapabilities';\n\nexport default new BrowserCapabilities();\n", "/* Copyright @ 2015-present 8x8, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nvar Logger = require(\"./Logger\");\nvar LogCollector = require(\"./LogCollector\");\n\n/**\n * Definition of the log method\n * @name log_method\n * @function\n * @param {...*} log_args the arguments to be logged\n */\n/**\n * The logger's transport type definition.\n *\n * @typedef {object} LoggerTransport\n *\n * @property {log_method} trace method called to log on {@link Logger.levels.TRACE} logging level\n * @property {log_method} debug method called to log on {@link Logger.levels.DEBUG} logging level\n * @property {log_method} info method called to log on {@link Logger.levels.INFO} logging level\n * @property {log_method} log method called to log on {@link Logger.levels.LOG} logging level\n * @property {log_method} warn method called to log on {@link Logger.levels.WARN} logging level\n * @property {log_method} error method called to log on {@link Logger.levels.ERROR} logging level\n */\n\n/**\n * Map with the created loggers with ID.\n */\nvar idLoggers = {};\n\n/**\n * Array with the loggers without id.\n */\nvar loggers = [];\n\n/**\n * Log level for the lbrary.\n */\nvar curLevel = Logger.levels.TRACE;\n\n\nmodule.exports = {\n /**\n * Adds given {@link LoggerTransport} instance to the list of global\n * transports which means that it'll be used by all {@link Logger}s\n * @param {LoggerTransport} transport\n */\n addGlobalTransport: function(transport) {\n Logger.addGlobalTransport(transport);\n },\n /**\n * Removes given {@link LoggerTransport} instance from the list of global\n * transports\n * @param {LoggerTransport} transport\n */\n removeGlobalTransport: function(transport) {\n Logger.removeGlobalTransport(transport);\n },\n /**\n * Sets global options which will be used by all loggers. Changing these\n * works even after other loggers are created.\n */\n setGlobalOptions: function(options) {\n Logger.setGlobalOptions(options);\n },\n /**\n * Creates new logger.\n * @arguments the same as Logger constructor\n */\n getLogger: function(id, transports, options) {\n var logger = new Logger(curLevel, id, transports, options);\n if(id) {\n idLoggers[id] = idLoggers[id] || [];\n idLoggers[id].push(logger);\n } else {\n loggers.push(logger);\n }\n return logger;\n },\n /**\n * Changes the log level for the existing loggers by id.\n * @param level the new log level.\n * @param id if specified the level will be changed only for loggers with the\n * same id. Otherwise the operation will affect all loggers that don't\n * have id.\n */\n setLogLevelById: function(level, id) {\n var l = id? (idLoggers[id] || []) : loggers;\n for(var i = 0; i < l.length; i++) {\n l[i].setLevel(level);\n }\n },\n /**\n * Changes the log level for all existing loggers.\n * @param level the new log level.\n */\n setLogLevel: function (level) {\n curLevel = level;\n var i = 0;\n for(; i < loggers.length; i++) {\n loggers[i].setLevel(level);\n }\n\n for(var id in idLoggers) {\n var l = idLoggers[id] || [];\n for(i = 0; i < l.length; i++) {\n l[i].setLevel(level);\n }\n }\n },\n /**\n * The supported log levels.\n */\n levels: Logger.levels,\n /**\n * Exports the LogCollector.\n */\n LogCollector: LogCollector\n};\n", "import EventEmitter from 'events';\n\nimport { FEEDBACK } from '../../service/statistics/AnalyticsEvents';\nimport analytics from './AnalyticsAdapter';\nimport CallStats from './CallStats';\nimport LocalStats from './LocalStatsCollector';\nimport RTPStats from './RTPStatsCollector';\n\nimport browser from '../browser';\nimport ScriptUtil from '../util/ScriptUtil';\nimport JitsiTrackError from '../../JitsiTrackError';\nimport * as StatisticsEvents from '../../service/statistics/Events';\n\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\n\n/**\n * Stores all active {@link Statistics} instances.\n * @type {Set}\n */\nlet _instances;\n\n/**\n * True if callstats API is loaded\n */\nlet isCallstatsLoaded = false;\n\n/**\n * Since callstats.io is a third party, we cannot guarantee the quality of their\n * service. More specifically, their server may take noticeably long time to\n * respond. Consequently, it is in our best interest (in the sense that the\n * intergration of callstats.io is pretty important to us but not enough to\n * allow it to prevent people from joining a conference) to (1) start\n * downloading their API as soon as possible and (2) do the downloading\n * asynchronously.\n *\n * @param {StatisticsOptions} options - Options to use for downloading and\n * initializing callstats backend.\n */\nfunction loadCallStatsAPI(options) {\n if (!isCallstatsLoaded) {\n ScriptUtil.loadScript(\n options.customScriptUrl\n || 'https://api.callstats.io/static/callstats-ws.min.js',\n /* async */ true,\n /* prepend */ true,\n /* relativeURL */ undefined,\n /* loadCallback */ () => _initCallStatsBackend(options)\n );\n isCallstatsLoaded = true;\n }\n}\n\n/**\n * Initializes Callstats backend.\n *\n * @param {StatisticsOptions} options - The options to use for initializing\n * callstats backend.\n * @private\n */\nfunction _initCallStatsBackend(options) {\n if (CallStats.isBackendInitialized()) {\n return;\n }\n\n if (!CallStats.initBackend({\n callStatsID: options.callStatsID,\n callStatsSecret: options.callStatsSecret,\n userName: options.userName,\n aliasName: options.aliasName,\n applicationName: options.applicationName,\n getWiFiStatsMethod: options.getWiFiStatsMethod,\n confID: options.confID\n })) {\n logger.error('CallStats Backend initialization failed bad');\n }\n}\n\n/**\n * callstats strips any additional fields from Error except for \"name\", \"stack\",\n * \"message\" and \"constraintName\". So we need to bundle additional information\n * from JitsiTrackError into error passed to callstats to preserve valuable\n * information about error.\n * @param {JitsiTrackError} error\n */\nfunction formatJitsiTrackErrorForCallStats(error) {\n const err = new Error();\n\n // Just copy original stack from error\n err.stack = error.stack;\n\n // Combine name from error's name plus (possibly) name of original GUM error\n err.name = (error.name || 'Unknown error') + (error.gum && error.gum.error\n && error.gum.error.name ? ` - ${error.gum.error.name}` : '');\n\n // Put all constraints into this field. For constraint failed errors we will\n // still know which exactly constraint failed as it will be a part of\n // message.\n err.constraintName = error.gum && error.gum.constraints\n ? JSON.stringify(error.gum.constraints) : '';\n\n // Just copy error's message.\n err.message = error.message;\n\n return err;\n}\n\n/**\n * Init statistic options\n * @param options\n */\nStatistics.init = function(options) {\n Statistics.audioLevelsEnabled = !options.disableAudioLevels;\n if (typeof options.pcStatsInterval === 'number') {\n Statistics.pcStatsInterval = options.pcStatsInterval;\n }\n\n if (typeof options.audioLevelsInterval === 'number') {\n Statistics.audioLevelsInterval = options.audioLevelsInterval;\n }\n\n Statistics.disableThirdPartyRequests = options.disableThirdPartyRequests;\n};\n\n/**\n * The options to configure Statistics.\n * @typedef {Object} StatisticsOptions\n * @property {string} applicationName - The application name to pass to\n * callstats.\n * @property {string} aliasName - The alias name to use when initializing callstats.\n * @property {string} userName - The user name to use when initializing callstats.\n * @property {string} callStatsConfIDNamespace - A namespace to prepend the\n * callstats conference ID with.\n * @property {string} confID - The callstats conference ID to use.\n * @property {string} callStatsID - Callstats credentials - the id.\n * @property {string} callStatsSecret - Callstats credentials - the secret.\n * @property {string} customScriptUrl - A custom lib url to use when downloading\n * callstats library.\n * @property {string} roomName - The room name we are currently in.\n */\n/**\n *\n * @param xmpp\n * @param {StatisticsOptions} options - The options to use creating the\n * Statistics.\n */\nexport default function Statistics(xmpp, options) {\n /**\n * {@link RTPStats} mapped by {@link TraceablePeerConnection.id} which\n * collect RTP statistics for each peerconnection.\n * @type {Map}\n */\n this.callsStatsInstances = new Map();\n\n Statistics.instances.add(this);\n}\nStatistics.audioLevelsEnabled = false;\nStatistics.audioLevelsInterval = 200;\nStatistics.pcStatsInterval = 10000;\nStatistics.disableThirdPartyRequests = false;\nStatistics.analytics = analytics;\n\nObject.defineProperty(Statistics, 'instances', {\n /**\n * Returns the Set holding all active {@link Statistics} instances. Lazily\n * initializes the Set to allow any Set polyfills to be applied.\n * @type {Set}\n */\n get() {\n if (!_instances) {\n _instances = new Set();\n }\n\n return _instances;\n }\n});\n\n/**\n * Starts collecting RTP stats for given peerconnection.\n * @param {TraceablePeerConnection} peerconnection\n */\nStatistics.prototype.startRemoteStats = function(peerconnection) {\n this.stopRemoteStats(peerconnection);\n\n try {\n const rtpStats\n = new RTPStats(\n peerconnection,\n Statistics.audioLevelsInterval,\n Statistics.pcStatsInterval,\n this.eventEmitter);\n\n rtpStats.start(Statistics.audioLevelsEnabled);\n this.rtpStatsMap.set(peerconnection.id, rtpStats);\n } catch (e) {\n logger.error(`Failed to start collecting remote statistics: ${e}`);\n }\n};\n\nStatistics.localStats = [];\n\nStatistics.startLocalStats = function(stream, callback) {\n if (!Statistics.audioLevelsEnabled) {\n return;\n }\n const localStats = new LocalStats(stream, Statistics.audioLevelsInterval,\n callback);\n\n this.localStats.push(localStats);\n localStats.start();\n};\n\nStatistics.prototype.addAudioLevelListener = function(listener) {\n if (!Statistics.audioLevelsEnabled) {\n return;\n }\n this.eventEmitter.on(StatisticsEvents.AUDIO_LEVEL, listener);\n};\n\nStatistics.prototype.removeAudioLevelListener = function(listener) {\n if (!Statistics.audioLevelsEnabled) {\n return;\n }\n this.eventEmitter.removeListener(StatisticsEvents.AUDIO_LEVEL, listener);\n};\n\nStatistics.prototype.addBeforeDisposedListener = function(listener) {\n this.eventEmitter.on(StatisticsEvents.BEFORE_DISPOSED, listener);\n};\n\nStatistics.prototype.removeBeforeDisposedListener = function(listener) {\n this.eventEmitter.removeListener(\n StatisticsEvents.BEFORE_DISPOSED, listener);\n};\n\nStatistics.prototype.addConnectionStatsListener = function(listener) {\n this.eventEmitter.on(StatisticsEvents.CONNECTION_STATS, listener);\n};\n\nStatistics.prototype.removeConnectionStatsListener = function(listener) {\n this.eventEmitter.removeListener(\n StatisticsEvents.CONNECTION_STATS,\n listener);\n};\n\nStatistics.prototype.addByteSentStatsListener = function(listener) {\n this.eventEmitter.on(StatisticsEvents.BYTE_SENT_STATS, listener);\n};\n\nStatistics.prototype.removeByteSentStatsListener = function(listener) {\n this.eventEmitter.removeListener(StatisticsEvents.BYTE_SENT_STATS,\n listener);\n};\n\nStatistics.prototype.dispose = function() {\n try {\n // NOTE Before reading this please see the comment in stopCallStats...\n //\n // Here we prevent from emitting the event twice in case it will be\n // triggered from stopCallStats.\n // If the event is triggered from here it means that the logs will not\n // be submitted anyway (because there is no CallStats instance), but\n // we're doing that for the sake of some kind of consistency.\n if (!this.callsStatsInstances.size) {\n this.eventEmitter.emit(StatisticsEvents.BEFORE_DISPOSED);\n }\n for (const callStats of this.callsStatsInstances.values()) {\n this.stopCallStats(callStats.tpc);\n }\n for (const tpcId of this.rtpStatsMap.keys()) {\n this._stopRemoteStats(tpcId);\n }\n if (this.eventEmitter) {\n this.eventEmitter.removeAllListeners();\n }\n } finally {\n Statistics.instances.delete(this);\n }\n};\n\nStatistics.stopLocalStats = function(stream) {\n if (!Statistics.audioLevelsEnabled) {\n return;\n }\n\n for (let i = 0; i < Statistics.localStats.length; i++) {\n if (Statistics.localStats[i].stream === stream) {\n const localStats = Statistics.localStats.splice(i, 1);\n\n localStats[0].stop();\n break;\n }\n }\n};\n\n/**\n * Stops remote RTP stats for given peerconnection ID.\n * @param {string} tpcId {@link TraceablePeerConnection.id}\n * @private\n */\nStatistics.prototype._stopRemoteStats = function(tpcId) {\n const rtpStats = this.rtpStatsMap.get(tpcId);\n\n if (rtpStats) {\n rtpStats.stop();\n this.rtpStatsMap.delete(tpcId);\n }\n};\n\n/**\n * Stops collecting RTP stats for given peerconnection\n * @param {TraceablePeerConnection} tpc\n */\nStatistics.prototype.stopRemoteStats = function(tpc) {\n this._stopRemoteStats(tpc.id);\n};\n\n// CALSTATS METHODS\n\n/**\n * Initializes the callstats.io API.\n * @param {TraceablePeerConnection} tpc the {@link TraceablePeerConnection}\n * instance for which CalStats will be started.\n * @param {string} remoteUserID\n */\nStatistics.prototype.startCallStats = function(tpc, remoteUserID) {\n if (!this.callStatsIntegrationEnabled) {\n return;\n } else if (this.callsStatsInstances.has(tpc.id)) {\n logger.error('CallStats instance for ${tpc} exists already');\n\n return;\n }\n\n logger.info(`Starting CallStats for ${tpc}...`);\n\n const newInstance\n = new CallStats(\n tpc,\n {\n confID: this._getCallStatsConfID(),\n remoteUserID\n });\n\n this.callsStatsInstances.set(tpc.id, newInstance);\n};\n\n/**\n * Obtains the list of *all* {@link CallStats} instances collected from every\n * valid {@link Statistics} instance.\n * @return {Set}\n * @private\n */\nStatistics._getAllCallStatsInstances = function() {\n const csInstances = new Set();\n\n for (const statistics of Statistics.instances) {\n for (const cs of statistics.callsStatsInstances.values()) {\n csInstances.add(cs);\n }\n }\n\n return csInstances;\n};\n\n/**\n * Constructs the CallStats conference ID based on the options currently\n * configured in this instance.\n * @return {string}\n * @private\n */\nStatistics.prototype._getCallStatsConfID = function() {\n // The conference ID is case sensitive!!!\n return this.options.callStatsConfIDNamespace\n ? `${this.options.callStatsConfIDNamespace}/${this.options.roomName}`\n : this.options.roomName;\n};\n\n/**\n * Removes the callstats.io instances.\n */\nStatistics.prototype.stopCallStats = function(tpc) {\n const callStatsInstance = this.callsStatsInstances.get(tpc.id);\n\n if (callStatsInstance) {\n // FIXME the original purpose of adding BEFORE_DISPOSED event was to be\n // able to submit the last log batch from jitsi-meet to CallStats. After\n // recent changes we dispose the CallStats earlier\n // (before Statistics.dispose), so we need to emit this event here to\n // give this last chance for final log batch submission.\n //\n // Eventually there should be a separate module called \"log storage\"\n // which should emit proper events when it's underlying\n // CallStats instance is going away.\n if (this.callsStatsInstances.size === 1) {\n this.eventEmitter.emit(StatisticsEvents.BEFORE_DISPOSED);\n }\n this.callsStatsInstances.delete(tpc.id);\n\n // The fabric needs to be terminated when being stopped\n callStatsInstance.sendTerminateEvent();\n }\n};\n\n/**\n * Returns true if the callstats integration is enabled, otherwise returns\n * false.\n *\n * @returns true if the callstats integration is enabled, otherwise returns\n * false.\n */\nStatistics.prototype.isCallstatsEnabled = function() {\n return this.callStatsIntegrationEnabled;\n};\n\n/**\n * Logs either resume or hold event for the given peer connection.\n * @param {TraceablePeerConnection} tpc the connection for which event will be\n * reported\n * @param {boolean} isResume true for resume or false for hold\n */\nStatistics.prototype.sendConnectionResumeOrHoldEvent = function(tpc, isResume) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendResumeOrHoldEvent(isResume);\n }\n};\n\n/**\n * Notifies CallStats and analytics (if present) for ice connection failed\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n */\nStatistics.prototype.sendIceConnectionFailedEvent = function(tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendIceConnectionFailedEvent();\n }\n};\n\n/**\n * Notifies CallStats for mute events\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n * @param {boolean} muted true for muted and false for not muted\n * @param {String} type \"audio\"/\"video\"\n */\nStatistics.prototype.sendMuteEvent = function(tpc, muted, type) {\n const instance = tpc && this.callsStatsInstances.get(tpc.id);\n\n CallStats.sendMuteEvent(muted, type, instance);\n};\n\n/**\n * Notifies CallStats for screen sharing events\n * @param start {boolean} true for starting screen sharing and\n * false for not stopping\n * @param {string|null} ssrc - optional ssrc value, used only when\n * starting screen sharing.\n */\nStatistics.prototype.sendScreenSharingEvent\n = function(start, ssrc) {\n for (const cs of this.callsStatsInstances.values()) {\n cs.sendScreenSharingEvent(start, ssrc);\n }\n };\n\n/**\n * Notifies the statistics module that we are now the dominant speaker of the\n * conference.\n * @param {String} roomJid - The room jid where the speaker event occurred.\n */\nStatistics.prototype.sendDominantSpeakerEvent = function(roomJid) {\n for (const cs of this.callsStatsInstances.values()) {\n cs.sendDominantSpeakerEvent();\n }\n\n // xmpp send dominant speaker event\n this.xmpp.sendDominantSpeakerEvent(roomJid);\n};\n\n/**\n * Notifies about active device.\n * @param {{deviceList: {String:String}}} devicesData - list of devices with\n * their data\n */\nStatistics.sendActiveDeviceListEvent = function(devicesData) {\n const globalSet = Statistics._getAllCallStatsInstances();\n\n if (globalSet.size) {\n for (const cs of globalSet) {\n CallStats.sendActiveDeviceListEvent(devicesData, cs);\n }\n } else {\n CallStats.sendActiveDeviceListEvent(devicesData, null);\n }\n};\n\n/* eslint-disable max-params */\n\n/**\n * Lets the underlying statistics module know where is given SSRC rendered by\n * providing renderer tag ID.\n * @param {TraceablePeerConnection} tpc the connection to which the stream\n * belongs to\n * @param {number} ssrc the SSRC of the stream\n * @param {boolean} isLocal\n * @param {string} userId\n * @param {string} usageLabel meaningful usage label of this stream like\n * 'microphone', 'camera' or 'screen'.\n * @param {string} containerId the id of media 'audio' or 'video' tag which\n * renders the stream.\n */\nStatistics.prototype.associateStreamWithVideoTag = function(\n tpc,\n ssrc,\n isLocal,\n userId,\n usageLabel,\n containerId) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.associateStreamWithVideoTag(\n ssrc,\n isLocal,\n userId,\n usageLabel,\n containerId);\n }\n};\n\n/* eslint-enable max-params */\n\n/**\n * Notifies CallStats that getUserMedia failed.\n *\n * @param {Error} e error to send\n */\nStatistics.sendGetUserMediaFailed = function(e) {\n const error\n = e instanceof JitsiTrackError\n ? formatJitsiTrackErrorForCallStats(e) : e;\n const globalSet = Statistics._getAllCallStatsInstances();\n\n if (globalSet.size) {\n for (const cs of globalSet) {\n CallStats.sendGetUserMediaFailed(error, cs);\n }\n } else {\n CallStats.sendGetUserMediaFailed(error, null);\n }\n};\n\n/**\n * Notifies CallStats that peer connection failed to create offer.\n *\n * @param {Error} e error to send\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n */\nStatistics.prototype.sendCreateOfferFailed = function(e, tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendCreateOfferFailed(e);\n }\n};\n\n/**\n * Notifies CallStats that peer connection failed to create answer.\n *\n * @param {Error} e error to send\n * @param {TraceablePeerConnection} tpc connection on which failure occured.\n */\nStatistics.prototype.sendCreateAnswerFailed = function(e, tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendCreateAnswerFailed(e);\n }\n};\n\n/**\n * Notifies CallStats that peer connection failed to set local description.\n *\n * @param {Error} e error to send\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n */\nStatistics.prototype.sendSetLocalDescFailed = function(e, tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendSetLocalDescFailed(e);\n }\n};\n\n/**\n * Notifies CallStats that peer connection failed to set remote description.\n *\n * @param {Error} e error to send\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n */\nStatistics.prototype.sendSetRemoteDescFailed = function(e, tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendSetRemoteDescFailed(e);\n }\n};\n\n/**\n * Notifies CallStats that peer connection failed to add ICE candidate.\n *\n * @param {Error} e error to send\n * @param {TraceablePeerConnection} tpc connection on which failure occurred.\n */\nStatistics.prototype.sendAddIceCandidateFailed = function(e, tpc) {\n const instance = this.callsStatsInstances.get(tpc.id);\n\n if (instance) {\n instance.sendAddIceCandidateFailed(e);\n }\n};\n\n/**\n * Adds to CallStats an application log.\n *\n * @param {String} m a log message to send or an {Error} object to be reported\n */\nStatistics.sendLog = function(m) {\n const globalSubSet = new Set();\n\n // FIXME we don't want to duplicate logs over P2P instance, but\n // here we should go over instances and call this method for each\n // unique conference ID rather than selecting the first one.\n // We don't have such use case though, so leaving as is for now.\n for (const stats of Statistics.instances) {\n if (stats.callStatsApplicationLogsDisabled) {\n return;\n }\n\n if (stats.callsStatsInstances.size) {\n globalSubSet.add(stats.callsStatsInstances.values().next().value);\n }\n }\n\n if (globalSubSet.size) {\n for (const csPerStats of globalSubSet) {\n CallStats.sendApplicationLog(m, csPerStats);\n }\n } else {\n CallStats.sendApplicationLog(m, null);\n }\n};\n\n/**\n * Sends the given feedback through CallStats.\n *\n * @param overall an integer between 1 and 5 indicating the user's rating.\n * @param comment the comment from the user.\n * @returns {Promise} Resolves when callstats feedback has been submitted\n * successfully.\n */\nStatistics.prototype.sendFeedback = function(overall, comment) {\n // Statistics.analytics.sendEvent is currently fire and forget, without\n // confirmation of successful send.\n Statistics.analytics.sendEvent(\n FEEDBACK,\n {\n rating: overall,\n comment\n });\n\n return CallStats.sendFeedback(this._getCallStatsConfID(), overall, comment);\n};\n\nStatistics.LOCAL_JID = require('../../service/statistics/constants').LOCAL_JID;\n\n/**\n * Reports global error to CallStats.\n *\n * @param {Error} error\n */\nStatistics.reportGlobalError = function(error) {\n if (error instanceof JitsiTrackError && error.gum) {\n Statistics.sendGetUserMediaFailed(error);\n } else {\n Statistics.sendLog(error);\n }\n};\n\n/**\n * Sends event to analytics and logs a message to the logger/console. Console\n * messages might also be logged to callstats automatically.\n *\n * @param {string | Object} event the event name, or an object which\n * represents the entire event.\n * @param {Object} properties properties to attach to the event (if an event\n * name as opposed to an event object is provided).\n */\nStatistics.sendAnalyticsAndLog = function(event, properties = {}) {\n if (!event) {\n logger.warn('No event or event name given.');\n\n return;\n }\n\n let eventToLog;\n\n // Also support an API with a single object as an event.\n if (typeof event === 'object') {\n eventToLog = event;\n } else {\n eventToLog = {\n name: event,\n properties\n };\n }\n\n logger.log(JSON.stringify(eventToLog));\n\n // We do this last, because it may modify the object which is passed.\n this.analytics.sendEvent(event, properties);\n};\n\n/**\n * Sends event to analytics.\n *\n * @param {string | Object} eventName the event name, or an object which\n * represents the entire event.\n * @param {Object} properties properties to attach to the event\n */\nStatistics.sendAnalytics = function(eventName, properties = {}) {\n this.analytics.sendEvent(eventName, properties);\n};\n", "import { getLogger } from 'jitsi-meet-logger';\nconst logger = getLogger(__filename);\n\nimport RandomUtil from '../util/RandomUtil';\nimport browser from '../browser';\n\nconst SDPUtil = {\n filterSpecialChars(text) {\n // XXX Neither one of the falsy values (e.g. null, undefined, false,\n // \"\", etc.) \"contain\" special chars.\n // eslint-disable-next-line no-useless-escape\n return text ? text.replace(/[\\\\\\/\\{,\\}\\+]/g, '') : text;\n },\n iceparams(mediadesc, sessiondesc) {\n let data = null;\n let pwd, ufrag;\n\n if ((ufrag = SDPUtil.findLine(mediadesc, 'a=ice-ufrag:', sessiondesc))\n && (pwd\n = SDPUtil.findLine(\n mediadesc,\n 'a=ice-pwd:',\n sessiondesc))) {\n data = {\n ufrag: SDPUtil.parseICEUfrag(ufrag),\n pwd: SDPUtil.parseICEPwd(pwd)\n };\n }\n\n return data;\n },\n parseICEUfrag(line) {\n return line.substring(12);\n },\n buildICEUfrag(frag) {\n return `a=ice-ufrag:${frag}`;\n },\n parseICEPwd(line) {\n return line.substring(10);\n },\n buildICEPwd(pwd) {\n return `a=ice-pwd:${pwd}`;\n },\n parseMID(line) {\n return line.substring(6);\n },\n parseMLine(line) {\n const data = {};\n const parts = line.substring(2).split(' ');\n\n data.media = parts.shift();\n data.port = parts.shift();\n data.proto = parts.shift();\n if (parts[parts.length - 1] === '') { // trailing whitespace\n parts.pop();\n }\n data.fmt = parts;\n\n return data;\n },\n buildMLine(mline) {\n return (\n `m=${mline.media} ${mline.port} ${mline.proto} ${\n mline.fmt.join(' ')}`);\n },\n parseRTPMap(line) {\n const data = {};\n let parts = line.substring(9).split(' ');\n\n data.id = parts.shift();\n parts = parts[0].split('/');\n data.name = parts.shift();\n data.clockrate = parts.shift();\n data.channels = parts.length ? parts.shift() : '1';\n\n return data;\n },\n\n /**\n * Parses SDP line \"a=sctpmap:...\" and extracts SCTP port from it.\n * @param line eg. \"a=sctpmap:5000 webrtc-datachannel\"\n * @returns [SCTP port number, protocol, streams]\n */\n parseSCTPMap(line) {\n const parts = line.substring(10).split(' ');\n const sctpPort = parts[0];\n const protocol = parts[1];\n\n // Stream count is optional\n const streamCount = parts.length > 2 ? parts[2] : null;\n\n\n return [ sctpPort, protocol, streamCount ];// SCTP port\n },\n buildRTPMap(el) {\n let line\n = `a=rtpmap:${el.getAttribute('id')} ${el.getAttribute('name')}/${\n el.getAttribute('clockrate')}`;\n\n if (el.getAttribute('channels')\n && el.getAttribute('channels') !== '1') {\n line += `/${el.getAttribute('channels')}`;\n }\n\n return line;\n },\n parseCrypto(line) {\n const data = {};\n const parts = line.substring(9).split(' ');\n\n data.tag = parts.shift();\n data['crypto-suite'] = parts.shift();\n data['key-params'] = parts.shift();\n if (parts.length) {\n data['session-params'] = parts.join(' ');\n }\n\n return data;\n },\n parseFingerprint(line) { // RFC 4572\n const data = {};\n const parts = line.substring(14).split(' ');\n\n data.hash = parts.shift();\n data.fingerprint = parts.shift();\n\n // TODO assert that fingerprint satisfies 2UHEX *(\":\" 2UHEX) ?\n return data;\n },\n parseFmtp(line) {\n const data = [];\n let parts = line.split(' ');\n\n parts.shift();\n parts = parts.join(' ').split(';');\n for (let i = 0; i < parts.length; i++) {\n let key = parts[i].split('=')[0];\n\n while (key.length && key[0] === ' ') {\n key = key.substring(1);\n }\n const value = parts[i].split('=')[1];\n\n if (key && value) {\n data.push({ name: key,\n value });\n } else if (key) {\n // rfc 4733 (DTMF) style stuff\n data.push({ name: '',\n value: key });\n }\n }\n\n return data;\n },\n parseICECandidate(line) {\n const candidate = {};\n const elems = line.split(' ');\n\n candidate.foundation = elems[0].substring(12);\n candidate.component = elems[1];\n candidate.protocol = elems[2].toLowerCase();\n candidate.priority = elems[3];\n candidate.ip = elems[4];\n candidate.port = elems[5];\n\n // elems[6] => \"typ\"\n candidate.type = elems[7];\n candidate.generation = 0; // default value, may be overwritten below\n for (let i = 8; i < elems.length; i += 2) {\n switch (elems[i]) {\n case 'raddr':\n candidate['rel-addr'] = elems[i + 1];\n break;\n case 'rport':\n candidate['rel-port'] = elems[i + 1];\n break;\n case 'generation':\n candidate.generation = elems[i + 1];\n break;\n case 'tcptype':\n candidate.tcptype = elems[i + 1];\n break;\n default: // TODO\n logger.log(\n `parseICECandidate not translating \"${\n elems[i]}\" = \"${elems[i + 1]}\"`);\n }\n }\n candidate.network = '1';\n\n // not applicable to SDP -- FIXME: should be unique, not just random\n // eslint-disable-next-line newline-per-chained-call\n candidate.id = Math.random().toString(36).substr(2, 10);\n\n return candidate;\n },\n buildICECandidate(cand) {\n let line = [\n `a=candidate:${cand.foundation}`,\n cand.component,\n cand.protocol,\n cand.priority,\n cand.ip,\n cand.port,\n 'typ',\n cand.type\n ].join(' ');\n\n line += ' ';\n switch (cand.type) {\n case 'srflx':\n case 'prflx':\n case 'relay':\n if (cand.hasOwnAttribute('rel-addr')\n && cand.hasOwnAttribute('rel-port')) {\n line += 'raddr';\n line += ' ';\n line += cand['rel-addr'];\n line += ' ';\n line += 'rport';\n line += ' ';\n line += cand['rel-port'];\n line += ' ';\n }\n break;\n }\n if (cand.hasOwnAttribute('tcptype')) {\n line += 'tcptype';\n line += ' ';\n line += cand.tcptype;\n line += ' ';\n }\n line += 'generation';\n line += ' ';\n line += cand.hasOwnAttribute('generation') ? cand.generation : '0';\n\n return line;\n },\n parseSSRC(desc) {\n // proprietary mapping of a=ssrc lines\n // TODO: see \"Jingle RTP Source Description\" by Juberti and P. Thatcher\n // on google docs and parse according to that\n const data = new Map();\n const lines = desc.split('\\r\\n');\n\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].substring(0, 7) === 'a=ssrc:') {\n // FIXME: Use regex to smartly find the ssrc.\n const ssrc = lines[i].split('a=ssrc:')[1].split(' ')[0];\n\n if (!data.get(ssrc)) {\n data.set(ssrc, []);\n }\n\n data.get(ssrc).push(lines[i]);\n }\n }\n\n return data;\n },\n parseRTCPFB(line) {\n const parts = line.substr(10).split(' ');\n const data = {};\n\n data.pt = parts.shift();\n data.type = parts.shift();\n data.params = parts;\n\n return data;\n },\n parseExtmap(line) {\n const parts = line.substr(9).split(' ');\n const data = {};\n\n data.value = parts.shift();\n if (data.value.indexOf('/') === -1) {\n data.direction = 'both';\n } else {\n data.direction = data.value.substr(data.value.indexOf('/') + 1);\n data.value = data.value.substr(0, data.value.indexOf('/'));\n }\n data.uri = parts.shift();\n data.params = parts;\n\n return data;\n },\n findLine(haystack, needle, sessionpart) {\n let lines = haystack.split('\\r\\n');\n\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].substring(0, needle.length) === needle) {\n return lines[i];\n }\n }\n if (!sessionpart) {\n return false;\n }\n\n // search session part\n lines = sessionpart.split('\\r\\n');\n for (let j = 0; j < lines.length; j++) {\n if (lines[j].substring(0, needle.length) === needle) {\n return lines[j];\n }\n }\n\n return false;\n },\n findLines(haystack, needle, sessionpart) {\n let lines = haystack.split('\\r\\n');\n const needles = [];\n\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].substring(0, needle.length) === needle) {\n needles.push(lines[i]);\n }\n }\n if (needles.length || !sessionpart) {\n return needles;\n }\n\n // search session part\n lines = sessionpart.split('\\r\\n');\n for (let j = 0; j < lines.length; j++) {\n if (lines[j].substring(0, needle.length) === needle) {\n needles.push(lines[j]);\n }\n }\n\n return needles;\n },\n candidateToJingle(line) {\n // a=candidate:2979166662 1 udp 2113937151 192.168.2.100 57698 typ host\n // generation 0\n // \n if (line.indexOf('candidate:') === 0) {\n // eslint-disable-next-line no-param-reassign\n line = `a=${line}`;\n } else if (line.substring(0, 12) !== 'a=candidate:') {\n logger.log(\n 'parseCandidate called with a line that is not a candidate'\n + ' line');\n logger.log(line);\n\n return null;\n }\n if (line.substring(line.length - 2) === '\\r\\n') { // chomp it\n // eslint-disable-next-line no-param-reassign\n line = line.substring(0, line.length - 2);\n }\n const candidate = {};\n const elems = line.split(' ');\n\n if (elems[6] !== 'typ') {\n logger.log('did not find typ in the right place');\n logger.log(line);\n\n return null;\n }\n candidate.foundation = elems[0].substring(12);\n candidate.component = elems[1];\n candidate.protocol = elems[2].toLowerCase();\n candidate.priority = elems[3];\n candidate.ip = elems[4];\n candidate.port = elems[5];\n\n // elems[6] => \"typ\"\n candidate.type = elems[7];\n\n candidate.generation = '0'; // default, may be overwritten below\n for (let i = 8; i < elems.length; i += 2) {\n switch (elems[i]) {\n case 'raddr':\n candidate['rel-addr'] = elems[i + 1];\n break;\n case 'rport':\n candidate['rel-port'] = elems[i + 1];\n break;\n case 'generation':\n candidate.generation = elems[i + 1];\n break;\n case 'tcptype':\n candidate.tcptype = elems[i + 1];\n break;\n default: // TODO\n logger.log(`not translating \"${elems[i]}\" = \"${elems[i + 1]}\"`);\n }\n }\n candidate.network = '1';\n\n // not applicable to SDP -- FIXME: should be unique, not just random\n // eslint-disable-next-line newline-per-chained-call\n candidate.id = Math.random().toString(36).substr(2, 10);\n\n return candidate;\n },\n candidateFromJingle(cand) {\n let line = 'a=candidate:';\n\n line += cand.getAttribute('foundation');\n line += ' ';\n line += cand.getAttribute('component');\n line += ' ';\n\n let protocol = cand.getAttribute('protocol');\n\n // use tcp candidates for FF\n\n if (browser.isFirefox() && protocol.toLowerCase() === 'ssltcp') {\n protocol = 'tcp';\n }\n\n line += protocol; // .toUpperCase(); // chrome M23 doesn't like this\n line += ' ';\n line += cand.getAttribute('priority');\n line += ' ';\n line += cand.getAttribute('ip');\n line += ' ';\n line += cand.getAttribute('port');\n line += ' ';\n line += 'typ';\n line += ` ${cand.getAttribute('type')}`;\n line += ' ';\n switch (cand.getAttribute('type')) {\n case 'srflx':\n case 'prflx':\n case 'relay':\n if (cand.getAttribute('rel-addr')\n && cand.getAttribute('rel-port')) {\n line += 'raddr';\n line += ' ';\n line += cand.getAttribute('rel-addr');\n line += ' ';\n line += 'rport';\n line += ' ';\n line += cand.getAttribute('rel-port');\n line += ' ';\n }\n break;\n }\n if (protocol.toLowerCase() === 'tcp') {\n line += 'tcptype';\n line += ' ';\n line += cand.getAttribute('tcptype');\n line += ' ';\n }\n line += 'generation';\n line += ' ';\n line += cand.getAttribute('generation') || '0';\n\n return `${line}\\r\\n`;\n },\n\n /**\n * Parse the 'most' primary video ssrc from the given m line\n * @param {object} mLine object as parsed from transform.parse\n * @return {number} the primary video ssrc from the given m line\n */\n parsePrimaryVideoSsrc(videoMLine) {\n const numSsrcs = videoMLine.ssrcs\n .map(ssrcInfo => ssrcInfo.id)\n .filter((ssrc, index, array) => array.indexOf(ssrc) === index)\n .length;\n const numGroups\n = (videoMLine.ssrcGroups && videoMLine.ssrcGroups.length) || 0;\n\n if (numSsrcs > 1 && numGroups === 0) {\n // Ambiguous, can't figure out the primary\n return;\n }\n let primarySsrc = null;\n\n if (numSsrcs === 1) {\n primarySsrc = videoMLine.ssrcs[0].id;\n } else if (numSsrcs === 2) {\n // Can figure it out if there's an FID group\n const fidGroup\n = videoMLine.ssrcGroups.find(\n group => group.semantics === 'FID');\n\n if (fidGroup) {\n primarySsrc = fidGroup.ssrcs.split(' ')[0];\n }\n } else if (numSsrcs >= 3) {\n // Can figure it out if there's a sim group\n const simGroup\n = videoMLine.ssrcGroups.find(\n group => group.semantics === 'SIM');\n\n if (simGroup) {\n primarySsrc = simGroup.ssrcs.split(' ')[0];\n }\n }\n\n return primarySsrc;\n },\n\n /**\n * Generate an ssrc\n * @returns {number} an ssrc\n */\n generateSsrc() {\n return RandomUtil.randomInt(1, 0xffffffff);\n },\n\n /**\n * Get an attribute for the given ssrc with the given attributeName\n * from the given mline\n * @param {object} mLine an mLine object as parsed from transform.parse\n * @param {number} ssrc the ssrc for which an attribute is desired\n * @param {string} attributeName the name of the desired attribute\n * @returns {string} the value corresponding to the given ssrc\n * and attributeName\n */\n getSsrcAttribute(mLine, ssrc, attributeName) {\n for (let i = 0; i < mLine.ssrcs.length; ++i) {\n const ssrcLine = mLine.ssrcs[i];\n\n if (ssrcLine.id === ssrc\n && ssrcLine.attribute === attributeName) {\n return ssrcLine.value;\n }\n }\n },\n\n /**\n * Parses the ssrcs from the group sdp line and\n * returns them as a list of numbers\n * @param {object} the ssrcGroup object as parsed from\n * sdp-transform\n * @returns {list} a list of the ssrcs in the group\n * parsed as numbers\n */\n parseGroupSsrcs(ssrcGroup) {\n return ssrcGroup\n .ssrcs\n .split(' ')\n .map(ssrcStr => parseInt(ssrcStr, 10));\n },\n\n /**\n * Get the mline of the given type from the given sdp\n * @param {object} sdp sdp as parsed from transform.parse\n * @param {string} type the type of the desired mline (e.g. \"video\")\n * @returns {object} a media object\n */\n getMedia(sdp, type) {\n return sdp.media.find(m => m.type === type);\n },\n\n /**\n * Extracts the ICE username fragment from an SDP string.\n * @param {string} sdp the SDP in raw text format\n */\n getUfrag(sdp) {\n const ufragLines\n = sdp.split('\\n').filter(line => line.startsWith('a=ice-ufrag:'));\n\n if (ufragLines.length > 0) {\n return ufragLines[0].substr('a=ice-ufrag:'.length);\n }\n },\n\n /**\n * Sets the given codecName as the preferred codec by\n * moving it to the beginning of the payload types\n * list (modifies the given mline in place). If there\n * are multiple options within the same codec (multiple h264\n * profiles, for instance), this will prefer the first one\n * that is found.\n * @param {object} videoMLine the video mline object from\n * an sdp as parsed by transform.parse\n * @param {string} codecName the name of the preferred codec\n */\n preferVideoCodec(videoMLine, codecName) {\n let payloadType = null;\n\n if (!videoMLine || !codecName) {\n return;\n }\n\n for (let i = 0; i < videoMLine.rtp.length; ++i) {\n const rtp = videoMLine.rtp[i];\n\n if (rtp.codec\n && rtp.codec.toLowerCase() === codecName.toLowerCase()) {\n payloadType = rtp.payload;\n break;\n }\n }\n if (payloadType) {\n // Call toString() on payloads to get around an issue within\n // SDPTransform that sets payloads as a number, instead of a string,\n // when there is only one payload.\n const payloadTypes\n = videoMLine.payloads\n .toString()\n .split(' ')\n .map(p => parseInt(p, 10));\n const payloadIndex = payloadTypes.indexOf(payloadType);\n\n payloadTypes.splice(payloadIndex, 1);\n payloadTypes.unshift(payloadType);\n videoMLine.payloads = payloadTypes.join(' ');\n }\n },\n\n /**\n * Strips the given codec from the given mline. All related RTX payload\n * types are also stripped. If the resulting mline would have no codecs,\n * it's disabled.\n *\n * @param {object} videoMLine the video mline object from an sdp as parsed\n * by transform.parse.\n * @param {string} codecName the name of the codec which will be stripped.\n */\n stripVideoCodec(videoMLine, codecName) {\n if (!videoMLine || !codecName) {\n return;\n }\n\n const removePts = [];\n\n for (const rtp of videoMLine.rtp) {\n if (rtp.codec\n && rtp.codec.toLowerCase() === codecName.toLowerCase()) {\n removePts.push(rtp.payload);\n }\n }\n\n if (removePts.length > 0) {\n // We also need to remove the payload types that are related to RTX\n // for the codecs we want to disable.\n const rtxApts = removePts.map(item => `apt=${item}`);\n const rtxPts = videoMLine.fmtp.filter(\n item => rtxApts.indexOf(item.config) !== -1);\n\n removePts.push(...rtxPts.map(item => item.payload));\n\n // Call toString() on payloads to get around an issue within\n // SDPTransform that sets payloads as a number, instead of a string,\n // when there is only one payload.\n const allPts = videoMLine.payloads\n .toString()\n .split(' ')\n .map(Number);\n const keepPts = allPts.filter(pt => removePts.indexOf(pt) === -1);\n\n if (keepPts.length === 0) {\n // There are no other video codecs, disable the stream.\n videoMLine.port = 0;\n videoMLine.direction = 'inactive';\n videoMLine.payloads = '*';\n } else {\n videoMLine.payloads = keepPts.join(' ');\n }\n\n videoMLine.rtp = videoMLine.rtp.filter(\n item => keepPts.indexOf(item.payload) !== -1);\n videoMLine.fmtp = videoMLine.fmtp.filter(\n item => keepPts.indexOf(item.payload) !== -1);\n if (videoMLine.rtcpFb) {\n videoMLine.rtcpFb = videoMLine.rtcpFb.filter(\n item => keepPts.indexOf(item.payload) !== -1);\n }\n }\n }\n};\n\nexport default SDPUtil;\n", "/**\n * This class exports constants and factory methods related to the analytics\n * API provided by AnalyticsAdapter. In order for entries in a database to be\n * somewhat easily traceable back to the code which produced them, events sent\n * through analytics should be defined here.\n *\n * Since the AnalyticsAdapter API can be used in different ways, for some events\n * it is more convenient to just define the event name as a constant. For other\n * events a factory function is easier.\n *\n * A general approach for adding a new event:\n * 1. Determine the event type: track, UI, page, or operational. If in doubt use\n * operational.\n * 2. Determine whether the event is related to other existing events, and\n * which fields are desired to be set: name, action, actionSubject, source.\n * 3. If the name is sufficient (the other fields are not important), use a\n * constant. Otherwise use a factory function.\n *\n * Note that the AnalyticsAdapter uses the events passed to its functions for\n * its own purposes, and might modify them. Because of this, factory functions\n * should create new objects.\n *\n */\n\n/**\n * The constant which identifies an event of type \"operational\".\n * @type {string}\n */\nexport const TYPE_OPERATIONAL = 'operational';\n\n/**\n * The constant which identifies an event of type \"page\".\n * @type {string}\n */\nexport const TYPE_PAGE = 'page';\n\n/**\n * The constant which identifies an event of type \"track\".\n * @type {string}\n */\nexport const TYPE_TRACK = 'track';\n\n/**\n * The constant which identifies an event of type \"ui\".\n * @type {string}\n */\nexport const TYPE_UI = 'ui';\n\n/**\n * The \"action\" value for Jingle events which indicates that the Jingle session\n * was restarted (TODO: verify/fix the documentation)\n * @type {string}\n */\nexport const ACTION_JINGLE_RESTART = 'restart';\n\n/**\n * The \"action\" value for Jingle events which indicates that a session-accept\n * timed out (TODO: verify/fix the documentation)\n * @type {string}\n */\nexport const ACTION_JINGLE_SA_TIMEOUT = 'session-accept.timeout';\n\n/**\n * The \"action\" value for Jingle events which indicates that a session-initiate\n * was received.\n * @type {string}\n */\nexport const ACTION_JINGLE_SI_RECEIVED = 'session-initiate.received';\n\n/**\n * The \"action\" value for Jingle events which indicates that a session-initiate\n * not arrived within a timeout (the value is specified in\n * the {@link JingleSessionPC}.\n * @type {string}\n */\nexport const ACTION_JINGLE_SI_TIMEOUT = 'session-initiate.timeout';\n\n/**\n * A constant for the \"terminate\" action for Jingle events. TODO: verify/fix\n * the documentation)\n * @type {string}\n */\nexport const ACTION_JINGLE_TERMINATE = 'terminate';\n\n/**\n * The \"action\" value for Jingle events which indicates that a transport-replace\n * was received.\n * @type {string}\n */\nexport const ACTION_JINGLE_TR_RECEIVED\n = 'transport-replace.received';\n\n/**\n * The \"action\" value for Jingle events which indicates that a transport-replace\n * succeeded (TODO: verify/fix the documentation)\n * @type {string}\n */\nexport const ACTION_JINGLE_TR_SUCCESS\n = 'transport-replace.success';\n\n/**\n * The \"action\" value for P2P events which indicates that P2P session initiate message has been rejected by the client\n * because the mandatory requirements were not met.\n * @type {string}\n */\nexport const ACTION_P2P_DECLINED = 'decline';\n\n/**\n * The \"action\" value for P2P events which indicates that a connection was\n * established (TODO: verify/fix the documentation)\n * @type {string}\n */\nexport const ACTION_P2P_ESTABLISHED = 'established';\n\n/**\n * The \"action\" value for P2P events which indicates that something failed.\n * @type {string}\n */\nexport const ACTION_P2P_FAILED = 'failed';\n\n/**\n * The \"action\" value for P2P events which indicates that a switch to\n * jitsi-videobridge happened.\n * @type {string}\n */\nexport const ACTION_P2P_SWITCH_TO_JVB = 'switch.to.jvb';\n\n/**\n * The name of an event which indicates an available device. We send one such\n * event per available device once when the available devices are first known,\n * and every time that they change\n * @type {string}\n *\n * Properties:\n * audio_input_device_count: the number of audio input devices available at\n * the time the event was sent.\n * audio_output_device_count: the number of audio output devices available\n * at the time the event was sent.\n * video_input_device_count: the number of video input devices available at\n * the time the event was sent.\n * video_output_device_count: the number of video output devices available\n * at the time the event was sent.\n * device_id: an identifier of the device described in this event.\n * device_group_id:\n * device_kind: one of 'audioinput', 'audiooutput', 'videoinput' or\n * 'videooutput'.\n * device_label: a string which describes the device.\n */\nexport const AVAILABLE_DEVICE = 'available.device';\n\n/**\n * This appears to be fired only in certain cases when the XMPP connection\n * disconnects (and it was intentional?). It is currently never observed to\n * fire in production.\n *\n * TODO: document\n *\n * Properties:\n * message: an error message\n */\nexport const CONNECTION_DISCONNECTED = 'connection.disconnected';\n\n/**\n * Indicates that the user of the application provided feedback in terms of a\n * rating (an integer from 1 to 5) and an optional comment.\n * Properties:\n * value: the user's rating (an integer from 1 to 5)\n * comment: the user's comment\n */\nexport const FEEDBACK = 'feedback';\n\n/**\n * Indicates the duration of a particular phase of the ICE connectivity\n * establishment.\n *\n * Properties:\n * phase: the ICE phase (e.g. 'gathering', 'checking', 'establishment')\n * value: the duration in milliseconds.\n * p2p: whether the associated ICE connection is p2p or towards a\n * jitsi-videobridge\n * initiator: whether the local Jingle peer is the initiator or responder\n * in the Jingle session. XXX we probably actually care about the ICE\n * role (controlling vs controlled), and we assume that this correlates\n * with the Jingle initiator.\n */\nexport const ICE_DURATION = 'ice.duration';\n\n/**\n * Indicates the difference in milliseconds between the ICE establishment time\n * for the P2P and JVB connections (e.g. a value of 10 would indicate that the\n * P2P connection took 10ms more than JVB connection to establish).\n *\n * Properties:\n * value: the difference in establishment durations in milliseconds.\n *\n */\nexport const ICE_ESTABLISHMENT_DURATION_DIFF\n = 'ice.establishment.duration.diff';\n\n/**\n * Indicates that the ICE state has changed.\n *\n * Properties:\n * state: the ICE state which was entered (e.g. 'checking', 'connected',\n * 'completed', etc).\n * value: the time in milliseconds (as reported by\n * window.performance.now()) that the state change occurred.\n * p2p: whether the associated ICE connection is p2p or towards a\n * jitsi-videobridge\n * signalingState: The signaling state of the associated PeerConnection\n * reconnect: whether the associated Jingle session is in the process of\n * reconnecting (or is it ICE? TODO: verify/fix the documentation)\n */\nexport const ICE_STATE_CHANGED = 'ice.state.changed';\n\n/**\n * Indicates that no bytes have been sent for the track.\n *\n * Properties:\n * mediaType: the media type of the local track ('audio' or 'video').\n */\nexport const NO_BYTES_SENT = 'track.no-bytes-sent';\n\n/**\n * Indicates that a track was unmuted (?).\n *\n * Properties:\n * mediaType: the media type of the local track ('audio' or 'video').\n * trackType: the type of the track ('local' or 'remote').\n * value: TODO: document\n */\nexport const TRACK_UNMUTED = 'track.unmuted';\n\n/**\n * Creates an operational event which indicates that we have received a\n * \"bridge down\" event from jicofo.\n */\nexport const createBridgeDownEvent = function() {\n const bridgeDown = 'bridge.down';\n\n return {\n action: bridgeDown,\n actionSubject: bridgeDown,\n type: TYPE_OPERATIONAL\n };\n};\n\n/**\n * Creates an event which indicates that the XMPP connection failed\n * @param errorType TODO\n * @param errorMessage TODO\n * @param detail connection failed details.\n */\nexport const createConnectionFailedEvent\n = function(errorType, errorMessage, details) {\n return {\n type: TYPE_OPERATIONAL,\n action: 'connection.failed',\n attributes: {\n 'error_type': errorType,\n 'error_message': errorMessage,\n ...details\n }\n };\n };\n\n/**\n * Creates a conference event.\n *\n * @param {string} action - The action of the event.\n * @param {Object} attributes - The attributes to be added to the event.\n * @returns {{type: string, source: string, action: string, attributes: object}}\n */\nexport function createConferenceEvent(action, attributes) {\n return {\n action,\n attributes,\n source: 'conference',\n type: TYPE_OPERATIONAL\n };\n}\n\n/**\n * Creates an operational event which indicates that a particular connection\n * stage was reached (i.e. the XMPP connection transitioned to the \"connected\"\n * state).\n *\n * @param stage the stage which was reached\n * @param attributes additional attributes for the event. This should be an\n * object with a \"value\" property indicating a timestamp in milliseconds\n * relative to the beginning of the document's lifetime.\n *\n */\nexport const createConnectionStageReachedEvent = function(stage, attributes) {\n const action = 'connection.stage.reached';\n\n return {\n action,\n actionSubject: stage,\n attributes,\n source: action,\n type: TYPE_OPERATIONAL\n };\n};\n\n/**\n * Creates an operational event for the end-to-end round trip time to a\n * specific remote participant.\n * @param participantId the ID of the remote participant.\n * @param region the region of the remote participant\n * @param rtt the rtt\n */\nexport const createE2eRttEvent = function(participantId, region, rtt) {\n const attributes = {\n 'participant_id': participantId,\n region,\n rtt\n };\n\n return {\n attributes,\n name: 'e2e_rtt',\n type: TYPE_OPERATIONAL\n };\n};\n\n/**\n * Creates an event which indicates that the focus has left the MUC.\n */\nexport const createFocusLeftEvent = function() {\n const action = 'focus.left';\n\n return {\n action,\n actionSubject: action,\n type: TYPE_OPERATIONAL\n };\n};\n\n/**\n * Creates an event related to a getUserMedia call.\n *\n * @param action the type of the result that the event represents: 'error',\n * 'success', 'warning', etc.\n * @param attributes the attributes to attach to the event.\n * @returns {{type: string, source: string, name: string}}\n */\nexport const createGetUserMediaEvent = function(action, attributes = {}) {\n return {\n type: TYPE_OPERATIONAL,\n source: 'get.user.media',\n action,\n attributes\n };\n};\n\n/**\n * Creates an event related to remote participant connection status changes.\n *\n * @param attributes the attributes to attach to the event.\n * @returns {{type: string, source: string, name: string}}\n */\nexport const createParticipantConnectionStatusEvent = function(attributes = {}) {\n const action = 'duration';\n\n return {\n type: TYPE_OPERATIONAL,\n source: 'peer.conn.status',\n action,\n attributes\n };\n};\n\n/**\n * Creates an event for a Jingle-related event.\n * @param action the action of the event\n * @param attributes attributes to add to the event.\n */\nexport const createJingleEvent = function(action, attributes = {}) {\n return {\n type: TYPE_OPERATIONAL,\n action,\n source: 'jingle',\n attributes\n };\n};\n\n/**\n * Creates an event which indicates that a local track was not able to read\n * data from its source (a camera or a microphone).\n *\n * @param mediaType {String} the media type of the local track ('audio' or\n * 'video').\n */\nexport const createNoDataFromSourceEvent = function(mediaType, value) {\n return {\n attributes: {\n 'media_type': mediaType,\n value\n },\n action: 'track.no.data.from.source',\n type: TYPE_OPERATIONAL\n };\n};\n\n/**\n * Creates an event for a p2p-related event.\n * @param action the action of the event\n * @param attributes attributes to add to the event.\n */\nexport const createP2PEvent = function(action, attributes = {}) {\n return {\n type: TYPE_OPERATIONAL,\n action,\n source: 'p2p',\n attributes\n };\n};\n\n/**\n * Indicates that we received a remote command to mute.\n */\nexport const createRemotelyMutedEvent = function() {\n return {\n type: TYPE_OPERATIONAL,\n action: 'remotely.muted'\n };\n};\n\n/**\n * Creates an event which contains RTP statistics such as RTT and packet loss.\n *\n * All average RTP stats are currently reported under 1 event name, but with\n * different properties that allows to distinguish between a P2P call, a\n * call relayed through TURN or the JVB, and multiparty vs 1:1.\n *\n * The structure of the event is:\n *\n * {\n * p2p: true,\n * conferenceSize: 2,\n * localCandidateType: \"relay\",\n * remoteCandidateType: \"relay\",\n * transportType: \"udp\",\n *\n * // Average RTT of 200ms\n * \"rtt.avg\": 200,\n * \"rtt.samples\": \"[100, 200, 300]\",\n *\n * // Average packet loss of 10%\n * \"packet.loss.avg\": 10,\n * \"packet.loss.samples\": '[5, 10, 15]'\n *\n * // Difference in milliseconds in the end-to-end RTT between p2p and jvb.\n * // The e2e RTT through jvb is 15ms shorter:\n * \"rtt.diff\": 15,\n *\n * // End-to-end RTT through JVB is ms.\n * \"end2end.rtt.avg\" = 100\n * }\n *\n * Note that the value of the \"samples\" properties are (JSON encoded) strings,\n * and not JSON arrays, as events' attributes can not be nested. The samples are\n * currently included for debug purposes only and can be removed anytime soon\n * from the structure.\n *\n * Also note that not all of values are present in each event, as values are\n * obtained and calculated as part of different process/event pipe. For example\n * {@link ConnectionAvgStats} instances are doing the reports for each\n * {@link TraceablePeerConnection} and work independently from the main stats\n * pipe.\n */\nexport const createRtpStatsEvent = function(attributes) {\n return {\n type: TYPE_OPERATIONAL,\n action: 'rtp.stats',\n attributes\n };\n};\n\n/**\n * Creates an event which contains the round trip time (RTT) to a set of\n * regions.\n *\n * @param attributes\n * @returns {{type: string, action: string, attributes: *}}\n */\nexport const createRttByRegionEvent = function(attributes) {\n return {\n type: TYPE_OPERATIONAL,\n action: 'rtt.by.region',\n attributes\n };\n};\n\n/**\n * Creates an event which contains the local and remote ICE candidate types\n * for the transport that is currently selected.\n *\n * @param attributes\n * @returns {{type: string, action: string, attributes: *}}\n */\nexport const createTransportStatsEvent = function(attributes) {\n return {\n type: TYPE_OPERATIONAL,\n action: 'transport.stats',\n attributes\n };\n};\n\n/**\n * Creates an event which contains information about the audio output problem (the user id of the affected participant,\n * the local audio levels and the remote audio levels that triggered the event).\n *\n * @param {string} userID - The user id of the affected participant.\n * @param {*} localAudioLevels - The local audio levels.\n * @param {*} remoteAudioLevels - The audio levels received from the participant.\n */\nexport function createAudioOutputProblemEvent(userID, localAudioLevels, remoteAudioLevels) {\n return {\n type: TYPE_OPERATIONAL,\n action: 'audio.output.problem',\n attributes: {\n userID,\n localAudioLevels,\n remoteAudioLevels\n }\n };\n}\n\n/**\n * Creates an event which contains an information related to the bridge channel close event.\n *\n * @param {string} code - A code from {@link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent}\n * @param {string} reason - A string which describes the reason for closing the bridge channel.\n * @returns {{type: string, action: string, attributes: { code: string, reason: string }}}\n */\nexport const createBridgeChannelClosedEvent = function(code, reason) {\n return {\n type: TYPE_OPERATIONAL,\n action: 'bridge-channel.error',\n attributes: {\n code,\n reason\n }\n };\n};\n\n/**\n * Creates an event which indicates the Time To First Media (TTFM).\n * It is measured in milliseconds relative to the beginning of the document's\n * lifetime (i.e. the origin used by window.performance.now()), and it excludes\n * the following:\n * 1. The delay due to getUserMedia()\n * 2. The period between the MUC being joined and the reception of the Jingle\n * session-initiate from jicofo. This is because jicofo will not start a Jingle\n * session until there are at least 2 participants in the room.\n *\n * @param attributes the attributes to add to the event. Currently used fields:\n * mediaType: the media type of the local track ('audio' or 'video').\n * muted: whether the track has ever been muted (?)\n * value: the TTMF in milliseconds.\n */\nexport const createTtfmEvent = function(attributes) {\n return createConnectionStageReachedEvent('ttfm', attributes);\n};\n", "const RTCEvents = {\n /**\n * Indicates error while create answer call.\n */\n CREATE_ANSWER_FAILED: 'rtc.create_answer_failed',\n\n /**\n * Indicates error while create offer call.\n */\n CREATE_OFFER_FAILED: 'rtc.create_offer_failed',\n DATA_CHANNEL_OPEN: 'rtc.data_channel_open',\n ENDPOINT_CONN_STATUS_CHANGED: 'rtc.endpoint_conn_status_changed',\n DOMINANT_SPEAKER_CHANGED: 'rtc.dominant_speaker_changed',\n LASTN_ENDPOINT_CHANGED: 'rtc.lastn_endpoint_changed',\n\n /**\n * Event emitted when the user granted a permission for the camera / mic.\n * Used to keep track of the granted permissions on browsers which don't\n * support the Permissions API.\n */\n GRANTED_PERMISSIONS: 'rtc.granted_permissions',\n\n IS_SELECTED_CHANGED: 'rtc.is_selected_change',\n\n /**\n * Event emitted when {@link RTC.setLastN} method is called to update with\n * the new value set.\n * The first argument is the value passed to {@link RTC.setLastN}.\n */\n LASTN_VALUE_CHANGED: 'rtc.lastn_value_changed',\n\n /**\n * Event emitted when ssrc for a local track is extracted and stored\n * in {@link TraceablePeerConnection}.\n * @param {JitsiLocalTrack} track which ssrc was updated\n * @param {string} ssrc that was stored\n */\n LOCAL_TRACK_SSRC_UPDATED: 'rtc.local_track_ssrc_updated',\n\n TRACK_ATTACHED: 'rtc.track_attached',\n\n /**\n * Event fired when we remote track is added to the conference.\n * 1st event argument is the added JitsiRemoteTrack instance.\n **/\n REMOTE_TRACK_ADDED: 'rtc.remote_track_added',\n\n // FIXME get rid of this event in favour of NO_DATA_FROM_SOURCE event\n // (currently implemented for local tracks only)\n REMOTE_TRACK_MUTE: 'rtc.remote_track_mute',\n\n /**\n * Indicates that the remote track has been removed from the conference.\n * 1st event argument is the removed {@link JitsiRemoteTrack} instance.\n */\n REMOTE_TRACK_REMOVED: 'rtc.remote_track_removed',\n\n // FIXME get rid of this event in favour of NO_DATA_FROM_SOURCE event\n // (currently implemented for local tracks only)\n REMOTE_TRACK_UNMUTE: 'rtc.remote_track_unmute',\n\n /**\n * Indicates error while set local description.\n */\n SET_LOCAL_DESCRIPTION_FAILED: 'rtc.set_local_description_failed',\n\n /**\n * Indicates error while set remote description.\n */\n SET_REMOTE_DESCRIPTION_FAILED: 'rtc.set_remote_description_failed',\n AUDIO_OUTPUT_DEVICE_CHANGED: 'rtc.audio_output_device_changed',\n DEVICE_LIST_CHANGED: 'rtc.device_list_changed',\n\n /**\n * Indicates that the list with available devices will change.\n */\n DEVICE_LIST_WILL_CHANGE: 'rtc.device_list_will_change',\n DEVICE_LIST_AVAILABLE: 'rtc.device_list_available',\n\n /**\n * Indicates that a message from another participant is received on\n * data channel.\n */\n ENDPOINT_MESSAGE_RECEIVED: 'rtc.endpoint_message_received',\n\n /**\n * Designates an event indicating that the local ICE username fragment of\n * the jingle session has changed.\n * The first argument of the vent is TraceablePeerConnection which\n * is the source of the event.\n * The second argument is the actual \"ufrag\" string.\n */\n LOCAL_UFRAG_CHANGED: 'rtc.local_ufrag_changed',\n\n /**\n * Designates an event indicating that the local ICE username fragment of\n * the jingle session has changed.\n * The first argument of the vent is TraceablePeerConnection which\n * is the source of the event.\n * The second argument is the actual \"ufrag\" string.\n */\n REMOTE_UFRAG_CHANGED: 'rtc.remote_ufrag_changed'\n};\n\nmodule.exports = RTCEvents;\n", "/**\n * The audio type.\n */\nexport const AUDIO = 'audio';\n\n/**\n * The presenter type.\n */\nexport const PRESENTER = 'presenter';\n\n/**\n * The video type.\n */\nexport const VIDEO = 'video';\n", "/* global\n __filename,\n MediaStreamTrack,\n RTCIceCandidate: true,\n RTCPeerConnection,\n RTCSessionDescription: true\n*/\n\nimport { AVAILABLE_DEVICE } from '../../service/statistics/AnalyticsEvents';\nimport CameraFacingMode from '../../service/RTC/CameraFacingMode';\nimport EventEmitter from 'events';\nimport { getLogger } from 'jitsi-meet-logger';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport JitsiTrackError from '../../JitsiTrackError';\nimport Listenable from '../util/Listenable';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport Resolutions from '../../service/RTC/Resolutions';\nimport browser from '../browser';\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport screenObtainer from './ScreenObtainer';\nimport SDPUtil from '../xmpp/SDPUtil';\nimport Statistics from '../statistics/statistics';\nimport VideoType from '../../service/RTC/VideoType';\n\nconst logger = getLogger(__filename);\n\n// Require adapter only for certain browsers. This is being done for\n// react-native, which has its own shims, and while browsers are being migrated\n// over to use adapter's shims.\nif (browser.usesAdapter()) {\n require('webrtc-adapter');\n}\n\nconst eventEmitter = new EventEmitter();\n\nconst AVAILABLE_DEVICES_POLL_INTERVAL_TIME = 3000; // ms\n\n/**\n * Default resolution to obtain for video tracks if no resolution is specified.\n * This default is used for old gum flow only, as new gum flow uses\n * {@link DEFAULT_CONSTRAINTS}.\n */\nconst OLD_GUM_DEFAULT_RESOLUTION = 720;\n\n/**\n * Default devices to obtain when no specific devices are specified. This\n * default is used for old gum flow only.\n */\nconst OLD_GUM_DEFAULT_DEVICES = [ 'audio', 'video' ];\n\n/**\n * Default MediaStreamConstraints to use for calls to getUserMedia.\n *\n * @private\n */\nconst DEFAULT_CONSTRAINTS = {\n video: {\n height: {\n ideal: 720,\n max: 720,\n min: 240\n }\n }\n};\n\n/**\n * The default frame rate for Screen Sharing.\n */\nconst SS_DEFAULT_FRAME_RATE = 5;\n\n// Currently audio output device change is supported only in Chrome and\n// default output always has 'default' device ID\nlet audioOutputDeviceId = 'default'; // default device\n// whether user has explicitly set a device to use\nlet audioOutputChanged = false;\n\n// Disables all audio processing\nlet disableAP = false;\n\n// Disables Acoustic Echo Cancellation\nlet disableAEC = false;\n\n// Disables Noise Suppression\nlet disableNS = false;\n\n// Disables Automatic Gain Control\nlet disableAGC = false;\n\n// Disables Highpass Filter\nlet disableHPF = false;\n\nconst featureDetectionAudioEl = document.createElement('audio');\nconst isAudioOutputDeviceChangeAvailable\n = typeof featureDetectionAudioEl.setSinkId !== 'undefined';\n\nlet availableDevices;\nlet availableDevicesPollTimer;\n\n/**\n * Initialize wrapper function for enumerating devices.\n * TODO: remove this, it should no longer be needed.\n *\n * @returns {?Function}\n */\nfunction initEnumerateDevicesWithCallback() {\n if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {\n return callback => {\n navigator.mediaDevices.enumerateDevices()\n .then(callback, () => callback([]));\n };\n }\n}\n\n/**\n *\n * @param constraints\n * @param isNewStyleConstraintsSupported\n * @param resolution\n */\nfunction setResolutionConstraints(\n constraints,\n isNewStyleConstraintsSupported,\n resolution) {\n if (Resolutions[resolution]) {\n if (isNewStyleConstraintsSupported) {\n constraints.video.width = {\n ideal: Resolutions[resolution].width\n };\n constraints.video.height = {\n ideal: Resolutions[resolution].height\n };\n }\n\n constraints.video.mandatory.minWidth = Resolutions[resolution].width;\n constraints.video.mandatory.minHeight = Resolutions[resolution].height;\n }\n\n if (constraints.video.mandatory.minWidth) {\n constraints.video.mandatory.maxWidth\n = constraints.video.mandatory.minWidth;\n }\n\n if (constraints.video.mandatory.minHeight) {\n constraints.video.mandatory.maxHeight\n = constraints.video.mandatory.minHeight;\n }\n}\n\n/**\n * @param {string[]} um required user media types\n *\n * @param {Object} [options={}] optional parameters\n * @param {string} options.resolution\n * @param {number} options.bandwidth\n * @param {number} options.fps\n * @param {string} options.desktopStream\n * @param {string} options.cameraDeviceId\n * @param {string} options.micDeviceId\n * @param {CameraFacingMode} options.facingMode\n * @param {bool} firefox_fake_device\n * @param {Object} options.frameRate - used only for dekstop sharing.\n * @param {Object} options.frameRate.min - Minimum fps\n * @param {Object} options.frameRate.max - Maximum fps\n * @param {bool} options.screenShareAudio - Used by electron clients to\n * enable system audio screen sharing.\n */\nfunction getConstraints(um, options = {}) {\n const constraints = {\n audio: false,\n video: false\n };\n\n // Don't mix new and old style settings for Chromium as this leads\n // to TypeError in new Chromium versions. @see\n // https://bugs.chromium.org/p/chromium/issues/detail?id=614716\n // This is a temporary solution, in future we will fully split old and\n // new style constraints when new versions of Chromium and Firefox will\n // have stable support of new constraints format. For more information\n // @see https://github.com/jitsi/lib-jitsi-meet/pull/136\n const isNewStyleConstraintsSupported\n = browser.isFirefox()\n || browser.isSafari()\n || browser.isReactNative();\n\n if (um.indexOf('video') >= 0) {\n // same behaviour as true\n constraints.video = { mandatory: {},\n optional: [] };\n\n if (options.cameraDeviceId) {\n if (isNewStyleConstraintsSupported) {\n // New style of setting device id.\n constraints.video.deviceId = options.cameraDeviceId;\n }\n\n // Old style.\n constraints.video.mandatory.sourceId = options.cameraDeviceId;\n } else {\n // Prefer the front i.e. user-facing camera (to the back i.e.\n // environment-facing camera, for example).\n // TODO: Maybe use \"exact\" syntax if options.facingMode is defined,\n // but this probably needs to be decided when updating other\n // constraints, as we currently don't use \"exact\" syntax anywhere.\n const facingMode = options.facingMode || CameraFacingMode.USER;\n\n if (isNewStyleConstraintsSupported) {\n constraints.video.facingMode = facingMode;\n }\n constraints.video.optional.push({\n facingMode\n });\n }\n\n if (options.minFps || options.maxFps || options.fps) {\n // for some cameras it might be necessary to request 30fps\n // so they choose 30fps mjpg over 10fps yuy2\n if (options.minFps || options.fps) {\n // Fall back to options.fps for backwards compatibility\n options.minFps = options.minFps || options.fps;\n constraints.video.mandatory.minFrameRate = options.minFps;\n }\n if (options.maxFps) {\n constraints.video.mandatory.maxFrameRate = options.maxFps;\n }\n }\n\n setResolutionConstraints(\n constraints, isNewStyleConstraintsSupported, options.resolution);\n }\n if (um.indexOf('audio') >= 0) {\n if (browser.isReactNative()) {\n // The react-native-webrtc project that we're currently using\n // expects the audio constraint to be a boolean.\n constraints.audio = true;\n } else if (browser.isFirefox()) {\n if (options.micDeviceId) {\n constraints.audio = {\n mandatory: {},\n deviceId: options.micDeviceId, // new style\n optional: [ {\n sourceId: options.micDeviceId // old style\n } ] };\n } else {\n constraints.audio = true;\n }\n } else {\n // same behaviour as true\n constraints.audio = { mandatory: {},\n optional: [] };\n if (options.micDeviceId) {\n if (isNewStyleConstraintsSupported) {\n // New style of setting device id.\n constraints.audio.deviceId = options.micDeviceId;\n }\n\n // Old style.\n constraints.audio.optional.push({\n sourceId: options.micDeviceId\n });\n }\n\n // if it is good enough for hangouts...\n constraints.audio.optional.push(\n { echoCancellation: !disableAEC && !disableAP },\n { googEchoCancellation: !disableAEC && !disableAP },\n { googAutoGainControl: !disableAGC && !disableAP },\n { googNoiseSuppression: !disableNS && !disableAP },\n { googHighpassFilter: !disableHPF && !disableAP },\n { googNoiseSuppression2: !disableNS && !disableAP },\n { googEchoCancellation2: !disableAEC && !disableAP },\n { googAutoGainControl2: !disableAGC && !disableAP }\n );\n }\n }\n if (um.indexOf('screen') >= 0) {\n if (browser.isChrome()) {\n constraints.video = {\n mandatory: getSSConstraints({\n ...options,\n source: 'screen'\n }),\n optional: []\n };\n\n } else if (browser.isFirefox()) {\n constraints.video = {\n mozMediaSource: 'window',\n mediaSource: 'window',\n frameRate: options.frameRate || {\n min: SS_DEFAULT_FRAME_RATE,\n max: SS_DEFAULT_FRAME_RATE\n }\n };\n\n } else {\n const errmsg\n = '\\'screen\\' WebRTC media source is supported only in Chrome'\n + ' and Firefox';\n\n GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));\n logger.error(errmsg);\n }\n }\n if (um.indexOf('desktop') >= 0) {\n constraints.video = {\n mandatory: getSSConstraints({\n ...options,\n source: 'desktop'\n }),\n optional: []\n };\n\n // Audio screen sharing for electron only works for screen type devices.\n // i.e. when the user shares the whole desktop.\n if (browser.isElectron() && options.screenShareAudio\n && (options.desktopStream.indexOf('screen') >= 0)) {\n\n // Provide constraints as described by the electron desktop capturer\n // documentation here:\n // https://www.electronjs.org/docs/api/desktop-capturer\n constraints.audio = { mandatory: {\n chromeMediaSource: constraints.video.mandatory.chromeMediaSource\n } };\n\n delete constraints.video.mandatory.chromeMediaSourceId;\n }\n }\n\n if (options.bandwidth) {\n if (!constraints.video) {\n // same behaviour as true\n constraints.video = { mandatory: {},\n optional: [] };\n }\n constraints.video.optional.push({ bandwidth: options.bandwidth });\n }\n\n // we turn audio for both audio and video tracks, the fake audio & video\n // seems to work only when enabled in one getUserMedia call, we cannot get\n // fake audio separate by fake video this later can be a problem with some\n // of the tests\n if (browser.isFirefox() && options.firefox_fake_device) {\n // seems to be fixed now, removing this experimental fix, as having\n // multiple audio tracks brake the tests\n // constraints.audio = true;\n constraints.fake = true;\n }\n\n return constraints;\n}\n\n/**\n * Creates a constraints object to be passed into a call to getUserMedia.\n *\n * @param {Array} um - An array of user media types to get. The accepted\n * types are \"video\", \"audio\", and \"desktop.\"\n * @param {Object} options - Various values to be added to the constraints.\n * @param {string} options.cameraDeviceId - The device id for the video\n * capture device to get video from.\n * @param {Object} options.constraints - Default constraints object to use\n * as a base for the returned constraints.\n * @param {Object} options.desktopStream - The desktop source id from which\n * to capture a desktop sharing video.\n * @param {string} options.facingMode - Which direction the camera is\n * pointing to.\n * @param {string} options.micDeviceId - The device id for the audio capture\n * device to get audio from.\n * @param {Object} options.frameRate - used only for dekstop sharing.\n * @param {Object} options.frameRate.min - Minimum fps\n * @param {Object} options.frameRate.max - Maximum fps\n * @private\n * @returns {Object}\n */\nfunction newGetConstraints(um = [], options = {}) {\n // Create a deep copy of the constraints to avoid any modification of\n // the passed in constraints object.\n const constraints = JSON.parse(JSON.stringify(\n options.constraints || DEFAULT_CONSTRAINTS));\n\n if (um.indexOf('video') >= 0) {\n if (!constraints.video) {\n constraints.video = {};\n }\n\n if (options.cameraDeviceId) {\n constraints.video.deviceId = options.cameraDeviceId;\n } else {\n const facingMode = options.facingMode || CameraFacingMode.USER;\n\n constraints.video.facingMode = facingMode;\n }\n } else {\n constraints.video = false;\n }\n\n if (um.indexOf('audio') >= 0) {\n if (!constraints.audio || typeof constraints.audio === 'boolean') {\n constraints.audio = {};\n }\n\n // NOTE(brian): the new-style ('advanced' instead of 'optional')\n // doesn't seem to carry through the googXXX constraints\n // Changing back to 'optional' here (even with video using\n // the 'advanced' style) allows them to be passed through\n // but also requires the device id to capture to be set in optional\n // as sourceId otherwise the constraints are considered malformed.\n if (!constraints.audio.optional) {\n constraints.audio.optional = [];\n }\n\n constraints.audio.optional.push(\n { sourceId: options.micDeviceId },\n { echoCancellation: !disableAEC && !disableAP },\n { googEchoCancellation: !disableAEC && !disableAP },\n { googAutoGainControl: !disableAGC && !disableAP },\n { googNoiseSuppression: !disableNS && !disableAP },\n { googHighpassFilter: !disableHPF && !disableAP },\n { googNoiseSuppression2: !disableNS && !disableAP },\n { googEchoCancellation2: !disableAEC && !disableAP },\n { googAutoGainControl2: !disableAGC && !disableAP }\n );\n } else {\n constraints.audio = false;\n }\n\n if (um.indexOf('desktop') >= 0) {\n if (!constraints.video || typeof constraints.video === 'boolean') {\n constraints.video = {};\n }\n\n constraints.video = {\n mandatory: getSSConstraints({\n ...options,\n source: 'desktop'\n })\n };\n }\n\n return constraints;\n}\n\n/**\n * Generates GUM constraints for screen sharing.\n *\n * @param {Object} options - The options passed to\n * obtainAudioAndVideoPermissions.\n * @returns {Object} - GUM constraints.\n *\n * TODO: Currently only the new GUM flow and Chrome is using the method. We\n * should make it work for all use cases.\n */\nfunction getSSConstraints(options = {}) {\n const {\n desktopStream,\n frameRate = {\n min: SS_DEFAULT_FRAME_RATE,\n max: SS_DEFAULT_FRAME_RATE\n }\n } = options;\n const { max, min } = frameRate;\n\n const constraints = {\n chromeMediaSource: options.source,\n maxWidth: window.screen.width,\n maxHeight: window.screen.height\n };\n\n if (typeof min === 'number') {\n constraints.minFrameRate = min;\n }\n\n if (typeof max === 'number') {\n constraints.maxFrameRate = max;\n }\n\n if (typeof desktopStream !== 'undefined') {\n constraints.chromeMediaSourceId = desktopStream;\n }\n\n return constraints;\n}\n\n/**\n * Generates constraints for screen sharing when using getDisplayMedia.\n * The constraints(MediaTrackConstraints) are applied to the resulting track.\n *\n * @returns {Object} - MediaTrackConstraints constraints.\n */\nfunction getTrackSSConstraints(options = {}) {\n // we used to set height and width in the constraints, but this can lead\n // to inconsistencies if the browser is on a lower resolution screen\n // and we share a screen with bigger resolution, so they are now not set\n const constraints = {\n frameRate: SS_DEFAULT_FRAME_RATE\n };\n const { desktopSharingFrameRate } = options;\n\n if (desktopSharingFrameRate && desktopSharingFrameRate.max) {\n constraints.frameRate = desktopSharingFrameRate.max;\n }\n\n return constraints;\n}\n\n/**\n * Updates the granted permissions based on the options we requested and the\n * streams we received.\n * @param um the options we requested to getUserMedia.\n * @param stream the stream we received from calling getUserMedia.\n */\nfunction updateGrantedPermissions(um, stream) {\n const audioTracksReceived\n = Boolean(stream) && stream.getAudioTracks().length > 0;\n const videoTracksReceived\n = Boolean(stream) && stream.getVideoTracks().length > 0;\n const grantedPermissions = {};\n\n if (um.indexOf('video') !== -1) {\n grantedPermissions.video = videoTracksReceived;\n }\n if (um.indexOf('audio') !== -1) {\n grantedPermissions.audio = audioTracksReceived;\n }\n\n eventEmitter.emit(RTCEvents.GRANTED_PERMISSIONS, grantedPermissions);\n}\n\n/**\n * Checks if new list of available media devices differs from previous one.\n * @param {MediaDeviceInfo[]} newDevices - list of new devices.\n * @returns {boolean} - true if list is different, false otherwise.\n */\nfunction compareAvailableMediaDevices(newDevices) {\n if (newDevices.length !== availableDevices.length) {\n return true;\n }\n\n /* eslint-disable newline-per-chained-call */\n\n return (\n newDevices.map(mediaDeviceInfoToJSON).sort().join('')\n !== availableDevices\n .map(mediaDeviceInfoToJSON).sort().join(''));\n\n /* eslint-enable newline-per-chained-call */\n\n /**\n *\n * @param info\n */\n function mediaDeviceInfoToJSON(info) {\n return JSON.stringify({\n kind: info.kind,\n deviceId: info.deviceId,\n groupId: info.groupId,\n label: info.label,\n facing: info.facing\n });\n }\n}\n\n/**\n * Sends analytics event with the passed device list.\n *\n * @param {Array} deviceList - List with info about the\n * available devices.\n * @returns {void}\n */\nfunction sendDeviceListToAnalytics(deviceList) {\n const audioInputDeviceCount\n = deviceList.filter(d => d.kind === 'audioinput').length;\n const audioOutputDeviceCount\n = deviceList.filter(d => d.kind === 'audiooutput').length;\n const videoInputDeviceCount\n = deviceList.filter(d => d.kind === 'videoinput').length;\n const videoOutputDeviceCount\n = deviceList.filter(d => d.kind === 'videooutput').length;\n\n deviceList.forEach(device => {\n const attributes = {\n 'audio_input_device_count': audioInputDeviceCount,\n 'audio_output_device_count': audioOutputDeviceCount,\n 'video_input_device_count': videoInputDeviceCount,\n 'video_output_device_count': videoOutputDeviceCount,\n 'device_id': device.deviceId,\n 'device_group_id': device.groupId,\n 'device_kind': device.kind,\n 'device_label': device.label\n };\n\n Statistics.sendAnalytics(AVAILABLE_DEVICE, attributes);\n });\n}\n\n/**\n * Event handler for the 'devicechange' event.\n *\n * @param {MediaDeviceInfo[]} devices - list of media devices.\n * @emits RTCEvents.DEVICE_LIST_CHANGED\n */\nfunction onMediaDevicesListChanged(devicesReceived) {\n availableDevices = devicesReceived.slice(0);\n logger.info(\n 'list of media devices has changed:',\n availableDevices);\n\n sendDeviceListToAnalytics(availableDevices);\n\n // Used by tracks to update the real device id before the consumer of lib-jitsi-meet receives the new device list.\n eventEmitter.emit(RTCEvents.DEVICE_LIST_WILL_CHANGE, devicesReceived);\n\n eventEmitter.emit(RTCEvents.DEVICE_LIST_CHANGED, devicesReceived);\n}\n\n/**\n * Handles the newly created Media Streams.\n * @param streams the new Media Streams\n * @param resolution the resolution of the video streams\n * @returns {*[]} object that describes the new streams\n */\nfunction handleLocalStream(streams, resolution) {\n let audioStream, desktopStream, videoStream;\n const res = [];\n\n // XXX The function obtainAudioAndVideoPermissions has examined the type of\n // the browser, its capabilities, etc. and has taken the decision whether to\n // invoke getUserMedia per device (e.g. Firefox) or once for both audio and\n // video (e.g. Chrome). In order to not duplicate the logic here, examine\n // the specified streams and figure out what we've received based on\n // obtainAudioAndVideoPermissions' decision.\n if (streams) {\n // As mentioned above, certian types of browser (e.g. Chrome) support\n // (with a result which meets our requirements expressed bellow) calling\n // getUserMedia once for both audio and video.\n const audioVideo = streams.audioVideo;\n\n if (audioVideo) {\n const audioTracks = audioVideo.getAudioTracks();\n\n if (audioTracks.length) {\n audioStream = new MediaStream();\n for (let i = 0; i < audioTracks.length; i++) {\n audioStream.addTrack(audioTracks[i]);\n }\n }\n\n const videoTracks = audioVideo.getVideoTracks();\n\n if (videoTracks.length) {\n videoStream = new MediaStream();\n for (let j = 0; j < videoTracks.length; j++) {\n videoStream.addTrack(videoTracks[j]);\n }\n }\n } else {\n // On other types of browser (e.g. Firefox) we choose (namely,\n // obtainAudioAndVideoPermissions) to call getUserMedia per device\n // (type).\n audioStream = streams.audio;\n videoStream = streams.video;\n }\n\n desktopStream = streams.desktop;\n }\n\n if (desktopStream) {\n const { stream, sourceId, sourceType } = desktopStream;\n\n res.push({\n stream,\n sourceId,\n sourceType,\n track: stream.getVideoTracks()[0],\n mediaType: MediaType.VIDEO,\n videoType: VideoType.DESKTOP\n });\n }\n if (audioStream) {\n res.push({\n stream: audioStream,\n track: audioStream.getAudioTracks()[0],\n mediaType: MediaType.AUDIO,\n videoType: null\n });\n }\n if (videoStream) {\n res.push({\n stream: videoStream,\n track: videoStream.getVideoTracks()[0],\n mediaType: MediaType.VIDEO,\n videoType: VideoType.CAMERA,\n resolution\n });\n }\n\n return res;\n}\n\n/**\n * Represents a default implementation of setting a MediaStream as the\n * source of a video element that tries to be browser-agnostic through feature\n * checking. Note though that it was not completely clear from the predating\n * browser-specific implementations what "videoSrc" was because one\n * implementation of {@link RTCUtils#getVideoSrc} would return\n * MediaStream (e.g. Firefox), another a string representation\n * of the URL of the MediaStream (e.g. Chrome) and the return\n * value was only used by {@link RTCUIHelper#getVideoId} which itself did not\n * appear to be used anywhere. Generally, the implementation will try to follow\n * the related standards i.e. work with the srcObject and src\n * properties of the specified element taking into account vender\n * prefixes.\n *\n * @param element the element whose video source/src is to be set to the\n * specified stream\n * @param {MediaStream} stream the MediaStream to set as the video\n * source/src of element\n */\nfunction defaultSetVideoSrc(element, stream) {\n // srcObject\n let srcObjectPropertyName = 'srcObject';\n\n if (!(srcObjectPropertyName in element)) {\n srcObjectPropertyName = 'mozSrcObject';\n if (!(srcObjectPropertyName in element)) {\n srcObjectPropertyName = null;\n }\n }\n if (srcObjectPropertyName) {\n element[srcObjectPropertyName] = stream;\n\n return;\n }\n\n // src\n let src;\n\n if (stream) {\n src = stream.jitsiObjectURL;\n\n // Save the created URL for stream so we can reuse it and not keep\n // creating URLs.\n if (!src) {\n stream.jitsiObjectURL = src = URL.createObjectURL(stream);\n }\n }\n element.src = src || '';\n}\n\n/**\n *\n */\nclass RTCUtils extends Listenable {\n /**\n *\n */\n constructor() {\n super(eventEmitter);\n }\n\n /**\n * Depending on the browser, sets difference instance methods for\n * interacting with user media and adds methods to native WebRTC-related\n * objects. Also creates an instance variable for peer connection\n * constraints.\n *\n * @param {Object} options\n * @returns {void}\n */\n init(options = {}) {\n if (typeof options.disableAEC === 'boolean') {\n disableAEC = options.disableAEC;\n logger.info(`Disable AEC: ${disableAEC}`);\n }\n if (typeof options.disableNS === 'boolean') {\n disableNS = options.disableNS;\n logger.info(`Disable NS: ${disableNS}`);\n }\n if (typeof options.disableAP === 'boolean') {\n disableAP = options.disableAP;\n logger.info(`Disable AP: ${disableAP}`);\n }\n if (typeof options.disableAGC === 'boolean') {\n disableAGC = options.disableAGC;\n logger.info(`Disable AGC: ${disableAGC}`);\n }\n if (typeof options.disableHPF === 'boolean') {\n disableHPF = options.disableHPF;\n logger.info(`Disable HPF: ${disableHPF}`);\n }\n\n availableDevices = undefined;\n window.clearInterval(availableDevicesPollTimer);\n availableDevicesPollTimer = undefined;\n\n this.enumerateDevices = initEnumerateDevicesWithCallback();\n\n if (browser.usesNewGumFlow()) {\n this.RTCPeerConnectionType = RTCPeerConnection;\n\n this.attachMediaStream\n = wrapAttachMediaStream((element, stream) => {\n if (element) {\n element.srcObject = stream;\n }\n });\n\n this.getStreamID = ({ id }) => id;\n this.getTrackID = ({ id }) => id;\n } else if (browser.isChromiumBased() // this is chrome < 61\n || browser.isReactNative()) {\n\n this.RTCPeerConnectionType = RTCPeerConnection;\n\n this.attachMediaStream\n = wrapAttachMediaStream((element, stream) => {\n defaultSetVideoSrc(element, stream);\n\n return element;\n });\n\n this.getStreamID = function({ id }) {\n // A. MediaStreams from FF endpoints have the characters '{' and\n // '}' that make jQuery choke.\n // B. The react-native-webrtc implementation that we use at the\n // time of this writing returns a number for the id of\n // MediaStream. Let's just say that a number contains no special\n // characters.\n return (\n typeof id === 'number'\n ? id\n : SDPUtil.filterSpecialChars(id));\n };\n this.getTrackID = ({ id }) => id;\n\n if (!MediaStream.prototype.getVideoTracks) {\n MediaStream.prototype.getVideoTracks = function() {\n return this.videoTracks;\n };\n }\n if (!MediaStream.prototype.getAudioTracks) {\n MediaStream.prototype.getAudioTracks = function() {\n return this.audioTracks;\n };\n }\n } else {\n const message = 'Endpoint does not appear to be WebRTC-capable';\n\n logger.error(message);\n throw new Error(message);\n }\n\n this._initPCConstraints(options);\n\n screenObtainer.init(\n options,\n this.getUserMediaWithConstraints.bind(this));\n\n if (this.isDeviceListAvailable()) {\n this.enumerateDevices(ds => {\n availableDevices = ds.splice(0);\n\n logger.debug('Available devices: ', availableDevices);\n sendDeviceListToAnalytics(availableDevices);\n\n eventEmitter.emit(\n RTCEvents.DEVICE_LIST_AVAILABLE,\n availableDevices);\n\n\n // Use a shared callback to handle both the devicechange event\n // and the polling implementations. This prevents duplication\n // and works around a chrome bug (verified to occur on 68) where\n // devicechange fires twice in a row, which can cause async post\n // devicechange processing to collide.\n const updateKnownDevices = () => this.enumerateDevices(pds => {\n if (compareAvailableMediaDevices(pds)) {\n onMediaDevicesListChanged(pds);\n }\n });\n\n if (browser.supportsDeviceChangeEvent()) {\n navigator.mediaDevices.addEventListener(\n 'devicechange',\n updateKnownDevices);\n } else {\n // Periodically poll enumerateDevices() method to check if\n // list of media devices has changed.\n availableDevicesPollTimer = window.setInterval(\n updateKnownDevices,\n AVAILABLE_DEVICES_POLL_INTERVAL_TIME);\n }\n });\n }\n }\n\n /**\n * Creates instance objects for peer connection constraints both for p2p\n * and outside of p2p.\n *\n * @params {Object} options - Configuration for setting RTCUtil's instance\n * objects for peer connection constraints.\n * @params {boolean} options.useIPv6 - Set to true if IPv6 should be used.\n * @params {Object} options.testing - Additional configuration for work in\n * development.\n * @params {Object} options.testing.forceP2PSuspendVideoRatio - True if\n * video should become suspended if bandwidth estimation becomes low while\n * in peer to peer connection mode.\n */\n _initPCConstraints(options) {\n if (browser.isFirefox()) {\n this.pcConstraints = {};\n } else if (browser.isChromiumBased() || browser.isReactNative()) {\n this.pcConstraints = { optional: [\n { googHighStartBitrate: 0 },\n { googPayloadPadding: true },\n { googScreencastMinBitrate: 100 },\n { googCpuOveruseDetection: true },\n { googCpuOveruseEncodeUsage: true },\n { googCpuUnderuseThreshold: 55 },\n { googCpuOveruseThreshold: 85 }\n ] };\n\n if (options.useIPv6) {\n // https://code.google.com/p/webrtc/issues/detail?id=2828\n this.pcConstraints.optional.push({ googIPv6: true });\n }\n\n this.p2pPcConstraints\n = JSON.parse(JSON.stringify(this.pcConstraints));\n }\n\n this.p2pPcConstraints = this.p2pPcConstraints || this.pcConstraints;\n }\n\n /* eslint-disable max-params */\n\n /**\n * @param {string[]} um required user media types\n * @param {Object} [options] optional parameters\n * @param {string} options.resolution\n * @param {number} options.bandwidth\n * @param {number} options.fps\n * @param {string} options.desktopStream\n * @param {string} options.cameraDeviceId\n * @param {string} options.micDeviceId\n * @param {Object} options.frameRate - used only for dekstop sharing.\n * @param {Object} options.frameRate.min - Minimum fps\n * @param {Object} options.frameRate.max - Maximum fps\n * @param {bool} options.screenShareAudio - Used by electron clients to\n * enable system audio screen sharing.\n * @returns {Promise} Returns a media stream on success or a JitsiTrackError\n * on failure.\n **/\n getUserMediaWithConstraints(um, options = {}) {\n const constraints = getConstraints(um, options);\n\n logger.info('Get media constraints', constraints);\n\n return new Promise((resolve, reject) => {\n navigator.mediaDevices.getUserMedia(constraints)\n .then(stream => {\n logger.log('onUserMediaSuccess');\n updateGrantedPermissions(um, stream);\n resolve(stream);\n })\n .catch(error => {\n logger.warn('Failed to get access to local media. '\n + ` ${error} ${constraints} `);\n updateGrantedPermissions(um, undefined);\n reject(new JitsiTrackError(error, constraints, um));\n });\n });\n }\n\n /**\n * Acquires a media stream via getUserMedia that\n * matches the given constraints\n *\n * @param {array} umDevices which devices to acquire (e.g. audio, video)\n * @param {Object} constraints - Stream specifications to use.\n * @returns {Promise}\n */\n _newGetUserMediaWithConstraints(umDevices, constraints = {}) {\n return new Promise((resolve, reject) => {\n navigator.mediaDevices.getUserMedia(constraints)\n .then(stream => {\n logger.log('onUserMediaSuccess');\n updateGrantedPermissions(umDevices, stream);\n resolve(stream);\n })\n .catch(error => {\n logger.warn('Failed to get access to local media. '\n + ` ${error} ${constraints} `);\n updateGrantedPermissions(umDevices, undefined);\n reject(new JitsiTrackError(error, constraints, umDevices));\n });\n });\n }\n\n /**\n * Acquire a display stream via the screenObtainer. This requires extra\n * logic compared to use screenObtainer versus normal device capture logic\n * in RTCUtils#_newGetUserMediaWithConstraints.\n *\n * @param {Object} options\n * @param {Object} options.desktopSharingExtensionExternalInstallation\n * @param {string[]} options.desktopSharingSources\n * @param {Object} options.desktopSharingFrameRate\n * @param {Object} options.desktopSharingFrameRate.min - Minimum fps\n * @param {Object} options.desktopSharingFrameRate.max - Maximum fps\n * @returns {Promise} A promise which will be resolved with an object which\n * contains the acquired display stream. If desktop sharing is not supported\n * then a rejected promise will be returned.\n */\n _newGetDesktopMedia(options) {\n if (!screenObtainer.isSupported() || !browser.supportsVideo()) {\n return Promise.reject(\n new Error('Desktop sharing is not supported!'));\n }\n\n return new Promise((resolve, reject) => {\n screenObtainer.obtainStream(\n this._parseDesktopSharingOptions(options),\n stream => {\n resolve(stream);\n },\n error => {\n reject(error);\n });\n });\n }\n\n /* eslint-enable max-params */\n\n /**\n * Creates the local MediaStreams.\n * @param {Object} [options] optional parameters\n * @param {Array} options.devices the devices that will be requested\n * @param {string} options.resolution resolution constraints\n * @param {string} options.cameraDeviceId\n * @param {string} options.micDeviceId\n * @param {Object} options.desktopSharingFrameRate\n * @param {Object} options.desktopSharingFrameRate.min - Minimum fps\n * @param {Object} options.desktopSharingFrameRate.max - Maximum fps\n * @returns {*} Promise object that will receive the new JitsiTracks\n */\n obtainAudioAndVideoPermissions(options = {}) {\n options.devices = options.devices || [ ...OLD_GUM_DEFAULT_DEVICES ];\n options.resolution = options.resolution || OLD_GUM_DEFAULT_RESOLUTION;\n\n const requestingDesktop = options.devices.includes('desktop');\n\n if (requestingDesktop && !screenObtainer.isSupported()) {\n return Promise.reject(\n new Error('Desktop sharing is not supported!'));\n }\n\n return this._getAudioAndVideoStreams(options).then(streams =>\n handleLocalStream(streams, options.resolution));\n }\n\n /**\n * Performs one call to getUserMedia for audio and/or video and another call\n * for desktop.\n *\n * @param {Object} options - An object describing how the gUM request should\n * be executed. See {@link obtainAudioAndVideoPermissions} for full options.\n * @returns {*} Promise object that will receive the new JitsiTracks on\n * success or a JitsiTrackError on failure.\n */\n _getAudioAndVideoStreams(options) {\n const requestingDesktop = options.devices.includes('desktop');\n\n options.devices = options.devices.filter(device =>\n device !== 'desktop');\n\n const gumPromise = options.devices.length\n ? this.getUserMediaWithConstraints(options.devices, options)\n : Promise.resolve(null);\n\n return gumPromise\n .then(avStream => {\n // If any requested devices are missing, call gum again in\n // an attempt to obtain the actual error. For example, the\n // requested video device is missing or permission was\n // denied.\n const missingTracks\n = this._getMissingTracks(options.devices, avStream);\n\n if (missingTracks.length) {\n this.stopMediaStream(avStream);\n\n return this.getUserMediaWithConstraints(\n missingTracks, options)\n\n // GUM has already failed earlier and this success\n // handling should not be reached.\n .then(() => Promise.reject(new JitsiTrackError(\n { name: 'UnknownError' },\n getConstraints(options.devices, options),\n missingTracks)));\n }\n\n return avStream;\n })\n .then(audioVideo => {\n if (!requestingDesktop) {\n return { audioVideo };\n }\n\n if (options.desktopSharingSourceDevice) {\n this.stopMediaStream(audioVideo);\n\n throw new Error('Using a camera as screenshare source is'\n + 'not supported on this browser.');\n }\n\n return new Promise((resolve, reject) => {\n screenObtainer.obtainStream(\n this._parseDesktopSharingOptions(options),\n desktop => resolve({\n audioVideo,\n desktop\n }),\n error => {\n if (audioVideo) {\n this.stopMediaStream(audioVideo);\n }\n reject(error);\n });\n });\n });\n }\n\n /**\n * Private utility for determining if the passed in MediaStream contains\n * tracks of the type(s) specified in the requested devices.\n *\n * @param {string[]} requestedDevices - The track types that are expected to\n * be includes in the stream.\n * @param {MediaStream} stream - The MediaStream to check if it has the\n * expected track types.\n * @returns {string[]} An array of string with the missing track types. The\n * array will be empty if all requestedDevices are found in the stream.\n */\n _getMissingTracks(requestedDevices = [], stream) {\n const missingDevices = [];\n\n const audioDeviceRequested = requestedDevices.includes('audio');\n const audioTracksReceived\n = stream && stream.getAudioTracks().length > 0;\n\n if (audioDeviceRequested && !audioTracksReceived) {\n missingDevices.push('audio');\n }\n\n const videoDeviceRequested = requestedDevices.includes('video');\n const videoTracksReceived\n = stream && stream.getVideoTracks().length > 0;\n\n if (videoDeviceRequested && !videoTracksReceived) {\n missingDevices.push('video');\n }\n\n return missingDevices;\n }\n\n /**\n * Returns an object formatted for specifying desktop sharing parameters.\n *\n * @param {Object} options - Takes in the same options object as\n * {@link obtainAudioAndVideoPermissions}.\n * @returns {Object}\n */\n _parseDesktopSharingOptions(options) {\n return {\n ...options.desktopSharingExtensionExternalInstallation,\n desktopSharingSources: options.desktopSharingSources,\n gumOptions: {\n frameRate: options.desktopSharingFrameRate\n },\n trackOptions: getTrackSSConstraints(options)\n };\n }\n\n /**\n * Gets streams from specified device types. This function intentionally\n * ignores errors for upstream to catch and handle instead.\n *\n * @param {Object} options - A hash describing what devices to get and\n * relevant constraints.\n * @param {string[]} options.devices - The types of media to capture. Valid\n * values are \"desktop\", \"audio\", and \"video\".\n * @param {Object} options.desktopSharingFrameRate\n * @param {Object} options.desktopSharingFrameRate.min - Minimum fps\n * @param {Object} options.desktopSharingFrameRate.max - Maximum fps\n * @param {String} options.desktopSharingSourceDevice - The device id or\n * label for a video input source that should be used for screensharing.\n * @returns {Promise} The promise, when successful, will return an array of\n * meta data for the requested device type, which includes the stream and\n * track. If an error occurs, it will be deferred to the caller for\n * handling.\n */\n newObtainAudioAndVideoPermissions(options) {\n logger.info('Using the new gUM flow');\n\n const mediaStreamsMetaData = [];\n\n // Declare private functions to be used in the promise chain below.\n // These functions are declared in the scope of this function because\n // they are not being used anywhere else, so only this function needs to\n // know about them.\n\n /**\n * Executes a request for desktop media if specified in options.\n *\n * @returns {Promise}\n */\n const maybeRequestDesktopDevice = function() {\n const umDevices = options.devices || [];\n const isDesktopDeviceRequested\n = umDevices.indexOf('desktop') !== -1;\n\n if (!isDesktopDeviceRequested) {\n return Promise.resolve();\n }\n\n const {\n desktopSharingExtensionExternalInstallation,\n desktopSharingSourceDevice,\n desktopSharingSources,\n desktopSharingFrameRate\n } = options;\n\n // Attempt to use a video input device as a screenshare source if\n // the option is defined.\n if (desktopSharingSourceDevice) {\n const matchingDevice\n = availableDevices && availableDevices.find(device =>\n device.kind === 'videoinput'\n && (device.deviceId === desktopSharingSourceDevice\n || device.label === desktopSharingSourceDevice));\n\n if (!matchingDevice) {\n return Promise.reject(new JitsiTrackError(\n { name: 'ConstraintNotSatisfiedError' },\n {},\n [ desktopSharingSourceDevice ]\n ));\n }\n\n const requestedDevices = [ 'video' ];\n\n // Leverage the helper used by {@link _newGetDesktopMedia} to\n // get constraints for the desktop stream.\n const { gumOptions, trackOptions }\n = this._parseDesktopSharingOptions(options);\n\n const constraints = {\n video: {\n ...gumOptions,\n deviceId: matchingDevice.deviceId\n }\n };\n\n return this._newGetUserMediaWithConstraints(\n requestedDevices, constraints)\n .then(stream => {\n const track = stream && stream.getTracks()[0];\n const applyConstrainsPromise\n = track && track.applyConstraints\n ? track.applyConstraints(trackOptions)\n : Promise.resolve();\n\n return applyConstrainsPromise\n .then(() => {\n return {\n sourceType: 'device',\n stream\n };\n });\n });\n }\n\n return this._newGetDesktopMedia({\n desktopSharingExtensionExternalInstallation,\n desktopSharingSources,\n desktopSharingFrameRate\n });\n }.bind(this);\n\n /**\n * Creates a meta data object about the passed in desktopStream and\n * pushes the meta data to the internal array mediaStreamsMetaData to be\n * returned later.\n *\n * @param {MediaStreamTrack} desktopStream - A track for a desktop\n * capture.\n * @returns {void}\n */\n const maybeCreateAndAddDesktopTrack = function(desktopStream) {\n if (!desktopStream) {\n return;\n }\n\n const { stream, sourceId, sourceType } = desktopStream;\n\n const desktopAudioTracks = stream.getAudioTracks();\n\n if (desktopAudioTracks.length) {\n const desktopAudioStream = new MediaStream(desktopAudioTracks);\n\n mediaStreamsMetaData.push({\n stream: desktopAudioStream,\n sourceId,\n sourceType,\n track: desktopAudioStream.getAudioTracks()[0]\n });\n }\n\n const desktopVideoTracks = stream.getVideoTracks();\n\n if (desktopVideoTracks.length) {\n const desktopVideoStream = new MediaStream(desktopVideoTracks);\n\n mediaStreamsMetaData.push({\n stream: desktopVideoStream,\n sourceId,\n sourceType,\n track: desktopVideoStream.getVideoTracks()[0],\n videoType: VideoType.DESKTOP\n });\n }\n };\n\n /**\n * Executes a request for audio and/or video, as specified in options.\n * By default both audio and video will be captured if options.devices\n * is not defined.\n *\n * @returns {Promise}\n */\n const maybeRequestCaptureDevices = function() {\n const umDevices = options.devices || [ 'audio', 'video' ];\n const requestedCaptureDevices = umDevices.filter(device =>\n device === 'audio'\n || (device === 'video' && browser.supportsVideo()));\n\n if (!requestedCaptureDevices.length) {\n return Promise.resolve();\n }\n\n const constraints = newGetConstraints(\n requestedCaptureDevices, options);\n\n logger.info('Got media constraints: ', constraints);\n\n return this._newGetUserMediaWithConstraints(\n requestedCaptureDevices, constraints);\n }.bind(this);\n\n /**\n * Splits the passed in media stream into separate audio and video\n * streams and creates meta data objects for each and pushes them to the\n * internal array mediaStreamsMetaData to be returned later.\n *\n * @param {MediaStreamTrack} avStream - A track for with audio and/or\n * video track.\n * @returns {void}\n */\n const maybeCreateAndAddAVTracks = function(avStream) {\n if (!avStream) {\n return;\n }\n\n const audioTracks = avStream.getAudioTracks();\n\n if (audioTracks.length) {\n const audioStream = new MediaStream(audioTracks);\n\n mediaStreamsMetaData.push({\n stream: audioStream,\n track: audioStream.getAudioTracks()[0],\n effects: options.effects\n });\n }\n\n const videoTracks = avStream.getVideoTracks();\n\n if (videoTracks.length) {\n const videoStream = new MediaStream(videoTracks);\n\n mediaStreamsMetaData.push({\n stream: videoStream,\n track: videoStream.getVideoTracks()[0],\n videoType: VideoType.CAMERA,\n effects: options.effects\n });\n }\n };\n\n return maybeRequestDesktopDevice()\n .then(maybeCreateAndAddDesktopTrack)\n .then(maybeRequestCaptureDevices)\n .then(maybeCreateAndAddAVTracks)\n .then(() => mediaStreamsMetaData)\n .catch(error => {\n mediaStreamsMetaData.forEach(({ stream }) => {\n this.stopMediaStream(stream);\n });\n\n return Promise.reject(error);\n });\n }\n\n /**\n * Checks whether it is possible to enumerate available cameras/microphones.\n *\n * @returns {boolean} {@code true} if the device listing is available;\n * {@code false}, otherwise.\n */\n isDeviceListAvailable() {\n return Boolean(\n navigator.mediaDevices\n && navigator.mediaDevices.enumerateDevices);\n }\n\n /**\n * Returns true if changing the input (camera / microphone) or output\n * (audio) device is supported and false if not.\n * @params {string} [deviceType] - type of device to change. Default is\n * undefined or 'input', 'output' - for audio output device change.\n * @returns {boolean} true if available, false otherwise.\n */\n isDeviceChangeAvailable(deviceType) {\n return deviceType === 'output' || deviceType === 'audiooutput'\n ? isAudioOutputDeviceChangeAvailable\n : true;\n }\n\n /**\n * A method to handle stopping of the stream.\n * One point to handle the differences in various implementations.\n * @param mediaStream MediaStream object to stop.\n */\n stopMediaStream(mediaStream) {\n if (!mediaStream) {\n return;\n }\n\n mediaStream.getTracks().forEach(track => {\n if (track.stop) {\n track.stop();\n }\n });\n\n // leave stop for implementation still using it\n if (mediaStream.stop) {\n mediaStream.stop();\n }\n\n // The MediaStream implementation of the react-native-webrtc project has\n // an explicit release method that is to be invoked in order to release\n // used resources such as memory.\n if (mediaStream.release) {\n mediaStream.release();\n }\n\n // if we have done createObjectURL, lets clean it\n const url = mediaStream.jitsiObjectURL;\n\n if (url) {\n delete mediaStream.jitsiObjectURL;\n URL.revokeObjectURL(url);\n }\n }\n\n /**\n * Returns whether the desktop sharing is enabled or not.\n * @returns {boolean}\n */\n isDesktopSharingEnabled() {\n return screenObtainer.isSupported();\n }\n\n /**\n * Sets current audio output device.\n * @param {string} deviceId - id of 'audiooutput' device from\n * navigator.mediaDevices.enumerateDevices(), 'default' for default\n * device\n * @returns {Promise} - resolves when audio output is changed, is rejected\n * otherwise\n */\n setAudioOutputDevice(deviceId) {\n if (!this.isDeviceChangeAvailable('output')) {\n return Promise.reject(\n new Error('Audio output device change is not supported'));\n }\n\n return featureDetectionAudioEl.setSinkId(deviceId)\n .then(() => {\n audioOutputDeviceId = deviceId;\n audioOutputChanged = true;\n\n logger.log(`Audio output device set to ${deviceId}`);\n\n eventEmitter.emit(RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,\n deviceId);\n });\n }\n\n /**\n * Returns currently used audio output device id, '' stands for default\n * device\n * @returns {string}\n */\n getAudioOutputDevice() {\n return audioOutputDeviceId;\n }\n\n /**\n * Returns list of available media devices if its obtained, otherwise an\n * empty array is returned/\n * @returns {Array} list of available media devices.\n */\n getCurrentlyAvailableMediaDevices() {\n return availableDevices;\n }\n\n /**\n * Returns event data for device to be reported to stats.\n * @returns {MediaDeviceInfo} device.\n */\n getEventDataForActiveDevice(device) {\n const deviceList = [];\n const deviceData = {\n 'deviceId': device.deviceId,\n 'kind': device.kind,\n 'label': device.label,\n 'groupId': device.groupId\n };\n\n deviceList.push(deviceData);\n\n return { deviceList };\n }\n\n /**\n * Configures the given PeerConnection constraints to either enable or\n * disable (according to the value of the 'enable' parameter) the\n * 'googSuspendBelowMinBitrate' option.\n * @param constraints the constraints on which to operate.\n * @param enable {boolean} whether to enable or disable the suspend video\n * option.\n */\n setSuspendVideo(constraints, enable) {\n if (!constraints.optional) {\n constraints.optional = [];\n }\n\n // Get rid of all \"googSuspendBelowMinBitrate\" constraints (we assume\n // that the elements of constraints.optional contain a single property).\n constraints.optional\n = constraints.optional.filter(\n c => !c.hasOwnProperty('googSuspendBelowMinBitrate'));\n\n if (enable) {\n constraints.optional.push({ googSuspendBelowMinBitrate: 'true' });\n }\n }\n}\n\nconst rtcUtils = new RTCUtils();\n\n/**\n * Wraps original attachMediaStream function to set current audio output device\n * if this is supported.\n * @param {Function} origAttachMediaStream\n * @returns {Function}\n */\nfunction wrapAttachMediaStream(origAttachMediaStream) {\n return function(element, stream) {\n // eslint-disable-next-line prefer-rest-params\n const res = origAttachMediaStream.apply(rtcUtils, arguments);\n\n if (stream\n && rtcUtils.isDeviceChangeAvailable('output')\n && stream.getAudioTracks\n && stream.getAudioTracks().length\n\n // we skip setting audio output if there was no explicit change\n && audioOutputChanged) {\n element.setSinkId(rtcUtils.getAudioOutputDevice())\n .catch(function(ex) {\n const err\n = new JitsiTrackError(ex, null, [ 'audiooutput' ]);\n\n GlobalOnErrorHandler.callUnhandledRejectionHandler({\n promise: this, // eslint-disable-line no-invalid-this\n reason: err\n });\n\n logger.warn(\n 'Failed to set audio output device for the element.'\n + ' Default audio output device will be used'\n + ' instead',\n element,\n err);\n });\n }\n\n return res;\n };\n}\n\nexport default rtcUtils;\n", "/**\n * This utility class defines custom onerror and onunhandledrejection functions.\n * The custom error handlers respect the previously-defined error handlers.\n * GlobalOnErrorHandler class provides utilities to add many custom error\n * handlers and to execute the error handlers directly.\n */\n\n\n/**\n * List with global error handlers that will be executed.\n */\nconst handlers = [];\n\n// If an old handler exists, also fire its events.\nconst oldOnErrorHandler = window.onerror;\n\n/**\n * Custom error handler that calls the old global error handler and executes\n * all handlers that were previously added.\n */\nfunction JitsiGlobalErrorHandler(...args) {\n handlers.forEach(handler => handler(...args));\n oldOnErrorHandler && oldOnErrorHandler(...args);\n}\n\n// If an old handler exists, also fire its events.\nconst oldOnUnhandledRejection = window.onunhandledrejection;\n\n/**\n * Custom handler that calls the old global handler and executes all handlers\n * that were previously added. This handler handles rejected Promises.\n */\nfunction JitsiGlobalUnhandledRejection(event) {\n handlers.forEach(handler => handler(null, null, null, null, event.reason));\n oldOnUnhandledRejection && oldOnUnhandledRejection(event);\n}\n\n// Setting the custom error handlers.\nwindow.onerror = JitsiGlobalErrorHandler;\nwindow.onunhandledrejection = JitsiGlobalUnhandledRejection;\n\nconst GlobalOnErrorHandler = {\n /**\n * Adds new error handlers.\n * @param handler the new handler.\n */\n addHandler(handler) {\n handlers.push(handler);\n },\n\n /**\n * Calls the global error handler if there is one.\n * @param error the error to pass to the error handler\n */\n callErrorHandler(error) {\n const errHandler = window.onerror;\n\n if (!errHandler) {\n return;\n }\n errHandler(null, null, null, null, error);\n },\n\n /**\n * Calls the global rejection handler if there is one.\n * @param error the error to pass to the rejection handler.\n */\n callUnhandledRejectionHandler(error) {\n const errHandler = window.onunhandledrejection;\n\n if (!errHandler) {\n return;\n }\n errHandler(error);\n }\n};\n\n\nmodule.exports = GlobalOnErrorHandler;\n", "/* global __filename */\n\nimport { getLogger } from 'jitsi-meet-logger';\n\nimport BridgeChannel from './BridgeChannel';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport * as JitsiConferenceEvents from '../../JitsiConferenceEvents';\nimport JitsiLocalTrack from './JitsiLocalTrack';\nimport Listenable from '../util/Listenable';\nimport { safeCounterIncrement } from '../util/MathUtil';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport browser from '../browser';\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport RTCUtils from './RTCUtils';\nimport Statistics from '../statistics/statistics';\nimport TraceablePeerConnection from './TraceablePeerConnection';\nimport VideoType from '../../service/RTC/VideoType';\n\nconst logger = getLogger(__filename);\n\n/**\n * The counter used to generated id numbers assigned to peer connections\n * @type {number}\n */\nlet peerConnectionIdCounter = 0;\n\n/**\n * The counter used to generate id number for the local\n * MediaStreamTracks.\n * @type {number}\n */\nlet rtcTrackIdCounter = 0;\n\n/**\n *\n * @param tracksInfo\n * @param options\n */\nfunction createLocalTracks(tracksInfo, options) {\n const newTracks = [];\n let deviceId = null;\n\n tracksInfo.forEach(trackInfo => {\n if (trackInfo.mediaType === MediaType.AUDIO) {\n deviceId = options.micDeviceId;\n } else if (trackInfo.videoType === VideoType.CAMERA) {\n deviceId = options.cameraDeviceId;\n }\n rtcTrackIdCounter = safeCounterIncrement(rtcTrackIdCounter);\n const localTrack = new JitsiLocalTrack({\n ...trackInfo,\n deviceId,\n facingMode: options.facingMode,\n rtcId: rtcTrackIdCounter,\n effects: options.effects\n });\n\n newTracks.push(localTrack);\n });\n\n return newTracks;\n}\n\n/**\n * Creates {@code JitsiLocalTrack} instances from the passed in meta information\n * about MedieaTracks.\n *\n * @param {Object[]} mediaStreamMetaData - An array of meta information with\n * MediaTrack instances. Each can look like:\n * {{\n * stream: MediaStream instance that holds a track with audio or video,\n * track: MediaTrack within the MediaStream,\n * videoType: \"camera\" or \"desktop\" or falsy,\n * sourceId: ID of the desktopsharing source,\n * sourceType: The desktopsharing source type,\n * effects: Array of effect types\n * }}\n */\nfunction _newCreateLocalTracks(mediaStreamMetaData = []) {\n return mediaStreamMetaData.map(metaData => {\n const {\n sourceId,\n sourceType,\n stream,\n track,\n videoType,\n effects\n } = metaData;\n\n const { deviceId, facingMode } = track.getSettings();\n\n // FIXME Move rtcTrackIdCounter to a static method in JitsiLocalTrack\n // so RTC does not need to handle ID management. This move would be\n // safer to do once the old createLocalTracks is removed.\n rtcTrackIdCounter = safeCounterIncrement(rtcTrackIdCounter);\n\n return new JitsiLocalTrack({\n deviceId,\n facingMode,\n mediaType: track.kind,\n rtcId: rtcTrackIdCounter,\n sourceId,\n sourceType,\n stream,\n track,\n videoType: videoType || null,\n effects\n });\n });\n}\n\n/**\n *\n */\nexport default class RTC extends Listenable {\n /**\n *\n * @param conference\n * @param options\n */\n constructor(conference, options = {}) {\n super();\n this.conference = conference;\n\n /**\n * A map of active TraceablePeerConnection.\n * @type {Map.}\n */\n this.peerConnections = new Map();\n\n this.localTracks = [];\n\n this.options = options;\n\n // BridgeChannel instance.\n // @private\n // @type {BridgeChannel}\n this._channel = null;\n\n // A flag whether we had received that the channel had opened we can\n // get this flag out of sync if for some reason channel got closed\n // from server, a desired behaviour so we can see errors when this\n // happen.\n // @private\n // @type {boolean}\n this._channelOpen = false;\n\n /**\n * The value specified to the last invocation of setLastN before the\n * channel completed opening. If non-null, the value will be sent\n * through a channel (once) as soon as it opens and will then be\n * discarded.\n * @private\n * @type {number}\n */\n this._lastN = -1;\n\n /**\n * Defines the last N endpoints list. It can be null or an array once\n * initialised with a channel last N event.\n * @type {Array|null}\n * @private\n */\n this._lastNEndpoints = null;\n\n /**\n * The number representing the maximum video height the local client\n * should receive from the bridge.\n *\n * @type {number|undefined}\n * @private\n */\n this._maxFrameHeight = undefined;\n\n /**\n * The endpoint ID of currently pinned participant or null if\n * no user is pinned.\n * @type {string|null}\n * @private\n */\n this._pinnedEndpoint = null;\n\n /**\n * The endpoint IDs of currently selected participants.\n *\n * @type {Array}\n * @private\n */\n this._selectedEndpoints = [];\n\n // The last N change listener.\n this._lastNChangeListener = this._onLastNChanged.bind(this);\n\n this._onDeviceListChanged = this._onDeviceListChanged.bind(this);\n this._updateAudioOutputForAudioTracks\n = this._updateAudioOutputForAudioTracks.bind(this);\n\n // Switch audio output device on all remote audio tracks. Local audio\n // tracks handle this event by themselves.\n if (RTCUtils.isDeviceChangeAvailable('output')) {\n RTCUtils.addListener(\n RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,\n this._updateAudioOutputForAudioTracks\n );\n\n RTCUtils.addListener(\n RTCEvents.DEVICE_LIST_CHANGED,\n this._onDeviceListChanged\n );\n }\n }\n\n /**\n * Removes any listeners and stored state from this {@code RTC} instance.\n *\n * @returns {void}\n */\n destroy() {\n RTCUtils.removeListener(\n RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,\n this._updateAudioOutputForAudioTracks\n );\n\n RTCUtils.removeListener(\n RTCEvents.DEVICE_LIST_CHANGED,\n this._onDeviceListChanged\n );\n\n this.removeListener(\n RTCEvents.LASTN_ENDPOINT_CHANGED,\n this._lastNChangeListener\n );\n\n if (this._channelOpenListener) {\n this.removeListener(\n RTCEvents.DATA_CHANNEL_OPEN,\n this._channelOpenListener\n );\n }\n }\n\n /**\n * Exposes the private helper for converting a WebRTC MediaStream to a\n * JitsiLocalTrack.\n *\n * @param {Array} tracksInfo\n * @returns {Array}\n */\n static newCreateLocalTracks(tracksInfo) {\n return _newCreateLocalTracks(tracksInfo);\n }\n\n /**\n * Creates the local MediaStreams.\n * @param {object} [options] Optional parameters.\n * @param {array} options.devices The devices that will be requested.\n * @param {string} options.resolution Resolution constraints.\n * @param {string} options.cameraDeviceId\n * @param {string} options.micDeviceId\n * @returns {*} Promise object that will receive the new JitsiTracks\n */\n static obtainAudioAndVideoPermissions(options) {\n const usesNewGumFlow = browser.usesNewGumFlow();\n const obtainMediaPromise = usesNewGumFlow\n ? RTCUtils.newObtainAudioAndVideoPermissions(options)\n : RTCUtils.obtainAudioAndVideoPermissions(options);\n\n return obtainMediaPromise.then(tracksInfo => {\n if (usesNewGumFlow) {\n return _newCreateLocalTracks(tracksInfo);\n }\n\n return createLocalTracks(tracksInfo, options);\n });\n }\n\n /**\n * Initializes the bridge channel of this instance.\n * At least one of both, peerconnection or wsUrl parameters, must be\n * given.\n * @param {RTCPeerConnection} [peerconnection] WebRTC peer connection\n * instance.\n * @param {string} [wsUrl] WebSocket URL.\n */\n initializeBridgeChannel(peerconnection, wsUrl) {\n this._channel = new BridgeChannel(\n peerconnection, wsUrl, this.eventEmitter);\n\n this._channelOpenListener = () => {\n // Mark that channel as opened.\n this._channelOpen = true;\n\n // When the channel becomes available, tell the bridge about\n // video selections so that it can do adaptive simulcast,\n // we want the notification to trigger even if userJid\n // is undefined, or null.\n try {\n this._channel.sendPinnedEndpointMessage(\n this._pinnedEndpoint);\n this._channel.sendSelectedEndpointsMessage(\n this._selectedEndpoints);\n\n if (typeof this._maxFrameHeight !== 'undefined') {\n this._channel.sendReceiverVideoConstraintMessage(\n this._maxFrameHeight);\n }\n } catch (error) {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error(\n `Cannot send selected(${this._selectedEndpoint})`\n + `pinned(${this._pinnedEndpoint})`\n + `frameHeight(${this._maxFrameHeight}) endpoint message`,\n error);\n }\n\n this.removeListener(RTCEvents.DATA_CHANNEL_OPEN,\n this._channelOpenListener);\n this._channelOpenListener = null;\n\n // If setLastN was invoked before the bridge channel completed\n // opening, apply the specified value now that the channel\n // is open. NOTE that -1 is the default value assumed by both\n // RTC module and the JVB.\n if (this._lastN !== -1) {\n this._channel.sendSetLastNMessage(this._lastN);\n }\n };\n\n this.addListener(RTCEvents.DATA_CHANNEL_OPEN,\n this._channelOpenListener);\n\n // Add Last N change listener.\n this.addListener(RTCEvents.LASTN_ENDPOINT_CHANGED,\n this._lastNChangeListener);\n }\n\n /**\n * Callback invoked when the list of known audio and video devices has\n * been updated. Attempts to update the known available audio output\n * devices.\n *\n * @private\n * @returns {void}\n */\n _onDeviceListChanged() {\n this._updateAudioOutputForAudioTracks(RTCUtils.getAudioOutputDevice());\n }\n\n /**\n * Receives events when Last N had changed.\n * @param {array} lastNEndpoints The new Last N endpoints.\n * @private\n */\n _onLastNChanged(lastNEndpoints = []) {\n const oldLastNEndpoints = this._lastNEndpoints || [];\n let leavingLastNEndpoints = [];\n let enteringLastNEndpoints = [];\n\n this._lastNEndpoints = lastNEndpoints;\n\n leavingLastNEndpoints = oldLastNEndpoints.filter(\n id => !this.isInLastN(id));\n\n enteringLastNEndpoints = lastNEndpoints.filter(\n id => oldLastNEndpoints.indexOf(id) === -1);\n\n this.conference.eventEmitter.emit(\n JitsiConferenceEvents.LAST_N_ENDPOINTS_CHANGED,\n leavingLastNEndpoints,\n enteringLastNEndpoints);\n }\n\n /**\n * Should be called when current media session ends and after the\n * PeerConnection has been closed using PeerConnection.close() method.\n */\n onCallEnded() {\n if (this._channel) {\n // The BridgeChannel is not explicitly closed as the PeerConnection\n // is closed on call ended which triggers datachannel onclose\n // events. If using a WebSocket, the channel must be closed since\n // it is not managed by the PeerConnection.\n // The reference is cleared to disable any logic related to the\n // channel.\n if (this._channel && this._channel.mode === 'websocket') {\n this._channel.close();\n }\n\n this._channel = null;\n this._channelOpen = false;\n }\n }\n\n /**\n * Sets the maximum video size the local participant should receive from\n * remote participants. Will cache the value and send it through the channel\n * once it is created.\n *\n * @param {number} maxFrameHeightPixels the maximum frame height, in pixels,\n * this receiver is willing to receive.\n * @returns {void}\n */\n setReceiverVideoConstraint(maxFrameHeight) {\n this._maxFrameHeight = maxFrameHeight;\n\n if (this._channel && this._channelOpen) {\n this._channel.sendReceiverVideoConstraintMessage(maxFrameHeight);\n }\n }\n\n /**\n * Elects the participants with the given ids to be the selected\n * participants in order to always receive video for this participant (even\n * when last n is enabled). If there is no channel we store it and send it\n * through the channel once it is created.\n *\n * @param {Array} ids - The user ids.\n * @throws NetworkError or InvalidStateError or Error if the operation\n * fails.\n * @returns {void}\n */\n selectEndpoints(ids) {\n this._selectedEndpoints = ids;\n\n if (this._channel && this._channelOpen) {\n this._channel.sendSelectedEndpointsMessage(ids);\n }\n }\n\n /**\n * Elects the participant with the given id to be the pinned participant in\n * order to always receive video for this participant (even when last n is\n * enabled).\n * @param {stirng} id The user id.\n * @throws NetworkError or InvalidStateError or Error if the operation\n * fails.\n */\n pinEndpoint(id) {\n // Cache the value if channel is missing, till we open it.\n this._pinnedEndpoint = id;\n if (this._channel && this._channelOpen) {\n this._channel.sendPinnedEndpointMessage(id);\n }\n }\n\n /**\n *\n * @param eventType\n * @param listener\n */\n static addListener(eventType, listener) {\n RTCUtils.addListener(eventType, listener);\n }\n\n /**\n *\n * @param eventType\n * @param listener\n */\n static removeListener(eventType, listener) {\n RTCUtils.removeListener(eventType, listener);\n }\n\n /**\n *\n * @param options\n */\n static init(options = {}) {\n this.options = options;\n\n return RTCUtils.init(this.options);\n }\n\n /* eslint-disable max-params */\n\n /**\n * Creates new TraceablePeerConnection\n * @param {SignalingLayer} signaling The signaling layer that will\n * provide information about the media or participants which is not\n * carried over SDP.\n * @param {object} iceConfig An object describing the ICE config like\n * defined in the WebRTC specification.\n * @param {boolean} isP2P Indicates whether or not the new TPC will be used\n * in a peer to peer type of session.\n * @param {object} options The config options.\n * @param {boolean} options.disableSimulcast If set to 'true' will disable\n * the simulcast.\n * @param {boolean} options.disableRtx If set to 'true' will disable the\n * RTX.\n * @param {boolean} options.disableH264 If set to 'true' H264 will be\n * disabled by removing it from the SDP.\n * @param {boolean} options.preferH264 If set to 'true' H264 will be\n * preferred over other video codecs.\n * @param {boolean} options.startSilent If set to 'true' no audio will be sent or received.\n * @return {TraceablePeerConnection}\n */\n createPeerConnection(signaling, iceConfig, isP2P, options) {\n const pcConstraints = RTC.getPCConstraints(isP2P);\n\n if (typeof options.abtestSuspendVideo !== 'undefined') {\n RTCUtils.setSuspendVideo(pcConstraints, options.abtestSuspendVideo);\n\n Statistics.analytics.addPermanentProperties(\n { abtestSuspendVideo: options.abtestSuspendVideo });\n }\n\n // FIXME: We should rename iceConfig to pcConfig.\n\n if (browser.supportsInsertableStreams()) {\n logger.debug('E2EE - setting insertable streams constraints');\n iceConfig.forceEncodedAudioInsertableStreams = true;\n iceConfig.forceEncodedVideoInsertableStreams = true;\n }\n\n if (browser.supportsSdpSemantics()) {\n iceConfig.sdpSemantics = 'plan-b';\n }\n\n // Set the RTCBundlePolicy to max-bundle so that only one set of ice candidates is generated.\n // The default policy generates separate ice candidates for audio and video connections.\n // This change is necessary for Unified plan to work properly on Chrome and Safari.\n iceConfig.bundlePolicy = 'max-bundle';\n\n peerConnectionIdCounter = safeCounterIncrement(peerConnectionIdCounter);\n\n const newConnection\n = new TraceablePeerConnection(\n this,\n peerConnectionIdCounter,\n signaling,\n iceConfig, pcConstraints,\n isP2P, options);\n\n this.peerConnections.set(newConnection.id, newConnection);\n\n return newConnection;\n }\n\n /* eslint-enable max-params */\n\n /**\n * Removed given peer connection from this RTC module instance.\n * @param {TraceablePeerConnection} traceablePeerConnection\n * @return {boolean} true if the given peer connection was removed\n * successfully or false if there was no peer connection mapped in\n * this RTC instance.\n */\n _removePeerConnection(traceablePeerConnection) {\n const id = traceablePeerConnection.id;\n\n if (this.peerConnections.has(id)) {\n // NOTE Remote tracks are not removed here.\n this.peerConnections.delete(id);\n\n return true;\n }\n\n return false;\n\n }\n\n /**\n *\n * @param track\n */\n addLocalTrack(track) {\n if (!track) {\n throw new Error('track must not be null nor undefined');\n }\n\n this.localTracks.push(track);\n\n track.conference = this.conference;\n }\n\n /**\n * Returns the current value for \"lastN\" - the amount of videos are going\n * to be delivered. When set to -1 for unlimited or all available videos.\n * @return {number}\n */\n getLastN() {\n return this._lastN;\n }\n\n /**\n * Get local video track.\n * @returns {JitsiLocalTrack|undefined}\n */\n getLocalVideoTrack() {\n const localVideo = this.getLocalTracks(MediaType.VIDEO);\n\n\n return localVideo.length ? localVideo[0] : undefined;\n }\n\n /**\n * Get local audio track.\n * @returns {JitsiLocalTrack|undefined}\n */\n getLocalAudioTrack() {\n const localAudio = this.getLocalTracks(MediaType.AUDIO);\n\n\n return localAudio.length ? localAudio[0] : undefined;\n }\n\n /**\n * Returns the local tracks of the given media type, or all local tracks if\n * no specific type is given.\n * @param {MediaType} [mediaType] Optional media type filter.\n * (audio or video).\n */\n getLocalTracks(mediaType) {\n let tracks = this.localTracks.slice();\n\n if (mediaType !== undefined) {\n tracks = tracks.filter(\n track => track.getType() === mediaType);\n }\n\n return tracks;\n }\n\n /**\n * Obtains all remote tracks currently known to this RTC module instance.\n * @param {MediaType} [mediaType] The remote tracks will be filtered\n * by their media type if this argument is specified.\n * @return {Array}\n */\n getRemoteTracks(mediaType) {\n let remoteTracks = [];\n\n for (const tpc of this.peerConnections.values()) {\n const pcRemoteTracks = tpc.getRemoteTracks(undefined, mediaType);\n\n if (pcRemoteTracks) {\n remoteTracks = remoteTracks.concat(pcRemoteTracks);\n }\n }\n\n return remoteTracks;\n }\n\n /**\n * Set mute for all local audio streams attached to the conference.\n * @param value The mute value.\n * @returns {Promise}\n */\n setAudioMute(value) {\n const mutePromises = [];\n\n this.getLocalTracks(MediaType.AUDIO).forEach(audioTrack => {\n // this is a Promise\n mutePromises.push(value ? audioTrack. : audioTrack.unmute());\n });\n\n // We return a Promise from all Promises so we can wait for their\n // execution.\n return Promise.all(mutePromises);\n }\n\n /**\n *\n * @param track\n */\n removeLocalTrack(track) {\n const pos = this.localTracks.indexOf(track);\n\n if (pos === -1) {\n return;\n }\n\n this.localTracks.splice(pos, 1);\n }\n\n /**\n * Removes all JitsiRemoteTracks associated with given MUC nickname\n * (resource part of the JID). Returns array of removed tracks.\n *\n * @param {string} Owner The resource part of the MUC JID.\n * @returns {JitsiRemoteTrack[]}\n */\n removeRemoteTracks(owner) {\n let removedTracks = [];\n\n for (const tpc of this.peerConnections.values()) {\n const pcRemovedTracks = tpc.removeRemoteTracks(owner);\n\n removedTracks = removedTracks.concat(pcRemovedTracks);\n }\n\n logger.debug(\n `Removed remote tracks for ${owner}`\n + ` count: ${removedTracks.length}`);\n\n return removedTracks;\n }\n\n /**\n *\n */\n static getPCConstraints(isP2P) {\n const pcConstraints\n = isP2P ? RTCUtils.p2pPcConstraints : RTCUtils.pcConstraints;\n\n if (!pcConstraints) {\n return {};\n }\n\n return JSON.parse(JSON.stringify(pcConstraints));\n }\n\n /**\n *\n * @param elSelector\n * @param stream\n */\n static attachMediaStream(elSelector, stream) {\n return RTCUtils.attachMediaStream(elSelector, stream);\n }\n\n /**\n * Returns the id of the given stream.\n * @param {MediaStream} stream\n */\n static getStreamID(stream) {\n return RTCUtils.getStreamID(stream);\n }\n\n /**\n * Returns the id of the given track.\n * @param {MediaStreamTrack} track\n */\n static getTrackID(track) {\n return RTCUtils.getTrackID(track);\n }\n\n /**\n * Returns true if retrieving the the list of input devices is supported\n * and false if not.\n */\n static isDeviceListAvailable() {\n return RTCUtils.isDeviceListAvailable();\n }\n\n /**\n * Returns true if changing the input (camera / microphone) or output\n * (audio) device is supported and false if not.\n * @param {string} [deviceType] Type of device to change. Default is\n * undefined or 'input', 'output' - for audio output device change.\n * @returns {boolean} true if available, false otherwise.\n */\n static isDeviceChangeAvailable(deviceType) {\n return RTCUtils.isDeviceChangeAvailable(deviceType);\n }\n\n /**\n * Returns whether the current execution environment supports WebRTC (for\n * use within this library).\n *\n * @returns {boolean} {@code true} if WebRTC is supported in the current\n * execution environment (for use within this library); {@code false},\n * otherwise.\n */\n static isWebRtcSupported() {\n return browser.isSupported();\n }\n\n /**\n * Returns currently used audio output device id, '' stands for default\n * device\n * @returns {string}\n */\n static getAudioOutputDevice() {\n return RTCUtils.getAudioOutputDevice();\n }\n\n /**\n * Returns list of available media devices if its obtained, otherwise an\n * empty array is returned/\n * @returns {array} list of available media devices.\n */\n static getCurrentlyAvailableMediaDevices() {\n return RTCUtils.getCurrentlyAvailableMediaDevices();\n }\n\n /**\n * Returns event data for device to be reported to stats.\n * @returns {MediaDeviceInfo} device.\n */\n static getEventDataForActiveDevice(device) {\n return RTCUtils.getEventDataForActiveDevice(device);\n }\n\n /**\n * Sets current audio output device.\n * @param {string} deviceId Id of 'audiooutput' device from\n * navigator.mediaDevices.enumerateDevices().\n * @returns {Promise} resolves when audio output is changed, is rejected\n * otherwise\n */\n static setAudioOutputDevice(deviceId) {\n return RTCUtils.setAudioOutputDevice(deviceId);\n }\n\n /**\n * Returns true if given WebRTC MediaStream is considered a valid\n * \"user\" stream which means that it's not a \"receive only\" stream nor a\n * \"mixed\" JVB stream.\n *\n * Clients that implement Unified Plan, such as Firefox use recvonly\n * \"streams/channels/tracks\" for receiving remote stream/tracks, as opposed\n * to Plan B where there are only 3 channels: audio, video and data.\n *\n * @param {MediaStream} stream The WebRTC MediaStream instance.\n * @returns {boolean}\n */\n static isUserStream(stream) {\n return RTC.isUserStreamById(RTCUtils.getStreamID(stream));\n }\n\n /**\n * Returns true if a WebRTC MediaStream identified by given stream\n * ID is considered a valid \"user\" stream which means that it's not a\n * \"receive only\" stream nor a \"mixed\" JVB stream.\n *\n * Clients that implement Unified Plan, such as Firefox use recvonly\n * \"streams/channels/tracks\" for receiving remote stream/tracks, as opposed\n * to Plan B where there are only 3 channels: audio, video and data.\n *\n * @param {string} streamId The id of WebRTC MediaStream.\n * @returns {boolean}\n */\n static isUserStreamById(streamId) {\n return streamId && streamId !== 'mixedmslabel'\n && streamId !== 'default';\n }\n\n /**\n * Allows to receive list of available cameras/microphones.\n * @param {function} callback Would receive array of devices as an\n * argument.\n */\n static enumerateDevices(callback) {\n RTCUtils.enumerateDevices(callback);\n }\n\n /**\n * A method to handle stopping of the stream.\n * One point to handle the differences in various implementations.\n * @param {MediaStream} mediaStream MediaStream object to stop.\n */\n static stopMediaStream(mediaStream) {\n RTCUtils.stopMediaStream(mediaStream);\n }\n\n /**\n * Returns whether the desktop sharing is enabled or not.\n * @returns {boolean}\n */\n static isDesktopSharingEnabled() {\n return RTCUtils.isDesktopSharingEnabled();\n }\n\n /**\n * Closes the currently opened bridge channel.\n */\n closeBridgeChannel() {\n if (this._channel) {\n this._channel.close();\n this._channelOpen = false;\n\n this.removeListener(RTCEvents.LASTN_ENDPOINT_CHANGED,\n this._lastNChangeListener);\n }\n }\n\n /* eslint-disable max-params */\n /**\n *\n * @param {TraceablePeerConnection} tpc\n * @param {number} ssrc\n * @param {number} audioLevel\n * @param {boolean} isLocal\n */\n setAudioLevel(tpc, ssrc, audioLevel, isLocal) {\n const track = tpc.getTrackBySSRC(ssrc);\n\n if (!track) {\n return;\n } else if (!track.isAudioTrack()) {\n logger.warn(`Received audio level for non-audio track: ${ssrc}`);\n\n return;\n } else if (track.isLocal() !== isLocal) {\n logger.error(\n `${track} was expected to ${isLocal ? 'be' : 'not be'} local`);\n }\n\n track.setAudioLevel(audioLevel, tpc);\n }\n\n /* eslint-enable max-params */\n\n /**\n * Sends message via the bridge channel.\n * @param {string} to The id of the endpoint that should receive the\n * message. If \"\" the message will be sent to all participants.\n * @param {object} payload The payload of the message.\n * @throws NetworkError or InvalidStateError or Error if the operation\n * fails or there is no data channel created.\n */\n sendChannelMessage(to, payload) {\n if (this._channel) {\n this._channel.sendMessage(to, payload);\n } else {\n throw new Error('Channel support is disabled!');\n }\n }\n\n /**\n * Selects a new value for \"lastN\". The requested amount of videos are going\n * to be delivered after the value is in effect. Set to -1 for unlimited or\n * all available videos.\n * @param {number} value the new value for lastN.\n */\n setLastN(value) {\n if (this._lastN !== value) {\n this._lastN = value;\n if (this._channel && this._channelOpen) {\n this._channel.sendSetLastNMessage(value);\n }\n this.eventEmitter.emit(RTCEvents.LASTN_VALUE_CHANGED, value);\n }\n }\n\n /**\n * Indicates if the endpoint id is currently included in the last N.\n * @param {string} id The endpoint id that we check for last N.\n * @returns {boolean} true if the endpoint id is in the last N or if we\n * don't have bridge channel support, otherwise we return false.\n */\n isInLastN(id) {\n return !this._lastNEndpoints // lastNEndpoints not initialised yet.\n || this._lastNEndpoints.indexOf(id) > -1;\n }\n\n /**\n * Updates the target audio output device for all remote audio tracks.\n *\n * @param {string} deviceId - The device id of the audio ouput device to\n * use for all remote tracks.\n * @private\n * @returns {void}\n */\n _updateAudioOutputForAudioTracks(deviceId) {\n const remoteAudioTracks = this.getRemoteTracks(MediaType.AUDIO);\n\n for (const track of remoteAudioTracks) {\n track.setAudioOutput(deviceId);\n }\n }\n}\n", "/**\n * The errors for the JitsiTrack objects.\n */\n\n/**\n * Generic error for jidesha extension for Chrome.\n */\nexport const CHROME_EXTENSION_GENERIC_ERROR\n = 'gum.chrome_extension_generic_error';\n\n/**\n * An error which indicates that the jidesha extension for Chrome is\n * failed to install.\n */\nexport const CHROME_EXTENSION_INSTALLATION_ERROR\n = 'gum.chrome_extension_installation_error';\n\n/**\n * This error indicates that the attempt to start screensharing was initiated by\n * a script which did not originate in user gesture handler. It means that\n * you should to trigger the action again in response to a button click for\n * example.\n * @type {string}\n */\nexport const CHROME_EXTENSION_USER_GESTURE_REQUIRED\n = 'gum.chrome_extension_user_gesture_required';\n\n/**\n * An error which indicates that user canceled screen sharing window\n * selection dialog in jidesha extension for Chrome.\n */\nexport const CHROME_EXTENSION_USER_CANCELED\n = 'gum.chrome_extension_user_canceled';\n\n/**\n * An error which indicates that some of requested constraints in\n * getUserMedia call were not satisfied.\n */\nexport const CONSTRAINT_FAILED = 'gum.constraint_failed';\n\n/**\n * A generic error which indicates an error occurred while selecting\n * a DesktopCapturerSource from the electron app.\n */\nexport const ELECTRON_DESKTOP_PICKER_ERROR\n = 'gum.electron_desktop_picker_error';\n\n/**\n * An error which indicates a custom desktop picker could not be detected\n * for the electron app.\n */\nexport const ELECTRON_DESKTOP_PICKER_NOT_FOUND\n = 'gum.electron_desktop_picker_not_found';\n\n/**\n * An error which indicates that the jidesha extension for Firefox is\n * needed to proceed with screen sharing, and that it is not installed.\n */\nexport const FIREFOX_EXTENSION_NEEDED = 'gum.firefox_extension_needed';\n\n/**\n * Generic getUserMedia error.\n */\nexport const GENERAL = 'gum.general';\n\n/**\n * An error which indicates that requested device was not found.\n */\nexport const NOT_FOUND = 'gum.not_found';\n\n/**\n * An error which indicates that user denied permission to share requested\n * device.\n */\nexport const PERMISSION_DENIED = 'gum.permission_denied';\n\n/**\n * An error which indicates that track has been already disposed and cannot\n * be longer used.\n */\nexport const TRACK_IS_DISPOSED = 'track.track_is_disposed';\n\n/**\n * An error which indicates that track has no MediaStream associated.\n */\nexport const TRACK_NO_STREAM_FOUND = 'track.no_stream_found';\n\n/**\n * An error which indicates that requested video resolution is not supported\n * by a webcam.\n */\nexport const UNSUPPORTED_RESOLUTION = 'gum.unsupported_resolution';\n", "/* global module */\n/**\n * Enumeration of the video types\n * @type {{CAMERA: string, DESKTOP: string}}\n */\nconst VideoType = {\n /**\n * The camera video type.\n */\n CAMERA: 'camera',\n\n /**\n * The desktop video type.\n */\n DESKTOP: 'desktop'\n};\n\nmodule.exports = VideoType;\n", "/**\n * The media track was removed to the conference.\n */\nexport const LOCAL_TRACK_STOPPED = 'track.stopped';\n\n/**\n * Audio levels of a this track was changed.\n * The first argument is a number with audio level value in range [0, 1].\n * The second argument is a TraceablePeerConnection which is the peer\n * connection which measured the audio level (one audio track can be added\n * to multiple peer connection at the same time). This argument is optional for\n * local tracks for which we can measure audio level without the peer\n * connection (the value will be undefined).\n *\n * NOTE The second argument should be treated as library internal and can be\n * removed at any time.\n */\nexport const TRACK_AUDIO_LEVEL_CHANGED = 'track.audioLevelsChanged';\n\n/**\n * The audio output of the track was changed.\n */\nexport const TRACK_AUDIO_OUTPUT_CHANGED = 'track.audioOutputChanged';\n\n/**\n * A media track mute status was changed.\n */\nexport const TRACK_MUTE_CHANGED = 'track.trackMuteChanged';\n\n/**\n * The video type(\"camera\" or \"desktop\") of the track was changed.\n */\nexport const TRACK_VIDEOTYPE_CHANGED = 'track.videoTypeChanged';\n\n/**\n * Indicates that the track is not receiving any data even though we expect it\n * to receive data (i.e. the stream is not stopped).\n */\nexport const NO_DATA_FROM_SOURCE = 'track.no_data_from_source';\n", "import * as JitsiTrackErrors from './JitsiTrackErrors';\n\nconst TRACK_ERROR_TO_MESSAGE_MAP = {};\n\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.UNSUPPORTED_RESOLUTION]\n = 'Video resolution is not supported: ';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.CHROME_EXTENSION_INSTALLATION_ERROR]\n = 'Failed to install Chrome extension';\nTRACK_ERROR_TO_MESSAGE_MAP[\n JitsiTrackErrors.CHROME_EXTENSION_USER_GESTURE_REQUIRED]\n = 'Failed to install Chrome extension - installations can only be initiated'\n + ' by a user gesture.';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.CHROME_EXTENSION_USER_CANCELED]\n = 'User canceled Chrome\\'s screen sharing prompt';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.CHROME_EXTENSION_GENERIC_ERROR]\n = 'Unknown error from Chrome extension';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.ELECTRON_DESKTOP_PICKER_ERROR]\n = 'Unkown error from desktop picker';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.ELECTRON_DESKTOP_PICKER_NOT_FOUND]\n = 'Failed to detect desktop picker';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.GENERAL]\n = 'Generic getUserMedia error';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.PERMISSION_DENIED]\n = 'User denied permission to use device(s): ';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.NOT_FOUND]\n = 'Requested device(s) was/were not found: ';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.CONSTRAINT_FAILED]\n = 'Constraint could not be satisfied: ';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.TRACK_IS_DISPOSED]\n = 'Track has been already disposed';\nTRACK_ERROR_TO_MESSAGE_MAP[JitsiTrackErrors.TRACK_NO_STREAM_FOUND]\n = 'Track does not have an associated Media Stream';\n\n// FIXME: Using prototype inheritance because otherwise instanceof is not\n// working properly (see https://github.com/babel/babel/issues/3083)\n\n/**\n *\n * Represents an error that occurred to a JitsiTrack. Can represent various\n * types of errors. For error descriptions (@see JitsiTrackErrors).\n *\n * @extends Error\n *\n *\n * @constructor\n * @param {Object|string} error - error object or error name\n * @param {Object|string} (options) - getUserMedia constraints object or\n * error message\n * @param {('audio'|'video'|'desktop'|'screen'|'audiooutput')[]} (devices) -\n * list of getUserMedia requested devices\n */\nfunction JitsiTrackError(error, options, devices) {\n if (typeof error === 'object' && typeof error.name !== 'undefined') {\n /**\n * Additional information about original getUserMedia error\n * and constraints.\n * @type {{\n * error: Object,\n * constraints: Object,\n * devices: Array.<'audio'|'video'|'desktop'|'screen'>\n * }}\n */\n this.gum = {\n error,\n constraints: options,\n devices: devices && Array.isArray(devices)\n ? devices.slice(0)\n : undefined\n };\n\n switch (error.name) {\n case 'NotAllowedError':\n case 'PermissionDeniedError':\n case 'SecurityError':\n this.name = JitsiTrackErrors.PERMISSION_DENIED;\n this.message\n = TRACK_ERROR_TO_MESSAGE_MAP[this.name]\n + (this.gum.devices || []).join(', ');\n break;\n case 'DevicesNotFoundError':\n case 'NotFoundError':\n this.name = JitsiTrackErrors.NOT_FOUND;\n this.message\n = TRACK_ERROR_TO_MESSAGE_MAP[this.name]\n + (this.gum.devices || []).join(', ');\n break;\n case 'ConstraintNotSatisfiedError':\n case 'OverconstrainedError': {\n const constraintName = error.constraintName || error.constraint;\n\n // we treat deviceId as unsupported resolution, as we want to\n // retry and finally if everything fails to remove deviceId from\n // mandatory constraints\n if (options\n && options.video\n && (!devices || devices.indexOf('video') > -1)\n && (constraintName === 'minWidth'\n || constraintName === 'maxWidth'\n || constraintName === 'minHeight'\n || constraintName === 'maxHeight'\n || constraintName === 'width'\n || constraintName === 'height'\n || constraintName === 'deviceId')) {\n this.name = JitsiTrackErrors.UNSUPPORTED_RESOLUTION;\n this.message\n = TRACK_ERROR_TO_MESSAGE_MAP[this.name]\n + getResolutionFromFailedConstraint(\n constraintName,\n options);\n } else {\n this.name = JitsiTrackErrors.CONSTRAINT_FAILED;\n this.message\n = TRACK_ERROR_TO_MESSAGE_MAP[this.name]\n + error.constraintName;\n }\n break;\n }\n\n default:\n this.name = JitsiTrackErrors.GENERAL;\n this.message\n = error.message || TRACK_ERROR_TO_MESSAGE_MAP[this.name];\n break;\n }\n } else if (typeof error === 'string') {\n if (TRACK_ERROR_TO_MESSAGE_MAP[error]) {\n this.name = error;\n this.message = options || TRACK_ERROR_TO_MESSAGE_MAP[error];\n } else {\n // this is some generic error that do not fit any of our\n // pre-defined errors, so don't give it any specific name, just\n // store message\n this.message = error;\n }\n } else {\n throw new Error('Invalid arguments');\n }\n\n this.stack = error.stack || (new Error()).stack;\n}\n\nJitsiTrackError.prototype = Object.create(Error.prototype);\nJitsiTrackError.prototype.constructor = JitsiTrackError;\n\n/**\n * Gets failed resolution constraint from corresponding object.\n * @param {string} failedConstraintName\n * @param {Object} constraints\n * @returns {string|number}\n */\nfunction getResolutionFromFailedConstraint(failedConstraintName, constraints) {\n if (constraints && constraints.video && constraints.video.mandatory) {\n switch (failedConstraintName) {\n case 'width':\n return constraints.video.mandatory.minWidth;\n case 'height':\n return constraints.video.mandatory.minHeight;\n default:\n return constraints.video.mandatory[failedConstraintName] || '';\n }\n }\n\n return '';\n}\n\nexport default JitsiTrackError;\n", "/* global $ */\n\nimport browser from '../browser';\nimport SDPUtil from './SDPUtil';\n\n/**\n *\n * @param sdp\n */\nexport default function SDP(sdp) {\n const media = sdp.split('\\r\\nm=');\n\n for (let i = 1, length = media.length; i < length; i++) {\n let mediaI = `m=${media[i]}`;\n\n if (i !== length - 1) {\n mediaI += '\\r\\n';\n }\n media[i] = mediaI;\n }\n const session = `${media.shift()}\\r\\n`;\n\n this.media = media;\n this.raw = session + media.join('');\n this.session = session;\n}\n\n/**\n * A flag will make {@link transportToJingle} and {@link jingle2media} replace\n * ICE candidates IPs with invalid value of '1.1.1.1' which will cause ICE\n * failure. The flag is used in the automated testing.\n * @type {boolean}\n */\nSDP.prototype.failICE = false;\n\n/**\n * Whether or not to remove TCP ice candidates when translating from/to jingle.\n * @type {boolean}\n */\nSDP.prototype.removeTcpCandidates = false;\n\n/**\n * Whether or not to remove UDP ice candidates when translating from/to jingle.\n * @type {boolean}\n */\nSDP.prototype.removeUdpCandidates = false;\n\n/**\n * Returns map of MediaChannel mapped per channel idx.\n */\nSDP.prototype.getMediaSsrcMap = function() {\n const self = this;\n const mediaSSRCs = {};\n let tmp;\n\n for (let mediaindex = 0; mediaindex < self.media.length; mediaindex++) {\n tmp = SDPUtil.findLines(self.media[mediaindex], 'a=ssrc:');\n const mid\n = SDPUtil.parseMID(\n SDPUtil.findLine(self.media[mediaindex], 'a=mid:'));\n const media = {\n mediaindex,\n mid,\n ssrcs: {},\n ssrcGroups: []\n };\n\n mediaSSRCs[mediaindex] = media;\n tmp.forEach(line => {\n const linessrc = line.substring(7).split(' ')[0];\n\n // allocate new ChannelSsrc\n\n if (!media.ssrcs[linessrc]) {\n media.ssrcs[linessrc] = {\n ssrc: linessrc,\n lines: []\n };\n }\n media.ssrcs[linessrc].lines.push(line);\n });\n tmp = SDPUtil.findLines(self.media[mediaindex], 'a=ssrc-group:');\n tmp.forEach(line => {\n const idx = line.indexOf(' ');\n const semantics = line.substr(0, idx).substr(13);\n const ssrcs = line.substr(14 + semantics.length).split(' ');\n\n if (ssrcs.length) {\n media.ssrcGroups.push({\n semantics,\n ssrcs\n });\n }\n });\n }\n\n return mediaSSRCs;\n};\n\n/**\n * Returns true if this SDP contains given SSRC.\n * @param ssrc the ssrc to check.\n * @returns {boolean} true if this SDP contains given SSRC.\n */\nSDP.prototype.containsSSRC = function(ssrc) {\n // FIXME this code is really strange - improve it if you can\n const medias = this.getMediaSsrcMap();\n let result = false;\n\n Object.keys(medias).forEach(mediaindex => {\n if (result) {\n return;\n }\n if (medias[mediaindex].ssrcs[ssrc]) {\n result = true;\n }\n });\n\n return result;\n};\n\n// remove iSAC and CN from SDP\nSDP.prototype.mangle = function() {\n let i, j, lines, mline, newdesc, rtpmap;\n\n for (i = 0; i < this.media.length; i++) {\n lines = this.media[i].split('\\r\\n');\n lines.pop(); // remove empty last element\n mline = SDPUtil.parseMLine(lines.shift());\n if (mline.media !== 'audio') {\n continue; // eslint-disable-line no-continue\n }\n newdesc = '';\n mline.fmt.length = 0;\n for (j = 0; j < lines.length; j++) {\n if (lines[j].substr(0, 9) === 'a=rtpmap:') {\n rtpmap = SDPUtil.parseRTPMap(lines[j]);\n if (rtpmap.name === 'CN' || rtpmap.name === 'ISAC') {\n continue; // eslint-disable-line no-continue\n }\n mline.fmt.push(rtpmap.id);\n }\n newdesc += `${lines[j]}\\r\\n`;\n }\n this.media[i] = `${SDPUtil.buildMLine(mline)}\\r\\n${newdesc}`;\n }\n this.raw = this.session + this.media.join('');\n};\n\n// remove lines matching prefix from session section\nSDP.prototype.removeSessionLines = function(prefix) {\n const self = this;\n const lines = SDPUtil.findLines(this.session, prefix);\n\n lines.forEach(line => {\n self.session = self.session.replace(`${line}\\r\\n`, '');\n });\n this.raw = this.session + this.media.join('');\n\n return lines;\n};\n\n// remove lines matching prefix from a media section specified by mediaindex\n// TODO: non-numeric mediaindex could match mid\nSDP.prototype.removeMediaLines = function(mediaindex, prefix) {\n const self = this;\n const lines = SDPUtil.findLines(this.media[mediaindex], prefix);\n\n lines.forEach(line => {\n self.media[mediaindex]\n = self.media[mediaindex].replace(`${line}\\r\\n`, '');\n });\n this.raw = this.session + this.media.join('');\n\n return lines;\n};\n\n// add content's to a jingle element\nSDP.prototype.toJingle = function(elem, thecreator) {\n let i, j, k, lines, mline, rtpmap, ssrc, tmp;\n\n // new bundle plan\n\n lines = SDPUtil.findLines(this.session, 'a=group:');\n if (lines.length) {\n for (i = 0; i < lines.length; i++) {\n tmp = lines[i].split(' ');\n const semantics = tmp.shift().substr(8);\n\n elem.c('group', { xmlns: 'urn:xmpp:jingle:apps:grouping:0',\n semantics });\n for (j = 0; j < tmp.length; j++) {\n elem.c('content', { name: tmp[j] }).up();\n }\n elem.up();\n }\n }\n for (i = 0; i < this.media.length; i++) {\n mline = SDPUtil.parseMLine(this.media[i].split('\\r\\n')[0]);\n if (!(mline.media === 'audio'\n || mline.media === 'video'\n || mline.media === 'application')) {\n continue; // eslint-disable-line no-continue\n }\n const assrcline = SDPUtil.findLine(this.media[i], 'a=ssrc:');\n\n if (assrcline) {\n ssrc = assrcline.substring(7).split(' ')[0]; // take the first\n } else {\n ssrc = false;\n }\n\n elem.c('content', { creator: thecreator,\n name: mline.media });\n const amidline = SDPUtil.findLine(this.media[i], 'a=mid:');\n\n if (amidline) {\n // prefer identifier from a=mid if present\n const mid = SDPUtil.parseMID(amidline);\n\n elem.attrs({ name: mid });\n }\n\n if (SDPUtil.findLine(this.media[i], 'a=rtpmap:').length) {\n elem.c('description',\n { xmlns: 'urn:xmpp:jingle:apps:rtp:1',\n media: mline.media });\n if (ssrc) {\n elem.attrs({ ssrc });\n }\n for (j = 0; j < mline.fmt.length; j++) {\n rtpmap\n = SDPUtil.findLine(\n this.media[i],\n `a=rtpmap:${mline.fmt[j]}`);\n elem.c('payload-type', SDPUtil.parseRTPMap(rtpmap));\n\n // put any 'a=fmtp:' + mline.fmt[j] lines into \n const afmtpline\n = SDPUtil.findLine(\n this.media[i],\n `a=fmtp:${mline.fmt[j]}`);\n\n if (afmtpline) {\n tmp = SDPUtil.parseFmtp(afmtpline);\n\n // eslint-disable-next-line max-depth\n for (k = 0; k < tmp.length; k++) {\n elem.c('parameter', tmp[k]).up();\n }\n }\n\n // XEP-0293 -- map a=rtcp-fb\n this.rtcpFbToJingle(i, elem, mline.fmt[j]);\n\n elem.up();\n }\n const crypto\n = SDPUtil.findLines(this.media[i], 'a=crypto:', this.session);\n\n if (crypto.length) {\n elem.c('encryption', { required: 1 });\n crypto.forEach(\n line => elem.c('crypto', SDPUtil.parseCrypto(line)).up());\n elem.up(); // end of encryption\n }\n\n if (ssrc) {\n const ssrcMap = SDPUtil.parseSSRC(this.media[i]);\n\n for (const [ availableSsrc, ssrcParameters ] of ssrcMap) {\n elem.c('source', {\n ssrc: availableSsrc,\n xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0'\n });\n\n ssrcParameters.forEach(ssrcSdpLine => {\n // get everything after first space\n const idx = ssrcSdpLine.indexOf(' ');\n const kv = ssrcSdpLine.substr(idx + 1);\n\n elem.c('parameter');\n if (kv.indexOf(':') === -1) {\n elem.attrs({ name: kv });\n } else {\n const name = kv.split(':', 2)[0];\n\n elem.attrs({ name });\n\n let v = kv.split(':', 2)[1];\n\n v = SDPUtil.filterSpecialChars(v);\n elem.attrs({ value: v });\n }\n elem.up();\n });\n\n elem.up();\n }\n\n // XEP-0339 handle ssrc-group attributes\n const ssrcGroupLines\n = SDPUtil.findLines(this.media[i], 'a=ssrc-group:');\n\n ssrcGroupLines.forEach(line => {\n const idx = line.indexOf(' ');\n const semantics = line.substr(0, idx).substr(13);\n const ssrcs = line.substr(14 + semantics.length).split(' ');\n\n if (ssrcs.length) {\n elem.c('ssrc-group', { semantics,\n xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });\n ssrcs.forEach(s => elem.c('source', { ssrc: s }).up());\n elem.up();\n }\n });\n }\n\n const ridLines = SDPUtil.findLines(this.media[i], 'a=rid');\n\n if (ridLines.length && browser.usesRidsForSimulcast()) {\n // Map a line which looks like \"a=rid:2 send\" to just\n // the rid (\"2\")\n const rids = ridLines\n .map(ridLine => ridLine.split(':')[1])\n .map(ridInfo => ridInfo.split(' ')[0]);\n\n rids.forEach(rid => {\n elem.c('source', {\n rid,\n xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0'\n });\n elem.up();\n });\n const unifiedSimulcast\n = SDPUtil.findLine(this.media[i], 'a=simulcast');\n\n if (unifiedSimulcast) {\n elem.c('rid-group', {\n semantics: 'SIM',\n xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0'\n });\n rids.forEach(rid => {\n elem.c('source', { rid }).up();\n });\n elem.up();\n }\n }\n\n if (SDPUtil.findLine(this.media[i], 'a=rtcp-mux')) {\n elem.c('rtcp-mux').up();\n }\n\n // XEP-0293 -- map a=rtcp-fb:*\n this.rtcpFbToJingle(i, elem, '*');\n\n // XEP-0294\n lines = SDPUtil.findLines(this.media[i], 'a=extmap:');\n if (lines.length) {\n for (j = 0; j < lines.length; j++) {\n tmp = SDPUtil.parseExtmap(lines[j]);\n elem.c('rtp-hdrext', {\n xmlns: 'urn:xmpp:jingle:apps:rtp:rtp-hdrext:0',\n uri: tmp.uri,\n id: tmp.value\n });\n\n // eslint-disable-next-line max-depth\n if (tmp.hasOwnProperty('direction')) {\n\n // eslint-disable-next-line max-depth\n switch (tmp.direction) {\n case 'sendonly':\n elem.attrs({ senders: 'responder' });\n break;\n case 'recvonly':\n elem.attrs({ senders: 'initiator' });\n break;\n case 'sendrecv':\n elem.attrs({ senders: 'both' });\n break;\n case 'inactive':\n elem.attrs({ senders: 'none' });\n break;\n }\n }\n\n // TODO: handle params\n elem.up();\n }\n }\n elem.up(); // end of description\n }\n\n // map ice-ufrag/pwd, dtls fingerprint, candidates\n this.transportToJingle(i, elem);\n\n const m = this.media[i];\n\n if (SDPUtil.findLine(m, 'a=sendrecv', this.session)) {\n elem.attrs({ senders: 'both' });\n } else if (SDPUtil.findLine(m, 'a=sendonly', this.session)) {\n elem.attrs({ senders: 'initiator' });\n } else if (SDPUtil.findLine(m, 'a=recvonly', this.session)) {\n elem.attrs({ senders: 'responder' });\n } else if (SDPUtil.findLine(m, 'a=inactive', this.session)) {\n elem.attrs({ senders: 'none' });\n }\n\n // Reject an m-line only when port is 0 and a=bundle-only is not present in the section.\n // The port is automatically set to 0 when bundle-only is used.\n if (mline.port === '0' && !SDPUtil.findLine(m, 'a=bundle-only', this.session)) {\n // estos hack to reject an m-line\n elem.attrs({ senders: 'rejected' });\n }\n elem.up(); // end of content\n }\n elem.up();\n\n return elem;\n};\n\nSDP.prototype.transportToJingle = function(mediaindex, elem) {\n let tmp;\n const self = this;\n\n elem.c('transport');\n\n // XEP-0343 DTLS/SCTP\n const sctpmap\n = SDPUtil.findLine(this.media[mediaindex], 'a=sctpmap:', self.session);\n\n if (sctpmap) {\n const sctpAttrs = SDPUtil.parseSCTPMap(sctpmap);\n\n elem.c('sctpmap', {\n xmlns: 'urn:xmpp:jingle:transports:dtls-sctp:1',\n number: sctpAttrs[0], /* SCTP port */\n protocol: sctpAttrs[1] /* protocol */\n });\n\n // Optional stream count attribute\n if (sctpAttrs.length > 2) {\n elem.attrs({ streams: sctpAttrs[2] });\n }\n elem.up();\n }\n\n // XEP-0320\n const fingerprints\n = SDPUtil.findLines(\n this.media[mediaindex],\n 'a=fingerprint:',\n this.session);\n\n fingerprints.forEach(line => {\n tmp = SDPUtil.parseFingerprint(line);\n tmp.xmlns = 'urn:xmpp:jingle:apps:dtls:0';\n elem.c('fingerprint').t(tmp.fingerprint);\n delete tmp.fingerprint;\n\n // eslint-disable-next-line no-param-reassign\n line\n = SDPUtil.findLine(\n self.media[mediaindex],\n 'a=setup:',\n self.session);\n if (line) {\n tmp.setup = line.substr(8);\n }\n elem.attrs(tmp);\n elem.up(); // end of fingerprint\n });\n tmp = SDPUtil.iceparams(this.media[mediaindex], this.session);\n if (tmp) {\n tmp.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';\n elem.attrs(tmp);\n\n // XEP-0176\n const lines\n = SDPUtil.findLines(\n this.media[mediaindex],\n 'a=candidate:',\n this.session);\n\n if (lines.length) { // add any a=candidate lines\n lines.forEach(line => {\n const candidate = SDPUtil.candidateToJingle(line);\n\n if (self.failICE) {\n candidate.ip = '1.1.1.1';\n }\n const protocol\n = candidate && typeof candidate.protocol === 'string'\n ? candidate.protocol.toLowerCase()\n : '';\n\n if ((self.removeTcpCandidates\n && (protocol === 'tcp' || protocol === 'ssltcp'))\n || (self.removeUdpCandidates && protocol === 'udp')) {\n return;\n }\n elem.c('candidate', candidate).up();\n });\n }\n }\n elem.up(); // end of transport\n};\n\n// XEP-0293\nSDP.prototype.rtcpFbToJingle = function(mediaindex, elem, payloadtype) {\n const lines\n = SDPUtil.findLines(\n this.media[mediaindex],\n `a=rtcp-fb:${payloadtype}`);\n\n lines.forEach(line => {\n const tmp = SDPUtil.parseRTCPFB(line);\n\n if (tmp.type === 'trr-int') {\n elem.c('rtcp-fb-trr-int', {\n xmlns: 'urn:xmpp:jingle:apps:rtp:rtcp-fb:0',\n value: tmp.params[0]\n });\n elem.up();\n } else {\n elem.c('rtcp-fb', {\n xmlns: 'urn:xmpp:jingle:apps:rtp:rtcp-fb:0',\n type: tmp.type\n });\n if (tmp.params.length > 0) {\n elem.attrs({ 'subtype': tmp.params[0] });\n }\n elem.up();\n }\n });\n};\n\nSDP.prototype.rtcpFbFromJingle = function(elem, payloadtype) { // XEP-0293\n let media = '';\n let tmp\n = elem.find(\n '>rtcp-fb-trr-int[xmlns=\"urn:xmpp:jingle:apps:rtp:rtcp-fb:0\"]');\n\n if (tmp.length) {\n media += 'a=rtcp-fb:* trr-int ';\n if (tmp.attr('value')) {\n media += tmp.attr('value');\n } else {\n media += '0';\n }\n media += '\\r\\n';\n }\n tmp = elem.find('>rtcp-fb[xmlns=\"urn:xmpp:jingle:apps:rtp:rtcp-fb:0\"]');\n tmp.each(function() {\n /* eslint-disable no-invalid-this */\n media += `a=rtcp-fb:${payloadtype} ${$(this).attr('type')}`;\n if ($(this).attr('subtype')) {\n media += ` ${$(this).attr('subtype')}`;\n }\n media += '\\r\\n';\n\n /* eslint-enable no-invalid-this */\n });\n\n return media;\n};\n\n// construct an SDP from a jingle stanza\nSDP.prototype.fromJingle = function(jingle) {\n const self = this;\n const sessionId = Date.now();\n\n // Use a unique session id for every TPC.\n this.raw = 'v=0\\r\\n'\n + `o=- ${sessionId} 2 IN IP4 0.0.0.0\\r\\n`\n + 's=-\\r\\n'\n + 't=0 0\\r\\n';\n\n // http://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-04\n // #section-8\n const groups\n = $(jingle).find('>group[xmlns=\"urn:xmpp:jingle:apps:grouping:0\"]');\n\n if (groups.length) {\n groups.each((idx, group) => {\n const contents\n = $(group)\n .find('>content')\n .map((_, content) => content.getAttribute('name'))\n .get();\n\n if (contents.length > 0) {\n self.raw\n += `a=group:${\n group.getAttribute('semantics')\n || group.getAttribute('type')} ${\n contents.join(' ')}\\r\\n`;\n }\n });\n }\n\n this.session = this.raw;\n jingle.find('>content').each(function() {\n // eslint-disable-next-line no-invalid-this\n const m = self.jingle2media($(this));\n\n self.media.push(m);\n });\n\n // reconstruct msid-semantic -- apparently not necessary\n /*\n var msid = SDPUtil.parseSSRC(this.raw);\n if (msid.hasOwnProperty('mslabel')) {\n this.session += \"a=msid-semantic: WMS \" + msid.mslabel + \"\\r\\n\";\n }\n */\n\n this.raw = this.session + this.media.join('');\n};\n\n// translate a jingle content element into an an SDP media part\nSDP.prototype.jingle2media = function(content) {\n const desc = content.find('description');\n let media = '';\n const self = this;\n const sctp = content.find(\n '>transport>sctpmap[xmlns=\"urn:xmpp:jingle:transports:dtls-sctp:1\"]');\n\n let tmp = { media: desc.attr('media') };\n\n tmp.port = '1';\n if (content.attr('senders') === 'rejected') {\n // estos hack to reject an m-line.\n tmp.port = '0';\n }\n if (content.find('>transport>fingerprint').length\n || desc.find('encryption').length) {\n tmp.proto = sctp.length ? 'DTLS/SCTP' : 'RTP/SAVPF';\n } else {\n tmp.proto = 'RTP/AVPF';\n }\n if (sctp.length) {\n media += `m=application ${tmp.port} DTLS/SCTP ${\n sctp.attr('number')}\\r\\n`;\n media += `a=sctpmap:${sctp.attr('number')} ${sctp.attr('protocol')}`;\n\n const streamCount = sctp.attr('streams');\n\n if (streamCount) {\n media += ` ${streamCount}\\r\\n`;\n } else {\n media += '\\r\\n';\n }\n } else {\n tmp.fmt\n = desc\n .find('payload-type')\n .map(function() {\n // eslint-disable-next-line no-invalid-this\n return this.getAttribute('id');\n })\n .get();\n media += `${SDPUtil.buildMLine(tmp)}\\r\\n`;\n }\n\n media += 'c=IN IP4 0.0.0.0\\r\\n';\n if (!sctp.length) {\n media += 'a=rtcp:1 IN IP4 0.0.0.0\\r\\n';\n }\n tmp\n = content.find(\n '>transport[xmlns=\"urn:xmpp:jingle:transports:ice-udp:1\"]');\n if (tmp.length) {\n if (tmp.attr('ufrag')) {\n media += `${SDPUtil.buildICEUfrag(tmp.attr('ufrag'))}\\r\\n`;\n }\n if (tmp.attr('pwd')) {\n media += `${SDPUtil.buildICEPwd(tmp.attr('pwd'))}\\r\\n`;\n }\n tmp.find('>fingerprint').each(function() {\n /* eslint-disable no-invalid-this */\n // FIXME: check namespace at some point\n media += `a=fingerprint:${this.getAttribute('hash')}`;\n media += ` ${$(this).text()}`;\n media += '\\r\\n';\n if (this.getAttribute('setup')) {\n media += `a=setup:${this.getAttribute('setup')}\\r\\n`;\n }\n\n /* eslint-enable no-invalid-this */\n });\n }\n switch (content.attr('senders')) {\n case 'initiator':\n media += 'a=sendonly\\r\\n';\n break;\n case 'responder':\n media += 'a=recvonly\\r\\n';\n break;\n case 'none':\n media += 'a=inactive\\r\\n';\n break;\n case 'both':\n media += 'a=sendrecv\\r\\n';\n break;\n }\n media += `a=mid:${content.attr('name')}\\r\\n`;\n\n // \n // see http://code.google.com/p/libjingle/issues/detail?id=309 -- no spec\n // though\n // and http://mail.jabber.org/pipermail/jingle/2011-December/001761.html\n if (desc.find('rtcp-mux').length) {\n media += 'a=rtcp-mux\\r\\n';\n }\n\n if (desc.find('encryption').length) {\n desc.find('encryption>crypto').each(function() {\n /* eslint-disable no-invalid-this */\n media += `a=crypto:${this.getAttribute('tag')}`;\n media += ` ${this.getAttribute('crypto-suite')}`;\n media += ` ${this.getAttribute('key-params')}`;\n if (this.getAttribute('session-params')) {\n media += ` ${this.getAttribute('session-params')}`;\n }\n media += '\\r\\n';\n\n /* eslint-enable no-invalid-this */\n });\n }\n desc.find('payload-type').each(function() {\n /* eslint-disable no-invalid-this */\n media += `${SDPUtil.buildRTPMap(this)}\\r\\n`;\n if ($(this).find('>parameter').length) {\n media += `a=fmtp:${this.getAttribute('id')} `;\n media\n += $(this)\n .find('parameter')\n .map(function() {\n const name = this.getAttribute('name');\n\n return (\n (name ? `${name}=` : '')\n + this.getAttribute('value'));\n })\n .get()\n .join('; ');\n media += '\\r\\n';\n }\n\n // xep-0293\n media += self.rtcpFbFromJingle($(this), this.getAttribute('id'));\n\n /* eslint-enable no-invalid-this */\n });\n\n // xep-0293\n media += self.rtcpFbFromJingle(desc, '*');\n\n // xep-0294\n tmp\n = desc.find(\n '>rtp-hdrext[xmlns=\"urn:xmpp:jingle:apps:rtp:rtp-hdrext:0\"]');\n tmp.each(function() {\n /* eslint-disable no-invalid-this */\n media\n += `a=extmap:${this.getAttribute('id')} ${\n this.getAttribute('uri')}\\r\\n`;\n\n /* eslint-enable no-invalid-this */\n });\n\n content\n .find(\n '>transport[xmlns=\"urn:xmpp:jingle:transports:ice-udp:1\"]'\n + '>candidate')\n .each(function() {\n /* eslint-disable no-invalid-this */\n let protocol = this.getAttribute('protocol');\n\n protocol\n = typeof protocol === 'string' ? protocol.toLowerCase() : '';\n\n if ((self.removeTcpCandidates\n && (protocol === 'tcp' || protocol === 'ssltcp'))\n || (self.removeUdpCandidates && protocol === 'udp')) {\n return;\n } else if (self.failICE) {\n this.setAttribute('ip', '1.1.1.1');\n }\n\n media += SDPUtil.candidateFromJingle(this);\n\n /* eslint-enable no-invalid-this */\n });\n\n // XEP-0339 handle ssrc-group attributes\n content\n .find('description>ssrc-group[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]')\n .each(function() {\n /* eslint-disable no-invalid-this */\n const semantics = this.getAttribute('semantics');\n const ssrcs\n = $(this)\n .find('>source')\n .map(function() {\n return this.getAttribute('ssrc');\n })\n .get();\n\n if (ssrcs.length) {\n media += `a=ssrc-group:${semantics} ${ssrcs.join(' ')}\\r\\n`;\n }\n\n /* eslint-enable no-invalid-this */\n });\n\n tmp\n = content.find(\n 'description>source[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]');\n tmp.each(function() {\n /* eslint-disable no-invalid-this */\n const ssrc = this.getAttribute('ssrc');\n\n // eslint-disable-next-line newline-per-chained-call\n $(this).find('>parameter').each(function() {\n const name = this.getAttribute('name');\n let value = this.getAttribute('value');\n\n value = SDPUtil.filterSpecialChars(value);\n media += `a=ssrc:${ssrc} ${name}`;\n if (value && value.length) {\n media += `:${value}`;\n }\n media += '\\r\\n';\n });\n\n /* eslint-enable no-invalid-this */\n });\n\n return media;\n};\n", "/**\n * The errors for the conference.\n */\n\n/**\n * Indicates that client must be authenticated to create the conference.\n */\nexport const AUTHENTICATION_REQUIRED = 'conference.authenticationRequired';\n\n/**\n * Indicates that chat error occurred.\n */\nexport const CHAT_ERROR = 'conference.chatError';\n\n/**\n * Indicates that conference has been destroyed.\n */\nexport const CONFERENCE_DESTROYED = 'conference.destroyed';\n\n/**\n * Indicates that max users limit has been reached.\n */\nexport const CONFERENCE_MAX_USERS = 'conference.max_users';\n\n/**\n * Indicates that a connection error occurred when trying to join a conference.\n */\nexport const CONNECTION_ERROR = 'conference.connectionError';\n\n/**\n * Indicates that a connection error is due to not allowed,\n * occurred when trying to join a conference.\n */\nexport const NOT_ALLOWED_ERROR = 'conference.connectionError.notAllowed';\n\n/**\n * Indicates that focus error happened.\n */\nexport const FOCUS_DISCONNECTED = 'conference.focusDisconnected';\n\n/**\n * Indicates that focus left the conference.\n */\nexport const FOCUS_LEFT = 'conference.focusLeft';\n\n/**\n * Indicates that graceful shutdown happened.\n */\nexport const GRACEFUL_SHUTDOWN = 'conference.gracefulShutdown';\n\n/**\n * Indicates that the versions of the server side components are incompatible\n * with the client side.\n */\nexport const INCOMPATIBLE_SERVER_VERSIONS\n = 'conference.incompatible_server_versions';\n\n/**\n * Indicates that offer/answer had failed.\n */\nexport const OFFER_ANSWER_FAILED = 'conference.offerAnswerFailed';\n\n/**\n * Indicates that password cannot be set for this conference.\n */\nexport const PASSWORD_NOT_SUPPORTED = 'conference.passwordNotSupported';\n\n/**\n * Indicates that a password is required in order to join the conference.\n */\nexport const PASSWORD_REQUIRED = 'conference.passwordRequired';\n\n/**\n * Indicates that reservation system returned error.\n */\nexport const RESERVATION_ERROR = 'conference.reservationError';\n\n/**\n * Indicates that the conference setup failed.\n */\nexport const SETUP_FAILED = 'conference.setup_failed';\n\n/**\n * Indicates that there is no available videobridge.\n */\nexport const VIDEOBRIDGE_NOT_AVAILABLE = 'conference.videobridgeNotAvailable';\n", "// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nfunction EventEmitter() {\n this._events = this._events || {};\n this._maxListeners = this._maxListeners || undefined;\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nEventEmitter.defaultMaxListeners = 10;\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function(n) {\n if (!isNumber(n) || n < 0 || isNaN(n))\n throw TypeError('n must be a positive number');\n this._maxListeners = n;\n return this;\n};\n\nEventEmitter.prototype.emit = function(type) {\n var er, handler, len, args, i, listeners;\n\n if (!this._events)\n this._events = {};\n\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events.error ||\n (isObject(this._events.error) && !this._events.error.length)) {\n er = arguments[1];\n if (er instanceof Error) {\n throw er; // Unhandled 'error' event\n } else {\n // At least give some kind of context to the user\n var err = new Error('Uncaught, unspecified \"error\" event. (' + er + ')');\n err.context = er;\n throw err;\n }\n }\n }\n\n handler = this._events[type];\n\n if (isUndefined(handler))\n return false;\n\n if (isFunction(handler)) {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n args = Array.prototype.slice.call(arguments, 1);\n handler.apply(this, args);\n }\n } else if (isObject(handler)) {\n args = Array.prototype.slice.call(arguments, 1);\n listeners = handler.slice();\n len = listeners.length;\n for (i = 0; i < len; i++)\n listeners[i].apply(this, args);\n }\n\n return true;\n};\n\nEventEmitter.prototype.addListener = function(type, listener) {\n var m;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events)\n this._events = {};\n\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (this._events.newListener)\n this.emit('newListener', type,\n isFunction(listener.listener) ?\n listener.listener : listener);\n\n if (!this._events[type])\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n else if (isObject(this._events[type]))\n // If we've already got an array, just append.\n this._events[type].push(listener);\n else\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n // Check for listener leak\n if (isObject(this._events[type]) && !this._events[type].warned) {\n if (!isUndefined(this._maxListeners)) {\n m = this._maxListeners;\n } else {\n m = EventEmitter.defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n", "/**\n * Event triggered by a audio detector indicating that its active state has changed from active to inactive or vice\n * versa.\n * @event\n * @type {boolean} - true when service has changed to active false otherwise.\n */\nexport const DETECTOR_STATE_CHANGE = 'detector_state_change';\n\n/** Event triggered by {@link NoAudioSignalDetector} when the local audio device associated with a JitsiConference\n * starts receiving audio levels with the value of 0 meaning no audio is being captured on that device, or when\n * it starts receiving audio levels !== 0 after being in a state of no audio.\n * @event\n * @type {boolean} - true when the current conference audio track has audio input false otherwise.\n */\nexport const AUDIO_INPUT_STATE_CHANGE = 'audio_input_state_changed';\n\n/** Event triggered by NoAudioSignalDetector when the local audio device associated with a JitsiConference goes silent\n * for a period of time, meaning that the device is either broken or hardware/software muted.\n * @event\n * @type {void}\n */\nexport const NO_AUDIO_INPUT = 'no_audio_input_detected';\n\n/**\n * Event generated by {@link VADNoiseDetection} when the tracked device is considered noisy.\n * @event\n * @type {Object}\n */\nexport const VAD_NOISY_DEVICE = 'detection.vad_noise_device';\n\n/**\n * Event generated by VADReportingService when if finishes creating a VAD report for the monitored devices.\n * The generated objects are of type Array, one score for each monitored device.\n * @event VAD_REPORT_PUBLISHED\n * @type Array with the following structure:\n * @property {Date} timestamp - Timestamp at which the compute took place.\n * @property {number} avgVAD - Average VAD score over monitored period of time.\n * @property {string} deviceId - Associate local audio device ID.\n */\nexport const VAD_REPORT_PUBLISHED = 'vad-report-published';\n\n/**\n * Event generated by {@link TrackVADEmitter} when PCM sample VAD score is available.\n *\n * @event\n * @type {Object}\n * @property {Date} timestamp - Exact time at which processed PCM sample was generated.\n * @property {number} score - VAD score on a scale from 0 to 1 (i.e. 0.7)\n * @property {Float32Array} pcmData - Raw PCM data with which the VAD score was calculated.\n * @property {string} deviceId - Device id of the associated track.\n */\nexport const VAD_SCORE_PUBLISHED = 'detection.vad_score_published';\n\n/**\n * Event generated by {@link VADTalkMutedDetection} when a user is talking while the mic is muted.\n *\n * @event\n * @type {Object}\n */\nexport const VAD_TALK_WHILE_MUTED = 'detection.vad_talk_while_muted';\n", "var parser = require('./parser');\nvar writer = require('./writer');\n\nexports.write = writer;\nexports.parse = parser.parse;\nexports.parseFmtpConfig = parser.parseFmtpConfig;\nexports.parseParams = parser.parseParams;\nexports.parsePayloads = parser.parsePayloads;\nexports.parseRemoteCandidates = parser.parseRemoteCandidates;\nexports.parseImageAttributes = parser.parseImageAttributes;\nexports.parseSimulcastStreamList = parser.parseSimulcastStreamList;\n", "/**\n * Status that video SIP GW service is available.\n * @type {string}\n */\nexport const STATUS_AVAILABLE = 'available';\n\n/**\n * Status that video SIP GW service is not available.\n * @type {string}\n */\nexport const STATUS_UNDEFINED = 'undefined';\n\n/**\n * Status that video SIP GW service is available but there are no free nodes\n * at the moment to serve new requests.\n * @type {string}\n */\nexport const STATUS_BUSY = 'busy';\n\n/**\n * Video SIP GW session state, currently running.\n * @type {string}\n */\nexport const STATE_ON = 'on';\n\n/**\n * Video SIP GW session state, currently stopped and not running.\n * @type {string}\n */\nexport const STATE_OFF = 'off';\n\n/**\n * Video SIP GW session state, currently is starting.\n * @type {string}\n */\nexport const STATE_PENDING = 'pending';\n\n/**\n * Video SIP GW session state, has observed some issues and is retrying at the\n * moment.\n * @type {string}\n */\nexport const STATE_RETRYING = 'retrying';\n\n/**\n * Video SIP GW session state, tried to start but it failed.\n * @type {string}\n */\nexport const STATE_FAILED = 'failed';\n\n/**\n * Error on trying to create video SIP GW session in conference where\n * there is no room connection (hasn't joined or has left the room).\n * @type {string}\n */\nexport const ERROR_NO_CONNECTION = 'error_no_connection';\n\n/**\n * Error on trying to create video SIP GW session with address for which\n * there is an already created session.\n * @type {string}\n */\nexport const ERROR_SESSION_EXISTS = 'error_session_already_exists';\n", "// TODO: Maybe fix the values to 'Chrome', 'Internet Explorer', etc. Currently\n// this values needs to be as they are becuse they are going to analytics,\n// callstats, etc.\n\nexport const CHROME = 'chrome';\n\nexport const OPERA = 'opera';\n\nexport const FIREFOX = 'firefox';\n\nexport const INTERNET_EXPLORER = 'iexplorer';\n\nexport const SAFARI = 'safari';\n\nexport const NWJS = 'nwjs';\n\nexport const ELECTRON = 'electron';\n\nexport const REACT_NATIVE = 'react-native';\n\nexport const UNKNOWN = 'unknown';\n", "import Bowser from 'bowser';\n\nimport {\n CHROME,\n OPERA,\n FIREFOX,\n INTERNET_EXPLORER,\n SAFARI,\n NWJS,\n ELECTRON,\n REACT_NATIVE,\n UNKNOWN\n} from './browsers';\n\n/**\n * Maps the names of the browsers from bowser to the internal names defined in\n * ./browsers.js\n */\nconst bowserNameToJitsiName = {\n 'Chrome': CHROME,\n 'Chromium': CHROME,\n 'Opera': OPERA,\n 'Firefox': FIREFOX,\n 'Internet Explorer': INTERNET_EXPLORER,\n 'Safari': SAFARI\n};\n\n/**\n * Detects a Chromium based environent.\n *\n * NOTE: Here we cannot check solely for \"Chrome\" in the UA, because Edge has\n * it too. We need to check explicitly for chromium based Edge first and then\n * detect other chromium based browsers.\n *\n * @returns {Object|undefined} - The name (CHROME) and version.\n */\nfunction _detectChromiumBased() {\n const userAgent = navigator.userAgent;\n const browserInfo = {\n name: UNKNOWN,\n version: undefined\n };\n\n if (userAgent.match(/Chrome/) && !userAgent.match(/Edge/)) {\n // Edge is currenly supported only on desktop and android.\n if (userAgent.match(/Edg(A?)/)) {\n // Compare the underlying chromium version.\n const version = userAgent.match(/Chrome\\/([\\d.]+)/)[1];\n\n if (Number.parseInt(version, 10) > 72) {\n browserInfo.name = CHROME;\n browserInfo.version = version;\n }\n } else {\n browserInfo.name = CHROME;\n browserInfo.version = userAgent.match(/Chrome\\/([\\d.]+)/)[1];\n }\n }\n\n return browserInfo;\n}\n\n/**\n * Detects Electron environment.\n *\n * @returns {Object|undefined} - The name (ELECTRON) and version.\n */\nfunction _detectElectron() {\n const userAgent = navigator.userAgent;\n\n if (userAgent.match(/Electron/)) {\n const version = userAgent.match(/Electron\\/([\\d.]+)/)[1];\n\n return {\n name: ELECTRON,\n version\n };\n }\n}\n\n/**\n * Detects NWJS environment.\n *\n * @returns {Object|undefined} - The name (NWJS) and version.\n */\nfunction _detectNWJS() {\n const userAgent = navigator.userAgent;\n\n if (userAgent.match(/JitsiMeetNW/)) {\n const version = userAgent.match(/JitsiMeetNW\\/([\\d.]+)/)[1];\n\n return {\n name: NWJS,\n version\n };\n }\n}\n\n/**\n * Detects React Native environment.\n * @returns {Object|undefined} - The name (REACT_NATIVE) and version.\n */\nfunction _detectReactNative() {\n const match\n = navigator.userAgent.match(/\\b(react[ \\t_-]*native)(?:\\/(\\S+))?/i);\n let version;\n\n // If we're remote debugging a React Native app, it may be treated as\n // Chrome. Check navigator.product as well and always return some version\n // even if we can't get the real one.\n\n if (match || navigator.product === 'ReactNative') {\n let name;\n\n if (match && match.length > 2) {\n name = match[1];\n version = match[2];\n }\n name || (name = 'react-native');\n version || (version = 'unknown');\n\n return {\n name: REACT_NATIVE,\n version\n };\n }\n}\n\n/**\n * Returns information about the current browser.\n * @param {Object} - The bowser instance.\n * @returns {Object} - The name and version of the browser.\n */\nfunction _detect(bowser) {\n let browserInfo;\n const detectors = [\n _detectReactNative,\n _detectElectron,\n _detectNWJS\n ];\n\n // Try all browser detectors\n for (let i = 0; i < detectors.length; i++) {\n browserInfo = detectors[i]();\n if (browserInfo) {\n return browserInfo;\n }\n }\n\n const name = bowser.getBrowserName();\n\n if (name in bowserNameToJitsiName) {\n return {\n name: bowserNameToJitsiName[name],\n version: bowser.getBrowserVersion()\n };\n }\n\n // Detect other browsers with the Chrome engine, such as Vivaldi and Brave.\n browserInfo = _detectChromiumBased();\n if (browserInfo) {\n return browserInfo;\n }\n\n return {\n name: UNKNOWN,\n version: undefined\n };\n}\n\n/**\n * Implements browser detection.\n */\nexport default class BrowserDetection {\n /**\n * Creates new BrowserDetection instance.\n *\n * @param {Object} [browserInfo] - Information about the browser.\n * @param {string} browserInfo.name - The name of the browser.\n * @param {string} browserInfo.version - The version of the browser.\n */\n constructor(browserInfo) {\n let name, version;\n\n this._bowser = Bowser.getParser(navigator.userAgent);\n if (typeof browserInfo === 'undefined') {\n const detectedBrowserInfo = _detect(this._bowser);\n\n name = detectedBrowserInfo.name;\n version = detectedBrowserInfo.version;\n } else if (browserInfo.name in bowserNameToJitsiName) {\n name = bowserNameToJitsiName[browserInfo.name];\n version = browserInfo.version;\n } else {\n name = UNKNOWN;\n version = undefined;\n }\n\n this._name = name;\n this._version = version;\n }\n\n /**\n * Gets current browser name.\n * @returns {string}\n */\n getName() {\n return this._name;\n }\n\n /**\n * Checks if current browser is Chrome.\n * @returns {boolean}\n */\n isChrome() {\n return this._name === CHROME;\n }\n\n /**\n * Checks if current browser is Opera.\n * @returns {boolean}\n */\n isOpera() {\n return this._name === OPERA;\n }\n\n /**\n * Checks if current browser is Firefox.\n * @returns {boolean}\n */\n isFirefox() {\n return this._name === FIREFOX;\n }\n\n /**\n * Checks if current browser is Internet Explorer.\n * @returns {boolean}\n */\n isIExplorer() {\n return this._name === INTERNET_EXPLORER;\n }\n\n /**\n * Checks if current browser is Safari.\n * @returns {boolean}\n */\n isSafari() {\n return this._name === SAFARI;\n }\n\n /**\n * Checks if current environment is NWJS.\n * @returns {boolean}\n */\n isNWJS() {\n return this._name === NWJS;\n }\n\n /**\n * Checks if current environment is Electron.\n * @returns {boolean}\n */\n isElectron() {\n return this._name === ELECTRON;\n }\n\n /**\n * Checks if current environment is React Native.\n * @returns {boolean}\n */\n isReactNative() {\n return this._name === REACT_NATIVE;\n }\n\n /**\n * Returns the version of the current browser.\n * @returns {string}\n */\n getVersion() {\n return this._version;\n }\n\n /**\n * Check if the parsed browser matches the passed condition.\n *\n * @param {Object} checkTree - It's one or two layered object, which can include a\n * platform or an OS on the first layer and should have browsers specs on the\n * bottom layer.\n * Eg. { chrome: '>71.1.0' }\n * { windows: { chrome: '<70.2' } }\n * @returns {boolean | undefined} - Returns true if the browser satisfies the set\n * conditions, false if not and undefined when the browser is not defined in the\n * checktree object or when the current browser's version is unknown.\n * @private\n */\n _checkCondition(checkTree) {\n if (this._version) {\n return this._bowser.satisfies(checkTree);\n }\n }\n\n /**\n * Compares the passed version with the current browser version.\n *\n * @param {*} version - The version to compare with. Anything different\n * than string will be converted to string.\n * @returns {boolean|undefined} - Returns true if the current version is\n * greater than the passed version and false otherwise. Returns undefined if\n * the current browser version is unknown.\n */\n isVersionGreaterThan(version) {\n return this._checkCondition({ [this._name]: `>${version}` });\n }\n\n /**\n * Compares the passed version with the current browser version.\n *\n * @param {*} version - The version to compare with. Anything different\n * than string will be converted to string.\n * @returns {boolean|undefined} - Returns true if the current version is\n * lower than the passed version and false otherwise. Returns undefined if\n * the current browser version is unknown.\n */\n isVersionLessThan(version) {\n return this._checkCondition({ [this._name]: `<${version}` });\n }\n\n /**\n * Compares the passed version with the current browser version.\n *\n * @param {*} version - The version to compare with. Anything different\n * than string will be converted to string.\n * @returns {boolean|undefined} - Returns true if the current version is\n * equal to the passed version and false otherwise. Returns undefined if\n * the current browser version is unknown.\n * A loose-equality operator is used here so that it matches the sub-versions as well.\n */\n isVersionEqualTo(version) {\n return this._checkCondition({ [this._name]: `~${version}` });\n }\n}\n", "export * from './browser-capabilities';\nexport * from './browser-detection';\nexport * from './avatar';\n", "import EventEmitter from 'events';\n\n/**\n * The class implements basic event operations - add/remove listener.\n * NOTE: The purpose of the class is to be extended in order to add\n * this functionality to other classes.\n */\nexport default class Listenable {\n /**\n * Creates new instance.\n * @param {EventEmitter} eventEmitter\n * @constructor\n */\n constructor(eventEmitter = new EventEmitter()) {\n this.eventEmitter = eventEmitter;\n\n // aliases for addListener/removeListener\n this.addEventListener = this.on = this.addListener;\n this.removeEventListener = this.off = this.removeListener;\n }\n\n /**\n * Adds new listener.\n * @param {String} eventName the name of the event\n * @param {Function} listener the listener.\n * @returns {Function} - The unsubscribe function.\n */\n addListener(eventName, listener) {\n this.eventEmitter.addListener(eventName, listener);\n\n return () => this.removeEventListener(eventName, listener);\n }\n\n /**\n * Removes listener.\n * @param {String} eventName the name of the event that triggers the\n * listener\n * @param {Function} listener the listener.\n */\n removeListener(eventName, listener) {\n this.eventEmitter.removeListener(eventName, listener);\n }\n}\n", "/**\n * The events for the connection.\n */\n\n/**\n * Indicates that the connection has been disconnected. The event provides\n * the following parameters to its listeners:\n *\n * @param msg {string} a message associated with the disconnect such as the\n * last (known) error message\n */\nexport const CONNECTION_DISCONNECTED = 'connection.connectionDisconnected';\n\n/**\n * Indicates that the connection has been established. The event provides\n * the following parameters to its listeners:\n *\n * @param id {string} the ID of the local endpoint/participant/peer (within\n * the context of the established connection)\n */\nexport const CONNECTION_ESTABLISHED = 'connection.connectionEstablished';\n\n/**\n * Indicates that the connection has been failed for some reason. The event\n * provides the following parameters to its listeners:\n *\n * @param errType {JitsiConnectionErrors} the type of error associated with\n * the failure\n * @param errReason {string} the error (message) associated with the failure\n * @param credentials {object} the credentials used to connect (if any)\n * @param errReasonDetails {object} an optional object with details about\n * the error, like shard moving, suspending. Used for analytics purposes.\n */\nexport const CONNECTION_FAILED = 'connection.connectionFailed';\n\n/**\n * Indicates that the performed action cannot be executed because the\n * connection is not in the correct state(connected, disconnected, etc.)\n */\nexport const WRONG_STATE = 'connection.wrongState';\n", "/**\n * Notifies about audio level in RTP statistics by SSRC.\n *\n * @param ssrc - The synchronization source identifier (SSRC) of the\n * endpoint/participant whose audio level is being reported.\n * @param {number} audioLevel - The audio level of ssrc according to\n * RTP statistics.\n * @param {boolean} isLocal - true if ssrc identifies the\n * local endpoint/participant; otherwise, false.\n */\nexport const AUDIO_LEVEL = 'statistics.audioLevel';\n\n/**\n * An event fired just before the statistics module gets disposes and it's\n * the last chance to submit some logs that will end up in stats services like\n * CallStats (if enabled).\n */\nexport const BEFORE_DISPOSED = 'statistics.before_disposed';\n\n/**\n * An event carrying all statistics by ssrc.\n */\nexport const BYTE_SENT_STATS = 'statistics.byte_sent_stats';\n\n/**\n * An event carrying connection statistics.\n *\n * @param {object} connectionStats - The connection statistics carried by the\n * event such as bandwidth, bitrate, packetLoss,\n * resolution, and transport.\n */\nexport const CONNECTION_STATS = 'statistics.connectionstats';\n", "import * as transform from 'sdp-transform';\n\n/**\n * Parses the primary SSRC of given SSRC group.\n * @param {object} group the SSRC group object as defined by the 'sdp-transform'\n * @return {Number} the primary SSRC number\n */\nexport function parsePrimarySSRC(group) {\n return parseInt(group.ssrcs.split(' ')[0], 10);\n}\n\n/**\n * Parses the secondary SSRC of given SSRC group.\n * @param {object} group the SSRC group object as defined by the 'sdp-transform'\n * @return {Number} the secondary SSRC number\n */\nexport function parseSecondarySSRC(group) {\n return parseInt(group.ssrcs.split(' ')[1], 10);\n}\n\n/**\n * Tells how many distinct SSRCs are contained in given media line.\n * @param {Object} mLine the media line object as defined by 'sdp-transform' lib\n * @return {number}\n */\nfunction _getSSRCCount(mLine) {\n if (!mLine.ssrcs) {\n return 0;\n }\n\n return mLine.ssrcs\n .map(ssrcInfo => ssrcInfo.id)\n .filter((ssrc, index, array) => array.indexOf(ssrc) === index)\n .length;\n}\n\n/**\n * A wrapper around 'sdp-transform' media description object which provides\n * utility methods for common SDP/SSRC related operations.\n */\nclass MLineWrap {\n\n /**\n * Creates new MLineWrap>\n * @param {Object} mLine the media line object as defined by 'sdp-transform'\n * lib.\n */\n constructor(mLine) {\n if (!mLine) {\n throw new Error('mLine is undefined');\n }\n\n this.mLine = mLine;\n }\n\n /**\n * Getter for the mLine's \"ssrcs\" array. If the array was undefined an empty\n * one will be preassigned.\n *\n * @return {Array} an array of 'sdp-transform' SSRC attributes\n * objects.\n */\n get ssrcs() {\n if (!this.mLine.ssrcs) {\n this.mLine.ssrcs = [];\n }\n\n return this.mLine.ssrcs;\n }\n\n /**\n * Setter for the mLine's \"ssrcs\" array.\n *\n * @param {Array} ssrcs an array of 'sdp-transform' SSRC attributes\n * objects.\n */\n set ssrcs(ssrcs) {\n this.mLine.ssrcs = ssrcs;\n }\n\n /**\n * Returns the direction of the underlying media description.\n * @return {string} the media direction name as defined in the SDP.\n */\n get direction() {\n return this.mLine.direction;\n }\n\n /**\n * Modifies the direction of the underlying media description.\n * @param {string} direction the new direction to be set\n */\n set direction(direction) {\n this.mLine.direction = direction;\n }\n\n /**\n * Exposes the SSRC group array of the underlying media description object.\n * @return {Array.}\n */\n get ssrcGroups() {\n if (!this.mLine.ssrcGroups) {\n this.mLine.ssrcGroups = [];\n }\n\n return this.mLine.ssrcGroups;\n }\n\n /**\n * Modifies the SSRC groups array of the underlying media description\n * object.\n * @param {Array.} ssrcGroups\n */\n set ssrcGroups(ssrcGroups) {\n this.mLine.ssrcGroups = ssrcGroups;\n }\n\n /**\n * Obtains value from SSRC attribute.\n * @param {number} ssrcNumber the SSRC number for which attribute is to be\n * found\n * @param {string} attrName the name of the SSRC attribute to be found.\n * @return {string|undefined} the value of SSRC attribute or\n * undefined if no such attribute exists.\n */\n getSSRCAttrValue(ssrcNumber, attrName) {\n const attribute = this.ssrcs.find(\n ssrcObj => ssrcObj.id === ssrcNumber\n && ssrcObj.attribute === attrName);\n\n\n return attribute && attribute.value;\n }\n\n /**\n * Removes all attributes for given SSRC number.\n * @param {number} ssrcNum the SSRC number for which all attributes will be\n * removed.\n */\n removeSSRC(ssrcNum) {\n if (!this.mLine.ssrcs || !this.mLine.ssrcs.length) {\n return;\n }\n\n this.mLine.ssrcs\n = this.mLine.ssrcs.filter(ssrcObj => ssrcObj.id !== ssrcNum);\n }\n\n /**\n * Adds SSRC attribute\n * @param {object} ssrcObj the SSRC attribute object as defined in\n * the 'sdp-transform' lib.\n */\n addSSRCAttribute(ssrcObj) {\n this.ssrcs.push(ssrcObj);\n }\n\n /**\n * Finds a SSRC group matching both semantics and SSRCs in order.\n * @param {string} semantics the name of the semantics\n * @param {string} [ssrcs] group SSRCs as a string (like it's defined in\n * SSRC group object of the 'sdp-transform' lib) e.g. \"1232546 342344 25434\"\n * @return {object|undefined} the SSRC group object or undefined if\n * not found.\n */\n findGroup(semantics, ssrcs) {\n return this.ssrcGroups.find(\n group =>\n group.semantics === semantics\n && (!ssrcs || ssrcs === group.ssrcs));\n }\n\n /**\n * Finds all groups matching given semantic's name.\n * @param {string} semantics the name of the semantics\n * @return {Array.} an array of SSRC group objects as defined by\n * the 'sdp-transform' lib.\n */\n findGroups(semantics) {\n return this.ssrcGroups.filter(\n group => group.semantics === semantics);\n }\n\n /**\n * Finds all groups matching given semantic's name and group's primary SSRC.\n * @param {string} semantics the name of the semantics\n * @param {number} primarySSRC the primary SSRC number to be matched\n * @return {Object} SSRC group object as defined by the 'sdp-transform' lib.\n */\n findGroupByPrimarySSRC(semantics, primarySSRC) {\n return this.ssrcGroups.find(\n group => group.semantics === semantics\n && parsePrimarySSRC(group) === primarySSRC);\n }\n\n /**\n * @param {string|null} msid the media stream id or null to match\n * the first SSRC object with any 'msid' value.\n * @return {Object|undefined} the SSRC object as defined by 'sdp-transform'\n * lib.\n */\n findSSRCByMSID(msid) {\n return this.ssrcs.find(\n ssrcObj => ssrcObj.attribute === 'msid'\n && (msid === null || ssrcObj.value === msid));\n }\n\n /**\n * Gets the SSRC count for the underlying media description.\n * @return {number}\n */\n getSSRCCount() {\n return _getSSRCCount(this.mLine);\n }\n\n /**\n * Checks whether the underlying media description contains any SSRC groups.\n * @return {boolean} true if there are any SSRC groups or\n * false otherwise.\n */\n containsAnySSRCGroups() {\n return this.mLine.ssrcGroups !== undefined;\n }\n\n /**\n * Finds the primary video SSRC.\n * @returns {number|undefined} the primary video ssrc\n * @throws Error if the underlying media description is not a video\n */\n getPrimaryVideoSsrc() {\n const mediaType = this.mLine.type;\n\n if (mediaType !== 'video') {\n throw new Error(\n `getPrimarySsrc doesn't work with '${mediaType}'`);\n }\n\n const numSsrcs = _getSSRCCount(this.mLine);\n\n if (numSsrcs === 1) {\n // Not using \"ssrcs\" getter on purpose here\n return this.mLine.ssrcs[0].id;\n }\n\n // Look for a SIM, FID, or FEC-FR group\n if (this.mLine.ssrcGroups) {\n const simGroup = this.findGroup('SIM');\n\n if (simGroup) {\n return parsePrimarySSRC(simGroup);\n }\n const fidGroup = this.findGroup('FID');\n\n if (fidGroup) {\n return parsePrimarySSRC(fidGroup);\n }\n const fecGroup = this.findGroup('FEC-FR');\n\n if (fecGroup) {\n return parsePrimarySSRC(fecGroup);\n }\n }\n\n }\n\n /**\n * Obtains RTX SSRC from the underlying video description (the\n * secondary SSRC of the first \"FID\" group found)\n * @param {number} primarySsrc the video ssrc for which to find the\n * corresponding rtx ssrc\n * @returns {number|undefined} the rtx ssrc (or undefined if there isn't\n * one)\n */\n getRtxSSRC(primarySsrc) {\n const fidGroup = this.findGroupByPrimarySSRC('FID', primarySsrc);\n\n\n return fidGroup && parseSecondarySSRC(fidGroup);\n }\n\n /**\n * Obtains all SSRCs contained in the underlying media description.\n * @return {Array.} an array with all SSRC as numbers.\n */\n getSSRCs() {\n return this.ssrcs\n .map(ssrcInfo => ssrcInfo.id)\n .filter((ssrc, index, array) => array.indexOf(ssrc) === index);\n }\n\n /**\n * Obtains primary video SSRCs.\n * @return {Array.} an array of all primary video SSRCs as numbers.\n * @throws Error if the wrapped media description is not a video.\n */\n getPrimaryVideoSSRCs() {\n const mediaType = this.mLine.type;\n\n if (mediaType !== 'video') {\n throw new Error(\n `getPrimaryVideoSSRCs doesn't work with ${mediaType}`);\n }\n\n const videoSSRCs = this.getSSRCs();\n\n for (const ssrcGroupInfo of this.ssrcGroups) {\n // Right now, FID and FEC-FR groups are the only ones we parse to\n // disqualify streams. If/when others arise we'll\n // need to add support for them here\n if (ssrcGroupInfo.semantics === 'FID'\n || ssrcGroupInfo.semantics === 'FEC-FR') {\n // secondary streams should be filtered out\n const secondarySsrc = parseSecondarySSRC(ssrcGroupInfo);\n\n videoSSRCs.splice(\n videoSSRCs.indexOf(secondarySsrc), 1);\n }\n }\n\n return videoSSRCs;\n }\n\n /**\n * Dumps all SSRC groups of this media description to JSON.\n */\n dumpSSRCGroups() {\n return JSON.stringify(this.mLine.ssrcGroups);\n }\n\n /**\n * Removes all SSRC groups which contain given SSRC number at any position.\n * @param {number} ssrc the SSRC for which all matching groups are to be\n * removed.\n */\n removeGroupsWithSSRC(ssrc) {\n if (!this.mLine.ssrcGroups) {\n return;\n }\n\n this.mLine.ssrcGroups = this.mLine.ssrcGroups\n .filter(groupInfo => groupInfo.ssrcs.indexOf(`${ssrc}`) === -1);\n }\n\n /**\n * Removes groups that match given semantics.\n * @param {string} semantics e.g. \"SIM\" or \"FID\"\n */\n removeGroupsBySemantics(semantics) {\n if (!this.mLine.ssrcGroups) {\n return;\n }\n\n this.mLine.ssrcGroups\n = this.mLine.ssrcGroups\n .filter(groupInfo => groupInfo.semantics !== semantics);\n }\n\n /**\n * Replaces SSRC (does not affect SSRC groups, but only attributes).\n * @param {number} oldSSRC the old SSRC number\n * @param {number} newSSRC the new SSRC number\n */\n replaceSSRC(oldSSRC, newSSRC) {\n if (this.mLine.ssrcs) {\n this.mLine.ssrcs.forEach(ssrcInfo => {\n if (ssrcInfo.id === oldSSRC) {\n ssrcInfo.id = newSSRC;\n }\n });\n }\n }\n\n /**\n * Adds given SSRC group to this media description.\n * @param {object} group the SSRC group object as defined by\n * the 'sdp-transform' lib.\n */\n addSSRCGroup(group) {\n this.ssrcGroups.push(group);\n }\n}\n\n/**\n * Utility class for SDP manipulation using the 'sdp-transform' library.\n *\n * Typical use usage scenario:\n *\n * const transformer = new SdpTransformWrap(rawSdp);\n * const videoMLine = transformer.selectMedia('video);\n * if (videoMLine) {\n * videoMLiner.addSSRCAttribute({\n * id: 2342343,\n * attribute: \"cname\",\n * value: \"someCname\"\n * });\n * rawSdp = transformer.toRawSdp();\n * }\n */\nexport class SdpTransformWrap {\n\n /**\n * Creates new instance and parses the raw SDP into objects using\n * 'sdp-transform' lib.\n * @param {string} rawSDP the SDP in raw text format.\n */\n constructor(rawSDP) {\n this.parsedSDP = transform.parse(rawSDP);\n }\n\n /**\n * Selects the first media SDP of given name.\n * @param {string} mediaType the name of the media e.g. 'audio', 'video',\n * 'data'.\n * @return {MLineWrap|null} return {@link MLineWrap} instance for the media\n * line or null if not found. The object returned references\n * the underlying SDP state held by this SdpTransformWrap instance\n * (it's not a copy).\n */\n selectMedia(mediaType) {\n const selectedMLine\n = this.parsedSDP.media.find(mLine => mLine.type === mediaType);\n\n return selectedMLine ? new MLineWrap(selectedMLine) : null;\n }\n\n /**\n * Converts the currently stored SDP state in this instance to raw text SDP\n * format.\n * @return {string}\n */\n toRawSDP() {\n return transform.write(this.parsedSDP);\n }\n}\n", "/**\n * Indicates that the local connection statistics were updated.\n */\nexport const LOCAL_STATS_UPDATED = 'cq.local_stats_updated';\n\n/**\n * Indicates that the connection statistics for a particular remote participant\n * were updated.\n */\nexport const REMOTE_STATS_UPDATED = 'cq.remote_stats_updated';\n", "\n\n/**\n * The method will increase the given number by 1. If the given counter is equal\n * or greater to {@link Number.MAX_SAFE_INTEGER} then it will be rolled back to\n * 1.\n * @param {number} number - An integer counter value to be incremented.\n * @return {number} the next counter value increased by 1 (see the description\n * above for exception).\n */\nexport function safeCounterIncrement(number) {\n let nextValue = number;\n\n if (number >= Number.MAX_SAFE_INTEGER) {\n nextValue = 0;\n }\n\n return nextValue + 1;\n}\n\n/**\n * Calculates the average value of am Array of numbers.\n *\n * @param {Float32Array} valueArray - Array of numbers.\n * @returns {number} - Number array average.\n */\nexport function calculateAverage(valueArray) {\n return valueArray.length > 0 ? valueArray.reduce((a, b) => a + b) / valueArray.length : 0;\n}\n\n\n/**\n * Returns only the positive values from an array of numbers.\n *\n * @param {Float32Array} valueArray - Array of vad scores.\n * @returns {Array} - Array of positive numbers.\n */\nexport function filterPositiveValues(valueArray) {\n return valueArray.filter(value => value >= 0);\n}\n", "/**\n * The know jingle actions that can be sent and should be acted upon by\n * {@code ProxyConnectionService} and {@code ProxyConnectionPC}.\n */\nexport const ACTIONS = {\n ACCEPT: 'session-accept',\n CONNECTION_ERROR: 'connection-error-encountered',\n INITIATE: 'session-initiate',\n TERMINATE: 'session-terminate',\n TRANSPORT_INFO: 'transport-info',\n UNAVAILABLE: 'unavailable'\n};\n", "const Resolutions = {\n '1080': {\n width: 1920,\n height: 1080,\n order: 8\n },\n 'fullhd': {\n width: 1920,\n height: 1080,\n order: 8\n },\n '720': {\n width: 1280,\n height: 720,\n order: 7\n },\n 'hd': {\n width: 1280,\n height: 720,\n order: 7\n },\n '960': {\n width: 960,\n height: 720,\n order: 6\n },\n '540': {\n width: 960,\n height: 540,\n order: 5\n },\n 'qhd': {\n width: 960,\n height: 540,\n order: 5\n },\n\n // 16:9 resolution first.\n '360': {\n width: 640,\n height: 360,\n order: 4\n },\n '640': {\n width: 640,\n height: 480,\n order: 3\n },\n 'vga': {\n width: 640,\n height: 480,\n order: 3\n },\n\n // 16:9 resolution first.\n '180': {\n width: 320,\n height: 180,\n order: 2\n },\n '320': {\n width: 320,\n height: 240,\n order: 1\n }\n};\n\nmodule.exports = Resolutions;\n", "/**\n * The pending Jingle session state which means the session as defined in\n * XEP-0166(before 'session-invite/session-accept' took place).\n *\n * @type {string}\n */\nexport const PENDING = 'pending';\n\n/**\n * The active Jingle session state as defined in XEP-0166\n * (after 'session-invite'/'session-accept').\n *\n * @type {string}\n */\nexport const ACTIVE = 'active';\n\n/**\n * The ended Jingle session state as defined in XEP-0166\n * (after 'session-terminate').\n * @type {string}\n */\nexport const ENDED = 'ended';\n", "/* global callstats */\n\nimport browser from '../browser';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\n\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\n\n/**\n * We define enumeration of wrtcFuncNames as we need them before\n * callstats is initialized to queue events.\n * @const\n * @see http://www.callstats.io/api/#enumeration-of-wrtcfuncnames\n */\nconst wrtcFuncNames = {\n createOffer: 'createOffer',\n createAnswer: 'createAnswer',\n setLocalDescription: 'setLocalDescription',\n setRemoteDescription: 'setRemoteDescription',\n addIceCandidate: 'addIceCandidate',\n getUserMedia: 'getUserMedia',\n iceConnectionFailure: 'iceConnectionFailure',\n signalingError: 'signalingError',\n applicationLog: 'applicationLog'\n};\n\n/**\n * We define enumeration of fabricEvent as we need them before\n * callstats is initialized to queue events.\n * @const\n * @see http://www.callstats.io/api/#enumeration-of-fabricevent\n */\nconst fabricEvent = {\n fabricHold: 'fabricHold',\n fabricResume: 'fabricResume',\n audioMute: 'audioMute',\n audioUnmute: 'audioUnmute',\n videoPause: 'videoPause',\n videoResume: 'videoResume',\n fabricUsageEvent: 'fabricUsageEvent',\n fabricStats: 'fabricStats',\n fabricTerminated: 'fabricTerminated',\n screenShareStart: 'screenShareStart',\n screenShareStop: 'screenShareStop',\n dominantSpeaker: 'dominantSpeaker',\n activeDeviceList: 'activeDeviceList'\n};\n\n/**\n * The user id to report to callstats as destination.\n * @type {string}\n */\nconst DEFAULT_REMOTE_USER = 'jitsi';\n\n/**\n * Type of pending reports, can be event or an error.\n * @type {{ERROR: string, EVENT: string}}\n */\nconst reportType = {\n ERROR: 'error',\n EVENT: 'event',\n MST_WITH_USERID: 'mstWithUserID'\n};\n\n/**\n * Set of currently existing {@link CallStats} instances.\n * @type {Set}\n */\nlet _fabrics;\n\n/**\n * An instance of this class is a wrapper for the CallStats API fabric. A fabric\n * reports one peer connection the the CallStats backend and is allocated with\n * {@link callstats.addNewFabric}. It has a bunch of instance methods for\n * reporting various events. A fabric is considered disposed when\n * {@link CallStats.sendTerminateEvent} is executed.\n *\n * Currently only one backend instance can be created ever and it's done using\n * {@link CallStats.initBackend}. At the time of this writing there is no way to\n * explicitly shutdown the backend, but it's supposed to close it's connection\n * automatically, after all fabrics have been terminated.\n */\nexport default class CallStats {\n /**\n * A callback passed to {@link callstats.addNewFabric}.\n * @param {string} error 'success' means ok\n * @param {string} msg some more details\n * @private\n */\n static _addNewFabricCallback(error, msg) {\n if (CallStats.backend && error !== 'success') {\n logger.error(`Monitoring status: ${error} msg: ${msg}`);\n }\n }\n\n /**\n * Callback passed to {@link callstats.initialize} (backend initialization)\n * @param {string} error 'success' means ok\n * @param {String} msg\n * @private\n */\n static _initCallback(error, msg) {\n logger.log(`CallStats Status: err=${error} msg=${msg}`);\n\n // there is no lib, nothing to report to\n if (error !== 'success') {\n return;\n }\n\n CallStats.backendInitialized = true;\n\n // I hate that\n let atLeastOneFabric = false;\n let defaultInstance = null;\n\n for (const callStatsInstance of CallStats.fabrics.values()) {\n if (!callStatsInstance.hasFabric) {\n logger.debug('addNewFabric - initCallback');\n if (callStatsInstance._addNewFabric()) {\n atLeastOneFabric = true;\n if (!defaultInstance) {\n defaultInstance = callStatsInstance;\n }\n }\n }\n }\n\n if (!atLeastOneFabric) {\n return;\n }\n\n CallStats._emptyReportQueue(defaultInstance);\n }\n\n /**\n * Empties report queue.\n *\n * @param {CallStats} csInstance - The callstats instance.\n * @private\n */\n static _emptyReportQueue(csInstance) {\n // There is no conference ID nor a PeerConnection available when some of\n // the events are scheduled on the reportsQueue, so those will be\n // reported on the first initialized fabric.\n const defaultConfID = csInstance.confID;\n const defaultPC = csInstance.peerconnection;\n\n // notify callstats about failures if there were any\n for (const report of CallStats.reportsQueue) {\n if (report.type === reportType.ERROR) {\n const errorData = report.data;\n\n CallStats._reportError(\n csInstance,\n errorData.type,\n errorData.error,\n errorData.pc || defaultPC);\n } else if (report.type === reportType.EVENT) {\n // if we have and event to report and we failed to add\n // fabric this event will not be reported anyway, returning\n // an error\n const eventData = report.data;\n\n CallStats.backend.sendFabricEvent(\n report.pc || defaultPC,\n eventData.event,\n defaultConfID,\n eventData.eventData);\n } else if (report.type === reportType.MST_WITH_USERID) {\n const data = report.data;\n\n CallStats.backend.associateMstWithUserID(\n report.pc || defaultPC,\n data.callStatsId,\n defaultConfID,\n data.ssrc,\n data.usageLabel,\n data.containerId\n );\n }\n }\n CallStats.reportsQueue.length = 0;\n }\n\n /* eslint-disable max-params */\n /**\n * Reports an error to callstats.\n *\n * @param {CallStats} [cs]\n * @param type the type of the error, which will be one of the wrtcFuncNames\n * @param error the error\n * @param pc the peerconnection\n * @private\n */\n static _reportError(cs, type, error, pc) {\n let _error = error;\n\n if (!_error) {\n logger.warn('No error is passed!');\n _error = new Error('Unknown error');\n }\n if (CallStats.backendInitialized && cs) {\n CallStats.backend.reportError(pc, cs.confID, type, _error);\n } else {\n CallStats.reportsQueue.push({\n type: reportType.ERROR,\n data: {\n error: _error,\n pc,\n type\n }\n });\n }\n\n // else just ignore it\n }\n\n /* eslint-enable max-params */\n\n /**\n * Reports an error to callstats.\n *\n * @param {CallStats} cs\n * @param event the type of the event, which will be one of the fabricEvent\n * @param eventData additional data to pass to event\n * @private\n */\n static _reportEvent(cs, event, eventData) {\n const pc = cs && cs.peerconnection;\n const confID = cs && cs.confID;\n\n if (CallStats.backendInitialized && cs) {\n CallStats.backend.sendFabricEvent(pc, event, confID, eventData);\n } else {\n CallStats.reportsQueue.push({\n confID,\n pc,\n type: reportType.EVENT,\n data: { event,\n eventData }\n });\n }\n }\n\n /**\n * Wraps some of the CallStats API method and logs their calls with\n * arguments on the debug logging level. Also wraps some of the backend\n * methods execution into try catch blocks to not crash the app in case\n * there is a problem with the backend itself.\n * @param {callstats} theBackend\n * @private\n */\n static _traceAndCatchBackendCalls(theBackend) {\n const tryCatchMethods = [\n 'associateMstWithUserID',\n 'sendFabricEvent',\n 'sendUserFeedback'\n\n // 'reportError', - this one needs special handling - see code below\n ];\n\n for (const methodName of tryCatchMethods) {\n const originalMethod = theBackend[methodName];\n\n theBackend[methodName] = function(...theArguments) {\n try {\n return originalMethod.apply(theBackend, theArguments);\n } catch (e) {\n GlobalOnErrorHandler.callErrorHandler(e);\n }\n };\n }\n const debugMethods = [\n 'associateMstWithUserID',\n 'sendFabricEvent',\n 'sendUserFeedback'\n\n // 'reportError', - this one needs special handling - see code below\n ];\n\n for (const methodName of debugMethods) {\n const originalMethod = theBackend[methodName];\n\n theBackend[methodName] = function(...theArguments) {\n logger.debug(methodName, theArguments);\n originalMethod.apply(theBackend, theArguments);\n };\n }\n const originalReportError = theBackend.reportError;\n\n /* eslint-disable max-params */\n theBackend.reportError = function(pc, cs, type, ...args) {\n // Logs from the logger are submitted on the applicationLog event\n // \"type\". Logging the arguments on the logger will create endless\n // loop, because it will put all the logs to the logger queue again.\n if (type === wrtcFuncNames.applicationLog) {\n // NOTE otherArguments are not logged to the console on purpose\n // to not log the whole log batch\n // FIXME check the current logging level (currently not exposed\n // by the logger implementation)\n // NOTE it is not safe to log whole objects on react-native as\n // those contain too many circular references and may crash\n // the app.\n if (!browser.isReactNative()) {\n console && console.debug('reportError', pc, cs, type);\n }\n } else {\n logger.debug('reportError', pc, cs, type, ...args);\n }\n try {\n originalReportError.call(theBackend, pc, cs, type, ...args);\n } catch (exception) {\n if (type === wrtcFuncNames.applicationLog) {\n console && console.error('reportError', exception);\n } else {\n GlobalOnErrorHandler.callErrorHandler(exception);\n }\n }\n };\n\n /* eslint-enable max-params */\n }\n\n /**\n * Returns the Set with the currently existing {@link CallStats} instances.\n * Lazily initializes the Set to allow any Set polyfills to be applied.\n * @type {Set}\n */\n static get fabrics() {\n if (!_fabrics) {\n _fabrics = new Set();\n }\n\n return _fabrics;\n }\n\n /**\n * Initializes the CallStats backend. Should be called only if\n * {@link CallStats.isBackendInitialized} returns false.\n * @param {object} options\n * @param {String} options.callStatsID CallStats credentials - ID\n * @param {String} options.callStatsSecret CallStats credentials - secret\n * @param {string} options.aliasName the aliasName part of\n * the userID aka endpoint ID, see CallStats docs for more info.\n * @param {string} options.userName the userName part of\n * the userID aka display name, see CallStats docs for more info.\n *\n */\n static initBackend(options) {\n if (CallStats.backend) {\n throw new Error('CallStats backend has been initialized already!');\n }\n try {\n const CallStatsBackend = callstats;\n\n CallStats.backend = new CallStatsBackend();\n CallStats._traceAndCatchBackendCalls(CallStats.backend);\n CallStats.userID = {\n aliasName: options.aliasName,\n userName: options.userName\n };\n CallStats.callStatsID = options.callStatsID;\n CallStats.callStatsSecret = options.callStatsSecret;\n\n let configParams;\n\n if (options.applicationName) {\n configParams = {\n applicationVersion:\n `${options.applicationName} (${\n browser.getName()})`\n };\n }\n\n if (options.confID) {\n // we first check is there a tenant in the confID\n const match = options.confID.match(/.*\\/(.*)\\/.*/);\n\n // if there is no tenant, we will just set '/'\n configParams.siteID = (match && match[1]) || '/';\n }\n\n // userID is generated or given by the origin server\n CallStats.backend.initialize(\n CallStats.callStatsID,\n CallStats.callStatsSecret,\n CallStats.userID,\n CallStats._initCallback,\n undefined,\n configParams);\n\n const getWiFiStatsMethod = options.getWiFiStatsMethod;\n\n if (getWiFiStatsMethod) {\n CallStats.backend.attachWifiStatsHandler(getWiFiStatsMethod);\n\n getWiFiStatsMethod().then(result => {\n if (result) {\n logger.info('Reported wifi addresses:'\n , JSON.parse(result).addresses);\n }\n })\n .catch(() => {});// eslint-disable-line no-empty-function\n }\n\n return true;\n } catch (e) {\n // The callstats.io API failed to initialize (e.g. because its\n // download did not succeed in general or on time). Further attempts\n // to utilize it cannot possibly succeed.\n GlobalOnErrorHandler.callErrorHandler(e);\n CallStats.backend = null;\n logger.error(e);\n\n return false;\n }\n }\n\n /**\n * Checks if the CallStats backend has been created. It does not mean that\n * it has been initialized, but only that the API instance has been\n * allocated successfully.\n * @return {boolean} true if backend exists or false\n * otherwise\n */\n static isBackendInitialized() {\n return Boolean(CallStats.backend);\n }\n\n /**\n * Notifies CallStats about active device.\n * @param {{deviceList: {String:String}}} devicesData list of devices with\n * their data\n * @param {CallStats} cs callstats instance related to the event\n */\n static sendActiveDeviceListEvent(devicesData, cs) {\n CallStats._reportEvent(cs, fabricEvent.activeDeviceList, devicesData);\n }\n\n /**\n * Notifies CallStats that there is a log we want to report.\n *\n * @param {Error} e error to send or {String} message\n * @param {CallStats} cs callstats instance related to the error (optional)\n */\n static sendApplicationLog(e, cs) {\n try {\n CallStats._reportError(\n cs,\n wrtcFuncNames.applicationLog,\n e,\n cs && cs.peerconnection);\n } catch (error) {\n // If sendApplicationLog fails it should not be printed to\n // the logger, because it will try to push the logs again\n // (through sendApplicationLog) and an endless loop is created.\n if (console && (typeof console.error === 'function')) {\n // FIXME send analytics event as well\n console.error('sendApplicationLog failed', error);\n }\n }\n }\n\n /**\n * Sends the given feedback through CallStats.\n *\n * @param {string} conferenceID the conference ID for which the feedback\n * will be reported.\n * @param overall an integer between 1 and 5 indicating the\n * user feedback\n * @param comment detailed feedback from the user.\n */\n static sendFeedback(conferenceID, overall, comment) {\n return new Promise((resolve, reject) => {\n if (CallStats.backend) {\n CallStats.backend.sendUserFeedback(\n conferenceID,\n {\n userID: CallStats.userID,\n overall,\n comment\n },\n (status, message) => {\n if (status === 'success') {\n resolve(message);\n } else {\n reject(message);\n }\n });\n } else {\n const reason = 'Failed to submit feedback to CallStats - no backend';\n\n logger.error(reason);\n reject(reason);\n }\n });\n }\n\n /**\n * Notifies CallStats that getUserMedia failed.\n *\n * @param {Error} e error to send\n * @param {CallStats} cs callstats instance related to the error (optional)\n */\n static sendGetUserMediaFailed(e, cs) {\n CallStats._reportError(cs, wrtcFuncNames.getUserMedia, e, null);\n }\n\n /**\n * Notifies CallStats for mute events\n * @param mute {boolean} true for muted and false for not muted\n * @param type {String} \"audio\"/\"video\"\n * @param {CallStats} cs callstats instance related to the event\n */\n static sendMuteEvent(mute, type, cs) {\n let event;\n\n if (type === 'video') {\n event = mute ? fabricEvent.videoPause : fabricEvent.videoResume;\n } else {\n event = mute ? fabricEvent.audioMute : fabricEvent.audioUnmute;\n }\n\n CallStats._reportEvent(cs, event);\n }\n\n /**\n * Creates new CallStats instance that handles all callstats API calls for\n * given {@link TraceablePeerConnection}. Each instance is meant to handle\n * one CallStats fabric added with 'addFabric' API method for the\n * {@link TraceablePeerConnection} instance passed in the constructor.\n * @param {TraceablePeerConnection} tpc\n * @param {Object} options\n * @param {string} options.confID the conference ID that wil be used to\n * report the session.\n * @param {string} [options.remoteUserID='jitsi'] the remote user ID to\n * which given tpc is connected.\n */\n constructor(tpc, options) {\n this.confID = options.confID;\n this.tpc = tpc;\n this.peerconnection = tpc.peerconnection;\n this.remoteUserID = options.remoteUserID || DEFAULT_REMOTE_USER;\n this.hasFabric = false;\n\n CallStats.fabrics.add(this);\n\n if (CallStats.backendInitialized) {\n this._addNewFabric();\n\n // if this is the first fabric let's try to empty the\n // report queue. Reports all events that we recorded between\n // backend initialization and receiving the first fabric\n if (CallStats.fabrics.size === 1) {\n CallStats._emptyReportQueue(this);\n }\n }\n }\n\n /**\n * Initializes CallStats fabric by calling \"addNewFabric\" for\n * the peer connection associated with this instance.\n * @return {boolean} true if the call was successful or false otherwise.\n */\n _addNewFabric() {\n logger.info('addNewFabric', this.remoteUserID);\n try {\n const fabricAttributes = {\n remoteEndpointType:\n this.tpc.isP2P\n ? CallStats.backend.endpointType.peer\n : CallStats.backend.endpointType.server\n };\n const ret\n = CallStats.backend.addNewFabric(\n this.peerconnection,\n this.remoteUserID,\n CallStats.backend.fabricUsage.multiplex,\n this.confID,\n fabricAttributes,\n CallStats._addNewFabricCallback);\n\n this.hasFabric = true;\n\n const success = ret.status === 'success';\n\n if (!success) {\n logger.error('callstats fabric not initilized', ret.message);\n }\n\n return success;\n\n } catch (error) {\n GlobalOnErrorHandler.callErrorHandler(error);\n\n return false;\n }\n }\n\n /* eslint-disable max-params */\n\n /**\n * Lets CallStats module know where is given SSRC rendered by providing\n * renderer tag ID.\n * If the lib is not initialized yet queue the call for later, when it's\n * ready.\n * @param {number} ssrc the SSRC of the stream\n * @param {boolean} isLocal indicates whether this the stream is local\n * @param {string|null} streamEndpointId if the stream is not local the it\n * needs to contain the stream owner's ID\n * @param {string} usageLabel meaningful usage label of this stream like\n * 'microphone', 'camera' or 'screen'.\n * @param {string} containerId the id of media 'audio' or 'video' tag which\n * renders the stream.\n */\n associateStreamWithVideoTag(\n ssrc,\n isLocal,\n streamEndpointId,\n usageLabel,\n containerId) {\n if (!CallStats.backend) {\n return;\n }\n\n const callStatsId = isLocal ? CallStats.userID : streamEndpointId;\n\n if (CallStats.backendInitialized) {\n CallStats.backend.associateMstWithUserID(\n this.peerconnection,\n callStatsId,\n this.confID,\n ssrc,\n usageLabel,\n containerId);\n } else {\n CallStats.reportsQueue.push({\n type: reportType.MST_WITH_USERID,\n pc: this.peerconnection,\n data: {\n callStatsId,\n containerId,\n ssrc,\n usageLabel\n }\n });\n }\n }\n\n /* eslint-enable max-params */\n\n /**\n * Notifies CallStats that we are the new dominant speaker in the\n * conference.\n */\n sendDominantSpeakerEvent() {\n CallStats._reportEvent(this, fabricEvent.dominantSpeaker);\n }\n\n /**\n * Notifies CallStats that the fabric for the underlying peerconnection was\n * closed and no evens should be reported, after this call.\n */\n sendTerminateEvent() {\n if (CallStats.backendInitialized) {\n CallStats.backend.sendFabricEvent(\n this.peerconnection,\n CallStats.backend.fabricEvent.fabricTerminated,\n this.confID);\n }\n CallStats.fabrics.delete(this);\n }\n\n /**\n * Notifies CallStats for ice connection failed\n */\n sendIceConnectionFailedEvent() {\n CallStats._reportError(\n this,\n wrtcFuncNames.iceConnectionFailure,\n null,\n this.peerconnection);\n }\n\n /**\n * Notifies CallStats that peer connection failed to create offer.\n *\n * @param {Error} e error to send\n */\n sendCreateOfferFailed(e) {\n CallStats._reportError(\n this, wrtcFuncNames.createOffer, e, this.peerconnection);\n }\n\n /**\n * Notifies CallStats that peer connection failed to create answer.\n *\n * @param {Error} e error to send\n */\n sendCreateAnswerFailed(e) {\n CallStats._reportError(\n this, wrtcFuncNames.createAnswer, e, this.peerconnection);\n }\n\n /**\n * Sends either resume or hold event for the fabric associated with\n * the underlying peerconnection.\n * @param {boolean} isResume true to resume or false to hold\n */\n sendResumeOrHoldEvent(isResume) {\n CallStats._reportEvent(\n this,\n isResume ? fabricEvent.fabricResume : fabricEvent.fabricHold);\n }\n\n /**\n * Notifies CallStats for screen sharing events\n * @param {boolean} start true for starting screen sharing and\n * false for not stopping\n * @param {string|null} ssrc - optional ssrc value, used only when\n * starting screen sharing.\n */\n sendScreenSharingEvent(start, ssrc) {\n let eventData;\n\n if (ssrc) {\n eventData = { ssrc };\n }\n\n CallStats._reportEvent(\n this,\n start ? fabricEvent.screenShareStart : fabricEvent.screenShareStop,\n eventData);\n }\n\n /**\n * Notifies CallStats that peer connection failed to set local description.\n *\n * @param {Error} e error to send\n */\n sendSetLocalDescFailed(e) {\n CallStats._reportError(\n this, wrtcFuncNames.setLocalDescription, e, this.peerconnection);\n }\n\n /**\n * Notifies CallStats that peer connection failed to set remote description.\n *\n * @param {Error} e error to send\n */\n sendSetRemoteDescFailed(e) {\n CallStats._reportError(\n this, wrtcFuncNames.setRemoteDescription, e, this.peerconnection);\n }\n\n /**\n * Notifies CallStats that peer connection failed to add ICE candidate.\n *\n * @param {Error} e error to send\n */\n sendAddIceCandidateFailed(e) {\n CallStats._reportError(\n this, wrtcFuncNames.addIceCandidate, e, this.peerconnection);\n }\n}\n\n/**\n * The CallStats API backend instance\n * @type {callstats}\n */\nCallStats.backend = null;\n\n// some errors/events may happen before CallStats init\n// in this case we accumulate them in this array\n// and send them to callstats on init\nCallStats.reportsQueue = [];\n\n/**\n * Whether the library was successfully initialized(the backend) using its\n * initialize method.\n * @type {boolean}\n */\nCallStats.backendInitialized = false;\n\n/**\n * Part of the CallStats credentials - application ID\n * @type {string}\n */\nCallStats.callStatsID = null;\n\n/**\n * Part of the CallStats credentials - application secret\n * @type {string}\n */\nCallStats.callStatsSecret = null;\n\n/**\n * Local CallStats user ID structure. Can be set only once when\n * {@link backend} is initialized, so it's static for the time being.\n * See CallStats API for more info:\n * https://www.callstats.io/api/#userid\n * @type {object}\n */\nCallStats.userID = null;\n", "import { getLogger } from 'jitsi-meet-logger';\nconst logger = getLogger(__filename);\n\nimport UsernameGenerator from '../util/UsernameGenerator';\n\nlet _callStatsUserName;\n\nlet _machineId;\n\n/**\n *\n */\nexport default {\n /**\n * Returns fake username for callstats\n * @returns {string} fake username for callstats\n */\n get callStatsUserName() {\n if (!_callStatsUserName) {\n const localStorage = getLocalStorage();\n\n if (localStorage) {\n _callStatsUserName = localStorage.getItem('callStatsUserName');\n }\n if (!_callStatsUserName) {\n _callStatsUserName = generateCallStatsUserName();\n if (localStorage) {\n localStorage.setItem(\n 'callStatsUserName',\n _callStatsUserName);\n }\n }\n }\n\n return _callStatsUserName;\n },\n\n /**\n * Returns current machine id.\n * @returns {string} machine id\n */\n get machineId() {\n if (!_machineId) {\n const localStorage = getLocalStorage();\n\n if (localStorage) {\n _machineId = localStorage.getItem('jitsiMeetId');\n }\n if (!_machineId) {\n _machineId = generateJitsiMeetId();\n if (localStorage) {\n localStorage.setItem('jitsiMeetId', _machineId);\n }\n }\n }\n\n return _machineId;\n },\n\n /**\n * Returns current session id.\n * @returns {string} current session id\n */\n get sessionId() {\n // We may update sessionId in localStorage from another JitsiConference\n // instance and that's why we should always re-read it.\n const localStorage = getLocalStorage();\n\n return localStorage ? localStorage.getItem('sessionId') : undefined;\n },\n\n /**\n * Save current session id.\n * @param {string} sessionId session id\n */\n set sessionId(sessionId) {\n const localStorage = getLocalStorage();\n\n if (localStorage) {\n if (sessionId) {\n localStorage.setItem('sessionId', sessionId);\n } else {\n localStorage.removeItem('sessionId');\n }\n }\n }\n};\n\n/**\n * Generate fake username for callstats.\n * @returns {string} fake random username\n */\nfunction generateCallStatsUserName() {\n const username = UsernameGenerator.generateUsername();\n\n logger.log('generated callstats uid', username);\n\n return username;\n}\n\n/**\n * Generate unique id.\n * @returns {string} random unique id\n */\nfunction generateJitsiMeetId() {\n const jitsiMeetId = generateUniqueId();\n\n logger.log('generated id', jitsiMeetId);\n\n return jitsiMeetId;\n}\n\n/**\n * Gets the localStorage of the browser. (Technically, gets the localStorage of\n * the global object because there may be no browser but React Native for\n * example).\n * @returns {Storage} the local Storage object (if any)\n */\nfunction getLocalStorage() {\n let storage;\n\n try {\n // eslint-disable-next-line no-invalid-this\n storage = (window || this).localStorage;\n } catch (error) {\n logger.error(error);\n }\n\n return storage;\n}\n\n/**\n *\n */\nfunction generateUniqueId() {\n return _p8() + _p8() + _p8() + _p8();\n}\n\n/**\n *\n */\nfunction _p8() {\n return `${Math.random().toString(16)}000000000`.substr(2, 8);\n}\n", "/**\n * @const\n */\nconst ALPHANUM\n = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n\n/**\n * Hexadecimal digits.\n * @const\n */\nconst HEX_DIGITS = '0123456789abcdef';\n\n/**\n * Generates random int within the range [min, max]\n * @param min the minimum value for the generated number\n * @param max the maximum value for the generated number\n * @returns random int number\n */\nfunction randomInt(min, max) {\n return Math.floor(Math.random() * (max - min + 1)) + min;\n}\n\n/**\n * Get random element from array or string.\n * @param {Array|string} arr source\n * @returns array element or string character\n */\nfunction randomElement(arr) {\n return arr[randomInt(0, arr.length - 1)];\n}\n\n/**\n * Generate random alphanumeric string.\n * @param {number} length expected string length\n * @returns {string} random string of specified length\n */\nfunction randomAlphanumStr(length) {\n let result = '';\n\n for (let i = 0; i < length; i += 1) {\n result += randomElement(ALPHANUM);\n }\n\n return result;\n}\n\n/**\n * Exported interface.\n */\nconst RandomUtil = {\n /**\n * Returns a random hex digit.\n * @returns {*}\n */\n randomHexDigit() {\n return randomElement(HEX_DIGITS);\n },\n\n /**\n * Returns a random string of hex digits with length 'len'.\n * @param len the length.\n */\n randomHexString(len) {\n let ret = '';\n\n while (len--) { // eslint-disable-line no-param-reassign\n ret += this.randomHexDigit();\n }\n\n return ret;\n },\n randomElement,\n randomAlphanumStr,\n randomInt\n};\n\nmodule.exports = RandomUtil;\n", "import Listenable from '../util/Listenable';\n\n/**\n * Creates ConnectionPlugin class that extends the passed class.\n * @param {Class} base the definition of the class that will be extended by\n * ConnectionPlugin\n */\nfunction getConnectionPluginDefinition(base = class {}) {\n /**\n * Base class for strophe connection plugins.\n */\n return class extends base {\n /**\n *\n */\n constructor(...args) {\n super(...args);\n this.connection = null;\n }\n\n /**\n *\n * @param connection\n */\n init(connection) {\n this.connection = connection;\n }\n };\n}\n\n/**\n * ConnectionPlugin class.\n */\nexport default getConnectionPluginDefinition();\n\n/**\n * ConnectionPlugin class that extends Listenable.\n */\nexport const ConnectionPluginListenable\n = getConnectionPluginDefinition(Listenable);\n", "/* global $ */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport { $msg, Strophe } from 'strophe.js';\nimport 'strophejs-plugin-disco';\n\nimport RandomUtil from '../util/RandomUtil';\nimport * as JitsiConnectionErrors from '../../JitsiConnectionErrors';\nimport * as JitsiConnectionEvents from '../../JitsiConnectionEvents';\nimport browser from '../browser';\nimport MucConnectionPlugin from './strophe.emuc';\nimport JingleConnectionPlugin from './strophe.jingle';\nimport initStropheUtil from './strophe.util';\nimport PingConnectionPlugin from './strophe.ping';\nimport RayoConnectionPlugin from './strophe.rayo';\nimport initStropheLogger from './strophe.logger';\nimport Listenable from '../util/Listenable';\nimport Caps from './Caps';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport XMPPEvents from '../../service/xmpp/XMPPEvents';\nimport XmppConnection from './XmppConnection';\n\nconst logger = getLogger(__filename);\n\n/**\n * Creates XMPP connection.\n *\n * @param {Object} options\n * @param {string} [options.token] - JWT token used for authentication(JWT authentication module must be enabled in\n * Prosody).\n * @param {string} options.serviceUrl - The service URL for XMPP connection.\n * @param {string} options.enableWebsocketResume - True to enable stream resumption.\n * @param {number} [options.websocketKeepAlive] - See {@link XmppConnection} constructor.\n * @returns {XmppConnection}\n */\nfunction createConnection({ enableWebsocketResume, serviceUrl = '/http-bind', token, websocketKeepAlive }) {\n // Append token as URL param\n if (token) {\n // eslint-disable-next-line no-param-reassign\n serviceUrl += `${serviceUrl.indexOf('?') === -1 ? '?' : '&'}token=${token}`;\n }\n\n return new XmppConnection({\n enableWebsocketResume,\n serviceUrl,\n websocketKeepAlive\n });\n}\n\n/**\n * Initializes Strophe plugins that need to work with Strophe.Connection directly rather than the lib-jitsi-meet's\n * {@link XmppConnection} wrapper.\n *\n * @returns {void}\n */\nfunction initStropheNativePlugins() {\n initStropheUtil();\n initStropheLogger();\n}\n\n// FIXME: remove once we have a default config template. -saghul\n/**\n * A list of ice servers to use by default for P2P.\n */\nexport const DEFAULT_STUN_SERVERS = [\n { urls: 'stun:stun.l.google.com:19302' },\n { urls: 'stun:stun1.l.google.com:19302' },\n { urls: 'stun:stun2.l.google.com:19302' }\n];\n\n/**\n * The name of the field used to recognize a chat message as carrying a JSON\n * payload from another endpoint.\n * If the json-message of a chat message contains a valid JSON object, and\n * the JSON has this key, then it is a valid json-message to be sent.\n */\nexport const JITSI_MEET_MUC_TYPE = 'type';\n\n/**\n *\n */\nexport default class XMPP extends Listenable {\n /**\n * FIXME describe all options\n * @param {Object} options\n * @param {String} options.serviceUrl - URL passed to the XMPP client which will be used to establish XMPP\n * connection with the server.\n * @param {String} options.bosh - Deprecated, use {@code serviceUrl}.\n * @param {boolean} options.enableWebsocketResume - Enables XEP-0198 stream management which will make the XMPP\n * module try to resume the session in case the Websocket connection breaks.\n * @param {number} [options.websocketKeepAlive] - The websocket keep alive interval. See {@link XmppConnection}\n * constructor for more details.\n * @param {Array} options.p2pStunServers see {@link JingleConnectionPlugin} for more details.\n * @param token\n */\n constructor(options, token) {\n super();\n this.connection = null;\n this.disconnectInProgress = false;\n this.connectionTimes = {};\n this.options = options;\n this.token = token;\n this.authenticatedUser = false;\n\n initStropheNativePlugins();\n\n this.connection = createConnection({\n enableWebsocketResume: options.enableWebsocketResume,\n\n // FIXME remove deprecated bosh option at some point\n serviceUrl: options.serviceUrl || options.bosh,\n token,\n websocketKeepAlive: options.websocketKeepAlive\n });\n\n this._initStrophePlugins();\n\n this.caps = new Caps(this.connection, this.options.clientNode);\n\n // Initialize features advertised in disco-info\n this.initFeaturesList();\n\n // Setup a disconnect on unload as a way to facilitate API consumers. It\n // sounds like they would want that. A problem for them though may be if\n // they wanted to utilize the connected connection in an unload handler\n // of their own. However, it should be fairly easy for them to do that\n // by registering their unload handler before us.\n $(window).on('beforeunload unload', ev => {\n this.disconnect(ev).catch(() => {\n // ignore errors in order to not brake the unload.\n });\n });\n }\n\n /**\n * Initializes the list of feature advertised through the disco-info\n * mechanism.\n */\n initFeaturesList() {\n // http://xmpp.org/extensions/xep-0167.html#support\n // http://xmpp.org/extensions/xep-0176.html#support\n this.caps.addFeature('urn:xmpp:jingle:1');\n this.caps.addFeature('urn:xmpp:jingle:apps:rtp:1');\n this.caps.addFeature('urn:xmpp:jingle:transports:ice-udp:1');\n this.caps.addFeature('urn:xmpp:jingle:apps:dtls:0');\n this.caps.addFeature('urn:xmpp:jingle:transports:dtls-sctp:1');\n this.caps.addFeature('urn:xmpp:jingle:apps:rtp:audio');\n this.caps.addFeature('urn:xmpp:jingle:apps:rtp:video');\n\n if (!this.options.disableRtx && browser.supportsRtx()) {\n this.caps.addFeature('urn:ietf:rfc:4588');\n }\n\n // this is dealt with by SDP O/A so we don't need to announce this\n // XEP-0293\n // this.caps.addFeature('urn:xmpp:jingle:apps:rtp:rtcp-fb:0');\n // XEP-0294\n // this.caps.addFeature('urn:xmpp:jingle:apps:rtp:rtp-hdrext:0');\n\n this.caps.addFeature('urn:ietf:rfc:5761'); // rtcp-mux\n this.caps.addFeature('urn:ietf:rfc:5888'); // a=group, e.g. bundle\n\n // this.caps.addFeature('urn:ietf:rfc:5576'); // a=ssrc\n\n // Enable Lipsync ?\n if (browser.isChrome() && this.options.enableLipSync === true) {\n logger.info('Lip-sync enabled !');\n this.caps.addFeature('http://jitsi.org/meet/lipsync');\n }\n\n if (this.connection.rayo) {\n this.caps.addFeature('urn:xmpp:rayo:client:1');\n }\n\n if (browser.supportsInsertableStreams()) {\n this.caps.addFeature('https://jitsi.org/meet/e2ee');\n }\n }\n\n /**\n * Returns {@code true} if the PING functionality is supported by the server\n * or {@code false} otherwise.\n * @returns {boolean}\n */\n isPingSupported() {\n return this._pingSupported !== false;\n }\n\n /**\n *\n */\n getConnection() {\n return this.connection;\n }\n\n /**\n * Receive connection status changes and handles them.\n *\n * @param {Object} credentials\n * @param {string} credentials.jid - The user's XMPP ID passed to the\n * connect method. For example, 'user@xmpp.com'.\n * @param {string} credentials.password - The password passed to the connect\n * method.\n * @param {string} status - One of Strophe's connection status strings.\n * @param {string} [msg] - The connection error message provided by Strophe.\n */\n connectionHandler(credentials = {}, status, msg) {\n const now = window.performance.now();\n const statusStr = Strophe.getStatusString(status).toLowerCase();\n\n this.connectionTimes[statusStr] = now;\n logger.log(\n `(TIME) Strophe ${statusStr}${msg ? `[${msg}]` : ''}:\\t`,\n now);\n\n this.eventEmitter.emit(XMPPEvents.CONNECTION_STATUS_CHANGED, credentials, status, msg);\n if (status === Strophe.Status.CONNECTED\n || status === Strophe.Status.ATTACHED) {\n if (this.options.useStunTurn\n || (this.options.p2p && this.options.p2p.useStunTurn)) {\n this.connection.jingle.getStunAndTurnCredentials();\n }\n\n logger.info(`My Jabber ID: ${this.connection.jid}`);\n\n // XmppConnection emits CONNECTED again on reconnect - a good opportunity to clear any \"last error\" flags\n this._resetState();\n\n // Schedule ping ?\n const pingJid = this.connection.domain;\n\n // FIXME no need to do it again on stream resume\n this.caps.getFeaturesAndIdentities(pingJid)\n .then(({ features, identities }) => {\n if (features.has(Strophe.NS.PING)) {\n this._pingSupported = true;\n this.connection.ping.startInterval(pingJid);\n } else {\n logger.warn(`Ping NOT supported by ${pingJid}`);\n }\n\n // check for speakerstats\n identities.forEach(identity => {\n if (identity.type === 'speakerstats') {\n this.speakerStatsComponentAddress = identity.name;\n }\n\n if (identity.type === 'conference_duration') {\n this.conferenceDurationComponentAddress = identity.name;\n }\n });\n\n if (this.speakerStatsComponentAddress\n || this.conferenceDurationComponentAddress) {\n this.connection.addHandler(\n this._onPrivateMessage.bind(this), null,\n 'message', null, null);\n }\n })\n .catch(error => {\n const errmsg = 'Feature discovery error';\n\n GlobalOnErrorHandler.callErrorHandler(\n new Error(`${errmsg}: ${error}`));\n logger.error(errmsg, error);\n });\n\n if (credentials.password) {\n this.authenticatedUser = true;\n }\n if (this.connection && this.connection.connected\n && Strophe.getResourceFromJid(this.connection.jid)) {\n // .connected is true while connecting?\n // this.connection.send($pres());\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_ESTABLISHED,\n Strophe.getResourceFromJid(this.connection.jid));\n }\n } else if (status === Strophe.Status.CONNFAIL) {\n if (msg === 'x-strophe-bad-non-anon-jid') {\n this.anonymousConnectionFailed = true;\n } else {\n this.connectionFailed = true;\n }\n this.lastErrorMsg = msg;\n if (msg === 'giving-up') {\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.OTHER_ERROR, msg);\n }\n } else if (status === Strophe.Status.ERROR) {\n this.lastErrorMsg = msg;\n } else if (status === Strophe.Status.DISCONNECTED) {\n // Stop ping interval\n this.connection.ping.stopInterval();\n const wasIntentionalDisconnect = Boolean(this.disconnectInProgress);\n const errMsg = msg || this.lastErrorMsg;\n\n if (this.anonymousConnectionFailed) {\n // prompt user for username and password\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.PASSWORD_REQUIRED);\n } else if (this.connectionFailed) {\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.OTHER_ERROR,\n errMsg,\n undefined, /* credentials */\n this._getConnectionFailedReasonDetails());\n } else if (wasIntentionalDisconnect) {\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_DISCONNECTED, errMsg);\n } else {\n // XXX if Strophe drops the connection while not being asked to,\n // it means that most likely some serious error has occurred.\n // One currently known case is when a BOSH request fails for\n // more than 4 times. The connection is dropped without\n // supplying a reason(error message/event) through the API.\n logger.error('XMPP connection dropped!');\n\n // XXX if the last request error is within 5xx range it means it\n // was a server failure\n const lastErrorStatus = Strophe.getLastErrorStatus();\n\n if (lastErrorStatus >= 500 && lastErrorStatus < 600) {\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.SERVER_ERROR,\n errMsg || 'server-error',\n /* credentials */ undefined,\n this._getConnectionFailedReasonDetails());\n } else {\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.CONNECTION_DROPPED_ERROR,\n errMsg || 'connection-dropped-error',\n /* credentials */ undefined,\n this._getConnectionFailedReasonDetails());\n }\n }\n } else if (status === Strophe.Status.AUTHFAIL) {\n // wrong password or username, prompt user\n this.eventEmitter.emit(\n JitsiConnectionEvents.CONNECTION_FAILED,\n JitsiConnectionErrors.PASSWORD_REQUIRED,\n msg,\n credentials);\n }\n }\n\n /**\n *\n * @param jid\n * @param password\n */\n _connect(jid, password) {\n // connection.connect() starts the connection process.\n //\n // As the connection process proceeds, the user supplied callback will\n // be triggered multiple times with status updates. The callback should\n // take two arguments - the status code and the error condition.\n //\n // The status code will be one of the values in the Strophe.Status\n // constants. The error condition will be one of the conditions defined\n // in RFC 3920 or the condition ‘strophe-parsererror’.\n //\n // The Parameters wait, hold and route are optional and only relevant\n // for BOSH connections. Please see XEP 124 for a more detailed\n // explanation of the optional parameters.\n //\n // Connection status constants for use by the connection handler\n // callback.\n //\n // Status.ERROR - An error has occurred (websockets specific)\n // Status.CONNECTING - The connection is currently being made\n // Status.CONNFAIL - The connection attempt failed\n // Status.AUTHENTICATING - The connection is authenticating\n // Status.AUTHFAIL - The authentication attempt failed\n // Status.CONNECTED - The connection has succeeded\n // Status.DISCONNECTED - The connection has been terminated\n // Status.DISCONNECTING - The connection is currently being terminated\n // Status.ATTACHED - The connection has been attached\n\n this._resetState();\n this.connection.connect(\n jid,\n password,\n this.connectionHandler.bind(this, {\n jid,\n password\n }));\n }\n\n /**\n * Attach to existing connection. Can be used for optimizations. For\n * example: if the connection is created on the server we can attach to it\n * and start using it.\n *\n * @param options {object} connecting options - rid, sid, jid and password.\n */\n attach(options) {\n this._resetState();\n const now = this.connectionTimes.attaching = window.performance.now();\n\n logger.log('(TIME) Strophe Attaching:\\t', now);\n this.connection.attach(options.jid, options.sid,\n parseInt(options.rid, 10) + 1,\n this.connectionHandler.bind(this, {\n jid: options.jid,\n password: options.password\n }));\n }\n\n /**\n * Resets any state/flag before starting a new connection.\n * @private\n */\n _resetState() {\n this.anonymousConnectionFailed = false;\n this.connectionFailed = false;\n this.lastErrorMsg = undefined;\n this.disconnectInProgress = undefined;\n }\n\n /**\n *\n * @param jid\n * @param password\n */\n connect(jid, password) {\n if (!jid) {\n const { anonymousdomain, domain } = this.options.hosts;\n let configDomain = anonymousdomain || domain;\n\n // Force authenticated domain if room is appended with '?login=true'\n // or if we're joining with the token\n\n // FIXME Do not rely on window.location because (1) React Native\n // does not have a window.location by default and (2) here we cannot\n // know for sure that query/search has not be stripped from\n // window.location by the time the following executes.\n const { location } = window;\n\n if (anonymousdomain) {\n const search = location && location.search;\n\n if ((search && search.indexOf('login=true') !== -1)\n || this.token) {\n configDomain = domain;\n }\n }\n\n // eslint-disable-next-line no-param-reassign\n jid = configDomain || (location && location.hostname);\n }\n\n return this._connect(jid, password);\n }\n\n /**\n * Joins or creates a muc with the provided jid, created from the passed\n * in room name and muc host and onCreateResource result.\n *\n * @param {string} roomName - The name of the muc to join.\n * @param {Object} options - Configuration for how to join the muc.\n * @param {Function} [onCreateResource] - Callback to invoke when a resource\n * is to be added to the jid.\n * @returns {Promise} Resolves with an instance of a strophe muc.\n */\n createRoom(roomName, options, onCreateResource) {\n let roomjid = `${roomName}@${this.options.hosts.muc}/`;\n\n const mucNickname = onCreateResource\n ? onCreateResource(this.connection.jid, this.authenticatedUser)\n : RandomUtil.randomHexString(8).toLowerCase();\n\n logger.info(`JID ${this.connection.jid} using MUC nickname ${mucNickname}`);\n roomjid += mucNickname;\n\n return this.connection.emuc.createRoom(roomjid, null, options);\n }\n\n /**\n * Returns the jid of the participant associated with the Strophe connection.\n *\n * @returns {string} The jid of the participant.\n */\n getJid() {\n return this.connection.jid;\n }\n\n /**\n * Returns the logs from strophe.jingle.\n * @returns {Object}\n */\n getJingleLog() {\n const jingle = this.connection.jingle;\n\n\n return jingle ? jingle.getLog() : {};\n }\n\n /**\n * Returns the logs from strophe.\n */\n getXmppLog() {\n return (this.connection.logger || {}).log || null;\n }\n\n /**\n *\n */\n dial(...args) {\n this.connection.rayo.dial(...args);\n }\n\n /**\n * Pings the server. Remember to check {@link isPingSupported} before using\n * this method.\n * @param timeout how many ms before a timeout should occur.\n * @returns {Promise} resolved on ping success and reject on an error or\n * a timeout.\n */\n ping(timeout) {\n return new Promise((resolve, reject) => {\n if (this.isPingSupported()) {\n this.connection.ping\n .ping(this.connection.domain, resolve, reject, timeout);\n } else {\n reject('PING operation is not supported by the server');\n }\n });\n }\n\n /**\n *\n */\n getSessions() {\n return this.connection.jingle.sessions;\n }\n\n /**\n * Disconnects this from the XMPP server (if this is connected).\n *\n * @param {Object} ev - Optionally, the event which triggered the necessity to\n * disconnect from the XMPP server (e.g. beforeunload, unload).\n * @returns {Promise} - Resolves when the disconnect process is finished or rejects with an error.\n */\n disconnect(ev) {\n if (this.disconnectInProgress) {\n return this.disconnectInProgress;\n } else if (!this.connection) {\n return Promise.resolve();\n }\n\n this.disconnectInProgress = new Promise(resolve => {\n const disconnectListener = (credentials, status) => {\n if (status === Strophe.Status.DISCONNECTED) {\n resolve();\n this.eventEmitter.removeListener(XMPPEvents.CONNECTION_STATUS_CHANGED, disconnectListener);\n }\n };\n\n this.eventEmitter.on(XMPPEvents.CONNECTION_STATUS_CHANGED, disconnectListener);\n });\n\n this._cleanupXmppConnection(ev);\n\n return this.disconnectInProgress;\n }\n\n /**\n * The method is supposed to gracefully close the XMPP connection and the main goal is to make sure that the current\n * participant will be removed from the conference XMPP MUC, so that it doesn't leave a \"ghost\" participant behind.\n *\n * @param {Object} ev - Optionally, the event which triggered the necessity to disconnect from the XMPP server\n * (e.g. beforeunload, unload).\n * @private\n * @returns {void}\n */\n _cleanupXmppConnection(ev) {\n // XXX Strophe is asynchronously sending by default. Unfortunately, that means that there may not be enough time\n // to send an unavailable presence or disconnect at all. Switching Strophe to synchronous sending is not much of\n // an option because it may lead to a noticeable delay in navigating away from the current location. As\n // a compromise, we will try to increase the chances of sending an unavailable presence and/or disconnecting\n // within the short time span that we have upon unloading by invoking flush() on the connection. We flush() once\n // before disconnect() in order to attempt to have its unavailable presence at the top of the send queue. We\n // flush() once more after disconnect() in order to attempt to have its unavailable presence sent as soon as\n // possible.\n !this.connection.isUsingWebSocket && this.connection.flush();\n\n if (!this.connection.isUsingWebSocket && ev !== null && typeof ev !== 'undefined') {\n const evType = ev.type;\n\n if (evType === 'beforeunload' || evType === 'unload') {\n // XXX Whatever we said above, synchronous sending is the best (known) way to properly disconnect from\n // the XMPP server. Consequently, it may be fine to have the source code and comment it in or out\n // depending on whether we want to run with it for some time.\n this.connection.options.sync = true;\n\n // This is needed in some browsers where sync xhr sending is disabled by default on unload.\n if (this.connection.sendUnavailableBeacon()) {\n\n return;\n }\n }\n }\n\n this.connection.disconnect();\n\n if (this.connection.options.sync !== true) {\n this.connection.flush();\n }\n }\n\n /**\n *\n */\n _initStrophePlugins() {\n const iceConfig = {\n jvb: { iceServers: [ ] },\n p2p: { iceServers: [ ] }\n };\n\n const p2pStunServers = (this.options.p2p\n && this.options.p2p.stunServers) || DEFAULT_STUN_SERVERS;\n\n if (Array.isArray(p2pStunServers)) {\n logger.info('P2P STUN servers: ', p2pStunServers);\n iceConfig.p2p.iceServers = p2pStunServers;\n }\n\n if (this.options.p2p && this.options.p2p.iceTransportPolicy) {\n logger.info('P2P ICE transport policy: ',\n this.options.p2p.iceTransportPolicy);\n\n iceConfig.p2p.iceTransportPolicy\n = this.options.p2p.iceTransportPolicy;\n }\n\n this.connection.addConnectionPlugin('emuc', new MucConnectionPlugin(this));\n this.connection.addConnectionPlugin('jingle', new JingleConnectionPlugin(this, this.eventEmitter, iceConfig));\n this.connection.addConnectionPlugin('ping', new PingConnectionPlugin(this));\n this.connection.addConnectionPlugin('rayo', new RayoConnectionPlugin());\n }\n\n /**\n * Returns details about connection failure. Shard change or is it after\n * suspend.\n * @returns {object} contains details about a connection failure.\n * @private\n */\n _getConnectionFailedReasonDetails() {\n const details = {};\n\n // check for moving between shard if information is available\n if (this.options.deploymentInfo\n && this.options.deploymentInfo.shard\n && this.connection.lastResponseHeaders) {\n\n // split headers by line\n const headersArr = this.connection.lastResponseHeaders\n .trim().split(/[\\r\\n]+/);\n const headers = {};\n\n headersArr.forEach(line => {\n const parts = line.split(': ');\n const header = parts.shift();\n const value = parts.join(': ');\n\n headers[header] = value;\n });\n\n /* eslint-disable camelcase */\n details.shard_changed\n = this.options.deploymentInfo.shard\n !== headers['x-jitsi-shard'];\n /* eslint-enable camelcase */\n }\n\n /* eslint-disable camelcase */\n // check for possible suspend\n details.suspend_time = this.connection.ping.getPingSuspendTime();\n details.time_since_last_success = this.connection.getTimeSinceLastSuccess();\n /* eslint-enable camelcase */\n\n return details;\n }\n\n /**\n * Notifies speaker stats component if available that we are the new\n * dominant speaker in the conference.\n * @param {String} roomJid - The room jid where the speaker event occurred.\n */\n sendDominantSpeakerEvent(roomJid) {\n // no speaker stats component advertised\n if (!this.speakerStatsComponentAddress || !roomJid) {\n return;\n }\n\n const msg = $msg({ to: this.speakerStatsComponentAddress });\n\n msg.c('speakerstats', {\n xmlns: 'http://jitsi.org/jitmeet',\n room: roomJid })\n .up();\n\n this.connection.send(msg);\n }\n\n /**\n * Check if the given argument is a valid JSON ENDPOINT_MESSAGE string by\n * parsing it and checking if it has a field called 'type'.\n *\n * @param {string} jsonString check if this string is a valid json string\n * and contains the special structure.\n * @returns {boolean, object} if given object is a valid JSON string, return\n * the json object. Otherwise, returns false.\n */\n tryParseJSONAndVerify(jsonString) {\n try {\n const json = JSON.parse(jsonString);\n\n // Handle non-exception-throwing cases:\n // Neither JSON.parse(false) or JSON.parse(1234) throw errors,\n // hence the type-checking,\n // but... JSON.parse(null) returns null, and\n // typeof null === \"object\",\n // so we must check for that, too.\n // Thankfully, null is falsey, so this suffices:\n if (json && typeof json === 'object') {\n const type = json[JITSI_MEET_MUC_TYPE];\n\n if (typeof type !== 'undefined') {\n return json;\n }\n\n logger.debug('parsing valid json but does not have correct '\n + 'structure', 'topic: ', type);\n }\n } catch (e) {\n return false;\n }\n\n return false;\n }\n\n /**\n * A private message is received, message that is not addressed to the muc.\n * We expect private message coming from plugins component if it is\n * enabled and running.\n *\n * @param {string} msg - The message.\n */\n _onPrivateMessage(msg) {\n const from = msg.getAttribute('from');\n\n if (!(from === this.speakerStatsComponentAddress\n || from === this.conferenceDurationComponentAddress)) {\n return;\n }\n\n const jsonMessage = $(msg).find('>json-message')\n .text();\n const parsedJson = this.tryParseJSONAndVerify(jsonMessage);\n\n if (parsedJson\n && parsedJson[JITSI_MEET_MUC_TYPE] === 'speakerstats'\n && parsedJson.users) {\n this.eventEmitter.emit(\n XMPPEvents.SPEAKER_STATS_RECEIVED, parsedJson.users);\n }\n\n if (parsedJson\n && parsedJson[JITSI_MEET_MUC_TYPE] === 'conference_duration'\n && parsedJson.created_timestamp) {\n this.eventEmitter.emit(\n XMPPEvents.CONFERENCE_TIMESTAMP_RECEIVED, parsedJson.created_timestamp);\n }\n\n return true;\n }\n}\n", "/**\n * Event triggered when participant's muted status changes.\n * @param {string} endpointId the track owner's identifier (MUC nickname)\n * @param {MediaType} mediaType \"audio\" or \"video\"\n * @param {boolean} isMuted the new muted state\n */\nexport const PEER_MUTED_CHANGED = 'signaling.peerMuted';\n\n/**\n * Event triggered when participant's video type changes.\n * @param {string} endpointId the video owner's ID (MUC nickname)\n * @param {VideoType} videoType the new value\n */\nexport const PEER_VIDEO_TYPE_CHANGED = 'signaling.peerVideoType';\n", "/**\n * The errors for the connection.\n */\n\n/**\n * Indicates that the connection was dropped with an error which was most likely\n * caused by some networking issues. The dropped term in this context means that\n * the connection was closed unexpectedly (not on user's request).\n *\n * One example is 'item-not-found' error thrown by Prosody when the BOSH session\n * times out after 60 seconds of inactivity. On the other hand 'item-not-found'\n * could also happen when BOSH request is sent to the server with the session-id\n * that is not know to the server. But this should not happen in lib-jitsi-meet\n * case as long as the service is configured correctly (there is no bug).\n */\nexport const CONNECTION_DROPPED_ERROR = 'connection.droppedError';\n\n/**\n * Not specified errors.\n */\nexport const OTHER_ERROR = 'connection.otherError';\n\n/**\n * Indicates that a password is required in order to join the conference.\n */\nexport const PASSWORD_REQUIRED = 'connection.passwordRequired';\n\n/**\n * Indicates that the connection was dropped, because of too many 5xx HTTP\n * errors on BOSH requests.\n */\nexport const SERVER_ERROR = 'connection.serverError';\n", "import { getLogger } from 'jitsi-meet-logger';\nimport { $pres, Strophe } from 'strophe.js';\nimport 'strophejs-plugin-stream-management';\n\nimport Listenable from '../util/Listenable';\nimport { getJitterDelay } from '../util/Retry';\n\nimport LastSuccessTracker from './StropheLastSuccess';\n\nconst logger = getLogger(__filename);\n\n/**\n * The lib-jitsi-meet layer for {@link Strophe.Connection}.\n */\nexport default class XmppConnection extends Listenable {\n /**\n * The list of {@link XmppConnection} events.\n *\n * @returns {Object}\n */\n static get Events() {\n return {\n CONN_STATUS_CHANGED: 'CONN_STATUS_CHANGED'\n };\n }\n\n /**\n * The list of Xmpp connection statuses.\n *\n * @returns {Strophe.Status}\n */\n static get Status() {\n return Strophe.Status;\n }\n\n /**\n * Initializes new connection instance.\n *\n * @param {Object} options\n * @param {String} options.serviceUrl - The BOSH or WebSocket service URL.\n * @param {String} [options.enableWebsocketResume=true] - True/false to control the stream resumption functionality.\n * It will enable automatically by default if supported by the XMPP server.\n * @param {Number} [options.websocketKeepAlive=240000] - The websocket keep alive interval. It's 4 minutes by\n * default with jitter. Pass -1 to disable. The actual interval equation is:\n * jitterDelay = (interval * 0.2) + (0.8 * interval * Math.random())\n * The keep alive is HTTP GET request to the {@link options.serviceUrl}.\n */\n constructor({ enableWebsocketResume, websocketKeepAlive, serviceUrl }) {\n super();\n this._options = {\n enableWebsocketResume: typeof enableWebsocketResume === 'undefined' ? true : enableWebsocketResume,\n websocketKeepAlive: typeof websocketKeepAlive === 'undefined' ? 4 * 60 * 1000 : Number(websocketKeepAlive)\n };\n\n /**\n * The counter increased before each resume retry attempt, used to calculate exponential backoff.\n * @type {number}\n * @private\n */\n this._resumeRetryN = 0;\n this._stropheConn = new Strophe.Connection(serviceUrl);\n this._usesWebsocket = serviceUrl.startsWith('ws:') || serviceUrl.startsWith('wss:');\n\n // The default maxRetries is 5, which is too long.\n this._stropheConn.maxRetries = 3;\n\n this._lastSuccessTracker = new LastSuccessTracker();\n this._lastSuccessTracker.startTracking(this._stropheConn);\n }\n\n /**\n * A getter for the connected state.\n *\n * @returns {boolean}\n */\n get connected() {\n return this._status === Strophe.Status.CONNECTED || this._status === Strophe.Status.ATTACHED;\n }\n\n /**\n * Retrieves the feature discovery plugin instance.\n *\n * @returns {Strophe.Connection.disco}\n */\n get disco() {\n return this._stropheConn.disco;\n }\n\n /**\n * A getter for the disconnecting state.\n *\n * @returns {boolean}\n */\n get disconnecting() {\n return this._stropheConn.disconnecting === true;\n }\n\n /**\n * A getter for the domain.\n *\n * @returns {string|null}\n */\n get domain() {\n return this._stropheConn.domain;\n }\n\n /**\n * Tells if Websocket is used as the transport for the current XMPP connection. Returns true for Websocket or false\n * for BOSH.\n * @returns {boolean}\n */\n get isUsingWebSocket() {\n return this._usesWebsocket;\n }\n\n /**\n * A getter for the JID.\n *\n * @returns {string|null}\n */\n get jid() {\n return this._stropheConn.jid;\n }\n\n /**\n * Returns headers for the last BOSH response received.\n *\n * @returns {string}\n */\n get lastResponseHeaders() {\n return this._stropheConn._proto && this._stropheConn._proto.lastResponseHeaders;\n }\n\n /**\n * A getter for the logger plugin instance.\n *\n * @returns {*}\n */\n get logger() {\n return this._stropheConn.logger;\n }\n\n /**\n * A getter for the connection options.\n *\n * @returns {*}\n */\n get options() {\n return this._stropheConn.options;\n }\n\n /**\n * A getter for the service URL.\n *\n * @returns {string}\n */\n get service() {\n return this._stropheConn.service;\n }\n\n /**\n * Returns the current connection status.\n *\n * @returns {Strophe.Status}\n */\n get status() {\n return this._status;\n }\n\n /**\n * Adds a connection plugin to this instance.\n *\n * @param {string} name - The name of the plugin or rather a key under which it will be stored on this connection\n * instance.\n * @param {ConnectionPluginListenable} plugin - The plugin to add.\n */\n addConnectionPlugin(name, plugin) {\n this[name] = plugin;\n plugin.init(this);\n }\n\n /**\n * See {@link Strophe.Connection.addHandler}\n *\n * @returns {void}\n */\n addHandler(...args) {\n this._stropheConn.addHandler(...args);\n }\n\n /* eslint-disable max-params */\n /**\n * Wraps {@link Strophe.Connection.attach} method in order to intercept the connection status updates.\n * See {@link Strophe.Connection.attach} for the params description.\n *\n * @returns {void}\n */\n attach(jid, sid, rid, callback, ...args) {\n this._stropheConn.attach(jid, sid, rid, this._stropheConnectionCb.bind(this, callback), ...args);\n }\n\n /**\n * Wraps Strophe.Connection.connect method in order to intercept the connection status updates.\n * See {@link Strophe.Connection.connect} for the params description.\n *\n * @returns {void}\n */\n connect(jid, pass, callback, ...args) {\n this._stropheConn.connect(jid, pass, this._stropheConnectionCb.bind(this, callback), ...args);\n }\n\n /* eslint-enable max-params */\n\n /**\n * Handles {@link Strophe.Status} updates for the current connection.\n *\n * @param {function} targetCallback - The callback passed by the {@link XmppConnection} consumer to one of\n * the connect methods.\n * @param {Strophe.Status} status - The new connection status.\n * @param {*} args - The rest of the arguments passed by Strophe.\n * @private\n */\n _stropheConnectionCb(targetCallback, status, ...args) {\n this._status = status;\n\n let blockCallback = false;\n\n if (status === Strophe.Status.CONNECTED) {\n this._maybeEnableStreamResume();\n this._maybeStartWSKeepAlive();\n this._resumeRetryN = 0;\n } else if (status === Strophe.Status.DISCONNECTED) {\n // FIXME add RECONNECTING state instead of blocking the DISCONNECTED update\n blockCallback = this._tryResumingConnection();\n if (!blockCallback) {\n clearTimeout(this._wsKeepAlive);\n }\n }\n\n if (!blockCallback) {\n targetCallback(status, ...args);\n this.eventEmitter.emit(XmppConnection.Events.CONN_STATUS_CHANGED, status);\n }\n }\n\n /**\n * The method is meant to be used for testing. It's a shortcut for closing the WebSocket.\n *\n * @returns {void}\n */\n closeWebsocket() {\n this._stropheConn._proto && this._stropheConn._proto.socket && this._stropheConn._proto.socket.close();\n }\n\n /**\n * See {@link Strophe.Connection.disconnect}.\n *\n * @returns {void}\n */\n disconnect(...args) {\n clearTimeout(this._resumeTimeout);\n clearTimeout(this._wsKeepAlive);\n this._stropheConn.disconnect(...args);\n }\n\n /**\n * See {@link Strophe.Connection.flush}.\n *\n * @returns {void}\n */\n flush(...args) {\n this._stropheConn.flush(...args);\n }\n\n /**\n * See {@link LastRequestTracker.getTimeSinceLastSuccess}.\n *\n * @returns {number|null}\n */\n getTimeSinceLastSuccess() {\n return this._lastSuccessTracker.getTimeSinceLastSuccess();\n }\n\n /**\n * Requests a resume token from the server if enabled and all requirements are met.\n *\n * @private\n */\n _maybeEnableStreamResume() {\n if (!this._options.enableWebsocketResume) {\n\n return;\n }\n\n const { streamManagement } = this._stropheConn;\n\n if (!this.isUsingWebSocket) {\n logger.warn('Stream resume enabled, but WebSockets are not enabled');\n } else if (!streamManagement) {\n logger.warn('Stream resume enabled, but Strophe streamManagement plugin is not installed');\n } else if (!streamManagement.isSupported()) {\n logger.warn('Stream resume enabled, but XEP-0198 is not supported by the server');\n } else if (!streamManagement.getResumeToken()) {\n logger.info('Enabling XEP-0198 stream management');\n streamManagement.enable(/* resume */ true);\n }\n }\n\n /**\n * Starts the Websocket keep alive if enabled.\n *\n * @private\n * @returns {void}\n */\n _maybeStartWSKeepAlive() {\n const { websocketKeepAlive } = this._options;\n\n if (this._usesWebsocket && websocketKeepAlive > 0) {\n this._wsKeepAlive || logger.info(`WebSocket keep alive interval: ${websocketKeepAlive}ms`);\n clearTimeout(this._wsKeepAlive);\n\n const intervalWithJitter\n = /* base */ (websocketKeepAlive * 0.2) + /* jitter */ (Math.random() * 0.8 * websocketKeepAlive);\n\n logger.debug(`Scheduling next WebSocket keep-alive in ${intervalWithJitter}ms`);\n\n this._wsKeepAlive = setTimeout(() => {\n const url = this.service.replace('wss://', 'https://').replace('ws://', 'http://');\n\n fetch(url).catch(\n error => {\n logger.error(`Websocket Keep alive failed for url: ${url}`, { error });\n })\n .then(() => this._maybeStartWSKeepAlive());\n }, intervalWithJitter);\n }\n }\n\n /**\n * Send a stanza. This function is called to push data onto the send queue to go out over the wire.\n *\n * @param {Element|Strophe.Builder} stanza - The stanza to send.\n * @returns {void}\n */\n send(stanza) {\n if (!this.connected) {\n throw new Error('Not connected');\n }\n this._stropheConn.send(stanza);\n }\n\n /**\n * Helper function to send IQ stanzas.\n *\n * @param {Element} elem - The stanza to send.\n * @param {Function} callback - The callback function for a successful request.\n * @param {Function} errback - The callback function for a failed or timed out request. On timeout, the stanza will\n * be null.\n * @param {number} timeout - The time specified in milliseconds for a timeout to occur.\n * @returns {number} - The id used to send the IQ.\n */\n sendIQ(elem, callback, errback, timeout) {\n if (!this.connected) {\n errback('Not connected');\n\n return;\n }\n\n return this._stropheConn.sendIQ(elem, callback, errback, timeout);\n }\n\n /**\n * Helper function to send presence stanzas. The main benefit is for sending presence stanzas for which you expect\n * a responding presence stanza with the same id (for example when leaving a chat room).\n *\n * @param {Element} elem - The stanza to send.\n * @param {Function} callback - The callback function for a successful request.\n * @param {Function} errback - The callback function for a failed or timed out request. On timeout, the stanza will\n * be null.\n * @param {number} timeout - The time specified in milliseconds for a timeout to occur.\n * @returns {number} - The id used to send the presence.\n */\n sendPresence(elem, callback, errback, timeout) {\n if (!this.connected) {\n errback('Not connected');\n\n return;\n }\n this._stropheConn.sendPresence(elem, callback, errback, timeout);\n }\n\n /**\n * The method gracefully closes the BOSH connection by using 'navigator.sendBeacon'.\n *\n * @returns {boolean} - true if the beacon was sent.\n */\n sendUnavailableBeacon() {\n if (!navigator.sendBeacon || this._stropheConn.disconnecting || !this._stropheConn.connected) {\n return false;\n }\n\n this._stropheConn._changeConnectStatus(Strophe.Status.DISCONNECTING);\n this._stropheConn.disconnecting = true;\n\n const body = this._stropheConn._proto._buildBody()\n .attrs({\n type: 'terminate'\n });\n const pres = $pres({\n xmlns: Strophe.NS.CLIENT,\n type: 'unavailable'\n });\n\n body.cnode(pres.tree());\n\n const res = navigator.sendBeacon(\n `https:${this.service}`,\n Strophe.serialize(body.tree()));\n\n logger.info(`Successfully send unavailable beacon ${res}`);\n\n this._stropheConn._proto._abortAllRequests();\n this._stropheConn._doDisconnect();\n\n return true;\n }\n\n /**\n * Tries to use stream management plugin to resume dropped XMPP connection. The streamManagement plugin clears\n * the resume token if any connection error occurs which would put it in unrecoverable state, so as long as\n * the token is present it means the connection can be resumed.\n *\n * @private\n * @returns {boolean}\n */\n _tryResumingConnection() {\n const { streamManagement } = this._stropheConn;\n const resumeToken = streamManagement && streamManagement.getResumeToken();\n\n if (resumeToken) {\n clearTimeout(this._resumeTimeout);\n\n // FIXME detect internet offline\n // The retry delay will be:\n // 1st retry: 1.5s - 3s\n // 2nd retry: 3s - 9s\n // 3rd retry: 3s - 27s\n this._resumeRetryN = Math.min(3, this._resumeRetryN + 1);\n const retryTimeout = getJitterDelay(this._resumeRetryN, 1500, 3);\n\n logger.info(`Will try to resume the XMPP connection in ${retryTimeout}ms`);\n\n this._resumeTimeout = setTimeout(() => {\n logger.info('Trying to resume the XMPP connection');\n\n const url = new URL(this._stropheConn.service);\n let { search } = url;\n\n search += search.indexOf('?') === -1 ? `?previd=${resumeToken}` : `&previd=${resumeToken}`;\n\n url.search = search;\n\n this._stropheConn.service = url.toString();\n\n streamManagement.resume();\n }, retryTimeout);\n\n return true;\n }\n\n return false;\n }\n}\n", "/**\n * The possible camera facing modes. For now support only 'user' and\n * 'environment' because 'left' and 'right' are not used anywhere in our\n * projects at the time of this writing. For more information please refer to\n * https://w3c.github.io/mediacapture-main/getusermedia.html\n * #def-constraint-facingMode.\n *\n * @enum {string}\n */\nconst CameraFacingMode = {\n /**\n * The mode which specifies the environment-facing camera.\n */\n ENVIRONMENT: 'environment',\n\n /**\n * The mode which specifies the user-facing camera.\n */\n USER: 'user'\n};\n\nmodule.exports = CameraFacingMode;\n", "/* global chrome, $, alert */\n\nimport JitsiTrackError from '../../JitsiTrackError';\nimport * as JitsiTrackErrors from '../../JitsiTrackErrors';\nimport browser from '../browser';\n\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\nconst GlobalOnErrorHandler = require('../util/GlobalOnErrorHandler');\n\n/**\n * Indicates whether the Chrome desktop sharing extension is installed.\n * @type {boolean}\n */\nlet chromeExtInstalled = false;\n\n/**\n * Indicates whether an update of the Chrome desktop sharing extension is\n * required.\n * @type {boolean}\n */\nlet chromeExtUpdateRequired = false;\n\nlet gumFunction = null;\n\n/**\n * The error message returned by chrome when the extension is installed.\n */\nconst CHROME_NO_EXTENSION_ERROR_MSG // eslint-disable-line no-unused-vars\n = 'Could not establish connection. Receiving end does not exist.';\n\n/**\n * Handles obtaining a stream from a screen capture on different browsers.\n */\nconst ScreenObtainer = {\n /**\n * If not null it means that the initialization process is still in\n * progress. It is used to make desktop stream request wait and continue\n * after it's done.\n * {@type Promise|null}\n */\n intChromeExtPromise: null,\n\n obtainStream: null,\n\n /**\n * Initializes the function used to obtain a screen capture\n * (this.obtainStream).\n *\n * @param {object} options\n * @param {boolean} [options.desktopSharingChromeDisabled]\n * @param {boolean} [options.desktopSharingChromeExtId]\n * @param {boolean} [options.desktopSharingFirefoxDisabled]\n * @param {Function} gum GUM method\n */\n init(options = {\n desktopSharingChromeDisabled: false,\n desktopSharingChromeExtId: null,\n desktopSharingFirefoxDisabled: false\n }, gum) {\n this.options = options;\n gumFunction = gum;\n\n this.obtainStream = this._createObtainStreamMethod(options);\n\n if (!this.obtainStream) {\n logger.info('Desktop sharing disabled');\n }\n },\n\n /**\n * Returns a method which will be used to obtain the screen sharing stream\n * (based on the browser type).\n *\n * @param {object} options passed from {@link init} - check description\n * there\n * @returns {Function}\n * @private\n */\n _createObtainStreamMethod(options) {\n if (browser.isNWJS()) {\n return (_, onSuccess, onFailure) => {\n window.JitsiMeetNW.obtainDesktopStream(\n onSuccess,\n (error, constraints) => {\n let jitsiError;\n\n // FIXME:\n // This is very very dirty fix for recognising that the\n // user have clicked the cancel button from the Desktop\n // sharing pick window. The proper solution would be to\n // detect this in the NWJS application by checking the\n // streamId === \"\". Even better solution would be to\n // stop calling GUM from the NWJS app and just pass the\n // streamId to lib-jitsi-meet. This way the desktop\n // sharing implementation for NWJS and chrome extension\n // will be the same and lib-jitsi-meet will be able to\n // control the constraints, check the streamId, etc.\n //\n // I cannot find documentation about \"InvalidStateError\"\n // but this is what we are receiving from GUM when the\n // streamId for the desktop sharing is \"\".\n\n if (error && error.name === 'InvalidStateError') {\n jitsiError = new JitsiTrackError(\n JitsiTrackErrors.CHROME_EXTENSION_USER_CANCELED\n );\n } else {\n jitsiError = new JitsiTrackError(\n error, constraints, [ 'desktop' ]);\n }\n (typeof onFailure === 'function')\n && onFailure(jitsiError);\n });\n };\n } else if (browser.isElectron()) {\n return this.obtainScreenOnElectron;\n } else if (browser.isChrome() || browser.isOpera()) {\n if (browser.supportsGetDisplayMedia()\n && !options.desktopSharingChromeDisabled) {\n\n return this.obtainScreenFromGetDisplayMedia;\n } else if (options.desktopSharingChromeDisabled\n || !options.desktopSharingChromeExtId) {\n\n return null;\n }\n\n logger.info('Using Chrome extension for desktop sharing');\n this.intChromeExtPromise\n = initChromeExtension(options).then(() => {\n this.intChromeExtPromise = null;\n });\n\n return this.obtainScreenFromExtension;\n } else if (browser.isFirefox()) {\n if (options.desktopSharingFirefoxDisabled) {\n return null;\n } else if (browser.supportsGetDisplayMedia()) {\n // Firefox 66 support getDisplayMedia\n return this.obtainScreenFromGetDisplayMedia;\n }\n\n // Legacy Firefox\n return this.obtainScreenOnFirefox;\n } else if (browser.isSafari() && browser.supportsGetDisplayMedia()) {\n return this.obtainScreenFromGetDisplayMedia;\n }\n\n logger.log(\n 'Screen sharing not supported by the current browser: ',\n browser.getName());\n\n return null;\n },\n\n /**\n * Checks whether obtaining a screen capture is supported in the current\n * environment.\n * @returns {boolean}\n */\n isSupported() {\n return this.obtainStream !== null;\n },\n\n /**\n * Obtains a screen capture stream on Firefox.\n * @param callback\n * @param errorCallback\n */\n obtainScreenOnFirefox(options, callback, errorCallback) {\n obtainWebRTCScreen(options.gumOptions, callback, errorCallback);\n },\n\n /**\n * Obtains a screen capture stream on Electron.\n *\n * @param {Object} [options] - Screen sharing options.\n * @param {Array} [options.desktopSharingSources] - Array with the\n * sources that have to be displayed in the desktop picker window ('screen',\n * 'window', etc.).\n * @param onSuccess - Success callback.\n * @param onFailure - Failure callback.\n */\n obtainScreenOnElectron(options = {}, onSuccess, onFailure) {\n if (window.JitsiMeetScreenObtainer\n && window.JitsiMeetScreenObtainer.openDesktopPicker) {\n const { desktopSharingSources, gumOptions } = options;\n\n window.JitsiMeetScreenObtainer.openDesktopPicker(\n {\n desktopSharingSources: desktopSharingSources\n || this.options.desktopSharingChromeSources\n },\n (streamId, streamType, screenShareAudio = false) =>\n onGetStreamResponse(\n {\n response: {\n streamId,\n streamType,\n screenShareAudio\n },\n gumOptions\n },\n onSuccess,\n onFailure\n ),\n err => onFailure(new JitsiTrackError(\n JitsiTrackErrors.ELECTRON_DESKTOP_PICKER_ERROR,\n err\n ))\n );\n } else {\n onFailure(new JitsiTrackError(\n JitsiTrackErrors.ELECTRON_DESKTOP_PICKER_NOT_FOUND));\n }\n },\n\n /**\n * Asks Chrome extension to call chooseDesktopMedia and gets chrome\n * 'desktop' stream for returned stream token.\n */\n obtainScreenFromExtension(options, streamCallback, failCallback) {\n if (this.intChromeExtPromise !== null) {\n this.intChromeExtPromise.then(() => {\n this.obtainScreenFromExtension(\n options, streamCallback, failCallback);\n });\n\n return;\n }\n\n const {\n desktopSharingChromeExtId,\n desktopSharingChromeSources\n } = this.options;\n\n const {\n gumOptions\n } = options;\n\n const doGetStreamFromExtensionOptions = {\n desktopSharingChromeExtId,\n desktopSharingChromeSources:\n options.desktopSharingSources || desktopSharingChromeSources,\n gumOptions\n };\n\n if (chromeExtInstalled) {\n doGetStreamFromExtension(\n doGetStreamFromExtensionOptions,\n streamCallback,\n failCallback);\n } else {\n if (chromeExtUpdateRequired) {\n /* eslint-disable no-alert */\n alert(\n 'Jitsi Desktop Streamer requires update. '\n + 'Changes will take effect after next Chrome restart.');\n\n /* eslint-enable no-alert */\n }\n\n this.handleExternalInstall(options, streamCallback,\n failCallback);\n }\n },\n\n /* eslint-disable max-params */\n\n handleExternalInstall(options, streamCallback, failCallback, e) {\n const webStoreInstallUrl = getWebStoreInstallUrl(this.options);\n\n options.listener('waitingForExtension', webStoreInstallUrl);\n this.checkForChromeExtensionOnInterval(options, streamCallback,\n failCallback, e);\n },\n\n /* eslint-enable max-params */\n\n checkForChromeExtensionOnInterval(options, streamCallback, failCallback) {\n if (options.checkAgain() === false) {\n failCallback(new JitsiTrackError(\n JitsiTrackErrors.CHROME_EXTENSION_INSTALLATION_ERROR));\n\n return;\n }\n waitForExtensionAfterInstall(this.options, options.interval, 1)\n .then(() => {\n chromeExtInstalled = true;\n options.listener('extensionFound');\n this.obtainScreenFromExtension(options,\n streamCallback, failCallback);\n })\n .catch(() => {\n this.checkForChromeExtensionOnInterval(options,\n streamCallback, failCallback);\n });\n },\n\n /**\n * Obtains a screen capture stream using getDisplayMedia.\n *\n * @param callback - The success callback.\n * @param errorCallback - The error callback.\n */\n obtainScreenFromGetDisplayMedia(options, callback, errorCallback) {\n logger.info('Using getDisplayMedia for screen sharing');\n\n let getDisplayMedia;\n\n if (navigator.getDisplayMedia) {\n getDisplayMedia = navigator.getDisplayMedia.bind(navigator);\n } else {\n // eslint-disable-next-line max-len\n getDisplayMedia = navigator.mediaDevices.getDisplayMedia.bind(navigator.mediaDevices);\n }\n\n getDisplayMedia({ video: true,\n audio: true })\n .then(stream => {\n let applyConstraintsPromise;\n\n if (stream\n && stream.getTracks()\n && stream.getTracks().length > 0) {\n const videoTrack = stream.getVideoTracks()[0];\n\n // Apply video track constraint.\n if (videoTrack) {\n applyConstraintsPromise = videoTrack.applyConstraints(options.trackOptions);\n }\n } else {\n applyConstraintsPromise = Promise.resolve();\n }\n\n applyConstraintsPromise.then(() =>\n callback({\n stream,\n sourceId: stream.id\n }));\n })\n .catch(() =>\n errorCallback(new JitsiTrackError(JitsiTrackErrors\n .CHROME_EXTENSION_USER_CANCELED)));\n }\n};\n\n/**\n * Obtains a desktop stream using getUserMedia.\n * For this to work on Chrome, the\n * 'chrome://flags/#enable-usermedia-screen-capture' flag must be enabled.\n *\n * On firefox, the document's domain must be white-listed in the\n * 'media.getusermedia.screensharing.allowed_domains' preference in\n * 'about:config'.\n */\nfunction obtainWebRTCScreen(options, streamCallback, failCallback) {\n gumFunction([ 'screen' ], options)\n .then(stream => streamCallback({ stream }), failCallback);\n}\n\n/**\n * Constructs inline install URL for Chrome desktop streaming extension.\n * The 'chromeExtensionId' must be defined in options parameter.\n * @param options supports \"desktopSharingChromeExtId\"\n * @returns {string}\n */\nfunction getWebStoreInstallUrl(options) {\n return (\n `https://chrome.google.com/webstore/detail/${\n options.desktopSharingChromeExtId}`);\n}\n\n/**\n * Checks whether an update of the Chrome extension is required.\n * @param minVersion minimal required version\n * @param extVersion current extension version\n * @returns {boolean}\n */\nfunction isUpdateRequired(minVersion, extVersion) {\n try {\n const s1 = minVersion.split('.');\n const s2 = extVersion.split('.');\n\n const len = Math.max(s1.length, s2.length);\n\n for (let i = 0; i < len; i++) {\n let n1 = 0,\n n2 = 0;\n\n if (i < s1.length) {\n n1 = parseInt(s1[i], 10);\n }\n if (i < s2.length) {\n n2 = parseInt(s2[i], 10);\n }\n\n if (isNaN(n1) || isNaN(n2)) {\n return true;\n } else if (n1 !== n2) {\n return n1 > n2;\n }\n }\n\n // will happen if both versions have identical numbers in\n // their components (even if one of them is longer, has more components)\n return false;\n } catch (e) {\n GlobalOnErrorHandler.callErrorHandler(e);\n logger.error('Failed to parse extension version', e);\n\n return true;\n }\n}\n\n/**\n *\n * @param callback\n * @param options\n */\nfunction checkChromeExtInstalled(callback, options) {\n if (typeof chrome === 'undefined' || !chrome || !chrome.runtime) {\n // No API, so no extension for sure\n callback(false, false);\n\n return;\n }\n chrome.runtime.sendMessage(\n options.desktopSharingChromeExtId,\n { getVersion: true },\n response => {\n if (!response || !response.version) {\n // Communication failure - assume that no endpoint exists\n logger.warn(\n 'Extension not installed?: ', chrome.runtime.lastError);\n callback(false, false);\n\n return;\n }\n\n // Check installed extension version\n const extVersion = response.version;\n\n logger.log(`Extension version is: ${extVersion}`);\n const updateRequired\n = isUpdateRequired(\n options.desktopSharingChromeMinExtVersion,\n extVersion);\n\n callback(!updateRequired, updateRequired);\n }\n );\n}\n\n/**\n *\n * @param options\n * @param streamCallback\n * @param failCallback\n */\nfunction doGetStreamFromExtension(options, streamCallback, failCallback) {\n const {\n desktopSharingChromeSources,\n desktopSharingChromeExtId,\n gumOptions\n } = options;\n\n // Sends 'getStream' msg to the extension.\n // Extension id must be defined in the config.\n chrome.runtime.sendMessage(\n desktopSharingChromeExtId,\n {\n getStream: true,\n sources: desktopSharingChromeSources\n },\n response => {\n if (!response) {\n // possibly re-wraping error message to make code consistent\n const lastError = chrome.runtime.lastError;\n\n failCallback(lastError instanceof Error\n ? lastError\n : new JitsiTrackError(\n JitsiTrackErrors.CHROME_EXTENSION_GENERIC_ERROR,\n lastError));\n\n return;\n }\n logger.log('Response from extension: ', response);\n onGetStreamResponse(\n {\n response,\n gumOptions\n },\n streamCallback,\n failCallback\n );\n }\n );\n}\n\n/**\n * Initializes with extension id set in\n * config.js to support inline installs. Host site must be selected as main\n * website of published extension.\n * @param options supports \"desktopSharingChromeExtId\"\n */\nfunction initInlineInstalls(options) {\n if ($('link[rel=chrome-webstore-item]').length === 0) {\n $('head').append('');\n }\n $('link[rel=chrome-webstore-item]').attr('href',\n getWebStoreInstallUrl(options));\n}\n\n/**\n *\n * @param options\n *\n * @return {Promise} - a Promise resolved once the initialization process is\n * finished.\n */\nfunction initChromeExtension(options) {\n // Initialize Chrome extension inline installs\n initInlineInstalls(options);\n\n return new Promise(resolve => {\n // Check if extension is installed\n checkChromeExtInstalled((installed, updateRequired) => {\n chromeExtInstalled = installed;\n chromeExtUpdateRequired = updateRequired;\n logger.info(\n `Chrome extension installed: ${\n chromeExtInstalled} updateRequired: ${\n chromeExtUpdateRequired}`);\n resolve();\n }, options);\n });\n}\n\n/**\n * Checks \"retries\" times on every \"waitInterval\"ms whether the ext is alive.\n * @param {Object} options the options passed to ScreanObtainer.obtainStream\n * @param {int} waitInterval the number of ms between retries\n * @param {int} retries the number of retries\n * @returns {Promise} returns promise that will be resolved when the extension\n * is alive and rejected if the extension is not alive even after \"retries\"\n * checks\n */\nfunction waitForExtensionAfterInstall(options, waitInterval, retries) {\n if (retries === 0) {\n return Promise.reject();\n }\n\n return new Promise((resolve, reject) => {\n let currentRetries = retries;\n const interval = window.setInterval(() => {\n checkChromeExtInstalled(installed => {\n if (installed) {\n window.clearInterval(interval);\n resolve();\n } else {\n currentRetries--;\n if (currentRetries === 0) {\n reject();\n window.clearInterval(interval);\n }\n }\n }, options);\n }, waitInterval);\n });\n}\n\n/**\n * Handles response from external application / extension and calls GUM to\n * receive the desktop streams or reports error.\n * @param {object} options\n * @param {object} options.response\n * @param {string} options.response.streamId - the streamId for the desktop\n * stream.\n * @param {bool} options.response.screenShareAudio - Used by electron clients to\n * enable system audio screen sharing.\n * @param {string} options.response.error - error to be reported.\n * @param {object} options.gumOptions - options passed to GUM.\n * @param {Function} onSuccess - callback for success.\n * @param {Function} onFailure - callback for failure.\n * @param {object} gumOptions - options passed to GUM.\n */\nfunction onGetStreamResponse(\n options = {\n response: {},\n gumOptions: {}\n },\n onSuccess,\n onFailure) {\n const { streamId, streamType, screenShareAudio, error } = options.response || {};\n\n if (streamId) {\n const gumOptions = {\n desktopStream: streamId,\n screenShareAudio,\n ...options.gumOptions\n };\n\n gumFunction([ 'desktop' ], gumOptions)\n .then(stream => onSuccess({\n stream,\n sourceId: streamId,\n sourceType: streamType\n }), onFailure);\n } else {\n // As noted in Chrome Desktop Capture API:\n // If user didn't select any source (i.e. canceled the prompt)\n // then the callback is called with an empty streamId.\n if (streamId === '') {\n onFailure(new JitsiTrackError(\n JitsiTrackErrors.CHROME_EXTENSION_USER_CANCELED));\n\n return;\n }\n\n onFailure(new JitsiTrackError(\n JitsiTrackErrors.CHROME_EXTENSION_GENERIC_ERROR,\n error));\n }\n}\n\nexport default ScreenObtainer;\n", "var g;\n\n// This works in non-strict mode\ng = (function() {\n\treturn this;\n})();\n\ntry {\n\t// This works if eval is allowed (see CSP)\n\tg = g || new Function(\"return this\")();\n} catch (e) {\n\t// This works if the window reference is available\n\tif (typeof window === \"object\") g = window;\n}\n\n// g can still be undefined, but nothing to do about it...\n// We return undefined, instead of nothing here, so it's\n// easier to handle this case. if(!global) { ...}\n\nmodule.exports = g;\n", "/* global __filename */\nimport { getLogger } from 'jitsi-meet-logger';\nimport * as JitsiConferenceEvents from '../../JitsiConferenceEvents';\nimport * as JitsiTrackEvents from '../../JitsiTrackEvents';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport browser from '../browser';\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport Statistics from '../statistics/statistics';\nimport { createParticipantConnectionStatusEvent } from '../../service/statistics/AnalyticsEvents';\n\nconst logger = getLogger(__filename);\n\n/**\n * Default value of 500 milliseconds for\n * {@link ParticipantConnectionStatus.outOfLastNTimeout}.\n *\n * @type {number}\n */\nconst DEFAULT_NOT_IN_LAST_N_TIMEOUT = 500;\n\n/**\n * Default value of 2000 milliseconds for\n * {@link ParticipantConnectionStatus.rtcMuteTimeout}.\n *\n * @type {number}\n */\nconst DEFAULT_RTC_MUTE_TIMEOUT = 10000;\n\n/**\n * The time to wait a track to be restored. Track which was out of lastN\n * should be inactive and when entering lastN it becomes restoring and when\n * data is received from bridge it will become active, but if no data is\n * received for some time we set status of that participant connection to\n * interrupted.\n * @type {number}\n */\nconst DEFAULT_RESTORING_TIMEOUT = 10000;\n\n/**\n * Participant connection statuses.\n *\n * @type {{\n * ACTIVE: string,\n * INACTIVE: string,\n * INTERRUPTED: string,\n * RESTORING: string\n * }}\n */\nexport const ParticipantConnectionStatus = {\n /**\n * Status indicating that connection is currently active.\n */\n ACTIVE: 'active',\n\n /**\n * Status indicating that connection is currently inactive.\n * Inactive means the connection was stopped on purpose from the bridge,\n * like exiting lastN or adaptivity decided to drop video because of not\n * enough bandwidth.\n */\n INACTIVE: 'inactive',\n\n /**\n * Status indicating that connection is currently interrupted.\n */\n INTERRUPTED: 'interrupted',\n\n /**\n * Status indicating that connection is currently restoring.\n */\n RESTORING: 'restoring'\n};\n\n/**\n * Class is responsible for emitting\n * JitsiConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED events.\n */\nexport default class ParticipantConnectionStatusHandler {\n /* eslint-disable max-params*/\n /**\n * Calculates the new {@link ParticipantConnectionStatus} based on\n * the values given for some specific remote user. It is assumed that\n * the conference is currently in the JVB mode (in contrary to the P2P mode)\n * @param {boolean} isConnectionActiveByJvb true if the JVB did not get any\n * data from the user for the last 15 seconds.\n * @param {boolean} isInLastN indicates whether the user is in the last N\n * set. When set to false it means that JVB is not sending any video for\n * the user.\n * @param {boolean} isRestoringTimedout if true it means that the user has\n * been outside of last N too long to be considered\n * {@link ParticipantConnectionStatus.RESTORING}.\n * @param {boolean} isVideoMuted true if the user is video muted and we\n * should not expect to receive any video.\n * @param {boolean} isVideoTrackFrozen if the current browser support video\n * frozen detection then it will be set to true when the video track is\n * frozen. If the current browser does not support frozen detection the it's\n * always false.\n * @return {ParticipantConnectionStatus} the new connection status for\n * the user for whom the values above were provided.\n * @private\n */\n static _getNewStateForJvbMode(\n isConnectionActiveByJvb,\n isInLastN,\n isRestoringTimedout,\n isVideoMuted,\n isVideoTrackFrozen) {\n if (!isConnectionActiveByJvb) {\n // when there is a connection problem signaled from jvb\n // it means no media was flowing for at least 15secs, so both audio\n // and video are most likely interrupted\n return ParticipantConnectionStatus.INTERRUPTED;\n } else if (isVideoMuted) {\n // If the connection is active according to JVB and the user is\n // video muted there is no way for the connection to be inactive,\n // because the detection logic below only makes sense for video.\n return ParticipantConnectionStatus.ACTIVE;\n }\n\n // Logic when isVideoTrackFrozen is supported\n if (browser.supportsVideoMuteOnConnInterrupted()) {\n if (!isVideoTrackFrozen) {\n // If the video is playing we're good\n return ParticipantConnectionStatus.ACTIVE;\n } else if (isInLastN) {\n return isRestoringTimedout\n ? ParticipantConnectionStatus.INTERRUPTED\n : ParticipantConnectionStatus.RESTORING;\n }\n\n return ParticipantConnectionStatus.INACTIVE;\n }\n\n // Because this browser is incapable of detecting frozen video we must\n // rely on the lastN value\n return isInLastN\n ? ParticipantConnectionStatus.ACTIVE\n : ParticipantConnectionStatus.INACTIVE;\n }\n\n /* eslint-enable max-params*/\n\n /**\n * In P2P mode we don't care about any values coming from the JVB and\n * the connection status can be only active or interrupted.\n * @param {boolean} isVideoMuted the user if video muted\n * @param {boolean} isVideoTrackFrozen true if the video track for\n * the remote user is currently frozen. If the current browser does not\n * support video frozen detection then it's always false.\n * @return {ParticipantConnectionStatus}\n * @private\n */\n static _getNewStateForP2PMode(isVideoMuted, isVideoTrackFrozen) {\n if (!browser.supportsVideoMuteOnConnInterrupted()) {\n // There's no way to detect problems in P2P when there's no video\n // track frozen detection...\n return ParticipantConnectionStatus.ACTIVE;\n }\n\n return isVideoMuted || !isVideoTrackFrozen\n ? ParticipantConnectionStatus.ACTIVE\n : ParticipantConnectionStatus.INTERRUPTED;\n }\n\n /**\n * Creates new instance of ParticipantConnectionStatus.\n *\n * @constructor\n * @param {RTC} rtc the RTC service instance\n * @param {JitsiConference} conference parent conference instance\n * @param {Object} options\n * @param {number} [options.rtcMuteTimeout=2000] custom value for\n * {@link ParticipantConnectionStatus.rtcMuteTimeout}.\n * @param {number} [options.outOfLastNTimeout=500] custom value for\n * {@link ParticipantConnectionStatus.outOfLastNTimeout}.\n */\n constructor(rtc, conference, options) {\n this.rtc = rtc;\n this.conference = conference;\n\n /**\n * A map of the \"endpoint ID\"(which corresponds to the resource part\n * of MUC JID(nickname)) to the timeout callback IDs scheduled using\n * window.setTimeout.\n * @type {Object.}\n */\n this.trackTimers = {};\n\n /**\n * This map holds the endpoint connection status received from the JVB\n * (as it might be different than the one stored in JitsiParticipant).\n * Required for getting back in sync when remote video track is removed.\n * @type {Object.}\n */\n this.connStatusFromJvb = { };\n\n /**\n * If video track frozen detection through RTC mute event is supported,\n * we wait some time until video track is considered frozen. But because\n * when the user falls out of last N it is expected for the video to\n * freeze this timeout must be significantly reduced in \"out of last N\"\n * case.\n *\n * Basically this value is used instead of {@link rtcMuteTimeout} when\n * user is not in last N.\n * @type {number}\n */\n this.outOfLastNTimeout\n = typeof options.outOfLastNTimeout === 'number'\n ? options.outOfLastNTimeout : DEFAULT_NOT_IN_LAST_N_TIMEOUT;\n\n /**\n * How long we're going to wait after the RTC video track muted event\n * for the corresponding signalling mute event, before the connection\n * interrupted is fired. The default value is\n * {@link DEFAULT_RTC_MUTE_TIMEOUT}.\n *\n * @type {number} amount of time in milliseconds\n */\n this.rtcMuteTimeout\n = typeof options.rtcMuteTimeout === 'number'\n ? options.rtcMuteTimeout : DEFAULT_RTC_MUTE_TIMEOUT;\n\n /**\n * This map holds a timestamp indicating when participant's video track\n * was RTC muted (it is assumed that each participant can have only 1\n * video track at a time). The purpose of storing the timestamp is to\n * avoid the transition to disconnected status in case of legitimate\n * video mute operation where the signalling video muted event can\n * arrive shortly after RTC muted event.\n *\n * The key is participant's ID which is the same as endpoint id in\n * the Colibri conference allocated on the JVB.\n *\n * The value is a timestamp measured in milliseconds obtained with\n * Date.now().\n *\n * FIXME merge this logic with NO_DATA_FROM_SOURCE event\n * implemented in JitsiLocalTrack by extending the event to\n * the remote track and allowing to set different timeout for\n * local and remote tracks.\n *\n * @type {Object.}\n */\n this.rtcMutedTimestamp = { };\n logger.info(`RtcMuteTimeout set to: ${this.rtcMuteTimeout}`);\n\n /**\n * This map holds the timestamps indicating when participant's video\n * entered lastN set. Participants entering lastN will have connection\n * status restoring and when we start receiving video will become\n * active, but if video is not received for certain time\n * {@link DEFAULT_RESTORING_TIMEOUT} that participant connection status\n * will become interrupted.\n *\n * @type {Map}\n */\n this.enteredLastNTimestamp = new Map();\n\n /**\n * A map of the \"endpoint ID\"(which corresponds to the resource part\n * of MUC JID(nickname)) to the restoring timeout callback IDs\n * scheduled using window.setTimeout.\n *\n * @type {Map}\n */\n this.restoringTimers = new Map();\n\n /**\n * A map that holds the current connection status (along with all the internal events that happen\n * while in that state).\n *\n * The goal is to send this information to the analytics backend for post-mortem analysis.\n */\n this.connectionStatusMap = new Map();\n }\n\n /**\n * Gets the video frozen timeout for given user.\n * @param {string} id endpoint/participant ID\n * @return {number} how long are we going to wait since RTC video muted\n * even, before a video track is considered frozen.\n * @private\n */\n _getVideoFrozenTimeout(id) {\n return this.rtc.isInLastN(id)\n ? this.rtcMuteTimeout : this.outOfLastNTimeout;\n }\n\n /**\n * Initializes ParticipantConnectionStatus and bind required event\n * listeners.\n */\n init() {\n\n this._onEndpointConnStatusChanged\n = this.onEndpointConnStatusChanged.bind(this);\n\n this.rtc.addListener(\n RTCEvents.ENDPOINT_CONN_STATUS_CHANGED,\n this._onEndpointConnStatusChanged);\n\n // Handles P2P status changes\n this._onP2PStatus = this.refreshConnectionStatusForAll.bind(this);\n this.conference.on(JitsiConferenceEvents.P2P_STATUS, this._onP2PStatus);\n\n // Used to send analytics events for the participant that left the call.\n this._onUserLeft = this.onUserLeft.bind(this);\n this.conference.on(JitsiConferenceEvents.USER_LEFT, this._onUserLeft);\n\n // On some browsers MediaStreamTrack trigger \"onmute\"/\"onunmute\"\n // events for video type tracks when they stop receiving data which is\n // often a sign that remote user is having connectivity issues\n if (browser.supportsVideoMuteOnConnInterrupted()) {\n\n this._onTrackRtcMuted = this.onTrackRtcMuted.bind(this);\n this.rtc.addListener(\n RTCEvents.REMOTE_TRACK_MUTE, this._onTrackRtcMuted);\n\n this._onTrackRtcUnmuted = this.onTrackRtcUnmuted.bind(this);\n this.rtc.addListener(\n RTCEvents.REMOTE_TRACK_UNMUTE, this._onTrackRtcUnmuted);\n\n // Track added/removed listeners are used to bind \"mute\"/\"unmute\"\n // event handlers\n this._onRemoteTrackAdded = this.onRemoteTrackAdded.bind(this);\n this.conference.on(\n JitsiConferenceEvents.TRACK_ADDED,\n this._onRemoteTrackAdded);\n\n this._onRemoteTrackRemoved = this.onRemoteTrackRemoved.bind(this);\n this.conference.on(\n JitsiConferenceEvents.TRACK_REMOVED,\n this._onRemoteTrackRemoved);\n\n // Listened which will be bound to JitsiRemoteTrack to listen for\n // signalling mute/unmute events.\n this._onSignallingMuteChanged\n = this.onSignallingMuteChanged.bind(this);\n\n // Used to send an analytics event when the video type changes.\n this._onTrackVideoTypeChanged\n = this.onTrackVideoTypeChanged.bind(this);\n }\n\n this._onLastNChanged = this._onLastNChanged.bind(this);\n this.conference.on(\n JitsiConferenceEvents.LAST_N_ENDPOINTS_CHANGED,\n this._onLastNChanged);\n\n this._onLastNValueChanged\n = this.refreshConnectionStatusForAll.bind(this);\n this.rtc.on(\n RTCEvents.LASTN_VALUE_CHANGED, this._onLastNValueChanged);\n }\n\n /**\n * Removes all event listeners and disposes of all resources held by this\n * instance.\n */\n dispose() {\n\n this.rtc.removeListener(\n RTCEvents.ENDPOINT_CONN_STATUS_CHANGED,\n this._onEndpointConnStatusChanged);\n\n if (browser.supportsVideoMuteOnConnInterrupted()) {\n this.rtc.removeListener(\n RTCEvents.REMOTE_TRACK_MUTE,\n this._onTrackRtcMuted);\n this.rtc.removeListener(\n RTCEvents.REMOTE_TRACK_UNMUTE,\n this._onTrackRtcUnmuted);\n\n this.conference.off(\n JitsiConferenceEvents.TRACK_ADDED,\n this._onRemoteTrackAdded);\n this.conference.off(\n JitsiConferenceEvents.TRACK_REMOVED,\n this._onRemoteTrackRemoved);\n }\n\n this.conference.off(\n JitsiConferenceEvents.LAST_N_ENDPOINTS_CHANGED,\n this._onLastNChanged);\n\n this.rtc.removeListener(\n RTCEvents.LASTN_VALUE_CHANGED, this._onLastNValueChanged);\n\n this.conference.off(\n JitsiConferenceEvents.P2P_STATUS, this._onP2PStatus);\n\n this.conference.off(\n JitsiConferenceEvents.USER_LEFT, this._onUserLeft);\n\n const participantIds = Object.keys(this.trackTimers);\n\n for (const participantId of participantIds) {\n this.clearTimeout(participantId);\n this.clearRtcMutedTimestamp(participantId);\n }\n\n for (const id in this.connectionStatusMap) {\n if (this.connectionStatusMap.hasOwnProperty(id)) {\n this.onUserLeft(id);\n }\n }\n\n // Clear RTC connection status cache\n this.connStatusFromJvb = {};\n }\n\n /**\n * Handles RTCEvents.ENDPOINT_CONN_STATUS_CHANGED triggered when we receive\n * notification over the data channel from the bridge about endpoint's\n * connection status update.\n * @param {string} endpointId - The endpoint ID(MUC nickname/resource JID).\n * @param {boolean} isActive - true if the connection is OK or false otherwise.\n */\n onEndpointConnStatusChanged(endpointId, isActive) {\n\n logger.debug(\n `Detector RTCEvents.ENDPOINT_CONN_STATUS_CHANGED(${Date.now()}): ${\n endpointId}: ${isActive}`);\n\n // Filter out events for the local JID for now\n if (endpointId !== this.conference.myUserId()) {\n // Store the status received over the data channels\n this.connStatusFromJvb[endpointId] = isActive;\n this.figureOutConnectionStatus(endpointId);\n }\n }\n\n /**\n * Changes connection status.\n * @param {JitsiParticipant} participant\n * @param newStatus\n */\n _changeConnectionStatus(participant, newStatus) {\n if (participant.getConnectionStatus() !== newStatus) {\n\n const endpointId = participant.getId();\n\n participant._setConnectionStatus(newStatus);\n\n logger.debug(\n `Emit endpoint conn status(${Date.now()}) ${endpointId}: ${\n newStatus}`);\n\n // Log the event on CallStats\n Statistics.sendLog(\n JSON.stringify({\n id: 'peer.conn.status',\n participant: endpointId,\n status: newStatus\n }));\n\n\n this.conference.eventEmitter.emit(\n JitsiConferenceEvents.PARTICIPANT_CONN_STATUS_CHANGED,\n endpointId, newStatus);\n }\n }\n\n /**\n * Reset the postponed \"connection interrupted\" event which was previously\n * scheduled as a timeout on RTC 'onmute' event.\n *\n * @param {string} participantId - The participant for which the \"connection\n * interrupted\" timeout was scheduled.\n */\n clearTimeout(participantId) {\n if (this.trackTimers[participantId]) {\n window.clearTimeout(this.trackTimers[participantId]);\n this.trackTimers[participantId] = null;\n }\n }\n\n /**\n * Clears the timestamp of the RTC muted event for participant's video track\n * @param {string} participantId the id of the conference participant which\n * is the same as the Colibri endpoint ID of the video channel allocated for\n * the user on the videobridge.\n */\n clearRtcMutedTimestamp(participantId) {\n this.rtcMutedTimestamp[participantId] = null;\n }\n\n /**\n * Bind signalling mute event listeners for video {JitsiRemoteTrack} when\n * a new one is added to the conference.\n *\n * @param {JitsiTrack} remoteTrack - The {JitsiTrack} which is being added to\n * the conference.\n */\n onRemoteTrackAdded(remoteTrack) {\n if (!remoteTrack.isLocal()\n && remoteTrack.getType() === MediaType.VIDEO) {\n\n logger.debug(\n `Detector on remote track added for: ${\n remoteTrack.getParticipantId()}`);\n\n remoteTrack.on(\n JitsiTrackEvents.TRACK_MUTE_CHANGED,\n this._onSignallingMuteChanged);\n remoteTrack.on(\n JitsiTrackEvents.TRACK_VIDEOTYPE_CHANGED,\n videoType => this._onTrackVideoTypeChanged(remoteTrack, videoType));\n }\n }\n\n /**\n * Removes all event listeners bound to the remote video track and clears\n * any related timeouts.\n *\n * @param {JitsiRemoteTrack} remoteTrack - The remote track which is being\n * removed from the conference.\n */\n onRemoteTrackRemoved(remoteTrack) {\n if (!remoteTrack.isLocal()\n && remoteTrack.getType() === MediaType.VIDEO) {\n\n const endpointId = remoteTrack.getParticipantId();\n\n logger.debug(`Detector on remote track removed: ${endpointId}`);\n\n remoteTrack.off(\n JitsiTrackEvents.TRACK_MUTE_CHANGED,\n this._onSignallingMuteChanged);\n\n this.clearTimeout(endpointId);\n this.clearRtcMutedTimestamp(endpointId);\n\n this.figureOutConnectionStatus(endpointId);\n }\n }\n\n /**\n * Checks if given participant's video is considered frozen.\n * @param {JitsiParticipant} participant - The participant.\n * @return {boolean} true if the video has frozen for given\n * participant or false when it's either not considered frozen\n * (yet) or if freeze detection is not supported by the current browser.\n *\n * FIXME merge this logic with NO_DATA_FROM_SOURCE event\n * implemented in JitsiLocalTrack by extending the event to\n * the remote track and allowing to set different timeout for\n * local and remote tracks.\n *\n */\n isVideoTrackFrozen(participant) {\n if (!browser.supportsVideoMuteOnConnInterrupted()) {\n return false;\n }\n\n const id = participant.getId();\n const hasAnyVideoRTCMuted = participant.hasAnyVideoTrackWebRTCMuted();\n const rtcMutedTimestamp = this.rtcMutedTimestamp[id];\n const timeout = this._getVideoFrozenTimeout(id);\n\n return hasAnyVideoRTCMuted\n && typeof rtcMutedTimestamp === 'number'\n && (Date.now() - rtcMutedTimestamp) >= timeout;\n }\n\n /**\n * Goes over every participant and updates connectivity status.\n * Should be called when a parameter which affects all of the participants\n * is changed (P2P for example).\n */\n refreshConnectionStatusForAll() {\n const participants = this.conference.getParticipants();\n\n for (const participant of participants) {\n this.figureOutConnectionStatus(participant.getId());\n }\n }\n\n /**\n * Figures out (and updates) the current connectivity status for\n * the participant identified by the given id.\n *\n * @param {string} id - The participant's id (MUC nickname or Colibri endpoint ID).\n */\n figureOutConnectionStatus(id) {\n const participant = this.conference.getParticipantById(id);\n\n if (!participant) {\n // Probably the participant is no longer in the conference\n // (at the time of writing this code, participant is\n // detached from the conference and TRACK_REMOVED events are\n // fired),\n // so we don't care, but let's print a log message for debugging purposes.\n logger.debug(`figure out conn status - no participant for: ${id}`);\n\n return;\n }\n\n const inP2PMode = this.conference.isP2PActive();\n const isRestoringTimedOut = this._isRestoringTimedout(id);\n const audioOnlyMode = this.rtc.getLastN() === 0;\n\n // NOTE Overriding videoMuted to true for audioOnlyMode should disable\n // any detection based on video playback or the last N.\n const isVideoMuted = participant.isVideoMuted() || audioOnlyMode;\n const isVideoTrackFrozen = this.isVideoTrackFrozen(participant);\n const isInLastN = this.rtc.isInLastN(id);\n let isConnActiveByJvb = this.connStatusFromJvb[id];\n\n if (typeof isConnActiveByJvb !== 'boolean') {\n // If no status was received from the JVB it means that it's active\n // (the bridge does not send notification unless there is a problem)\n logger.debug('Assuming connection active by JVB - no notification');\n isConnActiveByJvb = true;\n }\n\n const newState\n = inP2PMode\n ? ParticipantConnectionStatusHandler._getNewStateForP2PMode(\n isVideoMuted,\n isVideoTrackFrozen)\n : ParticipantConnectionStatusHandler._getNewStateForJvbMode(\n isConnActiveByJvb,\n isInLastN,\n isRestoringTimedOut,\n isVideoMuted,\n isVideoTrackFrozen);\n\n // if the new state is not restoring clear timers and timestamps\n // that we use to track the restoring state\n if (newState !== ParticipantConnectionStatus.RESTORING) {\n this._clearRestoringTimer(id);\n }\n\n logger.debug(\n `Figure out conn status for ${id}, is video muted: ${\n isVideoMuted} is active(jvb): ${\n isConnActiveByJvb} video track frozen: ${\n isVideoTrackFrozen} p2p mode: ${\n inP2PMode} is in last N: ${\n isInLastN} currentStatus => newStatus: ${\n participant.getConnectionStatus()} => ${newState}`);\n\n const oldConnectionStatus = this.connectionStatusMap[id] || {};\n\n // Send an analytics event (guard on either the p2p flag or the connection status has changed\n // since the last time this code block run).\n if (!('p2p' in oldConnectionStatus)\n || !('connectionStatus' in oldConnectionStatus)\n || oldConnectionStatus.p2p !== inP2PMode\n || oldConnectionStatus.connectionStatus !== newState) {\n\n const nowMs = Date.now();\n\n this.maybeSendParticipantConnectionStatusEvent(id, nowMs);\n\n this.connectionStatusMap[id] = {\n ...oldConnectionStatus,\n connectionStatus: newState,\n p2p: inP2PMode,\n startedMs: nowMs\n };\n\n // sometimes (always?) we're late to hook the TRACK_VIDEOTYPE_CHANGED event and the\n // video type is not in oldConnectionStatus.\n if (!('videoType' in this.connectionStatusMap[id])) {\n const videoTracks = participant.getTracksByMediaType(MediaType.VIDEO);\n\n if (Array.isArray(videoTracks) && videoTracks.length !== 0) {\n this.connectionStatusMap[id].videoType = videoTracks[0].videoType;\n }\n }\n }\n this._changeConnectionStatus(participant, newState);\n }\n\n /**\n * Computes the duration of the current connection status for the participant with the specified id (i.e. 15 seconds\n * in the INTERRUPTED state) and sends a participant connection status event.\n * @param {string} id - The jid of the participant.\n * @param {Number} nowMs - The current time (in millis).\n * @returns {void}\n */\n maybeSendParticipantConnectionStatusEvent(id, nowMs) {\n const participantConnectionStatus = this.connectionStatusMap[id];\n\n if (participantConnectionStatus\n && 'startedMs' in participantConnectionStatus\n && 'videoType' in participantConnectionStatus\n && 'connectionStatus' in participantConnectionStatus\n && 'p2p' in participantConnectionStatus) {\n participantConnectionStatus.value = nowMs - participantConnectionStatus.startedMs;\n Statistics.sendAnalytics(\n createParticipantConnectionStatusEvent(participantConnectionStatus));\n }\n }\n\n /**\n * On change in Last N set check all leaving and entering participants to\n * change their corresponding statuses.\n *\n * @param {Array} leavingLastN - The array of ids leaving lastN.\n * @param {Array} enteringLastN - The array of ids entering lastN.\n * @private\n */\n _onLastNChanged(leavingLastN = [], enteringLastN = []) {\n const now = Date.now();\n\n logger.debug(\n 'leaving/entering lastN', leavingLastN, enteringLastN, now);\n\n for (const id of leavingLastN) {\n this.enteredLastNTimestamp.delete(id);\n this._clearRestoringTimer(id);\n this.figureOutConnectionStatus(id);\n }\n for (const id of enteringLastN) {\n // store the timestamp this id is entering lastN\n this.enteredLastNTimestamp.set(id, now);\n this.figureOutConnectionStatus(id);\n }\n }\n\n /**\n * Clears the restoring timer for participant's video track and the\n * timestamp for entering lastN.\n *\n * @param {string} participantId - The id of the conference participant which\n * is the same as the Colibri endpoint ID of the video channel allocated for\n * the user on the videobridge.\n */\n _clearRestoringTimer(participantId) {\n const rTimer = this.restoringTimers.get(participantId);\n\n if (rTimer) {\n clearTimeout(rTimer);\n this.restoringTimers.delete(participantId);\n }\n }\n\n /**\n * Checks whether a track had stayed enough in restoring state, compares\n * current time and the time the track entered in lastN. If it hasn't\n * timedout and there is no timer added, add new timer in order to give it\n * more time to become active or mark it as interrupted on next check.\n *\n * @param {string} participantId - The id of the conference participant which\n * is the same as the Colibri endpoint ID of the video channel allocated for\n * the user on the videobridge.\n * @returns {boolean} true if the track was in restoring state\n * more than the timeout ({@link DEFAULT_RESTORING_TIMEOUT}.) in order to\n * set its status to interrupted.\n * @private\n */\n _isRestoringTimedout(participantId) {\n const enteredLastNTimestamp\n = this.enteredLastNTimestamp.get(participantId);\n\n if (enteredLastNTimestamp\n && (Date.now() - enteredLastNTimestamp)\n >= DEFAULT_RESTORING_TIMEOUT) {\n return true;\n }\n\n // still haven't reached timeout, if there is no timer scheduled,\n // schedule one so we can track the restoring state and change it after\n // reaching the timeout\n const rTimer = this.restoringTimers.get(participantId);\n\n if (!rTimer) {\n this.restoringTimers.set(participantId, setTimeout(\n () => this.figureOutConnectionStatus(participantId),\n DEFAULT_RESTORING_TIMEOUT));\n }\n\n return false;\n }\n\n /**\n * Sends a last/final participant connection status event for the participant that left the conference.\n * @param {string} id - The id of the participant that left the conference.\n * @returns {void}\n */\n onUserLeft(id) {\n this.maybeSendParticipantConnectionStatusEvent(id, Date.now());\n delete this.connectionStatusMap[id];\n }\n\n /**\n * Handles RTC 'onmute' event for the video track.\n *\n * @param {JitsiRemoteTrack} track - The video track for which 'onmute' event\n * will be processed.\n */\n onTrackRtcMuted(track) {\n const participantId = track.getParticipantId();\n const participant = this.conference.getParticipantById(participantId);\n\n logger.debug(`Detector track RTC muted: ${participantId}`, Date.now());\n if (!participant) {\n logger.error(`No participant for id: ${participantId}`);\n\n return;\n }\n this.rtcMutedTimestamp[participantId] = Date.now();\n if (!participant.isVideoMuted()) {\n // If the user is not muted according to the signalling we'll give\n // it some time, before the connection interrupted event is\n // triggered.\n this.clearTimeout(participantId);\n\n // The timeout is reduced when user is not in the last N\n const timeout = this._getVideoFrozenTimeout(participantId);\n\n this.trackTimers[participantId] = window.setTimeout(() => {\n logger.debug(\n `Set RTC mute timeout for: ${participantId}\\\n of ${timeout} ms`);\n this.clearTimeout(participantId);\n this.figureOutConnectionStatus(participantId);\n }, timeout);\n }\n }\n\n /**\n * Handles RTC 'onunmute' event for the video track.\n *\n * @param {JitsiRemoteTrack} track - The video track for which 'onunmute'\n * event will be processed.\n */\n onTrackRtcUnmuted(track) {\n const participantId = track.getParticipantId();\n\n logger.debug(\n `Detector track RTC unmuted: ${participantId}`, Date.now());\n\n this.clearTimeout(participantId);\n this.clearRtcMutedTimestamp(participantId);\n\n this.figureOutConnectionStatus(participantId);\n }\n\n /**\n * Here the signalling \"mute\"/\"unmute\" events are processed.\n *\n * @param {JitsiRemoteTrack} track - The remote video track for which\n * the signalling mute/unmute event will be processed.\n */\n onSignallingMuteChanged(track) {\n const participantId = track.getParticipantId();\n\n logger.debug(\n `Detector on track signalling mute changed: ${participantId}`,\n track.isMuted());\n\n this.figureOutConnectionStatus(participantId);\n }\n\n /**\n * Sends a participant connection status event as a result of the video type\n * changing.\n * @param {JitsiRemoteTrack} track - The track.\n * @param {VideoType} type - The video type.\n * @returns {void}\n */\n onTrackVideoTypeChanged(track, type) {\n const id = track.getParticipantId();\n const nowMs = Date.now();\n\n this.maybeSendParticipantConnectionStatusEvent(id, nowMs);\n\n this.connectionStatusMap[id] = {\n ...this.connectionStatusMap[id] || {},\n videoType: type,\n startedMs: nowMs\n };\n }\n}\n", "/* eslint-env node */\n'use strict';\n\n// SDP helpers.\nvar SDPUtils = {};\n\n// Generate an alphanumeric identifier for cname or mids.\n// TODO: use UUIDs instead? https://gist.github.com/jed/982883\nSDPUtils.generateIdentifier = function() {\n return Math.random().toString(36).substr(2, 10);\n};\n\n// The RTCP CNAME used by all peerconnections from the same JS.\nSDPUtils.localCName = SDPUtils.generateIdentifier();\n\n// Splits SDP into lines, dealing with both CRLF and LF.\nSDPUtils.splitLines = function(blob) {\n return blob.trim().split('\\n').map(function(line) {\n return line.trim();\n });\n};\n// Splits SDP into sessionpart and mediasections. Ensures CRLF.\nSDPUtils.splitSections = function(blob) {\n var parts = blob.split('\\nm=');\n return parts.map(function(part, index) {\n return (index > 0 ? 'm=' + part : part).trim() + '\\r\\n';\n });\n};\n\n// returns the session description.\nSDPUtils.getDescription = function(blob) {\n var sections = SDPUtils.splitSections(blob);\n return sections && sections[0];\n};\n\n// returns the individual media sections.\nSDPUtils.getMediaSections = function(blob) {\n var sections = SDPUtils.splitSections(blob);\n sections.shift();\n return sections;\n};\n\n// Returns lines that start with a certain prefix.\nSDPUtils.matchPrefix = function(blob, prefix) {\n return SDPUtils.splitLines(blob).filter(function(line) {\n return line.indexOf(prefix) === 0;\n });\n};\n\n// Parses an ICE candidate line. Sample input:\n// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8\n// rport 55996\"\nSDPUtils.parseCandidate = function(line) {\n var parts;\n // Parse both variants.\n if (line.indexOf('a=candidate:') === 0) {\n parts = line.substring(12).split(' ');\n } else {\n parts = line.substring(10).split(' ');\n }\n\n var candidate = {\n foundation: parts[0],\n component: parseInt(parts[1], 10),\n protocol: parts[2].toLowerCase(),\n priority: parseInt(parts[3], 10),\n ip: parts[4],\n address: parts[4], // address is an alias for ip.\n port: parseInt(parts[5], 10),\n // skip parts[6] == 'typ'\n type: parts[7]\n };\n\n for (var i = 8; i < parts.length; i += 2) {\n switch (parts[i]) {\n case 'raddr':\n candidate.relatedAddress = parts[i + 1];\n break;\n case 'rport':\n candidate.relatedPort = parseInt(parts[i + 1], 10);\n break;\n case 'tcptype':\n candidate.tcpType = parts[i + 1];\n break;\n case 'ufrag':\n candidate.ufrag = parts[i + 1]; // for backward compability.\n candidate.usernameFragment = parts[i + 1];\n break;\n default: // extension handling, in particular ufrag\n candidate[parts[i]] = parts[i + 1];\n break;\n }\n }\n return candidate;\n};\n\n// Translates a candidate object into SDP candidate attribute.\nSDPUtils.writeCandidate = function(candidate) {\n var sdp = [];\n sdp.push(candidate.foundation);\n sdp.push(candidate.component);\n sdp.push(candidate.protocol.toUpperCase());\n sdp.push(candidate.priority);\n sdp.push(candidate.address || candidate.ip);\n sdp.push(candidate.port);\n\n var type = candidate.type;\n sdp.push('typ');\n sdp.push(type);\n if (type !== 'host' && candidate.relatedAddress &&\n candidate.relatedPort) {\n sdp.push('raddr');\n sdp.push(candidate.relatedAddress);\n sdp.push('rport');\n sdp.push(candidate.relatedPort);\n }\n if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {\n sdp.push('tcptype');\n sdp.push(candidate.tcpType);\n }\n if (candidate.usernameFragment || candidate.ufrag) {\n sdp.push('ufrag');\n sdp.push(candidate.usernameFragment || candidate.ufrag);\n }\n return 'candidate:' + sdp.join(' ');\n};\n\n// Parses an ice-options line, returns an array of option tags.\n// a=ice-options:foo bar\nSDPUtils.parseIceOptions = function(line) {\n return line.substr(14).split(' ');\n};\n\n// Parses an rtpmap line, returns RTCRtpCoddecParameters. Sample input:\n// a=rtpmap:111 opus/48000/2\nSDPUtils.parseRtpMap = function(line) {\n var parts = line.substr(9).split(' ');\n var parsed = {\n payloadType: parseInt(parts.shift(), 10) // was: id\n };\n\n parts = parts[0].split('/');\n\n parsed.name = parts[0];\n parsed.clockRate = parseInt(parts[1], 10); // was: clockrate\n parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;\n // legacy alias, got renamed back to channels in ORTC.\n parsed.numChannels = parsed.channels;\n return parsed;\n};\n\n// Generate an a=rtpmap line from RTCRtpCodecCapability or\n// RTCRtpCodecParameters.\nSDPUtils.writeRtpMap = function(codec) {\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n var channels = codec.channels || codec.numChannels || 1;\n return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate +\n (channels !== 1 ? '/' + channels : '') + '\\r\\n';\n};\n\n// Parses an a=extmap line (headerextension from RFC 5285). Sample input:\n// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\n// a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset\nSDPUtils.parseExtmap = function(line) {\n var parts = line.substr(9).split(' ');\n return {\n id: parseInt(parts[0], 10),\n direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',\n uri: parts[1]\n };\n};\n\n// Generates a=extmap line from RTCRtpHeaderExtensionParameters or\n// RTCRtpHeaderExtension.\nSDPUtils.writeExtmap = function(headerExtension) {\n return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) +\n (headerExtension.direction && headerExtension.direction !== 'sendrecv'\n ? '/' + headerExtension.direction\n : '') +\n ' ' + headerExtension.uri + '\\r\\n';\n};\n\n// Parses an ftmp line, returns dictionary. Sample input:\n// a=fmtp:96 vbr=on;cng=on\n// Also deals with vbr=on; cng=on\nSDPUtils.parseFmtp = function(line) {\n var parsed = {};\n var kv;\n var parts = line.substr(line.indexOf(' ') + 1).split(';');\n for (var j = 0; j < parts.length; j++) {\n kv = parts[j].trim().split('=');\n parsed[kv[0].trim()] = kv[1];\n }\n return parsed;\n};\n\n// Generates an a=ftmp line from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeFmtp = function(codec) {\n var line = '';\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.parameters && Object.keys(codec.parameters).length) {\n var params = [];\n Object.keys(codec.parameters).forEach(function(param) {\n if (codec.parameters[param]) {\n params.push(param + '=' + codec.parameters[param]);\n } else {\n params.push(param);\n }\n });\n line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\\r\\n';\n }\n return line;\n};\n\n// Parses an rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:\n// a=rtcp-fb:98 nack rpsi\nSDPUtils.parseRtcpFb = function(line) {\n var parts = line.substr(line.indexOf(' ') + 1).split(' ');\n return {\n type: parts.shift(),\n parameter: parts.join(' ')\n };\n};\n// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeRtcpFb = function(codec) {\n var lines = '';\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.rtcpFeedback && codec.rtcpFeedback.length) {\n // FIXME: special handling for trr-int?\n codec.rtcpFeedback.forEach(function(fb) {\n lines += 'a=rtcp-fb:' + pt + ' ' + fb.type +\n (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') +\n '\\r\\n';\n });\n }\n return lines;\n};\n\n// Parses an RFC 5576 ssrc media attribute. Sample input:\n// a=ssrc:3735928559 cname:something\nSDPUtils.parseSsrcMedia = function(line) {\n var sp = line.indexOf(' ');\n var parts = {\n ssrc: parseInt(line.substr(7, sp - 7), 10)\n };\n var colon = line.indexOf(':', sp);\n if (colon > -1) {\n parts.attribute = line.substr(sp + 1, colon - sp - 1);\n parts.value = line.substr(colon + 1);\n } else {\n parts.attribute = line.substr(sp + 1);\n }\n return parts;\n};\n\nSDPUtils.parseSsrcGroup = function(line) {\n var parts = line.substr(13).split(' ');\n return {\n semantics: parts.shift(),\n ssrcs: parts.map(function(ssrc) {\n return parseInt(ssrc, 10);\n })\n };\n};\n\n// Extracts the MID (RFC 5888) from a media section.\n// returns the MID or undefined if no mid line was found.\nSDPUtils.getMid = function(mediaSection) {\n var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];\n if (mid) {\n return mid.substr(6);\n }\n};\n\nSDPUtils.parseFingerprint = function(line) {\n var parts = line.substr(14).split(' ');\n return {\n algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge.\n value: parts[1]\n };\n};\n\n// Extracts DTLS parameters from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the fingerprint line as input. See also getIceParameters.\nSDPUtils.getDtlsParameters = function(mediaSection, sessionpart) {\n var lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=fingerprint:');\n // Note: a=setup line is ignored since we use the 'auto' role.\n // Note2: 'algorithm' is not case sensitive except in Edge.\n return {\n role: 'auto',\n fingerprints: lines.map(SDPUtils.parseFingerprint)\n };\n};\n\n// Serializes DTLS parameters to SDP.\nSDPUtils.writeDtlsParameters = function(params, setupType) {\n var sdp = 'a=setup:' + setupType + '\\r\\n';\n params.fingerprints.forEach(function(fp) {\n sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\\r\\n';\n });\n return sdp;\n};\n\n// Parses a=crypto lines into\n// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members\nSDPUtils.parseCryptoLine = function(line) {\n var parts = line.substr(9).split(' ');\n return {\n tag: parseInt(parts[0], 10),\n cryptoSuite: parts[1],\n keyParams: parts[2],\n sessionParams: parts.slice(3),\n };\n};\n\nSDPUtils.writeCryptoLine = function(parameters) {\n return 'a=crypto:' + parameters.tag + ' ' +\n parameters.cryptoSuite + ' ' +\n (typeof parameters.keyParams === 'object'\n ? SDPUtils.writeCryptoKeyParams(parameters.keyParams)\n : parameters.keyParams) +\n (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') +\n '\\r\\n';\n};\n\n// Parses the crypto key parameters into\n// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*\nSDPUtils.parseCryptoKeyParams = function(keyParams) {\n if (keyParams.indexOf('inline:') !== 0) {\n return null;\n }\n var parts = keyParams.substr(7).split('|');\n return {\n keyMethod: 'inline',\n keySalt: parts[0],\n lifeTime: parts[1],\n mkiValue: parts[2] ? parts[2].split(':')[0] : undefined,\n mkiLength: parts[2] ? parts[2].split(':')[1] : undefined,\n };\n};\n\nSDPUtils.writeCryptoKeyParams = function(keyParams) {\n return keyParams.keyMethod + ':'\n + keyParams.keySalt +\n (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') +\n (keyParams.mkiValue && keyParams.mkiLength\n ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength\n : '');\n};\n\n// Extracts all SDES paramters.\nSDPUtils.getCryptoParameters = function(mediaSection, sessionpart) {\n var lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=crypto:');\n return lines.map(SDPUtils.parseCryptoLine);\n};\n\n// Parses ICE information from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the ice-ufrag and ice-pwd lines as input.\nSDPUtils.getIceParameters = function(mediaSection, sessionpart) {\n var ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=ice-ufrag:')[0];\n var pwd = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=ice-pwd:')[0];\n if (!(ufrag && pwd)) {\n return null;\n }\n return {\n usernameFragment: ufrag.substr(12),\n password: pwd.substr(10),\n };\n};\n\n// Serializes ICE parameters to SDP.\nSDPUtils.writeIceParameters = function(params) {\n return 'a=ice-ufrag:' + params.usernameFragment + '\\r\\n' +\n 'a=ice-pwd:' + params.password + '\\r\\n';\n};\n\n// Parses the SDP media section and returns RTCRtpParameters.\nSDPUtils.parseRtpParameters = function(mediaSection) {\n var description = {\n codecs: [],\n headerExtensions: [],\n fecMechanisms: [],\n rtcp: []\n };\n var lines = SDPUtils.splitLines(mediaSection);\n var mline = lines[0].split(' ');\n for (var i = 3; i < mline.length; i++) { // find all codecs from mline[3..]\n var pt = mline[i];\n var rtpmapline = SDPUtils.matchPrefix(\n mediaSection, 'a=rtpmap:' + pt + ' ')[0];\n if (rtpmapline) {\n var codec = SDPUtils.parseRtpMap(rtpmapline);\n var fmtps = SDPUtils.matchPrefix(\n mediaSection, 'a=fmtp:' + pt + ' ');\n // Only the first a=fmtp: is considered.\n codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};\n codec.rtcpFeedback = SDPUtils.matchPrefix(\n mediaSection, 'a=rtcp-fb:' + pt + ' ')\n .map(SDPUtils.parseRtcpFb);\n description.codecs.push(codec);\n // parse FEC mechanisms from rtpmap lines.\n switch (codec.name.toUpperCase()) {\n case 'RED':\n case 'ULPFEC':\n description.fecMechanisms.push(codec.name.toUpperCase());\n break;\n default: // only RED and ULPFEC are recognized as FEC mechanisms.\n break;\n }\n }\n }\n SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(function(line) {\n description.headerExtensions.push(SDPUtils.parseExtmap(line));\n });\n // FIXME: parse rtcp.\n return description;\n};\n\n// Generates parts of the SDP media section describing the capabilities /\n// parameters.\nSDPUtils.writeRtpDescription = function(kind, caps) {\n var sdp = '';\n\n // Build the mline.\n sdp += 'm=' + kind + ' ';\n sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.\n sdp += ' UDP/TLS/RTP/SAVPF ';\n sdp += caps.codecs.map(function(codec) {\n if (codec.preferredPayloadType !== undefined) {\n return codec.preferredPayloadType;\n }\n return codec.payloadType;\n }).join(' ') + '\\r\\n';\n\n sdp += 'c=IN IP4 0.0.0.0\\r\\n';\n sdp += 'a=rtcp:9 IN IP4 0.0.0.0\\r\\n';\n\n // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.\n caps.codecs.forEach(function(codec) {\n sdp += SDPUtils.writeRtpMap(codec);\n sdp += SDPUtils.writeFmtp(codec);\n sdp += SDPUtils.writeRtcpFb(codec);\n });\n var maxptime = 0;\n caps.codecs.forEach(function(codec) {\n if (codec.maxptime > maxptime) {\n maxptime = codec.maxptime;\n }\n });\n if (maxptime > 0) {\n sdp += 'a=maxptime:' + maxptime + '\\r\\n';\n }\n sdp += 'a=rtcp-mux\\r\\n';\n\n if (caps.headerExtensions) {\n caps.headerExtensions.forEach(function(extension) {\n sdp += SDPUtils.writeExtmap(extension);\n });\n }\n // FIXME: write fecMechanisms.\n return sdp;\n};\n\n// Parses the SDP media section and returns an array of\n// RTCRtpEncodingParameters.\nSDPUtils.parseRtpEncodingParameters = function(mediaSection) {\n var encodingParameters = [];\n var description = SDPUtils.parseRtpParameters(mediaSection);\n var hasRed = description.fecMechanisms.indexOf('RED') !== -1;\n var hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;\n\n // filter a=ssrc:... cname:, ignore PlanB-msid\n var ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(parts) {\n return parts.attribute === 'cname';\n });\n var primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;\n var secondarySsrc;\n\n var flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID')\n .map(function(line) {\n var parts = line.substr(17).split(' ');\n return parts.map(function(part) {\n return parseInt(part, 10);\n });\n });\n if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {\n secondarySsrc = flows[0][1];\n }\n\n description.codecs.forEach(function(codec) {\n if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {\n var encParam = {\n ssrc: primarySsrc,\n codecPayloadType: parseInt(codec.parameters.apt, 10)\n };\n if (primarySsrc && secondarySsrc) {\n encParam.rtx = {ssrc: secondarySsrc};\n }\n encodingParameters.push(encParam);\n if (hasRed) {\n encParam = JSON.parse(JSON.stringify(encParam));\n encParam.fec = {\n ssrc: primarySsrc,\n mechanism: hasUlpfec ? 'red+ulpfec' : 'red'\n };\n encodingParameters.push(encParam);\n }\n }\n });\n if (encodingParameters.length === 0 && primarySsrc) {\n encodingParameters.push({\n ssrc: primarySsrc\n });\n }\n\n // we support both b=AS and b=TIAS but interpret AS as TIAS.\n var bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');\n if (bandwidth.length) {\n if (bandwidth[0].indexOf('b=TIAS:') === 0) {\n bandwidth = parseInt(bandwidth[0].substr(7), 10);\n } else if (bandwidth[0].indexOf('b=AS:') === 0) {\n // use formula from JSEP to convert b=AS to TIAS value.\n bandwidth = parseInt(bandwidth[0].substr(5), 10) * 1000 * 0.95\n - (50 * 40 * 8);\n } else {\n bandwidth = undefined;\n }\n encodingParameters.forEach(function(params) {\n params.maxBitrate = bandwidth;\n });\n }\n return encodingParameters;\n};\n\n// parses http://draft.ortc.org/#rtcrtcpparameters*\nSDPUtils.parseRtcpParameters = function(mediaSection) {\n var rtcpParameters = {};\n\n // Gets the first SSRC. Note tha with RTX there might be multiple\n // SSRCs.\n var remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(obj) {\n return obj.attribute === 'cname';\n })[0];\n if (remoteSsrc) {\n rtcpParameters.cname = remoteSsrc.value;\n rtcpParameters.ssrc = remoteSsrc.ssrc;\n }\n\n // Edge uses the compound attribute instead of reducedSize\n // compound is !reducedSize\n var rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');\n rtcpParameters.reducedSize = rsize.length > 0;\n rtcpParameters.compound = rsize.length === 0;\n\n // parses the rtcp-mux attrіbute.\n // Note that Edge does not support unmuxed RTCP.\n var mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');\n rtcpParameters.mux = mux.length > 0;\n\n return rtcpParameters;\n};\n\n// parses either a=msid: or a=ssrc:... msid lines and returns\n// the id of the MediaStream and MediaStreamTrack.\nSDPUtils.parseMsid = function(mediaSection) {\n var parts;\n var spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');\n if (spec.length === 1) {\n parts = spec[0].substr(7).split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n var planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(msidParts) {\n return msidParts.attribute === 'msid';\n });\n if (planB.length > 0) {\n parts = planB[0].value.split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n};\n\n// SCTP\n// parses draft-ietf-mmusic-sctp-sdp-26 first and falls back\n// to draft-ietf-mmusic-sctp-sdp-05\nSDPUtils.parseSctpDescription = function(mediaSection) {\n var mline = SDPUtils.parseMLine(mediaSection);\n var maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');\n var maxMessageSize;\n if (maxSizeLine.length > 0) {\n maxMessageSize = parseInt(maxSizeLine[0].substr(19), 10);\n }\n if (isNaN(maxMessageSize)) {\n maxMessageSize = 65536;\n }\n var sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');\n if (sctpPort.length > 0) {\n return {\n port: parseInt(sctpPort[0].substr(12), 10),\n protocol: mline.fmt,\n maxMessageSize: maxMessageSize\n };\n }\n var sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');\n if (sctpMapLines.length > 0) {\n var parts = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:')[0]\n .substr(10)\n .split(' ');\n return {\n port: parseInt(parts[0], 10),\n protocol: parts[1],\n maxMessageSize: maxMessageSize\n };\n }\n};\n\n// SCTP\n// outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers\n// support by now receiving in this format, unless we originally parsed\n// as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line\n// protocol of DTLS/SCTP -- without UDP/ or TCP/)\nSDPUtils.writeSctpDescription = function(media, sctp) {\n var output = [];\n if (media.protocol !== 'DTLS/SCTP') {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctp-port:' + sctp.port + '\\r\\n'\n ];\n } else {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\\r\\n'\n ];\n }\n if (sctp.maxMessageSize !== undefined) {\n output.push('a=max-message-size:' + sctp.maxMessageSize + '\\r\\n');\n }\n return output.join('');\n};\n\n// Generate a session ID for SDP.\n// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1\n// recommends using a cryptographically random +ve 64-bit value\n// but right now this should be acceptable and within the right range\nSDPUtils.generateSessionId = function() {\n return Math.random().toString().substr(2, 21);\n};\n\n// Write boilder plate for start of SDP\n// sessId argument is optional - if not supplied it will\n// be generated randomly\n// sessVersion is optional and defaults to 2\n// sessUser is optional and defaults to 'thisisadapterortc'\nSDPUtils.writeSessionBoilerplate = function(sessId, sessVer, sessUser) {\n var sessionId;\n var version = sessVer !== undefined ? sessVer : 2;\n if (sessId) {\n sessionId = sessId;\n } else {\n sessionId = SDPUtils.generateSessionId();\n }\n var user = sessUser || 'thisisadapterortc';\n // FIXME: sess-id should be an NTP timestamp.\n return 'v=0\\r\\n' +\n 'o=' + user + ' ' + sessionId + ' ' + version +\n ' IN IP4 127.0.0.1\\r\\n' +\n 's=-\\r\\n' +\n 't=0 0\\r\\n';\n};\n\nSDPUtils.writeMediaSection = function(transceiver, caps, type, stream) {\n var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps);\n\n // Map ICE parameters (ufrag, pwd) to SDP.\n sdp += SDPUtils.writeIceParameters(\n transceiver.iceGatherer.getLocalParameters());\n\n // Map DTLS parameters to SDP.\n sdp += SDPUtils.writeDtlsParameters(\n transceiver.dtlsTransport.getLocalParameters(),\n type === 'offer' ? 'actpass' : 'active');\n\n sdp += 'a=mid:' + transceiver.mid + '\\r\\n';\n\n if (transceiver.direction) {\n sdp += 'a=' + transceiver.direction + '\\r\\n';\n } else if (transceiver.rtpSender && transceiver.rtpReceiver) {\n sdp += 'a=sendrecv\\r\\n';\n } else if (transceiver.rtpSender) {\n sdp += 'a=sendonly\\r\\n';\n } else if (transceiver.rtpReceiver) {\n sdp += 'a=recvonly\\r\\n';\n } else {\n sdp += 'a=inactive\\r\\n';\n }\n\n if (transceiver.rtpSender) {\n // spec.\n var msid = 'msid:' + stream.id + ' ' +\n transceiver.rtpSender.track.id + '\\r\\n';\n sdp += 'a=' + msid;\n\n // for Chrome.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' ' + msid;\n if (transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' ' + msid;\n sdp += 'a=ssrc-group:FID ' +\n transceiver.sendEncodingParameters[0].ssrc + ' ' +\n transceiver.sendEncodingParameters[0].rtx.ssrc +\n '\\r\\n';\n }\n }\n // FIXME: this should be written by writeRtpDescription.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n }\n return sdp;\n};\n\n// Gets the direction from the mediaSection or the sessionpart.\nSDPUtils.getDirection = function(mediaSection, sessionpart) {\n // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.\n var lines = SDPUtils.splitLines(mediaSection);\n for (var i = 0; i < lines.length; i++) {\n switch (lines[i]) {\n case 'a=sendrecv':\n case 'a=sendonly':\n case 'a=recvonly':\n case 'a=inactive':\n return lines[i].substr(2);\n default:\n // FIXME: What should happen here?\n }\n }\n if (sessionpart) {\n return SDPUtils.getDirection(sessionpart);\n }\n return 'sendrecv';\n};\n\nSDPUtils.getKind = function(mediaSection) {\n var lines = SDPUtils.splitLines(mediaSection);\n var mline = lines[0].split(' ');\n return mline[0].substr(2);\n};\n\nSDPUtils.isRejected = function(mediaSection) {\n return mediaSection.split(' ', 2)[1] === '0';\n};\n\nSDPUtils.parseMLine = function(mediaSection) {\n var lines = SDPUtils.splitLines(mediaSection);\n var parts = lines[0].substr(2).split(' ');\n return {\n kind: parts[0],\n port: parseInt(parts[1], 10),\n protocol: parts[2],\n fmt: parts.slice(3).join(' ')\n };\n};\n\nSDPUtils.parseOLine = function(mediaSection) {\n var line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];\n var parts = line.substr(2).split(' ');\n return {\n username: parts[0],\n sessionId: parts[1],\n sessionVersion: parseInt(parts[2], 10),\n netType: parts[3],\n addressType: parts[4],\n address: parts[5]\n };\n};\n\n// a very naive interpretation of a valid SDP.\nSDPUtils.isValidSDP = function(blob) {\n if (typeof blob !== 'string' || blob.length === 0) {\n return false;\n }\n var lines = SDPUtils.splitLines(blob);\n for (var i = 0; i < lines.length; i++) {\n if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {\n return false;\n }\n // TODO: check the modifier a bit more.\n }\n return true;\n};\n\n// Expose public methods.\nif (typeof module === 'object') {\n module.exports = SDPUtils;\n}\n", "/**\n * A collection of utility functions for taking in XML and parsing it to return\n * certain values.\n */\nexport default {\n /**\n * Parses the presence update of the focus and returns an object with the\n * statuses related to recording.\n *\n * @param {Node} presence - An XMPP presence update.\n * @returns {Object} The current presence values related to recording.\n */\n getFocusRecordingUpdate(presence) {\n const jibriStatus = presence\n && presence.getElementsByTagName('jibri-recording-status')[0];\n\n if (!jibriStatus) {\n return;\n }\n\n return {\n error: jibriStatus.getAttribute('failure_reason'),\n initiator: jibriStatus.getAttribute('initiator'),\n recordingMode: jibriStatus.getAttribute('recording_mode'),\n sessionID: jibriStatus.getAttribute('session_id'),\n status: jibriStatus.getAttribute('status')\n };\n },\n\n /**\n * Parses the presence update from a hidden domain participant and returns\n * an object with the statuses related to recording.\n *\n * @param {Node} presence - An XMPP presence update.\n * @returns {Object} The current presence values related to recording.\n */\n getHiddenDomainUpdate(presence) {\n const liveStreamViewURLContainer\n = presence.getElementsByTagName('live-stream-view-url')[0];\n const liveStreamViewURL = liveStreamViewURLContainer\n && liveStreamViewURLContainer.textContent;\n const modeContainer\n = presence.getElementsByTagName('mode')[0];\n const mode = modeContainer\n && modeContainer.textContent\n && modeContainer.textContent.toLowerCase();\n const sessionIDContainer\n = presence.getElementsByTagName('session_id')[0];\n const sessionID\n = sessionIDContainer && sessionIDContainer.textContent;\n\n return {\n liveStreamViewURL,\n mode,\n sessionID\n };\n },\n\n /**\n * Returns the recording session ID from a successful IQ.\n *\n * @param {Node} response - The response from the IQ.\n * @returns {string} The session ID of the recording session.\n */\n getSessionIdFromIq(response) {\n const jibri = response && response.getElementsByTagName('jibri')[0];\n\n return jibri && jibri.getAttribute('session_id');\n },\n\n /**\n * Returns the recording session ID from a presence, if it exists.\n *\n * @param {Node} presence - An XMPP presence update.\n * @returns {string|undefined} The session ID of the recording session.\n */\n getSessionId(presence) {\n const sessionIdContainer\n = presence.getElementsByTagName('session_id')[0];\n const sessionId = sessionIdContainer && sessionIdContainer.textContent;\n\n return sessionId;\n },\n\n /**\n * Returns whether or not a presence is from the focus.\n *\n * @param {Node} presence - An XMPP presence update.\n * @returns {boolean} True if the presence is from the focus.\n */\n isFromFocus(presence) {\n return presence.getAttribute('from').includes('focus');\n }\n};\n", "/* global __filename, $ */\n\nimport {\n ICE_DURATION,\n ICE_STATE_CHANGED\n} from '../../service/statistics/AnalyticsEvents';\nimport { getLogger } from 'jitsi-meet-logger';\nimport { $iq, Strophe } from 'strophe.js';\nimport { integerHash } from '../util/StringUtils';\n\nimport browser from './../browser';\nimport JingleSession from './JingleSession';\nimport * as JingleSessionState from './JingleSessionState';\nimport SDP from './SDP';\nimport SDPDiffer from './SDPDiffer';\nimport SDPUtil from './SDPUtil';\nimport SignalingLayerImpl from './SignalingLayerImpl';\n\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport Statistics from '../statistics/statistics';\nimport XMPPEvents from '../../service/xmpp/XMPPEvents';\nimport AsyncQueue from '../util/AsyncQueue';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport XmppConnection from './XmppConnection';\n\nconst logger = getLogger(__filename);\n\n/**\n * Constant tells how long we're going to wait for IQ response, before timeout\n * error is triggered.\n * @type {number}\n */\nconst IQ_TIMEOUT = 10000;\n\n/*\n * The default number of samples (per stat) to keep when webrtc stats gathering\n * is enabled in TraceablePeerConnection.\n */\nconst DEFAULT_MAX_STATS = 300;\n\n/**\n * @typedef {Object} JingleSessionPCOptions\n * @property {Object} abTesting - A/B testing related options (ask George).\n * @property {boolean} abTesting.enableSuspendVideoTest - enables the suspend\n * video test ?(ask George).\n * @property {boolean} disableH264 - Described in the config.js[1].\n * @property {boolean} disableRtx - Described in the config.js[1].\n * @property {boolean} disableSimulcast - Described in the config.js[1].\n * @property {boolean} enableLayerSuspension - Described in the config.js[1].\n * @property {boolean} failICE - it's an option used in the tests. Set to\n * true to block any real candidates and make the ICE fail.\n * @property {boolean} gatherStats - Described in the config.js[1].\n * @property {object} p2p - Peer to peer related options (FIXME those could be\n * fetched from config.p2p on the upper level).\n * @property {boolean} p2p.disableH264 - Described in the config.js[1].\n * @property {boolean} p2p.preferH264 - Described in the config.js[1].\n * @property {boolean} preferH264 - Described in the config.js[1].\n * @property {Object} testing - Testing and/or experimental options.\n * @property {boolean} webrtcIceUdpDisable - Described in the config.js[1].\n * @property {boolean} webrtcIceTcpDisable - Described in the config.js[1].\n *\n * [1]: https://github.com/jitsi/jitsi-meet/blob/master/config.js\n */\n/**\n *\n */\nexport default class JingleSessionPC extends JingleSession {\n /**\n * Parses 'senders' attribute of the video content.\n * @param {jQuery} jingleContents\n * @return {string|null} one of the values of content \"senders\" attribute\n * defined by Jingle. If there is no \"senders\" attribute or if the value is\n * invalid then null will be returned.\n * @private\n */\n static parseVideoSenders(jingleContents) {\n const videoContents = jingleContents.find('>content[name=\"video\"]');\n\n if (videoContents.length) {\n const senders = videoContents[0].getAttribute('senders');\n\n if (senders === 'both'\n || senders === 'initiator'\n || senders === 'responder'\n || senders === 'none') {\n return senders;\n }\n }\n\n return null;\n }\n\n /* eslint-disable max-params */\n\n /**\n * Creates new JingleSessionPC\n * @param {string} sid the Jingle Session ID - random string which\n * identifies the session\n * @param {string} localJid our JID\n * @param {string} remoteJid remote peer JID\n * @param {XmppConnection} connection - The XMPP connection instance.\n * @param mediaConstraints the media constraints object passed to\n * createOffer/Answer, as defined by the WebRTC standard\n * @param iceConfig the ICE servers config object as defined by the WebRTC\n * standard.\n * @param {boolean} isP2P indicates whether this instance is\n * meant to be used in a direct, peer to peer connection or false\n * if it's a JVB connection.\n * @param {boolean} isInitiator indicates if it will be the side which\n * initiates the session.\n * @constructor\n *\n * @implements {SignalingLayer}\n */\n constructor(\n sid,\n localJid,\n remoteJid,\n connection,\n mediaConstraints,\n iceConfig,\n isP2P,\n isInitiator) {\n super(\n sid,\n localJid,\n remoteJid, connection, mediaConstraints, iceConfig, isInitiator);\n\n /**\n * The bridge session's identifier. One Jingle session can during\n * it's lifetime participate in multiple bridge sessions managed by\n * Jicofo. A new bridge session is started whenever Jicofo sends\n * 'session-initiate' or 'transport-replace'.\n *\n * @type {?string}\n * @private\n */\n this._bridgeSessionId = null;\n\n /**\n * The oldest SDP passed to {@link notifyMySSRCUpdate} while the XMPP connection was offline that will be\n * used to update Jicofo once the XMPP connection goes back online.\n * @type {SDP|undefined}\n * @private\n */\n this._cachedOldLocalSdp = undefined;\n\n /**\n * The latest SDP passed to {@link notifyMySSRCUpdate} while the XMPP connection was offline that will be\n * used to update Jicofo once the XMPP connection goes back online.\n * @type {SDP|undefined}\n * @private\n */\n this._cachedNewLocalSdp = undefined;\n\n /**\n * Stores result of {@link window.performance.now()} at the time when\n * ICE enters 'checking' state.\n * @type {number|null} null if no value has been stored yet\n * @private\n */\n this._iceCheckingStartedTimestamp = null;\n\n /**\n * Stores result of {@link window.performance.now()} at the time when\n * first ICE candidate is spawned by the peerconnection to mark when\n * ICE gathering started. That's, because ICE gathering state changed\n * events are not supported by most of the browsers, so we try something\n * that will work everywhere. It may not be as accurate, but given that\n * 'host' candidate usually comes first, the delay should be minimal.\n * @type {number|null} null if no value has been stored yet\n * @private\n */\n this._gatheringStartedTimestamp = null;\n\n /**\n * Indicates whether or not this session is willing to send/receive\n * video media. When set to false the underlying peer\n * connection will disable local video transfer and the remote peer will\n * be will be asked to stop sending video via 'content-modify' IQ\n * (the senders attribute of video contents will be adjusted\n * accordingly). Note that this notification is sent only in P2P\n * session, because Jicofo does not support it yet. Obviously when\n * the value is changed from false to true another\n * notification will be sent to resume video transfer on the remote\n * side.\n * @type {boolean}\n * @private\n */\n this._localVideoActive = true;\n\n /**\n * Indicates whether or not the remote peer has video transfer active.\n * When set to true it means that remote peer is neither\n * sending nor willing to receive video. In such case we'll ask\n * our peerconnection to stop sending video by calling\n * {@link TraceablePeerConnection.setVideoTransferActive} with\n * false.\n * @type {boolean}\n * @private\n */\n this._remoteVideoActive = true;\n\n /**\n * Marks that ICE gathering duration has been reported already. That\n * prevents reporting it again, after eventual 'transport-replace' (JVB\n * conference migration/ICE restart).\n * @type {boolean}\n * @private\n */\n this._gatheringReported = false;\n\n this.lasticecandidate = false;\n this.closed = false;\n\n /**\n * Indicates whether or not this JingleSessionPC is used in\n * a peer to peer type of session.\n * @type {boolean} true if it's a peer to peer\n * session or false if it's a JVB session\n */\n this.isP2P = isP2P;\n\n /**\n * The signaling layer implementation.\n * @type {SignalingLayerImpl}\n */\n this.signalingLayer = new SignalingLayerImpl();\n\n /**\n * The queue used to serialize operations done on the peerconnection.\n *\n * @type {AsyncQueue}\n */\n this.modificationQueue = new AsyncQueue();\n\n /**\n * Flag used to guarantee that the connection established event is\n * triggered just once.\n * @type {boolean}\n */\n this.wasConnected = false;\n\n /**\n * Keeps track of how long (in ms) it took from ICE start to ICE\n * connect.\n *\n * @type {number}\n */\n this.establishmentDuration = undefined;\n\n this._xmppListeners = [];\n this._xmppListeners.push(\n connection.addEventListener(\n XmppConnection.Events.CONN_STATUS_CHANGED,\n this.onXmppStatusChanged.bind(this))\n );\n }\n\n /* eslint-enable max-params */\n\n /**\n * Checks whether or not this session instance is still operational.\n * @private\n * @returns {boolean} {@code true} if operation or {@code false} otherwise.\n */\n _assertNotEnded() {\n return this.state !== JingleSessionState.ENDED;\n }\n\n /**\n * @inheritDoc\n * @param {JingleSessionPCOptions} options - a set of config options.\n */\n doInitialize(options) {\n this.failICE = Boolean(options.failICE);\n this.lasticecandidate = false;\n this.options = options;\n\n /**\n * {@code true} if reconnect is in progress.\n * @type {boolean}\n */\n this.isReconnect = false;\n\n /**\n * Set to {@code true} if the connection was ever stable\n * @type {boolean}\n */\n this.wasstable = false;\n this.webrtcIceUdpDisable = Boolean(options.webrtcIceUdpDisable);\n this.webrtcIceTcpDisable = Boolean(options.webrtcIceTcpDisable);\n\n const pcOptions = { disableRtx: options.disableRtx };\n\n if (options.gatherStats) {\n pcOptions.maxstats = DEFAULT_MAX_STATS;\n }\n pcOptions.capScreenshareBitrate = false;\n if (this.isP2P) {\n // simulcast needs to be disabled for P2P (121) calls\n pcOptions.disableSimulcast = true;\n pcOptions.disableH264 = options.p2p && options.p2p.disableH264;\n pcOptions.preferH264 = options.p2p && options.p2p.preferH264;\n\n const abtestSuspendVideo = this._abtestSuspendVideoEnabled(options);\n\n if (typeof abtestSuspendVideo !== 'undefined') {\n pcOptions.abtestSuspendVideo = abtestSuspendVideo;\n }\n } else {\n // H264 does not support simulcast, so it needs to be disabled.\n pcOptions.disableSimulcast\n = options.disableSimulcast\n || (options.preferH264 && !options.disableH264);\n pcOptions.preferH264 = options.preferH264;\n pcOptions.enableLayerSuspension = options.enableLayerSuspension;\n\n // disable simulcast for screenshare and set the max bitrate to\n // 500Kbps if the testing flag is present in config.js.\n if (options.testing\n && options.testing.capScreenshareBitrate\n && typeof options.testing.capScreenshareBitrate === 'number') {\n pcOptions.capScreenshareBitrate\n = Math.random()\n < options.testing.capScreenshareBitrate;\n\n // add the capScreenshareBitrate to the permanent properties so\n // that it's included with every event that we send to the\n // analytics backend.\n Statistics.analytics.addPermanentProperties({ capScreenshareBitrate: pcOptions.capScreenshareBitrate });\n }\n }\n\n if (options.startSilent) {\n pcOptions.startSilent = true;\n }\n\n this.peerconnection\n = this.rtc.createPeerConnection(\n this.signalingLayer,\n this.iceConfig,\n this.isP2P,\n pcOptions);\n\n this.peerconnection.onicecandidate = ev => {\n if (!ev) {\n // There was an incomplete check for ev before which left\n // the last line of the function unprotected from a potential\n // throw of an exception. Consequently, it may be argued that\n // the check is unnecessary. Anyway, I'm leaving it and making\n // the check complete.\n return;\n }\n\n // XXX this is broken, candidate is not parsed.\n const candidate = ev.candidate;\n const now = window.performance.now();\n\n if (candidate) {\n if (this._gatheringStartedTimestamp === null) {\n this._gatheringStartedTimestamp = now;\n }\n\n // Discard candidates of disabled protocols.\n let protocol = candidate.protocol;\n\n if (typeof protocol === 'string') {\n protocol = protocol.toLowerCase();\n if (protocol === 'tcp' || protocol === 'ssltcp') {\n if (this.webrtcIceTcpDisable) {\n return;\n }\n } else if (protocol === 'udp') {\n if (this.webrtcIceUdpDisable) {\n return;\n }\n }\n }\n } else if (!this._gatheringReported) {\n // End of gathering\n Statistics.sendAnalytics(\n ICE_DURATION,\n {\n phase: 'gathering',\n value: now - this._gatheringStartedTimestamp,\n p2p: this.isP2P,\n initiator: this.isInitiator\n });\n this._gatheringReported = true;\n }\n this.sendIceCandidate(candidate);\n };\n\n // Note there is a change in the spec about closed:\n // This value moved into the RTCPeerConnectionState enum in\n // the May 13, 2016 draft of the specification, as it reflects the state\n // of the RTCPeerConnection, not the signaling connection. You now\n // detect a closed connection by checking for connectionState to be\n // \"closed\" instead.\n // I suppose at some point this will be moved to onconnectionstatechange\n this.peerconnection.onsignalingstatechange = () => {\n if (this.peerconnection.signalingState === 'stable') {\n this.wasstable = true;\n } else if (this.peerconnection.signalingState === 'closed'\n || this.peerconnection.connectionState === 'closed') {\n this.room.eventEmitter.emit(XMPPEvents.SUSPEND_DETECTED, this);\n }\n };\n\n /**\n * The oniceconnectionstatechange event handler contains the code to\n * execute when the iceconnectionstatechange event, of type Event,\n * is received by this RTCPeerConnection. Such an event is sent when\n * the value of RTCPeerConnection.iceConnectionState changes.\n */\n this.peerconnection.oniceconnectionstatechange = () => {\n const now = window.performance.now();\n\n if (!this.isP2P) {\n this.room.connectionTimes[\n `ice.state.${this.peerconnection.iceConnectionState}`]\n = now;\n }\n logger.log(\n `(TIME) ICE ${this.peerconnection.iceConnectionState}`\n + ` P2P? ${this.isP2P}:\\t`,\n now);\n\n Statistics.sendAnalytics(\n ICE_STATE_CHANGED,\n {\n p2p: this.isP2P,\n state: this.peerconnection.iceConnectionState,\n 'signaling_state': this.peerconnection.signalingState,\n reconnect: this.isReconnect,\n value: now\n });\n\n this.room.eventEmitter.emit(\n XMPPEvents.ICE_CONNECTION_STATE_CHANGED,\n this,\n this.peerconnection.iceConnectionState);\n switch (this.peerconnection.iceConnectionState) {\n case 'checking':\n this._iceCheckingStartedTimestamp = now;\n break;\n case 'connected':\n // Informs interested parties that the connection has been\n // restored.\n if (this.peerconnection.signalingState === 'stable') {\n if (this.isReconnect) {\n this.room.eventEmitter.emit(\n XMPPEvents.CONNECTION_RESTORED, this);\n }\n }\n\n if (!this.wasConnected && this.wasstable) {\n\n Statistics.sendAnalytics(\n ICE_DURATION,\n {\n phase: 'checking',\n value: now - this._iceCheckingStartedTimestamp,\n p2p: this.isP2P,\n initiator: this.isInitiator\n });\n\n // Switch between ICE gathering and ICE checking whichever\n // started first (scenarios are different for initiator\n // vs responder)\n const iceStarted\n = Math.min(\n this._iceCheckingStartedTimestamp,\n this._gatheringStartedTimestamp);\n\n this.establishmentDuration = now - iceStarted;\n\n Statistics.sendAnalytics(\n ICE_DURATION,\n {\n phase: 'establishment',\n value: this.establishmentDuration,\n p2p: this.isP2P,\n initiator: this.isInitiator\n });\n\n this.wasConnected = true;\n this.room.eventEmitter.emit(\n XMPPEvents.CONNECTION_ESTABLISHED, this);\n }\n this.isReconnect = false;\n break;\n case 'disconnected':\n this.isReconnect = true;\n\n // Informs interested parties that the connection has been\n // interrupted.\n if (this.wasstable) {\n this.room.eventEmitter.emit(\n XMPPEvents.CONNECTION_INTERRUPTED, this);\n }\n break;\n case 'failed':\n this.room.eventEmitter.emit(\n XMPPEvents.CONNECTION_ICE_FAILED, this);\n break;\n }\n };\n\n /**\n * The negotiationneeded event is fired whenever we shake the media on the\n * RTCPeerConnection object.\n */\n this.peerconnection.onnegotiationneeded = () => {\n const state = this.peerconnection.signalingState;\n const remoteDescription = this.peerconnection.remoteDescription;\n\n this.room.eventEmitter.emit(XMPPEvents.PEERCONNECTION_READY, this);\n if (browser.usesUnifiedPlan() && state === 'stable'\n && remoteDescription && typeof remoteDescription.sdp === 'string') {\n logger.debug(`onnegotiationneeded fired on ${this.peerconnection} in state: ${state}`);\n const workFunction = finishedCallback => {\n const oldSdp = new SDP(this.peerconnection.localDescription.sdp);\n\n this._renegotiate()\n .then(() => {\n const newSdp = new SDP(this.peerconnection.localDescription.sdp);\n\n this.notifyMySSRCUpdate(oldSdp, newSdp);\n finishedCallback();\n },\n finishedCallback /* will be called with en error */);\n };\n\n this.modificationQueue.push(\n workFunction,\n error => {\n if (error) {\n logger.error('onnegotiationneeded error', error);\n } else {\n logger.debug('onnegotiationneeded executed - OK');\n }\n });\n }\n };\n\n // The signaling layer will bind it's listeners at this point\n this.signalingLayer.setChatRoom(this.room);\n\n if (!this.isP2P && options.enableLayerSuspension) {\n // If this is the bridge session, we'll listen for\n // IS_SELECTED_CHANGED events and notify the peer connection\n this.rtc.addListener(RTCEvents.IS_SELECTED_CHANGED,\n isSelected => {\n this.peerconnection.setIsSelected(isSelected);\n logger.info('Doing local O/A due to '\n + 'IS_SELECTED_CHANGED event');\n this.modificationQueue.push(finishedCallback => {\n this._renegotiate()\n .then(finishedCallback)\n .catch(finishedCallback);\n });\n }\n );\n }\n }\n\n /**\n * Sends given candidate in Jingle 'transport-info' message.\n * @param {RTCIceCandidate} candidate the WebRTC ICE candidate instance\n * @private\n */\n sendIceCandidate(candidate) {\n const localSDP = new SDP(this.peerconnection.localDescription.sdp);\n\n if (candidate && candidate.candidate.length && !this.lasticecandidate) {\n const ice\n = SDPUtil.iceparams(\n localSDP.media[candidate.sdpMLineIndex], localSDP.session);\n const jcand = SDPUtil.candidateToJingle(candidate.candidate);\n\n if (!(ice && jcand)) {\n const errorMesssage = 'failed to get ice && jcand';\n\n GlobalOnErrorHandler.callErrorHandler(new Error(errorMesssage));\n logger.error(errorMesssage);\n\n return;\n }\n ice.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';\n\n if (this.usedrip) {\n if (this.dripContainer.length === 0) {\n // start 20ms callout\n setTimeout(() => {\n if (this.dripContainer.length === 0) {\n return;\n }\n this.sendIceCandidates(this.dripContainer);\n this.dripContainer = [];\n }, 20);\n }\n this.dripContainer.push(candidate);\n } else {\n this.sendIceCandidates([ candidate ]);\n }\n } else {\n logger.log('sendIceCandidate: last candidate.');\n\n // FIXME: remember to re-think in ICE-restart\n this.lasticecandidate = true;\n }\n }\n\n /**\n * Sends given candidates in Jingle 'transport-info' message.\n * @param {Array} candidates an array of the WebRTC ICE\n * candidate instances\n * @private\n */\n sendIceCandidates(candidates) {\n if (!this._assertNotEnded('sendIceCandidates')) {\n\n return;\n }\n\n logger.log('sendIceCandidates', candidates);\n const cand = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', { xmlns: 'urn:xmpp:jingle:1',\n action: 'transport-info',\n initiator: this.initiatorJid,\n sid: this.sid });\n\n const localSDP = new SDP(this.peerconnection.localDescription.sdp);\n\n for (let mid = 0; mid < localSDP.media.length; mid++) {\n const cands = candidates.filter(el => el.sdpMLineIndex === mid);\n const mline\n = SDPUtil.parseMLine(localSDP.media[mid].split('\\r\\n')[0]);\n\n if (cands.length > 0) {\n const ice\n = SDPUtil.iceparams(localSDP.media[mid], localSDP.session);\n\n ice.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';\n cand.c('content', {\n creator: this.initiatorJid === this.localJid\n ? 'initiator' : 'responder',\n name: cands[0].sdpMid ? cands[0].sdpMid : mline.media\n }).c('transport', ice);\n for (let i = 0; i < cands.length; i++) {\n const candidate\n = SDPUtil.candidateToJingle(cands[i].candidate);\n\n // Mangle ICE candidate if 'failICE' test option is enabled\n\n if (this.failICE) {\n candidate.ip = '1.1.1.1';\n }\n cand.c('candidate', candidate).up();\n }\n\n // add fingerprint\n const fingerprintLine\n = SDPUtil.findLine(\n localSDP.media[mid],\n 'a=fingerprint:', localSDP.session);\n\n if (fingerprintLine) {\n const tmp = SDPUtil.parseFingerprint(fingerprintLine);\n\n tmp.required = true;\n cand.c(\n 'fingerprint',\n { xmlns: 'urn:xmpp:jingle:apps:dtls:0' })\n .t(tmp.fingerprint);\n delete tmp.fingerprint;\n cand.attrs(tmp);\n cand.up();\n }\n cand.up(); // transport\n cand.up(); // content\n }\n }\n\n // might merge last-candidate notification into this, but it is called\n // a lot later. See webrtc issue #2340\n // logger.log('was this the last candidate', this.lasticecandidate);\n this.connection.sendIQ(\n cand, null, this.newJingleErrorHandler(cand), IQ_TIMEOUT);\n }\n\n /**\n * Sends Jingle 'session-info' message which includes custom Jitsi Meet\n * 'ice-state' element with the text value 'failed' to let Jicofo know\n * that the ICE connection has entered the failed state. It can then\n * choose to re-create JVB channels and send 'transport-replace' to\n * retry the connection.\n */\n sendIceFailedNotification() {\n const sessionInfo\n = $iq({\n to: this.remoteJid,\n type: 'set' })\n .c('jingle', { xmlns: 'urn:xmpp:jingle:1',\n action: 'session-info',\n initiator: this.initiatorJid,\n sid: this.sid })\n .c('ice-state', { xmlns: 'http://jitsi.org/protocol/focus' })\n .t('failed')\n .up();\n\n this._bridgeSessionId\n && sessionInfo.c(\n 'bridge-session', {\n xmlns: 'http://jitsi.org/protocol/focus',\n id: this._bridgeSessionId\n });\n\n this.connection.sendIQ(\n sessionInfo,\n null,\n this.newJingleErrorHandler(sessionInfo),\n /*\n * This message will be often sent when there are connectivity\n * issues, so make it slightly longer than Prosody's default BOSH\n * inactivity timeout of 60 seconds.\n */ 65);\n }\n\n /**\n * {@inheritDoc}\n */\n addIceCandidates(elem) {\n if (this.peerconnection.signalingState === 'closed') {\n logger.warn('Ignored add ICE candidate when in closed state');\n\n return;\n }\n\n const iceCandidates = [];\n\n elem.find('>content>transport>candidate')\n .each((idx, candidate) => {\n let line = SDPUtil.candidateFromJingle(candidate);\n\n line = line.replace('\\r\\n', '').replace('a=', '');\n\n // FIXME this code does not care to handle\n // non-bundle transport\n const rtcCandidate = new RTCIceCandidate({\n sdpMLineIndex: 0,\n\n // FF comes up with more complex names like audio-23423,\n // Given that it works on both Chrome and FF without\n // providing it, let's leave it like this for the time\n // being...\n // sdpMid: 'audio',\n sdpMid: '',\n candidate: line\n });\n\n iceCandidates.push(rtcCandidate);\n });\n\n if (!iceCandidates.length) {\n logger.error(\n 'No ICE candidates to add ?', elem[0] && elem[0].outerHTML);\n\n return;\n }\n\n // We want to have this task queued, so that we know it is executed,\n // after the initial sRD/sLD offer/answer cycle was done (based on\n // the assumption that candidates are spawned after the offer/answer\n // and XMPP preserves order).\n const workFunction = finishedCallback => {\n for (const iceCandidate of iceCandidates) {\n this.peerconnection.addIceCandidate(iceCandidate)\n .then(\n () => logger.debug('addIceCandidate ok!'),\n err => logger.error('addIceCandidate failed!', err));\n }\n\n finishedCallback();\n };\n\n logger.debug(\n `Queued add (${iceCandidates.length}) ICE candidates task...`);\n this.modificationQueue.push(workFunction);\n }\n\n /**\n *\n * @param contents\n */\n readSsrcInfo(contents) {\n const ssrcs\n = $(contents).find(\n '>description>'\n + 'source[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]');\n\n ssrcs.each((i, ssrcElement) => {\n const ssrc = Number(ssrcElement.getAttribute('ssrc'));\n\n if (this.isP2P) {\n // In P2P all SSRCs are owner by the remote peer\n this.signalingLayer.setSSRCOwner(\n ssrc, Strophe.getResourceFromJid(this.remoteJid));\n } else {\n $(ssrcElement)\n .find('>ssrc-info[xmlns=\"http://jitsi.org/jitmeet\"]')\n .each((i3, ssrcInfoElement) => {\n const owner = ssrcInfoElement.getAttribute('owner');\n\n if (owner && owner.length) {\n if (isNaN(ssrc) || ssrc < 0) {\n logger.warn(\n `Invalid SSRC ${ssrc} value received`\n + ` for ${owner}`);\n } else {\n this.signalingLayer.setSSRCOwner(\n ssrc,\n Strophe.getResourceFromJid(owner));\n }\n }\n });\n }\n });\n }\n\n /**\n * Makes the underlying TraceablePeerConnection generate new SSRC for\n * the recvonly video stream.\n * @deprecated\n */\n generateRecvonlySsrc() {\n if (this.peerconnection) {\n this.peerconnection.generateRecvonlySsrc();\n } else {\n logger.error(\n 'Unable to generate recvonly SSRC - no peerconnection');\n }\n }\n\n /* eslint-disable max-params */\n /**\n * Accepts incoming Jingle 'session-initiate' and should send\n * 'session-accept' in result.\n * @param jingleOffer jQuery selector pointing to the jingle element of\n * the offer IQ\n * @param success callback called when we accept incoming session\n * successfully and receive RESULT packet to 'session-accept' sent.\n * @param failure function(error) called if for any reason we fail to accept\n * the incoming offer. 'error' argument can be used to log some details\n * about the error.\n * @param {Array} [localTracks] the optional list of\n * the local tracks that will be added, before the offer/answer cycle\n * executes. We allow the localTracks to optionally be passed in so that\n * the addition of the local tracks and the processing of the initial offer\n * can all be done atomically. We want to make sure that any other\n * operations which originate in the XMPP Jingle messages related with\n * this session to be executed with an assumption that the initial\n * offer/answer cycle has been executed already.\n */\n acceptOffer(jingleOffer, success, failure, localTracks) {\n this.setOfferAnswerCycle(\n jingleOffer,\n () => {\n // FIXME we may not care about RESULT packet for session-accept\n // then we should either call 'success' here immediately or\n // modify sendSessionAccept method to do that\n this.sendSessionAccept(success, failure);\n },\n failure,\n localTracks);\n }\n\n /* eslint-enable max-params */\n\n /**\n * Creates an offer and sends Jingle 'session-initiate' to the remote peer.\n * @param {Array} localTracks the local tracks that will be\n * added, before the offer/answer cycle executes (for the local track\n * addition to be an atomic operation together with the offer/answer).\n */\n invite(localTracks) {\n if (!this.isInitiator) {\n throw new Error('Trying to invite from the responder session');\n }\n const workFunction = finishedCallback => {\n for (const localTrack of localTracks) {\n this.peerconnection.addTrack(localTrack, true /* isInitiator */);\n }\n this.peerconnection.createOffer(this.mediaConstraints)\n .then(offerSdp => {\n this.peerconnection.setLocalDescription(offerSdp)\n .then(() => {\n // NOTE that the offer is obtained from\n // the localDescription getter as it needs to go\n // though the transformation chain.\n this.sendSessionInitiate(\n this.peerconnection.localDescription.sdp);\n finishedCallback();\n }, error => {\n logger.error(\n 'Failed to set local SDP', error, offerSdp);\n finishedCallback(error);\n });\n }, error => {\n logger.error(\n 'Failed to create an offer',\n error,\n this.mediaConstraints);\n finishedCallback(error);\n });\n };\n\n this.modificationQueue.push(\n workFunction,\n error => {\n if (error) {\n logger.error('invite error', error);\n } else {\n logger.debug('invite executed - OK');\n }\n });\n }\n\n /**\n * Sends 'session-initiate' to the remote peer.\n *\n * NOTE this method is synchronous and we're not waiting for the RESULT\n * response which would delay the startup process.\n *\n * @param {string} offerSdp - The local session description which will be\n * used to generate an offer.\n * @private\n */\n sendSessionInitiate(offerSdp) {\n let init = $iq({\n to: this.remoteJid,\n type: 'set'\n }).c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'session-initiate',\n initiator: this.initiatorJid,\n sid: this.sid\n });\n\n new SDP(offerSdp).toJingle(\n init,\n this.isInitiator ? 'initiator' : 'responder');\n init = init.tree();\n logger.info('Session-initiate: ', init);\n this.connection.sendIQ(init,\n () => {\n logger.info('Got RESULT for \"session-initiate\"');\n },\n error => {\n logger.error('\"session-initiate\" error', error);\n },\n IQ_TIMEOUT);\n }\n\n /**\n * Sets the answer received from the remote peer.\n * @param jingleAnswer\n */\n setAnswer(jingleAnswer) {\n if (!this.isInitiator) {\n throw new Error('Trying to set an answer on the responder session');\n }\n this.setOfferAnswerCycle(\n jingleAnswer,\n () => {\n logger.info('setAnswer - succeeded');\n },\n error => {\n logger.error('setAnswer failed: ', error);\n });\n }\n\n /* eslint-disable max-params */\n /**\n * This is a setRemoteDescription/setLocalDescription cycle which starts at\n * converting Strophe Jingle IQ into remote offer SDP. Once converted\n * setRemoteDescription, createAnswer and setLocalDescription calls follow.\n * @param jingleOfferAnswerIq jQuery selector pointing to the jingle element\n * of the offer (or answer) IQ\n * @param success callback called when sRD/sLD cycle finishes successfully.\n * @param failure callback called with an error object as an argument if we\n * fail at any point during setRD, createAnswer, setLD.\n * @param {Array} [localTracks] the optional list of\n * the local tracks that will be added, before the offer/answer cycle\n * executes (for the local track addition to be an atomic operation together\n * with the offer/answer).\n */\n setOfferAnswerCycle(jingleOfferAnswerIq, success, failure, localTracks) {\n const workFunction = finishedCallback => {\n\n if (localTracks) {\n for (const track of localTracks) {\n this.peerconnection.addTrack(track);\n }\n }\n\n const newRemoteSdp\n = this._processNewJingleOfferIq(jingleOfferAnswerIq);\n const oldLocalSdp\n = this.peerconnection.localDescription.sdp;\n\n const bridgeSession\n = $(jingleOfferAnswerIq)\n .find('>bridge-session['\n + 'xmlns=\"http://jitsi.org/protocol/focus\"]');\n const bridgeSessionId = bridgeSession.attr('id');\n\n if (bridgeSessionId !== this._bridgeSessionId) {\n this._bridgeSessionId = bridgeSessionId;\n }\n\n this._renegotiate(newRemoteSdp.raw)\n .then(() => {\n if (this.state === JingleSessionState.PENDING) {\n this.state = JingleSessionState.ACTIVE;\n\n // Sync up video transfer active/inactive only after\n // the initial O/A cycle. We want to adjust the video\n // media direction only in the local SDP and the Jingle\n // contents direction included in the initial\n // offer/answer is mapped to the remote SDP. Jingle\n // 'content-modify' IQ is processed in a way that it\n // will only modify local SDP when remote peer is no\n // longer interested in receiving video content.\n // Changing media direction in the remote SDP will mess\n // up our SDP translation chain (simulcast, video mute,\n // RTX etc.)\n if (this.isP2P && !this._localVideoActive) {\n this.sendContentModify(this._localVideoActive);\n }\n }\n\n // Old local SDP will be available when we're setting answer\n // for the first time, but not when offer and it's fine\n // since we're generating an answer now it will contain all\n // our SSRCs\n if (oldLocalSdp) {\n const newLocalSdp\n = new SDP(this.peerconnection.localDescription.sdp);\n\n this.notifyMySSRCUpdate(\n new SDP(oldLocalSdp), newLocalSdp);\n }\n\n finishedCallback();\n }, error => {\n logger.error(\n `Error renegotiating after setting new remote ${\n this.isInitiator ? 'answer: ' : 'offer: '}${error}`,\n newRemoteSdp);\n\n finishedCallback(error);\n });\n };\n\n this.modificationQueue.push(\n workFunction,\n error => {\n error ? failure(error) : success();\n });\n }\n\n /* eslint-enable max-params */\n\n /**\n * Although it states \"replace transport\" it does accept full Jingle offer\n * which should contain new ICE transport details.\n * @param jingleOfferElem an element Jingle IQ that contains new offer and\n * transport info.\n * @param success callback called when we succeed to accept new offer.\n * @param failure function(error) called when we fail to accept new offer.\n */\n replaceTransport(jingleOfferElem, success, failure) {\n this.room.eventEmitter.emit(XMPPEvents.ICE_RESTARTING, this);\n\n // We need to first reject the 'data' section to have the SCTP stack\n // cleaned up to signal the known data channel is now invalid. After\n // that the original offer is set to have the SCTP connection\n // established with the new bridge.\n const originalOffer = jingleOfferElem.clone();\n\n jingleOfferElem\n .find('>content[name=\\'data\\']')\n .attr('senders', 'rejected');\n\n // Remove all remote sources in order to reset the client's state\n // for the remote MediaStreams. When a conference is moved to\n // another bridge it will start streaming with a sequence number\n // that is not in sync with the most recently seen by the client.\n // The symptoms include frozen or black video and lots of \"failed to\n // unprotect SRTP packets\" in Chrome logs.\n jingleOfferElem\n .find('>content>description>source')\n .remove();\n jingleOfferElem\n .find('>content>description>ssrc-group')\n .remove();\n\n // On the JVB it's not a real ICE restart and all layers are re-initialized from scratch as Jicofo does\n // the restart by re-allocating new channels. Chrome (or WebRTC stack) needs to have the DTLS transport layer\n // reset to start a new handshake with fresh DTLS transport on the bridge. Make it think that the DTLS\n // fingerprint has changed by setting an all zeros key.\n const newFingerprint = jingleOfferElem.find('>content>transport>fingerprint');\n\n newFingerprint.attr('hash', 'sha-1');\n newFingerprint.text('00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00');\n\n // First set an offer with a rejected 'data' section\n this.setOfferAnswerCycle(\n jingleOfferElem,\n () => {\n // Now set the original offer(with the 'data' section)\n this.setOfferAnswerCycle(\n originalOffer,\n () => {\n const localSDP\n = new SDP(this.peerconnection.localDescription.sdp);\n\n this.sendTransportAccept(localSDP, success, failure);\n\n this.room.eventEmitter.emit(\n XMPPEvents.ICE_RESTART_SUCCESS,\n this,\n originalOffer);\n },\n failure);\n },\n failure\n );\n }\n\n /**\n * Sends Jingle 'session-accept' message.\n * @param {function()} success callback called when we receive 'RESULT'\n * packet for the 'session-accept'\n * @param {function(error)} failure called when we receive an error response\n * or when the request has timed out.\n * @private\n */\n sendSessionAccept(success, failure) {\n // NOTE: since we're just reading from it, we don't need to be within\n // the modification queue to access the local description\n const localSDP = new SDP(this.peerconnection.localDescription.sdp);\n let accept = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', { xmlns: 'urn:xmpp:jingle:1',\n action: 'session-accept',\n initiator: this.initiatorJid,\n responder: this.responderJid,\n sid: this.sid });\n\n if (this.webrtcIceTcpDisable) {\n localSDP.removeTcpCandidates = true;\n }\n if (this.webrtcIceUdpDisable) {\n localSDP.removeUdpCandidates = true;\n }\n if (this.failICE) {\n localSDP.failICE = true;\n }\n localSDP.toJingle(\n accept,\n this.initiatorJid === this.localJid ? 'initiator' : 'responder',\n null);\n\n // Calling tree() to print something useful\n accept = accept.tree();\n logger.info('Sending session-accept', accept);\n this.connection.sendIQ(accept,\n success,\n this.newJingleErrorHandler(accept, error => {\n failure(error);\n\n // 'session-accept' is a critical timeout and we'll\n // have to restart\n this.room.eventEmitter.emit(\n XMPPEvents.SESSION_ACCEPT_TIMEOUT, this);\n }),\n IQ_TIMEOUT);\n\n // XXX Videobridge needs WebRTC's answer (ICE ufrag and pwd, DTLS\n // fingerprint and setup) ASAP in order to start the connection\n // establishment.\n //\n // FIXME Flushing the connection at this point triggers an issue with\n // BOSH request handling in Prosody on slow connections.\n //\n // The problem is that this request will be quite large and it may take\n // time before it reaches Prosody. In the meantime Strophe may decide\n // to send the next one. And it was observed that a small request with\n // 'transport-info' usually follows this one. It does reach Prosody\n // before the previous one was completely received. 'rid' on the server\n // is increased and Prosody ignores the request with 'session-accept'.\n // It will never reach Jicofo and everything in the request table is\n // lost. Removing the flush does not guarantee it will never happen, but\n // makes it much less likely('transport-info' is bundled with\n // 'session-accept' and any immediate requests).\n //\n // this.connection.flush();\n }\n\n /**\n * Will send 'content-modify' IQ in order to ask the remote peer to\n * either stop or resume sending video media.\n * @param {boolean} videoTransferActive false to let the other peer\n * know that we're not sending nor interested in receiving video contents.\n * When set to true remote peer will be asked to resume video\n * transfer.\n * @private\n */\n sendContentModify(videoTransferActive) {\n const newSendersValue = videoTransferActive ? 'both' : 'none';\n\n const sessionModify\n = $iq({\n to: this.remoteJid,\n type: 'set'\n })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'content-modify',\n initiator: this.initiatorJid,\n sid: this.sid\n })\n .c('content', {\n name: 'video',\n senders: newSendersValue\n });\n\n logger.info(\n `Sending content-modify, video senders: ${newSendersValue}`);\n\n this.connection.sendIQ(\n sessionModify,\n null,\n this.newJingleErrorHandler(sessionModify),\n IQ_TIMEOUT);\n }\n\n /**\n * Sends Jingle 'transport-accept' message which is a response to\n * 'transport-replace'.\n * @param localSDP the 'SDP' object with local session description\n * @param success callback called when we receive 'RESULT' packet for\n * 'transport-replace'\n * @param failure function(error) called when we receive an error response\n * or when the request has timed out.\n * @private\n */\n sendTransportAccept(localSDP, success, failure) {\n let transportAccept = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'transport-accept',\n initiator: this.initiatorJid,\n sid: this.sid\n });\n\n localSDP.media.forEach((medialines, idx) => {\n const mline = SDPUtil.parseMLine(medialines.split('\\r\\n')[0]);\n\n transportAccept.c('content',\n {\n creator:\n this.initiatorJid === this.localJid\n ? 'initiator'\n : 'responder',\n name: mline.media\n }\n );\n localSDP.transportToJingle(idx, transportAccept);\n transportAccept.up();\n });\n\n // Calling tree() to print something useful to the logger\n transportAccept = transportAccept.tree();\n logger.info('Sending transport-accept: ', transportAccept);\n\n this.connection.sendIQ(transportAccept,\n success,\n this.newJingleErrorHandler(transportAccept, failure),\n IQ_TIMEOUT);\n }\n\n /**\n * Sends Jingle 'transport-reject' message which is a response to\n * 'transport-replace'.\n * @param success callback called when we receive 'RESULT' packet for\n * 'transport-replace'\n * @param failure function(error) called when we receive an error response\n * or when the request has timed out.\n *\n * FIXME method should be marked as private, but there's some spaghetti that\n * needs to be fixed prior doing that\n */\n sendTransportReject(success, failure) {\n // Send 'transport-reject', so that the focus will\n // know that we've failed\n let transportReject = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'transport-reject',\n initiator: this.initiatorJid,\n sid: this.sid\n });\n\n transportReject = transportReject.tree();\n logger.info('Sending \\'transport-reject', transportReject);\n\n this.connection.sendIQ(transportReject,\n success,\n this.newJingleErrorHandler(transportReject, failure),\n IQ_TIMEOUT);\n }\n\n /**\n * @inheritDoc\n */\n terminate(success, failure, options) {\n if (this.state === JingleSessionState.ENDED) {\n return;\n }\n\n if (!options || Boolean(options.sendSessionTerminate)) {\n let sessionTerminate\n = $iq({\n to: this.remoteJid,\n type: 'set'\n })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'session-terminate',\n initiator: this.initiatorJid,\n sid: this.sid\n })\n .c('reason')\n .c((options && options.reason) || 'success');\n\n if (options && options.reasonDescription) {\n sessionTerminate.up()\n .c('text')\n .t(options.reasonDescription);\n }\n\n // Calling tree() to print something useful\n sessionTerminate = sessionTerminate.tree();\n logger.info('Sending session-terminate', sessionTerminate);\n this.connection.sendIQ(\n sessionTerminate,\n success,\n this.newJingleErrorHandler(sessionTerminate, failure),\n IQ_TIMEOUT);\n } else {\n logger.info(`Skipped sending session-terminate for ${this}`);\n }\n\n // this should result in 'onTerminated' being called by strope.jingle.js\n this.connection.jingle.terminate(this.sid);\n }\n\n /**\n *\n * @param reasonCondition\n * @param reasonText\n */\n onTerminated(reasonCondition, reasonText) {\n // Do something with reason and reasonCondition when we start to care\n // this.reasonCondition = reasonCondition;\n // this.reasonText = reasonText;\n logger.info(`Session terminated ${this}`, reasonCondition, reasonText);\n\n this._xmppListeners.forEach(removeListener => removeListener());\n this._xmppListeners = [];\n\n this.close();\n }\n\n /**\n * Handles XMPP connection state changes.\n *\n * @param {XmppConnection.Status} status - The new status.\n */\n onXmppStatusChanged(status) {\n if (status === XmppConnection.Status.CONNECTED && this._cachedOldLocalSdp) {\n logger.info('Sending SSRC update on reconnect');\n this.notifyMySSRCUpdate(\n this._cachedOldLocalSdp,\n this._cachedNewLocalSdp);\n }\n }\n\n /**\n * Parse the information from the xml sourceAddElem and translate it\n * into sdp lines\n * @param {jquery xml element} sourceAddElem the source-add\n * element from jingle\n * @param {SDP object} currentRemoteSdp the current remote\n * sdp (as of this new source-add)\n * @returns {list} a list of SDP line strings that should\n * be added to the remote SDP\n */\n _parseSsrcInfoFromSourceAdd(sourceAddElem, currentRemoteSdp) {\n const addSsrcInfo = [];\n\n $(sourceAddElem).each((i1, content) => {\n const name = $(content).attr('name');\n let lines = '';\n\n $(content)\n .find('ssrc-group[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]')\n .each(function() {\n // eslint-disable-next-line no-invalid-this\n const semantics = this.getAttribute('semantics');\n const ssrcs\n = $(this) // eslint-disable-line no-invalid-this\n .find('>source')\n .map(function() {\n // eslint-disable-next-line no-invalid-this\n return this.getAttribute('ssrc');\n })\n .get();\n\n if (ssrcs.length) {\n lines\n += `a=ssrc-group:${semantics} ${\n ssrcs.join(' ')}\\r\\n`;\n }\n });\n\n // handles both >source and >description>source\n const tmp\n = $(content).find(\n 'source[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]');\n\n /* eslint-disable no-invalid-this */\n tmp.each(function() {\n const ssrc = $(this).attr('ssrc');\n\n if (currentRemoteSdp.containsSSRC(ssrc)) {\n logger.warn(\n `Source-add request for existing SSRC: ${ssrc}`);\n\n return;\n }\n\n // eslint-disable-next-line newline-per-chained-call\n $(this).find('>parameter').each(function() {\n lines += `a=ssrc:${ssrc} ${$(this).attr('name')}`;\n if ($(this).attr('value') && $(this).attr('value').length) {\n lines += `:${$(this).attr('value')}`;\n }\n lines += '\\r\\n';\n });\n });\n\n /* eslint-enable no-invalid-this */\n currentRemoteSdp.media.forEach((media, i2) => {\n if (!SDPUtil.findLine(media, `a=mid:${name}`)) {\n return;\n }\n if (!addSsrcInfo[i2]) {\n addSsrcInfo[i2] = '';\n }\n addSsrcInfo[i2] += lines;\n });\n });\n\n return addSsrcInfo;\n }\n\n /**\n * Handles a Jingle source-add message for this Jingle session.\n * @param elem An array of Jingle \"content\" elements.\n */\n addRemoteStream(elem) {\n this._addOrRemoveRemoteStream(true /* add */, elem);\n }\n\n /**\n * Handles a Jingle source-remove message for this Jingle session.\n * @param elem An array of Jingle \"content\" elements.\n */\n removeRemoteStream(elem) {\n this._addOrRemoveRemoteStream(false /* remove */, elem);\n }\n\n /**\n * Handles either Jingle 'source-add' or 'source-remove' message for this\n * Jingle session.\n * @param {boolean} isAdd true for 'source-add' or false\n * otherwise.\n * @param {Array} elem an array of Jingle \"content\" elements.\n * @private\n */\n _addOrRemoveRemoteStream(isAdd, elem) {\n const logPrefix = isAdd ? 'addRemoteStream' : 'removeRemoteStream';\n\n if (isAdd) {\n this.readSsrcInfo(elem);\n }\n\n const workFunction = finishedCallback => {\n if (!this.peerconnection.localDescription\n || !this.peerconnection.localDescription.sdp) {\n const errMsg = `${logPrefix} - localDescription not ready yet`;\n\n logger.error(errMsg);\n finishedCallback(errMsg);\n\n return;\n }\n\n logger.log(`Processing ${logPrefix}`);\n logger.log(\n 'ICE connection state: ',\n this.peerconnection.iceConnectionState);\n\n const oldLocalSdp\n = new SDP(this.peerconnection.localDescription.sdp);\n const sdp = new SDP(this.peerconnection.remoteDescription.sdp);\n const addOrRemoveSsrcInfo\n = isAdd\n ? this._parseSsrcInfoFromSourceAdd(elem, sdp)\n : this._parseSsrcInfoFromSourceRemove(elem, sdp);\n const newRemoteSdp\n = isAdd\n ? this._processRemoteAddSource(addOrRemoveSsrcInfo)\n : this._processRemoteRemoveSource(addOrRemoveSsrcInfo);\n\n this._renegotiate(newRemoteSdp.raw)\n .then(() => {\n const newLocalSdp\n = new SDP(this.peerconnection.localDescription.sdp);\n\n logger.log(\n `${logPrefix} - OK, SDPs: `, oldLocalSdp, newLocalSdp);\n this.notifyMySSRCUpdate(oldLocalSdp, newLocalSdp);\n finishedCallback();\n }, error => {\n logger.error(`${logPrefix} failed:`, error);\n finishedCallback(error);\n });\n };\n\n // Queue and execute\n this.modificationQueue.push(workFunction);\n }\n\n /**\n * Takes in a jingle offer iq, returns the new sdp offer\n * @param {jquery xml element} offerIq the incoming offer\n * @returns {SDP object} the jingle offer translated to SDP\n */\n _processNewJingleOfferIq(offerIq) {\n const remoteSdp = new SDP('');\n\n if (this.webrtcIceTcpDisable) {\n remoteSdp.removeTcpCandidates = true;\n }\n if (this.webrtcIceUdpDisable) {\n remoteSdp.removeUdpCandidates = true;\n }\n if (this.failICE) {\n remoteSdp.failICE = true;\n }\n\n remoteSdp.fromJingle(offerIq);\n this.readSsrcInfo($(offerIq).find('>content'));\n\n return remoteSdp;\n }\n\n /**\n * Remove the given ssrc lines from the current remote sdp\n * @param {list} removeSsrcInfo a list of SDP line strings that\n * should be removed from the remote SDP\n * @returns type {SDP Object} the new remote SDP (after removing the lines\n * in removeSsrcInfo\n */\n _processRemoteRemoveSource(removeSsrcInfo) {\n const remoteSdp = browser.usesPlanB()\n ? new SDP(this.peerconnection.remoteDescription.sdp)\n : new SDP(this.peerconnection.peerconnection.remoteDescription.sdp);\n\n removeSsrcInfo.forEach((lines, idx) => {\n // eslint-disable-next-line no-param-reassign\n lines = lines.split('\\r\\n');\n lines.pop(); // remove empty last element;\n if (browser.usesPlanB()) {\n lines.forEach(line => {\n remoteSdp.media[idx]\n = remoteSdp.media[idx].replace(`${line}\\r\\n`, '');\n });\n } else {\n lines.forEach(line => {\n const mid = remoteSdp.media.findIndex(mLine => mLine.includes(line));\n\n if (mid > -1) {\n remoteSdp.media[mid] = remoteSdp.media[mid].replace(`${line}\\r\\n`, '');\n\n // Change the direction to \"inactive\".\n remoteSdp.media[mid] = remoteSdp.media[mid].replace('a=sendonly', 'a=inactive');\n }\n });\n }\n });\n remoteSdp.raw = remoteSdp.session + remoteSdp.media.join('');\n\n return remoteSdp;\n }\n\n /**\n * Add the given ssrc lines to the current remote sdp\n * @param {list} addSsrcInfo a list of SDP line strings that\n * should be added to the remote SDP\n * @returns type {SDP Object} the new remote SDP (after removing the lines\n * in removeSsrcInfo\n */\n _processRemoteAddSource(addSsrcInfo) {\n const remoteSdp = new SDP(this.peerconnection.remoteDescription.sdp);\n\n addSsrcInfo.forEach((lines, idx) => {\n remoteSdp.media[idx] += lines;\n });\n remoteSdp.raw = remoteSdp.session + remoteSdp.media.join('');\n\n return remoteSdp;\n }\n\n /**\n * Do a new o/a flow using the existing remote description\n * @param {string} [optionalRemoteSdp] optional, raw remote sdp\n * to use. If not provided, the remote sdp from the\n * peerconnection will be used\n * @returns {Promise} promise which resolves when the\n * o/a flow is complete with no arguments or\n * rejects with an error {string}\n */\n _renegotiate(optionalRemoteSdp) {\n if (this.peerconnection.signalingState === 'closed') {\n const error = new Error('Attempted to renegotiate in state closed');\n\n this.room.eventEmitter.emit(XMPPEvents.RENEGOTIATION_FAILED, error, this);\n\n return Promise.reject(error);\n }\n\n const remoteSdp\n = optionalRemoteSdp || this.peerconnection.remoteDescription.sdp;\n\n if (!remoteSdp) {\n const error = new Error(`Can not renegotiate without remote description, current state: ${this.state}`);\n\n this.room.eventEmitter.emit(XMPPEvents.RENEGOTIATION_FAILED, error, this);\n\n return Promise.reject(error);\n }\n\n const remoteDescription = new RTCSessionDescription({\n type: this.isInitiator ? 'answer' : 'offer',\n sdp: remoteSdp\n });\n\n if (this.isInitiator) {\n return this._initiatorRenegotiate(remoteDescription);\n }\n\n return this._responderRenegotiate(remoteDescription);\n }\n\n /**\n * Renegotiate cycle implementation for the responder case.\n * @param {object} remoteDescription the SDP object as defined by the WebRTC\n * which will be used as remote description in the cycle.\n * @private\n */\n _responderRenegotiate(remoteDescription) {\n logger.debug('Renegotiate: setting remote description');\n\n return this.peerconnection.setRemoteDescription(remoteDescription)\n .then(() => {\n logger.debug('Renegotiate: creating answer');\n\n return this.peerconnection.createAnswer(this.mediaConstraints)\n .then(answer => {\n logger.debug('Renegotiate: setting local description');\n\n return this.peerconnection.setLocalDescription(answer);\n });\n });\n }\n\n /**\n * Renegotiate cycle implementation for the initiator's case.\n * @param {object} remoteDescription the SDP object as defined by the WebRTC\n * which will be used as remote description in the cycle.\n * @private\n */\n _initiatorRenegotiate(remoteDescription) {\n logger.debug('Renegotiate: creating offer');\n\n return this.peerconnection.createOffer(this.mediaConstraints)\n .then(offer => {\n logger.debug('Renegotiate: setting local description');\n\n return this.peerconnection.setLocalDescription(offer)\n .then(() => {\n logger.debug(\n 'Renegotiate: setting remote description');\n\n // eslint-disable-next-line max-len\n return this.peerconnection.setRemoteDescription(remoteDescription);\n });\n });\n }\n\n /**\n * Replaces oldTrack with newTrack and performs a single\n * offer/answer cycle after both operations are done. Either\n * oldTrack or newTrack can be null; replacing a valid\n * oldTrack with a null newTrack effectively just removes\n * oldTrack\n * @param {JitsiLocalTrack|null} oldTrack the current track in use to be\n * replaced\n * @param {JitsiLocalTrack|null} newTrack the new track to use\n * @returns {Promise} which resolves once the replacement is complete\n * with no arguments or rejects with an error {string}\n */\n replaceTrack(oldTrack, newTrack) {\n const workFunction = finishedCallback => {\n const oldLocalSdp = this.peerconnection.localDescription.sdp;\n\n if (browser.usesPlanB()) {\n // NOTE the code below assumes that no more than 1 video track\n // can be added to the peer connection.\n // Transition from camera to desktop share\n // or transition from one camera source to another.\n if (this.peerconnection.options.capScreenshareBitrate\n && oldTrack && newTrack && newTrack.isVideoTrack()) {\n // Clearing current primary SSRC will make\n // the SdpConsistency generate a new one which will result\n // with:\n // 1. source-remove for the old video stream.\n // 2. source-add for the new video stream.\n this.peerconnection.clearRecvonlySsrc();\n }\n\n // Transition from no video to video (unmute).\n if (!oldTrack && newTrack && newTrack.isVideoTrack()) {\n // Clearing current primary SSRC will make\n // the SdpConsistency generate a new one which will result\n // with:\n // 1. source-remove for the recvonly\n // 2. source-add for the new video stream\n this.peerconnection.clearRecvonlySsrc();\n\n // Transition from video to no video\n } else if (oldTrack && oldTrack.isVideoTrack() && !newTrack) {\n // Clearing current primary SSRC and generating the recvonly\n // will result in:\n // 1. source-remove for the old video stream\n // 2. source-add for the recvonly stream\n this.peerconnection.clearRecvonlySsrc();\n this.peerconnection.generateRecvonlySsrc();\n }\n }\n\n this.peerconnection.replaceTrack(oldTrack, newTrack)\n .then(shouldRenegotiate => {\n let promise = Promise.resolve();\n\n if (shouldRenegotiate\n && (oldTrack || newTrack)\n && this.state === JingleSessionState.ACTIVE) {\n promise = this._renegotiate().then(() => {\n const newLocalSDP = new SDP(this.peerconnection.localDescription.sdp);\n\n this.notifyMySSRCUpdate(new SDP(oldLocalSdp), newLocalSDP);\n },\n finishedCallback /* will be called with en error */);\n }\n\n // Wait for the renegotation to be done if needed (plan-b) before adjusting\n // the max bitrates on the video sender.\n promise.then(() => {\n // configure max bitrate only when media is routed\n // through JVB. For p2p case, browser takes care of\n // adjusting the uplink based on the feedback it\n // gets from the peer.\n if (newTrack && !this.isP2P) {\n this.peerconnection.setMaxBitRate(newTrack);\n }\n finishedCallback();\n }, finishedCallback /* will be called with en error */);\n })\n .catch(err => {\n finishedCallback(err);\n });\n };\n\n return new Promise((resolve, reject) => {\n this.modificationQueue.push(\n workFunction,\n error => {\n if (error) {\n logger.error('Replace track error:', error);\n reject(error);\n } else {\n logger.info('Replace track done!');\n resolve();\n }\n });\n });\n }\n\n /**\n * Parse the information from the xml sourceRemoveElem and translate it\n * into sdp lines\n * @param {jquery xml element} sourceRemoveElem the source-remove\n * element from jingle\n * @param {SDP object} currentRemoteSdp the current remote\n * sdp (as of this new source-remove)\n * @returns {list} a list of SDP line strings that should\n * be removed from the remote SDP\n */\n _parseSsrcInfoFromSourceRemove(sourceRemoveElem, currentRemoteSdp) {\n const removeSsrcInfo = [];\n\n $(sourceRemoveElem).each((i1, content) => {\n const name = $(content).attr('name');\n let lines = '';\n\n $(content)\n .find('ssrc-group[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]')\n .each(function() {\n /* eslint-disable no-invalid-this */\n const semantics = this.getAttribute('semantics');\n const ssrcs\n = $(this)\n .find('>source')\n .map(function() {\n return this.getAttribute('ssrc');\n })\n .get();\n\n if (ssrcs.length) {\n lines\n += `a=ssrc-group:${semantics} ${\n ssrcs.join(' ')}\\r\\n`;\n }\n\n /* eslint-enable no-invalid-this */\n });\n const ssrcs = [];\n\n // handles both >source and >description>source versions\n const tmp\n = $(content).find(\n 'source[xmlns=\"urn:xmpp:jingle:apps:rtp:ssma:0\"]');\n\n tmp.each(function() {\n // eslint-disable-next-line no-invalid-this\n const ssrc = $(this).attr('ssrc');\n\n ssrcs.push(ssrc);\n });\n currentRemoteSdp.media.forEach((media, i2) => {\n if (!SDPUtil.findLine(media, `a=mid:${name}`)) {\n return;\n }\n if (!removeSsrcInfo[i2]) {\n removeSsrcInfo[i2] = '';\n }\n ssrcs.forEach(ssrc => {\n const ssrcLines\n = SDPUtil.findLines(media, `a=ssrc:${ssrc}`);\n\n if (ssrcLines.length) {\n removeSsrcInfo[i2] += `${ssrcLines.join('\\r\\n')}\\r\\n`;\n }\n });\n removeSsrcInfo[i2] += lines;\n });\n });\n\n return removeSsrcInfo;\n }\n\n /**\n * Will print an error if there is any difference, between the SSRCs given\n * in the oldSDP and the ones currently described in\n * the peerconnection's local description.\n * @param {string} operationName the operation's name which will be printed\n * in the error message.\n * @param {SDP} oldSDP the old local SDP which will be compared with\n * the current one.\n * @return {boolean} true if there was any change or false\n * otherwise.\n * @private\n */\n _verifyNoSSRCChanged(operationName, oldSDP) {\n const currentLocalSDP\n = new SDP(this.peerconnection.localDescription.sdp);\n let sdpDiff = new SDPDiffer(oldSDP, currentLocalSDP);\n const addedMedia = sdpDiff.getNewMedia();\n\n if (Object.keys(addedMedia).length) {\n logger.error(\n `${this} - some SSRC were added on ${operationName}`,\n addedMedia);\n\n return false;\n }\n\n sdpDiff = new SDPDiffer(currentLocalSDP, oldSDP);\n const removedMedia = sdpDiff.getNewMedia();\n\n if (Object.keys(removedMedia).length) {\n logger.error(\n `${this} - some SSRCs were removed on ${operationName}`,\n removedMedia);\n\n return false;\n }\n\n return true;\n }\n\n /**\n * Adds local track back to this session, as part of the unmute operation.\n * @param {JitsiLocalTrack} track\n * @return {Promise} a promise that will resolve once the local track is\n * added back to this session and renegotiation succeeds. Will be rejected\n * with a string that provides some error details in case something\n * goes wrong.\n */\n addTrackAsUnmute(track) {\n return this._addRemoveTrackAsMuteUnmute(\n false /* add as unmute */, track);\n }\n\n /**\n * Remove local track as part of the mute operation.\n * @param {JitsiLocalTrack} track the local track to be removed\n * @return {Promise} a promise which will be resolved once the local track\n * is removed from this session and the renegotiation is performed.\n * The promise will be rejected with a string that the describes\n * the error if anything goes wrong.\n */\n removeTrackAsMute(track) {\n return this._addRemoveTrackAsMuteUnmute(\n true /* remove as mute */, track);\n }\n\n /**\n * See {@link addTrackAsUnmute} and {@link removeTrackAsMute}.\n * @param {boolean} isMute true for \"remove as mute\" or\n * false for \"add as unmute\".\n * @param {JitsiLocalTrack} track the track that will be added/removed\n * @private\n */\n _addRemoveTrackAsMuteUnmute(isMute, track) {\n if (!track) {\n return Promise.reject('invalid \"track\" argument value');\n }\n const operationName = isMute ? 'removeTrackMute' : 'addTrackUnmute';\n const workFunction = finishedCallback => {\n const tpc = this.peerconnection;\n\n if (!tpc) {\n finishedCallback(\n `Error: tried ${operationName} track with no active peer`\n + 'connection');\n\n return;\n }\n const oldLocalSDP = tpc.localDescription.sdp;\n const operationPromise\n = isMute\n ? tpc.removeTrackMute(track)\n : tpc.addTrackUnmute(track);\n\n operationPromise\n .then(shouldRenegotiate => {\n if (shouldRenegotiate && oldLocalSDP && tpc.remoteDescription.sdp) {\n this._renegotiate()\n .then(() => {\n // The results are ignored, as this check failure is not\n // enough to fail the whole operation. It will log\n // an error inside.\n this._verifyNoSSRCChanged(\n operationName, new SDP(oldLocalSDP));\n finishedCallback();\n });\n } else {\n finishedCallback();\n }\n },\n finishedCallback /* will be called with an error */);\n };\n\n return new Promise((resolve, reject) => {\n this.modificationQueue.push(\n workFunction,\n error => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n\n /**\n * Resumes or suspends media transfer over the underlying peer connection.\n * @param {boolean} audioActive true to enable audio media\n * transfer or false to suspend audio media transmission.\n * @param {boolean} videoActive true to enable video media\n * transfer or false to suspend video media transmission.\n * @return {Promise} a Promise which will resolve once\n * the operation is done. It will be rejected with an error description as\n * a string in case anything goes wrong.\n */\n setMediaTransferActive(audioActive, videoActive) {\n if (!this.peerconnection) {\n return Promise.reject(\n 'Can not modify transfer active state,'\n + ' before \"initialize\" is called');\n }\n\n const logAudioStr = audioActive ? 'audio active' : 'audio inactive';\n const logVideoStr = videoActive ? 'video active' : 'video inactive';\n\n logger.info(`Queued make ${logVideoStr}, ${logAudioStr} task...`);\n\n const workFunction = finishedCallback => {\n const isSessionActive = this.state === JingleSessionState.ACTIVE;\n\n // Because the value is modified on the queue it's impossible to\n // check it's final value reliably prior to submitting the task.\n // The rule here is that the last submitted state counts.\n // Check the values here to avoid unnecessary renegotiation cycle.\n const audioActiveChanged\n = this.peerconnection.setAudioTransferActive(audioActive);\n\n if (this._localVideoActive !== videoActive) {\n this._localVideoActive = videoActive;\n\n // Do only for P2P - Jicofo will reply with 'bad-request'\n // We don't want to send 'content-modify', before the initial\n // O/A (state === JingleSessionState.ACTIVE), because that will\n // mess up video media direction in the remote SDP.\n // 'content-modify' when processed only affects the media\n // direction in the local SDP. We're doing that, because setting\n // 'inactive' on video media in remote SDP will mess up our SDP\n // translation chain (simulcast, RTX, video mute etc.).\n if (this.isP2P && isSessionActive) {\n this.sendContentModify(videoActive);\n }\n }\n\n const pcVideoActiveChanged\n = this.peerconnection.setVideoTransferActive(\n this._localVideoActive && this._remoteVideoActive);\n\n // Will do the sRD/sLD cycle to update SDPs and adjust the media\n // direction\n if (isSessionActive\n && (audioActiveChanged || pcVideoActiveChanged)) {\n this._renegotiate()\n .then(\n finishedCallback,\n finishedCallback /* will be called with an error */);\n } else {\n finishedCallback();\n }\n };\n\n return new Promise((resolve, reject) => {\n this.modificationQueue.push(\n workFunction,\n error => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n\n /**\n * Will put and execute on the queue a session modify task. Currently it\n * only checks the senders attribute of the video content in order to figure\n * out if the remote peer has video in the inactive state (stored locally\n * in {@link _remoteVideoActive} - see field description for more info).\n * @param {jQuery} jingleContents jQuery selector pointing to the jingle\n * element of the session modify IQ.\n * @see {@link _remoteVideoActive}\n * @see {@link _localVideoActive}\n */\n modifyContents(jingleContents) {\n const newVideoSenders\n = JingleSessionPC.parseVideoSenders(jingleContents);\n\n if (newVideoSenders === null) {\n logger.error(\n `${this} - failed to parse video \"senders\" attribute in`\n + '\"content-modify\" action');\n\n return;\n }\n\n const workFunction = finishedCallback => {\n if (this._assertNotEnded('content-modify')\n && this._modifyRemoteVideoActive(newVideoSenders)) {\n // Will do the sRD/sLD cycle to update SDPs and adjust\n // the media direction\n this._renegotiate()\n .then(finishedCallback, finishedCallback /* (error) */);\n } else {\n finishedCallback();\n }\n };\n\n logger.debug(\n `${this} queued \"content-modify\" task`\n + `(video senders=\"${newVideoSenders}\")`);\n\n this.modificationQueue.push(\n workFunction,\n error => {\n if (error) {\n logger.error('\"content-modify\" failed', error);\n }\n });\n }\n\n /**\n * Processes new value of remote video \"senders\" Jingle attribute and tries\n * to apply it for {@link _remoteVideoActive}.\n * @param {string} remoteVideoSenders the value of \"senders\" attribute of\n * Jingle video content element advertised by remote peer.\n * @return {boolean} true if the change affected state of\n * the underlying peerconnection and renegotiation is required for\n * the changes to take effect.\n * @private\n */\n _modifyRemoteVideoActive(remoteVideoSenders) {\n const isRemoteVideoActive\n = remoteVideoSenders === 'both'\n || (remoteVideoSenders === 'initiator' && this.isInitiator)\n || (remoteVideoSenders === 'responder' && !this.isInitiator);\n\n if (isRemoteVideoActive !== this._remoteVideoActive) {\n logger.debug(\n `${this} new remote video active: ${isRemoteVideoActive}`);\n this._remoteVideoActive = isRemoteVideoActive;\n }\n\n return this.peerconnection.setVideoTransferActive(\n this._localVideoActive && this._remoteVideoActive);\n }\n\n /**\n * Figures out added/removed ssrcs and send update IQs.\n * @param oldSDP SDP object for old description.\n * @param newSDP SDP object for new description.\n */\n notifyMySSRCUpdate(oldSDP, newSDP) {\n\n if (this.state !== JingleSessionState.ACTIVE) {\n logger.warn(`Skipping SSRC update in '${this.state} ' state.`);\n\n return;\n }\n\n if (!this.connection.connected) {\n // The goal is to compare the oldest SDP with the latest one upon reconnect\n if (!this._cachedOldLocalSdp) {\n this._cachedOldLocalSdp = oldSDP;\n }\n this._cachedNewLocalSdp = newSDP;\n logger.warn('Not sending SSRC update while the signaling is disconnected');\n\n return;\n }\n\n this._cachedOldLocalSdp = undefined;\n this._cachedNewLocalSdp = undefined;\n\n // send source-remove IQ.\n let sdpDiffer = new SDPDiffer(newSDP, oldSDP);\n const remove = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'source-remove',\n initiator: this.initiatorJid,\n sid: this.sid\n }\n );\n const removedAnySSRCs = sdpDiffer.toJingle(remove);\n\n if (removedAnySSRCs) {\n logger.info('Sending source-remove', remove.tree());\n this.connection.sendIQ(\n remove, null,\n this.newJingleErrorHandler(remove), IQ_TIMEOUT);\n } else {\n logger.log('removal not necessary');\n }\n\n // send source-add IQ.\n sdpDiffer = new SDPDiffer(oldSDP, newSDP);\n const add = $iq({ to: this.remoteJid,\n type: 'set' })\n .c('jingle', {\n xmlns: 'urn:xmpp:jingle:1',\n action: 'source-add',\n initiator: this.initiatorJid,\n sid: this.sid\n }\n );\n\n const containsNewSSRCs = sdpDiffer.toJingle(add);\n\n if (containsNewSSRCs) {\n logger.info('Sending source-add', add.tree());\n this.connection.sendIQ(\n add, null, this.newJingleErrorHandler(add), IQ_TIMEOUT);\n } else {\n logger.log('addition not necessary');\n }\n }\n\n /**\n * Method returns function(errorResponse) which is a callback to be passed\n * to Strophe connection.sendIQ method. An 'error' structure is created that\n * is passed as 1st argument to given failureCb. The format of this\n * structure is as follows:\n * {\n * code: {XMPP error response code}\n * reason: {the name of XMPP error reason element or 'timeout' if the\n * request has timed out within IQ_TIMEOUT milliseconds}\n * source: {request.tree() that provides original request}\n * session: {this JingleSessionPC.toString()}\n * }\n * @param request Strophe IQ instance which is the request to be dumped into\n * the error structure\n * @param failureCb function(error) called when error response was returned\n * or when a timeout has occurred.\n * @returns {function(this:JingleSessionPC)}\n */\n newJingleErrorHandler(request, failureCb) {\n return errResponse => {\n\n const error = {};\n\n // Get XMPP error code and condition(reason)\n const errorElSel = $(errResponse).find('error');\n\n if (errorElSel.length) {\n error.code = errorElSel.attr('code');\n const errorReasonSel = $(errResponse).find('error :first');\n\n if (errorReasonSel.length) {\n error.reason = errorReasonSel[0].tagName;\n }\n\n const errorMsgSel = errorElSel.find('>text');\n\n if (errorMsgSel.length) {\n error.msg = errorMsgSel.text();\n }\n }\n\n if (!errResponse) {\n error.reason = 'timeout';\n }\n\n error.session = this.toString();\n\n if (failureCb) {\n failureCb(error);\n } else if (this.state === JingleSessionState.ENDED\n && error.reason === 'item-not-found') {\n // When remote peer decides to terminate the session, but it\n // still have few messages on the queue for processing,\n // it will first send us 'session-terminate' (we enter ENDED)\n // and then follow with 'item-not-found' for the queued requests\n // We don't want to have that logged on error level.\n logger.debug(`Jingle error: ${JSON.stringify(error)}`);\n } else {\n GlobalOnErrorHandler.callErrorHandler(\n new Error(\n `Jingle error: ${JSON.stringify(error)}`));\n }\n };\n }\n\n /**\n * Returns the ice connection state for the peer connection.\n * @returns the ice connection state for the peer connection.\n */\n getIceConnectionState() {\n return this.peerconnection.iceConnectionState;\n }\n\n /**\n * Closes the peerconnection.\n */\n close() {\n this.state = JingleSessionState.ENDED;\n this.establishmentDuration = undefined;\n\n if (this.peerconnection) {\n this.peerconnection.onicecandidate = null;\n this.peerconnection.oniceconnectionstatechange = null;\n this.peerconnection.onnegotiationneeded = null;\n this.peerconnection.onsignalingstatechange = null;\n }\n\n // Remove any pending tasks from the queue\n this.modificationQueue.clear();\n\n this.modificationQueue.push(finishCallback => {\n // The signaling layer will remove it's listeners\n this.signalingLayer.setChatRoom(null);\n\n // do not try to close if already closed.\n this.peerconnection && this.peerconnection.close();\n finishCallback();\n });\n\n // No more tasks can go in after the close task\n this.modificationQueue.shutdown();\n }\n\n /**\n * Converts to string with minor summary.\n * @return {string}\n */\n toString() {\n return `JingleSessionPC[p2p=${this.isP2P},`\n + `initiator=${this.isInitiator},sid=${this.sid}]`;\n }\n\n /**\n * If the A/B test for suspend video is disabled according to the room's\n * configuration, returns undefined. Otherwise returns a boolean which\n * indicates whether the suspend video option should be enabled or disabled.\n * @param {JingleSessionPCOptions} options - The config options.\n */\n _abtestSuspendVideoEnabled({ abTesting }) {\n if (!abTesting || !abTesting.enableSuspendVideoTest) {\n return;\n }\n\n // We want the two participants in a P2P call to agree on the value of\n // the \"suspend\" option. We use the JID of the initiator, because it is\n // both randomly selected and agreed upon by both participants.\n const jid = this._getInitiatorJid();\n\n return integerHash(jid) % 2 === 0;\n }\n}\n", "/**\n * The events for the media devices.\n */\n\n/**\n * Indicates that the list of available media devices has been changed. The\n * event provides the following parameters to its listeners:\n *\n * @param {MediaDeviceInfo[]} devices - array of MediaDeviceInfo or\n * MediaDeviceInfo-like objects that are currently connected.\n * @see https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo\n */\nexport const DEVICE_LIST_CHANGED = 'mediaDevices.devicechange';\n\n/**\n * Indicates that the environment is currently showing permission prompt to\n * access camera and/or microphone. The event provides the following\n * parameters to its listeners:\n *\n * @param {'chrome'|'opera'|'firefox'|'safari'|'nwjs'\n * |'react-native'|'android'} environmentType - type of browser or\n * other execution environment.\n */\nexport const PERMISSION_PROMPT_IS_SHOWN\n = 'mediaDevices.permissionPromptIsShown';\n", "/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/**\n * Adds the key-value `pair` to `map`.\n *\n * @private\n * @param {Object} map The map to modify.\n * @param {Array} pair The key-value pair to add.\n * @returns {Object} Returns `map`.\n */\nfunction addMapEntry(map, pair) {\n // Don't return `map.set` because it's not chainable in IE 11.\n map.set(pair[0], pair[1]);\n return map;\n}\n\n/**\n * Adds `value` to `set`.\n *\n * @private\n * @param {Object} set The set to modify.\n * @param {*} value The value to add.\n * @returns {Object} Returns `set`.\n */\nfunction addSetEntry(set, value) {\n // Don't return `set.add` because it's not chainable in IE 11.\n set.add(value);\n return set;\n}\n\n/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n var index = -1,\n length = array ? array.length : 0;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n}\n\n/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\n/**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\nfunction arrayReduce(array, iteratee, accumulator, initAccum) {\n var index = -1,\n length = array ? array.length : 0;\n\n if (initAccum && length) {\n accumulator = array[++index];\n }\n while (++index < length) {\n accumulator = iteratee(accumulator, array[index], index, array);\n }\n return accumulator;\n}\n\n/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\n/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\n/**\n * Checks if `value` is a host object in IE < 9.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a host object, else `false`.\n */\nfunction isHostObject(value) {\n // Many host objects are `Object` objects that can coerce to strings\n // despite having improperly defined `toString` methods.\n var result = false;\n if (value != null && typeof value.toString != 'function') {\n try {\n result = !!(value + '');\n } catch (e) {}\n }\n return result;\n}\n\n/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\n/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\n/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype,\n funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n Symbol = root.Symbol,\n Uint8Array = root.Uint8Array,\n getPrototype = overArg(Object.getPrototypeOf, Object),\n objectCreate = Object.create,\n propertyIsEnumerable = objectProto.propertyIsEnumerable,\n splice = arrayProto.splice;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols,\n nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n nativeKeys = overArg(Object.keys, Object);\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView'),\n Map = getNative(root, 'Map'),\n Promise = getNative(root, 'Promise'),\n Set = getNative(root, 'Set'),\n WeakMap = getNative(root, 'WeakMap'),\n nativeCreate = getNative(Object, 'create');\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n}\n\n/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n return this.has(key) && delete this.__data__[key];\n}\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);\n}\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n}\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n return true;\n}\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n return getMapData(this, key)['delete'](key);\n}\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n getMapData(this, key).set(key, value);\n return this;\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n this.__data__ = new ListCache(entries);\n}\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n}\n\n/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n return this.__data__['delete'](key);\n}\n\n/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\n/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var cache = this.__data__;\n if (cache instanceof ListCache) {\n var pairs = cache.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n return this;\n }\n cache = this.__data__ = new MapCache(pairs);\n }\n cache.set(key, value);\n return this;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n // Safari 9 makes `arguments.length` enumerable in strict mode.\n var result = (isArray(value) || isArguments(value))\n ? baseTimes(value.length, String)\n : [];\n\n var length = result.length,\n skipIndexes = !!length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (key == 'length' || isIndex(key, length)))) {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n object[key] = value;\n }\n}\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\n/**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n}\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @param {boolean} [isFull] Specify a clone including symbols.\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, isDeep, isFull, customizer, key, object, stack) {\n var result;\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n if (isHostObject(value)) {\n return object ? value : {};\n }\n result = initCloneObject(isFunc ? {} : value);\n if (!isDeep) {\n return copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, baseClone, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (!isArr) {\n var props = isFull ? getAllKeys(value) : keys(value);\n }\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));\n });\n return result;\n}\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} prototype The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nfunction baseCreate(proto) {\n return isObject(proto) ? objectCreate(proto) : {};\n}\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\n/**\n * The base implementation of `getTag`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n return objectToString.call(value);\n}\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var result = new buffer.constructor(buffer.length);\n buffer.copy(result);\n return result;\n}\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\n/**\n * Creates a clone of `map`.\n *\n * @private\n * @param {Object} map The map to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned map.\n */\nfunction cloneMap(map, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);\n return arrayReduce(array, addMapEntry, new map.constructor);\n}\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n}\n\n/**\n * Creates a clone of `set`.\n *\n * @private\n * @param {Object} set The set to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned set.\n */\nfunction cloneSet(set, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);\n return arrayReduce(array, addSetEntry, new set.constructor);\n}\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\n/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n assignValue(object, key, newValue === undefined ? source[key] : newValue);\n }\n return object;\n}\n\n/**\n * Copies own symbol properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n}\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\n/**\n * Creates an array of the own enumerable symbol properties of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray;\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11,\n// for data views in Edge < 14, and promises in Node.js.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = objectToString.call(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : undefined;\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n var length = array.length,\n result = array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n}\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, cloneFunc, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return cloneMap(object, isDeep, cloneFunc);\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return cloneSet(object, isDeep, cloneFunc);\n\n case symbolTag:\n return cloneSymbol(object);\n }\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to process.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\n/**\n * This method is like `_.clone` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @returns {*} Returns the deep cloned value.\n * @see _.clone\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var deep = _.cloneDeep(objects);\n * console.log(deep[0] === objects[0]);\n * // => false\n */\nfunction cloneDeep(value) {\n return baseClone(value, true, true);\n}\n\n/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8-9 which returns 'object' for typed array and other constructors.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\n/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\n/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = cloneDeep;\n", "import SDPUtil from './SDPUtil';\n\n// this could be useful in Array.prototype.\n/**\n *\n * @param array1\n * @param array2\n */\nfunction arrayEquals(array1, array2) {\n // if the other array is a falsy value, return\n if (!array2) {\n return false;\n }\n\n // compare lengths - can save a lot of time\n if (array1.length !== array2.length) {\n return false;\n }\n\n for (let i = 0, l = array1.length; i < l; i++) {\n // Check if we have nested arrays\n if (array1[i] instanceof Array && array2[i] instanceof Array) {\n // recurse into the nested arrays\n if (!array1[i].equals(array2[i])) {\n return false;\n }\n } else if (array1[i] !== array2[i]) {\n // Warning - two different object instances will never be\n // equal: {x:20} != {x:20}\n return false;\n }\n }\n\n return true;\n}\n\n/**\n *\n * @param mySDP\n * @param otherSDP\n */\nexport default function SDPDiffer(mySDP, otherSDP) {\n this.mySDP = mySDP;\n this.otherSDP = otherSDP;\n if (!mySDP) {\n throw new Error('\"mySDP\" is undefined!');\n } else if (!otherSDP) {\n throw new Error('\"otherSDP\" is undefined!');\n }\n}\n\n/**\n * Returns map of MediaChannel that contains media contained in\n * 'mySDP', but not contained in 'otherSdp'. Mapped by channel idx.\n */\nSDPDiffer.prototype.getNewMedia = function() {\n\n const myMedias = this.mySDP.getMediaSsrcMap();\n const othersMedias = this.otherSDP.getMediaSsrcMap();\n const newMedia = {};\n\n Object.keys(othersMedias).forEach(othersMediaIdx => {\n const myMedia = myMedias[othersMediaIdx];\n const othersMedia = othersMedias[othersMediaIdx];\n\n if (!myMedia && othersMedia) {\n // Add whole channel\n newMedia[othersMediaIdx] = othersMedia;\n\n return;\n }\n\n // Look for new ssrcs across the channel\n Object.keys(othersMedia.ssrcs).forEach(ssrc => {\n if (Object.keys(myMedia.ssrcs).indexOf(ssrc) === -1) {\n // Allocate channel if we've found ssrc that doesn't exist in\n // our channel\n if (!newMedia[othersMediaIdx]) {\n newMedia[othersMediaIdx] = {\n mediaindex: othersMedia.mediaindex,\n mid: othersMedia.mid,\n ssrcs: {},\n ssrcGroups: []\n };\n }\n newMedia[othersMediaIdx].ssrcs[ssrc] = othersMedia.ssrcs[ssrc];\n } else if (othersMedia.ssrcs[ssrc].lines\n && myMedia.ssrcs[ssrc].lines) {\n // we want to detect just changes in adding/removing msid\n const myContainMsid = myMedia.ssrcs[ssrc].lines.find(\n line => line.indexOf('msid') !== -1) !== undefined;\n const newContainMsid = othersMedia.ssrcs[ssrc].lines.find(\n line => line.indexOf('msid') !== -1) !== undefined;\n\n if (myContainMsid !== newContainMsid) {\n if (!newMedia[othersMediaIdx]) {\n newMedia[othersMediaIdx] = {\n mediaindex: othersMedia.mediaindex,\n mid: othersMedia.mid,\n ssrcs: {},\n ssrcGroups: []\n };\n }\n newMedia[othersMediaIdx].ssrcs[ssrc]\n = othersMedia.ssrcs[ssrc];\n }\n }\n });\n\n // Look for new ssrc groups across the channels\n othersMedia.ssrcGroups.forEach(otherSsrcGroup => {\n\n // try to match the other ssrc-group with an ssrc-group of ours\n let matched = false;\n\n for (let i = 0; i < myMedia.ssrcGroups.length; i++) {\n const mySsrcGroup = myMedia.ssrcGroups[i];\n\n if (otherSsrcGroup.semantics === mySsrcGroup.semantics\n && arrayEquals(otherSsrcGroup.ssrcs, mySsrcGroup.ssrcs)) {\n\n matched = true;\n break;\n }\n }\n\n if (!matched) {\n // Allocate channel if we've found an ssrc-group that doesn't\n // exist in our channel\n\n if (!newMedia[othersMediaIdx]) {\n newMedia[othersMediaIdx] = {\n mediaindex: othersMedia.mediaindex,\n mid: othersMedia.mid,\n ssrcs: {},\n ssrcGroups: []\n };\n }\n newMedia[othersMediaIdx].ssrcGroups.push(otherSsrcGroup);\n }\n });\n });\n\n return newMedia;\n};\n\n/**\n * TODO: document!\n */\nSDPDiffer.prototype.toJingle = function(modify) {\n const sdpMediaSsrcs = this.getNewMedia();\n\n let modified = false;\n\n Object.keys(sdpMediaSsrcs).forEach(mediaindex => {\n modified = true;\n const media = sdpMediaSsrcs[mediaindex];\n\n modify.c('content', { name: media.mid });\n\n modify.c('description',\n { xmlns: 'urn:xmpp:jingle:apps:rtp:1',\n media: media.mid });\n\n // FIXME: not completely sure this operates on blocks and / or handles\n // different ssrcs correctly\n // generate sources from lines\n Object.keys(media.ssrcs).forEach(ssrcNum => {\n const mediaSsrc = media.ssrcs[ssrcNum];\n\n modify.c('source', { xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });\n modify.attrs({ ssrc: mediaSsrc.ssrc });\n\n // iterate over ssrc lines\n mediaSsrc.lines.forEach(line => {\n const idx = line.indexOf(' ');\n const kv = line.substr(idx + 1);\n\n modify.c('parameter');\n if (kv.indexOf(':') === -1) {\n modify.attrs({ name: kv });\n } else {\n const nv = kv.split(':', 2);\n const name = nv[0];\n const value = SDPUtil.filterSpecialChars(nv[1]);\n\n modify.attrs({ name });\n modify.attrs({ value });\n }\n modify.up(); // end of parameter\n });\n modify.up(); // end of source\n });\n\n // generate source groups from lines\n media.ssrcGroups.forEach(ssrcGroup => {\n if (ssrcGroup.ssrcs.length) {\n\n modify.c('ssrc-group', {\n semantics: ssrcGroup.semantics,\n xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0'\n });\n\n ssrcGroup.ssrcs.forEach(ssrc => {\n modify.c('source', { ssrc })\n .up(); // end of source\n });\n modify.up(); // end of ssrc-group\n }\n });\n\n modify.up(); // end of description\n modify.up(); // end of content\n });\n\n return modified;\n};\n", "// shim for using process in browser\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\nfunction defaultSetTimout() {\n throw new Error('setTimeout has not been defined');\n}\nfunction defaultClearTimeout () {\n throw new Error('clearTimeout has not been defined');\n}\n(function () {\n try {\n if (typeof setTimeout === 'function') {\n cachedSetTimeout = setTimeout;\n } else {\n cachedSetTimeout = defaultSetTimout;\n }\n } catch (e) {\n cachedSetTimeout = defaultSetTimout;\n }\n try {\n if (typeof clearTimeout === 'function') {\n cachedClearTimeout = clearTimeout;\n } else {\n cachedClearTimeout = defaultClearTimeout;\n }\n } catch (e) {\n cachedClearTimeout = defaultClearTimeout;\n }\n} ())\nfunction runTimeout(fun) {\n if (cachedSetTimeout === setTimeout) {\n //normal enviroments in sane situations\n return setTimeout(fun, 0);\n }\n // if setTimeout wasn't available but was latter defined\n if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {\n cachedSetTimeout = setTimeout;\n return setTimeout(fun, 0);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedSetTimeout(fun, 0);\n } catch(e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedSetTimeout.call(null, fun, 0);\n } catch(e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error\n return cachedSetTimeout.call(this, fun, 0);\n }\n }\n\n\n}\nfunction runClearTimeout(marker) {\n if (cachedClearTimeout === clearTimeout) {\n //normal enviroments in sane situations\n return clearTimeout(marker);\n }\n // if clearTimeout wasn't available but was latter defined\n if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {\n cachedClearTimeout = clearTimeout;\n return clearTimeout(marker);\n }\n try {\n // when when somebody has screwed with setTimeout but no I.E. maddness\n return cachedClearTimeout(marker);\n } catch (e){\n try {\n // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally\n return cachedClearTimeout.call(null, marker);\n } catch (e){\n // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.\n // Some versions of I.E. have different rules for clearTimeout vs setTimeout\n return cachedClearTimeout.call(this, marker);\n }\n }\n\n\n\n}\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = runTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n runClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n runTimeout(drainQueue);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\nprocess.prependListener = noop;\nprocess.prependOnceListener = noop;\n\nprocess.listeners = function (name) { return [] }\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n", "/**\n * Provides statistics for the local stream.\n */\n\n/**\n * Size of the webaudio analyzer buffer.\n * @type {number}\n */\nconst WEBAUDIO_ANALYZER_FFT_SIZE = 2048;\n\n/**\n * Value of the webaudio analyzer smoothing time parameter.\n * @type {number}\n */\nconst WEBAUDIO_ANALYZER_SMOOTING_TIME = 0.8;\n\nwindow.AudioContext = window.AudioContext || window.webkitAudioContext;\n\nlet context = null;\n\nif (window.AudioContext) {\n context = new AudioContext();\n\n // XXX Not all browsers define a suspend method on AudioContext. As the\n // invocation is at the (ES6 module) global execution level, it breaks the\n // loading of the lib-jitsi-meet library in such browsers and, consequently,\n // the loading of the very Web app that uses the lib-jitsi-meet library. For\n // example, Google Chrome 40 on Android does not define the method but we\n // still want to be able to load the lib-jitsi-meet library there and\n // display a page which notifies the user that the Web app is not supported\n // there.\n context.suspend && context.suspend();\n}\n\n/**\n * Converts time domain data array to audio level.\n * @param samples the time domain data array.\n * @returns {number} the audio level\n */\nfunction timeDomainDataToAudioLevel(samples) {\n\n let maxVolume = 0;\n\n const length = samples.length;\n\n for (let i = 0; i < length; i++) {\n if (maxVolume < samples[i]) {\n maxVolume = samples[i];\n }\n }\n\n return parseFloat(((maxVolume - 127) / 128).toFixed(3));\n}\n\n/**\n * Animates audio level change\n * @param newLevel the new audio level\n * @param lastLevel the last audio level\n * @returns {Number} the audio level to be set\n */\nfunction animateLevel(newLevel, lastLevel) {\n let value = 0;\n const diff = lastLevel - newLevel;\n\n if (diff > 0.2) {\n value = lastLevel - 0.2;\n } else if (diff < -0.4) {\n value = lastLevel + 0.4;\n } else {\n value = newLevel;\n }\n\n return parseFloat(value.toFixed(3));\n}\n\n\n/**\n * LocalStatsCollector calculates statistics for the local stream.\n *\n * @param stream the local stream\n * @param interval stats refresh interval given in ms.\n * @param callback function that receives the audio levels.\n * @constructor\n */\nexport default function LocalStatsCollector(stream, interval, callback) {\n this.stream = stream;\n this.intervalId = null;\n this.intervalMilis = interval;\n this.audioLevel = 0;\n this.callback = callback;\n}\n\n/**\n * Starts the collecting the statistics.\n */\nLocalStatsCollector.prototype.start = function() {\n if (!LocalStatsCollector.isLocalStatsSupported()) {\n return;\n }\n context.resume();\n const analyser = context.createAnalyser();\n\n analyser.smoothingTimeConstant = WEBAUDIO_ANALYZER_SMOOTING_TIME;\n analyser.fftSize = WEBAUDIO_ANALYZER_FFT_SIZE;\n\n const source = context.createMediaStreamSource(this.stream);\n\n source.connect(analyser);\n\n\n const self = this;\n\n this.intervalId = setInterval(\n () => {\n const array = new Uint8Array(analyser.frequencyBinCount);\n\n analyser.getByteTimeDomainData(array);\n const audioLevel = timeDomainDataToAudioLevel(array);\n\n if (audioLevel !== self.audioLevel) {\n self.audioLevel = animateLevel(audioLevel, self.audioLevel);\n self.callback(self.audioLevel);\n }\n },\n this.intervalMilis\n );\n};\n\n/**\n * Stops collecting the statistics.\n */\nLocalStatsCollector.prototype.stop = function() {\n if (this.intervalId) {\n clearInterval(this.intervalId);\n this.intervalId = null;\n }\n};\n\n/**\n * Checks if the environment has the necessary conditions to support\n * collecting stats from local streams.\n *\n * @returns {boolean}\n */\nLocalStatsCollector.isLocalStatsSupported = function() {\n return Boolean(context);\n};\n", "const currentExecutingScript = require('current-executing-script');\n\n/* eslint-disable max-params */\n\n/**\n * Implements utility functions which facilitate the dealing with scripts such\n * as the download and execution of a JavaScript file.\n */\nconst ScriptUtil = {\n /**\n * Loads a script from a specific source.\n *\n * @param src the source from the which the script is to be (down)loaded\n * @param async true to asynchronously load the script or false to\n * synchronously load the script\n * @param prepend true to schedule the loading of the script as soon as\n * possible or false to schedule the loading of the script at the end of the\n * scripts known at the time\n * @param relativeURL whether we need load the library from url relative\n * to the url that lib-jitsi-meet was loaded. Useful when sourcing the\n * library from different location than the app that is using it\n * @param loadCallback on load callback function\n * @param errorCallback callback to be called on error loading the script\n */\n loadScript(\n src,\n async,\n prepend,\n relativeURL,\n loadCallback,\n errorCallback) {\n const d = document;\n const tagName = 'script';\n const script = d.createElement(tagName);\n const referenceNode = d.getElementsByTagName(tagName)[0];\n\n script.async = async;\n\n if (relativeURL) {\n // finds the src url of the current loaded script\n // and use it as base of the src supplied argument\n const scriptEl = currentExecutingScript();\n\n if (scriptEl) {\n const scriptSrc = scriptEl.src;\n const baseScriptSrc\n = scriptSrc.substring(0, scriptSrc.lastIndexOf('/') + 1);\n\n if (scriptSrc && baseScriptSrc) {\n // eslint-disable-next-line no-param-reassign\n src = baseScriptSrc + src;\n }\n }\n }\n\n if (loadCallback) {\n script.onload = loadCallback;\n }\n if (errorCallback) {\n script.onerror = errorCallback;\n }\n\n script.src = src;\n if (prepend) {\n referenceNode.parentNode.insertBefore(script, referenceNode);\n } else {\n referenceNode.parentNode.appendChild(script);\n }\n }\n};\n\n/* eslint-enable max-params */\n\nmodule.exports = ScriptUtil;\n", "/* global __filename, module */\nimport EventEmitter from 'events';\nimport { getLogger } from 'jitsi-meet-logger';\nimport * as JitsiTrackEvents from '../../JitsiTrackEvents';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport RTCUtils from './RTCUtils';\n\nconst logger = getLogger(__filename);\n\n/**\n * Maps our handler types to MediaStreamTrack properties.\n */\nconst trackHandler2Prop = {\n 'track_mute': 'onmute', // Not supported on FF\n 'track_unmute': 'onunmute',\n 'track_ended': 'onended'\n};\n\n/**\n * Adds onended/oninactive handler to a MediaStream.\n * @param mediaStream a MediaStream to attach onended/oninactive handler\n * @param handler the handler\n */\nfunction addMediaStreamInactiveHandler(mediaStream, handler) {\n mediaStream.oninactive = handler;\n}\n\n/**\n * Represents a single media track (either audio or video).\n */\nexport default class JitsiTrack extends EventEmitter {\n /* eslint-disable max-params */\n /**\n * Represents a single media track (either audio or video).\n * @constructor\n * @param conference the rtc instance\n * @param stream the WebRTC MediaStream instance\n * @param track the WebRTC MediaStreamTrack instance, must be part of\n * the given stream.\n * @param streamInactiveHandler the function that will handle\n * onended/oninactive events of the stream.\n * @param trackMediaType the media type of the JitsiTrack\n * @param videoType the VideoType for this track if any\n */\n constructor(\n conference,\n stream,\n track,\n streamInactiveHandler,\n trackMediaType,\n videoType) {\n super();\n\n // aliases for addListener/removeListener\n this.addEventListener = this.addListener;\n this.removeEventListener = this.off = this.removeListener;\n\n /**\n * Array with the HTML elements that are displaying the streams.\n * @type {Array}\n */\n this.containers = [];\n this.conference = conference;\n this.audioLevel = -1;\n this.type = trackMediaType;\n this.track = track;\n this.videoType = videoType;\n this.handlers = new Map();\n\n /**\n * Indicates whether this JitsiTrack has been disposed. If true, this\n * JitsiTrack is to be considered unusable and operations involving it\n * are to fail (e.g. {@link JitsiConference#addTrack(JitsiTrack)},\n * {@link JitsiConference#removeTrack(JitsiTrack)}).\n * @type {boolean}\n */\n this.disposed = false;\n\n /**\n * The inactive handler which will be triggered when the underlying\n * MediaStream ends.\n *\n * @private\n * @type {Function}\n */\n this._streamInactiveHandler = streamInactiveHandler;\n\n this._setStream(stream);\n }\n\n /* eslint-enable max-params */\n\n /**\n * Sets handler to the WebRTC MediaStream or MediaStreamTrack object\n * depending on the passed type.\n * @param {string} type the type of the handler that is going to be set\n * @param {Function} handler the handler.\n */\n _setHandler(type, handler) {\n if (!trackHandler2Prop.hasOwnProperty(type)) {\n logger.error(`Invalid handler type ${type}`);\n\n return;\n }\n if (handler) {\n this.handlers.set(type, handler);\n } else {\n this.handlers.delete(type);\n }\n\n if (this.stream) {\n for (const track of this.stream.getTracks()) {\n track[trackHandler2Prop[type]] = handler;\n }\n }\n }\n\n /**\n * Unregisters all event handlers bound to the underlying media stream/track\n * @private\n */\n _unregisterHandlers() {\n if (!this.stream) {\n logger.warn(\n `${this}: unable to unregister handlers - no stream object`);\n\n return;\n }\n\n for (const type of this.handlers.keys()) {\n // FIXME Why only video tracks?\n for (const videoTrack of this.stream.getVideoTracks()) {\n videoTrack[trackHandler2Prop[type]] = undefined;\n }\n }\n if (this._streamInactiveHandler) {\n addMediaStreamInactiveHandler(this.stream, undefined);\n }\n }\n\n /**\n * Sets the stream property of JitsiTrack object and sets all stored\n * handlers to it.\n *\n * @param {MediaStream} stream the new stream.\n * @protected\n */\n _setStream(stream) {\n if (this.stream === stream) {\n return;\n }\n\n this.stream = stream;\n\n // TODO Practically, that's like the opposite of _unregisterHandlers\n // i.e. may be abstracted into a function/method called\n // _registerHandlers for clarity and easing the maintenance of the two\n // pieces of source code.\n if (this.stream) {\n for (const type of this.handlers.keys()) {\n this._setHandler(type, this.handlers.get(type));\n }\n if (this._streamInactiveHandler) {\n addMediaStreamInactiveHandler(\n this.stream, this._streamInactiveHandler);\n }\n }\n }\n\n /**\n * Returns the type (audio or video) of this track.\n */\n getType() {\n return this.type;\n }\n\n /**\n * Check if this is an audio track.\n */\n isAudioTrack() {\n return this.getType() === MediaType.AUDIO;\n }\n\n /**\n * Checks whether the underlying WebRTC MediaStreamTrack is muted\n * according to it's 'muted' field status.\n * @return {boolean} true if the underlying\n * MediaStreamTrack is muted or false otherwise.\n */\n isWebRTCTrackMuted() {\n return this.track && this.track.muted;\n }\n\n /**\n * Check if this is a video track.\n */\n isVideoTrack() {\n return this.getType() === MediaType.VIDEO;\n }\n\n /**\n * Checks whether this is a local track.\n * @abstract\n * @return {boolean} 'true' if it's a local track or 'false' otherwise.\n */\n isLocal() {\n throw new Error('Not implemented by subclass');\n }\n\n /**\n * Check whether this is a local audio track.\n *\n * @return {boolean} - true if track represents a local audio track, false otherwise.\n */\n isLocalAudioTrack() {\n return this.isAudioTrack() && this.isLocal();\n }\n\n /**\n * Returns the WebRTC MediaStream instance.\n */\n getOriginalStream() {\n return this.stream;\n }\n\n /**\n * Returns the ID of the underlying WebRTC Media Stream(if any)\n * @returns {String|null}\n */\n getStreamId() {\n return this.stream ? this.stream.id : null;\n }\n\n /**\n * Return the underlying WebRTC MediaStreamTrack\n * @returns {MediaStreamTrack}\n */\n getTrack() {\n return this.track;\n }\n\n /**\n * Return the underlying WebRTC MediaStreamTrack label\n * @returns {string}\n */\n getTrackLabel() {\n return this.track.label;\n }\n\n /**\n * Returns the ID of the underlying WebRTC MediaStreamTrack(if any)\n * @returns {String|null}\n */\n getTrackId() {\n return this.track ? this.track.id : null;\n }\n\n /**\n * Return meaningful usage label for this track depending on it's media and\n * eventual video type.\n * @returns {string}\n */\n getUsageLabel() {\n if (this.isAudioTrack()) {\n return 'mic';\n }\n\n return this.videoType ? this.videoType : 'default';\n }\n\n /**\n * Eventually will trigger RTCEvents.TRACK_ATTACHED event.\n * @param container the video/audio container to which this stream is\n * attached and for which event will be fired.\n * @private\n */\n _maybeFireTrackAttached(container) {\n if (this.conference && container) {\n this.conference._onTrackAttach(this, container);\n }\n }\n\n /**\n * Attaches the MediaStream of this track to an HTML container.\n * Adds the container to the list of containers that are displaying the\n * track.\n *\n * @param container the HTML container which can be 'video' or 'audio'\n * element.\n *\n * @returns {void}\n */\n attach(container) {\n if (this.stream) {\n this._onTrackAttach(container);\n RTCUtils.attachMediaStream(container, this.stream);\n }\n this.containers.push(container);\n this._maybeFireTrackAttached(container);\n this._attachTTFMTracker(container);\n }\n\n /**\n * Removes this JitsiTrack from the passed HTML container.\n *\n * @param container the HTML container to detach from this JitsiTrack. If\n * null or undefined, all containers are removed. A\n * container can be a 'video', 'audio' or 'object' HTML element instance to\n * which this JitsiTrack is currently attached.\n */\n detach(container) {\n for (let cs = this.containers, i = cs.length - 1; i >= 0; --i) {\n const c = cs[i];\n\n if (!container) {\n this._onTrackDetach(c);\n RTCUtils.attachMediaStream(c, null);\n }\n if (!container || c === container) {\n cs.splice(i, 1);\n }\n }\n\n if (container) {\n this._onTrackDetach(container);\n RTCUtils.attachMediaStream(container, null);\n }\n }\n\n /**\n * Called when the track has been attached to a new container.\n *\n * @param {HTMLElement} container the HTML container which can be 'video' or\n * 'audio' element.\n * @private\n */\n _onTrackAttach(container) { // eslint-disable-line no-unused-vars\n // Should be defined by the classes that are extending JitsiTrack\n }\n\n /**\n * Called when the track has been detached from a container.\n *\n * @param {HTMLElement} container the HTML container which can be 'video' or\n * 'audio' element.\n * @private\n */\n _onTrackDetach(container) { // eslint-disable-line no-unused-vars\n // Should be defined by the classes that are extending JitsiTrack\n }\n\n /**\n * Attach time to first media tracker only if there is conference and only\n * for the first element.\n *\n * @param {HTMLElement} container the HTML container which can be 'video' or\n * 'audio' element.\n * @private\n */\n _attachTTFMTracker(container) { // eslint-disable-line no-unused-vars\n // Should be defined by the classes that are extending JitsiTrack\n }\n\n /**\n * Removes attached event listeners.\n *\n * @returns {Promise}\n */\n dispose() {\n this.removeAllListeners();\n\n this.disposed = true;\n\n return Promise.resolve();\n }\n\n /**\n * Returns true if this is a video track and the source of the video is a\n * screen capture as opposed to a camera.\n */\n isScreenSharing() {\n // FIXME: Should be fixed or removed.\n }\n\n /**\n * Returns id of the track.\n * @returns {string|null} id of the track or null if this is fake track.\n */\n getId() {\n if (this.stream) {\n return RTCUtils.getStreamID(this.stream);\n }\n\n return null;\n }\n\n /**\n * Checks whether the MediaStream is active/not ended.\n * When there is no check for active we don't have information and so\n * will return that stream is active (in case of FF).\n * @returns {boolean} whether MediaStream is active.\n */\n isActive() {\n if (typeof this.stream.active !== 'undefined') {\n return this.stream.active;\n }\n\n return true;\n }\n\n /**\n * Sets the audio level for the stream\n * @param {number} audioLevel value between 0 and 1\n * @param {TraceablePeerConnection} [tpc] the peerconnection instance which\n * is source for the audio level. It can be undefined for\n * a local track if the audio level was measured outside of the\n * peerconnection (see /modules/statistics/LocalStatsCollector.js).\n */\n setAudioLevel(audioLevel, tpc) {\n if (this.audioLevel !== audioLevel) {\n this.audioLevel = audioLevel;\n this.emit(\n JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,\n audioLevel,\n tpc);\n }\n }\n\n /**\n * Returns the msid of the stream attached to the JitsiTrack object or null\n * if no stream is attached.\n */\n getMSID() {\n const streamId = this.getStreamId();\n const trackId = this.getTrackId();\n\n return streamId && trackId ? `${streamId} ${trackId}` : null;\n }\n\n /**\n * Sets new audio output device for track's DOM elements. Video tracks are\n * ignored.\n * @param {string} audioOutputDeviceId - id of 'audiooutput' device from\n * navigator.mediaDevices.enumerateDevices(), '' for default device\n * @emits JitsiTrackEvents.TRACK_AUDIO_OUTPUT_CHANGED\n * @returns {Promise}\n */\n setAudioOutput(audioOutputDeviceId) {\n if (!RTCUtils.isDeviceChangeAvailable('output')) {\n return Promise.reject(\n new Error('Audio output device change is not supported'));\n }\n\n // All audio communication is done through audio tracks, so ignore\n // changing audio output for video tracks at all.\n if (this.isVideoTrack()) {\n return Promise.resolve();\n }\n\n return (\n Promise.all(\n this.containers.map(\n element =>\n element.setSinkId(audioOutputDeviceId)\n .catch(error => {\n logger.warn(\n 'Failed to change audio output device on'\n + ' element. Default or previously set'\n + ' audio output device will be used.',\n element,\n error);\n throw error;\n }))\n )\n .then(() => {\n this.emit(\n JitsiTrackEvents.TRACK_AUDIO_OUTPUT_CHANGED,\n audioOutputDeviceId);\n }));\n }\n}\n", "/**\n * Adapter that creates AudioContext objects depending on the browser.\n *\n * @returns {AudioContext} - Return a new AudioContext or undefined if the browser does not support it.\n */\nexport function createAudioContext(options) {\n const AudioContextImpl = window.AudioContext || window.webkitAudioContext;\n\n if (!AudioContextImpl) {\n return undefined;\n }\n\n return new AudioContextImpl(options);\n}\n", "import EventEmitter from 'events';\n\nimport RTC from '../RTC/RTC';\n\nimport { createAudioContext } from '../webaudio/WebAudioUtils';\nimport { VAD_SCORE_PUBLISHED } from './DetectionEvents';\n\n/**\n * Connects an audio JitsiLocalTrack to a vadProcessor using WebAudio ScriptProcessorNode.\n * Once an object is created audio from the local track flows through the ScriptProcessorNode as raw PCM.\n * The PCM is processed by the injected vad module and a voice activity detection score is obtained, the\n * score is published to consumers via an EventEmitter.\n * After work is done with this service the destroy method needs to be called for a proper cleanup.\n *\n * @fires VAD_SCORE_PUBLISHED\n */\nexport default class TrackVADEmitter extends EventEmitter {\n /**\n * Constructor.\n *\n * @param {number} procNodeSampleRate - Sample rate of the ScriptProcessorNode. Possible values 256, 512, 1024,\n * 2048, 4096, 8192, 16384. Passing other values will default to closes neighbor.\n * @param {Object} vadProcessor - VAD processor that allows us to calculate VAD score for PCM samples.\n * @param {JitsiLocalTrack} jitsiLocalTrack - JitsiLocalTrack corresponding to micDeviceId.\n */\n constructor(procNodeSampleRate, vadProcessor, jitsiLocalTrack) {\n super();\n\n /**\n * Sample rate of the ScriptProcessorNode.\n */\n this._procNodeSampleRate = procNodeSampleRate;\n\n /**\n * VAD Processor that allows us to calculate VAD score for PCM samples\n */\n this._vadProcessor = vadProcessor;\n\n /**\n * The JitsiLocalTrack instance.\n */\n this._localTrack = jitsiLocalTrack;\n\n /**\n * Buffer to hold residue PCM resulting after a ScriptProcessorNode callback\n */\n this._bufferResidue = new Float32Array([]);\n\n /**\n * The AudioContext instance with the preferred sample frequency.\n */\n this._audioContext = createAudioContext({ sampleRate: vadProcessor.getRequiredPCMFrequency() });\n\n /**\n * PCM Sample size expected by the VAD Processor instance. We cache it here as this value is used extensively,\n * saves a couple of function calls.\n */\n this._vadSampleSize = vadProcessor.getSampleLength();\n\n /**\n * Event listener function that will be called by the ScriptProcessNode with raw PCM data, depending on the set\n * sample rate.\n */\n this._onAudioProcess = this._onAudioProcess.bind(this);\n\n this._initializeAudioContext();\n }\n\n /**\n * Factory method that sets up all the necessary components for the creation of the TrackVADEmitter.\n *\n * @param {string} micDeviceId - Target microphone device id.\n * @param {number} procNodeSampleRate - Sample rate of the proc node.\n * @param {Object} vadProcessor -Module that calculates the voice activity score for a certain audio PCM sample.\n * The processor needs to implement the following functions:\n * - getSampleLength() - Returns the sample size accepted by getSampleLength.\n * - getRequiredPCMFrequency() - Returns the PCM frequency at which the processor operates.\n * - calculateAudioFrameVAD(pcmSample) - Process a 32 float pcm sample of getSampleLength size.\n * @returns {Promise} - Promise resolving in a new instance of TrackVADEmitter.\n */\n static create(micDeviceId, procNodeSampleRate, vadProcessor) {\n return RTC.obtainAudioAndVideoPermissions({\n devices: [ 'audio' ],\n micDeviceId\n }).then(localTrack => {\n // We only expect one audio track when specifying a device id.\n if (!localTrack[0]) {\n throw new Error(`Failed to create jitsi local track for device id: ${micDeviceId}`);\n }\n\n return new TrackVADEmitter(procNodeSampleRate, vadProcessor, localTrack[0]);\n\n // We have no exception handling at this point as there is nothing to clean up, the vadProcessor\n // life cycle is handled by whoever created this instance.\n });\n }\n\n /**\n * Sets up the audio graph in the AudioContext.\n *\n * @returns {void}\n */\n _initializeAudioContext() {\n this._audioSource = this._audioContext.createMediaStreamSource(this._localTrack.stream);\n\n // TODO AudioProcessingNode is deprecated in the web audio specifications and the recommended replacement\n // is audio worklet, however at the point of implementation AudioProcessingNode was still de de facto way\n // of achieving this functionality and supported in all major browsers as opposed to audio worklet which\n // was only available in Chrome. This todo is just a reminder that we should replace AudioProcessingNode\n // with audio worklet when it's mature enough and has more browser support.\n // We don't need stereo for determining the VAD score so we create a single channel processing node.\n this._audioProcessingNode = this._audioContext.createScriptProcessor(this._procNodeSampleRate, 1, 1);\n }\n\n /**\n * ScriptProcessorNode callback, the input parameters contains the PCM audio that is then sent to rnnoise.\n * Rnnoise only accepts PCM samples of 480 bytes whereas the webaudio processor node can't sample at a multiple\n * of 480 thus after each _onAudioProcess callback there will remain and PCM buffer residue equal\n * to _procNodeSampleRate / 480 which will be added to the next sample buffer and so on.\\\n *\n *\n * @param {AudioProcessingEvent} audioEvent - Audio event.\n * @returns {void}\n * @fires VAD_SCORE_PUBLISHED\n */\n _onAudioProcess(audioEvent) {\n // Prepend the residue PCM buffer from the previous process callback.\n const inData = audioEvent.inputBuffer.getChannelData(0);\n const completeInData = [ ...this._bufferResidue, ...inData ];\n const sampleTimestamp = Date.now();\n\n let i = 0;\n\n for (; i + this._vadSampleSize < completeInData.length; i += this._vadSampleSize) {\n const pcmSample = completeInData.slice(i, i + this._vadSampleSize);\n\n // The VAD processor might change the values inside the array so we make a copy.\n const vadScore = this._vadProcessor.calculateAudioFrameVAD(pcmSample.slice());\n\n this.emit(VAD_SCORE_PUBLISHED, {\n timestamp: sampleTimestamp,\n score: vadScore,\n pcmData: pcmSample,\n deviceId: this._localTrack.getDeviceId()\n });\n }\n\n this._bufferResidue = completeInData.slice(i, completeInData.length);\n }\n\n /**\n * Connects the nodes in the AudioContext to start the flow of audio data.\n *\n * @returns {void}\n */\n _connectAudioGraph() {\n this._audioProcessingNode.onaudioprocess = this._onAudioProcess;\n this._audioSource.connect(this._audioProcessingNode);\n this._audioProcessingNode.connect(this._audioContext.destination);\n }\n\n /**\n * Disconnects the nodes in the AudioContext.\n *\n * @returns {void}\n */\n _disconnectAudioGraph() {\n // Even thought we disconnect the processing node it seems that some callbacks remain queued,\n // resulting in calls with and uninitialized context.\n // eslint-disable-next-line no-empty-function\n this._audioProcessingNode.onaudioprocess = () => {};\n this._audioProcessingNode.disconnect();\n this._audioSource.disconnect();\n }\n\n /**\n * Cleanup potentially acquired resources.\n *\n * @returns {void}\n */\n _cleanupResources() {\n this._disconnectAudioGraph();\n this._localTrack.stopStream();\n }\n\n /**\n * Get the associated track device ID.\n *\n * @returns {string}\n */\n getDeviceId() {\n return this._localTrack.getDeviceId();\n }\n\n\n /**\n * Get the associated track label.\n *\n * @returns {string}\n */\n getTrackLabel() {\n return this._localTrack.getDeviceLabel();\n }\n\n /**\n * Start the emitter by connecting the audio graph.\n *\n * @returns {void}\n */\n start() {\n this._connectAudioGraph();\n }\n\n /**\n * Stops the emitter by disconnecting the audio graph.\n *\n * @returns {void}\n */\n stop() {\n this._disconnectAudioGraph();\n this._bufferResidue = [];\n }\n\n /**\n * Destroy TrackVADEmitter instance (release resources and stop callbacks).\n *\n * @returns {void}\n */\n destroy() {\n if (this._destroyed) {\n return;\n }\n\n this._cleanupResources();\n this._destroyed = true;\n }\n}\n", "/**\n * Indicates that the end-to-end round-trip-time for a participant has changed.\n */\nexport const E2E_RTT_CHANGED = 'e2eping.e2e_rtt_changed';\n", "/**\n * Lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright JS Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n asyncTag = '[object AsyncFunction]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n nullTag = '[object Null]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n proxyTag = '[object Proxy]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n undefinedTag = '[object Undefined]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/** Used to identify `toStringTag` values of typed arrays. */\nvar typedArrayTags = {};\ntypedArrayTags[float32Tag] = typedArrayTags[float64Tag] =\ntypedArrayTags[int8Tag] = typedArrayTags[int16Tag] =\ntypedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =\ntypedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =\ntypedArrayTags[uint32Tag] = true;\ntypedArrayTags[argsTag] = typedArrayTags[arrayTag] =\ntypedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =\ntypedArrayTags[dataViewTag] = typedArrayTags[dateTag] =\ntypedArrayTags[errorTag] = typedArrayTags[funcTag] =\ntypedArrayTags[mapTag] = typedArrayTags[numberTag] =\ntypedArrayTags[objectTag] = typedArrayTags[regexpTag] =\ntypedArrayTags[setTag] = typedArrayTags[stringTag] =\ntypedArrayTags[weakMapTag] = false;\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/** Detect free variable `process` from Node.js. */\nvar freeProcess = moduleExports && freeGlobal.process;\n\n/** Used to access faster Node.js helpers. */\nvar nodeUtil = (function() {\n try {\n return freeProcess && freeProcess.binding && freeProcess.binding('util');\n } catch (e) {}\n}());\n\n/* Node.js helper references. */\nvar nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;\n\n/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\n/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\n/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\n/**\n * The base implementation of `_.unary` without support for storing metadata.\n *\n * @private\n * @param {Function} func The function to cap arguments for.\n * @returns {Function} Returns the new capped function.\n */\nfunction baseUnary(func) {\n return function(value) {\n return func(value);\n };\n}\n\n/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\n/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\n/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\n/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\n/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype,\n funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n Symbol = root.Symbol,\n Uint8Array = root.Uint8Array,\n propertyIsEnumerable = objectProto.propertyIsEnumerable,\n splice = arrayProto.splice,\n symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols,\n nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n nativeKeys = overArg(Object.keys, Object);\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView'),\n Map = getNative(root, 'Map'),\n Promise = getNative(root, 'Promise'),\n Set = getNative(root, 'Set'),\n WeakMap = getNative(root, 'WeakMap'),\n nativeCreate = getNative(Object, 'create');\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n this.size = 0;\n}\n\n/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key);\n}\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\n/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n var data = this.__data__ = new ListCache(entries);\n this.size = data.size;\n}\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n this.size = 0;\n}\n\n/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n var data = this.__data__,\n result = data['delete'](key);\n\n this.size = data.size;\n return result;\n}\n\n/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\n/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var data = this.__data__;\n if (data instanceof ListCache) {\n var pairs = data.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n this.size = ++data.size;\n return this;\n }\n data = this.__data__ = new MapCache(pairs);\n }\n data.set(key, value);\n this.size = data.size;\n return this;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n var isArr = isArray(value),\n isArg = !isArr && isArguments(value),\n isBuff = !isArr && !isArg && isBuffer(value),\n isType = !isArr && !isArg && !isBuff && isTypedArray(value),\n skipIndexes = isArr || isArg || isBuff || isType,\n result = skipIndexes ? baseTimes(value.length, String) : [],\n length = result.length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (\n // Safari 9 has enumerable `arguments.length` in strict mode.\n key == 'length' ||\n // Node.js 0.10 has enumerable non-index properties on buffers.\n (isBuff && (key == 'offset' || key == 'parent')) ||\n // PhantomJS 2 has enumerable non-index properties on typed arrays.\n (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||\n // Skip index properties.\n isIndex(key, length)\n ))) {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\n/**\n * The base implementation of `_.isArguments`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n */\nfunction baseIsArguments(value) {\n return isObjectLike(value) && baseGetTag(value) == argsTag;\n}\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = isFunction(value) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\n/**\n * The base implementation of `_.isTypedArray` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n */\nfunction baseIsTypedArray(value) {\n return isObjectLike(value) &&\n isLength(value.length) && !!typedArrayTags[baseGetTag(value)];\n}\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(array);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked && stack.get(other)) {\n return stacked == other;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = baseGetTag(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : '';\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\n/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nvar isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {\n return isObjectLike(value) && hasOwnProperty.call(value, 'callee') &&\n !propertyIsEnumerable.call(value, 'callee');\n};\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\n/**\n * Performs a deep comparison between two values to determine if they are\n * equivalent.\n *\n * **Note:** This method supports comparing arrays, array buffers, booleans,\n * date objects, error objects, maps, numbers, `Object` objects, regexes,\n * sets, strings, symbols, and typed arrays. `Object` objects are compared\n * by their own, not inherited, enumerable properties. Functions and DOM\n * nodes are compared by strict equality, i.e. `===`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.isEqual(object, other);\n * // => true\n *\n * object === other;\n * // => false\n */\nfunction isEqual(value, other) {\n return baseIsEqual(value, other);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a typed array.\n *\n * @static\n * @memberOf _\n * @since 3.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.\n * @example\n *\n * _.isTypedArray(new Uint8Array);\n * // => true\n *\n * _.isTypedArray([]);\n * // => false\n */\nvar isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\n/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\n/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = isEqual;\n", "/* global $ */\n\nimport { b64_sha1, Strophe } from 'strophe.js'; // eslint-disable-line camelcase\n\nimport XMPPEvents from '../../service/xmpp/XMPPEvents';\nimport Listenable from '../util/Listenable';\n\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\n\n/**\n * The property\n */\nconst IDENTITY_PROPERTIES = [ 'category', 'type', 'lang', 'name' ];\nconst IDENTITY_PROPERTIES_FOR_COMPARE = [ 'category', 'type', 'lang' ];\nconst HASH = 'sha-1';\n\nexport const ERROR_FEATURE_VERSION_MISMATCH = 'Feature version mismatch';\n\n/**\n *\n * @param a\n * @param b\n */\nfunction compareIdentities(a, b) {\n let res = 0;\n\n IDENTITY_PROPERTIES_FOR_COMPARE.some(key =>\n (res = ((a[key] > b[key]) && 1) || ((a[key] < b[key]) && -1)) !== 0\n );\n\n return res;\n}\n\n/**\n * Produces a sha-1 from provided identity and features values.\n *\n * @param {Array} identities - The identity objects.\n * @param {Array} features - The features.\n * @returns {string}\n */\nfunction generateSha(identities, features) {\n const sortedIdentities = identities.sort(compareIdentities).reduce(\n (accumulatedValue, identity) => `${\n IDENTITY_PROPERTIES.reduce(\n (tmp, key, idx) =>\n tmp\n + (idx === 0 ? '' : '/')\n + (identity[key] ? identity[key] : ''),\n '')\n }<`, '');\n const sortedFeatures = features.sort().reduce(\n (tmp, feature) => `${tmp + feature}<`, '');\n\n return b64_sha1(sortedIdentities + sortedFeatures);\n}\n\n/**\n * Implements xep-0115 ( http://xmpp.org/extensions/xep-0115.html )\n */\nexport default class Caps extends Listenable {\n /**\n * Constructs new Caps instance.\n * @param {Strophe.Connection} connection the strophe connection object\n * @param {String} node the value of the node attribute of the \"c\" xml node\n * that will be sent to the other participants\n */\n constructor(connection = {}, node = 'http://jitsi.org/jitsimeet') {\n super();\n this.node = node;\n this.disco = connection.disco;\n if (!this.disco) {\n throw new Error(\n 'Missing strophe-plugins '\n + '(disco plugin is required)!');\n }\n\n this.versionToCapabilities = Object.create(null);\n this.jidToVersion = Object.create(null);\n this.version = '';\n this.rooms = new Set();\n\n const emuc = connection.emuc;\n\n emuc.addListener(XMPPEvents.EMUC_ROOM_ADDED,\n room => this._addChatRoom(room));\n emuc.addListener(XMPPEvents.EMUC_ROOM_REMOVED,\n room => this._removeChatRoom(room));\n Object.keys(emuc.rooms).forEach(jid => {\n this._addChatRoom(emuc.rooms[jid]);\n });\n\n Strophe.addNamespace('CAPS', 'http://jabber.org/protocol/caps');\n this.disco.addFeature(Strophe.NS.CAPS);\n connection.addHandler(this._handleCaps.bind(this), Strophe.NS.CAPS);\n\n this._onMucMemberLeft = this._removeJidToVersionEntry.bind(this);\n }\n\n /**\n * Adds new feature to the list of supported features for the local\n * participant\n * @param {String} feature the name of the feature.\n * @param {boolean} submit if true - new presence with updated \"c\" node\n * will be sent.\n */\n addFeature(feature, submit = false) {\n this.disco.addFeature(feature);\n this._generateVersion();\n if (submit) {\n this.submit();\n }\n }\n\n /**\n * Removes a feature from the list of supported features for the local\n * participant\n * @param {String} feature the name of the feature.\n * @param {boolean} submit if true - new presence with updated \"c\" node\n * will be sent.\n */\n removeFeature(feature, submit = false) {\n this.disco.removeFeature(feature);\n this._generateVersion();\n if (submit) {\n this.submit();\n }\n }\n\n /**\n * Sends new presence stanza for every room from the list of rooms.\n */\n submit() {\n this.rooms.forEach(room => room.sendPresence());\n }\n\n /**\n * Returns a set with the features for a participant.\n * @param {String} jid the jid of the participant\n * @param {int} timeout the timeout in ms for reply from the participant.\n * @returns {Promise, Error>}\n */\n getFeatures(jid, timeout = 5000) {\n const user\n = jid in this.jidToVersion ? this.jidToVersion[jid] : null;\n\n if (!user || !(user.version in this.versionToCapabilities)) {\n const node = user ? `${user.node}#${user.version}` : null;\n\n return this._getDiscoInfo(jid, node, timeout)\n .then(({ features, identities }) => {\n if (user) {\n const sha = generateSha(\n Array.from(identities),\n Array.from(features)\n );\n const receivedNode = `${user.node}#${sha}`;\n\n if (receivedNode === node) {\n this.versionToCapabilities[receivedNode] = features;\n\n return features;\n }\n\n // Check once if it has been cached asynchronously.\n if (this.versionToCapabilities[receivedNode]) {\n return this.versionToCapabilities[receivedNode];\n }\n\n logger.error(`Expected node ${node} but received ${\n receivedNode}`);\n\n return Promise.reject(ERROR_FEATURE_VERSION_MISMATCH);\n }\n });\n }\n\n return Promise.resolve(this.versionToCapabilities[user.version]);\n }\n\n /**\n * Returns a set with the features for a host.\n * @param {String} jid the jid of the host\n * @param {int} timeout the timeout in ms for reply from the host.\n * @returns {Promise, Error>}\n */\n getFeaturesAndIdentities(jid, timeout = 5000) {\n return this._getDiscoInfo(jid, null, timeout);\n }\n\n /**\n * Returns a set with the features and identities for a host.\n * @param {String} jid the jid of the host\n * @param {String|null} node the node to query\n * @param {int} timeout the timeout in ms for reply from the host.\n * @returns {Promise}\n * @private\n */\n _getDiscoInfo(jid, node, timeout) {\n return new Promise((resolve, reject) =>\n this.disco.info(jid, node, response => {\n const features = new Set();\n const identities = new Set();\n\n $(response)\n .find('>query>feature')\n .each(\n (_, el) => features.add(el.getAttribute('var')));\n $(response)\n .find('>query>identity')\n .each(\n (_, el) => identities.add({\n type: el.getAttribute('type'),\n name: el.getAttribute('name'),\n category: el.getAttribute('category')\n }));\n resolve({\n features,\n identities });\n }, reject, timeout)\n );\n }\n\n /**\n * Adds ChatRoom instance to the list of rooms. Adds listeners to the room\n * and adds \"c\" element to the presences of the room.\n * @param {ChatRoom} room the room.\n */\n _addChatRoom(room) {\n this.rooms.add(room);\n room.addListener(XMPPEvents.MUC_MEMBER_LEFT, this._onMucMemberLeft);\n this._fixChatRoomPresenceMap(room);\n }\n\n /**\n * Removes ChatRoom instance from the list of rooms. Removes listeners\n * added from the Caps class.\n * @param {ChatRoom} room the room.\n */\n _removeChatRoom(room) {\n this.rooms.delete(room);\n room.removeListener(XMPPEvents.MUC_MEMBER_LEFT, this._onMucMemberLeft);\n }\n\n /**\n * Creates/updates the \"c\" xml node into the presence of the passed room.\n * @param {ChatRoom} room the room.\n */\n _fixChatRoomPresenceMap(room) {\n room.addToPresence('c', {\n attributes: {\n xmlns: Strophe.NS.CAPS,\n hash: HASH,\n node: this.node,\n ver: this.version\n }\n });\n }\n\n /**\n * Handles this.version changes.\n */\n _notifyVersionChanged() {\n // update the version for all rooms\n this.rooms.forEach(room => this._fixChatRoomPresenceMap(room));\n }\n\n /**\n * Generates the value for the \"ver\" attribute.\n */\n _generateVersion() {\n this.version\n = generateSha(this.disco._identities, this.disco._features);\n\n this._notifyVersionChanged();\n }\n\n /**\n * Parses the \"c\" xml node from presence.\n * @param {DOMElement} stanza the presence packet\n */\n _handleCaps(stanza) {\n const from = stanza.getAttribute('from');\n const caps = stanza.querySelector('c');\n const version = caps.getAttribute('ver');\n const node = caps.getAttribute('node');\n const oldVersion = this.jidToVersion[from];\n\n this.jidToVersion[from] = { version,\n node };\n if (oldVersion && oldVersion.version !== version) {\n this.eventEmitter.emit(XMPPEvents.PARTCIPANT_FEATURES_CHANGED,\n from);\n }\n\n // return true to not remove the handler from Strophe\n return true;\n }\n\n /**\n * Removes entry from this.jidToVersion map.\n * @param {String} jid the jid to be removed.\n */\n _removeJidToVersionEntry(jid) {\n if (jid in this.jidToVersion) {\n delete this.jidToVersion[jid];\n }\n }\n}\n", "/**\n * The transciption is on.\n *\n * @type {String}\n */\nexport const ON = 'on';\n\n/**\n * The transciption is off.\n *\n * @type {String}\n */\nexport const OFF = 'off';\n", "import { getLogger } from 'jitsi-meet-logger';\nimport transform from 'sdp-transform';\n\nimport * as JitsiTrackEvents from '../../JitsiTrackEvents';\nimport browser from '../browser';\nimport RTCEvents from '../../service/RTC/RTCEvents';\n\nconst logger = getLogger(__filename);\nconst SIM_LAYER_1_RID = '1';\nconst SIM_LAYER_2_RID = '2';\nconst SIM_LAYER_3_RID = '3';\n\nexport const SIM_LAYER_RIDS = [ SIM_LAYER_1_RID, SIM_LAYER_2_RID, SIM_LAYER_3_RID ];\n\n/**\n * Handles track related operations on TraceablePeerConnection when browser is\n * running in unified plan mode.\n */\nexport class TPCUtils {\n /**\n * @constructor\n */\n constructor(peerconnection) {\n this.pc = peerconnection;\n\n /**\n * The simulcast encodings that will be configured on the RTCRtpSender\n * for the video tracks in the unified plan mode.\n */\n this.simulcastEncodings = [\n {\n active: true,\n maxBitrate: browser.isFirefox() ? 2500000 : 200000,\n rid: SIM_LAYER_1_RID,\n scaleResolutionDownBy: browser.isFirefox() ? 1.0 : 4.0\n },\n {\n active: true,\n maxBitrate: 700000,\n rid: SIM_LAYER_2_RID,\n scaleResolutionDownBy: 2.0\n },\n {\n active: true,\n maxBitrate: browser.isFirefox() ? 200000 : 2500000,\n rid: SIM_LAYER_3_RID,\n scaleResolutionDownBy: browser.isFirefox() ? 4.0 : 1.0\n }\n ];\n }\n\n /**\n * Ensures that the ssrcs associated with a FID ssrc-group appear in the correct order, i.e.,\n * the primary ssrc first and the secondary rtx ssrc later. This is important for unified\n * plan since we have only one FID group per media description.\n * @param {Object} description the webRTC session description instance for the remote\n * description.\n * @private\n */\n _ensureCorrectOrderOfSsrcs(description) {\n const parsedSdp = transform.parse(description.sdp);\n\n parsedSdp.media.forEach(mLine => {\n if (mLine.type === 'audio') {\n return;\n }\n if (!mLine.ssrcGroups || !mLine.ssrcGroups.length) {\n return;\n }\n let reorderedSsrcs = [];\n\n mLine.ssrcGroups[0].ssrcs.split(' ').forEach(ssrc => {\n const sources = mLine.ssrcs.filter(source => source.id.toString() === ssrc);\n\n reorderedSsrcs = reorderedSsrcs.concat(sources);\n });\n mLine.ssrcs = reorderedSsrcs;\n });\n\n return new RTCSessionDescription({\n type: description.type,\n sdp: transform.write(parsedSdp)\n });\n }\n\n /**\n * Obtains stream encodings that need to be configured on the given track.\n * @param {JitsiLocalTrack} localTrack\n */\n _getStreamEncodings(localTrack) {\n if (this.pc.isSimulcastOn() && localTrack.isVideoTrack()) {\n return this.simulcastEncodings;\n }\n\n return [ { active: true } ];\n }\n\n /**\n * Takes in a *unified plan* offer and inserts the appropriate\n * parameters for adding simulcast receive support.\n * @param {Object} desc - A session description object\n * @param {String} desc.type - the type (offer/answer)\n * @param {String} desc.sdp - the sdp content\n *\n * @return {Object} A session description (same format as above) object\n * with its sdp field modified to advertise simulcast receive support\n */\n _insertUnifiedPlanSimulcastReceive(desc) {\n // a=simulcast line is not needed on browsers where\n // we munge SDP for turning on simulcast. Remove this check\n // when we move to RID/MID based simulcast on all browsers.\n if (browser.usesSdpMungingForSimulcast()) {\n return desc;\n }\n const sdp = transform.parse(desc.sdp);\n const idx = sdp.media.findIndex(mline => mline.type === 'video');\n\n if (sdp.media[idx].rids && (sdp.media[idx].simulcast_03 || sdp.media[idx].simulcast)) {\n // Make sure we don't have the simulcast recv line on video descriptions other than the\n // the first video description.\n sdp.media.forEach((mline, i) => {\n if (mline.type === 'video' && i !== idx) {\n sdp.media[i].rids = undefined;\n sdp.media[i].simulcast = undefined;\n\n // eslint-disable-next-line camelcase\n sdp.media[i].simulcast_03 = undefined;\n }\n });\n\n return new RTCSessionDescription({\n type: desc.type,\n sdp: transform.write(sdp)\n });\n }\n\n // In order of highest to lowest spatial quality\n sdp.media[idx].rids = [\n {\n id: SIM_LAYER_1_RID,\n direction: 'recv'\n },\n {\n id: SIM_LAYER_2_RID,\n direction: 'recv'\n },\n {\n id: SIM_LAYER_3_RID,\n direction: 'recv'\n }\n ];\n\n // Firefox 72 has stopped parsing the legacy rid= parameters in simulcast attributes.\n // eslint-disable-next-line max-len\n // https://www.fxsitecompat.dev/en-CA/docs/2019/pt-and-rid-in-webrtc-simulcast-attributes-are-no-longer-supported/\n const simulcastLine = browser.isFirefox() && browser.isVersionGreaterThan(71)\n ? `recv ${SIM_LAYER_RIDS.join(';')}`\n : `recv rid=${SIM_LAYER_RIDS.join(';')}`;\n\n // eslint-disable-next-line camelcase\n sdp.media[idx].simulcast_03 = {\n value: simulcastLine\n };\n\n return new RTCSessionDescription({\n type: desc.type,\n sdp: transform.write(sdp)\n });\n }\n\n /**\n * Adds {@link JitsiLocalTrack} to the WebRTC peerconnection for the first time.\n * @param {JitsiLocalTrack} track - track to be added to the peerconnection.\n * @returns {boolean} Returns true if the operation is successful,\n * false otherwise.\n */\n addTrack(localTrack, isInitiator = true) {\n const track = localTrack.getTrack();\n\n if (isInitiator) {\n // Use pc.addTransceiver() for the initiator case when local tracks are getting added\n // to the peerconnection before a session-initiate is sent over to the peer.\n const transceiverInit = {\n direction: 'sendrecv',\n streams: [ localTrack.getOriginalStream() ],\n sendEncodings: []\n };\n\n if (!browser.isFirefox()) {\n transceiverInit.sendEncodings = this._getStreamEncodings(localTrack);\n }\n this.pc.peerconnection.addTransceiver(track, transceiverInit);\n } else {\n // Use pc.addTrack() for responder case so that we can re-use the m-lines that were created\n // when setRemoteDescription was called. pc.addTrack() automatically attaches to any existing\n // unused \"recv-only\" transceiver.\n this.pc.peerconnection.addTrack(track);\n }\n }\n\n /**\n * Adds a track on the RTCRtpSender as part of the unmute operation.\n * @param {JitsiLocalTrack} localTrack - track to be unmuted.\n * @returns {Promise} - Promise that resolves to false if unmute\n * operation is successful, a reject otherwise.\n */\n addTrackUnmute(localTrack) {\n const mediaType = localTrack.getType();\n const track = localTrack.getTrack();\n\n // The assumption here is that the first transceiver of the specified\n // media type is that of the local track.\n const transceiver = this.pc.peerconnection.getTransceivers()\n .find(t => t.receiver && t.receiver.track && t.receiver.track.kind === mediaType);\n\n if (!transceiver) {\n return Promise.reject(new Error(`RTCRtpTransceiver for ${mediaType} not found`));\n }\n logger.debug(`Adding ${localTrack} on ${this.pc}`);\n\n // If the client starts with audio/video muted setting, the transceiver direction\n // will be set to 'recvonly'. Use addStream here so that a MSID is generated for the stream.\n if (transceiver.direction === 'recvonly') {\n this.pc.peerconnection.addStream(localTrack.getOriginalStream());\n this.setEncodings(localTrack);\n this.pc.localTracks.set(localTrack.rtcId, localTrack);\n transceiver.direction = 'sendrecv';\n\n return Promise.resolve(false);\n }\n\n return transceiver.sender.replaceTrack(track)\n .then(() => {\n this.pc.localTracks.set(localTrack.rtcId, localTrack);\n\n return Promise.resolve(false);\n });\n }\n\n /**\n * Removes the track from the RTCRtpSender as part of the mute operation.\n * @param {JitsiLocalTrack} localTrack - track to be removed.\n * @returns {Promise} - Promise that resolves to false if unmute\n * operation is successful, a reject otherwise.\n */\n removeTrackMute(localTrack) {\n const mediaType = localTrack.getType();\n const transceiver = this.pc.peerconnection.getTransceivers()\n .find(t => t.sender && t.sender.track && t.sender.track.id === localTrack.getTrackId());\n\n if (!transceiver) {\n return Promise.reject(new Error(`RTCRtpTransceiver for ${mediaType} not found`));\n }\n\n logger.debug(`Removing ${localTrack} on ${this.pc}`);\n\n return transceiver.sender.replaceTrack(null)\n .then(() => {\n this.pc.localTracks.delete(localTrack.rtcId);\n\n return Promise.resolve(false);\n });\n }\n\n /**\n * Replaces the existing track on a RTCRtpSender with the given track.\n * @param {JitsiLocalTrack} oldTrack - existing track on the sender that needs to be removed.\n * @param {JitsiLocalTrack} newTrack - new track that needs to be added to the sender.\n * @returns {Promise} Promise that resolves with false as we don't want\n * renegotiation to be triggered automatically after this operation. Renegotiation is\n * done when the browser fires the negotiationeeded event.\n */\n replaceTrack(oldTrack, newTrack) {\n if (oldTrack && newTrack) {\n const mediaType = newTrack.getType();\n const stream = newTrack.getOriginalStream();\n const track = stream.getVideoTracks()[0];\n const transceiver = this.pc.peerconnection.getTransceivers()\n .find(t => t.receiver.track.kind === mediaType && !t.stopped);\n\n if (!transceiver) {\n return Promise.reject(new Error('replace track failed'));\n }\n logger.debug(`Replacing ${oldTrack} with ${newTrack} on ${this.pc}`);\n\n return transceiver.sender.replaceTrack(track)\n .then(() => {\n const ssrc = this.pc.localSSRCs.get(oldTrack.rtcId);\n\n this.pc.localTracks.delete(oldTrack.rtcId);\n this.pc.localSSRCs.delete(oldTrack.rtcId);\n this.pc._addedStreams = this.pc._addedStreams.filter(s => s !== stream);\n this.pc.localTracks.set(newTrack.rtcId, newTrack);\n\n this.pc._addedStreams.push(stream);\n this.pc.localSSRCs.set(newTrack.rtcId, ssrc);\n this.pc.eventEmitter.emit(RTCEvents.LOCAL_TRACK_SSRC_UPDATED,\n newTrack,\n this.pc._extractPrimarySSRC(ssrc));\n });\n } else if (oldTrack && !newTrack) {\n if (!this.removeTrackMute(oldTrack)) {\n return Promise.reject(new Error('replace track failed'));\n }\n this.pc.localTracks.delete(oldTrack.rtcId);\n this.pc.localSSRCs.delete(oldTrack.rtcId);\n } else if (newTrack && !oldTrack) {\n const ssrc = this.pc.localSSRCs.get(newTrack.rtcId);\n\n if (!this.addTrackUnmute(newTrack)) {\n return Promise.reject(new Error('replace track failed'));\n }\n newTrack.emit(JitsiTrackEvents.TRACK_MUTE_CHANGED, newTrack);\n this.pc.localTracks.set(newTrack.rtcId, newTrack);\n this.pc.localSSRCs.set(newTrack.rtcId, ssrc);\n }\n\n return Promise.resolve(false);\n }\n\n /**\n * Enables/disables audio transmission on the peer connection. When\n * disabled the audio transceiver direction will be set to 'inactive'\n * which means that no data will be sent nor accepted, but\n * the connection should be kept alive.\n * @param {boolean} active - true to enable audio media transmission or\n * false to disable.\n * @returns {false} - returns false always so that renegotiation is not automatically\n * triggered after this operation.\n */\n setAudioTransferActive(active) {\n return this.setMediaTransferActive('audio', active);\n }\n\n /**\n * Set the simulcast stream encoding properties on the RTCRtpSender.\n * @param {JitsiLocalTrack} track - the current track in use for which\n * the encodings are to be set.\n */\n setEncodings(track) {\n const transceiver = this.pc.peerconnection.getTransceivers()\n .find(t => t.sender && t.sender.track && t.sender.track.kind === track.getType());\n const parameters = transceiver.sender.getParameters();\n\n parameters.encodings = this._getStreamEncodings(track);\n transceiver.sender.setParameters(parameters);\n }\n\n /**\n * Enables/disables media transmission on the peerconnection by changing the direction\n * on the transceiver for the specified media type.\n * @param {String} mediaType - 'audio' or 'video'\n * @param {boolean} active - true to enable media transmission or false\n * to disable.\n * @returns {false} - returns false always so that renegotiation is not automatically\n * triggered after this operation\n */\n setMediaTransferActive(mediaType, active) {\n const transceivers = this.pc.peerconnection.getTransceivers()\n .filter(t => t.receiver && t.receiver.track && t.receiver.track.kind === mediaType);\n const localTracks = Array.from(this.pc.localTracks.values())\n .filter(track => track.getType() === mediaType);\n\n if (active) {\n transceivers.forEach(transceiver => {\n if (localTracks.length) {\n transceiver.direction = 'sendrecv';\n const parameters = transceiver.sender.getParameters();\n\n if (parameters && parameters.encodings && parameters.encodings.length) {\n parameters.encodings.forEach(encoding => {\n encoding.active = true;\n });\n transceiver.sender.setParameters(parameters);\n }\n } else {\n transceiver.direction = 'recvonly';\n }\n });\n } else {\n transceivers.forEach(transceiver => {\n transceiver.direction = 'inactive';\n });\n }\n\n return false;\n }\n\n /**\n * Enables/disables video media transmission on the peer connection. When\n * disabled the SDP video media direction in the local SDP will be adjusted to\n * 'inactive' which means that no data will be sent nor accepted, but\n * the connection should be kept alive.\n * @param {boolean} active - true to enable video media transmission or\n * false to disable.\n * @returns {false} - returns false always so that renegotiation is not automatically\n * triggered after this operation.\n */\n setVideoTransferActive(active) {\n return this.setMediaTransferActive('video', active);\n }\n}\n", "/**\n * A model for keeping track of each user's total\n * time as a dominant speaker. The model also\n * keeps track of the user's last known name\n * in case the user has left the meeting,\n * which is also tracked.\n */\nclass SpeakerStats {\n /**\n * Initializes a new SpeakerStats instance.\n *\n * @constructor\n * @param {string} userId - The id of the user being tracked.\n * @param {string} displayName - The name of the user being tracked.\n * @param {boolean} isLocalStats - True if the stats model tracks\n * the local user.\n * @returns {void}\n */\n constructor(userId, displayName, isLocalStats) {\n this._userId = userId;\n this.setDisplayName(displayName);\n this._isLocalStats = isLocalStats || false;\n this.setDominantSpeaker(false);\n this.totalDominantSpeakerTime = 0;\n this._dominantSpeakerStart = 0;\n this._hasLeft = false;\n }\n\n /**\n * Get the user id being tracked.\n *\n * @returns {string} The user id.\n */\n getUserId() {\n return this._userId;\n }\n\n /**\n * Get the name of the user being tracked.\n *\n * @returns {string} The user name.\n */\n getDisplayName() {\n return this.displayName;\n }\n\n /**\n * Updates the last known name of the user being tracked.\n *\n * @param {string} - The user name.\n * @returns {void}\n */\n setDisplayName(newName) {\n this.displayName = newName;\n }\n\n /**\n * Returns true if the stats are tracking the local user.\n *\n * @returns {boolean}\n */\n isLocalStats() {\n return this._isLocalStats;\n }\n\n /**\n * Returns true if the tracked user is currently a dominant speaker.\n *\n * @returns {boolean}\n */\n isDominantSpeaker() {\n return this._dominantSpeakerStart > 0;\n }\n\n /**\n * Returns true if the tracked user is currently a dominant speaker.\n *\n * @param {boolean} - If true, the user will being accumulating time\n * as dominant speaker. If false, the user will not accumulate time\n * and will record any time accumulated since starting as dominant speaker.\n * @returns {void}\n */\n setDominantSpeaker(isNowDominantSpeaker) {\n if (!this.isDominantSpeaker() && isNowDominantSpeaker) {\n this._dominantSpeakerStart = Date.now();\n } else if (this.isDominantSpeaker() && !isNowDominantSpeaker) {\n const now = Date.now();\n const timeElapsed = now - this._dominantSpeakerStart;\n\n this.totalDominantSpeakerTime += timeElapsed;\n this._dominantSpeakerStart = 0;\n }\n }\n\n /**\n * Get how long the tracked user has been dominant speaker.\n *\n * @returns {number} - The speaker time in milliseconds.\n */\n getTotalDominantSpeakerTime() {\n let total = this.totalDominantSpeakerTime;\n\n if (this.isDominantSpeaker()) {\n total += Date.now() - this._dominantSpeakerStart;\n }\n\n return total;\n }\n\n /**\n * Get whether or not the user is still in the meeting.\n *\n * @returns {boolean} True if the user is no longer in the meeting.\n */\n hasLeft() {\n return this._hasLeft;\n }\n\n /**\n * Set the user as having left the meeting.\n *\n * @returns {void}\n */\n markAsHasLeft() {\n this._hasLeft = true;\n this.setDominantSpeaker(false);\n }\n}\n\nmodule.exports = SpeakerStats;\n", "const AuthenticationEvents = {\n /**\n * Event callback arguments:\n * function(authenticationEnabled, userIdentity)\n * authenticationEnabled - indicates whether authentication has been enabled\n * in this session\n * userIdentity - if user has been logged in then it contains user name. If\n * contains 'null' or 'undefined' then user is not logged in.\n */\n IDENTITY_UPDATED: 'authentication.identity_updated'\n};\n\nmodule.exports = AuthenticationEvents;\n", "/**\n * [js-md5]{@link https://github.com/emn178/js-md5}\n *\n * @namespace md5\n * @version 0.7.3\n * @author Chen, Yi-Cyuan [emn178@gmail.com]\n * @copyright Chen, Yi-Cyuan 2014-2017\n * @license MIT\n */\n(function () {\n 'use strict';\n\n var ERROR = 'input is invalid type';\n var WINDOW = typeof window === 'object';\n var root = WINDOW ? window : {};\n if (root.JS_MD5_NO_WINDOW) {\n WINDOW = false;\n }\n var WEB_WORKER = !WINDOW && typeof self === 'object';\n var NODE_JS = !root.JS_MD5_NO_NODE_JS && typeof process === 'object' && process.versions && process.versions.node;\n if (NODE_JS) {\n root = global;\n } else if (WEB_WORKER) {\n root = self;\n }\n var COMMON_JS = !root.JS_MD5_NO_COMMON_JS && typeof module === 'object' && module.exports;\n var AMD = typeof define === 'function' && define.amd;\n var ARRAY_BUFFER = !root.JS_MD5_NO_ARRAY_BUFFER && typeof ArrayBuffer !== 'undefined';\n var HEX_CHARS = '0123456789abcdef'.split('');\n var EXTRA = [128, 32768, 8388608, -2147483648];\n var SHIFT = [0, 8, 16, 24];\n var OUTPUT_TYPES = ['hex', 'array', 'digest', 'buffer', 'arrayBuffer', 'base64'];\n var BASE64_ENCODE_CHAR = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');\n\n var blocks = [], buffer8;\n if (ARRAY_BUFFER) {\n var buffer = new ArrayBuffer(68);\n buffer8 = new Uint8Array(buffer);\n blocks = new Uint32Array(buffer);\n }\n\n if (root.JS_MD5_NO_NODE_JS || !Array.isArray) {\n Array.isArray = function (obj) {\n return Object.prototype.toString.call(obj) === '[object Array]';\n };\n }\n\n if (ARRAY_BUFFER && (root.JS_MD5_NO_ARRAY_BUFFER_IS_VIEW || !ArrayBuffer.isView)) {\n ArrayBuffer.isView = function (obj) {\n return typeof obj === 'object' && obj.buffer && obj.buffer.constructor === ArrayBuffer;\n };\n }\n\n /**\n * @method hex\n * @memberof md5\n * @description Output hash as hex string\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {String} Hex string\n * @example\n * md5.hex('The quick brown fox jumps over the lazy dog');\n * // equal to\n * md5('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method digest\n * @memberof md5\n * @description Output hash as bytes array\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Array} Bytes array\n * @example\n * md5.digest('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method array\n * @memberof md5\n * @description Output hash as bytes array\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Array} Bytes array\n * @example\n * md5.array('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method arrayBuffer\n * @memberof md5\n * @description Output hash as ArrayBuffer\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {ArrayBuffer} ArrayBuffer\n * @example\n * md5.arrayBuffer('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method buffer\n * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.\n * @memberof md5\n * @description Output hash as ArrayBuffer\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {ArrayBuffer} ArrayBuffer\n * @example\n * md5.buffer('The quick brown fox jumps over the lazy dog');\n */\n /**\n * @method base64\n * @memberof md5\n * @description Output hash as base64 string\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {String} base64 string\n * @example\n * md5.base64('The quick brown fox jumps over the lazy dog');\n */\n var createOutputMethod = function (outputType) {\n return function (message) {\n return new Md5(true).update(message)[outputType]();\n };\n };\n\n /**\n * @method create\n * @memberof md5\n * @description Create Md5 object\n * @returns {Md5} Md5 object.\n * @example\n * var hash = md5.create();\n */\n /**\n * @method update\n * @memberof md5\n * @description Create and update Md5 object\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Md5} Md5 object.\n * @example\n * var hash = md5.update('The quick brown fox jumps over the lazy dog');\n * // equal to\n * var hash = md5.create();\n * hash.update('The quick brown fox jumps over the lazy dog');\n */\n var createMethod = function () {\n var method = createOutputMethod('hex');\n if (NODE_JS) {\n method = nodeWrap(method);\n }\n method.create = function () {\n return new Md5();\n };\n method.update = function (message) {\n return method.create().update(message);\n };\n for (var i = 0; i < OUTPUT_TYPES.length; ++i) {\n var type = OUTPUT_TYPES[i];\n method[type] = createOutputMethod(type);\n }\n return method;\n };\n\n var nodeWrap = function (method) {\n var crypto = eval(\"require('crypto')\");\n var Buffer = eval(\"require('buffer').Buffer\");\n var nodeMethod = function (message) {\n if (typeof message === 'string') {\n return crypto.createHash('md5').update(message, 'utf8').digest('hex');\n } else {\n if (message === null || message === undefined) {\n throw ERROR;\n } else if (message.constructor === ArrayBuffer) {\n message = new Uint8Array(message);\n }\n }\n if (Array.isArray(message) || ArrayBuffer.isView(message) ||\n message.constructor === Buffer) {\n return crypto.createHash('md5').update(new Buffer(message)).digest('hex');\n } else {\n return method(message);\n }\n };\n return nodeMethod;\n };\n\n /**\n * Md5 class\n * @class Md5\n * @description This is internal class.\n * @see {@link md5.create}\n */\n function Md5(sharedMemory) {\n if (sharedMemory) {\n blocks[0] = blocks[16] = blocks[1] = blocks[2] = blocks[3] =\n blocks[4] = blocks[5] = blocks[6] = blocks[7] =\n blocks[8] = blocks[9] = blocks[10] = blocks[11] =\n blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n this.blocks = blocks;\n this.buffer8 = buffer8;\n } else {\n if (ARRAY_BUFFER) {\n var buffer = new ArrayBuffer(68);\n this.buffer8 = new Uint8Array(buffer);\n this.blocks = new Uint32Array(buffer);\n } else {\n this.blocks = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\n }\n }\n this.h0 = this.h1 = this.h2 = this.h3 = this.start = this.bytes = this.hBytes = 0;\n this.finalized = this.hashed = false;\n this.first = true;\n }\n\n /**\n * @method update\n * @memberof Md5\n * @instance\n * @description Update hash\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {Md5} Md5 object.\n * @see {@link md5.update}\n */\n Md5.prototype.update = function (message) {\n if (this.finalized) {\n return;\n }\n\n var notString, type = typeof message;\n if (type !== 'string') {\n if (type === 'object') {\n if (message === null) {\n throw ERROR;\n } else if (ARRAY_BUFFER && message.constructor === ArrayBuffer) {\n message = new Uint8Array(message);\n } else if (!Array.isArray(message)) {\n if (!ARRAY_BUFFER || !ArrayBuffer.isView(message)) {\n throw ERROR;\n }\n }\n } else {\n throw ERROR;\n }\n notString = true;\n }\n var code, index = 0, i, length = message.length, blocks = this.blocks;\n var buffer8 = this.buffer8;\n\n while (index < length) {\n if (this.hashed) {\n this.hashed = false;\n blocks[0] = blocks[16];\n blocks[16] = blocks[1] = blocks[2] = blocks[3] =\n blocks[4] = blocks[5] = blocks[6] = blocks[7] =\n blocks[8] = blocks[9] = blocks[10] = blocks[11] =\n blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n }\n\n if (notString) {\n if (ARRAY_BUFFER) {\n for (i = this.start; index < length && i < 64; ++index) {\n buffer8[i++] = message[index];\n }\n } else {\n for (i = this.start; index < length && i < 64; ++index) {\n blocks[i >> 2] |= message[index] << SHIFT[i++ & 3];\n }\n }\n } else {\n if (ARRAY_BUFFER) {\n for (i = this.start; index < length && i < 64; ++index) {\n code = message.charCodeAt(index);\n if (code < 0x80) {\n buffer8[i++] = code;\n } else if (code < 0x800) {\n buffer8[i++] = 0xc0 | (code >> 6);\n buffer8[i++] = 0x80 | (code & 0x3f);\n } else if (code < 0xd800 || code >= 0xe000) {\n buffer8[i++] = 0xe0 | (code >> 12);\n buffer8[i++] = 0x80 | ((code >> 6) & 0x3f);\n buffer8[i++] = 0x80 | (code & 0x3f);\n } else {\n code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));\n buffer8[i++] = 0xf0 | (code >> 18);\n buffer8[i++] = 0x80 | ((code >> 12) & 0x3f);\n buffer8[i++] = 0x80 | ((code >> 6) & 0x3f);\n buffer8[i++] = 0x80 | (code & 0x3f);\n }\n }\n } else {\n for (i = this.start; index < length && i < 64; ++index) {\n code = message.charCodeAt(index);\n if (code < 0x80) {\n blocks[i >> 2] |= code << SHIFT[i++ & 3];\n } else if (code < 0x800) {\n blocks[i >> 2] |= (0xc0 | (code >> 6)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];\n } else if (code < 0xd800 || code >= 0xe000) {\n blocks[i >> 2] |= (0xe0 | (code >> 12)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];\n } else {\n code = 0x10000 + (((code & 0x3ff) << 10) | (message.charCodeAt(++index) & 0x3ff));\n blocks[i >> 2] |= (0xf0 | (code >> 18)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | ((code >> 12) & 0x3f)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | ((code >> 6) & 0x3f)) << SHIFT[i++ & 3];\n blocks[i >> 2] |= (0x80 | (code & 0x3f)) << SHIFT[i++ & 3];\n }\n }\n }\n }\n this.lastByteIndex = i;\n this.bytes += i - this.start;\n if (i >= 64) {\n this.start = i - 64;\n this.hash();\n this.hashed = true;\n } else {\n this.start = i;\n }\n }\n if (this.bytes > 4294967295) {\n this.hBytes += this.bytes / 4294967296 << 0;\n this.bytes = this.bytes % 4294967296;\n }\n return this;\n };\n\n Md5.prototype.finalize = function () {\n if (this.finalized) {\n return;\n }\n this.finalized = true;\n var blocks = this.blocks, i = this.lastByteIndex;\n blocks[i >> 2] |= EXTRA[i & 3];\n if (i >= 56) {\n if (!this.hashed) {\n this.hash();\n }\n blocks[0] = blocks[16];\n blocks[16] = blocks[1] = blocks[2] = blocks[3] =\n blocks[4] = blocks[5] = blocks[6] = blocks[7] =\n blocks[8] = blocks[9] = blocks[10] = blocks[11] =\n blocks[12] = blocks[13] = blocks[14] = blocks[15] = 0;\n }\n blocks[14] = this.bytes << 3;\n blocks[15] = this.hBytes << 3 | this.bytes >>> 29;\n this.hash();\n };\n\n Md5.prototype.hash = function () {\n var a, b, c, d, bc, da, blocks = this.blocks;\n\n if (this.first) {\n a = blocks[0] - 680876937;\n a = (a << 7 | a >>> 25) - 271733879 << 0;\n d = (-1732584194 ^ a & 2004318071) + blocks[1] - 117830708;\n d = (d << 12 | d >>> 20) + a << 0;\n c = (-271733879 ^ (d & (a ^ -271733879))) + blocks[2] - 1126478375;\n c = (c << 17 | c >>> 15) + d << 0;\n b = (a ^ (c & (d ^ a))) + blocks[3] - 1316259209;\n b = (b << 22 | b >>> 10) + c << 0;\n } else {\n a = this.h0;\n b = this.h1;\n c = this.h2;\n d = this.h3;\n a += (d ^ (b & (c ^ d))) + blocks[0] - 680876936;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ (a & (b ^ c))) + blocks[1] - 389564586;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ (d & (a ^ b))) + blocks[2] + 606105819;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ (c & (d ^ a))) + blocks[3] - 1044525330;\n b = (b << 22 | b >>> 10) + c << 0;\n }\n\n a += (d ^ (b & (c ^ d))) + blocks[4] - 176418897;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ (a & (b ^ c))) + blocks[5] + 1200080426;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ (d & (a ^ b))) + blocks[6] - 1473231341;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ (c & (d ^ a))) + blocks[7] - 45705983;\n b = (b << 22 | b >>> 10) + c << 0;\n a += (d ^ (b & (c ^ d))) + blocks[8] + 1770035416;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ (a & (b ^ c))) + blocks[9] - 1958414417;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ (d & (a ^ b))) + blocks[10] - 42063;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ (c & (d ^ a))) + blocks[11] - 1990404162;\n b = (b << 22 | b >>> 10) + c << 0;\n a += (d ^ (b & (c ^ d))) + blocks[12] + 1804603682;\n a = (a << 7 | a >>> 25) + b << 0;\n d += (c ^ (a & (b ^ c))) + blocks[13] - 40341101;\n d = (d << 12 | d >>> 20) + a << 0;\n c += (b ^ (d & (a ^ b))) + blocks[14] - 1502002290;\n c = (c << 17 | c >>> 15) + d << 0;\n b += (a ^ (c & (d ^ a))) + blocks[15] + 1236535329;\n b = (b << 22 | b >>> 10) + c << 0;\n a += (c ^ (d & (b ^ c))) + blocks[1] - 165796510;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ (c & (a ^ b))) + blocks[6] - 1069501632;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ (b & (d ^ a))) + blocks[11] + 643717713;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ (a & (c ^ d))) + blocks[0] - 373897302;\n b = (b << 20 | b >>> 12) + c << 0;\n a += (c ^ (d & (b ^ c))) + blocks[5] - 701558691;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ (c & (a ^ b))) + blocks[10] + 38016083;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ (b & (d ^ a))) + blocks[15] - 660478335;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ (a & (c ^ d))) + blocks[4] - 405537848;\n b = (b << 20 | b >>> 12) + c << 0;\n a += (c ^ (d & (b ^ c))) + blocks[9] + 568446438;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ (c & (a ^ b))) + blocks[14] - 1019803690;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ (b & (d ^ a))) + blocks[3] - 187363961;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ (a & (c ^ d))) + blocks[8] + 1163531501;\n b = (b << 20 | b >>> 12) + c << 0;\n a += (c ^ (d & (b ^ c))) + blocks[13] - 1444681467;\n a = (a << 5 | a >>> 27) + b << 0;\n d += (b ^ (c & (a ^ b))) + blocks[2] - 51403784;\n d = (d << 9 | d >>> 23) + a << 0;\n c += (a ^ (b & (d ^ a))) + blocks[7] + 1735328473;\n c = (c << 14 | c >>> 18) + d << 0;\n b += (d ^ (a & (c ^ d))) + blocks[12] - 1926607734;\n b = (b << 20 | b >>> 12) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[5] - 378558;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[8] - 2022574463;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[11] + 1839030562;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[14] - 35309556;\n b = (b << 23 | b >>> 9) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[1] - 1530992060;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[4] + 1272893353;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[7] - 155497632;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[10] - 1094730640;\n b = (b << 23 | b >>> 9) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[13] + 681279174;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[0] - 358537222;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[3] - 722521979;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[6] + 76029189;\n b = (b << 23 | b >>> 9) + c << 0;\n bc = b ^ c;\n a += (bc ^ d) + blocks[9] - 640364487;\n a = (a << 4 | a >>> 28) + b << 0;\n d += (bc ^ a) + blocks[12] - 421815835;\n d = (d << 11 | d >>> 21) + a << 0;\n da = d ^ a;\n c += (da ^ b) + blocks[15] + 530742520;\n c = (c << 16 | c >>> 16) + d << 0;\n b += (da ^ c) + blocks[2] - 995338651;\n b = (b << 23 | b >>> 9) + c << 0;\n a += (c ^ (b | ~d)) + blocks[0] - 198630844;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[7] + 1126891415;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[14] - 1416354905;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[5] - 57434055;\n b = (b << 21 | b >>> 11) + c << 0;\n a += (c ^ (b | ~d)) + blocks[12] + 1700485571;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[3] - 1894986606;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[10] - 1051523;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[1] - 2054922799;\n b = (b << 21 | b >>> 11) + c << 0;\n a += (c ^ (b | ~d)) + blocks[8] + 1873313359;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[15] - 30611744;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[6] - 1560198380;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[13] + 1309151649;\n b = (b << 21 | b >>> 11) + c << 0;\n a += (c ^ (b | ~d)) + blocks[4] - 145523070;\n a = (a << 6 | a >>> 26) + b << 0;\n d += (b ^ (a | ~c)) + blocks[11] - 1120210379;\n d = (d << 10 | d >>> 22) + a << 0;\n c += (a ^ (d | ~b)) + blocks[2] + 718787259;\n c = (c << 15 | c >>> 17) + d << 0;\n b += (d ^ (c | ~a)) + blocks[9] - 343485551;\n b = (b << 21 | b >>> 11) + c << 0;\n\n if (this.first) {\n this.h0 = a + 1732584193 << 0;\n this.h1 = b - 271733879 << 0;\n this.h2 = c - 1732584194 << 0;\n this.h3 = d + 271733878 << 0;\n this.first = false;\n } else {\n this.h0 = this.h0 + a << 0;\n this.h1 = this.h1 + b << 0;\n this.h2 = this.h2 + c << 0;\n this.h3 = this.h3 + d << 0;\n }\n };\n\n /**\n * @method hex\n * @memberof Md5\n * @instance\n * @description Output hash as hex string\n * @returns {String} Hex string\n * @see {@link md5.hex}\n * @example\n * hash.hex();\n */\n Md5.prototype.hex = function () {\n this.finalize();\n\n var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3;\n\n return HEX_CHARS[(h0 >> 4) & 0x0F] + HEX_CHARS[h0 & 0x0F] +\n HEX_CHARS[(h0 >> 12) & 0x0F] + HEX_CHARS[(h0 >> 8) & 0x0F] +\n HEX_CHARS[(h0 >> 20) & 0x0F] + HEX_CHARS[(h0 >> 16) & 0x0F] +\n HEX_CHARS[(h0 >> 28) & 0x0F] + HEX_CHARS[(h0 >> 24) & 0x0F] +\n HEX_CHARS[(h1 >> 4) & 0x0F] + HEX_CHARS[h1 & 0x0F] +\n HEX_CHARS[(h1 >> 12) & 0x0F] + HEX_CHARS[(h1 >> 8) & 0x0F] +\n HEX_CHARS[(h1 >> 20) & 0x0F] + HEX_CHARS[(h1 >> 16) & 0x0F] +\n HEX_CHARS[(h1 >> 28) & 0x0F] + HEX_CHARS[(h1 >> 24) & 0x0F] +\n HEX_CHARS[(h2 >> 4) & 0x0F] + HEX_CHARS[h2 & 0x0F] +\n HEX_CHARS[(h2 >> 12) & 0x0F] + HEX_CHARS[(h2 >> 8) & 0x0F] +\n HEX_CHARS[(h2 >> 20) & 0x0F] + HEX_CHARS[(h2 >> 16) & 0x0F] +\n HEX_CHARS[(h2 >> 28) & 0x0F] + HEX_CHARS[(h2 >> 24) & 0x0F] +\n HEX_CHARS[(h3 >> 4) & 0x0F] + HEX_CHARS[h3 & 0x0F] +\n HEX_CHARS[(h3 >> 12) & 0x0F] + HEX_CHARS[(h3 >> 8) & 0x0F] +\n HEX_CHARS[(h3 >> 20) & 0x0F] + HEX_CHARS[(h3 >> 16) & 0x0F] +\n HEX_CHARS[(h3 >> 28) & 0x0F] + HEX_CHARS[(h3 >> 24) & 0x0F];\n };\n\n /**\n * @method toString\n * @memberof Md5\n * @instance\n * @description Output hash as hex string\n * @returns {String} Hex string\n * @see {@link md5.hex}\n * @example\n * hash.toString();\n */\n Md5.prototype.toString = Md5.prototype.hex;\n\n /**\n * @method digest\n * @memberof Md5\n * @instance\n * @description Output hash as bytes array\n * @returns {Array} Bytes array\n * @see {@link md5.digest}\n * @example\n * hash.digest();\n */\n Md5.prototype.digest = function () {\n this.finalize();\n\n var h0 = this.h0, h1 = this.h1, h2 = this.h2, h3 = this.h3;\n return [\n h0 & 0xFF, (h0 >> 8) & 0xFF, (h0 >> 16) & 0xFF, (h0 >> 24) & 0xFF,\n h1 & 0xFF, (h1 >> 8) & 0xFF, (h1 >> 16) & 0xFF, (h1 >> 24) & 0xFF,\n h2 & 0xFF, (h2 >> 8) & 0xFF, (h2 >> 16) & 0xFF, (h2 >> 24) & 0xFF,\n h3 & 0xFF, (h3 >> 8) & 0xFF, (h3 >> 16) & 0xFF, (h3 >> 24) & 0xFF\n ];\n };\n\n /**\n * @method array\n * @memberof Md5\n * @instance\n * @description Output hash as bytes array\n * @returns {Array} Bytes array\n * @see {@link md5.array}\n * @example\n * hash.array();\n */\n Md5.prototype.array = Md5.prototype.digest;\n\n /**\n * @method arrayBuffer\n * @memberof Md5\n * @instance\n * @description Output hash as ArrayBuffer\n * @returns {ArrayBuffer} ArrayBuffer\n * @see {@link md5.arrayBuffer}\n * @example\n * hash.arrayBuffer();\n */\n Md5.prototype.arrayBuffer = function () {\n this.finalize();\n\n var buffer = new ArrayBuffer(16);\n var blocks = new Uint32Array(buffer);\n blocks[0] = this.h0;\n blocks[1] = this.h1;\n blocks[2] = this.h2;\n blocks[3] = this.h3;\n return buffer;\n };\n\n /**\n * @method buffer\n * @deprecated This maybe confuse with Buffer in node.js. Please use arrayBuffer instead.\n * @memberof Md5\n * @instance\n * @description Output hash as ArrayBuffer\n * @returns {ArrayBuffer} ArrayBuffer\n * @see {@link md5.buffer}\n * @example\n * hash.buffer();\n */\n Md5.prototype.buffer = Md5.prototype.arrayBuffer;\n\n /**\n * @method base64\n * @memberof Md5\n * @instance\n * @description Output hash as base64 string\n * @returns {String} base64 string\n * @see {@link md5.base64}\n * @example\n * hash.base64();\n */\n Md5.prototype.base64 = function () {\n var v1, v2, v3, base64Str = '', bytes = this.array();\n for (var i = 0; i < 15;) {\n v1 = bytes[i++];\n v2 = bytes[i++];\n v3 = bytes[i++];\n base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] +\n BASE64_ENCODE_CHAR[(v1 << 4 | v2 >>> 4) & 63] +\n BASE64_ENCODE_CHAR[(v2 << 2 | v3 >>> 6) & 63] +\n BASE64_ENCODE_CHAR[v3 & 63];\n }\n v1 = bytes[i];\n base64Str += BASE64_ENCODE_CHAR[v1 >>> 2] +\n BASE64_ENCODE_CHAR[(v1 << 4) & 63] +\n '==';\n return base64Str;\n };\n\n var exports = createMethod();\n\n if (COMMON_JS) {\n module.exports = exports;\n } else {\n /**\n * @method md5\b\n * @description Md5 hash function, export to global in browsers.\n * @param {String|Array|Uint8Array|ArrayBuffer} message message to hash\n * @returns {String} md5 hashes\n * @example\n * md5(''); // d41d8cd98f00b204e9800998ecf8427e\n * md5('The quick brown fox jumps over the lazy dog'); // 9e107d9d372bb6826bd81d3542a419d6\n * md5('The quick brown fox jumps over the lazy dog.'); // e4d909c290d0fb1ca068ffaddf22cbd0\n *\n * // It also supports UTF-8 encoding\n * md5('中文'); // a7bac2239fcdcb3a067903d8077c4a07\n *\n * // It also supports byte `Array`, `Uint8Array`, `ArrayBuffer`\n * md5([]); // d41d8cd98f00b204e9800998ecf8427e\n * md5(new Uint8Array([])); // d41d8cd98f00b204e9800998ecf8427e\n */\n root.md5 = exports;\n if (AMD) {\n define(function () {\n return exports;\n });\n }\n }\n})();\n", "/* global __filename, Promise */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport JitsiTrack from './JitsiTrack';\nimport JitsiTrackError from '../../JitsiTrackError';\nimport {\n TRACK_IS_DISPOSED,\n TRACK_NO_STREAM_FOUND\n} from '../../JitsiTrackErrors';\nimport {\n LOCAL_TRACK_STOPPED,\n NO_DATA_FROM_SOURCE,\n TRACK_MUTE_CHANGED\n} from '../../JitsiTrackEvents';\nimport browser from '../browser';\nimport RTCUtils from './RTCUtils';\nimport CameraFacingMode from '../../service/RTC/CameraFacingMode';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport VideoType from '../../service/RTC/VideoType';\nimport {\n NO_BYTES_SENT,\n TRACK_UNMUTED,\n createNoDataFromSourceEvent\n} from '../../service/statistics/AnalyticsEvents';\nimport Statistics from '../statistics/statistics';\n\nconst logger = getLogger(__filename);\n\n/**\n * Represents a single media track(either audio or video).\n * One JitsiLocalTrack corresponds to one WebRTC MediaStreamTrack.\n */\nexport default class JitsiLocalTrack extends JitsiTrack {\n /**\n * Constructs new JitsiLocalTrack instance.\n *\n * @constructor\n * @param {Object} trackInfo\n * @param {number} trackInfo.rtcId the ID assigned by the RTC module\n * @param trackInfo.stream WebRTC MediaStream, parent of the track\n * @param trackInfo.track underlying WebRTC MediaStreamTrack for new\n * JitsiRemoteTrack\n * @param trackInfo.mediaType the MediaType of the JitsiRemoteTrack\n * @param trackInfo.videoType the VideoType of the JitsiRemoteTrack\n * @param trackInfo.effects the effects array contains the effect instance to use\n * @param trackInfo.resolution the video resolution if it's a video track\n * @param trackInfo.deviceId the ID of the local device for this track\n * @param trackInfo.facingMode the camera facing mode used in getUserMedia\n * call\n * @param {sourceId} trackInfo.sourceId - The id of the desktop sharing\n * source. NOTE: defined for desktop sharing tracks only.\n */\n constructor({\n deviceId,\n facingMode,\n mediaType,\n resolution,\n rtcId,\n sourceId,\n sourceType,\n stream,\n track,\n videoType,\n effects = []\n }) {\n super(\n /* conference */ null,\n stream,\n track,\n /* streamInactiveHandler */ () => this.emit(LOCAL_TRACK_STOPPED),\n mediaType,\n videoType);\n\n this._setEffectInProgress = false;\n const effect = effects.find(e => e.isEnabled(this));\n\n if (effect) {\n this._startStreamEffect(effect);\n }\n\n /**\n * The ID assigned by the RTC module on instance creation.\n *\n * @type {number}\n */\n this.rtcId = rtcId;\n this.sourceId = sourceId;\n this.sourceType = sourceType;\n\n if (browser.usesNewGumFlow()) {\n // Get the resolution from the track itself because it cannot be\n // certain which resolution webrtc has fallen back to using.\n this.resolution = track.getSettings().height;\n\n // Cache the constraints of the track in case of any this track\n // model needs to call getUserMedia again, such as when unmuting.\n this._constraints = track.getConstraints();\n\n // Safari returns an empty constraints object, construct the constraints using getSettings.\n if (!Object.keys(this._constraints).length && videoType === VideoType.CAMERA) {\n this._constraints = {\n height: track.getSettings().height,\n width: track.getSettings().width\n };\n }\n } else {\n // FIXME Currently, Firefox is ignoring our constraints about\n // resolutions so we do not store it, to avoid wrong reporting of\n // local track resolution.\n this.resolution = browser.isFirefox() ? null : resolution;\n }\n\n this.deviceId = deviceId;\n\n /**\n * The Promise which represents the progress of a previously\n * queued/scheduled {@link _setMuted} (from the point of view of\n * {@link _queueSetMuted}).\n *\n * @private\n * @type {Promise}\n */\n this._prevSetMuted = Promise.resolve();\n\n /**\n * The facing mode of the camera from which this JitsiLocalTrack\n * instance was obtained.\n *\n * @private\n * @type {CameraFacingMode|undefined}\n */\n this._facingMode = facingMode;\n\n // Currently there is no way to know the MediaStreamTrack ended due to\n // to device disconnect in Firefox through e.g. \"readyState\" property.\n // Instead we will compare current track's label with device labels from\n // enumerateDevices() list.\n this._trackEnded = false;\n\n /**\n * Indicates whether data has been sent or not.\n */\n this._hasSentData = false;\n\n /**\n * Used only for detection of audio problems. We want to check only once\n * whether the track is sending data ot not. This flag is set to false\n * after the check.\n */\n this._testDataSent = true;\n\n // Currently there is no way to determine with what device track was\n // created (until getConstraints() support), however we can associate\n // tracks with real devices obtained from enumerateDevices() call as\n // soon as it's called.\n // NOTE: this.deviceId corresponds to the device id specified in GUM constraints and this._realDeviceId seems to\n // correspond to the id of a matching device from the available device list.\n this._realDeviceId = this.deviceId === '' ? undefined : this.deviceId;\n\n this._trackMutedTS = 0;\n\n this._onDeviceListWillChange = devices => {\n const oldRealDeviceId = this._realDeviceId;\n\n this._setRealDeviceIdFromDeviceList(devices);\n\n if (\n // Mark track as ended for those browsers that do not support\n // \"readyState\" property. We do not touch tracks created with\n // default device ID \"\".\n (typeof this.getTrack().readyState === 'undefined'\n && typeof this._realDeviceId !== 'undefined'\n && !devices.find(d => d.deviceId === this._realDeviceId))\n\n // If there was an associated realDeviceID and after the device change the realDeviceId is undefined\n // then the associated device has been disconnected and the _trackEnded flag needs to be set. In\n // addition on some Chrome versions the readyState property is set after the device change event is\n // triggered which causes issues in jitsi-meet with the selection of a new device because we don't\n // detect that the old one was removed.\n || (typeof oldRealDeviceId !== 'undefined' && typeof this._realDeviceId === 'undefined')\n ) {\n this._trackEnded = true;\n }\n };\n\n // Subscribe each created local audio track to\n // RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED event. This is different from\n // handling this event for remote tracks (which are handled in RTC.js),\n // because there might be local tracks not attached to a conference.\n if (this.isAudioTrack() && RTCUtils.isDeviceChangeAvailable('output')) {\n this._onAudioOutputDeviceChanged = this.setAudioOutput.bind(this);\n RTCUtils.addListener(\n RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,\n this._onAudioOutputDeviceChanged);\n }\n\n RTCUtils.addListener(RTCEvents.DEVICE_LIST_WILL_CHANGE, this._onDeviceListWillChange);\n\n this._initNoDataFromSourceHandlers();\n }\n\n /**\n * Returns if associated MediaStreamTrack is in the 'ended' state\n *\n * @returns {boolean}\n */\n isEnded() {\n if (this.isVideoTrack() && this.isMuted()) {\n // If a video track is muted the readyState will be ended, that's why we need to rely only on the\n // _trackEnded flag.\n return this._trackEnded;\n }\n\n return this.getTrack().readyState === 'ended' || this._trackEnded;\n }\n\n /**\n * Sets handlers to the MediaStreamTrack object that will detect camera\n * issues.\n */\n _initNoDataFromSourceHandlers() {\n if (!this._isNoDataFromSourceEventsEnabled()) {\n return;\n }\n\n this._setHandler('track_mute', () => {\n this._trackMutedTS = window.performance.now();\n this._fireNoDataFromSourceEvent();\n });\n\n this._setHandler('track_unmute', () => {\n this._fireNoDataFromSourceEvent();\n Statistics.sendAnalyticsAndLog(\n TRACK_UNMUTED,\n {\n 'media_type': this.getType(),\n 'track_type': 'local',\n value: window.performance.now() - this._trackMutedTS\n });\n });\n\n if (this.isVideoTrack() && this.videoType === VideoType.CAMERA) {\n this._setHandler('track_ended', () => {\n if (!this.isReceivingData()) {\n this._fireNoDataFromSourceEvent();\n }\n });\n }\n }\n\n /**\n * Returns true if no data from source events are enabled for this JitsiLocalTrack and false otherwise.\n *\n * @returns {boolean} - True if no data from source events are enabled for this JitsiLocalTrack and false otherwise.\n */\n _isNoDataFromSourceEventsEnabled() {\n // Disable the events for screen sharing.\n return !this.isVideoTrack() || this.videoType !== VideoType.DESKTOP;\n }\n\n /**\n * Fires NO_DATA_FROM_SOURCE event and logs it to analytics and callstats.\n */\n _fireNoDataFromSourceEvent() {\n const value = !this.isReceivingData();\n\n this.emit(NO_DATA_FROM_SOURCE, value);\n\n // FIXME: Should we report all of those events\n Statistics.sendAnalytics(createNoDataFromSourceEvent(this.getType(), value));\n Statistics.sendLog(JSON.stringify({\n name: NO_DATA_FROM_SOURCE,\n log: value\n }));\n }\n\n /**\n * Sets real device ID by comparing track information with device\n * information. This is temporary solution until getConstraints() method\n * will be implemented in browsers.\n *\n * @param {MediaDeviceInfo[]} devices - list of devices obtained from\n * enumerateDevices() call\n */\n _setRealDeviceIdFromDeviceList(devices) {\n const track = this.getTrack();\n const kind = `${track.kind}input`;\n let device = devices.find(d => d.kind === kind && d.label === track.label);\n\n if (!device && this._realDeviceId === 'default') { // the default device has been changed.\n // If the default device was 'A' and the default device is changed to 'B' the label for the track will\n // remain 'Default - A' but the label for the device in the device list will be updated to 'A'. That's\n // why in order to match it we need to remove the 'Default - ' part.\n const label = (track.label || '').replace('Default - ', '');\n\n device = devices.find(d => d.kind === kind && d.label === label);\n }\n\n if (device) {\n this._realDeviceId = device.deviceId;\n } else {\n this._realDeviceId = undefined;\n }\n }\n\n /**\n * Sets the stream property of JitsiLocalTrack object and sets all stored\n * handlers to it.\n *\n * @param {MediaStream} stream the new stream.\n * @protected\n */\n _setStream(stream) {\n super._setStream(stream);\n\n if (stream) {\n // Store the MSID for video mute/unmute purposes.\n this.storedMSID = this.getMSID();\n logger.debug(`Setting new MSID: ${this.storedMSID} on ${this}`);\n } else {\n logger.debug(`Setting 'null' stream on ${this}`);\n }\n }\n\n /**\n * Starts the effect process and returns the modified stream.\n *\n * @private\n * @param {*} effect - Represents effect instance\n * @returns {void}\n */\n _startStreamEffect(effect) {\n this._streamEffect = effect;\n this._originalStream = this.stream;\n this._setStream(this._streamEffect.startEffect(this._originalStream));\n }\n\n /**\n * Stops the effect process and returns the original stream.\n *\n * @private\n * @returns {void}\n */\n _stopStreamEffect() {\n if (this._streamEffect) {\n this._streamEffect.stopEffect();\n this._setStream(this._originalStream);\n }\n }\n\n /**\n * Stops the currently used effect (if there is one) and starts the passed effect (if there is one).\n *\n * @param {Object|undefined} effect - The new effect to be set.\n */\n _switchStreamEffect(effect) {\n if (this._streamEffect) {\n this._stopStreamEffect();\n this._streamEffect = undefined;\n }\n if (effect) {\n this._startStreamEffect(effect);\n }\n }\n\n /**\n * Sets the effect and switches between the modified stream and original one.\n *\n * @param {Object} effect - Represents the effect instance to be used.\n * @returns {Promise}\n */\n setEffect(effect) {\n if (typeof this._streamEffect === 'undefined' && typeof effect === 'undefined') {\n return Promise.resolve();\n }\n\n if (typeof effect !== 'undefined' && !effect.isEnabled(this)) {\n return Promise.reject(new Error('Incompatible effect instance!'));\n }\n\n if (this._setEffectInProgress === true) {\n return Promise.reject(new Error('setEffect already in progress!'));\n }\n\n // In case we have an audio track that is being enhanced with an effect, we still want it to be applied,\n // even if the track is muted. Where as for video the actual track doesn't exists if it's muted.\n if (this.isMuted() && !this.isAudioTrack()) {\n this._streamEffect = effect;\n\n return Promise.resolve();\n }\n\n const conference = this.conference;\n\n if (!conference) {\n this._switchStreamEffect(effect);\n\n return Promise.resolve();\n }\n\n this._setEffectInProgress = true;\n\n if (browser.usesUnifiedPlan()) {\n this._switchStreamEffect(effect);\n if (this.isVideoTrack()) {\n this.containers.forEach(cont => RTCUtils.attachMediaStream(cont, this.stream));\n }\n\n return conference.replaceTrack(this, this)\n .then(() => {\n this._setEffectInProgress = false;\n })\n .catch(error => {\n this._setEffectInProgress = false;\n this._switchStreamEffect();\n logger.error('Failed to switch to the new stream!', error);\n throw error;\n });\n }\n\n // TODO: Create new JingleSessionPC method for replacing a stream in JitsiLocalTrack without offer answer.\n return conference.removeTrack(this)\n .then(() => {\n this._switchStreamEffect(effect);\n if (this.isVideoTrack()) {\n this.containers.forEach(cont => RTCUtils.attachMediaStream(cont, this.stream));\n }\n\n return conference.addTrack(this);\n })\n .then(() => {\n this._setEffectInProgress = false;\n })\n .catch(error => {\n // Any error will be not recovarable and will trigger CONFERENCE_FAILED event. But let's try to cleanup\n // everyhting related to the effect functionality.\n this._setEffectInProgress = false;\n this._switchStreamEffect();\n logger.error('Failed to switch to the new stream!', error);\n throw error;\n });\n }\n\n /**\n * Asynchronously mutes this track.\n *\n * @returns {Promise}\n */\n mute() {\n return this._queueSetMuted(true);\n }\n\n /**\n * Asynchronously unmutes this track.\n *\n * @returns {Promise}\n */\n unmute() {\n return this._queueSetMuted(false);\n }\n\n /**\n * Initializes a new Promise to execute {@link #_setMuted}. May be called\n * multiple times in a row and the invocations of {@link #_setMuted} and,\n * consequently, {@link #mute} and/or {@link #unmute} will be resolved in a\n * serialized fashion.\n *\n * @param {boolean} muted - The value to invoke _setMuted with.\n * @returns {Promise}\n */\n _queueSetMuted(muted) {\n const setMuted = this._setMuted.bind(this, muted);\n\n this._prevSetMuted = this._prevSetMuted.then(setMuted, setMuted);\n\n return this._prevSetMuted;\n }\n\n /**\n * Mutes / unmutes this track.\n *\n * @param {boolean} muted - If true, this track will be muted;\n * otherwise, this track will be unmuted.\n * @private\n * @returns {Promise}\n */\n _setMuted(muted) {\n if (this.isMuted() === muted) {\n return Promise.resolve();\n }\n\n if (this.disposed) {\n return Promise.reject(new JitsiTrackError(TRACK_IS_DISPOSED));\n }\n\n let promise = Promise.resolve();\n\n // A function that will print info about muted status transition\n const logMuteInfo = () => logger.info(`Mute ${this}: ${muted}`);\n\n if (this.isAudioTrack()\n || this.videoType === VideoType.DESKTOP\n || !browser.doesVideoMuteByStreamRemove()) {\n logMuteInfo();\n if (this.track) {\n this.track.enabled = !muted;\n }\n } else if (muted) {\n promise = new Promise((resolve, reject) => {\n logMuteInfo();\n this._removeStreamFromConferenceAsMute(\n () => {\n if (this._streamEffect) {\n this._stopStreamEffect();\n }\n\n // FIXME: Maybe here we should set the SRC for the\n // containers to something\n // We don't want any events to be fired on this stream\n this._unregisterHandlers();\n this.stopStream();\n this._setStream(null);\n resolve();\n },\n reject);\n });\n } else {\n logMuteInfo();\n\n // This path is only for camera.\n const streamOptions = {\n cameraDeviceId: this.getDeviceId(),\n devices: [ MediaType.VIDEO ],\n effects: this._streamEffect ? [ this._streamEffect ] : [],\n facingMode: this.getCameraFacingMode()\n };\n\n if (browser.usesNewGumFlow()) {\n promise\n = RTCUtils.newObtainAudioAndVideoPermissions(Object.assign(\n {},\n streamOptions,\n { constraints: { video: this._constraints } }));\n } else {\n if (this.resolution) {\n streamOptions.resolution = this.resolution;\n }\n\n promise\n = RTCUtils.obtainAudioAndVideoPermissions(streamOptions);\n }\n\n promise.then(streamsInfo => {\n // The track kind for presenter track is video as well.\n const mediaType = this.getType() === MediaType.PRESENTER ? MediaType.VIDEO : this.getType();\n const streamInfo\n = browser.usesNewGumFlow()\n ? streamsInfo.find(\n info => info.track.kind === mediaType)\n : streamsInfo.find(\n info => info.mediaType === mediaType);\n\n if (streamInfo) {\n this._setStream(streamInfo.stream);\n this.track = streamInfo.track;\n\n // This is not good when video type changes after\n // unmute, but let's not crash here\n if (this.videoType !== streamInfo.videoType) {\n logger.warn(\n `${this}: video type has changed after unmute!`,\n this.videoType, streamInfo.videoType);\n this.videoType = streamInfo.videoType;\n }\n } else {\n throw new JitsiTrackError(TRACK_NO_STREAM_FOUND);\n }\n\n if (this._streamEffect) {\n this._startStreamEffect(this._streamEffect);\n }\n\n this.containers.map(\n cont => RTCUtils.attachMediaStream(cont, this.stream));\n\n return this._addStreamToConferenceAsUnmute();\n });\n }\n\n return promise\n .then(() => this._sendMuteStatus(muted))\n .then(() => this.emit(TRACK_MUTE_CHANGED, this));\n }\n\n /**\n * Adds stream to conference and marks it as \"unmute\" operation.\n *\n * @private\n * @returns {Promise}\n */\n _addStreamToConferenceAsUnmute() {\n if (!this.conference) {\n return Promise.resolve();\n }\n\n // FIXME it would be good to not included conference as part of this\n // process. Only TraceablePeerConnections to which the track is attached\n // should care about this action. The TPCs to which the track is not\n // attached can sync up when track is re-attached.\n // A problem with that is that the \"modify sources\" queue is part of\n // the JingleSessionPC and it would be excluded from the process. One\n // solution would be to extract class between TPC and JingleSessionPC\n // which would contain the queue and would notify the signaling layer\n // when local SSRCs are changed. This would help to separate XMPP from\n // the RTC module.\n return new Promise((resolve, reject) => {\n this.conference._addLocalTrackAsUnmute(this)\n .then(resolve, error => reject(new Error(error)));\n });\n }\n\n /**\n * Removes stream from conference and marks it as \"mute\" operation.\n *\n * @param {Function} successCallback will be called on success\n * @param {Function} errorCallback will be called on error\n * @private\n */\n _removeStreamFromConferenceAsMute(successCallback, errorCallback) {\n if (!this.conference) {\n successCallback();\n\n return;\n }\n this.conference._removeLocalTrackAsMute(this).then(\n successCallback,\n error => errorCallback(new Error(error)));\n }\n\n /**\n * Sends mute status for a track to conference if any.\n *\n * @param {boolean} mute - If track is muted.\n * @private\n * @returns {Promise}\n */\n _sendMuteStatus(mute) {\n if (!this.conference || !this.conference.room) {\n return Promise.resolve();\n }\n\n return new Promise(resolve => {\n this.conference.room[\n this.isAudioTrack()\n ? 'setAudioMute'\n : 'setVideoMute'](mute, resolve);\n });\n }\n\n /**\n * @inheritdoc\n *\n * Stops sending the media track. And removes it from the HTML.\n * NOTE: Works for local tracks only.\n *\n * @extends JitsiTrack#dispose\n * @returns {Promise}\n */\n dispose() {\n this._switchStreamEffect();\n\n let promise = Promise.resolve();\n\n if (this.conference) {\n promise = this.conference.removeTrack(this);\n }\n\n if (this.stream) {\n this.stopStream();\n this.detach();\n }\n\n RTCUtils.removeListener(RTCEvents.DEVICE_LIST_WILL_CHANGE, this._onDeviceListWillChange);\n\n if (this._onAudioOutputDeviceChanged) {\n RTCUtils.removeListener(RTCEvents.AUDIO_OUTPUT_DEVICE_CHANGED,\n this._onAudioOutputDeviceChanged);\n }\n\n return promise.then(() => super.dispose());\n }\n\n /**\n * Returns true - if the stream is muted and false\n * otherwise.\n *\n * @returns {boolean} true - if the stream is muted and\n * false otherwise.\n */\n isMuted() {\n // this.stream will be null when we mute local video on Chrome\n if (!this.stream) {\n return true;\n }\n if (this.isVideoTrack() && !this.isActive()) {\n return true;\n }\n\n return !this.track || !this.track.enabled;\n }\n\n /**\n * Sets the JitsiConference object associated with the track. This is temp\n * solution.\n *\n * @param conference the JitsiConference object\n */\n _setConference(conference) {\n this.conference = conference;\n\n // We want to keep up with postponed events which should have been fired\n // on \"attach\" call, but for local track we not always have the\n // conference before attaching. However this may result in duplicated\n // events if they have been triggered on \"attach\" already.\n for (let i = 0; i < this.containers.length; i++) {\n this._maybeFireTrackAttached(this.containers[i]);\n }\n }\n\n /**\n * Returns true.\n *\n * @returns {boolean} true\n */\n isLocal() {\n return true;\n }\n\n /**\n * Returns device id associated with track.\n *\n * @returns {string}\n */\n getDeviceId() {\n return this._realDeviceId || this.deviceId;\n }\n\n /**\n * Returns the participant id which owns the track.\n *\n * @returns {string} the id of the participants. It corresponds to the\n * Colibri endpoint id/MUC nickname in case of Jitsi-meet.\n */\n getParticipantId() {\n return this.conference && this.conference.myUserId();\n }\n\n /**\n * Handles bytes sent statistics.\n *\n * @param {TraceablePeerConnection} tpc the source of the \"bytes sent\" stat\n * @param {number} bytesSent the new value\n * NOTE: used only for audio tracks to detect audio issues.\n */\n _onByteSentStatsReceived(tpc, bytesSent) {\n if (bytesSent > 0) {\n this._hasSentData = true;\n }\n const iceConnectionState = tpc.getConnectionState();\n\n if (this._testDataSent && iceConnectionState === 'connected') {\n setTimeout(() => {\n if (!this._hasSentData) {\n logger.warn(`${this} 'bytes sent' <= 0: \\\n ${bytesSent}`);\n\n Statistics.analytics.sendEvent(NO_BYTES_SENT, { 'media_type': this.getType() });\n }\n }, 3000);\n this._testDataSent = false;\n }\n }\n\n /**\n * Returns facing mode for video track from camera. For other cases (e.g.\n * audio track or 'desktop' video track) returns undefined.\n *\n * @returns {CameraFacingMode|undefined}\n */\n getCameraFacingMode() {\n if (this.isVideoTrack() && this.videoType === VideoType.CAMERA) {\n // MediaStreamTrack#getSettings() is not implemented in many\n // browsers, so we need feature checking here. Progress on the\n // respective browser's implementation can be tracked at\n // https://bugs.chromium.org/p/webrtc/issues/detail?id=2481 for\n // Chromium and https://bugzilla.mozilla.org/show_bug.cgi?id=1213517\n // for Firefox. Even if a browser implements getSettings() already,\n // it might still not return anything for 'facingMode'.\n let trackSettings;\n\n try {\n trackSettings = this.track.getSettings();\n } catch (e) {\n // XXX React-native-webrtc, for example, defines\n // MediaStreamTrack#getSettings() but the implementation throws\n // a \"Not implemented\" Error.\n }\n if (trackSettings && 'facingMode' in trackSettings) {\n return trackSettings.facingMode;\n }\n\n if (typeof this._facingMode !== 'undefined') {\n return this._facingMode;\n }\n\n // In most cases we are showing a webcam. So if we've gotten here,\n // it should be relatively safe to assume that we are probably\n // showing the user-facing camera.\n return CameraFacingMode.USER;\n }\n\n return undefined;\n }\n\n /**\n * Stops the associated MediaStream.\n */\n stopStream() {\n /**\n * Indicates that we are executing {@link #stopStream} i.e.\n * {@link RTCUtils#stopMediaStream} for the MediaStream\n * associated with this JitsiTrack instance.\n *\n * @private\n * @type {boolean}\n */\n this._stopStreamInProgress = true;\n\n try {\n RTCUtils.stopMediaStream(this.stream);\n } finally {\n this._stopStreamInProgress = false;\n }\n }\n\n /**\n * Switches the camera facing mode if the WebRTC implementation supports the\n * custom MediaStreamTrack._switchCamera method. Currently, the method in\n * question is implemented in react-native-webrtc only. When such a WebRTC\n * implementation is executing, the method is the preferred way to switch\n * between the front/user-facing and the back/environment-facing cameras\n * because it will likely be (as is the case of react-native-webrtc)\n * noticeably faster that creating a new MediaStreamTrack via a new\n * getUserMedia call with the switched facingMode constraint value.\n * Moreover, the approach with a new getUserMedia call may not even work:\n * WebRTC on Android and iOS is either very slow to open the camera a second\n * time or plainly freezes attempting to do that.\n */\n _switchCamera() {\n if (this.isVideoTrack()\n && this.videoType === VideoType.CAMERA\n && typeof this.track._switchCamera === 'function') {\n this.track._switchCamera();\n\n this._facingMode\n = this._facingMode === CameraFacingMode.ENVIRONMENT\n ? CameraFacingMode.USER\n : CameraFacingMode.ENVIRONMENT;\n }\n }\n\n /**\n * Checks whether the attached MediaStream is receiving data from source or\n * not. If the stream property is null(because of mute or another reason)\n * this method will return false.\n * NOTE: This method doesn't indicate problem with the streams directly.\n * For example in case of video mute the method will return false or if the\n * user has disposed the track.\n *\n * @returns {boolean} true if the stream is receiving data and false\n * this otherwise.\n */\n isReceivingData() {\n if (this.isVideoTrack()\n && (this.isMuted() || this._stopStreamInProgress || this.videoType === VideoType.DESKTOP)) {\n return true;\n }\n\n if (!this.stream) {\n return false;\n }\n\n // In older version of the spec there is no muted property and\n // readyState can have value muted. In the latest versions\n // readyState can have values \"live\" and \"ended\" and there is\n // muted boolean property. If the stream is muted that means that\n // we aren't receiving any data from the source. We want to notify\n // the users for error if the stream is muted or ended on it's\n // creation.\n\n // For video blur enabled use the original video stream\n const stream = this._effectEnabled ? this._originalStream : this.stream;\n\n return stream.getTracks().some(track =>\n (!('readyState' in track) || track.readyState === 'live')\n && (!('muted' in track) || track.muted !== true));\n }\n\n /**\n * Creates a text representation of this local track instance.\n *\n * @return {string}\n */\n toString() {\n return `LocalTrack[${this.rtcId},${this.getType()}]`;\n }\n}\n", "import { EventEmitter } from 'events';\nimport { getLogger } from 'jitsi-meet-logger';\n\nimport * as JitsiConferenceEvents from '../../JitsiConferenceEvents';\n\nimport { VAD_SCORE_PUBLISHED, DETECTOR_STATE_CHANGE } from './DetectionEvents';\nimport TrackVADEmitter from './TrackVADEmitter';\n\nconst logger = getLogger(__filename);\n\n/**\n * Sample rate of TrackVADEmitter, it defines how many audio samples are processed at a time.\n * @type {number}\n */\nconst VAD_EMITTER_SAMPLE_RATE = 4096;\n\n/**\n * Connects a TrackVADEmitter to the target conference local audio track and manages various services that use\n * the data to produce audio analytics (VADTalkMutedDetection and VADNoiseDetection).\n */\nexport default class VADAudioAnalyser extends EventEmitter {\n /**\n * Creates VADAudioAnalyser\n * @param {JitsiConference} conference - JitsiConference instance that created us.\n * @param {Object} createVADProcessor - Function that creates a Voice activity detection processor. The processor\n * needs to implement the following functions:\n * - getSampleLength() - Returns the sample size accepted by getSampleLength.\n * - getRequiredPCMFrequency() - Returns the PCM frequency at which the processor operates.\n * - calculateAudioFrameVAD(pcmSample) - Process a 32 float pcm sample of getSampleLength size.\n * @constructor\n */\n constructor(conference, createVADProcessor) {\n super();\n\n /**\n * Member function that instantiates a VAD processor.\n */\n this._createVADProcessor = createVADProcessor;\n\n /**\n * Current {@link TrackVADEmitter}. VAD Emitter uses a {@link JitsiLocalTrack} and VAD processor to generate\n * period voice probability scores.\n */\n this._vadEmitter = null;\n\n /**\n * Current state of the _vadEmitter\n */\n this._isVADEmitterRunning = false;\n\n /**\n * Array of currently attached VAD processing services.\n */\n this._detectionServices = [];\n\n /**\n * Promise used to chain create and destroy operations associated with TRACK_ADDED and TRACK_REMOVED events\n * coming from the conference.\n * Because we have an async created component (VAD Processor) we need to make sure that it's initialized before\n * we destroy it ( when changing the device for instance), or when we use it from an external point of entry\n * i.e. (TRACK_MUTE_CHANGED event callback).\n */\n this._vadInitTracker = Promise.resolve();\n\n /**\n * Listens for {@link TrackVADEmitter} events and processes them.\n */\n this._processVADScore = this._processVADScore.bind(this);\n\n conference.on(JitsiConferenceEvents.TRACK_ADDED, this._trackAdded.bind(this));\n conference.on(JitsiConferenceEvents.TRACK_REMOVED, this._trackRemoved.bind(this));\n conference.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED, this._trackMuteChanged.bind(this));\n }\n\n /**\n * Attach a VAD detector service to the analyser and handle it's state changes.\n *\n * @param {Object} vadTMDetector\n */\n addVADDetectionService(vadService) {\n this._detectionServices.push(vadService);\n vadService.on(DETECTOR_STATE_CHANGE, () => {\n // When the state of a detector changes check if there are any active detectors attached so that\n // the _vadEmitter doesn't run needlessly.\n const activeDetector = this._detectionServices.filter(detector => detector.isActive() === true);\n\n // If there are no active detectors running and the vadEmitter is running then stop the emitter as it is\n // uses a considerable amount of CPU. Otherwise start the service if it's stopped and there is a detector\n // that needs it.\n if (!activeDetector.length && this._isVADEmitterRunning) {\n this._stopVADEmitter();\n } else if (!this._isVADEmitterRunning) {\n this._startVADEmitter();\n }\n });\n }\n\n /**\n * Start the {@link TrackVADEmitter} and attach the event listener.\n * @returns {void}\n */\n _startVADEmitter() {\n this._vadEmitter.on(VAD_SCORE_PUBLISHED, this._processVADScore);\n this._vadEmitter.start();\n this._isVADEmitterRunning = true;\n }\n\n /**\n * Stop the {@link TrackVADEmitter} and detach the event listener.\n * @returns {void}\n */\n _stopVADEmitter() {\n this._vadEmitter.removeListener(VAD_SCORE_PUBLISHED, this._processVADScore);\n this._vadEmitter.stop();\n this._isVADEmitterRunning = false;\n }\n\n /**\n * Listens for {@link TrackVADEmitter} events and directs them to attached services as needed.\n *\n * @param {Object} vadScore -VAD score emitted by {@link TrackVADEmitter}\n * @param {Date} vadScore.timestamp - Exact time at which processed PCM sample was generated.\n * @param {number} vadScore.score - VAD score on a scale from 0 to 1 (i.e. 0.7)\n * @param {Float32Array} pcmData - Raw PCM data with which the VAD score was calculated.\n * @param {string} vadScore.deviceId - Device id of the associated track.\n * @listens VAD_SCORE_PUBLISHED\n */\n _processVADScore(vadScore) {\n for (const detector of this._detectionServices) {\n detector.processVADScore(vadScore);\n }\n }\n\n /**\n * Change the isMuted state of all attached detection services.\n *\n * @param {boolean} isMuted\n */\n _changeDetectorsMuteState(isMuted) {\n for (const detector of this._detectionServices) {\n detector.changeMuteState(isMuted);\n }\n }\n\n /**\n * Notifies the detector that a track was added to the associated {@link JitsiConference}.\n * Only take into account local audio tracks.\n * @param {JitsiTrack} track - The added track.\n * @returns {void}\n * @listens TRACK_ADDED\n */\n _trackAdded(track) {\n if (track.isLocalAudioTrack()) {\n // Keep a track promise so we take into account successive TRACK_ADD events being generated so that we\n // destroy/create the processing context in the proper order.\n this._vadInitTracker = this._vadInitTracker.then(() => this._createVADProcessor())\n .then(vadProcessor =>\n TrackVADEmitter.create(track.getDeviceId(), VAD_EMITTER_SAMPLE_RATE, vadProcessor)\n )\n .then(vadEmitter => {\n logger.debug('Created VAD emitter for track: ', track.getTrackLabel());\n\n this._vadEmitter = vadEmitter;\n\n // Iterate through the detection services and set their appropriate mute state, depending on\n // service this will trigger a DETECTOR_STATE_CHANGE which in turn might start the _vadEmitter.\n this._changeDetectorsMuteState(track.isMuted());\n });\n }\n }\n\n /**\n * Notifies the detector that the mute state of a {@link JitsiConference} track has changed. Only takes into account\n * local audio tracks.\n * @param {JitsiTrack} track - The track whose mute state has changed.\n * @returns {void}\n * @listens TRACK_MUTE_CHANGED\n */\n _trackMuteChanged(track) {\n if (track.isLocalAudioTrack()) {\n // On a mute toggle reset the state.\n this._vadInitTracker = this._vadInitTracker.then(() => {\n // Set mute status for the attached detection services.\n this._changeDetectorsMuteState(track.isMuted());\n });\n }\n }\n\n /**\n * Notifies the detector that a track associated with the {@link JitsiConference} was removed. Only takes into\n * account local audio tracks. Cleans up resources associated with the track and resets the processing context.\n *\n * @param {JitsiTrack} track - The removed track.\n * @returns {void}\n * @listens TRACK_REMOVED\n */\n _trackRemoved(track) {\n if (track.isLocalAudioTrack()) {\n // Use the promise to make sure operations are in sequence.\n this._vadInitTracker = this._vadInitTracker.then(() => {\n logger.debug('Removing track from VAD detection - ', track.getTrackLabel());\n\n // Track was removed, clean up and set appropriate states.\n if (this._vadEmitter) {\n this._stopVADEmitter();\n this._vadEmitter.destroy();\n this._vadEmitter = null;\n }\n\n // Reset state of detectors when active track is removed.\n for (const detector of this._detectionServices) {\n detector.reset();\n }\n });\n }\n }\n\n\n}\n", "import { $iq } from 'strophe.js';\n\nimport recordingXMLUtils from './recordingXMLUtils';\n\n/**\n * Represents a recording session.\n */\nexport default class JibriSession {\n /**\n * Initializes a new JibriSession instance.\n *\n * @constructor\n */\n constructor(options = {}) {\n this._connection = options.connection;\n this._mode = options.mode;\n\n this._setSessionID(options.sessionID);\n this.setStatus(options.status);\n }\n\n /**\n * Returns the error related to the session instance, if any.\n *\n * @returns {string|undefined}\n */\n getError() {\n return this._error;\n }\n\n /**\n * Returns the session ID of the session instance.\n *\n * @returns {string|undefined}\n */\n getID() {\n return this._sessionID;\n }\n\n /**\n * Returns the initiator of the session instance.\n *\n * @returns {JitsiParticipant|undefined} The participant that started the session.\n */\n getInitiator() {\n return this._initiator;\n }\n\n /**\n * Returns the streaming URL of the session.\n *\n * @returns {string|undefined}\n */\n getLiveStreamViewURL() {\n return this._liveStreamViewURL;\n }\n\n /**\n * Returns the current status of the session.\n *\n * @returns {string|undefined}\n */\n getStatus() {\n return this._status;\n }\n\n /**\n * Returns the jid of the participant that stopped the session.\n *\n * @returns {JitsiParticipant|undefined} The participant that stopped the session.\n */\n getTerminator() {\n return this._terminator;\n }\n\n /**\n * Returns the current recording mode of the session, such as \"file\".\n *\n * @returns {string}\n */\n getMode() {\n return this._mode;\n }\n\n /**\n * Sets the last known error message related to the session.\n *\n * @param {string} error - The error string explaining why the session\n * entered an error state.\n * @returns {void}\n */\n setError(error) {\n this._error = error;\n }\n\n /**\n * Sets the last live stream URL for the session instance. Usually this is\n * a YouTube URL and usually this is only set for \"stream\" sessions.\n *\n * @param {string} url - The live stream URL associated with the session.\n * @returns {void}\n */\n setLiveStreamViewURL(url) {\n this._liveStreamViewURL = url;\n }\n\n /**\n * Sets the last known status for this recording session.\n *\n * @param {string} status - The new status to set.\n * @returns {void}\n */\n setStatus(status) {\n this._status = status;\n }\n\n /**\n * Sets the creator's jid of the session.\n * @param {JitsiParticipant} participant - The creator of the session.\n */\n setInitiator(participant) {\n this._initiator = participant;\n }\n\n /**\n * Sets the jid of the participant that stopped the session.\n * @param {JitsiParticipant} participant - The participant's jid,\n * that stopped the session.\n */\n setTerminator(participant) {\n this._terminator = participant;\n }\n\n /**\n * Sends a message to start the actual recording.\n *\n * @param {Object} options - Additional arguments for starting the\n * recording.\n * @param {string} [options.appData] - Data specific to the app/service that\n * the result file will be uploaded.\n * @param {string} [options.broadcastId] - The broadcast ID of an\n * associated YouTube stream, used for knowing the URL from which the stream\n * can be viewed.\n * @param {string} options.focusMucJid - The JID of the focus participant\n * that controls recording.\n * @param {streamId} options.streamId - Necessary for live streaming, this\n * is the the stream key needed to start a live streaming session with the\n * streaming service provider.\n * @returns Promise\n */\n start({ appData, broadcastId, focusMucJid, streamId }) {\n return new Promise((resolve, reject) => {\n this._connection.sendIQ(\n this._createIQ({\n action: 'start',\n appData,\n focusMucJid,\n broadcastId,\n streamId\n }),\n result => {\n // All users will eventually receive the 'pending' status\n // from the backend, but for the user initiating the session\n // it's better to give some instant feedback that recording\n // is starting so fire 'pending' here manually.\n this.setStatus('pending');\n this._setSessionID(\n recordingXMLUtils.getSessionIdFromIq(result));\n\n resolve();\n },\n error => {\n this._setErrorFromIq(error);\n\n reject(error);\n });\n });\n }\n\n /**\n * Sends a message to actually stop the recording session.\n *\n * @param {Object} options - Additional arguments for stopping the\n * recording.\n * @param {Object} options.focusMucJid - The JID of the focus participant\n * that controls recording.\n * @returns Promise\n */\n stop({ focusMucJid }) {\n return new Promise((resolve, reject) => {\n this._connection.sendIQ(\n this._createIQ({\n action: 'stop',\n focusMucJid\n }),\n resolve,\n reject);\n });\n }\n\n /**\n * Generates the message to change the status of the recording session.\n *\n * @param {string} status - The new status to which the recording session\n * should transition.\n * @param {string} [options.appData] - Data specific to the app/service that\n * the result file will be uploaded.\n * @param {string} [options.broadcastId] - The broadcast ID of an\n * associated YouTube stream, used for knowing the URL from which the stream\n * can be viewed.\n * @param {string} options.focusMucJid - The JID of the focus participant\n * that controls recording.\n * @param {streamId} options.streamId - Necessary for live streaming, this\n * is the the stream key needed to start a live streaming session with the\n * streaming service provider.\n * @returns Object - The XMPP IQ message.\n */\n _createIQ({ action, appData, broadcastId, focusMucJid, streamId }) {\n return $iq({\n to: focusMucJid,\n type: 'set'\n })\n .c('jibri', {\n 'xmlns': 'http://jitsi.org/protocol/jibri',\n 'action': action,\n 'app_data': appData,\n 'recording_mode': this._mode,\n 'streamid': streamId,\n 'you_tube_broadcast_id': broadcastId\n })\n .up();\n }\n\n /**\n * Handles the error from an iq and stores the error.\n *\n * @param {Node} errorIq - The error response from an Iq.\n * @private\n * @returns {void}\n */\n _setErrorFromIq(errorIq) {\n const error = errorIq.getElementsByTagName('error')[0];\n\n this.setError(error.children[0].tagName);\n }\n\n /**\n * Sets the known session ID for this recording session.\n *\n * @param {string} sessionID\n * @private\n * @returns {void}\n */\n _setSessionID(sessionID) {\n this._sessionID = sessionID;\n }\n}\n", "import EventEmitter from 'events';\n\nimport * as MediaType from './service/RTC/MediaType';\nimport browser from './modules/browser';\nimport RTC from './modules/RTC/RTC';\nimport RTCEvents from './service/RTC/RTCEvents';\nimport Statistics from './modules/statistics/statistics';\n\nimport * as JitsiMediaDevicesEvents from './JitsiMediaDevicesEvents';\n\nconst AUDIO_PERMISSION_NAME = 'microphone';\nconst PERMISSION_GRANTED_STATUS = 'granted';\nconst VIDEO_PERMISSION_NAME = 'camera';\n\n/**\n * Media devices utilities for Jitsi.\n */\nclass JitsiMediaDevices {\n /**\n * Initializes a {@code JitsiMediaDevices} object. There will be a single\n * instance of this class.\n */\n constructor() {\n this._eventEmitter = new EventEmitter();\n this._grantedPermissions = {};\n\n RTC.addListener(\n RTCEvents.DEVICE_LIST_CHANGED,\n devices =>\n this._eventEmitter.emit(\n JitsiMediaDevicesEvents.DEVICE_LIST_CHANGED,\n devices));\n RTC.addListener(\n RTCEvents.DEVICE_LIST_AVAILABLE,\n devices =>\n this._logOutputDevice(\n this.getAudioOutputDevice(),\n devices));\n RTC.addListener(\n RTCEvents.GRANTED_PERMISSIONS,\n grantedPermissions =>\n this._handleGrantedPermissions(grantedPermissions));\n\n // Test if the W3C Permissions API is implemented and the 'camera' and\n // 'microphone' permissions are implemented. (Testing for at least one\n // of them seems sufficient).\n this._permissionsApiSupported = new Promise(resolve => {\n if (!navigator.permissions) {\n resolve(false);\n\n return;\n }\n\n navigator.permissions.query({ name: VIDEO_PERMISSION_NAME })\n .then(() => resolve(true), () => resolve(false));\n });\n }\n\n /**\n * Updated the local granted permissions cache. A permissions might be\n * granted, denied, or undefined. This is represented by having its media\n * type key set to {@code true} or {@code false} respectively.\n *\n * @param {Object} grantedPermissions - Array with the permissions\n * which were granted.\n */\n _handleGrantedPermissions(grantedPermissions) {\n this._grantedPermissions = {\n ...this._grantedPermissions,\n ...grantedPermissions\n };\n }\n\n /**\n * Gathers data and sends it to statistics.\n * @param deviceID the device id to log\n * @param devices list of devices\n */\n _logOutputDevice(deviceID, devices) {\n const device\n = devices.find(\n d => d.kind === 'audiooutput' && d.deviceId === deviceID);\n\n if (device) {\n Statistics.sendActiveDeviceListEvent(\n RTC.getEventDataForActiveDevice(device));\n }\n }\n\n /**\n * Executes callback with list of media devices connected.\n * @param {function} callback\n */\n enumerateDevices(callback) {\n RTC.enumerateDevices(callback);\n }\n\n /**\n * Checks if its possible to enumerate available cameras/micropones.\n * @returns {Promise} a Promise which will be resolved only once\n * the WebRTC stack is ready, either with true if the device listing is\n * available available or with false otherwise.\n */\n isDeviceListAvailable() {\n return RTC.isDeviceListAvailable();\n }\n\n /**\n * Returns true if changing the input (camera / microphone) or output\n * (audio) device is supported and false if not.\n * @param {string} [deviceType] - type of device to change. Default is\n * undefined or 'input', 'output' - for audio output device change.\n * @returns {boolean} true if available, false otherwise.\n */\n isDeviceChangeAvailable(deviceType) {\n return RTC.isDeviceChangeAvailable(deviceType);\n }\n\n /**\n * Checks if the permission for the given device was granted.\n *\n * @param {'audio'|'video'} [type] - type of devices to check,\n * undefined stands for both 'audio' and 'video' together\n * @returns {Promise}\n */\n isDevicePermissionGranted(type) {\n return new Promise(resolve => {\n // Shortcut: first check if we already know the permission was\n // granted.\n if (type in this._grantedPermissions) {\n resolve(this._grantedPermissions[type]);\n\n return;\n }\n\n // Check using the Permissions API.\n this._permissionsApiSupported.then(supported => {\n if (!supported) {\n resolve(false);\n\n return;\n }\n\n const promises = [];\n\n switch (type) {\n case MediaType.VIDEO:\n promises.push(\n navigator.permissions.query({\n name: VIDEO_PERMISSION_NAME\n }));\n break;\n case MediaType.AUDIO:\n promises.push(\n navigator.permissions.query({\n name: AUDIO_PERMISSION_NAME\n }));\n break;\n default:\n promises.push(\n navigator.permissions.query({\n name: VIDEO_PERMISSION_NAME\n }));\n promises.push(\n navigator.permissions.query({\n name: AUDIO_PERMISSION_NAME\n }));\n }\n\n Promise.all(promises).then(\n results => resolve(results.every(permissionStatus => {\n // The status attribute is deprecated, and state\n // should be used instead, but check both for now\n // for backwards compatibility.\n const grantStatus = permissionStatus.state\n || permissionStatus.status;\n\n return grantStatus === PERMISSION_GRANTED_STATUS;\n })),\n () => resolve(false)\n );\n });\n });\n }\n\n /**\n * Returns true if it is possible to be simultaneously capturing audio\n * from more than one device.\n *\n * @returns {boolean}\n */\n isMultipleAudioInputSupported() {\n return !browser.isFirefox();\n }\n\n /**\n * Returns currently used audio output device id, 'default' stands\n * for default device\n * @returns {string}\n */\n getAudioOutputDevice() {\n return RTC.getAudioOutputDevice();\n }\n\n /**\n * Sets current audio output device.\n * @param {string} deviceId - id of 'audiooutput' device from\n * navigator.mediaDevices.enumerateDevices(), 'default' is for\n * default device\n * @returns {Promise} - resolves when audio output is changed, is rejected\n * otherwise\n */\n setAudioOutputDevice(deviceId) {\n const availableDevices = RTC.getCurrentlyAvailableMediaDevices();\n\n if (availableDevices && availableDevices.length > 0) {\n // if we have devices info report device to stats\n // normally this will not happen on startup as this method is called\n // too early. This will happen only on user selection of new device\n this._logOutputDevice(\n deviceId, RTC.getCurrentlyAvailableMediaDevices());\n }\n\n return RTC.setAudioOutputDevice(deviceId);\n }\n\n /**\n * Adds an event handler.\n * @param {string} event - event name\n * @param {function} handler - event handler\n */\n addEventListener(event, handler) {\n this._eventEmitter.addListener(event, handler);\n }\n\n /**\n * Removes event handler.\n * @param {string} event - event name\n * @param {function} handler - event handler\n */\n removeEventListener(event, handler) {\n this._eventEmitter.removeListener(event, handler);\n }\n\n /**\n * Emits an event.\n * @param {string} event - event name\n */\n emitEvent(event, ...args) {\n this._eventEmitter.emit(event, ...args);\n }\n\n /**\n * Returns whether or not the current browser can support capturing video,\n * be it camera or desktop, and displaying received video.\n *\n * @returns {boolean}\n */\n supportsVideo() {\n // Defer to the browser capabilities to allow exposure of the api to the\n // consumer but prevent other files from having to import\n // JitsiMediaDevices.\n return browser.supportsVideo();\n }\n}\n\nexport default new JitsiMediaDevices();\n", "/* Copyright @ 2015-present 8x8, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/*jslint latedef:false*/\n\n/**\n * Ordered log levels.\n */\nvar levels = {\n \"trace\": 0,\n \"debug\": 1,\n \"info\": 2,\n \"log\": 3,\n \"warn\": 4,\n \"error\": 5\n};\n\n/**\n * The default transport - console\n * @type LoggerTransport\n */\nLogger.consoleTransport = console;\n\n/**\n * The array which stores currently registered global transports.\n * @type {[LoggerTransport]}\n */\nvar globalTransports = [ Logger.consoleTransport ];\n\n/**\n * Adds given {@link LoggerTransport} instance to the list of global\n * transports which means that it'll be used by all {@link Logger}s\n * @param {LoggerTransport} transport\n */\nLogger.addGlobalTransport = function(transport) {\n if (globalTransports.indexOf(transport) === -1) {\n globalTransports.push(transport);\n }\n};\n\n/**\n * Removes given {@link LoggerTransport} instance from the list of global\n * transports\n * @param {LoggerTransport} transport\n */\nLogger.removeGlobalTransport = function(transport) {\n var transportIdx = globalTransports.indexOf(transport);\n if (transportIdx !== -1) {\n globalTransports.splice(transportIdx, 1);\n }\n};\n\n/**\n * The global configuration options.\n */\nvar globalOptions = {};\n\n/**\n * Sets global options which will be used by all loggers. Changing these works\n * even after other loggers are created.\n */\nLogger.setGlobalOptions = function(options) {\n globalOptions = options || {};\n};\n\n/**\n * Parses Error's object stack trace and extracts information about the last\n * caller before the log method was called.\n * @returns JS object with info about the caller - method name, file location,\n * line and column.\n */\nfunction getCallerInfo() {\n var callerInfo = {\n methodName: \"\",\n fileLocation: \"\",\n line: null,\n column: null\n };\n //gets the part of the stack without the logger wrappers\n var error = new Error();\n var stack = error.stack? error.stack.split(\"\\n\") : [];\n if(!stack || stack.length < 1) {\n return callerInfo;\n }\n var m = null;\n if(stack[3]) {\n m = stack[3].match(/\\s*at\\s*(.+?)\\s*\\((\\S*)\\s*:(\\d*)\\s*:(\\d*)\\)/);\n }\n if(!m || m.length <= 4) {\n //Firefox && Safari\n if(stack[2].indexOf(\"log@\") === 0){\n //Safari\n callerInfo.methodName = stack[3].substr(0, stack[3].indexOf(\"@\"));\n } else {\n //Firefox\n callerInfo.methodName = stack[2].substr(0, stack[2].indexOf(\"@\"));\n }\n return callerInfo;\n }\n\n callerInfo.methodName = m[1];\n callerInfo.fileLocation = m[2];\n callerInfo.line = m[3];\n callerInfo.column = m[4];\n return callerInfo;\n}\n\n/**\n * Logs messages using the transports and level from the logger.\n * @param logger a logger instance.\n * @param level the log level of the message. See the levels variable.\n * @param arguments array with arguments that will be logged.\n */\nfunction log() {\n var logger = arguments[0], level = arguments[1],\n args = Array.prototype.slice.call(arguments, 2);\n if(levels[level] < logger.level) {\n return;\n }\n\n var callerInfo\n = !(logger.options.disableCallerInfo || globalOptions.disableCallerInfo) &&\n getCallerInfo();\n var transports = globalTransports.concat(logger.transports);\n for(var i = 0; i < transports.length; i++) {\n var t = transports[i];\n var l = t[level];\n if(l && typeof(l) === \"function\") {\n var logPrefixes = [];\n\n logPrefixes.push(new Date().toISOString());\n\n if (logger.id) {\n logPrefixes.push(\"[\" + logger.id + \"]\");\n }\n\n if (callerInfo && callerInfo.methodName.length > 1) {\n logPrefixes.push(\"<\" + callerInfo.methodName + \">: \");\n }\n\n var fullLogParts = logPrefixes.concat(args);\n\n l.bind(t).apply(t, fullLogParts);\n }\n }\n}\n\n/**\n *\n * Constructs new logger object.\n * @param level the logging level for the new logger\n * @param id optional identifier for the logger instance.\n * @param {LoggerTransport} transports optional list of handlers(objects) for\n * the logs. The handlers must support - log, warn, error, debug, info, trace.\n * @param options optional configuration file for how the logger should behave.\n * @param {boolean} options.disableCallerInfo Whether the call site of a logger\n * method invocation should be included in the log. Defaults to false, so the\n * call site will be included.\n */\nfunction Logger(level, id, transports, options) {\n this.id = id;\n this.options = options || {};\n this.transports = transports;\n if(!this.transports) {\n this.transports = [];\n }\n this.level = levels[level];\n var methods = Object.keys(levels);\n for(var i = 0; i < methods.length; i++){\n this[methods[i]] =\n log.bind(null, this, methods[i]);\n }\n}\n\n/**\n * Sets the log level for the logger.\n * @param level the new log level.\n */\nLogger.prototype.setLevel = function (level) {\n this.level = levels[level];\n};\nmodule.exports = Logger;\n\n/**\n * Enum for the supported log levels.\n */\nLogger.levels = {\n TRACE: \"trace\",\n DEBUG: \"debug\",\n INFO: \"info\",\n LOG: \"log\",\n WARN: \"warn\",\n ERROR: \"error\"\n};\n", "module.exports = function(module) {\r\n\tif (!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tif (!module.children) module.children = [];\r\n\t\tObject.defineProperty(module, \"loaded\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tget: function() {\r\n\t\t\t\treturn module.l;\r\n\t\t\t}\r\n\t\t});\r\n\t\tObject.defineProperty(module, \"id\", {\r\n\t\t\tenumerable: true,\r\n\t\t\tget: function() {\r\n\t\t\t\treturn module.i;\r\n\t\t\t}\r\n\t\t});\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n};\r\n", "var grammar = module.exports = {\n v: [{\n name: 'version',\n reg: /^(\\d*)$/\n }],\n o: [{ //o=- 20518 0 IN IP4 203.0.113.1\n // NB: sessionId will be a String in most cases because it is huge\n name: 'origin',\n reg: /^(\\S*) (\\d*) (\\d*) (\\S*) IP(\\d) (\\S*)/,\n names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'],\n format: '%s %s %d %s IP%d %s'\n }],\n // default parsing of these only (though some of these feel outdated)\n s: [{ name: 'name' }],\n i: [{ name: 'description' }],\n u: [{ name: 'uri' }],\n e: [{ name: 'email' }],\n p: [{ name: 'phone' }],\n z: [{ name: 'timezones' }], // TODO: this one can actually be parsed properly..\n r: [{ name: 'repeats' }], // TODO: this one can also be parsed properly\n //k: [{}], // outdated thing ignored\n t: [{ //t=0 0\n name: 'timing',\n reg: /^(\\d*) (\\d*)/,\n names: ['start', 'stop'],\n format: '%d %d'\n }],\n c: [{ //c=IN IP4 10.47.197.26\n name: 'connection',\n reg: /^IN IP(\\d) (\\S*)/,\n names: ['version', 'ip'],\n format: 'IN IP%d %s'\n }],\n b: [{ //b=AS:4000\n push: 'bandwidth',\n reg: /^(TIAS|AS|CT|RR|RS):(\\d*)/,\n names: ['type', 'limit'],\n format: '%s:%s'\n }],\n m: [{ //m=video 51744 RTP/AVP 126 97 98 34 31\n // NB: special - pushes to session\n // TODO: rtp/fmtp should be filtered by the payloads found here?\n reg: /^(\\w*) (\\d*) ([\\w\\/]*)(?: (.*))?/,\n names: ['type', 'port', 'protocol', 'payloads'],\n format: '%s %d %s %s'\n }],\n a: [\n { //a=rtpmap:110 opus/48000/2\n push: 'rtp',\n reg: /^rtpmap:(\\d*) ([\\w\\-\\.]*)(?:\\s*\\/(\\d*)(?:\\s*\\/(\\S*))?)?/,\n names: ['payload', 'codec', 'rate', 'encoding'],\n format: function (o) {\n return (o.encoding) ?\n 'rtpmap:%d %s/%s/%s':\n o.rate ?\n 'rtpmap:%d %s/%s':\n 'rtpmap:%d %s';\n }\n },\n { //a=fmtp:108 profile-level-id=24;object=23;bitrate=64000\n //a=fmtp:111 minptime=10; useinbandfec=1\n push: 'fmtp',\n reg: /^fmtp:(\\d*) ([\\S| ]*)/,\n names: ['payload', 'config'],\n format: 'fmtp:%d %s'\n },\n { //a=control:streamid=0\n name: 'control',\n reg: /^control:(.*)/,\n format: 'control:%s'\n },\n { //a=rtcp:65179 IN IP4 193.84.77.194\n name: 'rtcp',\n reg: /^rtcp:(\\d*)(?: (\\S*) IP(\\d) (\\S*))?/,\n names: ['port', 'netType', 'ipVer', 'address'],\n format: function (o) {\n return (o.address != null) ?\n 'rtcp:%d %s IP%d %s':\n 'rtcp:%d';\n }\n },\n { //a=rtcp-fb:98 trr-int 100\n push: 'rtcpFbTrrInt',\n reg: /^rtcp-fb:(\\*|\\d*) trr-int (\\d*)/,\n names: ['payload', 'value'],\n format: 'rtcp-fb:%d trr-int %d'\n },\n { //a=rtcp-fb:98 nack rpsi\n push: 'rtcpFb',\n reg: /^rtcp-fb:(\\*|\\d*) ([\\w-_]*)(?: ([\\w-_]*))?/,\n names: ['payload', 'type', 'subtype'],\n format: function (o) {\n return (o.subtype != null) ?\n 'rtcp-fb:%s %s %s':\n 'rtcp-fb:%s %s';\n }\n },\n { //a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\n //a=extmap:1/recvonly URI-gps-string\n push: 'ext',\n reg: /^extmap:(\\d+)(?:\\/(\\w+))? (\\S*)(?: (\\S*))?/,\n names: ['value', 'direction', 'uri', 'config'],\n format: function (o) {\n return 'extmap:%d' + (o.direction ? '/%s' : '%v') + ' %s' + (o.config ? ' %s' : '');\n }\n },\n { //a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32\n push: 'crypto',\n reg: /^crypto:(\\d*) ([\\w_]*) (\\S*)(?: (\\S*))?/,\n names: ['id', 'suite', 'config', 'sessionConfig'],\n format: function (o) {\n return (o.sessionConfig != null) ?\n 'crypto:%d %s %s %s':\n 'crypto:%d %s %s';\n }\n },\n { //a=setup:actpass\n name: 'setup',\n reg: /^setup:(\\w*)/,\n format: 'setup:%s'\n },\n { //a=mid:1\n name: 'mid',\n reg: /^mid:([^\\s]*)/,\n format: 'mid:%s'\n },\n { //a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a\n name: 'msid',\n reg: /^msid:(.*)/,\n format: 'msid:%s'\n },\n { //a=ptime:20\n name: 'ptime',\n reg: /^ptime:(\\d*)/,\n format: 'ptime:%d'\n },\n { //a=maxptime:60\n name: 'maxptime',\n reg: /^maxptime:(\\d*)/,\n format: 'maxptime:%d'\n },\n { //a=sendrecv\n name: 'direction',\n reg: /^(sendrecv|recvonly|sendonly|inactive)/\n },\n { //a=ice-lite\n name: 'icelite',\n reg: /^(ice-lite)/\n },\n { //a=ice-ufrag:F7gI\n name: 'iceUfrag',\n reg: /^ice-ufrag:(\\S*)/,\n format: 'ice-ufrag:%s'\n },\n { //a=ice-pwd:x9cml/YzichV2+XlhiMu8g\n name: 'icePwd',\n reg: /^ice-pwd:(\\S*)/,\n format: 'ice-pwd:%s'\n },\n { //a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33\n name: 'fingerprint',\n reg: /^fingerprint:(\\S*) (\\S*)/,\n names: ['type', 'hash'],\n format: 'fingerprint:%s %s'\n },\n { //a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host\n //a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0 network-id 3 network-cost 10\n //a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0 network-id 3 network-cost 10\n //a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0 network-id 3 network-cost 10\n //a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0 network-id 3 network-cost 10\n push:'candidates',\n reg: /^candidate:(\\S*) (\\d*) (\\S*) (\\d*) (\\S*) (\\d*) typ (\\S*)(?: raddr (\\S*) rport (\\d*))?(?: tcptype (\\S*))?(?: generation (\\d*))?(?: network-id (\\d*))?(?: network-cost (\\d*))?/,\n names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation', 'network-id', 'network-cost'],\n format: function (o) {\n var str = 'candidate:%s %d %s %d %s %d typ %s';\n\n str += (o.raddr != null) ? ' raddr %s rport %d' : '%v%v';\n\n // NB: candidate has three optional chunks, so %void middles one if it's missing\n str += (o.tcptype != null) ? ' tcptype %s' : '%v';\n\n if (o.generation != null) {\n str += ' generation %d';\n }\n\n str += (o['network-id'] != null) ? ' network-id %d' : '%v';\n str += (o['network-cost'] != null) ? ' network-cost %d' : '%v';\n return str;\n }\n },\n { //a=end-of-candidates (keep after the candidates line for readability)\n name: 'endOfCandidates',\n reg: /^(end-of-candidates)/\n },\n { //a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ...\n name: 'remoteCandidates',\n reg: /^remote-candidates:(.*)/,\n format: 'remote-candidates:%s'\n },\n { //a=ice-options:google-ice\n name: 'iceOptions',\n reg: /^ice-options:(\\S*)/,\n format: 'ice-options:%s'\n },\n { //a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1\n push: 'ssrcs',\n reg: /^ssrc:(\\d*) ([\\w_]*)(?::(.*))?/,\n names: ['id', 'attribute', 'value'],\n format: function (o) {\n var str = 'ssrc:%d';\n if (o.attribute != null) {\n str += ' %s';\n if (o.value != null) {\n str += ':%s';\n }\n }\n return str;\n }\n },\n { //a=ssrc-group:FEC 1 2\n //a=ssrc-group:FEC-FR 3004364195 1080772241\n push: 'ssrcGroups',\n // token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E\n reg: /^ssrc-group:([\\x21\\x23\\x24\\x25\\x26\\x27\\x2A\\x2B\\x2D\\x2E\\w]*) (.*)/,\n names: ['semantics', 'ssrcs'],\n format: 'ssrc-group:%s %s'\n },\n { //a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV\n name: 'msidSemantic',\n reg: /^msid-semantic:\\s?(\\w*) (\\S*)/,\n names: ['semantic', 'token'],\n format: 'msid-semantic: %s %s' // space after ':' is not accidental\n },\n { //a=group:BUNDLE audio video\n push: 'groups',\n reg: /^group:(\\w*) (.*)/,\n names: ['type', 'mids'],\n format: 'group:%s %s'\n },\n { //a=rtcp-mux\n name: 'rtcpMux',\n reg: /^(rtcp-mux)/\n },\n { //a=rtcp-rsize\n name: 'rtcpRsize',\n reg: /^(rtcp-rsize)/\n },\n { //a=sctpmap:5000 webrtc-datachannel 1024\n name: 'sctpmap',\n reg: /^sctpmap:([\\w_\\/]*) (\\S*)(?: (\\S*))?/,\n names: ['sctpmapNumber', 'app', 'maxMessageSize'],\n format: function (o) {\n return (o.maxMessageSize != null) ?\n 'sctpmap:%s %s %s' :\n 'sctpmap:%s %s';\n }\n },\n { //a=x-google-flag:conference\n name: 'xGoogleFlag',\n reg: /^x-google-flag:([^\\s]*)/,\n format: 'x-google-flag:%s'\n },\n { //a=rid:1 send max-width=1280;max-height=720;max-fps=30;depend=0\n push: 'rids',\n reg: /^rid:([\\d\\w]+) (\\w+)(?: ([\\S| ]*))?/,\n names: ['id', 'direction', 'params'],\n format: function (o) {\n return (o.params) ? 'rid:%s %s %s' : 'rid:%s %s';\n }\n },\n { //a=imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]\n //a=imageattr:* send [x=800,y=640] recv *\n //a=imageattr:100 recv [x=320,y=240]\n push: 'imageattrs',\n reg: new RegExp(\n //a=imageattr:97\n '^imageattr:(\\\\d+|\\\\*)' +\n //send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320]\n '[\\\\s\\\\t]+(send|recv)[\\\\s\\\\t]+(\\\\*|\\\\[\\\\S+\\\\](?:[\\\\s\\\\t]+\\\\[\\\\S+\\\\])*)' +\n //recv [x=330,y=250]\n '(?:[\\\\s\\\\t]+(recv|send)[\\\\s\\\\t]+(\\\\*|\\\\[\\\\S+\\\\](?:[\\\\s\\\\t]+\\\\[\\\\S+\\\\])*))?'\n ),\n names: ['pt', 'dir1', 'attrs1', 'dir2', 'attrs2'],\n format: function (o) {\n return 'imageattr:%s %s %s' + (o.dir2 ? ' %s %s' : '');\n }\n },\n { //a=simulcast:send 1,2,3;~4,~5 recv 6;~7,~8\n //a=simulcast:recv 1;4,5 send 6;7\n name: 'simulcast',\n reg: new RegExp(\n //a=simulcast:\n '^simulcast:' +\n //send 1,2,3;~4,~5\n '(send|recv) ([a-zA-Z0-9\\\\-_~;,]+)' +\n //space + recv 6;~7,~8\n '(?:\\\\s?(send|recv) ([a-zA-Z0-9\\\\-_~;,]+))?' +\n //end\n '$'\n ),\n names: ['dir1', 'list1', 'dir2', 'list2'],\n format: function (o) {\n return 'simulcast:%s %s' + (o.dir2 ? ' %s %s' : '');\n }\n },\n { //Old simulcast draft 03 (implemented by Firefox)\n // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-03\n //a=simulcast: recv pt=97;98 send pt=97\n //a=simulcast: send rid=5;6;7 paused=6,7\n name: 'simulcast_03',\n reg: /^simulcast:[\\s\\t]+([\\S+\\s\\t]+)$/,\n names: ['value'],\n format: 'simulcast: %s'\n },\n {\n //a=framerate:25\n //a=framerate:29.97\n name: 'framerate',\n reg: /^framerate:(\\d+(?:$|\\.\\d+))/,\n format: 'framerate:%s'\n },\n { // any a= that we don't understand is kepts verbatim on media.invalid\n push: 'invalid',\n names: ['value']\n }\n ]\n};\n\n// set sensible defaults to avoid polluting the grammar with boring details\nObject.keys(grammar).forEach(function (key) {\n var objs = grammar[key];\n objs.forEach(function (obj) {\n if (!obj.reg) {\n obj.reg = /(.*)/;\n }\n if (!obj.format) {\n obj.format = '%s';\n }\n });\n});\n", "/* global MediaRecorder, MediaStream */\n\nconst RecordingResult = require('./recordingResult');\n\n/**\n * Possible audio formats MIME types\n */\nconst AUDIO_WEBM = 'audio/webm'; // Supported in chrome\nconst AUDIO_OGG = 'audio/ogg'; // Supported in firefox\n\n/**\n * A TrackRecorder object holds all the information needed for recording a\n * single JitsiTrack (either remote or local)\n * @param track The JitsiTrack the object is going to hold\n */\nconst TrackRecorder = function(track) {\n // The JitsiTrack holding the stream\n this.track = track;\n\n // The MediaRecorder recording the stream\n this.recorder = null;\n\n // The array of data chunks recorded from the stream\n // acts as a buffer until the data is stored on disk\n this.data = null;\n\n // the name of the person of the JitsiTrack. This can be undefined and/or\n // not unique\n this.name = null;\n\n // the time of the start of the recording\n this.startTime = null;\n};\n\n/**\n * Starts the recording of a JitsiTrack in a TrackRecorder object.\n * This will also define the timestamp and try to update the name\n * @param trackRecorder the TrackRecorder to start\n */\nfunction startRecorder(trackRecorder) {\n if (trackRecorder.recorder === undefined) {\n throw new Error('Passed an object to startRecorder which is not a '\n + 'TrackRecorder object');\n }\n trackRecorder.recorder.start();\n trackRecorder.startTime = new Date();\n}\n\n/**\n * Stops the recording of a JitsiTrack in a TrackRecorder object.\n * This will also try to update the name\n * @param trackRecorder the TrackRecorder to stop\n */\nfunction stopRecorder(trackRecorder) {\n if (trackRecorder.recorder === undefined) {\n throw new Error('Passed an object to stopRecorder which is not a '\n + 'TrackRecorder object');\n }\n trackRecorder.recorder.stop();\n}\n\n/**\n * Determines which kind of audio recording the browser supports\n * chrome supports \"audio/webm\" and firefox supports \"audio/ogg\"\n */\nfunction determineCorrectFileType() {\n if (MediaRecorder.isTypeSupported(AUDIO_WEBM)) {\n return AUDIO_WEBM;\n } else if (MediaRecorder.isTypeSupported(AUDIO_OGG)) {\n return AUDIO_OGG;\n }\n throw new Error(\n 'unable to create a MediaRecorder with the right mimetype!');\n}\n\n/**\n * main exported object of the file, holding all\n * relevant functions and variables for the outside world\n * @param jitsiConference the jitsiConference which this object\n * is going to record\n */\nfunction AudioRecorder(jitsiConference) {\n // array of TrackRecorders, where each trackRecorder\n // holds the JitsiTrack, MediaRecorder and recorder data\n this.recorders = [];\n\n // get which file type is supported by the current browser\n this.fileType = determineCorrectFileType();\n\n // boolean flag for active recording\n this.isRecording = false;\n\n // the jitsiconference the object is recording\n this.jitsiConference = jitsiConference;\n}\n\n/**\n * Add the the exported module so that it can be accessed by other files\n */\nAudioRecorder.determineCorrectFileType = determineCorrectFileType;\n\n/**\n * Adds a new TrackRecorder object to the array.\n *\n * @param track the track potentially holding an audio stream\n */\nAudioRecorder.prototype.addTrack = function(track) {\n if (track.isAudioTrack()) {\n // create the track recorder\n const trackRecorder = this.instantiateTrackRecorder(track);\n\n // push it to the local array of all recorders\n\n this.recorders.push(trackRecorder);\n\n // update the name of the trackRecorders\n this.updateNames();\n\n // If we're already recording, immediately start recording this new\n // track.\n if (this.isRecording) {\n startRecorder(trackRecorder);\n }\n }\n};\n\n/**\n * Creates a TrackRecorder object. Also creates the MediaRecorder and\n * data array for the trackRecorder.\n * @param track the JitsiTrack holding the audio MediaStream(s)\n */\nAudioRecorder.prototype.instantiateTrackRecorder = function(track) {\n const trackRecorder = new TrackRecorder(track);\n\n // Create a new stream which only holds the audio track\n const originalStream = trackRecorder.track.getOriginalStream();\n const stream = createEmptyStream();\n\n originalStream.getAudioTracks().forEach(t => stream.addTrack(t));\n\n // Create the MediaRecorder\n trackRecorder.recorder = new MediaRecorder(stream,\n { mimeType: this.fileType });\n\n // array for holding the recorder data. Resets it when\n // audio already has been recorder once\n trackRecorder.data = [];\n\n // function handling a dataEvent, e.g the stream gets new data\n trackRecorder.recorder.ondataavailable = function(dataEvent) {\n if (dataEvent.data.size > 0) {\n trackRecorder.data.push(dataEvent.data);\n }\n };\n\n return trackRecorder;\n};\n\n/**\n * Notifies the module that a specific track has stopped, e.g participant left\n * the conference.\n * if the recording has not started yet, the TrackRecorder will be removed from\n * the array. If the recording has started, the recorder will stop recording\n * but not removed from the array so that the recorded stream can still be\n * accessed\n *\n * @param {JitsiTrack} track the JitsiTrack to remove from the recording session\n */\nAudioRecorder.prototype.removeTrack = function(track) {\n if (track.isVideoTrack()) {\n return;\n }\n\n const array = this.recorders;\n let i;\n\n for (i = 0; i < array.length; i++) {\n if (array[i].track.getParticipantId() === track.getParticipantId()) {\n const recorderToRemove = array[i];\n\n if (this.isRecording) {\n stopRecorder(recorderToRemove);\n } else {\n // remove the TrackRecorder from the array\n array.splice(i, 1);\n }\n }\n }\n\n // make sure the names are up to date\n this.updateNames();\n};\n\n/**\n * Tries to update the name value of all TrackRecorder in the array.\n * If it hasn't changed,it will keep the exiting name. If it changes to a\n * undefined value, the old value will also be kept.\n */\nAudioRecorder.prototype.updateNames = function() {\n const conference = this.jitsiConference;\n\n this.recorders.forEach(trackRecorder => {\n if (trackRecorder.track.isLocal()) {\n trackRecorder.name = 'the transcriber';\n } else {\n const id = trackRecorder.track.getParticipantId();\n const participant = conference.getParticipantById(id);\n const newName = participant.getDisplayName();\n\n if (newName !== 'undefined') {\n trackRecorder.name = newName;\n }\n }\n });\n};\n\n/**\n * Starts the audio recording of every local and remote track\n */\nAudioRecorder.prototype.start = function() {\n if (this.isRecording) {\n throw new Error('audiorecorder is already recording');\n }\n\n // set boolean isRecording flag to true so if new participants join the\n // conference, that track can instantly start recording as well\n this.isRecording = true;\n\n // start all the mediaRecorders\n this.recorders.forEach(trackRecorder => startRecorder(trackRecorder));\n\n // log that recording has started\n console.log(\n `Started the recording of the audio. There are currently ${\n this.recorders.length} recorders active.`);\n};\n\n/**\n * Stops the audio recording of every local and remote track\n */\nAudioRecorder.prototype.stop = function() {\n // set the boolean flag to false\n this.isRecording = false;\n\n // stop all recorders\n this.recorders.forEach(trackRecorder => stopRecorder(trackRecorder));\n console.log('stopped recording');\n};\n\n/**\n * link hacking to download all recorded audio streams\n */\nAudioRecorder.prototype.download = function() {\n this.recorders.forEach(trackRecorder => {\n const blob = new Blob(trackRecorder.data, { type: this.fileType });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n\n document.body.appendChild(a);\n a.style = 'display: none';\n a.href = url;\n a.download = `test.${this.fileType.split('/')[1]}`;\n a.click();\n window.URL.revokeObjectURL(url);\n });\n};\n\n/**\n * returns the audio files of all recorders as an array of objects,\n * which include the name of the owner of the track and the starting time stamp\n * @returns {Array} an array of RecordingResult objects\n */\nAudioRecorder.prototype.getRecordingResults = function() {\n if (this.isRecording) {\n throw new Error(\n 'cannot get blobs because the AudioRecorder is still recording!');\n }\n\n // make sure the names are up to date before sending them off\n this.updateNames();\n\n const array = [];\n\n this.recorders.forEach(\n recorder =>\n array.push(\n new RecordingResult(\n new Blob(recorder.data, { type: this.fileType }),\n recorder.name,\n recorder.startTime)));\n\n return array;\n};\n\n/**\n * Gets the mime type of the recorder audio\n * @returns {String} the mime type of the recorder audio\n */\nAudioRecorder.prototype.getFileType = function() {\n return this.fileType;\n};\n\n/**\n * Creates a empty MediaStream object which can be used\n * to add MediaStreamTracks to\n * @returns MediaStream\n */\nfunction createEmptyStream() {\n if (typeof MediaStream !== 'undefined') {\n return new MediaStream();\n }\n throw new Error('cannot create a clean mediaStream');\n}\n\n/**\n * export the main object AudioRecorder\n */\nmodule.exports = AudioRecorder;\n", "import { getLogger } from 'jitsi-meet-logger';\n\nimport * as JitsiTrackEvents from '../../JitsiTrackEvents';\nimport RTC from '../RTC/RTC';\nimport Statistics from '../statistics/statistics';\n\n\nconst logger = getLogger(__filename);\n\n// If after 3000 ms the detector did not find any active devices consider that there aren't any usable ones available\n// i.e. audioLevel > 0.008\nconst DETECTION_TIMEOUT = 3000;\n\n\n/**\n * Go through all audio devices on the system and return one that is active, i.e. has audio signal.\n *\n * @returns Promise - Object containing information about the found device.\n */\nexport default function getActiveAudioDevice() {\n\n return new Promise(resolve => {\n RTC.enumerateDevices(devices => {\n const audioDevices = devices.filter(device => device.kind === 'audioinput');\n const devicePromiseArray = [];\n\n\n for (const micDevice of audioDevices) {\n const devicePromise = RTC.obtainAudioAndVideoPermissions({ devices: [ 'audio' ],\n micDeviceId: micDevice.deviceId }).then(tracks => {\n\n // We expect a single device to be available when obtained from obtainAudioAndVideoPermissions\n // that's why only take p.value[0].\n const track = tracks[0];\n const originalStream = track.getOriginalStream();\n\n Statistics.startLocalStats(originalStream, track.setAudioLevel.bind(track));\n track.addEventListener(JitsiTrackEvents.LOCAL_TRACK_STOPPED, () => {\n Statistics.stopLocalStats(originalStream);\n });\n\n return track;\n });\n\n devicePromiseArray.push(devicePromise);\n }\n\n Promise.allSettled(devicePromiseArray).then(outcomeArray => {\n const successfulPromises = outcomeArray.filter(p => p.status === 'fulfilled');\n const rejectedPromises = outcomeArray.filter(p => p.status === 'rejected');\n\n\n const availableDevices = successfulPromises.map(p => p.value);\n const rejectReasons = rejectedPromises.map(p => p.value);\n\n for (const reason of rejectReasons) {\n logger.error('Failed to acquire audio device with error: ', reason);\n }\n\n // Setup event handlers for monitored devices.\n for (const device of availableDevices) {\n device.on(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED, audioLevel => {\n // This is a very naive approach but works, a more accurate one would be to use rnnoise in\n // order to limit the number of false positives. The 0.008 constant is due to how\n // LocalStatsCollector from lib-jitsi-meet publishes audio-levels, in this case 0.008 denotes //\n // no input.\n if (audioLevel > 0.008) {\n stopActiveDevices(availableDevices);\n resolve({ deviceId: device.deviceId,\n deviceLabel: device.track.label });\n }\n });\n }\n\n // Cancel the detection in case no devices was found with audioLevel > 0 in the set timeout.\n setTimeout(() => {\n stopActiveDevices(availableDevices);\n resolve({\n deviceId: '',\n deviceLabel: '' }\n );\n }, DETECTION_TIMEOUT);\n\n });\n\n });\n });\n}\n\n/**\n * Stop the streams of the provided JitsiLocalTracks.\n *\n * @param {Array} deviceList - Array of JitsiLocalTracks to stop.\n * @returns {void}\n */\nfunction stopActiveDevices(deviceList) {\n for (const device of deviceList) {\n device.stopStream();\n }\n}\n", "import { getLogger } from 'jitsi-meet-logger';\n\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport { createBridgeChannelClosedEvent } from '../../service/statistics/AnalyticsEvents';\nimport Statistics from '../statistics/statistics';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\n\nconst logger = getLogger(__filename);\n\n/**\n * Handles a WebRTC RTCPeerConnection or a WebSocket instance to communicate\n * with the videobridge.\n */\nexport default class BridgeChannel {\n /**\n * Binds \"ondatachannel\" event listener on the given RTCPeerConnection\n * instance, or creates a WebSocket connection with the videobridge.\n * At least one of both, peerconnection or wsUrl parameters, must be\n * given.\n * @param {RTCPeerConnection} [peerconnection] WebRTC peer connection\n * instance.\n * @param {string} [wsUrl] WebSocket URL.\n * @param {EventEmitter} eventEmitter EventEmitter instance.\n */\n constructor(peerconnection, wsUrl, emitter) {\n if (!peerconnection && !wsUrl) {\n throw new TypeError(\n 'At least peerconnection or wsUrl must be given');\n } else if (peerconnection && wsUrl) {\n throw new TypeError(\n 'Just one of peerconnection or wsUrl must be given');\n }\n\n if (peerconnection) {\n logger.debug('constructor() with peerconnection');\n } else {\n logger.debug(`constructor() with wsUrl:\"${wsUrl}\"`);\n }\n\n // The underlying WebRTC RTCDataChannel or WebSocket instance.\n // @type {RTCDataChannel|WebSocket}\n this._channel = null;\n\n // @type {EventEmitter}\n this._eventEmitter = emitter;\n\n // Whether a RTCDataChannel or WebSocket is internally used.\n // @type {string} \"datachannel\" / \"websocket\"\n this._mode = null;\n\n // Indicates whether the connection retries are enabled or not.\n this._areRetriesEnabled = false;\n\n // Indicates whether the connection was closed from the client or not.\n this._closedFromClient = false;\n\n // If a RTCPeerConnection is given, listen for new RTCDataChannel\n // event.\n if (peerconnection) {\n const datachannel\n = peerconnection.createDataChannel(\n 'JVB data channel', {\n protocol: 'http://jitsi.org/protocols/colibri'\n });\n\n // Handle the RTCDataChannel.\n this._handleChannel(datachannel);\n this._mode = 'datachannel';\n\n // Otherwise create a WebSocket connection.\n } else if (wsUrl) {\n this._areRetriesEnabled = true;\n this._wsUrl = wsUrl;\n this._initWebSocket();\n }\n }\n\n /**\n * Initializes the web socket channel.\n *\n * @returns {void}\n */\n _initWebSocket() {\n // Create a WebSocket instance.\n const ws = new WebSocket(this._wsUrl);\n\n // Handle the WebSocket.\n this._handleChannel(ws);\n this._mode = 'websocket';\n }\n\n /**\n * Starts the websocket connection retries.\n *\n * @returns {void}\n */\n _startConnectionRetries() {\n let timeoutS = 1;\n\n const reload = () => {\n if (this.isOpen()) {\n return;\n }\n this._initWebSocket(this._wsUrl);\n timeoutS = Math.min(timeoutS * 2, 60);\n this._retryTimeout = setTimeout(reload, timeoutS * 1000);\n };\n\n this._retryTimeout = setTimeout(reload, timeoutS * 1000);\n }\n\n /**\n * Stops the websocket connection retries.\n *\n * @returns {void}\n */\n _stopConnectionRetries() {\n if (this._retryTimeout) {\n clearTimeout(this._retryTimeout);\n this._retryTimeout = undefined;\n }\n }\n\n /**\n * Retries to establish the websocket connection after the connection was closed by the server.\n *\n * @param {CloseEvent} closeEvent - The close event that triggered the retries.\n * @returns {void}\n */\n _retryWebSocketConnection(closeEvent) {\n if (!this._areRetriesEnabled) {\n return;\n }\n const { code, reason } = closeEvent;\n\n Statistics.sendAnalytics(createBridgeChannelClosedEvent(code, reason));\n this._areRetriesEnabled = false;\n this._eventEmitter.once(RTCEvents.DATA_CHANNEL_OPEN, () => {\n this._stopConnectionRetries();\n this._areRetriesEnabled = true;\n });\n this._startConnectionRetries();\n }\n\n /**\n * The channel mode.\n * @return {string} \"datachannel\" or \"websocket\" (or null if not yet set).\n */\n get mode() {\n return this._mode;\n }\n\n /**\n * Closes the currently opened channel.\n */\n close() {\n this._closedFromClient = true;\n this._stopConnectionRetries();\n this._areRetriesEnabled = false;\n if (this._channel) {\n try {\n this._channel.close();\n } catch (error) {} // eslint-disable-line no-empty\n\n this._channel = null;\n }\n }\n\n /**\n * Whether there is an underlying RTCDataChannel or WebSocket and it's\n * open.\n * @return {boolean}\n */\n isOpen() {\n return this._channel && (this._channel.readyState === 'open'\n || this._channel.readyState === WebSocket.OPEN);\n }\n\n /**\n * Sends message via the channel.\n * @param {string} to The id of the endpoint that should receive the\n * message. If \"\" the message will be sent to all participants.\n * @param {object} payload The payload of the message.\n * @throws NetworkError or InvalidStateError from RTCDataChannel#send (@see\n * {@link https://developer.mozilla.org/docs/Web/API/RTCDataChannel/send})\n * or from WebSocket#send or Error with \"No opened channel\" message.\n */\n sendMessage(to, payload) {\n this._send({\n colibriClass: 'EndpointMessage',\n msgPayload: payload,\n to\n });\n }\n\n /**\n * Sends a \"lastN value changed\" message via the channel.\n * @param {number} value The new value for lastN. -1 means unlimited.\n */\n sendSetLastNMessage(value) {\n const jsonObject = {\n colibriClass: 'LastNChangedEvent',\n lastN: value\n };\n\n this._send(jsonObject);\n logger.log(`Channel lastN set to: ${value}`);\n }\n\n /**\n * Sends a \"pinned endpoint changed\" message via the channel.\n * @param {string} endpointId The id of the pinned endpoint.\n * @throws NetworkError or InvalidStateError from RTCDataChannel#send (@see\n * {@link https://developer.mozilla.org/docs/Web/API/RTCDataChannel/send})\n * or from WebSocket#send or Error with \"No opened channel\" message.\n */\n sendPinnedEndpointMessage(endpointId) {\n logger.log(\n 'sending pinned changed notification to the bridge for endpoint ',\n endpointId);\n\n this._send({\n colibriClass: 'PinnedEndpointChangedEvent',\n pinnedEndpoint: endpointId || null\n });\n }\n\n /**\n * Sends a \"selected endpoints changed\" message via the channel.\n *\n * @param {Array} endpointIds - The ids of the selected endpoints.\n * @throws NetworkError or InvalidStateError from RTCDataChannel#send (@see\n * {@link https://developer.mozilla.org/docs/Web/API/RTCDataChannel/send})\n * or from WebSocket#send or Error with \"No opened channel\" message.\n */\n sendSelectedEndpointsMessage(endpointIds) {\n logger.log(\n 'sending selected changed notification to the bridge for endpoints',\n endpointIds);\n\n this._send({\n colibriClass: 'SelectedEndpointsChangedEvent',\n selectedEndpoints: endpointIds\n });\n }\n\n /**\n * Sends a \"receiver video constraint\" message via the channel.\n * @param {Number} maxFrameHeightPixels the maximum frame height,\n * in pixels, this receiver is willing to receive\n */\n sendReceiverVideoConstraintMessage(maxFrameHeightPixels) {\n logger.log('sending a ReceiverVideoConstraint message with '\n + `a maxFrameHeight of ${maxFrameHeightPixels} pixels`);\n this._send({\n colibriClass: 'ReceiverVideoConstraint',\n maxFrameHeight: maxFrameHeightPixels\n });\n }\n\n /**\n * Set events on the given RTCDataChannel or WebSocket instance.\n */\n _handleChannel(channel) {\n const emitter = this._eventEmitter;\n\n channel.onopen = () => {\n logger.info(`${this._mode} channel opened`);\n\n // Code sample for sending string and/or binary data.\n // Sends string message to the bridge:\n // channel.send(\"Hello bridge!\");\n // Sends 12 bytes binary message to the bridge:\n // channel.send(new ArrayBuffer(12));\n\n emitter.emit(RTCEvents.DATA_CHANNEL_OPEN);\n };\n\n channel.onerror = event => {\n // WS error events contain no information about the failure (this is available in the onclose event) and\n // the event references the WS object itself, which causes hangs on mobile.\n if (this._mode !== 'websocket') {\n logger.error(`Channel error: ${event.message}`);\n }\n };\n\n channel.onmessage = ({ data }) => {\n // JSON object.\n let obj;\n\n try {\n obj = JSON.parse(data);\n } catch (error) {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error(\n 'Failed to parse channel message as JSON: ',\n data, error);\n\n return;\n }\n\n const colibriClass = obj.colibriClass;\n\n switch (colibriClass) {\n case 'DominantSpeakerEndpointChangeEvent': {\n // Endpoint ID from the Videobridge.\n const dominantSpeakerEndpoint = obj.dominantSpeakerEndpoint;\n\n logger.info(\n 'Channel new dominant speaker event: ',\n dominantSpeakerEndpoint);\n emitter.emit(\n RTCEvents.DOMINANT_SPEAKER_CHANGED,\n dominantSpeakerEndpoint);\n break;\n }\n case 'EndpointConnectivityStatusChangeEvent': {\n const endpoint = obj.endpoint;\n const isActive = obj.active === 'true';\n\n logger.info(\n `Endpoint connection status changed: ${endpoint} active ? ${\n isActive}`);\n emitter.emit(RTCEvents.ENDPOINT_CONN_STATUS_CHANGED,\n endpoint, isActive);\n\n break;\n }\n case 'EndpointMessage': {\n emitter.emit(\n RTCEvents.ENDPOINT_MESSAGE_RECEIVED, obj.from,\n obj.msgPayload);\n\n break;\n }\n case 'LastNEndpointsChangeEvent': {\n // The new/latest list of last-n endpoint IDs.\n const lastNEndpoints = obj.lastNEndpoints;\n\n logger.info('Channel new last-n event: ',\n lastNEndpoints, obj);\n emitter.emit(RTCEvents.LASTN_ENDPOINT_CHANGED,\n lastNEndpoints, obj);\n\n break;\n }\n case 'SelectedUpdateEvent': {\n const isSelected = obj.isSelected;\n\n logger.info(`SelectedUpdateEvent isSelected? ${isSelected}`);\n emitter.emit(RTCEvents.IS_SELECTED_CHANGED, isSelected);\n break;\n }\n default: {\n logger.debug('Channel JSON-formatted message: ', obj);\n\n // The received message appears to be appropriately formatted\n // (i.e. is a JSON object which assigns a value to the\n // mandatory property colibriClass) so don't just swallow it,\n // expose it to public consumption.\n emitter.emit(`rtc.datachannel.${colibriClass}`, obj);\n }\n }\n };\n\n channel.onclose = event => {\n logger.info(`Channel closed by ${this._closedFromClient ? 'client' : 'server'}`);\n\n if (this._mode === 'websocket') {\n if (!this._closedFromClient) {\n logger.error(`Channel closed: ${event.code} ${event.reason}`);\n this._retryWebSocketConnection(event);\n }\n }\n\n // Remove the channel.\n this._channel = null;\n };\n\n // Store the channel.\n this._channel = channel;\n }\n\n /**\n * Sends passed object via the channel.\n * @param {object} jsonObject The object that will be sent.\n * @throws NetworkError or InvalidStateError from RTCDataChannel#send (@see\n * {@link https://developer.mozilla.org/docs/Web/API/RTCDataChannel/send})\n * or from WebSocket#send or Error with \"No opened channel\" message.\n */\n _send(jsonObject) {\n const channel = this._channel;\n\n if (!this.isOpen()) {\n logger.error('Bridge Channel send: no opened channel.');\n throw new Error('No opened channel');\n }\n\n channel.send(JSON.stringify(jsonObject));\n }\n}\n", "import {\n TYPE_OPERATIONAL,\n TYPE_PAGE,\n TYPE_TRACK,\n TYPE_UI\n} from '../../service/statistics/AnalyticsEvents';\nimport { getLogger } from 'jitsi-meet-logger';\nimport browser from '../browser';\n\nconst MAX_CACHE_SIZE = 100;\n\n// eslist-disable-line no-undef\nconst logger = getLogger(__filename);\n\n/**\n * This class provides an API to lib-jitsi-meet and its users for sending\n * analytics events. It serves as a bridge to different backend implementations\n * (\"analytics handlers\") and a cache for events attempted to be sent before\n * the analytics handlers were enabled.\n *\n * The API is designed to be an easy replacement for the previous version of\n * this adapter, and is meant to be extended with more convenience methods.\n *\n *\n * The API calls are translated to objects with the following structure, which\n * are then passed to the sendEvent(event) function of the underlying handlers:\n *\n * {\n * type,\n *\n * action,\n * actionSubject,\n * actionSubjectId,\n * attributes,\n * categories,\n * containerId,\n * containerType,\n * name,\n * objectId,\n * objectType,\n * source,\n * tags\n * }\n *\n * The 'type' is one of 'operational', 'page', 'track' or 'ui', and some of the\n * other properties are considered required according to the type.\n *\n * For events with type 'page', the required properties are: name.\n *\n * For events with type 'operational' and 'ui', the required properties are:\n * action, actionSubject, source\n *\n * For events with type 'page', the required properties are:\n * action, actionSubject, source, containerType, containerId, objectType,\n * objectId\n */\nclass AnalyticsAdapter {\n /**\n * Creates new AnalyticsAdapter instance.\n */\n constructor() {\n this.reset();\n }\n\n /**\n * Reset the state to the initial one.\n *\n * @returns {void}\n */\n reset() {\n /**\n * Whether this AnalyticsAdapter has been disposed of or not. Once this\n * is set to true, the AnalyticsAdapter is disabled and does not accept\n * any more events, and it can not be re-enabled.\n * @type {boolean}\n */\n this.disposed = false;\n\n /**\n * The set of handlers to which events will be sent.\n * @type {Set}\n */\n this.analyticsHandlers = new Set();\n\n /**\n * The cache of events which are not sent yet. The cache is enabled\n * while this field is truthy, and disabled otherwise.\n * @type {Array}\n */\n this.cache = [];\n\n /**\n * Map of properties that will be added to every event. Note that the\n * keys will be prefixed with \"permanent.\".\n */\n this.permanentProperties = {};\n\n /**\n * The name of the conference that this AnalyticsAdapter is associated\n * with.\n * @type {null}\n */\n this.conferenceName = '';\n\n this.addPermanentProperties({\n 'user_agent': navigator.userAgent,\n 'browser_name': browser.getName()\n });\n }\n\n /**\n * Dispose analytics. Clears all handlers.\n */\n dispose() {\n logger.warn('Disposing of analytics adapter.');\n\n if (this.analyticsHandlers && this.analyticsHandlers.size > 0) {\n this.analyticsHandlers.forEach(handler => {\n if (typeof handler.dispose === 'function') {\n handler.dispose();\n }\n });\n }\n\n this.setAnalyticsHandlers([]);\n this.disposed = true;\n }\n\n /**\n * Sets the handlers that are going to be used to send analytics. Sends any\n * cached events.\n * @param {Array} handlers the handlers\n */\n setAnalyticsHandlers(handlers) {\n if (this.disposed) {\n return;\n }\n\n this.analyticsHandlers = new Set(handlers);\n\n this._setUserProperties();\n\n // Note that we disable the cache even if the set of handlers is empty.\n const cache = this.cache;\n\n this.cache = null;\n if (cache) {\n cache.forEach(event => this._sendEvent(event));\n }\n }\n\n /**\n * Set the user properties to the analytics handlers.\n *\n * @returns {void}\n */\n _setUserProperties() {\n this.analyticsHandlers.forEach(handler => {\n try {\n handler.setUserProperties(this.permanentProperties);\n } catch (error) {\n logger.warn('Error in setUserProperties method of one of the '\n + `analytics handlers: ${error}`);\n }\n });\n }\n\n /**\n * Adds a set of permanent properties to this this AnalyticsAdapter.\n * Permanent properties will be added as \"attributes\" to events sent to\n * the underlying \"analytics handlers\", and their keys will be prefixed\n * by \"permanent_\", i.e. adding a permanent property {key: \"value\"} will\n * result in {\"permanent_key\": \"value\"} object to be added to the\n * \"attributes\" field of events.\n *\n * @param {Object} properties the properties to add\n */\n addPermanentProperties(properties) {\n this.permanentProperties = {\n ...this.permanentProperties,\n ...properties\n };\n\n this._setUserProperties();\n }\n\n /**\n * Sets the name of the conference that this AnalyticsAdapter is associated\n * with.\n * @param name the name to set.\n */\n setConferenceName(name) {\n this.conferenceName = name;\n this.addPermanentProperties({ 'conference_name': name });\n }\n\n /**\n * Sends an event with a given name and given properties. The first\n * parameter is either a string or an object. If it is a string, it is used\n * as the event name and the second parameter is used at the attributes to\n * attach to the event. If it is an object, it represents the whole event,\n * including any desired attributes, and the second parameter is ignored.\n *\n * @param {String|Object} eventName either a string to be used as the name\n * of the event, or an event object. If an event object is passed, the\n * properties parameters is ignored.\n * @param {Object} properties the properties/attributes to attach to the\n * event, if eventName is a string.\n */\n sendEvent(eventName, properties = {}) {\n if (this.disposed) {\n return;\n }\n\n let event = null;\n\n if (typeof eventName === 'string') {\n event = {\n type: TYPE_OPERATIONAL,\n action: eventName,\n actionSubject: eventName,\n source: eventName,\n attributes: properties\n };\n } else if (typeof eventName === 'object') {\n event = eventName;\n }\n\n if (!this._verifyRequiredFields(event)) {\n logger.error(\n `Dropping a mis-formatted event: ${JSON.stringify(event)}`);\n\n return;\n }\n\n this._sendEvent(event);\n }\n\n /**\n * Checks whether an event has all of the required fields set, and tries\n * to fill in some of the missing fields with reasonable default values.\n * Returns true if after this operation the event has all of the required\n * fields set, and false otherwise (if some of the required fields were not\n * set and the attempt to fill them in with a default failed).\n *\n * @param event the event object.\n * @return {boolean} true if the event (after the call to this function)\n * contains all of the required fields, and false otherwise.\n * @private\n */\n _verifyRequiredFields(event) {\n if (!event) {\n return false;\n }\n\n if (!event.type) {\n event.type = TYPE_OPERATIONAL;\n }\n\n const type = event.type;\n\n if (type !== TYPE_OPERATIONAL && type !== TYPE_PAGE\n && type !== TYPE_UI && type !== TYPE_TRACK) {\n logger.error(`Unknown event type: ${type}`);\n\n return false;\n }\n\n if (type === TYPE_PAGE) {\n return Boolean(event.name);\n }\n\n // Try to set some reasonable default values in case some of the\n // parameters required by the handler API are missing.\n event.action = event.action || event.name || event.actionSubject;\n event.actionSubject = event.actionSubject || event.name || event.action;\n event.source = event.source || event.name || event.action\n || event.actionSubject;\n\n if (!event.action || !event.actionSubject || !event.source) {\n logger.error(\n 'Required field missing (action, actionSubject or source)');\n\n return false;\n }\n\n // Track events have additional required fields.\n if (type === TYPE_TRACK) {\n event.objectType = event.objectType || 'generic-object-type';\n event.containerType = event.containerType || 'conference';\n if (event.containerType === 'conference' && !event.containerId) {\n event.containerId = this.conferenceName;\n }\n\n\n if (!event.objectType || !event.objectId\n || !event.containerType || !event.containerId) {\n logger.error(\n 'Required field missing (containerId, containerType, '\n + 'objectId or objectType)');\n\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Saves an event to the cache, if the cache is enabled.\n * @param event the event to save.\n * @returns {boolean} true if the event was saved, and false otherwise (i.e.\n * if the cache was disabled).\n * @private\n */\n _maybeCacheEvent(event) {\n if (this.cache) {\n this.cache.push(event);\n\n // We limit the size of the cache, in case the user fails to ever\n // set the analytics handlers.\n if (this.cache.length > MAX_CACHE_SIZE) {\n this.cache.splice(0, 1);\n }\n\n return true;\n }\n\n return false;\n\n }\n\n /**\n *\n * @param event\n * @private\n */\n _sendEvent(event) {\n if (this._maybeCacheEvent(event)) {\n // The event was consumed by the cache.\n } else {\n this.analyticsHandlers.forEach(handler => {\n try {\n handler.sendEvent(event);\n } catch (e) {\n logger.warn(`Error sending analytics event: ${e}`);\n }\n });\n }\n }\n}\n\nexport default new AnalyticsAdapter();\n", "import { getLogger } from 'jitsi-meet-logger';\nimport { BrowserDetection } from 'js-utils';\n\nconst logger = getLogger(__filename);\n\n// TODO: Move this code to js-utils.\n\n// NOTE: Now we are extending BrowserDetection in order to preserve\n// RTCBrowserType interface but maybe it worth exporting BrowserCapabilities\n// and BrowserDetection as separate objects in future.\n\n/**\n * Implements browser capabilities for lib-jitsi-meet.\n */\nexport default class BrowserCapabilities extends BrowserDetection {\n /**\n * Creates new BrowserCapabilities instance.\n */\n constructor() {\n super();\n logger.info(\n `This appears to be ${this.getName()}, ver: ${this.getVersion()}`);\n }\n\n /**\n * Tells whether or not the MediaStream/tt> is removed from\n * the PeerConnection and disposed on video mute (in order to turn\n * off the camera device).\n * @return {boolean} true if the current browser supports this\n * strategy or false otherwise.\n */\n doesVideoMuteByStreamRemove() {\n return this.isChromiumBased() || this.isSafari();\n }\n\n /**\n * Check whether or not the current browser support peer to peer connections\n * @return {boolean} true if p2p is supported or false\n * otherwise.\n */\n supportsP2P() {\n return !this.usesUnifiedPlan();\n }\n\n /**\n * Checks if the current browser is Chromium based, that is, it's either\n * Chrome / Chromium or uses it as its engine, but doesn't identify as\n * Chrome.\n *\n * This includes the following browsers:\n * - Chrome and Chromium\n * - Other browsers which use the Chrome engine, but are detected as Chrome,\n * such as Brave and Vivaldi\n * - Browsers which are NOT Chrome but use it as their engine, and have\n * custom detection code: Opera, Electron and NW.JS\n */\n isChromiumBased() {\n return this.isChrome()\n || this.isElectron()\n || this.isNWJS()\n || this.isOpera();\n }\n\n /**\n * Checks if the current browser is supported.\n *\n * @returns {boolean} true if the browser is supported, false otherwise.\n */\n isSupported() {\n return this.isChromiumBased()\n || this.isFirefox()\n || this.isReactNative()\n || (this.isSafari() && !this.isVersionLessThan('12.1'));\n }\n\n /**\n * Returns whether or not the current environment needs a user interaction\n * with the page before any unmute can occur.\n *\n * @returns {boolean}\n */\n isUserInteractionRequiredForUnmute() {\n return (this.isFirefox() && this.isVersionLessThan('68')) || this.isSafari();\n }\n\n /**\n * Checks if the current browser triggers 'onmute'/'onunmute' events when\n * user's connection is interrupted and the video stops playback.\n * @returns {*|boolean} 'true' if the event is supported or 'false'\n * otherwise.\n */\n supportsVideoMuteOnConnInterrupted() {\n return this.isChromiumBased() || this.isReactNative() || this.isSafari();\n }\n\n /**\n * Checks if the current browser reports upload and download bandwidth\n * statistics.\n * @return {boolean}\n */\n supportsBandwidthStatistics() {\n // FIXME bandwidth stats are currently not implemented for FF on our\n // side, but not sure if not possible ?\n return !this.isFirefox() && !this.isSafari();\n }\n\n /**\n * Checks if the current browser support the device change event.\n * @return {boolean}\n */\n supportsDeviceChangeEvent() {\n return navigator.mediaDevices\n && typeof navigator.mediaDevices.ondevicechange !== 'undefined'\n && typeof navigator.mediaDevices.addEventListener !== 'undefined';\n }\n\n /**\n * Checks if the current browser supports RTT statistics for srflx local\n * candidates through the legacy getStats() API.\n */\n supportsLocalCandidateRttStatistics() {\n return this.isChromiumBased() || this.isReactNative() || this.isSafari();\n }\n\n /**\n * Checks if the current browser reports round trip time statistics for\n * the ICE candidate pair.\n * @return {boolean}\n */\n supportsRTTStatistics() {\n // Firefox does not seem to report RTT for ICE candidate pair:\n // eslint-disable-next-line max-len\n // https://www.w3.org/TR/webrtc-stats/#dom-rtcicecandidatepairstats-currentroundtriptime\n // It does report mozRTT for RTP streams, but at the time of this\n // writing it's value does not make sense most of the time\n // (is reported as 1):\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1241066\n // For Chrome and others we rely on 'googRtt'.\n return !this.isFirefox();\n }\n\n /**\n * Checks whether the browser supports RTPSender.\n *\n * @returns {boolean}\n */\n supportsRtpSender() {\n return this.isFirefox() || this.isSafari();\n }\n\n /**\n * Checks whether the browser supports RTX.\n *\n * @returns {boolean}\n */\n supportsRtx() {\n return !this.isFirefox();\n }\n\n /**\n * Returns whether or not the current browser can support capturing video,\n * be it camera or desktop, and displaying received video.\n *\n * @returns {boolean}\n */\n supportsVideo() {\n return true;\n }\n\n /**\n * Checks if the browser uses plan B.\n *\n * @returns {boolean}\n */\n usesPlanB() {\n return !this.usesUnifiedPlan();\n }\n\n /**\n * Checks if the browser uses SDP munging for turning on simulcast.\n *\n * @returns {boolean}\n */\n usesSdpMungingForSimulcast() {\n return this.isChromiumBased() || this.isSafari();\n }\n\n /**\n * Checks if the browser uses unified plan.\n *\n * @returns {boolean}\n */\n usesUnifiedPlan() {\n if (this.isFirefox()) {\n return true;\n }\n\n if (this.isSafari() && typeof window.RTCRtpTransceiver !== 'undefined') {\n // eslint-disable-next-line max-len\n // https://trac.webkit.org/changeset/236144/webkit/trunk/LayoutTests/webrtc/video-addLegacyTransceiver.html\n // eslint-disable-next-line no-undef\n return Object.keys(RTCRtpTransceiver.prototype)\n .indexOf('currentDirection') > -1;\n }\n\n return false;\n }\n\n /**\n * Returns whether or not the current browser should be using the new\n * getUserMedia flow, which utilizes the adapter shim. This method should\n * be temporary and used while migrating all browsers to use adapter and\n * the new getUserMedia.\n *\n * @returns {boolean}\n */\n usesNewGumFlow() {\n const REQUIRED_CHROME_VERSION = 61;\n\n if (this.isChrome()) {\n return !this.isVersionLessThan(REQUIRED_CHROME_VERSION);\n }\n\n if (this.isFirefox() || this.isSafari()) {\n return true;\n }\n\n if (this.isChromiumBased()) {\n return this._getChromiumBasedVersion() >= REQUIRED_CHROME_VERSION;\n }\n\n return false;\n }\n\n /**\n * Checks if the browser uses webrtc-adapter. All browsers using the new\n * getUserMedia flow and Edge.\n *\n * @returns {boolean}\n */\n usesAdapter() {\n return this.usesNewGumFlow();\n }\n\n /**\n * Checks if the browser uses RIDs/MIDs for siganling the simulcast streams\n * to the bridge instead of the ssrcs.\n */\n usesRidsForSimulcast() {\n return false;\n }\n\n /**\n * Checks if the browser supports getDisplayMedia.\n * @returns {boolean} {@code true} if the browser supports getDisplayMedia.\n */\n supportsGetDisplayMedia() {\n return typeof navigator.getDisplayMedia !== 'undefined'\n || (typeof navigator.mediaDevices !== 'undefined'\n && typeof navigator.mediaDevices.getDisplayMedia\n !== 'undefined');\n }\n\n /**\n * Checks if the browser supports insertable streams, needed for E2EE.\n * @returns {boolean} {@code true} if the browser supports insertable streams.\n */\n supportsInsertableStreams() {\n return Boolean(typeof window.RTCRtpSender !== 'undefined'\n && window.RTCRtpSender.prototype.createEncodedVideoStreams);\n }\n\n /**\n * Checks if the browser supports the \"sdpSemantics\" configuration option.\n * https://webrtc.org/web-apis/chrome/unified-plan/\n *\n * @returns {boolean}\n */\n supportsSdpSemantics() {\n return this.isChromiumBased() && this._getChromiumBasedVersion() >= 65;\n }\n\n /**\n * Returns the version of a Chromium based browser.\n *\n * @returns {Number}\n */\n _getChromiumBasedVersion() {\n if (this.isChromiumBased()) {\n // NW.JS doesn't expose the Chrome version in the UA string.\n if (this.isNWJS()) {\n // eslint-disable-next-line no-undef\n return Number.parseInt(process.versions.chromium, 10);\n }\n\n // Here we process all browsers which use the Chrome engine but\n // don't necessarily identify as Chrome. We cannot use the version\n // comparing functions because the Electron, Opera and NW.JS\n // versions are inconsequential here, as we need to know the actual\n // Chrome engine version.\n const ua = navigator.userAgent;\n\n if (ua.match(/Chrome/)) {\n const version\n = Number.parseInt(ua.match(/Chrome\\/([\\d.]+)/)[1], 10);\n\n return version;\n }\n }\n\n return -1;\n }\n}\n", "!function(e,t){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define([],t):\"object\"==typeof exports?exports.bowser=t():e.bowser=t()}(this,(function(){return function(e){var t={};function r(i){if(t[i])return t[i].exports;var n=t[i]={i:i,l:!1,exports:{}};return e[i].call(n.exports,n,n.exports,r),n.l=!0,n.exports}return r.m=e,r.c=t,r.d=function(e,t,i){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},r.r=function(e){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&\"object\"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(r.r(i),Object.defineProperty(i,\"default\",{enumerable:!0,value:e}),2&t&&\"string\"!=typeof e)for(var n in e)r.d(i,n,function(t){return e[t]}.bind(null,n));return i},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,\"a\",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p=\"\",r(r.s=90)}({17:function(e,t,r){\"use strict\";t.__esModule=!0,t.default=void 0;var i=r(18),n=function(){function e(){}return e.getFirstMatch=function(e,t){var r=t.match(e);return r&&r.length>0&&r[1]||\"\"},e.getSecondMatch=function(e,t){var r=t.match(e);return r&&r.length>1&&r[2]||\"\"},e.matchAndReturnConst=function(e,t,r){if(e.test(t))return r},e.getWindowsVersionName=function(e){switch(e){case\"NT\":return\"NT\";case\"XP\":return\"XP\";case\"NT 5.0\":return\"2000\";case\"NT 5.1\":return\"XP\";case\"NT 5.2\":return\"2003\";case\"NT 6.0\":return\"Vista\";case\"NT 6.1\":return\"7\";case\"NT 6.2\":return\"8\";case\"NT 6.3\":return\"8.1\";case\"NT 10.0\":return\"10\";default:return}},e.getMacOSVersionName=function(e){var t=e.split(\".\").splice(0,2).map((function(e){return parseInt(e,10)||0}));if(t.push(0),10===t[0])switch(t[1]){case 5:return\"Leopard\";case 6:return\"Snow Leopard\";case 7:return\"Lion\";case 8:return\"Mountain Lion\";case 9:return\"Mavericks\";case 10:return\"Yosemite\";case 11:return\"El Capitan\";case 12:return\"Sierra\";case 13:return\"High Sierra\";case 14:return\"Mojave\";case 15:return\"Catalina\";default:return}},e.getAndroidVersionName=function(e){var t=e.split(\".\").splice(0,2).map((function(e){return parseInt(e,10)||0}));if(t.push(0),!(1===t[0]&&t[1]<5))return 1===t[0]&&t[1]<6?\"Cupcake\":1===t[0]&&t[1]>=6?\"Donut\":2===t[0]&&t[1]<2?\"Eclair\":2===t[0]&&2===t[1]?\"Froyo\":2===t[0]&&t[1]>2?\"Gingerbread\":3===t[0]?\"Honeycomb\":4===t[0]&&t[1]<1?\"Ice Cream Sandwich\":4===t[0]&&t[1]<4?\"Jelly Bean\":4===t[0]&&t[1]>=4?\"KitKat\":5===t[0]?\"Lollipop\":6===t[0]?\"Marshmallow\":7===t[0]?\"Nougat\":8===t[0]?\"Oreo\":9===t[0]?\"Pie\":void 0},e.getVersionPrecision=function(e){return e.split(\".\").length},e.compareVersions=function(t,r,i){void 0===i&&(i=!1);var n=e.getVersionPrecision(t),s=e.getVersionPrecision(r),o=Math.max(n,s),a=0,u=e.map([t,r],(function(t){var r=o-e.getVersionPrecision(t),i=t+new Array(r+1).join(\".0\");return e.map(i.split(\".\"),(function(e){return new Array(20-e.length).join(\"0\")+e})).reverse()}));for(i&&(a=o-Math.min(n,s)),o-=1;o>=a;){if(u[0][o]>u[1][o])return 1;if(u[0][o]===u[1][o]){if(o===a)return 0;o-=1}else if(u[0][o]0){var o=Object.keys(r),a=o.find((function(e){return t.isOS(e)}));if(a){var u=this.satisfies(r[a]);if(void 0!==u)return u}var d=o.find((function(e){return t.isPlatform(e)}));if(d){var c=this.satisfies(r[d]);if(void 0!==c)return c}}if(s>0){var f=Object.keys(n).find((function(e){return t.isBrowser(e,!0)}));if(void 0!==f)return this.compareVersion(n[f])}},t.isBrowser=function(e,t){void 0===t&&(t=!1);var r=this.getBrowserName().toLowerCase(),i=e.toLowerCase(),n=a.default.getBrowserTypeByAlias(i);return t&&n&&(i=n.toLowerCase()),i===r},t.compareVersion=function(e){var t=[0],r=e,i=!1,n=this.getBrowserVersion();if(\"string\"==typeof n)return\">\"===e[0]||\"<\"===e[0]?(r=e.substr(1),\"=\"===e[1]?(i=!0,r=e.substr(2)):t=[],\">\"===e[0]?t.push(1):t.push(-1)):\"=\"===e[0]?r=e.substr(1):\"~\"===e[0]&&(i=!0,r=e.substr(1)),t.indexOf(a.default.compareVersions(n,r,i))>-1},t.isOS=function(e){return this.getOSName(!0)===String(e).toLowerCase()},t.isPlatform=function(e){return this.getPlatformType(!0)===String(e).toLowerCase()},t.isEngine=function(e){return this.getEngineName(!0)===String(e).toLowerCase()},t.is=function(e){return this.isBrowser(e)||this.isOS(e)||this.isPlatform(e)},t.some=function(e){var t=this;return void 0===e&&(e=[]),e.some((function(e){return t.is(e)}))},e}();t.default=d,e.exports=t.default},92:function(e,t,r){\"use strict\";t.__esModule=!0,t.default=void 0;var i,n=(i=r(17))&&i.__esModule?i:{default:i};var s=/version\\/(\\d+(\\.?_?\\d+)+)/i,o=[{test:[/googlebot/i],describe:function(e){var t={name:\"Googlebot\"},r=n.default.getFirstMatch(/googlebot\\/(\\d+(\\.\\d+))/i,e)||n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/opera/i],describe:function(e){var t={name:\"Opera\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/(?:opera)[\\s/](\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/opr\\/|opios/i],describe:function(e){var t={name:\"Opera\"},r=n.default.getFirstMatch(/(?:opr|opios)[\\s/](\\S+)/i,e)||n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/SamsungBrowser/i],describe:function(e){var t={name:\"Samsung Internet for Android\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/(?:SamsungBrowser)[\\s/](\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/Whale/i],describe:function(e){var t={name:\"NAVER Whale Browser\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/(?:whale)[\\s/](\\d+(?:\\.\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/MZBrowser/i],describe:function(e){var t={name:\"MZ Browser\"},r=n.default.getFirstMatch(/(?:MZBrowser)[\\s/](\\d+(?:\\.\\d+)+)/i,e)||n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/focus/i],describe:function(e){var t={name:\"Focus\"},r=n.default.getFirstMatch(/(?:focus)[\\s/](\\d+(?:\\.\\d+)+)/i,e)||n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/swing/i],describe:function(e){var t={name:\"Swing\"},r=n.default.getFirstMatch(/(?:swing)[\\s/](\\d+(?:\\.\\d+)+)/i,e)||n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/coast/i],describe:function(e){var t={name:\"Opera Coast\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/(?:coast)[\\s/](\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/yabrowser/i],describe:function(e){var t={name:\"Yandex Browser\"},r=n.default.getFirstMatch(/(?:yabrowser)[\\s/](\\d+(\\.?_?\\d+)+)/i,e)||n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/ucbrowser/i],describe:function(e){var t={name:\"UC Browser\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/(?:ucbrowser)[\\s/](\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/Maxthon|mxios/i],describe:function(e){var t={name:\"Maxthon\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/(?:Maxthon|mxios)[\\s/](\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/epiphany/i],describe:function(e){var t={name:\"Epiphany\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/(?:epiphany)[\\s/](\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/puffin/i],describe:function(e){var t={name:\"Puffin\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/(?:puffin)[\\s/](\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/sleipnir/i],describe:function(e){var t={name:\"Sleipnir\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/(?:sleipnir)[\\s/](\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/k-meleon/i],describe:function(e){var t={name:\"K-Meleon\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/(?:k-meleon)[\\s/](\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/micromessenger/i],describe:function(e){var t={name:\"WeChat\"},r=n.default.getFirstMatch(/(?:micromessenger)[\\s/](\\d+(\\.?_?\\d+)+)/i,e)||n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/qqbrowser/i],describe:function(e){var t={name:/qqbrowserlite/i.test(e)?\"QQ Browser Lite\":\"QQ Browser\"},r=n.default.getFirstMatch(/(?:qqbrowserlite|qqbrowser)[/](\\d+(\\.?_?\\d+)+)/i,e)||n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/msie|trident/i],describe:function(e){var t={name:\"Internet Explorer\"},r=n.default.getFirstMatch(/(?:msie |rv:)(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/\\sedg\\//i],describe:function(e){var t={name:\"Microsoft Edge\"},r=n.default.getFirstMatch(/\\sedg\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/edg([ea]|ios)/i],describe:function(e){var t={name:\"Microsoft Edge\"},r=n.default.getSecondMatch(/edg([ea]|ios)\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/vivaldi/i],describe:function(e){var t={name:\"Vivaldi\"},r=n.default.getFirstMatch(/vivaldi\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/seamonkey/i],describe:function(e){var t={name:\"SeaMonkey\"},r=n.default.getFirstMatch(/seamonkey\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/sailfish/i],describe:function(e){var t={name:\"Sailfish\"},r=n.default.getFirstMatch(/sailfish\\s?browser\\/(\\d+(\\.\\d+)?)/i,e);return r&&(t.version=r),t}},{test:[/silk/i],describe:function(e){var t={name:\"Amazon Silk\"},r=n.default.getFirstMatch(/silk\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/phantom/i],describe:function(e){var t={name:\"PhantomJS\"},r=n.default.getFirstMatch(/phantomjs\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/slimerjs/i],describe:function(e){var t={name:\"SlimerJS\"},r=n.default.getFirstMatch(/slimerjs\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/blackberry|\\bbb\\d+/i,/rim\\stablet/i],describe:function(e){var t={name:\"BlackBerry\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/blackberry[\\d]+\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/(web|hpw)[o0]s/i],describe:function(e){var t={name:\"WebOS Browser\"},r=n.default.getFirstMatch(s,e)||n.default.getFirstMatch(/w(?:eb)?[o0]sbrowser\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/bada/i],describe:function(e){var t={name:\"Bada\"},r=n.default.getFirstMatch(/dolfin\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/tizen/i],describe:function(e){var t={name:\"Tizen\"},r=n.default.getFirstMatch(/(?:tizen\\s?)?browser\\/(\\d+(\\.?_?\\d+)+)/i,e)||n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/qupzilla/i],describe:function(e){var t={name:\"QupZilla\"},r=n.default.getFirstMatch(/(?:qupzilla)[\\s/](\\d+(\\.?_?\\d+)+)/i,e)||n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/firefox|iceweasel|fxios/i],describe:function(e){var t={name:\"Firefox\"},r=n.default.getFirstMatch(/(?:firefox|iceweasel|fxios)[\\s/](\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/chromium/i],describe:function(e){var t={name:\"Chromium\"},r=n.default.getFirstMatch(/(?:chromium)[\\s/](\\d+(\\.?_?\\d+)+)/i,e)||n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/chrome|crios|crmo/i],describe:function(e){var t={name:\"Chrome\"},r=n.default.getFirstMatch(/(?:chrome|crios|crmo)\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/GSA/i],describe:function(e){var t={name:\"Google Search\"},r=n.default.getFirstMatch(/(?:GSA)\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:function(e){var t=!e.test(/like android/i),r=e.test(/android/i);return t&&r},describe:function(e){var t={name:\"Android Browser\"},r=n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/playstation 4/i],describe:function(e){var t={name:\"PlayStation 4\"},r=n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/safari|applewebkit/i],describe:function(e){var t={name:\"Safari\"},r=n.default.getFirstMatch(s,e);return r&&(t.version=r),t}},{test:[/.*/i],describe:function(e){var t=-1!==e.search(\"\\\\(\")?/^(.*)\\/(.*)[ \\t]\\((.*)/:/^(.*)\\/(.*) /;return{name:n.default.getFirstMatch(t,e),version:n.default.getSecondMatch(t,e)}}}];t.default=o,e.exports=t.default},93:function(e,t,r){\"use strict\";t.__esModule=!0,t.default=void 0;var i,n=(i=r(17))&&i.__esModule?i:{default:i},s=r(18);var o=[{test:[/Roku\\/DVP/],describe:function(e){var t=n.default.getFirstMatch(/Roku\\/DVP-(\\d+\\.\\d+)/i,e);return{name:s.OS_MAP.Roku,version:t}}},{test:[/windows phone/i],describe:function(e){var t=n.default.getFirstMatch(/windows phone (?:os)?\\s?(\\d+(\\.\\d+)*)/i,e);return{name:s.OS_MAP.WindowsPhone,version:t}}},{test:[/windows/i],describe:function(e){var t=n.default.getFirstMatch(/Windows ((NT|XP)( \\d\\d?.\\d)?)/i,e),r=n.default.getWindowsVersionName(t);return{name:s.OS_MAP.Windows,version:t,versionName:r}}},{test:[/macintosh/i],describe:function(e){var t=n.default.getFirstMatch(/mac os x (\\d+(\\.?_?\\d+)+)/i,e).replace(/[_\\s]/g,\".\"),r=n.default.getMacOSVersionName(t),i={name:s.OS_MAP.MacOS,version:t};return r&&(i.versionName=r),i}},{test:[/(ipod|iphone|ipad)/i],describe:function(e){var t=n.default.getFirstMatch(/os (\\d+([_\\s]\\d+)*) like mac os x/i,e).replace(/[_\\s]/g,\".\");return{name:s.OS_MAP.iOS,version:t}}},{test:function(e){var t=!e.test(/like android/i),r=e.test(/android/i);return t&&r},describe:function(e){var t=n.default.getFirstMatch(/android[\\s/-](\\d+(\\.\\d+)*)/i,e),r=n.default.getAndroidVersionName(t),i={name:s.OS_MAP.Android,version:t};return r&&(i.versionName=r),i}},{test:[/(web|hpw)[o0]s/i],describe:function(e){var t=n.default.getFirstMatch(/(?:web|hpw)[o0]s\\/(\\d+(\\.\\d+)*)/i,e),r={name:s.OS_MAP.WebOS};return t&&t.length&&(r.version=t),r}},{test:[/blackberry|\\bbb\\d+/i,/rim\\stablet/i],describe:function(e){var t=n.default.getFirstMatch(/rim\\stablet\\sos\\s(\\d+(\\.\\d+)*)/i,e)||n.default.getFirstMatch(/blackberry\\d+\\/(\\d+([_\\s]\\d+)*)/i,e)||n.default.getFirstMatch(/\\bbb(\\d+)/i,e);return{name:s.OS_MAP.BlackBerry,version:t}}},{test:[/bada/i],describe:function(e){var t=n.default.getFirstMatch(/bada\\/(\\d+(\\.\\d+)*)/i,e);return{name:s.OS_MAP.Bada,version:t}}},{test:[/tizen/i],describe:function(e){var t=n.default.getFirstMatch(/tizen[/\\s](\\d+(\\.\\d+)*)/i,e);return{name:s.OS_MAP.Tizen,version:t}}},{test:[/linux/i],describe:function(){return{name:s.OS_MAP.Linux}}},{test:[/CrOS/],describe:function(){return{name:s.OS_MAP.ChromeOS}}},{test:[/PlayStation 4/],describe:function(e){var t=n.default.getFirstMatch(/PlayStation 4[/\\s](\\d+(\\.\\d+)*)/i,e);return{name:s.OS_MAP.PlayStation4,version:t}}}];t.default=o,e.exports=t.default},94:function(e,t,r){\"use strict\";t.__esModule=!0,t.default=void 0;var i,n=(i=r(17))&&i.__esModule?i:{default:i},s=r(18);var o=[{test:[/googlebot/i],describe:function(){return{type:\"bot\",vendor:\"Google\"}}},{test:[/huawei/i],describe:function(e){var t=n.default.getFirstMatch(/(can-l01)/i,e)&&\"Nova\",r={type:s.PLATFORMS_MAP.mobile,vendor:\"Huawei\"};return t&&(r.model=t),r}},{test:[/nexus\\s*(?:7|8|9|10).*/i],describe:function(){return{type:s.PLATFORMS_MAP.tablet,vendor:\"Nexus\"}}},{test:[/ipad/i],describe:function(){return{type:s.PLATFORMS_MAP.tablet,vendor:\"Apple\",model:\"iPad\"}}},{test:[/kftt build/i],describe:function(){return{type:s.PLATFORMS_MAP.tablet,vendor:\"Amazon\",model:\"Kindle Fire HD 7\"}}},{test:[/silk/i],describe:function(){return{type:s.PLATFORMS_MAP.tablet,vendor:\"Amazon\"}}},{test:[/tablet(?! pc)/i],describe:function(){return{type:s.PLATFORMS_MAP.tablet}}},{test:function(e){var t=e.test(/ipod|iphone/i),r=e.test(/like (ipod|iphone)/i);return t&&!r},describe:function(e){var t=n.default.getFirstMatch(/(ipod|iphone)/i,e);return{type:s.PLATFORMS_MAP.mobile,vendor:\"Apple\",model:t}}},{test:[/nexus\\s*[0-6].*/i,/galaxy nexus/i],describe:function(){return{type:s.PLATFORMS_MAP.mobile,vendor:\"Nexus\"}}},{test:[/[^-]mobi/i],describe:function(){return{type:s.PLATFORMS_MAP.mobile}}},{test:function(e){return\"blackberry\"===e.getBrowserName(!0)},describe:function(){return{type:s.PLATFORMS_MAP.mobile,vendor:\"BlackBerry\"}}},{test:function(e){return\"bada\"===e.getBrowserName(!0)},describe:function(){return{type:s.PLATFORMS_MAP.mobile}}},{test:function(e){return\"windows phone\"===e.getBrowserName()},describe:function(){return{type:s.PLATFORMS_MAP.mobile,vendor:\"Microsoft\"}}},{test:function(e){var t=Number(String(e.getOSVersion()).split(\".\")[0]);return\"android\"===e.getOSName(!0)&&t>=3},describe:function(){return{type:s.PLATFORMS_MAP.tablet}}},{test:function(e){return\"android\"===e.getOSName(!0)},describe:function(){return{type:s.PLATFORMS_MAP.mobile}}},{test:function(e){return\"macos\"===e.getOSName(!0)},describe:function(){return{type:s.PLATFORMS_MAP.desktop,vendor:\"Apple\"}}},{test:function(e){return\"windows\"===e.getOSName(!0)},describe:function(){return{type:s.PLATFORMS_MAP.desktop}}},{test:function(e){return\"linux\"===e.getOSName(!0)},describe:function(){return{type:s.PLATFORMS_MAP.desktop}}},{test:function(e){return\"playstation 4\"===e.getOSName(!0)},describe:function(){return{type:s.PLATFORMS_MAP.tv}}},{test:function(e){return\"roku\"===e.getOSName(!0)},describe:function(){return{type:s.PLATFORMS_MAP.tv}}}];t.default=o,e.exports=t.default},95:function(e,t,r){\"use strict\";t.__esModule=!0,t.default=void 0;var i,n=(i=r(17))&&i.__esModule?i:{default:i},s=r(18);var o=[{test:function(e){return\"microsoft edge\"===e.getBrowserName(!0)},describe:function(e){if(/\\sedg\\//i.test(e))return{name:s.ENGINE_MAP.Blink};var t=n.default.getFirstMatch(/edge\\/(\\d+(\\.?_?\\d+)+)/i,e);return{name:s.ENGINE_MAP.EdgeHTML,version:t}}},{test:[/trident/i],describe:function(e){var t={name:s.ENGINE_MAP.Trident},r=n.default.getFirstMatch(/trident\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:function(e){return e.test(/presto/i)},describe:function(e){var t={name:s.ENGINE_MAP.Presto},r=n.default.getFirstMatch(/presto\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:function(e){var t=e.test(/gecko/i),r=e.test(/like gecko/i);return t&&!r},describe:function(e){var t={name:s.ENGINE_MAP.Gecko},r=n.default.getFirstMatch(/gecko\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}},{test:[/(apple)?webkit\\/537\\.36/i],describe:function(){return{name:s.ENGINE_MAP.Blink}}},{test:[/(apple)?webkit/i],describe:function(e){var t={name:s.ENGINE_MAP.WebKit},r=n.default.getFirstMatch(/webkit\\/(\\d+(\\.?_?\\d+)+)/i,e);return r&&(t.version=r),t}}];t.default=o,e.exports=t.default}})}));", "import browser from '../browser';\nimport { browsers } from 'js-utils';\n\nimport * as StatisticsEvents from '../../service/statistics/Events';\nimport * as MediaType from '../../service/RTC/MediaType';\n\nconst GlobalOnErrorHandler = require('../util/GlobalOnErrorHandler');\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\n\n/**\n * The lib-jitsi-meet browser-agnostic names of the browser-specific keys\n * reported by RTCPeerConnection#getStats mapped by browser.\n */\nconst KEYS_BY_BROWSER_TYPE = {};\n\nKEYS_BY_BROWSER_TYPE[browsers.FIREFOX] = {\n 'ssrc': 'ssrc',\n 'packetsReceived': 'packetsReceived',\n 'packetsLost': 'packetsLost',\n 'packetsSent': 'packetsSent',\n 'bytesReceived': 'bytesReceived',\n 'bytesSent': 'bytesSent',\n 'framerateMean': 'framerateMean',\n 'ip': 'address',\n 'port': 'port',\n 'protocol': 'protocol'\n};\nKEYS_BY_BROWSER_TYPE[browsers.CHROME] = {\n 'receiveBandwidth': 'googAvailableReceiveBandwidth',\n 'sendBandwidth': 'googAvailableSendBandwidth',\n 'remoteAddress': 'googRemoteAddress',\n 'transportType': 'googTransportType',\n 'localAddress': 'googLocalAddress',\n 'activeConnection': 'googActiveConnection',\n 'ssrc': 'ssrc',\n 'packetsReceived': 'packetsReceived',\n 'packetsSent': 'packetsSent',\n 'packetsLost': 'packetsLost',\n 'bytesReceived': 'bytesReceived',\n 'bytesSent': 'bytesSent',\n 'googFrameHeightReceived': 'googFrameHeightReceived',\n 'googFrameWidthReceived': 'googFrameWidthReceived',\n 'googFrameHeightSent': 'googFrameHeightSent',\n 'googFrameWidthSent': 'googFrameWidthSent',\n 'googFrameRateReceived': 'googFrameRateReceived',\n 'googFrameRateSent': 'googFrameRateSent',\n 'audioInputLevel': 'audioInputLevel',\n 'audioOutputLevel': 'audioOutputLevel',\n 'currentRoundTripTime': 'googRtt',\n 'remoteCandidateType': 'googRemoteCandidateType',\n 'localCandidateType': 'googLocalCandidateType',\n 'ip': 'ip',\n 'port': 'port',\n 'protocol': 'protocol'\n};\nKEYS_BY_BROWSER_TYPE[browsers.OPERA]\n = KEYS_BY_BROWSER_TYPE[browsers.CHROME];\nKEYS_BY_BROWSER_TYPE[browsers.NWJS]\n = KEYS_BY_BROWSER_TYPE[browsers.CHROME];\nKEYS_BY_BROWSER_TYPE[browsers.ELECTRON]\n = KEYS_BY_BROWSER_TYPE[browsers.CHROME];\nKEYS_BY_BROWSER_TYPE[browsers.SAFARI]\n = KEYS_BY_BROWSER_TYPE[browsers.CHROME];\nKEYS_BY_BROWSER_TYPE[browsers.REACT_NATIVE]\n = KEYS_BY_BROWSER_TYPE[browsers.CHROME];\n\n/**\n * Calculates packet lost percent using the number of lost packets and the\n * number of all packet.\n * @param lostPackets the number of lost packets\n * @param totalPackets the number of all packets.\n * @returns {number} packet loss percent\n */\nfunction calculatePacketLoss(lostPackets, totalPackets) {\n if (!totalPackets || totalPackets <= 0\n || !lostPackets || lostPackets <= 0) {\n return 0;\n }\n\n return Math.round((lostPackets / totalPackets) * 100);\n}\n\n/**\n * Holds \"statistics\" for a single SSRC.\n * @constructor\n */\nfunction SsrcStats() {\n this.loss = {};\n this.bitrate = {\n download: 0,\n upload: 0\n };\n this.resolution = {};\n this.framerate = 0;\n}\n\n/**\n * Sets the \"loss\" object.\n * @param loss the value to set.\n */\nSsrcStats.prototype.setLoss = function(loss) {\n this.loss = loss || {};\n};\n\n/**\n * Sets resolution that belong to the ssrc represented by this instance.\n * @param resolution new resolution value to be set.\n */\nSsrcStats.prototype.setResolution = function(resolution) {\n this.resolution = resolution || {};\n};\n\n/**\n * Adds the \"download\" and \"upload\" fields from the \"bitrate\" parameter to\n * the respective fields of the \"bitrate\" field of this object.\n * @param bitrate an object holding the values to add.\n */\nSsrcStats.prototype.addBitrate = function(bitrate) {\n this.bitrate.download += bitrate.download;\n this.bitrate.upload += bitrate.upload;\n};\n\n/**\n * Resets the bit rate for given ssrc that belong to the peer\n * represented by this instance.\n */\nSsrcStats.prototype.resetBitrate = function() {\n this.bitrate.download = 0;\n this.bitrate.upload = 0;\n};\n\n/**\n * Sets the \"framerate\".\n * @param framerate the value to set.\n */\nSsrcStats.prototype.setFramerate = function(framerate) {\n this.framerate = framerate || 0;\n};\n\n/**\n *\n */\nfunction ConferenceStats() {\n\n /**\n * The bandwidth\n * @type {{}}\n */\n this.bandwidth = {};\n\n /**\n * The bit rate\n * @type {{}}\n */\n this.bitrate = {};\n\n /**\n * The packet loss rate\n * @type {{}}\n */\n this.packetLoss = null;\n\n /**\n * Array with the transport information.\n * @type {Array}\n */\n this.transport = [];\n}\n\n/* eslint-disable max-params */\n\n/**\n * StatsCollector registers for stats updates of given\n * peerconnection in given interval. On each update particular\n * stats are extracted and put in {@link SsrcStats} objects. Once the processing\n * is done audioLevelsUpdateCallback is called with this\n * instance as an event source.\n *\n * @param peerconnection WebRTC PeerConnection object.\n * @param audioLevelsInterval\n * @param statsInterval stats refresh interval given in ms.\n * @param eventEmitter\n * @constructor\n */\nexport default function StatsCollector(\n peerconnection,\n audioLevelsInterval,\n statsInterval,\n eventEmitter) {\n // StatsCollector depends entirely on the format of the reports returned by\n // RTCPeerConnection#getStats. Given that the value of\n // browser#getName() is very unlikely to change at runtime, it\n // makes sense to discover whether StatsCollector supports the executing\n // browser as soon as possible. Otherwise, (1) getStatValue would have to\n // needlessly check a \"static\" condition multiple times very very often and\n // (2) the lack of support for the executing browser would be discovered and\n // reported multiple times very very often too late in the execution in some\n // totally unrelated callback.\n /**\n * The browser type supported by this StatsCollector. In other words, the\n * type of the browser which initialized this StatsCollector\n * instance.\n * @private\n */\n this._browserType = browser.getName();\n const keys = KEYS_BY_BROWSER_TYPE[this._browserType];\n\n if (!keys) {\n // eslint-disable-next-line no-throw-literal\n throw `The browser type '${this._browserType}' isn't supported!`;\n }\n\n /**\n * Whether to use the Promise-based getStats API or not.\n * @type {boolean}\n */\n this._usesPromiseGetStats\n = browser.isSafari() || browser.isFirefox();\n\n /**\n * The function which is to be used to retrieve the value associated in a\n * report returned by RTCPeerConnection#getStats with a lib-jitsi-meet\n * browser-agnostic name/key.\n *\n * @function\n * @private\n */\n this._getStatValue\n = this._usesPromiseGetStats\n ? this._defineNewGetStatValueMethod(keys)\n : this._defineGetStatValueMethod(keys);\n\n this.peerconnection = peerconnection;\n this.baselineAudioLevelsReport = null;\n this.currentAudioLevelsReport = null;\n this.currentStatsReport = null;\n this.previousStatsReport = null;\n this.audioLevelReportHistory = {};\n this.audioLevelsIntervalId = null;\n this.eventEmitter = eventEmitter;\n this.conferenceStats = new ConferenceStats();\n\n // Updates stats interval\n this.audioLevelsIntervalMilis = audioLevelsInterval;\n\n this.statsIntervalId = null;\n this.statsIntervalMilis = statsInterval;\n\n /**\n * Maps SSRC numbers to {@link SsrcStats}.\n * @type {MapgetStats method.\n * @param error an error that occurred on getStats call.\n */\nStatsCollector.prototype.errorCallback = function(error) {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error('Get stats error', error);\n this.stop();\n};\n\n/**\n * Starts stats updates.\n */\nStatsCollector.prototype.start = function(startAudioLevelStats) {\n const self = this;\n\n if (startAudioLevelStats) {\n this.audioLevelsIntervalId = setInterval(\n () => {\n // Interval updates\n self.peerconnection.getStats(\n report => {\n let results = null;\n\n if (!report || !report.result\n || typeof report.result !== 'function') {\n results = report;\n } else {\n results = report.result();\n }\n self.currentAudioLevelsReport = results;\n if (this._usesPromiseGetStats) {\n self.processNewAudioLevelReport();\n } else {\n self.processAudioLevelReport();\n }\n\n self.baselineAudioLevelsReport\n = self.currentAudioLevelsReport;\n },\n error => self.errorCallback(error)\n );\n },\n self.audioLevelsIntervalMilis\n );\n }\n\n this.statsIntervalId = setInterval(\n () => {\n // Interval updates\n self.peerconnection.getStats(\n report => {\n let results = null;\n\n if (!report || !report.result\n || typeof report.result !== 'function') {\n // firefox\n results = report;\n } else {\n // chrome\n results = report.result();\n }\n\n self.currentStatsReport = results;\n try {\n if (this._usesPromiseGetStats) {\n self.processNewStatsReport();\n } else {\n self.processStatsReport();\n }\n } catch (e) {\n GlobalOnErrorHandler.callErrorHandler(e);\n logger.error(`Unsupported key:${e}`, e);\n }\n\n self.previousStatsReport = self.currentStatsReport;\n },\n error => self.errorCallback(error)\n );\n },\n self.statsIntervalMilis\n );\n};\n\n/**\n * Defines a function which (1) is to be used as a StatsCollector method and (2)\n * gets the value from a specific report returned by RTCPeerConnection#getStats\n * associated with a lib-jitsi-meet browser-agnostic name.\n *\n * @param {Object.} keys the map of LibJitsi browser-agnostic\n * names to RTCPeerConnection#getStats browser-specific keys\n */\nStatsCollector.prototype._defineGetStatValueMethod = function(keys) {\n // Define the function which converts a lib-jitsi-meet browser-asnostic name\n // to a browser-specific key of a report returned by\n // RTCPeerConnection#getStats.\n const keyFromName = function(name) {\n const key = keys[name];\n\n if (key) {\n return key;\n }\n\n // eslint-disable-next-line no-throw-literal\n throw `The property '${name}' isn't supported!`;\n };\n\n // Define the function which retrieves the value from a specific report\n // returned by RTCPeerConnection#getStats associated with a given\n // browser-specific key.\n let itemStatByKey;\n\n switch (this._browserType) {\n case browsers.CHROME:\n case browsers.OPERA:\n case browsers.NWJS:\n case browsers.ELECTRON:\n // TODO What about other types of browser which are based on Chrome such\n // as NW.js? Every time we want to support a new type browser we have to\n // go and add more conditions (here and in multiple other places).\n // Cannot we do a feature detection instead of a browser type check? For\n // example, if item has a stat property of type function, then it's very\n // likely that whoever defined it wanted you to call it in order to\n // retrieve the value associated with a specific key.\n itemStatByKey = (item, key) => item.stat(key);\n break;\n case browsers.REACT_NATIVE:\n // The implementation provided by react-native-webrtc follows the\n // Objective-C WebRTC API: RTCStatsReport has a values property of type\n // Array in which each element is a key-value pair.\n itemStatByKey = function(item, key) {\n let value;\n\n item.values.some(pair => {\n if (pair.hasOwnProperty(key)) {\n value = pair[key];\n\n return true;\n }\n\n return false;\n\n });\n\n return value;\n };\n break;\n default:\n itemStatByKey = (item, key) => item[key];\n }\n\n // Compose the 2 functions defined above to get a function which retrieves\n // the value from a specific report returned by RTCPeerConnection#getStats\n // associated with a specific lib-jitsi-meet browser-agnostic name.\n return (item, name) => itemStatByKey(item, keyFromName(name));\n};\n\n/**\n * Obtains a stat value from given stat and converts it to a non-negative\n * number. If the value is either invalid or negative then 0 will be returned.\n * @param report\n * @param {string} name\n * @return {number}\n * @private\n */\nStatsCollector.prototype.getNonNegativeStat = function(report, name) {\n let value = this._getStatValue(report, name);\n\n if (typeof value !== 'number') {\n value = Number(value);\n }\n\n if (isNaN(value)) {\n return 0;\n }\n\n return Math.max(0, value);\n};\n\n/* eslint-disable no-continue */\n\n/**\n * Stats processing logic.\n */\nStatsCollector.prototype.processStatsReport = function() {\n if (!this.previousStatsReport) {\n return;\n }\n\n const getStatValue = this._getStatValue;\n const byteSentStats = {};\n\n for (const idx in this.currentStatsReport) {\n if (!this.currentStatsReport.hasOwnProperty(idx)) {\n continue;\n }\n const now = this.currentStatsReport[idx];\n\n // The browser API may return \"undefined\" values in the array\n if (!now) {\n continue;\n }\n\n try {\n const receiveBandwidth = getStatValue(now, 'receiveBandwidth');\n const sendBandwidth = getStatValue(now, 'sendBandwidth');\n\n if (receiveBandwidth || sendBandwidth) {\n this.conferenceStats.bandwidth = {\n 'download': Math.round(receiveBandwidth / 1000),\n 'upload': Math.round(sendBandwidth / 1000)\n };\n }\n } catch (e) { /* not supported*/ }\n\n if (now.type === 'googCandidatePair') {\n let active, ip, localCandidateType, localip,\n remoteCandidateType, rtt, type;\n\n try {\n active = getStatValue(now, 'activeConnection');\n if (!active) {\n continue;\n }\n\n ip = getStatValue(now, 'remoteAddress');\n type = getStatValue(now, 'transportType');\n localip = getStatValue(now, 'localAddress');\n localCandidateType = getStatValue(now, 'localCandidateType');\n remoteCandidateType = getStatValue(now, 'remoteCandidateType');\n rtt = this.getNonNegativeStat(now, 'currentRoundTripTime');\n } catch (e) { /* not supported*/ }\n if (!ip || !type || !localip || active !== 'true') {\n continue;\n }\n\n // Save the address unless it has been saved already.\n const conferenceStatsTransport = this.conferenceStats.transport;\n\n if (!conferenceStatsTransport.some(\n t =>\n t.ip === ip\n && t.type === type\n && t.localip === localip)) {\n conferenceStatsTransport.push({\n ip,\n type,\n localip,\n p2p: this.peerconnection.isP2P,\n localCandidateType,\n remoteCandidateType,\n rtt\n });\n }\n continue;\n }\n\n if (now.type === 'candidatepair') {\n // we need succeeded and selected pairs only\n if (now.state !== 'succeeded' || !now.selected) {\n continue;\n }\n\n const local = this.currentStatsReport[now.localCandidateId];\n const remote = this.currentStatsReport[now.remoteCandidateId];\n\n this.conferenceStats.transport.push({\n ip: `${remote.ipAddress}:${remote.portNumber}`,\n type: local.transport,\n localip: `${local.ipAddress}:${local.portNumber}`,\n p2p: this.peerconnection.isP2P,\n localCandidateType: local.candidateType,\n remoteCandidateType: remote.candidateType\n });\n }\n\n if (now.type !== 'ssrc' && now.type !== 'outboundrtp'\n && now.type !== 'inboundrtp' && now.type !== 'track') {\n continue;\n }\n\n const before = this.previousStatsReport[idx];\n let ssrc = this.getNonNegativeStat(now, 'ssrc');\n\n // If type=\"track\", take the first SSRC from ssrcIds.\n if (now.type === 'track' && Array.isArray(now.ssrcIds)) {\n ssrc = Number(now.ssrcIds[0]);\n }\n\n if (!before || !ssrc) {\n continue;\n }\n\n // isRemote is available only in FF and is ignored in case of chrome\n // according to the spec\n // https://www.w3.org/TR/webrtc-stats/#dom-rtcrtpstreamstats-isremote\n // when isRemote is true indicates that the measurements were done at\n // the remote endpoint and reported in an RTCP RR/XR.\n // Fixes a problem where we are calculating local stats wrong adding\n // the sent bytes to the local download bitrate.\n // In new W3 stats spec, type=\"track\" has a remoteSource boolean\n // property.\n if (now.isRemote === true || now.remoteSource === true) {\n continue;\n }\n\n let ssrcStats = this.ssrc2stats.get(ssrc);\n\n if (!ssrcStats) {\n ssrcStats = new SsrcStats();\n this.ssrc2stats.set(ssrc, ssrcStats);\n }\n\n let isDownloadStream = true;\n let key = 'packetsReceived';\n let packetsNow = getStatValue(now, key);\n\n if (typeof packetsNow === 'undefined'\n || packetsNow === null || packetsNow === '') {\n isDownloadStream = false;\n key = 'packetsSent';\n packetsNow = getStatValue(now, key);\n if (typeof packetsNow === 'undefined' || packetsNow === null) {\n logger.warn('No packetsReceived nor packetsSent stat found');\n }\n }\n if (!packetsNow || packetsNow < 0) {\n packetsNow = 0;\n }\n\n const packetsBefore = this.getNonNegativeStat(before, key);\n const packetsDiff = Math.max(0, packetsNow - packetsBefore);\n\n const packetsLostNow\n = this.getNonNegativeStat(now, 'packetsLost');\n const packetsLostBefore\n = this.getNonNegativeStat(before, 'packetsLost');\n const packetsLostDiff = Math.max(0, packetsLostNow - packetsLostBefore);\n\n ssrcStats.setLoss({\n packetsTotal: packetsDiff + packetsLostDiff,\n packetsLost: packetsLostDiff,\n isDownloadStream\n });\n\n const bytesReceivedNow\n = this.getNonNegativeStat(now, 'bytesReceived');\n const bytesReceivedBefore\n = this.getNonNegativeStat(before, 'bytesReceived');\n const bytesReceived\n = Math.max(0, bytesReceivedNow - bytesReceivedBefore);\n\n let bytesSent = 0;\n\n // TODO: clean this mess up!\n let nowBytesTransmitted = getStatValue(now, 'bytesSent');\n\n if (typeof nowBytesTransmitted === 'number'\n || typeof nowBytesTransmitted === 'string') {\n nowBytesTransmitted = Number(nowBytesTransmitted);\n if (!isNaN(nowBytesTransmitted)) {\n byteSentStats[ssrc] = nowBytesTransmitted;\n if (nowBytesTransmitted > 0) {\n bytesSent = nowBytesTransmitted\n - getStatValue(before, 'bytesSent');\n }\n }\n }\n bytesSent = Math.max(0, bytesSent);\n\n const timeMs = now.timestamp - before.timestamp;\n let bitrateReceivedKbps = 0, bitrateSentKbps = 0;\n\n if (timeMs > 0) {\n // TODO is there any reason to round here?\n bitrateReceivedKbps = Math.round((bytesReceived * 8) / timeMs);\n bitrateSentKbps = Math.round((bytesSent * 8) / timeMs);\n }\n\n ssrcStats.addBitrate({\n 'download': bitrateReceivedKbps,\n 'upload': bitrateSentKbps\n });\n\n const resolution = {\n height: null,\n width: null\n };\n\n try {\n let height, width;\n\n if ((height = getStatValue(now, 'googFrameHeightReceived'))\n && (width = getStatValue(now, 'googFrameWidthReceived'))) {\n resolution.height = height;\n resolution.width = width;\n } else if ((height = getStatValue(now, 'googFrameHeightSent'))\n && (width = getStatValue(now, 'googFrameWidthSent'))) {\n resolution.height = height;\n resolution.width = width;\n }\n } catch (e) { /* not supported*/ }\n\n // Tries to get frame rate\n let frameRate;\n\n try {\n frameRate = getStatValue(now, 'googFrameRateReceived')\n || getStatValue(now, 'googFrameRateSent') || 0;\n } catch (e) {\n // if it fails with previous properties(chrome),\n // let's try with another one (FF)\n try {\n frameRate = this.getNonNegativeStat(now, 'framerateMean');\n } catch (err) { /* not supported*/ }\n }\n ssrcStats.setFramerate(Math.round(frameRate || 0));\n\n if (resolution.height && resolution.width) {\n ssrcStats.setResolution(resolution);\n } else {\n ssrcStats.setResolution(null);\n }\n }\n\n this.eventEmitter.emit(\n StatisticsEvents.BYTE_SENT_STATS, this.peerconnection, byteSentStats);\n\n this._processAndEmitReport();\n};\n\n/**\n *\n */\nStatsCollector.prototype._processAndEmitReport = function() {\n // process stats\n const totalPackets = {\n download: 0,\n upload: 0\n };\n const lostPackets = {\n download: 0,\n upload: 0\n };\n let bitrateDownload = 0;\n let bitrateUpload = 0;\n const resolutions = {};\n const framerates = {};\n let audioBitrateDownload = 0;\n let audioBitrateUpload = 0;\n let videoBitrateDownload = 0;\n let videoBitrateUpload = 0;\n\n for (const [ ssrc, ssrcStats ] of this.ssrc2stats) {\n // process packet loss stats\n const loss = ssrcStats.loss;\n const type = loss.isDownloadStream ? 'download' : 'upload';\n\n totalPackets[type] += loss.packetsTotal;\n lostPackets[type] += loss.packetsLost;\n\n // process bitrate stats\n bitrateDownload += ssrcStats.bitrate.download;\n bitrateUpload += ssrcStats.bitrate.upload;\n\n // collect resolutions and framerates\n const track = this.peerconnection.getTrackBySSRC(ssrc);\n\n if (track) {\n if (track.isAudioTrack()) {\n audioBitrateDownload += ssrcStats.bitrate.download;\n audioBitrateUpload += ssrcStats.bitrate.upload;\n } else {\n videoBitrateDownload += ssrcStats.bitrate.download;\n videoBitrateUpload += ssrcStats.bitrate.upload;\n }\n\n const participantId = track.getParticipantId();\n\n if (participantId) {\n const resolution = ssrcStats.resolution;\n\n if (resolution.width\n && resolution.height\n && resolution.width !== -1\n && resolution.height !== -1) {\n const userResolutions = resolutions[participantId] || {};\n\n userResolutions[ssrc] = resolution;\n resolutions[participantId] = userResolutions;\n }\n if (ssrcStats.framerate !== 0) {\n const userFramerates = framerates[participantId] || {};\n\n userFramerates[ssrc] = ssrcStats.framerate;\n framerates[participantId] = userFramerates;\n }\n } else {\n logger.error(`No participant ID returned by ${track}`);\n }\n }\n\n ssrcStats.resetBitrate();\n }\n\n this.conferenceStats.bitrate = {\n 'upload': bitrateUpload,\n 'download': bitrateDownload\n };\n\n this.conferenceStats.bitrate.audio = {\n 'upload': audioBitrateUpload,\n 'download': audioBitrateDownload\n };\n\n this.conferenceStats.bitrate.video = {\n 'upload': videoBitrateUpload,\n 'download': videoBitrateDownload\n };\n\n this.conferenceStats.packetLoss = {\n total:\n calculatePacketLoss(\n lostPackets.download + lostPackets.upload,\n totalPackets.download + totalPackets.upload),\n download:\n calculatePacketLoss(lostPackets.download, totalPackets.download),\n upload:\n calculatePacketLoss(lostPackets.upload, totalPackets.upload)\n };\n\n const avgAudioLevels = {};\n let localAvgAudioLevels;\n\n Object.keys(this.audioLevelReportHistory).forEach(ssrc => {\n const { data, isLocal } = this.audioLevelReportHistory[ssrc];\n const avgAudioLevel = data.reduce((sum, currentValue) => sum + currentValue) / data.length;\n\n if (isLocal) {\n localAvgAudioLevels = avgAudioLevel;\n } else {\n const track = this.peerconnection.getTrackBySSRC(Number(ssrc));\n\n if (track) {\n const participantId = track.getParticipantId();\n\n if (participantId) {\n avgAudioLevels[participantId] = avgAudioLevel;\n }\n }\n }\n });\n this.audioLevelReportHistory = {};\n\n this.eventEmitter.emit(\n StatisticsEvents.CONNECTION_STATS,\n this.peerconnection,\n {\n 'bandwidth': this.conferenceStats.bandwidth,\n 'bitrate': this.conferenceStats.bitrate,\n 'packetLoss': this.conferenceStats.packetLoss,\n 'resolution': resolutions,\n 'framerate': framerates,\n 'transport': this.conferenceStats.transport,\n localAvgAudioLevels,\n avgAudioLevels\n });\n this.conferenceStats.transport = [];\n};\n\n/**\n * Stats processing logic.\n */\nStatsCollector.prototype.processAudioLevelReport = function() {\n if (!this.baselineAudioLevelsReport) {\n return;\n }\n\n const getStatValue = this._getStatValue;\n\n for (const idx in this.currentAudioLevelsReport) {\n if (!this.currentAudioLevelsReport.hasOwnProperty(idx)) {\n continue;\n }\n\n const now = this.currentAudioLevelsReport[idx];\n\n if (now.type !== 'ssrc' && now.type !== 'track') {\n continue;\n }\n\n const before = this.baselineAudioLevelsReport[idx];\n let ssrc = this.getNonNegativeStat(now, 'ssrc');\n\n if (!ssrc && Array.isArray(now.ssrcIds)) {\n ssrc = Number(now.ssrcIds[0]);\n }\n\n if (!before) {\n logger.warn(`${ssrc} not enough data`);\n continue;\n }\n\n if (!ssrc) {\n if ((Date.now() - now.timestamp) < 3000) {\n logger.warn('No ssrc: ');\n }\n continue;\n }\n\n // Audio level\n let audioLevel;\n\n try {\n audioLevel\n = getStatValue(now, 'audioInputLevel')\n || getStatValue(now, 'audioOutputLevel');\n } catch (e) { /* not supported*/\n logger.warn('Audio Levels are not available in the statistics.');\n clearInterval(this.audioLevelsIntervalId);\n\n return;\n }\n\n if (audioLevel) {\n let isLocal;\n\n // If type=\"ssrc\" (legacy) check whether they are received packets.\n if (now.type === 'ssrc') {\n isLocal = !getStatValue(now, 'packetsReceived');\n\n // If type=\"track\", check remoteSource boolean property.\n } else {\n isLocal = !now.remoteSource;\n }\n\n // According to the W3C WebRTC Stats spec, audioLevel should be in\n // 0..1 range (0 == silence). However browsers don't behave that\n // way so we must convert it to 0..1.\n // TODO: Can't find specs about what this value really is, but it\n // seems to vary between 0 and around 32k.\n audioLevel = audioLevel / 32767;\n\n if (!(ssrc in this.audioLevelReportHistory)) {\n this.audioLevelReportHistory[ssrc] = {\n isLocal,\n data: []\n };\n }\n this.audioLevelReportHistory[ssrc].data.push(audioLevel);\n\n this.eventEmitter.emit(\n StatisticsEvents.AUDIO_LEVEL,\n this.peerconnection,\n ssrc,\n audioLevel,\n isLocal);\n }\n }\n};\n\n/* eslint-enable no-continue */\n\n/**\n * New promised based getStats report processing.\n * Tested with chrome, firefox and safari. Not switching it on for chrome as\n * frameRate stat is missing and calculating it using framesSent,\n * gives values double the values seen in webrtc-internals.\n * https://w3c.github.io/webrtc-stats/\n */\n\n/**\n * Defines a function which (1) is to be used as a StatsCollector method and (2)\n * gets the value from a specific report returned by RTCPeerConnection#getStats\n * associated with a lib-jitsi-meet browser-agnostic name in case of using\n * Promised based getStats.\n *\n * @param {Object.} keys the map of LibJitsi browser-agnostic\n * names to RTCPeerConnection#getStats browser-specific keys\n */\nStatsCollector.prototype._defineNewGetStatValueMethod = function(keys) {\n // Define the function which converts a lib-jitsi-meet browser-asnostic name\n // to a browser-specific key of a report returned by\n // RTCPeerConnection#getStats.\n const keyFromName = function(name) {\n const key = keys[name];\n\n if (key) {\n return key;\n }\n\n // eslint-disable-next-line no-throw-literal\n throw `The property '${name}' isn't supported!`;\n };\n\n // Compose the 2 functions defined above to get a function which retrieves\n // the value from a specific report returned by RTCPeerConnection#getStats\n // associated with a specific lib-jitsi-meet browser-agnostic name.\n return (item, name) => item[keyFromName(name)];\n};\n\n/**\n * Converts the value to a non-negative number.\n * If the value is either invalid or negative then 0 will be returned.\n * @param {*} v\n * @return {number}\n * @private\n */\nStatsCollector.prototype.getNonNegativeValue = function(v) {\n let value = v;\n\n if (typeof value !== 'number') {\n value = Number(value);\n }\n\n if (isNaN(value)) {\n return 0;\n }\n\n return Math.max(0, value);\n};\n\n/**\n * Calculates bitrate between before and now using a supplied field name and its\n * value in the stats.\n * @param {RTCInboundRtpStreamStats|RTCSentRtpStreamStats} now the current stats\n * @param {RTCInboundRtpStreamStats|RTCSentRtpStreamStats} before the\n * previous stats.\n * @param fieldName the field to use for calculations.\n * @return {number} the calculated bitrate between now and before.\n * @private\n */\nStatsCollector.prototype._calculateBitrate = function(now, before, fieldName) {\n const bytesNow = this.getNonNegativeValue(now[fieldName]);\n const bytesBefore = this.getNonNegativeValue(before[fieldName]);\n const bytesProcessed = Math.max(0, bytesNow - bytesBefore);\n\n const timeMs = now.timestamp - before.timestamp;\n let bitrateKbps = 0;\n\n if (timeMs > 0) {\n // TODO is there any reason to round here?\n bitrateKbps = Math.round((bytesProcessed * 8) / timeMs);\n }\n\n return bitrateKbps;\n};\n\n/**\n * Stats processing new getStats logic.\n */\nStatsCollector.prototype.processNewStatsReport = function() {\n if (!this.previousStatsReport) {\n return;\n }\n\n const getStatValue = this._getStatValue;\n const byteSentStats = {};\n\n this.currentStatsReport.forEach(now => {\n\n // RTCIceCandidatePairStats\n // https://w3c.github.io/webrtc-stats/#candidatepair-dict*\n if (now.type === 'candidate-pair'\n && now.nominated\n && now.state === 'succeeded') {\n\n const availableIncomingBitrate = now.availableIncomingBitrate;\n const availableOutgoingBitrate = now.availableOutgoingBitrate;\n\n if (availableIncomingBitrate || availableOutgoingBitrate) {\n this.conferenceStats.bandwidth = {\n 'download': Math.round(availableIncomingBitrate / 1000),\n 'upload': Math.round(availableOutgoingBitrate / 1000)\n };\n }\n\n const remoteUsedCandidate\n = this.currentStatsReport.get(now.remoteCandidateId);\n const localUsedCandidate\n = this.currentStatsReport.get(now.localCandidateId);\n\n // RTCIceCandidateStats\n // https://w3c.github.io/webrtc-stats/#icecandidate-dict*\n // safari currently does not provide ice candidates in stats\n if (remoteUsedCandidate && localUsedCandidate) {\n const remoteIpAddress = getStatValue(remoteUsedCandidate, 'ip');\n const remotePort = getStatValue(remoteUsedCandidate, 'port');\n const ip = `${remoteIpAddress}:${remotePort}`;\n\n const localIpAddress = getStatValue(localUsedCandidate, 'ip');\n const localPort = getStatValue(localUsedCandidate, 'port');\n\n const localIp = `${localIpAddress}:${localPort}`;\n const type = getStatValue(remoteUsedCandidate, 'protocol');\n\n // Save the address unless it has been saved already.\n const conferenceStatsTransport = this.conferenceStats.transport;\n\n if (!conferenceStatsTransport.some(\n t =>\n t.ip === ip\n && t.type === type\n && t.localip === localIp)) {\n conferenceStatsTransport.push({\n ip,\n type,\n localIp,\n p2p: this.peerconnection.isP2P,\n localCandidateType: localUsedCandidate.candidateType,\n remoteCandidateType: remoteUsedCandidate.candidateType,\n networkType: localUsedCandidate.networkType,\n rtt: now.currentRoundTripTime * 1000\n });\n }\n }\n\n // RTCReceivedRtpStreamStats\n // https://w3c.github.io/webrtc-stats/#receivedrtpstats-dict*\n // RTCSentRtpStreamStats\n // https://w3c.github.io/webrtc-stats/#sentrtpstats-dict*\n } else if (now.type === 'inbound-rtp' || now.type === 'outbound-rtp') {\n const before = this.previousStatsReport.get(now.id);\n const ssrc = this.getNonNegativeValue(now.ssrc);\n\n if (!before || !ssrc) {\n return;\n }\n\n let ssrcStats = this.ssrc2stats.get(ssrc);\n\n if (!ssrcStats) {\n ssrcStats = new SsrcStats();\n this.ssrc2stats.set(ssrc, ssrcStats);\n }\n\n let isDownloadStream = true;\n let key = 'packetsReceived';\n\n if (now.type === 'outbound-rtp') {\n isDownloadStream = false;\n key = 'packetsSent';\n }\n\n let packetsNow = now[key];\n\n if (!packetsNow || packetsNow < 0) {\n packetsNow = 0;\n }\n\n const packetsBefore = this.getNonNegativeValue(before[key]);\n const packetsDiff = Math.max(0, packetsNow - packetsBefore);\n\n const packetsLostNow\n = this.getNonNegativeValue(now.packetsLost);\n const packetsLostBefore\n = this.getNonNegativeValue(before.packetsLost);\n const packetsLostDiff\n = Math.max(0, packetsLostNow - packetsLostBefore);\n\n ssrcStats.setLoss({\n packetsTotal: packetsDiff + packetsLostDiff,\n packetsLost: packetsLostDiff,\n isDownloadStream\n });\n\n if (now.type === 'inbound-rtp') {\n\n ssrcStats.addBitrate({\n 'download': this._calculateBitrate(\n now, before, 'bytesReceived'),\n 'upload': 0\n });\n\n // RTCInboundRtpStreamStats\n // https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict*\n // TODO: can we use framesDecoded for frame rate, available\n // in chrome\n } else {\n byteSentStats[ssrc] = this.getNonNegativeValue(now.bytesSent);\n ssrcStats.addBitrate({\n 'download': 0,\n 'upload': this._calculateBitrate(\n now, before, 'bytesSent')\n });\n\n // RTCOutboundRtpStreamStats\n // https://w3c.github.io/webrtc-stats/#outboundrtpstats-dict*\n // TODO: can we use framesEncoded for frame rate, available\n // in chrome\n }\n\n // FF has framerateMean out of spec\n const framerateMean = now.framerateMean;\n\n if (framerateMean) {\n ssrcStats.setFramerate(Math.round(framerateMean || 0));\n }\n\n // track for resolution\n // RTCVideoHandlerStats\n // https://w3c.github.io/webrtc-stats/#vststats-dict*\n // RTCMediaHandlerStats\n // https://w3c.github.io/webrtc-stats/#mststats-dict*\n } else if (now.type === 'track') {\n\n const resolution = {\n height: now.frameHeight,\n width: now.frameWidth\n };\n\n // Tries to get frame rate\n let frameRate = now.framesPerSecond;\n\n if (!frameRate) {\n // we need to calculate it\n const before = this.previousStatsReport.get(now.id);\n\n if (before) {\n const timeMs = now.timestamp - before.timestamp;\n\n if (timeMs > 0 && now.framesSent) {\n const numberOfFramesSinceBefore\n = now.framesSent - before.framesSent;\n\n frameRate = (numberOfFramesSinceBefore / timeMs) * 1000;\n }\n }\n\n if (!frameRate) {\n return;\n }\n }\n\n const trackIdentifier = now.trackIdentifier;\n const ssrc = this.peerconnection.getSsrcByTrackId(trackIdentifier);\n\n if (!ssrc) {\n return;\n }\n let ssrcStats = this.ssrc2stats.get(ssrc);\n\n if (!ssrcStats) {\n ssrcStats = new SsrcStats();\n this.ssrc2stats.set(ssrc, ssrcStats);\n }\n ssrcStats.setFramerate(Math.round(frameRate || 0));\n\n if (resolution.height && resolution.width) {\n ssrcStats.setResolution(resolution);\n } else {\n ssrcStats.setResolution(null);\n }\n }\n });\n\n this.eventEmitter.emit(\n StatisticsEvents.BYTE_SENT_STATS, this.peerconnection, byteSentStats);\n\n this._processAndEmitReport();\n};\n\n/**\n * Stats processing logic.\n */\nStatsCollector.prototype.processNewAudioLevelReport = function() {\n if (!this.baselineAudioLevelsReport) {\n return;\n }\n\n this.currentAudioLevelsReport.forEach(now => {\n if (now.type !== 'track') {\n return;\n }\n\n // Audio level\n const audioLevel = now.audioLevel;\n\n if (!audioLevel) {\n return;\n }\n\n const trackIdentifier = now.trackIdentifier;\n const ssrc = this.peerconnection.getSsrcByTrackId(trackIdentifier);\n\n if (ssrc) {\n const isLocal\n = ssrc === this.peerconnection.getLocalSSRC(\n this.peerconnection.getLocalTracks(MediaType.AUDIO));\n\n this.eventEmitter.emit(\n StatisticsEvents.AUDIO_LEVEL,\n this.peerconnection,\n ssrc,\n audioLevel,\n isLocal);\n }\n });\n};\n\n/**\n * End new promised based getStats processing methods.\n */\n", "/*\n * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n'use strict';\n\nvar SDPUtils = require('sdp');\n\nfunction fixStatsType(stat) {\n return {\n inboundrtp: 'inbound-rtp',\n outboundrtp: 'outbound-rtp',\n candidatepair: 'candidate-pair',\n localcandidate: 'local-candidate',\n remotecandidate: 'remote-candidate'\n }[stat.type] || stat.type;\n}\n\nfunction writeMediaSection(transceiver, caps, type, stream, dtlsRole) {\n var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps);\n\n // Map ICE parameters (ufrag, pwd) to SDP.\n sdp += SDPUtils.writeIceParameters(\n transceiver.iceGatherer.getLocalParameters());\n\n // Map DTLS parameters to SDP.\n sdp += SDPUtils.writeDtlsParameters(\n transceiver.dtlsTransport.getLocalParameters(),\n type === 'offer' ? 'actpass' : dtlsRole || 'active');\n\n sdp += 'a=mid:' + transceiver.mid + '\\r\\n';\n\n if (transceiver.rtpSender && transceiver.rtpReceiver) {\n sdp += 'a=sendrecv\\r\\n';\n } else if (transceiver.rtpSender) {\n sdp += 'a=sendonly\\r\\n';\n } else if (transceiver.rtpReceiver) {\n sdp += 'a=recvonly\\r\\n';\n } else {\n sdp += 'a=inactive\\r\\n';\n }\n\n if (transceiver.rtpSender) {\n var trackId = transceiver.rtpSender._initialTrackId ||\n transceiver.rtpSender.track.id;\n transceiver.rtpSender._initialTrackId = trackId;\n // spec.\n var msid = 'msid:' + (stream ? stream.id : '-') + ' ' +\n trackId + '\\r\\n';\n sdp += 'a=' + msid;\n // for Chrome. Legacy should no longer be required.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' ' + msid;\n\n // RTX\n if (transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' ' + msid;\n sdp += 'a=ssrc-group:FID ' +\n transceiver.sendEncodingParameters[0].ssrc + ' ' +\n transceiver.sendEncodingParameters[0].rtx.ssrc +\n '\\r\\n';\n }\n }\n // FIXME: this should be written by writeRtpDescription.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n }\n return sdp;\n}\n\n// Edge does not like\n// 1) stun: filtered after 14393 unless ?transport=udp is present\n// 2) turn: that does not have all of turn:host:port?transport=udp\n// 3) turn: with ipv6 addresses\n// 4) turn: occurring muliple times\nfunction filterIceServers(iceServers, edgeVersion) {\n var hasTurn = false;\n iceServers = JSON.parse(JSON.stringify(iceServers));\n return iceServers.filter(function(server) {\n if (server && (server.urls || server.url)) {\n var urls = server.urls || server.url;\n if (server.url && !server.urls) {\n console.warn('RTCIceServer.url is deprecated! Use urls instead.');\n }\n var isString = typeof urls === 'string';\n if (isString) {\n urls = [urls];\n }\n urls = urls.filter(function(url) {\n var validTurn = url.indexOf('turn:') === 0 &&\n url.indexOf('transport=udp') !== -1 &&\n url.indexOf('turn:[') === -1 &&\n !hasTurn;\n\n if (validTurn) {\n hasTurn = true;\n return true;\n }\n return url.indexOf('stun:') === 0 && edgeVersion >= 14393 &&\n url.indexOf('?transport=udp') === -1;\n });\n\n delete server.url;\n server.urls = isString ? urls[0] : urls;\n return !!urls.length;\n }\n });\n}\n\n// Determines the intersection of local and remote capabilities.\nfunction getCommonCapabilities(localCapabilities, remoteCapabilities) {\n var commonCapabilities = {\n codecs: [],\n headerExtensions: [],\n fecMechanisms: []\n };\n\n var findCodecByPayloadType = function(pt, codecs) {\n pt = parseInt(pt, 10);\n for (var i = 0; i < codecs.length; i++) {\n if (codecs[i].payloadType === pt ||\n codecs[i].preferredPayloadType === pt) {\n return codecs[i];\n }\n }\n };\n\n var rtxCapabilityMatches = function(lRtx, rRtx, lCodecs, rCodecs) {\n var lCodec = findCodecByPayloadType(lRtx.parameters.apt, lCodecs);\n var rCodec = findCodecByPayloadType(rRtx.parameters.apt, rCodecs);\n return lCodec && rCodec &&\n lCodec.name.toLowerCase() === rCodec.name.toLowerCase();\n };\n\n localCapabilities.codecs.forEach(function(lCodec) {\n for (var i = 0; i < remoteCapabilities.codecs.length; i++) {\n var rCodec = remoteCapabilities.codecs[i];\n if (lCodec.name.toLowerCase() === rCodec.name.toLowerCase() &&\n lCodec.clockRate === rCodec.clockRate) {\n if (lCodec.name.toLowerCase() === 'rtx' &&\n lCodec.parameters && rCodec.parameters.apt) {\n // for RTX we need to find the local rtx that has a apt\n // which points to the same local codec as the remote one.\n if (!rtxCapabilityMatches(lCodec, rCodec,\n localCapabilities.codecs, remoteCapabilities.codecs)) {\n continue;\n }\n }\n rCodec = JSON.parse(JSON.stringify(rCodec)); // deepcopy\n // number of channels is the highest common number of channels\n rCodec.numChannels = Math.min(lCodec.numChannels,\n rCodec.numChannels);\n // push rCodec so we reply with offerer payload type\n commonCapabilities.codecs.push(rCodec);\n\n // determine common feedback mechanisms\n rCodec.rtcpFeedback = rCodec.rtcpFeedback.filter(function(fb) {\n for (var j = 0; j < lCodec.rtcpFeedback.length; j++) {\n if (lCodec.rtcpFeedback[j].type === fb.type &&\n lCodec.rtcpFeedback[j].parameter === fb.parameter) {\n return true;\n }\n }\n return false;\n });\n // FIXME: also need to determine .parameters\n // see https://github.com/openpeer/ortc/issues/569\n break;\n }\n }\n });\n\n localCapabilities.headerExtensions.forEach(function(lHeaderExtension) {\n for (var i = 0; i < remoteCapabilities.headerExtensions.length;\n i++) {\n var rHeaderExtension = remoteCapabilities.headerExtensions[i];\n if (lHeaderExtension.uri === rHeaderExtension.uri) {\n commonCapabilities.headerExtensions.push(rHeaderExtension);\n break;\n }\n }\n });\n\n // FIXME: fecMechanisms\n return commonCapabilities;\n}\n\n// is action=setLocalDescription with type allowed in signalingState\nfunction isActionAllowedInSignalingState(action, type, signalingState) {\n return {\n offer: {\n setLocalDescription: ['stable', 'have-local-offer'],\n setRemoteDescription: ['stable', 'have-remote-offer']\n },\n answer: {\n setLocalDescription: ['have-remote-offer', 'have-local-pranswer'],\n setRemoteDescription: ['have-local-offer', 'have-remote-pranswer']\n }\n }[type][action].indexOf(signalingState) !== -1;\n}\n\nfunction maybeAddCandidate(iceTransport, candidate) {\n // Edge's internal representation adds some fields therefore\n // not all fieldѕ are taken into account.\n var alreadyAdded = iceTransport.getRemoteCandidates()\n .find(function(remoteCandidate) {\n return candidate.foundation === remoteCandidate.foundation &&\n candidate.ip === remoteCandidate.ip &&\n candidate.port === remoteCandidate.port &&\n candidate.priority === remoteCandidate.priority &&\n candidate.protocol === remoteCandidate.protocol &&\n candidate.type === remoteCandidate.type;\n });\n if (!alreadyAdded) {\n iceTransport.addRemoteCandidate(candidate);\n }\n return !alreadyAdded;\n}\n\n\nfunction makeError(name, description) {\n var e = new Error(description);\n e.name = name;\n // legacy error codes from https://heycam.github.io/webidl/#idl-DOMException-error-names\n e.code = {\n NotSupportedError: 9,\n InvalidStateError: 11,\n InvalidAccessError: 15,\n TypeError: undefined,\n OperationError: undefined\n }[name];\n return e;\n}\n\nmodule.exports = function(window, edgeVersion) {\n // https://w3c.github.io/mediacapture-main/#mediastream\n // Helper function to add the track to the stream and\n // dispatch the event ourselves.\n function addTrackToStreamAndFireEvent(track, stream) {\n stream.addTrack(track);\n stream.dispatchEvent(new window.MediaStreamTrackEvent('addtrack',\n {track: track}));\n }\n\n function removeTrackFromStreamAndFireEvent(track, stream) {\n stream.removeTrack(track);\n stream.dispatchEvent(new window.MediaStreamTrackEvent('removetrack',\n {track: track}));\n }\n\n function fireAddTrack(pc, track, receiver, streams) {\n var trackEvent = new Event('track');\n trackEvent.track = track;\n trackEvent.receiver = receiver;\n trackEvent.transceiver = {receiver: receiver};\n trackEvent.streams = streams;\n window.setTimeout(function() {\n pc._dispatchEvent('track', trackEvent);\n });\n }\n\n var RTCPeerConnection = function(config) {\n var pc = this;\n\n var _eventTarget = document.createDocumentFragment();\n ['addEventListener', 'removeEventListener', 'dispatchEvent']\n .forEach(function(method) {\n pc[method] = _eventTarget[method].bind(_eventTarget);\n });\n\n this.canTrickleIceCandidates = null;\n\n this.needNegotiation = false;\n\n this.localStreams = [];\n this.remoteStreams = [];\n\n this._localDescription = null;\n this._remoteDescription = null;\n\n this.signalingState = 'stable';\n this.iceConnectionState = 'new';\n this.connectionState = 'new';\n this.iceGatheringState = 'new';\n\n config = JSON.parse(JSON.stringify(config || {}));\n\n this.usingBundle = config.bundlePolicy === 'max-bundle';\n if (config.rtcpMuxPolicy === 'negotiate') {\n throw(makeError('NotSupportedError',\n 'rtcpMuxPolicy \\'negotiate\\' is not supported'));\n } else if (!config.rtcpMuxPolicy) {\n config.rtcpMuxPolicy = 'require';\n }\n\n switch (config.iceTransportPolicy) {\n case 'all':\n case 'relay':\n break;\n default:\n config.iceTransportPolicy = 'all';\n break;\n }\n\n switch (config.bundlePolicy) {\n case 'balanced':\n case 'max-compat':\n case 'max-bundle':\n break;\n default:\n config.bundlePolicy = 'balanced';\n break;\n }\n\n config.iceServers = filterIceServers(config.iceServers || [], edgeVersion);\n\n this._iceGatherers = [];\n if (config.iceCandidatePoolSize) {\n for (var i = config.iceCandidatePoolSize; i > 0; i--) {\n this._iceGatherers.push(new window.RTCIceGatherer({\n iceServers: config.iceServers,\n gatherPolicy: config.iceTransportPolicy\n }));\n }\n } else {\n config.iceCandidatePoolSize = 0;\n }\n\n this._config = config;\n\n // per-track iceGathers, iceTransports, dtlsTransports, rtpSenders, ...\n // everything that is needed to describe a SDP m-line.\n this.transceivers = [];\n\n this._sdpSessionId = SDPUtils.generateSessionId();\n this._sdpSessionVersion = 0;\n\n this._dtlsRole = undefined; // role for a=setup to use in answers.\n\n this._isClosed = false;\n };\n\n Object.defineProperty(RTCPeerConnection.prototype, 'localDescription', {\n configurable: true,\n get: function() {\n return this._localDescription;\n }\n });\n Object.defineProperty(RTCPeerConnection.prototype, 'remoteDescription', {\n configurable: true,\n get: function() {\n return this._remoteDescription;\n }\n });\n\n // set up event handlers on prototype\n RTCPeerConnection.prototype.onicecandidate = null;\n RTCPeerConnection.prototype.onaddstream = null;\n RTCPeerConnection.prototype.ontrack = null;\n RTCPeerConnection.prototype.onremovestream = null;\n RTCPeerConnection.prototype.onsignalingstatechange = null;\n RTCPeerConnection.prototype.oniceconnectionstatechange = null;\n RTCPeerConnection.prototype.onconnectionstatechange = null;\n RTCPeerConnection.prototype.onicegatheringstatechange = null;\n RTCPeerConnection.prototype.onnegotiationneeded = null;\n RTCPeerConnection.prototype.ondatachannel = null;\n\n RTCPeerConnection.prototype._dispatchEvent = function(name, event) {\n if (this._isClosed) {\n return;\n }\n this.dispatchEvent(event);\n if (typeof this['on' + name] === 'function') {\n this['on' + name](event);\n }\n };\n\n RTCPeerConnection.prototype._emitGatheringStateChange = function() {\n var event = new Event('icegatheringstatechange');\n this._dispatchEvent('icegatheringstatechange', event);\n };\n\n RTCPeerConnection.prototype.getConfiguration = function() {\n return this._config;\n };\n\n RTCPeerConnection.prototype.getLocalStreams = function() {\n return this.localStreams;\n };\n\n RTCPeerConnection.prototype.getRemoteStreams = function() {\n return this.remoteStreams;\n };\n\n // internal helper to create a transceiver object.\n // (which is not yet the same as the WebRTC 1.0 transceiver)\n RTCPeerConnection.prototype._createTransceiver = function(kind, doNotAdd) {\n var hasBundleTransport = this.transceivers.length > 0;\n var transceiver = {\n track: null,\n iceGatherer: null,\n iceTransport: null,\n dtlsTransport: null,\n localCapabilities: null,\n remoteCapabilities: null,\n rtpSender: null,\n rtpReceiver: null,\n kind: kind,\n mid: null,\n sendEncodingParameters: null,\n recvEncodingParameters: null,\n stream: null,\n associatedRemoteMediaStreams: [],\n wantReceive: true\n };\n if (this.usingBundle && hasBundleTransport) {\n transceiver.iceTransport = this.transceivers[0].iceTransport;\n transceiver.dtlsTransport = this.transceivers[0].dtlsTransport;\n } else {\n var transports = this._createIceAndDtlsTransports();\n transceiver.iceTransport = transports.iceTransport;\n transceiver.dtlsTransport = transports.dtlsTransport;\n }\n if (!doNotAdd) {\n this.transceivers.push(transceiver);\n }\n return transceiver;\n };\n\n RTCPeerConnection.prototype.addTrack = function(track, stream) {\n if (this._isClosed) {\n throw makeError('InvalidStateError',\n 'Attempted to call addTrack on a closed peerconnection.');\n }\n\n var alreadyExists = this.transceivers.find(function(s) {\n return s.track === track;\n });\n\n if (alreadyExists) {\n throw makeError('InvalidAccessError', 'Track already exists.');\n }\n\n var transceiver;\n for (var i = 0; i < this.transceivers.length; i++) {\n if (!this.transceivers[i].track &&\n this.transceivers[i].kind === track.kind) {\n transceiver = this.transceivers[i];\n }\n }\n if (!transceiver) {\n transceiver = this._createTransceiver(track.kind);\n }\n\n this._maybeFireNegotiationNeeded();\n\n if (this.localStreams.indexOf(stream) === -1) {\n this.localStreams.push(stream);\n }\n\n transceiver.track = track;\n transceiver.stream = stream;\n transceiver.rtpSender = new window.RTCRtpSender(track,\n transceiver.dtlsTransport);\n return transceiver.rtpSender;\n };\n\n RTCPeerConnection.prototype.addStream = function(stream) {\n var pc = this;\n if (edgeVersion >= 15025) {\n stream.getTracks().forEach(function(track) {\n pc.addTrack(track, stream);\n });\n } else {\n // Clone is necessary for local demos mostly, attaching directly\n // to two different senders does not work (build 10547).\n // Fixed in 15025 (or earlier)\n var clonedStream = stream.clone();\n stream.getTracks().forEach(function(track, idx) {\n var clonedTrack = clonedStream.getTracks()[idx];\n track.addEventListener('enabled', function(event) {\n clonedTrack.enabled = event.enabled;\n });\n });\n clonedStream.getTracks().forEach(function(track) {\n pc.addTrack(track, clonedStream);\n });\n }\n };\n\n RTCPeerConnection.prototype.removeTrack = function(sender) {\n if (this._isClosed) {\n throw makeError('InvalidStateError',\n 'Attempted to call removeTrack on a closed peerconnection.');\n }\n\n if (!(sender instanceof window.RTCRtpSender)) {\n throw new TypeError('Argument 1 of RTCPeerConnection.removeTrack ' +\n 'does not implement interface RTCRtpSender.');\n }\n\n var transceiver = this.transceivers.find(function(t) {\n return t.rtpSender === sender;\n });\n\n if (!transceiver) {\n throw makeError('InvalidAccessError',\n 'Sender was not created by this connection.');\n }\n var stream = transceiver.stream;\n\n transceiver.rtpSender.stop();\n transceiver.rtpSender = null;\n transceiver.track = null;\n transceiver.stream = null;\n\n // remove the stream from the set of local streams\n var localStreams = this.transceivers.map(function(t) {\n return t.stream;\n });\n if (localStreams.indexOf(stream) === -1 &&\n this.localStreams.indexOf(stream) > -1) {\n this.localStreams.splice(this.localStreams.indexOf(stream), 1);\n }\n\n this._maybeFireNegotiationNeeded();\n };\n\n RTCPeerConnection.prototype.removeStream = function(stream) {\n var pc = this;\n stream.getTracks().forEach(function(track) {\n var sender = pc.getSenders().find(function(s) {\n return s.track === track;\n });\n if (sender) {\n pc.removeTrack(sender);\n }\n });\n };\n\n RTCPeerConnection.prototype.getSenders = function() {\n return this.transceivers.filter(function(transceiver) {\n return !!transceiver.rtpSender;\n })\n .map(function(transceiver) {\n return transceiver.rtpSender;\n });\n };\n\n RTCPeerConnection.prototype.getReceivers = function() {\n return this.transceivers.filter(function(transceiver) {\n return !!transceiver.rtpReceiver;\n })\n .map(function(transceiver) {\n return transceiver.rtpReceiver;\n });\n };\n\n\n RTCPeerConnection.prototype._createIceGatherer = function(sdpMLineIndex,\n usingBundle) {\n var pc = this;\n if (usingBundle && sdpMLineIndex > 0) {\n return this.transceivers[0].iceGatherer;\n } else if (this._iceGatherers.length) {\n return this._iceGatherers.shift();\n }\n var iceGatherer = new window.RTCIceGatherer({\n iceServers: this._config.iceServers,\n gatherPolicy: this._config.iceTransportPolicy\n });\n Object.defineProperty(iceGatherer, 'state',\n {value: 'new', writable: true}\n );\n\n this.transceivers[sdpMLineIndex].bufferedCandidateEvents = [];\n this.transceivers[sdpMLineIndex].bufferCandidates = function(event) {\n var end = !event.candidate || Object.keys(event.candidate).length === 0;\n // polyfill since RTCIceGatherer.state is not implemented in\n // Edge 10547 yet.\n iceGatherer.state = end ? 'completed' : 'gathering';\n if (pc.transceivers[sdpMLineIndex].bufferedCandidateEvents !== null) {\n pc.transceivers[sdpMLineIndex].bufferedCandidateEvents.push(event);\n }\n };\n iceGatherer.addEventListener('localcandidate',\n this.transceivers[sdpMLineIndex].bufferCandidates);\n return iceGatherer;\n };\n\n // start gathering from an RTCIceGatherer.\n RTCPeerConnection.prototype._gather = function(mid, sdpMLineIndex) {\n var pc = this;\n var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer;\n if (iceGatherer.onlocalcandidate) {\n return;\n }\n var bufferedCandidateEvents =\n this.transceivers[sdpMLineIndex].bufferedCandidateEvents;\n this.transceivers[sdpMLineIndex].bufferedCandidateEvents = null;\n iceGatherer.removeEventListener('localcandidate',\n this.transceivers[sdpMLineIndex].bufferCandidates);\n iceGatherer.onlocalcandidate = function(evt) {\n if (pc.usingBundle && sdpMLineIndex > 0) {\n // if we know that we use bundle we can drop candidates with\n // ѕdpMLineIndex > 0. If we don't do this then our state gets\n // confused since we dispose the extra ice gatherer.\n return;\n }\n var event = new Event('icecandidate');\n event.candidate = {sdpMid: mid, sdpMLineIndex: sdpMLineIndex};\n\n var cand = evt.candidate;\n // Edge emits an empty object for RTCIceCandidateComplete‥\n var end = !cand || Object.keys(cand).length === 0;\n if (end) {\n // polyfill since RTCIceGatherer.state is not implemented in\n // Edge 10547 yet.\n if (iceGatherer.state === 'new' || iceGatherer.state === 'gathering') {\n iceGatherer.state = 'completed';\n }\n } else {\n if (iceGatherer.state === 'new') {\n iceGatherer.state = 'gathering';\n }\n // RTCIceCandidate doesn't have a component, needs to be added\n cand.component = 1;\n // also the usernameFragment. TODO: update SDP to take both variants.\n cand.ufrag = iceGatherer.getLocalParameters().usernameFragment;\n\n var serializedCandidate = SDPUtils.writeCandidate(cand);\n event.candidate = Object.assign(event.candidate,\n SDPUtils.parseCandidate(serializedCandidate));\n\n event.candidate.candidate = serializedCandidate;\n event.candidate.toJSON = function() {\n return {\n candidate: event.candidate.candidate,\n sdpMid: event.candidate.sdpMid,\n sdpMLineIndex: event.candidate.sdpMLineIndex,\n usernameFragment: event.candidate.usernameFragment\n };\n };\n }\n\n // update local description.\n var sections = SDPUtils.getMediaSections(pc._localDescription.sdp);\n if (!end) {\n sections[event.candidate.sdpMLineIndex] +=\n 'a=' + event.candidate.candidate + '\\r\\n';\n } else {\n sections[event.candidate.sdpMLineIndex] +=\n 'a=end-of-candidates\\r\\n';\n }\n pc._localDescription.sdp =\n SDPUtils.getDescription(pc._localDescription.sdp) +\n sections.join('');\n var complete = pc.transceivers.every(function(transceiver) {\n return transceiver.iceGatherer &&\n transceiver.iceGatherer.state === 'completed';\n });\n\n if (pc.iceGatheringState !== 'gathering') {\n pc.iceGatheringState = 'gathering';\n pc._emitGatheringStateChange();\n }\n\n // Emit candidate. Also emit null candidate when all gatherers are\n // complete.\n if (!end) {\n pc._dispatchEvent('icecandidate', event);\n }\n if (complete) {\n pc._dispatchEvent('icecandidate', new Event('icecandidate'));\n pc.iceGatheringState = 'complete';\n pc._emitGatheringStateChange();\n }\n };\n\n // emit already gathered candidates.\n window.setTimeout(function() {\n bufferedCandidateEvents.forEach(function(e) {\n iceGatherer.onlocalcandidate(e);\n });\n }, 0);\n };\n\n // Create ICE transport and DTLS transport.\n RTCPeerConnection.prototype._createIceAndDtlsTransports = function() {\n var pc = this;\n var iceTransport = new window.RTCIceTransport(null);\n iceTransport.onicestatechange = function() {\n pc._updateIceConnectionState();\n pc._updateConnectionState();\n };\n\n var dtlsTransport = new window.RTCDtlsTransport(iceTransport);\n dtlsTransport.ondtlsstatechange = function() {\n pc._updateConnectionState();\n };\n dtlsTransport.onerror = function() {\n // onerror does not set state to failed by itself.\n Object.defineProperty(dtlsTransport, 'state',\n {value: 'failed', writable: true});\n pc._updateConnectionState();\n };\n\n return {\n iceTransport: iceTransport,\n dtlsTransport: dtlsTransport\n };\n };\n\n // Destroy ICE gatherer, ICE transport and DTLS transport.\n // Without triggering the callbacks.\n RTCPeerConnection.prototype._disposeIceAndDtlsTransports = function(\n sdpMLineIndex) {\n var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer;\n if (iceGatherer) {\n delete iceGatherer.onlocalcandidate;\n delete this.transceivers[sdpMLineIndex].iceGatherer;\n }\n var iceTransport = this.transceivers[sdpMLineIndex].iceTransport;\n if (iceTransport) {\n delete iceTransport.onicestatechange;\n delete this.transceivers[sdpMLineIndex].iceTransport;\n }\n var dtlsTransport = this.transceivers[sdpMLineIndex].dtlsTransport;\n if (dtlsTransport) {\n delete dtlsTransport.ondtlsstatechange;\n delete dtlsTransport.onerror;\n delete this.transceivers[sdpMLineIndex].dtlsTransport;\n }\n };\n\n // Start the RTP Sender and Receiver for a transceiver.\n RTCPeerConnection.prototype._transceive = function(transceiver,\n send, recv) {\n var params = getCommonCapabilities(transceiver.localCapabilities,\n transceiver.remoteCapabilities);\n if (send && transceiver.rtpSender) {\n params.encodings = transceiver.sendEncodingParameters;\n params.rtcp = {\n cname: SDPUtils.localCName,\n compound: transceiver.rtcpParameters.compound\n };\n if (transceiver.recvEncodingParameters.length) {\n params.rtcp.ssrc = transceiver.recvEncodingParameters[0].ssrc;\n }\n transceiver.rtpSender.send(params);\n }\n if (recv && transceiver.rtpReceiver && params.codecs.length > 0) {\n // remove RTX field in Edge 14942\n if (transceiver.kind === 'video'\n && transceiver.recvEncodingParameters\n && edgeVersion < 15019) {\n transceiver.recvEncodingParameters.forEach(function(p) {\n delete p.rtx;\n });\n }\n if (transceiver.recvEncodingParameters.length) {\n params.encodings = transceiver.recvEncodingParameters;\n } else {\n params.encodings = [{}];\n }\n params.rtcp = {\n compound: transceiver.rtcpParameters.compound\n };\n if (transceiver.rtcpParameters.cname) {\n params.rtcp.cname = transceiver.rtcpParameters.cname;\n }\n if (transceiver.sendEncodingParameters.length) {\n params.rtcp.ssrc = transceiver.sendEncodingParameters[0].ssrc;\n }\n transceiver.rtpReceiver.receive(params);\n }\n };\n\n RTCPeerConnection.prototype.setLocalDescription = function(description) {\n var pc = this;\n\n // Note: pranswer is not supported.\n if (['offer', 'answer'].indexOf(description.type) === -1) {\n return Promise.reject(makeError('TypeError',\n 'Unsupported type \"' + description.type + '\"'));\n }\n\n if (!isActionAllowedInSignalingState('setLocalDescription',\n description.type, pc.signalingState) || pc._isClosed) {\n return Promise.reject(makeError('InvalidStateError',\n 'Can not set local ' + description.type +\n ' in state ' + pc.signalingState));\n }\n\n var sections;\n var sessionpart;\n if (description.type === 'offer') {\n // VERY limited support for SDP munging. Limited to:\n // * changing the order of codecs\n sections = SDPUtils.splitSections(description.sdp);\n sessionpart = sections.shift();\n sections.forEach(function(mediaSection, sdpMLineIndex) {\n var caps = SDPUtils.parseRtpParameters(mediaSection);\n pc.transceivers[sdpMLineIndex].localCapabilities = caps;\n });\n\n pc.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n pc._gather(transceiver.mid, sdpMLineIndex);\n });\n } else if (description.type === 'answer') {\n sections = SDPUtils.splitSections(pc._remoteDescription.sdp);\n sessionpart = sections.shift();\n var isIceLite = SDPUtils.matchPrefix(sessionpart,\n 'a=ice-lite').length > 0;\n sections.forEach(function(mediaSection, sdpMLineIndex) {\n var transceiver = pc.transceivers[sdpMLineIndex];\n var iceGatherer = transceiver.iceGatherer;\n var iceTransport = transceiver.iceTransport;\n var dtlsTransport = transceiver.dtlsTransport;\n var localCapabilities = transceiver.localCapabilities;\n var remoteCapabilities = transceiver.remoteCapabilities;\n\n // treat bundle-only as not-rejected.\n var rejected = SDPUtils.isRejected(mediaSection) &&\n SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 0;\n\n if (!rejected && !transceiver.rejected) {\n var remoteIceParameters = SDPUtils.getIceParameters(\n mediaSection, sessionpart);\n var remoteDtlsParameters = SDPUtils.getDtlsParameters(\n mediaSection, sessionpart);\n if (isIceLite) {\n remoteDtlsParameters.role = 'server';\n }\n\n if (!pc.usingBundle || sdpMLineIndex === 0) {\n pc._gather(transceiver.mid, sdpMLineIndex);\n if (iceTransport.state === 'new') {\n iceTransport.start(iceGatherer, remoteIceParameters,\n isIceLite ? 'controlling' : 'controlled');\n }\n if (dtlsTransport.state === 'new') {\n dtlsTransport.start(remoteDtlsParameters);\n }\n }\n\n // Calculate intersection of capabilities.\n var params = getCommonCapabilities(localCapabilities,\n remoteCapabilities);\n\n // Start the RTCRtpSender. The RTCRtpReceiver for this\n // transceiver has already been started in setRemoteDescription.\n pc._transceive(transceiver,\n params.codecs.length > 0,\n false);\n }\n });\n }\n\n pc._localDescription = {\n type: description.type,\n sdp: description.sdp\n };\n if (description.type === 'offer') {\n pc._updateSignalingState('have-local-offer');\n } else {\n pc._updateSignalingState('stable');\n }\n\n return Promise.resolve();\n };\n\n RTCPeerConnection.prototype.setRemoteDescription = function(description) {\n var pc = this;\n\n // Note: pranswer is not supported.\n if (['offer', 'answer'].indexOf(description.type) === -1) {\n return Promise.reject(makeError('TypeError',\n 'Unsupported type \"' + description.type + '\"'));\n }\n\n if (!isActionAllowedInSignalingState('setRemoteDescription',\n description.type, pc.signalingState) || pc._isClosed) {\n return Promise.reject(makeError('InvalidStateError',\n 'Can not set remote ' + description.type +\n ' in state ' + pc.signalingState));\n }\n\n var streams = {};\n pc.remoteStreams.forEach(function(stream) {\n streams[stream.id] = stream;\n });\n var receiverList = [];\n var sections = SDPUtils.splitSections(description.sdp);\n var sessionpart = sections.shift();\n var isIceLite = SDPUtils.matchPrefix(sessionpart,\n 'a=ice-lite').length > 0;\n var usingBundle = SDPUtils.matchPrefix(sessionpart,\n 'a=group:BUNDLE ').length > 0;\n pc.usingBundle = usingBundle;\n var iceOptions = SDPUtils.matchPrefix(sessionpart,\n 'a=ice-options:')[0];\n if (iceOptions) {\n pc.canTrickleIceCandidates = iceOptions.substr(14).split(' ')\n .indexOf('trickle') >= 0;\n } else {\n pc.canTrickleIceCandidates = false;\n }\n\n sections.forEach(function(mediaSection, sdpMLineIndex) {\n var lines = SDPUtils.splitLines(mediaSection);\n var kind = SDPUtils.getKind(mediaSection);\n // treat bundle-only as not-rejected.\n var rejected = SDPUtils.isRejected(mediaSection) &&\n SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 0;\n var protocol = lines[0].substr(2).split(' ')[2];\n\n var direction = SDPUtils.getDirection(mediaSection, sessionpart);\n var remoteMsid = SDPUtils.parseMsid(mediaSection);\n\n var mid = SDPUtils.getMid(mediaSection) || SDPUtils.generateIdentifier();\n\n // Reject datachannels which are not implemented yet.\n if (rejected || (kind === 'application' && (protocol === 'DTLS/SCTP' ||\n protocol === 'UDP/DTLS/SCTP'))) {\n // TODO: this is dangerous in the case where a non-rejected m-line\n // becomes rejected.\n pc.transceivers[sdpMLineIndex] = {\n mid: mid,\n kind: kind,\n protocol: protocol,\n rejected: true\n };\n return;\n }\n\n if (!rejected && pc.transceivers[sdpMLineIndex] &&\n pc.transceivers[sdpMLineIndex].rejected) {\n // recycle a rejected transceiver.\n pc.transceivers[sdpMLineIndex] = pc._createTransceiver(kind, true);\n }\n\n var transceiver;\n var iceGatherer;\n var iceTransport;\n var dtlsTransport;\n var rtpReceiver;\n var sendEncodingParameters;\n var recvEncodingParameters;\n var localCapabilities;\n\n var track;\n // FIXME: ensure the mediaSection has rtcp-mux set.\n var remoteCapabilities = SDPUtils.parseRtpParameters(mediaSection);\n var remoteIceParameters;\n var remoteDtlsParameters;\n if (!rejected) {\n remoteIceParameters = SDPUtils.getIceParameters(mediaSection,\n sessionpart);\n remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection,\n sessionpart);\n remoteDtlsParameters.role = 'client';\n }\n recvEncodingParameters =\n SDPUtils.parseRtpEncodingParameters(mediaSection);\n\n var rtcpParameters = SDPUtils.parseRtcpParameters(mediaSection);\n\n var isComplete = SDPUtils.matchPrefix(mediaSection,\n 'a=end-of-candidates', sessionpart).length > 0;\n var cands = SDPUtils.matchPrefix(mediaSection, 'a=candidate:')\n .map(function(cand) {\n return SDPUtils.parseCandidate(cand);\n })\n .filter(function(cand) {\n return cand.component === 1;\n });\n\n // Check if we can use BUNDLE and dispose transports.\n if ((description.type === 'offer' || description.type === 'answer') &&\n !rejected && usingBundle && sdpMLineIndex > 0 &&\n pc.transceivers[sdpMLineIndex]) {\n pc._disposeIceAndDtlsTransports(sdpMLineIndex);\n pc.transceivers[sdpMLineIndex].iceGatherer =\n pc.transceivers[0].iceGatherer;\n pc.transceivers[sdpMLineIndex].iceTransport =\n pc.transceivers[0].iceTransport;\n pc.transceivers[sdpMLineIndex].dtlsTransport =\n pc.transceivers[0].dtlsTransport;\n if (pc.transceivers[sdpMLineIndex].rtpSender) {\n pc.transceivers[sdpMLineIndex].rtpSender.setTransport(\n pc.transceivers[0].dtlsTransport);\n }\n if (pc.transceivers[sdpMLineIndex].rtpReceiver) {\n pc.transceivers[sdpMLineIndex].rtpReceiver.setTransport(\n pc.transceivers[0].dtlsTransport);\n }\n }\n if (description.type === 'offer' && !rejected) {\n transceiver = pc.transceivers[sdpMLineIndex] ||\n pc._createTransceiver(kind);\n transceiver.mid = mid;\n\n if (!transceiver.iceGatherer) {\n transceiver.iceGatherer = pc._createIceGatherer(sdpMLineIndex,\n usingBundle);\n }\n\n if (cands.length && transceiver.iceTransport.state === 'new') {\n if (isComplete && (!usingBundle || sdpMLineIndex === 0)) {\n transceiver.iceTransport.setRemoteCandidates(cands);\n } else {\n cands.forEach(function(candidate) {\n maybeAddCandidate(transceiver.iceTransport, candidate);\n });\n }\n }\n\n localCapabilities = window.RTCRtpReceiver.getCapabilities(kind);\n\n // filter RTX until additional stuff needed for RTX is implemented\n // in adapter.js\n if (edgeVersion < 15019) {\n localCapabilities.codecs = localCapabilities.codecs.filter(\n function(codec) {\n return codec.name !== 'rtx';\n });\n }\n\n sendEncodingParameters = transceiver.sendEncodingParameters || [{\n ssrc: (2 * sdpMLineIndex + 2) * 1001\n }];\n\n // TODO: rewrite to use http://w3c.github.io/webrtc-pc/#set-associated-remote-streams\n var isNewTrack = false;\n if (direction === 'sendrecv' || direction === 'sendonly') {\n isNewTrack = !transceiver.rtpReceiver;\n rtpReceiver = transceiver.rtpReceiver ||\n new window.RTCRtpReceiver(transceiver.dtlsTransport, kind);\n\n if (isNewTrack) {\n var stream;\n track = rtpReceiver.track;\n // FIXME: does not work with Plan B.\n if (remoteMsid && remoteMsid.stream === '-') {\n // no-op. a stream id of '-' means: no associated stream.\n } else if (remoteMsid) {\n if (!streams[remoteMsid.stream]) {\n streams[remoteMsid.stream] = new window.MediaStream();\n Object.defineProperty(streams[remoteMsid.stream], 'id', {\n get: function() {\n return remoteMsid.stream;\n }\n });\n }\n Object.defineProperty(track, 'id', {\n get: function() {\n return remoteMsid.track;\n }\n });\n stream = streams[remoteMsid.stream];\n } else {\n if (!streams.default) {\n streams.default = new window.MediaStream();\n }\n stream = streams.default;\n }\n if (stream) {\n addTrackToStreamAndFireEvent(track, stream);\n transceiver.associatedRemoteMediaStreams.push(stream);\n }\n receiverList.push([track, rtpReceiver, stream]);\n }\n } else if (transceiver.rtpReceiver && transceiver.rtpReceiver.track) {\n transceiver.associatedRemoteMediaStreams.forEach(function(s) {\n var nativeTrack = s.getTracks().find(function(t) {\n return t.id === transceiver.rtpReceiver.track.id;\n });\n if (nativeTrack) {\n removeTrackFromStreamAndFireEvent(nativeTrack, s);\n }\n });\n transceiver.associatedRemoteMediaStreams = [];\n }\n\n transceiver.localCapabilities = localCapabilities;\n transceiver.remoteCapabilities = remoteCapabilities;\n transceiver.rtpReceiver = rtpReceiver;\n transceiver.rtcpParameters = rtcpParameters;\n transceiver.sendEncodingParameters = sendEncodingParameters;\n transceiver.recvEncodingParameters = recvEncodingParameters;\n\n // Start the RTCRtpReceiver now. The RTPSender is started in\n // setLocalDescription.\n pc._transceive(pc.transceivers[sdpMLineIndex],\n false,\n isNewTrack);\n } else if (description.type === 'answer' && !rejected) {\n transceiver = pc.transceivers[sdpMLineIndex];\n iceGatherer = transceiver.iceGatherer;\n iceTransport = transceiver.iceTransport;\n dtlsTransport = transceiver.dtlsTransport;\n rtpReceiver = transceiver.rtpReceiver;\n sendEncodingParameters = transceiver.sendEncodingParameters;\n localCapabilities = transceiver.localCapabilities;\n\n pc.transceivers[sdpMLineIndex].recvEncodingParameters =\n recvEncodingParameters;\n pc.transceivers[sdpMLineIndex].remoteCapabilities =\n remoteCapabilities;\n pc.transceivers[sdpMLineIndex].rtcpParameters = rtcpParameters;\n\n if (cands.length && iceTransport.state === 'new') {\n if ((isIceLite || isComplete) &&\n (!usingBundle || sdpMLineIndex === 0)) {\n iceTransport.setRemoteCandidates(cands);\n } else {\n cands.forEach(function(candidate) {\n maybeAddCandidate(transceiver.iceTransport, candidate);\n });\n }\n }\n\n if (!usingBundle || sdpMLineIndex === 0) {\n if (iceTransport.state === 'new') {\n iceTransport.start(iceGatherer, remoteIceParameters,\n 'controlling');\n }\n if (dtlsTransport.state === 'new') {\n dtlsTransport.start(remoteDtlsParameters);\n }\n }\n\n // If the offer contained RTX but the answer did not,\n // remove RTX from sendEncodingParameters.\n var commonCapabilities = getCommonCapabilities(\n transceiver.localCapabilities,\n transceiver.remoteCapabilities);\n\n var hasRtx = commonCapabilities.codecs.filter(function(c) {\n return c.name.toLowerCase() === 'rtx';\n }).length;\n if (!hasRtx && transceiver.sendEncodingParameters[0].rtx) {\n delete transceiver.sendEncodingParameters[0].rtx;\n }\n\n pc._transceive(transceiver,\n direction === 'sendrecv' || direction === 'recvonly',\n direction === 'sendrecv' || direction === 'sendonly');\n\n // TODO: rewrite to use http://w3c.github.io/webrtc-pc/#set-associated-remote-streams\n if (rtpReceiver &&\n (direction === 'sendrecv' || direction === 'sendonly')) {\n track = rtpReceiver.track;\n if (remoteMsid) {\n if (!streams[remoteMsid.stream]) {\n streams[remoteMsid.stream] = new window.MediaStream();\n }\n addTrackToStreamAndFireEvent(track, streams[remoteMsid.stream]);\n receiverList.push([track, rtpReceiver, streams[remoteMsid.stream]]);\n } else {\n if (!streams.default) {\n streams.default = new window.MediaStream();\n }\n addTrackToStreamAndFireEvent(track, streams.default);\n receiverList.push([track, rtpReceiver, streams.default]);\n }\n } else {\n // FIXME: actually the receiver should be created later.\n delete transceiver.rtpReceiver;\n }\n }\n });\n\n if (pc._dtlsRole === undefined) {\n pc._dtlsRole = description.type === 'offer' ? 'active' : 'passive';\n }\n\n pc._remoteDescription = {\n type: description.type,\n sdp: description.sdp\n };\n if (description.type === 'offer') {\n pc._updateSignalingState('have-remote-offer');\n } else {\n pc._updateSignalingState('stable');\n }\n Object.keys(streams).forEach(function(sid) {\n var stream = streams[sid];\n if (stream.getTracks().length) {\n if (pc.remoteStreams.indexOf(stream) === -1) {\n pc.remoteStreams.push(stream);\n var event = new Event('addstream');\n event.stream = stream;\n window.setTimeout(function() {\n pc._dispatchEvent('addstream', event);\n });\n }\n\n receiverList.forEach(function(item) {\n var track = item[0];\n var receiver = item[1];\n if (stream.id !== item[2].id) {\n return;\n }\n fireAddTrack(pc, track, receiver, [stream]);\n });\n }\n });\n receiverList.forEach(function(item) {\n if (item[2]) {\n return;\n }\n fireAddTrack(pc, item[0], item[1], []);\n });\n\n // check whether addIceCandidate({}) was called within four seconds after\n // setRemoteDescription.\n window.setTimeout(function() {\n if (!(pc && pc.transceivers)) {\n return;\n }\n pc.transceivers.forEach(function(transceiver) {\n if (transceiver.iceTransport &&\n transceiver.iceTransport.state === 'new' &&\n transceiver.iceTransport.getRemoteCandidates().length > 0) {\n console.warn('Timeout for addRemoteCandidate. Consider sending ' +\n 'an end-of-candidates notification');\n transceiver.iceTransport.addRemoteCandidate({});\n }\n });\n }, 4000);\n\n return Promise.resolve();\n };\n\n RTCPeerConnection.prototype.close = function() {\n this.transceivers.forEach(function(transceiver) {\n /* not yet\n if (transceiver.iceGatherer) {\n transceiver.iceGatherer.close();\n }\n */\n if (transceiver.iceTransport) {\n transceiver.iceTransport.stop();\n }\n if (transceiver.dtlsTransport) {\n transceiver.dtlsTransport.stop();\n }\n if (transceiver.rtpSender) {\n transceiver.rtpSender.stop();\n }\n if (transceiver.rtpReceiver) {\n transceiver.rtpReceiver.stop();\n }\n });\n // FIXME: clean up tracks, local streams, remote streams, etc\n this._isClosed = true;\n this._updateSignalingState('closed');\n };\n\n // Update the signaling state.\n RTCPeerConnection.prototype._updateSignalingState = function(newState) {\n this.signalingState = newState;\n var event = new Event('signalingstatechange');\n this._dispatchEvent('signalingstatechange', event);\n };\n\n // Determine whether to fire the negotiationneeded event.\n RTCPeerConnection.prototype._maybeFireNegotiationNeeded = function() {\n var pc = this;\n if (this.signalingState !== 'stable' || this.needNegotiation === true) {\n return;\n }\n this.needNegotiation = true;\n window.setTimeout(function() {\n if (pc.needNegotiation) {\n pc.needNegotiation = false;\n var event = new Event('negotiationneeded');\n pc._dispatchEvent('negotiationneeded', event);\n }\n }, 0);\n };\n\n // Update the ice connection state.\n RTCPeerConnection.prototype._updateIceConnectionState = function() {\n var newState;\n var states = {\n 'new': 0,\n closed: 0,\n checking: 0,\n connected: 0,\n completed: 0,\n disconnected: 0,\n failed: 0\n };\n this.transceivers.forEach(function(transceiver) {\n if (transceiver.iceTransport && !transceiver.rejected) {\n states[transceiver.iceTransport.state]++;\n }\n });\n\n newState = 'new';\n if (states.failed > 0) {\n newState = 'failed';\n } else if (states.checking > 0) {\n newState = 'checking';\n } else if (states.disconnected > 0) {\n newState = 'disconnected';\n } else if (states.new > 0) {\n newState = 'new';\n } else if (states.connected > 0) {\n newState = 'connected';\n } else if (states.completed > 0) {\n newState = 'completed';\n }\n\n if (newState !== this.iceConnectionState) {\n this.iceConnectionState = newState;\n var event = new Event('iceconnectionstatechange');\n this._dispatchEvent('iceconnectionstatechange', event);\n }\n };\n\n // Update the connection state.\n RTCPeerConnection.prototype._updateConnectionState = function() {\n var newState;\n var states = {\n 'new': 0,\n closed: 0,\n connecting: 0,\n connected: 0,\n completed: 0,\n disconnected: 0,\n failed: 0\n };\n this.transceivers.forEach(function(transceiver) {\n if (transceiver.iceTransport && transceiver.dtlsTransport &&\n !transceiver.rejected) {\n states[transceiver.iceTransport.state]++;\n states[transceiver.dtlsTransport.state]++;\n }\n });\n // ICETransport.completed and connected are the same for this purpose.\n states.connected += states.completed;\n\n newState = 'new';\n if (states.failed > 0) {\n newState = 'failed';\n } else if (states.connecting > 0) {\n newState = 'connecting';\n } else if (states.disconnected > 0) {\n newState = 'disconnected';\n } else if (states.new > 0) {\n newState = 'new';\n } else if (states.connected > 0) {\n newState = 'connected';\n }\n\n if (newState !== this.connectionState) {\n this.connectionState = newState;\n var event = new Event('connectionstatechange');\n this._dispatchEvent('connectionstatechange', event);\n }\n };\n\n RTCPeerConnection.prototype.createOffer = function() {\n var pc = this;\n\n if (pc._isClosed) {\n return Promise.reject(makeError('InvalidStateError',\n 'Can not call createOffer after close'));\n }\n\n var numAudioTracks = pc.transceivers.filter(function(t) {\n return t.kind === 'audio';\n }).length;\n var numVideoTracks = pc.transceivers.filter(function(t) {\n return t.kind === 'video';\n }).length;\n\n // Determine number of audio and video tracks we need to send/recv.\n var offerOptions = arguments[0];\n if (offerOptions) {\n // Reject Chrome legacy constraints.\n if (offerOptions.mandatory || offerOptions.optional) {\n throw new TypeError(\n 'Legacy mandatory/optional constraints not supported.');\n }\n if (offerOptions.offerToReceiveAudio !== undefined) {\n if (offerOptions.offerToReceiveAudio === true) {\n numAudioTracks = 1;\n } else if (offerOptions.offerToReceiveAudio === false) {\n numAudioTracks = 0;\n } else {\n numAudioTracks = offerOptions.offerToReceiveAudio;\n }\n }\n if (offerOptions.offerToReceiveVideo !== undefined) {\n if (offerOptions.offerToReceiveVideo === true) {\n numVideoTracks = 1;\n } else if (offerOptions.offerToReceiveVideo === false) {\n numVideoTracks = 0;\n } else {\n numVideoTracks = offerOptions.offerToReceiveVideo;\n }\n }\n }\n\n pc.transceivers.forEach(function(transceiver) {\n if (transceiver.kind === 'audio') {\n numAudioTracks--;\n if (numAudioTracks < 0) {\n transceiver.wantReceive = false;\n }\n } else if (transceiver.kind === 'video') {\n numVideoTracks--;\n if (numVideoTracks < 0) {\n transceiver.wantReceive = false;\n }\n }\n });\n\n // Create M-lines for recvonly streams.\n while (numAudioTracks > 0 || numVideoTracks > 0) {\n if (numAudioTracks > 0) {\n pc._createTransceiver('audio');\n numAudioTracks--;\n }\n if (numVideoTracks > 0) {\n pc._createTransceiver('video');\n numVideoTracks--;\n }\n }\n\n var sdp = SDPUtils.writeSessionBoilerplate(pc._sdpSessionId,\n pc._sdpSessionVersion++);\n pc.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n // For each track, create an ice gatherer, ice transport,\n // dtls transport, potentially rtpsender and rtpreceiver.\n var track = transceiver.track;\n var kind = transceiver.kind;\n var mid = transceiver.mid || SDPUtils.generateIdentifier();\n transceiver.mid = mid;\n\n if (!transceiver.iceGatherer) {\n transceiver.iceGatherer = pc._createIceGatherer(sdpMLineIndex,\n pc.usingBundle);\n }\n\n var localCapabilities = window.RTCRtpSender.getCapabilities(kind);\n // filter RTX until additional stuff needed for RTX is implemented\n // in adapter.js\n if (edgeVersion < 15019) {\n localCapabilities.codecs = localCapabilities.codecs.filter(\n function(codec) {\n return codec.name !== 'rtx';\n });\n }\n localCapabilities.codecs.forEach(function(codec) {\n // work around https://bugs.chromium.org/p/webrtc/issues/detail?id=6552\n // by adding level-asymmetry-allowed=1\n if (codec.name === 'H264' &&\n codec.parameters['level-asymmetry-allowed'] === undefined) {\n codec.parameters['level-asymmetry-allowed'] = '1';\n }\n\n // for subsequent offers, we might have to re-use the payload\n // type of the last offer.\n if (transceiver.remoteCapabilities &&\n transceiver.remoteCapabilities.codecs) {\n transceiver.remoteCapabilities.codecs.forEach(function(remoteCodec) {\n if (codec.name.toLowerCase() === remoteCodec.name.toLowerCase() &&\n codec.clockRate === remoteCodec.clockRate) {\n codec.preferredPayloadType = remoteCodec.payloadType;\n }\n });\n }\n });\n localCapabilities.headerExtensions.forEach(function(hdrExt) {\n var remoteExtensions = transceiver.remoteCapabilities &&\n transceiver.remoteCapabilities.headerExtensions || [];\n remoteExtensions.forEach(function(rHdrExt) {\n if (hdrExt.uri === rHdrExt.uri) {\n hdrExt.id = rHdrExt.id;\n }\n });\n });\n\n // generate an ssrc now, to be used later in rtpSender.send\n var sendEncodingParameters = transceiver.sendEncodingParameters || [{\n ssrc: (2 * sdpMLineIndex + 1) * 1001\n }];\n if (track) {\n // add RTX\n if (edgeVersion >= 15019 && kind === 'video' &&\n !sendEncodingParameters[0].rtx) {\n sendEncodingParameters[0].rtx = {\n ssrc: sendEncodingParameters[0].ssrc + 1\n };\n }\n }\n\n if (transceiver.wantReceive) {\n transceiver.rtpReceiver = new window.RTCRtpReceiver(\n transceiver.dtlsTransport, kind);\n }\n\n transceiver.localCapabilities = localCapabilities;\n transceiver.sendEncodingParameters = sendEncodingParameters;\n });\n\n // always offer BUNDLE and dispose on return if not supported.\n if (pc._config.bundlePolicy !== 'max-compat') {\n sdp += 'a=group:BUNDLE ' + pc.transceivers.map(function(t) {\n return t.mid;\n }).join(' ') + '\\r\\n';\n }\n sdp += 'a=ice-options:trickle\\r\\n';\n\n pc.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n sdp += writeMediaSection(transceiver, transceiver.localCapabilities,\n 'offer', transceiver.stream, pc._dtlsRole);\n sdp += 'a=rtcp-rsize\\r\\n';\n\n if (transceiver.iceGatherer && pc.iceGatheringState !== 'new' &&\n (sdpMLineIndex === 0 || !pc.usingBundle)) {\n transceiver.iceGatherer.getLocalCandidates().forEach(function(cand) {\n cand.component = 1;\n sdp += 'a=' + SDPUtils.writeCandidate(cand) + '\\r\\n';\n });\n\n if (transceiver.iceGatherer.state === 'completed') {\n sdp += 'a=end-of-candidates\\r\\n';\n }\n }\n });\n\n var desc = new window.RTCSessionDescription({\n type: 'offer',\n sdp: sdp\n });\n return Promise.resolve(desc);\n };\n\n RTCPeerConnection.prototype.createAnswer = function() {\n var pc = this;\n\n if (pc._isClosed) {\n return Promise.reject(makeError('InvalidStateError',\n 'Can not call createAnswer after close'));\n }\n\n if (!(pc.signalingState === 'have-remote-offer' ||\n pc.signalingState === 'have-local-pranswer')) {\n return Promise.reject(makeError('InvalidStateError',\n 'Can not call createAnswer in signalingState ' + pc.signalingState));\n }\n\n var sdp = SDPUtils.writeSessionBoilerplate(pc._sdpSessionId,\n pc._sdpSessionVersion++);\n if (pc.usingBundle) {\n sdp += 'a=group:BUNDLE ' + pc.transceivers.map(function(t) {\n return t.mid;\n }).join(' ') + '\\r\\n';\n }\n sdp += 'a=ice-options:trickle\\r\\n';\n\n var mediaSectionsInOffer = SDPUtils.getMediaSections(\n pc._remoteDescription.sdp).length;\n pc.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n if (sdpMLineIndex + 1 > mediaSectionsInOffer) {\n return;\n }\n if (transceiver.rejected) {\n if (transceiver.kind === 'application') {\n if (transceiver.protocol === 'DTLS/SCTP') { // legacy fmt\n sdp += 'm=application 0 DTLS/SCTP 5000\\r\\n';\n } else {\n sdp += 'm=application 0 ' + transceiver.protocol +\n ' webrtc-datachannel\\r\\n';\n }\n } else if (transceiver.kind === 'audio') {\n sdp += 'm=audio 0 UDP/TLS/RTP/SAVPF 0\\r\\n' +\n 'a=rtpmap:0 PCMU/8000\\r\\n';\n } else if (transceiver.kind === 'video') {\n sdp += 'm=video 0 UDP/TLS/RTP/SAVPF 120\\r\\n' +\n 'a=rtpmap:120 VP8/90000\\r\\n';\n }\n sdp += 'c=IN IP4 0.0.0.0\\r\\n' +\n 'a=inactive\\r\\n' +\n 'a=mid:' + transceiver.mid + '\\r\\n';\n return;\n }\n\n // FIXME: look at direction.\n if (transceiver.stream) {\n var localTrack;\n if (transceiver.kind === 'audio') {\n localTrack = transceiver.stream.getAudioTracks()[0];\n } else if (transceiver.kind === 'video') {\n localTrack = transceiver.stream.getVideoTracks()[0];\n }\n if (localTrack) {\n // add RTX\n if (edgeVersion >= 15019 && transceiver.kind === 'video' &&\n !transceiver.sendEncodingParameters[0].rtx) {\n transceiver.sendEncodingParameters[0].rtx = {\n ssrc: transceiver.sendEncodingParameters[0].ssrc + 1\n };\n }\n }\n }\n\n // Calculate intersection of capabilities.\n var commonCapabilities = getCommonCapabilities(\n transceiver.localCapabilities,\n transceiver.remoteCapabilities);\n\n var hasRtx = commonCapabilities.codecs.filter(function(c) {\n return c.name.toLowerCase() === 'rtx';\n }).length;\n if (!hasRtx && transceiver.sendEncodingParameters[0].rtx) {\n delete transceiver.sendEncodingParameters[0].rtx;\n }\n\n sdp += writeMediaSection(transceiver, commonCapabilities,\n 'answer', transceiver.stream, pc._dtlsRole);\n if (transceiver.rtcpParameters &&\n transceiver.rtcpParameters.reducedSize) {\n sdp += 'a=rtcp-rsize\\r\\n';\n }\n });\n\n var desc = new window.RTCSessionDescription({\n type: 'answer',\n sdp: sdp\n });\n return Promise.resolve(desc);\n };\n\n RTCPeerConnection.prototype.addIceCandidate = function(candidate) {\n var pc = this;\n var sections;\n if (candidate && !(candidate.sdpMLineIndex !== undefined ||\n candidate.sdpMid)) {\n return Promise.reject(new TypeError('sdpMLineIndex or sdpMid required'));\n }\n\n // TODO: needs to go into ops queue.\n return new Promise(function(resolve, reject) {\n if (!pc._remoteDescription) {\n return reject(makeError('InvalidStateError',\n 'Can not add ICE candidate without a remote description'));\n } else if (!candidate || candidate.candidate === '') {\n for (var j = 0; j < pc.transceivers.length; j++) {\n if (pc.transceivers[j].rejected) {\n continue;\n }\n pc.transceivers[j].iceTransport.addRemoteCandidate({});\n sections = SDPUtils.getMediaSections(pc._remoteDescription.sdp);\n sections[j] += 'a=end-of-candidates\\r\\n';\n pc._remoteDescription.sdp =\n SDPUtils.getDescription(pc._remoteDescription.sdp) +\n sections.join('');\n if (pc.usingBundle) {\n break;\n }\n }\n } else {\n var sdpMLineIndex = candidate.sdpMLineIndex;\n if (candidate.sdpMid) {\n for (var i = 0; i < pc.transceivers.length; i++) {\n if (pc.transceivers[i].mid === candidate.sdpMid) {\n sdpMLineIndex = i;\n break;\n }\n }\n }\n var transceiver = pc.transceivers[sdpMLineIndex];\n if (transceiver) {\n if (transceiver.rejected) {\n return resolve();\n }\n var cand = Object.keys(candidate.candidate).length > 0 ?\n SDPUtils.parseCandidate(candidate.candidate) : {};\n // Ignore Chrome's invalid candidates since Edge does not like them.\n if (cand.protocol === 'tcp' && (cand.port === 0 || cand.port === 9)) {\n return resolve();\n }\n // Ignore RTCP candidates, we assume RTCP-MUX.\n if (cand.component && cand.component !== 1) {\n return resolve();\n }\n // when using bundle, avoid adding candidates to the wrong\n // ice transport. And avoid adding candidates added in the SDP.\n if (sdpMLineIndex === 0 || (sdpMLineIndex > 0 &&\n transceiver.iceTransport !== pc.transceivers[0].iceTransport)) {\n if (!maybeAddCandidate(transceiver.iceTransport, cand)) {\n return reject(makeError('OperationError',\n 'Can not add ICE candidate'));\n }\n }\n\n // update the remoteDescription.\n var candidateString = candidate.candidate.trim();\n if (candidateString.indexOf('a=') === 0) {\n candidateString = candidateString.substr(2);\n }\n sections = SDPUtils.getMediaSections(pc._remoteDescription.sdp);\n sections[sdpMLineIndex] += 'a=' +\n (cand.type ? candidateString : 'end-of-candidates')\n + '\\r\\n';\n pc._remoteDescription.sdp =\n SDPUtils.getDescription(pc._remoteDescription.sdp) +\n sections.join('');\n } else {\n return reject(makeError('OperationError',\n 'Can not add ICE candidate'));\n }\n }\n resolve();\n });\n };\n\n RTCPeerConnection.prototype.getStats = function(selector) {\n if (selector && selector instanceof window.MediaStreamTrack) {\n var senderOrReceiver = null;\n this.transceivers.forEach(function(transceiver) {\n if (transceiver.rtpSender &&\n transceiver.rtpSender.track === selector) {\n senderOrReceiver = transceiver.rtpSender;\n } else if (transceiver.rtpReceiver &&\n transceiver.rtpReceiver.track === selector) {\n senderOrReceiver = transceiver.rtpReceiver;\n }\n });\n if (!senderOrReceiver) {\n throw makeError('InvalidAccessError', 'Invalid selector.');\n }\n return senderOrReceiver.getStats();\n }\n\n var promises = [];\n this.transceivers.forEach(function(transceiver) {\n ['rtpSender', 'rtpReceiver', 'iceGatherer', 'iceTransport',\n 'dtlsTransport'].forEach(function(method) {\n if (transceiver[method]) {\n promises.push(transceiver[method].getStats());\n }\n });\n });\n return Promise.all(promises).then(function(allStats) {\n var results = new Map();\n allStats.forEach(function(stats) {\n stats.forEach(function(stat) {\n results.set(stat.id, stat);\n });\n });\n return results;\n });\n };\n\n // fix low-level stat names and return Map instead of object.\n var ortcObjects = ['RTCRtpSender', 'RTCRtpReceiver', 'RTCIceGatherer',\n 'RTCIceTransport', 'RTCDtlsTransport'];\n ortcObjects.forEach(function(ortcObjectName) {\n var obj = window[ortcObjectName];\n if (obj && obj.prototype && obj.prototype.getStats) {\n var nativeGetstats = obj.prototype.getStats;\n obj.prototype.getStats = function() {\n return nativeGetstats.apply(this)\n .then(function(nativeStats) {\n var mapStats = new Map();\n Object.keys(nativeStats).forEach(function(id) {\n nativeStats[id].type = fixStatsType(nativeStats[id]);\n mapStats.set(id, nativeStats[id]);\n });\n return mapStats;\n });\n };\n }\n });\n\n // legacy callback shims. Should be moved to adapter.js some days.\n var methods = ['createOffer', 'createAnswer'];\n methods.forEach(function(method) {\n var nativeMethod = RTCPeerConnection.prototype[method];\n RTCPeerConnection.prototype[method] = function() {\n var args = arguments;\n if (typeof args[0] === 'function' ||\n typeof args[1] === 'function') { // legacy\n return nativeMethod.apply(this, [arguments[2]])\n .then(function(description) {\n if (typeof args[0] === 'function') {\n args[0].apply(null, [description]);\n }\n }, function(error) {\n if (typeof args[1] === 'function') {\n args[1].apply(null, [error]);\n }\n });\n }\n return nativeMethod.apply(this, arguments);\n };\n });\n\n methods = ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'];\n methods.forEach(function(method) {\n var nativeMethod = RTCPeerConnection.prototype[method];\n RTCPeerConnection.prototype[method] = function() {\n var args = arguments;\n if (typeof args[1] === 'function' ||\n typeof args[2] === 'function') { // legacy\n return nativeMethod.apply(this, arguments)\n .then(function() {\n if (typeof args[1] === 'function') {\n args[1].apply(null);\n }\n }, function(error) {\n if (typeof args[2] === 'function') {\n args[2].apply(null, [error]);\n }\n });\n }\n return nativeMethod.apply(this, arguments);\n };\n });\n\n // getStats is special. It doesn't have a spec legacy method yet we support\n // getStats(something, cb) without error callbacks.\n ['getStats'].forEach(function(method) {\n var nativeMethod = RTCPeerConnection.prototype[method];\n RTCPeerConnection.prototype[method] = function() {\n var args = arguments;\n if (typeof args[1] === 'function') {\n return nativeMethod.apply(this, arguments)\n .then(function() {\n if (typeof args[1] === 'function') {\n args[1].apply(null);\n }\n });\n }\n return nativeMethod.apply(this, arguments);\n };\n });\n\n return RTCPeerConnection;\n};\n", "/* global __filename, RTCSessionDescription */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport { Interop } from '@jitsi/sdp-interop';\nimport transform from 'sdp-transform';\n\nimport * as GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport JitsiRemoteTrack from './JitsiRemoteTrack';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport LocalSdpMunger from './LocalSdpMunger';\nimport RTC from './RTC';\nimport RTCUtils from './RTCUtils';\nimport browser from '../browser';\nimport RTCEvents from '../../service/RTC/RTCEvents';\nimport RtxModifier from '../xmpp/RtxModifier';\nimport { SIM_LAYER_RIDS, TPCUtils } from './TPCUtils';\n\n// FIXME SDP tools should end up in some kind of util module\nimport SDP from '../xmpp/SDP';\nimport SdpConsistency from '../xmpp/SdpConsistency';\nimport { SdpTransformWrap } from '../xmpp/SdpTransformUtil';\nimport SDPUtil from '../xmpp/SDPUtil';\nimport * as SignalingEvents from '../../service/RTC/SignalingEvents';\n\nconst logger = getLogger(__filename);\nconst MAX_BITRATE = 2500000;\nconst DESKSTOP_SHARE_RATE = 500000;\n\n/* eslint-disable max-params */\n\n/**\n * Creates new instance of 'TraceablePeerConnection'.\n *\n * @param {RTC} rtc the instance of RTC service\n * @param {number} id the peer connection id assigned by the parent RTC module.\n * @param {SignalingLayer} signalingLayer the signaling layer instance\n * @param {object} iceConfig WebRTC 'PeerConnection' ICE config\n * @param {object} constraints WebRTC 'PeerConnection' constraints\n * @param {boolean} isP2P indicates whether or not the new instance will be used\n * in a peer to peer connection\n * @param {object} options TracablePeerConnection config options.\n * @param {boolean} options.disableSimulcast if set to 'true' will disable\n * the simulcast.\n * @param {boolean} options.disableRtx if set to 'true' will disable the RTX\n * @param {boolean} options.capScreenshareBitrate if set to 'true' simulcast will\n * be disabled for screenshare and a max bitrate of 500Kbps will applied on the\n * stream.\n * @param {boolean} options.disableH264 If set to 'true' H264 will be\n * disabled by removing it from the SDP.\n * @param {boolean} options.preferH264 if set to 'true' H264 will be preferred\n * over other video codecs.\n * @param {boolean} options.enableLayerSuspension if set to 'true', we will\n * cap the video send bitrate when we are told we have not been selected by\n * any endpoints (and therefore the non-thumbnail streams are not in use).\n * @param {boolean} options.startSilent If set to 'true' no audio will be sent or received.\n *\n * FIXME: initially the purpose of TraceablePeerConnection was to be able to\n * debug the peer connection. Since many other responsibilities have been added\n * it would make sense to extract a separate class from it and come up with\n * a more suitable name.\n *\n * @constructor\n */\nexport default function TraceablePeerConnection(\n rtc,\n id,\n signalingLayer,\n iceConfig,\n constraints,\n isP2P,\n options) {\n\n /**\n * Indicates whether or not this peer connection instance is actively\n * sending/receiving audio media. When set to false the SDP audio\n * media direction will be adjusted to 'inactive' in order to suspend\n * the transmission.\n * @type {boolean}\n * @private\n */\n this.audioTransferActive = !(options.startSilent === true);\n\n /**\n * The DTMF sender instance used to send DTMF tones.\n *\n * @type {RTCDTMFSender|undefined}\n * @private\n */\n this._dtmfSender = undefined;\n\n /**\n * @typedef {Object} TouchToneRequest\n * @property {string} tones - The DTMF tones string as defined by\n * {@code RTCDTMFSender.insertDTMF}, 'tones' argument.\n * @property {number} duration - The amount of time in milliseconds that\n * each DTMF should last.\n * @property {string} interToneGap - The length of time in miliseconds to\n * wait between tones.\n */\n /**\n * TouchToneRequests which are waiting to be played. This queue is filled\n * if there are touch tones currently being played.\n *\n * @type {Array}\n * @private\n */\n this._dtmfTonesQueue = [];\n\n /**\n * Indicates whether or not this peer connection instance is actively\n * sending/receiving video media. When set to false the SDP video\n * media direction will be adjusted to 'inactive' in order to suspend\n * the transmission.\n * @type {boolean}\n * @private\n */\n this.videoTransferActive = true;\n\n /**\n * The parent instance of RTC service which created this\n * TracablePeerConnection.\n * @type {RTC}\n */\n this.rtc = rtc;\n\n /**\n * The peer connection identifier assigned by the RTC module.\n * @type {number}\n */\n this.id = id;\n\n /**\n * Indicates whether or not this instance is used in a peer to peer\n * connection.\n * @type {boolean}\n */\n this.isP2P = isP2P;\n\n // FIXME: We should support multiple streams per jid.\n /**\n * The map holds remote tracks associated with this peer connection.\n * It maps user's JID to media type and remote track\n * (one track per media type per user's JID).\n * @type {Map>}\n */\n this.remoteTracks = new Map();\n\n /**\n * A map which stores local tracks mapped by {@link JitsiLocalTrack.rtcId}\n * @type {Map}\n */\n this.localTracks = new Map();\n\n /**\n * Keeps tracks of the WebRTC MediaStreams that have been added to\n * the underlying WebRTC PeerConnection.\n * @type {Array}\n * @private\n */\n this._addedStreams = [];\n\n /**\n * @typedef {Object} TPCGroupInfo\n * @property {string} semantics the SSRC groups semantics\n * @property {Array} ssrcs group's SSRCs in order where the first\n * one is group's primary SSRC, the second one is secondary (RTX) and so\n * on...\n */\n /**\n * @typedef {Object} TPCSSRCInfo\n * @property {Array} ssrcs an array which holds all track's SSRCs\n * @property {Array} groups an array stores all track's SSRC\n * groups\n */\n /**\n * Holds the info about local track's SSRCs mapped per their\n * {@link JitsiLocalTrack.rtcId}\n * @type {Map}\n */\n this.localSSRCs = new Map();\n\n /**\n * The local ICE username fragment for this session.\n */\n this.localUfrag = null;\n\n /**\n * The remote ICE username fragment for this session.\n */\n this.remoteUfrag = null;\n\n /**\n * The signaling layer which operates this peer connection.\n * @type {SignalingLayer}\n */\n this.signalingLayer = signalingLayer;\n\n // SignalingLayer listeners\n this._peerVideoTypeChanged = this._peerVideoTypeChanged.bind(this);\n this.signalingLayer.on(\n SignalingEvents.PEER_VIDEO_TYPE_CHANGED,\n this._peerVideoTypeChanged);\n\n this._peerMutedChanged = this._peerMutedChanged.bind(this);\n this.signalingLayer.on(\n SignalingEvents.PEER_MUTED_CHANGED,\n this._peerMutedChanged);\n this.options = options;\n\n this.peerconnection\n = new RTCUtils.RTCPeerConnectionType(iceConfig, constraints);\n this.tpcUtils = new TPCUtils(this);\n this.updateLog = [];\n this.stats = {};\n this.statsinterval = null;\n\n /**\n * @type {number} The max number of stats to keep in this.stats. Limit to\n * 300 values, i.e. 5 minutes; set to 0 to disable\n */\n this.maxstats = options.maxstats;\n\n this.interop = new Interop();\n const Simulcast = require('@jitsi/sdp-simulcast');\n\n this.simulcast = new Simulcast(\n {\n numOfLayers: SIM_LAYER_RIDS.length,\n explodeRemoteSimulcast: false,\n usesUnifiedPlan: browser.usesUnifiedPlan()\n });\n this.sdpConsistency = new SdpConsistency(this.toString());\n\n /**\n * Munges local SDP provided to the Jingle Session in order to prevent from\n * sending SSRC updates on attach/detach and mute/unmute (for video).\n * @type {LocalSdpMunger}\n */\n this.localSdpMunger = new LocalSdpMunger(this);\n\n /**\n * TracablePeerConnection uses RTC's eventEmitter\n * @type {EventEmitter}\n */\n this.eventEmitter = rtc.eventEmitter;\n this.rtxModifier = new RtxModifier();\n\n // override as desired\n this.trace = (what, info) => {\n logger.debug(what, info);\n\n this.updateLog.push({\n time: new Date(),\n type: what,\n value: info || ''\n });\n };\n this.onicecandidate = null;\n this.peerconnection.onicecandidate = event => {\n this.trace(\n 'onicecandidate',\n JSON.stringify(event.candidate, null, ' '));\n\n if (this.onicecandidate !== null) {\n this.onicecandidate(event);\n }\n };\n\n // Use stream events in plan-b and track events in unified plan.\n if (browser.usesPlanB()) {\n this.peerconnection.onaddstream\n = event => this._remoteStreamAdded(event.stream);\n this.peerconnection.onremovestream\n = event => this._remoteStreamRemoved(event.stream);\n } else {\n this.peerconnection.ontrack = event => {\n const stream = event.streams[0];\n\n this._remoteTrackAdded(stream, event.track, event.transceiver);\n stream.onremovetrack = evt => {\n this._remoteTrackRemoved(stream, evt.track);\n };\n };\n }\n this.onsignalingstatechange = null;\n this.peerconnection.onsignalingstatechange = event => {\n this.trace('onsignalingstatechange', this.signalingState);\n if (this.onsignalingstatechange !== null) {\n this.onsignalingstatechange(event);\n }\n };\n this.oniceconnectionstatechange = null;\n this.peerconnection.oniceconnectionstatechange = event => {\n this.trace('oniceconnectionstatechange', this.iceConnectionState);\n if (this.oniceconnectionstatechange !== null) {\n this.oniceconnectionstatechange(event);\n }\n };\n this.onnegotiationneeded = null;\n this.peerconnection.onnegotiationneeded = event => {\n this.trace('onnegotiationneeded');\n if (this.onnegotiationneeded !== null) {\n this.onnegotiationneeded(event);\n }\n };\n this.ondatachannel = null;\n this.peerconnection.ondatachannel = event => {\n this.trace('ondatachannel');\n if (this.ondatachannel !== null) {\n this.ondatachannel(event);\n }\n };\n\n if (this.maxstats) {\n this.statsinterval = window.setInterval(() => {\n this.getStats(stats => {\n if (stats.result\n && typeof stats.result === 'function') {\n const results = stats.result();\n\n for (let i = 0; i < results.length; ++i) {\n const res = results[i];\n\n res.names().forEach(name => {\n this._processStat(res, name, res.stat(name));\n });\n }\n } else {\n stats.forEach(r => this._processStat(r, '', r));\n }\n }, () => {\n\n // empty error callback\n });\n }, 1000);\n }\n\n logger.info(`Create new ${this}`);\n}\n\n/* eslint-enable max-params */\n\n/**\n * Process stat and adds it to the array of stats we store.\n * @param report the current stats report.\n * @param name the name of the report, if available\n * @param statValue the value to add.\n * @private\n */\nTraceablePeerConnection.prototype._processStat\n = function(report, name, statValue) {\n const id = `${report.id}-${name}`;\n let s = this.stats[id];\n const now = new Date();\n\n if (!s) {\n this.stats[id] = s = {\n startTime: now,\n endTime: now,\n values: [],\n times: []\n };\n }\n s.values.push(statValue);\n s.times.push(now.getTime());\n if (s.values.length > this.maxstats) {\n s.values.shift();\n s.times.shift();\n }\n s.endTime = now;\n };\n\n/**\n * Returns a string representation of a SessionDescription object.\n */\nconst dumpSDP = function(description) {\n if (typeof description === 'undefined' || description === null) {\n return '';\n }\n\n return `type: ${description.type}\\r\\n${description.sdp}`;\n};\n\n\n/**\n * Forwards the {@link peerconnection.iceConnectionState} state except that it\n * will convert \"completed\" into \"connected\" where both mean that the ICE has\n * succeeded and is up and running. We never see \"completed\" state for\n * the JVB connection, but it started appearing for the P2P one. This method\n * allows to adapt old logic to this new situation.\n * @return {string}\n */\nTraceablePeerConnection.prototype.getConnectionState = function() {\n const state = this.peerconnection.iceConnectionState;\n\n if (state === 'completed') {\n return 'connected';\n }\n\n return state;\n};\n\n/**\n * Obtains the media direction for given {@link MediaType}. The method takes\n * into account whether or not there are any local tracks for media and\n * the {@link audioTransferActive} and {@link videoTransferActive} flags.\n * @param {MediaType} mediaType\n * @return {string} one of the SDP direction constants ('sendrecv, 'recvonly'\n * etc.) which should be used when setting local description on the peer\n * connection.\n * @private\n */\nTraceablePeerConnection.prototype._getDesiredMediaDirection = function(\n mediaType) {\n let mediaTransferActive = true;\n\n if (mediaType === MediaType.AUDIO) {\n mediaTransferActive = this.audioTransferActive;\n } else if (mediaType === MediaType.VIDEO) {\n mediaTransferActive = this.videoTransferActive;\n }\n if (mediaTransferActive) {\n return this.hasAnyTracksOfType(mediaType) ? 'sendrecv' : 'recvonly';\n }\n\n return 'inactive';\n};\n\n/**\n * Tells whether or not this TPC instance is using Simulcast.\n * @return {boolean} true if simulcast is enabled and active or\n * false if it's turned off.\n */\nTraceablePeerConnection.prototype.isSimulcastOn = function() {\n return !this.options.disableSimulcast;\n};\n\n/**\n * Handles {@link SignalingEvents.PEER_VIDEO_TYPE_CHANGED}\n * @param {string} endpointId the video owner's ID (MUC nickname)\n * @param {VideoType} videoType the new value\n * @private\n */\nTraceablePeerConnection.prototype._peerVideoTypeChanged = function(\n endpointId,\n videoType) {\n // Check if endpointId has a value to avoid action on random track\n if (!endpointId) {\n logger.error(`No endpointID on peerVideoTypeChanged ${this}`);\n\n return;\n }\n const videoTrack = this.getRemoteTracks(endpointId, MediaType.VIDEO);\n\n if (videoTrack.length) {\n // NOTE 1 track per media type is assumed\n videoTrack[0]._setVideoType(videoType);\n }\n};\n\n/**\n * Handles remote track mute / unmute events.\n * @param {string} endpointId the track owner's identifier (MUC nickname)\n * @param {MediaType} mediaType \"audio\" or \"video\"\n * @param {boolean} isMuted the new mute state\n * @private\n */\nTraceablePeerConnection.prototype._peerMutedChanged = function(\n endpointId,\n mediaType,\n isMuted) {\n // Check if endpointId is a value to avoid doing action on all remote tracks\n if (!endpointId) {\n logger.error('On peerMuteChanged - no endpoint ID');\n\n return;\n }\n const track = this.getRemoteTracks(endpointId, mediaType);\n\n if (track.length) {\n // NOTE 1 track per media type is assumed\n track[0].setMute(isMuted);\n }\n};\n\n/**\n * Obtains local tracks for given {@link MediaType}. If the mediaType\n * argument is omitted the list of all local tracks will be returned.\n * @param {MediaType} [mediaType]\n * @return {Array}\n */\nTraceablePeerConnection.prototype.getLocalTracks = function(mediaType) {\n let tracks = Array.from(this.localTracks.values());\n\n if (mediaType !== undefined) {\n tracks = tracks.filter(track => track.getType() === mediaType);\n }\n\n return tracks;\n};\n\n/**\n * Checks whether or not this {@link TraceablePeerConnection} instance contains\n * any local tracks for given mediaType.\n * @param {MediaType} mediaType\n * @return {boolean}\n */\nTraceablePeerConnection.prototype.hasAnyTracksOfType = function(mediaType) {\n if (!mediaType) {\n throw new Error('\"mediaType\" is required');\n }\n\n return this.getLocalTracks(mediaType).length > 0;\n};\n\n/**\n * Obtains all remote tracks currently known to this PeerConnection instance.\n * @param {string} [endpointId] the track owner's identifier (MUC nickname)\n * @param {MediaType} [mediaType] the remote tracks will be filtered\n * by their media type if this argument is specified.\n * @return {Array}\n */\nTraceablePeerConnection.prototype.getRemoteTracks = function(\n endpointId,\n mediaType) {\n const remoteTracks = [];\n const endpoints\n = endpointId ? [ endpointId ] : this.remoteTracks.keys();\n\n for (const endpoint of endpoints) {\n const endpointTrackMap = this.remoteTracks.get(endpoint);\n\n if (!endpointTrackMap) {\n\n // Otherwise an empty Map() would have to be allocated above\n // eslint-disable-next-line no-continue\n continue;\n }\n\n for (const trackMediaType of endpointTrackMap.keys()) {\n // per media type filtering\n if (!mediaType || mediaType === trackMediaType) {\n const mediaTrack = endpointTrackMap.get(trackMediaType);\n\n if (mediaTrack) {\n remoteTracks.push(mediaTrack);\n }\n }\n }\n }\n\n return remoteTracks;\n};\n\n/**\n * Tries to find {@link JitsiTrack} for given SSRC number. It will search both\n * local and remote tracks bound to this instance.\n * @param {number} ssrc\n * @return {JitsiTrack|null}\n */\nTraceablePeerConnection.prototype.getTrackBySSRC = function(ssrc) {\n if (typeof ssrc !== 'number') {\n throw new Error(`SSRC ${ssrc} is not a number`);\n }\n for (const localTrack of this.localTracks.values()) {\n if (this.getLocalSSRC(localTrack) === ssrc) {\n return localTrack;\n }\n }\n for (const remoteTrack of this.getRemoteTracks()) {\n if (remoteTrack.getSSRC() === ssrc) {\n return remoteTrack;\n }\n }\n\n return null;\n};\n\n/**\n * Tries to find SSRC number for given {@link JitsiTrack} id. It will search\n * both local and remote tracks bound to this instance.\n * @param {string} id\n * @return {number|null}\n */\nTraceablePeerConnection.prototype.getSsrcByTrackId = function(id) {\n\n const findTrackById = track => track.getTrack().id === id;\n const localTrack = this.getLocalTracks().find(findTrackById);\n\n if (localTrack) {\n return this.getLocalSSRC(localTrack);\n }\n\n const remoteTrack = this.getRemoteTracks().find(findTrackById);\n\n if (remoteTrack) {\n return remoteTrack.getSSRC();\n }\n\n return null;\n};\n\n/**\n * Called when new remote MediaStream is added to the PeerConnection.\n * @param {MediaStream} stream the WebRTC MediaStream for remote participant\n */\nTraceablePeerConnection.prototype._remoteStreamAdded = function(stream) {\n const streamId = RTC.getStreamID(stream);\n\n if (!RTC.isUserStreamById(streamId)) {\n logger.info(\n `${this} ignored remote 'stream added' event for non-user stream`\n + `id: ${streamId}`);\n\n return;\n }\n\n // Bind 'addtrack'/'removetrack' event handlers\n if (browser.isChromiumBased()) {\n stream.onaddtrack = event => {\n this._remoteTrackAdded(stream, event.track);\n };\n stream.onremovetrack = event => {\n this._remoteTrackRemoved(stream, event.track);\n };\n }\n\n // Call remoteTrackAdded for each track in the stream\n const streamAudioTracks = stream.getAudioTracks();\n\n for (const audioTrack of streamAudioTracks) {\n this._remoteTrackAdded(stream, audioTrack);\n }\n const streamVideoTracks = stream.getVideoTracks();\n\n for (const videoTrack of streamVideoTracks) {\n this._remoteTrackAdded(stream, videoTrack);\n }\n};\n\n\n/**\n * Called on \"track added\" and \"stream added\" PeerConnection events (because we\n * handle streams on per track basis). Finds the owner and the SSRC for\n * the track and passes that to ChatRoom for further processing.\n * @param {MediaStream} stream the WebRTC MediaStream instance which is\n * the parent of the track\n * @param {MediaStreamTrack} track the WebRTC MediaStreamTrack added for remote\n * participant.\n * @param {RTCRtpTransceiver} transceiver the WebRTC transceiver that is created\n * for the remote participant in unified plan.\n */\nTraceablePeerConnection.prototype._remoteTrackAdded = function(stream, track, transceiver = null) {\n const streamId = RTC.getStreamID(stream);\n const mediaType = track.kind;\n\n if (!this.isP2P && !RTC.isUserStreamById(streamId)) {\n logger.info(\n `${this} ignored remote 'stream added' event for non-user stream`\n + `id: ${streamId}`);\n\n return;\n }\n logger.info(`${this} remote track added:`, streamId, mediaType);\n\n // look up an associated JID for a stream id\n if (!mediaType) {\n GlobalOnErrorHandler.callErrorHandler(\n new Error(\n `MediaType undefined for remote track, stream id: ${streamId}`\n ));\n\n // Abort\n return;\n }\n\n const remoteSDP = browser.usesPlanB()\n ? new SDP(this.remoteDescription.sdp)\n : new SDP(this.peerconnection.remoteDescription.sdp);\n let mediaLines;\n\n if (browser.usesUnifiedPlan()) {\n if (transceiver && transceiver.mid) {\n const mid = transceiver.mid;\n\n mediaLines = remoteSDP.media.filter(mls => SDPUtil.findLine(mls, `a=mid:${mid}`));\n } else {\n mediaLines = remoteSDP.media.filter(mls => {\n const msid = SDPUtil.findLine(mls, 'a=msid');\n\n return typeof msid !== 'undefined' && streamId === msid.substring(7).split(' ')[0];\n });\n }\n } else {\n mediaLines = remoteSDP.media.filter(mls => mls.startsWith(`m=${mediaType}`));\n }\n\n if (!mediaLines.length) {\n GlobalOnErrorHandler.callErrorHandler(\n new Error(\n `No media lines for type ${\n mediaType} found in remote SDP for remote track: ${\n streamId}`));\n\n // Abort\n return;\n }\n\n let ssrcLines = SDPUtil.findLines(mediaLines[0], 'a=ssrc:');\n\n ssrcLines\n = ssrcLines.filter(line => line.indexOf(`msid:${streamId}`) !== -1);\n if (!ssrcLines.length) {\n GlobalOnErrorHandler.callErrorHandler(\n new Error(\n `No SSRC lines for streamId ${\n streamId} for remote track, media type: ${mediaType}`));\n\n // Abort\n return;\n }\n\n // FIXME the length of ssrcLines[0] not verified, but it will fail\n // with global error handler anyway\n const ssrcStr = ssrcLines[0].substring(7).split(' ')[0];\n const trackSsrc = Number(ssrcStr);\n const ownerEndpointId = this.signalingLayer.getSSRCOwner(trackSsrc);\n\n if (isNaN(trackSsrc) || trackSsrc < 0) {\n GlobalOnErrorHandler.callErrorHandler(\n new Error(\n `Invalid SSRC: ${ssrcStr} for remote track, msid: ${\n streamId} media type: ${mediaType}`));\n\n // Abort\n return;\n } else if (!ownerEndpointId) {\n GlobalOnErrorHandler.callErrorHandler(\n new Error(\n `No SSRC owner known for: ${\n trackSsrc} for remote track, msid: ${\n streamId} media type: ${mediaType}`));\n\n // Abort\n return;\n }\n\n logger.log(`${this} associated ssrc`, ownerEndpointId, trackSsrc);\n\n const peerMediaInfo\n = this.signalingLayer.getPeerMediaInfo(ownerEndpointId, mediaType);\n\n if (!peerMediaInfo) {\n GlobalOnErrorHandler.callErrorHandler(\n new Error(\n `${this}: no peer media info available for ${\n ownerEndpointId}`));\n\n return;\n }\n\n const muted = peerMediaInfo.muted;\n const videoType = peerMediaInfo.videoType; // can be undefined\n\n this._createRemoteTrack(\n ownerEndpointId, stream, track, mediaType, videoType, trackSsrc, muted);\n};\n\n// FIXME cleanup params\n/* eslint-disable max-params */\n\n/**\n * Initializes a new JitsiRemoteTrack instance with the data provided by\n * the signaling layer and SDP.\n *\n * @param {string} ownerEndpointId the owner's endpoint ID (MUC nickname)\n * @param {MediaStream} stream the WebRTC stream instance\n * @param {MediaStreamTrack} track the WebRTC track instance\n * @param {MediaType} mediaType the track's type of the media\n * @param {VideoType} [videoType] the track's type of the video (if applicable)\n * @param {number} ssrc the track's main SSRC number\n * @param {boolean} muted the initial muted status\n */\nTraceablePeerConnection.prototype._createRemoteTrack = function(\n ownerEndpointId,\n stream,\n track,\n mediaType,\n videoType,\n ssrc,\n muted) {\n let remoteTracksMap = this.remoteTracks.get(ownerEndpointId);\n\n if (!remoteTracksMap) {\n remoteTracksMap = new Map();\n this.remoteTracks.set(ownerEndpointId, remoteTracksMap);\n }\n\n const existingTrack = remoteTracksMap.get(mediaType);\n\n if (existingTrack && existingTrack.getTrack() === track) {\n // Ignore duplicated event which can originate either from\n // 'onStreamAdded' or 'onTrackAdded'.\n logger.info(\n `${this} ignored duplicated remote track added event for: `\n + `${ownerEndpointId}, ${mediaType}`);\n\n return;\n } else if (existingTrack) {\n logger.error(\n `${this} overwriting remote track for`\n + `${ownerEndpointId} ${mediaType}`);\n }\n\n const remoteTrack\n = new JitsiRemoteTrack(\n this.rtc,\n this.rtc.conference,\n ownerEndpointId,\n stream,\n track,\n mediaType,\n videoType,\n ssrc,\n muted,\n this.isP2P);\n\n remoteTracksMap.set(mediaType, remoteTrack);\n\n this.eventEmitter.emit(RTCEvents.REMOTE_TRACK_ADDED, remoteTrack);\n};\n\n/* eslint-enable max-params */\n\n/**\n * Handles remote stream removal.\n * @param stream the WebRTC MediaStream object which is being removed from the\n * PeerConnection\n */\nTraceablePeerConnection.prototype._remoteStreamRemoved = function(stream) {\n if (!RTC.isUserStream(stream)) {\n const id = RTC.getStreamID(stream);\n\n logger.info(\n `Ignored remote 'stream removed' event for non-user stream ${id}`);\n\n return;\n }\n\n // Call remoteTrackRemoved for each track in the stream\n const streamVideoTracks = stream.getVideoTracks();\n\n for (const videoTrack of streamVideoTracks) {\n this._remoteTrackRemoved(stream, videoTrack);\n }\n const streamAudioTracks = stream.getAudioTracks();\n\n for (const audioTrack of streamAudioTracks) {\n this._remoteTrackRemoved(stream, audioTrack);\n }\n};\n\n/**\n * Handles remote media track removal.\n * @param {MediaStream} stream WebRTC MediaStream instance which is the parent\n * of the track.\n * @param {MediaStreamTrack} track the WebRTC MediaStreamTrack which has been\n * removed from the PeerConnection.\n */\nTraceablePeerConnection.prototype._remoteTrackRemoved = function(\n stream,\n track) {\n const streamId = RTC.getStreamID(stream);\n const trackId = track && RTC.getTrackID(track);\n\n logger.info(`${this} - remote track removed: ${streamId}, ${trackId}`);\n\n if (!streamId) {\n GlobalOnErrorHandler.callErrorHandler(\n new Error(`${this} remote track removal failed - no stream ID`));\n\n return;\n }\n\n if (!trackId) {\n GlobalOnErrorHandler.callErrorHandler(\n new Error(`${this} remote track removal failed - no track ID`));\n\n return;\n }\n\n if (!this._removeRemoteTrackById(streamId, trackId)) {\n // NOTE this warning is always printed when user leaves the room,\n // because we remove remote tracks manually on MUC member left event,\n // before the SSRCs are removed by Jicofo. In most cases it is fine to\n // ignore this warning, but still it's better to keep it printed for\n // debugging purposes.\n //\n // We could change the behaviour to emit track removed only from here,\n // but the order of the events will change and consuming apps could\n // behave unexpectedly (the \"user left\" event would come before \"track\n // removed\" events).\n logger.warn(\n `${this} Removed track not found for msid: ${streamId},\n track id: ${trackId}`);\n }\n};\n\n/**\n * Finds remote track by it's stream and track ids.\n * @param {string} streamId the media stream id as defined by the WebRTC\n * @param {string} trackId the media track id as defined by the WebRTC\n * @return {JitsiRemoteTrack|undefined} the track's instance or\n * undefined if not found.\n * @private\n */\nTraceablePeerConnection.prototype._getRemoteTrackById = function(\n streamId,\n trackId) {\n // .find will break the loop once the first match is found\n for (const endpointTrackMap of this.remoteTracks.values()) {\n for (const mediaTrack of endpointTrackMap.values()) {\n // FIXME verify and try to use ===\n /* eslint-disable eqeqeq */\n if (mediaTrack.getStreamId() == streamId\n && mediaTrack.getTrackId() == trackId) {\n return mediaTrack;\n }\n\n /* eslint-enable eqeqeq */\n }\n }\n\n return undefined;\n};\n\n/**\n * Removes all JitsiRemoteTracks associated with given MUC nickname\n * (resource part of the JID). Returns array of removed tracks.\n *\n * @param {string} owner - The resource part of the MUC JID.\n * @returns {JitsiRemoteTrack[]}\n */\nTraceablePeerConnection.prototype.removeRemoteTracks = function(owner) {\n const removedTracks = [];\n const remoteTracksMap = this.remoteTracks.get(owner);\n\n if (remoteTracksMap) {\n const removedAudioTrack = remoteTracksMap.get(MediaType.AUDIO);\n const removedVideoTrack = remoteTracksMap.get(MediaType.VIDEO);\n\n removedAudioTrack && removedTracks.push(removedAudioTrack);\n removedVideoTrack && removedTracks.push(removedVideoTrack);\n\n this.remoteTracks.delete(owner);\n }\n\n logger.debug(\n `${this} removed remote tracks for ${owner} count: ${\n removedTracks.length}`);\n\n return removedTracks;\n};\n\n/**\n * Removes and disposes given JitsiRemoteTrack instance. Emits\n * {@link RTCEvents.REMOTE_TRACK_REMOVED}.\n * @param {JitsiRemoteTrack} toBeRemoved\n */\nTraceablePeerConnection.prototype._removeRemoteTrack = function(toBeRemoved) {\n toBeRemoved.dispose();\n const participantId = toBeRemoved.getParticipantId();\n const remoteTracksMap = this.remoteTracks.get(participantId);\n\n if (!remoteTracksMap) {\n logger.error(\n `removeRemoteTrack: no remote tracks map for ${participantId}`);\n } else if (!remoteTracksMap.delete(toBeRemoved.getType())) {\n logger.error(\n `Failed to remove ${toBeRemoved} - type mapping messed up ?`);\n }\n this.eventEmitter.emit(RTCEvents.REMOTE_TRACK_REMOVED, toBeRemoved);\n};\n\n/**\n * Removes and disposes JitsiRemoteTrack identified by given stream and\n * track ids.\n *\n * @param {string} streamId the media stream id as defined by the WebRTC\n * @param {string} trackId the media track id as defined by the WebRTC\n * @returns {JitsiRemoteTrack|undefined} the track which has been removed or\n * undefined if no track matching given stream and track ids was\n * found.\n */\nTraceablePeerConnection.prototype._removeRemoteTrackById = function(\n streamId,\n trackId) {\n const toBeRemoved = this._getRemoteTrackById(streamId, trackId);\n\n if (toBeRemoved) {\n this._removeRemoteTrack(toBeRemoved);\n }\n\n return toBeRemoved;\n};\n\n/**\n * @typedef {Object} SSRCGroupInfo\n * @property {Array} ssrcs group's SSRCs\n * @property {string} semantics\n */\n/**\n * @typedef {Object} TrackSSRCInfo\n * @property {Array} ssrcs track's SSRCs\n * @property {Array} groups track's SSRC groups\n */\n/**\n * Returns map with keys msid and TrackSSRCInfo values.\n * @param {Object} desc the WebRTC SDP instance.\n * @return {Map}\n */\nfunction extractSSRCMap(desc) {\n /**\n * Track SSRC infos mapped by stream ID (msid)\n * @type {Map}\n */\n const ssrcMap = new Map();\n\n /**\n * Groups mapped by primary SSRC number\n * @type {Map>}\n */\n const groupsMap = new Map();\n\n if (typeof desc !== 'object' || desc === null\n || typeof desc.sdp !== 'string') {\n logger.warn('An empty description was passed as an argument.');\n\n return ssrcMap;\n }\n\n const session = transform.parse(desc.sdp);\n\n if (!Array.isArray(session.media)) {\n return ssrcMap;\n }\n\n for (const mLine of session.media) {\n if (!Array.isArray(mLine.ssrcs)) {\n continue; // eslint-disable-line no-continue\n }\n\n if (Array.isArray(mLine.ssrcGroups)) {\n for (const group of mLine.ssrcGroups) {\n if (typeof group.semantics !== 'undefined'\n && typeof group.ssrcs !== 'undefined') {\n // Parse SSRCs and store as numbers\n const groupSSRCs\n = group.ssrcs.split(' ').map(\n ssrcStr => parseInt(ssrcStr, 10));\n const primarySSRC = groupSSRCs[0];\n\n // Note that group.semantics is already present\n\n group.ssrcs = groupSSRCs;\n\n // eslint-disable-next-line max-depth\n if (!groupsMap.has(primarySSRC)) {\n groupsMap.set(primarySSRC, []);\n }\n groupsMap.get(primarySSRC).push(group);\n }\n }\n }\n for (const ssrc of mLine.ssrcs) {\n if (ssrc.attribute !== 'msid') {\n continue; // eslint-disable-line no-continue\n }\n\n const msid = ssrc.value;\n let ssrcInfo = ssrcMap.get(msid);\n\n if (!ssrcInfo) {\n ssrcInfo = {\n ssrcs: [],\n groups: [],\n msid\n };\n ssrcMap.set(msid, ssrcInfo);\n }\n\n const ssrcNumber = ssrc.id;\n\n ssrcInfo.ssrcs.push(ssrcNumber);\n\n if (groupsMap.has(ssrcNumber)) {\n const ssrcGroups = groupsMap.get(ssrcNumber);\n\n for (const group of ssrcGroups) {\n ssrcInfo.groups.push(group);\n }\n }\n }\n }\n\n return ssrcMap;\n}\n\n/**\n * Takes a SessionDescription object and returns a \"normalized\" version.\n * Currently it takes care of ordering the a=ssrc lines and denoting receive\n * only SSRCs.\n */\nconst normalizePlanB = function(desc) {\n if (typeof desc !== 'object' || desc === null\n || typeof desc.sdp !== 'string') {\n logger.warn('An empty description was passed as an argument.');\n\n return desc;\n }\n\n // eslint-disable-next-line no-shadow\n const transform = require('sdp-transform');\n const session = transform.parse(desc.sdp);\n\n if (typeof session !== 'undefined'\n && typeof session.media !== 'undefined'\n && Array.isArray(session.media)) {\n session.media.forEach(mLine => {\n\n // Chrome appears to be picky about the order in which a=ssrc lines\n // are listed in an m-line when rtx is enabled (and thus there are\n // a=ssrc-group lines with FID semantics). Specifically if we have\n // \"a=ssrc-group:FID S1 S2\" and the \"a=ssrc:S2\" lines appear before\n // the \"a=ssrc:S1\" lines, SRD fails.\n // So, put SSRC which appear as the first SSRC in an FID ssrc-group\n // first.\n const firstSsrcs = [];\n const newSsrcLines = [];\n\n if (typeof mLine.ssrcGroups !== 'undefined'\n && Array.isArray(mLine.ssrcGroups)) {\n mLine.ssrcGroups.forEach(group => {\n if (typeof group.semantics !== 'undefined'\n && group.semantics === 'FID') {\n if (typeof group.ssrcs !== 'undefined') {\n firstSsrcs.push(Number(group.ssrcs.split(' ')[0]));\n }\n }\n });\n }\n\n if (Array.isArray(mLine.ssrcs)) {\n let i;\n\n for (i = 0; i < mLine.ssrcs.length; i++) {\n if (typeof mLine.ssrcs[i] === 'object'\n && typeof mLine.ssrcs[i].id !== 'undefined'\n && firstSsrcs.indexOf(mLine.ssrcs[i].id) >= 0) {\n newSsrcLines.push(mLine.ssrcs[i]);\n delete mLine.ssrcs[i];\n }\n }\n\n for (i = 0; i < mLine.ssrcs.length; i++) {\n if (typeof mLine.ssrcs[i] !== 'undefined') {\n newSsrcLines.push(mLine.ssrcs[i]);\n }\n }\n\n mLine.ssrcs = replaceDefaultUnifiedPlanMsid(newSsrcLines);\n }\n });\n }\n\n const resStr = transform.write(session);\n\n\n return new RTCSessionDescription({\n type: desc.type,\n sdp: resStr\n });\n};\n\n/**\n * Unified plan differentiates a remote track not associated with a stream using\n * the msid \"-\", which can incorrectly trigger an onaddstream event in plan-b.\n * For jitsi, these tracks are actually receive-only ssrcs. To prevent\n * onaddstream from firing, remove the ssrcs with msid \"-\" except the cname\n * line. Normally the ssrcs are not used by the client, as the bridge controls\n * media flow, but keep one reference to the ssrc for the p2p case.\n *\n * @param {Array} ssrcLines - The ssrc lines from a remote description.\n * @private\n * @returns {Array} ssrcLines with removed lines referencing msid \"-\".\n */\nfunction replaceDefaultUnifiedPlanMsid(ssrcLines = []) {\n if (!browser.isChrome() || !browser.isVersionGreaterThan(70)) {\n return ssrcLines;\n }\n\n let filteredLines = [ ...ssrcLines ];\n\n const problematicSsrcIds = ssrcLines.filter(ssrcLine =>\n ssrcLine.attribute === 'mslabel' && ssrcLine.value === '-')\n .map(ssrcLine => ssrcLine.id);\n\n problematicSsrcIds.forEach(ssrcId => {\n // Find the cname which is to be modified and left in.\n const cnameLine = filteredLines.find(line =>\n line.id === ssrcId && line.attribute === 'cname');\n\n cnameLine.value = `recvonly-${ssrcId}`;\n\n // Remove all of lines for the ssrc.\n filteredLines\n = filteredLines.filter(line => line.id !== ssrcId);\n\n // But re-add the cname line so there is a reference kept to the ssrc\n // in the SDP.\n filteredLines.push(cnameLine);\n });\n\n return filteredLines;\n}\n\n/**\n * Makes sure that both audio and video directions are configured as 'sendrecv'.\n * @param {Object} localDescription the SDP object as defined by WebRTC.\n * @param {object} options TracablePeerConnection config options.\n */\nconst enforceSendRecv = function(localDescription, options) {\n if (!localDescription) {\n throw new Error('No local description passed in.');\n }\n\n const transformer = new SdpTransformWrap(localDescription.sdp);\n const audioMedia = transformer.selectMedia('audio');\n let changed = false;\n\n if (audioMedia && audioMedia.direction !== 'sendrecv') {\n if (options.startSilent) {\n audioMedia.direction = 'inactive';\n } else {\n audioMedia.direction = 'sendrecv';\n }\n\n changed = true;\n }\n\n const videoMedia = transformer.selectMedia('video');\n\n if (videoMedia && videoMedia.direction !== 'sendrecv') {\n videoMedia.direction = 'sendrecv';\n changed = true;\n }\n\n if (changed) {\n return new RTCSessionDescription({\n type: localDescription.type,\n sdp: transformer.toRawSDP()\n });\n }\n\n return localDescription;\n};\n\n/**\n *\n * @param {JitsiLocalTrack} localTrack\n */\nTraceablePeerConnection.prototype.getLocalSSRC = function(localTrack) {\n const ssrcInfo = this._getSSRC(localTrack.rtcId);\n\n return ssrcInfo && ssrcInfo.ssrcs[0];\n};\n\n/**\n * When doing unified plan simulcast, we'll have a set of ssrcs with the\n * same msid but no ssrc-group, since unified plan signals the simulcast\n * group via the a=simulcast line. Unfortunately, Jicofo will complain\n * if it sees ssrcs with matching msids but no ssrc-group, so we'll inject\n * an ssrc-group line to make Jicofo happy.\n * NOTE: unlike plan B simulcast, the ssrcs in this inject ssrc-group will\n * NOT necessarily be in order of quality (low to high) because:\n * a) when translating between unified plan and plan b the order of the ssrcs\n * is not preserved and\n * b) it isn't guaranteed that firefox will give them to us in order to begin\n * with\n * @param desc A session description object (with 'type' and 'sdp' fields)\n * @return A session description object with its sdp field modified to\n * contain an inject ssrc-group for simulcast\n */\nTraceablePeerConnection.prototype._injectSsrcGroupForUnifiedSimulcast\n = function(desc) {\n const sdp = transform.parse(desc.sdp);\n const video = sdp.media.find(mline => mline.type === 'video');\n\n if (video.simulcast || video.simulcast_03) {\n const ssrcs = [];\n\n video.ssrcs.forEach(ssrc => {\n if (ssrc.attribute === 'msid') {\n ssrcs.push(ssrc.id);\n }\n });\n video.ssrcGroups = video.ssrcGroups || [];\n if (video.ssrcGroups.find(group => group.semantics === 'SIM')) {\n // Group already exists, no need to do anything\n return desc;\n }\n video.ssrcGroups.push({\n semantics: 'SIM',\n ssrcs: ssrcs.join(' ')\n });\n }\n\n return new RTCSessionDescription({\n type: desc.type,\n sdp: transform.write(sdp)\n });\n };\n\n/* eslint-disable-next-line vars-on-top */\nconst getters = {\n signalingState() {\n return this.peerconnection.signalingState;\n },\n iceConnectionState() {\n return this.peerconnection.iceConnectionState;\n },\n localDescription() {\n let desc = this.peerconnection.localDescription;\n\n if (!desc) {\n logger.debug('getLocalDescription no localDescription found');\n\n return {};\n }\n\n this.trace('getLocalDescription::preTransform', dumpSDP(desc));\n\n // if we're running on FF, transform to Plan B first.\n if (browser.usesUnifiedPlan()) {\n desc = this.interop.toPlanB(desc);\n this.trace('getLocalDescription::postTransform (Plan B)',\n dumpSDP(desc));\n\n desc = this._injectSsrcGroupForUnifiedSimulcast(desc);\n this.trace('getLocalDescription::postTransform (inject ssrc group)',\n dumpSDP(desc));\n } else {\n if (browser.doesVideoMuteByStreamRemove()) {\n desc = this.localSdpMunger.maybeAddMutedLocalVideoTracksToSDP(desc);\n logger.debug(\n 'getLocalDescription::postTransform (munge local SDP)', desc);\n }\n\n // What comes out of this getter will be signalled over Jingle to\n // the other peer, so we need to make sure the media direction is\n // 'sendrecv' because we won't change the direction later and don't want\n // the other peer to think we can't send or receive.\n //\n // Note that the description we set in chrome does have the accurate\n // direction (e.g. 'recvonly'), since that is technically what is\n // happening (check setLocalDescription impl).\n desc = enforceSendRecv(desc, this.options);\n }\n\n // See the method's doc for more info about this transformation.\n desc = this.localSdpMunger.transformStreamIdentifiers(desc);\n\n return desc;\n },\n remoteDescription() {\n let desc = this.peerconnection.remoteDescription;\n\n if (!desc) {\n logger.debug('getRemoteDescription no remoteDescription found');\n\n return {};\n }\n this.trace('getRemoteDescription::preTransform', dumpSDP(desc));\n\n // if we're running on FF, transform to Plan B first.\n if (browser.usesUnifiedPlan()) {\n desc = this.interop.toPlanB(desc);\n this.trace(\n 'getRemoteDescription::postTransform (Plan B)', dumpSDP(desc));\n }\n\n return desc;\n }\n};\n\nObject.keys(getters).forEach(prop => {\n Object.defineProperty(\n TraceablePeerConnection.prototype,\n prop, {\n get: getters[prop]\n }\n );\n});\n\nTraceablePeerConnection.prototype._getSSRC = function(rtcId) {\n return this.localSSRCs.get(rtcId);\n};\n\n/**\n * Add {@link JitsiLocalTrack} to this TPC.\n * @param {JitsiLocalTrack} track\n */\nTraceablePeerConnection.prototype.addTrack = function(track, isInitiator = false) {\n const rtcId = track.rtcId;\n\n logger.info(`add ${track} to: ${this}`);\n\n if (this.localTracks.has(rtcId)) {\n logger.error(`${track} is already in ${this}`);\n\n return;\n }\n\n this.localTracks.set(rtcId, track);\n if (browser.usesUnifiedPlan() && isInitiator) {\n return this.tpcUtils.addTrack(track, isInitiator);\n }\n\n const webrtcStream = track.getOriginalStream();\n\n if (webrtcStream) {\n this._addStream(webrtcStream);\n\n // It's not ok for a track to not have a WebRTC stream if:\n } else if (!browser.doesVideoMuteByStreamRemove()\n || track.isAudioTrack()\n || (track.isVideoTrack() && !track.isMuted())) {\n logger.error(`${this} no WebRTC stream for: ${track}`);\n }\n\n // Muted video tracks do not have WebRTC stream\n if (browser.usesPlanB() && browser.doesVideoMuteByStreamRemove()\n && track.isVideoTrack() && track.isMuted()) {\n const ssrcInfo = this.generateNewStreamSSRCInfo(track);\n\n this.sdpConsistency.setPrimarySsrc(ssrcInfo.ssrcs[0]);\n const simGroup\n = ssrcInfo.groups.find(groupInfo => groupInfo.semantics === 'SIM');\n\n if (simGroup) {\n this.simulcast.setSsrcCache(simGroup.ssrcs);\n }\n const fidGroups\n = ssrcInfo.groups.filter(\n groupInfo => groupInfo.semantics === 'FID');\n\n if (fidGroups) {\n const rtxSsrcMapping = new Map();\n\n fidGroups.forEach(fidGroup => {\n const primarySsrc = fidGroup.ssrcs[0];\n const rtxSsrc = fidGroup.ssrcs[1];\n\n rtxSsrcMapping.set(primarySsrc, rtxSsrc);\n });\n this.rtxModifier.setSsrcCache(rtxSsrcMapping);\n }\n }\n if (browser.usesUnifiedPlan() && !browser.usesSdpMungingForSimulcast()) {\n this.tpcUtils.setEncodings(track);\n }\n};\n\n/**\n * Adds local track as part of the unmute operation.\n * @param {JitsiLocalTrack} track the track to be added as part of the unmute\n * operation\n * @return {Promise} Promise that resolves to true if the underlying PeerConnection's\n * state has changed and renegotiation is required, false if no renegotiation is needed or\n * Promise is rejected when something goes wrong.\n */\nTraceablePeerConnection.prototype.addTrackUnmute = function(track) {\n if (browser.usesUnifiedPlan()) {\n return this.tpcUtils.addTrackUnmute(track);\n }\n if (!this._assertTrackBelongs('addTrackUnmute', track)) {\n // Abort\n return Promise.reject('Track not found on the peerconnection');\n }\n\n logger.info(`Adding ${track} as unmute to ${this}`);\n const webRtcStream = track.getOriginalStream();\n\n if (!webRtcStream) {\n logger.error(\n `Unable to add ${track} as unmute to ${this} - no WebRTC stream`);\n\n return Promise.reject('Stream not found');\n }\n this._addStream(webRtcStream);\n\n return Promise.resolve(true);\n};\n\n/**\n * Adds WebRTC media stream to the underlying PeerConnection\n * @param {MediaStream} mediaStream\n * @private\n */\nTraceablePeerConnection.prototype._addStream = function(mediaStream) {\n this.peerconnection.addStream(mediaStream);\n this._addedStreams.push(mediaStream);\n};\n\n/**\n * Removes WebRTC media stream from the underlying PeerConection\n * @param {MediaStream} mediaStream\n */\nTraceablePeerConnection.prototype._removeStream = function(mediaStream) {\n if (browser.supportsRtpSender()) {\n this._handleSenderRemoveStream(mediaStream);\n } else {\n this.peerconnection.removeStream(mediaStream);\n }\n this._addedStreams\n = this._addedStreams.filter(stream => stream !== mediaStream);\n};\n\n/**\n * This method when called will check if given localTrack belongs to\n * this TPC (that it has been previously added using {@link addTrack}). If the\n * track does not belong an error message will be logged.\n * @param {string} methodName the method name that will be logged in an error\n * message\n * @param {JitsiLocalTrack} localTrack\n * @return {boolean} true if given local track belongs to this TPC or\n * false otherwise.\n * @private\n */\nTraceablePeerConnection.prototype._assertTrackBelongs = function(\n methodName,\n localTrack) {\n const doesBelong = this.localTracks.has(localTrack.rtcId);\n\n if (!doesBelong) {\n logger.error(\n `${methodName}: ${localTrack} does not belong to ${this}`);\n }\n\n return doesBelong;\n};\n\n/**\n * Tells if the given WebRTC MediaStream has been added to\n * the underlying WebRTC PeerConnection.\n * @param {MediaStream} mediaStream\n * @returns {boolean}\n */\nTraceablePeerConnection.prototype.isMediaStreamInPc = function(mediaStream) {\n return this._addedStreams.indexOf(mediaStream) > -1;\n};\n\n/**\n * Remove local track from this TPC.\n * @param {JitsiLocalTrack} localTrack the track to be removed from this TPC.\n *\n * FIXME It should probably remove a boolean just like {@link removeTrackMute}\n * The same applies to addTrack.\n */\nTraceablePeerConnection.prototype.removeTrack = function(localTrack) {\n if (browser.usesUnifiedPlan()) {\n return this.tpcUtils.removeTrack(localTrack);\n }\n const webRtcStream = localTrack.getOriginalStream();\n\n this.trace(\n 'removeStream',\n localTrack.rtcId, webRtcStream ? webRtcStream.id : undefined);\n\n if (!this._assertTrackBelongs('removeStream', localTrack)) {\n // Abort - nothing to be done here\n return;\n }\n this.localTracks.delete(localTrack.rtcId);\n this.localSSRCs.delete(localTrack.rtcId);\n\n if (webRtcStream) {\n if (browser.supportsRtpSender()) {\n this._handleSenderRemoveStream(webRtcStream);\n } else {\n this.peerconnection.removeStream(webRtcStream);\n }\n }\n};\n\n/**\n * Returns the sender corresponding to the given media type.\n * @param {MEDIA_TYPE} mediaType - The media type 'audio' or 'video' to be used for the search.\n * @returns {RTPSender|undefined} - The found sender or undefined if no sender\n * was found.\n */\nTraceablePeerConnection.prototype.findSenderByKind = function(mediaType) {\n return this.peerconnection.getSenders().find(s => s.track && s.track.kind === mediaType);\n};\n\n/**\n * Returns the sender corresponding to the given MediaStream.\n *\n * @param {MediaStream} stream - The media stream used for the search.\n * @returns {RTPSender|undefined} - The found sender or undefined if no sender\n * was found.\n */\nTraceablePeerConnection.prototype.findSenderByStream = function(stream) {\n const track = stream.getTracks()[0];\n\n if (!track) {\n logger.error('Cannot find sender: no tracks.');\n\n return;\n }\n\n // Find the right sender (for audio or video)\n return this.peerconnection.getSenders().find(s => s.track === track);\n};\n\n/**\n * Returns the receiver corresponding to the given MediaStreamTrack.\n *\n * @param {MediaSreamTrack} track - The media stream track used for the search.\n * @returns {RTCRtpReceiver|undefined} - The found receiver or undefined if no receiver\n * was found.\n */\nTraceablePeerConnection.prototype.findReceiverForTrack = function(track) {\n return this.peerconnection.getReceivers().find(r => r.track === track);\n};\n\n/**\n * Returns the sender corresponding to the given MediaStreamTrack.\n *\n * @param {MediaSreamTrack} track - The media stream track used for the search.\n * @returns {RTCRtpSender|undefined} - The found sender or undefined if no sender\n * was found.\n */\nTraceablePeerConnection.prototype.findSenderForTrack = function(track) {\n return this.peerconnection.getSenders().find(s => s.track === track);\n};\n\n/**\n * Replaces oldTrack with newTrack from the peer connection.\n * Either oldTrack or newTrack can be null; replacing a valid\n * oldTrack with a null newTrack effectively just removes\n * oldTrack\n *\n * @param {JitsiLocalTrack|null} oldTrack - The current track in use to be\n * replaced\n * @param {JitsiLocalTrack|null} newTrack - The new track to use\n * @returns {Promise} - If the promise resolves with true,\n * renegotiation will be needed. Otherwise no renegotiation is needed.\n */\nTraceablePeerConnection.prototype.replaceTrack = function(oldTrack, newTrack) {\n if (browser.usesUnifiedPlan()) {\n return this.tpcUtils.replaceTrack(oldTrack, newTrack);\n }\n if (oldTrack) {\n this.removeTrack(oldTrack);\n }\n if (newTrack) {\n this.addTrack(newTrack);\n }\n\n return Promise.resolve(true);\n};\n\n/**\n * Removes local track as part of the mute operation.\n * @param {JitsiLocalTrack} localTrack the local track to be remove as part of\n * the mute operation.\n * @return {Promise} Promise that resolves to true if the underlying PeerConnection's\n * state has changed and renegotiation is required, false if no renegotiation is needed or\n * Promise is rejected when something goes wrong.\n */\nTraceablePeerConnection.prototype.removeTrackMute = function(localTrack) {\n if (browser.usesUnifiedPlan()) {\n return this.tpcUtils.removeTrackMute(localTrack);\n }\n const webRtcStream = localTrack.getOriginalStream();\n\n this.trace(\n 'removeStreamMute',\n localTrack.rtcId, webRtcStream ? webRtcStream.id : null);\n\n if (!this._assertTrackBelongs('removeStreamMute', localTrack)) {\n // Abort - nothing to be done here\n return Promise.reject('Track not found in the peerconnection');\n }\n if (webRtcStream) {\n logger.info(\n `Removing ${localTrack} as mute from ${this}`);\n this._removeStream(webRtcStream);\n\n return Promise.resolve(true);\n }\n\n logger.error(`removeStreamMute - no WebRTC stream for ${localTrack}`);\n\n return Promise.reject('Stream not found');\n};\n\n/**\n * Remove stream handling for browsers supporting RTPSender\n * @param stream: webrtc media stream\n */\nTraceablePeerConnection.prototype._handleSenderRemoveStream = function(\n stream) {\n if (!stream) {\n // There is nothing to be changed\n return;\n }\n\n const sender = this.findSenderByStream(stream);\n\n if (sender) {\n this.peerconnection.removeTrack(sender);\n } else {\n logger.log('Cannot remove tracks: no RTPSender.');\n }\n};\n\nTraceablePeerConnection.prototype.createDataChannel = function(label, opts) {\n this.trace('createDataChannel', label, opts);\n\n return this.peerconnection.createDataChannel(label, opts);\n};\n\n/**\n * Ensures that the simulcast ssrc-group appears after any other ssrc-groups\n * in the SDP so that simulcast is properly activated.\n *\n * @param {Object} localSdp the WebRTC session description instance for\n * the local description.\n * @private\n */\nTraceablePeerConnection.prototype._ensureSimulcastGroupIsLast = function(\n localSdp) {\n let sdpStr = localSdp.sdp;\n\n const videoStartIndex = sdpStr.indexOf('m=video');\n const simStartIndex = sdpStr.indexOf('a=ssrc-group:SIM', videoStartIndex);\n let otherStartIndex = sdpStr.lastIndexOf('a=ssrc-group');\n\n if (simStartIndex === -1\n || otherStartIndex === -1\n || otherStartIndex === simStartIndex) {\n return localSdp;\n }\n\n const simEndIndex = sdpStr.indexOf('\\r\\n', simStartIndex);\n const simStr = sdpStr.substring(simStartIndex, simEndIndex + 2);\n\n sdpStr = sdpStr.replace(simStr, '');\n otherStartIndex = sdpStr.lastIndexOf('a=ssrc-group');\n const otherEndIndex = sdpStr.indexOf('\\r\\n', otherStartIndex);\n const sdpHead = sdpStr.slice(0, otherEndIndex);\n const simStrTrimmed = simStr.trim();\n const sdpTail = sdpStr.slice(otherEndIndex);\n\n sdpStr = `${sdpHead}\\r\\n${simStrTrimmed}${sdpTail}`;\n\n return new RTCSessionDescription({\n type: localSdp.type,\n sdp: sdpStr\n });\n};\n\n/**\n * Will adjust audio and video media direction in the given SDP object to\n * reflect the current status of the {@link audioTransferActive} and\n * {@link videoTransferActive} flags.\n * @param {Object} localDescription the WebRTC session description instance for\n * the local description.\n * @private\n */\nTraceablePeerConnection.prototype._adjustLocalMediaDirection = function(\n localDescription) {\n const transformer = new SdpTransformWrap(localDescription.sdp);\n let modifiedDirection = false;\n const audioMedia = transformer.selectMedia('audio');\n\n if (audioMedia) {\n const desiredAudioDirection\n = this._getDesiredMediaDirection(MediaType.AUDIO);\n\n if (audioMedia.direction !== desiredAudioDirection) {\n audioMedia.direction = desiredAudioDirection;\n logger.info(\n `Adjusted local audio direction to ${desiredAudioDirection}`);\n modifiedDirection = true;\n }\n } else {\n logger.warn('No \"audio\" media found int the local description');\n }\n\n const videoMedia = transformer.selectMedia('video');\n\n if (videoMedia) {\n const desiredVideoDirection\n = this._getDesiredMediaDirection(MediaType.VIDEO);\n\n if (videoMedia.direction !== desiredVideoDirection) {\n videoMedia.direction = desiredVideoDirection;\n logger.info(\n `Adjusted local video direction to ${desiredVideoDirection}`);\n modifiedDirection = true;\n }\n } else {\n logger.warn('No \"video\" media found in the local description');\n }\n\n if (modifiedDirection) {\n return new RTCSessionDescription({\n type: localDescription.type,\n sdp: transformer.toRawSDP()\n });\n }\n\n return localDescription;\n};\n\nTraceablePeerConnection.prototype.setLocalDescription = function(description) {\n let localSdp = description;\n\n this.trace('setLocalDescription::preTransform', dumpSDP(localSdp));\n\n if (this.options.disableH264 || this.options.preferH264) {\n const parsedSdp = transform.parse(localSdp.sdp);\n const videoMLine = parsedSdp.media.find(m => m.type === 'video');\n\n if (this.options.disableH264) {\n SDPUtil.stripVideoCodec(videoMLine, 'h264');\n } else {\n SDPUtil.preferVideoCodec(videoMLine, 'h264');\n }\n\n localSdp = new RTCSessionDescription({\n type: localSdp.type,\n sdp: transform.write(parsedSdp)\n });\n\n this.trace('setLocalDescription::postTransform (H264)',\n dumpSDP(localSdp));\n }\n\n if (browser.usesPlanB()) {\n localSdp = this._adjustLocalMediaDirection(localSdp);\n localSdp = this._ensureSimulcastGroupIsLast(localSdp);\n } else {\n\n // if we're using unified plan, transform to it first.\n localSdp = this.interop.toUnifiedPlan(localSdp);\n this.trace(\n 'setLocalDescription::postTransform (Unified Plan)',\n dumpSDP(localSdp));\n }\n\n return new Promise((resolve, reject) => {\n this.peerconnection.setLocalDescription(localSdp)\n .then(() => {\n this.trace('setLocalDescriptionOnSuccess');\n const localUfrag = SDPUtil.getUfrag(localSdp.sdp);\n\n if (localUfrag !== this.localUfrag) {\n this.localUfrag = localUfrag;\n this.eventEmitter.emit(\n RTCEvents.LOCAL_UFRAG_CHANGED, this, localUfrag);\n }\n resolve();\n }, err => {\n this.trace('setLocalDescriptionOnFailure', err);\n this.eventEmitter.emit(\n RTCEvents.SET_LOCAL_DESCRIPTION_FAILED,\n err, this);\n reject(err);\n });\n });\n};\n\n/**\n * Enables/disables audio media transmission on this peer connection. When\n * disabled the SDP audio media direction in the local SDP will be adjusted to\n * 'inactive' which means that no data will be sent nor accepted, but\n * the connection should be kept alive.\n * @param {boolean} active true to enable audio media transmission or\n * false to disable. If the value is not a boolean the call will have\n * no effect.\n * @return {boolean} true if the value has changed and sRD/sLD cycle\n * needs to be executed in order for the changes to take effect or\n * false if the given value was the same as the previous one.\n * @public\n */\nTraceablePeerConnection.prototype.setAudioTransferActive = function(active) {\n logger.debug(`${this} audio transfer active: ${active}`);\n if (browser.usesUnifiedPlan()) {\n return this.tpcUtils.setAudioTransferActive(active);\n }\n const changed = this.audioTransferActive !== active;\n\n this.audioTransferActive = active;\n\n return changed;\n};\n\n/**\n * Sets the max bitrate on the RTCRtpSender so that the\n * bitrate of the enocder doesn't exceed the configured value.\n * This is needed for the desktop share until spec-complaint\n * simulcast is implemented.\n * @param {JitsiLocalTrack} localTrack - the local track whose\n * max bitrate is to be configured.\n */\nTraceablePeerConnection.prototype.setMaxBitRate = function(localTrack) {\n const mediaType = localTrack.type;\n\n // No need to set max bitrates on the streams in the following cases.\n // 1. When an audio track has been replaced.\n // 2. When a 'camera' track is replaced in plan-b mode, since its a new sender.\n // 3. When the config.js option for capping the SS bitrate is not enabled.\n if ((mediaType === MediaType.AUDIO)\n || (browser.usesPlanB() && !this.options.capScreenshareBitrate)\n || (browser.usesPlanB() && localTrack.videoType === 'camera')) {\n return;\n }\n if (!this.peerconnection.getSenders) {\n logger.debug('Browser doesn\\'t support RTCRtpSender');\n\n return;\n }\n const videoType = localTrack.videoType;\n const trackId = localTrack.track.id;\n\n this.peerconnection.getSenders()\n .filter(s => s.track && s.track.id === trackId)\n .forEach(sender => {\n try {\n const parameters = sender.getParameters();\n\n if (!parameters.encodings || !parameters.encodings.length) {\n return;\n }\n logger.debug('Setting max bitrate on video stream');\n for (const encoding in parameters.encodings) {\n if (parameters.encodings.hasOwnProperty(encoding)) {\n parameters.encodings[encoding].maxBitrate\n = videoType === 'desktop' && browser.usesPlanB()\n ? DESKSTOP_SHARE_RATE\n\n // In unified plan, simulcast for SS is on by default.\n // When simulcast is disabled through a config.js option,\n // we cap the bitrate on desktop and camera tracks to 2500 Kbps.\n : this.isSimulcastOn()\n ? this.tpcUtils.simulcastEncodings[encoding].maxBitrate\n : MAX_BITRATE;\n }\n }\n sender.setParameters(parameters);\n } catch (err) {\n logger.error('Browser does not support getParameters/setParamters '\n + 'or setting max bitrate on the encodings: ', err);\n }\n });\n};\n\nTraceablePeerConnection.prototype.setRemoteDescription = function(description) {\n this.trace('setRemoteDescription::preTransform', dumpSDP(description));\n\n if (browser.usesPlanB()) {\n // TODO the focus should squeze or explode the remote simulcast\n // eslint-disable-next-line no-param-reassign\n description = this.simulcast.mungeRemoteDescription(description);\n this.trace(\n 'setRemoteDescription::postTransform (simulcast)',\n dumpSDP(description));\n\n if (this.options.preferH264) {\n const parsedSdp = transform.parse(description.sdp);\n const videoMLine = parsedSdp.media.find(m => m.type === 'video');\n\n SDPUtil.preferVideoCodec(videoMLine, 'h264');\n\n // eslint-disable-next-line no-param-reassign\n description = new RTCSessionDescription({\n type: description.type,\n sdp: transform.write(parsedSdp)\n });\n }\n\n // eslint-disable-next-line no-param-reassign\n description = normalizePlanB(description);\n } else {\n const currentDescription = this.peerconnection.remoteDescription;\n\n // eslint-disable-next-line no-param-reassign\n description = this.interop.toUnifiedPlan(description, currentDescription);\n this.trace(\n 'setRemoteDescription::postTransform (Unified)',\n dumpSDP(description));\n\n if (this.isSimulcastOn()) {\n // eslint-disable-next-line no-param-reassign\n description = this.simulcast.mungeRemoteDescription(description);\n\n // eslint-disable-next-line no-param-reassign\n description = this.tpcUtils._insertUnifiedPlanSimulcastReceive(description);\n this.trace(\n 'setRemoteDescription::postTransform (sim receive)',\n dumpSDP(description));\n\n // eslint-disable-next-line no-param-reassign\n description = this.tpcUtils._ensureCorrectOrderOfSsrcs(description);\n }\n }\n\n return new Promise((resolve, reject) => {\n this.peerconnection.setRemoteDescription(description)\n .then(() => {\n this.trace('setRemoteDescriptionOnSuccess');\n const remoteUfrag = SDPUtil.getUfrag(description.sdp);\n\n if (remoteUfrag !== this.remoteUfrag) {\n this.remoteUfrag = remoteUfrag;\n this.eventEmitter.emit(\n RTCEvents.REMOTE_UFRAG_CHANGED, this, remoteUfrag);\n }\n resolve();\n }, err => {\n this.trace('setRemoteDescriptionOnFailure', err);\n this.eventEmitter.emit(\n RTCEvents.SET_REMOTE_DESCRIPTION_FAILED,\n err,\n this);\n reject(err);\n });\n });\n};\n\n/**\n * Enables/disables video media transmission on this peer connection. When\n * disabled the SDP video media direction in the local SDP will be adjusted to\n * 'inactive' which means that no data will be sent nor accepted, but\n * the connection should be kept alive.\n * @param {boolean} active true to enable video media transmission or\n * false to disable. If the value is not a boolean the call will have\n * no effect.\n * @return {boolean} true if the value has changed and sRD/sLD cycle\n * needs to be executed in order for the changes to take effect or\n * false if the given value was the same as the previous one.\n * @public\n */\nTraceablePeerConnection.prototype.setVideoTransferActive = function(active) {\n logger.debug(`${this} video transfer active: ${active}`);\n if (browser.usesUnifiedPlan()) {\n return this.tpcUtils.setVideoTransferActive(active);\n }\n const changed = this.videoTransferActive !== active;\n\n this.videoTransferActive = active;\n\n return changed;\n};\n\n/**\n * Sends DTMF tones if possible.\n *\n * @param {string} tones - The DTMF tones string as defined by {@code RTCDTMFSender.insertDTMF}, 'tones' argument.\n * @param {number} duration - The amount of time in milliseconds that each DTMF should last. It's 200ms by default.\n * @param {number} interToneGap - The length of time in miliseconds to wait between tones. It's 200ms by default.\n *\n * @returns {void}\n */\nTraceablePeerConnection.prototype.sendTones = function(tones, duration = 200, interToneGap = 200) {\n if (!this._dtmfSender) {\n if (this.peerconnection.getSenders) {\n const rtpSender = this.peerconnection.getSenders().find(s => s.dtmf);\n\n this._dtmfSender = rtpSender && rtpSender.dtmf;\n this._dtmfSender && logger.info(`${this} initialized DTMFSender using getSenders`);\n }\n\n if (!this._dtmfSender) {\n const localAudioTrack = Array.from(this.localTracks.values()).find(t => t.isAudioTrack());\n\n if (this.peerconnection.createDTMFSender && localAudioTrack) {\n this._dtmfSender = this.peerconnection.createDTMFSender(localAudioTrack.getTrack());\n }\n this._dtmfSender && logger.info(`${this} initialized DTMFSender using deprecated createDTMFSender`);\n }\n\n if (this._dtmfSender) {\n this._dtmfSender.ontonechange = this._onToneChange.bind(this);\n }\n }\n\n if (this._dtmfSender) {\n if (this._dtmfSender.toneBuffer) {\n this._dtmfTonesQueue.push({\n tones,\n duration,\n interToneGap\n });\n\n return;\n }\n\n this._dtmfSender.insertDTMF(tones, duration, interToneGap);\n } else {\n logger.warn(`${this} sendTones - failed to select DTMFSender`);\n }\n};\n\n/**\n * Callback ivoked by {@code this._dtmfSender} when it has finished playing\n * a single tone.\n *\n * @param {Object} event - The tonechange event which indicates what characters\n * are left to be played for the current tone.\n * @private\n * @returns {void}\n */\nTraceablePeerConnection.prototype._onToneChange = function(event) {\n // An empty event.tone indicates the current tones have finished playing.\n // Automatically start playing any queued tones on finish.\n if (this._dtmfSender && event.tone === '' && this._dtmfTonesQueue.length) {\n const { tones, duration, interToneGap } = this._dtmfTonesQueue.shift();\n\n this._dtmfSender.insertDTMF(tones, duration, interToneGap);\n }\n};\n\n/**\n * Makes the underlying TraceablePeerConnection generate new SSRC for\n * the recvonly video stream.\n */\nTraceablePeerConnection.prototype.generateRecvonlySsrc = function() {\n const newSSRC = SDPUtil.generateSsrc();\n\n logger.info(`${this} generated new recvonly SSRC: ${newSSRC}`);\n this.sdpConsistency.setPrimarySsrc(newSSRC);\n};\n\n/**\n * Makes the underlying TraceablePeerConnection forget the current primary video\n * SSRC.\n */\nTraceablePeerConnection.prototype.clearRecvonlySsrc = function() {\n logger.info('Clearing primary video SSRC!');\n this.sdpConsistency.clearVideoSsrcCache();\n};\n\n/**\n * Closes underlying WebRTC PeerConnection instance and removes all remote\n * tracks by emitting {@link RTCEvents.REMOTE_TRACK_REMOVED} for each one of\n * them.\n */\nTraceablePeerConnection.prototype.close = function() {\n this.trace('stop');\n\n // Off SignalingEvents\n this.signalingLayer.off(\n SignalingEvents.PEER_MUTED_CHANGED, this._peerMutedChanged);\n this.signalingLayer.off(\n SignalingEvents.PEER_VIDEO_TYPE_CHANGED, this._peerVideoTypeChanged);\n\n for (const peerTracks of this.remoteTracks.values()) {\n for (const remoteTrack of peerTracks.values()) {\n this._removeRemoteTrack(remoteTrack);\n }\n }\n this.remoteTracks.clear();\n\n this._addedStreams = [];\n\n this._dtmfSender = null;\n this._dtmfTonesQueue = [];\n\n if (!this.rtc._removePeerConnection(this)) {\n logger.error('RTC._removePeerConnection returned false');\n }\n if (this.statsinterval !== null) {\n window.clearInterval(this.statsinterval);\n this.statsinterval = null;\n }\n logger.info(`Closing ${this}...`);\n this.peerconnection.close();\n};\n\n/**\n * Modifies the values of the setup attributes (defined by\n * {@link http://tools.ietf.org/html/rfc4145#section-4}) of a specific SDP\n * answer in order to overcome a delay of 1 second in the connection\n * establishment between some devices and Videobridge.\n *\n * @param {SDP} offer - the SDP offer to which the specified SDP answer is\n * being prepared to respond\n * @param {SDP} answer - the SDP to modify\n * @private\n */\nconst _fixAnswerRFC4145Setup = function(offer, answer) {\n if (!(browser.isChromiumBased() || browser.isReactNative())) {\n // It looks like Firefox doesn't agree with the fix (at least in its\n // current implementation) because it effectively remains active even\n // after we tell it to become passive. Apart from Firefox which I tested\n // after the fix was deployed, I tested Chrome only. In order to prevent\n // issues with other browsers, limit the fix to known devices for the\n // time being.\n return;\n }\n\n // XXX Videobridge is the (SDP) offerer and WebRTC (e.g. Chrome) is the\n // answerer (as orchestrated by Jicofo). In accord with\n // http://tools.ietf.org/html/rfc5245#section-5.2 and because both peers\n // are ICE FULL agents, Videobridge will take on the controlling role and\n // WebRTC will take on the controlled role. In accord with\n // https://tools.ietf.org/html/rfc5763#section-5, Videobridge will use the\n // setup attribute value of setup:actpass and WebRTC will be allowed to\n // choose either the setup attribute value of setup:active or\n // setup:passive. Chrome will by default choose setup:active because it is\n // RECOMMENDED by the respective RFC since setup:passive adds additional\n // latency. The case of setup:active allows WebRTC to send a DTLS\n // ClientHello as soon as an ICE connectivity check of its succeeds.\n // Unfortunately, Videobridge will be unable to respond immediately because\n // may not have WebRTC's answer or may have not completed the ICE\n // connectivity establishment. Even more unfortunate is that in the\n // described scenario Chrome's DTLS implementation will insist on\n // retransmitting its ClientHello after a second (the time is in accord\n // with the respective RFC) and will thus cause the whole connection\n // establishment to exceed at least 1 second. To work around Chrome's\n // idiosyncracy, don't allow it to send a ClientHello i.e. change its\n // default choice of setup:active to setup:passive.\n if (offer && answer\n && offer.media && answer.media\n && offer.media.length === answer.media.length) {\n answer.media.forEach((a, i) => {\n if (SDPUtil.findLine(\n offer.media[i],\n 'a=setup:actpass',\n offer.session)) {\n answer.media[i]\n = a.replace(/a=setup:active/g, 'a=setup:passive');\n }\n });\n answer.raw = answer.session + answer.media.join('');\n }\n};\n\nTraceablePeerConnection.prototype.createAnswer = function(constraints) {\n return this._createOfferOrAnswer(false /* answer */, constraints);\n};\n\nTraceablePeerConnection.prototype.createOffer = function(constraints) {\n return this._createOfferOrAnswer(true /* offer */, constraints);\n};\n\n/**\n * Checks if a camera track has been added to the peerconnection\n * @param {TraceablePeerConnection} peerConnection\n * @return {boolean} true if the peerconnection has\n * a camera track for its video source false otherwise.\n */\nfunction hasCameraTrack(peerConnection) {\n return peerConnection.getLocalTracks()\n .some(t => t.videoType === 'camera');\n}\n\nTraceablePeerConnection.prototype._createOfferOrAnswer = function(\n isOffer,\n constraints) {\n const logName = isOffer ? 'Offer' : 'Answer';\n\n this.trace(`create${logName}`, JSON.stringify(constraints, null, ' '));\n\n const handleSuccess = (resultSdp, resolveFn, rejectFn) => {\n try {\n this.trace(\n `create${logName}OnSuccess::preTransform`, dumpSDP(resultSdp));\n\n if (browser.usesPlanB()) {\n // If there are no local video tracks, then a \"recvonly\"\n // SSRC needs to be generated\n if (!this.hasAnyTracksOfType(MediaType.VIDEO)\n && !this.sdpConsistency.hasPrimarySsrcCached()) {\n this.generateRecvonlySsrc();\n }\n\n // eslint-disable-next-line no-param-reassign\n resultSdp = new RTCSessionDescription({\n type: resultSdp.type,\n sdp: this.sdpConsistency.makeVideoPrimarySsrcsConsistent(\n resultSdp.sdp)\n });\n\n this.trace(\n `create${logName}OnSuccess::postTransform `\n + '(make primary audio/video ssrcs consistent)',\n dumpSDP(resultSdp));\n }\n\n // configure simulcast for camera tracks always and for\n // desktop tracks only when the testing flag for maxbitrates\n // in config.js is disabled.\n if (this.isSimulcastOn() && browser.usesSdpMungingForSimulcast()\n && (!this.options.capScreenshareBitrate\n || (this.options.capScreenshareBitrate && hasCameraTrack(this)))) {\n // eslint-disable-next-line no-param-reassign\n resultSdp = this.simulcast.mungeLocalDescription(resultSdp);\n this.trace(\n `create${logName}`\n + 'OnSuccess::postTransform (simulcast)',\n dumpSDP(resultSdp));\n }\n\n if (!this.options.disableRtx && browser.supportsRtx()) {\n // eslint-disable-next-line no-param-reassign\n resultSdp = new RTCSessionDescription({\n type: resultSdp.type,\n sdp: this.rtxModifier.modifyRtxSsrcs(resultSdp.sdp)\n });\n\n this.trace(\n `create${logName}`\n + 'OnSuccess::postTransform (rtx modifier)',\n dumpSDP(resultSdp));\n }\n\n // Fix the setup attribute (see _fixAnswerRFC4145Setup for\n // details)\n if (!isOffer) {\n const remoteDescription\n = new SDP(this.remoteDescription.sdp);\n const localDescription = new SDP(resultSdp.sdp);\n\n _fixAnswerRFC4145Setup(remoteDescription, localDescription);\n\n // eslint-disable-next-line no-param-reassign\n resultSdp = new RTCSessionDescription({\n type: resultSdp.type,\n sdp: localDescription.raw\n });\n }\n\n const ssrcMap = extractSSRCMap(resultSdp);\n\n logger.debug('Got local SSRCs MAP: ', ssrcMap);\n this._processLocalSSRCsMap(ssrcMap);\n\n resolveFn(resultSdp);\n } catch (e) {\n this.trace(`create${logName}OnError`, e);\n this.trace(`create${logName}OnError`, dumpSDP(resultSdp));\n logger.error(`create${logName}OnError`, e, dumpSDP(resultSdp));\n\n rejectFn(e);\n }\n };\n\n const handleFailure = (err, rejectFn) => {\n this.trace(`create${logName}OnFailure`, err);\n const eventType\n = isOffer\n ? RTCEvents.CREATE_OFFER_FAILED\n : RTCEvents.CREATE_ANSWER_FAILED;\n\n this.eventEmitter.emit(eventType, err, this);\n\n rejectFn(err);\n };\n\n return new Promise((resolve, reject) => {\n let oaPromise;\n\n if (isOffer) {\n oaPromise = this.peerconnection.createOffer(constraints);\n } else {\n oaPromise = this.peerconnection.createAnswer(constraints);\n }\n\n oaPromise\n .then(\n sdp => handleSuccess(sdp, resolve, reject),\n error => handleFailure(error, reject));\n });\n};\n\n/**\n * Extract primary SSRC from given {@link TrackSSRCInfo} object.\n * @param {TrackSSRCInfo} ssrcObj\n * @return {number|null} the primary SSRC or null\n */\nTraceablePeerConnection.prototype._extractPrimarySSRC = function(ssrcObj) {\n if (ssrcObj && ssrcObj.groups && ssrcObj.groups.length) {\n return ssrcObj.groups[0].ssrcs[0];\n } else if (ssrcObj && ssrcObj.ssrcs && ssrcObj.ssrcs.length) {\n return ssrcObj.ssrcs[0];\n }\n\n return null;\n};\n\n/**\n * Goes over the SSRC map extracted from the latest local description and tries\n * to match them with the local tracks (by MSID). Will update the values\n * currently stored in the {@link TraceablePeerConnection.localSSRCs} map.\n * @param {Map} ssrcMap\n * @private\n */\nTraceablePeerConnection.prototype._processLocalSSRCsMap = function(ssrcMap) {\n for (const track of this.localTracks.values()) {\n const trackMSID = track.storedMSID;\n\n if (ssrcMap.has(trackMSID)) {\n const newSSRC = ssrcMap.get(trackMSID);\n\n if (!newSSRC) {\n logger.error(`No SSRC found for: ${trackMSID} in ${this}`);\n\n return;\n }\n const oldSSRC = this.localSSRCs.get(track.rtcId);\n const newSSRCNum = this._extractPrimarySSRC(newSSRC);\n const oldSSRCNum = this._extractPrimarySSRC(oldSSRC);\n\n // eslint-disable-next-line no-negated-condition\n if (newSSRCNum !== oldSSRCNum) {\n if (oldSSRCNum === null) {\n logger.info(\n `Storing new local SSRC for ${track} in ${this}`,\n newSSRC);\n } else {\n logger.error(\n `Overwriting SSRC for ${track} ${trackMSID} in ${this\n } with: `, newSSRC);\n }\n this.localSSRCs.set(track.rtcId, newSSRC);\n\n this.eventEmitter.emit(\n RTCEvents.LOCAL_TRACK_SSRC_UPDATED, track, newSSRCNum);\n } else {\n logger.debug(\n `The local SSRC(${newSSRCNum}) for ${track} ${trackMSID}`\n + `is still up to date in ${this}`);\n }\n } else if (!track.isVideoTrack() && !track.isMuted()) {\n // It is normal to find no SSRCs for a muted video track in\n // the local SDP as the recv-only SSRC is no longer munged in.\n // So log the warning only if it's not a muted video track.\n logger.warn(`No SSRCs found in the local SDP for ${track} MSID: ${trackMSID} in ${this}`);\n }\n }\n};\n\nTraceablePeerConnection.prototype.addIceCandidate = function(candidate) {\n this.trace('addIceCandidate', JSON.stringify({\n candidate: candidate.candidate,\n sdpMid: candidate.sdpMid,\n sdpMLineIndex: candidate.sdpMLineIndex,\n usernameFragment: candidate.usernameFragment\n }, null, ' '));\n\n return this.peerconnection.addIceCandidate(candidate);\n};\n\n/**\n * Obtains call-related stats from the peer connection.\n *\n * @param {Function} callback - The function to invoke after successfully\n * obtaining stats.\n * @param {Function} errback - The function to invoke after failing to obtain\n * stats.\n * @returns {void}\n */\nTraceablePeerConnection.prototype.getStats = function(callback, errback) {\n // TODO (brian): After moving all browsers to adapter, check if adapter is\n // accounting for different getStats apis, making the browser-checking-if\n // unnecessary.\n if (browser.isSafari() || browser.isFirefox() || browser.isReactNative()) {\n // uses the new Promise based getStats\n this.peerconnection.getStats()\n .then(callback)\n .catch(errback || (() => {\n\n // Making sure that getStats won't fail if error callback is\n // not passed.\n }));\n } else {\n this.peerconnection.getStats(callback);\n }\n};\n\n/**\n * Generates and stores new SSRC info object for given local track.\n * The method should be called only for a video track being added to this TPC\n * in the muted state (given that the current browser uses this strategy).\n * @param {JitsiLocalTrack} track\n * @return {TPCSSRCInfo}\n */\nTraceablePeerConnection.prototype.generateNewStreamSSRCInfo = function(track) {\n const rtcId = track.rtcId;\n let ssrcInfo = this._getSSRC(rtcId);\n\n if (ssrcInfo) {\n logger.error(`Will overwrite local SSRCs for track ID: ${rtcId}`);\n }\n\n // configure simulcast for camera tracks always and for\n // desktop tracks only when the testing flag for maxbitrates\n // in config.js is disabled.\n if (this.isSimulcastOn()\n && (!this.options.capScreenshareBitrate\n || (this.options.capScreenshareBitrate && hasCameraTrack(this)))) {\n ssrcInfo = {\n ssrcs: [],\n groups: []\n };\n for (let i = 0; i < SIM_LAYER_RIDS.length; i++) {\n ssrcInfo.ssrcs.push(SDPUtil.generateSsrc());\n }\n ssrcInfo.groups.push({\n ssrcs: ssrcInfo.ssrcs.slice(),\n semantics: 'SIM'\n });\n } else {\n ssrcInfo = {\n ssrcs: [ SDPUtil.generateSsrc() ],\n groups: []\n };\n }\n if (!this.options.disableRtx && browser.supportsRtx()) {\n // Specifically use a for loop here because we'll\n // be adding to the list we're iterating over, so we\n // only want to iterate through the items originally\n // on the list\n const currNumSsrcs = ssrcInfo.ssrcs.length;\n\n for (let i = 0; i < currNumSsrcs; ++i) {\n const primarySsrc = ssrcInfo.ssrcs[i];\n const rtxSsrc = SDPUtil.generateSsrc();\n\n ssrcInfo.ssrcs.push(rtxSsrc);\n ssrcInfo.groups.push({\n ssrcs: [ primarySsrc, rtxSsrc ],\n semantics: 'FID'\n });\n }\n }\n ssrcInfo.msid = track.storedMSID;\n this.localSSRCs.set(rtcId, ssrcInfo);\n\n return ssrcInfo;\n};\n\nconst handleLayerSuspension = function(peerConnection, isSelected) {\n if (!peerConnection.getSenders) {\n logger.debug('Browser doesn\\'t support RTPSender');\n\n return;\n }\n\n const videoSender = peerConnection.getSenders()\n .find(sender => sender.track.kind === 'video');\n\n if (!videoSender) {\n logger.warn('handleLayerSuspension unable to find video sender');\n\n return;\n }\n if (!videoSender.getParameters) {\n logger.debug('Browser doesn\\'t support RTPSender parameters');\n\n return;\n }\n const parameters = videoSender.getParameters();\n\n if (isSelected) {\n logger.debug('Currently selected, enabling all sim layers');\n\n // Make sure all encodings are enabled\n parameters.encodings.forEach(e => {\n e.active = true;\n });\n } else {\n logger.debug('Not currently selected, disabling upper layers');\n\n // Turn off the upper simulcast layers\n [ 1, 2 ].forEach(simIndex => {\n if (parameters.encodings[simIndex]) {\n parameters.encodings[simIndex].active = false;\n }\n });\n }\n videoSender.setParameters(parameters);\n};\n\n/**\n * Set whether or not the endpoint is 'selected' by other endpoints, meaning\n * it appears on their main stage\n */\nTraceablePeerConnection.prototype.setIsSelected = function(isSelected) {\n if (this.options.enableLayerSuspension) {\n logger.debug('Layer suspension enabled,'\n + `currently selected? ${isSelected}`);\n handleLayerSuspension(this.peerconnection, isSelected);\n }\n};\n\n/**\n * Creates a text representation of this TraceablePeerConnection\n * instance.\n * @return {string}\n */\nTraceablePeerConnection.prototype.toString = function() {\n return `TPC[${this.id},p2p:${this.isP2P}]`;\n};\n", "import { createTtfmEvent } from '../../service/statistics/AnalyticsEvents';\nimport JitsiTrack from './JitsiTrack';\nimport * as JitsiTrackEvents from '../../JitsiTrackEvents';\nimport Statistics from '../statistics/statistics';\n\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\nconst RTCEvents = require('../../service/RTC/RTCEvents');\n\nlet ttfmTrackerAudioAttached = false;\nlet ttfmTrackerVideoAttached = false;\n\n/**\n * List of container events that we are going to process. _onContainerEventHandler will be added as listener to the\n * container for every event in the list.\n */\nconst containerEvents = [\n 'abort', 'canplay', 'canplaythrough', 'emptied', 'ended', 'error', 'loadeddata', 'loadedmetadata', 'loadstart',\n 'pause', 'play', 'playing', 'ratechange', 'stalled', 'suspend', 'waiting'\n];\n\n/* eslint-disable max-params */\n\n/**\n * Represents a single media track (either audio or video).\n */\nexport default class JitsiRemoteTrack extends JitsiTrack {\n /**\n * Creates new JitsiRemoteTrack instance.\n * @param {RTC} rtc the RTC service instance.\n * @param {JitsiConference} conference the conference to which this track\n * belongs to\n * @param {string} ownerEndpointId the endpoint ID of the track owner\n * @param {MediaStream} stream WebRTC MediaStream, parent of the track\n * @param {MediaStreamTrack} track underlying WebRTC MediaStreamTrack for\n * the new JitsiRemoteTrack\n * @param {MediaType} mediaType the type of the media\n * @param {VideoType} videoType the type of the video if applicable\n * @param {number} ssrc the SSRC number of the Media Stream\n * @param {boolean} muted the initial muted state\n * @param {boolean} isP2P indicates whether or not this track belongs to a\n * P2P session\n * @throws {TypeError} if ssrc is not a number.\n * @constructor\n */\n constructor(\n rtc,\n conference,\n ownerEndpointId,\n stream,\n track,\n mediaType,\n videoType,\n ssrc,\n muted,\n isP2P) {\n super(\n conference,\n stream,\n track,\n () => {\n // Nothing to do if the track is inactive.\n },\n mediaType,\n videoType);\n this.rtc = rtc;\n\n // Prevent from mixing up type of SSRC which should be a number\n if (typeof ssrc !== 'number') {\n throw new TypeError(`SSRC ${ssrc} is not a number`);\n }\n this.ssrc = ssrc;\n this.ownerEndpointId = ownerEndpointId;\n this.muted = muted;\n this.isP2P = isP2P;\n\n logger.debug(`New remote track added: ${this}`);\n\n // we want to mark whether the track has been ever muted\n // to detect ttfm events for startmuted conferences, as it can\n // significantly increase ttfm values\n this.hasBeenMuted = muted;\n\n // Bind 'onmute' and 'onunmute' event handlers\n if (this.rtc && this.track) {\n this._bindTrackHandlers();\n }\n this._containerHandlers = {};\n containerEvents.forEach(event => {\n this._containerHandlers[event] = this._containerEventHandler.bind(this, event);\n });\n }\n\n /* eslint-enable max-params */\n /**\n * Attaches the track handlers.\n *\n * @returns {void}\n */\n _bindTrackHandlers() {\n this.track.addEventListener('mute', () => this._onTrackMute());\n this.track.addEventListener('unmute', () => this._onTrackUnmute());\n this.track.addEventListener('ended', () => {\n logger.debug(`\"onended\" event(${Date.now()}): ${this}`);\n });\n }\n\n /**\n * Callback invoked when the track is muted. Emits an event notifying\n * listeners of the mute event.\n *\n * @private\n * @returns {void}\n */\n _onTrackMute() {\n logger.debug(`\"onmute\" event(${Date.now()}): ${this}`);\n\n this.rtc.eventEmitter.emit(RTCEvents.REMOTE_TRACK_MUTE, this);\n }\n\n /**\n * Callback invoked when the track is unmuted. Emits an event notifying\n * listeners of the mute event.\n *\n * @private\n * @returns {void}\n */\n _onTrackUnmute() {\n logger.debug(`\"onunmute\" event(${Date.now()}): ${this}`);\n\n this.rtc.eventEmitter.emit(RTCEvents.REMOTE_TRACK_UNMUTE, this);\n }\n\n /**\n * Sets current muted status and fires an events for the change.\n * @param value the muted status.\n */\n setMute(value) {\n if (this.muted === value) {\n return;\n }\n\n if (value) {\n this.hasBeenMuted = true;\n }\n\n // we can have a fake video stream\n if (this.stream) {\n this.stream.muted = value;\n }\n\n this.muted = value;\n this.emit(JitsiTrackEvents.TRACK_MUTE_CHANGED, this);\n }\n\n /**\n * Returns the current muted status of the track.\n * @returns {boolean|*|JitsiRemoteTrack.muted} true if the track is\n * muted and false otherwise.\n */\n isMuted() {\n return this.muted;\n }\n\n /**\n * Returns the participant id which owns the track.\n *\n * @returns {string} the id of the participants. It corresponds to the\n * Colibri endpoint id/MUC nickname in case of Jitsi-meet.\n */\n getParticipantId() {\n return this.ownerEndpointId;\n }\n\n /**\n * Return false;\n */\n isLocal() {\n return false;\n }\n\n /**\n * Returns the synchronization source identifier (SSRC) of this remote\n * track.\n *\n * @returns {number} the SSRC of this remote track.\n */\n getSSRC() {\n return this.ssrc;\n }\n\n /**\n * Changes the video type of the track.\n *\n * @param {string} type - The new video type(\"camera\", \"desktop\").\n */\n _setVideoType(type) {\n if (this.videoType === type) {\n return;\n }\n this.videoType = type;\n this.emit(JitsiTrackEvents.TRACK_VIDEOTYPE_CHANGED, type);\n }\n\n /**\n * Handles track play events.\n */\n _playCallback() {\n const type = this.isVideoTrack() ? 'video' : 'audio';\n\n const now = window.performance.now();\n\n console.log(`(TIME) Render ${type}:\\t`, now);\n this.conference.getConnectionTimes()[`${type}.render`] = now;\n\n // The conference can be started without calling GUM\n // FIXME if there would be a module for connection times this kind\n // of logic (gumDuration or ttfm) should end up there\n const gumStart = window.connectionTimes['obtainPermissions.start'];\n const gumEnd = window.connectionTimes['obtainPermissions.end'];\n const gumDuration\n = !isNaN(gumEnd) && !isNaN(gumStart) ? gumEnd - gumStart : 0;\n\n // Subtract the muc.joined-to-session-initiate duration because jicofo\n // waits until there are 2 participants to start Jingle sessions.\n const ttfm = now\n - (this.conference.getConnectionTimes()['session.initiate']\n - this.conference.getConnectionTimes()['muc.joined'])\n - gumDuration;\n\n this.conference.getConnectionTimes()[`${type}.ttfm`] = ttfm;\n console.log(`(TIME) TTFM ${type}:\\t`, ttfm);\n\n Statistics.sendAnalytics(createTtfmEvent(\n {\n 'media_type': type,\n muted: this.hasBeenMuted,\n value: ttfm\n }));\n\n }\n\n /**\n * Attach time to first media tracker only if there is conference and only\n * for the first element.\n * @param container the HTML container which can be 'video' or 'audio'\n * element.\n * @private\n */\n _attachTTFMTracker(container) {\n if ((ttfmTrackerAudioAttached && this.isAudioTrack())\n || (ttfmTrackerVideoAttached && this.isVideoTrack())) {\n return;\n }\n\n if (this.isAudioTrack()) {\n ttfmTrackerAudioAttached = true;\n }\n if (this.isVideoTrack()) {\n ttfmTrackerVideoAttached = true;\n }\n\n container.addEventListener('canplay', this._playCallback.bind(this));\n }\n\n /**\n * Called when the track has been attached to a new container.\n *\n * @param {HTMLElement} container the HTML container which can be 'video' or\n * 'audio' element.\n * @private\n */\n _onTrackAttach(container) {\n logger.debug(`Track has been attached to a container: ${this}`);\n\n containerEvents.forEach(event => {\n container.addEventListener(event, this._containerHandlers[event]);\n });\n }\n\n /**\n * Called when the track has been detached from a container.\n *\n * @param {HTMLElement} container the HTML container which can be 'video' or\n * 'audio' element.\n * @private\n */\n _onTrackDetach(container) {\n logger.debug(`Track has been detached from a container: ${this}`);\n\n containerEvents.forEach(event => {\n container.removeEventListener(event, this._containerHandlers[event]);\n });\n }\n\n /**\n * An event handler for events triggered by the attached container.\n *\n * @param {string} type - The type of the event.\n */\n _containerEventHandler(type) {\n logger.debug(`${type} handler was called for a container with attached ${this}`);\n }\n\n /**\n * Returns a string with a description of the current status of the track.\n *\n * @returns {string}\n */\n _getStatus() {\n const { enabled, muted, readyState } = this.track;\n\n return `readyState: ${readyState}, muted: ${muted}, enabled: ${enabled}`;\n }\n\n /**\n * Creates a text representation of this remote track instance.\n * @return {string}\n */\n toString() {\n return `RemoteTrack[userID: ${this.getParticipantId()}, type: ${this.getType()}, ssrc: ${\n this.getSSRC()}, p2p: ${this.isP2P}, status: ${this._getStatus()}]`;\n }\n}\n", "/* global __filename */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport { SdpTransformWrap } from '../xmpp/SdpTransformUtil';\n\nconst logger = getLogger(__filename);\n\n/**\n * Fakes local SDP exposed to {@link JingleSessionPC} through the local\n * description getter. Modifies the SDP, so that it will contain muted local\n * video tracks description, even though their underlying {MediaStreamTrack}s\n * are no longer in the WebRTC peerconnection. That prevents from SSRC updates\n * being sent to Jicofo/remote peer and prevents sRD/sLD cycle on the remote\n * side.\n */\nexport default class LocalSdpMunger {\n\n /**\n * Creates new LocalSdpMunger instance.\n *\n * @param {TraceablePeerConnection} tpc\n */\n constructor(tpc) {\n this.tpc = tpc;\n }\n\n /**\n * Makes sure that muted local video tracks associated with the parent\n * {@link TraceablePeerConnection} are described in the local SDP. It's done\n * in order to prevent from sending 'source-remove'/'source-add' Jingle\n * notifications when local video track is muted (MediaStream is\n * removed from the peerconnection).\n *\n * NOTE 1 video track is assumed\n *\n * @param {SdpTransformWrap} transformer the transformer instance which will\n * be used to process the SDP.\n * @return {boolean} true if there were any modifications to\n * the SDP wrapped by transformer.\n * @private\n */\n _addMutedLocalVideoTracksToSDP(transformer) {\n // Go over each video tracks and check if the SDP has to be changed\n const localVideos = this.tpc.getLocalTracks(MediaType.VIDEO);\n\n if (!localVideos.length) {\n return false;\n } else if (localVideos.length !== 1) {\n logger.error(\n `${this.tpc} there is more than 1 video track ! `\n + 'Strange things may happen !', localVideos);\n }\n\n const videoMLine = transformer.selectMedia('video');\n\n if (!videoMLine) {\n logger.debug(\n `${this.tpc} unable to hack local video track SDP`\n + '- no \"video\" media');\n\n return false;\n }\n\n let modified = false;\n\n for (const videoTrack of localVideos) {\n const muted = videoTrack.isMuted();\n const mediaStream = videoTrack.getOriginalStream();\n\n // During the mute/unmute operation there are periods of time when\n // the track's underlying MediaStream is not added yet to\n // the PeerConnection. The SDP needs to be munged in such case.\n const isInPeerConnection\n = mediaStream && this.tpc.isMediaStreamInPc(mediaStream);\n const shouldFakeSdp = muted || !isInPeerConnection;\n\n logger.debug(\n `${this.tpc} ${videoTrack} muted: ${\n muted}, is in PeerConnection: ${\n isInPeerConnection} => should fake sdp ? : ${\n shouldFakeSdp}`);\n\n if (!shouldFakeSdp) {\n continue; // eslint-disable-line no-continue\n }\n\n // Inject removed SSRCs\n const requiredSSRCs\n = this.tpc.isSimulcastOn()\n ? this.tpc.simulcast.ssrcCache\n : [ this.tpc.sdpConsistency.cachedPrimarySsrc ];\n\n if (!requiredSSRCs.length) {\n logger.error(\n `No SSRCs stored for: ${videoTrack} in ${this.tpc}`);\n\n continue; // eslint-disable-line no-continue\n }\n\n modified = true;\n\n // We need to fake sendrecv.\n // NOTE the SDP produced here goes only to Jicofo and is never set\n // as localDescription. That's why\n // TraceablePeerConnection.mediaTransferActive is ignored here.\n videoMLine.direction = 'sendrecv';\n\n // Check if the recvonly has MSID\n const primarySSRC = requiredSSRCs[0];\n\n // FIXME The cname could come from the stream, but may turn out to\n // be too complex. It is fine to come up with any value, as long as\n // we only care about the actual SSRC values when deciding whether\n // or not an update should be sent.\n const primaryCname = `injected-${primarySSRC}`;\n\n for (const ssrcNum of requiredSSRCs) {\n // Remove old attributes\n videoMLine.removeSSRC(ssrcNum);\n\n // Inject\n logger.debug(\n `${this.tpc} injecting video SSRC: ${ssrcNum} for ${\n videoTrack}`);\n videoMLine.addSSRCAttribute({\n id: ssrcNum,\n attribute: 'cname',\n value: primaryCname\n });\n videoMLine.addSSRCAttribute({\n id: ssrcNum,\n attribute: 'msid',\n value: videoTrack.storedMSID\n });\n }\n if (requiredSSRCs.length > 1) {\n const group = {\n ssrcs: requiredSSRCs.join(' '),\n semantics: 'SIM'\n };\n\n if (!videoMLine.findGroup(group.semantics, group.ssrcs)) {\n // Inject the group\n logger.debug(\n `${this.tpc} injecting SIM group for ${videoTrack}`,\n group);\n videoMLine.addSSRCGroup(group);\n }\n }\n\n // Insert RTX\n // FIXME in P2P RTX is used by Chrome regardless of config option\n // status. Because of that 'source-remove'/'source-add'\n // notifications are still sent to remove/add RTX SSRC and FID group\n if (!this.tpc.options.disableRtx) {\n this.tpc.rtxModifier.modifyRtxSsrcs2(videoMLine);\n }\n }\n\n return modified;\n }\n\n /**\n * Modifies 'cname', 'msid', 'label' and 'mslabel' by appending\n * the id of {@link LocalSdpMunger#tpc} at the end, preceding by a dash\n * sign.\n *\n * @param {MLineWrap} mediaSection - The media part (audio or video) of the\n * session description which will be modified in place.\n * @returns {void}\n * @private\n */\n _transformMediaIdentifiers(mediaSection) {\n const pcId = this.tpc.id;\n\n for (const ssrcLine of mediaSection.ssrcs) {\n switch (ssrcLine.attribute) {\n case 'cname':\n case 'label':\n case 'mslabel':\n ssrcLine.value = ssrcLine.value && `${ssrcLine.value}-${pcId}`;\n break;\n case 'msid': {\n if (ssrcLine.value) {\n const streamAndTrackIDs = ssrcLine.value.split(' ');\n\n if (streamAndTrackIDs.length === 2) {\n const streamId = streamAndTrackIDs[0];\n const trackId = streamAndTrackIDs[1];\n\n ssrcLine.value\n = `${streamId}-${pcId} ${trackId}-${pcId}`;\n } else {\n logger.warn(\n 'Unable to munge local MSID'\n + `- weird format detected: ${ssrcLine.value}`);\n }\n }\n break;\n }\n }\n }\n }\n\n /**\n * Maybe modifies local description to fake local video tracks SDP when\n * those are muted.\n *\n * @param {object} desc the WebRTC SDP object instance for the local\n * description.\n * @returns {RTCSessionDescription}\n */\n maybeAddMutedLocalVideoTracksToSDP(desc) {\n if (!desc) {\n throw new Error('No local description passed in.');\n }\n\n const transformer = new SdpTransformWrap(desc.sdp);\n\n if (this._addMutedLocalVideoTracksToSDP(transformer)) {\n return new RTCSessionDescription({\n type: desc.type,\n sdp: transformer.toRawSDP()\n });\n }\n\n return desc;\n }\n\n /**\n * This transformation will make sure that stream identifiers are unique\n * across all of the local PeerConnections even if the same stream is used\n * by multiple instances at the same time.\n * Each PeerConnection assigns different SSRCs to the same local\n * MediaStream, but the MSID remains the same as it's used to identify\n * the stream by the WebRTC backend. The transformation will append\n * {@link TraceablePeerConnection#id} at the end of each stream's identifier\n * (\"cname\", \"msid\", \"label\" and \"mslabel\").\n *\n * @param {RTCSessionDescription} sessionDesc - The local session\n * description (this instance remains unchanged).\n * @return {RTCSessionDescription} - Transformed local session description\n * (a modified copy of the one given as the input).\n */\n transformStreamIdentifiers(sessionDesc) {\n // FIXME similar check is probably duplicated in all other transformers\n if (!sessionDesc || !sessionDesc.sdp || !sessionDesc.type) {\n return sessionDesc;\n }\n\n const transformer = new SdpTransformWrap(sessionDesc.sdp);\n const audioMLine = transformer.selectMedia('audio');\n\n if (audioMLine) {\n this._transformMediaIdentifiers(audioMLine);\n }\n\n const videoMLine = transformer.selectMedia('video');\n\n if (videoMLine) {\n this._transformMediaIdentifiers(videoMLine);\n }\n\n return new RTCSessionDescription({\n type: sessionDesc.type,\n sdp: transformer.toRawSDP()\n });\n }\n}\n", "/* global __filename */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport { parseSecondarySSRC, SdpTransformWrap } from './SdpTransformUtil';\nimport SDPUtil from './SDPUtil';\n\nconst logger = getLogger(__filename);\n\n/**\n * Begin helper functions\n */\n/**\n * Updates or inserts the appropriate rtx information for primarySsrc with\n * the given rtxSsrc. If no rtx ssrc for primarySsrc currently exists, it will\n * add the appropriate ssrc and ssrc group lines. If primarySsrc already has\n * an rtx ssrc, the appropriate ssrc and group lines will be updated\n * @param {MLineWrap} mLine\n * @param {object} primarySsrcInfo the info (ssrc, msid & cname) for the\n * primary ssrc\n * @param {number} rtxSsrc the rtx ssrc to associate with the primary ssrc\n */\nfunction updateAssociatedRtxStream(mLine, primarySsrcInfo, rtxSsrc) {\n logger.debug(\n `Updating mline to associate ${rtxSsrc}`\n + `rtx ssrc with primary stream, ${primarySsrcInfo.id}`);\n const primarySsrc = primarySsrcInfo.id;\n const primarySsrcMsid = primarySsrcInfo.msid;\n const primarySsrcCname = primarySsrcInfo.cname;\n\n const previousRtxSSRC = mLine.getRtxSSRC(primarySsrc);\n\n if (previousRtxSSRC === rtxSsrc) {\n logger.debug(`${rtxSsrc} was already associated with ${primarySsrc}`);\n\n return;\n }\n if (previousRtxSSRC) {\n logger.debug(\n `${primarySsrc} was previously associated with rtx`\n + `${previousRtxSSRC}, removing all references to it`);\n\n // Stream already had an rtx ssrc that is different than the one given,\n // remove all trace of the old one\n mLine.removeSSRC(previousRtxSSRC);\n\n logger.debug(`groups before filtering for ${previousRtxSSRC}`);\n logger.debug(mLine.dumpSSRCGroups());\n\n mLine.removeGroupsWithSSRC(previousRtxSSRC);\n }\n mLine.addSSRCAttribute({\n id: rtxSsrc,\n attribute: 'cname',\n value: primarySsrcCname\n });\n mLine.addSSRCAttribute({\n id: rtxSsrc,\n attribute: 'msid',\n value: primarySsrcMsid\n });\n mLine.addSSRCGroup({\n semantics: 'FID',\n ssrcs: `${primarySsrc} ${rtxSsrc}`\n });\n}\n\n/**\n * End helper functions\n */\n\n/**\n * Adds any missing RTX streams for video streams\n * and makes sure that they remain consistent\n */\nexport default class RtxModifier {\n /**\n * Constructor\n */\n constructor() {\n /**\n * Map of video ssrc to corresponding RTX\n * ssrc\n */\n this.correspondingRtxSsrcs = new Map();\n }\n\n /**\n * Clear the cached map of primary video ssrcs to\n * their corresponding rtx ssrcs so that they will\n * not be used for the next call to modifyRtxSsrcs\n */\n clearSsrcCache() {\n this.correspondingRtxSsrcs.clear();\n }\n\n /**\n * Explicitly set the primary video ssrc -> rtx ssrc\n * mapping to be used in modifyRtxSsrcs\n * @param {Map} ssrcMapping a mapping of primary video\n * ssrcs to their corresponding rtx ssrcs\n */\n setSsrcCache(ssrcMapping) {\n logger.debug('Setting ssrc cache to ', ssrcMapping);\n this.correspondingRtxSsrcs = ssrcMapping;\n }\n\n /**\n * Adds RTX ssrcs for any video ssrcs that don't\n * already have them. If the video ssrc has been\n * seen before, and already had an RTX ssrc generated,\n * the same RTX ssrc will be used again.\n * @param {string} sdpStr sdp in raw string format\n */\n modifyRtxSsrcs(sdpStr) {\n const sdpTransformer = new SdpTransformWrap(sdpStr);\n const videoMLine = sdpTransformer.selectMedia('video');\n\n if (!videoMLine) {\n logger.debug(`No 'video' media found in the sdp: ${sdpStr}`);\n\n return sdpStr;\n }\n\n return this.modifyRtxSsrcs2(videoMLine)\n ? sdpTransformer.toRawSDP() : sdpStr;\n }\n\n /**\n * Does the same thing as {@link modifyRtxSsrcs}, but takes the\n * {@link MLineWrap} instance wrapping video media as an argument.\n * @param {MLineWrap} videoMLine\n * @return {boolean} true if the SDP wrapped by\n * {@link SdpTransformWrap} has been modified or false otherwise.\n */\n modifyRtxSsrcs2(videoMLine) {\n if (videoMLine.direction === 'recvonly') {\n logger.debug('RtxModifier doing nothing, video m line is recvonly');\n\n return false;\n }\n if (videoMLine.getSSRCCount() < 1) {\n logger.debug('RtxModifier doing nothing, no video ssrcs present');\n\n return false;\n }\n logger.debug('Current ssrc mapping: ', this.correspondingRtxSsrcs);\n const primaryVideoSsrcs = videoMLine.getPrimaryVideoSSRCs();\n\n logger.debug('Parsed primary video ssrcs ', primaryVideoSsrcs,\n ' making sure all have rtx streams');\n for (const ssrc of primaryVideoSsrcs) {\n const msid = videoMLine.getSSRCAttrValue(ssrc, 'msid');\n const cname = videoMLine.getSSRCAttrValue(ssrc, 'cname');\n let correspondingRtxSsrc = this.correspondingRtxSsrcs.get(ssrc);\n\n if (correspondingRtxSsrc) {\n logger.debug(\n 'Already have an associated rtx ssrc for'\n + `video ssrc ${ssrc}: ${correspondingRtxSsrc}`);\n } else {\n logger.debug(\n `No previously associated rtx ssrc for video ssrc ${ssrc}`);\n\n // If there's one in the sdp already for it, we'll just set\n // that as the corresponding one\n const previousAssociatedRtxStream = videoMLine.getRtxSSRC(ssrc);\n\n if (previousAssociatedRtxStream) {\n logger.debug(\n `Rtx stream ${previousAssociatedRtxStream} `\n + 'already existed in the sdp as an rtx stream for '\n + `${ssrc}`);\n correspondingRtxSsrc = previousAssociatedRtxStream;\n } else {\n correspondingRtxSsrc = SDPUtil.generateSsrc();\n logger.debug(`Generated rtx ssrc ${correspondingRtxSsrc} `\n + `for ssrc ${ssrc}`);\n }\n logger.debug(`Caching rtx ssrc ${correspondingRtxSsrc} `\n + `for video ssrc ${ssrc}`);\n this.correspondingRtxSsrcs.set(ssrc, correspondingRtxSsrc);\n }\n updateAssociatedRtxStream(\n videoMLine,\n {\n id: ssrc,\n cname,\n msid\n },\n correspondingRtxSsrc);\n }\n\n // FIXME we're not looking into much details whether the SDP has been\n // modified or not once the precondition requirements are met.\n return true;\n }\n\n /**\n * Strip all rtx streams from the given sdp\n * @param {string} sdpStr sdp in raw string format\n * @returns {string} sdp string with all rtx streams stripped\n */\n stripRtx(sdpStr) {\n const sdpTransformer = new SdpTransformWrap(sdpStr);\n const videoMLine = sdpTransformer.selectMedia('video');\n\n if (!videoMLine) {\n logger.debug(`No 'video' media found in the sdp: ${sdpStr}`);\n\n return sdpStr;\n }\n if (videoMLine.direction === 'recvonly') {\n logger.debug('RtxModifier doing nothing, video m line is recvonly');\n\n return sdpStr;\n }\n if (videoMLine.getSSRCCount() < 1) {\n logger.debug('RtxModifier doing nothing, no video ssrcs present');\n\n return sdpStr;\n }\n if (!videoMLine.containsAnySSRCGroups()) {\n logger.debug('RtxModifier doing nothing, '\n + 'no video ssrcGroups present');\n\n return sdpStr;\n }\n const fidGroups = videoMLine.findGroups('FID');\n\n // Remove the fid groups from the mline\n\n videoMLine.removeGroupsBySemantics('FID');\n\n // Get the rtx ssrcs and remove them from the mline\n for (const fidGroup of fidGroups) {\n const rtxSsrc = parseSecondarySSRC(fidGroup);\n\n videoMLine.removeSSRC(rtxSsrc);\n }\n\n return sdpTransformer.toRawSDP();\n }\n}\n", "/* global __filename */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport {\n parsePrimarySSRC,\n parseSecondarySSRC,\n SdpTransformWrap\n} from './SdpTransformUtil';\n\nconst logger = getLogger(__filename);\n\n/**\n * Handles the work of keeping video ssrcs consistent across multiple\n * o/a cycles, making it such that all stream operations can be\n * kept local and do not need to be signaled.\n * NOTE: This only keeps the 'primary' video ssrc consistent: meaning\n * the primary video stream\n */\nexport default class SdpConsistency {\n /**\n * Constructor\n * @param {string} logPrefix the log prefix appended to every logged\n * message, currently used to distinguish for which\n * TraceablePeerConnection the instance works.\n */\n constructor(logPrefix) {\n this.clearVideoSsrcCache();\n this.logPrefix = logPrefix;\n }\n\n /**\n * Clear the cached video primary and primary rtx ssrcs so that\n * they will not be used for the next call to\n * makeVideoPrimarySsrcsConsistent\n */\n clearVideoSsrcCache() {\n this.cachedPrimarySsrc = null;\n this.injectRecvOnly = false;\n }\n\n /**\n * Explicitly set the primary ssrc to be used in\n * makeVideoPrimarySsrcsConsistent\n * @param {number} primarySsrc the primarySsrc to be used\n * in future calls to makeVideoPrimarySsrcsConsistent\n * @throws Error if primarySsrc is not a number\n */\n setPrimarySsrc(primarySsrc) {\n if (typeof primarySsrc !== 'number') {\n throw new Error('Primary SSRC must be a number!');\n }\n this.cachedPrimarySsrc = primarySsrc;\n }\n\n /**\n * Checks whether or not there is a primary video SSRC cached already.\n * @return {boolean}\n */\n hasPrimarySsrcCached() {\n return Boolean(this.cachedPrimarySsrc);\n }\n\n /**\n * Given an sdp string, either:\n * 1) record the primary video and primary rtx ssrcs to be\n * used in future calls to makeVideoPrimarySsrcsConsistent or\n * 2) change the primary and primary rtx ssrcs in the given sdp\n * to match the ones previously cached\n * @param {string} sdpStr the sdp string to (potentially)\n * change to make the video ssrcs consistent\n * @returns {string} a (potentially) modified sdp string\n * with ssrcs consistent with this class' cache\n */\n makeVideoPrimarySsrcsConsistent(sdpStr) {\n const sdpTransformer = new SdpTransformWrap(sdpStr);\n const videoMLine = sdpTransformer.selectMedia('video');\n\n if (!videoMLine) {\n logger.debug(\n `${this.logPrefix} no 'video' media found in the sdp: `\n + `${sdpStr}`);\n\n return sdpStr;\n }\n\n if (videoMLine.direction === 'recvonly') {\n // If the mline is recvonly, we'll add the primary\n // ssrc as a recvonly ssrc\n if (this.cachedPrimarySsrc && this.injectRecvOnly) {\n videoMLine.addSSRCAttribute({\n id: this.cachedPrimarySsrc,\n attribute: 'cname',\n value: `recvonly-${this.cachedPrimarySsrc}`\n });\n } else {\n logger.info(\n `${this.logPrefix} no SSRC found for the recvonly video`\n + 'stream!');\n }\n } else {\n const newPrimarySsrc = videoMLine.getPrimaryVideoSsrc();\n\n if (!newPrimarySsrc) {\n logger.info(\n `${this.logPrefix} sdp-consistency couldn't`\n + ' parse new primary ssrc');\n\n return sdpStr;\n }\n if (this.cachedPrimarySsrc) {\n logger.info(\n `${this.logPrefix} sdp-consistency replacing new ssrc`\n + `${newPrimarySsrc} with cached `\n + `${this.cachedPrimarySsrc}`);\n videoMLine.replaceSSRC(newPrimarySsrc, this.cachedPrimarySsrc);\n for (const group of videoMLine.ssrcGroups) {\n if (group.semantics === 'FID') {\n const primarySsrc = parsePrimarySSRC(group);\n const rtxSsrc = parseSecondarySSRC(group);\n\n // eslint-disable-next-line max-depth\n if (primarySsrc === newPrimarySsrc) {\n group.ssrcs\n = `${this.cachedPrimarySsrc} ${rtxSsrc}`;\n }\n }\n }\n } else {\n this.cachedPrimarySsrc = newPrimarySsrc;\n logger.info(\n `${this.logPrefix} sdp-consistency caching primary ssrc`\n + `${this.cachedPrimarySsrc}`);\n }\n\n this.injectRecvOnly = true;\n }\n\n return sdpTransformer.toRawSDP();\n }\n}\n", "/* global\n __filename\n*/\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport { createAudioContext } from './WebAudioUtils';\n\nconst logger = getLogger(__filename);\n\n/**\n * The AudioMixer, as the name implies, mixes a number of MediaStreams containing audio tracks into a single\n * MediaStream.\n */\nexport default class AudioMixer {\n /**\n * Create AudioMixer instance.\n */\n constructor() {\n this._started = false;\n this._streamsToMix = [];\n this._streamMSSArray = [];\n }\n\n /**\n * Add audio MediaStream to be mixed, if the stream doesn't contain any audio tracks it will be ignored.\n *\n * @param {MediaStream} stream - MediaStream to be mixed.\n */\n addMediaStream(stream) {\n if (!stream.getAudioTracks()) {\n logger.warn('Added MediaStream doesn\\'t contain audio tracks.');\n }\n\n this._streamsToMix.push(stream);\n }\n\n /**\n * At this point a WebAudio ChannelMergerNode is created and and the two associated MediaStreams are connected to\n * it; the resulting mixed MediaStream is returned.\n *\n * @returns {MediaStream} - MediaStream containing added streams mixed together, or null if no MediaStream\n * is added.\n */\n start() {\n // If the mixer was already started just return the existing mixed stream.\n if (this._started) {\n return this._mixedMSD.stream;\n }\n\n this._audioContext = createAudioContext();\n\n if (!this._streamsToMix.length) {\n logger.warn('No MediaStream\\'s added to AudioMixer, nothing will happen.');\n\n return null;\n }\n\n this._started = true;\n\n this._mixedMSD = this._audioContext.createMediaStreamDestination();\n\n for (const stream of this._streamsToMix) {\n const streamMSS = this._audioContext.createMediaStreamSource(stream);\n\n streamMSS.connect(this._mixedMSD);\n\n // Maintain a list of MediaStreamAudioSourceNode so we can disconnect them on reset.\n this._streamMSSArray.push(streamMSS);\n }\n\n return this._mixedMSD.stream;\n }\n\n /**\n * Disconnect MediaStreamAudioSourceNode and clear references.\n *\n * @returns {void}\n */\n reset() {\n this._started = false;\n this._streamsToMix = [];\n\n // Clean up created MediaStreamAudioSourceNode.\n for (const streamMSS of this._streamMSSArray) {\n streamMSS.disconnect();\n }\n\n this._streamMSSArray = [];\n\n if (this._audioContext) {\n this._audioContext = undefined;\n }\n }\n}\n", "const AuthUtil = {\n /**\n * Creates the URL pointing to JWT token authentication service. It is\n * formatted from the 'urlPattern' argument which can contain the following\n * constants:\n * '{room}' - name of the conference room passed as roomName\n * argument to this method.\n * '{roleUpgrade}' - will contain 'true' if the URL will be used for\n * the role upgrade scenario, where user connects from anonymous domain and\n * then gets upgraded to the moderator by logging-in from the popup window.\n *\n * @param urlPattern a URL pattern pointing to the login service\n * @param roomName the name of the conference room for which the user will\n * be authenticated\n * @param {bool} roleUpgrade true if the URL will be used for role\n * upgrade scenario, where the user logs-in from the popup window in order\n * to have the moderator rights granted\n *\n * @returns {string|null} the URL pointing to JWT login service or\n * null if 'urlPattern' is not a string and the URL can not be\n * constructed.\n */\n getTokenAuthUrl(urlPattern, roomName, roleUpgrade) {\n const url = urlPattern;\n\n if (typeof url !== 'string') {\n return null;\n }\n\n return url.replace('{room}', roomName)\n .replace('{roleUpgrade}', roleUpgrade === true);\n }\n};\n\nmodule.exports = AuthUtil;\n", "import {\n CONNECTION_DISCONNECTED as ANALYTICS_CONNECTION_DISCONNECTED,\n createConnectionFailedEvent\n} from './service/statistics/AnalyticsEvents';\nimport JitsiConference from './JitsiConference';\nimport * as JitsiConnectionEvents from './JitsiConnectionEvents';\nimport Statistics from './modules/statistics/statistics';\nimport XMPP from './modules/xmpp/xmpp';\n\n/**\n * Creates a new connection object for the Jitsi Meet server side video\n * conferencing service. Provides access to the JitsiConference interface.\n * @param appID identification for the provider of Jitsi Meet video conferencing\n * services.\n * @param token the JWT token used to authenticate with the server(optional)\n * @param options Object with properties / settings related to connection with\n * the server.\n * @constructor\n */\nexport default function JitsiConnection(appID, token, options) {\n this.appID = appID;\n this.token = token;\n this.options = options;\n this.xmpp = new XMPP(options, token);\n\n /* eslint-disable max-params */\n this.addEventListener(JitsiConnectionEvents.CONNECTION_FAILED,\n (errType, msg, credentials, details) => {\n Statistics.sendAnalyticsAndLog(\n createConnectionFailedEvent(errType, msg, details));\n });\n /* eslint-enable max-params */\n\n this.addEventListener(JitsiConnectionEvents.CONNECTION_DISCONNECTED,\n msg => {\n // we can see disconnects from normal tab closing of the browser\n // and then there are no msgs, but we want to log only disconnects\n // when there is real error\n // XXX Do we need the difference in handling between the log and\n // analytics event here?\n if (msg) {\n Statistics.sendAnalytics(\n ANALYTICS_CONNECTION_DISCONNECTED,\n { message: msg });\n }\n Statistics.sendLog(\n JSON.stringify(\n {\n id: ANALYTICS_CONNECTION_DISCONNECTED,\n msg\n }));\n });\n}\n\n/**\n * Connect the client with the server.\n * @param options {object} connecting options\n * (for example authentications parameters).\n */\nJitsiConnection.prototype.connect = function(options = {}) {\n this.xmpp.connect(options.id, options.password);\n};\n\n/**\n * Attach to existing connection. Can be used for optimizations. For example:\n * if the connection is created on the server we can attach to it and start\n * using it.\n *\n * @param options {object} connecting options - rid, sid and jid.\n */\nJitsiConnection.prototype.attach = function(options) {\n this.xmpp.attach(options);\n};\n\n/**\n * Disconnect the client from the server.\n * @returns {Promise} - Resolves when the disconnect process is finished or rejects with an error.\n */\nJitsiConnection.prototype.disconnect = function(...args) {\n // XXX Forward any arguments passed to JitsiConnection.disconnect to\n // XMPP.disconnect. For example, the caller of JitsiConnection.disconnect\n // may optionally pass the event which triggered the disconnect in order to\n // provide the implementation with finer-grained context.\n return this.xmpp.disconnect(...args);\n};\n\n/**\n * Returns the jid of the participant associated with the XMPP connection.\n *\n * @returns {string} The jid of the participant.\n */\nJitsiConnection.prototype.getJid = function() {\n return this.xmpp.getJid();\n};\n\n/**\n * This method allows renewal of the tokens if they are expiring.\n * @param token the new token.\n */\nJitsiConnection.prototype.setToken = function(token) {\n this.token = token;\n};\n\n/**\n * Creates and joins new conference.\n * @param name the name of the conference; if null - a generated name will be\n * provided from the api\n * @param options Object with properties / settings related to the conference\n * that will be created.\n * @returns {JitsiConference} returns the new conference object.\n */\nJitsiConnection.prototype.initJitsiConference = function(name, options) {\n return new JitsiConference({\n name,\n config: options,\n connection: this\n });\n};\n\n/**\n * Subscribes the passed listener to the event.\n * @param event {JitsiConnectionEvents} the connection event.\n * @param listener {Function} the function that will receive the event\n */\nJitsiConnection.prototype.addEventListener = function(event, listener) {\n this.xmpp.addListener(event, listener);\n};\n\n/**\n * Unsubscribes the passed handler.\n * @param event {JitsiConnectionEvents} the connection event.\n * @param listener {Function} the function that will receive the event\n */\nJitsiConnection.prototype.removeEventListener = function(event, listener) {\n this.xmpp.removeListener(event, listener);\n};\n\n/**\n * Returns measured connectionTimes.\n */\nJitsiConnection.prototype.getConnectionTimes = function() {\n return this.xmpp.connectionTimes;\n};\n\n/**\n * Adds new feature to the list of supported features for the local\n * participant.\n * @param {String} feature the name of the feature.\n * @param {boolean} submit if true - the new list of features will be\n * immediately submitted to the others.\n */\nJitsiConnection.prototype.addFeature = function(feature, submit = false) {\n return this.xmpp.caps.addFeature(feature, submit);\n};\n\n/**\n * Removes a feature from the list of supported features for the local\n * participant\n * @param {String} feature the name of the feature.\n * @param {boolean} submit if true - the new list of features will be\n * immediately submitted to the others.\n */\nJitsiConnection.prototype.removeFeature = function(feature, submit = false) {\n return this.xmpp.caps.removeFeature(feature, submit);\n};\n", "/* global __filename, $, Promise */\nimport { Strophe } from 'strophe.js';\n\nimport EventEmitter from 'events';\nimport { getLogger } from 'jitsi-meet-logger';\nimport isEqual from 'lodash.isequal';\n\nimport * as JitsiConferenceErrors from './JitsiConferenceErrors';\nimport JitsiConferenceEventManager from './JitsiConferenceEventManager';\nimport * as JitsiConferenceEvents from './JitsiConferenceEvents';\nimport JitsiParticipant from './JitsiParticipant';\nimport JitsiTrackError from './JitsiTrackError';\nimport * as JitsiTrackErrors from './JitsiTrackErrors';\nimport * as JitsiTrackEvents from './JitsiTrackEvents';\nimport authenticateAndUpgradeRole from './authenticateAndUpgradeRole';\nimport P2PDominantSpeakerDetection from './modules/detection/P2PDominantSpeakerDetection';\nimport RTC from './modules/RTC/RTC';\nimport TalkMutedDetection from './modules/detection/TalkMutedDetection';\nimport VADTalkMutedDetection from './modules/detection/VADTalkMutedDetection';\nimport VADNoiseDetection from './modules/detection/VADNoiseDetection';\nimport VADAudioAnalyser from './modules/detection/VADAudioAnalyser';\nimport * as DetectionEvents from './modules/detection/DetectionEvents';\nimport NoAudioSignalDetection from './modules/detection/NoAudioSignalDetection';\nimport browser from './modules/browser';\nimport ConnectionQuality from './modules/connectivity/ConnectionQuality';\nimport IceFailedNotification\n from './modules/connectivity/IceFailedNotification';\nimport ParticipantConnectionStatusHandler\n from './modules/connectivity/ParticipantConnectionStatus';\nimport E2EEContext from './modules/e2ee/E2EEContext';\nimport E2ePing from './modules/e2eping/e2eping';\nimport Jvb121EventGenerator from './modules/event/Jvb121EventGenerator';\nimport RecordingManager from './modules/recording/RecordingManager';\nimport RttMonitor from './modules/rttmonitor/rttmonitor';\nimport Settings from './modules/settings/Settings';\nimport AvgRTPStatsReporter from './modules/statistics/AvgRTPStatsReporter';\nimport AudioOutputProblemDetector from './modules/statistics/AudioOutputProblemDetector';\nimport SpeakerStatsCollector from './modules/statistics/SpeakerStatsCollector';\nimport Statistics from './modules/statistics/statistics';\nimport Transcriber from './modules/transcription/transcriber';\nimport GlobalOnErrorHandler from './modules/util/GlobalOnErrorHandler';\nimport RandomUtil from './modules/util/RandomUtil';\nimport ComponentsVersions from './modules/version/ComponentsVersions';\nimport VideoSIPGW from './modules/videosipgw/VideoSIPGW';\nimport * as VideoSIPGWConstants from './modules/videosipgw/VideoSIPGWConstants';\nimport { JITSI_MEET_MUC_TYPE } from './modules/xmpp/xmpp';\nimport * as MediaType from './service/RTC/MediaType';\nimport * as RTCEvents from './service/RTC/RTCEvents';\nimport VideoType from './service/RTC/VideoType';\nimport {\n ACTION_JINGLE_RESTART,\n ACTION_JINGLE_SI_RECEIVED,\n ACTION_JINGLE_SI_TIMEOUT,\n ACTION_JINGLE_TERMINATE,\n ACTION_P2P_DECLINED,\n ACTION_P2P_ESTABLISHED,\n ACTION_P2P_FAILED,\n ACTION_P2P_SWITCH_TO_JVB,\n ICE_ESTABLISHMENT_DURATION_DIFF,\n createConferenceEvent,\n createJingleEvent,\n createP2PEvent\n} from './service/statistics/AnalyticsEvents';\nimport * as XMPPEvents from './service/xmpp/XMPPEvents';\n\nconst logger = getLogger(__filename);\n\n/**\n * How long since Jicofo is supposed to send a session-initiate, before\n * {@link ACTION_JINGLE_SI_TIMEOUT} analytics event is sent (in ms).\n * @type {number}\n */\nconst JINGLE_SI_TIMEOUT = 5000;\n\n/**\n * Creates a JitsiConference object with the given name and properties.\n * Note: this constructor is not a part of the public API (objects should be\n * created using JitsiConnection.createConference).\n * @param options.config properties / settings related to the conference that\n * will be created.\n * @param options.name the name of the conference\n * @param options.connection the JitsiConnection object for this\n * JitsiConference.\n * @param {number} [options.config.avgRtpStatsN=15] how many samples are to be\n * collected by {@link AvgRTPStatsReporter}, before arithmetic mean is\n * calculated and submitted to the analytics module.\n * @param {boolean} [options.config.p2p.enabled] when set to true\n * the peer to peer mode will be enabled. It means that when there are only 2\n * participants in the conference an attempt to make direct connection will be\n * made. If the connection succeeds the conference will stop sending data\n * through the JVB connection and will use the direct one instead.\n * @param {number} [options.config.p2p.backToP2PDelay=5] a delay given in\n * seconds, before the conference switches back to P2P, after the 3rd\n * participant has left the room.\n * @param {number} [options.config.channelLastN=-1] The requested amount of\n * videos are going to be delivered after the value is in effect. Set to -1 for\n * unlimited or all available videos.\n * @param {number} [options.config.forceJVB121Ratio]\n * \"Math.random() < forceJVB121Ratio\" will determine whether a 2 people\n * conference should be moved to the JVB instead of P2P. The decision is made on\n * the responder side, after ICE succeeds on the P2P connection.\n * @param {*} [options.config.openBridgeChannel] Which kind of communication to\n * open with the videobridge. Values can be \"datachannel\", \"websocket\", true\n * (treat it as \"datachannel\"), undefined (treat it as \"datachannel\") and false\n * (don't open any channel).\n * @constructor\n *\n * FIXME Make all methods which are called from lib-internal classes\n * to non-public (use _). To name a few:\n * {@link JitsiConference.onLocalRoleChanged}\n * {@link JitsiConference.onUserRoleChanged}\n * {@link JitsiConference.onMemberLeft}\n * and so on...\n */\nexport default function JitsiConference(options) {\n if (!options.name || options.name.toLowerCase() !== options.name) {\n const errmsg\n = 'Invalid conference name (no conference name passed or it '\n + 'contains invalid characters like capital letters)!';\n\n logger.error(errmsg);\n throw new Error(errmsg);\n }\n this.eventEmitter = new EventEmitter();\n this.options = options;\n this.eventManager = new JitsiConferenceEventManager(this);\n this.participants = {};\n this._init(options);\n this.componentsVersions = new ComponentsVersions(this);\n\n /**\n * Jingle session instance for the JVB connection.\n * @type {JingleSessionPC}\n */\n this.jvbJingleSession = null;\n this.lastDominantSpeaker = null;\n this.dtmfManager = null;\n this.somebodySupportsDTMF = false;\n this.authEnabled = false;\n this.startAudioMuted = false;\n this.startVideoMuted = false;\n this.startMutedPolicy = {\n audio: false,\n video: false\n };\n this.isMutedByFocus = false;\n\n // when muted by focus we receive the jid of the initiator of the mute\n this.mutedByFocusActor = null;\n\n // Flag indicates if the 'onCallEnded' method was ever called on this\n // instance. Used to log extra analytics event for debugging purpose.\n // We need to know if the potential issue happened before or after\n // the restart.\n this.wasStopped = false;\n\n // Conference properties, maintained by jicofo.\n this.properties = {};\n\n /**\n * The object which monitors local and remote connection statistics (e.g.\n * sending bitrate) and calculates a number which represents the connection\n * quality.\n */\n this.connectionQuality\n = new ConnectionQuality(this, this.eventEmitter, options);\n\n /**\n * Reports average RTP statistics to the analytics module.\n * @type {AvgRTPStatsReporter}\n */\n this.avgRtpStatsReporter\n = new AvgRTPStatsReporter(this, options.config.avgRtpStatsN || 15);\n\n /**\n * Detects issues with the audio of remote participants.\n * @type {AudioOutputProblemDetector}\n */\n this._audioOutputProblemDetector = new AudioOutputProblemDetector(this);\n\n /**\n * Indicates whether the connection is interrupted or not.\n */\n this.isJvbConnectionInterrupted = false;\n\n /**\n * The object which tracks active speaker times\n */\n this.speakerStatsCollector = new SpeakerStatsCollector(this);\n\n /* P2P related fields below: */\n\n /**\n * Stores reference to deferred start P2P task. It's created when 3rd\n * participant leaves the room in order to avoid ping pong effect (it\n * could be just a page reload).\n * @type {number|null}\n */\n this.deferredStartP2PTask = null;\n\n const delay\n = parseInt(options.config.p2p && options.config.p2p.backToP2PDelay, 10);\n\n /**\n * A delay given in seconds, before the conference switches back to P2P\n * after the 3rd participant has left.\n * @type {number}\n */\n this.backToP2PDelay = isNaN(delay) ? 5 : delay;\n logger.info(`backToP2PDelay: ${this.backToP2PDelay}`);\n\n /**\n * If set to true it means the P2P ICE is no longer connected.\n * When false it means that P2P ICE (media) connection is up\n * and running.\n * @type {boolean}\n */\n this.isP2PConnectionInterrupted = false;\n\n /**\n * Flag set to true when P2P session has been established\n * (ICE has been connected) and this conference is currently in the peer to\n * peer mode (P2P connection is the active one).\n * @type {boolean}\n */\n this.p2p = false;\n\n /**\n * A JingleSession for the direct peer to peer connection.\n * @type {JingleSessionPC}\n */\n this.p2pJingleSession = null;\n\n this.videoSIPGWHandler = new VideoSIPGW(this.room);\n this.recordingManager = new RecordingManager(this.room);\n this._conferenceJoinAnalyticsEventSent = false;\n\n if (browser.supportsInsertableStreams()) {\n this._e2eeCtx = new E2EEContext({ salt: this.options.name });\n }\n}\n\n// FIXME convert JitsiConference to ES6 - ASAP !\nJitsiConference.prototype.constructor = JitsiConference;\n\n/**\n * Create a resource for the a jid. We use the room nickname (the resource part\n * of the occupant JID, see XEP-0045) as the endpoint ID in colibri. We require\n * endpoint IDs to be 8 hex digits because in some cases they get serialized\n * into a 32bit field.\n *\n * @param {string} jid - The id set onto the XMPP connection.\n * @param {boolean} isAuthenticatedUser - Whether or not the user has connected\n * to the XMPP service with a password.\n * @returns {string}\n * @static\n */\nJitsiConference.resourceCreator = function(jid, isAuthenticatedUser) {\n let mucNickname;\n\n if (isAuthenticatedUser) {\n // For authenticated users generate a random ID.\n mucNickname = RandomUtil.randomHexString(8).toLowerCase();\n } else {\n // We try to use the first part of the node (which for anonymous users\n // on prosody is a UUID) to match the previous behavior (and maybe make\n // debugging easier).\n mucNickname = Strophe.getNodeFromJid(jid).substr(0, 8)\n .toLowerCase();\n\n // But if this doesn't have the required format we just generate a new\n // random nickname.\n const re = /[0-9a-f]{8}/g;\n\n if (!re.test(mucNickname)) {\n mucNickname = RandomUtil.randomHexString(8).toLowerCase();\n }\n }\n\n return mucNickname;\n};\n\n/**\n * Initializes the conference object properties\n * @param options {object}\n * @param options.connection {JitsiConnection} overrides this.connection\n */\nJitsiConference.prototype._init = function(options = {}) {\n // Override connection and xmpp properties (Useful if the connection\n // reloaded)\n if (options.connection) {\n this.connection = options.connection;\n this.xmpp = this.connection.xmpp;\n\n // Setup XMPP events only if we have new connection object.\n this.eventManager.setupXMPPListeners();\n }\n\n const { config } = this.options;\n\n this._statsCurrentId = config.statisticsId ? config.statisticsId : Settings.callStatsUserName;\n this.room = this.xmpp.createRoom(\n this.options.name, {\n ...config,\n statsId: this._statsCurrentId\n },\n JitsiConference.resourceCreator\n );\n\n // Connection interrupted/restored listeners\n this._onIceConnectionInterrupted\n = this._onIceConnectionInterrupted.bind(this);\n this.room.addListener(\n XMPPEvents.CONNECTION_INTERRUPTED, this._onIceConnectionInterrupted);\n\n this._onIceConnectionRestored = this._onIceConnectionRestored.bind(this);\n this.room.addListener(\n XMPPEvents.CONNECTION_RESTORED, this._onIceConnectionRestored);\n\n this._onIceConnectionEstablished\n = this._onIceConnectionEstablished.bind(this);\n this.room.addListener(\n XMPPEvents.CONNECTION_ESTABLISHED, this._onIceConnectionEstablished);\n\n this._updateProperties = this._updateProperties.bind(this);\n this.room.addListener(XMPPEvents.CONFERENCE_PROPERTIES_CHANGED,\n this._updateProperties);\n\n this._sendConferenceJoinAnalyticsEvent = this._sendConferenceJoinAnalyticsEvent.bind(this);\n this.room.addListener(XMPPEvents.MEETING_ID_SET, this._sendConferenceJoinAnalyticsEvent);\n\n this.rttMonitor = new RttMonitor(config.rttMonitor || {});\n\n this.e2eping = new E2ePing(\n this,\n config,\n (message, to) => {\n try {\n this.sendMessage(\n message, to, true /* sendThroughVideobridge */);\n } catch (error) {\n logger.warn('Failed to send E2E ping request or response.', error && error.msg);\n }\n });\n\n if (!this.rtc) {\n this.rtc = new RTC(this, options);\n this.eventManager.setupRTCListeners();\n }\n\n this.participantConnectionStatus\n = new ParticipantConnectionStatusHandler(\n this.rtc,\n this,\n {\n // Both these options are not public API, leaving it here only\n // as an entry point through config for tuning up purposes.\n // Default values should be adjusted as soon as optimal values\n // are discovered.\n rtcMuteTimeout: config._peerConnStatusRtcMuteTimeout,\n outOfLastNTimeout: config._peerConnStatusOutOfLastNTimeout\n });\n this.participantConnectionStatus.init();\n\n if (!this.statistics) {\n this.statistics = new Statistics(this.xmpp, {\n aliasName: this._statsCurrentId,\n userName: config.statisticsDisplayName ? config.statisticsDisplayName : this.myUserId(),\n callStatsConfIDNamespace: this.connection.options.hosts.domain,\n confID: config.confID || `${this.connection.options.hosts.domain}/${this.options.name}`,\n customScriptUrl: config.callStatsCustomScriptUrl,\n callStatsID: config.callStatsID,\n callStatsSecret: config.callStatsSecret,\n callStatsApplicationLogsDisabled: config.callStatsApplicationLogsDisabled,\n roomName: this.options.name,\n applicationName: config.applicationName,\n getWiFiStatsMethod: config.getWiFiStatsMethod\n });\n Statistics.analytics.addPermanentProperties({\n 'callstats_name': this._statsCurrentId\n });\n }\n\n this.eventManager.setupChatRoomListeners();\n\n // Always add listeners because on reload we are executing leave and the\n // listeners are removed from statistics module.\n this.eventManager.setupStatisticsListeners();\n\n if (config.enableTalkWhileMuted) {\n\n // If VAD processor factory method is provided uses VAD based detection, otherwise fallback to audio level\n // based detection.\n if (config.createVADProcessor) {\n logger.info('Using VAD detection for generating talk while muted events');\n\n if (!this._audioAnalyser) {\n this._audioAnalyser = new VADAudioAnalyser(this, config.createVADProcessor);\n }\n\n const vadTalkMutedDetection = new VADTalkMutedDetection();\n\n vadTalkMutedDetection.on(DetectionEvents.VAD_TALK_WHILE_MUTED, () =>\n this.eventEmitter.emit(JitsiConferenceEvents.TALK_WHILE_MUTED));\n\n this._audioAnalyser.addVADDetectionService(vadTalkMutedDetection);\n\n\n } else {\n logger.info('Using audio level based detection for generating talk while muted events');\n this._talkWhileMutedDetection = new TalkMutedDetection(\n this, () => this.eventEmitter.emit(JitsiConferenceEvents.TALK_WHILE_MUTED));\n }\n }\n\n if (config.enableNoisyMicDetection) {\n if (config.createVADProcessor) {\n if (!this._audioAnalyser) {\n this._audioAnalyser = new VADAudioAnalyser(this, config.createVADProcessor);\n }\n\n const vadNoiseDetection = new VADNoiseDetection();\n\n vadNoiseDetection.on(DetectionEvents.VAD_NOISY_DEVICE, () =>\n this.eventEmitter.emit(JitsiConferenceEvents.NOISY_MIC));\n\n this._audioAnalyser.addVADDetectionService(vadNoiseDetection);\n } else {\n logger.warn('No VAD Processor was provided. Noisy microphone detection service was not initialized!');\n }\n }\n\n // Generates events based on no audio input detector.\n if (config.enableNoAudioDetection) {\n this._noAudioSignalDetection = new NoAudioSignalDetection(this);\n this._noAudioSignalDetection.on(DetectionEvents.NO_AUDIO_INPUT, () => {\n this.eventEmitter.emit(JitsiConferenceEvents.NO_AUDIO_INPUT);\n });\n this._noAudioSignalDetection.on(DetectionEvents.AUDIO_INPUT_STATE_CHANGE, hasAudioSignal => {\n this.eventEmitter.emit(JitsiConferenceEvents.AUDIO_INPUT_STATE_CHANGE, hasAudioSignal);\n });\n }\n\n\n if ('channelLastN' in config) {\n this.setLastN(config.channelLastN);\n }\n\n /**\n * Emits {@link JitsiConferenceEvents.JVB121_STATUS}.\n * @type {Jvb121EventGenerator}\n */\n this.jvb121Status = new Jvb121EventGenerator(this);\n\n // creates dominant speaker detection that works only in p2p mode\n this.p2pDominantSpeakerDetection = new P2PDominantSpeakerDetection(this);\n\n if (config && config.deploymentInfo && config.deploymentInfo.userRegion) {\n this.setLocalParticipantProperty(\n 'region', config.deploymentInfo.userRegion);\n }\n};\n\n/**\n * Joins the conference.\n * @param password {string} the password\n */\nJitsiConference.prototype.join = function(password) {\n if (this.room) {\n this.room.join(password).then(() => this._maybeSetSITimeout());\n }\n};\n\n/**\n * Authenticates and upgrades the role of the local participant/user.\n *\n * @returns {Object} A thenable which (1) settles when the process of\n * authenticating and upgrading the role of the local participant/user finishes\n * and (2) has a cancel method that allows the caller to interrupt the\n * process.\n */\nJitsiConference.prototype.authenticateAndUpgradeRole = function(options) {\n return authenticateAndUpgradeRole.call(this, {\n ...options,\n onCreateResource: JitsiConference.resourceCreator\n });\n};\n\n/**\n * Check if joined to the conference.\n */\nJitsiConference.prototype.isJoined = function() {\n return this.room && this.room.joined;\n};\n\n/**\n * Tells whether or not the P2P mode is enabled in the configuration.\n * @return {boolean}\n */\nJitsiConference.prototype.isP2PEnabled = function() {\n return Boolean(this.options.config.p2p && this.options.config.p2p.enabled)\n\n // FIXME: remove once we have a default config template. -saghul\n || typeof this.options.config.p2p === 'undefined';\n};\n\n/**\n * When in P2P test mode, the conference will not automatically switch to P2P\n * when there 2 participants.\n * @return {boolean}\n */\nJitsiConference.prototype.isP2PTestModeEnabled = function() {\n return Boolean(this.options.config.testing\n && this.options.config.testing.p2pTestMode);\n};\n\n/**\n * Leaves the conference.\n * @returns {Promise}\n */\nJitsiConference.prototype.leave = function() {\n if (this.participantConnectionStatus) {\n this.participantConnectionStatus.dispose();\n this.participantConnectionStatus = null;\n }\n if (this.avgRtpStatsReporter) {\n this.avgRtpStatsReporter.dispose();\n this.avgRtpStatsReporter = null;\n }\n\n if (this._audioOutputProblemDetector) {\n this._audioOutputProblemDetector.dispose();\n this._audioOutputProblemDetector = null;\n }\n\n if (this.rttMonitor) {\n this.rttMonitor.stop();\n this.rttMonitor = null;\n }\n\n if (this.e2eping) {\n this.e2eping.stop();\n this.e2eping = null;\n }\n\n this.getLocalTracks().forEach(track => this.onLocalTrackRemoved(track));\n\n this.rtc.closeBridgeChannel();\n if (this.statistics) {\n this.statistics.dispose();\n }\n\n this._delayedIceFailed && this._delayedIceFailed.cancel();\n\n // Close both JVb and P2P JingleSessions\n if (this.jvbJingleSession) {\n this.jvbJingleSession.close();\n this.jvbJingleSession = null;\n }\n if (this.p2pJingleSession) {\n this.p2pJingleSession.close();\n this.p2pJingleSession = null;\n }\n\n // leave the conference\n if (this.room) {\n const room = this.room;\n\n // Unregister connection state listeners\n room.removeListener(\n XMPPEvents.CONNECTION_INTERRUPTED,\n this._onIceConnectionInterrupted);\n room.removeListener(\n XMPPEvents.CONNECTION_RESTORED,\n this._onIceConnectionRestored);\n room.removeListener(\n XMPPEvents.CONNECTION_ESTABLISHED,\n this._onIceConnectionEstablished);\n\n room.removeListener(\n XMPPEvents.CONFERENCE_PROPERTIES_CHANGED,\n this._updateProperties);\n\n room.removeListener(XMPPEvents.MEETING_ID_SET, this._sendConferenceJoinAnalyticsEvent);\n\n this.eventManager.removeXMPPListeners();\n\n this.room = null;\n\n return room.leave()\n .then(() => {\n if (this.rtc) {\n this.rtc.destroy();\n }\n })\n .catch(error => {\n // remove all participants because currently the conference\n // won't be usable anyway. This is done on success automatically\n // by the ChatRoom instance.\n this.getParticipants().forEach(\n participant => this.onMemberLeft(participant.getJid()));\n\n throw error;\n });\n }\n\n // If this.room == null we are calling second time leave().\n return Promise.reject(\n new Error('The conference is has been already left'));\n};\n\n/**\n * Returns name of this conference.\n */\nJitsiConference.prototype.getName = function() {\n return this.options.name;\n};\n\n/**\n * Returns the {@link JitsiConnection} used by this this conference.\n */\nJitsiConference.prototype.getConnection = function() {\n return this.connection;\n};\n\n/**\n * Check if authentication is enabled for this conference.\n */\nJitsiConference.prototype.isAuthEnabled = function() {\n return this.authEnabled;\n};\n\n/**\n * Check if user is logged in.\n */\nJitsiConference.prototype.isLoggedIn = function() {\n return Boolean(this.authIdentity);\n};\n\n/**\n * Get authorized login.\n */\nJitsiConference.prototype.getAuthLogin = function() {\n return this.authIdentity;\n};\n\n/**\n * Check if external authentication is enabled for this conference.\n */\nJitsiConference.prototype.isExternalAuthEnabled = function() {\n return this.room && this.room.moderator.isExternalAuthEnabled();\n};\n\n/**\n * Get url for external authentication.\n * @param {boolean} [urlForPopup] if true then return url for login popup,\n * else url of login page.\n * @returns {Promise}\n */\nJitsiConference.prototype.getExternalAuthUrl = function(urlForPopup) {\n return new Promise((resolve, reject) => {\n if (!this.isExternalAuthEnabled()) {\n reject();\n\n return;\n }\n if (urlForPopup) {\n this.room.moderator.getPopupLoginUrl(resolve, reject);\n } else {\n this.room.moderator.getLoginUrl(resolve, reject);\n }\n });\n};\n\n/**\n * Returns the local tracks of the given media type, or all local tracks if no\n * specific type is given.\n * @param {MediaType} [mediaType] Optional media type (audio or video).\n */\nJitsiConference.prototype.getLocalTracks = function(mediaType) {\n let tracks = [];\n\n if (this.rtc) {\n tracks = this.rtc.getLocalTracks(mediaType);\n }\n\n return tracks;\n};\n\n/**\n * Obtains local audio track.\n * @return {JitsiLocalTrack|null}\n */\nJitsiConference.prototype.getLocalAudioTrack = function() {\n return this.rtc ? this.rtc.getLocalAudioTrack() : null;\n};\n\n/**\n * Obtains local video track.\n * @return {JitsiLocalTrack|null}\n */\nJitsiConference.prototype.getLocalVideoTrack = function() {\n return this.rtc ? this.rtc.getLocalVideoTrack() : null;\n};\n\n/**\n * Attaches a handler for events(For example - \"participant joined\".) in the\n * conference. All possible event are defined in JitsiConferenceEvents.\n * @param eventId the event ID.\n * @param handler handler for the event.\n *\n * Note: consider adding eventing functionality by extending an EventEmitter\n * impl, instead of rolling ourselves\n */\nJitsiConference.prototype.on = function(eventId, handler) {\n if (this.eventEmitter) {\n this.eventEmitter.on(eventId, handler);\n }\n};\n\n/**\n * Removes event listener\n * @param eventId the event ID.\n * @param [handler] optional, the specific handler to unbind\n *\n * Note: consider adding eventing functionality by extending an EventEmitter\n * impl, instead of rolling ourselves\n */\nJitsiConference.prototype.off = function(eventId, handler) {\n if (this.eventEmitter) {\n this.eventEmitter.removeListener(eventId, handler);\n }\n};\n\n// Common aliases for event emitter\nJitsiConference.prototype.addEventListener = JitsiConference.prototype.on;\nJitsiConference.prototype.removeEventListener = JitsiConference.prototype.off;\n\n/**\n * Receives notifications from other participants about commands / custom events\n * (sent by sendCommand or sendCommandOnce methods).\n * @param command {String} the name of the command\n * @param handler {Function} handler for the command\n */\nJitsiConference.prototype.addCommandListener = function(command, handler) {\n if (this.room) {\n this.room.addPresenceListener(command, handler);\n }\n};\n\n/**\n * Removes command listener\n * @param command {String} the name of the command\n * @param handler {Function} handler to remove for the command\n */\nJitsiConference.prototype.removeCommandListener = function(command, handler) {\n if (this.room) {\n this.room.removePresenceListener(command, handler);\n }\n};\n\n/**\n * Sends text message to the other participants in the conference\n * @param message the text message.\n * @param elementName the element name to encapsulate the message.\n * @deprecated Use 'sendMessage' instead. TODO: this should be private.\n */\nJitsiConference.prototype.sendTextMessage = function(\n message, elementName = 'body') {\n if (this.room) {\n const displayName = (this.room.getFromPresence('nick') || {}).value;\n\n this.room.sendMessage(message, elementName, displayName);\n }\n};\n\n/**\n * Send private text message to another participant of the conference\n * @param id the id of the participant to send a private message.\n * @param message the text message.\n * @param elementName the element name to encapsulate the message.\n * @deprecated Use 'sendMessage' instead. TODO: this should be private.\n */\nJitsiConference.prototype.sendPrivateTextMessage = function(\n id, message, elementName = 'body') {\n if (this.room) {\n this.room.sendPrivateMessage(id, message, elementName);\n }\n};\n\n/**\n * Send presence command.\n * @param name {String} the name of the command.\n * @param values {Object} with keys and values that will be sent.\n **/\nJitsiConference.prototype.sendCommand = function(name, values) {\n if (this.room) {\n this.room.addToPresence(name, values);\n this.room.sendPresence();\n } else {\n logger.warn('Not sending a command, room not initialized.');\n }\n\n};\n\n/**\n * Send presence command one time.\n * @param name {String} the name of the command.\n * @param values {Object} with keys and values that will be sent.\n **/\nJitsiConference.prototype.sendCommandOnce = function(name, values) {\n this.sendCommand(name, values);\n this.removeCommand(name);\n};\n\n/**\n * Removes presence command.\n * @param name {String} the name of the command.\n **/\nJitsiConference.prototype.removeCommand = function(name) {\n if (this.room) {\n this.room.removeFromPresence(name);\n }\n};\n\n/**\n * Sets the display name for this conference.\n * @param name the display name to set\n */\nJitsiConference.prototype.setDisplayName = function(name) {\n if (this.room) {\n // remove previously set nickname\n this.room.removeFromPresence('nick');\n\n this.room.addToPresence('nick', {\n attributes: { xmlns: 'http://jabber.org/protocol/nick' },\n value: name\n });\n this.room.sendPresence();\n }\n};\n\n/**\n * Set new subject for this conference. (available only for moderator)\n * @param {string} subject new subject\n */\nJitsiConference.prototype.setSubject = function(subject) {\n if (this.room && this.isModerator()) {\n this.room.setSubject(subject);\n }\n};\n\n/**\n * Get a transcriber object for all current participants in this conference\n * @return {Transcriber} the transcriber object\n */\nJitsiConference.prototype.getTranscriber = function() {\n if (this.transcriber === undefined) {\n this.transcriber = new Transcriber();\n\n // add all existing local audio tracks to the transcriber\n const localAudioTracks = this.getLocalTracks(MediaType.AUDIO);\n\n for (const localAudio of localAudioTracks) {\n this.transcriber.addTrack(localAudio);\n }\n\n // and all remote audio tracks\n const remoteAudioTracks = this.rtc.getRemoteTracks(MediaType.AUDIO);\n\n for (const remoteTrack of remoteAudioTracks) {\n this.transcriber.addTrack(remoteTrack);\n }\n }\n\n return this.transcriber;\n};\n\n/**\n * Returns the transcription status.\n *\n * @returns {String} \"on\" or \"off\".\n */\nJitsiConference.prototype.getTranscriptionStatus = function() {\n return this.room.transcriptionStatus;\n};\n\n/**\n * Adds JitsiLocalTrack object to the conference.\n * @param track the JitsiLocalTrack object.\n * @returns {Promise}\n * @throws {Error} if the specified track is a video track and there is already\n * another video track in the conference.\n */\nJitsiConference.prototype.addTrack = function(track) {\n if (track.isVideoTrack()) {\n // Ensure there's exactly 1 local video track in the conference.\n const localVideoTrack = this.rtc.getLocalVideoTrack();\n\n if (localVideoTrack) {\n // Don't be excessively harsh and severe if the API client happens\n // to attempt to add the same local video track twice.\n if (track === localVideoTrack) {\n return Promise.resolve(track);\n }\n\n return Promise.reject(new Error(\n 'cannot add second video track to the conference'));\n\n }\n }\n\n return this.replaceTrack(null, track);\n};\n\n/**\n * Fires TRACK_AUDIO_LEVEL_CHANGED change conference event (for local tracks).\n * @param {number} audioLevel the audio level\n * @param {TraceablePeerConnection} [tpc]\n */\nJitsiConference.prototype._fireAudioLevelChangeEvent = function(\n audioLevel,\n tpc) {\n const activeTpc = this.getActivePeerConnection();\n\n // There will be no TraceablePeerConnection if audio levels do not come from\n // a peerconnection. LocalStatsCollector.js measures audio levels using Web\n // Audio Analyser API and emits local audio levels events through\n // JitsiTrack.setAudioLevel, but does not provide TPC instance which is\n // optional.\n if (!tpc || activeTpc === tpc) {\n this.eventEmitter.emit(\n JitsiConferenceEvents.TRACK_AUDIO_LEVEL_CHANGED,\n this.myUserId(), audioLevel);\n }\n};\n\n/**\n * Fires TRACK_MUTE_CHANGED change conference event.\n * @param track the JitsiTrack object related to the event.\n */\nJitsiConference.prototype._fireMuteChangeEvent = function(track) {\n // check if track was muted by focus and now is unmuted by user\n if (this.isMutedByFocus && track.isAudioTrack() && !track.isMuted()) {\n this.isMutedByFocus = false;\n\n // unmute local user on server\n this.room.muteParticipant(this.room.myroomjid, false);\n }\n\n let actorParticipant;\n\n if (this.mutedByFocusActor) {\n const actorId = Strophe.getResourceFromJid(this.mutedByFocusActor);\n\n actorParticipant = this.participants[actorId];\n }\n\n this.eventEmitter.emit(JitsiConferenceEvents.TRACK_MUTE_CHANGED, track, actorParticipant);\n};\n\n/**\n * Clear JitsiLocalTrack properties and listeners.\n * @param track the JitsiLocalTrack object.\n */\nJitsiConference.prototype.onLocalTrackRemoved = function(track) {\n track._setConference(null);\n this.rtc.removeLocalTrack(track);\n track.removeEventListener(JitsiTrackEvents.TRACK_MUTE_CHANGED,\n track.muteHandler);\n track.removeEventListener(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,\n track.audioLevelHandler);\n\n // send event for stopping screen sharing\n // FIXME: we assume we have only one screen sharing track\n // if we change this we need to fix this check\n if (track.isVideoTrack() && track.videoType === VideoType.DESKTOP) {\n this.statistics.sendScreenSharingEvent(false);\n }\n\n this.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, track);\n};\n\n/**\n * Removes JitsiLocalTrack from the conference and performs\n * a new offer/answer cycle.\n * @param {JitsiLocalTrack} track\n * @returns {Promise}\n */\nJitsiConference.prototype.removeTrack = function(track) {\n return this.replaceTrack(track, null);\n};\n\n/**\n * Replaces oldTrack with newTrack and performs a single offer/answer\n * cycle after both operations are done. Either oldTrack or newTrack\n * can be null; replacing a valid 'oldTrack' with a null 'newTrack'\n * effectively just removes 'oldTrack'\n * @param {JitsiLocalTrack} oldTrack the current stream in use to be replaced\n * @param {JitsiLocalTrack} newTrack the new stream to use\n * @returns {Promise} resolves when the replacement is finished\n */\nJitsiConference.prototype.replaceTrack = function(oldTrack, newTrack) {\n // First do the removal of the oldTrack at the JitsiConference level\n if (oldTrack) {\n if (oldTrack.disposed) {\n return Promise.reject(\n new JitsiTrackError(JitsiTrackErrors.TRACK_IS_DISPOSED));\n }\n }\n if (newTrack) {\n if (newTrack.disposed) {\n return Promise.reject(\n new JitsiTrackError(JitsiTrackErrors.TRACK_IS_DISPOSED));\n }\n }\n\n // Now replace the stream at the lower levels\n return this._doReplaceTrack(oldTrack, newTrack)\n .then(() => {\n if (oldTrack) {\n this.onLocalTrackRemoved(oldTrack);\n }\n if (newTrack) {\n // Now handle the addition of the newTrack at the\n // JitsiConference level\n this._setupNewTrack(newTrack);\n }\n\n return Promise.resolve();\n }, error => Promise.reject(new Error(error)));\n};\n\n/**\n * Replaces the tracks at the lower level by going through the Jingle session\n * and WebRTC peer connection. The method will resolve immediately if there is\n * currently no JingleSession started.\n * @param {JitsiLocalTrack|null} oldTrack the track to be removed during\n * the process or null if the method should act as \"add track\"\n * @param {JitsiLocalTrack|null} newTrack the new track to be added or\n * null if the method should act as \"remove track\"\n * @return {Promise} resolved when the process is done or rejected with a string\n * which describes the error.\n * @private\n */\nJitsiConference.prototype._doReplaceTrack = function(oldTrack, newTrack) {\n const replaceTrackPromises = [];\n\n if (this.jvbJingleSession) {\n replaceTrackPromises.push(\n this.jvbJingleSession.replaceTrack(oldTrack, newTrack));\n } else {\n logger.info('_doReplaceTrack - no JVB JingleSession');\n }\n\n if (this.p2pJingleSession) {\n replaceTrackPromises.push(\n this.p2pJingleSession.replaceTrack(oldTrack, newTrack));\n } else {\n logger.info('_doReplaceTrack - no P2P JingleSession');\n }\n\n return Promise.all(replaceTrackPromises);\n};\n\n/**\n * Operations related to creating a new track\n * @param {JitsiLocalTrack} newTrack the new track being created\n */\nJitsiConference.prototype._setupNewTrack = function(newTrack) {\n if (newTrack.isAudioTrack() || (newTrack.isVideoTrack()\n && newTrack.videoType !== VideoType.DESKTOP)) {\n // Report active device to statistics\n const devices = RTC.getCurrentlyAvailableMediaDevices();\n const device\n = devices.find(\n d =>\n d.kind === `${newTrack.getTrack().kind}input`\n && d.label === newTrack.getTrack().label);\n\n if (device) {\n Statistics.sendActiveDeviceListEvent(\n RTC.getEventDataForActiveDevice(device));\n }\n }\n if (newTrack.isVideoTrack()) {\n this.removeCommand('videoType');\n this.sendCommand('videoType', {\n value: newTrack.videoType,\n attributes: {\n xmlns: 'http://jitsi.org/jitmeet/video'\n }\n });\n }\n this.rtc.addLocalTrack(newTrack);\n\n // ensure that we're sharing proper \"is muted\" state\n if (newTrack.isAudioTrack()) {\n this.room.setAudioMute(newTrack.isMuted());\n } else {\n this.room.setVideoMute(newTrack.isMuted());\n }\n\n newTrack.muteHandler = this._fireMuteChangeEvent.bind(this, newTrack);\n newTrack.audioLevelHandler = this._fireAudioLevelChangeEvent.bind(this);\n newTrack.addEventListener(\n JitsiTrackEvents.TRACK_MUTE_CHANGED,\n newTrack.muteHandler);\n newTrack.addEventListener(\n JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,\n newTrack.audioLevelHandler);\n\n newTrack._setConference(this);\n\n this.eventEmitter.emit(JitsiConferenceEvents.TRACK_ADDED, newTrack);\n};\n\n/**\n * Method called by the {@link JitsiLocalTrack} (a video one) in order to add\n * back the underlying WebRTC MediaStream to the PeerConnection (which has\n * removed on video mute).\n * @param {JitsiLocalTrack} track the local track that will be added as part of\n * the unmute operation.\n * @return {Promise} resolved when the process is done or rejected with a string\n * which describes the error.\n */\nJitsiConference.prototype._addLocalTrackAsUnmute = function(track) {\n const addAsUnmutePromises = [];\n\n if (this.jvbJingleSession) {\n addAsUnmutePromises.push(this.jvbJingleSession.addTrackAsUnmute(track));\n } else {\n logger.info(\n 'Add local MediaStream as unmute -'\n + ' no JVB Jingle session started yet');\n }\n\n if (this.p2pJingleSession) {\n addAsUnmutePromises.push(this.p2pJingleSession.addTrackAsUnmute(track));\n } else {\n logger.info(\n 'Add local MediaStream as unmute -'\n + ' no P2P Jingle session started yet');\n }\n\n return Promise.all(addAsUnmutePromises);\n};\n\n/**\n * Method called by the {@link JitsiLocalTrack} (a video one) in order to remove\n * the underlying WebRTC MediaStream from the PeerConnection. The purpose of\n * that is to stop sending any data and turn off the HW camera device.\n * @param {JitsiLocalTrack} track the local track that will be removed.\n * @return {Promise}\n */\nJitsiConference.prototype._removeLocalTrackAsMute = function(track) {\n const removeAsMutePromises = [];\n\n if (this.jvbJingleSession) {\n removeAsMutePromises.push(\n this.jvbJingleSession.removeTrackAsMute(track));\n } else {\n logger.info(\n 'Remove local MediaStream - no JVB JingleSession started yet');\n }\n if (this.p2pJingleSession) {\n removeAsMutePromises.push(\n this.p2pJingleSession.removeTrackAsMute(track));\n } else {\n logger.info(\n 'Remove local MediaStream - no P2P JingleSession started yet');\n }\n\n return Promise.all(removeAsMutePromises);\n};\n\n/**\n * Get role of the local user.\n * @returns {string} user role: 'moderator' or 'none'\n */\nJitsiConference.prototype.getRole = function() {\n return this.room.role;\n};\n\n/**\n * Returns whether or not the current conference has been joined as a hidden\n * user.\n *\n * @returns {boolean|null} True if hidden, false otherwise. Will return null if\n * no connection is active.\n */\nJitsiConference.prototype.isHidden = function() {\n if (!this.connection) {\n return null;\n }\n\n return Strophe.getDomainFromJid(this.connection.getJid())\n === this.options.config.hiddenDomain;\n};\n\n/**\n * Check if local user is moderator.\n * @returns {boolean|null} true if local user is moderator, false otherwise. If\n * we're no longer in the conference room then null is returned.\n */\nJitsiConference.prototype.isModerator = function() {\n return this.room ? this.room.isModerator() : null;\n};\n\n/**\n * Set password for the room.\n * @param {string} password new password for the room.\n * @returns {Promise}\n */\nJitsiConference.prototype.lock = function(password) {\n if (!this.isModerator()) {\n return Promise.reject(new Error('You are not moderator.'));\n }\n\n return new Promise((resolve, reject) => {\n this.room.lockRoom(\n password || '',\n () => resolve(),\n err => reject(err),\n () => reject(JitsiConferenceErrors.PASSWORD_NOT_SUPPORTED));\n });\n};\n\n/**\n * Remove password from the room.\n * @returns {Promise}\n */\nJitsiConference.prototype.unlock = function() {\n return this.lock();\n};\n\n/**\n * Elects the participant with the given id to be the selected participant in\n * order to receive higher video quality (if simulcast is enabled).\n * Or cache it if channel is not created and send it once channel is available.\n * @param participantId the identifier of the participant\n * @throws NetworkError or InvalidStateError or Error if the operation fails.\n * @returns {void}\n */\nJitsiConference.prototype.selectParticipant = function(participantId) {\n this.selectParticipants([ participantId ]);\n};\n\n/*\n * Elects participants with given ids to be the selected participants in order\n * to receive higher video quality (if simulcast is enabled). The argument\n * should be an array of participant id strings or an empty array; an error will\n * be thrown if a non-array is passed in. The error is thrown as a layer of\n * protection against passing an invalid argument, as the error will happen in\n * the bridge and may not be visible in the client.\n *\n * @param {Array} participantIds - An array of identifiers for\n * participants.\n * @returns {void}\n */\nJitsiConference.prototype.selectParticipants = function(participantIds) {\n if (!Array.isArray(participantIds)) {\n throw new Error('Invalid argument; participantIds must be an array.');\n }\n\n this.rtc.selectEndpoints(participantIds);\n};\n\n/**\n * Elects the participant with the given id to be the pinned participant in\n * order to always receive video for this participant (even when last n is\n * enabled).\n * @param participantId the identifier of the participant\n * @throws NetworkError or InvalidStateError or Error if the operation fails.\n */\nJitsiConference.prototype.pinParticipant = function(participantId) {\n this.rtc.pinEndpoint(participantId);\n};\n\n/**\n * Obtains the current value for \"lastN\". See {@link setLastN} for more info.\n * @returns {number}\n */\nJitsiConference.prototype.getLastN = function() {\n return this.rtc.getLastN();\n};\n\n/**\n * Selects a new value for \"lastN\". The requested amount of videos are going\n * to be delivered after the value is in effect. Set to -1 for unlimited or\n * all available videos.\n * @param lastN the new number of videos the user would like to receive.\n * @throws Error or RangeError if the given value is not a number or is smaller\n * than -1.\n */\nJitsiConference.prototype.setLastN = function(lastN) {\n if (!Number.isInteger(lastN) && !Number.parseInt(lastN, 10)) {\n throw new Error(`Invalid value for lastN: ${lastN}`);\n }\n const n = Number(lastN);\n\n if (n < -1) {\n throw new RangeError('lastN cannot be smaller than -1');\n }\n this.rtc.setLastN(n);\n\n // If the P2P session is not fully established yet, we wait until it gets\n // established.\n if (this.p2pJingleSession) {\n const isVideoActive = n !== 0;\n\n this.p2pJingleSession\n .setMediaTransferActive(true, isVideoActive)\n .catch(error => {\n logger.error(\n `Failed to adjust video transfer status (${isVideoActive})`,\n error);\n });\n }\n};\n\n/**\n * Checks if the participant given by participantId is currently included in\n * the last N.\n * @param {string} participantId the identifier of the participant we would\n * like to check.\n * @return {boolean} true if the participant with id is in the last N set or\n * if there's no last N set, false otherwise.\n * @deprecated this method should never be used to figure out the UI, but\n * {@link ParticipantConnectionStatus} should be used instead.\n */\nJitsiConference.prototype.isInLastN = function(participantId) {\n return this.rtc.isInLastN(participantId);\n};\n\n/**\n * @return Array an array of all participants in this\n * conference.\n */\nJitsiConference.prototype.getParticipants = function() {\n return Object.keys(this.participants).map(function(key) {\n return this.participants[key];\n }, this);\n};\n\n/**\n * Returns the number of participants in the conference, including the local\n * participant.\n * @param countHidden {boolean} Whether or not to include hidden participants\n * in the count. Default: false.\n **/\nJitsiConference.prototype.getParticipantCount\n = function(countHidden = false) {\n\n let participants = this.getParticipants();\n\n if (!countHidden) {\n participants = participants.filter(p => !p.isHidden());\n }\n\n // Add one for the local participant.\n return participants.length + 1;\n };\n\n/**\n * @returns {JitsiParticipant} the participant in this conference with the\n * specified id (or undefined if there isn't one).\n * @param id the id of the participant.\n */\nJitsiConference.prototype.getParticipantById = function(id) {\n return this.participants[id];\n};\n\n/**\n * Kick participant from this conference.\n * @param {string} id id of the participant to kick\n */\nJitsiConference.prototype.kickParticipant = function(id) {\n const participant = this.getParticipantById(id);\n\n if (!participant) {\n return;\n }\n this.room.kick(participant.getJid());\n};\n\n/**\n * Maybe clears the timeout which emits {@link ACTION_JINGLE_SI_TIMEOUT}\n * analytics event.\n * @private\n */\nJitsiConference.prototype._maybeClearSITimeout = function() {\n if (this._sessionInitiateTimeout\n && (this.jvbJingleSession || this.getParticipantCount() < 2)) {\n window.clearTimeout(this._sessionInitiateTimeout);\n this._sessionInitiateTimeout = null;\n }\n};\n\n/**\n * Sets a timeout which will emit {@link ACTION_JINGLE_SI_TIMEOUT} analytics\n * event.\n * @private\n */\nJitsiConference.prototype._maybeSetSITimeout = function() {\n // Jicofo is supposed to invite if there are at least 2 participants\n if (!this.jvbJingleSession\n && this.getParticipantCount() >= 2\n && !this._sessionInitiateTimeout) {\n this._sessionInitiateTimeout = window.setTimeout(() => {\n this._sessionInitiateTimeout = null;\n Statistics.sendAnalytics(createJingleEvent(\n ACTION_JINGLE_SI_TIMEOUT,\n {\n p2p: false,\n value: JINGLE_SI_TIMEOUT\n }));\n }, JINGLE_SI_TIMEOUT);\n }\n};\n\n/**\n * Mutes a participant.\n * @param {string} id The id of the participant to mute.\n */\nJitsiConference.prototype.muteParticipant = function(id) {\n const participant = this.getParticipantById(id);\n\n if (!participant) {\n return;\n }\n this.room.muteParticipant(participant.getJid(), true);\n};\n\n/* eslint-disable max-params */\n\n/**\n * Notifies this JitsiConference that a new member has joined its chat room.\n *\n * FIXME This should NOT be exposed!\n *\n * @param jid the jid of the participant in the MUC\n * @param nick the display name of the participant\n * @param role the role of the participant in the MUC\n * @param isHidden indicates if this is a hidden participant (system\n * participant for example a recorder).\n * @param statsID the participant statsID (optional)\n * @param status the initial status if any\n * @param identity the member identity, if any\n * @param botType the member botType, if any\n */\nJitsiConference.prototype.onMemberJoined = function(\n jid, nick, role, isHidden, statsID, status, identity, botType) {\n const id = Strophe.getResourceFromJid(jid);\n\n if (id === 'focus' || this.myUserId() === id) {\n return;\n }\n\n const participant\n = new JitsiParticipant(jid, this, nick, isHidden, statsID, status, identity);\n\n participant._role = role;\n participant._botType = botType;\n this.participants[id] = participant;\n this.eventEmitter.emit(\n JitsiConferenceEvents.USER_JOINED,\n id,\n participant);\n\n this._updateFeatures(participant);\n\n this._maybeStartOrStopP2P();\n this._maybeSetSITimeout();\n};\n\n/* eslint-enable max-params */\n\n/**\n * Updates features for a participant.\n * @param {JitsiParticipant} participant - The participant to query for features.\n * @returns {void}\n * @private\n */\nJitsiConference.prototype._updateFeatures = function(participant) {\n participant.getFeatures()\n .then(features => {\n participant._supportsDTMF = features.has('urn:xmpp:jingle:dtmf:0');\n this.updateDTMFSupport();\n\n if (features.has('http://jitsi.org/protocol/jigasi')) {\n participant.setProperty('features_jigasi', true);\n }\n\n if (features.has('https://jitsi.org/meet/e2ee')) {\n participant.setProperty('features_e2ee', true);\n }\n })\n .catch(() => false);\n};\n\n/**\n * Get notified when member bot type had changed.\n * @param jid the member jid\n * @param botType the new botType value\n * @private\n */\nJitsiConference.prototype._onMemberBotTypeChanged = function(jid, botType) {\n\n // find the participant and mark it as non bot, as the real one will join\n // in a moment\n const peers = this.getParticipants();\n const botParticipant = peers.find(p => p.getJid() === jid);\n\n if (botParticipant) {\n botParticipant._botType = botType;\n const id = Strophe.getResourceFromJid(jid);\n\n this.eventEmitter.emit(\n JitsiConferenceEvents.BOT_TYPE_CHANGED,\n id,\n botType);\n }\n\n // if botType changed to undefined, botType was removed, in case of\n // poltergeist mode this is the moment when the poltergeist had exited and\n // the real participant had already replaced it.\n // In this case we can check and try p2p\n if (!botParticipant._botType) {\n this._maybeStartOrStopP2P();\n }\n};\n\nJitsiConference.prototype.onMemberLeft = function(jid) {\n const id = Strophe.getResourceFromJid(jid);\n\n if (id === 'focus' || this.myUserId() === id) {\n return;\n }\n\n const participant = this.participants[id];\n\n delete this.participants[id];\n\n const removedTracks = this.rtc.removeRemoteTracks(id);\n\n removedTracks.forEach(\n track =>\n this.eventEmitter.emit(JitsiConferenceEvents.TRACK_REMOVED, track));\n\n // there can be no participant in case the member that left is focus\n if (participant) {\n this.eventEmitter.emit(\n JitsiConferenceEvents.USER_LEFT, id, participant);\n }\n\n this._maybeStartOrStopP2P(true /* triggered by user left event */);\n this._maybeClearSITimeout();\n};\n\n/**\n * Designates an event indicating that we were kicked from the XMPP MUC.\n * @param {boolean} isSelfPresence - whether it is for local participant\n * or another participant.\n * @param {string} actorId - the id of the participant who was initiator\n * of the kick.\n * @param {string?} kickedParticipantId - when it is not a kick for local participant,\n * this is the id of the participant which was kicked.\n */\nJitsiConference.prototype.onMemberKicked = function(isSelfPresence, actorId, kickedParticipantId) {\n const actorParticipant = this.participants[actorId];\n\n if (isSelfPresence) {\n this.eventEmitter.emit(\n JitsiConferenceEvents.KICKED, actorParticipant);\n\n this.leave();\n\n return;\n }\n\n const kickedParticipant = this.participants[kickedParticipantId];\n\n this.eventEmitter.emit(\n JitsiConferenceEvents.PARTICIPANT_KICKED, actorParticipant, kickedParticipant);\n};\n\n/**\n * Method called on local MUC role change.\n * @param {string} role the name of new user's role as defined by XMPP MUC.\n */\nJitsiConference.prototype.onLocalRoleChanged = function(role) {\n // Emit role changed for local JID\n this.eventEmitter.emit(\n JitsiConferenceEvents.USER_ROLE_CHANGED, this.myUserId(), role);\n};\n\nJitsiConference.prototype.onUserRoleChanged = function(jid, role) {\n const id = Strophe.getResourceFromJid(jid);\n const participant = this.getParticipantById(id);\n\n if (!participant) {\n return;\n }\n participant._role = role;\n this.eventEmitter.emit(JitsiConferenceEvents.USER_ROLE_CHANGED, id, role);\n};\n\nJitsiConference.prototype.onDisplayNameChanged = function(jid, displayName) {\n const id = Strophe.getResourceFromJid(jid);\n const participant = this.getParticipantById(id);\n\n if (!participant) {\n return;\n }\n\n if (participant._displayName === displayName) {\n return;\n }\n\n participant._displayName = displayName;\n this.eventEmitter.emit(\n JitsiConferenceEvents.DISPLAY_NAME_CHANGED,\n id,\n displayName);\n};\n\n/**\n * Notifies this JitsiConference that a JitsiRemoteTrack was added into\n * the conference.\n *\n * @param {JitsiRemoteTrack} track the JitsiRemoteTrack which was added to this\n * JitsiConference\n */\nJitsiConference.prototype.onRemoteTrackAdded = function(track) {\n if (track.isP2P && !this.isP2PActive()) {\n logger.info(\n 'Trying to add remote P2P track, when not in P2P - IGNORED');\n\n return;\n } else if (!track.isP2P && this.isP2PActive()) {\n logger.info(\n 'Trying to add remote JVB track, when in P2P - IGNORED');\n\n return;\n }\n\n // Setup E2EE handling, if supported.\n this._setupReceiverE2EEForTrack(track);\n\n const id = track.getParticipantId();\n const participant = this.getParticipantById(id);\n\n if (!participant) {\n logger.error(`No participant found for id: ${id}`);\n\n return;\n }\n\n // Add track to JitsiParticipant.\n participant._tracks.push(track);\n\n if (this.transcriber) {\n this.transcriber.addTrack(track);\n }\n\n const emitter = this.eventEmitter;\n\n track.addEventListener(\n JitsiTrackEvents.TRACK_MUTE_CHANGED,\n () => emitter.emit(JitsiConferenceEvents.TRACK_MUTE_CHANGED, track));\n track.addEventListener(\n JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,\n (audioLevel, tpc) => {\n const activeTPC = this.getActivePeerConnection();\n\n if (activeTPC === tpc) {\n emitter.emit(\n JitsiConferenceEvents.TRACK_AUDIO_LEVEL_CHANGED,\n id,\n audioLevel);\n }\n }\n );\n\n emitter.emit(JitsiConferenceEvents.TRACK_ADDED, track);\n};\n\n/**\n * Callback called by the Jingle plugin when 'session-answer' is received.\n * @param {JingleSessionPC} session the Jingle session for which an answer was\n * received.\n * @param {jQuery} answer a jQuery selector pointing to 'jingle' IQ element\n */\n// eslint-disable-next-line no-unused-vars\nJitsiConference.prototype.onCallAccepted = function(session, answer) {\n if (this.p2pJingleSession === session) {\n logger.info('P2P setAnswer');\n\n // Setup E2EE.\n const localTracks = this.getLocalTracks();\n\n for (const track of localTracks) {\n this._setupSenderE2EEForTrack(session, track);\n }\n\n this.p2pJingleSession.setAnswer(answer);\n }\n};\n\n/**\n * Callback called by the Jingle plugin when 'transport-info' is received.\n * @param {JingleSessionPC} session the Jingle session for which the IQ was\n * received\n * @param {jQuery} transportInfo a jQuery selector pointing to 'jingle' IQ\n * element\n */\n// eslint-disable-next-line no-unused-vars\nJitsiConference.prototype.onTransportInfo = function(session, transportInfo) {\n if (this.p2pJingleSession === session) {\n logger.info('P2P addIceCandidates');\n this.p2pJingleSession.addIceCandidates(transportInfo);\n }\n};\n\n/**\n * Notifies this JitsiConference that a JitsiRemoteTrack was removed from\n * the conference.\n *\n * @param {JitsiRemoteTrack} removedTrack\n */\nJitsiConference.prototype.onRemoteTrackRemoved = function(removedTrack) {\n this.getParticipants().forEach(participant => {\n const tracks = participant.getTracks();\n\n for (let i = 0; i < tracks.length; i++) {\n if (tracks[i] === removedTrack) {\n // Since the tracks have been compared and are\n // considered equal the result of splice can be ignored.\n participant._tracks.splice(i, 1);\n\n this.eventEmitter.emit(\n JitsiConferenceEvents.TRACK_REMOVED, removedTrack);\n\n if (this.transcriber) {\n this.transcriber.removeTrack(removedTrack);\n }\n\n break;\n }\n }\n }, this);\n};\n\n/**\n * Handles an incoming call event for the P2P jingle session.\n */\nJitsiConference.prototype._onIncomingCallP2P = function(\n jingleSession,\n jingleOffer) {\n\n let rejectReason;\n\n if (!browser.supportsP2P()) {\n rejectReason = {\n reason: 'unsupported-applications',\n reasonDescription: 'P2P not supported',\n errorMsg: 'This client does not support P2P connections'\n };\n } else if (!this.isP2PEnabled() && !this.isP2PTestModeEnabled()) {\n rejectReason = {\n reason: 'decline',\n reasonDescription: 'P2P disabled',\n errorMsg: 'P2P mode disabled in the configuration'\n };\n } else if (this.p2pJingleSession) {\n // Reject incoming P2P call (already in progress)\n rejectReason = {\n reason: 'busy',\n reasonDescription: 'P2P already in progress',\n errorMsg: 'Duplicated P2P \"session-initiate\"'\n };\n } else if (!this._shouldBeInP2PMode()) {\n rejectReason = {\n reason: 'decline',\n reasonDescription: 'P2P requirements not met',\n errorMsg: 'Received P2P \"session-initiate\" when should not be in P2P mode'\n };\n Statistics.sendAnalytics(createJingleEvent(ACTION_P2P_DECLINED));\n }\n\n if (rejectReason) {\n this._rejectIncomingCall(jingleSession, rejectReason);\n } else {\n this._acceptP2PIncomingCall(jingleSession, jingleOffer);\n }\n};\n\n/**\n * Handles an incoming call event.\n */\nJitsiConference.prototype.onIncomingCall = function(\n jingleSession,\n jingleOffer,\n now) {\n // Handle incoming P2P call\n if (jingleSession.isP2P) {\n this._onIncomingCallP2P(jingleSession, jingleOffer);\n } else {\n if (!this.room.isFocus(jingleSession.remoteJid)) {\n const description = 'Rejecting session-initiate from non-focus.';\n\n this._rejectIncomingCall(\n jingleSession, {\n reason: 'security-error',\n reasonDescription: description,\n errorMsg: description\n });\n\n return;\n }\n this._acceptJvbIncomingCall(jingleSession, jingleOffer, now);\n }\n};\n\n/**\n * Accepts an incoming call event for the JVB jingle session.\n */\nJitsiConference.prototype._acceptJvbIncomingCall = function(\n jingleSession,\n jingleOffer,\n now) {\n\n // Accept incoming call\n this.jvbJingleSession = jingleSession;\n this.room.connectionTimes['session.initiate'] = now;\n this._sendConferenceJoinAnalyticsEvent();\n\n if (this.wasStopped) {\n Statistics.sendAnalyticsAndLog(\n createJingleEvent(ACTION_JINGLE_RESTART, { p2p: false }));\n }\n\n const serverRegion\n = $(jingleOffer)\n .find('>bridge-session[xmlns=\"http://jitsi.org/protocol/focus\"]')\n .attr('region');\n\n this.eventEmitter.emit(\n JitsiConferenceEvents.SERVER_REGION_CHANGED,\n serverRegion);\n\n this._maybeClearSITimeout();\n Statistics.sendAnalytics(createJingleEvent(\n ACTION_JINGLE_SI_RECEIVED,\n {\n p2p: false,\n value: now\n }));\n\n try {\n jingleSession.initialize(this.room, this.rtc, this.options.config);\n } catch (error) {\n GlobalOnErrorHandler.callErrorHandler(error);\n }\n\n // Open a channel with the videobridge.\n this._setBridgeChannel(jingleOffer, jingleSession.peerconnection);\n\n // Add local tracks to the session\n const localTracks = this.getLocalTracks();\n\n try {\n jingleSession.acceptOffer(\n jingleOffer,\n () => {\n // If for any reason invite for the JVB session arrived after\n // the P2P has been established already the media transfer needs\n // to be turned off here.\n if (this.isP2PActive() && this.jvbJingleSession) {\n this._suspendMediaTransferForJvbConnection();\n }\n\n // Setup E2EE.\n for (const track of localTracks) {\n this._setupSenderE2EEForTrack(jingleSession, track);\n }\n },\n error => {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error(\n 'Failed to accept incoming Jingle session', error);\n },\n localTracks\n );\n\n // Start callstats as soon as peerconnection is initialized,\n // do not wait for XMPPEvents.PEERCONNECTION_READY, as it may never\n // happen in case if user doesn't have or denied permission to\n // both camera and microphone.\n logger.info('Starting CallStats for JVB connection...');\n this.statistics.startCallStats(\n this.jvbJingleSession.peerconnection,\n 'jitsi' /* Remote user ID for JVB is 'jitsi' */);\n this.statistics.startRemoteStats(this.jvbJingleSession.peerconnection);\n } catch (e) {\n GlobalOnErrorHandler.callErrorHandler(e);\n logger.error(e);\n }\n};\n\n/**\n * Sets the BridgeChannel.\n *\n * @param {jQuery} offerIq a jQuery selector pointing to the jingle element of\n * the offer IQ which may carry the WebSocket URL for the 'websocket'\n * BridgeChannel mode.\n * @param {TraceablePeerConnection} pc the peer connection which will be used\n * to listen for new WebRTC Data Channels (in the 'datachannel' mode).\n */\nJitsiConference.prototype._setBridgeChannel = function(offerIq, pc) {\n let wsUrl = null;\n const webSocket\n = $(offerIq)\n .find('>content>transport>web-socket')\n .first();\n\n if (webSocket.length === 1) {\n wsUrl = webSocket[0].getAttribute('url');\n }\n\n let bridgeChannelType;\n\n switch (this.options.config.openBridgeChannel) {\n case 'datachannel':\n case true:\n case undefined:\n bridgeChannelType = 'datachannel';\n break;\n case 'websocket':\n bridgeChannelType = 'websocket';\n break;\n }\n\n if (bridgeChannelType === 'datachannel') {\n this.rtc.initializeBridgeChannel(pc, null);\n } else if (bridgeChannelType === 'websocket' && wsUrl) {\n this.rtc.initializeBridgeChannel(null, wsUrl);\n }\n};\n\n/**\n * Rejects incoming Jingle call.\n * @param {JingleSessionPC} jingleSession the session instance to be rejected.\n * @param {object} [options]\n * @param {string} options.reason the name of the reason element as defined\n * by Jingle\n * @param {string} options.reasonDescription the reason description which will\n * be included in Jingle 'session-terminate' message.\n * @param {string} options.errorMsg an error message to be logged on global\n * error handler\n * @private\n */\nJitsiConference.prototype._rejectIncomingCall = function(\n jingleSession,\n options) {\n if (options && options.errorMsg) {\n GlobalOnErrorHandler.callErrorHandler(new Error(options.errorMsg));\n }\n\n // Terminate the jingle session with a reason\n jingleSession.terminate(\n null /* success callback => we don't care */,\n error => {\n logger.warn(\n 'An error occurred while trying to terminate'\n + ' invalid Jingle session', error);\n }, {\n reason: options && options.reason,\n reasonDescription: options && options.reasonDescription,\n sendSessionTerminate: true\n });\n};\n\n/**\n * Handles the call ended event.\n * XXX is this due to the remote side terminating the Jingle session?\n *\n * @param {JingleSessionPC} jingleSession the jingle session which has been\n * terminated.\n * @param {String} reasonCondition the Jingle reason condition.\n * @param {String|null} reasonText human readable reason text which may provide\n * more details about why the call has been terminated.\n */\nJitsiConference.prototype.onCallEnded = function(\n jingleSession,\n reasonCondition,\n reasonText) {\n logger.info(\n `Call ended: ${reasonCondition} - ${reasonText} P2P ?${\n jingleSession.isP2P}`);\n if (jingleSession === this.jvbJingleSession) {\n this.wasStopped = true;\n\n Statistics.sendAnalytics(\n createJingleEvent(ACTION_JINGLE_TERMINATE, { p2p: false }));\n\n // Stop the stats\n if (this.statistics) {\n this.statistics.stopRemoteStats(\n this.jvbJingleSession.peerconnection);\n logger.info('Stopping JVB CallStats');\n this.statistics.stopCallStats(\n this.jvbJingleSession.peerconnection);\n }\n\n // Current JVB JingleSession is no longer valid, so set it to null\n this.jvbJingleSession = null;\n\n // Let the RTC service do any cleanups\n this.rtc.onCallEnded();\n } else if (jingleSession === this.p2pJingleSession) {\n // It's the responder who decides to enforce JVB mode, so that both\n // initiator and responder are aware if it was intentional.\n if (reasonCondition === 'decline' && reasonText === 'force JVB121') {\n logger.info('In forced JVB 121 mode...');\n Statistics.analytics.addPermanentProperties({ forceJvb121: true });\n } else if (reasonCondition === 'connectivity-error'\n && reasonText === 'ICE FAILED') {\n // It can happen that the other peer detects ICE failed and\n // terminates the session, before we get the event on our side.\n // But we are able to parse the reason and mark it here.\n Statistics.analytics.addPermanentProperties({ p2pFailed: true });\n }\n this._stopP2PSession();\n } else {\n logger.error(\n 'Received onCallEnded for invalid session',\n jingleSession.sid,\n jingleSession.remoteJid,\n reasonCondition,\n reasonText);\n }\n};\n\n/**\n * Handles the suspend detected event. Leaves the room and fires suspended.\n * @param {JingleSessionPC} jingleSession\n */\nJitsiConference.prototype.onSuspendDetected = function(jingleSession) {\n if (!jingleSession.isP2P) {\n this.leave();\n this.eventEmitter.emit(JitsiConferenceEvents.SUSPEND_DETECTED);\n }\n};\n\nJitsiConference.prototype.updateDTMFSupport = function() {\n let somebodySupportsDTMF = false;\n const participants = this.getParticipants();\n\n // check if at least 1 participant supports DTMF\n for (let i = 0; i < participants.length; i += 1) {\n if (participants[i].supportsDTMF()) {\n somebodySupportsDTMF = true;\n break;\n }\n }\n if (somebodySupportsDTMF !== this.somebodySupportsDTMF) {\n this.somebodySupportsDTMF = somebodySupportsDTMF;\n this.eventEmitter.emit(\n JitsiConferenceEvents.DTMF_SUPPORT_CHANGED,\n somebodySupportsDTMF);\n }\n};\n\n/**\n * Allows to check if there is at least one user in the conference\n * that supports DTMF.\n * @returns {boolean} true if somebody supports DTMF, false otherwise\n */\nJitsiConference.prototype.isDTMFSupported = function() {\n return this.somebodySupportsDTMF;\n};\n\n/**\n * Returns the local user's ID\n * @return {string} local user's ID\n */\nJitsiConference.prototype.myUserId = function() {\n return (\n this.room && this.room.myroomjid\n ? Strophe.getResourceFromJid(this.room.myroomjid)\n : null);\n};\n\nJitsiConference.prototype.sendTones = function(tones, duration, pause) {\n const peerConnection = this.getActivePeerConnection();\n\n if (peerConnection) {\n peerConnection.sendTones(tones, duration, pause);\n } else {\n logger.warn('cannot sendTones: no peer connection');\n }\n};\n\n/**\n * Starts recording the current conference.\n *\n * @param {Object} options - Configuration for the recording. See\n * {@link Chatroom#startRecording} for more info.\n * @returns {Promise} See {@link Chatroom#startRecording} for more info.\n */\nJitsiConference.prototype.startRecording = function(options) {\n if (this.room) {\n return this.recordingManager.startRecording(options);\n }\n\n return Promise.reject(new Error('The conference is not created yet!'));\n};\n\n/**\n * Stop a recording session.\n *\n * @param {string} sessionID - The ID of the recording session that\n * should be stopped.\n * @returns {Promise} See {@link Chatroom#stopRecording} for more info.\n */\nJitsiConference.prototype.stopRecording = function(sessionID) {\n if (this.room) {\n return this.recordingManager.stopRecording(sessionID);\n }\n\n return Promise.reject(new Error('The conference is not created yet!'));\n};\n\n/**\n * Returns true if the SIP calls are supported and false otherwise\n */\nJitsiConference.prototype.isSIPCallingSupported = function() {\n if (this.room) {\n return this.room.isSIPCallingSupported();\n }\n\n return false;\n};\n\n/**\n * Dials a number.\n * @param number the number\n */\nJitsiConference.prototype.dial = function(number) {\n if (this.room) {\n return this.room.dial(number);\n }\n\n return new Promise((resolve, reject) => {\n reject(new Error('The conference is not created yet!'));\n });\n};\n\n/**\n * Hangup an existing call\n */\nJitsiConference.prototype.hangup = function() {\n if (this.room) {\n return this.room.hangup();\n }\n\n return new Promise((resolve, reject) => {\n reject(new Error('The conference is not created yet!'));\n });\n};\n\n/**\n * Starts the transcription service.\n */\nJitsiConference.prototype.startTranscriber = function() {\n return this.dial('jitsi_meet_transcribe');\n};\n\n\n/**\n * Stops the transcription service.\n */\nJitsiConference.prototype.stopTranscriber = JitsiConference.prototype.hangup;\n\n/**\n * Returns the phone number for joining the conference.\n */\nJitsiConference.prototype.getPhoneNumber = function() {\n if (this.room) {\n return this.room.getPhoneNumber();\n }\n\n return null;\n};\n\n/**\n * Returns the pin for joining the conference with phone.\n */\nJitsiConference.prototype.getPhonePin = function() {\n if (this.room) {\n return this.room.getPhonePin();\n }\n\n return null;\n};\n\n/**\n * Returns the meeting unique ID if any.\n *\n * @returns {string|undefined}\n */\nJitsiConference.prototype.getMeetingUniqueId = function() {\n if (this.room) {\n return this.room.getMeetingId();\n }\n};\n\n/**\n * Will return P2P or JVB TraceablePeerConnection depending on\n * which connection is currently active.\n *\n * @return {TraceablePeerConnection|null} null if there isn't any active\n * TraceablePeerConnection currently available.\n * @public (FIXME how to make package local ?)\n */\nJitsiConference.prototype.getActivePeerConnection = function() {\n if (this.isP2PActive()) {\n return this.p2pJingleSession.peerconnection;\n }\n\n return this.jvbJingleSession ? this.jvbJingleSession.peerconnection : null;\n};\n\n/**\n * Returns the connection state for the current room. Its ice connection state\n * for its session.\n * NOTE that \"completed\" ICE state which can appear on the P2P connection will\n * be converted to \"connected\".\n * @return {string|null} ICE state name or null if there is no active\n * peer connection at this time.\n */\nJitsiConference.prototype.getConnectionState = function() {\n const peerConnection = this.getActivePeerConnection();\n\n return peerConnection ? peerConnection.getConnectionState() : null;\n};\n\n/**\n * Make all new participants mute their audio/video on join.\n * @param policy {Object} object with 2 boolean properties for video and audio:\n * @param {boolean} audio if audio should be muted.\n * @param {boolean} video if video should be muted.\n */\nJitsiConference.prototype.setStartMutedPolicy = function(policy) {\n if (!this.isModerator()) {\n return;\n }\n this.startMutedPolicy = policy;\n this.room.removeFromPresence('startmuted');\n this.room.addToPresence('startmuted', {\n attributes: {\n audio: policy.audio,\n video: policy.video,\n xmlns: 'http://jitsi.org/jitmeet/start-muted'\n }\n });\n this.room.sendPresence();\n};\n\n/**\n * Returns current start muted policy\n * @returns {Object} with 2 properties - audio and video.\n */\nJitsiConference.prototype.getStartMutedPolicy = function() {\n return this.startMutedPolicy;\n};\n\n/**\n * Check if audio is muted on join.\n */\nJitsiConference.prototype.isStartAudioMuted = function() {\n return this.startAudioMuted;\n};\n\n/**\n * Check if video is muted on join.\n */\nJitsiConference.prototype.isStartVideoMuted = function() {\n return this.startVideoMuted;\n};\n\n/**\n * Get object with internal logs.\n */\nJitsiConference.prototype.getLogs = function() {\n const data = this.xmpp.getJingleLog();\n\n const metadata = {};\n\n metadata.time = new Date();\n metadata.url = window.location.href;\n metadata.ua = navigator.userAgent;\n\n const log = this.xmpp.getXmppLog();\n\n if (log) {\n metadata.xmpp = log;\n }\n\n data.metadata = metadata;\n\n return data;\n};\n\n/**\n * Returns measured connectionTimes.\n */\nJitsiConference.prototype.getConnectionTimes = function() {\n return this.room.connectionTimes;\n};\n\n/**\n * Sets a property for the local participant.\n */\nJitsiConference.prototype.setLocalParticipantProperty = function(name, value) {\n this.sendCommand(`jitsi_participant_${name}`, { value });\n};\n\n/**\n * Removes a property for the local participant and sends the updated presence.\n */\nJitsiConference.prototype.removeLocalParticipantProperty = function(name) {\n this.removeCommand(`jitsi_participant_${name}`);\n this.room.sendPresence();\n};\n\n/**\n * Gets a local participant property.\n *\n * @return value of the local participant property if the tagName exists in the\n * list of properties, otherwise returns undefined.\n */\nJitsiConference.prototype.getLocalParticipantProperty = function(name) {\n const property = this.room.presMap.nodes.find(prop =>\n prop.tagName === `jitsi_participant_${name}`\n );\n\n return property ? property.value : undefined;\n};\n\n/**\n * Sends the given feedback through CallStats if enabled.\n *\n * @param overallFeedback an integer between 1 and 5 indicating the\n * user feedback\n * @param detailedFeedback detailed feedback from the user. Not yet used\n * @returns {Promise} Resolves if feedback is submitted successfully.\n */\nJitsiConference.prototype.sendFeedback = function(\n overallFeedback,\n detailedFeedback) {\n return this.statistics.sendFeedback(overallFeedback, detailedFeedback);\n};\n\n/**\n * Returns true if the callstats integration is enabled, otherwise returns\n * false.\n *\n * @returns true if the callstats integration is enabled, otherwise returns\n * false.\n */\nJitsiConference.prototype.isCallstatsEnabled = function() {\n return this.statistics.isCallstatsEnabled();\n};\n\n\n/**\n * Handles track attached to container (Calls associateStreamWithVideoTag method\n * from statistics module)\n * @param {JitsiLocalTrack|JitsiRemoteTrack} track the track\n * @param container the container\n */\nJitsiConference.prototype._onTrackAttach = function(track, container) {\n const isLocal = track.isLocal();\n let ssrc = null;\n const isP2P = track.isP2P;\n const remoteUserId = isP2P ? track.getParticipantId() : 'jitsi';\n const peerConnection\n = isP2P\n ? this.p2pJingleSession && this.p2pJingleSession.peerconnection\n : this.jvbJingleSession && this.jvbJingleSession.peerconnection;\n\n if (isLocal) {\n // Local tracks have SSRC stored on per peer connection basis\n if (peerConnection) {\n ssrc = peerConnection.getLocalSSRC(track);\n }\n } else {\n ssrc = track.getSSRC();\n }\n if (!container.id || !ssrc || !peerConnection) {\n return;\n }\n\n this.statistics.associateStreamWithVideoTag(\n peerConnection,\n ssrc,\n isLocal,\n remoteUserId,\n track.getUsageLabel(),\n container.id);\n};\n\n/**\n * Logs an \"application log\" message.\n * @param message {string} The message to log. Note that while this can be a\n * generic string, the convention used by lib-jitsi-meet and jitsi-meet is to\n * log valid JSON strings, with an \"id\" field used for distinguishing between\n * message types. E.g.: {id: \"recorder_status\", status: \"off\"}\n */\nJitsiConference.prototype.sendApplicationLog = function(message) {\n Statistics.sendLog(message);\n};\n\n/**\n * Checks if the user identified by given mucJid is the conference\n * focus.\n * @param mucJid the full MUC address of the user to be checked.\n * @returns {boolean|null} true if MUC user is the conference focus,\n * false when is not. null if we're not in the MUC anymore and\n * are unable to figure out the status or if given mucJid is invalid.\n */\nJitsiConference.prototype._isFocus = function(mucJid) {\n return this.room ? this.room.isFocus(mucJid) : null;\n};\n\n/**\n * Fires CONFERENCE_FAILED event with INCOMPATIBLE_SERVER_VERSIONS parameter\n */\nJitsiConference.prototype._fireIncompatibleVersionsEvent = function() {\n this.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.INCOMPATIBLE_SERVER_VERSIONS);\n};\n\n/**\n * Sends a message via the data channel.\n * @param to {string} the id of the endpoint that should receive the message.\n * If \"\" the message will be sent to all participants.\n * @param payload {object} the payload of the message.\n * @throws NetworkError or InvalidStateError or Error if the operation fails.\n * @deprecated Use 'sendMessage' instead. TODO: this should be private.\n */\nJitsiConference.prototype.sendEndpointMessage = function(to, payload) {\n this.rtc.sendChannelMessage(to, payload);\n};\n\n/**\n * Sends a broadcast message via the data channel.\n * @param payload {object} the payload of the message.\n * @throws NetworkError or InvalidStateError or Error if the operation fails.\n * @deprecated Use 'sendMessage' instead. TODO: this should be private.\n */\nJitsiConference.prototype.broadcastEndpointMessage = function(payload) {\n this.sendEndpointMessage('', payload);\n};\n\n/**\n * Sends a message to a given endpoint (if 'to' is a non-empty string), or\n * broadcasts it to all endpoints in the conference.\n * @param {string} to The ID of the endpoint/participant which is to receive\n * the message, or '' to broadcast the message to all endpoints in the\n * conference.\n * @param {string|object} message the message to send. If this is of type\n * 'string' it will be sent as a chat message. If it is of type 'object', it\n * will be encapsulated in a format recognized by jitsi-meet and converted to\n * JSON before being sent.\n * @param {boolean} sendThroughVideobridge Whether to send the message through\n * jitsi-videobridge (via the COLIBRI data channel or web socket), or through\n * the XMPP MUC. Currently only objects can be sent through jitsi-videobridge.\n */\nJitsiConference.prototype.sendMessage = function(\n message,\n to = '',\n sendThroughVideobridge = false) {\n const messageType = typeof message;\n\n // Through videobridge we support only objects. Through XMPP we support\n // objects (encapsulated in a specific JSON format) and strings (i.e.\n // regular chat messages).\n if (messageType !== 'object'\n && (sendThroughVideobridge || messageType !== 'string')) {\n logger.error(`Can not send a message of type ${messageType}`);\n\n return;\n }\n\n if (sendThroughVideobridge) {\n this.sendEndpointMessage(to, message);\n } else {\n let messageToSend = message;\n\n // Name of packet extension of message stanza to send the required\n // message in.\n let elementName = 'body';\n\n if (messageType === 'object') {\n elementName = 'json-message';\n\n // Mark as valid JSON message if not already\n if (!messageToSend.hasOwnProperty(JITSI_MEET_MUC_TYPE)) {\n messageToSend[JITSI_MEET_MUC_TYPE] = '';\n }\n\n try {\n messageToSend = JSON.stringify(messageToSend);\n } catch (e) {\n logger.error('Can not send a message, stringify failed: ', e);\n\n return;\n }\n }\n\n if (to) {\n this.sendPrivateTextMessage(to, messageToSend, elementName);\n } else {\n // Broadcast\n this.sendTextMessage(messageToSend, elementName);\n }\n }\n\n};\n\nJitsiConference.prototype.isConnectionInterrupted = function() {\n return this.isP2PActive()\n ? this.isP2PConnectionInterrupted : this.isJvbConnectionInterrupted;\n};\n\n/**\n * Handles {@link XMPPEvents.CONNECTION_INTERRUPTED}\n * @param {JingleSessionPC} session\n * @private\n */\nJitsiConference.prototype._onIceConnectionInterrupted = function(session) {\n if (session.isP2P) {\n this.isP2PConnectionInterrupted = true;\n } else {\n this.isJvbConnectionInterrupted = true;\n }\n if (session.isP2P === this.isP2PActive()) {\n this.eventEmitter.emit(JitsiConferenceEvents.CONNECTION_INTERRUPTED);\n }\n};\n\n/**\n * Handles {@link XMPPEvents.CONNECTION_ICE_FAILED}\n * @param {JingleSessionPC} session\n * @private\n */\nJitsiConference.prototype._onIceConnectionFailed = function(session) {\n // We do nothing for the JVB connection, because it's up to the Jicofo to\n // eventually come up with the new offer (at least for the time being).\n if (session.isP2P) {\n // Add p2pFailed property to analytics to distinguish, between \"good\"\n // and \"bad\" connection\n Statistics.analytics.addPermanentProperties({ p2pFailed: true });\n\n if (this.p2pJingleSession) {\n Statistics.sendAnalyticsAndLog(\n createP2PEvent(\n ACTION_P2P_FAILED,\n {\n initiator: this.p2pJingleSession.isInitiator\n }));\n\n }\n this._stopP2PSession('connectivity-error', 'ICE FAILED');\n } else if (session && this.jvbJingleSession === session) {\n if (this.xmpp.isPingSupported()) {\n this._delayedIceFailed = new IceFailedNotification(this);\n this._delayedIceFailed.start(session);\n } else {\n // Let Jicofo know that the JVB's ICE connection has failed\n logger.info('PING not supported - sending ICE failed immediately');\n session.sendIceFailedNotification();\n }\n }\n};\n\n/**\n * Handles {@link XMPPEvents.CONNECTION_RESTORED}\n * @param {JingleSessionPC} session\n * @private\n */\nJitsiConference.prototype._onIceConnectionRestored = function(session) {\n if (session.isP2P) {\n this.isP2PConnectionInterrupted = false;\n } else {\n this.isJvbConnectionInterrupted = false;\n this._delayedIceFailed && this._delayedIceFailed.cancel();\n }\n\n if (session.isP2P === this.isP2PActive()) {\n this.eventEmitter.emit(JitsiConferenceEvents.CONNECTION_RESTORED);\n }\n};\n\n/**\n * Accept incoming P2P Jingle call.\n * @param {JingleSessionPC} jingleSession the session instance\n * @param {jQuery} jingleOffer a jQuery selector pointing to 'jingle' IQ element\n * @private\n */\nJitsiConference.prototype._acceptP2PIncomingCall = function(\n jingleSession,\n jingleOffer) {\n this.isP2PConnectionInterrupted = false;\n\n // Accept the offer\n this.p2pJingleSession = jingleSession;\n this._sendConferenceJoinAnalyticsEvent();\n\n this.p2pJingleSession.initialize(this.room, this.rtc, this.options.config);\n\n logger.info('Starting CallStats for P2P connection...');\n\n let remoteID = Strophe.getResourceFromJid(this.p2pJingleSession.remoteJid);\n\n const participant = this.participants[remoteID];\n\n if (participant) {\n remoteID = participant.getStatsID() || remoteID;\n }\n\n this.statistics.startCallStats(\n this.p2pJingleSession.peerconnection,\n remoteID);\n\n const localTracks = this.getLocalTracks();\n\n this.p2pJingleSession.acceptOffer(\n jingleOffer,\n () => {\n logger.debug('Got RESULT for P2P \"session-accept\"');\n\n // Setup E2EE.\n for (const track of localTracks) {\n this._setupSenderE2EEForTrack(jingleSession, track);\n }\n },\n error => {\n logger.error(\n 'Failed to accept incoming P2P Jingle session', error);\n },\n localTracks);\n};\n\n/**\n * Adds remote tracks to the conference associated with the JVB session.\n * @private\n */\nJitsiConference.prototype._addRemoteJVBTracks = function() {\n this._addRemoteTracks(\n 'JVB', this.jvbJingleSession.peerconnection.getRemoteTracks());\n};\n\n/**\n * Adds remote tracks to the conference associated with the P2P session.\n * @private\n */\nJitsiConference.prototype._addRemoteP2PTracks = function() {\n this._addRemoteTracks(\n 'P2P', this.p2pJingleSession.peerconnection.getRemoteTracks());\n};\n\n/**\n * Generates fake \"remote track added\" events for given Jingle session.\n * @param {string} logName the session's nickname which will appear in log\n * messages.\n * @param {Array} remoteTracks the tracks that will be added\n * @private\n */\nJitsiConference.prototype._addRemoteTracks = function(logName, remoteTracks) {\n for (const track of remoteTracks) {\n logger.info(`Adding remote ${logName} track: ${track}`);\n this.rtc.eventEmitter.emit(RTCEvents.REMOTE_TRACK_ADDED, track);\n }\n};\n\n/**\n * Called when {@link XMPPEvents.CONNECTION_ESTABLISHED} event is\n * triggered for a {@link JingleSessionPC}. Switches the conference to use\n * the P2P connection if the event comes from the P2P session.\n * @param {JingleSessionPC} jingleSession the session instance.\n * @private\n */\nJitsiConference.prototype._onIceConnectionEstablished = function(\n jingleSession) {\n if (this.p2pJingleSession !== null) {\n // store the establishment time of the p2p session as a field of the\n // JitsiConference because the p2pJingleSession might get disposed (thus\n // the value is lost).\n this.p2pEstablishmentDuration\n = this.p2pJingleSession.establishmentDuration;\n }\n\n if (this.jvbJingleSession !== null) {\n this.jvbEstablishmentDuration\n = this.jvbJingleSession.establishmentDuration;\n }\n\n let done = false;\n const forceJVB121Ratio = this.options.config.forceJVB121Ratio;\n\n // We don't care about the JVB case, there's nothing to be done\n if (!jingleSession.isP2P) {\n done = true;\n } else if (this.p2pJingleSession !== jingleSession) {\n logger.error('CONNECTION_ESTABLISHED - wrong P2P session instance ?!');\n\n done = true;\n } else if (!jingleSession.isInitiator\n && typeof forceJVB121Ratio === 'number'\n && Math.random() < forceJVB121Ratio) {\n logger.info(`Forcing JVB 121 mode (ratio=${forceJVB121Ratio})...`);\n Statistics.analytics.addPermanentProperties({ forceJvb121: true });\n this._stopP2PSession('decline', 'force JVB121');\n\n done = true;\n }\n\n if (!isNaN(this.p2pEstablishmentDuration)\n && !isNaN(this.jvbEstablishmentDuration)) {\n const establishmentDurationDiff\n = this.p2pEstablishmentDuration - this.jvbEstablishmentDuration;\n\n Statistics.sendAnalytics(\n ICE_ESTABLISHMENT_DURATION_DIFF,\n { value: establishmentDurationDiff });\n }\n\n if (jingleSession.isP2P === this.isP2PActive()) {\n this.eventEmitter.emit(JitsiConferenceEvents.CONNECTION_ESTABLISHED);\n }\n\n if (done) {\n\n return;\n }\n\n // Update P2P status and emit events\n this._setP2PStatus(true);\n\n // Remove remote tracks\n if (this.jvbJingleSession) {\n this._removeRemoteJVBTracks();\n } else {\n logger.info('Not removing remote JVB tracks - no session yet');\n }\n\n this._addRemoteP2PTracks();\n\n // Stop media transfer over the JVB connection\n if (this.jvbJingleSession) {\n this._suspendMediaTransferForJvbConnection();\n }\n\n logger.info('Starting remote stats with p2p connection');\n this.statistics.startRemoteStats(this.p2pJingleSession.peerconnection);\n\n Statistics.sendAnalyticsAndLog(\n createP2PEvent(\n ACTION_P2P_ESTABLISHED,\n {\n initiator: this.p2pJingleSession.isInitiator\n }));\n\n};\n\n/**\n * Called when the chat room reads a new list of properties from jicofo's\n * presence. The properties may have changed, but they don't have to.\n *\n * @param {Object} properties - The properties keyed by the property name\n * ('key').\n * @private\n */\nJitsiConference.prototype._updateProperties = function(properties = {}) {\n const changed = !isEqual(properties, this.properties);\n\n this.properties = properties;\n if (changed) {\n this.eventEmitter.emit(\n JitsiConferenceEvents.PROPERTIES_CHANGED,\n this.properties);\n\n // Some of the properties need to be added to analytics events.\n const analyticsKeys = [\n\n // The number of jitsi-videobridge instances currently used for the\n // conference.\n 'bridge-count',\n\n // The conference creation time (set by jicofo).\n 'created-ms',\n 'octo-enabled'\n ];\n\n analyticsKeys.forEach(key => {\n if (properties[key] !== undefined) {\n Statistics.analytics.addPermanentProperties({\n [key.replace('-', '_')]: properties[key]\n });\n }\n });\n }\n};\n\n/**\n * Gets a conference property with a given key.\n *\n * @param {string} key - The key.\n * @returns {*} The value\n */\nJitsiConference.prototype.getProperty = function(key) {\n return this.properties[key];\n};\n\n/**\n * Clears the deferred start P2P task if it has been scheduled.\n * @private\n */\nJitsiConference.prototype._maybeClearDeferredStartP2P = function() {\n if (this.deferredStartP2PTask) {\n logger.info('Cleared deferred start P2P task');\n clearTimeout(this.deferredStartP2PTask);\n this.deferredStartP2PTask = null;\n }\n};\n\n/**\n * Removes from the conference remote tracks associated with the JVB\n * connection.\n * @private\n */\nJitsiConference.prototype._removeRemoteJVBTracks = function() {\n this._removeRemoteTracks(\n 'JVB', this.jvbJingleSession.peerconnection.getRemoteTracks());\n};\n\n/**\n * Removes from the conference remote tracks associated with the P2P\n * connection.\n * @private\n */\nJitsiConference.prototype._removeRemoteP2PTracks = function() {\n this._removeRemoteTracks(\n 'P2P', this.p2pJingleSession.peerconnection.getRemoteTracks());\n};\n\n/**\n * Generates fake \"remote track removed\" events for given Jingle session.\n * @param {string} sessionNickname the session's nickname which will appear in\n * log messages.\n * @param {Array} remoteTracks the tracks that will be removed\n * @private\n */\nJitsiConference.prototype._removeRemoteTracks = function(\n sessionNickname,\n remoteTracks) {\n for (const track of remoteTracks) {\n logger.info(`Removing remote ${sessionNickname} track: ${track}`);\n this.rtc.eventEmitter.emit(RTCEvents.REMOTE_TRACK_REMOVED, track);\n }\n};\n\n/**\n * Resumes media transfer over the JVB connection.\n * @private\n */\nJitsiConference.prototype._resumeMediaTransferForJvbConnection = function() {\n logger.info('Resuming media transfer over the JVB connection...');\n this.jvbJingleSession.setMediaTransferActive(true, true).then(\n () => {\n logger.info('Resumed media transfer over the JVB connection!');\n },\n error => {\n logger.error(\n 'Failed to resume media transfer over the JVB connection:',\n error);\n });\n};\n\n/**\n * Sets new P2P status and updates some events/states hijacked from\n * the JitsiConference.\n * @param {boolean} newStatus the new P2P status value, true means that\n * P2P is now in use, false means that the JVB connection is now in use\n * @private\n */\nJitsiConference.prototype._setP2PStatus = function(newStatus) {\n if (this.p2p === newStatus) {\n logger.debug(`Called _setP2PStatus with the same status: ${newStatus}`);\n\n return;\n }\n this.p2p = newStatus;\n if (newStatus) {\n logger.info('Peer to peer connection established!');\n\n // When we end up in a valid P2P session need to reset the properties\n // in case they have persisted, after session with another peer.\n Statistics.analytics.addPermanentProperties({\n p2pFailed: false,\n forceJvb121: false\n });\n\n // Sync up video transfer active in case p2pJingleSession not existed\n // when the lastN value was being adjusted.\n const isVideoActive = this.rtc.getLastN() !== 0;\n\n this.p2pJingleSession\n .setMediaTransferActive(true, isVideoActive)\n .catch(error => {\n logger.error(\n 'Failed to sync up P2P video transfer status'\n + `(${isVideoActive})`, error);\n });\n } else {\n logger.info('Peer to peer connection closed!');\n }\n\n // Put the JVB connection on hold/resume\n if (this.jvbJingleSession) {\n this.statistics.sendConnectionResumeOrHoldEvent(\n this.jvbJingleSession.peerconnection, !newStatus);\n }\n\n // Clear dtmfManager, so that it can be recreated with new connection\n this.dtmfManager = null;\n\n // Update P2P status\n this.eventEmitter.emit(\n JitsiConferenceEvents.P2P_STATUS,\n this,\n this.p2p);\n\n // Refresh connection interrupted/restored\n this.eventEmitter.emit(\n this.isConnectionInterrupted()\n ? JitsiConferenceEvents.CONNECTION_INTERRUPTED\n : JitsiConferenceEvents.CONNECTION_RESTORED);\n};\n\n/**\n * Starts new P2P session.\n * @param {string} remoteJid the JID of the remote participant\n * @private\n */\nJitsiConference.prototype._startP2PSession = function(remoteJid) {\n this._maybeClearDeferredStartP2P();\n if (this.p2pJingleSession) {\n logger.error('P2P session already started!');\n\n return;\n }\n\n this.isP2PConnectionInterrupted = false;\n this.p2pJingleSession\n = this.xmpp.connection.jingle.newP2PJingleSession(\n this.room.myroomjid,\n remoteJid);\n logger.info(\n 'Created new P2P JingleSession', this.room.myroomjid, remoteJid);\n this._sendConferenceJoinAnalyticsEvent();\n\n this.p2pJingleSession.initialize(this.room, this.rtc, this.options.config);\n\n logger.info('Starting CallStats for P2P connection...');\n\n let remoteID = Strophe.getResourceFromJid(this.p2pJingleSession.remoteJid);\n\n const participant = this.participants[remoteID];\n\n if (participant) {\n remoteID = participant.getStatsID() || remoteID;\n }\n\n this.statistics.startCallStats(\n this.p2pJingleSession.peerconnection,\n remoteID);\n\n // NOTE one may consider to start P2P with the local tracks detached,\n // but no data will be sent until ICE succeeds anyway. And we switch\n // immediately once the P2P ICE connects.\n const localTracks = this.getLocalTracks();\n\n this.p2pJingleSession.invite(localTracks);\n};\n\n/**\n * Suspends media transfer over the JVB connection.\n * @private\n */\nJitsiConference.prototype._suspendMediaTransferForJvbConnection = function() {\n logger.info('Suspending media transfer over the JVB connection...');\n this.jvbJingleSession.setMediaTransferActive(false, false).then(\n () => {\n logger.info('Suspended media transfer over the JVB connection !');\n },\n error => {\n logger.error(\n 'Failed to suspend media transfer over the JVB connection:',\n error);\n });\n};\n\n/**\n * Method when called will decide whether it's the time to start or stop\n * the P2P session.\n * @param {boolean} userLeftEvent if true it means that the call\n * originates from the user left event.\n * @private\n */\nJitsiConference.prototype._maybeStartOrStopP2P = function(userLeftEvent) {\n if (!browser.supportsP2P()\n || !this.isP2PEnabled()\n || this.isP2PTestModeEnabled()) {\n logger.info('Auto P2P disabled');\n\n return;\n }\n const peers = this.getParticipants();\n const peerCount = peers.length;\n\n // FIXME 1 peer and it must *support* P2P switching\n const shouldBeInP2P = this._shouldBeInP2PMode();\n\n // Clear deferred \"start P2P\" task\n if (!shouldBeInP2P && this.deferredStartP2PTask) {\n this._maybeClearDeferredStartP2P();\n }\n\n // Start peer to peer session\n if (!this.p2pJingleSession && shouldBeInP2P) {\n const peer = peerCount && peers[0];\n\n\n const myId = this.myUserId();\n const peersId = peer.getId();\n\n if (myId > peersId) {\n logger.debug(\n 'I\\'m the bigger peersId - '\n + 'the other peer should start P2P', myId, peersId);\n\n return;\n } else if (myId === peersId) {\n logger.error('The same IDs ? ', myId, peersId);\n\n return;\n }\n\n const jid = peer.getJid();\n\n if (userLeftEvent) {\n if (this.deferredStartP2PTask) {\n logger.error('Deferred start P2P task\\'s been set already!');\n\n return;\n }\n logger.info(\n `Will start P2P with: ${jid} after ${\n this.backToP2PDelay} seconds...`);\n this.deferredStartP2PTask = setTimeout(\n this._startP2PSession.bind(this, jid),\n this.backToP2PDelay * 1000);\n } else {\n logger.info(`Will start P2P with: ${jid}`);\n this._startP2PSession(jid);\n }\n } else if (this.p2pJingleSession && !shouldBeInP2P) {\n logger.info(`Will stop P2P with: ${this.p2pJingleSession.remoteJid}`);\n\n // Log that there will be a switch back to the JVB connection\n if (this.p2pJingleSession.isInitiator && peerCount > 1) {\n Statistics.sendAnalyticsAndLog(\n createP2PEvent(ACTION_P2P_SWITCH_TO_JVB));\n }\n this._stopP2PSession();\n }\n};\n\n/**\n * Tells whether or not this conference should be currently in the P2P mode.\n *\n * @private\n * @returns {boolean}\n */\nJitsiConference.prototype._shouldBeInP2PMode = function() {\n const peers = this.getParticipants();\n const peerCount = peers.length;\n const hasBotPeer = peers.find(p => p._botType === 'poltergeist') !== undefined;\n const shouldBeInP2P = peerCount === 1 && !hasBotPeer;\n\n logger.debug(`P2P? peerCount: ${peerCount}, hasBotPeer: ${hasBotPeer} => ${shouldBeInP2P}`);\n\n return shouldBeInP2P;\n};\n\n/**\n * Stops the current P2P session.\n * @param {string} [reason=\"success\"] one of the Jingle \"reason\" element\n * names as defined by https://xmpp.org/extensions/xep-0166.html#def-reason\n * @param {string} [reasonDescription=\"Turing off P2P session\"] text\n * description that will be included in the session terminate message\n * @private\n */\nJitsiConference.prototype._stopP2PSession = function(\n reason,\n reasonDescription) {\n if (!this.p2pJingleSession) {\n logger.error('No P2P session to be stopped!');\n\n return;\n }\n\n const wasP2PEstablished = this.isP2PActive();\n\n // Swap remote tracks, but only if the P2P has been fully established\n if (wasP2PEstablished) {\n if (this.jvbJingleSession) {\n this._resumeMediaTransferForJvbConnection();\n }\n\n // Remove remote P2P tracks\n this._removeRemoteP2PTracks();\n }\n\n // Stop P2P stats\n logger.info('Stopping remote stats for P2P connection');\n this.statistics.stopRemoteStats(this.p2pJingleSession.peerconnection);\n logger.info('Stopping CallStats for P2P connection');\n this.statistics.stopCallStats(this.p2pJingleSession.peerconnection);\n\n this.p2pJingleSession.terminate(\n () => {\n logger.info('P2P session terminate RESULT');\n },\n error => {\n // Because both initiator and responder are simultaneously\n // terminating their JingleSessions in case of the 'to JVB switch'\n // when 3rd participant joins, both will dispose their sessions and\n // reply with 'item-not-found' (see strophe.jingle.js). We don't\n // want to log this as an error since it's expected behaviour.\n //\n // We want them both to terminate, because in case of initiator's\n // crash the responder would stay in P2P mode until ICE fails which\n // could take up to 20 seconds.\n //\n // NOTE lack of 'reason' is considered as graceful session terminate\n // where both initiator and responder terminate their sessions\n // simultaneously.\n if (reason) {\n logger.error(\n 'An error occurred while trying to terminate'\n + ' P2P Jingle session', error);\n }\n }, {\n reason: reason ? reason : 'success',\n reasonDescription: reasonDescription\n ? reasonDescription : 'Turing off P2P session',\n sendSessionTerminate: this.room\n && this.getParticipantById(\n Strophe.getResourceFromJid(this.p2pJingleSession.remoteJid))\n });\n\n this.p2pJingleSession = null;\n\n // Update P2P status and other affected events/states\n this._setP2PStatus(false);\n\n if (wasP2PEstablished) {\n // Add back remote JVB tracks\n if (this.jvbJingleSession) {\n this._addRemoteJVBTracks();\n } else {\n logger.info('Not adding remote JVB tracks - no session yet');\n }\n }\n};\n\n/**\n * Checks whether or not the conference is currently in the peer to peer mode.\n * Being in peer to peer mode means that the direct connection has been\n * established and the P2P connection is being used for media transmission.\n * @return {boolean} true if in P2P mode or false otherwise.\n */\nJitsiConference.prototype.isP2PActive = function() {\n return this.p2p;\n};\n\n/**\n * Returns the current ICE state of the P2P connection.\n * NOTE: method is used by the jitsi-meet-torture tests.\n * @return {string|null} an ICE state or null if there's currently\n * no P2P connection.\n */\nJitsiConference.prototype.getP2PConnectionState = function() {\n if (this.isP2PActive()) {\n return this.p2pJingleSession.peerconnection.getConnectionState();\n }\n\n return null;\n};\n\n\n/**\n * Manually starts new P2P session (should be used only in the tests).\n */\nJitsiConference.prototype.startP2PSession = function() {\n const peers = this.getParticipants();\n\n // Start peer to peer session\n if (peers.length === 1) {\n const peerJid = peers[0].getJid();\n\n this._startP2PSession(peerJid);\n } else {\n throw new Error(\n 'There must be exactly 1 participant to start the P2P session !');\n }\n};\n\n/**\n * Manually stops the current P2P session (should be used only in the tests)\n */\nJitsiConference.prototype.stopP2PSession = function() {\n this._stopP2PSession();\n};\n\n/**\n * Get a summary of how long current participants have been the dominant speaker\n * @returns {object}\n */\nJitsiConference.prototype.getSpeakerStats = function() {\n return this.speakerStatsCollector.getStats();\n};\n\n/**\n * Sets the maximum video size the local participant should receive from remote\n * participants.\n *\n * @param {number} maxFrameHeightPixels the maximum frame height, in pixels,\n * this receiver is willing to receive.\n * @returns {void}\n */\nJitsiConference.prototype.setReceiverVideoConstraint = function(\n maxFrameHeight) {\n this.rtc.setReceiverVideoConstraint(maxFrameHeight);\n};\n\n/**\n * Creates a video SIP GW session and returns it if service is enabled. Before\n * creating a session one need to check whether video SIP GW service is\n * available in the system {@link JitsiConference.isVideoSIPGWAvailable}. Even\n * if there are available nodes to serve this request, after creating the\n * session those nodes can be taken and the request about using the\n * created session can fail.\n *\n * @param {string} sipAddress - The sip address to be used.\n * @param {string} displayName - The display name to be used for this session.\n * @returns {JitsiVideoSIPGWSession|Error} Returns null if conference is not\n * initialised and there is no room.\n */\nJitsiConference.prototype.createVideoSIPGWSession\n = function(sipAddress, displayName) {\n if (!this.room) {\n return new Error(VideoSIPGWConstants.ERROR_NO_CONNECTION);\n }\n\n return this.videoSIPGWHandler\n .createVideoSIPGWSession(sipAddress, displayName);\n };\n\n/**\n * Sends a conference.join analytics event.\n *\n * @returns {void}\n */\nJitsiConference.prototype._sendConferenceJoinAnalyticsEvent = function() {\n const meetingId = this.getMeetingUniqueId();\n\n if (this._conferenceJoinAnalyticsEventSent || !meetingId || this.getActivePeerConnection() === null) {\n return;\n }\n\n Statistics.sendAnalytics(createConferenceEvent('joined', {\n meetingId,\n participantId: `${meetingId}.${this._statsCurrentId}`\n }));\n this._conferenceJoinAnalyticsEventSent = true;\n};\n\n/**\n * Returns whether End-To-End encryption is supported. Note that not all participants\n * in the conference may support it.\n *\n * @returns {boolean}\n */\nJitsiConference.prototype.isE2EESupported = function() {\n return Boolean(this._e2eeCtx);\n};\n\n/**\n * Sets the key to be used for End-To-End encryption.\n *\n * @param {string} key the key to be used.\n * @returns {void}\n */\nJitsiConference.prototype.setE2EEKey = function(key) {\n if (!this._e2eeCtx) {\n logger.warn('Cannot set E2EE key: there is no defined context, platform is likely unsupported.');\n\n return;\n }\n\n this._e2eeCtx.setKey(key);\n};\n\n/**\n * Setup E2EE for the sending side, if supported.\n * Note that this is only done for the JVB Peer Connecction.\n *\n * @returns {void}\n */\nJitsiConference.prototype._setupSenderE2EEForTrack = function(session, track) {\n if (!this._e2eeCtx) {\n return;\n }\n const pc = session.peerconnection;\n const sender = pc.findSenderForTrack(track.track);\n\n if (sender) {\n this._e2eeCtx.handleSender(sender, track.getType());\n } else {\n logger.warn(`Could not handle E2EE for local ${track.getType()} track: sender not found`);\n }\n};\n\n/**\n * Setup E2EE for the receiving side, if supported.\n * Note that this is only done for the JVB Peer Connecction.\n *\n * @returns {void}\n */\nJitsiConference.prototype._setupReceiverE2EEForTrack = function(track) {\n if (!this._e2eeCtx) {\n return;\n }\n const session = track.isP2P ? this.p2pJingleSession : this.jvbJingleSession;\n const pc = session && session.peerconnection;\n\n if (pc) {\n const receiver = pc.findReceiverForTrack(track.track);\n\n if (receiver) {\n this._e2eeCtx.handleReceiver(receiver, track.getType());\n } else {\n logger.warn(`Could not handle E2EE for remote ${track.getType()} track: receiver not found`);\n }\n }\n};\n", "/* global __filename */\nimport { Strophe } from 'strophe.js';\n\nimport {\n ACTION_JINGLE_SA_TIMEOUT,\n createBridgeDownEvent,\n createConnectionStageReachedEvent,\n createFocusLeftEvent,\n createJingleEvent,\n createRemotelyMutedEvent\n} from './service/statistics/AnalyticsEvents';\nimport AuthenticationEvents\n from './service/authentication/AuthenticationEvents';\nimport EventEmitterForwarder from './modules/util/EventEmitterForwarder';\nimport { getLogger } from 'jitsi-meet-logger';\nimport * as JitsiConferenceErrors from './JitsiConferenceErrors';\nimport * as JitsiConferenceEvents from './JitsiConferenceEvents';\nimport * as MediaType from './service/RTC/MediaType';\nimport RTCEvents from './service/RTC/RTCEvents';\nimport VideoType from './service/RTC/VideoType';\nimport Statistics from './modules/statistics/statistics';\nimport XMPPEvents from './service/xmpp/XMPPEvents';\n\nconst logger = getLogger(__filename);\n\n/**\n * Setups all event listeners related to conference\n * @param conference {JitsiConference} the conference\n */\nexport default function JitsiConferenceEventManager(conference) {\n this.conference = conference;\n this.xmppListeners = {};\n\n // Listeners related to the conference only\n conference.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED,\n track => {\n if (!track.isLocal() || !conference.statistics) {\n return;\n }\n const session\n = track.isP2P\n ? conference.p2pJingleSession : conference.jvbJingleSession;\n\n // TPC will be null, before the conference starts, but the event\n // still should be queued\n const tpc = (session && session.peerconnection) || null;\n\n conference.statistics.sendMuteEvent(\n tpc,\n track.isMuted(),\n track.getType());\n });\n}\n\n/**\n * Setups event listeners related to conference.chatRoom\n */\nJitsiConferenceEventManager.prototype.setupChatRoomListeners = function() {\n const conference = this.conference;\n const chatRoom = conference.room;\n\n this.chatRoomForwarder = new EventEmitterForwarder(chatRoom,\n this.conference.eventEmitter);\n\n chatRoom.addListener(XMPPEvents.ICE_RESTARTING, jingleSession => {\n if (!jingleSession.isP2P) {\n // If using DataChannel as bridge channel, it must be closed\n // before ICE restart, otherwise Chrome will not trigger \"opened\"\n // event for the channel established with the new bridge.\n // TODO: This may be bypassed when using a WebSocket as bridge\n // channel.\n conference.rtc.closeBridgeChannel();\n }\n\n // else: there are no DataChannels in P2P session (at least for now)\n });\n\n chatRoom.addListener(\n XMPPEvents.ICE_RESTART_SUCCESS,\n (jingleSession, offerIq) => {\n // The JVB data chanel needs to be reopened in case the conference\n // has been moved to a new bridge.\n !jingleSession.isP2P\n && conference._setBridgeChannel(\n offerIq, jingleSession.peerconnection);\n });\n\n\n chatRoom.addListener(XMPPEvents.AUDIO_MUTED_BY_FOCUS,\n actor => {\n // TODO: Add a way to differentiate between commands which caused\n // us to mute and those that did not change our state (i.e. we were\n // already muted).\n Statistics.sendAnalytics(createRemotelyMutedEvent());\n\n conference.mutedByFocusActor = actor;\n\n // set isMutedByFocus when setAudioMute Promise ends\n conference.rtc.setAudioMute(true).then(\n () => {\n conference.isMutedByFocus = true;\n conference.mutedByFocusActor = null;\n })\n .catch(\n error => {\n conference.mutedByFocusActor = null;\n logger.warn(\n 'Error while audio muting due to focus request', error);\n });\n }\n );\n\n this.chatRoomForwarder.forward(XMPPEvents.SUBJECT_CHANGED,\n JitsiConferenceEvents.SUBJECT_CHANGED);\n\n this.chatRoomForwarder.forward(XMPPEvents.MUC_JOINED,\n JitsiConferenceEvents.CONFERENCE_JOINED);\n\n // send some analytics events\n chatRoom.addListener(XMPPEvents.MUC_JOINED,\n () => {\n this.conference.isJvbConnectionInterrupted = false;\n\n // TODO: Move all of the 'connectionTimes' logic to its own module.\n Object.keys(chatRoom.connectionTimes).forEach(key => {\n const event\n = createConnectionStageReachedEvent(\n `conference_${key}`,\n { value: chatRoom.connectionTimes[key] });\n\n Statistics.sendAnalytics(event);\n });\n\n // TODO: Move all of the 'connectionTimes' logic to its own module.\n Object.keys(chatRoom.xmpp.connectionTimes).forEach(key => {\n const event\n = createConnectionStageReachedEvent(\n `xmpp_${key}`,\n { value: chatRoom.xmpp.connectionTimes[key] });\n\n Statistics.sendAnalytics(event);\n });\n });\n\n chatRoom.addListener(XMPPEvents.RENEGOTIATION_FAILED, (e, session) => {\n if (!session.isP2P) {\n conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.OFFER_ANSWER_FAILED, e);\n }\n });\n\n this.chatRoomForwarder.forward(XMPPEvents.ROOM_JOIN_ERROR,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.CONNECTION_ERROR);\n\n this.chatRoomForwarder.forward(XMPPEvents.ROOM_CONNECT_ERROR,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.CONNECTION_ERROR);\n this.chatRoomForwarder.forward(XMPPEvents.ROOM_CONNECT_NOT_ALLOWED_ERROR,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.NOT_ALLOWED_ERROR);\n\n this.chatRoomForwarder.forward(XMPPEvents.ROOM_MAX_USERS_ERROR,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.CONFERENCE_MAX_USERS);\n\n this.chatRoomForwarder.forward(XMPPEvents.PASSWORD_REQUIRED,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.PASSWORD_REQUIRED);\n\n this.chatRoomForwarder.forward(XMPPEvents.AUTHENTICATION_REQUIRED,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.AUTHENTICATION_REQUIRED);\n\n this.chatRoomForwarder.forward(XMPPEvents.BRIDGE_DOWN,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.VIDEOBRIDGE_NOT_AVAILABLE);\n chatRoom.addListener(\n XMPPEvents.BRIDGE_DOWN,\n () => Statistics.sendAnalytics(createBridgeDownEvent()));\n\n this.chatRoomForwarder.forward(XMPPEvents.RESERVATION_ERROR,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.RESERVATION_ERROR);\n\n this.chatRoomForwarder.forward(XMPPEvents.GRACEFUL_SHUTDOWN,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.GRACEFUL_SHUTDOWN);\n\n chatRoom.addListener(XMPPEvents.CONNECTION_ICE_FAILED,\n jingleSession => {\n conference._onIceConnectionFailed(jingleSession);\n });\n\n this.chatRoomForwarder.forward(XMPPEvents.MUC_DESTROYED,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.CONFERENCE_DESTROYED);\n\n this.chatRoomForwarder.forward(XMPPEvents.CHAT_ERROR_RECEIVED,\n JitsiConferenceEvents.CONFERENCE_ERROR,\n JitsiConferenceErrors.CHAT_ERROR);\n\n this.chatRoomForwarder.forward(XMPPEvents.FOCUS_DISCONNECTED,\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.FOCUS_DISCONNECTED);\n\n chatRoom.addListener(XMPPEvents.FOCUS_LEFT,\n () => {\n Statistics.sendAnalytics(createFocusLeftEvent());\n conference.eventEmitter.emit(\n JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.FOCUS_LEFT);\n });\n\n chatRoom.addListener(XMPPEvents.SESSION_ACCEPT_TIMEOUT,\n jingleSession => {\n Statistics.sendAnalyticsAndLog(\n createJingleEvent(\n ACTION_JINGLE_SA_TIMEOUT,\n { p2p: jingleSession.isP2P }));\n });\n\n chatRoom.addListener(XMPPEvents.RECORDER_STATE_CHANGED,\n (session, jid) => {\n\n if (jid) {\n const participant = conference.getParticipantById(\n Strophe.getResourceFromJid(jid));\n\n if (session.getStatus() === 'off') {\n session.setTerminator(participant);\n } else if (session.getStatus() === 'on') {\n session.setInitiator(participant);\n }\n }\n\n conference.eventEmitter.emit(\n JitsiConferenceEvents.RECORDER_STATE_CHANGED,\n session);\n });\n\n this.chatRoomForwarder.forward(XMPPEvents.TRANSCRIPTION_STATUS_CHANGED,\n JitsiConferenceEvents.TRANSCRIPTION_STATUS_CHANGED);\n\n this.chatRoomForwarder.forward(XMPPEvents.VIDEO_SIP_GW_AVAILABILITY_CHANGED,\n JitsiConferenceEvents.VIDEO_SIP_GW_AVAILABILITY_CHANGED);\n\n this.chatRoomForwarder.forward(\n XMPPEvents.VIDEO_SIP_GW_SESSION_STATE_CHANGED,\n JitsiConferenceEvents.VIDEO_SIP_GW_SESSION_STATE_CHANGED);\n\n this.chatRoomForwarder.forward(XMPPEvents.PHONE_NUMBER_CHANGED,\n JitsiConferenceEvents.PHONE_NUMBER_CHANGED);\n\n chatRoom.setParticipantPropertyListener((node, from) => {\n const participant = conference.getParticipantById(from);\n\n if (!participant) {\n return;\n }\n\n participant.setProperty(\n node.tagName.substring('jitsi_participant_'.length),\n node.value);\n });\n\n chatRoom.addListener(XMPPEvents.KICKED,\n conference.onMemberKicked.bind(conference));\n chatRoom.addListener(XMPPEvents.SUSPEND_DETECTED,\n conference.onSuspendDetected.bind(conference));\n\n this.chatRoomForwarder.forward(XMPPEvents.MUC_LOCK_CHANGED,\n JitsiConferenceEvents.LOCK_STATE_CHANGED);\n\n chatRoom.addListener(XMPPEvents.MUC_MEMBER_JOINED,\n conference.onMemberJoined.bind(conference));\n chatRoom.addListener(XMPPEvents.MUC_MEMBER_BOT_TYPE_CHANGED,\n conference._onMemberBotTypeChanged.bind(conference));\n chatRoom.addListener(XMPPEvents.MUC_MEMBER_LEFT,\n conference.onMemberLeft.bind(conference));\n this.chatRoomForwarder.forward(XMPPEvents.MUC_LEFT,\n JitsiConferenceEvents.CONFERENCE_LEFT);\n\n chatRoom.addListener(XMPPEvents.DISPLAY_NAME_CHANGED,\n conference.onDisplayNameChanged.bind(conference));\n\n chatRoom.addListener(XMPPEvents.LOCAL_ROLE_CHANGED, role => {\n conference.onLocalRoleChanged(role);\n\n // log all events for the recorder operated by the moderator\n if (conference.statistics && conference.isModerator()) {\n conference.on(JitsiConferenceEvents.RECORDER_STATE_CHANGED,\n recorderSession => {\n const logObject = {\n error: recorderSession.getError(),\n id: 'recorder_status',\n status: recorderSession.getStatus()\n };\n\n Statistics.sendLog(JSON.stringify(logObject));\n });\n }\n });\n\n chatRoom.addListener(XMPPEvents.MUC_ROLE_CHANGED,\n conference.onUserRoleChanged.bind(conference));\n\n chatRoom.addListener(AuthenticationEvents.IDENTITY_UPDATED,\n (authEnabled, authIdentity) => {\n conference.authEnabled = authEnabled;\n conference.authIdentity = authIdentity;\n conference.eventEmitter.emit(\n JitsiConferenceEvents.AUTH_STATUS_CHANGED, authEnabled,\n authIdentity);\n });\n\n chatRoom.addListener(\n XMPPEvents.MESSAGE_RECEIVED,\n\n // eslint-disable-next-line max-params\n (jid, displayName, txt, myJid, ts) => {\n const id = Strophe.getResourceFromJid(jid);\n\n conference.eventEmitter.emit(\n JitsiConferenceEvents.MESSAGE_RECEIVED,\n id, txt, ts, displayName);\n });\n\n chatRoom.addListener(\n XMPPEvents.PRIVATE_MESSAGE_RECEIVED,\n\n // eslint-disable-next-line max-params\n (jid, displayName, txt, myJid, ts) => {\n const id = Strophe.getResourceFromJid(jid);\n\n conference.eventEmitter.emit(\n JitsiConferenceEvents.PRIVATE_MESSAGE_RECEIVED,\n id, txt, ts);\n });\n\n chatRoom.addListener(XMPPEvents.PRESENCE_STATUS,\n (jid, status) => {\n const id = Strophe.getResourceFromJid(jid);\n const participant = conference.getParticipantById(id);\n\n if (!participant || participant._status === status) {\n return;\n }\n participant._status = status;\n conference.eventEmitter.emit(\n JitsiConferenceEvents.USER_STATUS_CHANGED, id, status);\n });\n\n chatRoom.addListener(XMPPEvents.JSON_MESSAGE_RECEIVED,\n (from, payload) => {\n const id = Strophe.getResourceFromJid(from);\n const participant = conference.getParticipantById(id);\n\n if (participant) {\n conference.eventEmitter.emit(\n JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,\n participant, payload);\n } else {\n logger.warn(\n 'Ignored XMPPEvents.JSON_MESSAGE_RECEIVED for not existing '\n + `participant: ${from}`,\n payload);\n }\n });\n\n chatRoom.addPresenceListener('startmuted', (data, from) => {\n let isModerator = false;\n\n if (conference.myUserId() === from && conference.isModerator()) {\n isModerator = true;\n } else {\n const participant = conference.getParticipantById(from);\n\n if (participant && participant.isModerator()) {\n isModerator = true;\n }\n }\n\n if (!isModerator) {\n return;\n }\n\n const startAudioMuted = data.attributes.audio === 'true';\n const startVideoMuted = data.attributes.video === 'true';\n\n let updated = false;\n\n if (startAudioMuted !== conference.startMutedPolicy.audio) {\n conference.startMutedPolicy.audio = startAudioMuted;\n updated = true;\n }\n\n if (startVideoMuted !== conference.startMutedPolicy.video) {\n conference.startMutedPolicy.video = startVideoMuted;\n updated = true;\n }\n\n if (updated) {\n conference.eventEmitter.emit(\n JitsiConferenceEvents.START_MUTED_POLICY_CHANGED,\n conference.startMutedPolicy\n );\n }\n });\n\n if (conference.statistics) {\n // FIXME ICE related events should end up in RTCEvents eventually\n chatRoom.addListener(XMPPEvents.CONNECTION_ICE_FAILED,\n session => {\n conference.statistics.sendIceConnectionFailedEvent(\n session.peerconnection);\n });\n\n // FIXME XMPPEvents.ADD_ICE_CANDIDATE_FAILED is never emitted\n chatRoom.addListener(XMPPEvents.ADD_ICE_CANDIDATE_FAILED,\n (e, pc) => {\n conference.statistics.sendAddIceCandidateFailed(e, pc);\n });\n }\n};\n\n/**\n * Setups event listeners related to conference.rtc\n */\nJitsiConferenceEventManager.prototype.setupRTCListeners = function() {\n const conference = this.conference;\n const rtc = conference.rtc;\n\n rtc.addListener(\n RTCEvents.REMOTE_TRACK_ADDED,\n conference.onRemoteTrackAdded.bind(conference));\n\n rtc.addListener(\n RTCEvents.REMOTE_TRACK_REMOVED,\n conference.onRemoteTrackRemoved.bind(conference));\n\n rtc.addListener(RTCEvents.DOMINANT_SPEAKER_CHANGED,\n id => {\n if (conference.lastDominantSpeaker !== id && conference.room) {\n conference.lastDominantSpeaker = id;\n conference.eventEmitter.emit(\n JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED, id);\n\n if (conference.statistics && conference.myUserId() === id) {\n // We are the new dominant speaker.\n conference.statistics.sendDominantSpeakerEvent(\n conference.room.roomjid);\n }\n }\n });\n\n rtc.addListener(RTCEvents.DATA_CHANNEL_OPEN, () => {\n const now = window.performance.now();\n const key = 'data.channel.opened';\n\n // TODO: Move all of the 'connectionTimes' logic to its own module.\n logger.log(`(TIME) ${key}:\\t`, now);\n conference.room.connectionTimes[key] = now;\n Statistics.sendAnalytics(\n createConnectionStageReachedEvent(key, { value: now }));\n\n conference.eventEmitter.emit(JitsiConferenceEvents.DATA_CHANNEL_OPENED);\n });\n\n rtc.addListener(RTCEvents.ENDPOINT_MESSAGE_RECEIVED,\n (from, payload) => {\n const participant = conference.getParticipantById(from);\n\n if (participant) {\n conference.eventEmitter.emit(\n JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,\n participant, payload);\n } else {\n logger.warn(\n 'Ignored ENDPOINT_MESSAGE_RECEIVED for not existing '\n + `participant: ${from}`,\n payload);\n }\n });\n\n rtc.addListener(RTCEvents.LOCAL_UFRAG_CHANGED,\n (tpc, ufrag) => {\n if (!tpc.isP2P) {\n Statistics.sendLog(\n JSON.stringify({\n id: 'local_ufrag',\n value: ufrag\n }));\n }\n });\n rtc.addListener(RTCEvents.REMOTE_UFRAG_CHANGED,\n (tpc, ufrag) => {\n if (!tpc.isP2P) {\n Statistics.sendLog(\n JSON.stringify({\n id: 'remote_ufrag',\n value: ufrag\n }));\n }\n });\n\n rtc.addListener(RTCEvents.CREATE_ANSWER_FAILED,\n (e, tpc) => {\n conference.statistics.sendCreateAnswerFailed(e, tpc);\n if (!tpc.isP2P) {\n conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.OFFER_ANSWER_FAILED, e);\n }\n });\n\n rtc.addListener(RTCEvents.CREATE_OFFER_FAILED,\n (e, tpc) => {\n conference.statistics.sendCreateOfferFailed(e, tpc);\n if (!tpc.isP2P) {\n conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.OFFER_ANSWER_FAILED, e);\n }\n });\n\n rtc.addListener(RTCEvents.SET_LOCAL_DESCRIPTION_FAILED,\n (e, tpc) => {\n conference.statistics.sendSetLocalDescFailed(e, tpc);\n if (!tpc.isP2P) {\n conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.OFFER_ANSWER_FAILED, e);\n }\n });\n\n rtc.addListener(RTCEvents.SET_REMOTE_DESCRIPTION_FAILED,\n (e, tpc) => {\n conference.statistics.sendSetRemoteDescFailed(e, tpc);\n if (!tpc.isP2P) {\n conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_FAILED,\n JitsiConferenceErrors.OFFER_ANSWER_FAILED, e);\n }\n });\n\n rtc.addListener(RTCEvents.LOCAL_TRACK_SSRC_UPDATED,\n (track, ssrc) => {\n // when starting screen sharing, the track is created and when\n // we do set local description and we process the ssrc we\n // will be notified for it and we will report it with the event\n // for screen sharing\n if (track.isVideoTrack() && track.videoType === VideoType.DESKTOP) {\n conference.statistics.sendScreenSharingEvent(true, ssrc);\n }\n });\n};\n\n/**\n * Removes event listeners related to conference.xmpp\n */\nJitsiConferenceEventManager.prototype.removeXMPPListeners = function() {\n const conference = this.conference;\n\n conference.xmpp.caps.removeListener(\n XMPPEvents.PARTCIPANT_FEATURES_CHANGED,\n this.xmppListeners[XMPPEvents.PARTCIPANT_FEATURES_CHANGED]);\n delete this.xmppListeners[XMPPEvents.PARTCIPANT_FEATURES_CHANGED];\n\n Object.keys(this.xmppListeners).forEach(eventName => {\n conference.xmpp.removeListener(\n eventName,\n this.xmppListeners[eventName]);\n });\n this.xmppListeners = {};\n};\n\n\n/**\n * Setups event listeners related to conference.xmpp\n */\nJitsiConferenceEventManager.prototype.setupXMPPListeners = function() {\n const conference = this.conference;\n\n const featuresChangedListener = from => {\n const participant\n = conference.getParticipantById(\n Strophe.getResourceFromJid(from));\n\n if (participant) {\n conference.eventEmitter.emit(\n JitsiConferenceEvents.PARTCIPANT_FEATURES_CHANGED,\n participant);\n }\n };\n\n conference.xmpp.caps.addListener(\n XMPPEvents.PARTCIPANT_FEATURES_CHANGED,\n featuresChangedListener);\n this.xmppListeners[XMPPEvents.PARTCIPANT_FEATURES_CHANGED]\n = featuresChangedListener;\n\n this._addConferenceXMPPListener(\n XMPPEvents.CALL_INCOMING,\n conference.onIncomingCall.bind(conference));\n this._addConferenceXMPPListener(\n XMPPEvents.CALL_ACCEPTED,\n conference.onCallAccepted.bind(conference));\n this._addConferenceXMPPListener(\n XMPPEvents.TRANSPORT_INFO,\n conference.onTransportInfo.bind(conference));\n this._addConferenceXMPPListener(\n XMPPEvents.CALL_ENDED,\n conference.onCallEnded.bind(conference));\n\n this._addConferenceXMPPListener(XMPPEvents.START_MUTED_FROM_FOCUS,\n (audioMuted, videoMuted) => {\n if (conference.options.config.ignoreStartMuted) {\n return;\n }\n\n conference.startAudioMuted = audioMuted;\n conference.startVideoMuted = videoMuted;\n\n // mute existing local tracks because this is initial mute from\n // Jicofo\n conference.getLocalTracks().forEach(track => {\n switch (track.getType()) {\n case MediaType.AUDIO:\n conference.startAudioMuted && track.mute();\n break;\n case MediaType.VIDEO:\n conference.startVideoMuted && track.mute();\n break;\n }\n });\n\n conference.eventEmitter.emit(JitsiConferenceEvents.STARTED_MUTED);\n });\n\n this._addConferenceXMPPListener(XMPPEvents.CONFERENCE_TIMESTAMP_RECEIVED,\n createdTimestamp => {\n conference.eventEmitter.emit(JitsiConferenceEvents.CONFERENCE_CREATED_TIMESTAMP, createdTimestamp);\n });\n};\n\n/**\n * Add XMPP listener and save its reference for remove on leave conference.\n */\nJitsiConferenceEventManager.prototype._addConferenceXMPPListener = function(\n eventName, listener) {\n this.xmppListeners[eventName] = listener;\n this.conference.xmpp.addListener(eventName, listener);\n};\n\n/**\n * Setups event listeners related to conference.statistics\n */\nJitsiConferenceEventManager.prototype.setupStatisticsListeners = function() {\n const conference = this.conference;\n\n if (!conference.statistics) {\n return;\n }\n\n /* eslint-disable max-params */\n conference.statistics.addAudioLevelListener((tpc, ssrc, level, isLocal) => {\n conference.rtc.setAudioLevel(tpc, ssrc, level, isLocal);\n });\n\n /* eslint-enable max-params */\n\n // Forward the \"before stats disposed\" event\n conference.statistics.addBeforeDisposedListener(() => {\n conference.eventEmitter.emit(\n JitsiConferenceEvents.BEFORE_STATISTICS_DISPOSED);\n });\n\n // if we are in startSilent mode we will not be sending/receiving so nothing to detect\n if (!conference.options.config.startSilent) {\n conference.statistics.addByteSentStatsListener((tpc, stats) => {\n conference.getLocalTracks(MediaType.AUDIO).forEach(track => {\n const ssrc = tpc.getLocalSSRC(track);\n\n if (!ssrc || !stats.hasOwnProperty(ssrc)) {\n return;\n }\n\n track._onByteSentStatsReceived(tpc, stats[ssrc]);\n });\n });\n }\n};\n", "/**\n * Implements utility to forward events from one eventEmitter to another.\n * @param src {object} instance of EventEmitter or another class that implements\n * addListener method which will register listener to EventEmitter instance.\n * @param dest {object} instance of EventEmitter or another class that\n * implements emit method which will emit an event.\n */\nfunction EventEmitterForwarder(src, dest) {\n if (!src || !dest || typeof src.addListener !== 'function'\n || typeof dest.emit !== 'function') {\n throw new Error('Invalid arguments passed to EventEmitterForwarder');\n }\n this.src = src;\n this.dest = dest;\n}\n\n/**\n * Adds event to be forwarded from src to dest.\n * @param srcEvent {string} the event that EventEmitterForwarder is listening\n * for.\n * @param dstEvent {string} the event that will be fired from dest.\n * @param arguments all other passed arguments are going to be fired with\n * dstEvent.\n */\nEventEmitterForwarder.prototype.forward = function(...args) {\n const srcEvent = args[0];\n\n // This will be the \"this\" value for emit function.\n\n args[0] = this.dest;\n\n // Using bind.apply to pass the arguments as Array-like object (\"arguments\")\n this.src.addListener(\n srcEvent,\n Function.prototype.bind.apply(this.dest.emit, args));\n};\n\nmodule.exports = EventEmitterForwarder;\n", "\nimport { Strophe } from 'strophe.js';\n\nimport { getLogger } from 'jitsi-meet-logger';\n\nimport * as JitsiConferenceEvents from './JitsiConferenceEvents';\nimport { ParticipantConnectionStatus }\n from './modules/connectivity/ParticipantConnectionStatus';\nimport { ERROR_FEATURE_VERSION_MISMATCH } from './modules/xmpp/Caps';\nimport * as MediaType from './service/RTC/MediaType';\n\nconst logger = getLogger(__filename);\n\n/**\n * Represents a participant in (i.e. a member of) a conference.\n */\nexport default class JitsiParticipant {\n\n /* eslint-disable max-params */\n\n /**\n * Initializes a new JitsiParticipant instance.\n *\n * @constructor\n * @param jid the conference XMPP jid\n * @param conference\n * @param displayName\n * @param {Boolean} hidden - True if the new JitsiParticipant instance is to\n * represent a hidden participant; otherwise, false.\n * @param {string} statsID - optional participant statsID\n * @param {string} status - the initial status if any.\n * @param {object} identity - the xmpp identity\n */\n constructor(jid, conference, displayName, hidden, statsID, status, identity) {\n this._jid = jid;\n this._id = Strophe.getResourceFromJid(jid);\n this._conference = conference;\n this._displayName = displayName;\n this._supportsDTMF = false;\n this._tracks = [];\n this._role = 'none';\n this._status = status;\n this._hidden = hidden;\n this._statsID = statsID;\n this._connectionStatus = ParticipantConnectionStatus.ACTIVE;\n this._properties = {};\n this._identity = identity;\n }\n\n /* eslint-enable max-params */\n\n /**\n * @returns {JitsiConference} The conference that this participant belongs\n * to.\n */\n getConference() {\n return this._conference;\n }\n\n /**\n * Gets the value of a property of this participant.\n */\n getProperty(name) {\n return this._properties[name];\n }\n\n /**\n * Checks whether this JitsiParticipant has any video tracks which\n * are muted according to their underlying WebRTC MediaStreamTrack\n * muted status.\n * @return {boolean} true if this participant contains any\n * video JitsiTracks which are muted as defined in\n * {@link JitsiTrack.isWebRTCTrackMuted}.\n */\n hasAnyVideoTrackWebRTCMuted() {\n return (\n this.getTracks().some(\n jitsiTrack =>\n jitsiTrack.getType() === MediaType.VIDEO\n && jitsiTrack.isWebRTCTrackMuted()));\n }\n\n /**\n * Updates participant's connection status.\n * @param {string} state the current participant connection state.\n * {@link ParticipantConnectionStatus}.\n * @private\n */\n _setConnectionStatus(status) {\n this._connectionStatus = status;\n }\n\n /**\n * Return participant's connectivity status.\n *\n * @returns {string} the connection status\n * ParticipantConnectionStatus of the user.\n * {@link ParticipantConnectionStatus}.\n */\n getConnectionStatus() {\n return this._connectionStatus;\n }\n\n /**\n * Sets the value of a property of this participant, and fires an event if\n * the value has changed.\n * @name the name of the property.\n * @value the value to set.\n */\n setProperty(name, value) {\n const oldValue = this._properties[name];\n\n if (value !== oldValue) {\n this._properties[name] = value;\n this._conference.eventEmitter.emit(\n JitsiConferenceEvents.PARTICIPANT_PROPERTY_CHANGED,\n this,\n name,\n oldValue,\n value);\n }\n }\n\n /**\n * @returns {Array.} The list of media tracks for this\n * participant.\n */\n getTracks() {\n return this._tracks.slice();\n }\n\n /**\n * @param {MediaType} mediaType\n * @returns {Array.} an array of media tracks for this\n * participant, for given media type.\n */\n getTracksByMediaType(mediaType) {\n return this.getTracks().filter(track => track.getType() === mediaType);\n }\n\n /**\n * @returns {String} The ID of this participant.\n */\n getId() {\n return this._id;\n }\n\n /**\n * @returns {String} The JID of this participant.\n */\n getJid() {\n return this._jid;\n }\n\n /**\n * @returns {String} The human-readable display name of this participant.\n */\n getDisplayName() {\n return this._displayName;\n }\n\n /**\n * @returns {String} The stats ID of this participant.\n */\n getStatsID() {\n return this._statsID;\n }\n\n /**\n * @returns {String} The status of the participant.\n */\n getStatus() {\n return this._status;\n }\n\n /**\n * @returns {Boolean} Whether this participant is a moderator or not.\n */\n isModerator() {\n return this._role === 'moderator';\n }\n\n /**\n * @returns {Boolean} Whether this participant is a hidden participant. Some\n * special system participants may want to join hidden (like for example the\n * recorder).\n */\n isHidden() {\n return this._hidden;\n }\n\n /**\n * @returns {Boolean} Whether this participant has muted their audio.\n */\n isAudioMuted() {\n return this._isMediaTypeMuted(MediaType.AUDIO);\n }\n\n /**\n * Determines whether all JitsiTracks which are of a specific MediaType and\n * which belong to this JitsiParticipant are muted.\n *\n * @param {MediaType} mediaType - The MediaType of the JitsiTracks to be\n * checked.\n * @private\n * @returns {Boolean} True if all JitsiTracks which are of the specified\n * mediaType and which belong to this JitsiParticipant are muted; otherwise,\n * false.\n */\n _isMediaTypeMuted(mediaType) {\n return this.getTracks().reduce(\n (muted, track) =>\n muted && (track.getType() !== mediaType || track.isMuted()),\n true);\n }\n\n /**\n * @returns {Boolean} Whether this participant has muted their video.\n */\n isVideoMuted() {\n return this._isMediaTypeMuted(MediaType.VIDEO);\n }\n\n /**\n * @returns {String} The role of this participant.\n */\n getRole() {\n return this._role;\n }\n\n /**\n *\n */\n supportsDTMF() {\n return this._supportsDTMF;\n }\n\n /**\n * Returns a set with the features for the participant.\n * @param {int} timeout the timeout in ms for reply from the participant.\n * @returns {Promise, Error>}\n */\n getFeatures(timeout = 5000) {\n if (this._getFeaturesPromise) {\n return this._getFeaturesPromise;\n }\n\n this._getFeaturesPromise = this._conference.xmpp.caps.getFeatures(this._jid, timeout)\n .catch(error => {\n // Retry on feature version mismatch\n if (error === ERROR_FEATURE_VERSION_MISMATCH) {\n return this._conference.xmpp.caps.getFeatures(this._jid, timeout);\n }\n\n logger.warn(`Failed to discover features of ${this._jid}`, error);\n\n return Promise.reject(error);\n });\n\n return this._getFeaturesPromise\n .then(result => {\n this._getFeaturesPromise = undefined;\n\n return result;\n }, error => {\n this._getFeaturesPromise = undefined;\n\n throw error;\n });\n }\n\n /**\n * Returns the bot type for the participant.\n *\n * @returns {string|undefined} - The bot type of the participant.\n */\n getBotType() {\n return this._botType;\n }\n}\n", "import {\n CONNECTION_DISCONNECTED,\n CONNECTION_ESTABLISHED,\n CONNECTION_FAILED\n} from './JitsiConnectionEvents';\nimport XMPP from './modules/xmpp/xmpp';\n\n/**\n * @typedef {Object} UpgradeRoleError\n *\n * @property {JitsiConnectionErrors} [connectionError] - One of\n * {@link JitsiConnectionErrors} which occurred when trying to connect to the\n * XMPP server.\n * @property {String} [authenticationError] - One of XMPP error conditions\n * returned by Jicofo on authentication attempt. See\n * {@link https://xmpp.org/rfcs/rfc3920.html#streams-error}.\n * @property {String} [message] - More details about the error.\n * @property {Object} [credentials] - The credentials that failed the\n * authentication.\n * @property {String} [credentials.jid] - The XMPP ID part of the credentials\n * that failed the authentication.\n * @property {string} [credentials.password] - The password part of the\n * credentials that failed the authentication.\n *\n * NOTE If neither one of the errors is present, then the operation has been\n * canceled.\n */\n\n/* eslint-disable no-invalid-this */\n\n/**\n * Connects to the XMPP server using the specified credentials and contacts\n * Jicofo in order to obtain a session ID (which is then stored in the local\n * storage). The user's role of the parent conference will be upgraded to\n * moderator (by Jicofo). It's also used to join the conference when starting\n * from anonymous domain and only authenticated users are allowed to create new\n * rooms.\n *\n * @param {Object} options\n * @param {string} options.id - XMPP user's ID to log in. For example,\n * user@xmpp-server.com.\n * @param {string} options.password - XMPP user's password to log in with.\n * @param {string} [options.roomPassword] - The password to join the MUC with.\n * @param {Function} [options.onLoginSuccessful] - Callback called when logging\n * into the XMPP server was successful. The next step will be to obtain a new\n * session ID from Jicofo and join the MUC using it which will effectively\n * upgrade the user's role to moderator.\n * @returns {Object} A thenable which (1) settles when the process of\n * authenticating and upgrading the role of the specified XMPP user finishes and\n * (2) has a cancel method that allows the caller to interrupt the\n * process. If the process finishes successfully, the session ID has been stored\n * in the settings and the thenable is resolved. If the process\n * finishes with failure, the thenable is rejected with reason of type\n * {@link UpgradeRoleError} which will have either connectionError or\n * authenticationError property set depending on which of the steps has\n * failed. If cancel is called before the process finishes, then the\n * thenable will be rejected with an empty object (i.e. no error property will\n * be set on the rejection reason).\n */\nexport default function authenticateAndUpgradeRole({\n // 1. Log the specified XMPP user in.\n id,\n password,\n onCreateResource,\n\n // 2. Let the API client/consumer know as soon as the XMPP user has been\n // successfully logged in.\n onLoginSuccessful,\n\n // 3. Join the MUC.\n roomPassword\n}) {\n let canceled = false;\n let rejectPromise;\n let xmpp = new XMPP(this.connection.options);\n\n const process = new Promise((resolve, reject) => {\n // The process is represented by a Thenable with a cancel method. The\n // Thenable is implemented using Promise and the cancel using the\n // Promise's reject function.\n rejectPromise = reject;\n\n\n xmpp.addListener(\n CONNECTION_DISCONNECTED,\n () => {\n xmpp = undefined;\n });\n xmpp.addListener(\n CONNECTION_ESTABLISHED,\n () => {\n if (canceled) {\n return;\n }\n\n // Let the caller know that the XMPP login was successful.\n onLoginSuccessful && onLoginSuccessful();\n\n // Now authenticate with Jicofo and get a new session ID.\n const room = xmpp.createRoom(\n this.options.name,\n this.options.config,\n onCreateResource\n );\n\n room.moderator.authenticate()\n .then(() => {\n xmpp && xmpp.disconnect();\n\n if (canceled) {\n return;\n }\n\n // At this point we should have the new session ID\n // stored in the settings. Jicofo will allow to join the\n // room.\n this.join(roomPassword);\n\n resolve();\n })\n .catch(({ error, message }) => {\n xmpp.disconnect();\n\n reject({\n authenticationError: error,\n message\n });\n });\n });\n xmpp.addListener(\n CONNECTION_FAILED,\n (connectionError, message, credentials) => {\n reject({\n connectionError,\n credentials,\n message\n });\n xmpp = undefined;\n });\n\n canceled || xmpp.connect(id, password);\n });\n\n /**\n * Cancels the process, if it's in progress, of authenticating and upgrading\n * the role of the local participant/user.\n *\n * @public\n * @returns {void}\n */\n process.cancel = () => {\n canceled = true;\n rejectPromise({});\n xmpp && xmpp.disconnect();\n };\n\n return process;\n}\n\n/* eslint-enable no-invalid-this */\n", "/* global $ */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport { Strophe } from 'strophe.js';\n\nimport ChatRoom from './ChatRoom';\nimport { ConnectionPluginListenable } from './ConnectionPlugin';\nimport XMPPEvents from '../../service/xmpp/XMPPEvents';\n\nconst logger = getLogger(__filename);\n\n/**\n * MUC connection plugin.\n */\nexport default class MucConnectionPlugin extends ConnectionPluginListenable {\n /**\n *\n * @param xmpp\n */\n constructor(xmpp) {\n super();\n this.xmpp = xmpp;\n this.rooms = {};\n }\n\n /**\n *\n * @param connection\n */\n init(connection) {\n super.init(connection);\n\n // add handlers (just once)\n this.connection.addHandler(this.onPresence.bind(this), null,\n 'presence', null, null, null, null);\n this.connection.addHandler(this.onPresenceUnavailable.bind(this),\n null, 'presence', 'unavailable', null);\n this.connection.addHandler(this.onPresenceError.bind(this), null,\n 'presence', 'error', null);\n this.connection.addHandler(this.onMessage.bind(this), null,\n 'message', null, null);\n this.connection.addHandler(this.onMute.bind(this),\n 'http://jitsi.org/jitmeet/audio', 'iq', 'set', null, null);\n }\n\n /**\n *\n * @param jid\n * @param password\n * @param options\n */\n createRoom(jid, password, options) {\n const roomJid = Strophe.getBareJidFromJid(jid);\n\n if (this.rooms[roomJid]) {\n const errmsg = 'You are already in the room!';\n\n logger.error(errmsg);\n throw new Error(errmsg);\n }\n this.rooms[roomJid] = new ChatRoom(this.connection, jid,\n password, this.xmpp, options);\n this.eventEmitter.emit(\n XMPPEvents.EMUC_ROOM_ADDED, this.rooms[roomJid]);\n\n return this.rooms[roomJid];\n }\n\n /**\n *\n * @param jid\n */\n doLeave(jid) {\n this.eventEmitter.emit(\n XMPPEvents.EMUC_ROOM_REMOVED, this.rooms[jid]);\n delete this.rooms[jid];\n }\n\n /**\n *\n * @param pres\n */\n onPresence(pres) {\n const from = pres.getAttribute('from');\n\n // What is this for? A workaround for something?\n if (pres.getAttribute('type')) {\n return true;\n }\n\n const room = this.rooms[Strophe.getBareJidFromJid(from)];\n\n if (!room) {\n return true;\n }\n\n // Parse status.\n if ($(pres).find('>x[xmlns=\"http://jabber.org/protocol/muc#user\"]'\n + '>status[code=\"201\"]').length) {\n room.createNonAnonymousRoom();\n }\n\n room.onPresence(pres);\n\n return true;\n }\n\n /**\n *\n * @param pres\n */\n onPresenceUnavailable(pres) {\n const from = pres.getAttribute('from');\n const room = this.rooms[Strophe.getBareJidFromJid(from)];\n\n if (!room) {\n return true;\n }\n\n room.onPresenceUnavailable(pres, from);\n\n return true;\n }\n\n /**\n *\n * @param pres\n */\n onPresenceError(pres) {\n const from = pres.getAttribute('from');\n const room = this.rooms[Strophe.getBareJidFromJid(from)];\n\n if (!room) {\n return true;\n }\n\n room.onPresenceError(pres, from);\n\n return true;\n }\n\n /**\n *\n * @param msg\n */\n onMessage(msg) {\n // FIXME: this is a hack. but jingle on muc makes nickchanges hard\n const from = msg.getAttribute('from');\n const room = this.rooms[Strophe.getBareJidFromJid(from)];\n\n if (!room) {\n return true;\n }\n\n room.onMessage(msg, from);\n\n return true;\n }\n\n /**\n * TODO: Document\n * @param iq\n */\n onMute(iq) {\n const from = iq.getAttribute('from');\n const room = this.rooms[Strophe.getBareJidFromJid(from)];\n\n // Returning false would result in the listener being deregistered by Strophe\n if (!room) {\n return true;\n }\n\n room.onMute(iq);\n\n return true;\n }\n}\n", "/* global $, __filename */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport { $iq, $msg, $pres, Strophe } from 'strophe.js';\n\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport * as JitsiTranscriptionStatus from '../../JitsiTranscriptionStatus';\nimport Listenable from '../util/Listenable';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport XMPPEvents from '../../service/xmpp/XMPPEvents';\n\nimport Moderator from './moderator';\nimport XmppConnection from './XmppConnection';\n\nconst logger = getLogger(__filename);\n\nexport const parser = {\n packet2JSON(xmlElement, nodes) {\n for (const child of Array.from(xmlElement.children)) {\n const node = {\n attributes: {},\n children: [],\n tagName: child.tagName\n };\n\n for (const attr of Array.from(child.attributes)) {\n node.attributes[attr.name] = attr.value;\n }\n const text = Strophe.getText(child);\n\n if (text) {\n // Using Strophe.getText will do work for traversing all direct\n // child text nodes but returns an escaped value, which is not\n // desirable at this point.\n node.value = Strophe.xmlunescape(text);\n }\n nodes.push(node);\n this.packet2JSON(child, node.children);\n }\n },\n json2packet(nodes, packet) {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n if (node) {\n packet.c(node.tagName, node.attributes);\n if (node.value) {\n packet.t(node.value);\n }\n if (node.children) {\n this.json2packet(node.children, packet);\n }\n packet.up();\n }\n }\n\n // packet.up();\n }\n};\n\n/**\n * Returns array of JS objects from the presence JSON associated with the passed\n / nodeName\n * @param pres the presence JSON\n * @param nodeName the name of the node (videomuted, audiomuted, etc)\n */\nfunction filterNodeFromPresenceJSON(pres, nodeName) {\n const res = [];\n\n for (let i = 0; i < pres.length; i++) {\n if (pres[i].tagName === nodeName) {\n res.push(pres[i]);\n }\n }\n\n return res;\n}\n\n// XXX As ChatRoom constructs XMPP stanzas and Strophe is build around the idea\n// of chaining function calls, allow long function call chains.\n/* eslint-disable newline-per-chained-call */\n\n/**\n *\n */\nexport default class ChatRoom extends Listenable {\n\n /* eslint-disable max-params */\n\n /**\n *\n * @param {XmppConnection} connection - The XMPP connection instance.\n * @param jid\n * @param password\n * @param XMPP\n * @param options\n * @param {boolean} options.disableFocus - when set to {@code false} will\n * not invite Jicofo into the room. This is intended to be used only by\n * jitsi-meet-spot.\n */\n constructor(connection, jid, password, XMPP, options) {\n super();\n this.xmpp = XMPP;\n this.connection = connection;\n this.roomjid = Strophe.getBareJidFromJid(jid);\n this.myroomjid = jid;\n this.password = password;\n logger.info(`Joined MUC as ${this.myroomjid}`);\n this.members = {};\n this.presMap = {};\n this.presHandlers = {};\n this._removeConnListeners = [];\n this.joined = false;\n this.role = null;\n this.focusMucJid = null;\n this.noBridgeAvailable = false;\n this.options = options || {};\n this.moderator\n = new Moderator(this.roomjid, this.xmpp, this.eventEmitter, {\n connection: this.xmpp.options,\n conference: this.options\n });\n this.initPresenceMap(options);\n this.lastPresences = {};\n this.phoneNumber = null;\n this.phonePin = null;\n this.connectionTimes = {};\n this.participantPropertyListener = null;\n\n this.locked = false;\n this.transcriptionStatus = JitsiTranscriptionStatus.OFF;\n }\n\n /* eslint-enable max-params */\n\n /**\n *\n */\n initPresenceMap(options = {}) {\n this.presMap.to = this.myroomjid;\n this.presMap.xns = 'http://jabber.org/protocol/muc';\n this.presMap.nodes = [];\n\n if (options.statsId) {\n this.presMap.nodes.push({\n 'tagName': 'stats-id',\n 'value': options.statsId\n });\n }\n\n // We need to broadcast 'videomuted' status from the beginning, cause\n // Jicofo makes decisions based on that. Initialize it with 'false'\n // here.\n this.addVideoInfoToPresence(false);\n\n if (options.deploymentInfo && options.deploymentInfo.userRegion) {\n this.presMap.nodes.push({\n 'tagName': 'region',\n 'attributes': {\n id: options.deploymentInfo.userRegion,\n xmlns: 'http://jitsi.org/jitsi-meet'\n }\n });\n }\n }\n\n /**\n * Joins the chat room.\n * @param password\n * @returns {Promise} - resolved when join completes. At the time of this\n * writing it's never rejected.\n */\n join(password) {\n this.password = password;\n\n return new Promise(resolve => {\n this.options.disableFocus\n && logger.info('Conference focus disabled');\n\n const preJoin\n = this.options.disableFocus\n ? Promise.resolve()\n : this.moderator.allocateConferenceFocus();\n\n preJoin.then(() => {\n this.sendPresence(true);\n this._removeConnListeners.push(\n this.connection.addEventListener(\n XmppConnection.Events.CONN_STATUS_CHANGED,\n this.onConnStatusChanged.bind(this))\n );\n resolve();\n });\n });\n }\n\n /**\n *\n * @param fromJoin\n */\n sendPresence(fromJoin) {\n const to = this.presMap.to;\n\n if (!this.connection || !this.connection.connected || !to || (!this.joined && !fromJoin)) {\n // Too early to send presence - not initialized\n return;\n }\n\n const pres = $pres({ to });\n\n // xep-0045 defines: \"including in the initial presence stanza an empty\n // element qualified by the 'http://jabber.org/protocol/muc'\n // namespace\" and subsequent presences should not include that or it can\n // be considered as joining, and server can send us the message history\n // for the room on every presence\n if (fromJoin) {\n pres.c('x', { xmlns: this.presMap.xns });\n\n if (this.password) {\n pres.c('password').t(this.password).up();\n }\n pres.up();\n }\n\n parser.json2packet(this.presMap.nodes, pres);\n this.connection.send(pres);\n if (fromJoin) {\n // XXX We're pressed for time here because we're beginning a complex\n // and/or lengthy conference-establishment process which supposedly\n // involves multiple RTTs. We don't have the time to wait for\n // Strophe to decide to send our IQ.\n this.connection.flush();\n }\n }\n\n /**\n * Sends the presence unavailable, signaling the server\n * we want to leave the room.\n */\n doLeave() {\n logger.log('do leave', this.myroomjid);\n const pres = $pres({ to: this.myroomjid,\n type: 'unavailable' });\n\n this.presMap.length = 0;\n\n // XXX Strophe is asynchronously sending by default. Unfortunately, that\n // means that there may not be enough time to send the unavailable\n // presence. Switching Strophe to synchronous sending is not much of an\n // option because it may lead to a noticeable delay in navigating away\n // from the current location. As a compromise, we will try to increase\n // the chances of sending the unavailable presence within the short time\n // span that we have upon unloading by invoking flush() on the\n // connection. We flush() once before sending/queuing the unavailable\n // presence in order to attemtp to have the unavailable presence at the\n // top of the send queue. We flush() once more after sending/queuing the\n // unavailable presence in order to attempt to have it sent as soon as\n // possible.\n // FIXME do not use Strophe.Connection in the ChatRoom directly\n !this.connection.isUsingWebSocket && this.connection.flush();\n this.connection.send(pres);\n this.connection.flush();\n }\n\n /**\n *\n */\n discoRoomInfo() {\n // https://xmpp.org/extensions/xep-0045.html#disco-roominfo\n\n const getInfo\n = $iq({\n type: 'get',\n to: this.roomjid\n })\n .c('query', { xmlns: Strophe.NS.DISCO_INFO });\n\n this.connection.sendIQ(getInfo, result => {\n const locked\n = $(result).find('>query>feature[var=\"muc_passwordprotected\"]')\n .length\n === 1;\n\n if (locked !== this.locked) {\n this.eventEmitter.emit(XMPPEvents.MUC_LOCK_CHANGED, locked);\n this.locked = locked;\n }\n\n const meetingIdValEl\n = $(result).find('>query>x[type=\"result\"]>field[var=\"muc#roominfo_meetingId\"]>value');\n\n if (meetingIdValEl.length) {\n this.setMeetingId(meetingIdValEl.text());\n } else {\n logger.trace('No meeting ID from backend');\n }\n }, error => {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error('Error getting room info: ', error);\n });\n }\n\n /**\n * Sets the meeting unique Id (received from the backend).\n *\n * @param {string} meetingId - The new meetings id.\n * @returns {void}\n */\n setMeetingId(meetingId) {\n if (this.meetingId !== meetingId) {\n if (this.meetingId) {\n logger.warn(`Meeting Id changed from:${this.meetingId} to:${meetingId}`);\n }\n this.meetingId = meetingId;\n this.eventEmitter.emit(XMPPEvents.MEETING_ID_SET, meetingId);\n }\n }\n\n /**\n *\n */\n createNonAnonymousRoom() {\n // http://xmpp.org/extensions/xep-0045.html#createroom-reserved\n\n const getForm = $iq({ type: 'get',\n to: this.roomjid })\n .c('query', { xmlns: 'http://jabber.org/protocol/muc#owner' })\n .c('x', { xmlns: 'jabber:x:data',\n type: 'submit' });\n\n const self = this;\n\n this.connection.sendIQ(getForm, form => {\n if (!$(form).find(\n '>query>x[xmlns=\"jabber:x:data\"]'\n + '>field[var=\"muc#roomconfig_whois\"]').length) {\n const errmsg = 'non-anonymous rooms not supported';\n\n GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));\n logger.error(errmsg);\n\n return;\n }\n\n const formSubmit = $iq({ to: self.roomjid,\n type: 'set' })\n .c('query', { xmlns: 'http://jabber.org/protocol/muc#owner' });\n\n formSubmit.c('x', { xmlns: 'jabber:x:data',\n type: 'submit' });\n\n formSubmit.c('field', { 'var': 'FORM_TYPE' })\n .c('value')\n .t('http://jabber.org/protocol/muc#roomconfig').up().up();\n\n formSubmit.c('field', { 'var': 'muc#roomconfig_whois' })\n .c('value').t('anyone').up().up();\n\n self.connection.sendIQ(formSubmit);\n\n }, error => {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error('Error getting room configuration form: ', error);\n });\n }\n\n /**\n * Handles Xmpp Connection status updates.\n *\n * @param {Strophe.Status} status - The Strophe connection status.\n */\n onConnStatusChanged(status) {\n // Send cached presence when the XMPP connection is re-established.\n if (status === XmppConnection.Status.CONNECTED) {\n this.sendPresence();\n }\n }\n\n /**\n *\n * @param pres\n */\n onPresence(pres) {\n const from = pres.getAttribute('from');\n const member = {};\n const statusEl = pres.getElementsByTagName('status')[0];\n\n if (statusEl) {\n member.status = statusEl.textContent || '';\n }\n let hasStatusUpdate = false;\n let hasVersionUpdate = false;\n const xElement\n = pres.getElementsByTagNameNS(\n 'http://jabber.org/protocol/muc#user', 'x')[0];\n const mucUserItem\n = xElement && xElement.getElementsByTagName('item')[0];\n\n member.affiliation\n = mucUserItem && mucUserItem.getAttribute('affiliation');\n member.role = mucUserItem && mucUserItem.getAttribute('role');\n\n // Focus recognition\n const jid = mucUserItem && mucUserItem.getAttribute('jid');\n\n member.jid = jid;\n member.isFocus\n = jid && jid.indexOf(`${this.moderator.getFocusUserJid()}/`) === 0;\n member.isHiddenDomain\n = jid && jid.indexOf('@') > 0\n && this.options.hiddenDomain\n === jid.substring(jid.indexOf('@') + 1, jid.indexOf('/'));\n\n this.eventEmitter.emit(XMPPEvents.PRESENCE_RECEIVED, {\n fromHiddenDomain: member.isHiddenDomain,\n presence: pres\n });\n\n const xEl = pres.querySelector('x');\n\n if (xEl) {\n xEl.remove();\n }\n\n const nodes = [];\n\n parser.packet2JSON(pres, nodes);\n this.lastPresences[from] = nodes;\n\n // process nodes to extract data needed for MUC_JOINED and\n // MUC_MEMBER_JOINED events\n const extractIdentityInformation = node => {\n const identity = {};\n const userInfo = node.children.find(c => c.tagName === 'user');\n\n if (userInfo) {\n identity.user = {};\n for (const tag of [ 'id', 'name', 'avatar' ]) {\n const child\n = userInfo.children.find(c => c.tagName === tag);\n\n if (child) {\n identity.user[tag] = child.value;\n }\n }\n }\n const groupInfo = node.children.find(c => c.tagName === 'group');\n\n if (groupInfo) {\n identity.group = groupInfo.value;\n }\n\n return identity;\n };\n\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n switch (node.tagName) {\n case 'bot': {\n const { attributes } = node;\n\n if (!attributes) {\n break;\n }\n const { type } = attributes;\n\n member.botType = type;\n break;\n }\n case 'nick':\n member.nick = node.value;\n break;\n case 'userId':\n member.id = node.value;\n break;\n case 'stats-id':\n member.statsID = node.value;\n break;\n case 'identity':\n member.identity = extractIdentityInformation(node);\n break;\n case 'stat': {\n const { attributes } = node;\n\n if (!attributes) {\n break;\n }\n const { name } = attributes;\n\n if (name === 'version') {\n member.version = attributes.value;\n }\n break;\n }\n }\n }\n\n if (from === this.myroomjid) {\n const newRole\n = member.affiliation === 'owner' ? member.role : 'none';\n\n if (this.role !== newRole) {\n this.role = newRole;\n this.eventEmitter.emit(\n XMPPEvents.LOCAL_ROLE_CHANGED,\n this.role);\n }\n if (!this.joined) {\n this.joined = true;\n const now = this.connectionTimes['muc.joined']\n = window.performance.now();\n\n logger.log('(TIME) MUC joined:\\t', now);\n\n // set correct initial state of locked\n if (this.password) {\n this.locked = true;\n }\n\n // Re-send presence in case any presence updates were added,\n // but blocked from sending, during the join process.\n this.sendPresence();\n\n this.eventEmitter.emit(XMPPEvents.MUC_JOINED);\n\n // Now let's check the disco-info to retrieve the\n // meeting Id if any\n this.discoRoomInfo();\n }\n } else if (jid === undefined) {\n logger.info('Ignoring member with undefined JID');\n } else if (this.members[from] === undefined) {\n // new participant\n this.members[from] = member;\n logger.log('entered', from, member);\n hasStatusUpdate = member.status !== undefined;\n hasVersionUpdate = member.version !== undefined;\n if (member.isFocus) {\n this._initFocus(from, jid);\n } else {\n // identity is being added to member joined, so external\n // services can be notified for that (currently identity is\n // not used inside library)\n this.eventEmitter.emit(\n XMPPEvents.MUC_MEMBER_JOINED,\n from,\n member.nick,\n member.role,\n member.isHiddenDomain,\n member.statsID,\n member.status,\n member.identity,\n member.botType);\n\n // we are reporting the status with the join\n // so we do not want a second event about status update\n hasStatusUpdate = false;\n }\n } else {\n // Presence update for existing participant\n // Watch role change:\n const memberOfThis = this.members[from];\n\n if (memberOfThis.role !== member.role) {\n memberOfThis.role = member.role;\n this.eventEmitter.emit(\n XMPPEvents.MUC_ROLE_CHANGED, from, member.role);\n }\n\n // fire event that botType had changed\n if (memberOfThis.botType !== member.botType) {\n memberOfThis.botType = member.botType;\n this.eventEmitter.emit(\n XMPPEvents.MUC_MEMBER_BOT_TYPE_CHANGED,\n from,\n member.botType);\n }\n\n if (member.isFocus) {\n // From time to time first few presences of the focus are not\n // containing it's jid. That way we can mark later the focus\n // member instead of not marking it at all and not starting the\n // conference.\n // FIXME: Maybe there is a better way to handle this issue. It\n // seems there is some period of time in prosody that the\n // configuration form is received but not applied. And if any\n // participant joins during that period of time the first\n // presence from the focus won't contain\n // .\n memberOfThis.isFocus = true;\n this._initFocus(from, jid);\n }\n\n // store the new display name\n if (member.displayName) {\n memberOfThis.displayName = member.displayName;\n }\n\n // update stored status message to be able to detect changes\n if (memberOfThis.status !== member.status) {\n hasStatusUpdate = true;\n memberOfThis.status = member.status;\n }\n\n if (memberOfThis.version !== member.version) {\n hasVersionUpdate = true;\n memberOfThis.version = member.version;\n }\n }\n\n // after we had fired member or room joined events, lets fire events\n // for the rest info we got in presence\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n\n switch (node.tagName) {\n case 'nick':\n if (!member.isFocus) {\n const displayName\n = this.xmpp.options.displayJids\n ? Strophe.getResourceFromJid(from)\n : member.nick;\n\n this.eventEmitter.emit(\n XMPPEvents.DISPLAY_NAME_CHANGED,\n from,\n displayName);\n }\n break;\n case 'bridgeNotAvailable':\n if (member.isFocus && !this.noBridgeAvailable) {\n this.noBridgeAvailable = true;\n this.eventEmitter.emit(XMPPEvents.BRIDGE_DOWN);\n }\n break;\n case 'conference-properties':\n if (member.isFocus) {\n const properties = {};\n\n for (let j = 0; j < node.children.length; j++) {\n const { attributes } = node.children[j];\n\n if (attributes && attributes.key) {\n properties[attributes.key] = attributes.value;\n }\n }\n\n this.eventEmitter.emit(\n XMPPEvents.CONFERENCE_PROPERTIES_CHANGED, properties);\n }\n break;\n case 'transcription-status': {\n const { attributes } = node;\n\n if (!attributes) {\n break;\n }\n\n const { status } = attributes;\n\n if (status && status !== this.transcriptionStatus) {\n this.transcriptionStatus = status;\n this.eventEmitter.emit(\n XMPPEvents.TRANSCRIPTION_STATUS_CHANGED,\n status\n );\n }\n\n\n break;\n }\n case 'call-control': {\n const att = node.attributes;\n\n if (!att) {\n break;\n }\n this.phoneNumber = att.phone || null;\n this.phonePin = att.pin || null;\n this.eventEmitter.emit(XMPPEvents.PHONE_NUMBER_CHANGED);\n break;\n }\n default:\n this.processNode(node, from);\n }\n }\n\n // Trigger status message update if necessary\n if (hasStatusUpdate) {\n this.eventEmitter.emit(\n XMPPEvents.PRESENCE_STATUS,\n from,\n member.status);\n }\n\n if (hasVersionUpdate) {\n logger.info(`Received version for ${jid}: ${member.version}`);\n }\n }\n\n /**\n * Initialize some properties when the focus participant is verified.\n * @param from jid of the focus\n * @param mucJid the jid of the focus in the muc\n */\n _initFocus(from, mucJid) {\n this.focusMucJid = from;\n\n logger.info(`Ignore focus: ${from}, real JID: ${mucJid}`);\n }\n\n /**\n * Sets the special listener to be used for \"command\"s whose name starts\n * with \"jitsi_participant_\".\n */\n setParticipantPropertyListener(listener) {\n this.participantPropertyListener = listener;\n }\n\n /**\n *\n * @param node\n * @param from\n */\n processNode(node, from) {\n // make sure we catch all errors coming from any handler\n // otherwise we can remove the presence handler from strophe\n try {\n let tagHandlers = this.presHandlers[node.tagName];\n\n if (node.tagName.startsWith('jitsi_participant_')) {\n tagHandlers = [ this.participantPropertyListener ];\n }\n\n if (tagHandlers) {\n tagHandlers.forEach(handler => {\n handler(node, Strophe.getResourceFromJid(from), from);\n });\n }\n } catch (e) {\n GlobalOnErrorHandler.callErrorHandler(e);\n logger.error(`Error processing:${node.tagName} node.`, e);\n }\n }\n\n /**\n * Send text message to the other participants in the conference\n * @param message\n * @param elementName\n * @param nickname\n */\n sendMessage(message, elementName, nickname) {\n const msg = $msg({ to: this.roomjid,\n type: 'groupchat' });\n\n // We are adding the message in a packet extension. If this element\n // is different from 'body', we add a custom namespace.\n // e.g. for 'json-message' extension of message stanza.\n if (elementName === 'body') {\n msg.c(elementName, message).up();\n } else {\n msg.c(elementName, { xmlns: 'http://jitsi.org/jitmeet' }, message)\n .up();\n }\n if (nickname) {\n msg.c('nick', { xmlns: 'http://jabber.org/protocol/nick' })\n .t(nickname)\n .up()\n .up();\n }\n this.connection.send(msg);\n this.eventEmitter.emit(XMPPEvents.SENDING_CHAT_MESSAGE, message);\n }\n\n /* eslint-disable max-params */\n /**\n * Send private text message to another participant of the conference\n * @param id id/muc resource of the receiver\n * @param message\n * @param elementName\n * @param nickname\n */\n sendPrivateMessage(id, message, elementName, nickname) {\n const msg = $msg({ to: `${this.roomjid}/${id}`,\n type: 'chat' });\n\n // We are adding the message in packet. If this element is different\n // from 'body', we add our custom namespace for the same.\n // e.g. for 'json-message' message extension.\n if (elementName === 'body') {\n msg.c(elementName, message).up();\n } else {\n msg.c(elementName, { xmlns: 'http://jitsi.org/jitmeet' }, message)\n .up();\n }\n if (nickname) {\n msg.c('nick', { xmlns: 'http://jabber.org/protocol/nick' })\n .t(nickname)\n .up()\n .up();\n }\n\n this.connection.send(msg);\n this.eventEmitter.emit(\n XMPPEvents.SENDING_PRIVATE_CHAT_MESSAGE, message);\n }\n /* eslint-enable max-params */\n\n /**\n *\n * @param subject\n */\n setSubject(subject) {\n const msg = $msg({ to: this.roomjid,\n type: 'groupchat' });\n\n msg.c('subject', subject);\n this.connection.send(msg);\n }\n\n /**\n * Called when participant leaves.\n * @param jid the jid of the participant that leaves\n * @param skipEvents optional params to skip any events, including check\n * whether this is the focus that left\n */\n onParticipantLeft(jid, skipEvents) {\n delete this.lastPresences[jid];\n\n if (skipEvents) {\n return;\n }\n\n this.eventEmitter.emit(XMPPEvents.MUC_MEMBER_LEFT, jid);\n\n this.moderator.onMucMemberLeft(jid);\n }\n\n /**\n *\n * @param pres\n * @param from\n */\n onPresenceUnavailable(pres, from) {\n // ignore presence\n if ($(pres).find('>ignore[xmlns=\"http://jitsi.org/jitmeet/\"]').length) {\n return true;\n }\n\n // room destroyed ?\n if ($(pres).find('>x[xmlns=\"http://jabber.org/protocol/muc#user\"]'\n + '>destroy').length) {\n let reason;\n const reasonSelect\n = $(pres).find(\n '>x[xmlns=\"http://jabber.org/protocol/muc#user\"]'\n + '>destroy>reason');\n\n if (reasonSelect.length) {\n reason = reasonSelect.text();\n }\n\n this.eventEmitter.emit(XMPPEvents.MUC_DESTROYED, reason);\n this.connection.emuc.doLeave(this.roomjid);\n\n return true;\n }\n\n // Status code 110 indicates that this notification is \"self-presence\".\n const isSelfPresence\n = $(pres)\n .find(\n '>x[xmlns=\"http://jabber.org/protocol/muc#user\"]>'\n + 'status[code=\"110\"]')\n .length;\n const isKick\n = $(pres)\n .find(\n '>x[xmlns=\"http://jabber.org/protocol/muc#user\"]'\n + '>status[code=\"307\"]')\n .length;\n const membersKeys = Object.keys(this.members);\n\n if (isKick) {\n const actorSelect\n = $(pres)\n .find('>x[xmlns=\"http://jabber.org/protocol/muc#user\"]>item>actor');\n\n let actorNick;\n\n if (actorSelect.length) {\n actorNick = actorSelect.attr('nick');\n }\n\n // if no member is found this is the case we had kicked someone\n // and we are not in the list of members\n if (membersKeys.find(jid => Strophe.getResourceFromJid(jid) === actorNick)) {\n // we first fire the kicked so we can show the participant\n // who kicked, before notifying that participant left\n // we fire kicked for us and for any participant kicked\n this.eventEmitter.emit(\n XMPPEvents.KICKED,\n isSelfPresence,\n actorNick,\n Strophe.getResourceFromJid(from));\n }\n }\n\n if (!isSelfPresence) {\n delete this.members[from];\n this.onParticipantLeft(from, false);\n } else if (membersKeys.length > 0) {\n // If the status code is 110 this means we're leaving and we would\n // like to remove everyone else from our view, so we trigger the\n // event.\n membersKeys.forEach(jid => {\n const member = this.members[jid];\n\n delete this.members[jid];\n this.onParticipantLeft(jid, member.isFocus);\n });\n this.connection.emuc.doLeave(this.roomjid);\n\n // we fire muc_left only if this is not a kick,\n // kick has both statuses 110 and 307.\n if (!isKick) {\n this.eventEmitter.emit(XMPPEvents.MUC_LEFT);\n }\n }\n }\n\n /**\n *\n * @param msg\n * @param from\n */\n onMessage(msg, from) {\n const nick\n = $(msg).find('>nick[xmlns=\"http://jabber.org/protocol/nick\"]')\n .text()\n || Strophe.getResourceFromJid(from);\n\n const type = msg.getAttribute('type');\n\n if (type === 'error') {\n const errorMsg = $(msg).find('>error>text').text();\n\n this.eventEmitter.emit(XMPPEvents.CHAT_ERROR_RECEIVED, errorMsg);\n\n return true;\n }\n\n const txt = $(msg).find('>body').text();\n const subject = $(msg).find('>subject');\n\n if (subject.length) {\n const subjectText = subject.text();\n\n if (subjectText || subjectText === '') {\n this.eventEmitter.emit(XMPPEvents.SUBJECT_CHANGED, subjectText);\n logger.log(`Subject is changed to ${subjectText}`);\n }\n }\n\n // xep-0203 delay\n let stamp = $(msg).find('>delay').attr('stamp');\n\n if (!stamp) {\n // or xep-0091 delay, UTC timestamp\n stamp = $(msg).find('>[xmlns=\"jabber:x:delay\"]').attr('stamp');\n\n if (stamp) {\n // the format is CCYYMMDDThh:mm:ss\n const dateParts\n = stamp.match(/(\\d{4})(\\d{2})(\\d{2}T\\d{2}:\\d{2}:\\d{2})/);\n\n stamp = `${dateParts[1]}-${dateParts[2]}-${dateParts[3]}Z`;\n }\n }\n\n if (from === this.roomjid\n && $(msg).find('>x[xmlns=\"http://jabber.org/protocol/muc#user\"]>status[code=\"104\"]').length) {\n this.discoRoomInfo();\n }\n const jsonMessage = $(msg).find('>json-message').text();\n const parsedJson = this.xmpp.tryParseJSONAndVerify(jsonMessage);\n\n // We emit this event if the message is a valid json, and is not\n // delivered after a delay, i.e. stamp is undefined.\n // e.g. - subtitles should not be displayed if delayed.\n if (parsedJson && stamp === undefined) {\n this.eventEmitter.emit(XMPPEvents.JSON_MESSAGE_RECEIVED,\n from, parsedJson);\n\n return;\n }\n\n if (txt) {\n if (type === 'chat') {\n this.eventEmitter.emit(XMPPEvents.PRIVATE_MESSAGE_RECEIVED,\n from, nick, txt, this.myroomjid, stamp);\n } else if (type === 'groupchat') {\n this.eventEmitter.emit(XMPPEvents.MESSAGE_RECEIVED,\n from, nick, txt, this.myroomjid, stamp);\n }\n }\n }\n\n /**\n *\n * @param pres\n * @param from\n */\n onPresenceError(pres, from) {\n if ($(pres)\n .find(\n '>error[type=\"auth\"]'\n + '>not-authorized['\n + 'xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"]')\n .length) {\n logger.log('on password required', from);\n this.eventEmitter.emit(XMPPEvents.PASSWORD_REQUIRED);\n } else if ($(pres)\n .find(\n '>error[type=\"cancel\"]'\n + '>not-allowed['\n + 'xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"]')\n .length) {\n const toDomain = Strophe.getDomainFromJid(pres.getAttribute('to'));\n\n if (toDomain === this.xmpp.options.hosts.anonymousdomain) {\n // enter the room by replying with 'not-authorized'. This would\n // result in reconnection from authorized domain.\n // We're either missing Jicofo/Prosody config for anonymous\n // domains or something is wrong.\n this.eventEmitter.emit(XMPPEvents.ROOM_JOIN_ERROR);\n\n } else {\n logger.warn('onPresError ', pres);\n this.eventEmitter.emit(\n XMPPEvents.ROOM_CONNECT_NOT_ALLOWED_ERROR);\n }\n } else if ($(pres).find('>error>service-unavailable').length) {\n logger.warn('Maximum users limit for the room has been reached',\n pres);\n this.eventEmitter.emit(XMPPEvents.ROOM_MAX_USERS_ERROR);\n } else {\n logger.warn('onPresError ', pres);\n this.eventEmitter.emit(XMPPEvents.ROOM_CONNECT_ERROR);\n }\n }\n\n /**\n *\n * @param jid\n */\n kick(jid) {\n const kickIQ = $iq({ to: this.roomjid,\n type: 'set' })\n .c('query', { xmlns: 'http://jabber.org/protocol/muc#admin' })\n .c('item', { nick: Strophe.getResourceFromJid(jid),\n role: 'none' })\n .c('reason').t('You have been kicked.').up().up().up();\n\n this.connection.sendIQ(\n kickIQ,\n result => logger.log('Kick participant with jid: ', jid, result),\n error => logger.log('Kick participant error: ', error));\n }\n\n /* eslint-disable max-params */\n\n /**\n *\n * @param key\n * @param onSuccess\n * @param onError\n * @param onNotSupported\n */\n lockRoom(key, onSuccess, onError, onNotSupported) {\n // http://xmpp.org/extensions/xep-0045.html#roomconfig\n this.connection.sendIQ(\n $iq({\n to: this.roomjid,\n type: 'get'\n })\n .c('query', { xmlns: 'http://jabber.org/protocol/muc#owner' }),\n res => {\n if ($(res)\n .find(\n '>query>x[xmlns=\"jabber:x:data\"]'\n + '>field[var=\"muc#roomconfig_roomsecret\"]')\n .length) {\n const formsubmit\n = $iq({\n to: this.roomjid,\n type: 'set'\n })\n .c('query', {\n xmlns: 'http://jabber.org/protocol/muc#owner'\n });\n\n formsubmit.c('x', {\n xmlns: 'jabber:x:data',\n type: 'submit'\n });\n formsubmit\n .c('field', { 'var': 'FORM_TYPE' })\n .c('value')\n .t('http://jabber.org/protocol/muc#roomconfig')\n .up()\n .up();\n formsubmit\n .c('field', { 'var': 'muc#roomconfig_roomsecret' })\n .c('value')\n .t(key)\n .up()\n .up();\n formsubmit\n .c('field',\n { 'var': 'muc#roomconfig_passwordprotectedroom' })\n .c('value')\n .t(key === null || key.length === 0 ? '0' : '1')\n .up()\n .up();\n\n // Fixes a bug in prosody 0.9.+\n // https://prosody.im/issues/issue/373\n formsubmit\n .c('field', { 'var': 'muc#roomconfig_whois' })\n .c('value')\n .t('anyone')\n .up()\n .up();\n\n this.connection.sendIQ(formsubmit, onSuccess, onError);\n } else {\n onNotSupported();\n }\n },\n onError);\n }\n\n /* eslint-enable max-params */\n\n /**\n *\n * @param key\n * @param values\n */\n addToPresence(key, values) {\n values.tagName = key;\n this.removeFromPresence(key);\n this.presMap.nodes.push(values);\n }\n\n /**\n * Retreives a value from the presence map.\n *\n * @param {string} key - The key to find the value for.\n * @returns {Object?}\n */\n getFromPresence(key) {\n return this.presMap.nodes.find(node => key === node.tagName);\n }\n\n /**\n *\n * @param key\n */\n removeFromPresence(key) {\n const nodes = this.presMap.nodes.filter(node => key !== node.tagName);\n\n this.presMap.nodes = nodes;\n }\n\n /**\n *\n * @param name\n * @param handler\n */\n addPresenceListener(name, handler) {\n if (typeof handler !== 'function') {\n throw new Error('\"handler\" is not a function');\n }\n let tagHandlers = this.presHandlers[name];\n\n if (!tagHandlers) {\n this.presHandlers[name] = tagHandlers = [];\n }\n if (tagHandlers.indexOf(handler) === -1) {\n tagHandlers.push(handler);\n } else {\n logger.warn(\n `Trying to add the same handler more than once for: ${name}`);\n }\n }\n\n /**\n *\n * @param name\n * @param handler\n */\n removePresenceListener(name, handler) {\n const tagHandlers = this.presHandlers[name];\n const handlerIdx = tagHandlers ? tagHandlers.indexOf(handler) : -1;\n\n // eslint-disable-next-line no-negated-condition\n if (handlerIdx !== -1) {\n tagHandlers.splice(handlerIdx, 1);\n } else {\n logger.warn(`Handler for: ${name} was not registered`);\n }\n }\n\n /**\n * Checks if the user identified by given mucJid is the conference\n * focus.\n * @param mucJid the full MUC address of the user to be checked.\n * @returns {boolean|null} true if MUC user is the conference focus\n * or false if is not. When given mucJid does not exist in\n * the MUC then null is returned.\n */\n isFocus(mucJid) {\n const member = this.members[mucJid];\n\n if (member) {\n return member.isFocus;\n }\n\n return null;\n }\n\n /**\n *\n */\n isModerator() {\n return this.role === 'moderator';\n }\n\n /**\n *\n * @param peerJid\n */\n getMemberRole(peerJid) {\n if (this.members[peerJid]) {\n return this.members[peerJid].role;\n }\n\n return null;\n }\n\n /**\n *\n * @param mute\n * @param callback\n */\n setVideoMute(mute, callback) {\n this.sendVideoInfoPresence(mute);\n if (callback) {\n callback(mute);\n }\n }\n\n /**\n *\n * @param mute\n * @param callback\n */\n setAudioMute(mute, callback) {\n return this.sendAudioInfoPresence(mute, callback);\n }\n\n /**\n *\n * @param mute\n */\n addAudioInfoToPresence(mute) {\n this.removeFromPresence('audiomuted');\n this.addToPresence(\n 'audiomuted',\n {\n attributes: { 'xmlns': 'http://jitsi.org/jitmeet/audio' },\n value: mute.toString()\n });\n }\n\n /**\n *\n * @param mute\n * @param callback\n */\n sendAudioInfoPresence(mute, callback) {\n this.addAudioInfoToPresence(mute);\n\n // FIXME resend presence on CONNECTED\n this.sendPresence();\n if (callback) {\n callback();\n }\n }\n\n /**\n *\n * @param mute\n */\n addVideoInfoToPresence(mute) {\n this.removeFromPresence('videomuted');\n this.addToPresence(\n 'videomuted',\n {\n attributes: { 'xmlns': 'http://jitsi.org/jitmeet/video' },\n value: mute.toString()\n });\n }\n\n /**\n *\n * @param mute\n */\n sendVideoInfoPresence(mute) {\n this.addVideoInfoToPresence(mute);\n this.sendPresence();\n }\n\n /**\n * Obtains the info about given media advertised in the MUC presence of\n * the participant identified by the given endpoint JID.\n * @param {string} endpointId the endpoint ID mapped to the participant\n * which corresponds to MUC nickname.\n * @param {MediaType} mediaType the type of the media for which presence\n * info will be obtained.\n * @return {PeerMediaInfo} presenceInfo an object with media presence\n * info or null either if there is no presence available or if\n * the media type given is invalid.\n */\n getMediaPresenceInfo(endpointId, mediaType) {\n // Will figure out current muted status by looking up owner's presence\n const pres = this.lastPresences[`${this.roomjid}/${endpointId}`];\n\n if (!pres) {\n // No presence available\n return null;\n }\n const data = {\n muted: false, // unmuted by default\n videoType: undefined // no video type by default\n };\n let mutedNode = null;\n\n if (mediaType === MediaType.AUDIO) {\n mutedNode = filterNodeFromPresenceJSON(pres, 'audiomuted');\n } else if (mediaType === MediaType.VIDEO) {\n mutedNode = filterNodeFromPresenceJSON(pres, 'videomuted');\n const videoTypeNode = filterNodeFromPresenceJSON(pres, 'videoType');\n\n if (videoTypeNode.length > 0) {\n data.videoType = videoTypeNode[0].value;\n }\n } else {\n logger.error(`Unsupported media type: ${mediaType}`);\n\n return null;\n }\n\n data.muted = mutedNode.length > 0 && mutedNode[0].value === 'true';\n\n return data;\n }\n\n /**\n * Returns true if the SIP calls are supported and false otherwise\n */\n isSIPCallingSupported() {\n if (this.moderator) {\n return this.moderator.isSipGatewayEnabled();\n }\n\n return false;\n }\n\n /**\n * Dials a number.\n * @param number the number\n */\n dial(number) {\n return this.connection.rayo.dial(number, 'fromnumber',\n Strophe.getBareJidFromJid(this.myroomjid), this.password,\n this.focusMucJid);\n }\n\n /**\n * Hangup an existing call\n */\n hangup() {\n return this.connection.rayo.hangup();\n }\n\n /**\n * Returns the phone number for joining the conference.\n */\n getPhoneNumber() {\n return this.phoneNumber;\n }\n\n /**\n * Returns the pin for joining the conference with phone.\n */\n getPhonePin() {\n return this.phonePin;\n }\n\n /**\n * Returns the meeting unique ID if any came from backend.\n *\n * @returns {string} - The meeting ID.\n */\n getMeetingId() {\n return this.meetingId;\n }\n\n /**\n * Mutes remote participant.\n * @param jid of the participant\n * @param mute\n */\n muteParticipant(jid, mute) {\n logger.info('set mute', mute);\n const iqToFocus = $iq(\n { to: this.focusMucJid,\n type: 'set' })\n .c('mute', {\n xmlns: 'http://jitsi.org/jitmeet/audio',\n jid\n })\n .t(mute.toString())\n .up();\n\n this.connection.sendIQ(\n iqToFocus,\n result => logger.log('set mute', result),\n error => logger.log('set mute error', error));\n }\n\n /**\n * TODO: Document\n * @param iq\n */\n onMute(iq) {\n const from = iq.getAttribute('from');\n\n if (from !== this.focusMucJid) {\n logger.warn('Ignored mute from non focus peer');\n\n return;\n }\n const mute = $(iq).find('mute');\n\n if (mute.length && mute.text() === 'true') {\n this.eventEmitter.emit(XMPPEvents.AUDIO_MUTED_BY_FOCUS, mute.attr('actor'));\n } else {\n // XXX Why do we support anything but muting? Why do we encode the\n // value in the text of the element? Why do we use a separate XML\n // namespace?\n logger.warn('Ignoring a mute request which does not explicitly '\n + 'specify a positive mute command.');\n }\n }\n\n /**\n * Leaves the room. Closes the jingle session.\n * @returns {Promise} which is resolved if XMPPEvents.MUC_LEFT is received\n * less than 5s after sending presence unavailable. Otherwise the promise is\n * rejected.\n */\n leave() {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => onMucLeft(true), 5000);\n const eventEmitter = this.eventEmitter;\n\n this._removeConnListeners.forEach(remove => remove());\n this._removeConnListeners = [];\n\n /**\n *\n * @param doReject\n */\n function onMucLeft(doReject = false) {\n eventEmitter.removeListener(XMPPEvents.MUC_LEFT, onMucLeft);\n clearTimeout(timeout);\n if (doReject) {\n // the timeout expired\n reject(new Error('The timeout for the confirmation about '\n + 'leaving the room expired.'));\n } else {\n resolve();\n }\n }\n eventEmitter.on(XMPPEvents.MUC_LEFT, onMucLeft);\n this.doLeave();\n });\n }\n}\n\n/* eslint-enable newline-per-chained-call */\n", "/* global $, Promise */\n\nconst logger = require('jitsi-meet-logger').getLogger(__filename);\n\nimport { $iq, Strophe } from 'strophe.js';\n\nconst XMPPEvents = require('../../service/xmpp/XMPPEvents');\nconst AuthenticationEvents\n = require('../../service/authentication/AuthenticationEvents');\nconst GlobalOnErrorHandler = require('../util/GlobalOnErrorHandler');\n\nimport Settings from '../settings/Settings';\n\n/**\n *\n * @param step\n */\nfunction createExpBackoffTimer(step) {\n let count = 1;\n\n return function(reset) {\n // Reset call\n if (reset) {\n count = 1;\n\n return;\n }\n\n // Calculate next timeout\n const timeout = Math.pow(2, count - 1);\n\n count += 1;\n\n return timeout * step;\n };\n}\n\n/* eslint-disable max-params */\n\n/**\n *\n * @param roomName\n * @param xmpp\n * @param emitter\n * @param options\n */\nexport default function Moderator(roomName, xmpp, emitter, options) {\n this.roomName = roomName;\n this.xmppService = xmpp;\n this.getNextTimeout = createExpBackoffTimer(1000);\n this.getNextErrorTimeout = createExpBackoffTimer(1000);\n\n // External authentication stuff\n this.externalAuthEnabled = false;\n this.options = options;\n\n // Sip gateway can be enabled by configuring Jigasi host in config.js or\n // it will be enabled automatically if focus detects the component through\n // service discovery.\n this.sipGatewayEnabled\n = this.options.connection.hosts\n && this.options.connection.hosts.call_control !== undefined;\n\n this.eventEmitter = emitter;\n\n this.connection = this.xmppService.connection;\n\n // FIXME: Message listener that talks to POPUP window\n /**\n *\n * @param event\n */\n function listener(event) {\n if (event.data && event.data.sessionId) {\n if (event.origin !== window.location.origin) {\n logger.warn(\n `Ignoring sessionId from different origin: ${\n event.origin}`);\n\n return;\n }\n Settings.sessionId = event.data.sessionId;\n\n // After popup is closed we will authenticate\n }\n }\n\n // Register\n if (window.addEventListener) {\n window.addEventListener('message', listener, false);\n } else {\n window.attachEvent('onmessage', listener);\n }\n}\n\n/* eslint-enable max-params */\n\nModerator.prototype.isExternalAuthEnabled = function() {\n return this.externalAuthEnabled;\n};\n\nModerator.prototype.isSipGatewayEnabled = function() {\n return this.sipGatewayEnabled;\n};\n\nModerator.prototype.onMucMemberLeft = function(jid) {\n logger.info(`Someone left is it focus ? ${jid}`);\n const resource = Strophe.getResourceFromJid(jid);\n\n if (resource === 'focus') {\n logger.info(\n 'Focus has left the room - leaving conference');\n this.eventEmitter.emit(XMPPEvents.FOCUS_LEFT);\n }\n};\n\nModerator.prototype.setFocusUserJid = function(focusJid) {\n if (!this.focusUserJid) {\n this.focusUserJid = focusJid;\n logger.info(`Focus jid set to: ${this.focusUserJid}`);\n }\n};\n\nModerator.prototype.getFocusUserJid = function() {\n return this.focusUserJid;\n};\n\nModerator.prototype.getFocusComponent = function() {\n // Get focus component address\n let focusComponent = this.options.connection.hosts.focus;\n\n // If not specified use default: 'focus.domain'\n\n if (!focusComponent) {\n focusComponent = `focus.${this.options.connection.hosts.domain}`;\n }\n\n return focusComponent;\n};\n\nModerator.prototype.createConferenceIq = function() {\n // Generate create conference IQ\n const elem = $iq({ to: this.getFocusComponent(),\n type: 'set' });\n\n // Session Id used for authentication\n const { sessionId } = Settings;\n const machineUID = Settings.machineId;\n const config = this.options.conference;\n\n logger.info(`Session ID: ${sessionId} machine UID: ${machineUID}`);\n\n elem.c('conference', {\n xmlns: 'http://jitsi.org/protocol/focus',\n room: this.roomName,\n 'machine-uid': machineUID\n });\n\n if (sessionId) {\n elem.attrs({ 'session-id': sessionId });\n }\n if (this.options.connection.enforcedBridge !== undefined) {\n elem.c(\n 'property', {\n name: 'enforcedBridge',\n value: this.options.connection.enforcedBridge\n }).up();\n }\n\n // Tell the focus we have Jigasi configured\n if (this.options.connection.hosts !== undefined\n && this.options.connection.hosts.call_control !== undefined) {\n elem.c(\n 'property', {\n name: 'call_control',\n value: this.options.connection.hosts.call_control\n }).up();\n }\n if (config.channelLastN !== undefined) {\n elem.c(\n 'property', {\n name: 'channelLastN',\n value: config.channelLastN\n }).up();\n }\n elem.c(\n 'property', {\n name: 'disableRtx',\n value: Boolean(config.disableRtx)\n }).up();\n\n if (config.enableTcc !== undefined) {\n elem.c(\n 'property', {\n name: 'enableTcc',\n value: Boolean(config.enableTcc)\n }).up();\n }\n if (config.enableRemb !== undefined) {\n elem.c(\n 'property', {\n name: 'enableRemb',\n value: Boolean(config.enableRemb)\n }).up();\n }\n if (config.minParticipants !== undefined) {\n elem.c(\n 'property', {\n name: 'minParticipants',\n value: config.minParticipants\n }).up();\n }\n\n elem.c(\n 'property', {\n name: 'enableLipSync',\n value: this.options.connection.enableLipSync === true\n }).up();\n if (config.audioPacketDelay !== undefined) {\n elem.c(\n 'property', {\n name: 'audioPacketDelay',\n value: config.audioPacketDelay\n }).up();\n }\n if (config.startBitrate) {\n elem.c(\n 'property', {\n name: 'startBitrate',\n value: config.startBitrate\n }).up();\n }\n if (config.minBitrate) {\n elem.c(\n 'property', {\n name: 'minBitrate',\n value: config.minBitrate\n }).up();\n }\n if (config.testing && config.testing.octo\n && typeof config.testing.octo.probability === 'number') {\n if (Math.random() < config.testing.octo.probability) {\n elem.c(\n 'property', {\n name: 'octo',\n value: true\n }).up();\n }\n }\n\n let openSctp;\n\n switch (this.options.conference.openBridgeChannel) {\n case 'datachannel':\n case true:\n case undefined:\n openSctp = true;\n break;\n case 'websocket':\n openSctp = false;\n break;\n }\n\n elem.c(\n 'property', {\n name: 'openSctp',\n value: openSctp\n }).up();\n\n if (this.options.conference.startAudioMuted !== undefined) {\n elem.c(\n 'property', {\n name: 'startAudioMuted',\n value: this.options.conference.startAudioMuted\n }).up();\n }\n if (this.options.conference.startVideoMuted !== undefined) {\n elem.c(\n 'property', {\n name: 'startVideoMuted',\n value: this.options.conference.startVideoMuted\n }).up();\n }\n if (this.options.conference.stereo !== undefined) {\n elem.c(\n 'property', {\n name: 'stereo',\n value: this.options.conference.stereo\n }).up();\n }\n if (this.options.conference.useRoomAsSharedDocumentName !== undefined) {\n elem.c(\n 'property', {\n name: 'useRoomAsSharedDocumentName',\n value: this.options.conference.useRoomAsSharedDocumentName\n }).up();\n }\n elem.up();\n\n return elem;\n};\n\n\nModerator.prototype.parseSessionId = function(resultIq) {\n // eslint-disable-next-line newline-per-chained-call\n const sessionId = $(resultIq).find('conference').attr('session-id');\n\n if (sessionId) {\n logger.info(`Received sessionId: ${sessionId}`);\n Settings.sessionId = sessionId;\n }\n};\n\nModerator.prototype.parseConfigOptions = function(resultIq) {\n // eslint-disable-next-line newline-per-chained-call\n this.setFocusUserJid($(resultIq).find('conference').attr('focusjid'));\n\n const authenticationEnabled\n = $(resultIq).find(\n '>conference>property'\n + '[name=\\'authentication\\'][value=\\'true\\']').length > 0;\n\n logger.info(`Authentication enabled: ${authenticationEnabled}`);\n\n this.externalAuthEnabled = $(resultIq).find(\n '>conference>property'\n + '[name=\\'externalAuth\\'][value=\\'true\\']').length > 0;\n\n logger.info(\n `External authentication enabled: ${this.externalAuthEnabled}`);\n\n if (!this.externalAuthEnabled) {\n // We expect to receive sessionId in 'internal' authentication mode\n this.parseSessionId(resultIq);\n }\n\n // eslint-disable-next-line newline-per-chained-call\n const authIdentity = $(resultIq).find('>conference').attr('identity');\n\n this.eventEmitter.emit(AuthenticationEvents.IDENTITY_UPDATED,\n authenticationEnabled, authIdentity);\n\n // Check if focus has auto-detected Jigasi component(this will be also\n // included if we have passed our host from the config)\n if ($(resultIq).find(\n '>conference>property'\n + '[name=\\'sipGatewayEnabled\\'][value=\\'true\\']').length) {\n this.sipGatewayEnabled = true;\n }\n\n logger.info(`Sip gateway enabled: ${this.sipGatewayEnabled}`);\n};\n\n// FIXME We need to show the fact that we're waiting for the focus to the user\n// (or that the focus is not available)\n/**\n * Allocates the conference focus.\n *\n * @param {Function} callback - the function to be called back upon the\n * successful allocation of the conference focus\n * @returns {Promise} - Resolved when Jicofo allows to join the room. It's never\n * rejected and it'll keep on pinging Jicofo forever.\n */\nModerator.prototype.allocateConferenceFocus = function() {\n return new Promise(resolve => {\n // Try to use focus user JID from the config\n this.setFocusUserJid(this.options.connection.focusUserJid);\n\n // Send create conference IQ\n this.connection.sendIQ(\n this.createConferenceIq(),\n result => this._allocateConferenceFocusSuccess(result, resolve),\n error => this._allocateConferenceFocusError(error, resolve));\n\n // XXX We're pressed for time here because we're beginning a complex\n // and/or lengthy conference-establishment process which supposedly\n // involves multiple RTTs. We don't have the time to wait for Strophe to\n // decide to send our IQ.\n this.connection.flush();\n });\n};\n\n/**\n * Invoked by {@link #allocateConferenceFocus} upon its request receiving an\n * error result.\n *\n * @param error - the error result of the request that\n * {@link #allocateConferenceFocus} sent\n * @param {Function} callback - the function to be called back upon the\n * successful allocation of the conference focus\n */\nModerator.prototype._allocateConferenceFocusError = function(error, callback) {\n // If the session is invalid, remove and try again without session ID to get\n // a new one\n const invalidSession\n = $(error).find('>error>session-invalid').length\n || $(error).find('>error>not-acceptable').length;\n\n if (invalidSession) {\n logger.info('Session expired! - removing');\n Settings.sessionId = undefined;\n }\n if ($(error).find('>error>graceful-shutdown').length) {\n this.eventEmitter.emit(XMPPEvents.GRACEFUL_SHUTDOWN);\n\n return;\n }\n\n // Check for error returned by the reservation system\n const reservationErr = $(error).find('>error>reservation-error');\n\n if (reservationErr.length) {\n // Trigger error event\n const errorCode = reservationErr.attr('error-code');\n const errorTextNode = $(error).find('>error>text');\n let errorMsg;\n\n if (errorTextNode) {\n errorMsg = errorTextNode.text();\n }\n this.eventEmitter.emit(\n XMPPEvents.RESERVATION_ERROR,\n errorCode,\n errorMsg);\n\n return;\n }\n\n // Not authorized to create new room\n if ($(error).find('>error>not-authorized').length) {\n logger.warn('Unauthorized to start the conference', error);\n const toDomain = Strophe.getDomainFromJid(error.getAttribute('to'));\n\n if (toDomain !== this.options.connection.hosts.anonymousdomain) {\n // FIXME \"is external\" should come either from the focus or\n // config.js\n this.externalAuthEnabled = true;\n }\n this.eventEmitter.emit(XMPPEvents.AUTHENTICATION_REQUIRED);\n\n return;\n }\n const waitMs = this.getNextErrorTimeout();\n const errmsg = `Focus error, retry after ${waitMs}`;\n\n GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));\n logger.error(errmsg, error);\n\n // Show message\n const focusComponent = this.getFocusComponent();\n const retrySec = waitMs / 1000;\n\n // FIXME: message is duplicated ? Do not show in case of session invalid\n // which means just a retry\n\n if (!invalidSession) {\n this.eventEmitter.emit(\n XMPPEvents.FOCUS_DISCONNECTED,\n focusComponent,\n retrySec);\n }\n\n // Reset response timeout\n this.getNextTimeout(true);\n window.setTimeout(\n () => this.allocateConferenceFocus().then(callback),\n waitMs);\n};\n\n/**\n * Invoked by {@link #allocateConferenceFocus} upon its request receiving a\n * success (i.e. non-error) result.\n *\n * @param result - the success (i.e. non-error) result of the request that\n * {@link #allocateConferenceFocus} sent\n * @param {Function} callback - the function to be called back upon the\n * successful allocation of the conference focus\n */\nModerator.prototype._allocateConferenceFocusSuccess = function(\n result,\n callback) {\n // Setup config options\n this.parseConfigOptions(result);\n\n // Reset the error timeout (because we haven't failed here).\n this.getNextErrorTimeout(true);\n\n // eslint-disable-next-line newline-per-chained-call\n if ($(result).find('conference').attr('ready') === 'true') {\n // Reset the non-error timeout (because we've succeeded here).\n this.getNextTimeout(true);\n\n // Exec callback\n callback();\n } else {\n const waitMs = this.getNextTimeout();\n\n logger.info(`Waiting for the focus... ${waitMs}`);\n window.setTimeout(\n () => this.allocateConferenceFocus().then(callback),\n waitMs);\n }\n};\n\nModerator.prototype.authenticate = function() {\n return new Promise((resolve, reject) => {\n this.connection.sendIQ(\n this.createConferenceIq(),\n result => {\n this.parseSessionId(result);\n resolve();\n },\n errorIq => reject({\n error: $(errorIq).find('iq>error :first')\n .prop('tagName'),\n message: $(errorIq).find('iq>error>text')\n .text()\n })\n );\n });\n};\n\nModerator.prototype.getLoginUrl = function(urlCallback, failureCallback) {\n this._getLoginUrl(/* popup */ false, urlCallback, failureCallback);\n};\n\n/**\n *\n * @param {boolean} popup false for {@link Moderator#getLoginUrl} or true for\n * {@link Moderator#getPopupLoginUrl}\n * @param urlCb\n * @param failureCb\n */\nModerator.prototype._getLoginUrl = function(popup, urlCb, failureCb) {\n const iq = $iq({ to: this.getFocusComponent(),\n type: 'get' });\n const attrs = {\n xmlns: 'http://jitsi.org/protocol/focus',\n room: this.roomName,\n 'machine-uid': Settings.machineId\n };\n let str = 'auth url'; // for logger\n\n if (popup) {\n attrs.popup = true;\n str = `POPUP ${str}`;\n }\n iq.c('login-url', attrs);\n\n /**\n * Implements a failure callback which reports an error message and an error\n * through (1) GlobalOnErrorHandler, (2) logger, and (3) failureCb.\n *\n * @param {string} errmsg the error messsage to report\n * @param {*} error the error to report (in addition to errmsg)\n */\n function reportError(errmsg, err) {\n GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));\n logger.error(errmsg, err);\n failureCb(err);\n }\n this.connection.sendIQ(\n iq,\n result => {\n // eslint-disable-next-line newline-per-chained-call\n let url = $(result).find('login-url').attr('url');\n\n url = decodeURIComponent(url);\n if (url) {\n logger.info(`Got ${str}: ${url}`);\n urlCb(url);\n } else {\n reportError(`Failed to get ${str} from the focus`, result);\n }\n },\n reportError.bind(undefined, `Get ${str} error`)\n );\n};\n\nModerator.prototype.getPopupLoginUrl = function(urlCallback, failureCallback) {\n this._getLoginUrl(/* popup */ true, urlCallback, failureCallback);\n};\n\nModerator.prototype.logout = function(callback) {\n const iq = $iq({ to: this.getFocusComponent(),\n type: 'set' });\n const { sessionId } = Settings;\n\n if (!sessionId) {\n callback();\n\n return;\n }\n iq.c('logout', {\n xmlns: 'http://jitsi.org/protocol/focus',\n 'session-id': sessionId\n });\n this.connection.sendIQ(\n iq,\n result => {\n // eslint-disable-next-line newline-per-chained-call\n let logoutUrl = $(result).find('logout').attr('logout-url');\n\n if (logoutUrl) {\n logoutUrl = decodeURIComponent(logoutUrl);\n }\n logger.info(`Log out OK, url: ${logoutUrl}`, result);\n Settings.sessionId = undefined;\n callback(logoutUrl);\n },\n error => {\n const errmsg = 'Logout error';\n\n GlobalOnErrorHandler.callErrorHandler(new Error(errmsg));\n logger.error(errmsg, error);\n }\n );\n};\n", "const RandomUtil = require('./RandomUtil');\n\n/**\n * from faker.js - Copyright (c) 2014-2015 Matthew Bergman & Marak Squires\n * MIT License\n * http://github.com/marak/faker.js/\n *\n * @const\n */\nconst names = [\n 'Aaliyah', 'Aaron', 'Abagail', 'Abbey', 'Abbie', 'Abbigail', 'Abby',\n 'Abdiel', 'Abdul', 'Abdullah', 'Abe', 'Abel', 'Abelardo', 'Abigail',\n 'Abigale', 'Abigayle', 'Abner', 'Abraham', 'Ada', 'Adah', 'Adalberto',\n 'Adaline', 'Adam', 'Adan', 'Addie', 'Addison', 'Adela', 'Adelbert', 'Adele',\n 'Adelia', 'Adeline', 'Adell', 'Adella', 'Adelle', 'Aditya', 'Adolf',\n 'Adolfo', 'Adolph', 'Adolphus', 'Adonis', 'Adrain', 'Adrian', 'Adriana',\n 'Adrianna', 'Adriel', 'Adrien', 'Adrienne', 'Afton', 'Aglae', 'Agnes',\n 'Agustin', 'Agustina', 'Ahmad', 'Ahmed', 'Aida', 'Aidan', 'Aiden', 'Aileen',\n 'Aisha', 'Aiyana', 'Akeem', 'Al', 'Alaina', 'Alan', 'Alana', 'Alanis',\n 'Alanna', 'Alayna', 'Alba', 'Albert', 'Alberta', 'Albertha', 'Alberto',\n 'Albin', 'Albina', 'Alda', 'Alden', 'Alec', 'Aleen', 'Alejandra',\n 'Alejandrin', 'Alek', 'Alena', 'Alene', 'Alessandra', 'Alessandro',\n 'Alessia', 'Aletha', 'Alex', 'Alexa', 'Alexander', 'Alexandra', 'Alexandre',\n 'Alexandrea', 'Alexandria', 'Alexandrine', 'Alexandro', 'Alexane',\n 'Alexanne', 'Alexie', 'Alexis', 'Alexys', 'Alexzander', 'Alf', 'Alfonso',\n 'Alfonzo', 'Alford', 'Alfred', 'Alfreda', 'Alfredo', 'Ali', 'Alia', 'Alice',\n 'Alicia', 'Alisa', 'Alisha', 'Alison', 'Alivia', 'Aliya', 'Aliyah', 'Aliza',\n 'Alize', 'Allan', 'Allen', 'Allene', 'Allie', 'Allison', 'Ally', 'Alphonso',\n 'Alta', 'Althea', 'Alva', 'Alvah', 'Alvena', 'Alvera', 'Alverta', 'Alvina',\n 'Alvis', 'Alyce', 'Alycia', 'Alysa', 'Alysha', 'Alyson', 'Alysson',\n 'Amalia', 'Amanda', 'Amani', 'Amara', 'Amari', 'Amaya', 'Amber', 'Ambrose',\n 'Amelia', 'Amelie', 'Amely', 'America', 'Americo', 'Amie', 'Amina', 'Amir',\n 'Amira', 'Amiya', 'Amos', 'Amparo', 'Amy', 'Amya', 'Ana', 'Anabel',\n 'Anabelle', 'Anahi', 'Anais', 'Anastacio', 'Anastasia', 'Anderson', 'Andre',\n 'Andreane', 'Andreanne', 'Andres', 'Andrew', 'Andy', 'Angel', 'Angela',\n 'Angelica', 'Angelina', 'Angeline', 'Angelita', 'Angelo', 'Angie', 'Angus',\n 'Anibal', 'Anika', 'Anissa', 'Anita', 'Aniya', 'Aniyah', 'Anjali', 'Anna',\n 'Annabel', 'Annabell', 'Annabelle', 'Annalise', 'Annamae', 'Annamarie',\n 'Anne', 'Annetta', 'Annette', 'Annie', 'Ansel', 'Ansley', 'Anthony',\n 'Antoinette', 'Antone', 'Antonetta', 'Antonette', 'Antonia', 'Antonietta',\n 'Antonina', 'Antonio', 'Antwan', 'Antwon', 'Anya', 'April', 'Ara',\n 'Araceli', 'Aracely', 'Arch', 'Archibald', 'Ardella', 'Arden', 'Ardith',\n 'Arely', 'Ari', 'Ariane', 'Arianna', 'Aric', 'Ariel', 'Arielle', 'Arjun',\n 'Arlene', 'Arlie', 'Arlo', 'Armand', 'Armando', 'Armani', 'Arnaldo', 'Arne',\n 'Arno', 'Arnold', 'Arnoldo', 'Arnulfo', 'Aron', 'Art', 'Arthur', 'Arturo',\n 'Arvel', 'Arvid', 'Arvilla', 'Aryanna', 'Asa', 'Asha', 'Ashlee', 'Ashleigh',\n 'Ashley', 'Ashly', 'Ashlynn', 'Ashton', 'Ashtyn', 'Asia', 'Assunta',\n 'Astrid', 'Athena', 'Aubree', 'Aubrey', 'Audie', 'Audra', 'Audreanne',\n 'Audrey', 'August', 'Augusta', 'Augustine', 'Augustus', 'Aurelia',\n 'Aurelie', 'Aurelio', 'Aurore', 'Austen', 'Austin', 'Austyn', 'Autumn',\n 'Ava', 'Avery', 'Avis', 'Axel', 'Ayana', 'Ayden', 'Ayla', 'Aylin', 'Baby',\n 'Bailee', 'Bailey', 'Barbara', 'Barney', 'Baron', 'Barrett', 'Barry',\n 'Bart', 'Bartholome', 'Barton', 'Baylee', 'Beatrice', 'Beau', 'Beaulah',\n 'Bell', 'Bella', 'Belle', 'Ben', 'Benedict', 'Benjamin', 'Bennett',\n 'Bennie', 'Benny', 'Benton', 'Berenice', 'Bernadette', 'Bernadine',\n 'Bernard', 'Bernardo', 'Berneice', 'Bernhard', 'Bernice', 'Bernie',\n 'Berniece', 'Bernita', 'Berry', 'Bert', 'Berta', 'Bertha', 'Bertram',\n 'Bertrand', 'Beryl', 'Bessie', 'Beth', 'Bethany', 'Bethel', 'Betsy',\n 'Bette', 'Bettie', 'Betty', 'Bettye', 'Beulah', 'Beverly', 'Bianka', 'Bill',\n 'Billie', 'Billy', 'Birdie', 'Blair', 'Blaise', 'Blake', 'Blanca',\n 'Blanche', 'Blaze', 'Bo', 'Bobbie', 'Bobby', 'Bonita', 'Bonnie', 'Boris',\n 'Boyd', 'Brad', 'Braden', 'Bradford', 'Bradley', 'Bradly', 'Brady',\n 'Braeden', 'Brain', 'Brandi', 'Brando', 'Brandon', 'Brandt', 'Brandy',\n 'Brandyn', 'Brannon', 'Branson', 'Brant', 'Braulio', 'Braxton', 'Brayan',\n 'Breana', 'Breanna', 'Breanne', 'Brenda', 'Brendan', 'Brenden', 'Brendon',\n 'Brenna', 'Brennan', 'Brennon', 'Brent', 'Bret', 'Brett', 'Bria', 'Brian',\n 'Briana', 'Brianne', 'Brice', 'Bridget', 'Bridgette', 'Bridie', 'Brielle',\n 'Brigitte', 'Brionna', 'Brisa', 'Britney', 'Brittany', 'Brock', 'Broderick',\n 'Brody', 'Brook', 'Brooke', 'Brooklyn', 'Brooks', 'Brown', 'Bruce',\n 'Bryana', 'Bryce', 'Brycen', 'Bryon', 'Buck', 'Bud', 'Buddy', 'Buford',\n 'Bulah', 'Burdette', 'Burley', 'Burnice', 'Buster', 'Cade', 'Caden',\n 'Caesar', 'Caitlyn', 'Cale', 'Caleb', 'Caleigh', 'Cali', 'Calista',\n 'Callie', 'Camden', 'Cameron', 'Camila', 'Camilla', 'Camille', 'Camren',\n 'Camron', 'Camryn', 'Camylle', 'Candace', 'Candelario', 'Candice',\n 'Candida', 'Candido', 'Cara', 'Carey', 'Carissa', 'Carlee', 'Carleton',\n 'Carley', 'Carli', 'Carlie', 'Carlo', 'Carlos', 'Carlotta', 'Carmel',\n 'Carmela', 'Carmella', 'Carmelo', 'Carmen', 'Carmine', 'Carol', 'Carolanne',\n 'Carole', 'Carolina', 'Caroline', 'Carolyn', 'Carolyne', 'Carrie',\n 'Carroll', 'Carson', 'Carter', 'Cary', 'Casandra', 'Casey', 'Casimer',\n 'Casimir', 'Casper', 'Cassandra', 'Cassandre', 'Cassidy', 'Cassie',\n 'Catalina', 'Caterina', 'Catharine', 'Catherine', 'Cathrine', 'Cathryn',\n 'Cathy', 'Cayla', 'Ceasar', 'Cecelia', 'Cecil', 'Cecile', 'Cecilia',\n 'Cedrick', 'Celestine', 'Celestino', 'Celia', 'Celine', 'Cesar', 'Chad',\n 'Chadd', 'Chadrick', 'Chaim', 'Chance', 'Chandler', 'Chanel', 'Chanelle',\n 'Charity', 'Charlene', 'Charles', 'Charley', 'Charlie', 'Charlotte',\n 'Chase', 'Chasity', 'Chauncey', 'Chaya', 'Chaz', 'Chelsea', 'Chelsey',\n 'Chelsie', 'Chesley', 'Chester', 'Chet', 'Cheyanne', 'Cheyenne', 'Chloe',\n 'Chris', 'Christ', 'Christa', 'Christelle', 'Christian', 'Christiana',\n 'Christina', 'Christine', 'Christop', 'Christophe', 'Christopher',\n 'Christy', 'Chyna', 'Ciara', 'Cicero', 'Cielo', 'Cierra', 'Cindy',\n 'Citlalli', 'Clair', 'Claire', 'Clara', 'Clarabelle', 'Clare', 'Clarissa',\n 'Clark', 'Claud', 'Claude', 'Claudia', 'Claudie', 'Claudine', 'Clay',\n 'Clemens', 'Clement', 'Clementina', 'Clementine', 'Clemmie', 'Cleo',\n 'Cleora', 'Cleta', 'Cletus', 'Cleve', 'Cleveland', 'Clifford', 'Clifton',\n 'Clint', 'Clinton', 'Clotilde', 'Clovis', 'Cloyd', 'Clyde', 'Coby', 'Cody',\n 'Colby', 'Cole', 'Coleman', 'Colin', 'Colleen', 'Collin', 'Colt', 'Colten',\n 'Colton', 'Columbus', 'Concepcion', 'Conner', 'Connie', 'Connor', 'Conor',\n 'Conrad', 'Constance', 'Constantin', 'Consuelo', 'Cooper', 'Cora',\n 'Coralie', 'Corbin', 'Cordelia', 'Cordell', 'Cordia', 'Cordie', 'Corene',\n 'Corine', 'Cornelius', 'Cornell', 'Corrine', 'Cortez', 'Cortney', 'Cory',\n 'Coty', 'Courtney', 'Coy', 'Craig', 'Crawford', 'Creola', 'Cristal',\n 'Cristian', 'Cristina', 'Cristobal', 'Cristopher', 'Cruz', 'Crystal',\n 'Crystel', 'Cullen', 'Curt', 'Curtis', 'Cydney', 'Cynthia', 'Cyril',\n 'Cyrus', 'Dagmar', 'Dahlia', 'Daija', 'Daisha', 'Daisy', 'Dakota', 'Dale',\n 'Dallas', 'Dallin', 'Dalton', 'Damaris', 'Dameon', 'Damian', 'Damien',\n 'Damion', 'Damon', 'Dan', 'Dana', 'Dandre', 'Dane', 'D\\'angelo', 'Dangelo',\n 'Danial', 'Daniela', 'Daniella', 'Danielle', 'Danika', 'Dannie', 'Danny',\n 'Dante', 'Danyka', 'Daphne', 'Daphnee', 'Daphney', 'Darby', 'Daren',\n 'Darian', 'Dariana', 'Darien', 'Dario', 'Darion', 'Darius', 'Darlene',\n 'Daron', 'Darrel', 'Darrell', 'Darren', 'Darrick', 'Darrin', 'Darrion',\n 'Darron', 'Darryl', 'Darwin', 'Daryl', 'Dashawn', 'Dasia', 'Dave', 'David',\n 'Davin', 'Davion', 'Davon', 'Davonte', 'Dawn', 'Dawson', 'Dax', 'Dayana',\n 'Dayna', 'Dayne', 'Dayton', 'Dean', 'Deangelo', 'Deanna', 'Deborah',\n 'Declan', 'Dedric', 'Dedrick', 'Dee', 'Deion', 'Deja', 'Dejah', 'Dejon',\n 'Dejuan', 'Delaney', 'Delbert', 'Delfina', 'Delia', 'Delilah', 'Dell',\n 'Della', 'Delmer', 'Delores', 'Delpha', 'Delphia', 'Delphine', 'Delta',\n 'Demarco', 'Demarcus', 'Demario', 'Demetris', 'Demetrius', 'Demond', 'Dena',\n 'Denis', 'Dennis', 'Deon', 'Deondre', 'Deontae', 'Deonte', 'Dereck',\n 'Derek', 'Derick', 'Deron', 'Derrick', 'Deshaun', 'Deshawn', 'Desiree',\n 'Desmond', 'Dessie', 'Destany', 'Destin', 'Destinee', 'Destiney', 'Destini',\n 'Destiny', 'Devan', 'Devante', 'Deven', 'Devin', 'Devon', 'Devonte',\n 'Devyn', 'Dewayne', 'Dewitt', 'Dexter', 'Diamond', 'Diana', 'Dianna',\n 'Diego', 'Dillan', 'Dillon', 'Dimitri', 'Dina', 'Dino', 'Dion', 'Dixie',\n 'Dock', 'Dolly', 'Dolores', 'Domenic', 'Domenica', 'Domenick', 'Domenico',\n 'Domingo', 'Dominic', 'Dominique', 'Don', 'Donald', 'Donato', 'Donavon',\n 'Donna', 'Donnell', 'Donnie', 'Donny', 'Dora', 'Dorcas', 'Dorian', 'Doris',\n 'Dorothea', 'Dorothy', 'Dorris', 'Dortha', 'Dorthy', 'Doug', 'Douglas',\n 'Dovie', 'Doyle', 'Drake', 'Drew', 'Duane', 'Dudley', 'Dulce', 'Duncan',\n 'Durward', 'Dustin', 'Dusty', 'Dwight', 'Dylan', 'Earl', 'Earlene',\n 'Earline', 'Earnest', 'Earnestine', 'Easter', 'Easton', 'Ebba', 'Ebony',\n 'Ed', 'Eda', 'Edd', 'Eddie', 'Eden', 'Edgar', 'Edgardo', 'Edison', 'Edmond',\n 'Edmund', 'Edna', 'Eduardo', 'Edward', 'Edwardo', 'Edwin', 'Edwina',\n 'Edyth', 'Edythe', 'Effie', 'Efrain', 'Efren', 'Eileen', 'Einar', 'Eino',\n 'Eladio', 'Elaina', 'Elbert', 'Elda', 'Eldon', 'Eldora', 'Eldred',\n 'Eldridge', 'Eleanora', 'Eleanore', 'Eleazar', 'Electa', 'Elena', 'Elenor',\n 'Elenora', 'Eleonore', 'Elfrieda', 'Eli', 'Elian', 'Eliane', 'Elias',\n 'Eliezer', 'Elijah', 'Elinor', 'Elinore', 'Elisa', 'Elisabeth', 'Elise',\n 'Eliseo', 'Elisha', 'Elissa', 'Eliza', 'Elizabeth', 'Ella', 'Ellen',\n 'Ellie', 'Elliot', 'Elliott', 'Ellis', 'Ellsworth', 'Elmer', 'Elmira',\n 'Elmo', 'Elmore', 'Elna', 'Elnora', 'Elody', 'Eloisa', 'Eloise', 'Elouise',\n 'Eloy', 'Elroy', 'Elsa', 'Else', 'Elsie', 'Elta', 'Elton', 'Elva', 'Elvera',\n 'Elvie', 'Elvis', 'Elwin', 'Elwyn', 'Elyse', 'Elyssa', 'Elza', 'Emanuel',\n 'Emelia', 'Emelie', 'Emely', 'Emerald', 'Emerson', 'Emery', 'Emie', 'Emil',\n 'Emile', 'Emilia', 'Emiliano', 'Emilie', 'Emilio', 'Emily', 'Emma',\n 'Emmalee', 'Emmanuel', 'Emmanuelle', 'Emmet', 'Emmett', 'Emmie', 'Emmitt',\n 'Emmy', 'Emory', 'Ena', 'Enid', 'Enoch', 'Enola', 'Enos', 'Enrico',\n 'Enrique', 'Ephraim', 'Era', 'Eriberto', 'Eric', 'Erica', 'Erich', 'Erick',\n 'Ericka', 'Erik', 'Erika', 'Erin', 'Erling', 'Erna', 'Ernest', 'Ernestina',\n 'Ernestine', 'Ernesto', 'Ernie', 'Ervin', 'Erwin', 'Eryn', 'Esmeralda',\n 'Esperanza', 'Esta', 'Esteban', 'Estefania', 'Estel', 'Estell', 'Estella',\n 'Estelle', 'Estevan', 'Esther', 'Estrella', 'Etha', 'Ethan', 'Ethel',\n 'Ethelyn', 'Ethyl', 'Ettie', 'Eudora', 'Eugene', 'Eugenia', 'Eula', 'Eulah',\n 'Eulalia', 'Euna', 'Eunice', 'Eusebio', 'Eva', 'Evalyn', 'Evan',\n 'Evangeline', 'Evans', 'Eve', 'Eveline', 'Evelyn', 'Everardo', 'Everett',\n 'Everette', 'Evert', 'Evie', 'Ewald', 'Ewell', 'Ezekiel', 'Ezequiel',\n 'Ezra', 'Fabian', 'Fabiola', 'Fae', 'Fannie', 'Fanny', 'Fatima', 'Faustino',\n 'Fausto', 'Favian', 'Fay', 'Faye', 'Federico', 'Felicia', 'Felicita',\n 'Felicity', 'Felipa', 'Felipe', 'Felix', 'Felton', 'Fermin', 'Fern',\n 'Fernando', 'Ferne', 'Fidel', 'Filiberto', 'Filomena', 'Finn', 'Fiona',\n 'Flavie', 'Flavio', 'Fleta', 'Fletcher', 'Flo', 'Florence', 'Florencio',\n 'Florian', 'Florida', 'Florine', 'Flossie', 'Floy', 'Floyd', 'Ford',\n 'Forest', 'Forrest', 'Foster', 'Frances', 'Francesca', 'Francesco',\n 'Francis', 'Francisca', 'Francisco', 'Franco', 'Frank', 'Frankie', 'Franz',\n 'Fred', 'Freda', 'Freddie', 'Freddy', 'Frederic', 'Frederick', 'Frederik',\n 'Frederique', 'Fredrick', 'Fredy', 'Freeda', 'Freeman', 'Freida', 'Frida',\n 'Frieda', 'Friedrich', 'Fritz', 'Furman', 'Gabe', 'Gabriel', 'Gabriella',\n 'Gabrielle', 'Gaetano', 'Gage', 'Gail', 'Gardner', 'Garett', 'Garfield',\n 'Garland', 'Garnet', 'Garnett', 'Garret', 'Garrett', 'Garrick', 'Garrison',\n 'Garry', 'Garth', 'Gaston', 'Gavin', 'Gay', 'Gayle', 'Gaylord', 'Gene',\n 'General', 'Genesis', 'Genevieve', 'Gennaro', 'Genoveva', 'Geo', 'Geoffrey',\n 'George', 'Georgette', 'Georgiana', 'Georgianna', 'Geovanni', 'Geovanny',\n 'Geovany', 'Gerald', 'Geraldine', 'Gerard', 'Gerardo', 'Gerda', 'Gerhard',\n 'Germaine', 'German', 'Gerry', 'Gerson', 'Gertrude', 'Gia', 'Gianni',\n 'Gideon', 'Gilbert', 'Gilberto', 'Gilda', 'Giles', 'Gillian', 'Gina',\n 'Gino', 'Giovani', 'Giovanna', 'Giovanni', 'Giovanny', 'Gisselle',\n 'Giuseppe', 'Gladyce', 'Gladys', 'Glen', 'Glenda', 'Glenna', 'Glennie',\n 'Gloria', 'Godfrey', 'Golda', 'Golden', 'Gonzalo', 'Gordon', 'Grace',\n 'Gracie', 'Graciela', 'Grady', 'Graham', 'Grant', 'Granville', 'Grayce',\n 'Grayson', 'Green', 'Greg', 'Gregg', 'Gregoria', 'Gregorio', 'Gregory',\n 'Greta', 'Gretchen', 'Greyson', 'Griffin', 'Grover', 'Guadalupe', 'Gudrun',\n 'Guido', 'Guillermo', 'Guiseppe', 'Gunnar', 'Gunner', 'Gus', 'Gussie',\n 'Gust', 'Gustave', 'Guy', 'Gwen', 'Gwendolyn', 'Hadley', 'Hailee', 'Hailey',\n 'Hailie', 'Hal', 'Haleigh', 'Haley', 'Halie', 'Halle', 'Hallie', 'Hank',\n 'Hanna', 'Hannah', 'Hans', 'Hardy', 'Harley', 'Harmon', 'Harmony', 'Harold',\n 'Harrison', 'Harry', 'Harvey', 'Haskell', 'Hassan', 'Hassie', 'Hattie',\n 'Haven', 'Hayden', 'Haylee', 'Hayley', 'Haylie', 'Hazel', 'Hazle', 'Heath',\n 'Heather', 'Heaven', 'Heber', 'Hector', 'Heidi', 'Helen', 'Helena',\n 'Helene', 'Helga', 'Hellen', 'Helmer', 'Heloise', 'Henderson', 'Henri',\n 'Henriette', 'Henry', 'Herbert', 'Herman', 'Hermann', 'Hermina', 'Herminia',\n 'Herminio', 'Hershel', 'Herta', 'Hertha', 'Hester', 'Hettie', 'Hilario',\n 'Hilbert', 'Hilda', 'Hildegard', 'Hillard', 'Hillary', 'Hilma', 'Hilton',\n 'Hipolito', 'Hiram', 'Hobart', 'Holden', 'Hollie', 'Hollis', 'Holly',\n 'Hope', 'Horace', 'Horacio', 'Hortense', 'Hosea', 'Houston', 'Howard',\n 'Howell', 'Hoyt', 'Hubert', 'Hudson', 'Hugh', 'Hulda', 'Humberto', 'Hunter',\n 'Hyman', 'Ian', 'Ibrahim', 'Icie', 'Ida', 'Idell', 'Idella', 'Ignacio',\n 'Ignatius', 'Ike', 'Ila', 'Ilene', 'Iliana', 'Ima', 'Imani', 'Imelda',\n 'Immanuel', 'Imogene', 'Ines', 'Irma', 'Irving', 'Irwin', 'Isaac', 'Isabel',\n 'Isabell', 'Isabella', 'Isabelle', 'Isac', 'Isadore', 'Isai', 'Isaiah',\n 'Isaias', 'Isidro', 'Ismael', 'Isobel', 'Isom', 'Israel', 'Issac', 'Itzel',\n 'Iva', 'Ivah', 'Ivory', 'Ivy', 'Izabella', 'Izaiah', 'Jabari', 'Jace',\n 'Jacey', 'Jacinthe', 'Jacinto', 'Jack', 'Jackeline', 'Jackie', 'Jacklyn',\n 'Jackson', 'Jacky', 'Jaclyn', 'Jacquelyn', 'Jacques', 'Jacynthe', 'Jada',\n 'Jade', 'Jaden', 'Jadon', 'Jadyn', 'Jaeden', 'Jaida', 'Jaiden', 'Jailyn',\n 'Jaime', 'Jairo', 'Jakayla', 'Jake', 'Jakob', 'Jaleel', 'Jalen', 'Jalon',\n 'Jalyn', 'Jamaal', 'Jamal', 'Jamar', 'Jamarcus', 'Jamel', 'Jameson',\n 'Jamey', 'Jamie', 'Jamil', 'Jamir', 'Jamison', 'Jammie', 'Jan', 'Jana',\n 'Janae', 'Jane', 'Janelle', 'Janessa', 'Janet', 'Janice', 'Janick', 'Janie',\n 'Janis', 'Janiya', 'Jannie', 'Jany', 'Jaquan', 'Jaquelin', 'Jaqueline',\n 'Jared', 'Jaren', 'Jarod', 'Jaron', 'Jarred', 'Jarrell', 'Jarret',\n 'Jarrett', 'Jarrod', 'Jarvis', 'Jasen', 'Jasmin', 'Jason', 'Jasper',\n 'Jaunita', 'Javier', 'Javon', 'Javonte', 'Jay', 'Jayce', 'Jaycee', 'Jayda',\n 'Jayde', 'Jayden', 'Jaydon', 'Jaylan', 'Jaylen', 'Jaylin', 'Jaylon',\n 'Jayme', 'Jayne', 'Jayson', 'Jazlyn', 'Jazmin', 'Jazmyn', 'Jazmyne', 'Jean',\n 'Jeanette', 'Jeanie', 'Jeanne', 'Jed', 'Jedediah', 'Jedidiah', 'Jeff',\n 'Jefferey', 'Jeffery', 'Jeffrey', 'Jeffry', 'Jena', 'Jenifer', 'Jennie',\n 'Jennifer', 'Jennings', 'Jennyfer', 'Jensen', 'Jerad', 'Jerald', 'Jeramie',\n 'Jeramy', 'Jerel', 'Jeremie', 'Jeremy', 'Jermain', 'Jermaine', 'Jermey',\n 'Jerod', 'Jerome', 'Jeromy', 'Jerrell', 'Jerrod', 'Jerrold', 'Jerry',\n 'Jess', 'Jesse', 'Jessica', 'Jessie', 'Jessika', 'Jessy', 'Jessyca',\n 'Jesus', 'Jett', 'Jettie', 'Jevon', 'Jewel', 'Jewell', 'Jillian', 'Jimmie',\n 'Jimmy', 'Jo', 'Joan', 'Joana', 'Joanie', 'Joanne', 'Joannie', 'Joanny',\n 'Joany', 'Joaquin', 'Jocelyn', 'Jodie', 'Jody', 'Joe', 'Joel', 'Joelle',\n 'Joesph', 'Joey', 'Johan', 'Johann', 'Johanna', 'Johathan', 'John',\n 'Johnathan', 'Johnathon', 'Johnnie', 'Johnny', 'Johnpaul', 'Johnson',\n 'Jolie', 'Jon', 'Jonas', 'Jonatan', 'Jonathan', 'Jonathon', 'Jordan',\n 'Jordane', 'Jordi', 'Jordon', 'Jordy', 'Jordyn', 'Jorge', 'Jose', 'Josefa',\n 'Josefina', 'Joseph', 'Josephine', 'Josh', 'Joshua', 'Joshuah', 'Josiah',\n 'Josiane', 'Josianne', 'Josie', 'Josue', 'Jovan', 'Jovani', 'Jovanny',\n 'Jovany', 'Joy', 'Joyce', 'Juana', 'Juanita', 'Judah', 'Judd', 'Jude',\n 'Judge', 'Judson', 'Judy', 'Jules', 'Julia', 'Julian', 'Juliana',\n 'Julianne', 'Julie', 'Julien', 'Juliet', 'Julio', 'Julius', 'June',\n 'Junior', 'Junius', 'Justen', 'Justice', 'Justina', 'Justine', 'Juston',\n 'Justus', 'Justyn', 'Juvenal', 'Juwan', 'Kacey', 'Kaci', 'Kacie', 'Kade',\n 'Kaden', 'Kadin', 'Kaela', 'Kaelyn', 'Kaia', 'Kailee', 'Kailey', 'Kailyn',\n 'Kaitlin', 'Kaitlyn', 'Kale', 'Kaleb', 'Kaleigh', 'Kaley', 'Kali', 'Kallie',\n 'Kameron', 'Kamille', 'Kamren', 'Kamron', 'Kamryn', 'Kane', 'Kara',\n 'Kareem', 'Karelle', 'Karen', 'Kari', 'Kariane', 'Karianne', 'Karina',\n 'Karine', 'Karl', 'Karlee', 'Karley', 'Karli', 'Karlie', 'Karolann',\n 'Karson', 'Kasandra', 'Kasey', 'Kassandra', 'Katarina', 'Katelin',\n 'Katelyn', 'Katelynn', 'Katharina', 'Katherine', 'Katheryn', 'Kathleen',\n 'Kathlyn', 'Kathryn', 'Kathryne', 'Katlyn', 'Katlynn', 'Katrina', 'Katrine',\n 'Kattie', 'Kavon', 'Kay', 'Kaya', 'Kaycee', 'Kayden', 'Kayla', 'Kaylah',\n 'Kaylee', 'Kayleigh', 'Kayley', 'Kayli', 'Kaylie', 'Kaylin', 'Keagan',\n 'Keanu', 'Keara', 'Keaton', 'Keegan', 'Keeley', 'Keely', 'Keenan', 'Keira',\n 'Keith', 'Kellen', 'Kelley', 'Kelli', 'Kellie', 'Kelly', 'Kelsi', 'Kelsie',\n 'Kelton', 'Kelvin', 'Ken', 'Kendall', 'Kendra', 'Kendrick', 'Kenna',\n 'Kennedi', 'Kennedy', 'Kenneth', 'Kennith', 'Kenny', 'Kenton', 'Kenya',\n 'Kenyatta', 'Kenyon', 'Keon', 'Keshaun', 'Keshawn', 'Keven', 'Kevin',\n 'Kevon', 'Keyon', 'Keyshawn', 'Khalid', 'Khalil', 'Kian', 'Kiana', 'Kianna',\n 'Kiara', 'Kiarra', 'Kiel', 'Kiera', 'Kieran', 'Kiley', 'Kim', 'Kimberly',\n 'King', 'Kip', 'Kira', 'Kirk', 'Kirsten', 'Kirstin', 'Kitty', 'Kobe',\n 'Koby', 'Kody', 'Kolby', 'Kole', 'Korbin', 'Korey', 'Kory', 'Kraig', 'Kris',\n 'Krista', 'Kristian', 'Kristin', 'Kristina', 'Kristofer', 'Kristoffer',\n 'Kristopher', 'Kristy', 'Krystal', 'Krystel', 'Krystina', 'Kurt', 'Kurtis',\n 'Kyla', 'Kyle', 'Kylee', 'Kyleigh', 'Kyler', 'Kylie', 'Kyra', 'Lacey',\n 'Lacy', 'Ladarius', 'Lafayette', 'Laila', 'Laisha', 'Lamar', 'Lambert',\n 'Lamont', 'Lance', 'Landen', 'Lane', 'Laney', 'Larissa', 'Laron', 'Larry',\n 'Larue', 'Laura', 'Laurel', 'Lauren', 'Laurence', 'Lauretta', 'Lauriane',\n 'Laurianne', 'Laurie', 'Laurine', 'Laury', 'Lauryn', 'Lavada', 'Lavern',\n 'Laverna', 'Laverne', 'Lavina', 'Lavinia', 'Lavon', 'Lavonne', 'Lawrence',\n 'Lawson', 'Layla', 'Layne', 'Lazaro', 'Lea', 'Leann', 'Leanna', 'Leanne',\n 'Leatha', 'Leda', 'Lee', 'Leif', 'Leila', 'Leilani', 'Lela', 'Lelah',\n 'Leland', 'Lelia', 'Lempi', 'Lemuel', 'Lenna', 'Lennie', 'Lenny', 'Lenora',\n 'Lenore', 'Leo', 'Leola', 'Leon', 'Leonard', 'Leonardo', 'Leone', 'Leonel',\n 'Leonie', 'Leonor', 'Leonora', 'Leopold', 'Leopoldo', 'Leora', 'Lera',\n 'Lesley', 'Leslie', 'Lesly', 'Lessie', 'Lester', 'Leta', 'Letha', 'Letitia',\n 'Levi', 'Lew', 'Lewis', 'Lexi', 'Lexie', 'Lexus', 'Lia', 'Liam', 'Liana',\n 'Libbie', 'Libby', 'Lila', 'Lilian', 'Liliana', 'Liliane', 'Lilla',\n 'Lillian', 'Lilliana', 'Lillie', 'Lilly', 'Lily', 'Lilyan', 'Lina',\n 'Lincoln', 'Linda', 'Lindsay', 'Lindsey', 'Linnea', 'Linnie', 'Linwood',\n 'Lionel', 'Lisa', 'Lisandro', 'Lisette', 'Litzy', 'Liza', 'Lizeth',\n 'Lizzie', 'Llewellyn', 'Lloyd', 'Logan', 'Lois', 'Lola', 'Lolita', 'Loma',\n 'Lon', 'London', 'Lonie', 'Lonnie', 'Lonny', 'Lonzo', 'Lora', 'Loraine',\n 'Loren', 'Lorena', 'Lorenz', 'Lorenza', 'Lorenzo', 'Lori', 'Lorine',\n 'Lorna', 'Lottie', 'Lou', 'Louie', 'Louisa', 'Lourdes', 'Louvenia',\n 'Lowell', 'Loy', 'Loyal', 'Loyce', 'Lucas', 'Luciano', 'Lucie', 'Lucienne',\n 'Lucile', 'Lucinda', 'Lucio', 'Lucious', 'Lucius', 'Lucy', 'Ludie',\n 'Ludwig', 'Lue', 'Luella', 'Luigi', 'Luis', 'Luisa', 'Lukas', 'Lula',\n 'Lulu', 'Luna', 'Lupe', 'Lura', 'Lurline', 'Luther', 'Luz', 'Lyda', 'Lydia',\n 'Lyla', 'Lynn', 'Lyric', 'Lysanne', 'Mabel', 'Mabelle', 'Mable', 'Mac',\n 'Macey', 'Maci', 'Macie', 'Mack', 'Mackenzie', 'Macy', 'Madaline',\n 'Madalyn', 'Maddison', 'Madeline', 'Madelyn', 'Madelynn', 'Madge', 'Madie',\n 'Madilyn', 'Madisen', 'Madison', 'Madisyn', 'Madonna', 'Madyson', 'Mae',\n 'Maegan', 'Maeve', 'Mafalda', 'Magali', 'Magdalen', 'Magdalena', 'Maggie',\n 'Magnolia', 'Magnus', 'Maia', 'Maida', 'Maiya', 'Major', 'Makayla',\n 'Makenna', 'Makenzie', 'Malachi', 'Malcolm', 'Malika', 'Malinda', 'Mallie',\n 'Mallory', 'Malvina', 'Mandy', 'Manley', 'Manuel', 'Manuela', 'Mara',\n 'Marc', 'Marcel', 'Marcelina', 'Marcelino', 'Marcella', 'Marcelle',\n 'Marcellus', 'Marcelo', 'Marcia', 'Marco', 'Marcos', 'Marcus', 'Margaret',\n 'Margarete', 'Margarett', 'Margaretta', 'Margarette', 'Margarita', 'Marge',\n 'Margie', 'Margot', 'Margret', 'Marguerite', 'Maria', 'Mariah', 'Mariam',\n 'Marian', 'Mariana', 'Mariane', 'Marianna', 'Marianne', 'Mariano',\n 'Maribel', 'Marie', 'Mariela', 'Marielle', 'Marietta', 'Marilie', 'Marilou',\n 'Marilyne', 'Marina', 'Mario', 'Marion', 'Marisa', 'Marisol', 'Maritza',\n 'Marjolaine', 'Marjorie', 'Marjory', 'Mark', 'Markus', 'Marlee', 'Marlen',\n 'Marlene', 'Marley', 'Marlin', 'Marlon', 'Marques', 'Marquis', 'Marquise',\n 'Marshall', 'Marta', 'Martin', 'Martina', 'Martine', 'Marty', 'Marvin',\n 'Mary', 'Maryam', 'Maryjane', 'Maryse', 'Mason', 'Mateo', 'Mathew',\n 'Mathias', 'Mathilde', 'Matilda', 'Matilde', 'Matt', 'Matteo', 'Mattie',\n 'Maud', 'Maude', 'Maudie', 'Maureen', 'Maurice', 'Mauricio', 'Maurine',\n 'Maverick', 'Mavis', 'Max', 'Maxie', 'Maxime', 'Maximilian', 'Maximillia',\n 'Maximillian', 'Maximo', 'Maximus', 'Maxine', 'Maxwell', 'May', 'Maya',\n 'Maybell', 'Maybelle', 'Maye', 'Maymie', 'Maynard', 'Mayra', 'Mazie',\n 'Mckayla', 'Mckenna', 'Mckenzie', 'Meagan', 'Meaghan', 'Meda', 'Megane',\n 'Meggie', 'Meghan', 'Mekhi', 'Melany', 'Melba', 'Melisa', 'Melissa',\n 'Mellie', 'Melody', 'Melvin', 'Melvina', 'Melyna', 'Melyssa', 'Mercedes',\n 'Meredith', 'Merl', 'Merle', 'Merlin', 'Merritt', 'Mertie', 'Mervin',\n 'Meta', 'Mia', 'Micaela', 'Micah', 'Michael', 'Michaela', 'Michale',\n 'Micheal', 'Michel', 'Michele', 'Michelle', 'Miguel', 'Mikayla', 'Mike',\n 'Mikel', 'Milan', 'Miles', 'Milford', 'Miller', 'Millie', 'Milo', 'Milton',\n 'Mina', 'Minerva', 'Minnie', 'Miracle', 'Mireille', 'Mireya', 'Misael',\n 'Missouri', 'Misty', 'Mitchel', 'Mitchell', 'Mittie', 'Modesta', 'Modesto',\n 'Mohamed', 'Mohammad', 'Mohammed', 'Moises', 'Mollie', 'Molly', 'Mona',\n 'Monica', 'Monique', 'Monroe', 'Monserrat', 'Monserrate', 'Montana',\n 'Monte', 'Monty', 'Morgan', 'Moriah', 'Morris', 'Mortimer', 'Morton',\n 'Mose', 'Moses', 'Moshe', 'Mossie', 'Mozell', 'Mozelle', 'Muhammad',\n 'Muriel', 'Murl', 'Murphy', 'Murray', 'Mustafa', 'Mya', 'Myah', 'Mylene',\n 'Myles', 'Myra', 'Myriam', 'Myrl', 'Myrna', 'Myron', 'Myrtice', 'Myrtie',\n 'Myrtis', 'Myrtle', 'Nadia', 'Nakia', 'Name', 'Nannie', 'Naomi', 'Naomie',\n 'Napoleon', 'Narciso', 'Nash', 'Nasir', 'Nat', 'Natalia', 'Natalie',\n 'Natasha', 'Nathan', 'Nathanael', 'Nathanial', 'Nathaniel', 'Nathen',\n 'Nayeli', 'Neal', 'Ned', 'Nedra', 'Neha', 'Neil', 'Nelda', 'Nella', 'Nelle',\n 'Nellie', 'Nels', 'Nelson', 'Neoma', 'Nestor', 'Nettie', 'Neva', 'Newell',\n 'Newton', 'Nia', 'Nicholas', 'Nicholaus', 'Nichole', 'Nick', 'Nicklaus',\n 'Nickolas', 'Nico', 'Nicola', 'Nicolas', 'Nicole', 'Nicolette', 'Nigel',\n 'Nikita', 'Nikki', 'Nikko', 'Niko', 'Nikolas', 'Nils', 'Nina', 'Noah',\n 'Noble', 'Noe', 'Noel', 'Noelia', 'Noemi', 'Noemie', 'Noemy', 'Nola',\n 'Nolan', 'Nona', 'Nora', 'Norbert', 'Norberto', 'Norene', 'Norma', 'Norris',\n 'Norval', 'Norwood', 'Nova', 'Novella', 'Nya', 'Nyah', 'Nyasia', 'Obie',\n 'Oceane', 'Ocie', 'Octavia', 'Oda', 'Odell', 'Odessa', 'Odie', 'Ofelia',\n 'Okey', 'Ola', 'Olaf', 'Ole', 'Olen', 'Oleta', 'Olga', 'Olin', 'Oliver',\n 'Ollie', 'Oma', 'Omari', 'Omer', 'Ona', 'Onie', 'Opal', 'Ophelia', 'Ora',\n 'Oral', 'Oran', 'Oren', 'Orie', 'Orin', 'Orion', 'Orland', 'Orlando',\n 'Orlo', 'Orpha', 'Orrin', 'Orval', 'Orville', 'Osbaldo', 'Osborne', 'Oscar',\n 'Osvaldo', 'Oswald', 'Oswaldo', 'Otha', 'Otho', 'Otilia', 'Otis', 'Ottilie',\n 'Ottis', 'Otto', 'Ova', 'Owen', 'Ozella', 'Pablo', 'Paige', 'Palma',\n 'Pamela', 'Pansy', 'Paolo', 'Paris', 'Parker', 'Pascale', 'Pasquale', 'Pat',\n 'Patience', 'Patricia', 'Patrick', 'Patsy', 'Pattie', 'Paul', 'Paula',\n 'Pauline', 'Paxton', 'Payton', 'Pearl', 'Pearlie', 'Pearline', 'Pedro',\n 'Peggie', 'Penelope', 'Percival', 'Percy', 'Perry', 'Pete', 'Peter',\n 'Petra', 'Peyton', 'Philip', 'Phoebe', 'Phyllis', 'Pierce', 'Pierre',\n 'Pietro', 'Pink', 'Pinkie', 'Piper', 'Polly', 'Porter', 'Precious',\n 'Presley', 'Preston', 'Price', 'Prince', 'Princess', 'Priscilla',\n 'Providenci', 'Prudence', 'Queen', 'Queenie', 'Quentin', 'Quincy', 'Quinn',\n 'Quinten', 'Quinton', 'Rachael', 'Rachel', 'Rachelle', 'Rae', 'Raegan',\n 'Rafael', 'Rafaela', 'Raheem', 'Rahsaan', 'Rahul', 'Raina', 'Raleigh',\n 'Ralph', 'Ramiro', 'Ramon', 'Ramona', 'Randal', 'Randall', 'Randi', 'Randy',\n 'Ransom', 'Raoul', 'Raphael', 'Raphaelle', 'Raquel', 'Rashad', 'Rashawn',\n 'Rasheed', 'Raul', 'Raven', 'Ray', 'Raymond', 'Raymundo', 'Reagan',\n 'Reanna', 'Reba', 'Rebeca', 'Rebecca', 'Rebeka', 'Rebekah', 'Reece', 'Reed',\n 'Reese', 'Regan', 'Reggie', 'Reginald', 'Reid', 'Reilly', 'Reina',\n 'Reinhold', 'Remington', 'Rene', 'Renee', 'Ressie', 'Reta', 'Retha',\n 'Retta', 'Reuben', 'Reva', 'Rex', 'Rey', 'Reyes', 'Reymundo', 'Reyna',\n 'Reynold', 'Rhea', 'Rhett', 'Rhianna', 'Rhiannon', 'Rhoda', 'Ricardo',\n 'Richard', 'Richie', 'Richmond', 'Rick', 'Rickey', 'Rickie', 'Ricky',\n 'Rico', 'Rigoberto', 'Riley', 'Rita', 'River', 'Robb', 'Robbie', 'Robert',\n 'Roberta', 'Roberto', 'Robin', 'Robyn', 'Rocio', 'Rocky', 'Rod', 'Roderick',\n 'Rodger', 'Rodolfo', 'Rodrick', 'Rodrigo', 'Roel', 'Rogelio', 'Roger',\n 'Rogers', 'Rolando', 'Rollin', 'Roma', 'Romaine', 'Roman', 'Ron', 'Ronaldo',\n 'Ronny', 'Roosevelt', 'Rory', 'Rosa', 'Rosalee', 'Rosalia', 'Rosalind',\n 'Rosalinda', 'Rosalyn', 'Rosamond', 'Rosanna', 'Rosario', 'Roscoe', 'Rose',\n 'Rosella', 'Roselyn', 'Rosemarie', 'Rosemary', 'Rosendo', 'Rosetta',\n 'Rosie', 'Rosina', 'Roslyn', 'Ross', 'Rossie', 'Rowan', 'Rowena', 'Rowland',\n 'Roxane', 'Roxanne', 'Roy', 'Royal', 'Royce', 'Rozella', 'Ruben', 'Rubie',\n 'Ruby', 'Rubye', 'Rudolph', 'Rudy', 'Rupert', 'Russ', 'Russel', 'Russell',\n 'Rusty', 'Ruth', 'Ruthe', 'Ruthie', 'Ryan', 'Ryann', 'Ryder', 'Rylan',\n 'Rylee', 'Ryleigh', 'Ryley', 'Sabina', 'Sabrina', 'Sabryna', 'Sadie',\n 'Sadye', 'Sage', 'Saige', 'Sallie', 'Sally', 'Salma', 'Salvador',\n 'Salvatore', 'Sam', 'Samanta', 'Samantha', 'Samara', 'Samir', 'Sammie',\n 'Sammy', 'Samson', 'Sandra', 'Sandrine', 'Sandy', 'Sanford', 'Santa',\n 'Santiago', 'Santina', 'Santino', 'Santos', 'Sarah', 'Sarai', 'Sarina',\n 'Sasha', 'Saul', 'Savanah', 'Savanna', 'Savannah', 'Savion', 'Scarlett',\n 'Schuyler', 'Scot', 'Scottie', 'Scotty', 'Seamus', 'Sean', 'Sebastian',\n 'Sedrick', 'Selena', 'Selina', 'Selmer', 'Serena', 'Serenity', 'Seth',\n 'Shad', 'Shaina', 'Shakira', 'Shana', 'Shane', 'Shanel', 'Shanelle',\n 'Shania', 'Shanie', 'Shaniya', 'Shanna', 'Shannon', 'Shanny', 'Shanon',\n 'Shany', 'Sharon', 'Shaun', 'Shawn', 'Shawna', 'Shaylee', 'Shayna',\n 'Shayne', 'Shea', 'Sheila', 'Sheldon', 'Shemar', 'Sheridan', 'Sherman',\n 'Sherwood', 'Shirley', 'Shyann', 'Shyanne', 'Sibyl', 'Sid', 'Sidney',\n 'Sienna', 'Sierra', 'Sigmund', 'Sigrid', 'Sigurd', 'Silas', 'Sim', 'Simeon',\n 'Simone', 'Sincere', 'Sister', 'Skye', 'Skyla', 'Skylar', 'Sofia',\n 'Soledad', 'Solon', 'Sonia', 'Sonny', 'Sonya', 'Sophia', 'Sophie',\n 'Spencer', 'Stacey', 'Stacy', 'Stan', 'Stanford', 'Stanley', 'Stanton',\n 'Stefan', 'Stefanie', 'Stella', 'Stephan', 'Stephania', 'Stephanie',\n 'Stephany', 'Stephen', 'Stephon', 'Sterling', 'Steve', 'Stevie', 'Stewart',\n 'Stone', 'Stuart', 'Summer', 'Sunny', 'Susan', 'Susana', 'Susanna', 'Susie',\n 'Suzanne', 'Sven', 'Syble', 'Sydnee', 'Sydney', 'Sydni', 'Sydnie', 'Sylvan',\n 'Sylvester', 'Sylvia', 'Tabitha', 'Tad', 'Talia', 'Talon', 'Tamara',\n 'Tamia', 'Tania', 'Tanner', 'Tanya', 'Tara', 'Taryn', 'Tate', 'Tatum',\n 'Tatyana', 'Taurean', 'Tavares', 'Taya', 'Taylor', 'Teagan', 'Ted', 'Telly',\n 'Terence', 'Teresa', 'Terrance', 'Terrell', 'Terrence', 'Terrill', 'Terry',\n 'Tess', 'Tessie', 'Tevin', 'Thad', 'Thaddeus', 'Thalia', 'Thea', 'Thelma',\n 'Theo', 'Theodora', 'Theodore', 'Theresa', 'Therese', 'Theresia', 'Theron',\n 'Thomas', 'Thora', 'Thurman', 'Tia', 'Tiana', 'Tianna', 'Tiara', 'Tierra',\n 'Tiffany', 'Tillman', 'Timmothy', 'Timmy', 'Timothy', 'Tina', 'Tito',\n 'Titus', 'Tobin', 'Toby', 'Tod', 'Tom', 'Tomas', 'Tomasa', 'Tommie',\n 'Toney', 'Toni', 'Tony', 'Torey', 'Torrance', 'Torrey', 'Toy', 'Trace',\n 'Tracey', 'Tracy', 'Travis', 'Travon', 'Tre', 'Tremaine', 'Tremayne',\n 'Trent', 'Trenton', 'Tressa', 'Tressie', 'Treva', 'Trever', 'Trevion',\n 'Trevor', 'Trey', 'Trinity', 'Trisha', 'Tristian', 'Tristin', 'Triston',\n 'Troy', 'Trudie', 'Trycia', 'Trystan', 'Turner', 'Twila', 'Tyler', 'Tyra',\n 'Tyree', 'Tyreek', 'Tyrel', 'Tyrell', 'Tyrese', 'Tyrique', 'Tyshawn',\n 'Tyson', 'Ubaldo', 'Ulices', 'Ulises', 'Una', 'Unique', 'Urban', 'Uriah',\n 'Uriel', 'Ursula', 'Vada', 'Valentin', 'Valentina', 'Valentine', 'Valerie',\n 'Vallie', 'Van', 'Vance', 'Vanessa', 'Vaughn', 'Veda', 'Velda', 'Vella',\n 'Velma', 'Velva', 'Vena', 'Verda', 'Verdie', 'Vergie', 'Verla', 'Verlie',\n 'Vern', 'Verna', 'Verner', 'Vernice', 'Vernie', 'Vernon', 'Verona',\n 'Veronica', 'Vesta', 'Vicenta', 'Vicente', 'Vickie', 'Vicky', 'Victor',\n 'Victoria', 'Vida', 'Vidal', 'Vilma', 'Vince', 'Vincent', 'Vincenza',\n 'Vincenzo', 'Vinnie', 'Viola', 'Violet', 'Violette', 'Virgie', 'Virgil',\n 'Virginia', 'Virginie', 'Vita', 'Vito', 'Viva', 'Vivian', 'Viviane',\n 'Vivianne', 'Vivien', 'Vivienne', 'Vladimir', 'Wade', 'Waino', 'Waldo',\n 'Walker', 'Wallace', 'Walter', 'Walton', 'Wanda', 'Ward', 'Warren',\n 'Watson', 'Wava', 'Waylon', 'Wayne', 'Webster', 'Weldon', 'Wellington',\n 'Wendell', 'Wendy', 'Werner', 'Westley', 'Weston', 'Whitney', 'Wilber',\n 'Wilbert', 'Wilburn', 'Wiley', 'Wilford', 'Wilfred', 'Wilfredo', 'Wilfrid',\n 'Wilhelm', 'Wilhelmine', 'Will', 'Willa', 'Willard', 'William', 'Willie',\n 'Willis', 'Willow', 'Willy', 'Wilma', 'Wilmer', 'Wilson', 'Wilton',\n 'Winfield', 'Winifred', 'Winnifred', 'Winona', 'Winston', 'Woodrow',\n 'Wyatt', 'Wyman', 'Xander', 'Xavier', 'Xzavier', 'Yadira', 'Yasmeen',\n 'Yasmin', 'Yasmine', 'Yazmin', 'Yesenia', 'Yessenia', 'Yolanda', 'Yoshiko',\n 'Yvette', 'Yvonne', 'Zachariah', 'Zachary', 'Zachery', 'Zack', 'Zackary',\n 'Zackery', 'Zakary', 'Zander', 'Zane', 'Zaria', 'Zechariah', 'Zelda',\n 'Zella', 'Zelma', 'Zena', 'Zetta', 'Zion', 'Zita', 'Zoe', 'Zoey', 'Zoie',\n 'Zoila', 'Zola', 'Zora', 'Zula'\n];\n\n/**\n * Generate random username.\n * @returns {string} random username\n */\nfunction generateUsername() {\n const name = RandomUtil.randomElement(names);\n const suffix = RandomUtil.randomAlphanumStr(3);\n\n return `${name}-${suffix}`;\n}\n\nmodule.exports = {\n generateUsername\n};\n", "/**\n* Gets next timeout using the full jitter pattern.\n*\n* NOTE that there are no checks for argument correctness, so either do the math or use defaults.\n*\n* @param {number} retry - The retry number.\n* @param {number} minDelay - The minimal delay in milliseconds.\n* @param {number} base - The exponent base.\n* @returns {number} - The amount of waiting before trying another time given in milliseconds.\n* @private\n*/\nexport function getJitterDelay(retry, minDelay = 500, base = 2) {\n return Math.floor((Math.random() * ((Math.pow(base, retry) * 1000) - minDelay)) + minDelay);\n}\n", "/**\n * Attaches to the {@link Strophe.Connection.rawInput} which is called whenever any data is received from the server.\n */\nexport default class LastRequestTracker {\n /**\n * Initializes new instance.\n */\n constructor() {\n this._lastSuccess = null;\n }\n\n /**\n * Starts tracking requests on the given connection.\n *\n * @param {Object} stropheConnection - Strophe connection instance.\n */\n startTracking(stropheConnection) {\n const originalRawInput = stropheConnection.rawInput;\n\n stropheConnection.rawInput = function(...args) {\n this._lastSuccess = Date.now();\n originalRawInput.apply(stropheConnection, args);\n };\n }\n\n /**\n * Returns how many milliseconds have passed since the last successful BOSH request.\n *\n * @returns {number|null}\n */\n getTimeSinceLastSuccess() {\n return this._lastSuccess\n ? Date.now() - this._lastSuccess\n : null;\n }\n}\n", "/* global $, __filename */\n\nimport {\n ACTION_JINGLE_TR_RECEIVED,\n ACTION_JINGLE_TR_SUCCESS,\n createJingleEvent\n} from '../../service/statistics/AnalyticsEvents';\nimport { getLogger } from 'jitsi-meet-logger';\nimport { $iq, Strophe } from 'strophe.js';\n\nimport XMPPEvents from '../../service/xmpp/XMPPEvents';\nimport GlobalOnErrorHandler from '../util/GlobalOnErrorHandler';\nimport RandomUtil from '../util/RandomUtil';\nimport Statistics from '../statistics/statistics';\n\nimport JingleSessionPC from './JingleSessionPC';\nimport ConnectionPlugin from './ConnectionPlugin';\n\nconst logger = getLogger(__filename);\n\n// XXX Strophe is build around the idea of chaining function calls so allow long\n// function call chains.\n/* eslint-disable newline-per-chained-call */\n\n/**\n *\n */\nexport default class JingleConnectionPlugin extends ConnectionPlugin {\n /**\n * Creates new JingleConnectionPlugin\n * @param {XMPP} xmpp\n * @param {EventEmitter} eventEmitter\n * @param {Object} iceConfig an object that holds the iceConfig to be passed\n * to the p2p and the jvb PeerConnection.\n */\n constructor(xmpp, eventEmitter, iceConfig) {\n super();\n this.xmpp = xmpp;\n this.eventEmitter = eventEmitter;\n this.sessions = {};\n this.jvbIceConfig = iceConfig.jvb;\n this.p2pIceConfig = iceConfig.p2p;\n this.mediaConstraints = {\n offerToReceiveAudio: true,\n offerToReceiveVideo: true\n };\n }\n\n /**\n *\n * @param connection\n */\n init(connection) {\n super.init(connection);\n this.connection.addHandler(this.onJingle.bind(this),\n 'urn:xmpp:jingle:1', 'iq', 'set', null, null);\n }\n\n /**\n *\n * @param iq\n */\n onJingle(iq) {\n const sid = $(iq).find('jingle').attr('sid');\n const action = $(iq).find('jingle').attr('action');\n const fromJid = iq.getAttribute('from');\n\n // send ack first\n const ack = $iq({ type: 'result',\n to: fromJid,\n id: iq.getAttribute('id')\n });\n\n logger.log(`on jingle ${action} from ${fromJid}`, iq);\n let sess = this.sessions[sid];\n\n if (action !== 'session-initiate') {\n if (!sess) {\n ack.attrs({ type: 'error' });\n ack.c('error', { type: 'cancel' })\n .c('item-not-found', {\n xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'\n })\n .up()\n .c('unknown-session', {\n xmlns: 'urn:xmpp:jingle:errors:1'\n });\n logger.warn('invalid session id', iq);\n this.connection.send(ack);\n\n return true;\n }\n\n // local jid is not checked\n if (fromJid !== sess.remoteJid) {\n logger.warn(\n 'jid mismatch for session id', sid, sess.remoteJid, iq);\n ack.attrs({ type: 'error' });\n ack.c('error', { type: 'cancel' })\n .c('item-not-found', {\n xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'\n })\n .up()\n .c('unknown-session', {\n xmlns: 'urn:xmpp:jingle:errors:1'\n });\n this.connection.send(ack);\n\n return true;\n }\n } else if (sess !== undefined) {\n // Existing session with same session id. This might be out-of-order\n // if the sess.remoteJid is the same as from.\n ack.attrs({ type: 'error' });\n ack.c('error', { type: 'cancel' })\n .c('service-unavailable', {\n xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'\n })\n .up();\n logger.warn('duplicate session id', sid, iq);\n this.connection.send(ack);\n\n return true;\n }\n const now = window.performance.now();\n\n // FIXME that should work most of the time, but we'd have to\n // think how secure it is to assume that user with \"focus\"\n // nickname is Jicofo.\n const isP2P = Strophe.getResourceFromJid(fromJid) !== 'focus';\n\n // see http://xmpp.org/extensions/xep-0166.html#concepts-session\n\n switch (action) {\n case 'session-initiate': {\n logger.log('(TIME) received session-initiate:\\t', now);\n const startMuted = $(iq).find('jingle>startmuted');\n\n if (startMuted && startMuted.length > 0) {\n const audioMuted = startMuted.attr('audio');\n const videoMuted = startMuted.attr('video');\n\n this.eventEmitter.emit(\n XMPPEvents.START_MUTED_FROM_FOCUS,\n audioMuted === 'true',\n videoMuted === 'true');\n }\n\n logger.info(\n `Marking session from ${fromJid\n } as ${isP2P ? '' : '*not*'} P2P`);\n\n const iceConfig = isP2P ? this.p2pIceConfig : this.jvbIceConfig;\n\n sess\n = new JingleSessionPC(\n $(iq).find('jingle').attr('sid'),\n $(iq).attr('to'),\n fromJid,\n this.connection,\n this.mediaConstraints,\n\n // Makes a copy in order to prevent exception thrown on RN when either this.p2pIceConfig or\n // this.jvbIceConfig is modified and there's a PeerConnection instance holding a reference\n JSON.parse(JSON.stringify(iceConfig)),\n isP2P,\n /* initiator */ false);\n\n this.sessions[sess.sid] = sess;\n\n this.eventEmitter.emit(XMPPEvents.CALL_INCOMING,\n sess, $(iq).find('>jingle'), now);\n break;\n }\n case 'session-accept': {\n this.eventEmitter.emit(\n XMPPEvents.CALL_ACCEPTED, sess, $(iq).find('>jingle'));\n break;\n }\n case 'content-modify': {\n sess.modifyContents($(iq).find('>jingle'));\n break;\n }\n case 'transport-info': {\n this.eventEmitter.emit(\n XMPPEvents.TRANSPORT_INFO, sess, $(iq).find('>jingle'));\n break;\n }\n case 'session-terminate': {\n logger.log('terminating...', sess.sid);\n let reasonCondition = null;\n let reasonText = null;\n\n if ($(iq).find('>jingle>reason').length) {\n reasonCondition\n = $(iq).find('>jingle>reason>:first')[0].tagName;\n reasonText = $(iq).find('>jingle>reason>text').text();\n }\n this.terminate(sess.sid, reasonCondition, reasonText);\n this.eventEmitter.emit(XMPPEvents.CALL_ENDED,\n sess, reasonCondition, reasonText);\n break;\n }\n case 'transport-replace':\n logger.info('(TIME) Start transport replace:\\t', now);\n Statistics.sendAnalytics(createJingleEvent(\n ACTION_JINGLE_TR_RECEIVED,\n {\n p2p: isP2P,\n value: now\n }));\n\n sess.replaceTransport($(iq).find('>jingle'), () => {\n const successTime = window.performance.now();\n\n logger.info('(TIME) Transport replace success:\\t', successTime);\n Statistics.sendAnalytics(createJingleEvent(\n ACTION_JINGLE_TR_SUCCESS,\n {\n p2p: isP2P,\n value: successTime\n }));\n }, error => {\n GlobalOnErrorHandler.callErrorHandler(error);\n logger.error('Transport replace failed', error);\n sess.sendTransportReject();\n });\n break;\n case 'addsource': // FIXME: proprietary, un-jingleish\n case 'source-add': // FIXME: proprietary\n sess.addRemoteStream($(iq).find('>jingle>content'));\n break;\n case 'removesource': // FIXME: proprietary, un-jingleish\n case 'source-remove': // FIXME: proprietary\n sess.removeRemoteStream($(iq).find('>jingle>content'));\n break;\n default:\n logger.warn('jingle action not implemented', action);\n ack.attrs({ type: 'error' });\n ack.c('error', { type: 'cancel' })\n .c('bad-request',\n { xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas' })\n .up();\n break;\n }\n this.connection.send(ack);\n\n return true;\n }\n\n /**\n * Creates new JingleSessionPC meant to be used in a direct P2P\n * connection, configured as 'initiator'.\n * @param {string} me our JID\n * @param {string} peer remote participant's JID\n * @return {JingleSessionPC}\n */\n newP2PJingleSession(me, peer) {\n const sess\n = new JingleSessionPC(\n RandomUtil.randomHexString(12),\n me,\n peer,\n this.connection,\n this.mediaConstraints,\n this.p2pIceConfig,\n /* P2P */ true,\n /* initiator */ true);\n\n this.sessions[sess.sid] = sess;\n\n return sess;\n }\n\n /**\n *\n * @param sid\n * @param reasonCondition\n * @param reasonText\n */\n terminate(sid, reasonCondition, reasonText) {\n if (this.sessions.hasOwnProperty(sid)) {\n if (this.sessions[sid].state !== 'ended') {\n this.sessions[sid].onTerminated(reasonCondition, reasonText);\n }\n delete this.sessions[sid];\n }\n }\n\n /**\n *\n */\n getStunAndTurnCredentials() {\n // get stun and turn configuration from server via xep-0215\n // uses time-limited credentials as described in\n // http://tools.ietf.org/html/draft-uberti-behave-turn-rest-00\n //\n // See https://modules.prosody.im/mod_turncredentials.html\n // for a prosody module which implements this.\n //\n // Currently, this doesn't work with updateIce and therefore credentials\n // with a long validity have to be fetched before creating the\n // peerconnection.\n // TODO: implement refresh via updateIce as described in\n // https://code.google.com/p/webrtc/issues/detail?id=1650\n this.connection.sendIQ(\n $iq({ type: 'get',\n to: this.connection.domain })\n .c('services', { xmlns: 'urn:xmpp:extdisco:1' }),\n res => {\n const iceservers = [];\n\n $(res).find('>services>service').each((idx, el) => {\n // eslint-disable-next-line no-param-reassign\n el = $(el);\n const dict = {};\n const type = el.attr('type');\n\n switch (type) {\n case 'stun':\n dict.urls = `stun:${el.attr('host')}`;\n if (el.attr('port')) {\n dict.urls += `:${el.attr('port')}`;\n }\n iceservers.push(dict);\n break;\n case 'turn':\n case 'turns': {\n dict.urls = `${type}:`;\n const username = el.attr('username');\n\n // https://code.google.com/p/webrtc/issues/detail\n // ?id=1508\n\n if (username) {\n const match\n = navigator.userAgent.match(\n /Chrom(e|ium)\\/([0-9]+)\\./);\n\n if (match && parseInt(match[2], 10) < 28) {\n dict.urls += `${username}@`;\n } else {\n // only works in M28\n dict.username = username;\n }\n }\n dict.urls += el.attr('host');\n const port = el.attr('port');\n\n if (port) {\n dict.urls += `:${el.attr('port')}`;\n }\n const transport = el.attr('transport');\n\n if (transport && transport !== 'udp') {\n dict.urls += `?transport=${transport}`;\n }\n\n dict.credential = el.attr('password')\n || dict.credential;\n iceservers.push(dict);\n break;\n }\n }\n });\n\n const options = this.xmpp.options;\n\n if (options.useStunTurn) {\n // we want to filter and leave only tcp/turns candidates\n // which make sense for the jvb connections\n this.jvbIceConfig.iceServers\n = iceservers.filter(s => s.urls.startsWith('turns'));\n }\n\n if (options.p2p && options.p2p.useStunTurn) {\n this.p2pIceConfig.iceServers = iceservers;\n }\n\n }, err => {\n logger.warn('getting turn credentials failed', err);\n logger.warn('is mod_turncredentials or similar installed?');\n });\n\n // implement push?\n }\n\n /**\n * Returns the data saved in 'updateLog' in a format to be logged.\n */\n getLog() {\n const data = {};\n\n Object.keys(this.sessions).forEach(sid => {\n const session = this.sessions[sid];\n const pc = session.peerconnection;\n\n if (pc && pc.updateLog) {\n // FIXME: should probably be a .dump call\n data[`jingle_${sid}`] = {\n updateLog: pc.updateLog,\n stats: pc.stats,\n url: window.location.href\n };\n }\n });\n\n return data;\n }\n}\n\n/* eslint-enable newline-per-chained-call */\n", "/**\n * Implements a simple hash code for a string (see\n * https://en.wikipedia.org/wiki/Java_hashCode()).\n *\n * @param {string} The string to return a hash of.\n * @return {Number} the integer hash code of the string.\n */\nfunction integerHash(string) {\n if (!string) {\n return 0;\n }\n\n let char, hash = 0, i;\n\n for (i = 0; i < string.length; i++) {\n char = string.charCodeAt(i);\n hash += char * Math.pow(31, string.length - 1 - i);\n hash = Math.abs(hash | 0); // eslint-disable-line no-bitwise\n }\n\n return hash;\n}\n\nmodule.exports = { integerHash };\n", "/* global __filename */\nimport { getLogger } from 'jitsi-meet-logger';\nimport * as JingleSessionState from './JingleSessionState';\n\nconst logger = getLogger(__filename);\n\n/**\n * JingleSession provides an API to manage a single Jingle session. We will\n * have different implementations depending on the underlying interface used\n * (i.e. WebRTC and ORTC) and here we hold the code common to all of them.\n */\nexport default class JingleSession {\n\n /* eslint-disable max-params */\n\n /**\n * Creates new JingleSession.\n * @param {string} sid the Jingle session identifier\n * @param {string} localJid our JID\n * @param {string} remoteJid the JID of the remote peer\n * @param {Strophe.Connection} connection the XMPP connection\n * @param {Object} mediaConstraints the media constraints object passed to\n * the PeerConnection onCreateAnswer/Offer as defined by the WebRTC.\n * @param {Object} iceConfig the ICE servers config object as defined by\n * the WebRTC. Passed to the PeerConnection's constructor.\n * @param {boolean} isInitiator indicates if it will be the side which\n * initiates the session.\n */\n constructor(\n sid,\n localJid,\n remoteJid,\n connection,\n mediaConstraints,\n iceConfig,\n isInitiator) {\n this.sid = sid;\n this.localJid = localJid;\n this.remoteJid = remoteJid;\n this.connection = connection;\n this.mediaConstraints = mediaConstraints;\n this.iceConfig = iceConfig;\n\n /**\n * Indicates whether this instance is an initiator or an answerer of\n * the Jingle session.\n * @type {boolean}\n */\n this.isInitiator = isInitiator;\n\n /**\n * Whether to use dripping or not. Dripping is sending trickle\n * candidates not one-by-one.\n */\n this.usedrip = true;\n\n /**\n * When dripping is used, stores ICE candidates which are to be sent.\n */\n this.dripContainer = [];\n\n /**\n * The chat room instance associated with the session.\n * @type {ChatRoom}\n */\n this.room = null;\n\n /**\n * Jingle session state - uninitialized until {@link initialize} is\n * called @type {JingleSessionState}\n */\n this.state = null;\n\n /**\n * The RTC service instance\n * @type {RTC}\n */\n this.rtc = null;\n }\n\n /**\n * Returns XMPP address of this session's initiator.\n * @return {string}\n */\n get initiatorJid() {\n return this.isInitiator ? this.localJid : this.remoteJid;\n }\n\n /**\n * Returns XMPP address of this session's responder.\n * @return {string}\n */\n get responderJid() {\n return this.isInitiator ? this.remoteJid : this.localJid;\n }\n\n /* eslint-enable max-params */\n\n /**\n * Prepares this object to initiate a session.\n * @param {ChatRoom} room the chat room for the conference associated with\n * this session\n * @param {RTC} rtc the RTC service instance\n * @param {object} options - the options, see implementing class's\n * {@link #doInitialize} description for more details.\n */\n initialize(room, rtc, options) {\n if (this.state !== null) {\n const errmsg\n = `attempt to initiate on session ${this.sid}\n in state ${this.state}`;\n\n logger.error(errmsg);\n throw new Error(errmsg);\n }\n this.room = room;\n this.rtc = rtc;\n this.state = JingleSessionState.PENDING;\n this.doInitialize(options);\n }\n\n /**\n * The implementing class finishes initialization here. Called at the end of\n * {@link initialize}.\n * @param {Object} options - The options specific to the implementing class.\n * @protected\n */\n doInitialize(options) { } // eslint-disable-line no-unused-vars, no-empty-function, max-len\n\n /* eslint-disable no-unused-vars, no-empty-function */\n\n /**\n * Adds the ICE candidates found in the 'contents' array as remote\n * candidates?\n * Note: currently only used on transport-info\n *\n * @param contents\n */\n addIceCandidates(contents) {}\n\n /* eslint-enable no-unused-vars, no-empty-function */\n\n /**\n * Returns current state of this JingleSession instance.\n * @returns {JingleSessionState} the current state of this session instance.\n */\n getState() {\n return this.state;\n }\n\n /* eslint-disable no-unused-vars, no-empty-function */\n\n /**\n * Handles an 'add-source' event.\n *\n * @param contents an array of Jingle 'content' elements.\n */\n addSources(contents) {}\n\n /**\n * Handles a 'remove-source' event.\n *\n * @param contents an array of Jingle 'content' elements.\n */\n removeSources(contents) {}\n\n /**\n * Terminates this Jingle session by sending session-terminate\n * @param success a callback called once the 'session-terminate' packet has\n * been acknowledged with RESULT.\n * @param failure a callback called when either timeout occurs or ERROR\n * response is received.\n * @param {Object} options\n * @param {string} [options.reason] XMPP Jingle error condition\n * @param {string} [options.reasonDescription] some meaningful error message\n * @param {boolean} [options.sendSessionTerminate=true] set to false to skip\n * sending session-terminate. It may not make sense to send it if the XMPP\n * connection has been closed already or if the remote peer has disconnected\n */\n terminate(success, failure, options) {}\n\n /**\n * Handles an offer from the remote peer (prepares to accept a session).\n * @param jingle the 'jingle' XML element.\n * @param success callback called when we the incoming session has been\n * accepted\n * @param failure callback called when we fail for any reason, will supply\n * error object with details(which is meant more to be printed to the logger\n * than analysed in the code, as the error is unrecoverable anyway)\n */\n acceptOffer(jingle, success, failure) {}\n\n /**\n * Returns the JID of the initiator of the jingle session.\n */\n _getInitiatorJid() {\n return this.isInitiator ? this.localJid : this.remoteJid;\n }\n\n /* eslint-enable no-unused-vars, no-empty-function */\n}\n", "/* global __filename */\n\nimport { getLogger } from 'jitsi-meet-logger';\nimport * as MediaType from '../../service/RTC/MediaType';\nimport * as SignalingEvents from '../../service/RTC/SignalingEvents';\nimport SignalingLayer from '../../service/RTC/SignalingLayer';\n\nconst logger = getLogger(__filename);\n\n/**\n * Default XMPP implementation of the {@link SignalingLayer} interface. Obtains\n * the data from the MUC presence.\n */\nexport default class SignalingLayerImpl extends SignalingLayer {\n /**\n * Creates new instance.\n */\n constructor() {\n super();\n\n /**\n * A map that stores SSRCs of remote streams. And is used only locally\n * We store the mapping when jingle is received, and later is used\n * onaddstream webrtc event where we have only the ssrc\n * FIXME: This map got filled and never cleaned and can grow during long\n * conference\n * @type {Map} maps SSRC number to jid\n */\n this.ssrcOwners = new Map();\n\n /**\n *\n * @type {ChatRoom|null}\n */\n this.chatRoom = null;\n }\n\n /**\n * Sets the ChatRoom instance used and binds presence listeners.\n * @param {ChatRoom} room\n */\n setChatRoom(room) {\n const oldChatRoom = this.chatRoom;\n\n this.chatRoom = room;\n if (oldChatRoom) {\n oldChatRoom.removePresenceListener(\n 'audiomuted', this._audioMuteHandler);\n oldChatRoom.removePresenceListener(\n 'videomuted', this._videoMuteHandler);\n oldChatRoom.removePresenceListener(\n 'videoType', this._videoTypeHandler);\n }\n if (room) {\n // SignalingEvents\n this._audioMuteHandler = (node, from) => {\n this.eventEmitter.emit(\n SignalingEvents.PEER_MUTED_CHANGED,\n from, MediaType.AUDIO, node.value === 'true');\n };\n room.addPresenceListener('audiomuted', this._audioMuteHandler);\n\n this._videoMuteHandler = (node, from) => {\n this.eventEmitter.emit(\n SignalingEvents.PEER_MUTED_CHANGED,\n from, MediaType.VIDEO, node.value === 'true');\n };\n room.addPresenceListener('videomuted', this._videoMuteHandler);\n\n this._videoTypeHandler = (node, from) => {\n this.eventEmitter.emit(\n SignalingEvents.PEER_VIDEO_TYPE_CHANGED,\n from, node.value);\n };\n room.addPresenceListener('videoType', this._videoTypeHandler);\n }\n }\n\n /**\n * @inheritDoc\n */\n getPeerMediaInfo(owner, mediaType) {\n if (this.chatRoom) {\n return this.chatRoom.getMediaPresenceInfo(owner, mediaType);\n }\n logger.error('Requested peer media info, before room was set');\n }\n\n /**\n * @inheritDoc\n */\n getSSRCOwner(ssrc) {\n return this.ssrcOwners.get(ssrc);\n }\n\n /**\n * Set an SSRC owner.\n * @param {number} ssrc an SSRC to be owned\n * @param {string} endpointId owner's ID (MUC nickname)\n * @throws TypeError if ssrc is not a number\n */\n setSSRCOwner(ssrc, endpointId) {\n if (typeof ssrc !== 'number') {\n throw new TypeError(`SSRC(${ssrc}) must be a number`);\n }\n this.ssrcOwners.set(ssrc, endpointId);\n }\n}\n", "\nimport Listenable from '../../modules/util/Listenable';\n\n/**\n * An object that carries the info about specific media type advertised by\n * participant in the signaling channel.\n * @typedef {Object} PeerMediaInfo\n * @property {boolean} muted indicates if the media is currently muted\n * @property {VideoType|undefined} videoType the type of the video if applicable\n */\n\n/**\n * Interface used to expose the information carried over the signaling channel\n * which is not available to the RTC module in the media SDP.\n *\n * @interface SignalingLayer\n */\nexport default class SignalingLayer extends Listenable {\n\n /**\n * Obtains the endpoint ID for given SSRC.\n * @param {number} ssrc the SSRC number.\n * @return {string|null} the endpoint ID for given media SSRC.\n */\n getSSRCOwner(ssrc) { // eslint-disable-line no-unused-vars\n throw new Error('not implemented');\n }\n\n /**\n * Obtains the info about given media advertised in the MUC presence of\n * the participant identified by the given MUC JID.\n * @param {string} owner the MUC jid of the participant for whom\n * {@link PeerMediaInfo} will be obtained.\n * @param {MediaType} mediaType the type of the media for which presence\n * info will be obtained.\n * @return {PeerMediaInfo|null} presenceInfo an object with media presence\n * info or null either if there is no presence available for given\n * JID or if the media type given is invalid.\n */\n getPeerMediaInfo(owner, mediaType) { // eslint-disable-line no-unused-vars\n throw new Error('not implemented');\n }\n}\n", "import async from 'async';\n\n/**\n * A queue for async task execution.\n */\nexport default class AsyncQueue {\n /**\n * Creates new instance.\n */\n constructor() {\n this._queue = async.queue(this._processQueueTasks.bind(this), 1);\n this._stopped = false;\n }\n\n /**\n * Removes any pending tasks from the queue.\n */\n clear() {\n this._queue.kill();\n }\n\n /**\n * Internal task processing implementation which makes things work.\n */\n _processQueueTasks(task, finishedCallback) {\n task(finishedCallback);\n }\n\n /**\n * The 'task' function will be given a callback it MUST call with either:\n * 1) No arguments if it was successful or\n * 2) An error argument if there was an error\n * If the task wants to process the success or failure of the task, it\n * should pass the {@code callback} to the push function, e.g.:\n * queue.push(task, (err) => {\n * if (err) {\n * // error handling\n * } else {\n * // success handling\n * }\n * });\n *\n * @param {function} task - The task to be executed. See the description above.\n * @param {function} [callback] - Optional callback to be called after the task has been executed.\n */\n push(task, callback) {\n if (this._stopped) {\n callback && callback(new Error('The queue has been stopped'));\n\n return;\n }\n this._queue.push(task, callback);\n }\n\n /**\n * Shutdowns the queue. All already queued tasks will execute, but no future tasks can be added. If a task is added\n * after the queue has been shutdown then the callback will be called with an error.\n */\n shutdown() {\n this._stopped = true;\n }\n}\n", "/*!\n * async\n * https://github.com/caolan/async\n *\n * Copyright 2010-2014 Caolan McMahon\n * Released under the MIT license\n */\n/*jshint onevar: false, indent:4 */\n/*global setImmediate: false, setTimeout: false, console: false */\n(function () {\n\n var async = {};\n\n // global on the server, window in the browser\n var root, previous_async;\n\n root = this;\n if (root != null) {\n previous_async = root.async;\n }\n\n async.noConflict = function () {\n root.async = previous_async;\n return async;\n };\n\n function only_once(fn) {\n var called = false;\n return function() {\n if (called) throw new Error(\"Callback was already called.\");\n called = true;\n fn.apply(root, arguments);\n }\n }\n\n //// cross-browser compatiblity functions ////\n\n var _toString = Object.prototype.toString;\n\n var _isArray = Array.isArray || function (obj) {\n return _toString.call(obj) === '[object Array]';\n };\n\n var _each = function (arr, iterator) {\n if (arr.forEach) {\n return arr.forEach(iterator);\n }\n for (var i = 0; i < arr.length; i += 1) {\n iterator(arr[i], i, arr);\n }\n };\n\n var _map = function (arr, iterator) {\n if (arr.map) {\n return arr.map(iterator);\n }\n var results = [];\n _each(arr, function (x, i, a) {\n results.push(iterator(x, i, a));\n });\n return results;\n };\n\n var _reduce = function (arr, iterator, memo) {\n if (arr.reduce) {\n return arr.reduce(iterator, memo);\n }\n _each(arr, function (x, i, a) {\n memo = iterator(memo, x, i, a);\n });\n return memo;\n };\n\n var _keys = function (obj) {\n if (Object.keys) {\n return Object.keys(obj);\n }\n var keys = [];\n for (var k in obj) {\n if (obj.hasOwnProperty(k)) {\n keys.push(k);\n }\n }\n return keys;\n };\n\n //// exported async module functions ////\n\n //// nextTick implementation with browser-compatible fallback ////\n if (typeof process === 'undefined' || !(process.nextTick)) {\n if (typeof setImmediate === 'function') {\n async.nextTick = function (fn) {\n // not a direct alias for IE10 compatibility\n setImmediate(fn);\n };\n async.setImmediate = async.nextTick;\n }\n else {\n async.nextTick = function (fn) {\n setTimeout(fn, 0);\n };\n async.setImmediate = async.nextTick;\n }\n }\n else {\n async.nextTick = process.nextTick;\n if (typeof setImmediate !== 'undefined') {\n async.setImmediate = function (fn) {\n // not a direct alias for IE10 compatibility\n setImmediate(fn);\n };\n }\n else {\n async.setImmediate = async.nextTick;\n }\n }\n\n async.each = function (arr, iterator, callback) {\n callback = callback || function () {};\n if (!arr.length) {\n return callback();\n }\n var completed = 0;\n _each(arr, function (x) {\n iterator(x, only_once(done) );\n });\n function done(err) {\n if (err) {\n callback(err);\n callback = function () {};\n }\n else {\n completed += 1;\n if (completed >= arr.length) {\n callback();\n }\n }\n }\n };\n async.forEach = async.each;\n\n async.eachSeries = function (arr, iterator, callback) {\n callback = callback || function () {};\n if (!arr.length) {\n return callback();\n }\n var completed = 0;\n var iterate = function () {\n iterator(arr[completed], function (err) {\n if (err) {\n callback(err);\n callback = function () {};\n }\n else {\n completed += 1;\n if (completed >= arr.length) {\n callback();\n }\n else {\n iterate();\n }\n }\n });\n };\n iterate();\n };\n async.forEachSeries = async.eachSeries;\n\n async.eachLimit = function (arr, limit, iterator, callback) {\n var fn = _eachLimit(limit);\n fn.apply(null, [arr, iterator, callback]);\n };\n async.forEachLimit = async.eachLimit;\n\n var _eachLimit = function (limit) {\n\n return function (arr, iterator, callback) {\n callback = callback || function () {};\n if (!arr.length || limit <= 0) {\n return callback();\n }\n var completed = 0;\n var started = 0;\n var running = 0;\n\n (function replenish () {\n if (completed >= arr.length) {\n return callback();\n }\n\n while (running < limit && started < arr.length) {\n started += 1;\n running += 1;\n iterator(arr[started - 1], function (err) {\n if (err) {\n callback(err);\n callback = function () {};\n }\n else {\n completed += 1;\n running -= 1;\n if (completed >= arr.length) {\n callback();\n }\n else {\n replenish();\n }\n }\n });\n }\n })();\n };\n };\n\n\n var doParallel = function (fn) {\n return function () {\n var args = Array.prototype.slice.call(arguments);\n return fn.apply(null, [async.each].concat(args));\n };\n };\n var doParallelLimit = function(limit, fn) {\n return function () {\n var args = Array.prototype.slice.call(arguments);\n return fn.apply(null, [_eachLimit(limit)].concat(args));\n };\n };\n var doSeries = function (fn) {\n return function () {\n var args = Array.prototype.slice.call(arguments);\n return fn.apply(null, [async.eachSeries].concat(args));\n };\n };\n\n\n var _asyncMap = function (eachfn, arr, iterator, callback) {\n arr = _map(arr, function (x, i) {\n return {index: i, value: x};\n });\n if (!callback) {\n eachfn(arr, function (x, callback) {\n iterator(x.value, function (err) {\n callback(err);\n });\n });\n } else {\n var results = [];\n eachfn(arr, function (x, callback) {\n iterator(x.value, function (err, v) {\n results[x.index] = v;\n callback(err);\n });\n }, function (err) {\n callback(err, results);\n });\n }\n };\n async.map = doParallel(_asyncMap);\n async.mapSeries = doSeries(_asyncMap);\n async.mapLimit = function (arr, limit, iterator, callback) {\n return _mapLimit(limit)(arr, iterator, callback);\n };\n\n var _mapLimit = function(limit) {\n return doParallelLimit(limit, _asyncMap);\n };\n\n // reduce only has a series version, as doing reduce in parallel won't\n // work in many situations.\n async.reduce = function (arr, memo, iterator, callback) {\n async.eachSeries(arr, function (x, callback) {\n iterator(memo, x, function (err, v) {\n memo = v;\n callback(err);\n });\n }, function (err) {\n callback(err, memo);\n });\n };\n // inject alias\n async.inject = async.reduce;\n // foldl alias\n async.foldl = async.reduce;\n\n async.reduceRight = function (arr, memo, iterator, callback) {\n var reversed = _map(arr, function (x) {\n return x;\n }).reverse();\n async.reduce(reversed, memo, iterator, callback);\n };\n // foldr alias\n async.foldr = async.reduceRight;\n\n var _filter = function (eachfn, arr, iterator, callback) {\n var results = [];\n arr = _map(arr, function (x, i) {\n return {index: i, value: x};\n });\n eachfn(arr, function (x, callback) {\n iterator(x.value, function (v) {\n if (v) {\n results.push(x);\n }\n callback();\n });\n }, function (err) {\n callback(_map(results.sort(function (a, b) {\n return a.index - b.index;\n }), function (x) {\n return x.value;\n }));\n });\n };\n async.filter = doParallel(_filter);\n async.filterSeries = doSeries(_filter);\n // select alias\n async.select = async.filter;\n async.selectSeries = async.filterSeries;\n\n var _reject = function (eachfn, arr, iterator, callback) {\n var results = [];\n arr = _map(arr, function (x, i) {\n return {index: i, value: x};\n });\n eachfn(arr, function (x, callback) {\n iterator(x.value, function (v) {\n if (!v) {\n results.push(x);\n }\n callback();\n });\n }, function (err) {\n callback(_map(results.sort(function (a, b) {\n return a.index - b.index;\n }), function (x) {\n return x.value;\n }));\n });\n };\n async.reject = doParallel(_reject);\n async.rejectSeries = doSeries(_reject);\n\n var _detect = function (eachfn, arr, iterator, main_callback) {\n eachfn(arr, function (x, callback) {\n iterator(x, function (result) {\n if (result) {\n main_callback(x);\n main_callback = function () {};\n }\n else {\n callback();\n }\n });\n }, function (err) {\n main_callback();\n });\n };\n async.detect = doParallel(_detect);\n async.detectSeries = doSeries(_detect);\n\n async.some = function (arr, iterator, main_callback) {\n async.each(arr, function (x, callback) {\n iterator(x, function (v) {\n if (v) {\n main_callback(true);\n main_callback = function () {};\n }\n callback();\n });\n }, function (err) {\n main_callback(false);\n });\n };\n // any alias\n async.any = async.some;\n\n async.every = function (arr, iterator, main_callback) {\n async.each(arr, function (x, callback) {\n iterator(x, function (v) {\n if (!v) {\n main_callback(false);\n main_callback = function () {};\n }\n callback();\n });\n }, function (err) {\n main_callback(true);\n });\n };\n // all alias\n async.all = async.every;\n\n async.sortBy = function (arr, iterator, callback) {\n async.map(arr, function (x, callback) {\n iterator(x, function (err, criteria) {\n if (err) {\n callback(err);\n }\n else {\n callback(null, {value: x, criteria: criteria});\n }\n });\n }, function (err, results) {\n if (err) {\n return callback(err);\n }\n else {\n var fn = function (left, right) {\n var a = left.criteria, b = right.criteria;\n return a < b ? -1 : a > b ? 1 : 0;\n };\n callback(null, _map(results.sort(fn), function (x) {\n return x.value;\n }));\n }\n });\n };\n\n async.auto = function (tasks, callback) {\n callback = callback || function () {};\n var keys = _keys(tasks);\n var remainingTasks = keys.length\n if (!remainingTasks) {\n return callback();\n }\n\n var results = {};\n\n var listeners = [];\n var addListener = function (fn) {\n listeners.unshift(fn);\n };\n var removeListener = function (fn) {\n for (var i = 0; i < listeners.length; i += 1) {\n if (listeners[i] === fn) {\n listeners.splice(i, 1);\n return;\n }\n }\n };\n var taskComplete = function () {\n remainingTasks--\n _each(listeners.slice(0), function (fn) {\n fn();\n });\n };\n\n addListener(function () {\n if (!remainingTasks) {\n var theCallback = callback;\n // prevent final callback from calling itself if it errors\n callback = function () {};\n\n theCallback(null, results);\n }\n });\n\n _each(keys, function (k) {\n var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];\n var taskCallback = function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length <= 1) {\n args = args[0];\n }\n if (err) {\n var safeResults = {};\n _each(_keys(results), function(rkey) {\n safeResults[rkey] = results[rkey];\n });\n safeResults[k] = args;\n callback(err, safeResults);\n // stop subsequent errors hitting callback multiple times\n callback = function () {};\n }\n else {\n results[k] = args;\n async.setImmediate(taskComplete);\n }\n };\n var requires = task.slice(0, Math.abs(task.length - 1)) || [];\n var ready = function () {\n return _reduce(requires, function (a, x) {\n return (a && results.hasOwnProperty(x));\n }, true) && !results.hasOwnProperty(k);\n };\n if (ready()) {\n task[task.length - 1](taskCallback, results);\n }\n else {\n var listener = function () {\n if (ready()) {\n removeListener(listener);\n task[task.length - 1](taskCallback, results);\n }\n };\n addListener(listener);\n }\n });\n };\n\n async.retry = function(times, task, callback) {\n var DEFAULT_TIMES = 5;\n var attempts = [];\n // Use defaults if times not passed\n if (typeof times === 'function') {\n callback = task;\n task = times;\n times = DEFAULT_TIMES;\n }\n // Make sure times is a number\n times = parseInt(times, 10) || DEFAULT_TIMES;\n var wrappedTask = function(wrappedCallback, wrappedResults) {\n var retryAttempt = function(task, finalAttempt) {\n return function(seriesCallback) {\n task(function(err, result){\n seriesCallback(!err || finalAttempt, {err: err, result: result});\n }, wrappedResults);\n };\n };\n while (times) {\n attempts.push(retryAttempt(task, !(times-=1)));\n }\n async.series(attempts, function(done, data){\n data = data[data.length - 1];\n (wrappedCallback || callback)(data.err, data.result);\n });\n }\n // If a callback is passed, run this as a controll flow\n return callback ? wrappedTask() : wrappedTask\n };\n\n async.waterfall = function (tasks, callback) {\n callback = callback || function () {};\n if (!_isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n var wrapIterator = function (iterator) {\n return function (err) {\n if (err) {\n callback.apply(null, arguments);\n callback = function () {};\n }\n else {\n var args = Array.prototype.slice.call(arguments, 1);\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n async.setImmediate(function () {\n iterator.apply(null, args);\n });\n }\n };\n };\n wrapIterator(async.iterator(tasks))();\n };\n\n var _parallel = function(eachfn, tasks, callback) {\n callback = callback || function () {};\n if (_isArray(tasks)) {\n eachfn.map(tasks, function (fn, callback) {\n if (fn) {\n fn(function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length <= 1) {\n args = args[0];\n }\n callback.call(null, err, args);\n });\n }\n }, callback);\n }\n else {\n var results = {};\n eachfn.each(_keys(tasks), function (k, callback) {\n tasks[k](function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length <= 1) {\n args = args[0];\n }\n results[k] = args;\n callback(err);\n });\n }, function (err) {\n callback(err, results);\n });\n }\n };\n\n async.parallel = function (tasks, callback) {\n _parallel({ map: async.map, each: async.each }, tasks, callback);\n };\n\n async.parallelLimit = function(tasks, limit, callback) {\n _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);\n };\n\n async.series = function (tasks, callback) {\n callback = callback || function () {};\n if (_isArray(tasks)) {\n async.mapSeries(tasks, function (fn, callback) {\n if (fn) {\n fn(function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length <= 1) {\n args = args[0];\n }\n callback.call(null, err, args);\n });\n }\n }, callback);\n }\n else {\n var results = {};\n async.eachSeries(_keys(tasks), function (k, callback) {\n tasks[k](function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length <= 1) {\n args = args[0];\n }\n results[k] = args;\n callback(err);\n });\n }, function (err) {\n callback(err, results);\n });\n }\n };\n\n async.iterator = function (tasks) {\n var makeCallback = function (index) {\n var fn = function () {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n };\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1): null;\n };\n return fn;\n };\n return makeCallback(0);\n };\n\n async.apply = function (fn) {\n var args = Array.prototype.slice.call(arguments, 1);\n return function () {\n return fn.apply(\n null, args.concat(Array.prototype.slice.call(arguments))\n );\n };\n };\n\n var _concat = function (eachfn, arr, fn, callback) {\n var r = [];\n eachfn(arr, function (x, cb) {\n fn(x, function (err, y) {\n r = r.concat(y || []);\n cb(err);\n });\n }, function (err) {\n callback(err, r);\n });\n };\n async.concat = doParallel(_concat);\n async.concatSeries = doSeries(_concat);\n\n async.whilst = function (test, iterator, callback) {\n if (test()) {\n iterator(function (err) {\n if (err) {\n return callback(err);\n }\n async.whilst(test, iterator, callback);\n });\n }\n else {\n callback();\n }\n };\n\n async.doWhilst = function (iterator, test, callback) {\n iterator(function (err) {\n if (err) {\n return callback(err);\n }\n var args = Array.prototype.slice.call(arguments, 1);\n if (test.apply(null, args)) {\n async.doWhilst(iterator, test, callback);\n }\n else {\n callback();\n }\n });\n };\n\n async.until = function (test, iterator, callback) {\n if (!test()) {\n iterator(function (err) {\n if (err) {\n return callback(err);\n }\n async.until(test, iterator, callback);\n });\n }\n else {\n callback();\n }\n };\n\n async.doUntil = function (iterator, test, callback) {\n iterator(function (err) {\n if (err) {\n return callback(err);\n }\n var args = Array.prototype.slice.call(arguments, 1);\n if (!test.apply(null, args)) {\n async.doUntil(iterator, test, callback);\n }\n else {\n callback();\n }\n });\n };\n\n async.queue = function (worker, concurrency) {\n if (concurrency === undefined) {\n concurrency = 1;\n }\n function _insert(q, data, pos, callback) {\n if (!q.started){\n q.started = true;\n }\n if (!_isArray(data)) {\n data = [data];\n }\n if(data.length == 0) {\n // call drain immediately if there are no tasks\n return async.setImmediate(function() {\n if (q.drain) {\n q.drain();\n }\n });\n }\n _each(data, function(task) {\n var item = {\n data: task,\n callback: typeof callback === 'function' ? callback : null\n };\n\n if (pos) {\n q.tasks.unshift(item);\n } else {\n q.tasks.push(item);\n }\n\n if (q.saturated && q.tasks.length === q.concurrency) {\n q.saturated();\n }\n async.setImmediate(q.process);\n });\n }\n\n var workers = 0;\n var q = {\n tasks: [],\n concurrency: concurrency,\n saturated: null,\n empty: null,\n drain: null,\n started: false,\n paused: false,\n push: function (data, callback) {\n _insert(q, data, false, callback);\n },\n kill: function () {\n q.drain = null;\n q.tasks = [];\n },\n unshift: function (data, callback) {\n _insert(q, data, true, callback);\n },\n process: function () {\n if (!q.paused && workers < q.concurrency && q.tasks.length) {\n var task = q.tasks.shift();\n if (q.empty && q.tasks.length === 0) {\n q.empty();\n }\n workers += 1;\n var next = function () {\n workers -= 1;\n if (task.callback) {\n task.callback.apply(task, arguments);\n }\n if (q.drain && q.tasks.length + workers === 0) {\n q.drain();\n }\n q.process();\n };\n var cb = only_once(next);\n worker(task.data, cb);\n }\n },\n length: function () {\n return q.tasks.length;\n },\n running: function () {\n return workers;\n },\n idle: function() {\n return q.tasks.length + workers === 0;\n },\n pause: function () {\n if (q.paused === true) { return; }\n q.paused = true;\n q.process();\n },\n resume: function () {\n if (q.paused === false) { return; }\n q.paused = false;\n q.process();\n }\n };\n return q;\n };\n \n async.priorityQueue = function (worker, concurrency) {\n \n function _compareTasks(a, b){\n return a.priority - b.priority;\n };\n \n function _binarySearch(sequence, item, compare) {\n var beg = -1,\n end = sequence.length - 1;\n while (beg < end) {\n var mid = beg + ((end - beg + 1) >>> 1);\n if (compare(item, sequence[mid]) >= 0) {\n beg = mid;\n } else {\n end = mid - 1;\n }\n }\n return beg;\n }\n \n function _insert(q, data, priority, callback) {\n if (!q.started){\n q.started = true;\n }\n if (!_isArray(data)) {\n data = [data];\n }\n if(data.length == 0) {\n // call drain immediately if there are no tasks\n return async.setImmediate(function() {\n if (q.drain) {\n q.drain();\n }\n });\n }\n _each(data, function(task) {\n var item = {\n data: task,\n priority: priority,\n callback: typeof callback === 'function' ? callback : null\n };\n \n q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);\n\n if (q.saturated && q.tasks.length === q.concurrency) {\n q.saturated();\n }\n async.setImmediate(q.process);\n });\n }\n \n // Start with a normal queue\n var q = async.queue(worker, concurrency);\n \n // Override push to accept second parameter representing priority\n q.push = function (data, priority, callback) {\n _insert(q, data, priority, callback);\n };\n \n // Remove unshift function\n delete q.unshift;\n\n return q;\n };\n\n async.cargo = function (worker, payload) {\n var working = false,\n tasks = [];\n\n var cargo = {\n tasks: tasks,\n payload: payload,\n saturated: null,\n empty: null,\n drain: null,\n drained: true,\n push: function (data, callback) {\n if (!_isArray(data)) {\n data = [data];\n }\n _each(data, function(task) {\n tasks.push({\n data: task,\n callback: typeof callback === 'function' ? callback : null\n });\n cargo.drained = false;\n if (cargo.saturated && tasks.length === payload) {\n cargo.saturated();\n }\n });\n async.setImmediate(cargo.process);\n },\n process: function process() {\n if (working) return;\n if (tasks.length === 0) {\n if(cargo.drain && !cargo.drained) cargo.drain();\n cargo.drained = true;\n return;\n }\n\n var ts = typeof payload === 'number'\n ? tasks.splice(0, payload)\n : tasks.splice(0, tasks.length);\n\n var ds = _map(ts, function (task) {\n return task.data;\n });\n\n if(cargo.empty) cargo.empty();\n working = true;\n worker(ds, function () {\n working = false;\n\n var args = arguments;\n _each(ts, function (data) {\n if (data.callback) {\n data.callback.apply(null, args);\n }\n });\n\n process();\n });\n },\n length: function () {\n return tasks.length;\n },\n running: function () {\n return working;\n }\n };\n return cargo;\n };\n\n var _console_fn = function (name) {\n return function (fn) {\n var args = Array.prototype.slice.call(arguments, 1);\n fn.apply(null, args.concat([function (err) {\n var args = Array.prototype.slice.call(arguments, 1);\n if (typeof console !== 'undefined') {\n if (err) {\n if (console.error) {\n console.error(err);\n }\n }\n else if (console[name]) {\n _each(args, function (x) {\n console[name](x);\n });\n }\n }\n }]));\n };\n };\n async.log = _console_fn('log');\n async.dir = _console_fn('dir');\n /*async.info = _console_fn('info');\n async.warn = _console_fn('warn');\n async.error = _console_fn('error');*/\n\n async.memoize = function (fn, hasher) {\n var memo = {};\n var queues = {};\n hasher = hasher || function (x) {\n return x;\n };\n var memoized = function () {\n var args = Array.prototype.slice.call(arguments);\n var callback = args.pop();\n var key = hasher.apply(null, args);\n if (key in memo) {\n async.nextTick(function () {\n callback.apply(null, memo[key]);\n });\n }\n else if (key in queues) {\n queues[key].push(callback);\n }\n else {\n queues[key] = [callback];\n fn.apply(null, args.concat([function () {\n memo[key] = arguments;\n var q = queues[key];\n delete queues[key];\n for (var i = 0, l = q.length; i < l; i++) {\n q[i].apply(null, arguments);\n }\n }]));\n }\n };\n memoized.memo = memo;\n memoized.unmemoized = fn;\n return memoized;\n };\n\n async.unmemoize = function (fn) {\n return function () {\n return (fn.unmemoized || fn).apply(null, arguments);\n };\n };\n\n async.times = function (count, iterator, callback) {\n var counter = [];\n for (var i = 0; i < count; i++) {\n counter.push(i);\n }\n return async.map(counter, iterator, callback);\n };\n\n async.timesSeries = function (count, iterator, callback) {\n var counter = [];\n for (var i = 0; i < count; i++) {\n counter.push(i);\n }\n return async.mapSeries(counter, iterator, callback);\n };\n\n async.seq = function (/* functions... */) {\n var fns = arguments;\n return function () {\n var that = this;\n var args = Array.prototype.slice.call(arguments);\n var callback = args.pop();\n async.reduce(fns, args, function (newargs, fn, cb) {\n fn.apply(that, newargs.concat([function () {\n var err = arguments[0];\n var nextargs = Array.prototype.slice.call(arguments, 1);\n cb(err, nextargs);\n }]))\n },\n function (err, results) {\n callback.apply(that, [err].concat(results));\n });\n };\n };\n\n async.compose = function (/* functions... */) {\n return async.seq.apply(null, Array.prototype.reverse.call(arguments));\n };\n\n var _applyEach = function (eachfn, fns /*args...*/) {\n var go = function () {\n var that = this;\n var args = Array.prototype.slice.call(arguments);\n var callback = args.pop();\n return eachfn(fns, function (fn, cb) {\n fn.apply(that, args.concat([cb]));\n },\n callback);\n };\n if (arguments.length > 2) {\n var args = Array.prototype.slice.call(arguments, 2);\n return go.apply(this, args);\n }\n else {\n return go;\n }\n };\n async.applyEach = doParallel(_applyEach);\n async.applyEachSeries = doSeries(_applyEach);\n\n async.forever = function (fn, callback) {\n function next(err) {\n if (err) {\n if (callback) {\n return callback(err);\n }\n throw err;\n }\n fn(next);\n }\n next();\n };\n\n // Node.js\n if (typeof module !== 'undefined' && module.exports) {\n module.exports = async;\n }\n // AMD / RequireJS\n else if (typeof define !== 'undefined' && define.amd) {\n define([], function () {\n return async;\n });\n }\n // included directly via \n // \n if (hasNativeCurrentScriptAccessor) {\n script = document.currentScript;\n }\n }\n\n if (!script) {\n // Inaccuracies:\n // - If script currently being synchronously evaluated by the parser is the\n // originator of this call stack but NOT the source script of the caller/invocation\n // e.g.\n // ```html\n // \n // \n if (isNotOpera && supportsScriptReadyState) {\n for (i = eligibleScripts.length; i--; ) {\n if (eligibleScripts[i].readyState === \"interactive\") {\n script = eligibleScripts[i];\n break;\n }\n }\n }\n }\n\n if (!script) {\n // Inaccuracies:\n // - If a script is created dynamically and appended to some position\n // other than the very end of the document.\n // - If multiple scripts are created dynamically and all appended to the\n // same position within the document (and do not have their `async` attributes\n // set to `false`, at least in browsers that support async script evaluation.\n // other than the very end of the document.\n // - If any scripts are added with the `async` attribute set to `true` in a browser\n // that supports it.\n // - May get confused by `script` elements within `svg` elements\n // - If script currently being synchronously evaluated by the parser is the\n // originator of this call stack but NOT the source script of the caller/invocation\n // e.g.\n // ```html\n // \n // \n // ```\n script = eligibleScripts[eligibleScripts.length - 1] || null;\n }\n\n return script;\n}\n\n// Default stack depth to skip over when analyzing call stack frames\n_nearestExecutingScript.skipStackDepth = 1;\n\n\n\n //\n // Export the API\n //\n var currentExecutingScript = _nearestExecutingScript; // default\n currentExecutingScript.near = _nearestExecutingScript;\n currentExecutingScript.far = _farthestExecutingScript;\n currentExecutingScript.origin = _originatingExecutingScript;\n\n\n // Just return a value to define the module export.\n // This example returns an object, but the module\n // can return a function as the exported value.\n return currentExecutingScript;\n })\n);\n", "const Constants = {\n LOCAL_JID: 'local'\n};\n\nmodule.exports = Constants;\n", "var toIntIfInt = function (v) {\n return String(Number(v)) === v ? Number(v) : v;\n};\n\nvar attachProperties = function (match, location, names, rawName) {\n if (rawName && !names) {\n location[rawName] = toIntIfInt(match[1]);\n }\n else {\n for (var i = 0; i < names.length; i += 1) {\n if (match[i+1] != null) {\n location[names[i]] = toIntIfInt(match[i+1]);\n }\n }\n }\n};\n\nvar parseReg = function (obj, location, content) {\n var needsBlank = obj.name && obj.names;\n if (obj.push && !location[obj.push]) {\n location[obj.push] = [];\n }\n else if (needsBlank && !location[obj.name]) {\n location[obj.name] = {};\n }\n var keyLocation = obj.push ?\n {} : // blank object that will be pushed\n needsBlank ? location[obj.name] : location; // otherwise, named location or root\n\n attachProperties(content.match(obj.reg), keyLocation, obj.names, obj.name);\n\n if (obj.push) {\n location[obj.push].push(keyLocation);\n }\n};\n\nvar grammar = require('./grammar');\nvar validLine = RegExp.prototype.test.bind(/^([a-z])=(.*)/);\n\nexports.parse = function (sdp) {\n var session = {}\n , media = []\n , location = session; // points at where properties go under (one of the above)\n\n // parse lines we understand\n sdp.split(/(\\r\\n|\\r|\\n)/).filter(validLine).forEach(function (l) {\n var type = l[0];\n var content = l.slice(2);\n if (type === 'm') {\n media.push({rtp: [], fmtp: []});\n location = media[media.length-1]; // point at latest media line\n }\n\n for (var j = 0; j < (grammar[type] || []).length; j += 1) {\n var obj = grammar[type][j];\n if (obj.reg.test(content)) {\n return parseReg(obj, location, content);\n }\n }\n });\n\n session.media = media; // link it up\n return session;\n};\n\nvar paramReducer = function (acc, expr) {\n var s = expr.split(/=(.+)/, 2);\n if (s.length === 2) {\n acc[s[0]] = toIntIfInt(s[1]);\n }\n return acc;\n};\n\nexports.parseParams = function (str) {\n return str.split(/\\;\\s?/).reduce(paramReducer, {});\n};\n\n// For backward compatibility - alias will be removed in 3.0.0\nexports.parseFmtpConfig = exports.parseParams;\n\nexports.parsePayloads = function (str) {\n return str.split(' ').map(Number);\n};\n\nexports.parseRemoteCandidates = function (str) {\n var candidates = [];\n var parts = str.split(' ').map(toIntIfInt);\n for (var i = 0; i < parts.length; i += 3) {\n candidates.push({\n component: parts[i],\n ip: parts[i + 1],\n port: parts[i + 2]\n });\n }\n return candidates;\n};\n\nexports.parseImageAttributes = function (str) {\n return str.split(' ').map(function (item) {\n return item.substring(1, item.length-1).split(',').reduce(paramReducer, {});\n });\n};\n\nexports.parseSimulcastStreamList = function (str) {\n return str.split(';').map(function (stream) {\n return stream.split(',').map(function (format) {\n var scid, paused = false;\n\n if (format[0] !== '~') {\n scid = toIntIfInt(format);\n } else {\n scid = toIntIfInt(format.substring(1, format.length));\n paused = true;\n }\n\n return {\n scid: scid,\n paused: paused\n };\n });\n });\n};\n", "var grammar = require('./grammar');\n\n// customized util.format - discards excess arguments and can void middle ones\nvar formatRegExp = /%[sdv%]/g;\nvar format = function (formatStr) {\n var i = 1;\n var args = arguments;\n var len = args.length;\n return formatStr.replace(formatRegExp, function (x) {\n if (i >= len) {\n return x; // missing argument\n }\n var arg = args[i];\n i += 1;\n switch (x) {\n case '%%':\n return '%';\n case '%s':\n return String(arg);\n case '%d':\n return Number(arg);\n case '%v':\n return '';\n }\n });\n // NB: we discard excess arguments - they are typically undefined from makeLine\n};\n\nvar makeLine = function (type, obj, location) {\n var str = obj.format instanceof Function ?\n (obj.format(obj.push ? location : location[obj.name])) :\n obj.format;\n\n var args = [type + '=' + str];\n if (obj.names) {\n for (var i = 0; i < obj.names.length; i += 1) {\n var n = obj.names[i];\n if (obj.name) {\n args.push(location[obj.name][n]);\n }\n else { // for mLine and push attributes\n args.push(location[obj.names[i]]);\n }\n }\n }\n else {\n args.push(location[obj.name]);\n }\n return format.apply(null, args);\n};\n\n// RFC specified order\n// TODO: extend this with all the rest\nvar defaultOuterOrder = [\n 'v', 'o', 's', 'i',\n 'u', 'e', 'p', 'c',\n 'b', 't', 'r', 'z', 'a'\n];\nvar defaultInnerOrder = ['i', 'c', 'b', 'a'];\n\n\nmodule.exports = function (session, opts) {\n opts = opts || {};\n // ensure certain properties exist\n if (session.version == null) {\n session.version = 0; // 'v=0' must be there (only defined version atm)\n }\n if (session.name == null) {\n session.name = ' '; // 's= ' must be there if no meaningful name set\n }\n session.media.forEach(function (mLine) {\n if (mLine.payloads == null) {\n mLine.payloads = '';\n }\n });\n\n var outerOrder = opts.outerOrder || defaultOuterOrder;\n var innerOrder = opts.innerOrder || defaultInnerOrder;\n var sdp = [];\n\n // loop through outerOrder for matching properties on session\n outerOrder.forEach(function (type) {\n grammar[type].forEach(function (obj) {\n if (obj.name in session && session[obj.name] != null) {\n sdp.push(makeLine(type, obj, session));\n }\n else if (obj.push in session && session[obj.push] != null) {\n session[obj.push].forEach(function (el) {\n sdp.push(makeLine(type, obj, el));\n });\n }\n });\n });\n\n // then for each media line, follow the innerOrder\n session.media.forEach(function (mLine) {\n sdp.push(makeLine('m', grammar.m[0], mLine));\n\n innerOrder.forEach(function (type) {\n grammar[type].forEach(function (obj) {\n if (obj.name in mLine && mLine[obj.name] != null) {\n sdp.push(makeLine(type, obj, mLine));\n }\n else if (obj.push in mLine && mLine[obj.push] != null) {\n mLine[obj.push].forEach(function (el) {\n sdp.push(makeLine(type, obj, el));\n });\n }\n });\n });\n });\n\n return sdp.join('\\r\\n') + '\\r\\n';\n};\n", "/* Copyright @ 2016 Atlassian Pty Ltd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nvar transform = require('sdp-transform');\nvar transformUtils = require('./transform-utils');\nvar parseSsrcs = transformUtils.parseSsrcs;\nvar writeSsrcs = transformUtils.writeSsrcs;\n\n//region Constants\n\nvar DEFAULT_NUM_OF_LAYERS = 3;\n\n//endregion\n\nfunction getSsrcAttribute (mLine, ssrc, attributeName) {\n return mLine\n .ssrcs\n .filter(function(ssrcInfo) { return ssrcInfo.id === ssrc; })\n .filter(function(ssrcInfo) { return ssrcInfo.attribute === attributeName; })\n .map(function(ssrcInfo) { return ssrcInfo.value; })[0];\n}\n\n//region Ctor\n\nfunction Simulcast(options) {\n\n this.options = options ? options : {};\n\n if (!this.options.numOfLayers) {\n this.options.numOfLayers = DEFAULT_NUM_OF_LAYERS;\n }\n console.log(\"SdpSimulcast: using \" + this.options.numOfLayers + \" layers\");\n\n /**\n * An IN-ORDER list of the simulcast ssrcs\n * @type {list}\n */\n this.ssrcCache = [];\n}\n\n//endregion\n\n//region Stateless private utility functions\n\n/**\n * Returns a random integer between min (included) and max (excluded)\n * Using Math.round() gives a non-uniform distribution!\n * @returns {number}\n */\nfunction generateSSRC() {\n var min = 0, max = 0xffffffff;\n return Math.floor(Math.random() * (max - min)) + min;\n};\n\nfunction processVideo(session, action) {\n if (session == null || !Array.isArray(session.media)) {\n return;\n }\n\n session.media.forEach(function (mLine) {\n if (mLine.type === 'video') {\n action(mLine);\n }\n });\n};\n\nfunction validateDescription(desc)\n{\n return desc && desc != null\n && desc.type && desc.type != ''\n && desc.sdp && desc.sdp != '';\n}\n\nfunction explodeRemoteSimulcast(mLine) {\n\n if (!mLine || !Array.isArray(mLine.ssrcGroups)) {\n return;\n }\n\n var sources = parseSsrcs(mLine);\n var order = [];\n\n // Find the SIM group and explode its sources.\n var j = mLine.ssrcGroups.length;\n while (j--) {\n\n if (mLine.ssrcGroups[j].semantics !== 'SIM') {\n continue;\n }\n\n var simulcastSsrcs = mLine.ssrcGroups[j].ssrcs.split(' ');\n\n for (var i = 0; i < simulcastSsrcs.length; i++) {\n\n var ssrc = simulcastSsrcs[i];\n order.push(ssrc);\n\n var parts = sources[ssrc].msid.split(' ');\n sources[ssrc].msid = [parts[0], '/', i, ' ', parts[1], '/', i].join('');\n sources[ssrc].cname = [sources[ssrc].cname, '/', i].join('');\n\n // Remove all the groups that this SSRC participates in.\n mLine.ssrcGroups.forEach(function (relatedGroup) {\n if (relatedGroup.semantics === 'SIM') {\n return;\n }\n\n var relatedSsrcs = relatedGroup.ssrcs.split(' ');\n if (relatedSsrcs.indexOf(ssrc) === -1) {\n return;\n }\n\n // Nuke all the related SSRCs.\n relatedSsrcs.forEach(function (relatedSSRC) {\n sources[relatedSSRC].msid = sources[ssrc].msid;\n sources[relatedSSRC].cname = sources[ssrc].cname;\n if (relatedSSRC !== ssrc) {\n order.push(relatedSSRC);\n }\n });\n\n // Schedule the related group for nuking.\n })\n }\n\n mLine.ssrcs = writeSsrcs(sources, order);\n mLine.ssrcGroups.splice(j, 1);\n };\n}\n\nfunction implodeRemoteSimulcast(mLine) {\n\n if (!mLine || !Array.isArray(mLine.ssrcGroups)) {\n console.info('Halt: There are no SSRC groups in the remote ' +\n 'description.');\n return;\n }\n\n var sources = parseSsrcs(mLine);\n\n // Find the SIM group and nuke it.\n mLine.ssrcGroups.forEach(function (simulcastGroup) {\n if (simulcastGroup.semantics !== 'SIM') {\n return;\n }\n\n console.info(\"Imploding SIM group: \" + simulcastGroup.ssrcs);\n // Schedule the SIM group for nuking.\n simulcastGroup.nuke = true;\n\n var simulcastSsrcs = simulcastGroup.ssrcs.split(' ');\n\n // Nuke all the higher layer SSRCs.\n for (var i = 1; i < simulcastSsrcs.length; i++) {\n\n var ssrc = simulcastSsrcs[i];\n delete sources[ssrc];\n\n // Remove all the groups that this SSRC participates in.\n mLine.ssrcGroups.forEach(function (relatedGroup) {\n if (relatedGroup.semantics === 'SIM') {\n return;\n }\n\n var relatedSsrcs = relatedGroup.ssrcs.split(' ');\n if (relatedSsrcs.indexOf(ssrc) === -1) {\n return;\n }\n\n // Nuke all the related SSRCs.\n relatedSsrcs.forEach(function (relatedSSRC) {\n delete sources[relatedSSRC];\n });\n\n // Schedule the related group for nuking.\n relatedGroup.nuke = true;\n })\n }\n\n return;\n });\n\n mLine.ssrcs = writeSsrcs(sources);\n\n // Nuke all the scheduled groups.\n var i = mLine.ssrcGroups.length;\n while (i--) {\n if (mLine.ssrcGroups[i].nuke) {\n mLine.ssrcGroups.splice(i, 1);\n }\n }\n}\n\nfunction removeGoogConference(mLine) {\n if (!mLine || !Array.isArray(mLine.invalid)) {\n return;\n }\n\n var i = mLine.invalid.length;\n while (i--) {\n if (mLine.invalid[i].value == 'x-google-flag:conference') {\n mLine.invalid.splice(i, 1);\n }\n }\n}\n\nfunction assertGoogConference(mLine) {\n if (!mLine) {\n return;\n }\n\n if (!Array.isArray(mLine.invalid)) {\n mLine.invalid = [];\n }\n\n if (!mLine.invalid.some(\n function (i) { return i.value === 'x-google-flag:conference' })) {\n mLine.invalid.push({'value': 'x-google-flag:conference'});\n }\n}\n\nSimulcast.prototype.clearSsrcCache = function() {\n this.ssrcCache = [];\n}\n\n/**\n * When we start as video muted, all of the video\n * ssrcs get generated so we can include them as part\n * of the original session-accept. That means we\n * need this library to restore to those same ssrcs\n * the first time we unmute, so we need the ability to\n * force its cache\n */\nSimulcast.prototype.setSsrcCache = function(ssrcs) {\n this.ssrcCache = ssrcs;\n}\n\n//endregion\n\n//region \"Private\" functions\n\n/**\n * Given a video mLine, return a list of the video ssrcs\n * in simulcast layer order (returns a list of just\n * the primary ssrc if there are no simulcast layers)\n */\nSimulcast.prototype._parseSimLayers = function (mLine) {\n var simGroup = mLine.ssrcGroups &&\n mLine.ssrcGroups.find(function(group) { return group.semantics === \"SIM\"; });\n if (simGroup) {\n return simGroup.ssrcs\n .split(\" \")\n .map(function(ssrcStr) { return parseInt(ssrcStr) });\n } else {\n return [mLine.ssrcs[0].id];\n }\n}\n\nSimulcast.prototype._buildNewToOldSsrcMap = function (newSsrcList, oldSsrcList) {\n var ssrcMap = {};\n for (var i = 0; i < newSsrcList.length; ++i) {\n var newSsrc = newSsrcList[i];\n var oldSsrc = oldSsrcList[i] || null;\n ssrcMap[newSsrc] = oldSsrc;\n }\n return ssrcMap;\n}\n\nSimulcast.prototype._fillInSourceDataFromCache = function(mLine) {\n console.log(\"SdpSimulcast restoring from cache: \", this.ssrcCache);\n var newSimSsrcs = this._parseSimLayers(mLine);\n console.log(\"SdpSimulcast Parsed new sim ssrcs: \", newSimSsrcs);\n var newMsid = getSsrcAttribute(mLine, newSimSsrcs[0], \"msid\");\n var newCname = getSsrcAttribute(mLine, newSimSsrcs[0], \"cname\");\n var ssrcsToReplace = this._buildNewToOldSsrcMap(newSimSsrcs, this.ssrcCache);\n console.log(\"SdpSimulcast built replacement map: \", ssrcsToReplace);\n // New sdp might only have 1 layer, so not every cached ssrc will have a new one\n // to replace directly\n var ssrcsToAdd = this.ssrcCache\n .filter(function(ssrc) { return Object.values(ssrcsToReplace).indexOf(ssrc) === -1; });\n console.log(\"SdpSimulcast built ssrcs to add: \", ssrcsToAdd);\n\n // First do the replacements\n mLine.ssrcs.forEach(function(ssrc) {\n if (ssrcsToReplace[ssrc.id]) {\n ssrc.id = ssrcsToReplace[ssrc.id];\n }\n });\n // Now the adds\n ssrcsToAdd.forEach(function(ssrc) {\n mLine.ssrcs.push({\n id: ssrc,\n attribute: \"msid\",\n value: newMsid\n });\n mLine.ssrcs.push({\n id: ssrc,\n attribute: \"cname\",\n value: newCname\n });\n });\n mLine.ssrcGroups = mLine.ssrcGroups || [];\n mLine.ssrcGroups.push({\n semantics: \"SIM\",\n ssrcs: this.ssrcCache.join(\" \")\n });\n return mLine;\n}\n\nSimulcast.prototype._generateSourceData = function(mLine, primarySsrc) {\n var addAssociatedStream = function(mLine, ssrc) {\n mLine.ssrcs.push({\n id: ssrc,\n attribute: \"cname\",\n value: primarySsrcCname\n });\n mLine.ssrcs.push({\n id: ssrc,\n attribute: \"msid\",\n value: primarySsrcMsid\n });\n }\n var primarySsrcMsid = getSsrcAttribute(mLine, primarySsrc, \"msid\");\n var primarySsrcCname = getSsrcAttribute(mLine, primarySsrc, \"cname\");\n\n // In Unified-plan mode, the a=ssrc lines with the msid attribute are not present\n // in the answers that Chrome and Safari generate for an offer received from Jicofo.\n // Generate these a=ssrc lines using the msid values from the a=msid line.\n if (this.options.usesUnifiedPlan && !primarySsrcMsid) {\n primarySsrcMsid = mLine.msid;\n var primarySsrcs = mLine.ssrcs;\n primarySsrcs.forEach(ssrc => {\n mLine.ssrcs.push({\n id: ssrc.id,\n attribute: \"msid\",\n value: primarySsrcMsid\n });\n });\n }\n\n // Generate sim layers\n var simSsrcs = [];\n for (var i = 0; i < this.options.numOfLayers - 1; ++i) {\n var simSsrc = generateSSRC();\n addAssociatedStream(mLine, simSsrc);\n simSsrcs.push(simSsrc);\n }\n mLine.ssrcGroups = mLine.ssrcGroups || [];\n mLine.ssrcGroups.push({\n semantics: \"SIM\",\n ssrcs: primarySsrc + \" \" + simSsrcs.join(\" \")\n });\n return mLine;\n}\n\n\n\n// Assumptions:\n// 1) 'mLine' contains only a single primary video source\n// (i.e. it will not already have simulcast streams inserted)\n// 2) 'mLine' MAY already contain an RTX stream for its video source\n// 3) 'mLine' is in sendrecv or sendonly state\n// Guarantees:\n// 1) return mLine will contain 2 additional simulcast layers\n// generated\n// 2) if the base video ssrc in mLine has been seen before,\n// then the same generated simulcast streams from before will\n// be used again\n// 3) if rtx is enabled for the mLine, all generated simulcast\n// streams will have rtx streams generated as well\n// 4) if rtx has been generated for a src before, we will generate\n// the same rtx stream again\nSimulcast.prototype._restoreSimulcast = function(mLine) {\n // First, find the primary video source in the given\n // mLine and see if we've seen it before.\n var primarySsrc;\n var numSsrcs = mLine.ssrcs && mLine.ssrcs\n .map(function(ssrcInfo) { return ssrcInfo.id; })\n .filter(function(ssrc, index, array) {\n return array.indexOf(ssrc) === index;\n })\n .length || 0;\n var numGroups = (mLine.ssrcGroups && mLine.ssrcGroups.length) || 0;\n\n if (numSsrcs === 0 || numSsrcs > 2) {\n // Unsupported scenario\n return mLine;\n }\n if (numSsrcs == 2 && numGroups === 0) {\n // Unsupported scenario\n return mLine;\n }\n\n if (numSsrcs === 1) {\n primarySsrc = mLine.ssrcs[0].id;\n } else {\n // There must be an FID group, so parse\n // that and pull the primary ssrc from there\n var fidGroup = mLine.ssrcGroups.filter(function(group) { return group.semantics === \"FID\"; })[0];\n if (fidGroup) {\n primarySsrc = parseInt(fidGroup.ssrcs.split(\" \")[0]);\n } else {\n // Unsupported scenario\n return mLine;\n }\n }\n console.log(\"SdpSimulcast: current ssrc cache: \", this.ssrcCache);\n console.log(\"SdpSimulcast: parsed primary ssrc \" + primarySsrc);\n\n var seenPrimarySsrc = this.ssrcCache.indexOf(primarySsrc) !== -1;\n\n if (seenPrimarySsrc) {\n console.log(\"SdpSimulcast: Have seen primary ssrc before, \" +\n \"filling in data from cache\");\n mLine = this._fillInSourceDataFromCache(mLine);\n } else {\n console.log(\"SdpSimulcast: Have not seen primary ssrc before, \" +\n \"generating source data\");\n mLine = this._generateSourceData(mLine, primarySsrc);\n }\n // Now update the cache to match whatever we've just put into this sdp\n this.ssrcCache = this._parseSimLayers(mLine);\n return mLine;\n}\n\n//endregion\n\n//region \"Public\" functions\n\n/**\n *\n * @param desc\n * @returns {RTCSessionDescription}\n */\nSimulcast.prototype.mungeRemoteDescription = function (desc) {\n\n if (!validateDescription(desc)) {\n return desc;\n }\n\n var session = transform.parse(desc.sdp);\n\n var self = this;\n processVideo(session, function (mLine) {\n\n // Handle simulcast reception.\n if (self.options.explodeRemoteSimulcast) {\n explodeRemoteSimulcast(mLine);\n } else {\n implodeRemoteSimulcast(mLine);\n }\n\n // Make sure that we ALWAYS add the conference flag to the remote\n // description: That flag is deprecated but, as of this writing\n // (09/2019), it's still used in jitsi-meet to enable legacy simulcast\n // when screen-sharing (https://cs.chromium.org/chromium/src/third_party/webrtc/media/base/media_channel.h?rcl=f2773b54647633d5725fa25dea883f99dd1b400c&l=838).\n //\n // We've observed the following chain of events that almost always\n // results in connectivity issues at the receiver:\n //\n // 1. The user joins a call with startVideoMuted=true, so there's no\n // jitsi track created.\n // 2. The user enables screen-sharing. At this point we do a\n // renegotiation (which starts with an sRD); the ssrcCache is empty,\n // so the conference flag is not added to the remote description SDP.\n // 3. The next step of the re-negotiation is to set the answer, so\n // mungeLocalDescription is called, and because now we have a track\n // due to the user enabling screen-sharing, it enables simulcast.\n // 4. sLD is called with simulcast ssrcs, but the sRD call of step 2\n // didn't add the conference flag in the SDP, so the screen-sharing\n // is without simulcast.\n // 5. Any subsequent re-negotiation (for example, due to a participant\n // joining/leaving the call) will enable simulcast and this switch\n // almost always results in a broken stream at the receiver.\n if (!self.options.usesUnifiedPlan) {\n assertGoogConference(mLine);\n }\n });\n\n return new RTCSessionDescription({\n type: desc.type,\n sdp: transform.write(session)\n });\n};\n\n/**\n *\n * NOTE this method should be called only if simulcast is supported by\n * the current browser, otherwise local SDP should not be munged.\n * @param desc\n * @returns {RTCSessionDescription}\n */\nSimulcast.prototype.mungeLocalDescription = function (desc) {\n\n if (!validateDescription(desc)) {\n return desc;\n }\n\n var session = transform.parse(desc.sdp);\n\n var self = this;\n processVideo(session, function (mLine) {\n if (mLine.direction == 'recvonly' || mLine.direction == 'inactive')\n {\n return;\n }\n self._restoreSimulcast(mLine);\n });\n\n return new RTCSessionDescription({\n type: desc.type,\n sdp: transform.write(session)\n });\n};\n\n//endregion\n\nmodule.exports = Simulcast;\n", "/* Copyright @ 2015 Atlassian Pty Ltd\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * FIXME\n * @param sources FIXME\n * @param order An array of SSRCs which will be used to order the entries in\n * the returned array. Sources whose SSRC appears in 'order' will be added first,\n * in the specified order, and all other sources will be added afterwards (in\n * no specific order).\n * @returns {Array} FIXME\n */\nexports.writeSsrcs = function(sources, order) {\n var ssrcs = [];\n\n // expand sources to ssrcs\n if (typeof sources !== 'undefined' &&\n Object.keys(sources).length !== 0) {\n\n if (!Array.isArray(order)) {\n order = []\n }\n\n // Add the sources that appear in 'order' first.\n for (var i = 0; i < order.length; i++) {\n var ssrc = order[i];\n var source = sources[ssrc];\n Object.keys(source).forEach(function (attribute) {\n ssrcs.push({\n id: ssrc,\n attribute: attribute,\n value: source[attribute]\n });\n });\n }\n\n // Now add the rest of the sources.\n Object.keys(sources).forEach(function (ssrc) {\n ssrc = parseInt(ssrc); // Object.keys() returns string\n if (order.indexOf(ssrc) >= 0) {\n // Already added.\n return;\n }\n\n var source = sources[ssrc];\n Object.keys(source).forEach(function (attribute) {\n ssrcs.push({\n id: ssrc,\n attribute: attribute,\n value: source[attribute]\n });\n });\n });\n }\n\n return ssrcs;\n};\n\nexports.parseSsrcs = function (mLine) {\n var sources = {};\n // group sources attributes by ssrc.\n if (typeof mLine.ssrcs !== 'undefined' && Array.isArray(mLine.ssrcs)) {\n mLine.ssrcs.forEach(function (ssrc) {\n if (!sources[ssrc.id])\n sources[ssrc.id] = {};\n sources[ssrc.id][ssrc.attribute] = ssrc.value;\n });\n }\n return sources;\n};\n\n", "(function (global, factory) {\n\ttypeof exports === 'object' && typeof module !== 'undefined' ? factory(require('strophe.js')) :\n\ttypeof define === 'function' && define.amd ? define(['strophe.js'], factory) :\n\t(factory(global.window));\n}(this, (function (strophe_js) { 'use strict';\n\nstrophe_js.Strophe.addConnectionPlugin('disco',\n{\n _connection: null,\n _identities : [],\n _features : [],\n _items : [],\n /** Function: init\n * Plugin init\n *\n * Parameters:\n * (Strophe.Connection) conn - Strophe connection\n */\n init: function(conn)\n {\n this._connection = conn;\n this._identities = [];\n this._features = [];\n this._items = [];\n // disco info\n conn.addHandler(this._onDiscoInfo.bind(this), strophe_js.Strophe.NS.DISCO_INFO, 'iq', 'get', null, null);\n // disco items\n conn.addHandler(this._onDiscoItems.bind(this), strophe_js.Strophe.NS.DISCO_ITEMS, 'iq', 'get', null, null);\n },\n /** Function: addIdentity\n * See http://xmpp.org/registrar/disco-categories.html\n * Parameters:\n * (String) category - category of identity (like client, automation, etc ...)\n * (String) type - type of identity (like pc, web, bot , etc ...)\n * (String) name - name of identity in natural language\n * (String) lang - lang of name parameter\n *\n * Returns:\n * Boolean\n */\n addIdentity: function(category, type, name, lang)\n {\n for (var i=0; i 0;\n\n\t\t\treturn this._originalOnStreamFeaturesAfterSASL.apply(this._c, arguments);\n\t\t},\n\n\t\tstatusChanged: function (status) {\n\t\t\tif (!this.getResumeToken()\n\t\t\t\t&& (status === strophe_js.Strophe.Status.CONNECTED || status === strophe_js.Strophe.Status.DISCONNECTED)) {\n\t\t\t\tthis.logging && strophe_js.Strophe.debug('SM reset state');\n\n\t\t\t\tthis._serverProcesssedStanzasCounter = 0;\n\t\t\t\tthis._clientProcessedStanzasCounter = 0;\n\n\t\t\t\tthis._clientSentStanzasCounter = 0;\n\n\t\t\t\tthis._isStreamManagementEnabled = false;\n\t\t\t\tthis._requestResponseIntervalCount = 0;\n\n\t\t\t\t// FIXME not described in JSDocs\n\t\t\t\tthis._resuming = false;\n\n\t\t\t\tif (status === strophe_js.Strophe.Status.DISCONNECTED) {\n\t\t\t\t\tthis._isSupported = false;\n\t\t\t\t}\n\n\t\t\t\tthis._unacknowledgedStanzas = [];\n\n\t\t\t\tif (this._requestHandler) {\n\t\t\t\t\tthis._c.deleteHandler(this._requestHandler);\n\t\t\t\t}\n\n\t\t\t\tif (this._incomingHandler) {\n\t\t\t\t\tthis._c.deleteHandler(this._incomingHandler);\n\t\t\t\t}\n\n\t\t\t\tthis._requestHandler = this._c.addHandler(this._handleServerRequestHandler.bind(this), this._NS, 'r');\n\t\t\t\tthis._ackHandler = this._c.addHandler(this._handleServerAck.bind(this), this._NS, 'a');\n\t\t\t\tthis._incomingHandler = this._c.addHandler(this._incomingStanzaHandler.bind(this));\n\n\t\t\t\t// FIXME handler instances stored, but never used\n\t\t\t\tthis._enabledHandler = this._c._addSysHandler(this._handleEnabled.bind(this), this._NS, 'enabled');\n\t\t\t\tthis._resumeFailedHandler = this._c._addSysHandler(this._handleResumeFailed.bind(this), this._NS, 'failed');\n\t\t\t\tthis._resumedHandler = this._c._addSysHandler(this._handleResumed.bind(this), this._NS,'resumed');\n\n\t\t\t} else if (status === strophe_js.Strophe.Status.BINDREQUIRED) {\n\t\t\t\tthis._c.jid = this._storedJid;\n\n\t\t\t\t// Restore Strophe handlers\n\t\t\t\tfor (const property in this._resumeState) {\n\t\t\t\t\tthis._c[property] = this._resumeState[property];\n\t\t\t\t}\n\n\t\t\t\t// FIXME check conditions if there's session ID and if enabled\n\t\t\t\tthis._c.send(strophe_js.$build('resume', {\n\t\t\t\t\txmlns: this._NS,\n\t\t\t\t\th: this._clientProcessedStanzasCounter,\n\t\t\t\t\tprevid: this._resumeToken\n\t\t\t\t}));\n\t\t\t\tthis._c.flush();\n\t\t\t} else if (status === strophe_js.Strophe.Status.ERROR) {\n\t\t\t\tthis.logging && strophe_js.Strophe.debug('SM cleared resume token on error');\n\t\t\t\tthis._resumeToken = undefined;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t* This method overrides the send method implemented by Strophe.Connection\n\t\t* to count outgoing stanzas\n\t\t*\n\t\t* @method Send\n\t\t* @public\n\t\t*/\n\t\txmlOutput: function(elem) {\n\t\t\tif (strophe_js.Strophe.isTagEqual(elem, 'iq') ||\n\t\t\t\tstrophe_js.Strophe.isTagEqual(elem, 'presence') ||\n\t\t\t\tstrophe_js.Strophe.isTagEqual(elem, 'message')) {\n\t\t\t\tthis._increaseSentStanzasCounter(elem);\n\t\t\t}\n\n\t\t\treturn this._originalXMLOutput.call(this._c, elem);\n\t\t},\n\n\t\t_handleEnabled: function(elem) {\n\t\t\tthis._isStreamManagementEnabled = true;\n\t\t\t// FIXME fail if requested, but not enabled\n\t\t\tthis._resumeToken = elem.getAttribute('resume') === 'true' && elem.getAttribute('id');\n\n\t\t\tthis._c.resume();\n\n\t\t\treturn true;\n\t\t},\n\n\t\t_handleResumeFailed: function(elem) {\n\t\t\tconst error = elem && elem.firstElementChild && elem.firstElementChild.tagName;\n\n\t\t\tthis._c._changeConnectStatus(strophe_js.Strophe.Status.ERROR, error, elem);\n\t\t\tthis._c._doDisconnect();\n\n\t\t\treturn true;\n\t\t},\n\n\t\t_handleResumed: function(elem) {\n\t\t\t// FIXME check if in the correct state\n\t\t\tvar handledCount = parseInt(elem.getAttribute('h'));\n\t\t\tthis._handleAcknowledgedStanzas(handledCount, this._serverProcesssedStanzasCounter);\n\n\t\t\tthis._resuming = false;\n\t\t\tthis._c.do_bind = false; // No need to bind our resource anymore\n\t\t\tthis._c.authenticated = true;\n\t\t\tthis._c.restored = true;\n\n\t\t\tif (this._unacknowledgedStanzas.length > 0) {\n\t\t\t\tthis.logging && strophe_js.Strophe.debug('SM Sending unacknowledged stanzas', this._unacknowledgedStanzas);\n\t\t\t\tfor(const stanza of this._unacknowledgedStanzas) {\n\t\t\t\t\tthis._c.send(stanza);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.logging && strophe_js.Strophe.debug('SM No unacknowledged stanzas', this._unacknowledgedStanzas);\n\t\t\t}\n\n\t\t\tthis._c._changeConnectStatus(strophe_js.Strophe.Status.CONNECTED, null);\n\n\t\t\treturn true;\n\t\t},\n\n\t\t_incomingStanzaHandler: function(elem) {\n\t\t\tif (strophe_js.Strophe.isTagEqual(elem, 'iq') || strophe_js.Strophe.isTagEqual(elem, 'presence') || strophe_js.Strophe.isTagEqual(elem, 'message')) {\n\t\t\t\tthis._increaseReceivedStanzasCounter();\n\n\t\t\t\tif (this.autoSendCountOnEveryIncomingStanza) {\n\t\t\t\t\tthis._answerProcessedStanzas();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true;\n\t\t},\n\n\t\t_handleAcknowledgedStanzas: function(reportedHandledCount, lastKnownHandledCount) {\n\t\t\tvar delta = reportedHandledCount - lastKnownHandledCount;\n\n\t\t\tif (delta < 0) {\n\t\t\t\tthis._throwError('New reported stanza count lower than previous. New: ' + reportedHandledCount + ' - Previous: ' + lastKnownHandledCount);\n\t\t\t}\n\n\t\t\tif (delta > this._unacknowledgedStanzas.length) {\n\t\t\t\tthis._throwError('Higher reported acknowledge count than unacknowledged stanzas. Reported Acknowledge Count: ' + delta + ' - Unacknowledge Stanza Count: ' + this._unacknowledgedStanzas.length + ' - New: ' + reportedHandledCount + ' - Previous: ' + lastKnownHandledCount);\n\t\t\t}\n\n\t\t\tfor(var i = 0; i < delta; i++) {\n\t\t\t\tvar stanza = this._unacknowledgedStanzas.shift();\n\t\t\t\tfor (var j = 0; j < this._acknowledgedStanzaListeners.length; j++) {\n\t\t\t\t\tthis._acknowledgedStanzaListeners[j](stanza);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (this.logging && this._unacknowledgedStanzas.length > 0) {\n\t\t\t\tstrophe_js.Strophe.warn('SM Unacknowledged stanzas', this._unacknowledgedStanzas);\n\t\t\t}\n\n\t\t\tthis._serverProcesssedStanzasCounter = reportedHandledCount;\n\n\t\t\tif (this.requestResponseInterval > 0) {\n\t\t\t\tthis._requestResponseIntervalCount = 0;\n\t\t\t}\n\t\t},\n\n\t\t_handleServerRequestHandler: function() {\n\t\t\tthis._answerProcessedStanzas();\n\n\t\t\treturn true;\n\t\t},\n\n\t\t_handleServerAck: function(elem){\n\t\t\tvar handledCount = parseInt(elem.getAttribute('h'));\n\t\t\tthis._handleAcknowledgedStanzas(handledCount, this._serverProcesssedStanzasCounter);\n\n\t\t\treturn true;\n\t\t},\n\n\t\t_answerProcessedStanzas: function() {\n\t\t\tif (this._isStreamManagementEnabled) {\n\t\t\t\tthis._c.send(strophe_js.$build('a', { xmlns: this._NS, h: this._clientProcessedStanzasCounter }));\n\t\t\t}\n\t\t},\n\n\t\t_increaseSentStanzasCounter: function(elem) {\n\t\t\tif (this._isStreamManagementEnabled) {\n\t\t\t\tif (this._unacknowledgedStanzas.indexOf(elem) !== -1) {\n\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis._unacknowledgedStanzas.push(elem);\n\t\t\t\tthis._clientSentStanzasCounter++;\n\n\t\t\t\tif (this.requestResponseInterval > 0) {\n\t\t\t\t\tthis._requestResponseIntervalCount++;\n\n\t\t\t\t\tif (this._requestResponseIntervalCount === this.requestResponseInterval) {\n\t\t\t\t\t\t// FIXME Can not call send from onIdle.\n\t\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\t\tthis.requestAcknowledgement();\n\t\t\t\t\t\t}, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t_increaseReceivedStanzasCounter: function() {\n\t\t\tif (this._isStreamManagementEnabled) {\n\t\t\t\tthis._clientProcessedStanzasCounter++;\n\t\t\t}\n\t\t},\n\n\t\t_throwError: function(msg) {\n\t\t\tstrophe_js.Strophe.error(msg);\n\t\t\tthrow new Error(msg);\n\t\t}\n\n\t});\n\n})));\n//# sourceMappingURL=strophe.stream-management.js.map\n", "var scope = (typeof global !== \"undefined\" && global) ||\n (typeof self !== \"undefined\" && self) ||\n window;\nvar apply = Function.prototype.apply;\n\n// DOM APIs, for completeness\n\nexports.setTimeout = function() {\n return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout);\n};\nexports.setInterval = function() {\n return new Timeout(apply.call(setInterval, scope, arguments), clearInterval);\n};\nexports.clearTimeout =\nexports.clearInterval = function(timeout) {\n if (timeout) {\n timeout.close();\n }\n};\n\nfunction Timeout(id, clearFn) {\n this._id = id;\n this._clearFn = clearFn;\n}\nTimeout.prototype.unref = Timeout.prototype.ref = function() {};\nTimeout.prototype.close = function() {\n this._clearFn.call(scope, this._id);\n};\n\n// Does not start the time, just sets up the members needed.\nexports.enroll = function(item, msecs) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = msecs;\n};\n\nexports.unenroll = function(item) {\n clearTimeout(item._idleTimeoutId);\n item._idleTimeout = -1;\n};\n\nexports._unrefActive = exports.active = function(item) {\n clearTimeout(item._idleTimeoutId);\n\n var msecs = item._idleTimeout;\n if (msecs >= 0) {\n item._idleTimeoutId = setTimeout(function onTimeout() {\n if (item._onTimeout)\n item._onTimeout();\n }, msecs);\n }\n};\n\n// setimmediate attaches itself to the global object\nrequire(\"setimmediate\");\n// On some exotic environments, it's not clear which object `setimmediate` was\n// able to install onto. Search each possibility in the same order as the\n// `setimmediate` library.\nexports.setImmediate = (typeof self !== \"undefined\" && self.setImmediate) ||\n (typeof global !== \"undefined\" && global.setImmediate) ||\n (this && this.setImmediate);\nexports.clearImmediate = (typeof self !== \"undefined\" && self.clearImmediate) ||\n (typeof global !== \"undefined\" && global.clearImmediate) ||\n (this && this.clearImmediate);\n", "(function (global, undefined) {\n \"use strict\";\n\n if (global.setImmediate) {\n return;\n }\n\n var nextHandle = 1; // Spec says greater than zero\n var tasksByHandle = {};\n var currentlyRunningATask = false;\n var doc = global.document;\n var registerImmediate;\n\n function setImmediate(callback) {\n // Callback can either be a function or a string\n if (typeof callback !== \"function\") {\n callback = new Function(\"\" + callback);\n }\n // Copy function arguments\n var args = new Array(arguments.length - 1);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i + 1];\n }\n // Store and register the task\n var task = { callback: callback, args: args };\n tasksByHandle[nextHandle] = task;\n registerImmediate(nextHandle);\n return nextHandle++;\n }\n\n function clearImmediate(handle) {\n delete tasksByHandle[handle];\n }\n\n function run(task) {\n var callback = task.callback;\n var args = task.args;\n switch (args.length) {\n case 0:\n callback();\n break;\n case 1:\n callback(args[0]);\n break;\n case 2:\n callback(args[0], args[1]);\n break;\n case 3:\n callback(args[0], args[1], args[2]);\n break;\n default:\n callback.apply(undefined, args);\n break;\n }\n }\n\n function runIfPresent(handle) {\n // From the spec: \"Wait until any invocations of this algorithm started before this one have completed.\"\n // So if we're currently running a task, we'll need to delay this invocation.\n if (currentlyRunningATask) {\n // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a\n // \"too much recursion\" error.\n setTimeout(runIfPresent, 0, handle);\n } else {\n var task = tasksByHandle[handle];\n if (task) {\n currentlyRunningATask = true;\n try {\n run(task);\n } finally {\n clearImmediate(handle);\n currentlyRunningATask = false;\n }\n }\n }\n }\n\n function installNextTickImplementation() {\n registerImmediate = function(handle) {\n process.nextTick(function () { runIfPresent(handle); });\n };\n }\n\n function canUsePostMessage() {\n // The test against `importScripts` prevents this implementation from being installed inside a web worker,\n // where `global.postMessage` means something completely different and can't be used for this purpose.\n if (global.postMessage && !global.importScripts) {\n var postMessageIsAsynchronous = true;\n var oldOnMessage = global.onmessage;\n global.onmessage = function() {\n postMessageIsAsynchronous = false;\n };\n global.postMessage(\"\", \"*\");\n global.onmessage = oldOnMessage;\n return postMessageIsAsynchronous;\n }\n }\n\n function installPostMessageImplementation() {\n // Installs an event handler on `global` for the `message` event: see\n // * https://developer.mozilla.org/en/DOM/window.postMessage\n // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages\n\n var messagePrefix = \"setImmediate$\" + Math.random() + \"$\";\n var onGlobalMessage = function(event) {\n if (event.source === global &&\n typeof event.data === \"string\" &&\n event.data.indexOf(messagePrefix) === 0) {\n runIfPresent(+event.data.slice(messagePrefix.length));\n }\n };\n\n if (global.addEventListener) {\n global.addEventListener(\"message\", onGlobalMessage, false);\n } else {\n global.attachEvent(\"onmessage\", onGlobalMessage);\n }\n\n registerImmediate = function(handle) {\n global.postMessage(messagePrefix + handle, \"*\");\n };\n }\n\n function installMessageChannelImplementation() {\n var channel = new MessageChannel();\n channel.port1.onmessage = function(event) {\n var handle = event.data;\n runIfPresent(handle);\n };\n\n registerImmediate = function(handle) {\n channel.port2.postMessage(handle);\n };\n }\n\n function installReadyStateChangeImplementation() {\n var html = doc.documentElement;\n registerImmediate = function(handle) {\n // Create a