{ "version": 3, "sources": [ "webpack://JitsiMeetExternalAPI/webpack/universalModuleDefinition", "webpack://JitsiMeetExternalAPI/webpack/bootstrap", "webpack://JitsiMeetExternalAPI/./modules/API/external/functions.js", "webpack://JitsiMeetExternalAPI/./node_modules/events/events.js", "webpack://JitsiMeetExternalAPI/./node_modules/jitsi-meet-logger/lib/Logger.js", "webpack://JitsiMeetExternalAPI/./node_modules/@hapi/bourne/lib/index.js", "webpack://JitsiMeetExternalAPI/./node_modules/clipboard-copy/index.js", "webpack://JitsiMeetExternalAPI/./node_modules/@jitsi/js-utils/transport/postis.js", "webpack://JitsiMeetExternalAPI/./node_modules/jitsi-meet-logger/lib/index.js", "webpack://JitsiMeetExternalAPI/./modules/API/external/index.js", "webpack://JitsiMeetExternalAPI/./node_modules/jitsi-meet-logger/lib/LogCollector.js", "webpack://JitsiMeetExternalAPI/./node_modules/@jitsi/js-utils/jitsi-local-storage/index.js", "webpack://JitsiMeetExternalAPI/./react/features/base/util/parseURLParams.js", "webpack://JitsiMeetExternalAPI/./react/features/base/util/helpers.js", "webpack://JitsiMeetExternalAPI/./react/features/base/util/uri.js", "webpack://JitsiMeetExternalAPI/./node_modules/@jitsi/js-utils/transport/PostMessageTransportBackend.js", "webpack://JitsiMeetExternalAPI/./node_modules/@jitsi/js-utils/transport/Transport.js", "webpack://JitsiMeetExternalAPI/./node_modules/@jitsi/js-utils/transport/constants.js", "webpack://JitsiMeetExternalAPI/./modules/API/constants.js", "webpack://JitsiMeetExternalAPI/./modules/transport/index.js", "webpack://JitsiMeetExternalAPI/./modules/API/external/external_api.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", "logger", "Logger", "getLogger", "__filename", "getAvailableDevices", "transport", "sendRequest", "type", "catch", "e", "error", "getCurrentDevices", "isDeviceChangeAvailable", "deviceType", "isDeviceListAvailable", "isMultipleAudioInputSupported", "setAudioInputDevice", "label", "id", "_setDevice", "kind", "setAudioOutputDevice", "device", "setVideoInputDevice", "ReflectOwnKeys", "R", "Reflect", "ReflectApply", "apply", "target", "receiver", "args", "Function", "ownKeys", "getOwnPropertySymbols", "getOwnPropertyNames", "concat", "NumberIsNaN", "Number", "isNaN", "EventEmitter", "init", "this", "_events", "undefined", "_eventsCount", "_maxListeners", "defaultMaxListeners", "checkListener", "listener", "TypeError", "_getMaxListeners", "that", "_addListener", "prepend", "events", "existing", "warning", "newListener", "emit", "unshift", "push", "length", "warned", "w", "Error", "String", "emitter", "count", "console", "warn", "onceWrapper", "fired", "removeListener", "wrapFn", "arguments", "_onceWrap", "state", "wrapped", "_listeners", "unwrap", "evlistener", "arr", "ret", "Array", "unwrapListeners", "arrayClone", "listenerCount", "copy", "set", "arg", "RangeError", "getPrototypeOf", "setMaxListeners", "getMaxListeners", "doError", "er", "err", "message", "context", "handler", "len", "listeners", "addListener", "on", "prependListener", "once", "prependOnceListener", "list", "position", "originalListener", "shift", "index", "pop", "spliceOne", "off", "removeAllListeners", "keys", "rawListeners", "eventNames", "levels", "consoleTransport", "globalTransports", "addGlobalTransport", "indexOf", "removeGlobalTransport", "transportIdx", "splice", "globalOptions", "getCallerInfo", "callerInfo", "methodName", "fileLocation", "line", "column", "stack", "split", "match", "substr", "log", "level", "slice", "options", "disableCallerInfo", "transports", "logPrefixes", "Date", "toISOString", "fullLogParts", "methods", "setGlobalOptions", "setLevel", "TRACE", "DEBUG", "INFO", "LOG", "WARN", "ERROR", "internals", "parse", "text", "firstOptions", "reviver", "obj", "JSON", "protoAction", "scan", "next", "nodes", "node", "SyntaxError", "__proto__", "safeParse", "ignoreError", "makeError", "DOMException", "async", "navigator", "clipboard", "writeText", "copyClipboardApi", "span", "document", "createElement", "textContent", "style", "whiteSpace", "webkitUserSelect", "userSelect", "body", "appendChild", "selection", "getSelection", "range", "createRange", "removeAllRanges", "selectNode", "addRange", "success", "execCommand", "removeChild", "copyExecCommand", "err2", "readynessCheck", "scope", "targetWindow", "windowForEventListening", "allowedOrigin", "sendBuffer", "listenBuffer", "ready", "event", "data", "origin", "postis", "listenersForMethod", "method", "params", "addEventListener", "listen", "callback", "listenBufferForMethod", "j", "send", "opts", "postMessage", "stringify", "setTimeout", "destroy", "clearInterval", "removeEventListener", "readyCheckID", "Math", "random", "setInterval", "LogCollector", "idLoggers", "loggers", "curLevel", "setLogLevelById", "setLogLevel", "require", "default", "logStorage", "stringifyObjects", "storeInterval", "maxEntryLength", "forEach", "logLevel", "_log", "storeLogsIntervalID", "queue", "totalLen", "outputCache", "someObject", "formatLogMessage", "msg", "timestamp", "prevMessage", "prevMessageText", "_flush", "start", "_reschedulePublishInterval", "clearTimeout", "flush", "force", "reschedule", "isReady", "cachedQueue", "storeLogs", "stop", "DummyLocalStorage", "clear", "_storage", "getItem", "keyName", "setItem", "keyValue", "removeItem", "serialize", "JitsiLocalStorage", "constructor", "super", "localStorage", "_localStorageDisabled", "ignore", "isLocalStorageDisabled", "dontEmitChangedEvent", "localStorageContent", "jitsiLocalStorage", "blacklist", "parseURLParams", "url", "dontParse", "source", "paramStr", "search", "hash", "paramParts", "firstParam", "startsWith", "part", "param", "some", "k", "includes", "decoded", "decodeURIComponent", "replace", "Bourne", "onerror", "reportError", "_fixURIStringScheme", "uri", "regex", "RegExp", "exec", "protocol", "toLowerCase", "substring", "lastIndex", "_objectToURLParamsArray", "encodeURIComponent", "parseStandardURIString", "str", "toString", "_standardURIToString", "pathname", "authority", "userinfoEndIndex", "host", "portBeginIndex", "lastIndexOf", "port", "hostname", "hashBeginIndex", "thiz", "urlObjectToString", "tmp", "serverURL", "room", "URL", "scheme", "endsWith", "domain", "contextRoot", "roomName", "jwt", "urlPrefix", "urlParamsArray", "urlParamsString", "join", "DEFAULT_POSTIS_OPTIONS", "opener", "parent", "PostMessageTransportBackend", "postisOptions", "Postis", "_receiveCallback", "dispose", "setReceiveCallback", "Transport", "backend", "Map", "_requestID", "_responseHandlers", "_unprocessedMessages", "Set", "setBackend", "_disposeBackend", "_backend", "_onMessageReceived", "delete", "result", "eventName", "listenersForEvent", "isProcessed", "size", "add", "sendEvent", "request", "Promise", "reject", "resolve", "API_ID", "location", "jitsi_meet_external_api_id", "JitsiMeetJS", "app", "setExternalTransportBackend", "externalTransportBackend", "ALWAYS_ON_TOP_FILENAMES", "commands", "avatarUrl", "cancelPrivateChat", "displayName", "e2eeKey", "email", "toggleLobby", "hangup", "initiatePrivateChat", "kickParticipant", "muteEveryone", "overwriteConfig", "password", "pinParticipant", "resizeLargeVideo", "sendChatMessage", "sendEndpointTextMessage", "sendTones", "setFollowMe", "setLargeVideoParticipant", "setParticipantVolume", "setTileView", "setVideoQuality", "startRecording", "startShareVideo", "stopRecording", "stopShareVideo", "subject", "submitFeedback", "toggleAudio", "toggleCamera", "toggleCameraMirror", "toggleChat", "toggleFilmStrip", "toggleRaiseHand", "toggleShareAudio", "toggleShareScreen", "toggleTileView", "toggleVirtualBackgroundDialog", "toggleVideo", "changeParticipantNumber", "APIInstance", "number", "_numberOfParticipants", "generateURL", "parseSizeParam", "parsedValue", "JitsiMeetExternalAPI", "width", "height", "parentNode", "configOverwrite", "interfaceConfigOverwrite", "onload", "invitees", "devices", "userInfo", "parseArguments", "_parentNode", "_url", "appData", "_createIFrame", "_transport", "_frame", "contentWindow", "isArray", "invite", "_tmpE2EEKey", "_isLargeVideoVisible", "_participants", "_myUserID", "_onStageParticipant", "_setupListeners", "frameName", "allow", "src", "_setSize", "setAttribute", "border", "_getAlwaysOnTopResources", "iframeWindow", "iframeDocument", "baseURL", "base", "querySelector", "href", "map", "filename", "_getFormattedDisplayName", "participantId", "formattedDisplayName", "_getOnStageParticipant", "_getLargeVideo", "iframe", "getIFrame", "getElementById", "_getParticipantVideo", "parsedHeight", "parsedWidth", "_height", "_width", "userID", "executeCommand", "avatarURL", "user", "displayname", "isVisible", "_videoQuality", "videoQuality", "addEventListeners", "captureLargeVideoScreenshot", "executeCommands", "commandList", "getContentSharingParticipants", "getCustomAvatarBackgrounds", "getLivestreamUrl", "getParticipantsInfo", "participantIds", "participantsInfo", "values", "participant", "idx", "getVideoQuality", "isAudioAvailable", "isAudioMuted", "isSharingScreen", "getAvatarURL", "getDisplayName", "getEmail", "getNumberOfParticipants", "isVideoAvailable", "isVideoMuted", "removeEventListeners", "eventList", "sendProxyConnectionEvent", "deviceId" ], "mappings": "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", "file": "external_api.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[\"JitsiMeetExternalAPI\"] = factory();\n\telse\n\t\troot[\"JitsiMeetExternalAPI\"] = 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 = \"/libs/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 7);\n", "// @flow\n\nimport Logger from 'jitsi-meet-logger';\n\nconst logger = Logger.getLogger(__filename);\n\n/**\n * Returns Promise that resolves with result an list of available devices.\n *\n * @param {Transport} transport - The @code{Transport} instance responsible for\n * the external communication.\n * @returns {Promise}\n */\nexport function getAvailableDevices(transport: Object) {\n return transport.sendRequest({\n type: 'devices',\n name: 'getAvailableDevices'\n }).catch(e => {\n logger.error(e);\n\n return {};\n });\n}\n\n/**\n * Returns Promise that resolves with current selected devices.\n *\n * @param {Transport} transport - The @code{Transport} instance responsible for\n * the external communication.\n * @returns {Promise}\n */\nexport function getCurrentDevices(transport: Object) {\n return transport.sendRequest({\n type: 'devices',\n name: 'getCurrentDevices'\n }).catch(e => {\n logger.error(e);\n\n return {};\n });\n}\n\n/**\n * Returns Promise that resolves with true if the device change is available\n * and with false if not.\n *\n * @param {Transport} transport - The @code{Transport} instance responsible for\n * the external communication.\n * @param {string} [deviceType] - Values - 'output', 'input' or undefined.\n * Default - 'input'.\n * @returns {Promise}\n */\nexport function isDeviceChangeAvailable(transport: Object, deviceType: string) {\n return transport.sendRequest({\n deviceType,\n type: 'devices',\n name: 'isDeviceChangeAvailable'\n });\n}\n\n/**\n * Returns Promise that resolves with true if the device list is available\n * and with false if not.\n *\n * @param {Transport} transport - The @code{Transport} instance responsible for\n * the external communication.\n * @returns {Promise}\n */\nexport function isDeviceListAvailable(transport: Object) {\n return transport.sendRequest({\n type: 'devices',\n name: 'isDeviceListAvailable'\n });\n}\n\n/**\n * Returns Promise that resolves with true if multiple audio input is supported\n * and with false if not.\n *\n * @param {Transport} transport - The @code{Transport} instance responsible for\n * the external communication.\n * @returns {Promise}\n */\nexport function isMultipleAudioInputSupported(transport: Object) {\n return transport.sendRequest({\n type: 'devices',\n name: 'isMultipleAudioInputSupported'\n });\n}\n\n/**\n * Sets the audio input device to the one with the label or id that is passed.\n *\n * @param {Transport} transport - The @code{Transport} instance responsible for\n * the external communication.\n * @param {string} label - The label of the new device.\n * @param {string} id - The id of the new device.\n * @returns {Promise}\n */\nexport function setAudioInputDevice(transport: Object, label: string, id: string) {\n return _setDevice(transport, {\n id,\n kind: 'audioinput',\n label\n });\n}\n\n/**\n * Sets the audio output device to the one with the label or id that is passed.\n *\n * @param {Transport} transport - The @code{Transport} instance responsible for\n * the external communication.\n * @param {string} label - The label of the new device.\n * @param {string} id - The id of the new device.\n * @returns {Promise}\n */\nexport function setAudioOutputDevice(transport: Object, label: string, id: string) {\n return _setDevice(transport, {\n id,\n kind: 'audiooutput',\n label\n });\n}\n\n/**\n * Sets the currently used device to the one that is passed.\n *\n * @param {Transport} transport - The @code{Transport} instance responsible for\n * the external communication.\n * @param {Object} device - The new device to be used.\n * @returns {Promise}\n */\nfunction _setDevice(transport: Object, device) {\n return transport.sendRequest({\n type: 'devices',\n name: 'setDevice',\n device\n });\n}\n\n/**\n * Sets the video input device to the one with the label or id that is passed.\n *\n * @param {Transport} transport - The @code{Transport} instance responsible for\n * the external communication.\n * @param {string} label - The label of the new device.\n * @param {string} id - The id of the new device.\n * @returns {Promise}\n */\nexport function setVideoInputDevice(transport: Object, label: string, id: string) {\n return _setDevice(transport, {\n id,\n kind: 'videoinput',\n label\n });\n}\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\n'use strict';\n\nvar R = typeof Reflect === 'object' ? Reflect : null\nvar ReflectApply = R && typeof R.apply === 'function'\n ? R.apply\n : function ReflectApply(target, receiver, args) {\n return Function.prototype.apply.call(target, receiver, args);\n }\n\nvar ReflectOwnKeys\nif (R && typeof R.ownKeys === 'function') {\n ReflectOwnKeys = R.ownKeys\n} else if (Object.getOwnPropertySymbols) {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target)\n .concat(Object.getOwnPropertySymbols(target));\n };\n} else {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target);\n };\n}\n\nfunction ProcessEmitWarning(warning) {\n if (console && console.warn) console.warn(warning);\n}\n\nvar NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {\n return value !== value;\n}\n\nfunction EventEmitter() {\n EventEmitter.init.call(this);\n}\nmodule.exports = EventEmitter;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._eventsCount = 0;\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.\nvar defaultMaxListeners = 10;\n\nfunction checkListener(listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n}\n\nObject.defineProperty(EventEmitter, 'defaultMaxListeners', {\n enumerable: true,\n get: function() {\n return defaultMaxListeners;\n },\n set: function(arg) {\n if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {\n throw new RangeError('The value of \"defaultMaxListeners\" is out of range. It must be a non-negative number. Received ' + arg + '.');\n }\n defaultMaxListeners = arg;\n }\n});\n\nEventEmitter.init = function() {\n\n if (this._events === undefined ||\n this._events === Object.getPrototypeOf(this)._events) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n }\n\n this._maxListeners = this._maxListeners || undefined;\n};\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 setMaxListeners(n) {\n if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {\n throw new RangeError('The value of \"n\" is out of range. It must be a non-negative number. Received ' + n + '.');\n }\n this._maxListeners = n;\n return this;\n};\n\nfunction _getMaxListeners(that) {\n if (that._maxListeners === undefined)\n return EventEmitter.defaultMaxListeners;\n return that._maxListeners;\n}\n\nEventEmitter.prototype.getMaxListeners = function getMaxListeners() {\n return _getMaxListeners(this);\n};\n\nEventEmitter.prototype.emit = function emit(type) {\n var args = [];\n for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);\n var doError = (type === 'error');\n\n var events = this._events;\n if (events !== undefined)\n doError = (doError && events.error === undefined);\n else if (!doError)\n return false;\n\n // If there is no 'error' event listener then throw.\n if (doError) {\n var er;\n if (args.length > 0)\n er = args[0];\n if (er instanceof Error) {\n // Note: The comments on the `throw` lines are intentional, they show\n // up in Node's output if this results in an unhandled exception.\n throw er; // Unhandled 'error' event\n }\n // At least give some kind of context to the user\n var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));\n err.context = er;\n throw err; // Unhandled 'error' event\n }\n\n var handler = events[type];\n\n if (handler === undefined)\n return false;\n\n if (typeof handler === 'function') {\n ReflectApply(handler, this, args);\n } else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n ReflectApply(listeners[i], this, args);\n }\n\n return true;\n};\n\nfunction _addListener(target, type, listener, prepend) {\n var m;\n var events;\n var existing;\n\n checkListener(listener);\n\n events = target._events;\n if (events === undefined) {\n events = target._events = Object.create(null);\n target._eventsCount = 0;\n } else {\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (events.newListener !== undefined) {\n target.emit('newListener', type,\n listener.listener ? listener.listener : listener);\n\n // Re-assign `events` because a newListener handler could have caused the\n // this._events to be assigned to a new object\n events = target._events;\n }\n existing = events[type];\n }\n\n if (existing === undefined) {\n // Optimize the case of one listener. Don't need the extra array object.\n existing = events[type] = listener;\n ++target._eventsCount;\n } else {\n if (typeof existing === 'function') {\n // Adding the second element, need to change to array.\n existing = events[type] =\n prepend ? [listener, existing] : [existing, listener];\n // If we've already got an array, just append.\n } else if (prepend) {\n existing.unshift(listener);\n } else {\n existing.push(listener);\n }\n\n // Check for listener leak\n m = _getMaxListeners(target);\n if (m > 0 && existing.length > m && !existing.warned) {\n existing.warned = true;\n // No error code for this since it is a Warning\n // eslint-disable-next-line no-restricted-syntax\n var w = new Error('Possible EventEmitter memory leak detected. ' +\n existing.length + ' ' + String(type) + ' listeners ' +\n 'added. Use emitter.setMaxListeners() to ' +\n 'increase limit');\n w.name = 'MaxListenersExceededWarning';\n w.emitter = target;\n w.type = type;\n w.count = existing.length;\n ProcessEmitWarning(w);\n }\n }\n\n return target;\n}\n\nEventEmitter.prototype.addListener = function addListener(type, listener) {\n return _addListener(this, type, listener, false);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.prependListener =\n function prependListener(type, listener) {\n return _addListener(this, type, listener, true);\n };\n\nfunction onceWrapper() {\n if (!this.fired) {\n this.target.removeListener(this.type, this.wrapFn);\n this.fired = true;\n if (arguments.length === 0)\n return this.listener.call(this.target);\n return this.listener.apply(this.target, arguments);\n }\n}\n\nfunction _onceWrap(target, type, listener) {\n var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };\n var wrapped = onceWrapper.bind(state);\n wrapped.listener = listener;\n state.wrapFn = wrapped;\n return wrapped;\n}\n\nEventEmitter.prototype.once = function once(type, listener) {\n checkListener(listener);\n this.on(type, _onceWrap(this, type, listener));\n return this;\n};\n\nEventEmitter.prototype.prependOnceListener =\n function prependOnceListener(type, listener) {\n checkListener(listener);\n this.prependListener(type, _onceWrap(this, type, listener));\n return this;\n };\n\n// Emits a 'removeListener' event if and only if the listener was removed.\nEventEmitter.prototype.removeListener =\n function removeListener(type, listener) {\n var list, events, position, i, originalListener;\n\n checkListener(listener);\n\n events = this._events;\n if (events === undefined)\n return this;\n\n list = events[type];\n if (list === undefined)\n return this;\n\n if (list === listener || list.listener === listener) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else {\n delete events[type];\n if (events.removeListener)\n this.emit('removeListener', type, list.listener || listener);\n }\n } else if (typeof list !== 'function') {\n position = -1;\n\n for (i = list.length - 1; i >= 0; i--) {\n if (list[i] === listener || list[i].listener === listener) {\n originalListener = list[i].listener;\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (position === 0)\n list.shift();\n else {\n spliceOne(list, position);\n }\n\n if (list.length === 1)\n events[type] = list[0];\n\n if (events.removeListener !== undefined)\n this.emit('removeListener', type, originalListener || listener);\n }\n\n return this;\n };\n\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\nEventEmitter.prototype.removeAllListeners =\n function removeAllListeners(type) {\n var listeners, events, i;\n\n events = this._events;\n if (events === undefined)\n return this;\n\n // not listening for removeListener, no need to emit\n if (events.removeListener === undefined) {\n if (arguments.length === 0) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n } else if (events[type] !== undefined) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else\n delete events[type];\n }\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n var keys = Object.keys(events);\n var key;\n for (i = 0; i < keys.length; ++i) {\n key = keys[i];\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = Object.create(null);\n this._eventsCount = 0;\n return this;\n }\n\n listeners = events[type];\n\n if (typeof listeners === 'function') {\n this.removeListener(type, listeners);\n } else if (listeners !== undefined) {\n // LIFO order\n for (i = listeners.length - 1; i >= 0; i--) {\n this.removeListener(type, listeners[i]);\n }\n }\n\n return this;\n };\n\nfunction _listeners(target, type, unwrap) {\n var events = target._events;\n\n if (events === undefined)\n return [];\n\n var evlistener = events[type];\n if (evlistener === undefined)\n return [];\n\n if (typeof evlistener === 'function')\n return unwrap ? [evlistener.listener || evlistener] : [evlistener];\n\n return unwrap ?\n unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);\n}\n\nEventEmitter.prototype.listeners = function listeners(type) {\n return _listeners(this, type, true);\n};\n\nEventEmitter.prototype.rawListeners = function rawListeners(type) {\n return _listeners(this, type, false);\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n if (typeof emitter.listenerCount === 'function') {\n return emitter.listenerCount(type);\n } else {\n return listenerCount.call(emitter, type);\n }\n};\n\nEventEmitter.prototype.listenerCount = listenerCount;\nfunction listenerCount(type) {\n var events = this._events;\n\n if (events !== undefined) {\n var evlistener = events[type];\n\n if (typeof evlistener === 'function') {\n return 1;\n } else if (evlistener !== undefined) {\n return evlistener.length;\n }\n }\n\n return 0;\n}\n\nEventEmitter.prototype.eventNames = function eventNames() {\n return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];\n};\n\nfunction arrayClone(arr, n) {\n var copy = new Array(n);\n for (var i = 0; i < n; ++i)\n copy[i] = arr[i];\n return copy;\n}\n\nfunction spliceOne(list, index) {\n for (; index + 1 < list.length; index++)\n list[index] = list[index + 1];\n list.pop();\n}\n\nfunction unwrapListeners(arr) {\n var ret = new Array(arr.length);\n for (var i = 0; i < ret.length; ++i) {\n ret[i] = arr[i].listener || arr[i];\n }\n return ret;\n}\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 < 3) {\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", "'use strict';\n\n\nconst internals = {\n suspectRx: /\"(?:_|\\\\u005[Ff])(?:_|\\\\u005[Ff])(?:p|\\\\u0070)(?:r|\\\\u0072)(?:o|\\\\u006[Ff])(?:t|\\\\u0074)(?:o|\\\\u006[Ff])(?:_|\\\\u005[Ff])(?:_|\\\\u005[Ff])\"\\s*\\:/\n};\n\n\nexports.parse = function (text, ...args) {\n\n // Normalize arguments\n\n const firstOptions = typeof args[0] === 'object' && args[0];\n const reviver = args.length > 1 || !firstOptions ? args[0] : undefined;\n const options = (args.length > 1 && args[1]) || firstOptions || {};\n\n // Parse normally, allowing exceptions\n\n const obj = JSON.parse(text, reviver);\n\n // options.protoAction: 'error' (default) / 'remove' / 'ignore'\n\n if (options.protoAction === 'ignore') {\n return obj;\n }\n\n // Ignore null and non-objects\n\n if (!obj ||\n typeof obj !== 'object') {\n\n return obj;\n }\n\n // Check original string for potential exploit\n\n if (!text.match(internals.suspectRx)) {\n return obj;\n }\n\n // Scan result for proto keys\n\n exports.scan(obj, options);\n\n return obj;\n};\n\n\nexports.scan = function (obj, options = {}) {\n\n let next = [obj];\n\n while (next.length) {\n const nodes = next;\n next = [];\n\n for (const node of nodes) {\n if (Object.prototype.hasOwnProperty.call(node, '__proto__')) { // Avoid calling node.hasOwnProperty directly\n if (options.protoAction !== 'remove') {\n throw new SyntaxError('Object contains forbidden prototype property');\n }\n\n delete node.__proto__;\n }\n\n for (const key in node) {\n const value = node[key];\n if (value &&\n typeof value === 'object') {\n\n next.push(node[key]);\n }\n }\n }\n }\n};\n\n\nexports.safeParse = function (text, reviver) {\n\n try {\n return exports.parse(text, reviver);\n }\n catch (ignoreError) {\n return null;\n }\n};\n", "/*! clipboard-copy. MIT License. Feross Aboukhadijeh */\n/* global DOMException */\n\nmodule.exports = clipboardCopy\n\nfunction makeError () {\n return new DOMException('The request is not allowed', 'NotAllowedError')\n}\n\nasync function copyClipboardApi (text) {\n // Use the Async Clipboard API when available. Requires a secure browsing\n // context (i.e. HTTPS)\n if (!navigator.clipboard) {\n throw makeError()\n }\n return navigator.clipboard.writeText(text)\n}\n\nasync function copyExecCommand (text) {\n // Put the text to copy into a \n const span = document.createElement('span')\n span.textContent = text\n\n // Preserve consecutive spaces and newlines\n span.style.whiteSpace = 'pre'\n span.style.webkitUserSelect = 'auto'\n span.style.userSelect = 'all'\n\n // Add the to the page\n document.body.appendChild(span)\n\n // Make a selection object representing the range of text selected by the user\n const selection = window.getSelection()\n const range = window.document.createRange()\n selection.removeAllRanges()\n range.selectNode(span)\n selection.addRange(range)\n\n // Copy text to the clipboard\n let success = false\n try {\n success = window.document.execCommand('copy')\n } finally {\n // Cleanup\n selection.removeAllRanges()\n window.document.body.removeChild(span)\n }\n\n if (!success) throw makeError()\n}\n\nasync function clipboardCopy (text) {\n try {\n await copyClipboardApi(text)\n } catch (err) {\n // ...Otherwise, use document.execCommand() fallback\n try {\n await copyExecCommand(text)\n } catch (err2) {\n throw (err2 || err || makeError())\n }\n }\n}\n", "/* eslint-disable */\n\n// Ofiginally: https://github.com/adtile/postis\n//\n// The MIT License\n// \n// Copyright (c) 2015-2015 Adtile Technologies Inc. http://www.adtile.me\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n\nfunction Postis(options) {\n var scope = options.scope;\n var targetWindow = options.window;\n var windowForEventListening = options.windowForEventListening || window;\n var allowedOrigin = options.allowedOrigin;\n var listeners = {};\n var sendBuffer = [];\n var listenBuffer = {};\n var ready = false;\n var readyMethod = \"__ready__\";\n var readynessCheck;\n\n var listener = function(event) {\n var data;\n try {\n data = JSON.parse(event.data);\n } catch (e) {\n return;\n }\n\n if (allowedOrigin && event.origin !== allowedOrigin) {\n return;\n }\n\n if (data && data.postis && data.scope === scope) {\n var listenersForMethod = listeners[data.method];\n if (listenersForMethod) {\n for (var i = 0; i < listenersForMethod.length; i++) {\n listenersForMethod[i].call(null, data.params);\n }\n } else {\n listenBuffer[data.method] = listenBuffer[data.method] || [];\n listenBuffer[data.method].push(data.params);\n }\n }\n };\n\n windowForEventListening.addEventListener(\"message\", listener, false);\n\n var postis = {\n listen: function (method, callback) {\n listeners[method] = listeners[method] || [];\n listeners[method].push(callback);\n\n var listenBufferForMethod = listenBuffer[method];\n if (listenBufferForMethod) {\n var listenersForMethod = listeners[method];\n for (var i = 0; i < listenersForMethod.length; i++) {\n for (var j = 0; j < listenBufferForMethod.length; j++) {\n listenersForMethod[i].call(null, listenBufferForMethod[j]);\n }\n }\n }\n delete listenBuffer[method];\n },\n\n send: function (opts) {\n var method = opts.method;\n\n if ((ready || opts.method === readyMethod) && (targetWindow && typeof targetWindow.postMessage === \"function\")) {\n targetWindow.postMessage(JSON.stringify({\n postis: true,\n scope: scope,\n method: method,\n params: opts.params\n }), \"*\");\n } else {\n sendBuffer.push(opts);\n }\n },\n\n ready: function (callback) {\n if (ready) {\n callback();\n } else {\n setTimeout(function () { postis.ready(callback); }, 50);\n }\n },\n\n destroy: function (callback) {\n clearInterval(readynessCheck);\n ready = false;\n if (windowForEventListening && typeof windowForEventListening.removeEventListener === \"function\") {\n windowForEventListening.removeEventListener(\"message\", listener);\n }\n callback && callback();\n }\n };\n\n var readyCheckID = +new Date() + Math.random() + \"\";\n\n readynessCheck = setInterval(function () {\n postis.send({\n method: readyMethod,\n params: readyCheckID\n });\n }, 50);\n\n postis.listen(readyMethod, function (id) {\n if (id === readyCheckID) {\n clearInterval(readynessCheck);\n ready = true;\n\n for (var i = 0; i < sendBuffer.length; i++) {\n postis.send(sendBuffer[i]);\n }\n sendBuffer = [];\n } else {\n postis.send({\n method: readyMethod,\n params: id\n });\n }\n });\n\n return postis;\n}\n\nmodule.exports = Postis;\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", "// For legacy purposes, preserve the UMD of the public API of Jitsi Meet\n// external API (a.k.a. JitsiMeetExternalAPI).\nmodule.exports = require('./external_api').default;\n", "/* Copyright @ 2016-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.js');\n\n/**\n * Creates new LogCollector. Class implements LoggerTransport\n * and thus can be added as global transport in order to capture all the logs.\n *\n * It captures subsequent log lines created whenever Logger logs\n * a message and stores them in a queue in order to batch log entries. There are\n * time and size limit constraints which determine how often batch entries are\n * stored. Whenever one of these limits is exceeded the LogCollector\n * will use the logStorage object given as an argument to save\n * the batch log entry.\n *\n * @param {Object} logStorage an object which allows to store the logs collected\n * @param {function(string|object[])} logStorage.storeLogs a method called when\n * this LogCollector requests log entry storage. The method's argument\n * is an array which can contain strings and objects. If given\n * item is an object it means that it's an aggregated message. That is a message\n * which is the same as the previous one and it's representation has\n * the following format:\n * {\n * {string} text: 'the text of some duplicated message'\n * {number} count: 3 // how many times the message appeared in a row\n * }\n * If a message \"B\" after an aggregated message \"A\" is different, then it breaks\n * the sequence of \"A\". Which means that even if the next message \"C\" is\n * the same as \"A\" it will start a new aggregated message \"C\".\n * @param {function()} logStorage.isReady a method which should return\n * a boolean to tell the collector that it's ready to store. During the\n * time storage is not ready log batches will be cached and stored on the next\n * occasion (flush or interval timeout).\n *\n * @param {Object} options the LogCollector configuration options.\n * @param {number} options.maxEntryLength the size limit for a single log entry\n * to be stored. The LogCollector will push the entry as soon as it\n * reaches or exceeds this limit given that logStorage.isReady\n * returns true. Otherwise the log entry will be cached until the log\n * storage becomes ready. Note that the \"is ready\" condition is checked every\n * options.storeInterval milliseconds.\n * @param {number} options.storeInterval how often the logs should be stored in\n * case maxEntryLength was not exceeded.\n * @param {boolean} options.stringifyObjects indicates whether or not object\n * arguments should be \"stringified\" with JSON.stringify when a log\n * message is composed. Note that objects logged on the error log level are\n * always stringified.\n *\n * @constructor\n */\nfunction LogCollector(logStorage, options) {\n this.logStorage = logStorage;\n this.stringifyObjects = options && options.stringifyObjects ? options.stringifyObjects : false;\n this.storeInterval = options && options.storeInterval ? options.storeInterval: 30000;\n this.maxEntryLength = options && options.maxEntryLength ? options.maxEntryLength : 10000;\n // Bind the log method for each level to the corresponding method name\n // in order to implement \"global log transport\" object.\n Object.keys(Logger.levels).forEach(\n function (logLevel) {\n var methodName = Logger.levels[logLevel];\n this[methodName] = function () {\n this._log.apply(this, arguments);\n }.bind(this, logLevel);\n }.bind(this));\n /**\n * The ID of store logs interval if one is currently scheduled or\n * null otherwise.\n * @type {number|null}\n */\n this.storeLogsIntervalID = null;\n /**\n * The log messages that are to be batched into log entry when\n * {@link LogCollector._flush} method is called.\n * @type {string[]}\n */\n this.queue = [];\n /**\n * The total length of all messages currently stored in the {@link queue}.\n * @type {number}\n */\n this.totalLen = 0;\n /**\n * An array used to temporarily store log batches, before the storage gets\n * ready.\n * @type {string[]}\n */\n this.outputCache = [];\n}\n\n/**\n * Method called inside of {@link formatLogMessage} in order to covert an\n * Object argument to string. The conversion will happen when either\n * 'stringifyObjects' option is enabled or on the {@link Logger.levels.ERROR}\n * log level. The default implementation uses JSON.stringify and\n * returns \"[object with circular refs?]\" instead of an object if it fails.\n *\n * @param {object} someObject the object to be stringified.\n *\n * @return {string} the result of JSON.stringify or\n * \"[object with circular refs?]\" if any error occurs during \"stringification\".\n *\n * @protected\n */\nLogCollector.prototype.stringify = function (someObject) {\n try {\n return JSON.stringify(someObject);\n } catch (error) {\n return '[object with circular refs?]';\n }\n};\n\n/**\n * Formats log entry for the given logging level and arguments passed to the\n * Logger's log method. The first argument is log level and the next\n * arguments have to be captured using JS built-in 'arguments' variable.\n *\n * @param {Logger.levels} logLevel provides the logging level of the message to\n * be logged.\n * @param {Date} timestamp - The {@code Date} when a message has been logged.\n *\n * @return {string|null} a non-empty string representation of the log entry\n * crafted from the log arguments. If the return value is null then\n * the message wil be discarded by this LogCollector.\n *\n * @protected\n */\nLogCollector.prototype.formatLogMessage = function (\nlogLevel /* timestamp, arg2, arg3, arg4... */) {\n var msg = '';\n for (var i = 1, len = arguments.length; i < len; i++) {\n var arg = arguments[i];\n // objects logged on error level are always converted to JSON\n if ((this.stringifyObjects || logLevel === Logger.levels.ERROR) &&\n typeof arg === 'object') {\n arg = this.stringify(arg);\n }\n msg += arg;\n if (i !== len - 1) {\n msg += ' ';\n }\n }\n return msg.length ? msg : null;\n};\n\n/**\n * The log method bound to each of the logging levels in order to implement\n * \"global log transport\" object.\n *\n * @private\n */\nLogCollector.prototype._log = function() {\n\n // var logLevel = arguments[0]; first argument is the log level\n var timestamp = arguments[1];\n var msg = this.formatLogMessage.apply(this, arguments);\n if (msg) {\n // The same as the previous message aggregation logic\n var prevMessage = this.queue[this.queue.length - 1];\n var prevMessageText = prevMessage && prevMessage.text;\n if (prevMessageText === msg) {\n prevMessage.count += 1;\n } else {\n this.queue.push({\n text: msg,\n timestamp: timestamp,\n count: 1\n });\n this.totalLen += msg.length;\n }\n }\n\n if (this.totalLen >= this.maxEntryLength) {\n this._flush(true /* force */, true /* reschedule */);\n }\n};\n\n/**\n * Starts periodical \"store logs\" task which will be triggered at the interval\n * specified in the constructor options.\n */\nLogCollector.prototype.start = function () {\n this._reschedulePublishInterval();\n};\n\n/**\n * Reschedules the periodical \"store logs\" task which will store the next batch\n * log entry in the storage.\n * @private\n */\nLogCollector.prototype._reschedulePublishInterval = function () {\n if (this.storeLogsIntervalID) {\n window.clearTimeout(this.storeLogsIntervalID);\n this.storeLogsIntervalID = null;\n }\n // It's actually a timeout, because it is rescheduled on every flush\n this.storeLogsIntervalID = window.setTimeout(\n this._flush.bind(\n this, false /* do not force */, true /* reschedule */),\n this.storeInterval);\n};\n\n/**\n * Call this method to flush the log entry buffer and store it in the log\n * storage immediately (given that the storage is ready).\n */\nLogCollector.prototype.flush = function() {\n this._flush(\n false /* do not force, as it will not be stored anyway */,\n true /* reschedule next update */ );\n};\n\n/**\n * Stores the next batch log entry in the log storage.\n * @param {boolean} force enforce current logs batch to be stored or cached if\n * there is anything to be logged, but the storage is not ready yet. One of\n * legitimate reasons to force is when the logs length exceeds size limit which\n * could result in truncation.\n * @param {boolean} reschedule true if the next periodic task should be\n * scheduled after the log entry is stored. false will end the periodic\n * task cycle.\n * @private\n */\nLogCollector.prototype._flush = function(force, reschedule) {\n // Publish only if there's anything to be logged\n if (this.totalLen > 0 && (this.logStorage.isReady() || force)) {\n //FIXME avoid truncating\n // right now we don't care if the message size is \"slightly\" exceeded\n if (this.logStorage.isReady()) {\n // Sends all cached logs\n if (this.outputCache.length) {\n this.outputCache.forEach(\n function (cachedQueue) {\n this.logStorage.storeLogs(cachedQueue);\n }.bind(this)\n );\n // Clear the cache\n this.outputCache = [];\n }\n // Send current batch\n this.logStorage.storeLogs(this.queue);\n } else {\n this.outputCache.push(this.queue);\n }\n\n this.queue = [];\n this.totalLen = 0;\n }\n\n if (reschedule) {\n this._reschedulePublishInterval();\n }\n};\n\n/**\n * Stops the periodical \"store logs\" task and immediately stores any pending\n * log entries as a batch.\n */\nLogCollector.prototype.stop = function() {\n // Flush and stop publishing logs\n this._flush(false /* do not force */, false /* do not reschedule */);\n};\n\nmodule.exports = LogCollector;\n", "import EventEmitter from 'events';\n\n/**\n * Dummy implementation of Storage interface.\n */\nclass DummyLocalStorage extends EventEmitter {\n\n /**\n * The object used for storage.\n */\n _storage = {};\n\n /**\n * Empties all keys out of the storage.\n *\n * @returns {void}\n */\n clear() {\n this._storage = {};\n }\n\n /**\n * Returns the number of data items stored in the Storage object.\n *\n * @returns {number} - The number of data items stored in the Storage object.\n */\n get length() {\n return Object.keys(this._storage).length;\n }\n\n /**\n * Will return that key's value associated to the passed key name.\n *\n * @param {string} keyName - The key name.\n * @returns {*} - The key value.\n */\n getItem(keyName) {\n return this._storage[keyName];\n }\n\n /**\n * When passed a key name and value, will add that key to the storage,\n * or update that key's value if it already exists.\n *\n * @param {string} keyName - The key name.\n * @param {*} keyValue - The key value.\n * @returns {void}\n */\n setItem(keyName, keyValue) {\n this._storage[keyName] = keyValue;\n }\n\n /**\n * When passed a key name, will remove that key from the storage.\n *\n * @param {string} keyName - The key name.\n * @returns {void}\n */\n removeItem(keyName) {\n delete this._storage[keyName];\n }\n\n /**\n * When passed a number n, this method will return the name of the nth key in the storage.\n *\n * @param {number} idx - The index of the key.\n * @returns {string} - The nth key name.\n */\n key(n) {\n const keys = Object.keys(this._storage);\n\n if (keys.length <= n) {\n return undefined;\n }\n\n return keys[n];\n }\n\n /**\n * Serializes the content of the storage.\n *\n * @returns {string} - The serialized content.\n */\n serialize() {\n return JSON.stringify(this._storage);\n }\n}\n\n/**\n * Wrapper class for browser's local storage object.\n */\nclass JitsiLocalStorage extends EventEmitter {\n /**\n * @constructor\n * @param {Storage} storage browser's local storage object.\n */\n constructor() {\n super();\n\n try {\n this._storage = window.localStorage;\n this._localStorageDisabled = false;\n } catch (ignore) {\n // localStorage throws an exception.\n }\n\n if (!this._storage) { // Handles the case when window.localStorage is undefined or throws an exception.\n console.warn('Local storage is disabled.');\n this._storage = new DummyLocalStorage();\n this._localStorageDisabled = true;\n }\n }\n\n /**\n * Returns true if window.localStorage is disabled and false otherwise.\n *\n * @returns {boolean} - True if window.localStorage is disabled and false otherwise.\n */\n isLocalStorageDisabled() {\n return this._localStorageDisabled;\n }\n\n /**\n * Empties all keys out of the storage.\n *\n * @returns {void}\n */\n clear() {\n this._storage.clear();\n this.emit('changed');\n }\n\n /**\n * Returns the number of data items stored in the Storage object.\n *\n * @returns {number} - The number of data items stored in the Storage object.\n */\n get length() {\n return this._storage.length;\n }\n\n /**\n * Returns that passed key's value.\n * @param {string} keyName the name of the key you want to retrieve\n * the value of.\n * @returns {String|null} the value of the key. If the key does not exist,\n * null is returned.\n */\n getItem(keyName) {\n return this._storage.getItem(keyName);\n }\n\n /**\n * Adds a key to the storage, or update key's value if it already exists.\n * @param {string} keyName - the name of the key you want to create/update.\n * @param {string} keyValue - the value you want to give the key you are\n * creating/updating.\n * @param {boolean} dontEmitChangedEvent - If true a changed event won't be emitted.\n */\n setItem(keyName, keyValue, dontEmitChangedEvent = false) {\n this._storage.setItem(keyName, keyValue);\n\n if (!dontEmitChangedEvent) {\n this.emit('changed');\n }\n }\n\n /**\n * Remove a key from the storage.\n * @param {string} keyName the name of the key you want to remove.\n */\n removeItem(keyName) {\n this._storage.removeItem(keyName);\n this.emit('changed');\n }\n\n /**\n * Returns the name of the nth key in the list, or null if n is greater\n * than or equal to the number of key/value pairs in the object.\n *\n * @param {number} i - The index of the key in the list.\n * @returns {string}\n */\n key(i) {\n return this._storage.key(i);\n }\n\n /**\n * Serializes the content of the storage.\n *\n * @returns {string} - The serialized content.\n */\n serialize() {\n if (this.isLocalStorageDisabled()) {\n return this._storage.serialize();\n }\n\n const length = this._storage.length;\n const localStorageContent = {};\n\n for (let i = 0; i < length; i++) {\n const key = this._storage.key(i);\n\n localStorageContent[key] = this._storage.getItem(key);\n }\n\n return JSON.stringify(localStorageContent);\n }\n}\n\nexport const jitsiLocalStorage = new JitsiLocalStorage();\n", "/* @flow */\n\nimport Bourne from '@hapi/bourne';\n\nimport { reportError } from './helpers';\n\n/**\n * A list if keys to ignore when parsing.\n * @type {string[]}\n */\nconst blacklist = [ '__proto__', 'constructor', 'prototype' ];\n\n/**\n * Parses the query/search or fragment/hash parameters out of a specific URL and\n * returns them as a JS object.\n *\n * @param {URL} url - The URL to parse.\n * @param {boolean} dontParse - If falsy, some transformations (for parsing the\n * value as JSON) will be executed.\n * @param {string} source - If {@code 'search'}, the parameters will parsed out\n * of {@code url.search}; otherwise, out of {@code url.hash}.\n * @returns {Object}\n */\nexport function parseURLParams(\n url: URL,\n dontParse: boolean = false,\n source: string = 'hash'): Object {\n const paramStr = source === 'search' ? url.search : url.hash;\n const params = {};\n const paramParts = (paramStr && paramStr.substr(1).split('&')) || [];\n\n // Detect and ignore hash params for hash routers.\n if (source === 'hash' && paramParts.length === 1) {\n const firstParam = paramParts[0];\n\n if (firstParam.startsWith('/') && firstParam.split('&').length === 1) {\n return params;\n }\n }\n\n paramParts.forEach(part => {\n const param = part.split('=');\n const key = param[0];\n\n if (!key || key.split('.').some(k => blacklist.includes(k))) {\n return;\n }\n\n let value;\n\n try {\n value = param[1];\n\n if (!dontParse) {\n const decoded = decodeURIComponent(value).replace(/\\\\&/, '&');\n\n value = decoded === 'undefined' ? undefined : Bourne.parse(decoded);\n }\n } catch (e) {\n reportError(\n e, `Failed to parse URL parameter value: ${String(value)}`);\n\n return;\n }\n params[key] = value;\n });\n\n return params;\n}\n", "// @flow\n\nimport clipboardCopy from 'clipboard-copy';\n\n/**\n * A helper function that behaves similar to Object.assign, but only reassigns a\n * property in target if it's defined in source.\n *\n * @param {Object} target - The target object to assign the values into.\n * @param {Object} source - The source object.\n * @returns {Object}\n */\nexport function assignIfDefined(target: Object, source: Object) {\n const to = Object(target);\n\n for (const nextKey in source) {\n if (source.hasOwnProperty(nextKey)) {\n const value = source[nextKey];\n\n if (typeof value !== 'undefined') {\n to[nextKey] = value;\n }\n }\n }\n\n return to;\n}\n\n/**\n * Tries to copy a given text to the clipboard.\n * Returns true if the action succeeds.\n *\n * @param {string} textToCopy - Text to be copied.\n * @returns {Promise}\n */\nexport async function copyText(textToCopy: string) {\n try {\n await clipboardCopy(textToCopy);\n\n return true;\n } catch (e) {\n return false;\n }\n}\n\n/**\n * Creates a deferred object.\n *\n * @returns {{promise, resolve, reject}}\n */\nexport function createDeferred(): Object {\n const deferred = {};\n\n deferred.promise = new Promise((resolve, reject) => {\n deferred.resolve = resolve;\n deferred.reject = reject;\n });\n\n return deferred;\n}\n\nconst MATCH_OPERATOR_REGEXP = /[|\\\\{}()[\\]^$+*?.-]/g;\n\n/**\n * Escape RegExp special characters.\n *\n * Based on https://github.com/sindresorhus/escape-string-regexp.\n *\n * @param {string} s - The regexp string to escape.\n * @returns {string}\n */\nexport function escapeRegexp(s: string) {\n if (typeof s !== 'string') {\n throw new TypeError('Expected a string');\n }\n\n return s.replace(MATCH_OPERATOR_REGEXP, '\\\\$&');\n}\n\n/**\n * Returns the base URL of the app.\n *\n * @param {Object} w - Window object to use instead of the built in one.\n * @returns {string}\n */\nexport function getBaseUrl(w: Object = window) {\n const doc = w.document;\n const base = doc.querySelector('base');\n\n if (base && base.href) {\n return base.href;\n }\n\n const { protocol, host } = w.location;\n\n return `${protocol}//${host}`;\n}\n\n/**\n * Returns the namespace for all global variables, functions, etc that we need.\n *\n * @returns {Object} The namespace.\n *\n * NOTE: After React-ifying everything this should be the only global.\n */\nexport function getJitsiMeetGlobalNS() {\n if (!window.JitsiMeetJS) {\n window.JitsiMeetJS = {};\n }\n\n if (!window.JitsiMeetJS.app) {\n window.JitsiMeetJS.app = {};\n }\n\n return window.JitsiMeetJS.app;\n}\n\n/**\n * Prints the error and reports it to the global error handler.\n *\n * @param {Error} e - The error object.\n * @param {string} msg - A custom message to print in addition to the error.\n * @returns {void}\n */\nexport function reportError(e: Object, msg: string = '') {\n console.error(msg, e);\n window.onerror && window.onerror(msg, null, null, null, e);\n}\n\n/**\n * Adds alpha to a color css string.\n *\n * @param {string} color - The color string either in rgb... Or #... Format.\n * @param {number} opacity -The opacity(alpha) to apply to the color. Can take a value between 0 and 1, including.\n * @returns {string} - The color with applied alpha.\n */\nexport function setColorAlpha(color: string, opacity: number) {\n if (!color) {\n return `rgba(0, 0, 0, ${opacity})`;\n }\n\n let b, g, r;\n\n try {\n if (color.startsWith('rgb')) {\n [ r, g, b ] = color.split('(')[1].split(')')[0].split(',').map(c => c.trim());\n } else if (color.startsWith('#')) {\n if (color.length === 4) {\n [ r, g, b ] = parseShorthandColor(color);\n } else {\n r = parseInt(color.substring(1, 3), 16);\n g = parseInt(color.substring(3, 5), 16);\n b = parseInt(color.substring(5, 7), 16);\n }\n } else {\n return color;\n }\n\n return `rgba(${r}, ${g}, ${b}, ${opacity})`;\n } catch {\n return color;\n }\n}\n\n/**\n * Gets the hexa rgb values for a shorthand css color.\n *\n * @param {string} color -\n * @returns {Array} - Array containing parsed r, g, b values of the color.\n */\nfunction parseShorthandColor(color) {\n let b, g, r;\n\n r = color.substring(1, 2);\n r += r;\n r = parseInt(r, 16);\n\n g = color.substring(2, 3);\n g += g;\n g = parseInt(g, 16);\n\n b = color.substring(3, 4);\n b += b;\n b = parseInt(b, 16);\n\n return [ r, g, b ];\n}\n\n/**\n * Sorts an object by a sort function, same functionality as array.sort().\n *\n * @param {Object} object - The data object.\n * @param {Function} callback - The sort function.\n * @returns {void}\n */\nexport function objectSort(object: Object, callback: Function) {\n return Object.entries(object)\n .sort(([ , a ], [ , b ]) => callback(a, b))\n .reduce((row, [ key, value ]) => {\n return { ...row,\n [key]: value };\n }, {});\n}\n", "// @flow\n\nimport { parseURLParams } from './parseURLParams';\nimport { normalizeNFKC } from './strings';\n\n/**\n * The app linking scheme.\n * TODO: This should be read from the manifest files later.\n */\nexport const APP_LINK_SCHEME = 'org.jitsi.meet:';\n\n/**\n * A list of characters to be excluded/removed from the room component/segment\n * of a conference/meeting URI/URL. The list is based on RFC 3986 and the jxmpp\n * library utilized by jicofo.\n */\nconst _ROOM_EXCLUDE_PATTERN = '[\\\\:\\\\?#\\\\[\\\\]@!$&\\'()*+,;=> | null = regex.exec(uri);\n\n if (match) {\n // As an implementation convenience, pick up the last scheme and make\n // sure that it is a well-known one.\n let protocol = match[match.length - 1].toLowerCase();\n\n if (protocol !== 'http:' && protocol !== 'https:') {\n protocol = 'https:';\n }\n\n /* eslint-disable no-param-reassign */\n\n uri = uri.substring(regex.lastIndex);\n if (uri.startsWith('//')) {\n // The specified URL was not a room name only, it contained an\n // authority.\n uri = protocol + uri;\n }\n\n /* eslint-enable no-param-reassign */\n }\n\n return uri;\n}\n\n/**\n * Converts a path to a backend-safe format, by splitting the path '/' processing each part.\n * Properly lowercased and url encoded.\n *\n * @param {string?} path - The path to convert.\n * @returns {string?}\n */\nexport function getBackendSafePath(path: ?string): ?string {\n if (!path) {\n return path;\n }\n\n return path\n .split('/')\n .map(getBackendSafeRoomName)\n .join('/');\n}\n\n/**\n * Converts a room name to a backend-safe format. Properly lowercased and url encoded.\n *\n * @param {string?} room - The room name to convert.\n * @returns {string?}\n */\nexport function getBackendSafeRoomName(room: ?string): ?string {\n if (!room) {\n return room;\n }\n\n /* eslint-disable no-param-reassign */\n try {\n // We do not know if we get an already encoded string at this point\n // as different platforms do it differently, but we need a decoded one\n // for sure. However since decoding a non-encoded string is a noop, we're safe\n // doing it here.\n room = decodeURIComponent(room);\n } catch (e) {\n // This can happen though if we get an unencoded string and it contains\n // some characters that look like an encoded entity, but it's not.\n // But in this case we're fine goin on...\n }\n\n // Normalize the character set.\n room = normalizeNFKC(room);\n\n // Only decoded and normalized strings can be lowercased properly.\n room = room.toLowerCase();\n\n // But we still need to (re)encode it.\n room = encodeURIComponent(room);\n /* eslint-enable no-param-reassign */\n\n // Unfortunately we still need to lowercase it, because encoding a string will\n // add some uppercase characters, but some backend services\n // expect it to be full lowercase. However lowercasing an encoded string\n // doesn't change the string value.\n return room.toLowerCase();\n}\n\n/**\n * Gets the (Web application) context root defined by a specific location (URI).\n *\n * @param {Object} location - The location (URI) which defines the (Web\n * application) context root.\n * @public\n * @returns {string} - The (Web application) context root defined by the\n * specified {@code location} (URI).\n */\nexport function getLocationContextRoot({ pathname }: { pathname: string }) {\n const contextRootEndIndex = pathname.lastIndexOf('/');\n\n return (\n contextRootEndIndex === -1\n ? '/'\n : pathname.substring(0, contextRootEndIndex + 1));\n}\n\n/**\n * Constructs a new {@code Array} with URL parameter {@code String}s out of a\n * specific {@code Object}.\n *\n * @param {Object} obj - The {@code Object} to turn into URL parameter\n * {@code String}s.\n * @returns {Array} The {@code Array} with URL parameter {@code String}s\n * constructed out of the specified {@code obj}.\n */\nfunction _objectToURLParamsArray(obj = {}) {\n const params = [];\n\n for (const key in obj) { // eslint-disable-line guard-for-in\n try {\n params.push(\n `${key}=${encodeURIComponent(JSON.stringify(obj[key]))}`);\n } catch (e) {\n console.warn(`Error encoding ${key}: ${e}`);\n }\n }\n\n return params;\n}\n\n/**\n * Parses a specific URI string into an object with the well-known properties of\n * the {@link Location} and/or {@link URL} interfaces implemented by Web\n * browsers. The parsing attempts to be in accord with IETF's RFC 3986.\n *\n * @param {string} str - The URI string to parse.\n * @public\n * @returns {{\n * hash: string,\n * host: (string|undefined),\n * hostname: (string|undefined),\n * pathname: string,\n * port: (string|undefined),\n * protocol: (string|undefined),\n * search: string\n * }}\n */\nexport function parseStandardURIString(str: string) {\n /* eslint-disable no-param-reassign */\n\n const obj: Object = {\n toString: _standardURIToString\n };\n\n let regex;\n let match: Array | null;\n\n // XXX A URI string as defined by RFC 3986 does not contain any whitespace.\n // Usually, a browser will have already encoded any whitespace. In order to\n // avoid potential later problems related to whitespace in URI, strip any\n // whitespace. Anyway, the Jitsi Meet app is not known to utilize unencoded\n // whitespace so the stripping is deemed safe.\n str = str.replace(/\\s/g, '');\n\n // protocol\n regex = new RegExp(URI_PROTOCOL_PATTERN, 'gi');\n match = regex.exec(str);\n if (match) {\n obj.protocol = match[1].toLowerCase();\n str = str.substring(regex.lastIndex);\n }\n\n // authority\n regex = new RegExp(`^${_URI_AUTHORITY_PATTERN}`, 'gi');\n match = regex.exec(str);\n if (match) {\n let authority: string = match[1].substring(/* // */ 2);\n\n str = str.substring(regex.lastIndex);\n\n // userinfo\n const userinfoEndIndex = authority.indexOf('@');\n\n if (userinfoEndIndex !== -1) {\n authority = authority.substring(userinfoEndIndex + 1);\n }\n\n obj.host = authority;\n\n // port\n const portBeginIndex = authority.lastIndexOf(':');\n\n if (portBeginIndex !== -1) {\n obj.port = authority.substring(portBeginIndex + 1);\n authority = authority.substring(0, portBeginIndex);\n }\n\n // hostname\n obj.hostname = authority;\n }\n\n // pathname\n regex = new RegExp(`^${_URI_PATH_PATTERN}`, 'gi');\n match = regex.exec(str);\n\n let pathname: ?string;\n\n if (match) {\n pathname = match[1];\n str = str.substring(regex.lastIndex);\n }\n if (pathname) {\n pathname.startsWith('/') || (pathname = `/${pathname}`);\n } else {\n pathname = '/';\n }\n obj.pathname = pathname;\n\n // query\n if (str.startsWith('?')) {\n let hashBeginIndex = str.indexOf('#', 1);\n\n if (hashBeginIndex === -1) {\n hashBeginIndex = str.length;\n }\n obj.search = str.substring(0, hashBeginIndex);\n str = str.substring(hashBeginIndex);\n } else {\n obj.search = ''; // Google Chrome\n }\n\n // fragment\n obj.hash = str.startsWith('#') ? str : '';\n\n /* eslint-enable no-param-reassign */\n\n return obj;\n}\n\n/**\n * Parses a specific URI which (supposedly) references a Jitsi Meet resource\n * (location).\n *\n * @param {(string|undefined)} uri - The URI to parse which (supposedly)\n * references a Jitsi Meet resource (location).\n * @public\n * @returns {{\n * contextRoot: string,\n * hash: string,\n * host: string,\n * hostname: string,\n * pathname: string,\n * port: string,\n * protocol: string,\n * room: (string|undefined),\n * search: string\n * }}\n */\nexport function parseURIString(uri: ?string) {\n if (typeof uri !== 'string') {\n return undefined;\n }\n\n const obj = parseStandardURIString(_fixURIStringScheme(uri));\n\n // XXX While the components/segments of pathname are URI encoded, Jitsi Meet\n // on the client and/or server sides still don't support certain characters.\n obj.pathname = obj.pathname.split('/').map(pathPart => _fixPathPart(pathPart))\n .join('/');\n\n // Add the properties that are specific to a Jitsi Meet resource (location)\n // such as contextRoot, room:\n\n // contextRoot\n obj.contextRoot = getLocationContextRoot(obj);\n\n // The room (name) is the last component/segment of pathname.\n const { pathname } = obj;\n\n const contextRootEndIndex = pathname.lastIndexOf('/');\n\n obj.room = pathname.substring(contextRootEndIndex + 1) || undefined;\n\n if (contextRootEndIndex > 1) {\n // The part of the pathname from the beginning to the room name is the tenant.\n obj.tenant = pathname.substring(1, contextRootEndIndex);\n }\n\n return obj;\n}\n\n/**\n * Implements {@code href} and {@code toString} for the {@code Object} returned\n * by {@link #parseStandardURIString}.\n *\n * @param {Object} [thiz] - An {@code Object} returned by\n * {@code #parseStandardURIString} if any; otherwise, it is presumed that the\n * function is invoked on such an instance.\n * @returns {string}\n */\nfunction _standardURIToString(thiz: ?Object) {\n // eslint-disable-next-line no-invalid-this\n const { hash, host, pathname, protocol, search } = thiz || this;\n let str = '';\n\n protocol && (str += protocol);\n\n // TODO userinfo\n\n host && (str += `//${host}`);\n str += pathname || '/';\n search && (str += search);\n hash && (str += hash);\n\n return str;\n}\n\n/**\n * Sometimes we receive strings that we don't know if already percent-encoded, or not, due to the\n * various sources we get URLs or room names. This function encapsulates the decoding in a safe way.\n *\n * @param {string} text - The text to decode.\n * @returns {string}\n */\nexport function safeDecodeURIComponent(text: string) {\n try {\n return decodeURIComponent(text);\n } catch (e) {\n // The text wasn't encoded.\n }\n\n return text;\n}\n\n/**\n * Attempts to return a {@code String} representation of a specific\n * {@code Object} which is supposed to represent a URL. Obviously, if a\n * {@code String} is specified, it is returned. If a {@code URL} is specified,\n * its {@code URL#href} is returned. Additionally, an {@code Object} similar to\n * the one accepted by the constructor of Web's ExternalAPI is supported on both\n * mobile/React Native and Web/React.\n *\n * @param {Object|string} obj - The URL to return a {@code String}\n * representation of.\n * @returns {string} - A {@code String} representation of the specified\n * {@code obj} which is supposed to represent a URL.\n */\nexport function toURLString(obj: ?(Object | string)): ?string {\n let str;\n\n switch (typeof obj) {\n case 'object':\n if (obj) {\n if (obj instanceof URL) {\n str = obj.href;\n } else {\n str = urlObjectToString(obj);\n }\n }\n break;\n\n case 'string':\n str = String(obj);\n break;\n }\n\n return str;\n}\n\n/**\n * Attempts to return a {@code String} representation of a specific\n * {@code Object} similar to the one accepted by the constructor\n * of Web's ExternalAPI.\n *\n * @param {Object} o - The URL to return a {@code String} representation of.\n * @returns {string} - A {@code String} representation of the specified\n * {@code Object}.\n */\nexport function urlObjectToString(o: Object): ?string {\n // First normalize the given url. It come as o.url or split into o.serverURL\n // and o.room.\n let tmp;\n\n if (o.serverURL && o.room) {\n tmp = new URL(o.room, o.serverURL).toString();\n } else if (o.room) {\n tmp = o.room;\n } else {\n tmp = o.url || '';\n }\n\n const url = parseStandardURIString(_fixURIStringScheme(tmp));\n\n // protocol\n if (!url.protocol) {\n let protocol: ?string = o.protocol || o.scheme;\n\n if (protocol) {\n // Protocol is supposed to be the scheme and the final ':'. Anyway,\n // do not make a fuss if the final ':' is not there.\n protocol.endsWith(':') || (protocol += ':');\n url.protocol = protocol;\n }\n }\n\n // authority & pathname\n let { pathname } = url;\n\n if (!url.host) {\n // Web's ExternalAPI domain\n //\n // It may be host/hostname and pathname with the latter denoting the\n // tenant.\n const domain: ?string = o.domain || o.host || o.hostname;\n\n if (domain) {\n const { host, hostname, pathname: contextRoot, port }\n = parseStandardURIString(\n\n // XXX The value of domain in supposed to be host/hostname\n // and, optionally, pathname. Make sure it is not taken for\n // a pathname only.\n _fixURIStringScheme(`${APP_LINK_SCHEME}//${domain}`));\n\n // authority\n if (host) {\n url.host = host;\n url.hostname = hostname;\n url.port = port;\n }\n\n // pathname\n pathname === '/' && contextRoot !== '/' && (pathname = contextRoot);\n }\n }\n\n // pathname\n\n // Web's ExternalAPI roomName\n const room = o.roomName || o.room;\n\n if (room\n && (url.pathname.endsWith('/')\n || !url.pathname.endsWith(`/${room}`))) {\n pathname.endsWith('/') || (pathname += '/');\n pathname += room;\n }\n\n url.pathname = pathname;\n\n // query/search\n\n // Web's ExternalAPI jwt\n const { jwt } = o;\n\n if (jwt) {\n let { search } = url;\n\n if (search.indexOf('?jwt=') === -1 && search.indexOf('&jwt=') === -1) {\n search.startsWith('?') || (search = `?${search}`);\n search.length === 1 || (search += '&');\n search += `jwt=${jwt}`;\n\n url.search = search;\n }\n }\n\n // fragment/hash\n\n let { hash } = url;\n\n for (const urlPrefix of [ 'config', 'interfaceConfig', 'devices', 'userInfo', 'appData' ]) {\n const urlParamsArray\n = _objectToURLParamsArray(\n o[`${urlPrefix}Overwrite`]\n || o[urlPrefix]\n || o[`${urlPrefix}Override`]);\n\n if (urlParamsArray.length) {\n let urlParamsString\n = `${urlPrefix}.${urlParamsArray.join(`&${urlPrefix}.`)}`;\n\n if (hash.length) {\n urlParamsString = `&${urlParamsString}`;\n } else {\n hash = '#';\n }\n hash += urlParamsString;\n }\n }\n\n url.hash = hash;\n\n return url.toString() || undefined;\n}\n\n/**\n * Adds hash params to URL.\n *\n * @param {URL} url - The URL.\n * @param {Object} hashParamsToAdd - A map with the parameters to be set.\n * @returns {URL} - The new URL.\n */\nexport function addHashParamsToURL(url: URL, hashParamsToAdd: Object = {}) {\n const params = parseURLParams(url);\n const urlParamsArray = _objectToURLParamsArray({\n ...params,\n ...hashParamsToAdd\n });\n\n if (urlParamsArray.length) {\n url.hash = `#${urlParamsArray.join('&')}`;\n }\n\n return url;\n}\n\n/**\n * Returns the decoded URI.\n *\n * @param {string} uri - The URI to decode.\n * @returns {string}\n */\nexport function getDecodedURI(uri: string) {\n return decodeURI(uri.replace(/^https?:\\/\\//i, ''));\n}\n", "import Postis from './postis';\n\n/**\n * The default options for postis.\n *\n * @type {Object}\n */\nconst DEFAULT_POSTIS_OPTIONS = {\n window: window.opener || window.parent\n};\n\n/**\n * The postis method used for all messages.\n *\n * @type {string}\n */\nconst POSTIS_METHOD_NAME = 'message';\n\n/**\n * Implements message transport using the postMessage API.\n */\nexport default class PostMessageTransportBackend {\n /**\n * Creates new PostMessageTransportBackend instance.\n *\n * @param {Object} options - Optional parameters for configuration of the\n * transport.\n */\n constructor({ postisOptions } = {}) {\n // eslint-disable-next-line new-cap\n this.postis = Postis({\n ...DEFAULT_POSTIS_OPTIONS,\n ...postisOptions\n });\n\n this._receiveCallback = () => {\n // Do nothing until a callback is set by the consumer of\n // PostMessageTransportBackend via setReceiveCallback.\n };\n\n this.postis.listen(\n POSTIS_METHOD_NAME,\n message => this._receiveCallback(message));\n }\n\n /**\n * Disposes the allocated resources.\n *\n * @returns {void}\n */\n dispose() {\n this.postis.destroy();\n }\n\n /**\n * Sends the passed message.\n *\n * @param {Object} message - The message to be sent.\n * @returns {void}\n */\n send(message) {\n this.postis.send({\n method: POSTIS_METHOD_NAME,\n params: message\n });\n }\n\n /**\n * Sets the callback for receiving data.\n *\n * @param {Function} callback - The new callback.\n * @returns {void}\n */\n setReceiveCallback(callback) {\n this._receiveCallback = callback;\n }\n}\n", "import {\n MESSAGE_TYPE_EVENT,\n MESSAGE_TYPE_REQUEST,\n MESSAGE_TYPE_RESPONSE\n} from './constants';\n\n/**\n* Stores the currnet transport backend that have to be used. Also implements\n* request/response mechanism.\n*/\nexport default class Transport {\n /**\n * Creates new instance.\n *\n * @param {Object} options - Optional parameters for configuration of the\n * transport backend.\n */\n constructor({ backend } = {}) {\n /**\n * Maps an event name and listener that have been added to the Transport\n * instance.\n *\n * @type {Map}\n */\n this._listeners = new Map();\n\n /**\n * The request ID counter used for the id property of the request. This\n * property is used to match the responses with the request.\n *\n * @type {number}\n */\n this._requestID = 0;\n\n /**\n * Maps an IDs of the requests and handlers that will process the\n * responses of those requests.\n *\n * @type {Map}\n */\n this._responseHandlers = new Map();\n\n /**\n * A set with the events and requests that were received but not\n * processed by any listener. They are later passed on every new\n * listener until they are processed.\n *\n * @type {Set}\n */\n this._unprocessedMessages = new Set();\n\n /**\n * Alias.\n */\n this.addListener = this.on;\n\n if (backend) {\n this.setBackend(backend);\n }\n }\n\n /**\n * Disposes the current transport backend.\n *\n * @returns {void}\n */\n _disposeBackend() {\n if (this._backend) {\n this._backend.dispose();\n this._backend = null;\n }\n }\n\n /**\n * Handles incoming messages from the transport backend.\n *\n * @param {Object} message - The message.\n * @returns {void}\n */\n _onMessageReceived(message) {\n if (message.type === MESSAGE_TYPE_RESPONSE) {\n const handler = this._responseHandlers.get(message.id);\n\n if (handler) {\n handler(message);\n this._responseHandlers.delete(message.id);\n }\n } else if (message.type === MESSAGE_TYPE_REQUEST) {\n this.emit('request', message.data, (result, error) => {\n this._backend.send({\n type: MESSAGE_TYPE_RESPONSE,\n error,\n id: message.id,\n result\n });\n });\n } else {\n this.emit('event', message.data);\n }\n }\n\n /**\n * Disposes the allocated resources.\n *\n * @returns {void}\n */\n dispose() {\n this._responseHandlers.clear();\n this._unprocessedMessages.clear();\n this.removeAllListeners();\n this._disposeBackend();\n }\n\n /**\n * Calls each of the listeners registered for the event named eventName, in\n * the order they were registered, passing the supplied arguments to each.\n *\n * @param {string} eventName - The name of the event.\n * @returns {boolean} True if the event has been processed by any listener,\n * false otherwise.\n */\n emit(eventName, ...args) {\n const listenersForEvent = this._listeners.get(eventName);\n let isProcessed = false;\n\n if (listenersForEvent && listenersForEvent.size) {\n listenersForEvent.forEach(listener => {\n isProcessed = listener(...args) || isProcessed;\n });\n }\n\n if (!isProcessed) {\n this._unprocessedMessages.add(args);\n }\n\n return isProcessed;\n }\n\n /**\n * Adds the listener function to the listeners collection for the event\n * named eventName.\n *\n * @param {string} eventName - The name of the event.\n * @param {Function} listener - The listener that will be added.\n * @returns {Transport} References to the instance of Transport class, so\n * that calls can be chained.\n */\n on(eventName, listener) {\n let listenersForEvent = this._listeners.get(eventName);\n\n if (!listenersForEvent) {\n listenersForEvent = new Set();\n this._listeners.set(eventName, listenersForEvent);\n }\n\n listenersForEvent.add(listener);\n\n this._unprocessedMessages.forEach(args => {\n if (listener(...args)) {\n this._unprocessedMessages.delete(args);\n }\n });\n\n return this;\n }\n\n /**\n * Removes all listeners, or those of the specified eventName.\n *\n * @param {string} [eventName] - The name of the event. If this parameter is\n * not specified all listeners will be removed.\n * @returns {Transport} References to the instance of Transport class, so\n * that calls can be chained.\n */\n removeAllListeners(eventName) {\n if (eventName) {\n this._listeners.delete(eventName);\n } else {\n this._listeners.clear();\n }\n\n return this;\n }\n\n /**\n * Removes the listener function from the listeners collection for the event\n * named eventName.\n *\n * @param {string} eventName - The name of the event.\n * @param {Function} listener - The listener that will be removed.\n * @returns {Transport} References to the instance of Transport class, so\n * that calls can be chained.\n */\n removeListener(eventName, listener) {\n const listenersForEvent = this._listeners.get(eventName);\n\n if (listenersForEvent) {\n listenersForEvent.delete(listener);\n }\n\n return this;\n }\n\n /**\n * Sends the passed event.\n *\n * @param {Object} event - The event to be sent.\n * @returns {void}\n */\n sendEvent(event = {}) {\n if (this._backend) {\n this._backend.send({\n type: MESSAGE_TYPE_EVENT,\n data: event\n });\n }\n }\n\n /**\n * Sending request.\n *\n * @param {Object} request - The request to be sent.\n * @returns {Promise}\n */\n sendRequest(request) {\n if (!this._backend) {\n return Promise.reject(new Error('No transport backend defined!'));\n }\n\n this._requestID++;\n\n const id = this._requestID;\n\n return new Promise((resolve, reject) => {\n this._responseHandlers.set(id, ({ error, result }) => {\n if (typeof result !== 'undefined') {\n resolve(result);\n\n // eslint-disable-next-line no-negated-condition\n } else if (typeof error !== 'undefined') {\n reject(error);\n } else { // no response\n reject(new Error('Unexpected response format!'));\n }\n });\n\n this._backend.send({\n type: MESSAGE_TYPE_REQUEST,\n data: request,\n id\n });\n });\n }\n\n /**\n * Changes the current backend transport.\n *\n * @param {Object} backend - The new transport backend that will be used.\n * @returns {void}\n */\n setBackend(backend) {\n this._disposeBackend();\n\n this._backend = backend;\n this._backend.setReceiveCallback(this._onMessageReceived.bind(this));\n }\n}\n", "/**\n * The message type for events.\n *\n * @type {string}\n */\nexport const MESSAGE_TYPE_EVENT = 'event';\n\n/**\n * The message type for requests.\n *\n * @type {string}\n */\nexport const MESSAGE_TYPE_REQUEST = 'request';\n\n/**\n * The message type for responses.\n *\n * @type {string}\n */\nexport const MESSAGE_TYPE_RESPONSE = 'response';\n", "// XXX The function parseURLParams is exported by the feature base/util (as\n// defined in the terminology of react/). However, this file is (very likely)\n// bundled in external_api in addition to app.bundle and, consequently, it is\n// best to import as little as possible here (rather than the whole feature\n// base/util) in order to minimize the amount of source code bundled into\n// multiple bundles.\nimport { parseURLParams } from '../../react/features/base/util/parseURLParams';\n\n/**\n * JitsiMeetExternalAPI id - unique for a webpage.\n */\nexport const API_ID = parseURLParams(window.location).jitsi_meet_external_api_id;\n\n/**\n * The payload name for the datachannel/endpoint text message event\n */\nexport const ENDPOINT_TEXT_MESSAGE_NAME = 'endpoint-text-message';\n", "// FIXME: change to '../API' when we update to webpack2. If we do this now all\n// files from API modules will be included in external_api.js.\nimport { PostMessageTransportBackend, Transport } from '@jitsi/js-utils/transport';\n\nimport { getJitsiMeetGlobalNS } from '../../react/features/base/util';\nimport { API_ID } from '../API/constants';\n\n\nexport {\n PostMessageTransportBackend,\n Transport\n};\n\n/**\n * Option for the default low level transport.\n *\n * @type {Object}\n */\nconst postisOptions = {};\n\nif (typeof API_ID === 'number') {\n postisOptions.scope = `jitsi_meet_external_api_${API_ID}`;\n}\n\n/**\n * The instance of Transport class that will be used by Jitsi Meet.\n *\n * @type {Transport}\n */\nlet transport;\n\n/**\n * Returns the instance of Transport class that will be used by Jitsi Meet.\n *\n * @returns {Transport}\n */\nexport function getJitsiMeetTransport() {\n if (!transport) {\n transport = new Transport({ backend: new PostMessageTransportBackend({ postisOptions }) });\n }\n\n return transport;\n}\n\n/**\n * Sets the transport to passed transport.\n *\n * @param {Object} externalTransportBackend - The new transport.\n * @returns {void}\n */\ngetJitsiMeetGlobalNS().setExternalTransportBackend = externalTransportBackend =>\n transport.setBackend(externalTransportBackend);\n", "import { jitsiLocalStorage } from '@jitsi/js-utils/jitsi-local-storage';\nimport EventEmitter from 'events';\n\nimport { urlObjectToString } from '../../../react/features/base/util/uri';\nimport {\n PostMessageTransportBackend,\n Transport\n} from '../../transport';\n\nimport {\n getAvailableDevices,\n getCurrentDevices,\n isDeviceChangeAvailable,\n isDeviceListAvailable,\n isMultipleAudioInputSupported,\n setAudioInputDevice,\n setAudioOutputDevice,\n setVideoInputDevice\n} from './functions';\n\nconst ALWAYS_ON_TOP_FILENAMES = [\n 'css/all.css', 'libs/alwaysontop.min.js'\n];\n\n/**\n * Maps the names of the commands expected by the API with the name of the\n * commands expected by jitsi-meet\n */\nconst commands = {\n avatarUrl: 'avatar-url',\n cancelPrivateChat: 'cancel-private-chat',\n displayName: 'display-name',\n e2eeKey: 'e2ee-key',\n email: 'email',\n toggleLobby: 'toggle-lobby',\n hangup: 'video-hangup',\n initiatePrivateChat: 'initiate-private-chat',\n kickParticipant: 'kick-participant',\n muteEveryone: 'mute-everyone',\n overwriteConfig: 'overwrite-config',\n password: 'password',\n pinParticipant: 'pin-participant',\n resizeLargeVideo: 'resize-large-video',\n sendChatMessage: 'send-chat-message',\n sendEndpointTextMessage: 'send-endpoint-text-message',\n sendTones: 'send-tones',\n setFollowMe: 'set-follow-me',\n setLargeVideoParticipant: 'set-large-video-participant',\n setParticipantVolume: 'set-participant-volume',\n setTileView: 'set-tile-view',\n setVideoQuality: 'set-video-quality',\n startRecording: 'start-recording',\n startShareVideo: 'start-share-video',\n stopRecording: 'stop-recording',\n stopShareVideo: 'stop-share-video',\n subject: 'subject',\n submitFeedback: 'submit-feedback',\n toggleAudio: 'toggle-audio',\n toggleCamera: 'toggle-camera',\n toggleCameraMirror: 'toggle-camera-mirror',\n toggleChat: 'toggle-chat',\n toggleFilmStrip: 'toggle-film-strip',\n toggleRaiseHand: 'toggle-raise-hand',\n toggleShareAudio: 'toggle-share-audio',\n toggleShareScreen: 'toggle-share-screen',\n toggleTileView: 'toggle-tile-view',\n toggleVirtualBackgroundDialog: 'toggle-virtual-background',\n toggleVideo: 'toggle-video'\n};\n\n/**\n * Maps the names of the events expected by the API with the name of the\n * events expected by jitsi-meet\n */\nconst events = {\n 'avatar-changed': 'avatarChanged',\n 'audio-availability-changed': 'audioAvailabilityChanged',\n 'audio-mute-status-changed': 'audioMuteStatusChanged',\n 'browser-support': 'browserSupport',\n 'camera-error': 'cameraError',\n 'chat-updated': 'chatUpdated',\n 'content-sharing-participants-changed': 'contentSharingParticipantsChanged',\n 'data-channel-opened': 'dataChannelOpened',\n 'device-list-changed': 'deviceListChanged',\n 'display-name-change': 'displayNameChange',\n 'email-change': 'emailChange',\n 'error-occurred': 'errorOccurred',\n 'endpoint-text-message-received': 'endpointTextMessageReceived',\n 'feedback-submitted': 'feedbackSubmitted',\n 'feedback-prompt-displayed': 'feedbackPromptDisplayed',\n 'filmstrip-display-changed': 'filmstripDisplayChanged',\n 'incoming-message': 'incomingMessage',\n 'log': 'log',\n 'mic-error': 'micError',\n 'mouse-enter': 'mouseEnter',\n 'mouse-leave': 'mouseLeave',\n 'mouse-move': 'mouseMove',\n 'outgoing-message': 'outgoingMessage',\n 'participant-joined': 'participantJoined',\n 'participant-kicked-out': 'participantKickedOut',\n 'participant-left': 'participantLeft',\n 'participant-role-changed': 'participantRoleChanged',\n 'password-required': 'passwordRequired',\n 'proxy-connection-event': 'proxyConnectionEvent',\n 'raise-hand-updated': 'raiseHandUpdated',\n 'recording-status-changed': 'recordingStatusChanged',\n 'video-ready-to-close': 'readyToClose',\n 'video-conference-joined': 'videoConferenceJoined',\n 'video-conference-left': 'videoConferenceLeft',\n 'video-availability-changed': 'videoAvailabilityChanged',\n 'video-mute-status-changed': 'videoMuteStatusChanged',\n 'video-quality-changed': 'videoQualityChanged',\n 'screen-sharing-status-changed': 'screenSharingStatusChanged',\n 'dominant-speaker-changed': 'dominantSpeakerChanged',\n 'subject-change': 'subjectChange',\n 'suspend-detected': 'suspendDetected',\n 'tile-view-changed': 'tileViewChanged',\n 'toolbar-button-clicked': 'toolbarButtonClicked'\n};\n\n/**\n * Last id of api object\n * @type {number}\n */\nlet id = 0;\n\n/**\n * Adds given number to the numberOfParticipants property of given APIInstance.\n *\n * @param {JitsiMeetExternalAPI} APIInstance - The instance of the API.\n * @param {int} number - The number of participants to be added to\n * numberOfParticipants property (this parameter can be negative number if the\n * numberOfParticipants should be decreased).\n * @returns {void}\n */\nfunction changeParticipantNumber(APIInstance, number) {\n APIInstance._numberOfParticipants += number;\n}\n\n/**\n * Generates the URL for the iframe.\n *\n * @param {string} domain - The domain name of the server that hosts the\n * conference.\n * @param {string} [options] - Another optional parameters.\n * @param {Object} [options.configOverwrite] - Object containing configuration\n * options defined in config.js to be overridden.\n * @param {Object} [options.interfaceConfigOverwrite] - Object containing\n * configuration options defined in interface_config.js to be overridden.\n * @param {string} [options.jwt] - The JWT token if needed by jitsi-meet for\n * authentication.\n * @param {string} [options.roomName] - The name of the room to join.\n * @returns {string} The URL.\n */\nfunction generateURL(domain, options = {}) {\n return urlObjectToString({\n ...options,\n url: `https://${domain}/#jitsi_meet_external_api_id=${id}`\n });\n}\n\n/**\n * Parses the arguments passed to the constructor. If the old format is used\n * the function translates the arguments to the new format.\n *\n * @param {Array} args - The arguments to be parsed.\n * @returns {Object} JS object with properties.\n */\nfunction parseArguments(args) {\n if (!args.length) {\n return {};\n }\n\n const firstArg = args[0];\n\n switch (typeof firstArg) {\n case 'string': // old arguments format\n case 'undefined': {\n // Not sure which format but we are trying to parse the old\n // format because if the new format is used everything will be undefined\n // anyway.\n const [\n roomName,\n width,\n height,\n parentNode,\n configOverwrite,\n interfaceConfigOverwrite,\n jwt,\n onload\n ] = args;\n\n return {\n roomName,\n width,\n height,\n parentNode,\n configOverwrite,\n interfaceConfigOverwrite,\n jwt,\n onload\n };\n }\n case 'object': // new arguments format\n return args[0];\n default:\n throw new Error('Can\\'t parse the arguments!');\n }\n}\n\n/**\n * Compute valid values for height and width. If a number is specified it's\n * treated as pixel units. If the value is expressed in px, em, pt or\n * percentage, it's used as is.\n *\n * @param {any} value - The value to be parsed.\n * @returns {string|undefined} The parsed value that can be used for setting\n * sizes through the style property. If invalid value is passed the method\n * returns undefined.\n */\nfunction parseSizeParam(value) {\n let parsedValue;\n\n // This regex parses values of the form 100px, 100em, 100pt or 100%.\n // Values like 100 or 100px are handled outside of the regex, and\n // invalid values will be ignored and the minimum will be used.\n const re = /([0-9]*\\.?[0-9]+)(em|pt|px|%)$/;\n\n if (typeof value === 'string' && String(value).match(re) !== null) {\n parsedValue = value;\n } else if (typeof value === 'number') {\n parsedValue = `${value}px`;\n }\n\n return parsedValue;\n}\n\n\n/**\n * The IFrame API interface class.\n */\nexport default class JitsiMeetExternalAPI extends EventEmitter {\n /**\n * Constructs new API instance. Creates iframe and loads Jitsi Meet in it.\n *\n * @param {string} domain - The domain name of the server that hosts the\n * conference.\n * @param {Object} [options] - Optional arguments.\n * @param {string} [options.roomName] - The name of the room to join.\n * @param {number|string} [options.width] - Width of the iframe. Check\n * parseSizeParam for format details.\n * @param {number|string} [options.height] - Height of the iframe. Check\n * parseSizeParam for format details.\n * @param {DOMElement} [options.parentNode] - The node that will contain the\n * iframe.\n * @param {Object} [options.configOverwrite] - Object containing\n * configuration options defined in config.js to be overridden.\n * @param {Object} [options.interfaceConfigOverwrite] - Object containing\n * configuration options defined in interface_config.js to be overridden.\n * @param {string} [options.jwt] - The JWT token if needed by jitsi-meet for\n * authentication.\n * @param {string} [options.onload] - The onload function that will listen\n * for iframe onload event.\n * @param {Array} [options.invitees] - Array of objects containing\n * information about new participants that will be invited in the call.\n * @param {Array} [options.devices] - Array of objects containing\n * information about the initial devices that will be used in the call.\n * @param {Object} [options.userInfo] - Object containing information about\n * the participant opening the meeting.\n * @param {string} [options.e2eeKey] - The key used for End-to-End encryption.\n * THIS IS EXPERIMENTAL.\n */\n constructor(domain, ...args) {\n super();\n const {\n roomName = '',\n width = '100%',\n height = '100%',\n parentNode = document.body,\n configOverwrite = {},\n interfaceConfigOverwrite = {},\n jwt = undefined,\n onload = undefined,\n invitees,\n devices,\n userInfo,\n e2eeKey\n } = parseArguments(args);\n const localStorageContent = jitsiLocalStorage.getItem('jitsiLocalStorage');\n\n this._parentNode = parentNode;\n this._url = generateURL(domain, {\n configOverwrite,\n interfaceConfigOverwrite,\n jwt,\n roomName,\n devices,\n userInfo,\n appData: {\n localStorageContent\n }\n });\n this._createIFrame(height, width, onload);\n this._transport = new Transport({\n backend: new PostMessageTransportBackend({\n postisOptions: {\n allowedOrigin: new URL(this._url).origin,\n scope: `jitsi_meet_external_api_${id}`,\n window: this._frame.contentWindow\n }\n })\n });\n if (Array.isArray(invitees) && invitees.length > 0) {\n this.invite(invitees);\n }\n this._tmpE2EEKey = e2eeKey;\n this._isLargeVideoVisible = true;\n this._numberOfParticipants = 0;\n this._participants = {};\n this._myUserID = undefined;\n this._onStageParticipant = undefined;\n this._setupListeners();\n id++;\n }\n\n /**\n * Creates the iframe element.\n *\n * @param {number|string} height - The height of the iframe. Check\n * parseSizeParam for format details.\n * @param {number|string} width - The with of the iframe. Check\n * parseSizeParam for format details.\n * @param {Function} onload - The function that will listen\n * for onload event.\n * @returns {void}\n *\n * @private\n */\n _createIFrame(height, width, onload) {\n const frameName = `jitsiConferenceFrame${id}`;\n\n this._frame = document.createElement('iframe');\n this._frame.allow = 'camera; microphone; display-capture; autoplay; clipboard-write';\n this._frame.src = this._url;\n this._frame.name = frameName;\n this._frame.id = frameName;\n this._setSize(height, width);\n this._frame.setAttribute('allowFullScreen', 'true');\n this._frame.style.border = 0;\n\n if (onload) {\n // waits for iframe resources to load\n // and fires event when it is done\n this._frame.onload = onload;\n }\n\n this._frame = this._parentNode.appendChild(this._frame);\n }\n\n /**\n * Returns arrays with the all resources for the always on top feature.\n *\n * @returns {Array}\n */\n _getAlwaysOnTopResources() {\n const iframeWindow = this._frame.contentWindow;\n const iframeDocument = iframeWindow.document;\n let baseURL = '';\n const base = iframeDocument.querySelector('base');\n\n if (base && base.href) {\n baseURL = base.href;\n } else {\n const { protocol, host } = iframeWindow.location;\n\n baseURL = `${protocol}//${host}`;\n }\n\n return ALWAYS_ON_TOP_FILENAMES.map(\n filename => (new URL(filename, baseURL)).href\n );\n }\n\n /**\n * Returns the formatted display name of a participant.\n *\n * @param {string} participantId - The id of the participant.\n * @returns {string} The formatted display name.\n */\n _getFormattedDisplayName(participantId) {\n const { formattedDisplayName }\n = this._participants[participantId] || {};\n\n return formattedDisplayName;\n }\n\n /**\n * Returns the id of the on stage participant.\n *\n * @returns {string} - The id of the on stage participant.\n */\n _getOnStageParticipant() {\n return this._onStageParticipant;\n }\n\n\n /**\n * Getter for the large video element in Jitsi Meet.\n *\n * @returns {HTMLElement|undefined} - The large video.\n */\n _getLargeVideo() {\n const iframe = this.getIFrame();\n\n if (!this._isLargeVideoVisible\n || !iframe\n || !iframe.contentWindow\n || !iframe.contentWindow.document) {\n return;\n }\n\n return iframe.contentWindow.document.getElementById('largeVideo');\n }\n\n /**\n * Getter for participant specific video element in Jitsi Meet.\n *\n * @param {string|undefined} participantId - Id of participant to return the video for.\n *\n * @returns {HTMLElement|undefined} - The requested video. Will return the local video\n * by default if participantId is undefined.\n */\n _getParticipantVideo(participantId) {\n const iframe = this.getIFrame();\n\n if (!iframe\n || !iframe.contentWindow\n || !iframe.contentWindow.document) {\n return;\n }\n\n if (typeof participantId === 'undefined' || participantId === this._myUserID) {\n return iframe.contentWindow.document.getElementById('localVideo_container');\n }\n\n return iframe.contentWindow.document.querySelector(`#participant_${participantId} video`);\n }\n\n /**\n * Sets the size of the iframe element.\n *\n * @param {number|string} height - The height of the iframe.\n * @param {number|string} width - The with of the iframe.\n * @returns {void}\n *\n * @private\n */\n _setSize(height, width) {\n const parsedHeight = parseSizeParam(height);\n const parsedWidth = parseSizeParam(width);\n\n if (parsedHeight !== undefined) {\n this._height = height;\n this._frame.style.height = parsedHeight;\n }\n\n if (parsedWidth !== undefined) {\n this._width = width;\n this._frame.style.width = parsedWidth;\n }\n }\n\n /**\n * Setups listeners that are used internally for JitsiMeetExternalAPI.\n *\n * @returns {void}\n *\n * @private\n */\n _setupListeners() {\n this._transport.on('event', ({ name, ...data }) => {\n const userID = data.id;\n\n switch (name) {\n case 'video-conference-joined': {\n if (typeof this._tmpE2EEKey !== 'undefined') {\n this.executeCommand(commands.e2eeKey, this._tmpE2EEKey);\n this._tmpE2EEKey = undefined;\n }\n\n this._myUserID = userID;\n this._participants[userID] = {\n avatarURL: data.avatarURL\n };\n }\n\n // eslint-disable-next-line no-fallthrough\n case 'participant-joined': {\n this._participants[userID] = this._participants[userID] || {};\n this._participants[userID].displayName = data.displayName;\n this._participants[userID].formattedDisplayName\n = data.formattedDisplayName;\n changeParticipantNumber(this, 1);\n break;\n }\n case 'participant-left':\n changeParticipantNumber(this, -1);\n delete this._participants[userID];\n break;\n case 'display-name-change': {\n const user = this._participants[userID];\n\n if (user) {\n user.displayName = data.displayname;\n user.formattedDisplayName = data.formattedDisplayName;\n }\n break;\n }\n case 'email-change': {\n const user = this._participants[userID];\n\n if (user) {\n user.email = data.email;\n }\n break;\n }\n case 'avatar-changed': {\n const user = this._participants[userID];\n\n if (user) {\n user.avatarURL = data.avatarURL;\n }\n break;\n }\n case 'on-stage-participant-changed':\n this._onStageParticipant = userID;\n this.emit('largeVideoChanged');\n break;\n case 'large-video-visibility-changed':\n this._isLargeVideoVisible = data.isVisible;\n this.emit('largeVideoChanged');\n break;\n case 'video-conference-left':\n changeParticipantNumber(this, -1);\n delete this._participants[this._myUserID];\n break;\n case 'video-quality-changed':\n this._videoQuality = data.videoQuality;\n break;\n case 'local-storage-changed':\n jitsiLocalStorage.setItem('jitsiLocalStorage', data.localStorageContent);\n\n // Since this is internal event we don't need to emit it to the consumer of the API.\n return true;\n }\n\n const eventName = events[name];\n\n if (eventName) {\n this.emit(eventName, data);\n\n return true;\n }\n\n return false;\n });\n }\n\n /**\n * Adds event listener to Meet Jitsi.\n *\n * @param {string} event - The name of the event.\n * @param {Function} listener - The listener.\n * @returns {void}\n *\n * @deprecated\n * NOTE: This method is not removed for backward comatability purposes.\n */\n addEventListener(event, listener) {\n this.on(event, listener);\n }\n\n /**\n * Adds event listeners to Meet Jitsi.\n *\n * @param {Object} listeners - The object key should be the name of\n * the event and value - the listener.\n * Currently we support the following\n * events:\n * {@code log} - receives event notifications whenever information has\n * been logged and has a log level specified within {@code config.apiLogLevels}.\n * The listener will receive object with the following structure:\n * {{\n * logLevel: the message log level\n * arguments: an array of strings that compose the actual log message\n * }}\n * {@code chatUpdated} - receives event notifications about chat state being\n * updated. The listener will receive object with the following structure:\n * {{\n * 'unreadCount': unreadCounter, // the unread message(s) counter,\n * 'isOpen': isOpen, // whether the chat panel is open or not\n * }}\n * {@code incomingMessage} - receives event notifications about incoming\n * messages. The listener will receive object with the following structure:\n * {{\n * 'from': from,//JID of the user that sent the message\n * 'nick': nick,//the nickname of the user that sent the message\n * 'message': txt//the text of the message\n * }}\n * {@code outgoingMessage} - receives event notifications about outgoing\n * messages. The listener will receive object with the following structure:\n * {{\n * 'message': txt//the text of the message\n * }}\n * {@code displayNameChanged} - receives event notifications about display\n * name change. The listener will receive object with the following\n * structure:\n * {{\n * jid: jid,//the JID of the participant that changed his display name\n * displayname: displayName //the new display name\n * }}\n * {@code participantJoined} - receives event notifications about new\n * participant.\n * The listener will receive object with the following structure:\n * {{\n * jid: jid //the jid of the participant\n * }}\n * {@code participantLeft} - receives event notifications about the\n * participant that left the room.\n * The listener will receive object with the following structure:\n * {{\n * jid: jid //the jid of the participant\n * }}\n * {@code videoConferenceJoined} - receives event notifications about the\n * local user has successfully joined the video conference.\n * The listener will receive object with the following structure:\n * {{\n * roomName: room //the room name of the conference\n * }}\n * {@code videoConferenceLeft} - receives event notifications about the\n * local user has left the video conference.\n * The listener will receive object with the following structure:\n * {{\n * roomName: room //the room name of the conference\n * }}\n * {@code screenSharingStatusChanged} - receives event notifications about\n * turning on/off the local user screen sharing.\n * The listener will receive object with the following structure:\n * {{\n * on: on //whether screen sharing is on\n * }}\n * {@code dominantSpeakerChanged} - receives event notifications about\n * change in the dominant speaker.\n * The listener will receive object with the following structure:\n * {{\n * id: participantId //participantId of the new dominant speaker\n * }}\n * {@code suspendDetected} - receives event notifications about detecting suspend event in host computer.\n * {@code readyToClose} - all hangup operations are completed and Jitsi Meet\n * is ready to be disposed.\n * @returns {void}\n *\n * @deprecated\n * NOTE: This method is not removed for backward comatability purposes.\n */\n addEventListeners(listeners) {\n for (const event in listeners) { // eslint-disable-line guard-for-in\n this.addEventListener(event, listeners[event]);\n }\n }\n\n /**\n * Captures the screenshot of the large video.\n *\n * @returns {Promise} - Resolves with a base64 encoded image data of the screenshot\n * if large video is detected, an error otherwise.\n */\n captureLargeVideoScreenshot() {\n return this._transport.sendRequest({\n name: 'capture-largevideo-screenshot'\n });\n }\n\n /**\n * Removes the listeners and removes the Jitsi Meet frame.\n *\n * @returns {void}\n */\n dispose() {\n this.emit('_willDispose');\n this._transport.dispose();\n this.removeAllListeners();\n if (this._frame && this._frame.parentNode) {\n this._frame.parentNode.removeChild(this._frame);\n }\n }\n\n /**\n * Executes command. The available commands are:\n * {@code displayName} - Sets the display name of the local participant to\n * the value passed in the arguments array.\n * {@code subject} - Sets the subject of the conference, the value passed\n * in the arguments array. Note: Available only for moderator.\n *\n * {@code toggleAudio} - Mutes / unmutes audio with no arguments.\n * {@code toggleVideo} - Mutes / unmutes video with no arguments.\n * {@code toggleFilmStrip} - Hides / shows the filmstrip with no arguments.\n *\n * If the command doesn't require any arguments the parameter should be set\n * to empty array or it may be omitted.\n *\n * @param {string} name - The name of the command.\n * @returns {void}\n */\n executeCommand(name, ...args) {\n if (!(name in commands)) {\n console.error('Not supported command name.');\n\n return;\n }\n this._transport.sendEvent({\n data: args,\n name: commands[name]\n });\n }\n\n /**\n * Executes commands. The available commands are:\n * {@code displayName} - Sets the display name of the local participant to\n * the value passed in the arguments array.\n * {@code toggleAudio} - Mutes / unmutes audio. No arguments.\n * {@code toggleVideo} - Mutes / unmutes video. No arguments.\n * {@code toggleFilmStrip} - Hides / shows the filmstrip. No arguments.\n * {@code toggleChat} - Hides / shows chat. No arguments.\n * {@code toggleShareScreen} - Starts / stops screen sharing. No arguments.\n *\n * @param {Object} commandList - The object with commands to be executed.\n * The keys of the object are the commands that will be executed and the\n * values are the arguments for the command.\n * @returns {void}\n */\n executeCommands(commandList) {\n for (const key in commandList) { // eslint-disable-line guard-for-in\n this.executeCommand(key, commandList[key]);\n }\n }\n\n /**\n * Returns Promise that resolves with a list of available devices.\n *\n * @returns {Promise}\n */\n getAvailableDevices() {\n return getAvailableDevices(this._transport);\n }\n\n /**\n * Gets a list of the currently sharing participant id's.\n *\n * @returns {Promise} - Resolves with the list of participant id's currently sharing.\n */\n getContentSharingParticipants() {\n return this._transport.sendRequest({\n name: 'get-content-sharing-participants'\n });\n }\n\n /**\n * Returns Promise that resolves with current selected devices.\n *\n * @returns {Promise}\n */\n getCurrentDevices() {\n return getCurrentDevices(this._transport);\n }\n\n /**\n * Returns any custom avatars backgrounds.\n *\n * @returns {Promise} - Resolves with the list of custom avatar backgrounds.\n */\n getCustomAvatarBackgrounds() {\n return this._transport.sendRequest({\n name: 'get-custom-avatar-backgrounds'\n });\n }\n\n /**\n * Returns the current livestream url.\n *\n * @returns {Promise} - Resolves with the current livestream URL if exists, with\n * undefined if not and rejects on failure.\n */\n getLivestreamUrl() {\n return this._transport.sendRequest({\n name: 'get-livestream-url'\n });\n }\n\n /**\n * Returns the conference participants information.\n *\n * @returns {Array} - Returns an array containing participants\n * information like participant id, display name, avatar URL and email.\n */\n getParticipantsInfo() {\n const participantIds = Object.keys(this._participants);\n const participantsInfo = Object.values(this._participants);\n\n participantsInfo.forEach((participant, idx) => {\n participant.participantId = participantIds[idx];\n });\n\n return participantsInfo;\n }\n\n /**\n * Returns the current video quality setting.\n *\n * @returns {number}\n */\n getVideoQuality() {\n return this._videoQuality;\n }\n\n /**\n * Check if the audio is available.\n *\n * @returns {Promise} - Resolves with true if the audio available, with\n * false if not and rejects on failure.\n */\n isAudioAvailable() {\n return this._transport.sendRequest({\n name: 'is-audio-available'\n });\n }\n\n /**\n * Returns Promise that resolves with true if the device change is available\n * and with false if not.\n *\n * @param {string} [deviceType] - Values - 'output', 'input' or undefined.\n * Default - 'input'.\n * @returns {Promise}\n */\n isDeviceChangeAvailable(deviceType) {\n return isDeviceChangeAvailable(this._transport, deviceType);\n }\n\n /**\n * Returns Promise that resolves with true if the device list is available\n * and with false if not.\n *\n * @returns {Promise}\n */\n isDeviceListAvailable() {\n return isDeviceListAvailable(this._transport);\n }\n\n /**\n * Returns Promise that resolves with true if multiple audio input is supported\n * and with false if not.\n *\n * @returns {Promise}\n */\n isMultipleAudioInputSupported() {\n return isMultipleAudioInputSupported(this._transport);\n }\n\n /**\n * Invite people to the call.\n *\n * @param {Array} invitees - The invitees.\n * @returns {Promise} - Resolves on success and rejects on failure.\n */\n invite(invitees) {\n if (!Array.isArray(invitees) || invitees.length === 0) {\n return Promise.reject(new TypeError('Invalid Argument'));\n }\n\n return this._transport.sendRequest({\n name: 'invite',\n invitees\n });\n }\n\n /**\n * Returns the audio mute status.\n *\n * @returns {Promise} - Resolves with the audio mute status and rejects on\n * failure.\n */\n isAudioMuted() {\n return this._transport.sendRequest({\n name: 'is-audio-muted'\n });\n }\n\n /**\n * Returns screen sharing status.\n *\n * @returns {Promise} - Resolves with screensharing status and rejects on failure.\n */\n isSharingScreen() {\n return this._transport.sendRequest({\n name: 'is-sharing-screen'\n });\n }\n\n /**\n * Returns the avatar URL of a participant.\n *\n * @param {string} participantId - The id of the participant.\n * @returns {string} The avatar URL.\n */\n getAvatarURL(participantId) {\n const { avatarURL } = this._participants[participantId] || {};\n\n return avatarURL;\n }\n\n /**\n * Returns the display name of a participant.\n *\n * @param {string} participantId - The id of the participant.\n * @returns {string} The display name.\n */\n getDisplayName(participantId) {\n const { displayName } = this._participants[participantId] || {};\n\n return displayName;\n }\n\n /**\n * Returns the email of a participant.\n *\n * @param {string} participantId - The id of the participant.\n * @returns {string} The email.\n */\n getEmail(participantId) {\n const { email } = this._participants[participantId] || {};\n\n return email;\n }\n\n /**\n * Returns the iframe that loads Jitsi Meet.\n *\n * @returns {HTMLElement} The iframe.\n */\n getIFrame() {\n return this._frame;\n }\n\n /**\n * Returns the number of participants in the conference. The local\n * participant is included.\n *\n * @returns {int} The number of participants in the conference.\n */\n getNumberOfParticipants() {\n return this._numberOfParticipants;\n }\n\n /**\n * Check if the video is available.\n *\n * @returns {Promise} - Resolves with true if the video available, with\n * false if not and rejects on failure.\n */\n isVideoAvailable() {\n return this._transport.sendRequest({\n name: 'is-video-available'\n });\n }\n\n /**\n * Returns the audio mute status.\n *\n * @returns {Promise} - Resolves with the audio mute status and rejects on\n * failure.\n */\n isVideoMuted() {\n return this._transport.sendRequest({\n name: 'is-video-muted'\n });\n }\n\n /**\n * Pins a participant's video on to the stage view.\n *\n * @param {string} participantId - Participant id (JID) of the participant\n * that needs to be pinned on the stage view.\n * @returns {void}\n */\n pinParticipant(participantId) {\n this.executeCommand('pinParticipant', participantId);\n }\n\n /**\n * Removes event listener.\n *\n * @param {string} event - The name of the event.\n * @returns {void}\n *\n * @deprecated\n * NOTE: This method is not removed for backward comatability purposes.\n */\n removeEventListener(event) {\n this.removeAllListeners(event);\n }\n\n /**\n * Removes event listeners.\n *\n * @param {Array} eventList - Array with the names of the events.\n * @returns {void}\n *\n * @deprecated\n * NOTE: This method is not removed for backward comatability purposes.\n */\n removeEventListeners(eventList) {\n eventList.forEach(event => this.removeEventListener(event));\n }\n\n /**\n * Resizes the large video container as per the dimensions provided.\n *\n * @param {number} width - Width that needs to be applied on the large video container.\n * @param {number} height - Height that needs to be applied on the large video container.\n * @returns {void}\n */\n resizeLargeVideo(width, height) {\n if (width <= this._width && height <= this._height) {\n this.executeCommand('resizeLargeVideo', width, height);\n }\n }\n\n /**\n * Passes an event along to the local conference participant to establish\n * or update a direct peer connection. This is currently used for developing\n * wireless screensharing with room integration and it is advised against to\n * use as its api may change.\n *\n * @param {Object} event - An object with information to pass along.\n * @param {Object} event.data - The payload of the event.\n * @param {string} event.from - The jid of the sender of the event. Needed\n * when a reply is to be sent regarding the event.\n * @returns {void}\n */\n sendProxyConnectionEvent(event) {\n this._transport.sendEvent({\n data: [ event ],\n name: 'proxy-connection-event'\n });\n }\n\n /**\n * Sets the audio input device to the one with the label or id that is\n * passed.\n *\n * @param {string} label - The label of the new device.\n * @param {string} deviceId - The id of the new device.\n * @returns {Promise}\n */\n setAudioInputDevice(label, deviceId) {\n return setAudioInputDevice(this._transport, label, deviceId);\n }\n\n /**\n * Sets the audio output device to the one with the label or id that is\n * passed.\n *\n * @param {string} label - The label of the new device.\n * @param {string} deviceId - The id of the new device.\n * @returns {Promise}\n */\n setAudioOutputDevice(label, deviceId) {\n return setAudioOutputDevice(this._transport, label, deviceId);\n }\n\n /**\n * Displays the given participant on the large video. If no participant id is specified,\n * dominant and pinned speakers will be taken into consideration while selecting the\n * the large video participant.\n *\n * @param {string} participantId - Jid of the participant to be displayed on the large video.\n * @returns {void}\n */\n setLargeVideoParticipant(participantId) {\n this.executeCommand('setLargeVideoParticipant', participantId);\n }\n\n /**\n * Sets the video input device to the one with the label or id that is\n * passed.\n *\n * @param {string} label - The label of the new device.\n * @param {string} deviceId - The id of the new device.\n * @returns {Promise}\n */\n setVideoInputDevice(label, deviceId) {\n return setVideoInputDevice(this._transport, label, deviceId);\n }\n\n /**\n * Starts a file recording or streaming session depending on the passed on params.\n * For RTMP streams, `rtmpStreamKey` must be passed on. `rtmpBroadcastID` is optional.\n * For youtube streams, `youtubeStreamKey` must be passed on. `youtubeBroadcastID` is optional.\n * For dropbox recording, recording `mode` should be `file` and a dropbox oauth2 token must be provided.\n * For file recording, recording `mode` should be `file` and optionally `shouldShare` could be passed on.\n * No other params should be passed.\n *\n * @param {Object} options - An object with config options to pass along.\n * @param { string } options.mode - Recording mode, either `file` or `stream`.\n * @param { string } options.dropboxToken - Dropbox oauth2 token.\n * @param { boolean } options.shouldShare - Whether the recording should be shared with the participants or not.\n * Only applies to certain jitsi meet deploys.\n * @param { string } options.rtmpStreamKey - The RTMP stream key.\n * @param { string } options.rtmpBroadcastID - The RTMP broacast ID.\n * @param { string } options.youtubeStreamKey - The youtube stream key.\n * @param { string } options.youtubeBroadcastID - The youtube broacast ID.\n * @returns {void}\n */\n startRecording(options) {\n this.executeCommand('startRecording', options);\n }\n\n /**\n * Stops a recording or streaming session that is in progress.\n *\n * @param {string} mode - `file` or `stream`.\n * @returns {void}\n */\n stopRecording(mode) {\n this.executeCommand('startRecording', mode);\n }\n}\n" ], "sourceRoot": "" }