speaker-calibration 2.2.225 → 2.2.227

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -103,7 +103,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core
103
103
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
104
104
 
105
105
  "use strict";
106
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_object_from_entries_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.object.from-entries.js */ \"./node_modules/core-js/modules/es.object.from-entries.js\");\n/* harmony import */ var core_js_modules_es_object_from_entries_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_object_from_entries_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/web.dom-collections.iterator.js */ \"./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_web_url_search_params_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/web.url-search-params.js */ \"./node_modules/core-js/modules/web.url-search-params.js\");\n/* harmony import */ var core_js_modules_web_url_search_params_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_url_search_params_js__WEBPACK_IMPORTED_MODULE_2__);\n\n\n\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\n\n\n// TODO: this was already here before, but appears to be unused\nconst pressFeedbackURI = 'data:audio/mpeg;base64,//uQZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASW5mbwAAAA8AAAALAAATlgAXFxcXFxcXFxcuLi4uLi4uLi5FRUVFRUVFRUVdXV1dXV1dXV10dHR0dHR0dHSLi4uLi4uLi4uioqKioqKioqK6urq6urq6urrR0dHR0dHR0dHo6Ojo6Ojo6Oj///////////8AAAA5TEFNRTMuMTAwAaoAAAAALgYAABSAJAZbTgAAgAAAE5YfafL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//uQZAAAA0YVyhVvQAAAAA0goAABGfWdITn6gAgAADSDAAAAAEWjAwMwMDMFBzCQsw8PMPCwUDgkNMpNzXEoSUTP3s6nJPd4z28k62JNdIwIUHj3nvynRempMmLAo/tff9/3IchyHIch/IxY3SUmG86enD4Pg+fgmfEAIQQcsP+oH//E7/+Ud/1HP/B9AAABMCFFFAAAwDgCyMCVAgQcBQmARAHw0AOGAUgFJgUoL8YKsEvqzGA1APJQAIGBNgDpoBRvQYb6EIGhIkmJg1QA0aH0H4GDBgJ4G55UBpM1AGgUG0wAgOBIUAYJGoGFQ4AkHitxzRSocGMwDYYCwJAWAICgBD8jhwlEqBNsMiAkCBpQY2FxpG61opmucDLrjKi6Fmk5oK9PWVh1DNFM2IaRH/q8mTQgTF4sk0bnv//zEuqRMjYycuuj///5wxZzIvLSMTUxYyZL////86ZBqh4D+QUIABcwBQBLMCmAeTA4wJowO8E2DAeYwQ8CWMDLBHDB1QpIxscoSMwBQJj/WZBA3O4mFMHIAGzAKAVgwmcG8OIV//uSZCIN9VQ4wgd/gAAAAA0g4AABD+S/Di5+qgAAADSAAAAEEzcNTC4yM0m41SLDHAJLSggBKwtKRwb6+IBi4ctbepDskh2KmAgA16NTNrON66ptO40mNa9ayZHVx7zmGPHktZb7vP9xLn4fr+9jeO//8P+z39///9T/////t+d6vf1+c6fP9Hv5cxg4aA4TgkGIYmLbYHGAxaCjHwlM0lwBC4zGwzVG+MFnGoTY8sn0w1MSHA09vAM8ssDCSYAykIABmeCI4AKDMDIRfGbFAjWE8h+BfIEfBoFCTQJUcA5ZIrQDjzQ+gWzxsjDLtE4s46kxjHZZom2SXfyj6uadvNvb0ee/3dX//01YAVKw/FoW3hDrwUDTAwDMVigy8rTYaRNKug2tzzBwxnAx/DOuMhFECAOxWsDO6kAwkdQFH0BiwIgYlAwCgdAwiZBBI1kCC5JcWwCQWMQ/JQnkVFkOVN8oku8yDkjbMiry+2rrLvW/MvT53q/yv+n2///dywQL8DRgOgsrBBi0LGcngZrCZgYxGEAoZ+IplUdGJ1ifHVRh5v/7kmRMDPOhJ0MTn6qAAAANIAAAARDEiQhOf0pAAAA0gAAABAdCcEnCwmbqA1JhbIFwYKEAUGAXgOJo45oXAyjT0MinMgXM2UNoNGyYeLN0ENORMgQC5EYAJlr4Z3L3lgaHG5VO0lWX1q92J3t9sWM+bu9/fe8/VT/L+zq9v+zr9/+//8r71SAAAA9tq0AA1hzXXdxmzgPWzJyU20wh4EDDUSzWI4x4rgMGBd+IImDoAiEBAMCJn2HpqAlRpDIZhbxxp2ASQcGVRJG6RC4xmaZHiYlYPKGGdEGJjIoa4YtICXGHRhGJg2QMkYJADRGfCMTZE5+4ze1gMF1k163DfQrNgh83G3zIYoMdC4wEOwcrzMxMMam0AlYxkKzOgqMDhUuUBgYIQOWiEgwYHAogAwXBAYHAKAVVm0ZW2J1Wno9taaAzuOSF34AjMUjdBOy+pjbpKCil9TG/hOWRkUkxad2pAAAGFlrIADgyUqh1syPqzGQRoUAEDDoFgKMDw7MVA2NJ1sKHaMVghBwfGAgOgJR0migMTBUODDQezBI5jGNQzXD/+5JkjYD20jDN67/kngAADSAAAAEXjN0dTv9SAAAANIAAAASwgEb7HKvHZpiFAM0Bgs8wPYBNNi8MMfMIKRGRlOETOErM6wMGpBTQHTjJEQaKEBoKmlLXGizd5Ax5W2Byh0X6R9YRJ2rQFSKzgZDB0DQDKJHDr/MoZRDsaleN+vVhpoVqzczvZYx+Hdbx1/MuWOZb///Vr1YX93I/6P9KAWAQE8pFZWkOCuFAO0EEAThJ4OYwBQMHIJgUUVrHHRwaURUkZ4YX6MYvO6EDvpgTJY6aVeR7mGcgzBgfQE2YCuA5H9adJQKBCAhAqA53/aS/bk0T1zjIhpmcjVumpqS/ZZ1v6TuOXxF1+49x5d5Knl/Luvw7ua/8P/DdWT+dOkhD5zhvqb0db/93/5AQAQsF3glyO4MAysKti2BGAAdE0L31C4EMAhEAgAu28hgMOFHwEgaYACAFHpko0GM0ia2Yx0/wmKECIhpq5poYK2CTmAQAMhgAQBKYAoARFUAhUQbKhIMAxAFG3eFpLns4drJbaY9+pDVDPZ/QKtLHKNCpsTA6//uSZIEE9GAuRhNfzIAAAA0gAAABEnjLFK588sAAADSAAAAEdTXMSKxfop3DPM5RNbal/EvU7p6/Ie/t93Z1v6OqEAzmEmBoIQcGTCwGMCghPwvOQgUwEbKMZBgNAwOPZioUiMIl/ACXRGoREDB0clmTLApMiq4x2azRlmMM7NijivBEQxUIGvMGdAsjAxgHcDSxgRZANSYAOAgYs0FXAnwaIl43xAcuEVEogHIiFKRHEuREzUfFfSOoEgRyTk8Isema00Fl0gzqujqL/ZT3Krfoq7r1H/AvWzp/yXv/3f/oA0GjFwIZS19BgKAsiCDxuUBAMZ8D6zIZAIFMChweF7GFbQAITYoiSSSvMRBoUJ5l4RGVzOa2hhmAr6mbNSaYcYlxgqAvmAaCEYDAE6yBgAFIpAsGADyaXw+/MSnONGVBjhuNW+/dbYnEQqJJNwIgainmo0TB3Ofkus/yHs5P3dnW/+ryf+QqTEFNRTMuMTAwqqqqqqqqqqqqAABjBgrdYuwIwHSioNCCFkYbBZpMaoVDIRMDhB326ByJkJgYuGdC4P/7kmSwDPT4N0MLn6SAAAANIAAAARDIpRJOePLAAAA0gAAABDAGIA0YOGJhoVGKx+YbQxu2mmHbCT5rII6wYW2ASgYFJDgHYBAIpMARM6WcpEFALUjnWoXbkbwf8AGkx+2FugJGw/l2gIK+vverzfFet8Re/kur09f/f/u6f/1GySAhOMFigxOOnJAAdLIIqmTCCa9ahACTDANMqFMLAIQjQw0EVbjH4aOuN8OAgFCBn0sS0GpU0IAjUJ3MCoPaDTTB4AwnIE7MGrBCjAcgE836g5kUx6AtCKkjKElvKarxnFzLOlKRocalMtnabKM6hpYW5TSrdLe1Kop3e+ZWtymHt445fv9Vfyy/Hn5Xv///v1bXt4M9Z7+o729b+K/4b6pMQU1FMy4xMDCqqqqqqqqqqqoAArJ2QY8DbERAFjDyZMdBUwYDwIEDHduP9KsmPhhMKGHR0ZzTg0NTB4kGhkYqgZ2MZGQRUYNHoGXBgA4HWYEoBbGCNgvJhVgV8ZJaR2GsQJb5g5gRMYD+BQmAhADQNAVRoA4EQAOXUBwAkYBsAVr/+5Jk0w/0GynDE59coAAADSAAAAEULMkADn9SAAAANIAAAATsdabY4ta/VUMV5DuqzWuVs3pSSLmoKyJqFQGpUi+IAy2PdQm57ZU/m8oR6dDu/KvzehHpx5O/KkuvNN/o39SX9fblC3lusxd7wMr2zmhS+YLExsQBmRRQGKE6HITacxM2hgy8ATH50NVDsxSlQMPDL4bNJAg7HUAIBQcOjCRbMBtAdDAAACkwB4EWMCzCGTGll+U7EVMUMoPCSjDHgWcwaECqP+mza0I1QpATkY0Sm3lwsB0q0C3xd6GWuF4jEAeiqacWb5bdVxJbap8YzlnZWta3hLq34RaGf5hj3/pZ3HveY/3ku7/5a/7Wf//9/92aGoPcO9Z3nep/9H+mTEFNRTMuMTAwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqgBOZ2IMSwdMDATGQhDC4ZXKRj8wGMxub0k5717G//uSZPaO9axfvJOfPEAAAA0gAAABFsja3g5/cEAAADSAAAAELQSBSmZKFYVCYsIjBA1MCgYxWdDkBzMRAEwgQDIIBMgFIzWQTUjgPK3c02lpDWsiqM0Ih0w6QzjB4BzMDcD4wFgEzAfAeQQs8TcsNydp+n5wlq8UapFM2auMpwfZrv475ll25Y5ll3mtzMuwCWO8Ocqe/lndv+j/b1f6/9QATU2x0wCPIAYTCoUHAxhIYX2MXBDC24mvTCAedLotPVa09tEZwuBrSZmkoXXBgkY2SmmPBjQkpGrwfaYZQGhQDcPACJNPw90xLlijCVZWUifsophFk7ww7v7fGk6gE/vB+l0VNkSFwo0bYXJC6gyQQEiwvlDzbHAhHpZLIQbJ1UxBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUASWNHVvyNdkdcuCnNLhmA8HuRIHbo/1AhfJ9JZVctla8gMQwpDT96eCGcDAGg8qCCIBce3D8P35RGMZXL8gcmxBByacE9hDD09hNohydtFshlp7EeIe9aMiMe/P/7kmTNjPTPJLaLvPDwAAANIAAAAQ/obuBt+FJAAAA0gAAABEchD3bEIchgekEBmZYRmyPAM3j4DJ8fhgfmeIjtD4HTwPAiPgNGB+BAAjtCABG8AwMvgwAEo5cSIfzt69YYDMdo9RxSsKtgIcom1PMylIK9rWkMkKzctAIIkqXCTqLYAoUrBCJrAlHzJipaMuaPvWraLnsMj6ExUtGUZ0ZRnJ7Q6PrnS7VrsC55kSlRyTYjonPkkybMT2AyVMrbMrYly661bq13Fz0K2JlbEdH1zk9ocnsB09CcutLYmj71p7Q6PWDI+hMXWjJ06Mozk9odH0BkfQmLrRlGdE6M5JrhKJzZKPoSSephKVHJlGcmLhkZXJJ9CYnrRkqSmMZybKpMQU1FMy4xMDCqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr/+5Jk7QT0dTc4kxw0ogAADSAAAAEZOaLm5+WQSAAANIAAAASqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqglFJEIRoPjA2MDYyViqViCJxDHghjyPQ4ioUiYKw4EMzYZXAooDEE1y2zRpTu00acWUWWcacaUWYeWcacJAhYgWJFCRQGIFiBZZRZRZlw7s7PG////s7M7Ozs7M5xpRZR5RRpxZRZh5RRZRbRC1NP///9PKqqq4NNNNRKqJXTTTTVVVTEFNRTMuMTAwVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//uSZIIP9BFGHYksMlIAAA0gAAABAAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ==';\n\n/**\r\n * @typedef initParameters - Parameters for initializing the AudioPeer\r\n * @type {object}\r\n * @property {string} targetElementId - Target element where new elements will be appended.\r\n * @property {string} siteUrl: The url of the current site.\r\n */\nconst initParameters = {\n targetElementId: null,\n siteUrl: null\n};\n\n/**\r\n * @class The first layer of abstraction on the PeerJS library.\r\n * It meant to be extended by the two seperate client classes, Speaker and Listener.\r\n * It implements the shared methods and properties of both classes.\r\n */\nclass AudioPeer {\n /**\r\n * Creates an instance of AudioPeer\r\n * Takes the url of the current site and a target element where html elements will be appended.\r\n *\r\n * @param params - See type definition for initParameters.\r\n * @param param\r\n * @example\r\n */\n constructor() {\n var _this = this;\n let param = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initParameters;\n /** .\r\n * .\r\n * .\r\n * Helper method to display information to DOM element\r\n *\r\n * @param {string} message\r\n * @param {boolean} append\r\n * @example\r\n */\n _defineProperty(this, \"displayUpdate\", function (message) {\n let append = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n // If the specified elem exists, update that elem\n if (document.getElementById(_this.targetElement)) {\n const displayElement = document.getElementById(_this.targetElement);\n if (append) {\n displayElement.innerText += \"\\n\".concat(message);\n } else {\n displayElement.innerText = message;\n }\n } else {\n console.log('MESSAGE: ', message);\n }\n });\n /**\r\n * Callback method for when a peer connection is lost\r\n * saves the last peer id, last server id, and attempts to reconnect.\r\n *\r\n * @example\r\n */\n _defineProperty(this, \"onPeerDisconnected\", () => {\n this.displayUpdate('Connection lost. Please reconnect');\n\n // Workaround for peer.reconnect deleting previous id\n try {\n this.peer.id = this.lastPeerId;\n // eslint-disable-next-line no-underscore-dangle\n this.peer._lastServerId = this.lastPeerId;\n this.peer.reconnect();\n } catch (e) {\n console.log(e);\n }\n });\n /** .\r\n * .\r\n * .\r\n * Callback method that cleans up after peer connection is closed\r\n *\r\n * @example\r\n */\n _defineProperty(this, \"onPeerClose\", () => {\n this.displayUpdate('Connection closed');\n this.conn = null;\n });\n /** .\r\n * .\r\n * .\r\n * Helper method for when an error occurs\r\n *\r\n * @param {*} err\r\n * @example\r\n */\n _defineProperty(this, \"onPeerError\", err => {\n this.displayUpdate(err);\n console.log(\"\".concat(err));\n });\n /** .\r\n * .\r\n * .\r\n * Helper method that converts url paramters to an object\r\n *\r\n * @returns {object}\r\n * @example\r\n */\n _defineProperty(this, \"parseURLSearchParams\", () =>\n // SOURCE: chickens, https://stackoverflow.com/questions/8648892/how-to-convert-url-parameters-to-a-javascript-object\n // eslint-disable-next-line no-restricted-globals\n Object.fromEntries(new URLSearchParams(location.search)));\n /** .\r\n * .\r\n * .\r\n * Helper method that converts an object to a query string\r\n *\r\n * @param {object} params\r\n * @returns {string}\r\n * @example\r\n */\n _defineProperty(this, \"queryStringFromObject\", params => Object.keys(params).map(key => \"\".concat(key, \"=\").concat(params[key])).join('&'));\n this.conn = null;\n this.lastPeerId = null;\n\n // Display information to HTML elem with given id\n this.targetElement = param.targetElementId;\n this.siteUrl = param.siteUrl;\n this.debug = false;\n // Store for all incoming data\n this.dataStore = [];\n\n // Create and play sounds using this audio context\n this.sourceAudioContext = new (window.AudioContext || window.webkitAudioContext || window.audioContext)();\n }\n}\n_defineProperty(AudioPeer, \"keypressFeedbackSound\", pressFeedbackURI);\n/* harmony default export */ __webpack_exports__[\"default\"] = (AudioPeer);\n\n//# sourceURL=webpack://speakerCalibrator/./src/peer-connection/audioPeer.js?");
106
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_object_from_entries_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.object.from-entries.js */ \"./node_modules/core-js/modules/es.object.from-entries.js\");\n/* harmony import */ var core_js_modules_es_object_from_entries_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_object_from_entries_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/web.dom-collections.iterator.js */ \"./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_web_url_search_params_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/web.url-search-params.js */ \"./node_modules/core-js/modules/web.url-search-params.js\");\n/* harmony import */ var core_js_modules_web_url_search_params_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_url_search_params_js__WEBPACK_IMPORTED_MODULE_2__);\n\n\n\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\n\n\n// TODO: this was already here before, but appears to be unused\nconst pressFeedbackURI = 'data:audio/mpeg;base64,//uQZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASW5mbwAAAA8AAAALAAATlgAXFxcXFxcXFxcuLi4uLi4uLi5FRUVFRUVFRUVdXV1dXV1dXV10dHR0dHR0dHSLi4uLi4uLi4uioqKioqKioqK6urq6urq6urrR0dHR0dHR0dHo6Ojo6Ojo6Oj///////////8AAAA5TEFNRTMuMTAwAaoAAAAALgYAABSAJAZbTgAAgAAAE5YfafL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//uQZAAAA0YVyhVvQAAAAA0goAABGfWdITn6gAgAADSDAAAAAEWjAwMwMDMFBzCQsw8PMPCwUDgkNMpNzXEoSUTP3s6nJPd4z28k62JNdIwIUHj3nvynRempMmLAo/tff9/3IchyHIch/IxY3SUmG86enD4Pg+fgmfEAIQQcsP+oH//E7/+Ud/1HP/B9AAABMCFFFAAAwDgCyMCVAgQcBQmARAHw0AOGAUgFJgUoL8YKsEvqzGA1APJQAIGBNgDpoBRvQYb6EIGhIkmJg1QA0aH0H4GDBgJ4G55UBpM1AGgUG0wAgOBIUAYJGoGFQ4AkHitxzRSocGMwDYYCwJAWAICgBD8jhwlEqBNsMiAkCBpQY2FxpG61opmucDLrjKi6Fmk5oK9PWVh1DNFM2IaRH/q8mTQgTF4sk0bnv//zEuqRMjYycuuj///5wxZzIvLSMTUxYyZL////86ZBqh4D+QUIABcwBQBLMCmAeTA4wJowO8E2DAeYwQ8CWMDLBHDB1QpIxscoSMwBQJj/WZBA3O4mFMHIAGzAKAVgwmcG8OIV//uSZCIN9VQ4wgd/gAAAAA0g4AABD+S/Di5+qgAAADSAAAAEEzcNTC4yM0m41SLDHAJLSggBKwtKRwb6+IBi4ctbepDskh2KmAgA16NTNrON66ptO40mNa9ayZHVx7zmGPHktZb7vP9xLn4fr+9jeO//8P+z39///9T/////t+d6vf1+c6fP9Hv5cxg4aA4TgkGIYmLbYHGAxaCjHwlM0lwBC4zGwzVG+MFnGoTY8sn0w1MSHA09vAM8ssDCSYAykIABmeCI4AKDMDIRfGbFAjWE8h+BfIEfBoFCTQJUcA5ZIrQDjzQ+gWzxsjDLtE4s46kxjHZZom2SXfyj6uadvNvb0ee/3dX//01YAVKw/FoW3hDrwUDTAwDMVigy8rTYaRNKug2tzzBwxnAx/DOuMhFECAOxWsDO6kAwkdQFH0BiwIgYlAwCgdAwiZBBI1kCC5JcWwCQWMQ/JQnkVFkOVN8oku8yDkjbMiry+2rrLvW/MvT53q/yv+n2///dywQL8DRgOgsrBBi0LGcngZrCZgYxGEAoZ+IplUdGJ1ifHVRh5v/7kmRMDPOhJ0MTn6qAAAANIAAAARDEiQhOf0pAAAA0gAAABAdCcEnCwmbqA1JhbIFwYKEAUGAXgOJo45oXAyjT0MinMgXM2UNoNGyYeLN0ENORMgQC5EYAJlr4Z3L3lgaHG5VO0lWX1q92J3t9sWM+bu9/fe8/VT/L+zq9v+zr9/+//8r71SAAAA9tq0AA1hzXXdxmzgPWzJyU20wh4EDDUSzWI4x4rgMGBd+IImDoAiEBAMCJn2HpqAlRpDIZhbxxp2ASQcGVRJG6RC4xmaZHiYlYPKGGdEGJjIoa4YtICXGHRhGJg2QMkYJADRGfCMTZE5+4ze1gMF1k163DfQrNgh83G3zIYoMdC4wEOwcrzMxMMam0AlYxkKzOgqMDhUuUBgYIQOWiEgwYHAogAwXBAYHAKAVVm0ZW2J1Wno9taaAzuOSF34AjMUjdBOy+pjbpKCil9TG/hOWRkUkxad2pAAAGFlrIADgyUqh1syPqzGQRoUAEDDoFgKMDw7MVA2NJ1sKHaMVghBwfGAgOgJR0migMTBUODDQezBI5jGNQzXD/+5JkjYD20jDN67/kngAADSAAAAEXjN0dTv9SAAAANIAAAASwgEb7HKvHZpiFAM0Bgs8wPYBNNi8MMfMIKRGRlOETOErM6wMGpBTQHTjJEQaKEBoKmlLXGizd5Ax5W2Byh0X6R9YRJ2rQFSKzgZDB0DQDKJHDr/MoZRDsaleN+vVhpoVqzczvZYx+Hdbx1/MuWOZb///Vr1YX93I/6P9KAWAQE8pFZWkOCuFAO0EEAThJ4OYwBQMHIJgUUVrHHRwaURUkZ4YX6MYvO6EDvpgTJY6aVeR7mGcgzBgfQE2YCuA5H9adJQKBCAhAqA53/aS/bk0T1zjIhpmcjVumpqS/ZZ1v6TuOXxF1+49x5d5Knl/Luvw7ua/8P/DdWT+dOkhD5zhvqb0db/93/5AQAQsF3glyO4MAysKti2BGAAdE0L31C4EMAhEAgAu28hgMOFHwEgaYACAFHpko0GM0ia2Yx0/wmKECIhpq5poYK2CTmAQAMhgAQBKYAoARFUAhUQbKhIMAxAFG3eFpLns4drJbaY9+pDVDPZ/QKtLHKNCpsTA6//uSZIEE9GAuRhNfzIAAAA0gAAABEnjLFK588sAAADSAAAAEdTXMSKxfop3DPM5RNbal/EvU7p6/Ie/t93Z1v6OqEAzmEmBoIQcGTCwGMCghPwvOQgUwEbKMZBgNAwOPZioUiMIl/ACXRGoREDB0clmTLApMiq4x2azRlmMM7NijivBEQxUIGvMGdAsjAxgHcDSxgRZANSYAOAgYs0FXAnwaIl43xAcuEVEogHIiFKRHEuREzUfFfSOoEgRyTk8Isema00Fl0gzqujqL/ZT3Krfoq7r1H/AvWzp/yXv/3f/oA0GjFwIZS19BgKAsiCDxuUBAMZ8D6zIZAIFMChweF7GFbQAITYoiSSSvMRBoUJ5l4RGVzOa2hhmAr6mbNSaYcYlxgqAvmAaCEYDAE6yBgAFIpAsGADyaXw+/MSnONGVBjhuNW+/dbYnEQqJJNwIgainmo0TB3Ofkus/yHs5P3dnW/+ryf+QqTEFNRTMuMTAwqqqqqqqqqqqqAABjBgrdYuwIwHSioNCCFkYbBZpMaoVDIRMDhB326ByJkJgYuGdC4P/7kmSwDPT4N0MLn6SAAAANIAAAARDIpRJOePLAAAA0gAAABDAGIA0YOGJhoVGKx+YbQxu2mmHbCT5rII6wYW2ASgYFJDgHYBAIpMARM6WcpEFALUjnWoXbkbwf8AGkx+2FugJGw/l2gIK+vverzfFet8Re/kur09f/f/u6f/1GySAhOMFigxOOnJAAdLIIqmTCCa9ahACTDANMqFMLAIQjQw0EVbjH4aOuN8OAgFCBn0sS0GpU0IAjUJ3MCoPaDTTB4AwnIE7MGrBCjAcgE836g5kUx6AtCKkjKElvKarxnFzLOlKRocalMtnabKM6hpYW5TSrdLe1Kop3e+ZWtymHt445fv9Vfyy/Hn5Xv///v1bXt4M9Z7+o729b+K/4b6pMQU1FMy4xMDCqqqqqqqqqqqoAArJ2QY8DbERAFjDyZMdBUwYDwIEDHduP9KsmPhhMKGHR0ZzTg0NTB4kGhkYqgZ2MZGQRUYNHoGXBgA4HWYEoBbGCNgvJhVgV8ZJaR2GsQJb5g5gRMYD+BQmAhADQNAVRoA4EQAOXUBwAkYBsAVr/+5Jk0w/0GynDE59coAAADSAAAAEULMkADn9SAAAANIAAAATsdabY4ta/VUMV5DuqzWuVs3pSSLmoKyJqFQGpUi+IAy2PdQm57ZU/m8oR6dDu/KvzehHpx5O/KkuvNN/o39SX9fblC3lusxd7wMr2zmhS+YLExsQBmRRQGKE6HITacxM2hgy8ATH50NVDsxSlQMPDL4bNJAg7HUAIBQcOjCRbMBtAdDAAACkwB4EWMCzCGTGll+U7EVMUMoPCSjDHgWcwaECqP+mza0I1QpATkY0Sm3lwsB0q0C3xd6GWuF4jEAeiqacWb5bdVxJbap8YzlnZWta3hLq34RaGf5hj3/pZ3HveY/3ku7/5a/7Wf//9/92aGoPcO9Z3nep/9H+mTEFNRTMuMTAwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqgBOZ2IMSwdMDATGQhDC4ZXKRj8wGMxub0k5717G//uSZPaO9axfvJOfPEAAAA0gAAABFsja3g5/cEAAADSAAAAELQSBSmZKFYVCYsIjBA1MCgYxWdDkBzMRAEwgQDIIBMgFIzWQTUjgPK3c02lpDWsiqM0Ih0w6QzjB4BzMDcD4wFgEzAfAeQQs8TcsNydp+n5wlq8UapFM2auMpwfZrv475ll25Y5ll3mtzMuwCWO8Ocqe/lndv+j/b1f6/9QATU2x0wCPIAYTCoUHAxhIYX2MXBDC24mvTCAedLotPVa09tEZwuBrSZmkoXXBgkY2SmmPBjQkpGrwfaYZQGhQDcPACJNPw90xLlijCVZWUifsophFk7ww7v7fGk6gE/vB+l0VNkSFwo0bYXJC6gyQQEiwvlDzbHAhHpZLIQbJ1UxBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUASWNHVvyNdkdcuCnNLhmA8HuRIHbo/1AhfJ9JZVctla8gMQwpDT96eCGcDAGg8qCCIBce3D8P35RGMZXL8gcmxBByacE9hDD09hNohydtFshlp7EeIe9aMiMe/P/7kmTNjPTPJLaLvPDwAAANIAAAAQ/obuBt+FJAAAA0gAAABEchD3bEIchgekEBmZYRmyPAM3j4DJ8fhgfmeIjtD4HTwPAiPgNGB+BAAjtCABG8AwMvgwAEo5cSIfzt69YYDMdo9RxSsKtgIcom1PMylIK9rWkMkKzctAIIkqXCTqLYAoUrBCJrAlHzJipaMuaPvWraLnsMj6ExUtGUZ0ZRnJ7Q6PrnS7VrsC55kSlRyTYjonPkkybMT2AyVMrbMrYly661bq13Fz0K2JlbEdH1zk9ocnsB09CcutLYmj71p7Q6PWDI+hMXWjJ06Mozk9odH0BkfQmLrRlGdE6M5JrhKJzZKPoSSephKVHJlGcmLhkZXJJ9CYnrRkqSmMZybKpMQU1FMy4xMDCqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr/+5Jk7QT0dTc4kxw0ogAADSAAAAEZOaLm5+WQSAAANIAAAASqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqglFJEIRoPjA2MDYyViqViCJxDHghjyPQ4ioUiYKw4EMzYZXAooDEE1y2zRpTu00acWUWWcacaUWYeWcacJAhYgWJFCRQGIFiBZZRZRZlw7s7PG////s7M7Ozs7M5xpRZR5RRpxZRZh5RRZRbRC1NP///9PKqqq4NNNNRKqJXTTTTVVVTEFNRTMuMTAwVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//uSZIIP9BFGHYksMlIAAA0gAAABAAABpAAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ==';\n\n/**\r\n * @typedef initParameters - Parameters for initializing the AudioPeer\r\n * @type {object}\r\n * @property {string} targetElementId - Target element where new elements will be appended.\r\n * @property {string} siteUrl: The url of the current site.\r\n */\nconst initParameters = {\n targetElementId: null,\n siteUrl: null\n};\n\n/**\r\n * @class The first layer of abstraction on the PeerJS library.\r\n * It meant to be extended by the two seperate client classes, Speaker and Listener.\r\n * It implements the shared methods and properties of both classes.\r\n */\nclass AudioPeer {\n /**\r\n * Creates an instance of AudioPeer\r\n * Takes the url of the current site and a target element where html elements will be appended.\r\n *\r\n * @param params - See type definition for initParameters.\r\n * @param param\r\n * @example\r\n */\n constructor() {\n var _this = this;\n let param = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initParameters;\n /** .\r\n * .\r\n * .\r\n * Helper method to display information to DOM element\r\n *\r\n * @param {string} message\r\n * @param {boolean} append\r\n * @example\r\n */\n _defineProperty(this, \"displayUpdate\", function (message) {\n let append = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n // If the specified elem exists, update that elem\n if (document.getElementById(_this.targetElement)) {\n const displayElement = document.getElementById(_this.targetElement);\n if (append) {\n displayElement.innerText += \"\\n\".concat(message);\n } else {\n displayElement.innerText = message;\n }\n } else {\n console.log('MESSAGE: ', message);\n }\n });\n /** .\r\n * .\r\n * .\r\n * Helper method that converts url paramters to an object\r\n *\r\n * @returns {object}\r\n * @example\r\n */\n _defineProperty(this, \"parseURLSearchParams\", () =>\n // SOURCE: chickens, https://stackoverflow.com/questions/8648892/how-to-convert-url-parameters-to-a-javascript-object\n // eslint-disable-next-line no-restricted-globals\n Object.fromEntries(new URLSearchParams(location.search)));\n /** .\r\n * .\r\n * .\r\n * Helper method that converts an object to a query string\r\n *\r\n * @param {object} params\r\n * @returns {string}\r\n * @example\r\n */\n _defineProperty(this, \"queryStringFromObject\", params => Object.keys(params).map(key => \"\".concat(key, \"=\").concat(params[key])).join('&'));\n // Display information to HTML elem with given id\n this.targetElement = param.targetElementId;\n this.siteUrl = param.siteUrl;\n this.debug = false;\n // Store for all incoming data\n this.dataStore = [];\n\n // Create and play sounds using this audio context\n this.sourceAudioContext = new (window.AudioContext || window.webkitAudioContext || window.audioContext)();\n }\n}\n_defineProperty(AudioPeer, \"keypressFeedbackSound\", pressFeedbackURI);\n/* harmony default export */ __webpack_exports__[\"default\"] = (AudioPeer);\n\n//# sourceURL=webpack://speakerCalibrator/./src/peer-connection/audioPeer.js?");
107
107
 
108
108
  /***/ }),
109
109
 
@@ -125,7 +125,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
125
125
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
126
126
 
127
127
  "use strict";
128
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array-buffer.slice.js */ \"./node_modules/core-js/modules/es.array-buffer.slice.js\");\n/* harmony import */ var core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.string.replace.js */ \"./node_modules/core-js/modules/es.string.replace.js\");\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_es_typed_array_uint8_array_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.typed-array.uint8-array.js */ \"./node_modules/core-js/modules/es.typed-array.uint8-array.js\");\n/* harmony import */ var core_js_modules_es_typed_array_uint8_array_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_uint8_array_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.typed-array.fill.js */ \"./node_modules/core-js/modules/es.typed-array.fill.js\");\n/* harmony import */ var core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.typed-array.set.js */ \"./node_modules/core-js/modules/es.typed-array.set.js\");\n/* harmony import */ var core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.typed-array.sort.js */ \"./node_modules/core-js/modules/es.typed-array.sort.js\");\n/* harmony import */ var core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/web.dom-collections.iterator.js */ \"./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var qrcode__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! qrcode */ \"./node_modules/qrcode/lib/browser.js\");\n/* harmony import */ var _audioPeer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./audioPeer */ \"./src/peer-connection/audioPeer.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils */ \"./src/utils.js\");\n/* harmony import */ var _peerErrors__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./peerErrors */ \"./src/peer-connection/peerErrors.js\");\n/* harmony import */ var peerjs__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! peerjs */ \"./node_modules/peerjs/dist/bundler.mjs\");\nvar _Speaker;\n\n\n\n\n\n\n\nfunction _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }\nfunction _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError(\"Cannot initialize the same private elements twice on an object\"); }\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nfunction _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }\nfunction _assertClassBrand(e, t, n) { if (\"function\" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError(\"Private element is not present on this object\"); }\n\n\n\n\n\n\n//import {phrases} from '../../dist/example/i18n';\n\n/**\r\n * @class Handles the speaker's side of the connection. Responsible for initiating the connection,\r\n * rendering the QRCode, and answering the call.\r\n * @augments AudioPeer\r\n */\nvar _showQRCode = /*#__PURE__*/new WeakMap();\nvar _showSpinner = /*#__PURE__*/new WeakMap();\nvar _removeUIElems = /*#__PURE__*/new WeakMap();\nvar _onPeerOpen = /*#__PURE__*/new WeakMap();\nvar _onPeerConnection = /*#__PURE__*/new WeakMap();\nvar _onPeerDisconnected = /*#__PURE__*/new WeakMap();\nvar _onPeerError = /*#__PURE__*/new WeakMap();\nvar _onIncomingData = /*#__PURE__*/new WeakMap();\nvar _ready = /*#__PURE__*/new WeakMap();\nclass Speaker extends _audioPeer__WEBPACK_IMPORTED_MODULE_8__[\"default\"] {\n /**\r\n * Takes the url of the current site and a target element where html elements will be appended.\r\n *\r\n * @param params - See type definition for initParameters.\r\n * @param Calibrator - An instance of the AudioCalibrator class, should not use AudioCalibrator directly, instead use an extended class available in /tasks/.\r\n * @param CalibratorInstance\r\n * @example\r\n */\n constructor(_params, _CalibratorInstance) {\n var _params$language, _params$debug, _params$isSmartPhone, _params$calibrateSoun, _params$calibrateSoun2, _params$instructionDi, _params$soundSubtitle, _params$timeToCalibra, _params$soundMessageI, _params$titleDisplayI, _params$timeToCalibra2, _params$isParticipant, _params$isLoudspeaker, _params$micrpohoneIdF, _params$buttonsContai, _params$phrases, _params$calibrateSoun3;\n super(_params);\n _defineProperty(this, \"uri\", '');\n _defineProperty(this, \"qrImage\", void 0);\n _defineProperty(this, \"shortURL\", void 0);\n _defineProperty(this, \"initPeer\", async () => {\n const id = await this.generateTimeBasedPeerID();\n this.peer = new peerjs__WEBPACK_IMPORTED_MODULE_11__[\"default\"](id, {\n secure: true,\n host: 'easyeyes-peer-server.herokuapp.com',\n port: 443,\n config: {\n iceServers: [{\n urls: 'turn:global.relay.metered.ca:80',\n username: 'de884cfc34189cdf1a5dd616',\n credential: 'IcOpouU9/TYBmpHU'\n }, {\n urls: 'turn:global.relay.metered.ca:80?transport=tcp',\n username: 'de884cfc34189cdf1a5dd616',\n credential: 'IcOpouU9/TYBmpHU'\n }, {\n urls: 'turn:global.relay.metered.ca:443',\n username: 'de884cfc34189cdf1a5dd616',\n credential: 'IcOpouU9/TYBmpHU'\n }, {\n urls: 'turns:global.relay.metered.ca:443?transport=tcp',\n username: 'de884cfc34189cdf1a5dd616',\n credential: 'IcOpouU9/TYBmpHU'\n }]\n }\n });\n this.peer.on('open', _classPrivateFieldGet(_onPeerOpen, this));\n this.peer.on('connection', _classPrivateFieldGet(_onPeerConnection, this));\n this.peer.on('close', this.onPeerClose);\n this.peer.on('disconnected', _classPrivateFieldGet(_onPeerDisconnected, this));\n this.peer.on('error', _classPrivateFieldGet(_onPeerError, this));\n });\n _defineProperty(this, \"generateTimeBasedPeerID\", async () => {\n const now = new Date().getTime();\n const randomBuffer = new Uint8Array(10);\n crypto.getRandomValues(randomBuffer);\n const randomPart = Array.from(randomBuffer).map(b => b.toString(36)).join('');\n const toHash = \"\".concat(now, \"-\").concat(randomPart);\n const encoder = new TextEncoder();\n const data = encoder.encode(toHash);\n const hash = await crypto.subtle.digest('SHA-256', data);\n const hashArray = Array.from(new Uint8Array(hash)); // Convert buffer to byte array\n const hashString = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n const shortHash = hashString.substring(0, 12); // Use more of the hash for a longer ID\n // return shortHash; // Consider converting this to Base62\n return this.encodeBase62(parseInt(shortHash, 16));\n });\n _defineProperty(this, \"encodeBase62\", num => {\n const base = 36;\n const characters = '0123456789abcdefghijklmnopqrstuvwxyz';\n let result = '';\n while (num > 0) {\n result = characters[num % base] + result;\n num = Math.floor(num / base);\n }\n return result;\n });\n /**\r\n * Called after the peer conncection has been opened.\r\n * Generates a QR code for the connection and displays it.\r\n *\r\n * @private\r\n * @example\r\n */\n\n _classPrivateFieldInitSpec(this, _showQRCode, async () => {\n const queryStringParameters = {\n speakerPeerId: this.peer.id,\n sp: this.isSmartPhone,\n hz: this.calibrateSoundHz,\n bits: this.calibrateSoundSamplingDesiredBits,\n lang: this.language,\n deviceId: this.deviceId\n };\n const queryString = this.queryStringFromObject(queryStringParameters);\n this.uri = this.siteUrl + queryString;\n if (this.isSmartPhone) {\n // Generate QR code\n const qrCanvas = document.createElement('canvas');\n qrCanvas.setAttribute('id', 'qrCanvas');\n qrcode__WEBPACK_IMPORTED_MODULE_7__.toCanvas(qrCanvas, this.uri, error => {\n if (error) console.error(error);\n });\n\n // Create QR image\n const qrImage = new Image();\n qrImage.setAttribute('id', 'compatibilityCheckQRImage');\n qrImage.style.zIndex = Infinity;\n qrImage.style.height = '150px';\n qrImage.style.width = '150px';\n qrImage.style.margin = '-10px';\n qrImage.style.aspectRatio = 1;\n qrImage.src = qrCanvas.toDataURL();\n this.qrImage = qrImage;\n\n // Get shortened URL\n let shortURL = this.uri;\n try {\n const response = await fetch('https://api.short.io/links/public', {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: 'pk_fysLKGj3legZz4XZ'\n },\n body: JSON.stringify({\n domain: 'listeners.link',\n originalURL: this.uri\n })\n });\n if (!response.ok) {\n throw new Error(\"HTTP error! Status: \".concat(response.status));\n }\n const data = await response.json();\n shortURL = data.shortURL;\n } catch (error) {\n console.error('Error:', error.message);\n }\n\n // Main container with 3 columns\n const container = document.createElement('div');\n container.style.display = 'flex';\n container.style.alignItems = 'flex-start';\n container.style.paddingTop = '0';\n container.id = 'skipQRContainer';\n\n // Column 1: QR Code\n const qrColumn = document.createElement('div');\n qrColumn.style.flex = '0 0 auto';\n qrColumn.appendChild(qrImage);\n\n // Column 2: Explanation Text\n const textColumn = document.createElement('div');\n textColumn.style.flex = '1';\n textColumn.style.padding = '0 20px';\n textColumn.style.maxWidth = '560px';\n const explanation = document.createElement('h2');\n explanation.style.fontSize = '1.1rem';\n explanation.id = 'skipQRExplanation';\n explanation.style.margin = '0';\n explanation.style.textAlign = 'left';\n explanation.innerHTML = (0,_utils__WEBPACK_IMPORTED_MODULE_9__.formatLineBreak)(this.phrases.RC_skipQR_ExplanationWithoutPreferNot[this.language].replace('xxx', \"<b style=\\\"user-select: text\\\">\".concat(shortURL, \"</b>\")).replace('XXX', \"<b style=\\\"user-select: text\\\">\".concat(shortURL, \"</b>\")), this.phrases.RC_checkInternetConnection[this.language]);\n const language = this.language;\n const phrases = this.phrases;\n const checkConnection = document.createElement('a');\n checkConnection.id = 'check-connection';\n checkConnection.href = '#';\n checkConnection.innerHTML = \"check the phone's internet connection\";\n checkConnection.addEventListener('click', function (event) {\n event.preventDefault();\n (0,_utils__WEBPACK_IMPORTED_MODULE_9__.createAndShowPopup)(language, phrases);\n });\n explanation.querySelector('a#check-connection').replaceWith(checkConnection);\n textColumn.appendChild(explanation);\n\n // Column 3: Buttons\n const buttonColumn = document.createElement('div');\n buttonColumn.style.display = 'flex';\n buttonColumn.style.flexDirection = 'column';\n buttonColumn.style.gap = '10px';\n buttonColumn.style.flex = '0 0 auto';\n buttonColumn.style.alignItems = 'flex-end';\n buttonColumn.appendChild(this.buttonsContainer);\n\n // Assemble the columns\n container.appendChild(qrColumn);\n container.appendChild(textColumn);\n container.appendChild(buttonColumn);\n document.getElementById(this.targetElement).appendChild(container);\n } else {\n // show the link to the user\n // If specified HTML Id is available, show QR code there\n if (document.getElementById(this.targetElement)) {\n // const linkTag = document.createElement('a');\n // linkTag.setAttribute('href', uri);\n // linkTag.innerHTML = 'Click here to start the calibration';\n // linkTag.target = '_blank';\n // document.getElementById(this.targetElement).appendChild(linkTag);\n // document.getElementById(this.targetElement).appendChild(qrCanvas);\n\n const proceedButton = document.createElement('button');\n proceedButton.setAttribute('id', 'calibrationProceedButton');\n proceedButton.setAttribute('class', 'btn btn-success');\n proceedButton.innerHTML = this.phrases.T_proceed[this.language];\n proceedButton.onclick = () => {\n // open the link in a new tab\n window.open(this.uri, '_blank');\n // remove the button\n document.getElementById('calibrationProceedButton').remove();\n };\n document.getElementById(this.targetElement).appendChild(proceedButton);\n }\n }\n // or just print it to console\n console.log('TEST: Peer reachable at: ', this.uri);\n });\n _classPrivateFieldInitSpec(this, _showSpinner, () => {\n const spinner = document.createElement('div');\n spinner.className = 'spinner-border ml-auto';\n spinner.role = 'status';\n spinner.ariaHidden = 'true';\n spinner.style.marginTop = '0.8rem';\n document.getElementById(this.targetElement).appendChild(spinner);\n\n // clear instructionDisplay\n const soundMessage = document.getElementById(this.soundMessageId);\n soundMessage.innerHTML = '';\n soundMessage.style.display = 'none';\n const instructionDisplay = document.getElementById(this.instructionDisplayId);\n const background = document.getElementById('background'); // todo: get background id from params\n const subtitle = document.getElementById(this.soundSubtitleId);\n if (subtitle) {\n subtitle.innerHTML = '';\n }\n if (instructionDisplay) {\n instructionDisplay.innerHTML = '';\n instructionDisplay.style.whiteSpace = 'nowrap';\n instructionDisplay.style.fontWeight = 'bold';\n instructionDisplay.style.width = 'fit-content';\n instructionDisplay.innerHTML = this.phrases.RC_soundRecording[this.language];\n let fontSize = 100;\n instructionDisplay.style.fontSize = fontSize + 'px';\n while (instructionDisplay.scrollWidth > background.scrollWidth * 0.9 && fontSize > 10) {\n fontSize--;\n instructionDisplay.style.fontSize = fontSize + 'px';\n }\n // const p = document.createElement('p');\n // // font size\n // p.style.fontSize = '1.1rem';\n // p.style.fontWeight = 'normal';\n // p.style.paddingTop = '20px';\n // const timeToCalibrateText = phrases.RC_howLongToCalibrate['en-US'];\n // p.innerHTML = timeToCalibrateText.replace('111', this.timeToCalibrate);\n // instructionDisplay.appendChild(p);\n }\n const timeToCalibrateDisplay = document.getElementById(this.timeToCalibrateDisplay);\n if (timeToCalibrateDisplay) {\n const timeToCalibrateText = this.phrases.RC_howLongToCalibrate[this.language];\n timeToCalibrateDisplay.innerHTML = timeToCalibrateText.replace('111', this.timeToCalibrate);\n timeToCalibrateDisplay.style.fontWeight = 'normal';\n timeToCalibrateDisplay.style.fontSize = '1rem';\n // timeToCalibrateDisplay.style.paddingTop = '20px';\n }\n\n // Update title - titleDisplayId\n const titleDisplay = document.getElementById(this.titleDisplayId);\n if (titleDisplay) {\n // if (this.isParticipant) {\n // titleDisplay.innerHTML = titleDisplay.innerHTML.replace('3', '4');\n // } else if (this.isSmartPhone) {\n // if (this.isLoudspeakerCalibration) {\n // titleDisplay.innerHTML = titleDisplay.innerHTML.replace('6', '7');\n // } else {\n // titleDisplay.innerHTML = titleDisplay.innerHTML.replace('5', '6');\n // }\n // } else {\n // titleDisplay.innerHTML = titleDisplay.innerHTML.replace('5', '6');\n // }\n if (this.isLoudspeakerCalibration) {\n if (this.isParticipant) {\n titleDisplay.innerHTML = titleDisplay.innerHTML.replace('3', '4');\n } else if (this.isSmartPhone) {\n titleDisplay.innerHTML = titleDisplay.innerHTML.replace('6', '7');\n } else {\n titleDisplay.innerHTML = titleDisplay.innerHTML.replace('4', '5');\n }\n } else {\n if (this.isSmartPhone) {\n titleDisplay.innerHTML = titleDisplay.innerHTML.replace('5', '6');\n } else {\n titleDisplay.innerHTML = titleDisplay.innerHTML.replace('3', '4');\n }\n }\n }\n });\n _classPrivateFieldInitSpec(this, _removeUIElems, () => {\n const parent = document.getElementById(this.targetElement);\n while (parent.firstChild) {\n parent.firstChild.remove();\n }\n });\n /**\r\n * Called when the peer connection is opened.\r\n * Saves the peer id and calls the QR code generator.\r\n *\r\n * @param peerId - The peer id of the peer connection.\r\n * @param id\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onPeerOpen, id => {\n // Workaround for peer.reconnect deleting previous id\n try {\n if (id === null) {\n console.error('Received null id from peer open');\n this.peer.id = this.lastPeerId;\n } else {\n this.lastPeerId = this.peer.id;\n }\n if (id !== this.peer.id) {\n console.warn('DEBUG Check you assumption that id === this.peer.id');\n }\n } catch (error) {\n console.error('Error in #onPeerOpen: ', error);\n }\n _classPrivateFieldGet(_showQRCode, this).call(this);\n });\n /**\r\n * Called when the peer connection is established.\r\n * Enforces a single connection.\r\n *\r\n * @param connection - The connection object.\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onPeerConnection, connection => {\n // Allow only a single connection\n if (this.conn && this.conn.open) {\n connection.on('open', () => {\n connection.send('Already connected to another client');\n setTimeout(() => {\n connection.close();\n }, 500);\n });\n return;\n }\n this.conn = connection;\n console.log('Connected to: ', this.conn.peer);\n _classPrivateFieldGet(_ready, this).call(this);\n });\n /**\r\n * Called when the peer connection is closed.\r\n *\r\n * @private\r\n * @example\r\n */\n _defineProperty(this, \"onPeerClose\", () => {\n this.conn = null;\n console.log('Connection destroyed');\n });\n /**\r\n * Called when the peer connection is disconnected.\r\n * Attempts to reconnect.\r\n *\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onPeerDisconnected, () => {\n console.log('Connection lost. Please reconnect');\n try {\n // Workaround for peer.reconnect deleting previous id\n this.peer.id = this.lastPeerId;\n // eslint-disable-next-line no-underscore-dangle\n this.peer._lastServerId = this.lastPeerId;\n this.peer.reconnect();\n } catch (error) {\n console.error('Error in #onPeerDisconnected: ', error);\n }\n });\n /**\r\n * Called when the peer connection encounters an error.\r\n *\r\n * @param error\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onPeerError, error => {\n // TODO: check if this function is needed or not\n console.error(error);\n });\n /**\r\n * Called when data is received from the peer connection.\r\n *\r\n * @param data\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onIncomingData, data => {\n // enforce object type\n if (!Object.prototype.hasOwnProperty.call(data, 'name') || !Object.prototype.hasOwnProperty.call(data, 'payload')) {\n console.error('Received malformed data: ', data);\n return;\n }\n switch (data.name) {\n case 'samplingRate':\n console.log('Received sampling rate from listener: ', data.payload);\n if (!data.payload) {\n this.ac.setSamplingRates(this.calibrateSoundHz);\n } else {\n this.ac.setSamplingRates(data.payload);\n }\n break;\n case 'sampleSize':\n this.ac.setSampleSize(data.payload);\n break;\n case 'deviceType':\n this.ac.setDeviceType(data.payload);\n break;\n case 'deviceName':\n this.ac.setDeviceName(data.payload);\n break;\n case 'flags':\n //this.ac.setDeviceName(data.payload);\n console.log('FLAGS');\n console.log(data.payload);\n this.ac.setFlags(data.payload);\n break;\n case 'deviceInfo':\n this.ac.setDeviceInfo(data.payload);\n console.log('Received device info from listener: ', data.payload);\n break;\n case 'permissionStatus':\n console.log('Received permission status from listener: ', data.payload);\n if (data.payload.type === 'error') {\n this.permissionStatus = 'error';\n this.ac.setPermissionStatus('error');\n } else if (data.payload.type === 'denied') {\n this.permissionStatus = 'denied';\n this.ac.setPermissionStatus('denied');\n } else if (data.payload.type === 'granted') {\n this.permissionStatus = 'granted';\n this.ac.setPermissionStatus('granted');\n console.log('Permission granted');\n }\n break;\n case _peerErrors__WEBPACK_IMPORTED_MODULE_10__.UnsupportedDeviceError.name:\n case _peerErrors__WEBPACK_IMPORTED_MODULE_10__.MissingSpeakerIdError.name:\n throw data.payload;\n break;\n default:\n break;\n }\n });\n /**\r\n * Called when the peer connection is #ready.\r\n *\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _ready, () => {\n // Perform callback with data\n this.conn.on('data', _classPrivateFieldGet(_onIncomingData, this));\n this.conn.on('close', () => {\n console.log('Connection reset<br>Awaiting connection...');\n this.conn = null;\n });\n });\n /** .\r\n * .\r\n * .\r\n * Debug method for downloading the recorded audio\r\n *\r\n * @public\r\n * @example\r\n */\n _defineProperty(this, \"downloadData\", () => {\n this.ac.downloadData();\n });\n _defineProperty(this, \"repeatCalibration\", async (params, stream, CalibratorInstance) => {\n this.ac = CalibratorInstance;\n _classPrivateFieldGet(_removeUIElems, this).call(this);\n _classPrivateFieldGet(_showSpinner, this).call(this);\n console.log('This is a repeat');\n // wrap the calibration process in a promise so we can await it\n return new Promise((resolve, reject) => {\n // Add a permission check handler\n const permissionCheckInterval = setInterval(() => {\n if (this.permissionStatus === 'error' || this.permissionStatus === 'denied') {\n clearInterval(permissionCheckInterval);\n _classPrivateFieldGet(_removeUIElems, this).call(this);\n resolve('permission denied');\n }\n }, 100);\n\n // Start calibration process\n (async () => {\n try {\n const result = await this.ac.startCalibration(stream, params.gainValues, params.ICalib, params.knownIR, params.microphoneName, params.calibrateSoundCheck, params.isSmartPhone, params.calibrateSoundBurstDb, params.calibrateSoundBurstFilteredExtraDb, params.calibrateSoundBurstLevelReTBool, params.calibrateSoundBurstUses1000HzGainBool, params.calibrateSoundBurstRepeats, params.calibrateSoundBurstSec, params._calibrateSoundBurstPreSec, params._calibrateSoundBurstPostSec, params.calibrateSoundHz, params.calibrateSoundIRSec, params.calibrateSoundIIRSec, params.calibrateSoundIIRPhase, params.calibrateSound1000HzPreSec, params.calibrateSound1000HzSec, params.calibrateSound1000HzPostSec, params.calibrateSoundBackgroundSecs, params.calibrateSoundSmoothOctaves, params.calibrateSoundSmoothMinBandwidthHz, params.calibrateSoundPowerBinDesiredSec, params.calibrateSoundPowerDbSDToleratedDb, params.calibrateSoundTaperSec, params.micManufacturer, params.micSerialNumber, params.micModelNumber, params.micModelName, params.calibrateMicrophonesBool, params.authorEmails, params.webAudioDeviceNames, params.IDsToSaveInSoundProfileLibrary, params.restartButton, params.reminder, params.calibrateSoundLimit, params.calibrateSoundBurstNormalizeBy1000HzGainBool, params.calibrateSoundBurstScalarDB, params.calibrateSound1000HzMaxSD_dB, params.calibrateSound1000HzMaxTries, params._calibrateSoundBurstMaxSD_dB, params.calibrateSoundSamplingDesiredBits, params.language, params.loudspeakerModelName, params.phrases, params.soundSubtitleId);\n clearInterval(permissionCheckInterval);\n _classPrivateFieldGet(_removeUIElems, this).call(this);\n resolve(result);\n } catch (error) {\n clearInterval(permissionCheckInterval);\n reject(error);\n }\n })();\n });\n });\n this.language = (_params$language = _params === null || _params === void 0 ? void 0 : _params.language) !== null && _params$language !== void 0 ? _params$language : 'en-US';\n this.siteUrl += '/listener?';\n this.ac = _CalibratorInstance;\n this.result = null;\n this.debug = (_params$debug = _params === null || _params === void 0 ? void 0 : _params.debug) !== null && _params$debug !== void 0 ? _params$debug : false;\n this.isSmartPhone = (_params$isSmartPhone = _params === null || _params === void 0 ? void 0 : _params.isSmartPhone) !== null && _params$isSmartPhone !== void 0 ? _params$isSmartPhone : false;\n this.calibrateSoundHz = (_params$calibrateSoun = _params === null || _params === void 0 ? void 0 : _params.calibrateSoundHz) !== null && _params$calibrateSoun !== void 0 ? _params$calibrateSoun : 48000;\n this.calibrateSoundSamplingDesiredBits = (_params$calibrateSoun2 = _params === null || _params === void 0 ? void 0 : _params.calibrateSoundSamplingDesiredBits) !== null && _params$calibrateSoun2 !== void 0 ? _params$calibrateSoun2 : 24;\n this.instructionDisplayId = (_params$instructionDi = _params === null || _params === void 0 ? void 0 : _params.instructionDisplayId) !== null && _params$instructionDi !== void 0 ? _params$instructionDi : '';\n this.soundSubtitleId = (_params$soundSubtitle = _params === null || _params === void 0 ? void 0 : _params.soundSubtitleId) !== null && _params$soundSubtitle !== void 0 ? _params$soundSubtitle : '';\n this.timeToCalibrateDisplay = (_params$timeToCalibra = _params === null || _params === void 0 ? void 0 : _params.timeToCalibrateId) !== null && _params$timeToCalibra !== void 0 ? _params$timeToCalibra : '';\n this.soundMessageId = (_params$soundMessageI = _params === null || _params === void 0 ? void 0 : _params.soundMessageId) !== null && _params$soundMessageI !== void 0 ? _params$soundMessageI : '';\n this.titleDisplayId = (_params$titleDisplayI = _params === null || _params === void 0 ? void 0 : _params.titleDisplayId) !== null && _params$titleDisplayI !== void 0 ? _params$titleDisplayI : '';\n this.timeToCalibrate = (_params$timeToCalibra2 = _params === null || _params === void 0 ? void 0 : _params.timeToCalibrate) !== null && _params$timeToCalibra2 !== void 0 ? _params$timeToCalibra2 : 10;\n this.isParticipant = (_params$isParticipant = _params === null || _params === void 0 ? void 0 : _params.isParticipant) !== null && _params$isParticipant !== void 0 ? _params$isParticipant : false;\n this.isLoudspeakerCalibration = (_params$isLoudspeaker = _params === null || _params === void 0 ? void 0 : _params.isLoudspeakerCalibration) !== null && _params$isLoudspeaker !== void 0 ? _params$isLoudspeaker : false;\n this.deviceId = (_params$micrpohoneIdF = _params === null || _params === void 0 ? void 0 : _params.micrpohoneIdFromWebAudioApi) !== null && _params$micrpohoneIdF !== void 0 ? _params$micrpohoneIdF : '';\n this.buttonsContainer = (_params$buttonsContai = _params === null || _params === void 0 ? void 0 : _params.buttonsContainer) !== null && _params$buttonsContai !== void 0 ? _params$buttonsContai : document.createElement('div');\n this.phrases = (_params$phrases = _params === null || _params === void 0 ? void 0 : _params.phrases) !== null && _params$phrases !== void 0 ? _params$phrases : {};\n this.permissionStatus = 'pending';\n this.calibrateSoundHz = (_params$calibrateSoun3 = _params === null || _params === void 0 ? void 0 : _params.calibrateSoundHz) !== null && _params$calibrateSoun3 !== void 0 ? _params$calibrateSoun3 : 48000;\n\n /* Set up callbacks that handle any events related to our peer object. */\n }\n}\n\n/* \r\nReferenced links:\r\nhttps://stackoverflow.com/questions/28016664/when-you-pass-this-as-an-argument/28016676#28016676\r\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes\r\nhttps://stackoverflow.com/questions/879152/how-do-i-make-javascript-beep [3]\r\n*/\n_Speaker = Speaker;\n/**\r\n * Async factory method that creates the Speaker object, and returns a promise that resolves to the result of the calibration.\r\n *\r\n * @param params - The parameters to be passed to the peer object.\r\n * @param Calibrator - The class that defines the calibration process.\r\n * @param CalibratorInstance\r\n * @param timeOut - The amount of time to wait before timing out the connection (in milliseconds).\r\n * @public\r\n * @example\r\n */\n_defineProperty(Speaker, \"startCalibration\", async function (params, CalibratorInstance) {\n let timeOut = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 180000;\n window.speaker = new _Speaker(params, CalibratorInstance);\n const {\n speaker\n } = window;\n await speaker.initPeer();\n // wrap the calibration process in a promise so we can await it\n return new Promise((resolve, reject) => {\n // Add a permission check handler\n const permissionCheckInterval = setInterval(() => {\n if (speaker.permissionStatus === 'error' || speaker.permissionStatus === 'denied') {\n clearInterval(permissionCheckInterval);\n _classPrivateFieldGet(_removeUIElems, speaker).call(speaker);\n resolve('permission denied');\n }\n }, 100);\n\n // when a call is received\n speaker.peer.on('call', async call => {\n clearInterval(permissionCheckInterval); // Clear interval when call is received\n // Rest of the existing call handling code...\n call.answer();\n _classPrivateFieldGet(_removeUIElems, speaker).call(speaker);\n _classPrivateFieldGet(_showSpinner, speaker).call(speaker);\n speaker.ac.createLocalAudio(document.getElementById(speaker.targetElement));\n // when we start receiving audio\n call.on('stream', async stream => {\n window.localStream = stream;\n window.localAudio.srcObject = stream;\n window.localAudio.autoplay = false;\n\n // if the sinkSamplingRate is not set sleep\n while (!speaker.ac.sampleRatesSet()) {\n console.log('SinkSamplingRate is undefined, sleeping');\n await (0,_utils__WEBPACK_IMPORTED_MODULE_9__.sleep)(1);\n }\n if (params.displayUpdate) {\n params.displayUpdate.style.display = '';\n }\n\n // resolve when we have a result\n speaker.result = await speaker.ac.startCalibration(stream, params.gainValues, params.ICalib, params.knownIR, params.microphoneName, params.calibrateSoundCheck, params.isSmartPhone, params.calibrateSoundBurstDb, params.calibrateSoundBurstFilteredExtraDb, params.calibrateSoundBurstLevelReTBool, params.calibrateSoundBurstUses1000HzGainBool, params.calibrateSoundBurstRepeats, params.calibrateSoundBurstSec, params._calibrateSoundBurstPreSec, params._calibrateSoundBurstPostSec, params.calibrateSoundHz, params.calibrateSoundIRSec, params.calibrateSoundIIRSec, params.calibrateSoundIIRPhase, params.calibrateSound1000HzPreSec, params.calibrateSound1000HzSec, params.calibrateSound1000HzPostSec, params.calibrateSoundBackgroundSecs, params.calibrateSoundSmoothOctaves, params.calibrateSoundSmoothMinBandwidthHz, params.calibrateSoundPowerBinDesiredSec, params.calibrateSoundPowerDbSDToleratedDb, params.calibrateSoundTaperSec, params.micManufacturer, params.micSerialNumber, params.micModelNumber, params.micModelName, params.calibrateMicrophonesBool, params.authorEmails, params.webAudioDeviceNames, params.IDsToSaveInSoundProfileLibrary, params.restartButton, params.reminder, params.calibrateSoundLimit, params.calibrateSoundBurstNormalizeBy1000HzGainBool, params.calibrateSoundBurstScalarDB, params.calibrateSound1000HzMaxSD_dB, params.calibrateSound1000HzMaxTries, params._calibrateSoundBurstMaxSD_dB, params.calibrateSoundSamplingDesiredBits, params.language, params.loudspeakerModelName, params.phrases, params.soundSubtitleId);\n _classPrivateFieldGet(_removeUIElems, speaker).call(speaker);\n resolve(speaker.result);\n });\n // if we do not receive a result within the timeout, reject\n setTimeout(() => {\n clearInterval(permissionCheckInterval);\n reject(new _peerErrors__WEBPACK_IMPORTED_MODULE_10__.CalibrationTimedOutError(\"Calibration failed to produce a result after \".concat(timeOut / 1000, \" seconds. Try increasing \\\"_timeoutSec\\\", which is currently \").concat(timeOut / 1000, \" seconds.\")));\n }, timeOut);\n });\n });\n});\n_defineProperty(Speaker, \"testIIR\", async function (params, CalibratorInstance, IIR) {\n let timeOut = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 180000;\n window.speaker = new _Speaker(params, CalibratorInstance);\n const {\n speaker\n } = window;\n speaker.initPeer();\n // wrap the calibration process in a promise so we can await it\n return new Promise((resolve, reject) => {\n // when a call is received\n speaker.peer.on('call', async call => {\n // Answer the call (one way)\n call.answer();\n _classPrivateFieldGet(_removeUIElems, speaker).call(speaker);\n _classPrivateFieldGet(_showSpinner, speaker).call(speaker);\n speaker.ac.createLocalAudio(document.getElementById(speaker.targetElement));\n // when we start receiving audio\n call.on('stream', async stream => {\n window.localStream = stream;\n window.localAudio.srcObject = stream;\n window.localAudio.autoplay = false;\n\n // if the sinkSamplingRate is not set sleep\n while (!speaker.ac.sampleRatesSet()) {\n console.log('SinkSamplingRate is undefined, sleeping');\n await (0,_utils__WEBPACK_IMPORTED_MODULE_9__.sleep)(1);\n }\n // resolve when we have a result\n speaker.result = await speaker.ac.playMLSwithIIR(stream, IIR);\n _classPrivateFieldGet(_removeUIElems, speaker).call(speaker);\n resolve(speaker.result);\n });\n // if we do not receive a result within the timeout, reject\n setTimeout(() => {\n reject(new _peerErrors__WEBPACK_IMPORTED_MODULE_10__.CalibrationTimedOutError(\"Calibration failed to produce a result after \".concat(timeOut / 1000, \" seconds. Try increasing \\\"_timeoutSec\\\", which is currently \").concat(timeOut / 1000, \" seconds.\")));\n }, timeOut);\n });\n });\n});\n_defineProperty(Speaker, \"closeConnection\", () => {\n _Speaker.conn = null;\n console.log('Connection destroyed');\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (Speaker);\n\n//# sourceURL=webpack://speakerCalibrator/./src/peer-connection/speaker.js?");
128
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.string.replace.js */ \"./node_modules/core-js/modules/es.string.replace.js\");\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/web.dom-collections.iterator.js */ \"./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var qrcode__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! qrcode */ \"./node_modules/qrcode/lib/browser.js\");\n/* harmony import */ var _audioPeer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./audioPeer */ \"./src/peer-connection/audioPeer.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils */ \"./src/utils.js\");\n/* harmony import */ var _peerErrors__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./peerErrors */ \"./src/peer-connection/peerErrors.js\");\nvar _Speaker;\n\n\nfunction _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }\nfunction _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError(\"Cannot initialize the same private elements twice on an object\"); }\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nfunction _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }\nfunction _assertClassBrand(e, t, n) { if (\"function\" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError(\"Private element is not present on this object\"); }\n\n\n\n\n\n\n//import {phrases} from '../../dist/example/i18n';\n\n/**\r\n * @class Handles the speaker's side of the connection. Responsible for calibration process\r\n * and communication with the listener.\r\n * @augments AudioPeer\r\n */\nvar _showQRCode = /*#__PURE__*/new WeakMap();\nvar _showSpinner = /*#__PURE__*/new WeakMap();\nvar _removeUIElems = /*#__PURE__*/new WeakMap();\nvar _onPeerOpen = /*#__PURE__*/new WeakMap();\nvar _onPeerConnection = /*#__PURE__*/new WeakMap();\nvar _onPeerDisconnected = /*#__PURE__*/new WeakMap();\nvar _onPeerError = /*#__PURE__*/new WeakMap();\nvar _onIncomingData = /*#__PURE__*/new WeakMap();\nvar _ready = /*#__PURE__*/new WeakMap();\nclass Speaker extends _audioPeer__WEBPACK_IMPORTED_MODULE_3__[\"default\"] {\n /**\r\n * Takes the parameters for calibration and a connection manager instance.\r\n *\r\n * @param params - See type definition for initParameters.\r\n * @param CalibratorInstance - An instance of the AudioCalibrator class\r\n * @param connectionManager - An instance of the ConnectionManager class\r\n */\n constructor(params, CalibratorInstance) {\n var _params$language, _params$debug, _params$isSmartPhone, _params$calibrateSoun, _params$calibrateSoun2, _params$instructionDi, _params$soundSubtitle, _params$timeToCalibra, _params$soundMessageI, _params$titleDisplayI, _params$timeToCalibra2, _params$isParticipant, _params$isLoudspeaker, _params$micrpohoneIdF, _params$buttonsContai, _params$phrases, _params$calibrateSoun3;\n let connectionManager = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;\n super(params);\n _defineProperty(this, \"uri\", '');\n _defineProperty(this, \"qrImage\", void 0);\n _defineProperty(this, \"shortURL\", void 0);\n /**\r\n * Called after the peer conncection has been opened.\r\n * Generates a QR code for the connection and displays it.\r\n *\r\n * @private\r\n * @example\r\n */\n\n _classPrivateFieldInitSpec(this, _showQRCode, async () => {\n const queryStringParameters = {\n speakerPeerId: this.peer.id,\n sp: this.isSmartPhone,\n hz: this.calibrateSoundHz,\n bits: this.calibrateSoundSamplingDesiredBits,\n lang: this.language,\n deviceId: this.deviceId\n };\n const queryString = this.queryStringFromObject(queryStringParameters);\n this.uri = this.siteUrl + queryString;\n if (this.isSmartPhone) {\n // Generate QR code\n const qrCanvas = document.createElement('canvas');\n qrCanvas.setAttribute('id', 'qrCanvas');\n qrcode__WEBPACK_IMPORTED_MODULE_2__.toCanvas(qrCanvas, this.uri, error => {\n if (error) console.error(error);\n });\n\n // Create QR image\n const qrImage = new Image();\n qrImage.setAttribute('id', 'compatibilityCheckQRImage');\n qrImage.style.zIndex = Infinity;\n qrImage.style.height = '150px';\n qrImage.style.width = '150px';\n qrImage.style.margin = '-10px';\n qrImage.style.aspectRatio = 1;\n qrImage.src = qrCanvas.toDataURL();\n this.qrImage = qrImage;\n\n // Get shortened URL\n let shortURL = this.uri;\n try {\n const response = await fetch('https://api.short.io/links/public', {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: 'pk_fysLKGj3legZz4XZ'\n },\n body: JSON.stringify({\n domain: 'listeners.link',\n originalURL: this.uri\n })\n });\n if (!response.ok) {\n throw new Error(\"HTTP error! Status: \".concat(response.status));\n }\n const data = await response.json();\n shortURL = data.shortURL;\n } catch (error) {\n console.error('Error:', error.message);\n }\n\n // Main container with 3 columns\n const container = document.createElement('div');\n container.style.display = 'flex';\n container.style.alignItems = 'flex-start';\n container.style.paddingTop = '0';\n container.id = 'skipQRContainer';\n\n // Column 1: QR Code\n const qrColumn = document.createElement('div');\n qrColumn.style.flex = '0 0 auto';\n qrColumn.appendChild(qrImage);\n\n // Column 2: Explanation Text\n const textColumn = document.createElement('div');\n textColumn.style.flex = '1';\n textColumn.style.padding = '0 20px';\n textColumn.style.maxWidth = '560px';\n const explanation = document.createElement('h2');\n explanation.style.fontSize = '1.1rem';\n explanation.id = 'skipQRExplanation';\n explanation.style.margin = '0';\n explanation.style.textAlign = 'left';\n explanation.innerHTML = (0,_utils__WEBPACK_IMPORTED_MODULE_4__.formatLineBreak)(this.phrases.RC_skipQR_ExplanationWithoutPreferNot[this.language].replace('xxx', \"<b style=\\\"user-select: text\\\">\".concat(shortURL, \"</b>\")).replace('XXX', \"<b style=\\\"user-select: text\\\">\".concat(shortURL, \"</b>\")), this.phrases.RC_checkInternetConnection[this.language]);\n const language = this.language;\n const phrases = this.phrases;\n const checkConnection = document.createElement('a');\n checkConnection.id = 'check-connection';\n checkConnection.href = '#';\n checkConnection.innerHTML = \"check the phone's internet connection\";\n checkConnection.addEventListener('click', function (event) {\n event.preventDefault();\n (0,_utils__WEBPACK_IMPORTED_MODULE_4__.createAndShowPopup)(language, phrases);\n });\n explanation.querySelector('a#check-connection').replaceWith(checkConnection);\n textColumn.appendChild(explanation);\n\n // Column 3: Buttons\n const buttonColumn = document.createElement('div');\n buttonColumn.style.display = 'flex';\n buttonColumn.style.flexDirection = 'column';\n buttonColumn.style.gap = '10px';\n buttonColumn.style.flex = '0 0 auto';\n buttonColumn.style.alignItems = 'flex-end';\n buttonColumn.appendChild(this.buttonsContainer);\n\n // Assemble the columns\n container.appendChild(qrColumn);\n container.appendChild(textColumn);\n container.appendChild(buttonColumn);\n document.getElementById(this.targetElement).appendChild(container);\n } else {\n // show the link to the user\n // If specified HTML Id is available, show QR code there\n if (document.getElementById(this.targetElement)) {\n // const linkTag = document.createElement('a');\n // linkTag.setAttribute('href', uri);\n // linkTag.innerHTML = 'Click here to start the calibration';\n // linkTag.target = '_blank';\n // document.getElementById(this.targetElement).appendChild(linkTag);\n // document.getElementById(this.targetElement).appendChild(qrCanvas);\n\n const proceedButton = document.createElement('button');\n proceedButton.setAttribute('id', 'calibrationProceedButton');\n proceedButton.setAttribute('class', 'btn btn-success');\n proceedButton.innerHTML = this.phrases.T_proceed[this.language];\n proceedButton.onclick = () => {\n // open the link in a new tab\n window.open(this.uri, '_blank');\n // remove the button\n document.getElementById('calibrationProceedButton').remove();\n };\n document.getElementById(this.targetElement).appendChild(proceedButton);\n }\n }\n // or just print it to console\n console.log('TEST: Peer reachable at: ', this.uri);\n });\n _classPrivateFieldInitSpec(this, _showSpinner, () => {\n const spinner = document.createElement('div');\n spinner.className = 'spinner-border ml-auto';\n spinner.role = 'status';\n spinner.ariaHidden = 'true';\n spinner.style.marginTop = '0.8rem';\n document.getElementById(this.targetElement).appendChild(spinner);\n\n // clear instructionDisplay\n const soundMessage = document.getElementById(this.soundMessageId);\n soundMessage.innerHTML = '';\n soundMessage.style.display = 'none';\n const instructionDisplay = document.getElementById(this.instructionDisplayId);\n const background = document.getElementById('background'); // todo: get background id from params\n const subtitle = document.getElementById(this.soundSubtitleId);\n if (subtitle) {\n subtitle.innerHTML = '';\n }\n if (instructionDisplay) {\n instructionDisplay.innerHTML = '';\n instructionDisplay.style.whiteSpace = 'nowrap';\n instructionDisplay.style.fontWeight = 'bold';\n instructionDisplay.style.width = 'fit-content';\n instructionDisplay.innerHTML = this.phrases.RC_soundRecording[this.language];\n let fontSize = 100;\n instructionDisplay.style.fontSize = fontSize + 'px';\n while (instructionDisplay.scrollWidth > background.scrollWidth * 0.9 && fontSize > 10) {\n fontSize--;\n instructionDisplay.style.fontSize = fontSize + 'px';\n }\n // const p = document.createElement('p');\n // // font size\n // p.style.fontSize = '1.1rem';\n // p.style.fontWeight = 'normal';\n // p.style.paddingTop = '20px';\n // const timeToCalibrateText = phrases.RC_howLongToCalibrate['en-US'];\n // p.innerHTML = timeToCalibrateText.replace('111', this.timeToCalibrate);\n // instructionDisplay.appendChild(p);\n }\n const timeToCalibrateDisplay = document.getElementById(this.timeToCalibrateDisplay);\n if (timeToCalibrateDisplay) {\n const timeToCalibrateText = this.phrases.RC_howLongToCalibrate[this.language];\n timeToCalibrateDisplay.innerHTML = timeToCalibrateText.replace('111', this.timeToCalibrate);\n timeToCalibrateDisplay.style.fontWeight = 'normal';\n timeToCalibrateDisplay.style.fontSize = '1rem';\n // timeToCalibrateDisplay.style.paddingTop = '20px';\n }\n\n // Update title - titleDisplayId\n const titleDisplay = document.getElementById(this.titleDisplayId);\n if (titleDisplay) {\n // if (this.isParticipant) {\n // titleDisplay.innerHTML = titleDisplay.innerHTML.replace('3', '4');\n // } else if (this.isSmartPhone) {\n // if (this.isLoudspeakerCalibration) {\n // titleDisplay.innerHTML = titleDisplay.innerHTML.replace('6', '7');\n // } else {\n // titleDisplay.innerHTML = titleDisplay.innerHTML.replace('5', '6');\n // }\n // } else {\n // titleDisplay.innerHTML = titleDisplay.innerHTML.replace('5', '6');\n // }\n if (this.isLoudspeakerCalibration) {\n if (this.isParticipant) {\n titleDisplay.innerHTML = titleDisplay.innerHTML.replace('3', '4');\n } else if (this.isSmartPhone) {\n titleDisplay.innerHTML = titleDisplay.innerHTML.replace('6', '7');\n } else {\n titleDisplay.innerHTML = titleDisplay.innerHTML.replace('4', '5');\n }\n } else {\n if (this.isSmartPhone) {\n titleDisplay.innerHTML = titleDisplay.innerHTML.replace('5', '6');\n } else {\n titleDisplay.innerHTML = titleDisplay.innerHTML.replace('3', '4');\n }\n }\n }\n });\n _classPrivateFieldInitSpec(this, _removeUIElems, () => {\n const parent = document.getElementById(this.targetElement);\n while (parent.firstChild) {\n parent.firstChild.remove();\n }\n });\n /**\r\n * Called when the peer connection is opened.\r\n * Saves the peer id and calls the QR code generator.\r\n *\r\n * @param peerId - The peer id of the peer connection.\r\n * @param id\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onPeerOpen, id => {\n // Workaround for peer.reconnect deleting previous id\n try {\n if (id === null) {\n console.error('Received null id from peer open');\n this.peer.id = this.lastPeerId;\n } else {\n this.lastPeerId = this.peer.id;\n }\n if (id !== this.peer.id) {\n console.warn('DEBUG Check you assumption that id === this.peer.id');\n }\n } catch (error) {\n console.error('Error in #onPeerOpen: ', error);\n }\n _classPrivateFieldGet(_showQRCode, this).call(this);\n });\n /**\r\n * Called when the peer connection is established.\r\n * Enforces a single connection.\r\n *\r\n * @param connection - The connection object.\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onPeerConnection, connection => {\n // Allow only a single connection\n if (this.conn && this.conn.open) {\n connection.on('open', () => {\n connection.send('Already connected to another client');\n setTimeout(() => {\n connection.close();\n }, 500);\n });\n return;\n }\n this.conn = connection;\n console.log('Connected to: ', this.conn.peer);\n _classPrivateFieldGet(_ready, this).call(this);\n });\n /**\r\n * Called when the peer connection is closed.\r\n *\r\n * @private\r\n * @example\r\n */\n _defineProperty(this, \"onPeerClose\", () => {\n this.conn = null;\n console.log('Connection destroyed');\n });\n /**\r\n * Called when the peer connection is disconnected.\r\n * Attempts to reconnect.\r\n *\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onPeerDisconnected, () => {\n console.log('Connection lost. Please reconnect');\n try {\n // Workaround for peer.reconnect deleting previous id\n this.peer.id = this.lastPeerId;\n // eslint-disable-next-line no-underscore-dangle\n this.peer._lastServerId = this.lastPeerId;\n this.peer.reconnect();\n } catch (error) {\n console.error('Error in #onPeerDisconnected: ', error);\n }\n });\n /**\r\n * Called when the peer connection encounters an error.\r\n *\r\n * @param error\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onPeerError, error => {\n // TODO: check if this function is needed or not\n console.error(error);\n });\n /**\r\n * Called when data is received from the peer connection.\r\n *\r\n * @param data\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onIncomingData, data => {\n // enforce object type\n if (!Object.prototype.hasOwnProperty.call(data, 'name') || !Object.prototype.hasOwnProperty.call(data, 'payload')) {\n console.error('Received malformed data: ', data);\n return;\n }\n const name = data.payload.name;\n const payload = data.payload.payload;\n switch (name) {\n case 'samplingRate':\n console.log('Received sampling rate from listener: ', payload);\n if (!payload) {\n window.speaker.ac.setSamplingRates(window.speaker.calibrateSoundHz);\n } else {\n window.speaker.ac.setSamplingRates(payload);\n }\n break;\n case 'sampleSize':\n window.speaker.ac.setSampleSize(payload);\n break;\n case 'deviceType':\n window.speaker.ac.setDeviceType(payload);\n break;\n case 'deviceName':\n window.speaker.ac.setDeviceName(payload);\n break;\n case 'flags':\n //this.ac.setDeviceName(data.payload);\n console.log('FLAGS');\n console.log(payload);\n window.speaker.ac.setFlags(payload);\n break;\n case 'deviceInfo':\n window.speaker.ac.setDeviceInfo(payload);\n console.log('Received device info from listener: ', payload);\n break;\n case 'permissionStatus':\n console.log('Received permission status from listener: ', payload);\n if (payload.type === 'error') {\n this.permissionStatus = 'error';\n window.speaker.ac.setPermissionStatus('error');\n } else if (payload.type === 'denied') {\n this.permissionStatus = 'denied';\n window.speaker.ac.setPermissionStatus('denied');\n } else if (payload.type === 'granted') {\n this.permissionStatus = 'granted';\n window.speaker.ac.setPermissionStatus('granted');\n console.log('Permission granted');\n }\n break;\n case _peerErrors__WEBPACK_IMPORTED_MODULE_5__.UnsupportedDeviceError.name:\n case _peerErrors__WEBPACK_IMPORTED_MODULE_5__.MissingSpeakerIdError.name:\n throw payload;\n break;\n default:\n break;\n }\n });\n /**\r\n * Called when the peer connection is #ready.\r\n *\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _ready, () => {\n // Perform callback with data\n this.conn.on('data', _classPrivateFieldGet(_onIncomingData, this));\n this.conn.on('close', () => {\n console.log('Connection reset<br>Awaiting connection...');\n this.conn = null;\n });\n });\n /** .\r\n * .\r\n * .\r\n * Debug method for downloading the recorded audio\r\n *\r\n * @public\r\n * @example\r\n */\n _defineProperty(this, \"downloadData\", () => {\n this.ac.downloadData();\n });\n this.language = (_params$language = params === null || params === void 0 ? void 0 : params.language) !== null && _params$language !== void 0 ? _params$language : 'en-US';\n this.siteUrl += '/listener?';\n // this.ac = CalibratorInstance;\n this.result = null;\n this.debug = (_params$debug = params === null || params === void 0 ? void 0 : params.debug) !== null && _params$debug !== void 0 ? _params$debug : false;\n this.isSmartPhone = (_params$isSmartPhone = params === null || params === void 0 ? void 0 : params.isSmartPhone) !== null && _params$isSmartPhone !== void 0 ? _params$isSmartPhone : false;\n this.calibrateSoundHz = (_params$calibrateSoun = params === null || params === void 0 ? void 0 : params.calibrateSoundHz) !== null && _params$calibrateSoun !== void 0 ? _params$calibrateSoun : 48000;\n this.calibrateSoundSamplingDesiredBits = (_params$calibrateSoun2 = params === null || params === void 0 ? void 0 : params.calibrateSoundSamplingDesiredBits) !== null && _params$calibrateSoun2 !== void 0 ? _params$calibrateSoun2 : 24;\n this.instructionDisplayId = (_params$instructionDi = params === null || params === void 0 ? void 0 : params.instructionDisplayId) !== null && _params$instructionDi !== void 0 ? _params$instructionDi : '';\n this.soundSubtitleId = (_params$soundSubtitle = params === null || params === void 0 ? void 0 : params.soundSubtitleId) !== null && _params$soundSubtitle !== void 0 ? _params$soundSubtitle : '';\n this.timeToCalibrateDisplay = (_params$timeToCalibra = params === null || params === void 0 ? void 0 : params.timeToCalibrateId) !== null && _params$timeToCalibra !== void 0 ? _params$timeToCalibra : '';\n this.soundMessageId = (_params$soundMessageI = params === null || params === void 0 ? void 0 : params.soundMessageId) !== null && _params$soundMessageI !== void 0 ? _params$soundMessageI : '';\n this.titleDisplayId = (_params$titleDisplayI = params === null || params === void 0 ? void 0 : params.titleDisplayId) !== null && _params$titleDisplayI !== void 0 ? _params$titleDisplayI : '';\n this.timeToCalibrate = (_params$timeToCalibra2 = params === null || params === void 0 ? void 0 : params.timeToCalibrate) !== null && _params$timeToCalibra2 !== void 0 ? _params$timeToCalibra2 : 10;\n this.isParticipant = (_params$isParticipant = params === null || params === void 0 ? void 0 : params.isParticipant) !== null && _params$isParticipant !== void 0 ? _params$isParticipant : false;\n this.isLoudspeakerCalibration = (_params$isLoudspeaker = params === null || params === void 0 ? void 0 : params.isLoudspeakerCalibration) !== null && _params$isLoudspeaker !== void 0 ? _params$isLoudspeaker : false;\n this.deviceId = (_params$micrpohoneIdF = params === null || params === void 0 ? void 0 : params.micrpohoneIdFromWebAudioApi) !== null && _params$micrpohoneIdF !== void 0 ? _params$micrpohoneIdF : '';\n this.buttonsContainer = (_params$buttonsContai = params === null || params === void 0 ? void 0 : params.buttonsContainer) !== null && _params$buttonsContai !== void 0 ? _params$buttonsContai : document.createElement('div');\n this.phrases = (_params$phrases = params === null || params === void 0 ? void 0 : params.phrases) !== null && _params$phrases !== void 0 ? _params$phrases : {};\n this.permissionStatus = 'pending';\n this.calibrateSoundHz = (_params$calibrateSoun3 = params === null || params === void 0 ? void 0 : params.calibrateSoundHz) !== null && _params$calibrateSoun3 !== void 0 ? _params$calibrateSoun3 : 48000;\n this.name = 'SoundCalibration'; // Name used for submodule registration\n this.connectionManager = connectionManager;\n\n // Register with connection manager if provided\n if (this.connectionManager) {\n this.connectionManager.registerSubmodule(this);\n }\n }\n // Required method for submodule interface\n onMessage(data, connectionManager) {\n if (!data || !data.name && !data.type) {\n console.error('Received malformed data: ', data);\n return;\n }\n\n // Convert type to name if needed for backward compatibility\n const messageName = data.payload.name;\n const payload = data.payload.payload;\n switch (messageName) {\n case 'samplingRate':\n console.log('Received sampling rate from listener: ', payload);\n if (!payload) {\n window.speaker.ac.setSamplingRates(window.speaker.calibrateSoundHz);\n } else {\n window.speaker.ac.setSamplingRates(payload);\n }\n break;\n case 'sampleSize':\n window.speaker.ac.setSampleSize(payload);\n break;\n case 'deviceType':\n window.speaker.ac.setDeviceType(payload);\n break;\n case 'deviceName':\n window.speaker.ac.setDeviceName(payload);\n break;\n case 'flags':\n console.log('FLAGS');\n console.log(payload);\n window.speaker.ac.setFlags(payload);\n break;\n case 'deviceInfo':\n window.speaker.ac.setDeviceInfo(payload);\n console.log('Received device info from listener: ', payload);\n break;\n case 'permissionStatus':\n console.log('Received permission status from listener: ', payload);\n if (payload.type === 'error') {\n this.permissionStatus = 'error';\n window.speaker.ac.setPermissionStatus('error');\n } else if (payload.type === 'denied') {\n this.permissionStatus = 'denied';\n window.speaker.ac.setPermissionStatus('denied');\n } else if (payload.type === 'granted') {\n this.permissionStatus = 'granted';\n window.speaker.ac.setPermissionStatus('granted');\n console.log('Permission granted');\n }\n break;\n case _peerErrors__WEBPACK_IMPORTED_MODULE_5__.UnsupportedDeviceError.name:\n case _peerErrors__WEBPACK_IMPORTED_MODULE_5__.MissingSpeakerIdError.name:\n throw payload;\n default:\n break;\n }\n }\n\n /**\r\n * Prepares the parameters to send to the listener\r\n * @returns {Object} Parameters for the listener\r\n */\n prepareConnectionParams() {\n var _this$connectionManag;\n const params = {\n type: 'SoundCalibration',\n name: 'SoundCalibration',\n message: 'connectionParams',\n payload: {\n speakerPeerId: (_this$connectionManag = this.connectionManager) === null || _this$connectionManag === void 0 ? void 0 : _this$connectionManag.getPeerID(),\n sp: this.isSmartPhone,\n hz: this.calibrateSoundHz,\n bits: this.calibrateSoundSamplingDesiredBits,\n lang: this.language,\n deviceId: this.deviceId\n }\n };\n console.log('prepareConnectionParams', params);\n return params;\n }\n\n /**\r\n * Async factory method that creates the Speaker object, and returns a promise that resolves to the result of the calibration.\r\n *\r\n * @param params - The parameters to be passed to the peer object.\r\n * @param CalibratorInstance - The class that defines the calibration process.\r\n * @param connectionManager - Instance of the ConnectionManager\r\n * @param timeOut - The amount of time to wait before timing out the connection (in milliseconds).\r\n * @public\r\n */\n}\n\n/* \r\nReferenced links:\r\nhttps://stackoverflow.com/questions/28016664/when-you-pass-this-as-an-argument/28016676#28016676\r\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes\r\nhttps://stackoverflow.com/questions/879152/how-do-i-make-javascript-beep [3]\r\n*/\n_Speaker = Speaker;\n_defineProperty(Speaker, \"startCalibration\", async function (params, CalibratorInstance, connectionManager) {\n let timeOut = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 180000;\n // Create a speaker instance and register with the connection manager\n window.speaker = new _Speaker(params, CalibratorInstance, connectionManager);\n const {\n speaker\n } = window;\n speaker.ac = CalibratorInstance;\n await speaker.connectionManager.waitForPeerConnection();\n await speaker.connectionManager.resolveWhenHandshakeReceived();\n\n // Send connection parameters to the listener\n speaker.connectionManager.send(speaker.prepareConnectionParams());\n\n // wrap the calibration process in a promise so we can await it\n return new Promise((resolve, reject) => {\n // Add a permission check handler\n const permissionCheckInterval = setInterval(() => {\n if (speaker.permissionStatus === 'error' || speaker.permissionStatus === 'denied') {\n clearInterval(permissionCheckInterval);\n _classPrivateFieldGet(_removeUIElems, speaker).call(speaker);\n resolve('permission denied');\n }\n }, 100);\n console.log('Setting up call handler on the peer');\n // Set up call handler on the peer\n speaker.connectionManager.peer.on('call', async call => {\n console.log('Received call from listener');\n clearInterval(permissionCheckInterval); // Clear interval when call is received\n\n // Answer the call\n call.answer();\n _classPrivateFieldGet(_removeUIElems, speaker).call(speaker);\n _classPrivateFieldGet(_showSpinner, speaker).call(speaker);\n speaker.ac.createLocalAudio(document.getElementById(speaker.targetElement));\n\n // when we start receiving audio\n call.on('stream', async stream => {\n window.localStream = stream;\n window.localAudio.srcObject = stream;\n window.localAudio.autoplay = false;\n\n // if the sinkSamplingRate is not set sleep\n while (!speaker.ac.sampleRatesSet()) {\n console.log('SinkSamplingRate is undefined, sleeping');\n await (0,_utils__WEBPACK_IMPORTED_MODULE_4__.sleep)(1);\n }\n if (params.displayUpdate) {\n params.displayUpdate.style.display = '';\n }\n\n // resolve when we have a result\n speaker.result = await speaker.ac.startCalibration(stream, params.gainValues, params.ICalib, params.knownIR, params.microphoneName, params.calibrateSoundCheck, params.isSmartPhone, params.calibrateSoundBurstDb, params.calibrateSoundBurstFilteredExtraDb, params.calibrateSoundBurstLevelReTBool, params.calibrateSoundBurstUses1000HzGainBool, params.calibrateSoundBurstRepeats, params.calibrateSoundBurstSec, params._calibrateSoundBurstPreSec, params._calibrateSoundBurstPostSec, params.calibrateSoundHz, params.calibrateSoundIRSec, params.calibrateSoundIIRSec, params.calibrateSoundIIRPhase, params.calibrateSound1000HzPreSec, params.calibrateSound1000HzSec, params.calibrateSound1000HzPostSec, params.calibrateSoundBackgroundSecs, params.calibrateSoundSmoothOctaves, params.calibrateSoundSmoothMinBandwidthHz, params.calibrateSoundPowerBinDesiredSec, params.calibrateSoundPowerDbSDToleratedDb, params.calibrateSoundTaperSec, params.micManufacturer, params.micSerialNumber, params.micModelNumber, params.micModelName, params.calibrateMicrophonesBool, params.authorEmails, params.webAudioDeviceNames, params.IDsToSaveInSoundProfileLibrary, params.restartButton, params.reminder, params.calibrateSoundLimit, params.calibrateSoundBurstNormalizeBy1000HzGainBool, params.calibrateSoundBurstScalarDB, params.calibrateSound1000HzMaxSD_dB, params.calibrateSound1000HzMaxTries, params._calibrateSoundBurstMaxSD_dB, params.calibrateSoundSamplingDesiredBits, params.language, params.loudspeakerModelName, params.phrases, params.soundSubtitleId, params.calibrateSoundBurstDownsample);\n _classPrivateFieldGet(_removeUIElems, speaker).call(speaker);\n //remove the call\n speaker.connectionManager.peer.off('call');\n resolve(speaker.result);\n });\n\n // if we do not receive a result within the timeout, reject\n setTimeout(() => {\n clearInterval(permissionCheckInterval);\n reject(new _peerErrors__WEBPACK_IMPORTED_MODULE_5__.CalibrationTimedOutError(\"Calibration failed to produce a result after \".concat(timeOut / 1000, \" seconds. Try increasing \\\"_timeoutSec\\\", which is currently \").concat(timeOut / 1000, \" seconds.\")));\n }, timeOut);\n });\n console.log('Call handler set up', speaker.connectionManager.peer);\n });\n});\n_defineProperty(Speaker, \"testIIR\", async function (params, CalibratorInstance, IIR, connectionManager) {\n let timeOut = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 180000;\n window.speaker = new _Speaker(params, CalibratorInstance, connectionManager);\n const {\n speaker\n } = window;\n\n // Set QR code parameters\n connectionManager.setQueryParams(speaker.prepareQRParams());\n\n // wrap the calibration process in a promise so we can await it\n return new Promise((resolve, reject) => {\n // when a call is received\n connectionManager.peer.on('call', async call => {\n // Answer the call (one way)\n call.answer();\n _classPrivateFieldGet(_removeUIElems, speaker).call(speaker);\n _classPrivateFieldGet(_showSpinner, speaker).call(speaker);\n speaker.ac.createLocalAudio(document.getElementById(speaker.targetElement));\n // when we start receiving audio\n call.on('stream', async stream => {\n window.localStream = stream;\n window.localAudio.srcObject = stream;\n window.localAudio.autoplay = false;\n\n // if the sinkSamplingRate is not set sleep\n while (!speaker.ac.sampleRatesSet()) {\n console.log('SinkSamplingRate is undefined, sleeping');\n await (0,_utils__WEBPACK_IMPORTED_MODULE_4__.sleep)(1);\n }\n // resolve when we have a result\n speaker.result = await speaker.ac.playMLSwithIIR(stream, IIR);\n _classPrivateFieldGet(_removeUIElems, speaker).call(speaker);\n resolve(speaker.result);\n });\n // if we do not receive a result within the timeout, reject\n setTimeout(() => {\n reject(new _peerErrors__WEBPACK_IMPORTED_MODULE_5__.CalibrationTimedOutError(\"Calibration failed to produce a result after \".concat(timeOut / 1000, \" seconds. Try increasing \\\"_timeoutSec\\\", which is currently \").concat(timeOut / 1000, \" seconds.\")));\n }, timeOut);\n });\n });\n});\n_defineProperty(Speaker, \"closeConnection\", () => {\n _Speaker.conn = null;\n console.log('Connection destroyed');\n});\n_defineProperty(Speaker, \"repeatCalibration\", async (params, stream, CalibratorInstance) => {\n var _window$speaker, _window$speaker2;\n window.speaker.ac = CalibratorInstance;\n _classPrivateFieldGet(_removeUIElems, _window$speaker = window.speaker).call(_window$speaker);\n _classPrivateFieldGet(_showSpinner, _window$speaker2 = window.speaker).call(_window$speaker2);\n console.log('This is a repeat');\n // wrap the calibration process in a promise so we can await it\n return new Promise((resolve, reject) => {\n // Add a permission check handler\n const permissionCheckInterval = setInterval(() => {\n if (window.speaker.permissionStatus === 'error' || window.speaker.permissionStatus === 'denied') {\n var _window$speaker3;\n clearInterval(permissionCheckInterval);\n _classPrivateFieldGet(_removeUIElems, _window$speaker3 = window.speaker).call(_window$speaker3);\n resolve('permission denied');\n }\n }, 100);\n\n // Start calibration process\n (async () => {\n try {\n var _window$speaker4;\n const result = await window.speaker.ac.startCalibration(stream, params.gainValues, params.ICalib, params.knownIR, params.microphoneName, params.calibrateSoundCheck, params.isSmartPhone, params.calibrateSoundBurstDb, params.calibrateSoundBurstFilteredExtraDb, params.calibrateSoundBurstLevelReTBool, params.calibrateSoundBurstUses1000HzGainBool, params.calibrateSoundBurstRepeats, params.calibrateSoundBurstSec, params._calibrateSoundBurstPreSec, params._calibrateSoundBurstPostSec, params.calibrateSoundHz, params.calibrateSoundIRSec, params.calibrateSoundIIRSec, params.calibrateSoundIIRPhase, params.calibrateSound1000HzPreSec, params.calibrateSound1000HzSec, params.calibrateSound1000HzPostSec, params.calibrateSoundBackgroundSecs, params.calibrateSoundSmoothOctaves, params.calibrateSoundSmoothMinBandwidthHz, params.calibrateSoundPowerBinDesiredSec, params.calibrateSoundPowerDbSDToleratedDb, params.calibrateSoundTaperSec, params.micManufacturer, params.micSerialNumber, params.micModelNumber, params.micModelName, params.calibrateMicrophonesBool, params.authorEmails, params.webAudioDeviceNames, params.IDsToSaveInSoundProfileLibrary, params.restartButton, params.reminder, params.calibrateSoundLimit, params.calibrateSoundBurstNormalizeBy1000HzGainBool, params.calibrateSoundBurstScalarDB, params.calibrateSound1000HzMaxSD_dB, params.calibrateSound1000HzMaxTries, params._calibrateSoundBurstMaxSD_dB, params.calibrateSoundSamplingDesiredBits, params.language, params.loudspeakerModelName, params.phrases, params.soundSubtitleId, params.calibrateSoundBurstDownsample);\n clearInterval(permissionCheckInterval);\n _classPrivateFieldGet(_removeUIElems, _window$speaker4 = window.speaker).call(_window$speaker4);\n resolve(result);\n } catch (error) {\n clearInterval(permissionCheckInterval);\n reject(error);\n }\n })();\n });\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (Speaker);\n\n//# sourceURL=webpack://speakerCalibrator/./src/peer-connection/speaker.js?");
129
129
 
130
130
  /***/ }),
131
131
 
@@ -147,7 +147,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
147
147
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
148
148
 
149
149
  "use strict";
150
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! axios */ \"./node_modules/axios/lib/axios.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ \"./src/utils.js\");\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\n\n\n/**\r\n *\r\n */\nclass PythonServerAPI {\n constructor() {\n // static PYTHON_SERVER_URL ='http://127.0.0.1:5000';\n /** @private */\n _defineProperty(this, \"MAX_RETRY_COUNT\", 3);\n /** @private */\n _defineProperty(this, \"RETRY_DELAY_MS\", 1000);\n /**\r\n * @param data- -\r\n * g = inverted impulse response, when convolved with the impulse\r\n * reponse, they cancel out.\r\n * @param data.payload\r\n * @param data.sampleRate\r\n * @param data.P\r\n * @param data-.payload\r\n * @param data-.sampleRate\r\n * @param data-.P\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getImpulseResponse\", async _ref => {\n let {\n mls,\n sampleRate,\n numPeriods,\n sig,\n fs2,\n L_new_n,\n dL_n\n } = _ref;\n const task = 'impulse-response';\n let res = null;\n const data = JSON.stringify({\n task,\n 'sample-rate': sampleRate,\n mls,\n numPeriods,\n sig,\n fs2,\n L_new_n,\n dL_n\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getAutocorrelation\", async _ref2 => {\n let {\n mls,\n payload,\n sampleRate,\n numPeriods\n } = _ref2;\n const task = 'autocorrelation';\n let res = null;\n const data = JSON.stringify({\n task,\n payload: payload,\n 'sample-rate': sampleRate,\n mls,\n numPeriods\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getConvolution\", async _ref3 => {\n let {\n mls,\n inverse_response,\n inverse_response_no_bandpass,\n attenuatorGain_dB,\n mls_amplitude\n } = _ref3;\n const task = 'convolution';\n let res = null;\n const data = JSON.stringify({\n task,\n mls,\n inverse_response,\n inverse_response_no_bandpass,\n attenuatorGain_dB,\n mls_amplitude\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getMLS\", async _ref4 => {\n let {\n length,\n amplitude,\n calibrateSoundBurstMLSVersions\n } = _ref4;\n const task = 'mls';\n let res = null;\n const data = JSON.stringify({\n task,\n length: length,\n amplitude: amplitude,\n calibrateSoundBurstMLSVersions: calibrateSoundBurstMLSVersions\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getShortURL\", async originalURL => {\n const task = 'url';\n let res = null;\n console.log(originalURL);\n const data = JSON.stringify({\n URL: originalURL\n });\n console.log(data);\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n console.log(res.data[task]);\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getMemory\", async () => {\n let res;\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/memory\",\n headers: {\n 'Content-Type': 'application/json'\n }\n }).then(response => {\n console.log('memory used:', Math.round(response.data['memory']), 'mb');\n res = response.data['memory'];\n }).catch(error => {\n throw error;\n });\n return res;\n });\n _defineProperty(this, \"checkMemory\", async () => {\n console.log('wait for memory under 500 mb to continue calibration');\n await this.getMemory();\n // let memory = await this.getMemory();\n // while (memory >= 500) {\n // console.log(\"sleep 30s\");\n // await sleep(30);\n // memory = await this.getMemory();\n // }\n });\n _defineProperty(this, \"getMLSWithRetry\", async _ref5 => {\n let {\n length,\n amplitude,\n calibrateSoundBurstMLSVersions\n } = _ref5;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getMLS({\n length,\n amplitude,\n calibrateSoundBurstMLSVersions\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get MLS after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getPSD\", async _ref6 => {\n let {\n unconv_rec,\n conv_rec,\n sampleRate\n } = _ref6;\n const task = 'psd';\n let res = null;\n const data = JSON.stringify({\n task,\n unconv_rec,\n conv_rec,\n sampleRate\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getBackgroundNoisePSD\", async _ref7 => {\n let {\n background_rec,\n sampleRate\n } = _ref7;\n const task = 'background-psd';\n let res = null;\n const data = JSON.stringify({\n task,\n background_rec,\n sampleRate\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getBackgroundNoisePSDWithRetry\", async _ref8 => {\n let {\n background_rec,\n sampleRate\n } = _ref8;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getBackgroundNoisePSD({\n background_rec,\n sampleRate\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get PSD after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getSubtractedPSD\", async (rec, knownGains, knownFrequencies, sampleRate) => {\n const task = 'subtracted-psd';\n let res = null;\n const data = JSON.stringify({\n task,\n rec,\n knownGains,\n knownFrequencies,\n sampleRate\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getSubtractedPSDWithRetry\", async (rec, knownGains, knownFrequencies, sampleRate) => {\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getSubtractedPSD(rec, knownGains, knownFrequencies, sampleRate);\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get PSD after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getPSDWithRetry\", async _ref9 => {\n let {\n unconv_rec,\n conv_rec,\n sampleRate\n } = _ref9;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getPSD({\n unconv_rec,\n conv_rec,\n sampleRate\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get PSD after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getComponentInverseImpulseResponse\", async _ref10 => {\n let {\n payload,\n mls,\n lowHz,\n highHz,\n componentIRGains,\n iirLength,\n componentIRFreqs,\n sampleRate,\n mlsAmplitude,\n irLength,\n calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase\n } = _ref10;\n const task = 'component-inverse-impulse-response';\n let res = null;\n const data = JSON.stringify({\n task,\n payload,\n mls,\n lowHz,\n highHz,\n iirLength,\n componentIRGains,\n componentIRFreqs,\n sampleRate,\n mlsAmplitude,\n irLength,\n calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getSystemInverseImpulseResponse\", async _ref11 => {\n let {\n payload,\n mls,\n lowHz,\n highHz,\n iirLength,\n sampleRate,\n mlsAmplitude,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase\n } = _ref11;\n const task = 'system-inverse-impulse-response';\n let res = null;\n const data = JSON.stringify({\n task,\n payload,\n mls,\n lowHz,\n iirLength,\n highHz,\n sampleRate,\n mlsAmplitude,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getMLSPSD\", async _ref12 => {\n let {\n mls,\n sampleRate\n } = _ref12;\n const task = 'mls-psd';\n let res = null;\n const data = JSON.stringify({\n task,\n mls,\n sampleRate\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getMLSPSDWithRetry\", async _ref13 => {\n let {\n mls,\n sampleRate\n } = _ref13;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getMLSPSD({\n mls,\n sampleRate\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get inverse impulse response after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getComponentInverseImpulseResponseWithRetry\", async _ref14 => {\n let {\n payload,\n mls,\n lowHz,\n highHz,\n componentIRGains,\n iirLength,\n componentIRFreqs,\n sampleRate,\n mlsAmplitude,\n irLength,\n calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase\n } = _ref14;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getComponentInverseImpulseResponse({\n payload,\n mls,\n lowHz,\n highHz,\n componentIRGains,\n iirLength,\n componentIRFreqs,\n sampleRate,\n mlsAmplitude,\n irLength,\n calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get inverse impulse response after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getSystemInverseImpulseResponseWithRetry\", async _ref15 => {\n let {\n payload,\n mls,\n lowHz,\n highHz,\n iirLength,\n sampleRate,\n mlsAmplitude,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase\n } = _ref15;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getSystemInverseImpulseResponse({\n payload,\n mls,\n lowHz,\n highHz,\n iirLength,\n sampleRate,\n mlsAmplitude,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get inverse impulse response after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getVolumeCalibration\", async _ref16 => {\n let {\n payload,\n sampleRate,\n lCalib\n } = _ref16;\n const task = 'volume';\n let res = null;\n console.log({\n payload\n });\n const data = JSON.stringify({\n task,\n payload,\n 'sample-rate': sampleRate,\n lCalib\n });\n const response = await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n // if response.data is a string, parse it\n if (typeof response.data === 'string') {\n // response.data = response.data.replaceAll('Infinity', 99999999);\n // response.data = JSON.parse(response.data);\n //if there is Infinity in the string, throw an error\n if (response.data.includes('Infinity')) {\n throw new Error('Server returned Infinity. Please make sure the microphone is recording correctly');\n }\n response.data = JSON.parse(response.data);\n }\n return response.data[task];\n }).catch(error => {\n alert('Invalid data. Please make sure the microphone is recording correctly and press on \"Re-Record\"');\n throw error;\n });\n console.log(response);\n return response;\n });\n _defineProperty(this, \"getVolumeCalibrationParameters\", async _ref17 => {\n let {\n inDBValues,\n outDBSPLValues,\n lCalib,\n componentGainDBSPL\n } = _ref17;\n const task = 'volume-parameters';\n let res = null;\n const data = JSON.stringify({\n task,\n inDBValues,\n outDBSPLValues,\n lCalib,\n componentGainDBSPL\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n //server\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n console.log(res.data[task]);\n }).catch(error => {\n throw error;\n });\n\n // console.log(res.data[task]);\n //below is an example of res.data[task]\n //{\n // R: 16.56981076554259,\n // RMSError: 1.9289162528535229\n // T: -47.79799120884434,\n // W: 61.0485247483732,\n // backgroundDBSPL: 43.88233142069752,\n // gainDBSPL: -128.24742161208985\n //}\n return res.data[task];\n });\n _defineProperty(this, \"allHzPowerCheck\", async _ref18 => {\n let {\n payload,\n sampleRate,\n binDesiredSec,\n burstSec,\n repeats,\n warmUp\n } = _ref18;\n const task = 'all-hz-check';\n let res = null;\n console.log({\n payload,\n sampleRate,\n binDesiredSec,\n burstSec,\n repeats,\n warmUp\n });\n const data = JSON.stringify({\n payload,\n sampleRate,\n binDesiredSec,\n burstSec,\n repeats,\n warmUp\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n //server\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n console.log(res.data[task]);\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"volumePowerCheck\", async _ref19 => {\n let {\n payload,\n sampleRate,\n preSec,\n Sec,\n binDesiredSec\n } = _ref19;\n const task = 'volume-check';\n let res = null;\n const data = JSON.stringify({\n payload,\n sampleRate,\n preSec,\n Sec,\n binDesiredSec\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n //server\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n console.log(res.data[task]);\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"volumePowerCheckWithRetry\", async _ref20 => {\n let {\n payload,\n sampleRate,\n preSec,\n Sec,\n binDesiredSec\n } = _ref20;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.volumePowerCheck({\n payload,\n sampleRate,\n preSec,\n Sec,\n binDesiredSec\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get volume power check after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n }\n}\n_defineProperty(PythonServerAPI, \"PYTHON_SERVER_URL\", 'https://easyeyes-python-flask-server.herokuapp.com');\n_defineProperty(PythonServerAPI, \"TEST_SERVER_URL\", 'http://127.0.0.1:5000');\n/* harmony default export */ __webpack_exports__[\"default\"] = (PythonServerAPI);\n\n//# sourceURL=webpack://speakerCalibrator/./src/server/PythonServerAPI.js?");
150
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! axios */ \"./node_modules/axios/lib/axios.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ \"./src/utils.js\");\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\n\n\n/**\r\n *\r\n */\nclass PythonServerAPI {\n constructor() {\n // static PYTHON_SERVER_URL ='http://127.0.0.1:5000';\n /** @private */\n _defineProperty(this, \"MAX_RETRY_COUNT\", 3);\n /** @private */\n _defineProperty(this, \"RETRY_DELAY_MS\", 1000);\n /**\r\n * @param data- -\r\n * g = inverted impulse response, when convolved with the impulse\r\n * reponse, they cancel out.\r\n * @param data.payload\r\n * @param data.sampleRate\r\n * @param data.P\r\n * @param data-.payload\r\n * @param data-.sampleRate\r\n * @param data-.P\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getImpulseResponse\", async _ref => {\n let {\n mls,\n sampleRate,\n numPeriods,\n sig,\n fs2,\n L_new_n,\n dL_n\n } = _ref;\n const task = 'impulse-response';\n let res = null;\n const data = JSON.stringify({\n task,\n 'sample-rate': sampleRate,\n mls,\n numPeriods,\n sig,\n fs2,\n L_new_n,\n dL_n\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getAutocorrelation\", async _ref2 => {\n let {\n mls,\n payload,\n sampleRate,\n numPeriods\n } = _ref2;\n const task = 'autocorrelation';\n let res = null;\n const data = JSON.stringify({\n task,\n payload: payload,\n 'sample-rate': sampleRate,\n mls,\n numPeriods\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getConvolution\", async _ref3 => {\n let {\n mls,\n inverse_response,\n inverse_response_no_bandpass,\n attenuatorGain_dB,\n mls_amplitude\n } = _ref3;\n const task = 'convolution';\n let res = null;\n const data = JSON.stringify({\n task,\n mls,\n inverse_response,\n inverse_response_no_bandpass,\n attenuatorGain_dB,\n mls_amplitude\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getMLS\", async _ref4 => {\n let {\n length,\n amplitude,\n calibrateSoundBurstMLSVersions,\n calibrateSoundBurstDownsample\n } = _ref4;\n const task = 'mls';\n let res = null;\n const data = JSON.stringify({\n task,\n length: length,\n amplitude: amplitude,\n calibrateSoundBurstMLSVersions: calibrateSoundBurstMLSVersions,\n calibrateSoundBurstDownsample: calibrateSoundBurstDownsample\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getShortURL\", async originalURL => {\n const task = 'url';\n let res = null;\n console.log(originalURL);\n const data = JSON.stringify({\n URL: originalURL\n });\n console.log(data);\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n console.log(res.data[task]);\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getMemory\", async () => {\n let res;\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/memory\",\n headers: {\n 'Content-Type': 'application/json'\n }\n }).then(response => {\n console.log('memory used:', Math.round(response.data['memory']), 'mb');\n res = response.data['memory'];\n }).catch(error => {\n throw error;\n });\n return res;\n });\n _defineProperty(this, \"checkMemory\", async () => {\n console.log('wait for memory under 500 mb to continue calibration');\n await this.getMemory();\n // let memory = await this.getMemory();\n // while (memory >= 500) {\n // console.log(\"sleep 30s\");\n // await sleep(30);\n // memory = await this.getMemory();\n // }\n });\n _defineProperty(this, \"getMLSWithRetry\", async _ref5 => {\n let {\n length,\n amplitude,\n calibrateSoundBurstMLSVersions,\n calibrateSoundBurstDownsample\n } = _ref5;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getMLS({\n length,\n amplitude,\n calibrateSoundBurstMLSVersions,\n calibrateSoundBurstDownsample\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get MLS after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getPSD\", async _ref6 => {\n let {\n unconv_rec,\n conv_rec,\n sampleRate,\n downsample\n } = _ref6;\n const task = 'psd';\n let res = null;\n const data = JSON.stringify({\n task,\n unconv_rec,\n conv_rec,\n sampleRate,\n downsample\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getBackgroundNoisePSD\", async _ref7 => {\n let {\n background_rec,\n sampleRate\n } = _ref7;\n const task = 'background-psd';\n let res = null;\n const data = JSON.stringify({\n task,\n background_rec,\n sampleRate\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getBackgroundNoisePSDWithRetry\", async _ref8 => {\n let {\n background_rec,\n sampleRate\n } = _ref8;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getBackgroundNoisePSD({\n background_rec,\n sampleRate\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get PSD after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getSubtractedPSD\", async (rec, knownGains, knownFrequencies, sampleRate, downsample) => {\n const task = 'subtracted-psd';\n let res = null;\n const data = JSON.stringify({\n task,\n rec,\n knownGains,\n knownFrequencies,\n sampleRate,\n downsample\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getSubtractedPSDWithRetry\", async (rec, knownGains, knownFrequencies, sampleRate, downsample) => {\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getSubtractedPSD(rec, knownGains, knownFrequencies, sampleRate, downsample);\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get PSD after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getPSDWithRetry\", async _ref9 => {\n let {\n unconv_rec,\n conv_rec,\n sampleRate,\n downsample\n } = _ref9;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getPSD({\n unconv_rec,\n conv_rec,\n sampleRate,\n downsample\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get PSD after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getComponentInverseImpulseResponse\", async _ref10 => {\n let {\n payload,\n mls,\n lowHz,\n highHz,\n componentIRGains,\n iirLength,\n componentIRFreqs,\n sampleRate,\n mlsAmplitude,\n irLength,\n calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase,\n downsample\n } = _ref10;\n const task = 'component-inverse-impulse-response';\n let res = null;\n const data = JSON.stringify({\n task,\n payload,\n mls,\n lowHz,\n highHz,\n iirLength,\n componentIRGains,\n componentIRFreqs,\n sampleRate,\n mlsAmplitude,\n irLength,\n calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase,\n downsample\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getSystemInverseImpulseResponse\", async _ref11 => {\n let {\n payload,\n mls,\n lowHz,\n highHz,\n iirLength,\n sampleRate,\n mlsAmplitude,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase,\n downsample\n } = _ref11;\n const task = 'system-inverse-impulse-response';\n let res = null;\n const data = JSON.stringify({\n task,\n payload,\n mls,\n lowHz,\n iirLength,\n highHz,\n sampleRate,\n mlsAmplitude,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase,\n downsample\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getMLSPSD\", async _ref12 => {\n let {\n mls,\n sampleRate,\n downsample\n } = _ref12;\n const task = 'mls-psd';\n let res = null;\n const data = JSON.stringify({\n task,\n mls,\n sampleRate,\n downsample\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"getMLSPSDWithRetry\", async _ref13 => {\n let {\n mls,\n sampleRate,\n downsample\n } = _ref13;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getMLSPSD({\n mls,\n sampleRate,\n downsample\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get inverse impulse response after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getComponentInverseImpulseResponseWithRetry\", async _ref14 => {\n let {\n payload,\n mls,\n lowHz,\n highHz,\n componentIRGains,\n iirLength,\n componentIRFreqs,\n sampleRate,\n mlsAmplitude,\n irLength,\n calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase,\n downsample\n } = _ref14;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getComponentInverseImpulseResponse({\n payload,\n mls,\n lowHz,\n highHz,\n componentIRGains,\n iirLength,\n componentIRFreqs,\n sampleRate,\n mlsAmplitude,\n irLength,\n calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase,\n downsample\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get inverse impulse response after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getSystemInverseImpulseResponseWithRetry\", async _ref15 => {\n let {\n payload,\n mls,\n lowHz,\n highHz,\n iirLength,\n sampleRate,\n mlsAmplitude,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase,\n downsample\n } = _ref15;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.getSystemInverseImpulseResponse({\n payload,\n mls,\n lowHz,\n highHz,\n iirLength,\n sampleRate,\n mlsAmplitude,\n calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase,\n downsample\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get inverse impulse response after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n _defineProperty(this, \"getVolumeCalibration\", async _ref16 => {\n let {\n payload,\n sampleRate,\n lCalib\n } = _ref16;\n const task = 'volume';\n let res = null;\n console.log({\n payload\n });\n const data = JSON.stringify({\n task,\n payload,\n 'sample-rate': sampleRate,\n lCalib\n });\n const response = await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n // if response.data is a string, parse it\n if (typeof response.data === 'string') {\n // response.data = response.data.replaceAll('Infinity', 99999999);\n // response.data = JSON.parse(response.data);\n //if there is Infinity in the string, throw an error\n if (response.data.includes('Infinity')) {\n throw new Error('Server returned Infinity. Please make sure the microphone is recording correctly');\n }\n response.data = JSON.parse(response.data);\n }\n return response.data[task];\n }).catch(error => {\n alert('Invalid data. Please make sure the microphone is recording correctly and press on \"Re-Record\"');\n throw error;\n });\n console.log(response);\n return response;\n });\n _defineProperty(this, \"getVolumeCalibrationParameters\", async _ref17 => {\n let {\n inDBValues,\n outDBSPLValues,\n lCalib,\n componentGainDBSPL\n } = _ref17;\n const task = 'volume-parameters';\n let res = null;\n const data = JSON.stringify({\n task,\n inDBValues,\n outDBSPLValues,\n lCalib,\n componentGainDBSPL\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n //server\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n console.log(res.data[task]);\n }).catch(error => {\n throw error;\n });\n\n // console.log(res.data[task]);\n //below is an example of res.data[task]\n //{\n // R: 16.56981076554259,\n // RMSError: 1.9289162528535229\n // T: -47.79799120884434,\n // W: 61.0485247483732,\n // backgroundDBSPL: 43.88233142069752,\n // gainDBSPL: -128.24742161208985\n //}\n return res.data[task];\n });\n _defineProperty(this, \"allHzPowerCheck\", async _ref18 => {\n let {\n payload,\n sampleRate,\n binDesiredSec,\n burstSec,\n repeats,\n warmUp,\n downsample\n } = _ref18;\n const task = 'all-hz-check';\n let res = null;\n console.log({\n payload,\n sampleRate,\n binDesiredSec,\n burstSec,\n repeats,\n warmUp\n });\n const data = JSON.stringify({\n payload,\n sampleRate,\n binDesiredSec,\n burstSec,\n repeats,\n warmUp,\n downsample\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n //server\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n console.log(res.data[task]);\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"volumePowerCheck\", async _ref19 => {\n let {\n payload,\n sampleRate,\n preSec,\n Sec,\n binDesiredSec\n } = _ref19;\n const task = 'volume-check';\n let res = null;\n const data = JSON.stringify({\n payload,\n sampleRate,\n preSec,\n Sec,\n binDesiredSec\n });\n await (0,axios__WEBPACK_IMPORTED_MODULE_1__[\"default\"])({\n method: 'post',\n baseURL: PythonServerAPI.PYTHON_SERVER_URL,\n //server\n url: \"/task/\".concat(task),\n headers: {\n 'Content-Type': 'application/json'\n },\n data\n }).then(response => {\n res = response;\n console.log(res.data[task]);\n }).catch(error => {\n throw error;\n });\n return res.data[task];\n });\n _defineProperty(this, \"volumePowerCheckWithRetry\", async _ref20 => {\n let {\n payload,\n sampleRate,\n preSec,\n Sec,\n binDesiredSec\n } = _ref20;\n let retryCount = 0;\n let response = null;\n while (retryCount < this.MAX_RETRY_COUNT) {\n try {\n response = await this.volumePowerCheck({\n payload,\n sampleRate,\n preSec,\n Sec,\n binDesiredSec\n });\n // If the request is successful, break out of the loop\n break;\n } catch (error) {\n console.error(\"Error occurred. Retrying... (\".concat(retryCount + 1, \"/\").concat(this.MAX_RETRY_COUNT, \")\"));\n retryCount++;\n await new Promise(resolve => setTimeout(resolve, this.RETRY_DELAY_MS));\n }\n }\n if (response) {\n return response;\n } else {\n throw new Error(\"Failed to get volume power check after \".concat(this.MAX_RETRY_COUNT, \" attempts.\"));\n }\n });\n }\n}\n_defineProperty(PythonServerAPI, \"PYTHON_SERVER_URL\", 'https://easyeyes-python-flask-server.herokuapp.com');\n_defineProperty(PythonServerAPI, \"TEST_SERVER_URL\", 'http://127.0.0.1:5000');\n/* harmony default export */ __webpack_exports__[\"default\"] = (PythonServerAPI);\n\n//# sourceURL=webpack://speakerCalibrator/./src/server/PythonServerAPI.js?");
151
151
 
152
152
  /***/ }),
153
153
 
@@ -158,7 +158,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var axio
158
158
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
159
159
 
160
160
  "use strict";
161
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _audioRecorder__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./audioRecorder */ \"./src/tasks/audioRecorder.js\");\n/* harmony import */ var _server_PythonServerAPI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../server/PythonServerAPI */ \"./src/server/PythonServerAPI.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils */ \"./src/utils.js\");\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\n/* eslint-disable no-await-in-loop */\n\n\n\n\n/**\r\n * .\r\n * .\r\n * .\r\n * Provides methods for calibrating the user's speakers\r\n *\r\n * @extends AudioRecorder\r\n */\nclass AudioCalibrator extends _audioRecorder__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\n /**\r\n *\r\n * @param numCaptures\r\n * @param numMLSPerCapture\r\n * @example\r\n */\n constructor() {\n var _this;\n let numCaptures = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;\n let numMLSPerCapture = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n super();\n _this = this;\n /** @private */\n _defineProperty(this, \"isCalibrating\", false);\n /** @private */\n _defineProperty(this, \"sourceAudioContext\", void 0);\n /** @private */\n _defineProperty(this, \"sourceAudioContextConvolved\", void 0);\n /** @protected */\n _defineProperty(this, \"numCalibratingRounds\", 1);\n /** @protected */\n _defineProperty(this, \"numSuccessfulCaptured\", 0);\n /** @private */\n _defineProperty(this, \"sourceSamplingRate\", void 0);\n /** @protected */\n _defineProperty(this, \"calibrationNodes\", []);\n /** @protected */\n _defineProperty(this, \"calibrationNodesConvolved\", []);\n /** @protected */\n _defineProperty(this, \"localAudio\", void 0);\n /** @private */\n _defineProperty(this, \"startTime\", void 0);\n _defineProperty(this, \"numCalibratingRoundsCompleted\", 0);\n /**\r\n * Called when a call is received.\r\n * Creates a local audio DOM element and attaches it to the page.\r\n *\r\n * @param targetElement\r\n * @example\r\n */\n _defineProperty(this, \"createLocalAudio\", targetElement => {\n this.localAudio = document.createElement('audio');\n this.localAudio.setAttribute('id', 'localAudio');\n targetElement.appendChild(this.localAudio);\n });\n _defineProperty(this, \"addTimeStamp\", taskName => {\n const currentTime = new Date().getTime(); // Current time in ms\n const elapsedTime = (currentTime - this.startTime) / 1000; // Convert to seconds\n const stepDuration = elapsedTime - this.currentTime;\n this.currentTime = elapsedTime; // Update for next step\n\n // Format numbers to 1 decimal place without padding\n const elapsedStr = elapsedTime.toFixed(1);\n const stepStr = stepDuration.toFixed(1);\n\n // Push timestamp string (without padding)\n this.timeStamp.push(\"\".concat(elapsedStr, \" s. \\u2206 \").concat(stepStr, \" s. \").concat(taskName));\n });\n _defineProperty(this, \"recordBackground\", async function (stream) {\n let loopCondition = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : () => false;\n let duringRecord = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : async () => {};\n let afterRecord = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : async () => {};\n let mode = arguments.length > 4 ? arguments[4] : undefined;\n let checkRec = arguments.length > 5 ? arguments[5] : undefined;\n console.warn('before recording background noise');\n // calibration loop\n while (loopCondition()) {\n // start recording\n console.warn('startRecording');\n await _this.startRecording(stream);\n\n // do something during the recording such as sleep n amount of time\n console.warn('duringRecord');\n await duringRecord();\n\n // when done, stop recording\n console.warn('stopRecording');\n await _this.stopRecording(mode, checkRec);\n\n // do something after recording such as start processing values\n console.warn('afterRecord');\n await afterRecord();\n\n // eslint-disable-next-line no-await-in-loop\n await (0,_utils__WEBPACK_IMPORTED_MODULE_2__.sleep)(1);\n }\n });\n /**\r\n *\r\n * @param {MediaStream} stream\r\n * @param {Function} playCalibrationAudio - (async) function that plays the calibration audio\r\n * @param {*} beforePlay - (async) function that is called before playing the audio\r\n * @param {*} beforeRecord - (async) function that is called before recording\r\n * @param {*} duringRecord - (async) function that is called while recording\r\n * @param {*} afterRecord - (async) function that is called after recording\r\n * @example\r\n */\n _defineProperty(this, \"calibrationSteps\", async function (stream, playCalibrationAudio) {\n let beforePlay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : async () => {};\n let beforeRecord = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : async () => {};\n let loopCondition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : () => false;\n let duringRecord = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : async () => {};\n let afterRecord = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : async () => {};\n let mode = arguments.length > 7 ? arguments[7] : undefined;\n let checkRec = arguments.length > 8 ? arguments[8] : undefined;\n // if it finished 2 attempts, it move to next iteration so reset numSuccessfulCaptured\n if (_this.numSuccessfulCaptured >= 2) {\n _this.numSuccessfulCaptured = 0;\n }\n\n // do something before playing such as using the MLS to fill the buffers\n console.warn('beforePlay');\n await beforePlay();\n\n // play calibration audio\n console.warn('playCalibrationAudio');\n playCalibrationAudio();\n\n // do something before recording such as awaiting a certain amount of time\n console.warn('beforeRecord');\n await beforeRecord();\n const totalSec = _this._calibrateSoundBurstPreSec + (_this.numMLSPerCapture - _this.num_mls_to_skip) * _this._calibrateSoundBurstSec + _this._calibrateSoundBurstPostSec;\n\n // calibration loop\n while (loopCondition()) {\n if (_this.isCalibrating) break;\n // start recording\n console.warn('startRecording');\n await _this.startRecording(stream);\n if (_this.isCalibrating) break;\n // do something during the recording such as sleep n amount of time\n console.warn('duringRecord');\n await duringRecord();\n if (_this.isCalibrating) break;\n // when done, stop recording\n console.warn('stopRecording');\n await _this.stopRecording(mode, checkRec);\n if (_this.isCalibrating) break;\n // do something after recording such as start processing values\n console.warn('afterRecord');\n await afterRecord();\n\n // eslint-disable-next-line no-await-in-loop\n await (0,_utils__WEBPACK_IMPORTED_MODULE_2__.sleep)(1);\n }\n });\n /**\r\n *\r\n * @param {MediaStream} stream\r\n * @param {Function} playCalibrationAudio - (async) function that plays the calibration audio\r\n * @param {*} beforeRecord - (async) function that is called before recording\r\n * @param {*} afterRecord - (async) function that is called after recording\r\n * @param {Number} gainValue - the gain value to set the gain node to\r\n */\n _defineProperty(this, \"volumeCalibrationSteps\", async function (stream, playCalibrationAudio) {\n let beforeRecord = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : () => {};\n let afterRecord = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : () => {};\n let gainValue = arguments.length > 4 ? arguments[4] : undefined;\n let lCalib = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 104.92978421490648;\n let checkRec = arguments.length > 6 ? arguments[6] : undefined;\n let checkSD = arguments.length > 7 ? arguments[7] : undefined;\n let maxSD = arguments.length > 8 ? arguments[8] : undefined;\n let maxRetry = arguments.length > 9 ? arguments[9] : undefined;\n _this.numCalibratingRoundsCompleted = 0;\n console.log(\"maxSD in VolumeCaibrationSteps: \", maxSD, '0' >= maxSD);\n // calibration loop\n while (!_this.isCalibrating && _this.numCalibratingRoundsCompleted < maxRetry) {\n if (_this.isCalibrating) break;\n // before recording\n await beforeRecord(gainValue);\n if (_this.isCalibrating) break;\n // start recording\n await _this.startRecording(stream);\n if (_this.isCalibrating) break;\n // play calibration audio\n console.log(\"Calibration Round \".concat(_this.numCalibratingRoundsCompleted));\n await playCalibrationAudio();\n if (_this.isCalibrating) break;\n // when done, stop recording\n console.log('Calibration Round Complete');\n await _this.stopRecording('volume', checkRec);\n if (_this.isCalibrating) break;\n // after recording\n await afterRecord(lCalib);\n const sd = await checkSD();\n let sdMessage;\n if (sd <= maxSD) {\n console.log(\"SD =\".concat(sd, \", less than calibrateSound1000HzMaxSD_dB=\").concat(maxSD));\n _this.numCalibratingRoundsCompleted += maxRetry;\n sdMessage = \". SD = \".concat(sd, \" dB\");\n } else {\n // if exist the maxSD do it one more time and only one more time\n console.log(\"SD =\".concat(sd, \", greater than calibrateSound1000HzMaxSD_dB=\").concat(maxSD));\n _this.numCalibratingRoundsCompleted += 1;\n sdMessage = \". SD = \".concat(sd, \" > \").concat(_this.calibrateSound1000HzMaxSD_dB, \" dB.\");\n }\n _this.addTimeStamp(\"\".concat(_this.calibrateSound1000HzPreSec.toFixed(1)) + \"+\".concat(_this.calibrateSound1000HzSec.toFixed(1)) + \"+\".concat(_this.calibrateSound1000HzPostSec.toFixed(1), \" s. \") + \"1000 Hz at \".concat(_this.inDB, \" dB\").concat(sdMessage));\n _this.calibrationNodes = [];\n\n // eslint-disable-next-line no-await-in-loop\n await (0,_utils__WEBPACK_IMPORTED_MODULE_2__.sleep)(2);\n }\n });\n /**\r\n * Getter for the isCalibrating property.\r\n *\r\n * @public\r\n * @returns - True if the audio is being calibrated, false otherwise.\r\n * @example\r\n */\n _defineProperty(this, \"getCalibrationStatus\", () => this.isCalibrating);\n /** .\r\n * .\r\n * .\r\n * Set the sampling rate to the value received from the listener\r\n *\r\n * @param {*} sinkSamplingRate\r\n * @param samplingRate\r\n * @example\r\n */\n _defineProperty(this, \"setSamplingRates\", samplingRate => {\n this.sinkSamplingRate = samplingRate;\n this.sourceSamplingRate = samplingRate;\n\n // this.emit('update', {message: `sampling at ${samplingRate}Hz...`});\n });\n _defineProperty(this, \"setSampleSize\", sampleSize => {\n this.sampleSize = sampleSize;\n });\n _defineProperty(this, \"setFlags\", flags => {\n this.flags = flags;\n });\n _defineProperty(this, \"sampleRatesSet\", () => this.sourceSamplingRate && this.sinkSamplingRate);\n _defineProperty(this, \"addCalibrationNode\", node => {\n this.calibrationNodes.push(node);\n });\n _defineProperty(this, \"addCalibrationNodeConvolved\", node => {\n this.calibrationNodesConvolved.push(node);\n });\n _defineProperty(this, \"makeNewSourceAudioContext\", () => {\n const options = {\n sampleRate: this.sourceSamplingRate\n };\n this.sourceAudioContext = new (window.AudioContext || window.webkitAudioContext || window.audioContext)(options);\n return this.sourceAudioContext;\n });\n _defineProperty(this, \"makeNewSourceAudioContextConvolved\", () => {\n const options = {\n sampleRate: this.sourceSamplingRate\n };\n this.sourceAudioContextConvolved = new (window.AudioContext || window.webkitAudioContext || window.audioContext)(options);\n return this.sourceAudioContextConvolved;\n });\n /** .\r\n * .\r\n * .\r\n * Download the result of the calibration roudns\r\n *\r\n * @example\r\n */\n _defineProperty(this, \"downloadData\", () => {\n const recordings = this.getAllRecordedSignals();\n const i = recordings.length - 1;\n (0,_utils__WEBPACK_IMPORTED_MODULE_2__.saveToCSV)(recordings[i], \"recordedMLSignal_\".concat(i, \"_unconvolved.csv\"));\n });\n _defineProperty(this, \"downloadSingleUnfilteredRecording\", () => {\n const recordings = this.getAllUnfilteredRecordedSignals();\n (0,_utils__WEBPACK_IMPORTED_MODULE_2__.saveToCSV)(recordings[recordings.length - 1], \"recordedMLSignal_unconvolved.csv\");\n });\n _defineProperty(this, \"downloadSingleFilteredRecording\", () => {\n const recordings = this.getAllFilteredRecordedSignals();\n console.log('Single filtered recording should be of length: ' + recordings[0].length);\n (0,_utils__WEBPACK_IMPORTED_MODULE_2__.saveToCSV)(recordings[0], \"recordedMLSignal_convolved.csv\");\n });\n _defineProperty(this, \"downloadUnfilteredRecordings\", () => {\n const recordings = this.getAllRecordedSignals();\n console.log('unfilterd download?');\n for (let i = 0; i < recordings.length; i++) {\n console.log(i);\n (0,_utils__WEBPACK_IMPORTED_MODULE_2__.saveToCSV)(recordings[i], \"recordedMLSignal_\".concat(i, \"_unconvolved.csv\"));\n }\n });\n _defineProperty(this, \"downloadFilteredRecordings\", () => {\n const recordings = this.getAllFilteredRecordedSignals();\n for (let i = 0; i < recordings.length; i++) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_2__.saveToCSV)(recordings[i], \"recordedMLSignal_\".concat(i, \"_convolved.csv\"));\n }\n });\n this.numCaptures = numCaptures;\n this.numMLSPerCapture = numMLSPerCapture;\n this.pyServerAPI = new _server_PythonServerAPI__WEBPACK_IMPORTED_MODULE_1__[\"default\"]();\n this.currentTime = 0;\n }\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (AudioCalibrator);\n\n//# sourceURL=webpack://speakerCalibrator/./src/tasks/audioCalibrator.js?");
161
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _audioRecorder__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./audioRecorder */ \"./src/tasks/audioRecorder.js\");\n/* harmony import */ var _server_PythonServerAPI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../server/PythonServerAPI */ \"./src/server/PythonServerAPI.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils */ \"./src/utils.js\");\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\n/* eslint-disable no-await-in-loop */\n\n\n\n\n/**\r\n * .\r\n * .\r\n * .\r\n * Provides methods for calibrating the user's speakers\r\n *\r\n * @extends AudioRecorder\r\n */\nclass AudioCalibrator extends _audioRecorder__WEBPACK_IMPORTED_MODULE_0__[\"default\"] {\n /**\r\n *\r\n * @param numCaptures\r\n * @param numMLSPerCapture\r\n * @example\r\n */\n constructor() {\n var _this;\n let numCaptures = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;\n let numMLSPerCapture = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n super();\n _this = this;\n /** @private */\n _defineProperty(this, \"isCalibrating\", false);\n /** @private */\n _defineProperty(this, \"sourceAudioContext\", void 0);\n /** @private */\n _defineProperty(this, \"sourceAudioContextConvolved\", void 0);\n /** @protected */\n _defineProperty(this, \"numCalibratingRounds\", 1);\n /** @protected */\n _defineProperty(this, \"numSuccessfulCaptured\", 0);\n /** @private */\n _defineProperty(this, \"sourceSamplingRate\", void 0);\n /** @protected */\n _defineProperty(this, \"calibrationNodes\", []);\n /** @protected */\n _defineProperty(this, \"calibrationNodesConvolved\", []);\n /** @protected */\n _defineProperty(this, \"localAudio\", void 0);\n /** @private */\n _defineProperty(this, \"startTime\", void 0);\n _defineProperty(this, \"numCalibratingRoundsCompleted\", 0);\n /**\r\n * Called when a call is received.\r\n * Creates a local audio DOM element and attaches it to the page.\r\n *\r\n * @param targetElement\r\n * @example\r\n */\n _defineProperty(this, \"createLocalAudio\", targetElement => {\n this.localAudio = document.createElement('audio');\n this.localAudio.setAttribute('id', 'localAudio');\n targetElement.appendChild(this.localAudio);\n });\n _defineProperty(this, \"addTimeStamp\", taskName => {\n const currentTime = new Date().getTime(); // Current time in ms\n const elapsedTime = (currentTime - this.startTime) / 1000; // Convert to seconds\n const stepDuration = elapsedTime - this.currentTime;\n this.currentTime = elapsedTime; // Update for next step\n\n // Format numbers to 1 decimal place without padding\n const elapsedStr = elapsedTime.toFixed(1);\n const stepStr = stepDuration.toFixed(1);\n\n // Push timestamp string (without padding)\n this.timeStamp.push(\"\".concat(elapsedStr, \" s. \\u2206 \").concat(stepStr, \" s. \").concat(taskName));\n });\n _defineProperty(this, \"recordBackground\", async function (stream) {\n let loopCondition = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : () => false;\n let duringRecord = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : async () => {};\n let afterRecord = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : async () => {};\n let mode = arguments.length > 4 ? arguments[4] : undefined;\n let checkRec = arguments.length > 5 ? arguments[5] : undefined;\n console.warn('before recording background noise');\n // calibration loop\n while (loopCondition()) {\n // start recording\n console.warn('startRecording');\n await _this.startRecording(stream);\n\n // do something during the recording such as sleep n amount of time\n console.warn('duringRecord');\n await duringRecord();\n\n // when done, stop recording\n console.warn('stopRecording');\n await _this.stopRecording(mode, checkRec);\n\n // do something after recording such as start processing values\n console.warn('afterRecord');\n await afterRecord();\n\n // eslint-disable-next-line no-await-in-loop\n await (0,_utils__WEBPACK_IMPORTED_MODULE_2__.sleep)(1);\n }\n });\n /**\r\n *\r\n * @param {MediaStream} stream\r\n * @param {Function} playCalibrationAudio - (async) function that plays the calibration audio\r\n * @param {*} beforePlay - (async) function that is called before playing the audio\r\n * @param {*} beforeRecord - (async) function that is called before recording\r\n * @param {*} duringRecord - (async) function that is called while recording\r\n * @param {*} afterRecord - (async) function that is called after recording\r\n * @example\r\n */\n _defineProperty(this, \"calibrationSteps\", async function (stream, playCalibrationAudio) {\n let beforePlay = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : async () => {};\n let beforeRecord = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : async () => {};\n let loopCondition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : () => false;\n let duringRecord = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : async () => {};\n let afterRecord = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : async () => {};\n let mode = arguments.length > 7 ? arguments[7] : undefined;\n let checkRec = arguments.length > 8 ? arguments[8] : undefined;\n // if it finished 2 attempts, it move to next iteration so reset numSuccessfulCaptured\n if (_this.numSuccessfulCaptured >= 2) {\n _this.numSuccessfulCaptured = 0;\n }\n\n // do something before playing such as using the MLS to fill the buffers\n console.warn('beforePlay');\n await beforePlay();\n\n // play calibration audio\n console.warn('playCalibrationAudio');\n playCalibrationAudio();\n\n // do something before recording such as awaiting a certain amount of time\n console.warn('beforeRecord');\n await beforeRecord();\n const totalSec = _this._calibrateSoundBurstPreSec + (_this.numMLSPerCapture - _this.num_mls_to_skip) * _this._calibrateSoundBurstSec + _this._calibrateSoundBurstPostSec;\n\n // calibration loop\n while (loopCondition()) {\n if (_this.isCalibrating) break;\n // start recording\n console.warn('startRecording');\n await _this.startRecording(stream);\n if (_this.isCalibrating) break;\n // do something during the recording such as sleep n amount of time\n console.warn('duringRecord');\n await duringRecord();\n if (_this.isCalibrating) break;\n // when done, stop recording\n console.warn('stopRecording');\n await _this.stopRecording(mode, checkRec);\n if (_this.isCalibrating) break;\n // do something after recording such as start processing values\n console.warn('afterRecord');\n await afterRecord();\n\n // eslint-disable-next-line no-await-in-loop\n await (0,_utils__WEBPACK_IMPORTED_MODULE_2__.sleep)(1);\n }\n });\n /**\r\n *\r\n * @param {MediaStream} stream\r\n * @param {Function} playCalibrationAudio - (async) function that plays the calibration audio\r\n * @param {*} beforeRecord - (async) function that is called before recording\r\n * @param {*} afterRecord - (async) function that is called after recording\r\n * @param {Number} gainValue - the gain value to set the gain node to\r\n */\n _defineProperty(this, \"volumeCalibrationSteps\", async function (stream, playCalibrationAudio) {\n let beforeRecord = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : () => {};\n let afterRecord = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : () => {};\n let gainValue = arguments.length > 4 ? arguments[4] : undefined;\n let lCalib = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 104.92978421490648;\n let checkRec = arguments.length > 6 ? arguments[6] : undefined;\n let checkSD = arguments.length > 7 ? arguments[7] : undefined;\n let maxSD = arguments.length > 8 ? arguments[8] : undefined;\n let maxRetry = arguments.length > 9 ? arguments[9] : undefined;\n _this.numCalibratingRoundsCompleted = 0;\n console.log('maxSD in VolumeCaibrationSteps: ', maxSD, '0' >= maxSD);\n // calibration loop\n while (!_this.isCalibrating && _this.numCalibratingRoundsCompleted < maxRetry) {\n if (_this.isCalibrating) break;\n // before recording\n await beforeRecord(gainValue);\n if (_this.isCalibrating) break;\n // start recording\n await _this.startRecording(stream);\n if (_this.isCalibrating) break;\n // play calibration audio\n console.log(\"Calibration Round \".concat(_this.numCalibratingRoundsCompleted));\n await playCalibrationAudio();\n if (_this.isCalibrating) break;\n // when done, stop recording\n console.log('Calibration Round Complete');\n await _this.stopRecording('volume', checkRec);\n if (_this.isCalibrating) break;\n // after recording\n await afterRecord(lCalib);\n const sd = await checkSD();\n let sdMessage;\n if (sd <= maxSD) {\n console.log(\"SD =\".concat(sd, \", less than calibrateSound1000HzMaxSD_dB=\").concat(maxSD));\n _this.numCalibratingRoundsCompleted += maxRetry;\n sdMessage = \". SD = \".concat(sd, \" dB\");\n } else {\n // if exist the maxSD do it one more time and only one more time\n console.log(\"SD =\".concat(sd, \", greater than calibrateSound1000HzMaxSD_dB=\").concat(maxSD));\n _this.numCalibratingRoundsCompleted += 1;\n sdMessage = \". SD = \".concat(sd, \" > \").concat(_this.calibrateSound1000HzMaxSD_dB, \" dB.\");\n }\n _this.addTimeStamp(\"\".concat(_this.calibrateSound1000HzPreSec.toFixed(1)) + \"+\".concat(_this.calibrateSound1000HzSec.toFixed(1)) + \"+\".concat(_this.calibrateSound1000HzPostSec.toFixed(1), \" s. \") + \"1000 Hz at \".concat(_this.inDB, \" dB\").concat(sdMessage));\n _this.calibrationNodes = [];\n\n // eslint-disable-next-line no-await-in-loop\n await (0,_utils__WEBPACK_IMPORTED_MODULE_2__.sleep)(2);\n }\n });\n /**\r\n * Getter for the isCalibrating property.\r\n *\r\n * @public\r\n * @returns - True if the audio is being calibrated, false otherwise.\r\n * @example\r\n */\n _defineProperty(this, \"getCalibrationStatus\", () => this.isCalibrating);\n /** .\r\n * .\r\n * .\r\n * Set the sampling rate to the value received from the listener\r\n *\r\n * @param {*} sinkSamplingRate\r\n * @param samplingRate\r\n * @example\r\n */\n _defineProperty(this, \"setSamplingRates\", samplingRate => {\n this.sinkSamplingRate = samplingRate;\n this.sourceSamplingRate = samplingRate;\n\n // this.emit('update', {message: `sampling at ${samplingRate}Hz...`});\n });\n _defineProperty(this, \"setSampleSize\", sampleSize => {\n this.sampleSize = sampleSize;\n });\n _defineProperty(this, \"setFlags\", flags => {\n this.flags = flags;\n });\n _defineProperty(this, \"sampleRatesSet\", () => this.sourceSamplingRate && this.sinkSamplingRate);\n _defineProperty(this, \"addCalibrationNode\", node => {\n this.calibrationNodes.push(node);\n });\n _defineProperty(this, \"addCalibrationNodeConvolved\", node => {\n this.calibrationNodesConvolved.push(node);\n });\n _defineProperty(this, \"makeNewSourceAudioContext\", () => {\n const options = {\n sampleRate: this.sourceSamplingRate\n };\n this.sourceAudioContext = new (window.AudioContext || window.webkitAudioContext || window.audioContext)(options);\n return this.sourceAudioContext;\n });\n _defineProperty(this, \"makeNewSourceAudioContextConvolved\", () => {\n const options = {\n sampleRate: this.sourceSamplingRate\n };\n this.sourceAudioContextConvolved = new (window.AudioContext || window.webkitAudioContext || window.audioContext)(options);\n return this.sourceAudioContextConvolved;\n });\n /** .\r\n * .\r\n * .\r\n * Download the result of the calibration roudns\r\n *\r\n * @example\r\n */\n _defineProperty(this, \"downloadData\", () => {\n const recordings = this.getAllRecordedSignals();\n const i = recordings.length - 1;\n (0,_utils__WEBPACK_IMPORTED_MODULE_2__.saveToCSV)(recordings[i], \"recordedMLSignal_\".concat(i, \"_unconvolved.csv\"));\n });\n _defineProperty(this, \"downloadSingleUnfilteredRecording\", () => {\n const recordings = this.getAllUnfilteredRecordedSignals();\n (0,_utils__WEBPACK_IMPORTED_MODULE_2__.saveToCSV)(recordings[recordings.length - 1], \"recordedMLSignal_unconvolved.csv\");\n });\n _defineProperty(this, \"downloadSingleFilteredRecording\", () => {\n const recordings = this.getAllFilteredRecordedSignals();\n console.log('Single filtered recording should be of length: ' + recordings[0].length);\n (0,_utils__WEBPACK_IMPORTED_MODULE_2__.saveToCSV)(recordings[0], \"recordedMLSignal_convolved.csv\");\n });\n _defineProperty(this, \"downloadUnfilteredRecordings\", () => {\n const recordings = this.getAllRecordedSignals();\n console.log('unfilterd download?');\n for (let i = 0; i < recordings.length; i++) {\n console.log(i);\n (0,_utils__WEBPACK_IMPORTED_MODULE_2__.saveToCSV)(recordings[i], \"recordedMLSignal_\".concat(i, \"_unconvolved.csv\"));\n }\n });\n _defineProperty(this, \"downloadFilteredRecordings\", () => {\n const recordings = this.getAllFilteredRecordedSignals();\n for (let i = 0; i < recordings.length; i++) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_2__.saveToCSV)(recordings[i], \"recordedMLSignal_\".concat(i, \"_convolved.csv\"));\n }\n });\n this.numCaptures = numCaptures;\n this.numMLSPerCapture = numMLSPerCapture;\n this.pyServerAPI = new _server_PythonServerAPI__WEBPACK_IMPORTED_MODULE_1__[\"default\"]();\n this.currentTime = 0;\n }\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (AudioCalibrator);\n\n//# sourceURL=webpack://speakerCalibrator/./src/tasks/audioCalibrator.js?");
162
162
 
163
163
  /***/ }),
164
164
 
@@ -169,7 +169,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _aud
169
169
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
170
170
 
171
171
  "use strict";
172
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/web.dom-collections.iterator.js */ \"./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _myEventEmitter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../myEventEmitter */ \"./src/myEventEmitter.js\");\n\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nfunction _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }\nfunction _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError(\"Cannot initialize the same private elements twice on an object\"); }\nfunction _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }\nfunction _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }\nfunction _assertClassBrand(e, t, n) { if (\"function\" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError(\"Private element is not present on this object\"); }\n\n\n/**\r\n * @class provides a simple interface for recording audio from a microphone\r\n * using the Media Recorder API.\r\n */\nvar _mediaRecorder = /*#__PURE__*/new WeakMap();\nvar _recordedChunks = /*#__PURE__*/new WeakMap();\nvar _audioBlob = /*#__PURE__*/new WeakMap();\nvar _audioContext = /*#__PURE__*/new WeakMap();\nvar _recordedSignals = /*#__PURE__*/new WeakMap();\nvar _allHzUnfilteredRecordings = /*#__PURE__*/new WeakMap();\nvar _allBackgroundRecordings = /*#__PURE__*/new WeakMap();\nvar _allHzFilteredRecordings = /*#__PURE__*/new WeakMap();\nvar _allVolumeRecordings = /*#__PURE__*/new WeakMap();\nvar _saveRecording = /*#__PURE__*/new WeakMap();\nvar _saveFilteredRecording = /*#__PURE__*/new WeakMap();\nvar _onRecorderDataAvailable = /*#__PURE__*/new WeakMap();\nvar _setMediaRecorder = /*#__PURE__*/new WeakMap();\nvar _setAudioContext = /*#__PURE__*/new WeakMap();\nclass AudioRecorder extends _myEventEmitter__WEBPACK_IMPORTED_MODULE_1__[\"default\"] {\n constructor() {\n super(...arguments);\n /** @private */\n _classPrivateFieldInitSpec(this, _mediaRecorder, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _recordedChunks, []);\n /** @private */\n _classPrivateFieldInitSpec(this, _audioBlob, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _audioContext, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _recordedSignals, []);\n /**@private */\n _classPrivateFieldInitSpec(this, _allHzUnfilteredRecordings, []);\n /**@private */\n _classPrivateFieldInitSpec(this, _allBackgroundRecordings, []);\n /** @private */\n _classPrivateFieldInitSpec(this, _allHzFilteredRecordings, []);\n /** @private */\n _defineProperty(this, \"sinkSamplingRate\", void 0);\n /** @private */\n _defineProperty(this, \"sampleSize\", void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _allVolumeRecordings, []);\n /** @private */\n _defineProperty(this, \"flags\", {});\n /**\r\n * Decode the audio data from the recorded audio blob.\r\n *\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _saveRecording, async (mode, checkRec) => {\n const arrayBuffer = await _classPrivateFieldGet(_audioBlob, this).arrayBuffer();\n const audioBuffer = await _classPrivateFieldGet(_audioContext, this).decodeAudioData(arrayBuffer);\n console.log(audioBuffer);\n const data = audioBuffer.getChannelData(0);\n const dataArray = Array.from(data);\n console.log(\"Decoded audio buffer with \".concat(data.length, \" samples\"));\n console.log(\"Unfiltered recording should be of length: \".concat(data.length));\n if (checkRec == 'loudest') {\n const uniqueSet = new Set(dataArray);\n const numberOfUniqueValues = uniqueSet.size;\n const squaredValues = dataArray.map(value => value * value);\n const sum_of_squares = squaredValues.reduce((total, value) => total + value, 0);\n const squared_mean = sum_of_squares / dataArray.length;\n const dbLevel = 20 * Math.log10(Math.sqrt(squared_mean));\n const roundedDbLevel = Math.round(dbLevel * 10) / 10;\n console.log('Loudest 1000-Hz recording: ' + roundedDbLevel + ' dB with ' + numberOfUniqueValues + ' unique values.');\n } else if (checkRec == 'allhz') {\n const uniqueSet = new Set(dataArray);\n const numberOfUniqueValues = uniqueSet.size;\n const squaredValues = dataArray.map(value => value * value);\n const sum_of_squares = squaredValues.reduce((total, value) => total + value, 0);\n const squared_mean = sum_of_squares / dataArray.length;\n const dbLevel = 20 * Math.log10(Math.sqrt(squared_mean));\n const roundedDbLevel = Math.round(dbLevel * 10) / 10;\n console.log('All Hz Recording: ' + roundedDbLevel + ' dB with ' + numberOfUniqueValues + ' unique values.');\n }\n if (mode === 'volume') {\n console.log('Saving 1000 Hz Recording to #allVolumeRecordings');\n _classPrivateFieldGet(_allVolumeRecordings, this).push(dataArray);\n } else if (mode === 'unfiltered') {\n console.log('Saving unfiltered all Hz recording to #allHzUnfilteredRecordings');\n _classPrivateFieldGet(_allHzUnfilteredRecordings, this).push(dataArray);\n } else if (mode === 'filtered') {\n console.log('Saving filtered all hz recording to #allHzFilteredRecordings');\n _classPrivateFieldGet(_allHzFilteredRecordings, this).push(dataArray);\n } else if (mode === 'background') {\n console.log('Saving background recording to #allBackgroundRecordings');\n _classPrivateFieldGet(_allBackgroundRecordings, this).push(dataArray);\n }\n });\n _classPrivateFieldInitSpec(this, _saveFilteredRecording, async () => {\n const arrayBuffer = await _classPrivateFieldGet(_audioBlob, this).arrayBuffer();\n const audioBuffer = await _classPrivateFieldGet(_audioContext, this).decodeAudioData(arrayBuffer);\n const data = audioBuffer.getChannelData(0);\n console.log(\"Decoded audio buffer with \".concat(data.length, \" samples\"));\n console.log(\"Filtered recording should be of length: \".concat(data.length));\n _classPrivateFieldGet(_allHzFilteredRecordings, this).push(Array.from(data));\n });\n /**\r\n * Event listener triggered when data is available in the media recorder.\r\n *\r\n * @private\r\n * @param e - The event object.\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onRecorderDataAvailable, e => {\n if (e.data && e.data.size > 0) _classPrivateFieldGet(_recordedChunks, this).push(e.data);\n });\n /**\r\n * Method to create a media recorder object and set up event listeners.\r\n *\r\n * @private\r\n * @param stream - The stream of audio from the Listener.\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _setMediaRecorder, stream => {\n // Create a new MediaRecorder object\n _classPrivateFieldSet(_mediaRecorder, this, new MediaRecorder(stream));\n\n // Add event listeners\n _classPrivateFieldGet(_mediaRecorder, this).ondataavailable = e => _classPrivateFieldGet(_onRecorderDataAvailable, this).call(this, e);\n });\n _classPrivateFieldInitSpec(this, _setAudioContext, () => {\n _classPrivateFieldSet(_audioContext, this, new (window.AudioContext || window.webkitAudioContext || window.audioContext)({\n sampleRate: this.sinkSamplingRate,\n sampleSize: this.sampleSize\n //sampleRate: 96000\n }));\n });\n /**\r\n * Public method to start the recording process.\r\n *\r\n * @param stream - The stream of audio from the Listener.\r\n * @example\r\n */\n _defineProperty(this, \"startRecording\", async stream => {\n try {\n // Create a fresh audio context\n _classPrivateFieldGet(_setAudioContext, this).call(this);\n // Set up media recorder if needed\n if (!_classPrivateFieldGet(_mediaRecorder, this)) _classPrivateFieldGet(_setMediaRecorder, this).call(this, stream);\n // clear recorded chunks\n _classPrivateFieldSet(_recordedChunks, this, []);\n // start recording\n _classPrivateFieldGet(_mediaRecorder, this).start();\n } catch (error) {\n console.error('Error in startRecording:', error);\n // Handle the error as needed, e.g., throw it or perform error-specific actions\n }\n });\n /**\r\n * Method to stop the recording process.\r\n *\r\n * @public\r\n * @example\r\n */\n _defineProperty(this, \"stopRecording\", async (mode, checkRec) => {\n try {\n // Stop the media recorder, and wait for the data to be available\n await new Promise(resolve => {\n _classPrivateFieldGet(_mediaRecorder, this).onstop = () => {\n // when the stop event is triggered, resolve the promise\n _classPrivateFieldSet(_audioBlob, this, new Blob(_classPrivateFieldGet(_recordedChunks, this), {\n type: 'audio/wav; codecs=opus'\n }));\n resolve(_classPrivateFieldGet(_audioBlob, this));\n };\n // call stop\n _classPrivateFieldGet(_mediaRecorder, this).stop();\n });\n // Now that we have data, save it\n await _classPrivateFieldGet(_saveRecording, this).call(this, mode, checkRec);\n } catch (error) {\n console.error('Error in stopRecording:', error);\n // Handle the error as needed, e.g., throw it or perform error-specific actions\n }\n });\n /** .\r\n * .\r\n * .\r\n * Public method to get the last recorded audio signal\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getLastRecordedSignal\", () => _classPrivateFieldGet(_recordedSignals, this)[_classPrivateFieldGet(_recordedSignals, this).length - 1]);\n /** .\r\n * .\r\n * .\r\n * Public method to get the last 1000hz recorded audio signal\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getLastVolumeRecordedSignal\", () => Array.from(_classPrivateFieldGet(_allVolumeRecordings, this)[_classPrivateFieldGet(_allVolumeRecordings, this).length - 1]));\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getAllRecordedSignals\", () => _classPrivateFieldGet(_recordedSignals, this));\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getAllVolumeRecordedSignals\", () => _classPrivateFieldGet(_allVolumeRecordings, this));\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getAllFilteredRecordedSignals\", () => _classPrivateFieldGet(_allHzFilteredRecordings, this));\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"clearAllFilteredRecordedSignals\", () => _classPrivateFieldSet(_allHzFilteredRecordings, this, []));\n /** .\r\n * .\r\n * .\r\n * Public method to clear last the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"clearLastFilteredRecordedSignals\", () => _classPrivateFieldGet(_allHzFilteredRecordings, this).pop());\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals for psd\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getAllUnfilteredRecordedSignals\", () => _classPrivateFieldGet(_allHzUnfilteredRecordings, this));\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"clearLastUnfilteredRecordedSignals\", () => _classPrivateFieldGet(_allHzUnfilteredRecordings, this).pop());\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals for psd\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getAllBackgroundRecordings\", () => _classPrivateFieldGet(_allBackgroundRecordings, this));\n /** .\r\n * .\r\n * .\r\n * Public method to set the sampling rate used by the capture device\r\n *\r\n * @param {Number} sinkSamplingRate - The sampling rate of the capture device\r\n * @example\r\n */\n _defineProperty(this, \"setSinkSamplingRate\", sinkSamplingRate => {\n this.sinkSamplingRate = sinkSamplingRate;\n });\n }\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (AudioRecorder);\n\n//# sourceURL=webpack://speakerCalibrator/./src/tasks/audioRecorder.js?");
172
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/web.dom-collections.iterator.js */ \"./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _myEventEmitter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../myEventEmitter */ \"./src/myEventEmitter.js\");\n\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nfunction _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }\nfunction _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError(\"Cannot initialize the same private elements twice on an object\"); }\nfunction _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }\nfunction _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }\nfunction _assertClassBrand(e, t, n) { if (\"function\" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError(\"Private element is not present on this object\"); }\n\n\n/**\r\n * @class provides a simple interface for recording audio from a microphone\r\n * using the Media Recorder API.\r\n */\nvar _mediaRecorder = /*#__PURE__*/new WeakMap();\nvar _recordedChunks = /*#__PURE__*/new WeakMap();\nvar _audioBlob = /*#__PURE__*/new WeakMap();\nvar _audioContext = /*#__PURE__*/new WeakMap();\nvar _recordedSignals = /*#__PURE__*/new WeakMap();\nvar _allHzUnfilteredRecordings = /*#__PURE__*/new WeakMap();\nvar _allBackgroundRecordings = /*#__PURE__*/new WeakMap();\nvar _allHzFilteredRecordings = /*#__PURE__*/new WeakMap();\nvar _allVolumeRecordings = /*#__PURE__*/new WeakMap();\nvar _saveRecording = /*#__PURE__*/new WeakMap();\nvar _saveFilteredRecording = /*#__PURE__*/new WeakMap();\nvar _onRecorderDataAvailable = /*#__PURE__*/new WeakMap();\nvar _setMediaRecorder = /*#__PURE__*/new WeakMap();\nvar _removeMediaRecorder = /*#__PURE__*/new WeakMap();\nvar _setAudioContext = /*#__PURE__*/new WeakMap();\nclass AudioRecorder extends _myEventEmitter__WEBPACK_IMPORTED_MODULE_1__[\"default\"] {\n constructor() {\n super(...arguments);\n /** @private */\n _classPrivateFieldInitSpec(this, _mediaRecorder, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _recordedChunks, []);\n /** @private */\n _classPrivateFieldInitSpec(this, _audioBlob, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _audioContext, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _recordedSignals, []);\n /**@private */\n _classPrivateFieldInitSpec(this, _allHzUnfilteredRecordings, []);\n /**@private */\n _classPrivateFieldInitSpec(this, _allBackgroundRecordings, []);\n /** @private */\n _classPrivateFieldInitSpec(this, _allHzFilteredRecordings, []);\n /** @private */\n _defineProperty(this, \"sinkSamplingRate\", void 0);\n /** @private */\n _defineProperty(this, \"sampleSize\", void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _allVolumeRecordings, []);\n /** @private */\n _defineProperty(this, \"flags\", {});\n /**\r\n * Decode the audio data from the recorded audio blob.\r\n *\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _saveRecording, async (mode, checkRec) => {\n const arrayBuffer = await _classPrivateFieldGet(_audioBlob, this).arrayBuffer();\n const audioBuffer = await _classPrivateFieldGet(_audioContext, this).decodeAudioData(arrayBuffer);\n console.log(audioBuffer);\n const data = audioBuffer.getChannelData(0);\n const dataArray = Array.from(data);\n console.log(\"Decoded audio buffer with \".concat(data.length, \" samples\"));\n console.log(\"Unfiltered recording should be of length: \".concat(data.length));\n if (checkRec == 'loudest') {\n const uniqueSet = new Set(dataArray);\n const numberOfUniqueValues = uniqueSet.size;\n const squaredValues = dataArray.map(value => value * value);\n const sum_of_squares = squaredValues.reduce((total, value) => total + value, 0);\n const squared_mean = sum_of_squares / dataArray.length;\n const dbLevel = 20 * Math.log10(Math.sqrt(squared_mean));\n const roundedDbLevel = Math.round(dbLevel * 10) / 10;\n console.log('Loudest 1000-Hz recording: ' + roundedDbLevel + ' dB with ' + numberOfUniqueValues + ' unique values.');\n } else if (checkRec == 'allhz') {\n const uniqueSet = new Set(dataArray);\n const numberOfUniqueValues = uniqueSet.size;\n const squaredValues = dataArray.map(value => value * value);\n const sum_of_squares = squaredValues.reduce((total, value) => total + value, 0);\n const squared_mean = sum_of_squares / dataArray.length;\n const dbLevel = 20 * Math.log10(Math.sqrt(squared_mean));\n const roundedDbLevel = Math.round(dbLevel * 10) / 10;\n console.log('All Hz Recording: ' + roundedDbLevel + ' dB with ' + numberOfUniqueValues + ' unique values.');\n }\n if (mode === 'volume') {\n console.log('Saving 1000 Hz Recording to #allVolumeRecordings');\n _classPrivateFieldGet(_allVolumeRecordings, this).push(dataArray);\n } else if (mode === 'unfiltered') {\n console.log('Saving unfiltered all Hz recording to #allHzUnfilteredRecordings');\n _classPrivateFieldGet(_allHzUnfilteredRecordings, this).push(dataArray);\n } else if (mode === 'filtered') {\n console.log('Saving filtered all hz recording to #allHzFilteredRecordings');\n _classPrivateFieldGet(_allHzFilteredRecordings, this).push(dataArray);\n } else if (mode === 'background') {\n console.log('Saving background recording to #allBackgroundRecordings');\n _classPrivateFieldGet(_allBackgroundRecordings, this).push(dataArray);\n }\n });\n _classPrivateFieldInitSpec(this, _saveFilteredRecording, async () => {\n const arrayBuffer = await _classPrivateFieldGet(_audioBlob, this).arrayBuffer();\n const audioBuffer = await _classPrivateFieldGet(_audioContext, this).decodeAudioData(arrayBuffer);\n const data = audioBuffer.getChannelData(0);\n console.log(\"Decoded audio buffer with \".concat(data.length, \" samples\"));\n console.log(\"Filtered recording should be of length: \".concat(data.length));\n _classPrivateFieldGet(_allHzFilteredRecordings, this).push(Array.from(data));\n });\n /**\r\n * Event listener triggered when data is available in the media recorder.\r\n *\r\n * @private\r\n * @param e - The event object.\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _onRecorderDataAvailable, e => {\n if (e.data && e.data.size > 0) _classPrivateFieldGet(_recordedChunks, this).push(e.data);\n });\n /**\r\n * Method to create a media recorder object and set up event listeners.\r\n *\r\n * @private\r\n * @param stream - The stream of audio from the Listener.\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _setMediaRecorder, stream => {\n // Create a new MediaRecorder object\n _classPrivateFieldSet(_mediaRecorder, this, new MediaRecorder(stream));\n\n // Add event listeners\n _classPrivateFieldGet(_mediaRecorder, this).ondataavailable = e => _classPrivateFieldGet(_onRecorderDataAvailable, this).call(this, e);\n });\n _classPrivateFieldInitSpec(this, _removeMediaRecorder, () => {\n _classPrivateFieldGet(_mediaRecorder, this).ondataavailable = null;\n _classPrivateFieldSet(_mediaRecorder, this, null);\n });\n _classPrivateFieldInitSpec(this, _setAudioContext, () => {\n _classPrivateFieldSet(_audioContext, this, new (window.AudioContext || window.webkitAudioContext || window.audioContext)({\n sampleRate: this.sinkSamplingRate,\n sampleSize: this.sampleSize\n //sampleRate: 96000\n }));\n });\n /**\r\n * Public method to start the recording process.\r\n *\r\n * @param stream - The stream of audio from the Listener.\r\n * @example\r\n */\n _defineProperty(this, \"startRecording\", async stream => {\n try {\n // Create a fresh audio context\n _classPrivateFieldGet(_setAudioContext, this).call(this);\n // Set up media recorder if needed\n if (!_classPrivateFieldGet(_mediaRecorder, this)) _classPrivateFieldGet(_setMediaRecorder, this).call(this, stream);\n // clear recorded chunks\n _classPrivateFieldSet(_recordedChunks, this, []);\n if (_classPrivateFieldGet(_mediaRecorder, this).state === 'recording') {\n _classPrivateFieldGet(_mediaRecorder, this).stop();\n }\n // start recording\n _classPrivateFieldGet(_mediaRecorder, this).start();\n } catch (error) {\n console.error('Error in startRecording:', error);\n // Handle the error as needed, e.g., throw it or perform error-specific actions\n }\n });\n /**\r\n * Method to stop the recording process.\r\n *\r\n * @public\r\n * @example\r\n */\n _defineProperty(this, \"stopRecording\", async (mode, checkRec) => {\n try {\n // Stop the media recorder, and wait for the data to be available\n await new Promise(resolve => {\n _classPrivateFieldGet(_mediaRecorder, this).onstop = () => {\n // when the stop event is triggered, resolve the promise\n _classPrivateFieldSet(_audioBlob, this, new Blob(_classPrivateFieldGet(_recordedChunks, this), {\n type: 'audio/wav; codecs=opus'\n }));\n resolve(_classPrivateFieldGet(_audioBlob, this));\n };\n // call stop\n _classPrivateFieldGet(_mediaRecorder, this).stop();\n });\n // Now that we have data, save it\n await _classPrivateFieldGet(_saveRecording, this).call(this, mode, checkRec);\n } catch (error) {\n console.error('Error in stopRecording:', error);\n // Handle the error as needed, e.g., throw it or perform error-specific actions\n }\n });\n /** .\r\n * .\r\n * .\r\n * Public method to get the last recorded audio signal\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getLastRecordedSignal\", () => _classPrivateFieldGet(_recordedSignals, this)[_classPrivateFieldGet(_recordedSignals, this).length - 1]);\n /** .\r\n * .\r\n * .\r\n * Public method to get the last 1000hz recorded audio signal\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getLastVolumeRecordedSignal\", () => Array.from(_classPrivateFieldGet(_allVolumeRecordings, this)[_classPrivateFieldGet(_allVolumeRecordings, this).length - 1]));\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getAllRecordedSignals\", () => _classPrivateFieldGet(_recordedSignals, this));\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getAllVolumeRecordedSignals\", () => _classPrivateFieldGet(_allVolumeRecordings, this));\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getAllFilteredRecordedSignals\", () => _classPrivateFieldGet(_allHzFilteredRecordings, this));\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"clearAllFilteredRecordedSignals\", () => _classPrivateFieldSet(_allHzFilteredRecordings, this, []));\n /** .\r\n * .\r\n * .\r\n * Public method to clear last the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"clearLastFilteredRecordedSignals\", () => _classPrivateFieldGet(_allHzFilteredRecordings, this).pop());\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals for psd\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getAllUnfilteredRecordedSignals\", () => _classPrivateFieldGet(_allHzUnfilteredRecordings, this));\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"clearLastUnfilteredRecordedSignals\", () => _classPrivateFieldGet(_allHzUnfilteredRecordings, this).pop());\n /** .\r\n * .\r\n * .\r\n * Public method to get all the recorded audio signals for psd\r\n *\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"getAllBackgroundRecordings\", () => _classPrivateFieldGet(_allBackgroundRecordings, this));\n /** .\r\n * .\r\n * .\r\n * Public method to set the sampling rate used by the capture device\r\n *\r\n * @param {Number} sinkSamplingRate - The sampling rate of the capture device\r\n * @example\r\n */\n _defineProperty(this, \"setSinkSamplingRate\", sinkSamplingRate => {\n this.sinkSamplingRate = sinkSamplingRate;\n });\n }\n}\n/* harmony default export */ __webpack_exports__[\"default\"] = (AudioRecorder);\n\n//# sourceURL=webpack://speakerCalibrator/./src/tasks/audioRecorder.js?");
173
173
 
174
174
  /***/ }),
175
175
 
@@ -180,7 +180,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core
180
180
  /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
181
181
 
182
182
  "use strict";
183
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array-buffer.slice.js */ \"./node_modules/core-js/modules/es.array-buffer.slice.js\");\n/* harmony import */ var core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.string.replace.js */ \"./node_modules/core-js/modules/es.string.replace.js\");\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.typed-array.float32-array.js */ \"./node_modules/core-js/modules/es.typed-array.float32-array.js\");\n/* harmony import */ var core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.typed-array.fill.js */ \"./node_modules/core-js/modules/es.typed-array.fill.js\");\n/* harmony import */ var core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.typed-array.set.js */ \"./node_modules/core-js/modules/es.typed-array.set.js\");\n/* harmony import */ var core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.typed-array.sort.js */ \"./node_modules/core-js/modules/es.typed-array.sort.js\");\n/* harmony import */ var core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/web.dom-collections.iterator.js */ \"./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _audioCalibrator__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../audioCalibrator */ \"./src/tasks/audioCalibrator.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../utils */ \"./src/utils.js\");\n/* harmony import */ var _powerCheck__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../powerCheck */ \"./src/powerCheck.js\");\n/* harmony import */ var _config_firebase__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../config/firebase */ \"./src/config/firebase.js\");\n/* harmony import */ var firebase_database__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! firebase/database */ \"./node_modules/firebase/database/dist/esm/index.esm.js\");\n/* harmony import */ var firebase_firestore__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! firebase/firestore */ \"./node_modules/firebase/firestore/dist/esm/index.esm.js\");\n\n\n\n\n\n\n\nfunction _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }\nfunction _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError(\"Cannot initialize the same private elements twice on an object\"); }\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nfunction _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }\nfunction _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }\nfunction _assertClassBrand(e, t, n) { if (\"function\" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError(\"Private element is not present on this object\"); }\n\n\n\n\n\n\n//import { phrases } from '../../../dist/example/i18n';\n\n/**\r\n *\r\n */\nvar _download = /*#__PURE__*/new WeakMap();\nvar _mlsGenInterface = /*#__PURE__*/new WeakMap();\nvar _mlsBufferView = /*#__PURE__*/new WeakMap();\nvar _mlsOrder = /*#__PURE__*/new WeakMap();\nvar _lowHz = /*#__PURE__*/new WeakMap();\nvar _highHz = /*#__PURE__*/new WeakMap();\nvar _mls = /*#__PURE__*/new WeakMap();\nvar _P = /*#__PURE__*/new WeakMap();\nvar _audioContext = /*#__PURE__*/new WeakMap();\nvar _CALIBRATION_TONE_FREQUENCY = /*#__PURE__*/new WeakMap();\nvar _CALIBRATION_TONE_TYPE = /*#__PURE__*/new WeakMap();\nvar _currentConvolution = /*#__PURE__*/new WeakMap();\nvar _awaitDesiredMLSLength = /*#__PURE__*/new WeakMap();\nvar _awaitBackgroundNoiseRecording = /*#__PURE__*/new WeakMap();\nvar _awaitSignalOnset = /*#__PURE__*/new WeakMap();\nvar _afterMLSRecord = /*#__PURE__*/new WeakMap();\nvar _afterMLSwIIRRecord = /*#__PURE__*/new WeakMap();\nvar _createCalibrationNodeFromBuffer = /*#__PURE__*/new WeakMap();\nvar _setCalibrationNodesFromBuffer = /*#__PURE__*/new WeakMap();\nvar _playCalibrationAudio = /*#__PURE__*/new WeakMap();\nvar _getTruncatedSignal = /*#__PURE__*/new WeakMap();\nvar _createCalibrationToneWithGainValue = /*#__PURE__*/new WeakMap();\nvar _createCalibrationNode = /*#__PURE__*/new WeakMap();\nvar _playCalibrationAudioVolume = /*#__PURE__*/new WeakMap();\nvar _sendToServerForProcessing = /*#__PURE__*/new WeakMap();\nclass Combination extends _audioCalibrator__WEBPACK_IMPORTED_MODULE_7__[\"default\"] {\n /**\r\n * Default constructor. Creates an instance with any number of paramters passed or the default parameters defined here.\r\n *\r\n * @param {Object<boolean, number, number, number>} calibratorParams - paramter object\r\n * @param {boolean} [calibratorParams.download = false] - boolean flag to download captures\r\n * @param {number} [calibratorParams.mlsOrder = 18] - order of the MLS to be generated\r\n * @param {number} [calibratorParams.numCaptures = 5] - number of captures to perform\r\n * @param {number} [calibratorParams.numMLSPerCapture = 2] - number of bursts of MLS per capture\r\n */\n constructor(_ref) {\n var _this;\n let {\n download = false,\n mlsOrder = 18,\n numCaptures = 3,\n numMLSPerCapture = 2,\n lowHz: _lowHz2 = 20,\n highHz: _highHz2 = 10000\n } = _ref;\n super(numCaptures, numMLSPerCapture);\n _this = this;\n /** @private */\n _defineProperty(this, \"stepNum\", 0);\n /** @private */\n _defineProperty(this, \"totalSteps\", 25);\n /** @private */\n _classPrivateFieldInitSpec(this, _download, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsGenInterface, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsBufferView, void 0);\n /** @private */\n _defineProperty(this, \"componentInvertedImpulseResponse\", null);\n /** @private */\n _defineProperty(this, \"systemInvertedImpulseResponse\", null);\n //averaged and subtracted ir returned from calibration used to calculated iir\n /** @private */\n _defineProperty(this, \"ir\", null);\n /** @private */\n _defineProperty(this, \"impulseResponses\", []);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsOrder, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _lowHz, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _highHz, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mls, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _P, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _audioContext, void 0);\n /** @private */\n _defineProperty(this, \"offsetGainNode\", void 0);\n /** @private */\n _defineProperty(this, \"componentConvolution\", void 0);\n /** @private */\n _defineProperty(this, \"componentConvolutionNoBandpass\", void 0);\n /** @private */\n _defineProperty(this, \"componentIROrigin\", {\n Freq: [],\n Gain: []\n });\n /** @private */\n _defineProperty(this, \"systemConvolution\", void 0);\n /** @private */\n _defineProperty(this, \"systemConvolutionNoBandpass\", void 0);\n ////////////////////////volume\n /** @private */\n _classPrivateFieldInitSpec(this, _CALIBRATION_TONE_FREQUENCY, 1000);\n // Hz\n\n /** @private */\n _classPrivateFieldInitSpec(this, _CALIBRATION_TONE_TYPE, 'sine');\n _defineProperty(this, \"CALIBRATION_TONE_DURATION\", 5);\n // seconds\n _defineProperty(this, \"calibrateSound1000HzPreSec\", 3.5);\n _defineProperty(this, \"calibrateSound1000HzSec\", 1.0);\n _defineProperty(this, \"calibrateSound1000HzPostSec\", 0.5);\n /** @private */\n _defineProperty(this, \"outDBSPL\", null);\n _defineProperty(this, \"THD\", null);\n _defineProperty(this, \"outDBSPL1000\", null);\n /** @private */\n _defineProperty(this, \"TAPER_SECS\", 0.01);\n // seconds\n /** @private */\n _defineProperty(this, \"status_denominator\", 8);\n /** @private */\n _defineProperty(this, \"status_numerator\", 0);\n /** @private */\n _defineProperty(this, \"percent_complete\", 0);\n /** @private */\n _defineProperty(this, \"status\", \"\");\n /**@private */\n _defineProperty(this, \"status_literal\", \"<div style=\\\"display: flex; justify-content: center;\\\"><div style=\\\"width: 200px; height: 20px; border: 2px solid #000; border-radius: 10px;\\\"><div style=\\\"width: \".concat(this.percent_complete, \"%; height: 100%; background-color: #00aaff; border-radius: 8px;\\\"></div></div></div>\"));\n /**@private */\n _defineProperty(this, \"componentIR\", null);\n /**@private */\n _defineProperty(this, \"oldComponentIR\", null);\n /**@private */\n _defineProperty(this, \"systemIR\", null);\n /**@private */\n _defineProperty(this, \"_calibrateSoundCheck\", '');\n _defineProperty(this, \"deviceType\", null);\n _defineProperty(this, \"deviceName\", null);\n _defineProperty(this, \"deviceInfo\", null);\n _defineProperty(this, \"desired_time_per_mls\", 0);\n _defineProperty(this, \"num_mls_to_skip\", 0);\n _defineProperty(this, \"desired_sampling_rate\", 0);\n _classPrivateFieldInitSpec(this, _currentConvolution, []);\n _defineProperty(this, \"mode\", 'unfiltered');\n _defineProperty(this, \"sourceNode\", void 0);\n _defineProperty(this, \"autocorrelations\", []);\n _defineProperty(this, \"iirLength\", 0);\n _defineProperty(this, \"irLength\", 0);\n _defineProperty(this, \"calibrateSoundIIRPhase\", 'linear');\n _defineProperty(this, \"componentInvertedImpulseResponseNoBandpass\", []);\n _defineProperty(this, \"componentIRInTimeDomain\", []);\n _defineProperty(this, \"systemInvertedImpulseResponseNoBandpass\", []);\n _defineProperty(this, \"_calibrateSoundBackgroundSecs\", void 0);\n _defineProperty(this, \"_calibrateSoundSmoothOctaves\", void 0);\n _defineProperty(this, \"background_noise\", {});\n _defineProperty(this, \"numSuccessfulBackgroundCaptured\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstDb\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstFilteredExtraDb\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstLevelReTBool\", void 0);\n _defineProperty(this, \"SDofFilteredRange\", {\n mls: undefined,\n component: undefined,\n system: undefined\n });\n _defineProperty(this, \"transducerType\", 'Loudspeaker');\n _defineProperty(this, \"componentIRPhase\", []);\n _defineProperty(this, \"systemIRPhase\", []);\n _defineProperty(this, \"webAudioDeviceNames\", {\n loudspeaker: '',\n microphone: '',\n loudspeakerText: '',\n microphoneText: ''\n });\n _defineProperty(this, \"waveforms\", {\n volume: {}\n });\n _defineProperty(this, \"recordingChecks\", {\n volume: {},\n unfiltered: [],\n system: [],\n component: [],\n warnings: []\n });\n _defineProperty(this, \"inDB\", void 0);\n _defineProperty(this, \"soundCheck\", '');\n _defineProperty(this, \"filteredMLSRange\", {\n component: {\n Min: null,\n Max: null\n },\n system: {\n Min: null,\n Max: null\n }\n });\n /** @private */\n _defineProperty(this, \"timeStamp\", []);\n _defineProperty(this, \"restartCalibration\", false);\n _defineProperty(this, \"calibrateSoundLimit\", 1);\n _defineProperty(this, \"filteredMLSAttenuation\", {\n component: 1,\n system: 1,\n maxAbsSystem: 1,\n maxAbsComponent: 1\n });\n //parameter result from volume calibration\n _defineProperty(this, \"T\", 0);\n //gainDBSPL result from volume calibration\n _defineProperty(this, \"gainDBSPL\", 0);\n //not always just using _calibrateSoundBurstDb for MLS so created a new parameter\n _defineProperty(this, \"power_dB\", 0);\n //system\n _defineProperty(this, \"systemAttenuatorGainDB\", 0);\n _defineProperty(this, \"systemFMaxHz\", 0);\n //component\n _defineProperty(this, \"componentAttentuatorGainDB\", 0);\n _defineProperty(this, \"componentFMaxHz\", 0);\n _defineProperty(this, \"dL_n\", void 0);\n _defineProperty(this, \"L_new_n\", void 0);\n _defineProperty(this, \"fs2\", void 0);\n _defineProperty(this, \"icapture\", 0);\n _defineProperty(this, \"permissionStatus\", null);\n /**generate string template that gets reevaluated as variable increases */\n _defineProperty(this, \"generateTemplate\", status => {\n if (this.isCalibrating) {\n return '';\n }\n if (this.percent_complete > 100) {\n this.percent_complete = 100;\n }\n let MLSsd = '';\n let componentSD = '';\n let systemSD = '';\n let flags = '';\n const soundSubtitle = document.getElementById(this.soundSubtitleId);\n if (soundSubtitle) {\n const reportWebAudioNames = \"\".concat(this.webAudioDeviceNames.loudspeakerText, \"<br/> \").concat(this.webAudioDeviceNames.microphoneText);\n soundSubtitle.innerHTML = reportWebAudioNames;\n }\n const samplingParamText = this.phrases.RC_SamplingHzBits[this.language].replace('111', this.sourceSamplingRate).replace('222', this.sinkSamplingRate).replace('333', this.calibrateSoundSamplingDesiredBits);\n const reportParameters = \"\".concat(samplingParamText);\n if (this.flags) {\n flags = \"<br> autoGainControl: \".concat(this.flags.autoGainControl, \"; \\n echoCancellation: \").concat(this.flags.echoCancellation, \";\\n noiseSuppression: \").concat(this.flags.noiseSuppression);\n }\n if (this.SDofFilteredRange['mls']) {\n MLSsd = \"<br> Recorded MLS power SD: \".concat(this.SDofFilteredRange['mls'], \" dB\");\n }\n if (this.SDofFilteredRange['system']) {\n systemSD = \"<br> Loudspeaker+Microphone correction SD: \".concat(this.SDofFilteredRange['system'], \" dB\");\n }\n if (this.SDofFilteredRange['component']) {\n componentSD = \"<br> \".concat(this.transducerType, \" correction SD: \").concat(this.SDofFilteredRange['component'], \" dB\");\n }\n const template = \"<div style=\\\"display: flex; justify-content: flex-start; margin-top: 0.4rem;\\\"><div style=\\\"width: 100%; height: 20px; border: 2px solid #000; border-radius: 10px;\\\"><div style=\\\"width: \".concat(this.percent_complete, \"%; height: 100%; background-color: #00aaff; border-radius: 8px;\\\"></div></div></div>\");\n return \"\\n \".concat(reportParameters, \" \\n \").concat(MLSsd, \"\\n \").concat(systemSD, \"\\n \").concat(componentSD, \"\\n \").concat(flags, \"\\n <br>\").concat(status, \"\\n \").concat(template);\n });\n /** increment numerator and percent for status bar */\n _defineProperty(this, \"incrementStatusBar\", () => {\n this.status_numerator += 1;\n this.percent_complete = this.status_numerator / this.status_denominator * 100;\n });\n _defineProperty(this, \"setDeviceType\", deviceType => {\n this.deviceType = deviceType;\n });\n _defineProperty(this, \"setDeviceName\", deviceName => {\n this.deviceName = deviceName;\n });\n _defineProperty(this, \"setDeviceInfo\", deviceInfo => {\n this.deviceInfo = deviceInfo;\n });\n _defineProperty(this, \"setPermissionStatus\", permissionStatus => {\n this.permissionStatus = permissionStatus;\n });\n /** .\r\n * .\r\n * .\r\n * Sends all the computed impulse responses to the backend server for processing\r\n *\r\n * @returns sets the resulting inverted impulse response to the class property\r\n * @example\r\n */\n _defineProperty(this, \"sendSystemImpulseResponsesToServerForProcessing\", async () => {\n this.addTimeStamp('Compute system IIR');\n const computedIRs = await Promise.all(this.impulseResponses);\n const filteredComputedIRs = computedIRs.filter(element => {\n return element != undefined;\n }); //log any errors that are found in this step\n console.log('filteredComputedIRs', filteredComputedIRs);\n const mls = _classPrivateFieldGet(_mls, this)[this.icapture];\n const lowHz = _classPrivateFieldGet(_lowHz, this); //gain of 1 below cutoff, need gain of 0\n const highHz = _classPrivateFieldGet(_highHz, this); //check error for anything other than 10 kHz\n const iirLength = this.iirLength;\n this.stepNum += 1;\n console.log('send impulse responses to server: ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return await this.pyServerAPI.getSystemInverseImpulseResponseWithRetry({\n payload: filteredComputedIRs.slice(0, this.numCaptures),\n mls,\n lowHz,\n highHz,\n iirLength,\n sampleRate: this.sourceSamplingRate || 96000,\n mlsAmplitude: Math.pow(10, this.power_dB / 20),\n calibrateSoundBurstFilteredExtraDb: this._calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase: this.calibrateSoundIIRPhase\n }).then(async res => {\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.systemInvertedImpulseResponse = res['iir'];\n this.systemIR = res['ir'];\n this.systemInvertedImpulseResponseNoBandpass = res['iirNoBandpass'];\n this.systemAttenuatorGainDB = res['attenuatorGain_dB'];\n this.systemFMaxHz = res['fMaxHz'];\n await this.pyServerAPI.checkMemory();\n await this.pyServerAPI.getConvolution({\n mls,\n inverse_response: this.systemInvertedImpulseResponse,\n inverse_response_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n attenuatorGain_dB: this.systemAttenuatorGainDB,\n mls_amplitude: Math.pow(10, this.power_dB / 20)\n }).then(result => {\n console.log(result);\n this.systemConvolution = result['convolution'];\n this.systemConvolutionNoBandpass = result['convolution_no_bandpass'];\n });\n\n // attenuate the system convolution if the amplitude is greater than this.calibrateSoundLimit\n // find max of absolute value of system convolution\n\n const max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(this.systemConvolution);\n this.filteredMLSAttenuation.system = this.systemConvolution.reduce((a, b) => a + b ** 2, 0) / this.systemConvolution.length;\n this.filteredMLSAttenuation.maxAbsSystem = max;\n }).catch(err => {\n console.error(err);\n });\n });\n /** .\r\n * .\r\n * .\r\n * Sends all the computed impulse responses to the backend server for processing\r\n *\r\n * @returns sets the resulting inverted impulse response to the class property\r\n * @example\r\n */\n _defineProperty(this, \"sendComponentImpulseResponsesToServerForProcessing\", async () => {\n this.addTimeStamp('Compute component IIR');\n const computedIRs = await Promise.all(this.impulseResponses);\n const filteredComputedIRs = computedIRs.filter(element => {\n return element != undefined;\n });\n let componentIRGains = this.componentIR['Gain'];\n const componentIRFreqs = this.componentIR['Freq'];\n //normalize the component IR gains\n componentIRGains = componentIRGains.map(value => {\n return value - this._calibrateSoundBurstScalarDB - this._calibrateSoundBurstDb;\n });\n if (this._calibrateSoundBurstNormalizeBy1000HzGainBool) {\n const sineGainAt1000Hz_dB = this.gainDBSPL;\n componentIRGains = componentIRGains.map(value => {\n return value - sineGainAt1000Hz_dB;\n });\n }\n const mls = _classPrivateFieldGet(_mls, this)[this.icapture];\n const lowHz = _classPrivateFieldGet(_lowHz, this);\n const iirLength = this.iirLength;\n const irLength = this.irLength;\n const highHz = _classPrivateFieldGet(_highHz, this);\n this.stepNum += 1;\n console.log('send impulse responses to server: ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n console.log();\n return this.pyServerAPI.getComponentInverseImpulseResponseWithRetry({\n payload: filteredComputedIRs.slice(0, this.numCaptures),\n mls,\n lowHz,\n highHz,\n iirLength,\n componentIRGains,\n componentIRFreqs,\n sampleRate: this.sourceSamplingRate || 96000,\n mlsAmplitude: Math.pow(10, this.power_dB / 20),\n irLength,\n calibrateSoundSmoothOctaves: this._calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz: this._calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb: this._calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase: this.calibrateSoundIIRPhase\n }).then(async res => {\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.componentInvertedImpulseResponse = res['iir'];\n this.componentInvertedImpulseResponseNoBandpass = res['iirNoBandpass'];\n this.componentIR['Gain'] = res['ir'];\n this.componentIR['Freq'] = res['frequencies'];\n this.componentIRPhase = res['component_angle'];\n this.systemIRPhase = res['system_angle'];\n this.componentIROrigin['Freq'] = res['frequencies'];\n this.componentIROrigin['Gain'] = res['irOrigin'];\n this.componentIRInTimeDomain = res['irTime'];\n this.componentAttenuatorGainDB = res['attenuatorGain_dB'];\n this.componentFMaxHz = res['fMaxHz'];\n await this.pyServerAPI.checkMemory();\n await this.pyServerAPI.getConvolution({\n mls,\n inverse_response: this.componentInvertedImpulseResponse,\n inverse_response_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n attenuatorGain_dB: this.componentAttenuatorGainDB,\n mls_amplitude: Math.pow(10, this.power_dB / 20)\n }).then(result => {\n console.log(result);\n this.componentConvolution = result['convolution'];\n this.componentConvolutionNoBandpass = result['convolution_no_bandpass'];\n });\n // attenuate the component convolution if the amplitude is greater than this.calibrateSoundLimit\n // find max of absolute value of component convolution\n const max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(this.componentConvolution);\n // if (max > this.calibrateSoundLimit) {\n // const gain = this.calibrateSoundLimit / max;\n // // apply gain to component convolution\n // this.componentConvolution = this.componentConvolution.map(value => value * gain);\n // this.filteredMLSAttenuation.component = gain;\n // }\n this.filteredMLSAttenuation.component = this.componentConvolution.reduce((a, b) => a + b ** 2, 0) / this.componentConvolution.length;\n this.filteredMLSAttenuation.maxAbsComponent = max;\n }).catch(err => {\n // this.emit('InvertedImpulseResponse', {res: false});\n console.error(err);\n });\n });\n _defineProperty(this, \"sendBackgroundRecording\", () => {\n const allSignals = this.getAllBackgroundRecordings();\n const numSignals = allSignals.length;\n const background_rec_whole = allSignals[numSignals - 1];\n const fraction = 0.5 / (this._calibrateSoundBackgroundSecs + 0.5);\n // Calculate the starting index for slicing the array\n const startIndex = Math.round(fraction * background_rec_whole.length);\n // Slice the array from the calculated start index to the end of the array\n const background_rec = background_rec_whole.slice(startIndex);\n console.log('Sending background recording to server for processing');\n this.addTimeStamp('Compute PSD of background');\n this.pyServerAPI.getBackgroundNoisePSDWithRetry({\n background_rec,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n if (this.numSuccessfulBackgroundCaptured < 1) {\n this.numSuccessfulBackgroundCaptured += 1;\n //storing all background data in background_psd object\n this.background_noise['x_background'] = res['x_background'];\n this.background_noise['y_background'] = res['y_background'];\n this.background_noise['recording'] = background_rec;\n }\n }).catch(err => {\n console.error(err);\n });\n });\n /** .\r\n * .\r\n * .\r\n * Sends the recorded signal, or a given csv string of a signal, to the back end server for processing\r\n *\r\n * @param {<array>String} signalCsv - Optional csv string of a previously recorded signal, if given, this signal will be processed\r\n * @example\r\n */\n _defineProperty(this, \"sendRecordingToServerForProcessing\", async signalCsv => {\n const allSignals = this.getAllUnfilteredRecordedSignals();\n console.log('Obtaining last all hz unfiltered recording from #allHzUnfilteredRecordings to send to server for processing');\n const numSignals = allSignals.length;\n const mls = _classPrivateFieldGet(_mlsBufferView, this)[this.icapture];\n const payload = signalCsv && signalCsv.length > 0 ? (0,_utils__WEBPACK_IMPORTED_MODULE_8__.csvToArray)(signalCsv) : allSignals[numSignals - 1];\n console.log('sending rec');\n this.stepNum += 1;\n console.log('send rec ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration Step: computing the IR of the last recording...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n if (this.isCalibrating) return null;\n await this.pyServerAPI.allHzPowerCheck({\n payload,\n sampleRate: this.sourceSamplingRate || 96000,\n binDesiredSec: this._calibrateSoundPowerBinDesiredSec,\n burstSec: this.desired_time_per_mls,\n repeats: this.numMLSPerCapture - this.num_mls_to_skip,\n warmUp: this.num_mls_to_skip\n }).then(async result => {\n if (result) {\n if (result['sd'] > this._calibrateSoundBurstMaxSD_dB && this.numSuccessfulCaptured == 0) {\n console.log('SD: ' + result['sd'] + ', greater than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n this.recordingChecks['unfiltered'].push(result);\n this.clearLastUnfilteredRecordedSignals();\n this.numSuccessfulCaptured += 1;\n } else {\n if (result['sd'] <= this._calibrateSoundBurstMaxSD_dB) {\n console.log('SD: ' + result['sd'] + ', less than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n } else {\n console.log('SD: ' + result['sd'] + ', greater than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n this.recordingChecks['warnings'].push(\"All Hz. Re-recorded \".concat(this.inDB, \" dB because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n this.status = this.generateTemplate(\"All Hz: Re-recording at \".concat(this.inDB, \" dB because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n }\n if (this.numSuccessfulCaptured == 1) {\n console.log('pop last unfiltered mls volume check');\n this.recordingChecks['unfiltered'].pop();\n }\n this.recordingChecks['unfiltered'].push(result);\n // let start = new Date().getTime() / 1000;\n // const payloadT = tf.tensor1d(payload);\n // payloadT.print();\n // const xfft = payloadT.rfft(); // tf.spe\n // xfft.array().then(array => {\n // console.log(\"fft:\", array);\n // let setItem = new Set(array);\n // console.log(\"all zero\", setItem.size === 1 && setItem.has(0));\n // });\n // console.log(\"dimention:\", xfft.shape);\n // let end = new Date().getTime() / 1000;\n // console.log(\"Time taken:\", end - start, \"seconds\");\n console.log('start calculate impulse response');\n const usedPeriodStart = this.num_mls_to_skip * this.sourceSamplingRate;\n const payload_skipped_warmUp = payload.slice(usedPeriodStart);\n await this.pyServerAPI.getAutocorrelation({\n mls: mls,\n payload: payload_skipped_warmUp,\n sampleRate: this.sourceSamplingRate || 96000,\n numPeriods: this.numMLSPerCapture - this.num_mls_to_skip\n }).then(async res => {\n this.autocorrelations.push(res['autocorrelation']);\n this.fs2 = res['fs2'];\n this.L_new_n = res['L_new_n'];\n this.dL_n = res['dL_n'];\n this.impulseResponses.push(await this.pyServerAPI.getImpulseResponse({\n mls,\n sampleRate: this.sourceSamplingRate || 96000,\n numPeriods: this.numMLSPerCapture - this.num_mls_to_skip,\n sig: payload_skipped_warmUp,\n fs2: this.fs2,\n L_new_n: this.L_new_n,\n dL_n: this.dL_n\n }).then(res => {\n this.numSuccessfulCaptured += 2;\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: \".concat(this.numSuccessfulCaptured, \"/\").concat(this.numCaptures, \" IRs computed...\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res['ir'];\n }).catch(err => {\n console.error(err);\n }));\n });\n }\n console.log('number of unfiltered recording checks:' + this.recordingChecks['unfiltered'].length);\n }\n }).catch(err => {\n console.error(err);\n });\n });\n /**\r\n * Passed to the calibration steps function, awaits the desired amount of seconds to capture the desired number\r\n * of MLS periods defined in the constructor.\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitDesiredMLSLength, async () => {\n // seconds per MLS = P / SR\n // await N * P / SR\n this.stepNum += 1;\n console.log('await desired length ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: sampling the calibration signal...\".toString() + \"\\niteration \".concat(this.stepNum));\n this.emit('update', {\n message: this.status\n });\n let time_to_wait = 0;\n if (this.mode === 'unfiltered') {\n //unfiltered\n time_to_wait = _classPrivateFieldGet(_mls, this)[0].length / this.sourceSamplingRate * this.numMLSPerCapture;\n time_to_wait = time_to_wait + this._calibrateSoundBurstPostSec;\n } else if (this.mode === 'filtered') {\n //filtered\n // time_to_wait =\n // (this.#currentConvolution.length / this.sourceSamplingRate) *\n // (this.numMLSPerCapture / (this.num_mls_to_skip + this.numMLSPerCapture));\n time_to_wait = _classPrivateFieldGet(_currentConvolution, this).length / this.sourceSamplingRate * this.numMLSPerCapture;\n time_to_wait = time_to_wait + this._calibrateSoundBurstPostSec;\n } else {\n throw new Error('Mode broke in awaitDesiredMLSLength');\n }\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_wait);\n });\n /**\r\n * Passed to the background noise recording function, awaits the desired amount of seconds to capture the desired number\r\n * of seconds of background noise\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitBackgroundNoiseRecording, async () => {\n console.log('Waiting ' + this._calibrateSoundBackgroundSecs + ' second(s) to record background noise');\n let time_to_wait = this._calibrateSoundBackgroundSecs + 0.5;\n this.addTimeStamp(\"Record \".concat(time_to_wait.toFixed(1), \" s of background.\"));\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_wait);\n });\n /** .\r\n * .\r\n * .\r\n * Passed to the calibration steps function, awaits the onset of the signal to ensure a steady state\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitSignalOnset, async () => {\n this.stepNum += 1;\n console.log('await signal onset ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: waiting for the signal to stabilize...\".toString());\n this.emit('update', {\n message: this.status\n });\n let number_of_bursts_to_skip = 0;\n let time_to_sleep = 0;\n if (this.mode === 'unfiltered') {\n time_to_sleep = _classPrivateFieldGet(_mls, this)[0].length / this.sourceSamplingRate * number_of_bursts_to_skip;\n } else if (this.mode === 'filtered') {\n console.log(_classPrivateFieldGet(_currentConvolution, this).length);\n // time_to_sleep =\n // (this.#currentConvolution.length / this.sourceSamplingRate) *\n // (number_of_bursts_to_skip / (number_of_bursts_to_skip + this.numMLSPerCapture));\n time_to_sleep = _classPrivateFieldGet(_currentConvolution, this).length / this.sourceSamplingRate * number_of_bursts_to_skip;\n } else {\n throw new Error('Mode broke in awaitSignalOnset');\n }\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_sleep);\n });\n /**\r\n * Called immediately after a recording is captured. Used to process the resulting signal\r\n * whether by sending the result to a server or by computing a result locally.\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _afterMLSRecord, async () => {\n console.log('after record');\n this.addTimeStamp(\"Send MLS to the server\");\n await this.sendRecordingToServerForProcessing();\n });\n _classPrivateFieldInitSpec(this, _afterMLSwIIRRecord, async () => {\n await this.checkPowerVariation();\n });\n /** .\r\n * .\r\n * .\r\n * Created an S Curver Buffer to taper the signal onset\r\n *\r\n * @param {*} onSetBool\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"createSCurveBuffer\", function () {\n let onSetBool = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n const curve = new Float32Array(_this.TAPER_SECS * _this.sourceSamplingRate + 1);\n const frequency = 1 / (4 * _this.TAPER_SECS);\n let j = 0;\n for (let i = 0; i < _this.TAPER_SECS * _this.sourceSamplingRate + 1; i += 1) {\n const phase = 2 * Math.PI * frequency * j;\n const onsetTaper = Math.pow(Math.sin(phase), 2);\n const offsetTaper = Math.pow(Math.cos(phase), 2);\n curve[i] = onSetBool ? onsetTaper : offsetTaper;\n j += 1 / _this.sourceSamplingRate;\n }\n return curve;\n });\n /**\r\n * Construct a Calibration Node with the calibration parameters.\r\n *\r\n * @param dataBuffer\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _createCalibrationNodeFromBuffer, dataBuffer => {\n console.log('length databuffer');\n console.log(dataBuffer.length);\n if (!this.sourceAudioContext) {\n this.makeNewSourceAudioContext();\n }\n const buffer = this.sourceAudioContext.createBuffer(1,\n // number of channels\n dataBuffer.length, this.sourceAudioContext.sampleRate // sample rate\n );\n const data = buffer.getChannelData(0); // get data\n\n // fill the buffer with our data\n try {\n for (let i = 0; i < dataBuffer.length; i += 1) {\n data[i] = dataBuffer[i];\n }\n } catch (error) {\n console.error(error);\n }\n this.sourceNode = this.sourceAudioContext.createBufferSource();\n this.sourceNode.buffer = buffer;\n if (this.mode === 'filtered') {\n //used to not loop filtered\n this.sourceNode.loop = true;\n } else {\n this.sourceNode.loop = true;\n }\n this.sourceNode.connect(this.sourceAudioContext.destination);\n this.addCalibrationNode(this.sourceNode);\n });\n /**\r\n * Given a data buffer, creates the required calibration node\r\n *\r\n * @param {*} dataBufferArray\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _setCalibrationNodesFromBuffer, function () {\n let dataBufferArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [_classPrivateFieldGet(_mlsBufferView, _this)[_this.icapture]];\n if (dataBufferArray.length === 1) {\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, _this).call(_this, dataBufferArray[0]);\n } else {\n throw new Error('The length of the data buffer array must be 1');\n }\n });\n /**\r\n * Creates an audio context and plays it for a few seconds.\r\n *\r\n * @private\r\n * @returns - Resolves when the audio is done playing.\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _playCalibrationAudio, () => {\n this.calibrationNodes[0].start(0);\n this.status = \"\";\n if (this.mode === 'unfiltered') {\n console.log('play calibration audio ' + this.stepNum);\n const pre = this._calibrateSoundBurstPreSec;\n const repeats = this._calibrateSoundBurstRepeats;\n const burst = this._calibrateSoundBurstSec;\n const post = this._calibrateSoundBurstPostSec;\n const total_dur = pre + repeats * burst + post;\n this.addTimeStamp(\"Record \".concat(total_dur.toFixed(1), \" s \") + \"(\".concat(pre.toFixed(1), \" + \").concat(repeats, \"\\xD7\").concat(burst.toFixed(1), \" + \").concat(post.toFixed(1), \" s) of MLS ver. \").concat(this.icapture));\n this.status = this.generateTemplate(\"All Hz Calibration: playing the calibration tone...\".toString()).toString();\n } else if (this.mode === 'filtered') {\n console.log('play convolved audio ' + this.stepNum);\n this.status = this.generateTemplate().toString(\"All Hz Calibration: playing the convolved calibration tone...\".toString());\n } else {\n throw new Error('Mode is incorrect');\n }\n this.emit('update', {\n message: this.status\n });\n this.stepNum += 1;\n console.log('sink sampling rate');\n console.log(this.sinkSamplingRate);\n console.log('source sampling rate');\n console.log(this.sourceSamplingRate);\n console.log('sample size');\n console.log(this.sampleSize);\n });\n /** .\r\n * .\r\n * .\r\n * Stops the audio with tapered offset\r\n *\r\n * @example\r\n */\n _defineProperty(this, \"stopCalibrationAudio\", () => {\n if (this.calibrationNodes.length === 0) {\n return;\n }\n this.calibrationNodes[0].stop(0);\n this.calibrationNodes = [];\n if (this.sourceNode) this.sourceNode.disconnect();\n this.stepNum += 1;\n console.log('stop calibration audio ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: stopping the calibration tone...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n });\n _defineProperty(this, \"playMLSwithIIR\", async (stream, convolution) => {\n let checkRec = false;\n this.mode = 'filtered';\n console.log('play mls with iir');\n //this.invertedImpulseResponse = iir\n\n await this.calibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudio, this), // play audio func (required)\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, this).call(this, convolution),\n // before play func\n _classPrivateFieldGet(_awaitSignalOnset, this),\n // before record\n () => this.numSuccessfulCaptured < 2, _classPrivateFieldGet(_awaitDesiredMLSLength, this),\n // during record\n _classPrivateFieldGet(_afterMLSwIIRRecord, this),\n // after record\n this.mode, checkRec);\n });\n _defineProperty(this, \"bothSoundCheck\", async stream => {\n let iir_ir_and_plots;\n _classPrivateFieldSet(_currentConvolution, this, this.componentConvolution);\n this.filteredMLSRange.component.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.component.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n const pre = this._calibrateSoundBurstPreSec;\n const repeats = this._calibrateSoundBurstRepeats;\n const burst = this._calibrateSoundBurstSec;\n const post = this._calibrateSoundBurstPostSec;\n const total_dur = pre + repeats * burst + post;\n this.soundCheck = 'component';\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(this.soundCheck, \" IIR.\\u201D\"));\n if (this.isCalibrating) return null;\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n let component_conv_recs = this.getAllFilteredRecordedSignals();\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttentuatorGainDB / 20);\n component_conv_recs = component_conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n let return_component_conv_rec = component_conv_recs[component_conv_recs.length - 1];\n this.clearAllFilteredRecordedSignals();\n this.numSuccessfulCaptured = 0;\n _classPrivateFieldSet(_currentConvolution, this, this.systemConvolution);\n this.filteredMLSRange.system.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.system.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'system';\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(this.soundCheck, \" IIR.\\u201D\"));\n if (this.isCalibrating) return null;\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n let system_conv_recs = this.getAllFilteredRecordedSignals();\n if (this.systemAttenuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttenuatorGainDB / 20);\n system_conv_recs = system_conv_recs.map(rec => {\n return rec.map(value => value / linearScaleAttenuation);\n });\n }\n let return_system_conv_rec = system_conv_recs[system_conv_recs.length - 1];\n // await this.checkPowerVariation(return_system_conv_rec);\n\n this.clearAllFilteredRecordedSignals();\n this.sourceAudioContext.close();\n let recs = this.getAllUnfilteredRecordedSignals();\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttentuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n let unconv_rec = recs[0];\n let return_unconv_rec = unconv_rec;\n let conv_rec = component_conv_recs[component_conv_recs.length - 1];\n\n //psd of component\n let knownGain = this.oldComponentIR.Gain;\n let knownFreq = this.oldComponentIR.Freq;\n let sampleRate = this.sourceSamplingRate || 96000;\n this.addTimeStamp('Compute PSD of MLS recording');\n if (this.isCalibrating) return null;\n let component_unconv_rec_psd = await this.pyServerAPI.getSubtractedPSDWithRetry(unconv_rec, knownGain, knownFreq, sampleRate).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of filtered recording (component)');\n if (this.isCalibrating) return null;\n let component_conv_rec_psd = await this.pyServerAPI.getSubtractedPSDWithRetry(conv_rec, knownGain, knownFreq, sampleRate).then(res => {\n let interpolatedGain = res.x.map((freq, index) => {\n let i = 0;\n while (i < knownFreq.length && knownFreq[i] < freq) {\n i++;\n }\n if (i === 0 || i === knownFreq.length) {\n return knownGain[i];\n }\n return (0,_utils__WEBPACK_IMPORTED_MODULE_8__.interpolate)(freq, knownFreq[i - 1], knownFreq[i], knownGain[i - 1], knownGain[i]);\n });\n let correctedGain = res.y.map((gain, index) => 10 * Math.log10(gain) - interpolatedGain[index]);\n let filtered_psd = correctedGain.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= this.componentFMaxHz);\n this.SDofFilteredRange['component'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n conv_rec = system_conv_recs[system_conv_recs.length - 1];\n //psd of system\n this.addTimeStamp('Compute PSD of filtered recording (system) and unfiltered recording');\n if (this.isCalibrating) return null;\n let system_recs_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n let filtered_psd = res.y_conv.filter((value, index) => res.x_conv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= _classPrivateFieldGet(_highHz, this)).map(value => 10 * Math.log10(value));\n let mls_psd = res.y_unconv.filter((value, index) => res.x_unconv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= _classPrivateFieldGet(_highHz, this)).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n console.log('mls_psd', this.SDofFilteredRange['mls']);\n this.SDofFilteredRange['system'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n\n //iir w/ and without bandpass psd. done\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of component IIR and component IIR no band pass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of system IIR and system IIR no band pass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of MLS sequence');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: _classPrivateFieldGet(_mlsBufferView, this)[0],\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of filtered MLS (system)');\n if (this.isCalibrating) return null;\n let system_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolution,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let system_no_bandpass_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolution,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of filtered MLS (component)');\n if (this.isCalibrating) return null;\n let component_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolution,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let component_no_bandpass_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolutionNoBandpass,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n filtered_recording: {\n component: return_component_conv_rec,\n system: return_system_conv_rec\n },\n unfiltered_recording: this.getAllUnfilteredRecordedSignals()[0],\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['x_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: system_filtered_mls_psd['x_mls'],\n y: system_filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: system_no_bandpass_filtered_mls_psd['x_mls'],\n y: system_no_bandpass_filtered_mls_psd['y_mls']\n },\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: system_recs_psd['x_unconv'],\n y: system_recs_psd['y_unconv']\n },\n conv: {\n x: system_recs_psd['x_conv'],\n y: system_recs_psd['y_conv']\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: component_filtered_mls_psd['x_mls'],\n y: component_filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: component_no_bandpass_filtered_mls_psd['x_mls'],\n y: component_no_bandpass_filtered_mls_psd['y_mls']\n },\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: component_unconv_rec_psd['x'],\n y: component_unconv_rec_psd['y']\n },\n conv: {\n x: component_conv_rec_psd['x'],\n y: component_conv_rec_psd['y']\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n return iir_ir_and_plots;\n });\n _defineProperty(this, \"singleSoundCheck\", async stream => {\n let iir_ir_and_plots;\n const pre = this._calibrateSoundBurstPreSec;\n const repeats = this._calibrateSoundBurstRepeats;\n const burst = this._calibrateSoundBurstSec;\n const post = this._calibrateSoundBurstPostSec;\n const total_dur = pre + repeats * burst + post;\n if (this._calibrateSoundCheck != 'system') {\n _classPrivateFieldSet(_currentConvolution, this, this.componentConvolution);\n this.filteredMLSRange.component.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.component.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'component';\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(this.soundCheck, \" IIR.\"));\n //this.addTimeStamp(`Record ${total_dur} s of MLS with speaker or microphone IIR.`);\n if (this.isCalibrating) return null;\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n } else {\n _classPrivateFieldSet(_currentConvolution, this, this.systemConvolution);\n this.filteredMLSRange.system.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.system.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'system';\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(this.soundCheck, \" IIR.\"));\n //this.addTimeStamp(`Record ${total_dur} s of MLS with speaker or microphone IIR.`);\n if (this.isCalibrating) return null;\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n }\n let conv_recs = this.getAllFilteredRecordedSignals();\n if (this._calibrateSoundCheck == 'goal') {\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttentuatorGainDB / 20);\n conv_recs = conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n } else if (this._calibrateSoundCheck == 'system') {\n if (this.systemAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttentuatorGainDB / 20);\n conv_recs = conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n }\n\n //remove the filteredMLSAttenuation from the recorded signals\n // conv_recs = conv_recs.map(rec => {\n // if (this.soundCheck === 'component') {\n // return rec.map(value => value / this.filteredMLSAttenuation.component);\n // }\n // return rec.map(value => value / this.filteredMLSAttenuation.system);\n // });\n\n let recs = this.getAllUnfilteredRecordedSignals();\n if (this._calibrateSoundCheck == 'goal') {\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttentuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n } else if (this._calibrateSoundCheck == 'system') {\n if (this.systemAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttentuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n }\n this.clearAllFilteredRecordedSignals();\n console.log('Obtaining unfiltered recording from #allHzUnfilteredRecordings to calculate PSD');\n console.log('Obtaining filtered recording from #allHzFilteredRecordings to calculate PSD');\n let unconv_rec = recs[0];\n let return_unconv_rec = unconv_rec;\n let conv_rec = conv_recs[conv_recs.length - 1];\n let return_conv_rec = conv_rec;\n this.sourceAudioContext.close();\n if (this._calibrateSoundCheck != 'system') {\n let knownGain = this.oldComponentIR.Gain;\n let knownFreq = this.oldComponentIR.Freq;\n let sampleRate = this.sourceSamplingRate || 96000;\n this.addTimeStamp('Compute PSD of MLS recording');\n if (this.isCalibrating) return null;\n let unconv_results = await this.pyServerAPI.getSubtractedPSDWithRetry(unconv_rec, knownGain, knownFreq, sampleRate).then(res => {\n console.log(res);\n let mls_psd = res.y.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n console.log('mls sd', this.SDofFilteredRange['mls']);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD recording of speaker+ mic IIR-filtered MLS recording');\n if (this.isCalibrating) return null;\n let conv_results = await this.pyServerAPI.getSubtractedPSDWithRetry(conv_rec, knownGain, knownFreq, sampleRate).then(res => {\n let interpolatedGain = res.x.map((freq, index) => {\n let i = 0;\n while (i < knownFreq.length && knownFreq[i] < freq) {\n i++;\n }\n if (i === 0 || i === knownFreq.length) {\n return knownGain[i];\n }\n return (0,_utils__WEBPACK_IMPORTED_MODULE_8__.interpolate)(freq, knownFreq[i - 1], knownFreq[i], knownGain[i - 1], knownGain[i]);\n });\n let correctedGain = res.y.map((gain, index) => 10 * Math.log10(gain) - interpolatedGain[index]);\n let filtered_psd = correctedGain.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= _classPrivateFieldGet(_highHz, this));\n this.SDofFilteredRange['component'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of speaker or mic IIR, with and without bandpass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of speaker +mic IIR, with and without bandpass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of MLS');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: _classPrivateFieldGet(_mlsBufferView, this)[this.icapture],\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of speaker or mic');\n if (this.isCalibrating) return null;\n let filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolution,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let filtered_no_bandpass_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.componentConvolutionNoBandpass,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['y_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_recording: [],\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: filtered_mls_psd['x_mls'],\n y: filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: filtered_no_bandpass_mls_psd['x_mls'],\n y: filtered_no_bandpass_mls_psd['y_mls']\n },\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: unconv_results['x'],\n y: unconv_results['y']\n },\n conv: {\n x: conv_results['x'],\n y: conv_results['y']\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n } else {\n this.addTimeStamp('Compute PSD of filtered recording (system) and unfiltered recording');\n if (this.isCalibrating) return null;\n let results = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n let filtered_psd = res.y_conv.filter((value, index) => res.x_conv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n let mls_psd = res.y_unconv.filter((value, index) => res.x_unconv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n this.SDofFilteredRange['system'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n\n //iir w/ and without bandpass psd\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of component IIR and component IIR no band pass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of system IIR and system IIR no band pass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of MLS sequence');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: _classPrivateFieldGet(_mlsBufferView, this)[this.icapture],\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of filtered MLS (system)');\n if (this.isCalibrating) return null;\n let filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolution,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let filtered_no_bandpass_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.systemConvolutionNoBandpass,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['y_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_recording: [],\n filtered_mls_psd: {\n x: filtered_mls_psd['x_mls'],\n y: filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: filtered_no_bandpass_mls_psd['x_mls'],\n y: filtered_no_bandpass_mls_psd['y_mls']\n },\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: results['x_unconv'],\n y: results['y_unconv']\n },\n conv: {\n x: results['x_conv'],\n y: results['y_conv']\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n }\n if (this.isCalibrating) return null;\n await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n iir_ir_and_plots['impulseResponses'].push(res[i]);\n }\n }\n });\n if (_classPrivateFieldGet(_download, this)) {\n this.downloadSingleUnfilteredRecording();\n this.downloadSingleFilteredRecording();\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(_classPrivateFieldGet(_mls, this), 'MLS.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentConvolution, 'python_component_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemConvolution, 'python_system_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentInvertedImpulseResponse, 'componentIIR.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemInvertedImpulseResponse, 'systemIIR.csv');\n for (let i = 0; i < this.autocorrelations.length; i++) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.autocorrelations[i], \"autocorrelation_\".concat(i));\n }\n const computedIRagain = await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(res[i], \"IR_\".concat(i));\n }\n }\n });\n }\n return iir_ir_and_plots;\n });\n /**\r\n * Public method to start the calibration process. Objects intialized from webassembly allocate new memory\r\n * and must be manually freed. This function is responsible for intializing the MlsGenInterface,\r\n * and wrapping the calibration steps with a garbage collection safe gaurd.\r\n *\r\n * @public\r\n * @param stream - The stream of audio from the Listener.\r\n * @example\r\n */\n _defineProperty(this, \"startCalibrationImpulseResponse\", async stream => {\n let desired_time = this.desired_time_per_mls;\n let checkRec = 'allhz';\n console.log('MLS sequence should be of length: ' + this.sourceSamplingRate * desired_time);\n length = this.sourceSamplingRate * desired_time;\n //get mls here\n // const calibrateSoundBurstDb = Math.pow(10, this._calibrateSoundBurstDb / 20);\n\n this.power_dB = 0;\n if (!this._calibrateSoundBurstLevelReTBool) {\n this.power_dB = this._calibrateSoundBurstDb;\n } else {\n this.power_dB = this._calibrateSoundBurstDb + (this.T - this.gainDBSPL);\n }\n const amplitude = Math.pow(10, this.power_dB / 20);\n //MLSpower = Math.pow(10,this.power_dB/20);\n this.addTimeStamp('Compute MLS sequence');\n if (this.isCalibrating) return null;\n await this.pyServerAPI.getMLSWithRetry({\n length,\n amplitude,\n calibrateSoundBurstMLSVersions: this.numCaptures\n }).then(res => {\n console.log(res);\n _classPrivateFieldSet(_mlsBufferView, this, res['mls']);\n _classPrivateFieldSet(_mls, this, res['unscaledMLS']);\n }).catch(err => {\n // this.emit('InvertedImpulseResponse', {res: false});\n console.error(err);\n });\n this.numSuccessfulBackgroundCaptured = 0;\n if (this._calibrateSoundBackgroundSecs > 0) {\n this.mode = 'background';\n this.status = this.generateTemplate(\"All Hz Calibration: sampling the background noise...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n if (this.isCalibrating) return null;\n await this.recordBackground(stream,\n //stream\n () => this.numSuccessfulBackgroundCaptured < 1,\n //loop condition\n _classPrivateFieldGet(_awaitBackgroundNoiseRecording, this),\n //sleep to record\n this.sendBackgroundRecording,\n //send to get PSD\n this.mode, checkRec);\n this.incrementStatusBar();\n }\n this.mode = 'unfiltered';\n this.numSuccessfulCaptured = 0;\n if (this.isCalibrating) return null;\n for (var i = 0; i < this.numCaptures; i++) {\n this.icapture = i;\n await this.calibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudio, this), // play audio func (required)\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, this).call(this, _classPrivateFieldGet(_mlsBufferView, this)[this.icapture]),\n // before play func\n _classPrivateFieldGet(_awaitSignalOnset, this),\n // before record\n () => this.numSuccessfulCaptured < 2,\n // loop while true\n _classPrivateFieldGet(_awaitDesiredMLSLength, this),\n // during record\n _classPrivateFieldGet(_afterMLSRecord, this),\n // after record\n this.mode, checkRec);\n this.stopCalibrationAudio();\n }\n checkRec = false;\n\n // at this stage we've captured all the required signals,\n // and have received IRs for each one\n // so let's send all the IRs to the server to be converted to a single IIR\n if (this.isCalibrating) return null;\n await this.sendSystemImpulseResponsesToServerForProcessing();\n await this.pyServerAPI.checkMemory();\n if (this.isCalibrating) return null;\n await this.sendComponentImpulseResponsesToServerForProcessing();\n this.numSuccessfulCaptured = 0;\n let iir_ir_and_plots;\n if (this._calibrateSoundCheck != 'none') {\n //do single check\n if (this._calibrateSoundCheck == 'goal' || this._calibrateSoundCheck == 'system') {\n if (this.isCalibrating) return null;\n iir_ir_and_plots = await this.singleSoundCheck(stream);\n if (this.isCalibrating) return null;\n } else {\n //both\n if (this.isCalibrating) return null;\n iir_ir_and_plots = await this.bothSoundCheck(stream);\n if (this.isCalibrating) return null;\n }\n } else {\n let unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n let conv_rec = this.componentInvertedImpulseResponse;\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec,\n conv_rec,\n sampleRate: this.sourceSamplingRate || 96000\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['y_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_recording: [],\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n if (this.isCalibrating) return null;\n await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n iir_ir_and_plots['impulseResponses'].push(res[i]);\n }\n }\n });\n if (_classPrivateFieldGet(_download, this)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(_classPrivateFieldGet(_mls, this), 'MLS.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentConvolution, 'python_component_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemConvolution, 'python_system_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentInvertedImpulseResponse, 'componentIIR.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemInvertedImpulseResponse, 'systemIIR.csv');\n for (let i = 0; i < this.autocorrelations.length; i++) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.autocorrelations[i], \"autocorrelation_\".concat(i));\n }\n const computedIRagain = await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(res[i], \"IR_\".concat(i));\n }\n }\n });\n }\n }\n if (this.isCalibrating) return null;\n this.percent_complete = 100;\n this.status = this.generateTemplate(\"All Hz Calibration: Finished\".toString()).toString();\n this.addTimeStamp('Done');\n this.emit('update', {\n message: this.status\n });\n\n //here after calibration we have the component calibration (either loudspeaker or microphone) in the same form as the componentIR\n //that was used to calibrate\n // saveToJSON(iir_ir_and_plots);\n return iir_ir_and_plots;\n });\n //////////////////////volume\n _defineProperty(this, \"handleIncomingData\", data => {\n console.log('Received data: ', data);\n if (data.type === 'soundGainDBSPL') {\n this.soundGainDBSPL = data.value;\n } else {\n throw new Error(\"Unknown data type: \".concat(data.type));\n }\n });\n _classPrivateFieldInitSpec(this, _getTruncatedSignal, function () {\n let left = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3.5;\n let right = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4.5;\n const start = Math.floor(left * _this.sourceSamplingRate);\n const end = Math.floor(right * _this.sourceSamplingRate);\n const result = Array.from(_this.getLastVolumeRecordedSignal().slice(start, end));\n console.log('Obtaining last 1000 hz recording from #allVolumeRecordings to send for processing');\n /**\r\n * function to check that capture was properly made\r\n * @param {*} list\r\n */\n const checkResult = list => {\n const setItem = new Set(list);\n if (setItem.size === 1 && setItem.has(0)) {\n console.warn('The last capture failed, all recorded signal is zero', _this.getAllVolumeRecordedSignals());\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n // restartButton.style.display = 'none';\n _this.emit('update', {\n message: 'Connection failed, hit restart button to reconnect'\n });\n }\n if (setItem.size === 0) {\n console.warn('The last capture failed, no recorded signal');\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n // restartButton.style.display = 'none';\n _this.emit('update', {\n message: 'Connection failed, hit restart button to reconnect'\n });\n }\n };\n checkResult(result);\n return result;\n });\n /** \r\n * \r\n * \r\n Construct a calibration Node with the calibration parameters and given gain value\r\n * @param {*} gainValue\r\n * */\n _classPrivateFieldInitSpec(this, _createCalibrationToneWithGainValue, gainValue => {\n const audioContext = this.makeNewSourceAudioContext();\n const oscilator = audioContext.createOscillator();\n const gainNode = audioContext.createGain();\n const taperGainNode = audioContext.createGain();\n const offsetGainNode = audioContext.createGain();\n const totalDuration = this.CALIBRATION_TONE_DURATION * 1.2;\n oscilator.frequency.value = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this);\n oscilator.type = _classPrivateFieldGet(_CALIBRATION_TONE_TYPE, this);\n gainNode.gain.value = gainValue;\n oscilator.connect(gainNode);\n gainNode.connect(taperGainNode);\n const onsetCurve = this.createSCurveBuffer();\n taperGainNode.gain.setValueCurveAtTime(onsetCurve, 0, this.TAPER_SECS);\n taperGainNode.connect(offsetGainNode);\n const offsetCurve = this.createSCurveBuffer(false);\n offsetGainNode.gain.setValueCurveAtTime(offsetCurve, totalDuration - this.TAPER_SECS, this.TAPER_SECS);\n offsetGainNode.connect(audioContext.destination);\n const gainValuesOverTime = [];\n const sampleRate = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this); // Number of samples per second\n const interval = 1 / sampleRate; // Time between samples\n\n for (let t = 0; t <= totalDuration; t += interval) {\n let gainValueAtTime = gainValue;\n\n // Apply the onset curve\n if (t < this.TAPER_SECS) {\n const onsetIndex = Math.floor(t / this.TAPER_SECS * onsetCurve.length);\n gainValueAtTime *= onsetCurve[onsetIndex];\n }\n\n // Apply the offset curve\n if (t > totalDuration - this.TAPER_SECS) {\n const offsetTime = t - (totalDuration - this.TAPER_SECS);\n const offsetIndex = Math.floor(offsetTime / this.TAPER_SECS * offsetCurve.length);\n gainValueAtTime *= offsetCurve[offsetIndex];\n }\n gainValuesOverTime.push(gainValueAtTime);\n }\n this.waveforms['volume'][this.inDB] = gainValuesOverTime;\n this.addCalibrationNode(oscilator);\n });\n /**\r\n * Construct a Calibration Node with the calibration parameters.\r\n *\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _createCalibrationNode, () => {\n const audioContext = this.makeNewSourceAudioContext();\n const oscilator = audioContext.createOscillator();\n const gainNode = audioContext.createGain();\n oscilator.frequency.value = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this);\n oscilator.type = _classPrivateFieldGet(_CALIBRATION_TONE_TYPE, this);\n gainNode.gain.value = 0.04;\n oscilator.connect(gainNode);\n gainNode.connect(audioContext.destination);\n this.addCalibrationNode(oscilator);\n });\n _classPrivateFieldInitSpec(this, _playCalibrationAudioVolume, async () => {\n if (this.numCalibratingRoundsCompleted == 1) {\n this.recordingChecks['warnings'].push(\"1000Hz. Re-recorded \".concat(this.inDB, \" dB because SD \").concat(this.recordingChecks['volume'][this.inDB]['sd'], \" > \").concat(this.calibrateSound1000HzMaxSD_dB, \" dB\"));\n const currentStatus = \"1000 Hz: Re-recording at \".concat(this.inDB, \" dB because SD \\n \").concat(this.recordingChecks['volume'][this.inDB]['sd'], \" > \\n \").concat(this.calibrateSound1000HzMaxSD_dB, \" dB\").toString();\n this.status = this.generateTemplate(currentStatus).toString();\n this.emit('update', {\n message: this.status\n });\n }\n const totalDuration = this.CALIBRATION_TONE_DURATION * 1.2;\n this.calibrationNodes[0].start(0);\n this.calibrationNodes[0].stop(totalDuration);\n console.log(\"Playing a buffer of \".concat(this.CALIBRATION_TONE_DURATION, \" seconds of audio\"));\n console.log(\"Waiting a total of \".concat(totalDuration, \" seconds\"));\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(totalDuration);\n });\n _defineProperty(this, \"stopCalibrationAudioVolume\", () => {\n if (this.calibrationNodes.length > 0) {\n this.calibrationNodes[0].stop();\n }\n });\n _classPrivateFieldInitSpec(this, _sendToServerForProcessing, async lCalib => {\n console.log('Sending data to server');\n let left = this.calibrateSound1000HzPreSec;\n let right = this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec;\n if (this.isCalibrating) return null;\n this.pyServerAPI.getVolumeCalibration({\n sampleRate: this.sourceSamplingRate,\n payload: _classPrivateFieldGet(_getTruncatedSignal, this).call(this, left, right),\n lCalib: lCalib\n }).then(res => {\n //if res is undefined, throw an error\n if (res === undefined) {\n throw new Error('No response from server in getVolumeCalibration function. Please try again.');\n }\n if (this.outDBSPL === null) {\n this.incrementStatusBar();\n this.outDBSPL = res['outDbSPL'];\n this.outDBSPL1000 = res['outDbSPL1000'];\n this.THD = res['thd'];\n }\n }).catch(err => {\n console.warn(err);\n });\n const rec = this.getLastVolumeRecordedSignal();\n console.log('pre period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice(0, this.calibrateSound1000HzPreSec * this.sourceSamplingRate)).toFixed(1));\n console.log('pre period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice(this.calibrateSound1000HzPreSec * this.sourceSamplingRate, (this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec) * this.sourceSamplingRate)).toFixed(1));\n console.log('pre period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice((this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec) * this.sourceSamplingRate)).toFixed(1));\n const res = (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.volumePowerCheck)(rec, this.sourceSamplingRate || 96000, this.calibrateSound1000HzPreSec, this.calibrateSound1000HzSec, this._calibrateSoundPowerBinDesiredSec);\n console.log(res);\n this.recordingChecks['volume'][this.inDB] = res;\n console.log('Recording checks in sendToServer', this.recordingChecks['volume']);\n const getSD = () => this.recordingChecks['volume'][this.inDB]['sd'];\n // const getSDMessage = () => {\n // //SOUND 6.7 s. 2.5+2.5+0.5 s. 1000 Hz at -60 dB. SD = 1.3 dB\n // // And reporting each rejected recording as\n // // SOUND 6.7 s. 2.5+2.5+0.5 s. 1000 Hz at -60 dB, SD = 19.7 > 4 dB.\n\n // if (this.numCalibratingRoundsCompleted == 1)\n // return `. SD = ${getSD()} > ${this.calibrateSound1000HzMaxSD_dB} dB.`;\n // return `. SD = ${getSD()} dB`;\n // };\n // const total_dur =\n // this.calibrateSound1000HzPreSec +\n // this.calibrateSound1000HzSec +\n // this.calibrateSound1000HzPostSec;\n\n // this.addTimeStamp(\n // `${this.calibrateSound1000HzPreSec.toFixed(1)}` +\n // `+${this.calibrateSound1000HzSec.toFixed(1)}` +\n // `+${this.calibrateSound1000HzPostSec.toFixed(1)} s.` +\n // `1000 Hz at ${this.inDB} dB${getSDMessage()}`\n // );\n });\n _defineProperty(this, \"startCalibrationVolume\", async (stream, gainValues, lCalib, componentGainDBSPL) => {\n if (this.isCalibrating) return null;\n const trialIterations = gainValues.length;\n this.status_denominator += trialIterations;\n const thdValues = [];\n const inDBValues = [];\n let inDB = 0;\n const outDBSPLValues = [];\n const outDBSPL1000Values = [];\n let checkRec = 'loudest';\n // do one calibration that will be discarded\n const soundLevelToDiscard = -60;\n const gainToDiscard = Math.pow(10, soundLevelToDiscard / 20);\n this.inDB = soundLevelToDiscard;\n this.status = this.generateTemplate(\"1000 Hz Calibration: Sound Level \".concat(soundLevelToDiscard, \" dB\").toString()).toString();\n //this.emit('update', {message: `1000 Hz Calibration: Sound Level ${soundLevelToDiscard} dB`});\n this.emit('update', {\n message: this.status\n });\n this.startTime = new Date().getTime();\n do {\n console.log('while loop');\n if (this.isCalibrating) {\n console.log('restart calibration');\n return null;\n }\n // eslint-disable-next-line no-await-in-loop\n await this.volumeCalibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudioVolume, this), _classPrivateFieldGet(_createCalibrationToneWithGainValue, this), _classPrivateFieldGet(_sendToServerForProcessing, this), gainToDiscard, lCalib,\n //todo make this a class parameter\n checkRec, () => {\n return this.recordingChecks['volume'][this.inDB]['sd'];\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } while (this.outDBSPL === null);\n //reset the values\n //this.incrementStatusBar();\n\n this.outDBSPL = null;\n this.outDBSPL = null;\n this.outDBSPL1000 = null;\n this.THD = null;\n\n // run the calibration at different gain values provided by the user\n for (let i = 0; i < trialIterations; i++) {\n //convert gain to DB and add to inDB\n if (i == trialIterations - 1) {\n checkRec = 'loudest';\n }\n inDB = Math.log10(gainValues[i]) * 20;\n // precision to 1 decimal place\n inDB = Math.round(inDB * 10) / 10;\n this.inDB = inDB;\n inDBValues.push(inDB);\n console.log('next update');\n this.status = this.generateTemplate(\"1000 Hz Calibration: Sound Level \".concat(inDB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n do {\n if (this.isCalibrating) {\n console.log('restart calibration');\n return null;\n }\n // eslint-disable-next-line no-await-in-loop\n await this.volumeCalibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudioVolume, this), _classPrivateFieldGet(_createCalibrationToneWithGainValue, this), _classPrivateFieldGet(_sendToServerForProcessing, this), gainValues[i], lCalib,\n //todo make this a class parameter\n checkRec, () => {\n var _this$recordingChecks;\n return ((_this$recordingChecks = this.recordingChecks) === null || _this$recordingChecks === void 0 || (_this$recordingChecks = _this$recordingChecks['volume']) === null || _this$recordingChecks === void 0 || (_this$recordingChecks = _this$recordingChecks[this.inDB]) === null || _this$recordingChecks === void 0 ? void 0 : _this$recordingChecks['sd']) || 0;\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } while (this.outDBSPL === null);\n outDBSPL1000Values.push(this.outDBSPL1000);\n thdValues.push(this.THD);\n outDBSPLValues.push(this.outDBSPL);\n this.outDBSPL = null;\n this.outDBSPL1000 = null;\n this.THD = null;\n }\n if (this.isCalibrating) return null;\n // get the volume calibration parameters from the server\n this.addTimeStamp('Compute sound calibration parameters');\n const parameters = await this.pyServerAPI.getVolumeCalibrationParameters({\n inDBValues: inDBValues,\n outDBSPLValues: outDBSPL1000Values,\n lCalib: lCalib,\n componentGainDBSPL\n }).then(res => {\n this.incrementStatusBar();\n return res;\n }).catch(err => {\n throw err;\n });\n if (this.isCalibrating) return null;\n const result = {\n parameters: parameters,\n inDBValues: inDBValues,\n outDBSPLValues: outDBSPLValues,\n outDBSPL1000Values: outDBSPL1000Values,\n thdValues: thdValues\n };\n return result;\n });\n _defineProperty(this, \"writeFrqGainToFirestore\", async (speakerID, frq, gain, OEM, documentID) => {\n // freq and gain are too large to take samples 1 in every 100 samples\n // const sampledFrq = [];\n // const sampledGain = [];\n // for (let i = 0; i < frq.length; i += 100) {\n // sampledFrq.push(frq[i]);\n // sampledGain.push(gain[i]);\n // }\n\n const data = {\n Freq: frq,\n Gain: gain\n };\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.updateDoc)(docRef, {\n linear: data\n });\n\n // divide frq and gain into smaller chunks and write to firestore one chunk at a time\n // use arrayUnion to append to the array\n // const chunkSize = 600;\n // const chunkedFrq = [];\n // const chunkedGain = [];\n // for (let i = 0; i < frq.length; i += chunkSize) {\n // chunkedFrq.push(frq.slice(i, i + chunkSize));\n // chunkedGain.push(gain.slice(i, i + chunkSize));\n // }\n // const docRef = doc(database, 'Microphones', documentID);\n // for (let i = 0; i < chunkedFrq.length; i++) {\n // await updateDoc(docRef, {\n // linear: {\n // Freq: arrayUnion(...chunkedFrq[i]),\n // Gain: arrayUnion(...chunkedGain[i]),\n // },\n // });\n // }\n });\n // function to write frq and gain to firebase database given speakerID\n _defineProperty(this, \"writeFrqGain\", async (speakerID, frq, gain, OEM) => {\n // freq and gain are too large to take samples 1 in every 100 samples\n\n const sampledFrq = [];\n const sampledGain = [];\n for (let i = 0; i < frq.length; i += 100) {\n sampledFrq.push(frq[i]);\n sampledGain.push(gain[i]);\n }\n const data = {\n Freq: sampledFrq,\n Gain: sampledGain\n };\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/linear\")), data);\n });\n // Function to Read frq and gain from firebase database given speakerID\n // returns an array of frq and gain if speakerID exists, returns null otherwise\n _defineProperty(this, \"readFrqGainFromFirestore\", async (speakerID, OEM, isDefault) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', isDefault));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n // if exists return the linear field of the first document\n if (querySnapshot.size > 0) {\n const timestamp = new firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.Timestamp(querySnapshot.docs[0].data().createDate.seconds, querySnapshot.docs[0].data().createDate.nanoseconds);\n return {\n ir: querySnapshot.docs[0].data().linear,\n createDate: timestamp.toDate(),\n jsonFileName: querySnapshot.docs[0].data().jsonFileName\n };\n }\n return null;\n });\n _defineProperty(this, \"readFrqGain\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/linear\")));\n if (snapshot.exists()) {\n return snapshot.val();\n }\n return null;\n });\n _defineProperty(this, \"readGainat1000HzFromFirestore\", async (speakerID, OEM, isDefault) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', isDefault));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n // if exists return the Gain1000 field of the first document\n if (querySnapshot.size > 0) {\n return querySnapshot.docs[0].data().Gain1000;\n }\n return null;\n });\n _defineProperty(this, \"readGainat1000Hz\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/Gain1000\")));\n if (snapshot.exists()) {\n return snapshot.val();\n }\n return null;\n });\n _defineProperty(this, \"writeGainat1000HzToFirestore\", async (speakerID, gain, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.updateDoc)(docRef, {\n Gain1000: gain\n });\n });\n _defineProperty(this, \"writeGainat1000Hz\", async (speakerID, gain, OEM) => {\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/Gain1000\")), gain);\n });\n _defineProperty(this, \"writeIsSmartPhoneToFirestore\", async (speakerID, isSmartPhone, OEM) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', true));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n if (querySnapshot.size > 0) {\n const docRef = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.addDoc)(collectionRef, {\n isSmartPhone: isSmartPhone,\n isDefault: false\n });\n return docRef.id;\n } else {\n const docRef = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.addDoc)(collectionRef, {\n isSmartPhone: isSmartPhone,\n isDefault: true\n });\n return docRef.id;\n }\n });\n _defineProperty(this, \"writeIsSmartPhone\", async (speakerID, isSmartPhone, OEM) => {\n const data = {\n isSmartPhone: isSmartPhone\n };\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/isSmartPhone\")), isSmartPhone);\n });\n _defineProperty(this, \"writeMicrophoneInfoToFirestore\", async (speakerID, micInfo, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.setDoc)(docRef, micInfo, {\n merge: true\n });\n });\n _defineProperty(this, \"doesMicrophoneExistInFirestore\", async (speakerID, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphone', OEM, speakerID, documentID);\n const docSnap = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDoc)(docRef);\n if (docSnap.exists()) {\n return true;\n }\n return false;\n });\n _defineProperty(this, \"doesMicrophoneExist\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID)));\n if (snapshot.exists()) {\n return true;\n }\n return false;\n });\n _defineProperty(this, \"addMicrophoneInfo\", async (speakerID, OEM, micInfo) => {\n // add to database if /info does not exist\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/info\")));\n if (!snapshot.exists()) {\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/info\")), micInfo);\n }\n });\n _defineProperty(this, \"convertToDB\", gain => {\n return Math.log10(gain) * 20;\n });\n _defineProperty(this, \"findGainatFrequency\", (frequencies, gains, targetFrequency) => {\n // Find the index of the first frequency in the array greater than the target frequency\n let index = 0;\n while (index < frequencies.length && frequencies[index] < targetFrequency) {\n index++;\n }\n\n // Handle cases when the target frequency is outside the range of the given data\n if (index === 0) {\n return gains[0];\n } else if (index === frequencies.length) {\n return gains[gains.length - 1];\n } else {\n // Interpolate the gain based on the surrounding frequencies\n const x0 = frequencies[index - 1];\n const y0 = gains[index - 1];\n const x1 = frequencies[index];\n const y1 = gains[index];\n return this.interpolate(targetFrequency, x0, y0, x1, y1);\n }\n });\n _defineProperty(this, \"checkPowerVariation\", async () => {\n let recordings = this.getAllFilteredRecordedSignals();\n // remove filteredMLSAttenuation from the recordings\n\n // recordings = recordings.map(recording => {\n // if (this.soundCheck == 'component') {\n // return recording.map(value => value / this.filteredMLSAttenuation.component);\n // }\n // return recording.map(value => value / this.filteredMLSAttenuation.system);\n // });\n\n const rec = recordings[recordings.length - 1];\n await this.pyServerAPI.allHzPowerCheck({\n payload: rec,\n sampleRate: this.sourceSamplingRate || 96000,\n binDesiredSec: this._calibrateSoundPowerBinDesiredSec,\n burstSec: this.desired_time_per_mls,\n repeats: this.numMLSPerCapture - this.num_mls_to_skip,\n warmUp: this.num_mls_to_skip\n }).then(result => {\n if (result) {\n if (result['sd'] > this._calibrateSoundBurstMaxSD_dB && this.numSuccessfulCaptured == 0) {\n console.log('filtered recording sd too high');\n this.recordingChecks['warnings'].push(\"All Hz. Re-recorded \".concat(this.inDB, \" because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n this.status = this.generateTemplate(\"All Hz: Re-recording at \".concat(this.inDB, \" dB because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n // numSuccessfulCaptured no longer to count number of successful capture but count attemps\n // is sd below _calibrateSoundBurstMaxSD_dB then count two attemps\n // else count one attemp\n this.numSuccessfulCaptured += 1;\n } else {\n this.recordingChecks[this.soundCheck].push(result);\n // Now we do at most 2 attempts if sd > _calibrateSoundBurstMaxSD_dB\n // Second attempt is the final\n if (this.numSuccessfulCaptured < 2) {\n this.numSuccessfulCaptured += 2;\n this.stepNum += 1;\n this.incrementStatusBar();\n console.log('after mls w iir record for some reason add numSucc capt ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: \".concat(this.numSuccessfulCaptured, \" recording of convolved MLS captured\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n }\n }\n }\n });\n });\n _defineProperty(this, \"getGainDBSPL\", () => {\n var freqIndex = this.componentIR.Freq.indexOf(1000);\n\n // If freqIndex is not -1 (meaning 1000 is found in the freq array)\n if (freqIndex !== -1) {\n // Get the corresponding gain value using the index\n var gainValue = this.componentIR.Gain[freqIndex];\n return gainValue;\n } else {\n console.log('Freq 1000 not found in the array.');\n return null;\n }\n });\n // Example of how to use the writeFrqGain and readFrqGain functions\n // writeFrqGain('speaker1', [1, 2, 3], [4, 5, 6]);\n // Speaker1 is the speakerID you want to write to in the database\n // readFrqGain('MiniDSPUMIK_1').then(data => console.log(data));\n // MiniDSPUMIK_1 is the speakerID with some Data in the database\n //adding gainDBSPL\n _defineProperty(this, \"startCalibration\", async function (stream, gainValues) {\n let lCalib = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 104.92978421490648;\n let componentIR = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n let microphoneName = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'MiniDSP-UMIK1-711-4754-vertical';\n let _calibrateSoundCheck = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 'goal';\n let isSmartPhone = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;\n let _calibrateSoundBurstDb = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : -18;\n let _calibrateSoundBurstFilteredExtraDb = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 6;\n let _calibrateSoundBurstLevelReTBool = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;\n let _calibrateSoundBurstUses1000HzGainBool = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : false;\n let _calibrateSoundBurstRepeats = arguments.length > 11 && arguments[11] !== undefined ? arguments[11] : 3;\n let _calibrateSoundBurstSec = arguments.length > 12 && arguments[12] !== undefined ? arguments[12] : 1;\n let _calibrateSoundBurstPreSec = arguments.length > 13 && arguments[13] !== undefined ? arguments[13] : 1;\n let _calibrateSoundBurstPostSec = arguments.length > 14 && arguments[14] !== undefined ? arguments[14] : 1;\n let _calibrateSoundHz = arguments.length > 15 && arguments[15] !== undefined ? arguments[15] : 48000;\n let _calibrateSoundIRSec = arguments.length > 16 && arguments[16] !== undefined ? arguments[16] : 0.2;\n let _calibrateSoundIIRSec = arguments.length > 17 && arguments[17] !== undefined ? arguments[17] : 0.2;\n let _calibrateSoundIIRPhase = arguments.length > 18 && arguments[18] !== undefined ? arguments[18] : 'linear';\n let calibrateSound1000HzPreSec = arguments.length > 19 && arguments[19] !== undefined ? arguments[19] : 0.5;\n let calibrateSound1000HzSec = arguments.length > 20 && arguments[20] !== undefined ? arguments[20] : 0.5;\n let calibrateSound1000HzPostSec = arguments.length > 21 && arguments[21] !== undefined ? arguments[21] : 0.5;\n let _calibrateSoundBackgroundSecs = arguments.length > 22 && arguments[22] !== undefined ? arguments[22] : 0;\n let _calibrateSoundSmoothOctaves = arguments.length > 23 && arguments[23] !== undefined ? arguments[23] : 0.33;\n let _calibrateSoundSmoothMinBandwidthHz = arguments.length > 24 && arguments[24] !== undefined ? arguments[24] : 200;\n let _calibrateSoundPowerBinDesiredSec = arguments.length > 25 && arguments[25] !== undefined ? arguments[25] : 0.2;\n let _calibrateSoundPowerDbSDToleratedDb = arguments.length > 26 && arguments[26] !== undefined ? arguments[26] : 1;\n let _calibrateSoundTaperSec = arguments.length > 27 && arguments[27] !== undefined ? arguments[27] : 0.01;\n let micManufacturer = arguments.length > 28 && arguments[28] !== undefined ? arguments[28] : '';\n let micSerialNumber = arguments.length > 29 && arguments[29] !== undefined ? arguments[29] : '';\n let micModelNumber = arguments.length > 30 && arguments[30] !== undefined ? arguments[30] : '';\n let micModelName = arguments.length > 31 && arguments[31] !== undefined ? arguments[31] : '';\n let calibrateMicrophonesBool = arguments.length > 32 ? arguments[32] : undefined;\n let authorEmails = arguments.length > 33 ? arguments[33] : undefined;\n let webAudioDeviceNames = arguments.length > 34 && arguments[34] !== undefined ? arguments[34] : {\n loudspeaker: 'loudspeaker',\n microphone: 'microphone',\n microphoneText: 'xxx XXX'\n };\n let userIDs = arguments.length > 35 ? arguments[35] : undefined;\n let restartButton = arguments.length > 36 ? arguments[36] : undefined;\n let reminder = arguments.length > 37 ? arguments[37] : undefined;\n let calibrateSoundLimit = arguments.length > 38 ? arguments[38] : undefined;\n let _calibrateSoundBurstNormalizeBy1000HzGainBool = arguments.length > 39 && arguments[39] !== undefined ? arguments[39] : false;\n let _calibrateSoundBurstScalarDB = arguments.length > 40 && arguments[40] !== undefined ? arguments[40] : 71;\n let calibrateSound1000HzMaxSD_dB = arguments.length > 41 && arguments[41] !== undefined ? arguments[41] : 4;\n let calibrateSound1000HzMaxTries = arguments.length > 42 && arguments[42] !== undefined ? arguments[42] : 4;\n let _calibrateSoundBurstMaxSD_dB = arguments.length > 43 && arguments[43] !== undefined ? arguments[43] : 4;\n let calibrateSoundSamplingDesiredBits = arguments.length > 44 && arguments[44] !== undefined ? arguments[44] : 24;\n let language = arguments.length > 45 ? arguments[45] : undefined;\n let loudspeakerModelName = arguments.length > 46 && arguments[46] !== undefined ? arguments[46] : '';\n let phrases = arguments.length > 47 ? arguments[47] : undefined;\n let soundSubtitleId = arguments.length > 48 ? arguments[48] : undefined;\n _this._calibrateSoundBurstPreSec = _calibrateSoundBurstPreSec;\n _this._calibrateSoundBurstRepeats = _calibrateSoundBurstRepeats;\n _this._calibrateSoundBurstSec = _calibrateSoundBurstSec;\n _this.micModelName = micModelName;\n _this.loudspeakerModelName = loudspeakerModelName;\n _this.language = language;\n _this.TAPER_SECS = _calibrateSoundTaperSec;\n _this.calibrateSoundLimit = calibrateSoundLimit;\n _this._calibrateSoundBurstDb = _calibrateSoundBurstDb;\n _this._calibrateSoundBurstFilteredExtraDb = _calibrateSoundBurstFilteredExtraDb;\n _this._calibrateSoundBurstLevelReTBool = _calibrateSoundBurstLevelReTBool;\n _this.CALIBRATION_TONE_DURATION = calibrateSound1000HzPreSec + calibrateSound1000HzSec + calibrateSound1000HzPostSec;\n _this.calibrateSound1000HzPreSec = calibrateSound1000HzPreSec;\n _this.calibrateSound1000HzSec = calibrateSound1000HzSec;\n _this.calibrateSound1000HzPostSec = calibrateSound1000HzPostSec;\n _this.iirLength = Math.floor(_calibrateSoundIIRSec * _this.sourceSamplingRate);\n _this.irLength = Math.floor(_calibrateSoundIRSec * _this.sourceSamplingRate);\n _this.calibrateSoundIIRPhase = _calibrateSoundIIRPhase;\n _this.num_mls_to_skip = Math.ceil(_calibrateSoundBurstPreSec / _calibrateSoundBurstSec);\n _this._calibrateSoundBurstPostSec = _calibrateSoundBurstPostSec;\n _this.numMLSPerCapture = _calibrateSoundBurstRepeats + _this.num_mls_to_skip;\n _this.desired_time_per_mls = _calibrateSoundBurstSec;\n _this.desired_sampling_rate = _calibrateSoundHz;\n _this._calibrateSoundBackgroundSecs = _calibrateSoundBackgroundSecs;\n _this._calibrateSoundSmoothOctaves = _calibrateSoundSmoothOctaves;\n _this._calibrateSoundSmoothMinBandwidthHz = _calibrateSoundSmoothMinBandwidthHz;\n _this._calibrateSoundPowerBinDesiredSec = _calibrateSoundPowerBinDesiredSec;\n _this._calibrateSoundBurstUses1000HzGainBool = _calibrateSoundBurstUses1000HzGainBool;\n _this._calibrateSoundPowerDbSDToleratedDb = _calibrateSoundPowerDbSDToleratedDb;\n _this._calibrateSoundBurstNormalizeBy1000HzGainBool = _calibrateSoundBurstNormalizeBy1000HzGainBool;\n _this._calibrateSoundBurstScalarDB = _calibrateSoundBurstScalarDB;\n _this.webAudioDeviceNames = webAudioDeviceNames;\n _this.calibrateSoundSamplingDesiredBits = calibrateSoundSamplingDesiredBits;\n _this.phrases = phrases;\n _this.soundSubtitleId = soundSubtitleId;\n if (isSmartPhone) {\n const leftQuote = '\\u201C'; // “\n const rightQuote = '\\u201D'; // ”\n _this.webAudioDeviceNames.microphone = _this.deviceInfo.microphoneFromAPI;\n const quotedWebAudioMic = leftQuote + _this.webAudioDeviceNames.microphone + rightQuote;\n const combinedMicText = _this.micModelName + ' ' + quotedWebAudioMic;\n webAudioDeviceNames.microphoneText = _this.phrases.RC_nameMicrophone[_this.language].replace('“xxx”', combinedMicText).replace('“XXX”', combinedMicText);\n }\n // this.webAudioDeviceNames.microphoneText = this.webAudioDeviceNames.microphoneText\n // .replace('xxx', this.webAudioDeviceNames.microphone)\n // .replace('XXX', this.webAudioDeviceNames.microphone);\n //feed calibration goal here\n _this._calibrateSoundCheck = _calibrateSoundCheck;\n _this.calibrateSound1000HzMaxSD_dB = calibrateSound1000HzMaxSD_dB;\n _this.calibrateSound1000HzMaxTries = calibrateSound1000HzMaxTries;\n _this._calibrateSoundBurstMaxSD_dB = _calibrateSoundBurstMaxSD_dB;\n //check if a componentIR was given to the system, if it isn't check for the microphone. using dummy data here bc we need to\n //check the db based on the microphone currently connected\n\n //new lCalib found at top of calibration files *1000hz, make sure to correct\n //based on zeroing of 1000hz, search for \"*1000Hz\"\n const ID = isSmartPhone ? micModelNumber : micSerialNumber;\n const OEM = isSmartPhone ? micModelName === 'UMIK-1' || micModelName === 'UMIK-2' ? 'minidsp' : _this.deviceInfo.OEM ? _this.deviceInfo.OEM.toLowerCase().split(' ').join('') : micManufacturer.toLowerCase().split(' ').join('') : micManufacturer.toLowerCase().split(' ').join('');\n // const ID = \"712-5669\";\n // const OEM = \"minidsp\";\n const micInfo = {\n micModelName: isSmartPhone ? micModelName : microphoneName,\n OEM: isSmartPhone ? micModelName === 'UMIK-1' || micModelName === 'UMIK-2' ? 'miniDSP' : _this.deviceInfo.OEM : micManufacturer,\n ID: ID,\n createDate: new Date(),\n DateText: (0,_utils__WEBPACK_IMPORTED_MODULE_8__.getCurrentTimeString)(),\n HardwareName: isSmartPhone ? _this.deviceInfo.hardwarename : microphoneName,\n hardwareFamily: isSmartPhone ? _this.deviceInfo.hardwarefamily : microphoneName,\n HardwareModel: isSmartPhone ? _this.deviceInfo.hardwaremodel : microphoneName,\n PlatformName: isSmartPhone ? _this.deviceInfo.platformname : 'N/A',\n PlatformVersion: isSmartPhone ? _this.deviceInfo.platformversion : 'N/A',\n DeviceType: isSmartPhone ? _this.deviceInfo.devicetype : 'N/A',\n ID_from_51Degrees: isSmartPhone ? _this.deviceInfo.DeviceId : 'N/A',\n calibrateMicrophonesBool: calibrateMicrophonesBool,\n screenHeight: _this.deviceInfo.screenHeight,\n screenWidth: _this.deviceInfo.screenWidth,\n webAudioDeviceNames: {\n loudspeaker: _this.webAudioDeviceNames.loudspeaker,\n microphone: _this.webAudioDeviceNames.microphone\n },\n userIDs: userIDs,\n lowercaseOEM: OEM ? OEM.toLowerCase().split(' ').join('') : ''\n };\n if (calibrateMicrophonesBool) {\n micInfo['authorEmails'] = authorEmails;\n }\n // if undefined in micInfo, set to empty string\n for (const [key, value] of Object.entries(micInfo)) {\n if (value === undefined) {\n micInfo[key] = '';\n }\n }\n\n // this.writeMicrophoneInfoToFirestore(ID, micInfo, OEM, 'default');\n // this.addMicrophoneInfo(ID, OEM, micInfo);\n if (componentIR == null) {\n //mode 'ir'\n //global variable this.componentIR must be set\n await _this.readFrqGainFromFirestore(ID, OEM, true).then(data => {\n if (data !== null) {\n _this.componentIR = data.ir;\n micInfo['parentTimestamp'] = data.createDate ? data.createDate : new Date();\n micInfo['parentFilenameJSON'] = data.jsonFileName ? data.jsonFileName : '';\n }\n });\n\n // await this.readFrqGain(ID, OEM).then(data => {\n // return data;\n // });\n\n // lCalib = await this.readGainat1000Hz(ID, OEM);\n lCalib = await _this.readGainat1000HzFromFirestore(ID, OEM, true);\n micInfo['gainDBSPL'] = lCalib;\n // this.componentGainDBSPL = this.convertToDB(lCalib);\n _this.componentGainDBSPL = lCalib;\n //TODO: if this call to database is unknown, cannot perform experiment => return false\n if (_this.componentIR == null) {\n _this.status = \"Microphone (\".concat(OEM, \",\").concat(ID, \") is not found in the database. Please add it to the database.\").toString();\n _this.emit('update', {\n message: _this.status\n });\n return false;\n }\n } else {\n _this.transducerType = 'Microphone';\n _this.componentIR = componentIR;\n lCalib = _this.findGainatFrequency(_this.componentIR.Freq, _this.componentIR.Gain, 1000);\n // this.componentGainDBSPL = this.convertToDB(lCalib);\n _this.componentGainDBSPL = lCalib;\n // await this.writeIsSmartPhone(ID, isSmartPhone, OEM);\n }\n _this.oldComponentIR = JSON.parse(JSON.stringify(_this.componentIR));\n return await new Promise(async (resolve, reject) => {\n // add event listner to params.restartButton to resolve the promise with a string: 'restart'\n\n if (reminder) {\n reminder.style.display = '';\n }\n if (restartButton) {\n restartButton.style.display = '';\n restartButton.addEventListener('click', () => {\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n restartButton.style.display = 'none';\n if (reminder) {\n reminder.style.display = 'none';\n }\n _this.emit('update', {\n message: 'Restarting calibration...'\n });\n resolve('restart');\n });\n }\n await _this.pyServerAPI.checkMemory();\n // calibrate volume\n\n let volumeResults = await _this.startCalibrationVolume(stream, gainValues, lCalib, _this.componentGainDBSPL);\n if (!volumeResults) return;\n _this.T = volumeResults['parameters']['T'];\n _this.gainDBSPL = volumeResults['parameters']['gainDBSPL'];\n\n // end calibrate volume\n\n let impulseResponseResults = await _this.startCalibrationImpulseResponse(stream);\n if (!impulseResponseResults) return;\n impulseResponseResults['background_noise'] = _this.background_noise;\n impulseResponseResults['system']['background_noise'] = _this.background_noise;\n impulseResponseResults['component']['background_noise'] = _this.background_noise;\n\n //attenuate system background noise\n if (_this.systemAttenuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, _this.systemAttenuatorGainDB / 20);\n let linearScalePowerAttenuation = Math.pow(10, _this.systemAttenuatorGainDB / 10);\n impulseResponseResults['system']['background_noise']['recording'] = impulseResponseResults['background_noise']['recording'].map(value => value / linearScaleAttenuation);\n impulseResponseResults['system']['background_noise']['x_background'] = impulseResponseResults['background_noise']['x_background'];\n impulseResponseResults['system']['background_noise']['y_background'] = impulseResponseResults['background_noise']['y_background'].map(value => value / linearScalePowerAttenuation);\n }\n //attenuate component background noise\n if (_this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, _this.componentAttenuatorGainDB / 20);\n let linearScalePowerAttenuation = Math.pow(10, _this.componentAttenuatorGainDB / 10);\n impulseResponseResults['component']['background_noise']['recording'] = impulseResponseResults['background_noise']['recording'].map(value => value / linearScaleAttenuation);\n impulseResponseResults['component']['background_noise']['x_background'] = impulseResponseResults['background_noise']['x_background'];\n impulseResponseResults['component']['background_noise']['y_background'] = impulseResponseResults['background_noise']['y_background'].map(value => value / linearScalePowerAttenuation);\n }\n impulseResponseResults['system']['attenuatorGainDB'] = _this.systemAttenuatorGainDB;\n impulseResponseResults['component']['attenuatorGainDB'] = _this.componentAttenuatorGainDB;\n impulseResponseResults['system']['fMaxHz'] = _this.systemFMaxHz;\n impulseResponseResults['component']['fMaxHz'] = _this.componentFMaxHz;\n impulseResponseResults['L_new_n'] = _this.L_new_n;\n impulseResponseResults['fs2'] = _this.fs2;\n if (componentIR != null) {\n var _impulseResponseResul;\n // I corrected microphone/loudpeaker IR scale in easyeyes,\n // but since we write microphone IR to firestore here\n // we need to correct microphone IR here\n let correctGain = Math.round((volumeResults.parameters.gainDBSPL - _this.componentGainDBSPL) * 10) / 10;\n let IrFreq = impulseResponseResults === null || impulseResponseResults === void 0 ? void 0 : impulseResponseResults.component.ir.Freq.map(freq => Math.round(freq));\n let IrGain = impulseResponseResults === null || impulseResponseResults === void 0 || (_impulseResponseResul = impulseResponseResults.component) === null || _impulseResponseResul === void 0 ? void 0 : _impulseResponseResul.ir.Gain;\n const IrGainAt1000Hz = IrGain[IrFreq.findIndex(freq => freq === 1000)];\n const difference = Math.round(10 * (IrGainAt1000Hz - correctGain)) / 10;\n IrGain = IrGain.map(gain => gain - difference);\n micInfo['mls'] = Number(_this.SDofFilteredRange['mls']);\n micInfo['systemCorrectionSD'] = Number(_this.SDofFilteredRange['system']);\n micInfo['componentCorrectionSD'] = Number(_this.SDofFilteredRange['component']);\n console.log(typeof micInfo['componentCorrectionSD']);\n // const id = await this.writeIsSmartPhoneToFirestore(ID, isSmartPhone, OEM);\n // await this.writeMicrophoneInfoToFirestore(ID, micInfo, OEM, id);\n // await this.writeFrqGainToFirestore(ID, IrFreq, IrGain, OEM, id);\n // micInfo['gainDBSPL'] = impulseResponseResults.component.gainDBSPL;\n // await this.writeGainat1000HzToFirestore(ID, micInfo['gainDBSPL'], OEM, id);\n // await this.writeGainat1000Hz(ID, micInfo['gainDBSPL'], OEM);\n }\n const total_results = {\n ...volumeResults,\n ...impulseResponseResults\n };\n total_results['filteredMLSRange'] = _this.filteredMLSRange;\n total_results['filteredMLSAttenuation'] = _this.filteredMLSAttenuation;\n total_results['micInfo'] = micInfo;\n total_results['audioInfo'] = {};\n total_results['audioInfo']['sinkSampleRate'] = _this.sinkSamplingRate;\n total_results['audioInfo']['sourceSampleRate'] = _this.sourceSamplingRate;\n total_results['audioInfo']['bitsPerSample'] = _this.sampleSize;\n const timeStampresult = [..._this.timeStamp].join('\\n');\n total_results['timeStamps'] = timeStampresult;\n total_results['recordingChecks'] = _this.recordingChecks;\n total_results['waveforms'] = _this.waveforms;\n total_results['component']['phase'] = _this.componentIRPhase;\n total_results['system']['phase'] = _this.systemIRPhase;\n total_results['qualityMetrics'] = _this.SDofFilteredRange;\n total_results['flags'] = _this.flags;\n total_results['permissionStatus'] = _this.permissionStatus;\n console.log('total results');\n console.log(total_results);\n console.log('Time Stamps');\n console.log(timeStampresult);\n resolve(total_results);\n });\n });\n _classPrivateFieldSet(_mlsOrder, this, parseInt(mlsOrder, 10));\n _classPrivateFieldSet(_P, this, 2 ** mlsOrder - 1);\n _classPrivateFieldSet(_download, this, download);\n _classPrivateFieldSet(_mls, this, []);\n _classPrivateFieldSet(_lowHz, this, _lowHz2);\n _classPrivateFieldSet(_highHz, this, _highHz2);\n }\n // Function to perform linear interpolation between two points\n interpolate(x, x0, y0, x1, y1) {\n return y0 + (x - x0) * (y1 - y0) / (x1 - x0);\n }\n}\n_defineProperty(Combination, \"createInverseSCurveBuffer\", (length, phase) => {\n const curve = new Float32Array(length);\n let i;\n let j = length - 1;\n for (i = 0; i < length; i += 1) {\n // scale the curve to be between 0-1\n curve[i] = Math.sin(Math.PI * j / length - phase) / 2 + 0.5;\n j -= 1;\n }\n return curve;\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (Combination);\n\n//# sourceURL=webpack://speakerCalibrator/./src/tasks/combination/combination.js?");
183
+ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! core-js/modules/es.array-buffer.slice.js */ \"./node_modules/core-js/modules/es.array-buffer.slice.js\");\n/* harmony import */ var core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_array_buffer_slice_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! core-js/modules/es.string.replace.js */ \"./node_modules/core-js/modules/es.string.replace.js\");\n/* harmony import */ var core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_string_replace_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! core-js/modules/es.typed-array.float32-array.js */ \"./node_modules/core-js/modules/es.typed-array.float32-array.js\");\n/* harmony import */ var core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_float32_array_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! core-js/modules/es.typed-array.fill.js */ \"./node_modules/core-js/modules/es.typed-array.fill.js\");\n/* harmony import */ var core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_fill_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! core-js/modules/es.typed-array.set.js */ \"./node_modules/core-js/modules/es.typed-array.set.js\");\n/* harmony import */ var core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_set_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! core-js/modules/es.typed-array.sort.js */ \"./node_modules/core-js/modules/es.typed-array.sort.js\");\n/* harmony import */ var core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_es_typed_array_sort_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! core-js/modules/web.dom-collections.iterator.js */ \"./node_modules/core-js/modules/web.dom-collections.iterator.js\");\n/* harmony import */ var core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(core_js_modules_web_dom_collections_iterator_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _audioCalibrator__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../audioCalibrator */ \"./src/tasks/audioCalibrator.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../utils */ \"./src/utils.js\");\n/* harmony import */ var _powerCheck__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../powerCheck */ \"./src/powerCheck.js\");\n/* harmony import */ var _config_firebase__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../config/firebase */ \"./src/config/firebase.js\");\n/* harmony import */ var firebase_database__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! firebase/database */ \"./node_modules/firebase/database/dist/esm/index.esm.js\");\n/* harmony import */ var firebase_firestore__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! firebase/firestore */ \"./node_modules/firebase/firestore/dist/esm/index.esm.js\");\n\n\n\n\n\n\n\nfunction _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }\nfunction _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError(\"Cannot initialize the same private elements twice on an object\"); }\nfunction _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }\nfunction _toPropertyKey(t) { var i = _toPrimitive(t, \"string\"); return \"symbol\" == typeof i ? i : i + \"\"; }\nfunction _toPrimitive(t, r) { if (\"object\" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || \"default\"); if (\"object\" != typeof i) return i; throw new TypeError(\"@@toPrimitive must return a primitive value.\"); } return (\"string\" === r ? String : Number)(t); }\nfunction _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }\nfunction _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }\nfunction _assertClassBrand(e, t, n) { if (\"function\" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError(\"Private element is not present on this object\"); }\n\n\n\n\n\n\n//import { phrases } from '../../../dist/example/i18n';\n\n/**\r\n *\r\n */\nvar _download = /*#__PURE__*/new WeakMap();\nvar _mlsGenInterface = /*#__PURE__*/new WeakMap();\nvar _mlsBufferView = /*#__PURE__*/new WeakMap();\nvar _mlsOrder = /*#__PURE__*/new WeakMap();\nvar _lowHz = /*#__PURE__*/new WeakMap();\nvar _highHz = /*#__PURE__*/new WeakMap();\nvar _mls = /*#__PURE__*/new WeakMap();\nvar _P = /*#__PURE__*/new WeakMap();\nvar _audioContext = /*#__PURE__*/new WeakMap();\nvar _CALIBRATION_TONE_FREQUENCY = /*#__PURE__*/new WeakMap();\nvar _CALIBRATION_TONE_TYPE = /*#__PURE__*/new WeakMap();\nvar _currentConvolution = /*#__PURE__*/new WeakMap();\nvar _awaitDesiredMLSLength = /*#__PURE__*/new WeakMap();\nvar _awaitBackgroundNoiseRecording = /*#__PURE__*/new WeakMap();\nvar _awaitSignalOnset = /*#__PURE__*/new WeakMap();\nvar _afterMLSRecord = /*#__PURE__*/new WeakMap();\nvar _afterMLSwIIRRecord = /*#__PURE__*/new WeakMap();\nvar _createCalibrationNodeFromBuffer = /*#__PURE__*/new WeakMap();\nvar _setCalibrationNodesFromBuffer = /*#__PURE__*/new WeakMap();\nvar _playCalibrationAudio = /*#__PURE__*/new WeakMap();\nvar _getTruncatedSignal = /*#__PURE__*/new WeakMap();\nvar _createCalibrationToneWithGainValue = /*#__PURE__*/new WeakMap();\nvar _createCalibrationNode = /*#__PURE__*/new WeakMap();\nvar _playCalibrationAudioVolume = /*#__PURE__*/new WeakMap();\nvar _sendToServerForProcessing = /*#__PURE__*/new WeakMap();\nclass Combination extends _audioCalibrator__WEBPACK_IMPORTED_MODULE_7__[\"default\"] {\n /**\r\n * Default constructor. Creates an instance with any number of paramters passed or the default parameters defined here.\r\n *\r\n * @param {Object<boolean, number, number, number>} calibratorParams - paramter object\r\n * @param {boolean} [calibratorParams.download = false] - boolean flag to download captures\r\n * @param {number} [calibratorParams.mlsOrder = 18] - order of the MLS to be generated\r\n * @param {number} [calibratorParams.numCaptures = 5] - number of captures to perform\r\n * @param {number} [calibratorParams.numMLSPerCapture = 2] - number of bursts of MLS per capture\r\n */\n constructor(_ref) {\n var _this;\n let {\n download = false,\n mlsOrder = 18,\n numCaptures = 3,\n numMLSPerCapture = 2,\n lowHz: _lowHz2 = 20,\n highHz: _highHz2 = 10000\n } = _ref;\n super(numCaptures, numMLSPerCapture);\n _this = this;\n /** @private */\n _defineProperty(this, \"stepNum\", 0);\n /** @private */\n _defineProperty(this, \"totalSteps\", 25);\n /** @private */\n _classPrivateFieldInitSpec(this, _download, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsGenInterface, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsBufferView, void 0);\n /** @private */\n _defineProperty(this, \"componentInvertedImpulseResponse\", null);\n /** @private */\n _defineProperty(this, \"systemInvertedImpulseResponse\", null);\n //averaged and subtracted ir returned from calibration used to calculated iir\n /** @private */\n _defineProperty(this, \"ir\", null);\n /** @private */\n _defineProperty(this, \"impulseResponses\", []);\n /** @private */\n _classPrivateFieldInitSpec(this, _mlsOrder, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _lowHz, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _highHz, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _mls, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _P, void 0);\n /** @private */\n _classPrivateFieldInitSpec(this, _audioContext, void 0);\n /** @private */\n _defineProperty(this, \"offsetGainNode\", void 0);\n /** @private */\n _defineProperty(this, \"componentConvolution\", void 0);\n /** @private */\n _defineProperty(this, \"componentConvolutionNoBandpass\", void 0);\n /** @private */\n _defineProperty(this, \"componentIROrigin\", {\n Freq: [],\n Gain: []\n });\n /** @private */\n _defineProperty(this, \"systemConvolution\", void 0);\n /** @private */\n _defineProperty(this, \"systemConvolutionNoBandpass\", void 0);\n ////////////////////////volume\n /** @private */\n _classPrivateFieldInitSpec(this, _CALIBRATION_TONE_FREQUENCY, 1000);\n // Hz\n\n /** @private */\n _classPrivateFieldInitSpec(this, _CALIBRATION_TONE_TYPE, 'sine');\n _defineProperty(this, \"CALIBRATION_TONE_DURATION\", 5);\n // seconds\n _defineProperty(this, \"calibrateSound1000HzPreSec\", 3.5);\n _defineProperty(this, \"calibrateSound1000HzSec\", 1.0);\n _defineProperty(this, \"calibrateSound1000HzPostSec\", 0.5);\n /** @private */\n _defineProperty(this, \"outDBSPL\", null);\n _defineProperty(this, \"THD\", null);\n _defineProperty(this, \"outDBSPL1000\", null);\n /** @private */\n _defineProperty(this, \"TAPER_SECS\", 0.01);\n // seconds\n /** @private */\n _defineProperty(this, \"status_denominator\", 8);\n /** @private */\n _defineProperty(this, \"status_numerator\", 0);\n /** @private */\n _defineProperty(this, \"percent_complete\", 0);\n /** @private */\n _defineProperty(this, \"status\", \"\");\n /**@private */\n _defineProperty(this, \"status_literal\", \"<div style=\\\"display: flex; justify-content: center;\\\"><div style=\\\"width: 200px; height: 20px; border: 2px solid #000; border-radius: 10px;\\\"><div style=\\\"width: \".concat(this.percent_complete, \"%; height: 100%; background-color: #00aaff; border-radius: 8px;\\\"></div></div></div>\"));\n /**@private */\n _defineProperty(this, \"componentIR\", null);\n /**@private */\n _defineProperty(this, \"oldComponentIR\", null);\n /**@private */\n _defineProperty(this, \"systemIR\", null);\n /**@private */\n _defineProperty(this, \"_calibrateSoundCheck\", '');\n _defineProperty(this, \"deviceType\", null);\n _defineProperty(this, \"deviceName\", null);\n _defineProperty(this, \"deviceInfo\", null);\n _defineProperty(this, \"desired_time_per_mls\", 0);\n _defineProperty(this, \"num_mls_to_skip\", 0);\n _defineProperty(this, \"desired_sampling_rate\", 0);\n _classPrivateFieldInitSpec(this, _currentConvolution, []);\n _defineProperty(this, \"mode\", 'unfiltered');\n _defineProperty(this, \"sourceNode\", void 0);\n _defineProperty(this, \"autocorrelations\", []);\n _defineProperty(this, \"iirLength\", 0);\n _defineProperty(this, \"irLength\", 0);\n _defineProperty(this, \"calibrateSoundIIRPhase\", 'linear');\n _defineProperty(this, \"componentInvertedImpulseResponseNoBandpass\", []);\n _defineProperty(this, \"componentIRInTimeDomain\", []);\n _defineProperty(this, \"systemInvertedImpulseResponseNoBandpass\", []);\n _defineProperty(this, \"_calibrateSoundBackgroundSecs\", void 0);\n _defineProperty(this, \"_calibrateSoundSmoothOctaves\", void 0);\n _defineProperty(this, \"background_noise\", {});\n _defineProperty(this, \"numSuccessfulBackgroundCaptured\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstDb\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstFilteredExtraDb\", void 0);\n _defineProperty(this, \"_calibrateSoundBurstLevelReTBool\", void 0);\n _defineProperty(this, \"SDofFilteredRange\", {\n mls: undefined,\n component: undefined,\n system: undefined\n });\n _defineProperty(this, \"transducerType\", 'Loudspeaker');\n _defineProperty(this, \"componentIRPhase\", []);\n _defineProperty(this, \"systemIRPhase\", []);\n _defineProperty(this, \"webAudioDeviceNames\", {\n loudspeaker: '',\n microphone: '',\n loudspeakerText: '',\n microphoneText: ''\n });\n _defineProperty(this, \"waveforms\", {\n volume: {}\n });\n _defineProperty(this, \"recordingChecks\", {\n volume: {},\n unfiltered: [],\n system: [],\n component: [],\n warnings: []\n });\n _defineProperty(this, \"inDB\", void 0);\n _defineProperty(this, \"soundCheck\", '');\n _defineProperty(this, \"filteredMLSRange\", {\n component: {\n Min: null,\n Max: null\n },\n system: {\n Min: null,\n Max: null\n }\n });\n /** @private */\n _defineProperty(this, \"timeStamp\", []);\n _defineProperty(this, \"restartCalibration\", false);\n _defineProperty(this, \"calibrateSoundLimit\", 1);\n _defineProperty(this, \"filteredMLSAttenuation\", {\n component: 1,\n system: 1,\n maxAbsSystem: 1,\n maxAbsComponent: 1\n });\n //parameter result from volume calibration\n _defineProperty(this, \"T\", 0);\n //gainDBSPL result from volume calibration\n _defineProperty(this, \"gainDBSPL\", 0);\n //not always just using _calibrateSoundBurstDb for MLS so created a new parameter\n _defineProperty(this, \"power_dB\", 0);\n //system\n _defineProperty(this, \"systemAttenuatorGainDB\", 0);\n _defineProperty(this, \"systemFMaxHz\", 0);\n //component\n _defineProperty(this, \"componentAttentuatorGainDB\", 0);\n _defineProperty(this, \"componentFMaxHz\", 0);\n _defineProperty(this, \"dL_n\", void 0);\n _defineProperty(this, \"L_new_n\", void 0);\n _defineProperty(this, \"fs2\", void 0);\n _defineProperty(this, \"icapture\", 0);\n _defineProperty(this, \"permissionStatus\", null);\n /**generate string template that gets reevaluated as variable increases */\n _defineProperty(this, \"generateTemplate\", status => {\n if (this.isCalibrating) {\n return '';\n }\n if (this.percent_complete > 100) {\n this.percent_complete = 100;\n }\n let MLSsd = '';\n let componentSD = '';\n let systemSD = '';\n let flags = '';\n const soundSubtitle = document.getElementById(this.soundSubtitleId);\n if (soundSubtitle) {\n const reportWebAudioNames = \"\".concat(this.webAudioDeviceNames.loudspeakerText, \"<br/> \").concat(this.webAudioDeviceNames.microphoneText);\n soundSubtitle.innerHTML = reportWebAudioNames;\n }\n const samplingParamText = this.phrases.RC_SamplingHzBits[this.language].replace('111', this.sourceSamplingRate).replace('222', this.sinkSamplingRate).replace('333', this.calibrateSoundSamplingDesiredBits);\n const reportParameters = \"\".concat(samplingParamText);\n if (this.flags) {\n flags = \"<br> autoGainControl: \".concat(this.flags.autoGainControl, \"; \\n echoCancellation: \").concat(this.flags.echoCancellation, \";\\n noiseSuppression: \").concat(this.flags.noiseSuppression);\n }\n if (this.SDofFilteredRange['mls']) {\n MLSsd = \"<br> Recorded MLS power SD: \".concat(this.SDofFilteredRange['mls'], \" dB\");\n }\n if (this.SDofFilteredRange['system']) {\n systemSD = \"<br> Loudspeaker+Microphone correction SD: \".concat(this.SDofFilteredRange['system'], \" dB\");\n }\n if (this.SDofFilteredRange['component']) {\n componentSD = \"<br> \".concat(this.transducerType, \" correction SD: \").concat(this.SDofFilteredRange['component'], \" dB\");\n }\n const template = \"<div style=\\\"display: flex; justify-content: flex-start; margin-top: 0.4rem;\\\"><div style=\\\"width: 100%; height: 20px; border: 2px solid #000; border-radius: 10px;\\\"><div style=\\\"width: \".concat(this.percent_complete, \"%; height: 100%; background-color: #00aaff; border-radius: 8px;\\\"></div></div></div>\");\n return \"\\n \".concat(reportParameters, \" \\n \").concat(MLSsd, \"\\n \").concat(systemSD, \"\\n \").concat(componentSD, \"\\n \").concat(flags, \"\\n <br>\").concat(status, \"\\n \").concat(template);\n });\n /** increment numerator and percent for status bar */\n _defineProperty(this, \"incrementStatusBar\", () => {\n this.status_numerator += 1;\n this.percent_complete = this.status_numerator / this.status_denominator * 100;\n });\n _defineProperty(this, \"setDeviceType\", deviceType => {\n this.deviceType = deviceType;\n });\n _defineProperty(this, \"setDeviceName\", deviceName => {\n this.deviceName = deviceName;\n });\n _defineProperty(this, \"setDeviceInfo\", deviceInfo => {\n this.deviceInfo = deviceInfo;\n });\n _defineProperty(this, \"setPermissionStatus\", permissionStatus => {\n this.permissionStatus = permissionStatus;\n });\n /** .\r\n * .\r\n * .\r\n * Sends all the computed impulse responses to the backend server for processing\r\n *\r\n * @returns sets the resulting inverted impulse response to the class property\r\n * @example\r\n */\n _defineProperty(this, \"sendSystemImpulseResponsesToServerForProcessing\", async () => {\n this.addTimeStamp('Compute system IIR');\n const computedIRs = await Promise.all(this.impulseResponses);\n const filteredComputedIRs = computedIRs.filter(element => {\n return element != undefined;\n }); //log any errors that are found in this step\n console.log('filteredComputedIRs', filteredComputedIRs);\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const mls = this.downsampleSignal(_classPrivateFieldGet(_mls, this)[this.icapture], this._calibrateSoundBurstDownsample);\n const lowHz = _classPrivateFieldGet(_lowHz, this); //gain of 1 below cutoff, need gain of 0\n const highHz = _classPrivateFieldGet(_highHz, this); //check error for anything other than 10 kHz\n const iirLength = this.iirLength;\n this.stepNum += 1;\n console.log('send impulse responses to server: ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n const filteredComputedIRs_slice = filteredComputedIRs.slice(0, this.numCaptures);\n // for each element in filteredComputedIRs_slice, downsample it\n const payload_downsampled = filteredComputedIRs_slice.map(ir => this.downsampleSignal(ir, this._calibrateSoundBurstDownsample));\n return await this.pyServerAPI.getSystemInverseImpulseResponseWithRetry({\n payload: payload_downsampled,\n mls,\n lowHz,\n highHz,\n iirLength,\n sampleRate: fMLS,\n mlsAmplitude: Math.pow(10, this.power_dB / 20),\n calibrateSoundBurstFilteredExtraDb: this._calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase: this.calibrateSoundIIRPhase,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async res => {\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.systemInvertedImpulseResponse = res['iir'];\n this.systemIR = res['ir'];\n this.systemInvertedImpulseResponseNoBandpass = res['iirNoBandpass'];\n this.systemAttenuatorGainDB = res['attenuatorGain_dB'];\n this.systemFMaxHz = res['fMaxHz'];\n await this.pyServerAPI.checkMemory();\n await this.pyServerAPI.getConvolution({\n mls,\n inverse_response: this.systemInvertedImpulseResponse,\n inverse_response_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n attenuatorGain_dB: this.systemAttenuatorGainDB,\n mls_amplitude: Math.pow(10, this.power_dB / 20)\n }).then(result => {\n console.log(result);\n this.systemConvolution = this.upsampleSignal(result['convolution'], this._calibrateSoundBurstDownsample);\n this.systemConvolutionNoBandpass = this.upsampleSignal(result['convolution_no_bandpass'], this._calibrateSoundBurstDownsample);\n });\n\n // attenuate the system convolution if the amplitude is greater than this.calibrateSoundLimit\n // find max of absolute value of system convolution\n\n const max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(this.systemConvolution);\n this.filteredMLSAttenuation.system = this.systemConvolution.reduce((a, b) => a + b ** 2, 0) / this.systemConvolution.length;\n this.filteredMLSAttenuation.maxAbsSystem = max;\n }).catch(err => {\n console.error(err);\n });\n });\n /** .\r\n * .\r\n * .\r\n * Sends all the computed impulse responses to the backend server for processing\r\n *\r\n * @returns sets the resulting inverted impulse response to the class property\r\n * @example\r\n */\n _defineProperty(this, \"sendComponentImpulseResponsesToServerForProcessing\", async () => {\n this.addTimeStamp('Compute component IIR');\n const computedIRs = await Promise.all(this.impulseResponses);\n const filteredComputedIRs = computedIRs.filter(element => {\n return element != undefined;\n });\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const filteredComputedIRs_slice = filteredComputedIRs.slice(0, this.numCaptures);\n // for each element in filteredComputedIRs_slice, downsample it\n const payload_downsampled = filteredComputedIRs_slice.map(ir => this.downsampleSignal(ir, this._calibrateSoundBurstDownsample));\n let componentIRGains = this.componentIR['Gain'];\n const componentIRFreqs = this.componentIR['Freq'];\n //normalize the component IR gains\n componentIRGains = componentIRGains.map(value => {\n return value - this._calibrateSoundBurstScalarDB - this._calibrateSoundBurstDb;\n });\n if (this._calibrateSoundBurstNormalizeBy1000HzGainBool) {\n const sineGainAt1000Hz_dB = this.gainDBSPL;\n componentIRGains = componentIRGains.map(value => {\n return value - sineGainAt1000Hz_dB;\n });\n }\n const mls = this.downsampleSignal(_classPrivateFieldGet(_mls, this)[this.icapture], this._calibrateSoundBurstDownsample);\n const lowHz = _classPrivateFieldGet(_lowHz, this);\n const iirLength = this.iirLength;\n const irLength = this.irLength;\n const highHz = _classPrivateFieldGet(_highHz, this);\n this.stepNum += 1;\n console.log('send impulse responses to server: ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return this.pyServerAPI.getComponentInverseImpulseResponseWithRetry({\n payload: payload_downsampled,\n mls,\n lowHz,\n highHz,\n iirLength,\n componentIRGains,\n componentIRFreqs,\n sampleRate: fMLS,\n mlsAmplitude: Math.pow(10, this.power_dB / 20),\n irLength,\n calibrateSoundSmoothOctaves: this._calibrateSoundSmoothOctaves,\n calibrateSoundSmoothMinBandwidthHz: this._calibrateSoundSmoothMinBandwidthHz,\n calibrateSoundBurstFilteredExtraDb: this._calibrateSoundBurstFilteredExtraDb,\n calibrateSoundIIRPhase: this.calibrateSoundIIRPhase,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async res => {\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the IIR...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n this.componentInvertedImpulseResponse = res['iir'];\n this.componentInvertedImpulseResponseNoBandpass = res['iirNoBandpass'];\n this.componentIR['Gain'] = res['ir'];\n this.componentIR['Freq'] = res['frequencies'];\n this.componentIRPhase = res['component_angle'];\n this.systemIRPhase = res['system_angle'];\n this.componentIROrigin['Freq'] = res['frequencies'];\n this.componentIROrigin['Gain'] = res['irOrigin'];\n this.componentIRInTimeDomain = res['irTime'];\n this.componentAttenuatorGainDB = res['attenuatorGain_dB'];\n this.componentFMaxHz = res['fMaxHz'];\n await this.pyServerAPI.checkMemory();\n await this.pyServerAPI.getConvolution({\n mls,\n inverse_response: this.componentInvertedImpulseResponse,\n inverse_response_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n attenuatorGain_dB: this.componentAttenuatorGainDB,\n mls_amplitude: Math.pow(10, this.power_dB / 20)\n }).then(result => {\n console.log('result', result);\n this.componentConvolution = this.upsampleSignal(result['convolution'], this._calibrateSoundBurstDownsample);\n this.componentConvolutionNoBandpass = this.upsampleSignal(result['convolution_no_bandpass'], this._calibrateSoundBurstDownsample);\n console.log('this.componentConvolution...', this.componentConvolution);\n console.log('this.componentConvolutionNoBandpass...', this.componentConvolutionNoBandpass);\n });\n // attenuate the component convolution if the amplitude is greater than this.calibrateSoundLimit\n // find max of absolute value of component convolution\n const max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(this.componentConvolution);\n // if (max > this.calibrateSoundLimit) {\n // const gain = this.calibrateSoundLimit / max;\n // // apply gain to component convolution\n // this.componentConvolution = this.componentConvolution.map(value => value * gain);\n // this.filteredMLSAttenuation.component = gain;\n // }\n this.filteredMLSAttenuation.component = this.componentConvolution.reduce((a, b) => a + b ** 2, 0) / this.componentConvolution.length;\n this.filteredMLSAttenuation.maxAbsComponent = max;\n }).catch(err => {\n // this.emit('InvertedImpulseResponse', {res: false});\n console.error(err);\n });\n });\n /**\r\n * Upsamples a signal by repeating each sample N times\r\n * @param {Array<number>} signal - The input signal to upsample\r\n * @param {number} N - The upsampling factor\r\n * @returns {Array<number>} - The upsampled signal\r\n */\n _defineProperty(this, \"upsampleSignal\", (signal, N) => {\n if (N <= 1) return signal;\n const result = [];\n for (let sample of signal) {\n // Repeat each sample N times\n for (let i = 0; i < N; i++) {\n result.push(sample);\n }\n }\n return result;\n });\n /**\r\n * Downsamples a signal by averaging groups of N samples\r\n * @param {Array<number>} signal - The input signal to downsample\r\n * @param {number} N - The downsampling factor\r\n * @returns {Array<number>} - The downsampled signal\r\n */\n _defineProperty(this, \"downsampleSignal\", (signal, N) => {\n if (N <= 1) return signal;\n const result = [];\n for (let i = 0; i < signal.length; i += N) {\n const chunk = signal.slice(i, Math.min(i + N, signal.length));\n // Calculate average of the chunk\n const avg = chunk.reduce((sum, val) => sum + val, 0) / chunk.length;\n result.push(avg);\n }\n return result;\n });\n _defineProperty(this, \"sendBackgroundRecording\", () => {\n const allSignals = this.getAllBackgroundRecordings();\n const numSignals = allSignals.length;\n const background_rec_whole = allSignals[numSignals - 1];\n const fraction = 0.5 / (this._calibrateSoundBackgroundSecs + 0.5);\n // Calculate the starting index for slicing the array\n const startIndex = Math.round(fraction * background_rec_whole.length);\n // Slice the array from the calculated start index to the end of the array\n const background_rec = background_rec_whole.slice(startIndex);\n console.log('Sending background recording to server for processing');\n this.addTimeStamp('Compute PSD of background');\n const fBackground = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const background_rec_downsampled = this.downsampleSignal(background_rec, this._calibrateSoundBurstDownsample);\n this.pyServerAPI.getBackgroundNoisePSDWithRetry({\n background_rec: background_rec_downsampled,\n sampleRate: fBackground\n }).then(res => {\n if (this.numSuccessfulBackgroundCaptured < 1) {\n this.numSuccessfulBackgroundCaptured += 1;\n //storing all background data in background_psd object\n this.background_noise['x_background'] = res['x_background'];\n this.background_noise['y_background'] = res['y_background'];\n this.background_noise['recording'] = background_rec;\n }\n }).catch(err => {\n console.error(err);\n });\n });\n /** .\r\n * .\r\n * .\r\n * Sends the recorded signal, or a given csv string of a signal, to the back end server for processing\r\n *\r\n * @param {<array>String} signalCsv - Optional csv string of a previously recorded signal, if given, this signal will be processed\r\n * @example\r\n */\n _defineProperty(this, \"sendRecordingToServerForProcessing\", async signalCsv => {\n const allSignals = this.getAllUnfilteredRecordedSignals();\n console.log('Obtaining last all hz unfiltered recording from #allHzUnfilteredRecordings to send to server for processing');\n const numSignals = allSignals.length;\n const mls = _classPrivateFieldGet(_mlsBufferView, this)[this.icapture];\n const payload = signalCsv && signalCsv.length > 0 ? (0,_utils__WEBPACK_IMPORTED_MODULE_8__.csvToArray)(signalCsv) : allSignals[numSignals - 1];\n console.log('sending rec');\n this.stepNum += 1;\n console.log('send rec ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration Step: computing the IR of the last recording...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n if (this.isCalibrating) return null;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n await this.pyServerAPI.allHzPowerCheck({\n payload,\n sampleRate: fMLS,\n binDesiredSec: this._calibrateSoundPowerBinDesiredSec,\n burstSec: this.desired_time_per_mls,\n repeats: this.numMLSPerCapture - this.num_mls_to_skip,\n warmUp: this.num_mls_to_skip,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async result => {\n if (result) {\n if (result['sd'] > this._calibrateSoundBurstMaxSD_dB && this.numSuccessfulCaptured == 0) {\n console.log('SD: ' + result['sd'] + ', greater than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n this.recordingChecks['unfiltered'].push(result);\n this.clearLastUnfilteredRecordedSignals();\n this.numSuccessfulCaptured += 1;\n } else {\n if (result['sd'] <= this._calibrateSoundBurstMaxSD_dB) {\n console.log('SD: ' + result['sd'] + ', less than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n } else {\n console.log('SD: ' + result['sd'] + ', greater than _calibrateSoundBurstMaxSD_dB: ' + this._calibrateSoundBurstMaxSD_dB);\n this.recordingChecks['warnings'].push(\"All Hz. Re-recorded \".concat(this.inDB, \" dB because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n this.status = this.generateTemplate(\"All Hz: Re-recording at \".concat(this.inDB, \" dB because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n }\n if (this.numSuccessfulCaptured == 1) {\n console.log('pop last unfiltered mls volume check');\n this.recordingChecks['unfiltered'].pop();\n }\n this.recordingChecks['unfiltered'].push(result);\n // let start = new Date().getTime() / 1000;\n // const payloadT = tf.tensor1d(payload);\n // payloadT.print();\n // const xfft = payloadT.rfft(); // tf.spe\n // xfft.array().then(array => {\n // console.log(\"fft:\", array);\n // let setItem = new Set(array);\n // console.log(\"all zero\", setItem.size === 1 && setItem.has(0));\n // });\n // console.log(\"dimention:\", xfft.shape);\n // let end = new Date().getTime() / 1000;\n // console.log(\"Time taken:\", end - start, \"seconds\");\n console.log('start calculate impulse response');\n const usedPeriodStart = this.num_mls_to_skip * this.sourceSamplingRate;\n const payload_skipped_warmUp = payload.slice(usedPeriodStart);\n const payload_skipped_warmUp_downsampled = this.downsampleSignal(payload_skipped_warmUp, this._calibrateSoundBurstDownsample);\n await this.pyServerAPI.getAutocorrelation({\n mls: mls,\n payload: payload_skipped_warmUp_downsampled,\n sampleRate: fMLS,\n numPeriods: this.numMLSPerCapture - this.num_mls_to_skip,\n downsample: this._calibrateSoundBurstDownsample\n }).then(async res => {\n this.autocorrelations.push(res['autocorrelation']);\n this.fs2 = res['fs2'];\n this.L_new_n = res['L_new_n'];\n this.dL_n = res['dL_n'];\n this.impulseResponses.push(await this.pyServerAPI.getImpulseResponse({\n mls,\n sampleRate: fMLS,\n numPeriods: this.numMLSPerCapture - this.num_mls_to_skip,\n sig: payload_skipped_warmUp_downsampled,\n fs2: this.fs2,\n L_new_n: this.L_new_n,\n dL_n: this.dL_n,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.numSuccessfulCaptured += 2;\n this.stepNum += 1;\n console.log('got impulse response ' + this.stepNum);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: \".concat(this.numSuccessfulCaptured, \"/\").concat(this.numCaptures, \" IRs computed...\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res['ir'];\n }).catch(err => {\n console.error(err);\n }));\n });\n }\n console.log('number of unfiltered recording checks:' + this.recordingChecks['unfiltered'].length);\n }\n }).catch(err => {\n console.error(err);\n });\n });\n /**\r\n * Passed to the calibration steps function, awaits the desired amount of seconds to capture the desired number\r\n * of MLS periods defined in the constructor.\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitDesiredMLSLength, async () => {\n // seconds per MLS = P / SR\n // await N * P / SR\n this.stepNum += 1;\n console.log('await desired length ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: sampling the calibration signal...\".toString() + \"\\niteration \".concat(this.stepNum));\n this.emit('update', {\n message: this.status\n });\n let time_to_wait = 0;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n if (this.mode === 'unfiltered') {\n //unfiltered\n time_to_wait = _classPrivateFieldGet(_mls, this)[0].length / fMLS * this.numMLSPerCapture;\n time_to_wait = time_to_wait + this._calibrateSoundBurstPostSec;\n } else if (this.mode === 'filtered') {\n //filtered\n // time_to_wait =\n // (this.#currentConvolution.length / this.sourceSamplingRate) *\n // (this.numMLSPerCapture / (this.num_mls_to_skip + this.numMLSPerCapture));\n time_to_wait = _classPrivateFieldGet(_currentConvolution, this).length / fMLS * this.numMLSPerCapture;\n time_to_wait = time_to_wait + this._calibrateSoundBurstPostSec;\n } else {\n throw new Error('Mode broke in awaitDesiredMLSLength');\n }\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_wait);\n });\n /**\r\n * Passed to the background noise recording function, awaits the desired amount of seconds to capture the desired number\r\n * of seconds of background noise\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitBackgroundNoiseRecording, async () => {\n console.log('Waiting ' + this._calibrateSoundBackgroundSecs + ' second(s) to record background noise');\n let time_to_wait = this._calibrateSoundBackgroundSecs + 0.5;\n this.addTimeStamp(\"Record \".concat(time_to_wait.toFixed(1), \" s of background.\"));\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_wait);\n });\n /** .\r\n * .\r\n * .\r\n * Passed to the calibration steps function, awaits the onset of the signal to ensure a steady state\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _awaitSignalOnset, async () => {\n this.stepNum += 1;\n console.log('await signal onset ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: waiting for the signal to stabilize...\".toString());\n this.emit('update', {\n message: this.status\n });\n let number_of_bursts_to_skip = 0;\n let time_to_sleep = 0;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n if (this.mode === 'unfiltered') {\n time_to_sleep = _classPrivateFieldGet(_mls, this)[0].length / fMLS * number_of_bursts_to_skip;\n } else if (this.mode === 'filtered') {\n console.log(_classPrivateFieldGet(_currentConvolution, this).length);\n // time_to_sleep =\n // (this.#currentConvolution.length / this.sourceSamplingRate) *\n // (number_of_bursts_to_skip / (number_of_bursts_to_skip + this.numMLSPerCapture));\n time_to_sleep = _classPrivateFieldGet(_currentConvolution, this).length / fMLS * number_of_bursts_to_skip;\n } else {\n throw new Error('Mode broke in awaitSignalOnset');\n }\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(time_to_sleep);\n });\n /**\r\n * Called immediately after a recording is captured. Used to process the resulting signal\r\n * whether by sending the result to a server or by computing a result locally.\r\n *\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _afterMLSRecord, async () => {\n console.log('after record');\n this.addTimeStamp(\"Send MLS to the server\");\n await this.sendRecordingToServerForProcessing();\n });\n _classPrivateFieldInitSpec(this, _afterMLSwIIRRecord, async () => {\n await this.checkPowerVariation();\n });\n /** .\r\n * .\r\n * .\r\n * Created an S Curver Buffer to taper the signal onset\r\n *\r\n * @param {*} onSetBool\r\n * @returns\r\n * @example\r\n */\n _defineProperty(this, \"createSCurveBuffer\", function () {\n let onSetBool = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n const curve = new Float32Array(_this.TAPER_SECS * _this.sourceSamplingRate + 1);\n const frequency = 1 / (4 * _this.TAPER_SECS);\n let j = 0;\n for (let i = 0; i < _this.TAPER_SECS * _this.sourceSamplingRate + 1; i += 1) {\n const phase = 2 * Math.PI * frequency * j;\n const onsetTaper = Math.pow(Math.sin(phase), 2);\n const offsetTaper = Math.pow(Math.cos(phase), 2);\n curve[i] = onSetBool ? onsetTaper : offsetTaper;\n j += 1 / _this.sourceSamplingRate;\n }\n return curve;\n });\n /**\r\n * Construct a Calibration Node with the calibration parameters.\r\n *\r\n * @param dataBuffer\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _createCalibrationNodeFromBuffer, dataBuffer => {\n console.log('length databuffer');\n console.log(dataBuffer.length);\n if (!this.sourceAudioContext) {\n this.makeNewSourceAudioContext();\n }\n const buffer = this.sourceAudioContext.createBuffer(1,\n // number of channels\n dataBuffer.length, this.sourceAudioContext.sampleRate // sample rate\n );\n const data = buffer.getChannelData(0); // get data\n\n // fill the buffer with our data\n try {\n for (let i = 0; i < dataBuffer.length; i += 1) {\n data[i] = dataBuffer[i];\n }\n } catch (error) {\n console.error(error);\n }\n this.sourceNode = this.sourceAudioContext.createBufferSource();\n this.sourceNode.buffer = buffer;\n if (this.mode === 'filtered') {\n //used to not loop filtered\n this.sourceNode.loop = true;\n } else {\n this.sourceNode.loop = true;\n }\n this.sourceNode.connect(this.sourceAudioContext.destination);\n this.addCalibrationNode(this.sourceNode);\n });\n /**\r\n * Given a data buffer, creates the required calibration node\r\n *\r\n * @param {*} dataBufferArray\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _setCalibrationNodesFromBuffer, function () {\n let dataBufferArray = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [_classPrivateFieldGet(_mlsBufferView, _this)[_this.icapture]];\n if (dataBufferArray.length === 1) {\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, _this).call(_this, dataBufferArray[0]);\n } else {\n throw new Error('The length of the data buffer array must be 1');\n }\n });\n /**\r\n * Creates an audio context and plays it for a few seconds.\r\n *\r\n * @private\r\n * @returns - Resolves when the audio is done playing.\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _playCalibrationAudio, () => {\n this.calibrationNodes[0].start(0);\n this.status = \"\";\n if (this.mode === 'unfiltered') {\n console.log('play calibration audio ' + this.stepNum);\n const pre = this._calibrateSoundBurstPreSec;\n const repeats = this._calibrateSoundBurstRepeats;\n const burst = this._calibrateSoundBurstSec;\n const post = this._calibrateSoundBurstPostSec;\n const total_dur = pre + repeats * burst + post;\n this.addTimeStamp(\"Record \".concat(total_dur.toFixed(1), \" s \") + \"(\".concat(pre.toFixed(1), \" + \").concat(repeats, \"\\xD7\").concat(burst.toFixed(1), \" + \").concat(post.toFixed(1), \" s) of MLS ver. \").concat(this.icapture));\n this.status = this.generateTemplate(\"All Hz Calibration: playing the calibration tone...\".toString()).toString();\n } else if (this.mode === 'filtered') {\n console.log('play convolved audio ' + this.stepNum);\n this.status = this.generateTemplate().toString(\"All Hz Calibration: playing the convolved calibration tone...\".toString());\n } else {\n throw new Error('Mode is incorrect');\n }\n this.emit('update', {\n message: this.status\n });\n this.stepNum += 1;\n console.log('sink sampling rate');\n console.log(this.sinkSamplingRate);\n console.log('source sampling rate');\n console.log(this.sourceSamplingRate);\n console.log('sample size');\n console.log(this.sampleSize);\n });\n /** .\r\n * .\r\n * .\r\n * Stops the audio with tapered offset\r\n *\r\n * @example\r\n */\n _defineProperty(this, \"stopCalibrationAudio\", () => {\n if (this.calibrationNodes.length === 0) {\n return;\n }\n this.calibrationNodes[0].stop(0);\n this.calibrationNodes = [];\n if (this.sourceNode) this.sourceNode.disconnect();\n this.stepNum += 1;\n console.log('stop calibration audio ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: stopping the calibration tone...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n });\n _defineProperty(this, \"playMLSwithIIR\", async (stream, convolution) => {\n let checkRec = false;\n this.mode = 'filtered';\n console.log('play mls with iir');\n //this.invertedImpulseResponse = iir\n\n await this.calibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudio, this), // play audio func (required)\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, this).call(this, convolution),\n // before play func\n _classPrivateFieldGet(_awaitSignalOnset, this),\n // before record\n () => this.numSuccessfulCaptured < 2, _classPrivateFieldGet(_awaitDesiredMLSLength, this),\n // during record\n _classPrivateFieldGet(_afterMLSwIIRRecord, this),\n // after record\n this.mode, checkRec);\n });\n _defineProperty(this, \"bothSoundCheck\", async stream => {\n let iir_ir_and_plots;\n _classPrivateFieldSet(_currentConvolution, this, this.componentConvolution);\n this.filteredMLSRange.component.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.component.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n const pre = this._calibrateSoundBurstPreSec;\n const repeats = this._calibrateSoundBurstRepeats;\n const burst = this._calibrateSoundBurstSec;\n const post = this._calibrateSoundBurstPostSec;\n const total_dur = pre + repeats * burst + post;\n this.soundCheck = 'component';\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(this.soundCheck, \" IIR.\\u201D\"));\n if (this.isCalibrating) return null;\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n let component_conv_recs = this.getAllFilteredRecordedSignals();\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttentuatorGainDB / 20);\n component_conv_recs = component_conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n let return_component_conv_rec = component_conv_recs[component_conv_recs.length - 1];\n this.clearAllFilteredRecordedSignals();\n this.numSuccessfulCaptured = 0;\n _classPrivateFieldSet(_currentConvolution, this, this.systemConvolution);\n this.filteredMLSRange.system.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.system.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'system';\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(this.soundCheck, \" IIR.\\u201D\"));\n if (this.isCalibrating) return null;\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n let system_conv_recs = this.getAllFilteredRecordedSignals();\n if (this.systemAttenuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttenuatorGainDB / 20);\n system_conv_recs = system_conv_recs.map(rec => {\n return rec.map(value => value / linearScaleAttenuation);\n });\n }\n let return_system_conv_rec = system_conv_recs[system_conv_recs.length - 1];\n // await this.checkPowerVariation(return_system_conv_rec);\n\n this.clearAllFilteredRecordedSignals();\n this.sourceAudioContext.close();\n let recs = this.getAllUnfilteredRecordedSignals();\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttentuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n let unconv_rec = recs[0];\n let return_unconv_rec = unconv_rec;\n let conv_rec = component_conv_recs[component_conv_recs.length - 1];\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n //psd of component\n let knownGain = this.oldComponentIR.Gain;\n let knownFreq = this.oldComponentIR.Freq;\n let sampleRate = this.sourceSamplingRate || 96000;\n this.addTimeStamp('Compute PSD of MLS recording');\n if (this.isCalibrating) return null;\n let component_unconv_rec_psd = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of filtered recording (component)');\n if (this.isCalibrating) return null;\n let component_conv_rec_psd = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n let interpolatedGain = res.x.map((freq, index) => {\n let i = 0;\n while (i < knownFreq.length && knownFreq[i] < freq) {\n i++;\n }\n if (i === 0 || i === knownFreq.length) {\n return knownGain[i];\n }\n return (0,_utils__WEBPACK_IMPORTED_MODULE_8__.interpolate)(freq, knownFreq[i - 1], knownFreq[i], knownGain[i - 1], knownGain[i]);\n });\n let correctedGain = res.y.map((gain, index) => 10 * Math.log10(gain) - interpolatedGain[index]);\n let filtered_psd = correctedGain.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= this.componentFMaxHz);\n this.SDofFilteredRange['component'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n conv_rec = system_conv_recs[system_conv_recs.length - 1];\n //psd of system\n this.addTimeStamp('Compute PSD of filtered recording (system) and unfiltered recording');\n if (this.isCalibrating) return null;\n let system_recs_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n let filtered_psd = res.y_conv.filter((value, index) => res.x_conv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= _classPrivateFieldGet(_highHz, this)).map(value => 10 * Math.log10(value));\n let mls_psd = res.y_unconv.filter((value, index) => res.x_unconv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= _classPrivateFieldGet(_highHz, this)).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n console.log('mls_psd', this.SDofFilteredRange['mls']);\n this.SDofFilteredRange['system'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n\n //iir w/ and without bandpass psd. done\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of component IIR and component IIR no band pass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of system IIR and system IIR no band pass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of MLS sequence');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(_classPrivateFieldGet(_mlsBufferView, this)[0], this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of filtered MLS (system)');\n if (this.isCalibrating) return null;\n let system_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(this.systemConvolution, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let system_no_bandpass_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(this.systemConvolutionNoBandpass, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of filtered MLS (component)');\n if (this.isCalibrating) return null;\n let component_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(this.componentConvolution, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let component_no_bandpass_filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(this.componentConvolutionNoBandpass, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n filtered_recording: {\n component: return_component_conv_rec,\n system: return_system_conv_rec\n },\n unfiltered_recording: this.getAllUnfilteredRecordedSignals()[0],\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['x_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: system_filtered_mls_psd['x_mls'],\n y: system_filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: system_no_bandpass_filtered_mls_psd['x_mls'],\n y: system_no_bandpass_filtered_mls_psd['y_mls']\n },\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: system_recs_psd['x_unconv'],\n y: system_recs_psd['y_unconv']\n },\n conv: {\n x: system_recs_psd['x_conv'],\n y: system_recs_psd['y_conv']\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: component_filtered_mls_psd['x_mls'],\n y: component_filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: component_no_bandpass_filtered_mls_psd['x_mls'],\n y: component_no_bandpass_filtered_mls_psd['y_mls']\n },\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: component_unconv_rec_psd['x'],\n y: component_unconv_rec_psd['y']\n },\n conv: {\n x: component_conv_rec_psd['x'],\n y: component_conv_rec_psd['y']\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n return iir_ir_and_plots;\n });\n _defineProperty(this, \"singleSoundCheck\", async stream => {\n let iir_ir_and_plots;\n const pre = this._calibrateSoundBurstPreSec;\n const repeats = this._calibrateSoundBurstRepeats;\n const burst = this._calibrateSoundBurstSec;\n const post = this._calibrateSoundBurstPostSec;\n const total_dur = pre + repeats * burst + post;\n if (this._calibrateSoundCheck != 'system') {\n _classPrivateFieldSet(_currentConvolution, this, this.componentConvolution);\n this.filteredMLSRange.component.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.component.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'component';\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(this.soundCheck, \" IIR.\"));\n //this.addTimeStamp(`Record ${total_dur} s of MLS with speaker or microphone IIR.`);\n if (this.isCalibrating) return null;\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n } else {\n _classPrivateFieldSet(_currentConvolution, this, this.systemConvolution);\n this.filteredMLSRange.system.Min = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMinValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.filteredMLSRange.system.Max = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.findMaxValue)(_classPrivateFieldGet(_currentConvolution, this));\n this.soundCheck = 'system';\n this.addTimeStamp(\"Record \".concat(total_dur, \" s of MLS with \").concat(this.soundCheck, \" IIR.\"));\n //this.addTimeStamp(`Record ${total_dur} s of MLS with speaker or microphone IIR.`);\n if (this.isCalibrating) return null;\n await this.playMLSwithIIR(stream, _classPrivateFieldGet(_currentConvolution, this));\n this.stopCalibrationAudio();\n }\n let conv_recs = this.getAllFilteredRecordedSignals();\n if (this._calibrateSoundCheck == 'goal') {\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttentuatorGainDB / 20);\n conv_recs = conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n } else if (this._calibrateSoundCheck == 'system') {\n if (this.systemAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttentuatorGainDB / 20);\n conv_recs = conv_recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n }\n\n //remove the filteredMLSAttenuation from the recorded signals\n // conv_recs = conv_recs.map(rec => {\n // if (this.soundCheck === 'component') {\n // return rec.map(value => value / this.filteredMLSAttenuation.component);\n // }\n // return rec.map(value => value / this.filteredMLSAttenuation.system);\n // });\n\n let recs = this.getAllUnfilteredRecordedSignals();\n if (this._calibrateSoundCheck == 'goal') {\n if (this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.componentAttentuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n } else if (this._calibrateSoundCheck == 'system') {\n if (this.systemAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, this.systemAttentuatorGainDB / 20);\n recs = recs.map(rec => {\n return rec.map(value => value / this.linearScaleAttenuation);\n });\n }\n }\n this.clearAllFilteredRecordedSignals();\n console.log('Obtaining unfiltered recording from #allHzUnfilteredRecordings to calculate PSD');\n console.log('Obtaining filtered recording from #allHzFilteredRecordings to calculate PSD');\n let unconv_rec = recs[0];\n let return_unconv_rec = unconv_rec;\n let conv_rec = conv_recs[conv_recs.length - 1];\n let return_conv_rec = conv_rec;\n this.sourceAudioContext.close();\n if (this._calibrateSoundCheck != 'system') {\n let knownGain = this.oldComponentIR.Gain;\n let knownFreq = this.oldComponentIR.Freq;\n let sampleRate = this.sourceSamplingRate || 96000;\n this.addTimeStamp('Compute PSD of MLS recording');\n if (this.isCalibrating) return null;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n let unconv_results = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n console.log(res);\n let mls_psd = res.y.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n console.log('mls sd', this.SDofFilteredRange['mls']);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD recording of speaker+ mic IIR-filtered MLS recording');\n if (this.isCalibrating) return null;\n let conv_results = await this.pyServerAPI.getSubtractedPSDWithRetry(this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample), knownGain, knownFreq, fMLS, this._calibrateSoundBurstDownsample).then(res => {\n let interpolatedGain = res.x.map((freq, index) => {\n let i = 0;\n while (i < knownFreq.length && knownFreq[i] < freq) {\n i++;\n }\n if (i === 0 || i === knownFreq.length) {\n return knownGain[i];\n }\n return (0,_utils__WEBPACK_IMPORTED_MODULE_8__.interpolate)(freq, knownFreq[i - 1], knownFreq[i], knownGain[i - 1], knownGain[i]);\n });\n let correctedGain = res.y.map((gain, index) => 10 * Math.log10(gain) - interpolatedGain[index]);\n let filtered_psd = correctedGain.filter((value, index) => res.x[index] >= _classPrivateFieldGet(_lowHz, this) && res.x[index] <= _classPrivateFieldGet(_highHz, this));\n this.SDofFilteredRange['component'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of speaker or mic IIR, with and without bandpass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of speaker +mic IIR, with and without bandpass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of MLS');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(_classPrivateFieldGet(_mlsBufferView, this)[this.icapture], this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of speaker or mic');\n if (this.isCalibrating) return null;\n let filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(this.componentConvolution, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let filtered_no_bandpass_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(this.componentConvolutionNoBandpass, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['y_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_recording: [],\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {\n x: filtered_mls_psd['x_mls'],\n y: filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: filtered_no_bandpass_mls_psd['x_mls'],\n y: filtered_no_bandpass_mls_psd['y_mls']\n },\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: unconv_results['x'],\n y: unconv_results['y']\n },\n conv: {\n x: conv_results['x'],\n y: conv_results['y']\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n } else {\n this.addTimeStamp('Compute PSD of filtered recording (system) and unfiltered recording');\n if (this.isCalibrating) return null;\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n let results = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n let filtered_psd = res.y_conv.filter((value, index) => res.x_conv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n let mls_psd = res.y_unconv.filter((value, index) => res.x_unconv[index] >= _classPrivateFieldGet(_lowHz, this) && res.x_conv[index] <= this.systemFMaxHz).map(value => 10 * Math.log10(value));\n this.SDofFilteredRange['mls'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(mls_psd);\n this.SDofFilteredRange['system'] = (0,_utils__WEBPACK_IMPORTED_MODULE_8__.standardDeviation)(filtered_psd);\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n\n //iir w/ and without bandpass psd\n unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n conv_rec = this.componentInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of component IIR and component IIR no band pass');\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n this.addTimeStamp('Compute PSD of system IIR and system IIR no band pass');\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of MLS sequence');\n if (this.isCalibrating) return null;\n let mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(_classPrivateFieldGet(_mlsBufferView, this)[this.icapture], this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n this.addTimeStamp('Compute PSD of filtered MLS (system)');\n if (this.isCalibrating) return null;\n let filtered_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(this.systemConvolution, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let filtered_no_bandpass_mls_psd = await this.pyServerAPI.getMLSPSDWithRetry({\n mls: this.downsampleSignal(this.systemConvolutionNoBandpass, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['y_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_recording: [],\n filtered_mls_psd: {\n x: filtered_mls_psd['x_mls'],\n y: filtered_mls_psd['y_mls']\n },\n filtered_no_bandpass_mls_psd: {\n x: filtered_no_bandpass_mls_psd['x_mls'],\n y: filtered_no_bandpass_mls_psd['y_mls']\n },\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: results['x_unconv'],\n y: results['y_unconv']\n },\n conv: {\n x: results['x_conv'],\n y: results['y_conv']\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_origin: this.componentIROrigin,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n filtered_mls_psd: {},\n filtered_no_bandpass_mls_psd: {},\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n mls_psd: {\n x: mls_psd['x_mls'],\n y: mls_psd['y_mls']\n },\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n }\n if (this.isCalibrating) return null;\n await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n iir_ir_and_plots['impulseResponses'].push(res[i]);\n }\n }\n });\n if (_classPrivateFieldGet(_download, this)) {\n this.downloadSingleUnfilteredRecording();\n this.downloadSingleFilteredRecording();\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(_classPrivateFieldGet(_mls, this), 'MLS.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentConvolution, 'python_component_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemConvolution, 'python_system_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentInvertedImpulseResponse, 'componentIIR.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemInvertedImpulseResponse, 'systemIIR.csv');\n for (let i = 0; i < this.autocorrelations.length; i++) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.autocorrelations[i], \"autocorrelation_\".concat(i));\n }\n const computedIRagain = await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(res[i], \"IR_\".concat(i));\n }\n }\n });\n }\n return iir_ir_and_plots;\n });\n /**\r\n * Public method to start the calibration process. Objects intialized from webassembly allocate new memory\r\n * and must be manually freed. This function is responsible for intializing the MlsGenInterface,\r\n * and wrapping the calibration steps with a garbage collection safe gaurd.\r\n *\r\n * @public\r\n * @param stream - The stream of audio from the Listener.\r\n * @example\r\n */\n _defineProperty(this, \"startCalibrationImpulseResponse\", async stream => {\n let desired_time = this.desired_time_per_mls;\n let checkRec = 'allhz';\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n console.log('MLS sequence should be of length: ' + fMLS * desired_time);\n length = fMLS * desired_time;\n //get mls here\n // const calibrateSoundBurstDb = Math.pow(10, this._calibrateSoundBurstDb / 20);\n\n this.power_dB = 0;\n if (!this._calibrateSoundBurstLevelReTBool) {\n this.power_dB = this._calibrateSoundBurstDb;\n } else {\n this.power_dB = this._calibrateSoundBurstDb + (this.T - this.gainDBSPL);\n }\n const amplitude = Math.pow(10, this.power_dB / 20);\n //MLSpower = Math.pow(10,this.power_dB/20);\n this.addTimeStamp('Compute MLS sequence');\n if (this.isCalibrating) return null;\n await this.pyServerAPI.getMLSWithRetry({\n length,\n amplitude,\n calibrateSoundBurstMLSVersions: this.numCaptures,\n calibrateSoundBurstDownsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n console.log(res);\n _classPrivateFieldSet(_mlsBufferView, this, this.upsampleSignal(res['mls'], this._calibrateSoundBurstDownsample));\n _classPrivateFieldSet(_mls, this, this.upsampleSignal(res['unscaledMLS'], this._calibrateSoundBurstDownsample));\n }).catch(err => {\n // this.emit('InvertedImpulseResponse', {res: false});\n console.error(err);\n });\n this.numSuccessfulBackgroundCaptured = 0;\n if (this._calibrateSoundBackgroundSecs > 0) {\n this.mode = 'background';\n this.status = this.generateTemplate(\"All Hz Calibration: sampling the background noise...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n if (this.isCalibrating) return null;\n await this.recordBackground(stream,\n //stream\n () => this.numSuccessfulBackgroundCaptured < 1,\n //loop condition\n _classPrivateFieldGet(_awaitBackgroundNoiseRecording, this),\n //sleep to record\n this.sendBackgroundRecording,\n //send to get PSD\n this.mode, checkRec);\n this.incrementStatusBar();\n }\n this.mode = 'unfiltered';\n this.numSuccessfulCaptured = 0;\n if (this.isCalibrating) return null;\n for (var i = 0; i < this.numCaptures; i++) {\n this.icapture = i;\n await this.calibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudio, this), // play audio func (required)\n _classPrivateFieldGet(_createCalibrationNodeFromBuffer, this).call(this, _classPrivateFieldGet(_mlsBufferView, this)[this.icapture]),\n // before play func\n _classPrivateFieldGet(_awaitSignalOnset, this),\n // before record\n () => this.numSuccessfulCaptured < 2,\n // loop while true\n _classPrivateFieldGet(_awaitDesiredMLSLength, this),\n // during record\n _classPrivateFieldGet(_afterMLSRecord, this),\n // after record\n this.mode, checkRec);\n this.stopCalibrationAudio();\n }\n checkRec = false;\n\n // at this stage we've captured all the required signals,\n // and have received IRs for each one\n // so let's send all the IRs to the server to be converted to a single IIR\n if (this.isCalibrating) return null;\n await this.sendSystemImpulseResponsesToServerForProcessing();\n await this.pyServerAPI.checkMemory();\n if (this.isCalibrating) return null;\n await this.sendComponentImpulseResponsesToServerForProcessing();\n this.numSuccessfulCaptured = 0;\n let iir_ir_and_plots;\n if (this._calibrateSoundCheck != 'none') {\n //do single check\n if (this._calibrateSoundCheck == 'goal' || this._calibrateSoundCheck == 'system') {\n if (this.isCalibrating) return null;\n iir_ir_and_plots = await this.singleSoundCheck(stream);\n if (this.isCalibrating) return null;\n } else {\n //both\n if (this.isCalibrating) return null;\n iir_ir_and_plots = await this.bothSoundCheck(stream);\n if (this.isCalibrating) return null;\n }\n } else {\n let unconv_rec = this.componentInvertedImpulseResponseNoBandpass;\n let conv_rec = this.componentInvertedImpulseResponse;\n if (this.isCalibrating) return null;\n let component_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n unconv_rec = this.systemInvertedImpulseResponseNoBandpass;\n conv_rec = this.systemInvertedImpulseResponse;\n if (this.isCalibrating) return null;\n let system_iir_psd = await this.pyServerAPI.getPSDWithRetry({\n unconv_rec: this.downsampleSignal(unconv_rec, this._calibrateSoundBurstDownsample),\n conv_rec: this.downsampleSignal(conv_rec, this._calibrateSoundBurstDownsample),\n sampleRate: fMLS,\n downsample: this._calibrateSoundBurstDownsample\n }).then(res => {\n this.incrementStatusBar();\n this.status = this.generateTemplate(\"All Hz Calibration: done computing the PSD graphs...\".toString()).toString();\n this.emit('update', {\n message: this.status\n });\n return res;\n }).catch(err => {\n console.error(err);\n });\n let gainValue = this.getGainDBSPL();\n iir_ir_and_plots = {\n unfiltered_recording: return_unconv_rec,\n filtered_recording: return_conv_rec,\n system: {\n iir: this.systemInvertedImpulseResponse,\n iir_no_bandpass: this.systemInvertedImpulseResponseNoBandpass,\n ir: this.systemIR,\n iir_psd: {\n y: system_iir_psd['y_conv'],\n x: system_iir_psd['y_conv'],\n y_no_bandpass: system_iir_psd['y_unconv'],\n x_no_bandpass: system_iir_psd['x_unconv']\n },\n filtered_recording: [],\n convolution: this.systemConvolution,\n convolutionNoBandpass: this.systemConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n }\n },\n component: {\n iir: this.componentInvertedImpulseResponse,\n iir_no_bandpass: this.componentInvertedImpulseResponseNoBandpass,\n ir: this.componentIR,\n ir_in_time_domain: this.componentIRInTimeDomain,\n iir_psd: {\n y: component_iir_psd['y_conv'],\n x: component_iir_psd['x_conv'],\n y_no_bandpass: component_iir_psd['y_unconv'],\n x_no_bandpass: component_iir_psd['x_unconv']\n },\n convolution: this.componentConvolution,\n convolutionNoBandpass: this.componentConvolutionNoBandpass,\n psd: {\n unconv: {\n x: [],\n y: []\n },\n conv: {\n x: [],\n y: []\n }\n },\n gainDBSPL: gainValue\n },\n mls: _classPrivateFieldGet(_mlsBufferView, this),\n autocorrelations: this.autocorrelations,\n impulseResponses: []\n };\n if (this.isCalibrating) return null;\n await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n iir_ir_and_plots['impulseResponses'].push(res[i]);\n }\n }\n });\n if (_classPrivateFieldGet(_download, this)) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(_classPrivateFieldGet(_mls, this), 'MLS.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentConvolution, 'python_component_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemConvolution, 'python_system_convolution_mls_iir.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.componentInvertedImpulseResponse, 'componentIIR.csv');\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.systemInvertedImpulseResponse, 'systemIIR.csv');\n for (let i = 0; i < this.autocorrelations.length; i++) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(this.autocorrelations[i], \"autocorrelation_\".concat(i));\n }\n const computedIRagain = await Promise.all(this.impulseResponses).then(res => {\n for (let i = 0; i < res.length; i++) {\n if (res[i] != undefined) {\n (0,_utils__WEBPACK_IMPORTED_MODULE_8__.saveToCSV)(res[i], \"IR_\".concat(i));\n }\n }\n });\n }\n }\n if (this.isCalibrating) return null;\n this.percent_complete = 100;\n this.status = this.generateTemplate(\"All Hz Calibration: Finished\".toString()).toString();\n this.addTimeStamp('Done');\n this.emit('update', {\n message: this.status\n });\n\n //here after calibration we have the component calibration (either loudspeaker or microphone) in the same form as the componentIR\n //that was used to calibrate\n // saveToJSON(iir_ir_and_plots);\n return iir_ir_and_plots;\n });\n //////////////////////volume\n _defineProperty(this, \"handleIncomingData\", data => {\n console.log('Received data: ', data);\n if (data.type === 'soundGainDBSPL') {\n this.soundGainDBSPL = data.value;\n } else {\n throw new Error(\"Unknown data type: \".concat(data.type));\n }\n });\n _classPrivateFieldInitSpec(this, _getTruncatedSignal, function () {\n let left = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 3.5;\n let right = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4.5;\n const start = Math.floor(left * _this.sourceSamplingRate);\n const end = Math.floor(right * _this.sourceSamplingRate);\n const result = Array.from(_this.getLastVolumeRecordedSignal().slice(start, end));\n console.log('Obtaining last 1000 hz recording from #allVolumeRecordings to send for processing');\n /**\r\n * function to check that capture was properly made\r\n * @param {*} list\r\n */\n const checkResult = list => {\n const setItem = new Set(list);\n if (setItem.size === 1 && setItem.has(0)) {\n console.warn('The last capture failed, all recorded signal is zero', _this.getAllVolumeRecordedSignals());\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n // restartButton.style.display = 'none';\n _this.emit('update', {\n message: 'Connection failed, hit restart button to reconnect'\n });\n }\n if (setItem.size === 0) {\n console.warn('The last capture failed, no recorded signal');\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n // restartButton.style.display = 'none';\n _this.emit('update', {\n message: 'Connection failed, hit restart button to reconnect'\n });\n }\n };\n checkResult(result);\n return result;\n });\n /** \r\n * \r\n * \r\n Construct a calibration Node with the calibration parameters and given gain value\r\n * @param {*} gainValue\r\n * */\n _classPrivateFieldInitSpec(this, _createCalibrationToneWithGainValue, gainValue => {\n const audioContext = this.makeNewSourceAudioContext();\n const oscilator = audioContext.createOscillator();\n const gainNode = audioContext.createGain();\n const taperGainNode = audioContext.createGain();\n const offsetGainNode = audioContext.createGain();\n const totalDuration = this.CALIBRATION_TONE_DURATION * 1.2;\n oscilator.frequency.value = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this);\n oscilator.type = _classPrivateFieldGet(_CALIBRATION_TONE_TYPE, this);\n gainNode.gain.value = gainValue;\n oscilator.connect(gainNode);\n gainNode.connect(taperGainNode);\n const onsetCurve = this.createSCurveBuffer();\n taperGainNode.gain.setValueCurveAtTime(onsetCurve, 0, this.TAPER_SECS);\n taperGainNode.connect(offsetGainNode);\n const offsetCurve = this.createSCurveBuffer(false);\n offsetGainNode.gain.setValueCurveAtTime(offsetCurve, totalDuration - this.TAPER_SECS, this.TAPER_SECS);\n offsetGainNode.connect(audioContext.destination);\n const gainValuesOverTime = [];\n const sampleRate = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this); // Number of samples per second\n const interval = 1 / sampleRate; // Time between samples\n\n for (let t = 0; t <= totalDuration; t += interval) {\n let gainValueAtTime = gainValue;\n\n // Apply the onset curve\n if (t < this.TAPER_SECS) {\n const onsetIndex = Math.floor(t / this.TAPER_SECS * onsetCurve.length);\n gainValueAtTime *= onsetCurve[onsetIndex];\n }\n\n // Apply the offset curve\n if (t > totalDuration - this.TAPER_SECS) {\n const offsetTime = t - (totalDuration - this.TAPER_SECS);\n const offsetIndex = Math.floor(offsetTime / this.TAPER_SECS * offsetCurve.length);\n gainValueAtTime *= offsetCurve[offsetIndex];\n }\n gainValuesOverTime.push(gainValueAtTime);\n }\n this.waveforms['volume'][this.inDB] = gainValuesOverTime;\n this.addCalibrationNode(oscilator);\n });\n /**\r\n * Construct a Calibration Node with the calibration parameters.\r\n *\r\n * @private\r\n * @example\r\n */\n _classPrivateFieldInitSpec(this, _createCalibrationNode, () => {\n const audioContext = this.makeNewSourceAudioContext();\n const oscilator = audioContext.createOscillator();\n const gainNode = audioContext.createGain();\n oscilator.frequency.value = _classPrivateFieldGet(_CALIBRATION_TONE_FREQUENCY, this);\n oscilator.type = _classPrivateFieldGet(_CALIBRATION_TONE_TYPE, this);\n gainNode.gain.value = 0.04;\n oscilator.connect(gainNode);\n gainNode.connect(audioContext.destination);\n this.addCalibrationNode(oscilator);\n });\n _classPrivateFieldInitSpec(this, _playCalibrationAudioVolume, async () => {\n if (this.numCalibratingRoundsCompleted == 1) {\n this.recordingChecks['warnings'].push(\"1000Hz. Re-recorded \".concat(this.inDB, \" dB because SD \").concat(this.recordingChecks['volume'][this.inDB]['sd'], \" > \").concat(this.calibrateSound1000HzMaxSD_dB, \" dB\"));\n const currentStatus = \"1000 Hz: Re-recording at \".concat(this.inDB, \" dB because SD \\n \").concat(this.recordingChecks['volume'][this.inDB]['sd'], \" > \\n \").concat(this.calibrateSound1000HzMaxSD_dB, \" dB\").toString();\n this.status = this.generateTemplate(currentStatus).toString();\n this.emit('update', {\n message: this.status\n });\n }\n const totalDuration = this.CALIBRATION_TONE_DURATION * 1.2;\n console.log('this.calibrationNodes', this.calibrationNodes);\n this.calibrationNodes[0].start(0);\n this.calibrationNodes[0].stop(totalDuration);\n console.log(\"Playing a buffer of \".concat(this.CALIBRATION_TONE_DURATION, \" seconds of audio\"));\n console.log(\"Waiting a total of \".concat(totalDuration, \" seconds\"));\n await (0,_utils__WEBPACK_IMPORTED_MODULE_8__.sleep)(totalDuration);\n });\n _defineProperty(this, \"stopCalibrationAudioVolume\", () => {\n if (this.calibrationNodes.length > 0) {\n this.calibrationNodes[0].stop();\n }\n this.calibrationNodes = [];\n });\n _classPrivateFieldInitSpec(this, _sendToServerForProcessing, async lCalib => {\n console.log('Sending data to server');\n let left = this.calibrateSound1000HzPreSec;\n let right = this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec;\n if (this.isCalibrating) return null;\n this.pyServerAPI.getVolumeCalibration({\n sampleRate: this.sourceSamplingRate,\n payload: _classPrivateFieldGet(_getTruncatedSignal, this).call(this, left, right),\n lCalib: lCalib\n }).then(res => {\n //if res is undefined, throw an error\n if (res === undefined) {\n throw new Error('No response from server in getVolumeCalibration function. Please try again.');\n }\n if (this.outDBSPL === null) {\n this.incrementStatusBar();\n this.outDBSPL = res['outDbSPL'];\n this.outDBSPL1000 = res['outDbSPL1000'];\n this.THD = res['thd'];\n }\n }).catch(err => {\n console.warn(err);\n });\n const rec = this.getLastVolumeRecordedSignal();\n console.log('pre period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice(0, this.calibrateSound1000HzPreSec * this.sourceSamplingRate)).toFixed(1));\n console.log('pre period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice(this.calibrateSound1000HzPreSec * this.sourceSamplingRate, (this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec) * this.sourceSamplingRate)).toFixed(1));\n console.log('pre period power: ', (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.getPower)(rec.slice((this.calibrateSound1000HzPreSec + this.calibrateSound1000HzSec) * this.sourceSamplingRate)).toFixed(1));\n const res = (0,_powerCheck__WEBPACK_IMPORTED_MODULE_9__.volumePowerCheck)(rec, this.sourceSamplingRate || 96000, this.calibrateSound1000HzPreSec, this.calibrateSound1000HzSec, this._calibrateSoundPowerBinDesiredSec);\n console.log(res);\n this.recordingChecks['volume'][this.inDB] = res;\n console.log('Recording checks in sendToServer', this.recordingChecks['volume']);\n const getSD = () => this.recordingChecks['volume'][this.inDB]['sd'];\n // const getSDMessage = () => {\n // //SOUND 6.7 s. 2.5+2.5+0.5 s. 1000 Hz at -60 dB. SD = 1.3 dB\n // // And reporting each rejected recording as\n // // SOUND 6.7 s. 2.5+2.5+0.5 s. 1000 Hz at -60 dB, SD = 19.7 > 4 dB.\n\n // if (this.numCalibratingRoundsCompleted == 1)\n // return `. SD = ${getSD()} > ${this.calibrateSound1000HzMaxSD_dB} dB.`;\n // return `. SD = ${getSD()} dB`;\n // };\n // const total_dur =\n // this.calibrateSound1000HzPreSec +\n // this.calibrateSound1000HzSec +\n // this.calibrateSound1000HzPostSec;\n\n // this.addTimeStamp(\n // `${this.calibrateSound1000HzPreSec.toFixed(1)}` +\n // `+${this.calibrateSound1000HzSec.toFixed(1)}` +\n // `+${this.calibrateSound1000HzPostSec.toFixed(1)} s.` +\n // `1000 Hz at ${this.inDB} dB${getSDMessage()}`\n // );\n });\n _defineProperty(this, \"startCalibrationVolume\", async (stream, gainValues, lCalib, componentGainDBSPL) => {\n if (this.isCalibrating) return null;\n const trialIterations = gainValues.length;\n this.status_denominator += trialIterations;\n const thdValues = [];\n const inDBValues = [];\n let inDB = 0;\n const outDBSPLValues = [];\n const outDBSPL1000Values = [];\n let checkRec = 'loudest';\n // do one calibration that will be discarded\n const soundLevelToDiscard = -60;\n const gainToDiscard = Math.pow(10, soundLevelToDiscard / 20);\n this.inDB = soundLevelToDiscard;\n this.status = this.generateTemplate(\"1000 Hz Calibration: Sound Level \".concat(soundLevelToDiscard, \" dB\").toString()).toString();\n //this.emit('update', {message: `1000 Hz Calibration: Sound Level ${soundLevelToDiscard} dB`});\n this.emit('update', {\n message: this.status\n });\n this.startTime = new Date().getTime();\n this.calibrationNodes = [];\n do {\n console.log('while loop');\n if (this.isCalibrating) {\n console.log('restart calibration');\n return null;\n }\n // eslint-disable-next-line no-await-in-loop\n await this.volumeCalibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudioVolume, this), _classPrivateFieldGet(_createCalibrationToneWithGainValue, this), _classPrivateFieldGet(_sendToServerForProcessing, this), gainToDiscard, lCalib,\n //todo make this a class parameter\n checkRec, () => {\n return this.recordingChecks['volume'][this.inDB]['sd'];\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } while (this.outDBSPL === null);\n //reset the values\n //this.incrementStatusBar();\n\n this.outDBSPL = null;\n this.outDBSPL = null;\n this.outDBSPL1000 = null;\n this.THD = null;\n\n // run the calibration at different gain values provided by the user\n for (let i = 0; i < trialIterations; i++) {\n //convert gain to DB and add to inDB\n if (i == trialIterations - 1) {\n checkRec = 'loudest';\n }\n inDB = Math.log10(gainValues[i]) * 20;\n // precision to 1 decimal place\n inDB = Math.round(inDB * 10) / 10;\n this.inDB = inDB;\n inDBValues.push(inDB);\n console.log('next update');\n this.status = this.generateTemplate(\"1000 Hz Calibration: Sound Level \".concat(inDB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n do {\n if (this.isCalibrating) {\n console.log('restart calibration');\n return null;\n }\n // eslint-disable-next-line no-await-in-loop\n await this.volumeCalibrationSteps(stream, _classPrivateFieldGet(_playCalibrationAudioVolume, this), _classPrivateFieldGet(_createCalibrationToneWithGainValue, this), _classPrivateFieldGet(_sendToServerForProcessing, this), gainValues[i], lCalib,\n //todo make this a class parameter\n checkRec, () => {\n var _this$recordingChecks;\n return ((_this$recordingChecks = this.recordingChecks) === null || _this$recordingChecks === void 0 || (_this$recordingChecks = _this$recordingChecks['volume']) === null || _this$recordingChecks === void 0 || (_this$recordingChecks = _this$recordingChecks[this.inDB]) === null || _this$recordingChecks === void 0 ? void 0 : _this$recordingChecks['sd']) || 0;\n }, this.calibrateSound1000HzMaxSD_dB, this.calibrateSound1000HzMaxTries);\n } while (this.outDBSPL === null);\n outDBSPL1000Values.push(this.outDBSPL1000);\n thdValues.push(this.THD);\n outDBSPLValues.push(this.outDBSPL);\n this.outDBSPL = null;\n this.outDBSPL1000 = null;\n this.THD = null;\n }\n if (this.isCalibrating) return null;\n // get the volume calibration parameters from the server\n this.addTimeStamp('Compute sound calibration parameters');\n const parameters = await this.pyServerAPI.getVolumeCalibrationParameters({\n inDBValues: inDBValues,\n outDBSPLValues: outDBSPL1000Values,\n lCalib: lCalib,\n componentGainDBSPL\n }).then(res => {\n this.incrementStatusBar();\n return res;\n }).catch(err => {\n throw err;\n });\n if (this.isCalibrating) return null;\n const result = {\n parameters: parameters,\n inDBValues: inDBValues,\n outDBSPLValues: outDBSPLValues,\n outDBSPL1000Values: outDBSPL1000Values,\n thdValues: thdValues\n };\n return result;\n });\n _defineProperty(this, \"writeFrqGainToFirestore\", async (speakerID, frq, gain, OEM, documentID) => {\n // freq and gain are too large to take samples 1 in every 100 samples\n // const sampledFrq = [];\n // const sampledGain = [];\n // for (let i = 0; i < frq.length; i += 100) {\n // sampledFrq.push(frq[i]);\n // sampledGain.push(gain[i]);\n // }\n\n const data = {\n Freq: frq,\n Gain: gain\n };\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.updateDoc)(docRef, {\n linear: data\n });\n\n // divide frq and gain into smaller chunks and write to firestore one chunk at a time\n // use arrayUnion to append to the array\n // const chunkSize = 600;\n // const chunkedFrq = [];\n // const chunkedGain = [];\n // for (let i = 0; i < frq.length; i += chunkSize) {\n // chunkedFrq.push(frq.slice(i, i + chunkSize));\n // chunkedGain.push(gain.slice(i, i + chunkSize));\n // }\n // const docRef = doc(database, 'Microphones', documentID);\n // for (let i = 0; i < chunkedFrq.length; i++) {\n // await updateDoc(docRef, {\n // linear: {\n // Freq: arrayUnion(...chunkedFrq[i]),\n // Gain: arrayUnion(...chunkedGain[i]),\n // },\n // });\n // }\n });\n // function to write frq and gain to firebase database given speakerID\n _defineProperty(this, \"writeFrqGain\", async (speakerID, frq, gain, OEM) => {\n // freq and gain are too large to take samples 1 in every 100 samples\n\n const sampledFrq = [];\n const sampledGain = [];\n for (let i = 0; i < frq.length; i += 100) {\n sampledFrq.push(frq[i]);\n sampledGain.push(gain[i]);\n }\n const data = {\n Freq: sampledFrq,\n Gain: sampledGain\n };\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/linear\")), data);\n });\n // Function to Read frq and gain from firebase database given speakerID\n // returns an array of frq and gain if speakerID exists, returns null otherwise\n _defineProperty(this, \"readFrqGainFromFirestore\", async (speakerID, OEM, isDefault) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', isDefault));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n // if exists return the linear field of the first document\n if (querySnapshot.size > 0) {\n const timestamp = new firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.Timestamp(querySnapshot.docs[0].data().createDate.seconds, querySnapshot.docs[0].data().createDate.nanoseconds);\n return {\n ir: querySnapshot.docs[0].data().linear,\n createDate: timestamp.toDate(),\n jsonFileName: querySnapshot.docs[0].data().jsonFileName\n };\n }\n return null;\n });\n _defineProperty(this, \"readFrqGain\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/linear\")));\n if (snapshot.exists()) {\n return snapshot.val();\n }\n return null;\n });\n _defineProperty(this, \"readGainat1000HzFromFirestore\", async (speakerID, OEM, isDefault) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', isDefault));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n // if exists return the Gain1000 field of the first document\n if (querySnapshot.size > 0) {\n return querySnapshot.docs[0].data().Gain1000;\n }\n return null;\n });\n _defineProperty(this, \"readGainat1000Hz\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/Gain1000\")));\n if (snapshot.exists()) {\n return snapshot.val();\n }\n return null;\n });\n _defineProperty(this, \"writeGainat1000HzToFirestore\", async (speakerID, gain, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.updateDoc)(docRef, {\n Gain1000: gain\n });\n });\n _defineProperty(this, \"writeGainat1000Hz\", async (speakerID, gain, OEM) => {\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/Gain1000\")), gain);\n });\n _defineProperty(this, \"writeIsSmartPhoneToFirestore\", async (speakerID, isSmartPhone, OEM) => {\n const collectionRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.collection)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones');\n const q = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.query)(collectionRef, (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('ID', '==', speakerID), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('lowercaseOEM', '==', OEM), (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.where)('isDefault', '==', true));\n const querySnapshot = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDocs)(q);\n if (querySnapshot.size > 0) {\n const docRef = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.addDoc)(collectionRef, {\n isSmartPhone: isSmartPhone,\n isDefault: false\n });\n return docRef.id;\n } else {\n const docRef = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.addDoc)(collectionRef, {\n isSmartPhone: isSmartPhone,\n isDefault: true\n });\n return docRef.id;\n }\n });\n _defineProperty(this, \"writeIsSmartPhone\", async (speakerID, isSmartPhone, OEM) => {\n const data = {\n isSmartPhone: isSmartPhone\n };\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/isSmartPhone\")), isSmartPhone);\n });\n _defineProperty(this, \"writeMicrophoneInfoToFirestore\", async (speakerID, micInfo, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphones', documentID);\n await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.setDoc)(docRef, micInfo, {\n merge: true\n });\n });\n _defineProperty(this, \"doesMicrophoneExistInFirestore\", async (speakerID, OEM, documentID) => {\n const docRef = (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.doc)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], 'Microphone', OEM, speakerID, documentID);\n const docSnap = await (0,firebase_firestore__WEBPACK_IMPORTED_MODULE_12__.getDoc)(docRef);\n if (docSnap.exists()) {\n return true;\n }\n return false;\n });\n _defineProperty(this, \"doesMicrophoneExist\", async (speakerID, OEM) => {\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID)));\n if (snapshot.exists()) {\n return true;\n }\n return false;\n });\n _defineProperty(this, \"addMicrophoneInfo\", async (speakerID, OEM, micInfo) => {\n // add to database if /info does not exist\n const dbRef = (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"]);\n const snapshot = await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.get)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.child)(dbRef, \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/info\")));\n if (!snapshot.exists()) {\n await (0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.set)((0,firebase_database__WEBPACK_IMPORTED_MODULE_11__.ref)(_config_firebase__WEBPACK_IMPORTED_MODULE_10__[\"default\"], \"Microphone2/\".concat(OEM, \"/\").concat(speakerID, \"/info\")), micInfo);\n }\n });\n _defineProperty(this, \"convertToDB\", gain => {\n return Math.log10(gain) * 20;\n });\n _defineProperty(this, \"findGainatFrequency\", (frequencies, gains, targetFrequency) => {\n // Find the index of the first frequency in the array greater than the target frequency\n let index = 0;\n while (index < frequencies.length && frequencies[index] < targetFrequency) {\n index++;\n }\n\n // Handle cases when the target frequency is outside the range of the given data\n if (index === 0) {\n return gains[0];\n } else if (index === frequencies.length) {\n return gains[gains.length - 1];\n } else {\n // Interpolate the gain based on the surrounding frequencies\n const x0 = frequencies[index - 1];\n const y0 = gains[index - 1];\n const x1 = frequencies[index];\n const y1 = gains[index];\n return this.interpolate(targetFrequency, x0, y0, x1, y1);\n }\n });\n _defineProperty(this, \"checkPowerVariation\", async () => {\n let recordings = this.getAllFilteredRecordedSignals();\n // remove filteredMLSAttenuation from the recordings\n\n // recordings = recordings.map(recording => {\n // if (this.soundCheck == 'component') {\n // return recording.map(value => value / this.filteredMLSAttenuation.component);\n // }\n // return recording.map(value => value / this.filteredMLSAttenuation.system);\n // });\n\n const rec = recordings[recordings.length - 1];\n const fMLS = this.sourceSamplingRate / this._calibrateSoundBurstDownsample;\n const payload_downsampled = this.downsampleSignal(rec, this._calibrateSoundBurstDownsample);\n await this.pyServerAPI.allHzPowerCheck({\n payload: payload_downsampled,\n sampleRate: fMLS,\n binDesiredSec: this._calibrateSoundPowerBinDesiredSec,\n burstSec: this.desired_time_per_mls,\n repeats: this.numMLSPerCapture - this.num_mls_to_skip,\n warmUp: this.num_mls_to_skip,\n downsample: this._calibrateSoundBurstDownsample\n }).then(result => {\n if (result) {\n if (result['sd'] > this._calibrateSoundBurstMaxSD_dB && this.numSuccessfulCaptured == 0) {\n console.log('filtered recording sd too high');\n this.recordingChecks['warnings'].push(\"All Hz. Re-recorded \".concat(this.inDB, \" because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\"));\n this.status = this.generateTemplate(\"All Hz: Re-recording at \".concat(this.inDB, \" dB because SD \").concat(result['sd'], \" > \").concat(this._calibrateSoundBurstMaxSD_dB, \" dB\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n // numSuccessfulCaptured no longer to count number of successful capture but count attemps\n // is sd below _calibrateSoundBurstMaxSD_dB then count two attemps\n // else count one attemp\n this.numSuccessfulCaptured += 1;\n } else {\n this.recordingChecks[this.soundCheck].push(result);\n // Now we do at most 2 attempts if sd > _calibrateSoundBurstMaxSD_dB\n // Second attempt is the final\n if (this.numSuccessfulCaptured < 2) {\n this.numSuccessfulCaptured += 2;\n this.stepNum += 1;\n this.incrementStatusBar();\n console.log('after mls w iir record for some reason add numSucc capt ' + this.stepNum);\n this.status = this.generateTemplate(\"All Hz Calibration: \".concat(this.numSuccessfulCaptured, \" recording of convolved MLS captured\").toString()).toString();\n this.emit('update', {\n message: this.status\n });\n }\n }\n }\n });\n });\n _defineProperty(this, \"getGainDBSPL\", () => {\n var freqIndex = this.componentIR.Freq.indexOf(1000);\n\n // If freqIndex is not -1 (meaning 1000 is found in the freq array)\n if (freqIndex !== -1) {\n // Get the corresponding gain value using the index\n var gainValue = this.componentIR.Gain[freqIndex];\n return gainValue;\n } else {\n console.log('Freq 1000 not found in the array.');\n return null;\n }\n });\n // Example of how to use the writeFrqGain and readFrqGain functions\n // writeFrqGain('speaker1', [1, 2, 3], [4, 5, 6]);\n // Speaker1 is the speakerID you want to write to in the database\n // readFrqGain('MiniDSPUMIK_1').then(data => console.log(data));\n // MiniDSPUMIK_1 is the speakerID with some Data in the database\n //adding gainDBSPL\n _defineProperty(this, \"startCalibration\", async function (stream, gainValues) {\n let lCalib = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 104.92978421490648;\n let componentIR = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;\n let microphoneName = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'MiniDSP-UMIK1-711-4754-vertical';\n let _calibrateSoundCheck = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 'goal';\n let isSmartPhone = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;\n let _calibrateSoundBurstDb = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : -18;\n let _calibrateSoundBurstFilteredExtraDb = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 6;\n let _calibrateSoundBurstLevelReTBool = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;\n let _calibrateSoundBurstUses1000HzGainBool = arguments.length > 10 && arguments[10] !== undefined ? arguments[10] : false;\n let _calibrateSoundBurstRepeats = arguments.length > 11 && arguments[11] !== undefined ? arguments[11] : 3;\n let _calibrateSoundBurstSec = arguments.length > 12 && arguments[12] !== undefined ? arguments[12] : 1;\n let _calibrateSoundBurstPreSec = arguments.length > 13 && arguments[13] !== undefined ? arguments[13] : 1;\n let _calibrateSoundBurstPostSec = arguments.length > 14 && arguments[14] !== undefined ? arguments[14] : 1;\n let _calibrateSoundHz = arguments.length > 15 && arguments[15] !== undefined ? arguments[15] : 48000;\n let _calibrateSoundIRSec = arguments.length > 16 && arguments[16] !== undefined ? arguments[16] : 0.2;\n let _calibrateSoundIIRSec = arguments.length > 17 && arguments[17] !== undefined ? arguments[17] : 0.2;\n let _calibrateSoundIIRPhase = arguments.length > 18 && arguments[18] !== undefined ? arguments[18] : 'linear';\n let calibrateSound1000HzPreSec = arguments.length > 19 && arguments[19] !== undefined ? arguments[19] : 0.5;\n let calibrateSound1000HzSec = arguments.length > 20 && arguments[20] !== undefined ? arguments[20] : 0.5;\n let calibrateSound1000HzPostSec = arguments.length > 21 && arguments[21] !== undefined ? arguments[21] : 0.5;\n let _calibrateSoundBackgroundSecs = arguments.length > 22 && arguments[22] !== undefined ? arguments[22] : 0;\n let _calibrateSoundSmoothOctaves = arguments.length > 23 && arguments[23] !== undefined ? arguments[23] : 0.33;\n let _calibrateSoundSmoothMinBandwidthHz = arguments.length > 24 && arguments[24] !== undefined ? arguments[24] : 200;\n let _calibrateSoundPowerBinDesiredSec = arguments.length > 25 && arguments[25] !== undefined ? arguments[25] : 0.2;\n let _calibrateSoundPowerDbSDToleratedDb = arguments.length > 26 && arguments[26] !== undefined ? arguments[26] : 1;\n let _calibrateSoundTaperSec = arguments.length > 27 && arguments[27] !== undefined ? arguments[27] : 0.01;\n let micManufacturer = arguments.length > 28 && arguments[28] !== undefined ? arguments[28] : '';\n let micSerialNumber = arguments.length > 29 && arguments[29] !== undefined ? arguments[29] : '';\n let micModelNumber = arguments.length > 30 && arguments[30] !== undefined ? arguments[30] : '';\n let micModelName = arguments.length > 31 && arguments[31] !== undefined ? arguments[31] : '';\n let calibrateMicrophonesBool = arguments.length > 32 ? arguments[32] : undefined;\n let authorEmails = arguments.length > 33 ? arguments[33] : undefined;\n let webAudioDeviceNames = arguments.length > 34 && arguments[34] !== undefined ? arguments[34] : {\n loudspeaker: 'loudspeaker',\n microphone: 'microphone',\n microphoneText: 'xxx XXX'\n };\n let userIDs = arguments.length > 35 ? arguments[35] : undefined;\n let restartButton = arguments.length > 36 ? arguments[36] : undefined;\n let reminder = arguments.length > 37 ? arguments[37] : undefined;\n let calibrateSoundLimit = arguments.length > 38 ? arguments[38] : undefined;\n let _calibrateSoundBurstNormalizeBy1000HzGainBool = arguments.length > 39 && arguments[39] !== undefined ? arguments[39] : false;\n let _calibrateSoundBurstScalarDB = arguments.length > 40 && arguments[40] !== undefined ? arguments[40] : 71;\n let calibrateSound1000HzMaxSD_dB = arguments.length > 41 && arguments[41] !== undefined ? arguments[41] : 4;\n let calibrateSound1000HzMaxTries = arguments.length > 42 && arguments[42] !== undefined ? arguments[42] : 4;\n let _calibrateSoundBurstMaxSD_dB = arguments.length > 43 && arguments[43] !== undefined ? arguments[43] : 4;\n let calibrateSoundSamplingDesiredBits = arguments.length > 44 && arguments[44] !== undefined ? arguments[44] : 24;\n let language = arguments.length > 45 ? arguments[45] : undefined;\n let loudspeakerModelName = arguments.length > 46 && arguments[46] !== undefined ? arguments[46] : '';\n let phrases = arguments.length > 47 ? arguments[47] : undefined;\n let soundSubtitleId = arguments.length > 48 ? arguments[48] : undefined;\n let calibrateSoundBurstDownsample = arguments.length > 49 && arguments[49] !== undefined ? arguments[49] : 1;\n _this._calibrateSoundBurstDownsample = calibrateSoundBurstDownsample;\n _this._calibrateSoundBurstPreSec = _calibrateSoundBurstPreSec;\n _this._calibrateSoundBurstRepeats = _calibrateSoundBurstRepeats;\n _this._calibrateSoundBurstSec = _calibrateSoundBurstSec;\n _this.micModelName = micModelName;\n _this.loudspeakerModelName = loudspeakerModelName;\n _this.language = language;\n _this.TAPER_SECS = _calibrateSoundTaperSec;\n _this.calibrateSoundLimit = calibrateSoundLimit;\n _this._calibrateSoundBurstDb = _calibrateSoundBurstDb;\n _this._calibrateSoundBurstFilteredExtraDb = _calibrateSoundBurstFilteredExtraDb;\n _this._calibrateSoundBurstLevelReTBool = _calibrateSoundBurstLevelReTBool;\n _this.CALIBRATION_TONE_DURATION = calibrateSound1000HzPreSec + calibrateSound1000HzSec + calibrateSound1000HzPostSec;\n _this.calibrateSound1000HzPreSec = calibrateSound1000HzPreSec;\n _this.calibrateSound1000HzSec = calibrateSound1000HzSec;\n _this.calibrateSound1000HzPostSec = calibrateSound1000HzPostSec;\n const fMLS = _this.sourceSamplingRate / _this._calibrateSoundBurstDownsample;\n _this.iirLength = Math.floor(_calibrateSoundIIRSec * fMLS);\n _this.irLength = Math.floor(_calibrateSoundIRSec * fMLS);\n _this.calibrateSoundIIRPhase = _calibrateSoundIIRPhase;\n _this.num_mls_to_skip = Math.ceil(_calibrateSoundBurstPreSec / _calibrateSoundBurstSec);\n _this._calibrateSoundBurstPostSec = _calibrateSoundBurstPostSec;\n _this.numMLSPerCapture = _calibrateSoundBurstRepeats + _this.num_mls_to_skip;\n _this.desired_time_per_mls = _calibrateSoundBurstSec;\n _this.desired_sampling_rate = _calibrateSoundHz;\n _this._calibrateSoundBackgroundSecs = _calibrateSoundBackgroundSecs;\n _this._calibrateSoundSmoothOctaves = _calibrateSoundSmoothOctaves;\n _this._calibrateSoundSmoothMinBandwidthHz = _calibrateSoundSmoothMinBandwidthHz;\n _this._calibrateSoundPowerBinDesiredSec = _calibrateSoundPowerBinDesiredSec;\n _this._calibrateSoundBurstUses1000HzGainBool = _calibrateSoundBurstUses1000HzGainBool;\n _this._calibrateSoundPowerDbSDToleratedDb = _calibrateSoundPowerDbSDToleratedDb;\n _this._calibrateSoundBurstNormalizeBy1000HzGainBool = _calibrateSoundBurstNormalizeBy1000HzGainBool;\n _this._calibrateSoundBurstScalarDB = _calibrateSoundBurstScalarDB;\n _this.webAudioDeviceNames = webAudioDeviceNames;\n _this.calibrateSoundSamplingDesiredBits = calibrateSoundSamplingDesiredBits;\n _this.phrases = phrases;\n _this.soundSubtitleId = soundSubtitleId;\n if (isSmartPhone) {\n const leftQuote = '\\u201C'; // “\n const rightQuote = '\\u201D'; // ”\n _this.webAudioDeviceNames.microphone = _this.deviceInfo.microphoneFromAPI;\n const quotedWebAudioMic = leftQuote + _this.webAudioDeviceNames.microphone + rightQuote;\n const combinedMicText = _this.micModelName + ' ' + quotedWebAudioMic;\n webAudioDeviceNames.microphoneText = _this.phrases.RC_nameMicrophone[_this.language].replace('“xxx”', combinedMicText).replace('“XXX”', combinedMicText);\n }\n // this.webAudioDeviceNames.microphoneText = this.webAudioDeviceNames.microphoneText\n // .replace('xxx', this.webAudioDeviceNames.microphone)\n // .replace('XXX', this.webAudioDeviceNames.microphone);\n //feed calibration goal here\n _this._calibrateSoundCheck = _calibrateSoundCheck;\n _this.calibrateSound1000HzMaxSD_dB = calibrateSound1000HzMaxSD_dB;\n _this.calibrateSound1000HzMaxTries = calibrateSound1000HzMaxTries;\n _this._calibrateSoundBurstMaxSD_dB = _calibrateSoundBurstMaxSD_dB;\n //check if a componentIR was given to the system, if it isn't check for the microphone. using dummy data here bc we need to\n //check the db based on the microphone currently connected\n\n //new lCalib found at top of calibration files *1000hz, make sure to correct\n //based on zeroing of 1000hz, search for \"*1000Hz\"\n const ID = isSmartPhone ? micModelNumber : micSerialNumber;\n const OEM = isSmartPhone ? micModelName === 'UMIK-1' || micModelName === 'UMIK-2' ? 'minidsp' : _this.deviceInfo.OEM ? _this.deviceInfo.OEM.toLowerCase().split(' ').join('') : micManufacturer.toLowerCase().split(' ').join('') : micManufacturer.toLowerCase().split(' ').join('');\n // const ID = \"712-5669\";\n // const OEM = \"minidsp\";\n const micInfo = {\n micModelName: isSmartPhone ? micModelName : microphoneName,\n OEM: isSmartPhone ? micModelName === 'UMIK-1' || micModelName === 'UMIK-2' ? 'miniDSP' : _this.deviceInfo.OEM : micManufacturer,\n ID: ID,\n createDate: new Date(),\n DateText: (0,_utils__WEBPACK_IMPORTED_MODULE_8__.getCurrentTimeString)(),\n HardwareName: isSmartPhone ? _this.deviceInfo.hardwarename : microphoneName,\n hardwareFamily: isSmartPhone ? _this.deviceInfo.hardwarefamily : microphoneName,\n HardwareModel: isSmartPhone ? _this.deviceInfo.hardwaremodel : microphoneName,\n PlatformName: isSmartPhone ? _this.deviceInfo.platformname : 'N/A',\n PlatformVersion: isSmartPhone ? _this.deviceInfo.platformversion : 'N/A',\n DeviceType: isSmartPhone ? _this.deviceInfo.devicetype : 'N/A',\n ID_from_51Degrees: isSmartPhone ? _this.deviceInfo.DeviceId : 'N/A',\n calibrateMicrophonesBool: calibrateMicrophonesBool,\n screenHeight: _this.deviceInfo.screenHeight,\n screenWidth: _this.deviceInfo.screenWidth,\n webAudioDeviceNames: {\n loudspeaker: _this.webAudioDeviceNames.loudspeaker,\n microphone: _this.webAudioDeviceNames.microphone\n },\n userIDs: userIDs,\n lowercaseOEM: OEM ? OEM.toLowerCase().split(' ').join('') : ''\n };\n if (calibrateMicrophonesBool) {\n micInfo['authorEmails'] = authorEmails;\n }\n // if undefined in micInfo, set to empty string\n for (const [key, value] of Object.entries(micInfo)) {\n if (value === undefined) {\n micInfo[key] = '';\n }\n }\n\n // this.writeMicrophoneInfoToFirestore(ID, micInfo, OEM, 'default');\n // this.addMicrophoneInfo(ID, OEM, micInfo);\n if (componentIR == null) {\n //mode 'ir'\n //global variable this.componentIR must be set\n await _this.readFrqGainFromFirestore(ID, OEM, true).then(data => {\n if (data !== null) {\n _this.componentIR = data.ir;\n micInfo['parentTimestamp'] = data.createDate ? data.createDate : new Date();\n micInfo['parentFilenameJSON'] = data.jsonFileName ? data.jsonFileName : '';\n }\n });\n\n // await this.readFrqGain(ID, OEM).then(data => {\n // return data;\n // });\n\n // lCalib = await this.readGainat1000Hz(ID, OEM);\n lCalib = await _this.readGainat1000HzFromFirestore(ID, OEM, true);\n micInfo['gainDBSPL'] = lCalib;\n // this.componentGainDBSPL = this.convertToDB(lCalib);\n _this.componentGainDBSPL = lCalib;\n //TODO: if this call to database is unknown, cannot perform experiment => return false\n if (_this.componentIR == null) {\n _this.status = \"Microphone (\".concat(OEM, \",\").concat(ID, \") is not found in the database. Please add it to the database.\").toString();\n _this.emit('update', {\n message: _this.status\n });\n return false;\n }\n } else {\n _this.transducerType = 'Microphone';\n _this.componentIR = componentIR;\n lCalib = _this.findGainatFrequency(_this.componentIR.Freq, _this.componentIR.Gain, 1000);\n // this.componentGainDBSPL = this.convertToDB(lCalib);\n _this.componentGainDBSPL = lCalib;\n // await this.writeIsSmartPhone(ID, isSmartPhone, OEM);\n }\n _this.oldComponentIR = JSON.parse(JSON.stringify(_this.componentIR));\n return await new Promise(async (resolve, reject) => {\n // add event listner to params.restartButton to resolve the promise with a string: 'restart'\n\n if (reminder) {\n reminder.style.display = '';\n }\n if (restartButton) {\n restartButton.style.display = '';\n restartButton.addEventListener('click', () => {\n _this.stopCalibrationAudio();\n _this.isCalibrating = true;\n restartButton.style.display = 'none';\n if (reminder) {\n reminder.style.display = 'none';\n }\n _this.emit('update', {\n message: 'Restarting calibration...'\n });\n resolve('restart');\n });\n }\n await _this.pyServerAPI.checkMemory();\n // calibrate volume\n\n let volumeResults = await _this.startCalibrationVolume(stream, gainValues, lCalib, _this.componentGainDBSPL);\n if (!volumeResults) return;\n _this.T = volumeResults['parameters']['T'];\n _this.gainDBSPL = volumeResults['parameters']['gainDBSPL'];\n\n // end calibrate volume\n\n let impulseResponseResults = await _this.startCalibrationImpulseResponse(stream);\n if (!impulseResponseResults) return;\n impulseResponseResults['background_noise'] = _this.background_noise;\n impulseResponseResults['system']['background_noise'] = _this.background_noise;\n impulseResponseResults['component']['background_noise'] = _this.background_noise;\n\n //attenuate system background noise\n if (_this.systemAttenuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, _this.systemAttenuatorGainDB / 20);\n let linearScalePowerAttenuation = Math.pow(10, _this.systemAttenuatorGainDB / 10);\n impulseResponseResults['system']['background_noise']['recording'] = impulseResponseResults['background_noise']['recording'].map(value => value / linearScaleAttenuation);\n impulseResponseResults['system']['background_noise']['x_background'] = impulseResponseResults['background_noise']['x_background'];\n impulseResponseResults['system']['background_noise']['y_background'] = impulseResponseResults['background_noise']['y_background'].map(value => value / linearScalePowerAttenuation);\n }\n //attenuate component background noise\n if (_this.componentAttentuatorGainDB != 0) {\n let linearScaleAttenuation = Math.pow(10, _this.componentAttenuatorGainDB / 20);\n let linearScalePowerAttenuation = Math.pow(10, _this.componentAttenuatorGainDB / 10);\n impulseResponseResults['component']['background_noise']['recording'] = impulseResponseResults['background_noise']['recording'].map(value => value / linearScaleAttenuation);\n impulseResponseResults['component']['background_noise']['x_background'] = impulseResponseResults['background_noise']['x_background'];\n impulseResponseResults['component']['background_noise']['y_background'] = impulseResponseResults['background_noise']['y_background'].map(value => value / linearScalePowerAttenuation);\n }\n impulseResponseResults['system']['attenuatorGainDB'] = _this.systemAttenuatorGainDB;\n impulseResponseResults['component']['attenuatorGainDB'] = _this.componentAttenuatorGainDB;\n impulseResponseResults['system']['fMaxHz'] = _this.systemFMaxHz;\n impulseResponseResults['component']['fMaxHz'] = _this.componentFMaxHz;\n impulseResponseResults['L_new_n'] = _this.L_new_n;\n impulseResponseResults['fs2'] = _this.fs2;\n if (componentIR != null) {\n var _impulseResponseResul;\n // I corrected microphone/loudpeaker IR scale in easyeyes,\n // but since we write microphone IR to firestore here\n // we need to correct microphone IR here\n let correctGain = Math.round((volumeResults.parameters.gainDBSPL - _this.componentGainDBSPL) * 10) / 10;\n let IrFreq = impulseResponseResults === null || impulseResponseResults === void 0 ? void 0 : impulseResponseResults.component.ir.Freq.map(freq => Math.round(freq));\n let IrGain = impulseResponseResults === null || impulseResponseResults === void 0 || (_impulseResponseResul = impulseResponseResults.component) === null || _impulseResponseResul === void 0 ? void 0 : _impulseResponseResul.ir.Gain;\n const IrGainAt1000Hz = IrGain[IrFreq.findIndex(freq => freq === 1000)];\n const difference = Math.round(10 * (IrGainAt1000Hz - correctGain)) / 10;\n IrGain = IrGain.map(gain => gain - difference);\n micInfo['mls'] = Number(_this.SDofFilteredRange['mls']);\n micInfo['systemCorrectionSD'] = Number(_this.SDofFilteredRange['system']);\n micInfo['componentCorrectionSD'] = Number(_this.SDofFilteredRange['component']);\n console.log(typeof micInfo['componentCorrectionSD']);\n // const id = await this.writeIsSmartPhoneToFirestore(ID, isSmartPhone, OEM);\n // await this.writeMicrophoneInfoToFirestore(ID, micInfo, OEM, id);\n // await this.writeFrqGainToFirestore(ID, IrFreq, IrGain, OEM, id);\n // micInfo['gainDBSPL'] = impulseResponseResults.component.gainDBSPL;\n // await this.writeGainat1000HzToFirestore(ID, micInfo['gainDBSPL'], OEM, id);\n // await this.writeGainat1000Hz(ID, micInfo['gainDBSPL'], OEM);\n }\n const total_results = {\n ...volumeResults,\n ...impulseResponseResults\n };\n total_results['filteredMLSRange'] = _this.filteredMLSRange;\n total_results['filteredMLSAttenuation'] = _this.filteredMLSAttenuation;\n total_results['micInfo'] = micInfo;\n total_results['audioInfo'] = {};\n total_results['audioInfo']['sinkSampleRate'] = _this.sinkSamplingRate;\n total_results['audioInfo']['sourceSampleRate'] = _this.sourceSamplingRate;\n total_results['audioInfo']['bitsPerSample'] = _this.sampleSize;\n const timeStampresult = [..._this.timeStamp].join('\\n');\n total_results['timeStamps'] = timeStampresult;\n total_results['recordingChecks'] = _this.recordingChecks;\n total_results['waveforms'] = _this.waveforms;\n total_results['component']['phase'] = _this.componentIRPhase;\n total_results['system']['phase'] = _this.systemIRPhase;\n total_results['qualityMetrics'] = _this.SDofFilteredRange;\n total_results['flags'] = _this.flags;\n total_results['permissionStatus'] = _this.permissionStatus;\n console.log('total results');\n console.log(total_results);\n console.log('Time Stamps');\n console.log(timeStampresult);\n _this.stopCalibrationAudio();\n resolve(total_results);\n });\n });\n _classPrivateFieldSet(_mlsOrder, this, parseInt(mlsOrder, 10));\n _classPrivateFieldSet(_P, this, 2 ** mlsOrder - 1);\n _classPrivateFieldSet(_download, this, download);\n _classPrivateFieldSet(_mls, this, []);\n _classPrivateFieldSet(_lowHz, this, _lowHz2);\n _classPrivateFieldSet(_highHz, this, _highHz2);\n }\n // Function to perform linear interpolation between two points\n interpolate(x, x0, y0, x1, y1) {\n return y0 + (x - x0) * (y1 - y0) / (x1 - x0);\n }\n}\n_defineProperty(Combination, \"createInverseSCurveBuffer\", (length, phase) => {\n const curve = new Float32Array(length);\n let i;\n let j = length - 1;\n for (i = 0; i < length; i += 1) {\n // scale the curve to be between 0-1\n curve[i] = Math.sin(Math.PI * j / length - phase) / 2 + 0.5;\n j -= 1;\n }\n return curve;\n});\n/* harmony default export */ __webpack_exports__[\"default\"] = (Combination);\n\n//# sourceURL=webpack://speakerCalibrator/./src/tasks/combination/combination.js?");
184
184
 
185
185
  /***/ }),
186
186
 
@@ -250,26 +250,6 @@ eval("\n\nmodule.exports = function encodeUtf8 (input) {\n var result = []\n v
250
250
 
251
251
  /***/ }),
252
252
 
253
- /***/ "./node_modules/peerjs-js-binarypack/lib/binarypack.js":
254
- /*!*************************************************************!*\
255
- !*** ./node_modules/peerjs-js-binarypack/lib/binarypack.js ***!
256
- \*************************************************************/
257
- /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
258
-
259
- eval("var BufferBuilder = (__webpack_require__(/*! ./bufferbuilder */ \"./node_modules/peerjs-js-binarypack/lib/bufferbuilder.js\").BufferBuilder);\r\nvar binaryFeatures = (__webpack_require__(/*! ./bufferbuilder */ \"./node_modules/peerjs-js-binarypack/lib/bufferbuilder.js\").binaryFeatures);\r\n\r\nvar BinaryPack = {\r\n unpack: function (data) {\r\n var unpacker = new Unpacker(data);\r\n return unpacker.unpack();\r\n },\r\n pack: function (data) {\r\n var packer = new Packer();\r\n packer.pack(data);\r\n var buffer = packer.getBuffer();\r\n return buffer;\r\n }\r\n};\r\n\r\nmodule.exports = BinaryPack;\r\n\r\nfunction Unpacker (data) {\r\n // Data is ArrayBuffer\r\n this.index = 0;\r\n this.dataBuffer = data;\r\n this.dataView = new Uint8Array(this.dataBuffer);\r\n this.length = this.dataBuffer.byteLength;\r\n}\r\n\r\nUnpacker.prototype.unpack = function () {\r\n var type = this.unpack_uint8();\r\n if (type < 0x80) {\r\n return type;\r\n } else if ((type ^ 0xe0) < 0x20) {\r\n return (type ^ 0xe0) - 0x20;\r\n }\r\n\r\n var size;\r\n if ((size = type ^ 0xa0) <= 0x0f) {\r\n return this.unpack_raw(size);\r\n } else if ((size = type ^ 0xb0) <= 0x0f) {\r\n return this.unpack_string(size);\r\n } else if ((size = type ^ 0x90) <= 0x0f) {\r\n return this.unpack_array(size);\r\n } else if ((size = type ^ 0x80) <= 0x0f) {\r\n return this.unpack_map(size);\r\n }\r\n\r\n switch (type) {\r\n case 0xc0:\r\n return null;\r\n case 0xc1:\r\n return undefined;\r\n case 0xc2:\r\n return false;\r\n case 0xc3:\r\n return true;\r\n case 0xca:\r\n return this.unpack_float();\r\n case 0xcb:\r\n return this.unpack_double();\r\n case 0xcc:\r\n return this.unpack_uint8();\r\n case 0xcd:\r\n return this.unpack_uint16();\r\n case 0xce:\r\n return this.unpack_uint32();\r\n case 0xcf:\r\n return this.unpack_uint64();\r\n case 0xd0:\r\n return this.unpack_int8();\r\n case 0xd1:\r\n return this.unpack_int16();\r\n case 0xd2:\r\n return this.unpack_int32();\r\n case 0xd3:\r\n return this.unpack_int64();\r\n case 0xd4:\r\n return undefined;\r\n case 0xd5:\r\n return undefined;\r\n case 0xd6:\r\n return undefined;\r\n case 0xd7:\r\n return undefined;\r\n case 0xd8:\r\n size = this.unpack_uint16();\r\n return this.unpack_string(size);\r\n case 0xd9:\r\n size = this.unpack_uint32();\r\n return this.unpack_string(size);\r\n case 0xda:\r\n size = this.unpack_uint16();\r\n return this.unpack_raw(size);\r\n case 0xdb:\r\n size = this.unpack_uint32();\r\n return this.unpack_raw(size);\r\n case 0xdc:\r\n size = this.unpack_uint16();\r\n return this.unpack_array(size);\r\n case 0xdd:\r\n size = this.unpack_uint32();\r\n return this.unpack_array(size);\r\n case 0xde:\r\n size = this.unpack_uint16();\r\n return this.unpack_map(size);\r\n case 0xdf:\r\n size = this.unpack_uint32();\r\n return this.unpack_map(size);\r\n }\r\n};\r\n\r\nUnpacker.prototype.unpack_uint8 = function () {\r\n var byte = this.dataView[this.index] & 0xff;\r\n this.index++;\r\n return byte;\r\n};\r\n\r\nUnpacker.prototype.unpack_uint16 = function () {\r\n var bytes = this.read(2);\r\n var uint16 =\r\n ((bytes[0] & 0xff) * 256) + (bytes[1] & 0xff);\r\n this.index += 2;\r\n return uint16;\r\n};\r\n\r\nUnpacker.prototype.unpack_uint32 = function () {\r\n var bytes = this.read(4);\r\n var uint32 =\r\n ((bytes[0] * 256 +\r\n bytes[1]) * 256 +\r\n bytes[2]) * 256 +\r\n bytes[3];\r\n this.index += 4;\r\n return uint32;\r\n};\r\n\r\nUnpacker.prototype.unpack_uint64 = function () {\r\n var bytes = this.read(8);\r\n var uint64 =\r\n ((((((bytes[0] * 256 +\r\n bytes[1]) * 256 +\r\n bytes[2]) * 256 +\r\n bytes[3]) * 256 +\r\n bytes[4]) * 256 +\r\n bytes[5]) * 256 +\r\n bytes[6]) * 256 +\r\n bytes[7];\r\n this.index += 8;\r\n return uint64;\r\n};\r\n\r\nUnpacker.prototype.unpack_int8 = function () {\r\n var uint8 = this.unpack_uint8();\r\n return (uint8 < 0x80) ? uint8 : uint8 - (1 << 8);\r\n};\r\n\r\nUnpacker.prototype.unpack_int16 = function () {\r\n var uint16 = this.unpack_uint16();\r\n return (uint16 < 0x8000) ? uint16 : uint16 - (1 << 16);\r\n};\r\n\r\nUnpacker.prototype.unpack_int32 = function () {\r\n var uint32 = this.unpack_uint32();\r\n return (uint32 < Math.pow(2, 31)) ? uint32\r\n : uint32 - Math.pow(2, 32);\r\n};\r\n\r\nUnpacker.prototype.unpack_int64 = function () {\r\n var uint64 = this.unpack_uint64();\r\n return (uint64 < Math.pow(2, 63)) ? uint64\r\n : uint64 - Math.pow(2, 64);\r\n};\r\n\r\nUnpacker.prototype.unpack_raw = function (size) {\r\n if (this.length < this.index + size) {\r\n throw new Error('BinaryPackFailure: index is out of range' +\r\n ' ' + this.index + ' ' + size + ' ' + this.length);\r\n }\r\n var buf = this.dataBuffer.slice(this.index, this.index + size);\r\n this.index += size;\r\n\r\n // buf = util.bufferToString(buf);\r\n\r\n return buf;\r\n};\r\n\r\nUnpacker.prototype.unpack_string = function (size) {\r\n var bytes = this.read(size);\r\n var i = 0;\r\n var str = '';\r\n var c;\r\n var code;\r\n\r\n while (i < size) {\r\n c = bytes[i];\r\n if (c < 128) {\r\n str += String.fromCharCode(c);\r\n i++;\r\n } else if ((c ^ 0xc0) < 32) {\r\n code = ((c ^ 0xc0) << 6) | (bytes[i + 1] & 63);\r\n str += String.fromCharCode(code);\r\n i += 2;\r\n } else {\r\n code = ((c & 15) << 12) | ((bytes[i + 1] & 63) << 6) |\r\n (bytes[i + 2] & 63);\r\n str += String.fromCharCode(code);\r\n i += 3;\r\n }\r\n }\r\n\r\n this.index += size;\r\n return str;\r\n};\r\n\r\nUnpacker.prototype.unpack_array = function (size) {\r\n var objects = new Array(size);\r\n for (var i = 0; i < size; i++) {\r\n objects[i] = this.unpack();\r\n }\r\n return objects;\r\n};\r\n\r\nUnpacker.prototype.unpack_map = function (size) {\r\n var map = {};\r\n for (var i = 0; i < size; i++) {\r\n var key = this.unpack();\r\n var value = this.unpack();\r\n map[key] = value;\r\n }\r\n return map;\r\n};\r\n\r\nUnpacker.prototype.unpack_float = function () {\r\n var uint32 = this.unpack_uint32();\r\n var sign = uint32 >> 31;\r\n var exp = ((uint32 >> 23) & 0xff) - 127;\r\n var fraction = (uint32 & 0x7fffff) | 0x800000;\r\n return (sign === 0 ? 1 : -1) *\r\n fraction * Math.pow(2, exp - 23);\r\n};\r\n\r\nUnpacker.prototype.unpack_double = function () {\r\n var h32 = this.unpack_uint32();\r\n var l32 = this.unpack_uint32();\r\n var sign = h32 >> 31;\r\n var exp = ((h32 >> 20) & 0x7ff) - 1023;\r\n var hfrac = (h32 & 0xfffff) | 0x100000;\r\n var frac = hfrac * Math.pow(2, exp - 20) +\r\n l32 * Math.pow(2, exp - 52);\r\n return (sign === 0 ? 1 : -1) * frac;\r\n};\r\n\r\nUnpacker.prototype.read = function (length) {\r\n var j = this.index;\r\n if (j + length <= this.length) {\r\n return this.dataView.subarray(j, j + length);\r\n } else {\r\n throw new Error('BinaryPackFailure: read index out of range');\r\n }\r\n};\r\n\r\nfunction Packer () {\r\n this.bufferBuilder = new BufferBuilder();\r\n}\r\n\r\nPacker.prototype.getBuffer = function () {\r\n return this.bufferBuilder.getBuffer();\r\n};\r\n\r\nPacker.prototype.pack = function (value) {\r\n var type = typeof (value);\r\n if (type === 'string') {\r\n this.pack_string(value);\r\n } else if (type === 'number') {\r\n if (Math.floor(value) === value) {\r\n this.pack_integer(value);\r\n } else {\r\n this.pack_double(value);\r\n }\r\n } else if (type === 'boolean') {\r\n if (value === true) {\r\n this.bufferBuilder.append(0xc3);\r\n } else if (value === false) {\r\n this.bufferBuilder.append(0xc2);\r\n }\r\n } else if (type === 'undefined') {\r\n this.bufferBuilder.append(0xc0);\r\n } else if (type === 'object') {\r\n if (value === null) {\r\n this.bufferBuilder.append(0xc0);\r\n } else {\r\n var constructor = value.constructor;\r\n if (constructor == Array) {\r\n this.pack_array(value);\r\n } else if (constructor == Blob || constructor == File || value instanceof Blob || value instanceof File) {\r\n this.pack_bin(value);\r\n } else if (constructor == ArrayBuffer) {\r\n if (binaryFeatures.useArrayBufferView) {\r\n this.pack_bin(new Uint8Array(value));\r\n } else {\r\n this.pack_bin(value);\r\n }\r\n } else if ('BYTES_PER_ELEMENT' in value) {\r\n if (binaryFeatures.useArrayBufferView) {\r\n this.pack_bin(new Uint8Array(value.buffer));\r\n } else {\r\n this.pack_bin(value.buffer);\r\n }\r\n } else if ((constructor == Object) || (constructor.toString().startsWith('class'))) {\r\n this.pack_object(value);\r\n } else if (constructor == Date) {\r\n this.pack_string(value.toString());\r\n } else if (typeof value.toBinaryPack === 'function') {\r\n this.bufferBuilder.append(value.toBinaryPack());\r\n } else {\r\n throw new Error('Type \"' + constructor.toString() + '\" not yet supported');\r\n }\r\n }\r\n } else {\r\n throw new Error('Type \"' + type + '\" not yet supported');\r\n }\r\n this.bufferBuilder.flush();\r\n};\r\n\r\nPacker.prototype.pack_bin = function (blob) {\r\n var length = blob.length || blob.byteLength || blob.size;\r\n if (length <= 0x0f) {\r\n this.pack_uint8(0xa0 + length);\r\n } else if (length <= 0xffff) {\r\n this.bufferBuilder.append(0xda);\r\n this.pack_uint16(length);\r\n } else if (length <= 0xffffffff) {\r\n this.bufferBuilder.append(0xdb);\r\n this.pack_uint32(length);\r\n } else {\r\n throw new Error('Invalid length');\r\n }\r\n this.bufferBuilder.append(blob);\r\n};\r\n\r\nPacker.prototype.pack_string = function (str) {\r\n var length = utf8Length(str);\r\n\r\n if (length <= 0x0f) {\r\n this.pack_uint8(0xb0 + length);\r\n } else if (length <= 0xffff) {\r\n this.bufferBuilder.append(0xd8);\r\n this.pack_uint16(length);\r\n } else if (length <= 0xffffffff) {\r\n this.bufferBuilder.append(0xd9);\r\n this.pack_uint32(length);\r\n } else {\r\n throw new Error('Invalid length');\r\n }\r\n this.bufferBuilder.append(str);\r\n};\r\n\r\nPacker.prototype.pack_array = function (ary) {\r\n var length = ary.length;\r\n if (length <= 0x0f) {\r\n this.pack_uint8(0x90 + length);\r\n } else if (length <= 0xffff) {\r\n this.bufferBuilder.append(0xdc);\r\n this.pack_uint16(length);\r\n } else if (length <= 0xffffffff) {\r\n this.bufferBuilder.append(0xdd);\r\n this.pack_uint32(length);\r\n } else {\r\n throw new Error('Invalid length');\r\n }\r\n for (var i = 0; i < length; i++) {\r\n this.pack(ary[i]);\r\n }\r\n};\r\n\r\nPacker.prototype.pack_integer = function (num) {\r\n if (num >= -0x20 && num <= 0x7f) {\r\n this.bufferBuilder.append(num & 0xff);\r\n } else if (num >= 0x00 && num <= 0xff) {\r\n this.bufferBuilder.append(0xcc);\r\n this.pack_uint8(num);\r\n } else if (num >= -0x80 && num <= 0x7f) {\r\n this.bufferBuilder.append(0xd0);\r\n this.pack_int8(num);\r\n } else if (num >= 0x0000 && num <= 0xffff) {\r\n this.bufferBuilder.append(0xcd);\r\n this.pack_uint16(num);\r\n } else if (num >= -0x8000 && num <= 0x7fff) {\r\n this.bufferBuilder.append(0xd1);\r\n this.pack_int16(num);\r\n } else if (num >= 0x00000000 && num <= 0xffffffff) {\r\n this.bufferBuilder.append(0xce);\r\n this.pack_uint32(num);\r\n } else if (num >= -0x80000000 && num <= 0x7fffffff) {\r\n this.bufferBuilder.append(0xd2);\r\n this.pack_int32(num);\r\n } else if (num >= -0x8000000000000000 && num <= 0x7FFFFFFFFFFFFFFF) {\r\n this.bufferBuilder.append(0xd3);\r\n this.pack_int64(num);\r\n } else if (num >= 0x0000000000000000 && num <= 0xFFFFFFFFFFFFFFFF) {\r\n this.bufferBuilder.append(0xcf);\r\n this.pack_uint64(num);\r\n } else {\r\n throw new Error('Invalid integer');\r\n }\r\n};\r\n\r\nPacker.prototype.pack_double = function (num) {\r\n var sign = 0;\r\n if (num < 0) {\r\n sign = 1;\r\n num = -num;\r\n }\r\n var exp = Math.floor(Math.log(num) / Math.LN2);\r\n var frac0 = num / Math.pow(2, exp) - 1;\r\n var frac1 = Math.floor(frac0 * Math.pow(2, 52));\r\n var b32 = Math.pow(2, 32);\r\n var h32 = (sign << 31) | ((exp + 1023) << 20) |\r\n (frac1 / b32) & 0x0fffff;\r\n var l32 = frac1 % b32;\r\n this.bufferBuilder.append(0xcb);\r\n this.pack_int32(h32);\r\n this.pack_int32(l32);\r\n};\r\n\r\nPacker.prototype.pack_object = function (obj) {\r\n var keys = Object.keys(obj);\r\n var length = keys.length;\r\n if (length <= 0x0f) {\r\n this.pack_uint8(0x80 + length);\r\n } else if (length <= 0xffff) {\r\n this.bufferBuilder.append(0xde);\r\n this.pack_uint16(length);\r\n } else if (length <= 0xffffffff) {\r\n this.bufferBuilder.append(0xdf);\r\n this.pack_uint32(length);\r\n } else {\r\n throw new Error('Invalid length');\r\n }\r\n for (var prop in obj) {\r\n if (obj.hasOwnProperty(prop)) {\r\n this.pack(prop);\r\n this.pack(obj[prop]);\r\n }\r\n }\r\n};\r\n\r\nPacker.prototype.pack_uint8 = function (num) {\r\n this.bufferBuilder.append(num);\r\n};\r\n\r\nPacker.prototype.pack_uint16 = function (num) {\r\n this.bufferBuilder.append(num >> 8);\r\n this.bufferBuilder.append(num & 0xff);\r\n};\r\n\r\nPacker.prototype.pack_uint32 = function (num) {\r\n var n = num & 0xffffffff;\r\n this.bufferBuilder.append((n & 0xff000000) >>> 24);\r\n this.bufferBuilder.append((n & 0x00ff0000) >>> 16);\r\n this.bufferBuilder.append((n & 0x0000ff00) >>> 8);\r\n this.bufferBuilder.append((n & 0x000000ff));\r\n};\r\n\r\nPacker.prototype.pack_uint64 = function (num) {\r\n var high = num / Math.pow(2, 32);\r\n var low = num % Math.pow(2, 32);\r\n this.bufferBuilder.append((high & 0xff000000) >>> 24);\r\n this.bufferBuilder.append((high & 0x00ff0000) >>> 16);\r\n this.bufferBuilder.append((high & 0x0000ff00) >>> 8);\r\n this.bufferBuilder.append((high & 0x000000ff));\r\n this.bufferBuilder.append((low & 0xff000000) >>> 24);\r\n this.bufferBuilder.append((low & 0x00ff0000) >>> 16);\r\n this.bufferBuilder.append((low & 0x0000ff00) >>> 8);\r\n this.bufferBuilder.append((low & 0x000000ff));\r\n};\r\n\r\nPacker.prototype.pack_int8 = function (num) {\r\n this.bufferBuilder.append(num & 0xff);\r\n};\r\n\r\nPacker.prototype.pack_int16 = function (num) {\r\n this.bufferBuilder.append((num & 0xff00) >> 8);\r\n this.bufferBuilder.append(num & 0xff);\r\n};\r\n\r\nPacker.prototype.pack_int32 = function (num) {\r\n this.bufferBuilder.append((num >>> 24) & 0xff);\r\n this.bufferBuilder.append((num & 0x00ff0000) >>> 16);\r\n this.bufferBuilder.append((num & 0x0000ff00) >>> 8);\r\n this.bufferBuilder.append((num & 0x000000ff));\r\n};\r\n\r\nPacker.prototype.pack_int64 = function (num) {\r\n var high = Math.floor(num / Math.pow(2, 32));\r\n var low = num % Math.pow(2, 32);\r\n this.bufferBuilder.append((high & 0xff000000) >>> 24);\r\n this.bufferBuilder.append((high & 0x00ff0000) >>> 16);\r\n this.bufferBuilder.append((high & 0x0000ff00) >>> 8);\r\n this.bufferBuilder.append((high & 0x000000ff));\r\n this.bufferBuilder.append((low & 0xff000000) >>> 24);\r\n this.bufferBuilder.append((low & 0x00ff0000) >>> 16);\r\n this.bufferBuilder.append((low & 0x0000ff00) >>> 8);\r\n this.bufferBuilder.append((low & 0x000000ff));\r\n};\r\n\r\nfunction _utf8Replace (m) {\r\n var code = m.charCodeAt(0);\r\n\r\n if (code <= 0x7ff) return '00';\r\n if (code <= 0xffff) return '000';\r\n if (code <= 0x1fffff) return '0000';\r\n if (code <= 0x3ffffff) return '00000';\r\n return '000000';\r\n}\r\n\r\nfunction utf8Length (str) {\r\n if (str.length > 600) {\r\n // Blob method faster for large strings\r\n return (new Blob([str])).size;\r\n } else {\r\n return str.replace(/[^\\u0000-\\u007F]/g, _utf8Replace).length;\r\n }\r\n}\r\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/peerjs-js-binarypack/lib/binarypack.js?");
260
-
261
- /***/ }),
262
-
263
- /***/ "./node_modules/peerjs-js-binarypack/lib/bufferbuilder.js":
264
- /*!****************************************************************!*\
265
- !*** ./node_modules/peerjs-js-binarypack/lib/bufferbuilder.js ***!
266
- \****************************************************************/
267
- /***/ (function(module) {
268
-
269
- eval("var binaryFeatures = {};\r\nbinaryFeatures.useBlobBuilder = (function () {\r\n try {\r\n new Blob([]);\r\n return false;\r\n } catch (e) {\r\n return true;\r\n }\r\n})();\r\n\r\nbinaryFeatures.useArrayBufferView = !binaryFeatures.useBlobBuilder && (function () {\r\n try {\r\n return (new Blob([new Uint8Array([])])).size === 0;\r\n } catch (e) {\r\n return true;\r\n }\r\n})();\r\n\r\nmodule.exports.binaryFeatures = binaryFeatures;\r\nvar BlobBuilder = module.exports.BlobBuilder;\r\nif (typeof window !== 'undefined') {\r\n BlobBuilder = module.exports.BlobBuilder = window.WebKitBlobBuilder ||\r\n window.MozBlobBuilder || window.MSBlobBuilder || window.BlobBuilder;\r\n}\r\n\r\nfunction BufferBuilder () {\r\n this._pieces = [];\r\n this._parts = [];\r\n}\r\n\r\nBufferBuilder.prototype.append = function (data) {\r\n if (typeof data === 'number') {\r\n this._pieces.push(data);\r\n } else {\r\n this.flush();\r\n this._parts.push(data);\r\n }\r\n};\r\n\r\nBufferBuilder.prototype.flush = function () {\r\n if (this._pieces.length > 0) {\r\n var buf = new Uint8Array(this._pieces);\r\n if (!binaryFeatures.useArrayBufferView) {\r\n buf = buf.buffer;\r\n }\r\n this._parts.push(buf);\r\n this._pieces = [];\r\n }\r\n};\r\n\r\nBufferBuilder.prototype.getBuffer = function () {\r\n this.flush();\r\n if (binaryFeatures.useBlobBuilder) {\r\n var builder = new BlobBuilder();\r\n for (var i = 0, ii = this._parts.length; i < ii; i++) {\r\n builder.append(this._parts[i]);\r\n }\r\n return builder.getBlob();\r\n } else {\r\n return new Blob(this._parts);\r\n }\r\n};\r\n\r\nmodule.exports.BufferBuilder = BufferBuilder;\r\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/peerjs-js-binarypack/lib/bufferbuilder.js?");
270
-
271
- /***/ }),
272
-
273
253
  /***/ "./node_modules/qrcode/lib/browser.js":
274
254
  /*!********************************************!*\
275
255
  !*** ./node_modules/qrcode/lib/browser.js ***!
@@ -540,28 +520,6 @@ eval("function hex2rgba (hex) {\n if (typeof hex === 'number') {\n hex = hex
540
520
 
541
521
  /***/ }),
542
522
 
543
- /***/ "./node_modules/rtcpeerconnection-shim/rtcpeerconnection.js":
544
- /*!******************************************************************!*\
545
- !*** ./node_modules/rtcpeerconnection-shim/rtcpeerconnection.js ***!
546
- \******************************************************************/
547
- /***/ (function(module, __unused_webpack_exports, __webpack_require__) {
548
-
549
- "use strict";
550
- eval("/*\n * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n\n\nvar SDPUtils = __webpack_require__(/*! sdp */ \"./node_modules/sdp/sdp.js\");\n\nfunction fixStatsType(stat) {\n return {\n inboundrtp: 'inbound-rtp',\n outboundrtp: 'outbound-rtp',\n candidatepair: 'candidate-pair',\n localcandidate: 'local-candidate',\n remotecandidate: 'remote-candidate'\n }[stat.type] || stat.type;\n}\n\nfunction writeMediaSection(transceiver, caps, type, stream, dtlsRole) {\n var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps);\n\n // Map ICE parameters (ufrag, pwd) to SDP.\n sdp += SDPUtils.writeIceParameters(\n transceiver.iceGatherer.getLocalParameters());\n\n // Map DTLS parameters to SDP.\n sdp += SDPUtils.writeDtlsParameters(\n transceiver.dtlsTransport.getLocalParameters(),\n type === 'offer' ? 'actpass' : dtlsRole || 'active');\n\n sdp += 'a=mid:' + transceiver.mid + '\\r\\n';\n\n if (transceiver.rtpSender && transceiver.rtpReceiver) {\n sdp += 'a=sendrecv\\r\\n';\n } else if (transceiver.rtpSender) {\n sdp += 'a=sendonly\\r\\n';\n } else if (transceiver.rtpReceiver) {\n sdp += 'a=recvonly\\r\\n';\n } else {\n sdp += 'a=inactive\\r\\n';\n }\n\n if (transceiver.rtpSender) {\n var trackId = transceiver.rtpSender._initialTrackId ||\n transceiver.rtpSender.track.id;\n transceiver.rtpSender._initialTrackId = trackId;\n // spec.\n var msid = 'msid:' + (stream ? stream.id : '-') + ' ' +\n trackId + '\\r\\n';\n sdp += 'a=' + msid;\n // for Chrome. Legacy should no longer be required.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' ' + msid;\n\n // RTX\n if (transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' ' + msid;\n sdp += 'a=ssrc-group:FID ' +\n transceiver.sendEncodingParameters[0].ssrc + ' ' +\n transceiver.sendEncodingParameters[0].rtx.ssrc +\n '\\r\\n';\n }\n }\n // FIXME: this should be written by writeRtpDescription.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n }\n return sdp;\n}\n\n// Edge does not like\n// 1) stun: filtered after 14393 unless ?transport=udp is present\n// 2) turn: that does not have all of turn:host:port?transport=udp\n// 3) turn: with ipv6 addresses\n// 4) turn: occurring muliple times\nfunction filterIceServers(iceServers, edgeVersion) {\n var hasTurn = false;\n iceServers = JSON.parse(JSON.stringify(iceServers));\n return iceServers.filter(function(server) {\n if (server && (server.urls || server.url)) {\n var urls = server.urls || server.url;\n if (server.url && !server.urls) {\n console.warn('RTCIceServer.url is deprecated! Use urls instead.');\n }\n var isString = typeof urls === 'string';\n if (isString) {\n urls = [urls];\n }\n urls = urls.filter(function(url) {\n var validTurn = url.indexOf('turn:') === 0 &&\n url.indexOf('transport=udp') !== -1 &&\n url.indexOf('turn:[') === -1 &&\n !hasTurn;\n\n if (validTurn) {\n hasTurn = true;\n return true;\n }\n return url.indexOf('stun:') === 0 && edgeVersion >= 14393 &&\n url.indexOf('?transport=udp') === -1;\n });\n\n delete server.url;\n server.urls = isString ? urls[0] : urls;\n return !!urls.length;\n }\n });\n}\n\n// Determines the intersection of local and remote capabilities.\nfunction getCommonCapabilities(localCapabilities, remoteCapabilities) {\n var commonCapabilities = {\n codecs: [],\n headerExtensions: [],\n fecMechanisms: []\n };\n\n var findCodecByPayloadType = function(pt, codecs) {\n pt = parseInt(pt, 10);\n for (var i = 0; i < codecs.length; i++) {\n if (codecs[i].payloadType === pt ||\n codecs[i].preferredPayloadType === pt) {\n return codecs[i];\n }\n }\n };\n\n var rtxCapabilityMatches = function(lRtx, rRtx, lCodecs, rCodecs) {\n var lCodec = findCodecByPayloadType(lRtx.parameters.apt, lCodecs);\n var rCodec = findCodecByPayloadType(rRtx.parameters.apt, rCodecs);\n return lCodec && rCodec &&\n lCodec.name.toLowerCase() === rCodec.name.toLowerCase();\n };\n\n localCapabilities.codecs.forEach(function(lCodec) {\n for (var i = 0; i < remoteCapabilities.codecs.length; i++) {\n var rCodec = remoteCapabilities.codecs[i];\n if (lCodec.name.toLowerCase() === rCodec.name.toLowerCase() &&\n lCodec.clockRate === rCodec.clockRate) {\n if (lCodec.name.toLowerCase() === 'rtx' &&\n lCodec.parameters && rCodec.parameters.apt) {\n // for RTX we need to find the local rtx that has a apt\n // which points to the same local codec as the remote one.\n if (!rtxCapabilityMatches(lCodec, rCodec,\n localCapabilities.codecs, remoteCapabilities.codecs)) {\n continue;\n }\n }\n rCodec = JSON.parse(JSON.stringify(rCodec)); // deepcopy\n // number of channels is the highest common number of channels\n rCodec.numChannels = Math.min(lCodec.numChannels,\n rCodec.numChannels);\n // push rCodec so we reply with offerer payload type\n commonCapabilities.codecs.push(rCodec);\n\n // determine common feedback mechanisms\n rCodec.rtcpFeedback = rCodec.rtcpFeedback.filter(function(fb) {\n for (var j = 0; j < lCodec.rtcpFeedback.length; j++) {\n if (lCodec.rtcpFeedback[j].type === fb.type &&\n lCodec.rtcpFeedback[j].parameter === fb.parameter) {\n return true;\n }\n }\n return false;\n });\n // FIXME: also need to determine .parameters\n // see https://github.com/openpeer/ortc/issues/569\n break;\n }\n }\n });\n\n localCapabilities.headerExtensions.forEach(function(lHeaderExtension) {\n for (var i = 0; i < remoteCapabilities.headerExtensions.length;\n i++) {\n var rHeaderExtension = remoteCapabilities.headerExtensions[i];\n if (lHeaderExtension.uri === rHeaderExtension.uri) {\n commonCapabilities.headerExtensions.push(rHeaderExtension);\n break;\n }\n }\n });\n\n // FIXME: fecMechanisms\n return commonCapabilities;\n}\n\n// is action=setLocalDescription with type allowed in signalingState\nfunction isActionAllowedInSignalingState(action, type, signalingState) {\n return {\n offer: {\n setLocalDescription: ['stable', 'have-local-offer'],\n setRemoteDescription: ['stable', 'have-remote-offer']\n },\n answer: {\n setLocalDescription: ['have-remote-offer', 'have-local-pranswer'],\n setRemoteDescription: ['have-local-offer', 'have-remote-pranswer']\n }\n }[type][action].indexOf(signalingState) !== -1;\n}\n\nfunction maybeAddCandidate(iceTransport, candidate) {\n // Edge's internal representation adds some fields therefore\n // not all fieldѕ are taken into account.\n var alreadyAdded = iceTransport.getRemoteCandidates()\n .find(function(remoteCandidate) {\n return candidate.foundation === remoteCandidate.foundation &&\n candidate.ip === remoteCandidate.ip &&\n candidate.port === remoteCandidate.port &&\n candidate.priority === remoteCandidate.priority &&\n candidate.protocol === remoteCandidate.protocol &&\n candidate.type === remoteCandidate.type;\n });\n if (!alreadyAdded) {\n iceTransport.addRemoteCandidate(candidate);\n }\n return !alreadyAdded;\n}\n\n\nfunction makeError(name, description) {\n var e = new Error(description);\n e.name = name;\n // legacy error codes from https://heycam.github.io/webidl/#idl-DOMException-error-names\n e.code = {\n NotSupportedError: 9,\n InvalidStateError: 11,\n InvalidAccessError: 15,\n TypeError: undefined,\n OperationError: undefined\n }[name];\n return e;\n}\n\nmodule.exports = function(window, edgeVersion) {\n // https://w3c.github.io/mediacapture-main/#mediastream\n // Helper function to add the track to the stream and\n // dispatch the event ourselves.\n function addTrackToStreamAndFireEvent(track, stream) {\n stream.addTrack(track);\n stream.dispatchEvent(new window.MediaStreamTrackEvent('addtrack',\n {track: track}));\n }\n\n function removeTrackFromStreamAndFireEvent(track, stream) {\n stream.removeTrack(track);\n stream.dispatchEvent(new window.MediaStreamTrackEvent('removetrack',\n {track: track}));\n }\n\n function fireAddTrack(pc, track, receiver, streams) {\n var trackEvent = new Event('track');\n trackEvent.track = track;\n trackEvent.receiver = receiver;\n trackEvent.transceiver = {receiver: receiver};\n trackEvent.streams = streams;\n window.setTimeout(function() {\n pc._dispatchEvent('track', trackEvent);\n });\n }\n\n var RTCPeerConnection = function(config) {\n var pc = this;\n\n var _eventTarget = document.createDocumentFragment();\n ['addEventListener', 'removeEventListener', 'dispatchEvent']\n .forEach(function(method) {\n pc[method] = _eventTarget[method].bind(_eventTarget);\n });\n\n this.canTrickleIceCandidates = null;\n\n this.needNegotiation = false;\n\n this.localStreams = [];\n this.remoteStreams = [];\n\n this._localDescription = null;\n this._remoteDescription = null;\n\n this.signalingState = 'stable';\n this.iceConnectionState = 'new';\n this.connectionState = 'new';\n this.iceGatheringState = 'new';\n\n config = JSON.parse(JSON.stringify(config || {}));\n\n this.usingBundle = config.bundlePolicy === 'max-bundle';\n if (config.rtcpMuxPolicy === 'negotiate') {\n throw(makeError('NotSupportedError',\n 'rtcpMuxPolicy \\'negotiate\\' is not supported'));\n } else if (!config.rtcpMuxPolicy) {\n config.rtcpMuxPolicy = 'require';\n }\n\n switch (config.iceTransportPolicy) {\n case 'all':\n case 'relay':\n break;\n default:\n config.iceTransportPolicy = 'all';\n break;\n }\n\n switch (config.bundlePolicy) {\n case 'balanced':\n case 'max-compat':\n case 'max-bundle':\n break;\n default:\n config.bundlePolicy = 'balanced';\n break;\n }\n\n config.iceServers = filterIceServers(config.iceServers || [], edgeVersion);\n\n this._iceGatherers = [];\n if (config.iceCandidatePoolSize) {\n for (var i = config.iceCandidatePoolSize; i > 0; i--) {\n this._iceGatherers.push(new window.RTCIceGatherer({\n iceServers: config.iceServers,\n gatherPolicy: config.iceTransportPolicy\n }));\n }\n } else {\n config.iceCandidatePoolSize = 0;\n }\n\n this._config = config;\n\n // per-track iceGathers, iceTransports, dtlsTransports, rtpSenders, ...\n // everything that is needed to describe a SDP m-line.\n this.transceivers = [];\n\n this._sdpSessionId = SDPUtils.generateSessionId();\n this._sdpSessionVersion = 0;\n\n this._dtlsRole = undefined; // role for a=setup to use in answers.\n\n this._isClosed = false;\n };\n\n Object.defineProperty(RTCPeerConnection.prototype, 'localDescription', {\n configurable: true,\n get: function() {\n return this._localDescription;\n }\n });\n Object.defineProperty(RTCPeerConnection.prototype, 'remoteDescription', {\n configurable: true,\n get: function() {\n return this._remoteDescription;\n }\n });\n\n // set up event handlers on prototype\n RTCPeerConnection.prototype.onicecandidate = null;\n RTCPeerConnection.prototype.onaddstream = null;\n RTCPeerConnection.prototype.ontrack = null;\n RTCPeerConnection.prototype.onremovestream = null;\n RTCPeerConnection.prototype.onsignalingstatechange = null;\n RTCPeerConnection.prototype.oniceconnectionstatechange = null;\n RTCPeerConnection.prototype.onconnectionstatechange = null;\n RTCPeerConnection.prototype.onicegatheringstatechange = null;\n RTCPeerConnection.prototype.onnegotiationneeded = null;\n RTCPeerConnection.prototype.ondatachannel = null;\n\n RTCPeerConnection.prototype._dispatchEvent = function(name, event) {\n if (this._isClosed) {\n return;\n }\n this.dispatchEvent(event);\n if (typeof this['on' + name] === 'function') {\n this['on' + name](event);\n }\n };\n\n RTCPeerConnection.prototype._emitGatheringStateChange = function() {\n var event = new Event('icegatheringstatechange');\n this._dispatchEvent('icegatheringstatechange', event);\n };\n\n RTCPeerConnection.prototype.getConfiguration = function() {\n return this._config;\n };\n\n RTCPeerConnection.prototype.getLocalStreams = function() {\n return this.localStreams;\n };\n\n RTCPeerConnection.prototype.getRemoteStreams = function() {\n return this.remoteStreams;\n };\n\n // internal helper to create a transceiver object.\n // (which is not yet the same as the WebRTC 1.0 transceiver)\n RTCPeerConnection.prototype._createTransceiver = function(kind, doNotAdd) {\n var hasBundleTransport = this.transceivers.length > 0;\n var transceiver = {\n track: null,\n iceGatherer: null,\n iceTransport: null,\n dtlsTransport: null,\n localCapabilities: null,\n remoteCapabilities: null,\n rtpSender: null,\n rtpReceiver: null,\n kind: kind,\n mid: null,\n sendEncodingParameters: null,\n recvEncodingParameters: null,\n stream: null,\n associatedRemoteMediaStreams: [],\n wantReceive: true\n };\n if (this.usingBundle && hasBundleTransport) {\n transceiver.iceTransport = this.transceivers[0].iceTransport;\n transceiver.dtlsTransport = this.transceivers[0].dtlsTransport;\n } else {\n var transports = this._createIceAndDtlsTransports();\n transceiver.iceTransport = transports.iceTransport;\n transceiver.dtlsTransport = transports.dtlsTransport;\n }\n if (!doNotAdd) {\n this.transceivers.push(transceiver);\n }\n return transceiver;\n };\n\n RTCPeerConnection.prototype.addTrack = function(track, stream) {\n if (this._isClosed) {\n throw makeError('InvalidStateError',\n 'Attempted to call addTrack on a closed peerconnection.');\n }\n\n var alreadyExists = this.transceivers.find(function(s) {\n return s.track === track;\n });\n\n if (alreadyExists) {\n throw makeError('InvalidAccessError', 'Track already exists.');\n }\n\n var transceiver;\n for (var i = 0; i < this.transceivers.length; i++) {\n if (!this.transceivers[i].track &&\n this.transceivers[i].kind === track.kind) {\n transceiver = this.transceivers[i];\n }\n }\n if (!transceiver) {\n transceiver = this._createTransceiver(track.kind);\n }\n\n this._maybeFireNegotiationNeeded();\n\n if (this.localStreams.indexOf(stream) === -1) {\n this.localStreams.push(stream);\n }\n\n transceiver.track = track;\n transceiver.stream = stream;\n transceiver.rtpSender = new window.RTCRtpSender(track,\n transceiver.dtlsTransport);\n return transceiver.rtpSender;\n };\n\n RTCPeerConnection.prototype.addStream = function(stream) {\n var pc = this;\n if (edgeVersion >= 15025) {\n stream.getTracks().forEach(function(track) {\n pc.addTrack(track, stream);\n });\n } else {\n // Clone is necessary for local demos mostly, attaching directly\n // to two different senders does not work (build 10547).\n // Fixed in 15025 (or earlier)\n var clonedStream = stream.clone();\n stream.getTracks().forEach(function(track, idx) {\n var clonedTrack = clonedStream.getTracks()[idx];\n track.addEventListener('enabled', function(event) {\n clonedTrack.enabled = event.enabled;\n });\n });\n clonedStream.getTracks().forEach(function(track) {\n pc.addTrack(track, clonedStream);\n });\n }\n };\n\n RTCPeerConnection.prototype.removeTrack = function(sender) {\n if (this._isClosed) {\n throw makeError('InvalidStateError',\n 'Attempted to call removeTrack on a closed peerconnection.');\n }\n\n if (!(sender instanceof window.RTCRtpSender)) {\n throw new TypeError('Argument 1 of RTCPeerConnection.removeTrack ' +\n 'does not implement interface RTCRtpSender.');\n }\n\n var transceiver = this.transceivers.find(function(t) {\n return t.rtpSender === sender;\n });\n\n if (!transceiver) {\n throw makeError('InvalidAccessError',\n 'Sender was not created by this connection.');\n }\n var stream = transceiver.stream;\n\n transceiver.rtpSender.stop();\n transceiver.rtpSender = null;\n transceiver.track = null;\n transceiver.stream = null;\n\n // remove the stream from the set of local streams\n var localStreams = this.transceivers.map(function(t) {\n return t.stream;\n });\n if (localStreams.indexOf(stream) === -1 &&\n this.localStreams.indexOf(stream) > -1) {\n this.localStreams.splice(this.localStreams.indexOf(stream), 1);\n }\n\n this._maybeFireNegotiationNeeded();\n };\n\n RTCPeerConnection.prototype.removeStream = function(stream) {\n var pc = this;\n stream.getTracks().forEach(function(track) {\n var sender = pc.getSenders().find(function(s) {\n return s.track === track;\n });\n if (sender) {\n pc.removeTrack(sender);\n }\n });\n };\n\n RTCPeerConnection.prototype.getSenders = function() {\n return this.transceivers.filter(function(transceiver) {\n return !!transceiver.rtpSender;\n })\n .map(function(transceiver) {\n return transceiver.rtpSender;\n });\n };\n\n RTCPeerConnection.prototype.getReceivers = function() {\n return this.transceivers.filter(function(transceiver) {\n return !!transceiver.rtpReceiver;\n })\n .map(function(transceiver) {\n return transceiver.rtpReceiver;\n });\n };\n\n\n RTCPeerConnection.prototype._createIceGatherer = function(sdpMLineIndex,\n usingBundle) {\n var pc = this;\n if (usingBundle && sdpMLineIndex > 0) {\n return this.transceivers[0].iceGatherer;\n } else if (this._iceGatherers.length) {\n return this._iceGatherers.shift();\n }\n var iceGatherer = new window.RTCIceGatherer({\n iceServers: this._config.iceServers,\n gatherPolicy: this._config.iceTransportPolicy\n });\n Object.defineProperty(iceGatherer, 'state',\n {value: 'new', writable: true}\n );\n\n this.transceivers[sdpMLineIndex].bufferedCandidateEvents = [];\n this.transceivers[sdpMLineIndex].bufferCandidates = function(event) {\n var end = !event.candidate || Object.keys(event.candidate).length === 0;\n // polyfill since RTCIceGatherer.state is not implemented in\n // Edge 10547 yet.\n iceGatherer.state = end ? 'completed' : 'gathering';\n if (pc.transceivers[sdpMLineIndex].bufferedCandidateEvents !== null) {\n pc.transceivers[sdpMLineIndex].bufferedCandidateEvents.push(event);\n }\n };\n iceGatherer.addEventListener('localcandidate',\n this.transceivers[sdpMLineIndex].bufferCandidates);\n return iceGatherer;\n };\n\n // start gathering from an RTCIceGatherer.\n RTCPeerConnection.prototype._gather = function(mid, sdpMLineIndex) {\n var pc = this;\n var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer;\n if (iceGatherer.onlocalcandidate) {\n return;\n }\n var bufferedCandidateEvents =\n this.transceivers[sdpMLineIndex].bufferedCandidateEvents;\n this.transceivers[sdpMLineIndex].bufferedCandidateEvents = null;\n iceGatherer.removeEventListener('localcandidate',\n this.transceivers[sdpMLineIndex].bufferCandidates);\n iceGatherer.onlocalcandidate = function(evt) {\n if (pc.usingBundle && sdpMLineIndex > 0) {\n // if we know that we use bundle we can drop candidates with\n // ѕdpMLineIndex > 0. If we don't do this then our state gets\n // confused since we dispose the extra ice gatherer.\n return;\n }\n var event = new Event('icecandidate');\n event.candidate = {sdpMid: mid, sdpMLineIndex: sdpMLineIndex};\n\n var cand = evt.candidate;\n // Edge emits an empty object for RTCIceCandidateComplete‥\n var end = !cand || Object.keys(cand).length === 0;\n if (end) {\n // polyfill since RTCIceGatherer.state is not implemented in\n // Edge 10547 yet.\n if (iceGatherer.state === 'new' || iceGatherer.state === 'gathering') {\n iceGatherer.state = 'completed';\n }\n } else {\n if (iceGatherer.state === 'new') {\n iceGatherer.state = 'gathering';\n }\n // RTCIceCandidate doesn't have a component, needs to be added\n cand.component = 1;\n // also the usernameFragment. TODO: update SDP to take both variants.\n cand.ufrag = iceGatherer.getLocalParameters().usernameFragment;\n\n var serializedCandidate = SDPUtils.writeCandidate(cand);\n event.candidate = Object.assign(event.candidate,\n SDPUtils.parseCandidate(serializedCandidate));\n\n event.candidate.candidate = serializedCandidate;\n event.candidate.toJSON = function() {\n return {\n candidate: event.candidate.candidate,\n sdpMid: event.candidate.sdpMid,\n sdpMLineIndex: event.candidate.sdpMLineIndex,\n usernameFragment: event.candidate.usernameFragment\n };\n };\n }\n\n // update local description.\n var sections = SDPUtils.getMediaSections(pc._localDescription.sdp);\n if (!end) {\n sections[event.candidate.sdpMLineIndex] +=\n 'a=' + event.candidate.candidate + '\\r\\n';\n } else {\n sections[event.candidate.sdpMLineIndex] +=\n 'a=end-of-candidates\\r\\n';\n }\n pc._localDescription.sdp =\n SDPUtils.getDescription(pc._localDescription.sdp) +\n sections.join('');\n var complete = pc.transceivers.every(function(transceiver) {\n return transceiver.iceGatherer &&\n transceiver.iceGatherer.state === 'completed';\n });\n\n if (pc.iceGatheringState !== 'gathering') {\n pc.iceGatheringState = 'gathering';\n pc._emitGatheringStateChange();\n }\n\n // Emit candidate. Also emit null candidate when all gatherers are\n // complete.\n if (!end) {\n pc._dispatchEvent('icecandidate', event);\n }\n if (complete) {\n pc._dispatchEvent('icecandidate', new Event('icecandidate'));\n pc.iceGatheringState = 'complete';\n pc._emitGatheringStateChange();\n }\n };\n\n // emit already gathered candidates.\n window.setTimeout(function() {\n bufferedCandidateEvents.forEach(function(e) {\n iceGatherer.onlocalcandidate(e);\n });\n }, 0);\n };\n\n // Create ICE transport and DTLS transport.\n RTCPeerConnection.prototype._createIceAndDtlsTransports = function() {\n var pc = this;\n var iceTransport = new window.RTCIceTransport(null);\n iceTransport.onicestatechange = function() {\n pc._updateIceConnectionState();\n pc._updateConnectionState();\n };\n\n var dtlsTransport = new window.RTCDtlsTransport(iceTransport);\n dtlsTransport.ondtlsstatechange = function() {\n pc._updateConnectionState();\n };\n dtlsTransport.onerror = function() {\n // onerror does not set state to failed by itself.\n Object.defineProperty(dtlsTransport, 'state',\n {value: 'failed', writable: true});\n pc._updateConnectionState();\n };\n\n return {\n iceTransport: iceTransport,\n dtlsTransport: dtlsTransport\n };\n };\n\n // Destroy ICE gatherer, ICE transport and DTLS transport.\n // Without triggering the callbacks.\n RTCPeerConnection.prototype._disposeIceAndDtlsTransports = function(\n sdpMLineIndex) {\n var iceGatherer = this.transceivers[sdpMLineIndex].iceGatherer;\n if (iceGatherer) {\n delete iceGatherer.onlocalcandidate;\n delete this.transceivers[sdpMLineIndex].iceGatherer;\n }\n var iceTransport = this.transceivers[sdpMLineIndex].iceTransport;\n if (iceTransport) {\n delete iceTransport.onicestatechange;\n delete this.transceivers[sdpMLineIndex].iceTransport;\n }\n var dtlsTransport = this.transceivers[sdpMLineIndex].dtlsTransport;\n if (dtlsTransport) {\n delete dtlsTransport.ondtlsstatechange;\n delete dtlsTransport.onerror;\n delete this.transceivers[sdpMLineIndex].dtlsTransport;\n }\n };\n\n // Start the RTP Sender and Receiver for a transceiver.\n RTCPeerConnection.prototype._transceive = function(transceiver,\n send, recv) {\n var params = getCommonCapabilities(transceiver.localCapabilities,\n transceiver.remoteCapabilities);\n if (send && transceiver.rtpSender) {\n params.encodings = transceiver.sendEncodingParameters;\n params.rtcp = {\n cname: SDPUtils.localCName,\n compound: transceiver.rtcpParameters.compound\n };\n if (transceiver.recvEncodingParameters.length) {\n params.rtcp.ssrc = transceiver.recvEncodingParameters[0].ssrc;\n }\n transceiver.rtpSender.send(params);\n }\n if (recv && transceiver.rtpReceiver && params.codecs.length > 0) {\n // remove RTX field in Edge 14942\n if (transceiver.kind === 'video'\n && transceiver.recvEncodingParameters\n && edgeVersion < 15019) {\n transceiver.recvEncodingParameters.forEach(function(p) {\n delete p.rtx;\n });\n }\n if (transceiver.recvEncodingParameters.length) {\n params.encodings = transceiver.recvEncodingParameters;\n } else {\n params.encodings = [{}];\n }\n params.rtcp = {\n compound: transceiver.rtcpParameters.compound\n };\n if (transceiver.rtcpParameters.cname) {\n params.rtcp.cname = transceiver.rtcpParameters.cname;\n }\n if (transceiver.sendEncodingParameters.length) {\n params.rtcp.ssrc = transceiver.sendEncodingParameters[0].ssrc;\n }\n transceiver.rtpReceiver.receive(params);\n }\n };\n\n RTCPeerConnection.prototype.setLocalDescription = function(description) {\n var pc = this;\n\n // Note: pranswer is not supported.\n if (['offer', 'answer'].indexOf(description.type) === -1) {\n return Promise.reject(makeError('TypeError',\n 'Unsupported type \"' + description.type + '\"'));\n }\n\n if (!isActionAllowedInSignalingState('setLocalDescription',\n description.type, pc.signalingState) || pc._isClosed) {\n return Promise.reject(makeError('InvalidStateError',\n 'Can not set local ' + description.type +\n ' in state ' + pc.signalingState));\n }\n\n var sections;\n var sessionpart;\n if (description.type === 'offer') {\n // VERY limited support for SDP munging. Limited to:\n // * changing the order of codecs\n sections = SDPUtils.splitSections(description.sdp);\n sessionpart = sections.shift();\n sections.forEach(function(mediaSection, sdpMLineIndex) {\n var caps = SDPUtils.parseRtpParameters(mediaSection);\n pc.transceivers[sdpMLineIndex].localCapabilities = caps;\n });\n\n pc.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n pc._gather(transceiver.mid, sdpMLineIndex);\n });\n } else if (description.type === 'answer') {\n sections = SDPUtils.splitSections(pc._remoteDescription.sdp);\n sessionpart = sections.shift();\n var isIceLite = SDPUtils.matchPrefix(sessionpart,\n 'a=ice-lite').length > 0;\n sections.forEach(function(mediaSection, sdpMLineIndex) {\n var transceiver = pc.transceivers[sdpMLineIndex];\n var iceGatherer = transceiver.iceGatherer;\n var iceTransport = transceiver.iceTransport;\n var dtlsTransport = transceiver.dtlsTransport;\n var localCapabilities = transceiver.localCapabilities;\n var remoteCapabilities = transceiver.remoteCapabilities;\n\n // treat bundle-only as not-rejected.\n var rejected = SDPUtils.isRejected(mediaSection) &&\n SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 0;\n\n if (!rejected && !transceiver.rejected) {\n var remoteIceParameters = SDPUtils.getIceParameters(\n mediaSection, sessionpart);\n var remoteDtlsParameters = SDPUtils.getDtlsParameters(\n mediaSection, sessionpart);\n if (isIceLite) {\n remoteDtlsParameters.role = 'server';\n }\n\n if (!pc.usingBundle || sdpMLineIndex === 0) {\n pc._gather(transceiver.mid, sdpMLineIndex);\n if (iceTransport.state === 'new') {\n iceTransport.start(iceGatherer, remoteIceParameters,\n isIceLite ? 'controlling' : 'controlled');\n }\n if (dtlsTransport.state === 'new') {\n dtlsTransport.start(remoteDtlsParameters);\n }\n }\n\n // Calculate intersection of capabilities.\n var params = getCommonCapabilities(localCapabilities,\n remoteCapabilities);\n\n // Start the RTCRtpSender. The RTCRtpReceiver for this\n // transceiver has already been started in setRemoteDescription.\n pc._transceive(transceiver,\n params.codecs.length > 0,\n false);\n }\n });\n }\n\n pc._localDescription = {\n type: description.type,\n sdp: description.sdp\n };\n if (description.type === 'offer') {\n pc._updateSignalingState('have-local-offer');\n } else {\n pc._updateSignalingState('stable');\n }\n\n return Promise.resolve();\n };\n\n RTCPeerConnection.prototype.setRemoteDescription = function(description) {\n var pc = this;\n\n // Note: pranswer is not supported.\n if (['offer', 'answer'].indexOf(description.type) === -1) {\n return Promise.reject(makeError('TypeError',\n 'Unsupported type \"' + description.type + '\"'));\n }\n\n if (!isActionAllowedInSignalingState('setRemoteDescription',\n description.type, pc.signalingState) || pc._isClosed) {\n return Promise.reject(makeError('InvalidStateError',\n 'Can not set remote ' + description.type +\n ' in state ' + pc.signalingState));\n }\n\n var streams = {};\n pc.remoteStreams.forEach(function(stream) {\n streams[stream.id] = stream;\n });\n var receiverList = [];\n var sections = SDPUtils.splitSections(description.sdp);\n var sessionpart = sections.shift();\n var isIceLite = SDPUtils.matchPrefix(sessionpart,\n 'a=ice-lite').length > 0;\n var usingBundle = SDPUtils.matchPrefix(sessionpart,\n 'a=group:BUNDLE ').length > 0;\n pc.usingBundle = usingBundle;\n var iceOptions = SDPUtils.matchPrefix(sessionpart,\n 'a=ice-options:')[0];\n if (iceOptions) {\n pc.canTrickleIceCandidates = iceOptions.substr(14).split(' ')\n .indexOf('trickle') >= 0;\n } else {\n pc.canTrickleIceCandidates = false;\n }\n\n sections.forEach(function(mediaSection, sdpMLineIndex) {\n var lines = SDPUtils.splitLines(mediaSection);\n var kind = SDPUtils.getKind(mediaSection);\n // treat bundle-only as not-rejected.\n var rejected = SDPUtils.isRejected(mediaSection) &&\n SDPUtils.matchPrefix(mediaSection, 'a=bundle-only').length === 0;\n var protocol = lines[0].substr(2).split(' ')[2];\n\n var direction = SDPUtils.getDirection(mediaSection, sessionpart);\n var remoteMsid = SDPUtils.parseMsid(mediaSection);\n\n var mid = SDPUtils.getMid(mediaSection) || SDPUtils.generateIdentifier();\n\n // Reject datachannels which are not implemented yet.\n if (rejected || (kind === 'application' && (protocol === 'DTLS/SCTP' ||\n protocol === 'UDP/DTLS/SCTP'))) {\n // TODO: this is dangerous in the case where a non-rejected m-line\n // becomes rejected.\n pc.transceivers[sdpMLineIndex] = {\n mid: mid,\n kind: kind,\n protocol: protocol,\n rejected: true\n };\n return;\n }\n\n if (!rejected && pc.transceivers[sdpMLineIndex] &&\n pc.transceivers[sdpMLineIndex].rejected) {\n // recycle a rejected transceiver.\n pc.transceivers[sdpMLineIndex] = pc._createTransceiver(kind, true);\n }\n\n var transceiver;\n var iceGatherer;\n var iceTransport;\n var dtlsTransport;\n var rtpReceiver;\n var sendEncodingParameters;\n var recvEncodingParameters;\n var localCapabilities;\n\n var track;\n // FIXME: ensure the mediaSection has rtcp-mux set.\n var remoteCapabilities = SDPUtils.parseRtpParameters(mediaSection);\n var remoteIceParameters;\n var remoteDtlsParameters;\n if (!rejected) {\n remoteIceParameters = SDPUtils.getIceParameters(mediaSection,\n sessionpart);\n remoteDtlsParameters = SDPUtils.getDtlsParameters(mediaSection,\n sessionpart);\n remoteDtlsParameters.role = 'client';\n }\n recvEncodingParameters =\n SDPUtils.parseRtpEncodingParameters(mediaSection);\n\n var rtcpParameters = SDPUtils.parseRtcpParameters(mediaSection);\n\n var isComplete = SDPUtils.matchPrefix(mediaSection,\n 'a=end-of-candidates', sessionpart).length > 0;\n var cands = SDPUtils.matchPrefix(mediaSection, 'a=candidate:')\n .map(function(cand) {\n return SDPUtils.parseCandidate(cand);\n })\n .filter(function(cand) {\n return cand.component === 1;\n });\n\n // Check if we can use BUNDLE and dispose transports.\n if ((description.type === 'offer' || description.type === 'answer') &&\n !rejected && usingBundle && sdpMLineIndex > 0 &&\n pc.transceivers[sdpMLineIndex]) {\n pc._disposeIceAndDtlsTransports(sdpMLineIndex);\n pc.transceivers[sdpMLineIndex].iceGatherer =\n pc.transceivers[0].iceGatherer;\n pc.transceivers[sdpMLineIndex].iceTransport =\n pc.transceivers[0].iceTransport;\n pc.transceivers[sdpMLineIndex].dtlsTransport =\n pc.transceivers[0].dtlsTransport;\n if (pc.transceivers[sdpMLineIndex].rtpSender) {\n pc.transceivers[sdpMLineIndex].rtpSender.setTransport(\n pc.transceivers[0].dtlsTransport);\n }\n if (pc.transceivers[sdpMLineIndex].rtpReceiver) {\n pc.transceivers[sdpMLineIndex].rtpReceiver.setTransport(\n pc.transceivers[0].dtlsTransport);\n }\n }\n if (description.type === 'offer' && !rejected) {\n transceiver = pc.transceivers[sdpMLineIndex] ||\n pc._createTransceiver(kind);\n transceiver.mid = mid;\n\n if (!transceiver.iceGatherer) {\n transceiver.iceGatherer = pc._createIceGatherer(sdpMLineIndex,\n usingBundle);\n }\n\n if (cands.length && transceiver.iceTransport.state === 'new') {\n if (isComplete && (!usingBundle || sdpMLineIndex === 0)) {\n transceiver.iceTransport.setRemoteCandidates(cands);\n } else {\n cands.forEach(function(candidate) {\n maybeAddCandidate(transceiver.iceTransport, candidate);\n });\n }\n }\n\n localCapabilities = window.RTCRtpReceiver.getCapabilities(kind);\n\n // filter RTX until additional stuff needed for RTX is implemented\n // in adapter.js\n if (edgeVersion < 15019) {\n localCapabilities.codecs = localCapabilities.codecs.filter(\n function(codec) {\n return codec.name !== 'rtx';\n });\n }\n\n sendEncodingParameters = transceiver.sendEncodingParameters || [{\n ssrc: (2 * sdpMLineIndex + 2) * 1001\n }];\n\n // TODO: rewrite to use http://w3c.github.io/webrtc-pc/#set-associated-remote-streams\n var isNewTrack = false;\n if (direction === 'sendrecv' || direction === 'sendonly') {\n isNewTrack = !transceiver.rtpReceiver;\n rtpReceiver = transceiver.rtpReceiver ||\n new window.RTCRtpReceiver(transceiver.dtlsTransport, kind);\n\n if (isNewTrack) {\n var stream;\n track = rtpReceiver.track;\n // FIXME: does not work with Plan B.\n if (remoteMsid && remoteMsid.stream === '-') {\n // no-op. a stream id of '-' means: no associated stream.\n } else if (remoteMsid) {\n if (!streams[remoteMsid.stream]) {\n streams[remoteMsid.stream] = new window.MediaStream();\n Object.defineProperty(streams[remoteMsid.stream], 'id', {\n get: function() {\n return remoteMsid.stream;\n }\n });\n }\n Object.defineProperty(track, 'id', {\n get: function() {\n return remoteMsid.track;\n }\n });\n stream = streams[remoteMsid.stream];\n } else {\n if (!streams.default) {\n streams.default = new window.MediaStream();\n }\n stream = streams.default;\n }\n if (stream) {\n addTrackToStreamAndFireEvent(track, stream);\n transceiver.associatedRemoteMediaStreams.push(stream);\n }\n receiverList.push([track, rtpReceiver, stream]);\n }\n } else if (transceiver.rtpReceiver && transceiver.rtpReceiver.track) {\n transceiver.associatedRemoteMediaStreams.forEach(function(s) {\n var nativeTrack = s.getTracks().find(function(t) {\n return t.id === transceiver.rtpReceiver.track.id;\n });\n if (nativeTrack) {\n removeTrackFromStreamAndFireEvent(nativeTrack, s);\n }\n });\n transceiver.associatedRemoteMediaStreams = [];\n }\n\n transceiver.localCapabilities = localCapabilities;\n transceiver.remoteCapabilities = remoteCapabilities;\n transceiver.rtpReceiver = rtpReceiver;\n transceiver.rtcpParameters = rtcpParameters;\n transceiver.sendEncodingParameters = sendEncodingParameters;\n transceiver.recvEncodingParameters = recvEncodingParameters;\n\n // Start the RTCRtpReceiver now. The RTPSender is started in\n // setLocalDescription.\n pc._transceive(pc.transceivers[sdpMLineIndex],\n false,\n isNewTrack);\n } else if (description.type === 'answer' && !rejected) {\n transceiver = pc.transceivers[sdpMLineIndex];\n iceGatherer = transceiver.iceGatherer;\n iceTransport = transceiver.iceTransport;\n dtlsTransport = transceiver.dtlsTransport;\n rtpReceiver = transceiver.rtpReceiver;\n sendEncodingParameters = transceiver.sendEncodingParameters;\n localCapabilities = transceiver.localCapabilities;\n\n pc.transceivers[sdpMLineIndex].recvEncodingParameters =\n recvEncodingParameters;\n pc.transceivers[sdpMLineIndex].remoteCapabilities =\n remoteCapabilities;\n pc.transceivers[sdpMLineIndex].rtcpParameters = rtcpParameters;\n\n if (cands.length && iceTransport.state === 'new') {\n if ((isIceLite || isComplete) &&\n (!usingBundle || sdpMLineIndex === 0)) {\n iceTransport.setRemoteCandidates(cands);\n } else {\n cands.forEach(function(candidate) {\n maybeAddCandidate(transceiver.iceTransport, candidate);\n });\n }\n }\n\n if (!usingBundle || sdpMLineIndex === 0) {\n if (iceTransport.state === 'new') {\n iceTransport.start(iceGatherer, remoteIceParameters,\n 'controlling');\n }\n if (dtlsTransport.state === 'new') {\n dtlsTransport.start(remoteDtlsParameters);\n }\n }\n\n // If the offer contained RTX but the answer did not,\n // remove RTX from sendEncodingParameters.\n var commonCapabilities = getCommonCapabilities(\n transceiver.localCapabilities,\n transceiver.remoteCapabilities);\n\n var hasRtx = commonCapabilities.codecs.filter(function(c) {\n return c.name.toLowerCase() === 'rtx';\n }).length;\n if (!hasRtx && transceiver.sendEncodingParameters[0].rtx) {\n delete transceiver.sendEncodingParameters[0].rtx;\n }\n\n pc._transceive(transceiver,\n direction === 'sendrecv' || direction === 'recvonly',\n direction === 'sendrecv' || direction === 'sendonly');\n\n // TODO: rewrite to use http://w3c.github.io/webrtc-pc/#set-associated-remote-streams\n if (rtpReceiver &&\n (direction === 'sendrecv' || direction === 'sendonly')) {\n track = rtpReceiver.track;\n if (remoteMsid) {\n if (!streams[remoteMsid.stream]) {\n streams[remoteMsid.stream] = new window.MediaStream();\n }\n addTrackToStreamAndFireEvent(track, streams[remoteMsid.stream]);\n receiverList.push([track, rtpReceiver, streams[remoteMsid.stream]]);\n } else {\n if (!streams.default) {\n streams.default = new window.MediaStream();\n }\n addTrackToStreamAndFireEvent(track, streams.default);\n receiverList.push([track, rtpReceiver, streams.default]);\n }\n } else {\n // FIXME: actually the receiver should be created later.\n delete transceiver.rtpReceiver;\n }\n }\n });\n\n if (pc._dtlsRole === undefined) {\n pc._dtlsRole = description.type === 'offer' ? 'active' : 'passive';\n }\n\n pc._remoteDescription = {\n type: description.type,\n sdp: description.sdp\n };\n if (description.type === 'offer') {\n pc._updateSignalingState('have-remote-offer');\n } else {\n pc._updateSignalingState('stable');\n }\n Object.keys(streams).forEach(function(sid) {\n var stream = streams[sid];\n if (stream.getTracks().length) {\n if (pc.remoteStreams.indexOf(stream) === -1) {\n pc.remoteStreams.push(stream);\n var event = new Event('addstream');\n event.stream = stream;\n window.setTimeout(function() {\n pc._dispatchEvent('addstream', event);\n });\n }\n\n receiverList.forEach(function(item) {\n var track = item[0];\n var receiver = item[1];\n if (stream.id !== item[2].id) {\n return;\n }\n fireAddTrack(pc, track, receiver, [stream]);\n });\n }\n });\n receiverList.forEach(function(item) {\n if (item[2]) {\n return;\n }\n fireAddTrack(pc, item[0], item[1], []);\n });\n\n // check whether addIceCandidate({}) was called within four seconds after\n // setRemoteDescription.\n window.setTimeout(function() {\n if (!(pc && pc.transceivers)) {\n return;\n }\n pc.transceivers.forEach(function(transceiver) {\n if (transceiver.iceTransport &&\n transceiver.iceTransport.state === 'new' &&\n transceiver.iceTransport.getRemoteCandidates().length > 0) {\n console.warn('Timeout for addRemoteCandidate. Consider sending ' +\n 'an end-of-candidates notification');\n transceiver.iceTransport.addRemoteCandidate({});\n }\n });\n }, 4000);\n\n return Promise.resolve();\n };\n\n RTCPeerConnection.prototype.close = function() {\n this.transceivers.forEach(function(transceiver) {\n /* not yet\n if (transceiver.iceGatherer) {\n transceiver.iceGatherer.close();\n }\n */\n if (transceiver.iceTransport) {\n transceiver.iceTransport.stop();\n }\n if (transceiver.dtlsTransport) {\n transceiver.dtlsTransport.stop();\n }\n if (transceiver.rtpSender) {\n transceiver.rtpSender.stop();\n }\n if (transceiver.rtpReceiver) {\n transceiver.rtpReceiver.stop();\n }\n });\n // FIXME: clean up tracks, local streams, remote streams, etc\n this._isClosed = true;\n this._updateSignalingState('closed');\n };\n\n // Update the signaling state.\n RTCPeerConnection.prototype._updateSignalingState = function(newState) {\n this.signalingState = newState;\n var event = new Event('signalingstatechange');\n this._dispatchEvent('signalingstatechange', event);\n };\n\n // Determine whether to fire the negotiationneeded event.\n RTCPeerConnection.prototype._maybeFireNegotiationNeeded = function() {\n var pc = this;\n if (this.signalingState !== 'stable' || this.needNegotiation === true) {\n return;\n }\n this.needNegotiation = true;\n window.setTimeout(function() {\n if (pc.needNegotiation) {\n pc.needNegotiation = false;\n var event = new Event('negotiationneeded');\n pc._dispatchEvent('negotiationneeded', event);\n }\n }, 0);\n };\n\n // Update the ice connection state.\n RTCPeerConnection.prototype._updateIceConnectionState = function() {\n var newState;\n var states = {\n 'new': 0,\n closed: 0,\n checking: 0,\n connected: 0,\n completed: 0,\n disconnected: 0,\n failed: 0\n };\n this.transceivers.forEach(function(transceiver) {\n if (transceiver.iceTransport && !transceiver.rejected) {\n states[transceiver.iceTransport.state]++;\n }\n });\n\n newState = 'new';\n if (states.failed > 0) {\n newState = 'failed';\n } else if (states.checking > 0) {\n newState = 'checking';\n } else if (states.disconnected > 0) {\n newState = 'disconnected';\n } else if (states.new > 0) {\n newState = 'new';\n } else if (states.connected > 0) {\n newState = 'connected';\n } else if (states.completed > 0) {\n newState = 'completed';\n }\n\n if (newState !== this.iceConnectionState) {\n this.iceConnectionState = newState;\n var event = new Event('iceconnectionstatechange');\n this._dispatchEvent('iceconnectionstatechange', event);\n }\n };\n\n // Update the connection state.\n RTCPeerConnection.prototype._updateConnectionState = function() {\n var newState;\n var states = {\n 'new': 0,\n closed: 0,\n connecting: 0,\n connected: 0,\n completed: 0,\n disconnected: 0,\n failed: 0\n };\n this.transceivers.forEach(function(transceiver) {\n if (transceiver.iceTransport && transceiver.dtlsTransport &&\n !transceiver.rejected) {\n states[transceiver.iceTransport.state]++;\n states[transceiver.dtlsTransport.state]++;\n }\n });\n // ICETransport.completed and connected are the same for this purpose.\n states.connected += states.completed;\n\n newState = 'new';\n if (states.failed > 0) {\n newState = 'failed';\n } else if (states.connecting > 0) {\n newState = 'connecting';\n } else if (states.disconnected > 0) {\n newState = 'disconnected';\n } else if (states.new > 0) {\n newState = 'new';\n } else if (states.connected > 0) {\n newState = 'connected';\n }\n\n if (newState !== this.connectionState) {\n this.connectionState = newState;\n var event = new Event('connectionstatechange');\n this._dispatchEvent('connectionstatechange', event);\n }\n };\n\n RTCPeerConnection.prototype.createOffer = function() {\n var pc = this;\n\n if (pc._isClosed) {\n return Promise.reject(makeError('InvalidStateError',\n 'Can not call createOffer after close'));\n }\n\n var numAudioTracks = pc.transceivers.filter(function(t) {\n return t.kind === 'audio';\n }).length;\n var numVideoTracks = pc.transceivers.filter(function(t) {\n return t.kind === 'video';\n }).length;\n\n // Determine number of audio and video tracks we need to send/recv.\n var offerOptions = arguments[0];\n if (offerOptions) {\n // Reject Chrome legacy constraints.\n if (offerOptions.mandatory || offerOptions.optional) {\n throw new TypeError(\n 'Legacy mandatory/optional constraints not supported.');\n }\n if (offerOptions.offerToReceiveAudio !== undefined) {\n if (offerOptions.offerToReceiveAudio === true) {\n numAudioTracks = 1;\n } else if (offerOptions.offerToReceiveAudio === false) {\n numAudioTracks = 0;\n } else {\n numAudioTracks = offerOptions.offerToReceiveAudio;\n }\n }\n if (offerOptions.offerToReceiveVideo !== undefined) {\n if (offerOptions.offerToReceiveVideo === true) {\n numVideoTracks = 1;\n } else if (offerOptions.offerToReceiveVideo === false) {\n numVideoTracks = 0;\n } else {\n numVideoTracks = offerOptions.offerToReceiveVideo;\n }\n }\n }\n\n pc.transceivers.forEach(function(transceiver) {\n if (transceiver.kind === 'audio') {\n numAudioTracks--;\n if (numAudioTracks < 0) {\n transceiver.wantReceive = false;\n }\n } else if (transceiver.kind === 'video') {\n numVideoTracks--;\n if (numVideoTracks < 0) {\n transceiver.wantReceive = false;\n }\n }\n });\n\n // Create M-lines for recvonly streams.\n while (numAudioTracks > 0 || numVideoTracks > 0) {\n if (numAudioTracks > 0) {\n pc._createTransceiver('audio');\n numAudioTracks--;\n }\n if (numVideoTracks > 0) {\n pc._createTransceiver('video');\n numVideoTracks--;\n }\n }\n\n var sdp = SDPUtils.writeSessionBoilerplate(pc._sdpSessionId,\n pc._sdpSessionVersion++);\n pc.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n // For each track, create an ice gatherer, ice transport,\n // dtls transport, potentially rtpsender and rtpreceiver.\n var track = transceiver.track;\n var kind = transceiver.kind;\n var mid = transceiver.mid || SDPUtils.generateIdentifier();\n transceiver.mid = mid;\n\n if (!transceiver.iceGatherer) {\n transceiver.iceGatherer = pc._createIceGatherer(sdpMLineIndex,\n pc.usingBundle);\n }\n\n var localCapabilities = window.RTCRtpSender.getCapabilities(kind);\n // filter RTX until additional stuff needed for RTX is implemented\n // in adapter.js\n if (edgeVersion < 15019) {\n localCapabilities.codecs = localCapabilities.codecs.filter(\n function(codec) {\n return codec.name !== 'rtx';\n });\n }\n localCapabilities.codecs.forEach(function(codec) {\n // work around https://bugs.chromium.org/p/webrtc/issues/detail?id=6552\n // by adding level-asymmetry-allowed=1\n if (codec.name === 'H264' &&\n codec.parameters['level-asymmetry-allowed'] === undefined) {\n codec.parameters['level-asymmetry-allowed'] = '1';\n }\n\n // for subsequent offers, we might have to re-use the payload\n // type of the last offer.\n if (transceiver.remoteCapabilities &&\n transceiver.remoteCapabilities.codecs) {\n transceiver.remoteCapabilities.codecs.forEach(function(remoteCodec) {\n if (codec.name.toLowerCase() === remoteCodec.name.toLowerCase() &&\n codec.clockRate === remoteCodec.clockRate) {\n codec.preferredPayloadType = remoteCodec.payloadType;\n }\n });\n }\n });\n localCapabilities.headerExtensions.forEach(function(hdrExt) {\n var remoteExtensions = transceiver.remoteCapabilities &&\n transceiver.remoteCapabilities.headerExtensions || [];\n remoteExtensions.forEach(function(rHdrExt) {\n if (hdrExt.uri === rHdrExt.uri) {\n hdrExt.id = rHdrExt.id;\n }\n });\n });\n\n // generate an ssrc now, to be used later in rtpSender.send\n var sendEncodingParameters = transceiver.sendEncodingParameters || [{\n ssrc: (2 * sdpMLineIndex + 1) * 1001\n }];\n if (track) {\n // add RTX\n if (edgeVersion >= 15019 && kind === 'video' &&\n !sendEncodingParameters[0].rtx) {\n sendEncodingParameters[0].rtx = {\n ssrc: sendEncodingParameters[0].ssrc + 1\n };\n }\n }\n\n if (transceiver.wantReceive) {\n transceiver.rtpReceiver = new window.RTCRtpReceiver(\n transceiver.dtlsTransport, kind);\n }\n\n transceiver.localCapabilities = localCapabilities;\n transceiver.sendEncodingParameters = sendEncodingParameters;\n });\n\n // always offer BUNDLE and dispose on return if not supported.\n if (pc._config.bundlePolicy !== 'max-compat') {\n sdp += 'a=group:BUNDLE ' + pc.transceivers.map(function(t) {\n return t.mid;\n }).join(' ') + '\\r\\n';\n }\n sdp += 'a=ice-options:trickle\\r\\n';\n\n pc.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n sdp += writeMediaSection(transceiver, transceiver.localCapabilities,\n 'offer', transceiver.stream, pc._dtlsRole);\n sdp += 'a=rtcp-rsize\\r\\n';\n\n if (transceiver.iceGatherer && pc.iceGatheringState !== 'new' &&\n (sdpMLineIndex === 0 || !pc.usingBundle)) {\n transceiver.iceGatherer.getLocalCandidates().forEach(function(cand) {\n cand.component = 1;\n sdp += 'a=' + SDPUtils.writeCandidate(cand) + '\\r\\n';\n });\n\n if (transceiver.iceGatherer.state === 'completed') {\n sdp += 'a=end-of-candidates\\r\\n';\n }\n }\n });\n\n var desc = new window.RTCSessionDescription({\n type: 'offer',\n sdp: sdp\n });\n return Promise.resolve(desc);\n };\n\n RTCPeerConnection.prototype.createAnswer = function() {\n var pc = this;\n\n if (pc._isClosed) {\n return Promise.reject(makeError('InvalidStateError',\n 'Can not call createAnswer after close'));\n }\n\n if (!(pc.signalingState === 'have-remote-offer' ||\n pc.signalingState === 'have-local-pranswer')) {\n return Promise.reject(makeError('InvalidStateError',\n 'Can not call createAnswer in signalingState ' + pc.signalingState));\n }\n\n var sdp = SDPUtils.writeSessionBoilerplate(pc._sdpSessionId,\n pc._sdpSessionVersion++);\n if (pc.usingBundle) {\n sdp += 'a=group:BUNDLE ' + pc.transceivers.map(function(t) {\n return t.mid;\n }).join(' ') + '\\r\\n';\n }\n sdp += 'a=ice-options:trickle\\r\\n';\n\n var mediaSectionsInOffer = SDPUtils.getMediaSections(\n pc._remoteDescription.sdp).length;\n pc.transceivers.forEach(function(transceiver, sdpMLineIndex) {\n if (sdpMLineIndex + 1 > mediaSectionsInOffer) {\n return;\n }\n if (transceiver.rejected) {\n if (transceiver.kind === 'application') {\n if (transceiver.protocol === 'DTLS/SCTP') { // legacy fmt\n sdp += 'm=application 0 DTLS/SCTP 5000\\r\\n';\n } else {\n sdp += 'm=application 0 ' + transceiver.protocol +\n ' webrtc-datachannel\\r\\n';\n }\n } else if (transceiver.kind === 'audio') {\n sdp += 'm=audio 0 UDP/TLS/RTP/SAVPF 0\\r\\n' +\n 'a=rtpmap:0 PCMU/8000\\r\\n';\n } else if (transceiver.kind === 'video') {\n sdp += 'm=video 0 UDP/TLS/RTP/SAVPF 120\\r\\n' +\n 'a=rtpmap:120 VP8/90000\\r\\n';\n }\n sdp += 'c=IN IP4 0.0.0.0\\r\\n' +\n 'a=inactive\\r\\n' +\n 'a=mid:' + transceiver.mid + '\\r\\n';\n return;\n }\n\n // FIXME: look at direction.\n if (transceiver.stream) {\n var localTrack;\n if (transceiver.kind === 'audio') {\n localTrack = transceiver.stream.getAudioTracks()[0];\n } else if (transceiver.kind === 'video') {\n localTrack = transceiver.stream.getVideoTracks()[0];\n }\n if (localTrack) {\n // add RTX\n if (edgeVersion >= 15019 && transceiver.kind === 'video' &&\n !transceiver.sendEncodingParameters[0].rtx) {\n transceiver.sendEncodingParameters[0].rtx = {\n ssrc: transceiver.sendEncodingParameters[0].ssrc + 1\n };\n }\n }\n }\n\n // Calculate intersection of capabilities.\n var commonCapabilities = getCommonCapabilities(\n transceiver.localCapabilities,\n transceiver.remoteCapabilities);\n\n var hasRtx = commonCapabilities.codecs.filter(function(c) {\n return c.name.toLowerCase() === 'rtx';\n }).length;\n if (!hasRtx && transceiver.sendEncodingParameters[0].rtx) {\n delete transceiver.sendEncodingParameters[0].rtx;\n }\n\n sdp += writeMediaSection(transceiver, commonCapabilities,\n 'answer', transceiver.stream, pc._dtlsRole);\n if (transceiver.rtcpParameters &&\n transceiver.rtcpParameters.reducedSize) {\n sdp += 'a=rtcp-rsize\\r\\n';\n }\n });\n\n var desc = new window.RTCSessionDescription({\n type: 'answer',\n sdp: sdp\n });\n return Promise.resolve(desc);\n };\n\n RTCPeerConnection.prototype.addIceCandidate = function(candidate) {\n var pc = this;\n var sections;\n if (candidate && !(candidate.sdpMLineIndex !== undefined ||\n candidate.sdpMid)) {\n return Promise.reject(new TypeError('sdpMLineIndex or sdpMid required'));\n }\n\n // TODO: needs to go into ops queue.\n return new Promise(function(resolve, reject) {\n if (!pc._remoteDescription) {\n return reject(makeError('InvalidStateError',\n 'Can not add ICE candidate without a remote description'));\n } else if (!candidate || candidate.candidate === '') {\n for (var j = 0; j < pc.transceivers.length; j++) {\n if (pc.transceivers[j].rejected) {\n continue;\n }\n pc.transceivers[j].iceTransport.addRemoteCandidate({});\n sections = SDPUtils.getMediaSections(pc._remoteDescription.sdp);\n sections[j] += 'a=end-of-candidates\\r\\n';\n pc._remoteDescription.sdp =\n SDPUtils.getDescription(pc._remoteDescription.sdp) +\n sections.join('');\n if (pc.usingBundle) {\n break;\n }\n }\n } else {\n var sdpMLineIndex = candidate.sdpMLineIndex;\n if (candidate.sdpMid) {\n for (var i = 0; i < pc.transceivers.length; i++) {\n if (pc.transceivers[i].mid === candidate.sdpMid) {\n sdpMLineIndex = i;\n break;\n }\n }\n }\n var transceiver = pc.transceivers[sdpMLineIndex];\n if (transceiver) {\n if (transceiver.rejected) {\n return resolve();\n }\n var cand = Object.keys(candidate.candidate).length > 0 ?\n SDPUtils.parseCandidate(candidate.candidate) : {};\n // Ignore Chrome's invalid candidates since Edge does not like them.\n if (cand.protocol === 'tcp' && (cand.port === 0 || cand.port === 9)) {\n return resolve();\n }\n // Ignore RTCP candidates, we assume RTCP-MUX.\n if (cand.component && cand.component !== 1) {\n return resolve();\n }\n // when using bundle, avoid adding candidates to the wrong\n // ice transport. And avoid adding candidates added in the SDP.\n if (sdpMLineIndex === 0 || (sdpMLineIndex > 0 &&\n transceiver.iceTransport !== pc.transceivers[0].iceTransport)) {\n if (!maybeAddCandidate(transceiver.iceTransport, cand)) {\n return reject(makeError('OperationError',\n 'Can not add ICE candidate'));\n }\n }\n\n // update the remoteDescription.\n var candidateString = candidate.candidate.trim();\n if (candidateString.indexOf('a=') === 0) {\n candidateString = candidateString.substr(2);\n }\n sections = SDPUtils.getMediaSections(pc._remoteDescription.sdp);\n sections[sdpMLineIndex] += 'a=' +\n (cand.type ? candidateString : 'end-of-candidates')\n + '\\r\\n';\n pc._remoteDescription.sdp =\n SDPUtils.getDescription(pc._remoteDescription.sdp) +\n sections.join('');\n } else {\n return reject(makeError('OperationError',\n 'Can not add ICE candidate'));\n }\n }\n resolve();\n });\n };\n\n RTCPeerConnection.prototype.getStats = function(selector) {\n if (selector && selector instanceof window.MediaStreamTrack) {\n var senderOrReceiver = null;\n this.transceivers.forEach(function(transceiver) {\n if (transceiver.rtpSender &&\n transceiver.rtpSender.track === selector) {\n senderOrReceiver = transceiver.rtpSender;\n } else if (transceiver.rtpReceiver &&\n transceiver.rtpReceiver.track === selector) {\n senderOrReceiver = transceiver.rtpReceiver;\n }\n });\n if (!senderOrReceiver) {\n throw makeError('InvalidAccessError', 'Invalid selector.');\n }\n return senderOrReceiver.getStats();\n }\n\n var promises = [];\n this.transceivers.forEach(function(transceiver) {\n ['rtpSender', 'rtpReceiver', 'iceGatherer', 'iceTransport',\n 'dtlsTransport'].forEach(function(method) {\n if (transceiver[method]) {\n promises.push(transceiver[method].getStats());\n }\n });\n });\n return Promise.all(promises).then(function(allStats) {\n var results = new Map();\n allStats.forEach(function(stats) {\n stats.forEach(function(stat) {\n results.set(stat.id, stat);\n });\n });\n return results;\n });\n };\n\n // fix low-level stat names and return Map instead of object.\n var ortcObjects = ['RTCRtpSender', 'RTCRtpReceiver', 'RTCIceGatherer',\n 'RTCIceTransport', 'RTCDtlsTransport'];\n ortcObjects.forEach(function(ortcObjectName) {\n var obj = window[ortcObjectName];\n if (obj && obj.prototype && obj.prototype.getStats) {\n var nativeGetstats = obj.prototype.getStats;\n obj.prototype.getStats = function() {\n return nativeGetstats.apply(this)\n .then(function(nativeStats) {\n var mapStats = new Map();\n Object.keys(nativeStats).forEach(function(id) {\n nativeStats[id].type = fixStatsType(nativeStats[id]);\n mapStats.set(id, nativeStats[id]);\n });\n return mapStats;\n });\n };\n }\n });\n\n // legacy callback shims. Should be moved to adapter.js some days.\n var methods = ['createOffer', 'createAnswer'];\n methods.forEach(function(method) {\n var nativeMethod = RTCPeerConnection.prototype[method];\n RTCPeerConnection.prototype[method] = function() {\n var args = arguments;\n if (typeof args[0] === 'function' ||\n typeof args[1] === 'function') { // legacy\n return nativeMethod.apply(this, [arguments[2]])\n .then(function(description) {\n if (typeof args[0] === 'function') {\n args[0].apply(null, [description]);\n }\n }, function(error) {\n if (typeof args[1] === 'function') {\n args[1].apply(null, [error]);\n }\n });\n }\n return nativeMethod.apply(this, arguments);\n };\n });\n\n methods = ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate'];\n methods.forEach(function(method) {\n var nativeMethod = RTCPeerConnection.prototype[method];\n RTCPeerConnection.prototype[method] = function() {\n var args = arguments;\n if (typeof args[1] === 'function' ||\n typeof args[2] === 'function') { // legacy\n return nativeMethod.apply(this, arguments)\n .then(function() {\n if (typeof args[1] === 'function') {\n args[1].apply(null);\n }\n }, function(error) {\n if (typeof args[2] === 'function') {\n args[2].apply(null, [error]);\n }\n });\n }\n return nativeMethod.apply(this, arguments);\n };\n });\n\n // getStats is special. It doesn't have a spec legacy method yet we support\n // getStats(something, cb) without error callbacks.\n ['getStats'].forEach(function(method) {\n var nativeMethod = RTCPeerConnection.prototype[method];\n RTCPeerConnection.prototype[method] = function() {\n var args = arguments;\n if (typeof args[1] === 'function') {\n return nativeMethod.apply(this, arguments)\n .then(function() {\n if (typeof args[1] === 'function') {\n args[1].apply(null);\n }\n });\n }\n return nativeMethod.apply(this, arguments);\n };\n });\n\n return RTCPeerConnection;\n};\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/rtcpeerconnection-shim/rtcpeerconnection.js?");
551
-
552
- /***/ }),
553
-
554
- /***/ "./node_modules/sdp/sdp.js":
555
- /*!*********************************!*\
556
- !*** ./node_modules/sdp/sdp.js ***!
557
- \*********************************/
558
- /***/ (function(module) {
559
-
560
- "use strict";
561
- eval("/* eslint-env node */\n\n\n// SDP helpers.\nvar SDPUtils = {};\n\n// Generate an alphanumeric identifier for cname or mids.\n// TODO: use UUIDs instead? https://gist.github.com/jed/982883\nSDPUtils.generateIdentifier = function() {\n return Math.random().toString(36).substr(2, 10);\n};\n\n// The RTCP CNAME used by all peerconnections from the same JS.\nSDPUtils.localCName = SDPUtils.generateIdentifier();\n\n// Splits SDP into lines, dealing with both CRLF and LF.\nSDPUtils.splitLines = function(blob) {\n return blob.trim().split('\\n').map(function(line) {\n return line.trim();\n });\n};\n// Splits SDP into sessionpart and mediasections. Ensures CRLF.\nSDPUtils.splitSections = function(blob) {\n var parts = blob.split('\\nm=');\n return parts.map(function(part, index) {\n return (index > 0 ? 'm=' + part : part).trim() + '\\r\\n';\n });\n};\n\n// returns the session description.\nSDPUtils.getDescription = function(blob) {\n var sections = SDPUtils.splitSections(blob);\n return sections && sections[0];\n};\n\n// returns the individual media sections.\nSDPUtils.getMediaSections = function(blob) {\n var sections = SDPUtils.splitSections(blob);\n sections.shift();\n return sections;\n};\n\n// Returns lines that start with a certain prefix.\nSDPUtils.matchPrefix = function(blob, prefix) {\n return SDPUtils.splitLines(blob).filter(function(line) {\n return line.indexOf(prefix) === 0;\n });\n};\n\n// Parses an ICE candidate line. Sample input:\n// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8\n// rport 55996\"\nSDPUtils.parseCandidate = function(line) {\n var parts;\n // Parse both variants.\n if (line.indexOf('a=candidate:') === 0) {\n parts = line.substring(12).split(' ');\n } else {\n parts = line.substring(10).split(' ');\n }\n\n var candidate = {\n foundation: parts[0],\n component: parseInt(parts[1], 10),\n protocol: parts[2].toLowerCase(),\n priority: parseInt(parts[3], 10),\n ip: parts[4],\n address: parts[4], // address is an alias for ip.\n port: parseInt(parts[5], 10),\n // skip parts[6] == 'typ'\n type: parts[7]\n };\n\n for (var i = 8; i < parts.length; i += 2) {\n switch (parts[i]) {\n case 'raddr':\n candidate.relatedAddress = parts[i + 1];\n break;\n case 'rport':\n candidate.relatedPort = parseInt(parts[i + 1], 10);\n break;\n case 'tcptype':\n candidate.tcpType = parts[i + 1];\n break;\n case 'ufrag':\n candidate.ufrag = parts[i + 1]; // for backward compability.\n candidate.usernameFragment = parts[i + 1];\n break;\n default: // extension handling, in particular ufrag\n candidate[parts[i]] = parts[i + 1];\n break;\n }\n }\n return candidate;\n};\n\n// Translates a candidate object into SDP candidate attribute.\nSDPUtils.writeCandidate = function(candidate) {\n var sdp = [];\n sdp.push(candidate.foundation);\n sdp.push(candidate.component);\n sdp.push(candidate.protocol.toUpperCase());\n sdp.push(candidate.priority);\n sdp.push(candidate.address || candidate.ip);\n sdp.push(candidate.port);\n\n var type = candidate.type;\n sdp.push('typ');\n sdp.push(type);\n if (type !== 'host' && candidate.relatedAddress &&\n candidate.relatedPort) {\n sdp.push('raddr');\n sdp.push(candidate.relatedAddress);\n sdp.push('rport');\n sdp.push(candidate.relatedPort);\n }\n if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {\n sdp.push('tcptype');\n sdp.push(candidate.tcpType);\n }\n if (candidate.usernameFragment || candidate.ufrag) {\n sdp.push('ufrag');\n sdp.push(candidate.usernameFragment || candidate.ufrag);\n }\n return 'candidate:' + sdp.join(' ');\n};\n\n// Parses an ice-options line, returns an array of option tags.\n// a=ice-options:foo bar\nSDPUtils.parseIceOptions = function(line) {\n return line.substr(14).split(' ');\n};\n\n// Parses an rtpmap line, returns RTCRtpCoddecParameters. Sample input:\n// a=rtpmap:111 opus/48000/2\nSDPUtils.parseRtpMap = function(line) {\n var parts = line.substr(9).split(' ');\n var parsed = {\n payloadType: parseInt(parts.shift(), 10) // was: id\n };\n\n parts = parts[0].split('/');\n\n parsed.name = parts[0];\n parsed.clockRate = parseInt(parts[1], 10); // was: clockrate\n parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;\n // legacy alias, got renamed back to channels in ORTC.\n parsed.numChannels = parsed.channels;\n return parsed;\n};\n\n// Generate an a=rtpmap line from RTCRtpCodecCapability or\n// RTCRtpCodecParameters.\nSDPUtils.writeRtpMap = function(codec) {\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n var channels = codec.channels || codec.numChannels || 1;\n return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate +\n (channels !== 1 ? '/' + channels : '') + '\\r\\n';\n};\n\n// Parses an a=extmap line (headerextension from RFC 5285). Sample input:\n// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\n// a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset\nSDPUtils.parseExtmap = function(line) {\n var parts = line.substr(9).split(' ');\n return {\n id: parseInt(parts[0], 10),\n direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',\n uri: parts[1]\n };\n};\n\n// Generates a=extmap line from RTCRtpHeaderExtensionParameters or\n// RTCRtpHeaderExtension.\nSDPUtils.writeExtmap = function(headerExtension) {\n return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) +\n (headerExtension.direction && headerExtension.direction !== 'sendrecv'\n ? '/' + headerExtension.direction\n : '') +\n ' ' + headerExtension.uri + '\\r\\n';\n};\n\n// Parses an ftmp line, returns dictionary. Sample input:\n// a=fmtp:96 vbr=on;cng=on\n// Also deals with vbr=on; cng=on\nSDPUtils.parseFmtp = function(line) {\n var parsed = {};\n var kv;\n var parts = line.substr(line.indexOf(' ') + 1).split(';');\n for (var j = 0; j < parts.length; j++) {\n kv = parts[j].trim().split('=');\n parsed[kv[0].trim()] = kv[1];\n }\n return parsed;\n};\n\n// Generates an a=ftmp line from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeFmtp = function(codec) {\n var line = '';\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.parameters && Object.keys(codec.parameters).length) {\n var params = [];\n Object.keys(codec.parameters).forEach(function(param) {\n if (codec.parameters[param]) {\n params.push(param + '=' + codec.parameters[param]);\n } else {\n params.push(param);\n }\n });\n line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\\r\\n';\n }\n return line;\n};\n\n// Parses an rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:\n// a=rtcp-fb:98 nack rpsi\nSDPUtils.parseRtcpFb = function(line) {\n var parts = line.substr(line.indexOf(' ') + 1).split(' ');\n return {\n type: parts.shift(),\n parameter: parts.join(' ')\n };\n};\n// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeRtcpFb = function(codec) {\n var lines = '';\n var pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.rtcpFeedback && codec.rtcpFeedback.length) {\n // FIXME: special handling for trr-int?\n codec.rtcpFeedback.forEach(function(fb) {\n lines += 'a=rtcp-fb:' + pt + ' ' + fb.type +\n (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') +\n '\\r\\n';\n });\n }\n return lines;\n};\n\n// Parses an RFC 5576 ssrc media attribute. Sample input:\n// a=ssrc:3735928559 cname:something\nSDPUtils.parseSsrcMedia = function(line) {\n var sp = line.indexOf(' ');\n var parts = {\n ssrc: parseInt(line.substr(7, sp - 7), 10)\n };\n var colon = line.indexOf(':', sp);\n if (colon > -1) {\n parts.attribute = line.substr(sp + 1, colon - sp - 1);\n parts.value = line.substr(colon + 1);\n } else {\n parts.attribute = line.substr(sp + 1);\n }\n return parts;\n};\n\nSDPUtils.parseSsrcGroup = function(line) {\n var parts = line.substr(13).split(' ');\n return {\n semantics: parts.shift(),\n ssrcs: parts.map(function(ssrc) {\n return parseInt(ssrc, 10);\n })\n };\n};\n\n// Extracts the MID (RFC 5888) from a media section.\n// returns the MID or undefined if no mid line was found.\nSDPUtils.getMid = function(mediaSection) {\n var mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];\n if (mid) {\n return mid.substr(6);\n }\n};\n\nSDPUtils.parseFingerprint = function(line) {\n var parts = line.substr(14).split(' ');\n return {\n algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge.\n value: parts[1]\n };\n};\n\n// Extracts DTLS parameters from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the fingerprint line as input. See also getIceParameters.\nSDPUtils.getDtlsParameters = function(mediaSection, sessionpart) {\n var lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=fingerprint:');\n // Note: a=setup line is ignored since we use the 'auto' role.\n // Note2: 'algorithm' is not case sensitive except in Edge.\n return {\n role: 'auto',\n fingerprints: lines.map(SDPUtils.parseFingerprint)\n };\n};\n\n// Serializes DTLS parameters to SDP.\nSDPUtils.writeDtlsParameters = function(params, setupType) {\n var sdp = 'a=setup:' + setupType + '\\r\\n';\n params.fingerprints.forEach(function(fp) {\n sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\\r\\n';\n });\n return sdp;\n};\n\n// Parses a=crypto lines into\n// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members\nSDPUtils.parseCryptoLine = function(line) {\n var parts = line.substr(9).split(' ');\n return {\n tag: parseInt(parts[0], 10),\n cryptoSuite: parts[1],\n keyParams: parts[2],\n sessionParams: parts.slice(3),\n };\n};\n\nSDPUtils.writeCryptoLine = function(parameters) {\n return 'a=crypto:' + parameters.tag + ' ' +\n parameters.cryptoSuite + ' ' +\n (typeof parameters.keyParams === 'object'\n ? SDPUtils.writeCryptoKeyParams(parameters.keyParams)\n : parameters.keyParams) +\n (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') +\n '\\r\\n';\n};\n\n// Parses the crypto key parameters into\n// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*\nSDPUtils.parseCryptoKeyParams = function(keyParams) {\n if (keyParams.indexOf('inline:') !== 0) {\n return null;\n }\n var parts = keyParams.substr(7).split('|');\n return {\n keyMethod: 'inline',\n keySalt: parts[0],\n lifeTime: parts[1],\n mkiValue: parts[2] ? parts[2].split(':')[0] : undefined,\n mkiLength: parts[2] ? parts[2].split(':')[1] : undefined,\n };\n};\n\nSDPUtils.writeCryptoKeyParams = function(keyParams) {\n return keyParams.keyMethod + ':'\n + keyParams.keySalt +\n (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') +\n (keyParams.mkiValue && keyParams.mkiLength\n ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength\n : '');\n};\n\n// Extracts all SDES paramters.\nSDPUtils.getCryptoParameters = function(mediaSection, sessionpart) {\n var lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=crypto:');\n return lines.map(SDPUtils.parseCryptoLine);\n};\n\n// Parses ICE information from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the ice-ufrag and ice-pwd lines as input.\nSDPUtils.getIceParameters = function(mediaSection, sessionpart) {\n var ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=ice-ufrag:')[0];\n var pwd = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=ice-pwd:')[0];\n if (!(ufrag && pwd)) {\n return null;\n }\n return {\n usernameFragment: ufrag.substr(12),\n password: pwd.substr(10),\n };\n};\n\n// Serializes ICE parameters to SDP.\nSDPUtils.writeIceParameters = function(params) {\n return 'a=ice-ufrag:' + params.usernameFragment + '\\r\\n' +\n 'a=ice-pwd:' + params.password + '\\r\\n';\n};\n\n// Parses the SDP media section and returns RTCRtpParameters.\nSDPUtils.parseRtpParameters = function(mediaSection) {\n var description = {\n codecs: [],\n headerExtensions: [],\n fecMechanisms: [],\n rtcp: []\n };\n var lines = SDPUtils.splitLines(mediaSection);\n var mline = lines[0].split(' ');\n for (var i = 3; i < mline.length; i++) { // find all codecs from mline[3..]\n var pt = mline[i];\n var rtpmapline = SDPUtils.matchPrefix(\n mediaSection, 'a=rtpmap:' + pt + ' ')[0];\n if (rtpmapline) {\n var codec = SDPUtils.parseRtpMap(rtpmapline);\n var fmtps = SDPUtils.matchPrefix(\n mediaSection, 'a=fmtp:' + pt + ' ');\n // Only the first a=fmtp:<pt> is considered.\n codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};\n codec.rtcpFeedback = SDPUtils.matchPrefix(\n mediaSection, 'a=rtcp-fb:' + pt + ' ')\n .map(SDPUtils.parseRtcpFb);\n description.codecs.push(codec);\n // parse FEC mechanisms from rtpmap lines.\n switch (codec.name.toUpperCase()) {\n case 'RED':\n case 'ULPFEC':\n description.fecMechanisms.push(codec.name.toUpperCase());\n break;\n default: // only RED and ULPFEC are recognized as FEC mechanisms.\n break;\n }\n }\n }\n SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(function(line) {\n description.headerExtensions.push(SDPUtils.parseExtmap(line));\n });\n // FIXME: parse rtcp.\n return description;\n};\n\n// Generates parts of the SDP media section describing the capabilities /\n// parameters.\nSDPUtils.writeRtpDescription = function(kind, caps) {\n var sdp = '';\n\n // Build the mline.\n sdp += 'm=' + kind + ' ';\n sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.\n sdp += ' UDP/TLS/RTP/SAVPF ';\n sdp += caps.codecs.map(function(codec) {\n if (codec.preferredPayloadType !== undefined) {\n return codec.preferredPayloadType;\n }\n return codec.payloadType;\n }).join(' ') + '\\r\\n';\n\n sdp += 'c=IN IP4 0.0.0.0\\r\\n';\n sdp += 'a=rtcp:9 IN IP4 0.0.0.0\\r\\n';\n\n // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.\n caps.codecs.forEach(function(codec) {\n sdp += SDPUtils.writeRtpMap(codec);\n sdp += SDPUtils.writeFmtp(codec);\n sdp += SDPUtils.writeRtcpFb(codec);\n });\n var maxptime = 0;\n caps.codecs.forEach(function(codec) {\n if (codec.maxptime > maxptime) {\n maxptime = codec.maxptime;\n }\n });\n if (maxptime > 0) {\n sdp += 'a=maxptime:' + maxptime + '\\r\\n';\n }\n sdp += 'a=rtcp-mux\\r\\n';\n\n if (caps.headerExtensions) {\n caps.headerExtensions.forEach(function(extension) {\n sdp += SDPUtils.writeExtmap(extension);\n });\n }\n // FIXME: write fecMechanisms.\n return sdp;\n};\n\n// Parses the SDP media section and returns an array of\n// RTCRtpEncodingParameters.\nSDPUtils.parseRtpEncodingParameters = function(mediaSection) {\n var encodingParameters = [];\n var description = SDPUtils.parseRtpParameters(mediaSection);\n var hasRed = description.fecMechanisms.indexOf('RED') !== -1;\n var hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;\n\n // filter a=ssrc:... cname:, ignore PlanB-msid\n var ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(parts) {\n return parts.attribute === 'cname';\n });\n var primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;\n var secondarySsrc;\n\n var flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID')\n .map(function(line) {\n var parts = line.substr(17).split(' ');\n return parts.map(function(part) {\n return parseInt(part, 10);\n });\n });\n if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {\n secondarySsrc = flows[0][1];\n }\n\n description.codecs.forEach(function(codec) {\n if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {\n var encParam = {\n ssrc: primarySsrc,\n codecPayloadType: parseInt(codec.parameters.apt, 10)\n };\n if (primarySsrc && secondarySsrc) {\n encParam.rtx = {ssrc: secondarySsrc};\n }\n encodingParameters.push(encParam);\n if (hasRed) {\n encParam = JSON.parse(JSON.stringify(encParam));\n encParam.fec = {\n ssrc: primarySsrc,\n mechanism: hasUlpfec ? 'red+ulpfec' : 'red'\n };\n encodingParameters.push(encParam);\n }\n }\n });\n if (encodingParameters.length === 0 && primarySsrc) {\n encodingParameters.push({\n ssrc: primarySsrc\n });\n }\n\n // we support both b=AS and b=TIAS but interpret AS as TIAS.\n var bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');\n if (bandwidth.length) {\n if (bandwidth[0].indexOf('b=TIAS:') === 0) {\n bandwidth = parseInt(bandwidth[0].substr(7), 10);\n } else if (bandwidth[0].indexOf('b=AS:') === 0) {\n // use formula from JSEP to convert b=AS to TIAS value.\n bandwidth = parseInt(bandwidth[0].substr(5), 10) * 1000 * 0.95\n - (50 * 40 * 8);\n } else {\n bandwidth = undefined;\n }\n encodingParameters.forEach(function(params) {\n params.maxBitrate = bandwidth;\n });\n }\n return encodingParameters;\n};\n\n// parses http://draft.ortc.org/#rtcrtcpparameters*\nSDPUtils.parseRtcpParameters = function(mediaSection) {\n var rtcpParameters = {};\n\n // Gets the first SSRC. Note tha with RTX there might be multiple\n // SSRCs.\n var remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(obj) {\n return obj.attribute === 'cname';\n })[0];\n if (remoteSsrc) {\n rtcpParameters.cname = remoteSsrc.value;\n rtcpParameters.ssrc = remoteSsrc.ssrc;\n }\n\n // Edge uses the compound attribute instead of reducedSize\n // compound is !reducedSize\n var rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');\n rtcpParameters.reducedSize = rsize.length > 0;\n rtcpParameters.compound = rsize.length === 0;\n\n // parses the rtcp-mux attrіbute.\n // Note that Edge does not support unmuxed RTCP.\n var mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');\n rtcpParameters.mux = mux.length > 0;\n\n return rtcpParameters;\n};\n\n// parses either a=msid: or a=ssrc:... msid lines and returns\n// the id of the MediaStream and MediaStreamTrack.\nSDPUtils.parseMsid = function(mediaSection) {\n var parts;\n var spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');\n if (spec.length === 1) {\n parts = spec[0].substr(7).split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n var planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(function(line) {\n return SDPUtils.parseSsrcMedia(line);\n })\n .filter(function(msidParts) {\n return msidParts.attribute === 'msid';\n });\n if (planB.length > 0) {\n parts = planB[0].value.split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n};\n\n// SCTP\n// parses draft-ietf-mmusic-sctp-sdp-26 first and falls back\n// to draft-ietf-mmusic-sctp-sdp-05\nSDPUtils.parseSctpDescription = function(mediaSection) {\n var mline = SDPUtils.parseMLine(mediaSection);\n var maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');\n var maxMessageSize;\n if (maxSizeLine.length > 0) {\n maxMessageSize = parseInt(maxSizeLine[0].substr(19), 10);\n }\n if (isNaN(maxMessageSize)) {\n maxMessageSize = 65536;\n }\n var sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');\n if (sctpPort.length > 0) {\n return {\n port: parseInt(sctpPort[0].substr(12), 10),\n protocol: mline.fmt,\n maxMessageSize: maxMessageSize\n };\n }\n var sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');\n if (sctpMapLines.length > 0) {\n var parts = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:')[0]\n .substr(10)\n .split(' ');\n return {\n port: parseInt(parts[0], 10),\n protocol: parts[1],\n maxMessageSize: maxMessageSize\n };\n }\n};\n\n// SCTP\n// outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers\n// support by now receiving in this format, unless we originally parsed\n// as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line\n// protocol of DTLS/SCTP -- without UDP/ or TCP/)\nSDPUtils.writeSctpDescription = function(media, sctp) {\n var output = [];\n if (media.protocol !== 'DTLS/SCTP') {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctp-port:' + sctp.port + '\\r\\n'\n ];\n } else {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\\r\\n'\n ];\n }\n if (sctp.maxMessageSize !== undefined) {\n output.push('a=max-message-size:' + sctp.maxMessageSize + '\\r\\n');\n }\n return output.join('');\n};\n\n// Generate a session ID for SDP.\n// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1\n// recommends using a cryptographically random +ve 64-bit value\n// but right now this should be acceptable and within the right range\nSDPUtils.generateSessionId = function() {\n return Math.random().toString().substr(2, 21);\n};\n\n// Write boilder plate for start of SDP\n// sessId argument is optional - if not supplied it will\n// be generated randomly\n// sessVersion is optional and defaults to 2\n// sessUser is optional and defaults to 'thisisadapterortc'\nSDPUtils.writeSessionBoilerplate = function(sessId, sessVer, sessUser) {\n var sessionId;\n var version = sessVer !== undefined ? sessVer : 2;\n if (sessId) {\n sessionId = sessId;\n } else {\n sessionId = SDPUtils.generateSessionId();\n }\n var user = sessUser || 'thisisadapterortc';\n // FIXME: sess-id should be an NTP timestamp.\n return 'v=0\\r\\n' +\n 'o=' + user + ' ' + sessionId + ' ' + version +\n ' IN IP4 127.0.0.1\\r\\n' +\n 's=-\\r\\n' +\n 't=0 0\\r\\n';\n};\n\nSDPUtils.writeMediaSection = function(transceiver, caps, type, stream) {\n var sdp = SDPUtils.writeRtpDescription(transceiver.kind, caps);\n\n // Map ICE parameters (ufrag, pwd) to SDP.\n sdp += SDPUtils.writeIceParameters(\n transceiver.iceGatherer.getLocalParameters());\n\n // Map DTLS parameters to SDP.\n sdp += SDPUtils.writeDtlsParameters(\n transceiver.dtlsTransport.getLocalParameters(),\n type === 'offer' ? 'actpass' : 'active');\n\n sdp += 'a=mid:' + transceiver.mid + '\\r\\n';\n\n if (transceiver.direction) {\n sdp += 'a=' + transceiver.direction + '\\r\\n';\n } else if (transceiver.rtpSender && transceiver.rtpReceiver) {\n sdp += 'a=sendrecv\\r\\n';\n } else if (transceiver.rtpSender) {\n sdp += 'a=sendonly\\r\\n';\n } else if (transceiver.rtpReceiver) {\n sdp += 'a=recvonly\\r\\n';\n } else {\n sdp += 'a=inactive\\r\\n';\n }\n\n if (transceiver.rtpSender) {\n // spec.\n var msid = 'msid:' + stream.id + ' ' +\n transceiver.rtpSender.track.id + '\\r\\n';\n sdp += 'a=' + msid;\n\n // for Chrome.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' ' + msid;\n if (transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' ' + msid;\n sdp += 'a=ssrc-group:FID ' +\n transceiver.sendEncodingParameters[0].ssrc + ' ' +\n transceiver.sendEncodingParameters[0].rtx.ssrc +\n '\\r\\n';\n }\n }\n // FIXME: this should be written by writeRtpDescription.\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n if (transceiver.rtpSender && transceiver.sendEncodingParameters[0].rtx) {\n sdp += 'a=ssrc:' + transceiver.sendEncodingParameters[0].rtx.ssrc +\n ' cname:' + SDPUtils.localCName + '\\r\\n';\n }\n return sdp;\n};\n\n// Gets the direction from the mediaSection or the sessionpart.\nSDPUtils.getDirection = function(mediaSection, sessionpart) {\n // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.\n var lines = SDPUtils.splitLines(mediaSection);\n for (var i = 0; i < lines.length; i++) {\n switch (lines[i]) {\n case 'a=sendrecv':\n case 'a=sendonly':\n case 'a=recvonly':\n case 'a=inactive':\n return lines[i].substr(2);\n default:\n // FIXME: What should happen here?\n }\n }\n if (sessionpart) {\n return SDPUtils.getDirection(sessionpart);\n }\n return 'sendrecv';\n};\n\nSDPUtils.getKind = function(mediaSection) {\n var lines = SDPUtils.splitLines(mediaSection);\n var mline = lines[0].split(' ');\n return mline[0].substr(2);\n};\n\nSDPUtils.isRejected = function(mediaSection) {\n return mediaSection.split(' ', 2)[1] === '0';\n};\n\nSDPUtils.parseMLine = function(mediaSection) {\n var lines = SDPUtils.splitLines(mediaSection);\n var parts = lines[0].substr(2).split(' ');\n return {\n kind: parts[0],\n port: parseInt(parts[1], 10),\n protocol: parts[2],\n fmt: parts.slice(3).join(' ')\n };\n};\n\nSDPUtils.parseOLine = function(mediaSection) {\n var line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];\n var parts = line.substr(2).split(' ');\n return {\n username: parts[0],\n sessionId: parts[1],\n sessionVersion: parseInt(parts[2], 10),\n netType: parts[3],\n addressType: parts[4],\n address: parts[5]\n };\n};\n\n// a very naive interpretation of a valid SDP.\nSDPUtils.isValidSDP = function(blob) {\n if (typeof blob !== 'string' || blob.length === 0) {\n return false;\n }\n var lines = SDPUtils.splitLines(blob);\n for (var i = 0; i < lines.length; i++) {\n if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {\n return false;\n }\n // TODO: check the modifier a bit more.\n }\n return true;\n};\n\n// Expose public methods.\nif (true) {\n module.exports = SDPUtils;\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/sdp/sdp.js?");
562
-
563
- /***/ }),
564
-
565
523
  /***/ "./node_modules/sweetalert2/dist/sweetalert2.all.js":
566
524
  /*!**********************************************************!*\
567
525
  !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
@@ -572,171 +530,6 @@ eval("/*!\n* sweetalert2 v11.14.0\n* Released under the MIT License.\n*/\n(funct
572
530
 
573
531
  /***/ }),
574
532
 
575
- /***/ "./node_modules/webrtc-adapter/src/js/adapter_core.js":
576
- /*!************************************************************!*\
577
- !*** ./node_modules/webrtc-adapter/src/js/adapter_core.js ***!
578
- \************************************************************/
579
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
580
-
581
- "use strict";
582
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _adapter_factory_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./adapter_factory.js */ \"./node_modules/webrtc-adapter/src/js/adapter_factory.js\");\n/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n\n\n\n\n\nconst adapter =\n (0,_adapter_factory_js__WEBPACK_IMPORTED_MODULE_0__.adapterFactory)({window: typeof window === 'undefined' ? undefined : window});\n/* harmony default export */ __webpack_exports__[\"default\"] = (adapter);\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/adapter_core.js?");
583
-
584
- /***/ }),
585
-
586
- /***/ "./node_modules/webrtc-adapter/src/js/adapter_factory.js":
587
- /*!***************************************************************!*\
588
- !*** ./node_modules/webrtc-adapter/src/js/adapter_factory.js ***!
589
- \***************************************************************/
590
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
591
-
592
- "use strict";
593
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ adapterFactory: function() { return /* binding */ adapterFactory; }\n/* harmony export */ });\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils */ \"./node_modules/webrtc-adapter/src/js/utils.js\");\n/* harmony import */ var _chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./chrome/chrome_shim */ \"./node_modules/webrtc-adapter/src/js/chrome/chrome_shim.js\");\n/* harmony import */ var _edge_edge_shim__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./edge/edge_shim */ \"./node_modules/webrtc-adapter/src/js/edge/edge_shim.js\");\n/* harmony import */ var _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./firefox/firefox_shim */ \"./node_modules/webrtc-adapter/src/js/firefox/firefox_shim.js\");\n/* harmony import */ var _safari_safari_shim__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./safari/safari_shim */ \"./node_modules/webrtc-adapter/src/js/safari/safari_shim.js\");\n/* harmony import */ var _common_shim__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./common_shim */ \"./node_modules/webrtc-adapter/src/js/common_shim.js\");\n/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n\n\n // Browser shims.\n\n\n\n\n\n\n// Shimming starts here.\nfunction adapterFactory({window} = {}, options = {\n shimChrome: true,\n shimFirefox: true,\n shimEdge: true,\n shimSafari: true,\n}) {\n // Utils.\n const logging = _utils__WEBPACK_IMPORTED_MODULE_0__.log;\n const browserDetails = _utils__WEBPACK_IMPORTED_MODULE_0__.detectBrowser(window);\n\n const adapter = {\n browserDetails,\n commonShim: _common_shim__WEBPACK_IMPORTED_MODULE_5__,\n extractVersion: _utils__WEBPACK_IMPORTED_MODULE_0__.extractVersion,\n disableLog: _utils__WEBPACK_IMPORTED_MODULE_0__.disableLog,\n disableWarnings: _utils__WEBPACK_IMPORTED_MODULE_0__.disableWarnings\n };\n\n // Shim browser if found.\n switch (browserDetails.browser) {\n case 'chrome':\n if (!_chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__ || !_chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__.shimPeerConnection ||\n !options.shimChrome) {\n logging('Chrome shim is not included in this adapter release.');\n return adapter;\n }\n if (browserDetails.version === null) {\n logging('Chrome shim can not determine version, not shimming.');\n return adapter;\n }\n logging('adapter.js shimming chrome.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = _chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__;\n\n // Must be called before shimPeerConnection.\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimAddIceCandidateNullOrEmpty(window, browserDetails);\n\n _chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__.shimGetUserMedia(window, browserDetails);\n _chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__.shimMediaStream(window, browserDetails);\n _chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__.shimPeerConnection(window, browserDetails);\n _chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__.shimOnTrack(window, browserDetails);\n _chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__.shimAddTrackRemoveTrack(window, browserDetails);\n _chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__.shimGetSendersWithDtmf(window, browserDetails);\n _chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__.shimGetStats(window, browserDetails);\n _chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__.shimSenderReceiverGetStats(window, browserDetails);\n _chrome_chrome_shim__WEBPACK_IMPORTED_MODULE_1__.fixNegotiationNeeded(window, browserDetails);\n\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimRTCIceCandidate(window, browserDetails);\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimConnectionState(window, browserDetails);\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimMaxMessageSize(window, browserDetails);\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimSendThrowTypeError(window, browserDetails);\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.removeExtmapAllowMixed(window, browserDetails);\n break;\n case 'firefox':\n if (!_firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__ || !_firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimPeerConnection ||\n !options.shimFirefox) {\n logging('Firefox shim is not included in this adapter release.');\n return adapter;\n }\n logging('adapter.js shimming firefox.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__;\n\n // Must be called before shimPeerConnection.\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimAddIceCandidateNullOrEmpty(window, browserDetails);\n\n _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimGetUserMedia(window, browserDetails);\n _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimPeerConnection(window, browserDetails);\n _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimOnTrack(window, browserDetails);\n _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimRemoveStream(window, browserDetails);\n _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimSenderGetStats(window, browserDetails);\n _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimReceiverGetStats(window, browserDetails);\n _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimRTCDataChannel(window, browserDetails);\n _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimAddTransceiver(window, browserDetails);\n _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimGetParameters(window, browserDetails);\n _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimCreateOffer(window, browserDetails);\n _firefox_firefox_shim__WEBPACK_IMPORTED_MODULE_3__.shimCreateAnswer(window, browserDetails);\n\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimRTCIceCandidate(window, browserDetails);\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimConnectionState(window, browserDetails);\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimMaxMessageSize(window, browserDetails);\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimSendThrowTypeError(window, browserDetails);\n break;\n case 'edge':\n if (!_edge_edge_shim__WEBPACK_IMPORTED_MODULE_2__ || !_edge_edge_shim__WEBPACK_IMPORTED_MODULE_2__.shimPeerConnection || !options.shimEdge) {\n logging('MS edge shim is not included in this adapter release.');\n return adapter;\n }\n logging('adapter.js shimming edge.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = _edge_edge_shim__WEBPACK_IMPORTED_MODULE_2__;\n\n _edge_edge_shim__WEBPACK_IMPORTED_MODULE_2__.shimGetUserMedia(window, browserDetails);\n _edge_edge_shim__WEBPACK_IMPORTED_MODULE_2__.shimGetDisplayMedia(window, browserDetails);\n _edge_edge_shim__WEBPACK_IMPORTED_MODULE_2__.shimPeerConnection(window, browserDetails);\n _edge_edge_shim__WEBPACK_IMPORTED_MODULE_2__.shimReplaceTrack(window, browserDetails);\n\n // the edge shim implements the full RTCIceCandidate object.\n\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimMaxMessageSize(window, browserDetails);\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimSendThrowTypeError(window, browserDetails);\n break;\n case 'safari':\n if (!_safari_safari_shim__WEBPACK_IMPORTED_MODULE_4__ || !options.shimSafari) {\n logging('Safari shim is not included in this adapter release.');\n return adapter;\n }\n logging('adapter.js shimming safari.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = _safari_safari_shim__WEBPACK_IMPORTED_MODULE_4__;\n\n // Must be called before shimCallbackAPI.\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimAddIceCandidateNullOrEmpty(window, browserDetails);\n\n _safari_safari_shim__WEBPACK_IMPORTED_MODULE_4__.shimRTCIceServerUrls(window, browserDetails);\n _safari_safari_shim__WEBPACK_IMPORTED_MODULE_4__.shimCreateOfferLegacy(window, browserDetails);\n _safari_safari_shim__WEBPACK_IMPORTED_MODULE_4__.shimCallbacksAPI(window, browserDetails);\n _safari_safari_shim__WEBPACK_IMPORTED_MODULE_4__.shimLocalStreamsAPI(window, browserDetails);\n _safari_safari_shim__WEBPACK_IMPORTED_MODULE_4__.shimRemoteStreamsAPI(window, browserDetails);\n _safari_safari_shim__WEBPACK_IMPORTED_MODULE_4__.shimTrackEventTransceiver(window, browserDetails);\n _safari_safari_shim__WEBPACK_IMPORTED_MODULE_4__.shimGetUserMedia(window, browserDetails);\n _safari_safari_shim__WEBPACK_IMPORTED_MODULE_4__.shimAudioContext(window, browserDetails);\n\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimRTCIceCandidate(window, browserDetails);\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimMaxMessageSize(window, browserDetails);\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.shimSendThrowTypeError(window, browserDetails);\n _common_shim__WEBPACK_IMPORTED_MODULE_5__.removeExtmapAllowMixed(window, browserDetails);\n break;\n default:\n logging('Unsupported browser!');\n break;\n }\n\n return adapter;\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/adapter_factory.js?");
594
-
595
- /***/ }),
596
-
597
- /***/ "./node_modules/webrtc-adapter/src/js/chrome/chrome_shim.js":
598
- /*!******************************************************************!*\
599
- !*** ./node_modules/webrtc-adapter/src/js/chrome/chrome_shim.js ***!
600
- \******************************************************************/
601
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
602
-
603
- "use strict";
604
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ fixNegotiationNeeded: function() { return /* binding */ fixNegotiationNeeded; },\n/* harmony export */ shimAddTrackRemoveTrack: function() { return /* binding */ shimAddTrackRemoveTrack; },\n/* harmony export */ shimAddTrackRemoveTrackWithNative: function() { return /* binding */ shimAddTrackRemoveTrackWithNative; },\n/* harmony export */ shimGetDisplayMedia: function() { return /* reexport safe */ _getdisplaymedia__WEBPACK_IMPORTED_MODULE_2__.shimGetDisplayMedia; },\n/* harmony export */ shimGetSendersWithDtmf: function() { return /* binding */ shimGetSendersWithDtmf; },\n/* harmony export */ shimGetStats: function() { return /* binding */ shimGetStats; },\n/* harmony export */ shimGetUserMedia: function() { return /* reexport safe */ _getusermedia__WEBPACK_IMPORTED_MODULE_1__.shimGetUserMedia; },\n/* harmony export */ shimMediaStream: function() { return /* binding */ shimMediaStream; },\n/* harmony export */ shimOnTrack: function() { return /* binding */ shimOnTrack; },\n/* harmony export */ shimPeerConnection: function() { return /* binding */ shimPeerConnection; },\n/* harmony export */ shimSenderReceiverGetStats: function() { return /* binding */ shimSenderReceiverGetStats; }\n/* harmony export */ });\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils.js */ \"./node_modules/webrtc-adapter/src/js/utils.js\");\n/* harmony import */ var _getusermedia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getusermedia */ \"./node_modules/webrtc-adapter/src/js/chrome/getusermedia.js\");\n/* harmony import */ var _getdisplaymedia__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getdisplaymedia */ \"./node_modules/webrtc-adapter/src/js/chrome/getdisplaymedia.js\");\n/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n\n\n\n\n\n\nfunction shimMediaStream(window) {\n window.MediaStream = window.MediaStream || window.webkitMediaStream;\n}\n\nfunction shimOnTrack(window) {\n if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in\n window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {\n get() {\n return this._ontrack;\n },\n set(f) {\n if (this._ontrack) {\n this.removeEventListener('track', this._ontrack);\n }\n this.addEventListener('track', this._ontrack = f);\n },\n enumerable: true,\n configurable: true\n });\n const origSetRemoteDescription =\n window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription() {\n if (!this._ontrackpoly) {\n this._ontrackpoly = (e) => {\n // onaddstream does not fire when a track is added to an existing\n // stream. But stream.onaddtrack is implemented so we use that.\n e.stream.addEventListener('addtrack', te => {\n let receiver;\n if (window.RTCPeerConnection.prototype.getReceivers) {\n receiver = this.getReceivers()\n .find(r => r.track && r.track.id === te.track.id);\n } else {\n receiver = {track: te.track};\n }\n\n const event = new Event('track');\n event.track = te.track;\n event.receiver = receiver;\n event.transceiver = {receiver};\n event.streams = [e.stream];\n this.dispatchEvent(event);\n });\n e.stream.getTracks().forEach(track => {\n let receiver;\n if (window.RTCPeerConnection.prototype.getReceivers) {\n receiver = this.getReceivers()\n .find(r => r.track && r.track.id === track.id);\n } else {\n receiver = {track};\n }\n const event = new Event('track');\n event.track = track;\n event.receiver = receiver;\n event.transceiver = {receiver};\n event.streams = [e.stream];\n this.dispatchEvent(event);\n });\n };\n this.addEventListener('addstream', this._ontrackpoly);\n }\n return origSetRemoteDescription.apply(this, arguments);\n };\n } else {\n // even if RTCRtpTransceiver is in window, it is only used and\n // emitted in unified-plan. Unfortunately this means we need\n // to unconditionally wrap the event.\n _utils_js__WEBPACK_IMPORTED_MODULE_0__.wrapPeerConnectionEvent(window, 'track', e => {\n if (!e.transceiver) {\n Object.defineProperty(e, 'transceiver',\n {value: {receiver: e.receiver}});\n }\n return e;\n });\n }\n}\n\nfunction shimGetSendersWithDtmf(window) {\n // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack.\n if (typeof window === 'object' && window.RTCPeerConnection &&\n !('getSenders' in window.RTCPeerConnection.prototype) &&\n 'createDTMFSender' in window.RTCPeerConnection.prototype) {\n const shimSenderWithDtmf = function(pc, track) {\n return {\n track,\n get dtmf() {\n if (this._dtmf === undefined) {\n if (track.kind === 'audio') {\n this._dtmf = pc.createDTMFSender(track);\n } else {\n this._dtmf = null;\n }\n }\n return this._dtmf;\n },\n _pc: pc\n };\n };\n\n // augment addTrack when getSenders is not available.\n if (!window.RTCPeerConnection.prototype.getSenders) {\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n this._senders = this._senders || [];\n return this._senders.slice(); // return a copy of the internal state.\n };\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, stream) {\n let sender = origAddTrack.apply(this, arguments);\n if (!sender) {\n sender = shimSenderWithDtmf(this, track);\n this._senders.push(sender);\n }\n return sender;\n };\n\n const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;\n window.RTCPeerConnection.prototype.removeTrack =\n function removeTrack(sender) {\n origRemoveTrack.apply(this, arguments);\n const idx = this._senders.indexOf(sender);\n if (idx !== -1) {\n this._senders.splice(idx, 1);\n }\n };\n }\n const origAddStream = window.RTCPeerConnection.prototype.addStream;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n this._senders = this._senders || [];\n origAddStream.apply(this, [stream]);\n stream.getTracks().forEach(track => {\n this._senders.push(shimSenderWithDtmf(this, track));\n });\n };\n\n const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n this._senders = this._senders || [];\n origRemoveStream.apply(this, [stream]);\n\n stream.getTracks().forEach(track => {\n const sender = this._senders.find(s => s.track === track);\n if (sender) { // remove sender\n this._senders.splice(this._senders.indexOf(sender), 1);\n }\n });\n };\n } else if (typeof window === 'object' && window.RTCPeerConnection &&\n 'getSenders' in window.RTCPeerConnection.prototype &&\n 'createDTMFSender' in window.RTCPeerConnection.prototype &&\n window.RTCRtpSender &&\n !('dtmf' in window.RTCRtpSender.prototype)) {\n const origGetSenders = window.RTCPeerConnection.prototype.getSenders;\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n const senders = origGetSenders.apply(this, []);\n senders.forEach(sender => sender._pc = this);\n return senders;\n };\n\n Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {\n get() {\n if (this._dtmf === undefined) {\n if (this.track.kind === 'audio') {\n this._dtmf = this._pc.createDTMFSender(this.track);\n } else {\n this._dtmf = null;\n }\n }\n return this._dtmf;\n }\n });\n }\n}\n\nfunction shimGetStats(window) {\n if (!window.RTCPeerConnection) {\n return;\n }\n\n const origGetStats = window.RTCPeerConnection.prototype.getStats;\n window.RTCPeerConnection.prototype.getStats = function getStats() {\n const [selector, onSucc, onErr] = arguments;\n\n // If selector is a function then we are in the old style stats so just\n // pass back the original getStats format to avoid breaking old users.\n if (arguments.length > 0 && typeof selector === 'function') {\n return origGetStats.apply(this, arguments);\n }\n\n // When spec-style getStats is supported, return those when called with\n // either no arguments or the selector argument is null.\n if (origGetStats.length === 0 && (arguments.length === 0 ||\n typeof selector !== 'function')) {\n return origGetStats.apply(this, []);\n }\n\n const fixChromeStats_ = function(response) {\n const standardReport = {};\n const reports = response.result();\n reports.forEach(report => {\n const standardStats = {\n id: report.id,\n timestamp: report.timestamp,\n type: {\n localcandidate: 'local-candidate',\n remotecandidate: 'remote-candidate'\n }[report.type] || report.type\n };\n report.names().forEach(name => {\n standardStats[name] = report.stat(name);\n });\n standardReport[standardStats.id] = standardStats;\n });\n\n return standardReport;\n };\n\n // shim getStats with maplike support\n const makeMapStats = function(stats) {\n return new Map(Object.keys(stats).map(key => [key, stats[key]]));\n };\n\n if (arguments.length >= 2) {\n const successCallbackWrapper_ = function(response) {\n onSucc(makeMapStats(fixChromeStats_(response)));\n };\n\n return origGetStats.apply(this, [successCallbackWrapper_,\n selector]);\n }\n\n // promise-support\n return new Promise((resolve, reject) => {\n origGetStats.apply(this, [\n function(response) {\n resolve(makeMapStats(fixChromeStats_(response)));\n }, reject]);\n }).then(onSucc, onErr);\n };\n}\n\nfunction shimSenderReceiverGetStats(window) {\n if (!(typeof window === 'object' && window.RTCPeerConnection &&\n window.RTCRtpSender && window.RTCRtpReceiver)) {\n return;\n }\n\n // shim sender stats.\n if (!('getStats' in window.RTCRtpSender.prototype)) {\n const origGetSenders = window.RTCPeerConnection.prototype.getSenders;\n if (origGetSenders) {\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n const senders = origGetSenders.apply(this, []);\n senders.forEach(sender => sender._pc = this);\n return senders;\n };\n }\n\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n if (origAddTrack) {\n window.RTCPeerConnection.prototype.addTrack = function addTrack() {\n const sender = origAddTrack.apply(this, arguments);\n sender._pc = this;\n return sender;\n };\n }\n window.RTCRtpSender.prototype.getStats = function getStats() {\n const sender = this;\n return this._pc.getStats().then(result =>\n /* Note: this will include stats of all senders that\n * send a track with the same id as sender.track as\n * it is not possible to identify the RTCRtpSender.\n */\n _utils_js__WEBPACK_IMPORTED_MODULE_0__.filterStats(result, sender.track, true));\n };\n }\n\n // shim receiver stats.\n if (!('getStats' in window.RTCRtpReceiver.prototype)) {\n const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;\n if (origGetReceivers) {\n window.RTCPeerConnection.prototype.getReceivers =\n function getReceivers() {\n const receivers = origGetReceivers.apply(this, []);\n receivers.forEach(receiver => receiver._pc = this);\n return receivers;\n };\n }\n _utils_js__WEBPACK_IMPORTED_MODULE_0__.wrapPeerConnectionEvent(window, 'track', e => {\n e.receiver._pc = e.srcElement;\n return e;\n });\n window.RTCRtpReceiver.prototype.getStats = function getStats() {\n const receiver = this;\n return this._pc.getStats().then(result =>\n _utils_js__WEBPACK_IMPORTED_MODULE_0__.filterStats(result, receiver.track, false));\n };\n }\n\n if (!('getStats' in window.RTCRtpSender.prototype &&\n 'getStats' in window.RTCRtpReceiver.prototype)) {\n return;\n }\n\n // shim RTCPeerConnection.getStats(track).\n const origGetStats = window.RTCPeerConnection.prototype.getStats;\n window.RTCPeerConnection.prototype.getStats = function getStats() {\n if (arguments.length > 0 &&\n arguments[0] instanceof window.MediaStreamTrack) {\n const track = arguments[0];\n let sender;\n let receiver;\n let err;\n this.getSenders().forEach(s => {\n if (s.track === track) {\n if (sender) {\n err = true;\n } else {\n sender = s;\n }\n }\n });\n this.getReceivers().forEach(r => {\n if (r.track === track) {\n if (receiver) {\n err = true;\n } else {\n receiver = r;\n }\n }\n return r.track === track;\n });\n if (err || (sender && receiver)) {\n return Promise.reject(new DOMException(\n 'There are more than one sender or receiver for the track.',\n 'InvalidAccessError'));\n } else if (sender) {\n return sender.getStats();\n } else if (receiver) {\n return receiver.getStats();\n }\n return Promise.reject(new DOMException(\n 'There is no sender or receiver for the track.',\n 'InvalidAccessError'));\n }\n return origGetStats.apply(this, arguments);\n };\n}\n\nfunction shimAddTrackRemoveTrackWithNative(window) {\n // shim addTrack/removeTrack with native variants in order to make\n // the interactions with legacy getLocalStreams behave as in other browsers.\n // Keeps a mapping stream.id => [stream, rtpsenders...]\n window.RTCPeerConnection.prototype.getLocalStreams =\n function getLocalStreams() {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n return Object.keys(this._shimmedLocalStreams)\n .map(streamId => this._shimmedLocalStreams[streamId][0]);\n };\n\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, stream) {\n if (!stream) {\n return origAddTrack.apply(this, arguments);\n }\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n\n const sender = origAddTrack.apply(this, arguments);\n if (!this._shimmedLocalStreams[stream.id]) {\n this._shimmedLocalStreams[stream.id] = [stream, sender];\n } else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) {\n this._shimmedLocalStreams[stream.id].push(sender);\n }\n return sender;\n };\n\n const origAddStream = window.RTCPeerConnection.prototype.addStream;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n\n stream.getTracks().forEach(track => {\n const alreadyExists = this.getSenders().find(s => s.track === track);\n if (alreadyExists) {\n throw new DOMException('Track already exists.',\n 'InvalidAccessError');\n }\n });\n const existingSenders = this.getSenders();\n origAddStream.apply(this, arguments);\n const newSenders = this.getSenders()\n .filter(newSender => existingSenders.indexOf(newSender) === -1);\n this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders);\n };\n\n const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n delete this._shimmedLocalStreams[stream.id];\n return origRemoveStream.apply(this, arguments);\n };\n\n const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;\n window.RTCPeerConnection.prototype.removeTrack =\n function removeTrack(sender) {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n if (sender) {\n Object.keys(this._shimmedLocalStreams).forEach(streamId => {\n const idx = this._shimmedLocalStreams[streamId].indexOf(sender);\n if (idx !== -1) {\n this._shimmedLocalStreams[streamId].splice(idx, 1);\n }\n if (this._shimmedLocalStreams[streamId].length === 1) {\n delete this._shimmedLocalStreams[streamId];\n }\n });\n }\n return origRemoveTrack.apply(this, arguments);\n };\n}\n\nfunction shimAddTrackRemoveTrack(window, browserDetails) {\n if (!window.RTCPeerConnection) {\n return;\n }\n // shim addTrack and removeTrack.\n if (window.RTCPeerConnection.prototype.addTrack &&\n browserDetails.version >= 65) {\n return shimAddTrackRemoveTrackWithNative(window);\n }\n\n // also shim pc.getLocalStreams when addTrack is shimmed\n // to return the original streams.\n const origGetLocalStreams = window.RTCPeerConnection.prototype\n .getLocalStreams;\n window.RTCPeerConnection.prototype.getLocalStreams =\n function getLocalStreams() {\n const nativeStreams = origGetLocalStreams.apply(this);\n this._reverseStreams = this._reverseStreams || {};\n return nativeStreams.map(stream => this._reverseStreams[stream.id]);\n };\n\n const origAddStream = window.RTCPeerConnection.prototype.addStream;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n this._streams = this._streams || {};\n this._reverseStreams = this._reverseStreams || {};\n\n stream.getTracks().forEach(track => {\n const alreadyExists = this.getSenders().find(s => s.track === track);\n if (alreadyExists) {\n throw new DOMException('Track already exists.',\n 'InvalidAccessError');\n }\n });\n // Add identity mapping for consistency with addTrack.\n // Unless this is being used with a stream from addTrack.\n if (!this._reverseStreams[stream.id]) {\n const newStream = new window.MediaStream(stream.getTracks());\n this._streams[stream.id] = newStream;\n this._reverseStreams[newStream.id] = stream;\n stream = newStream;\n }\n origAddStream.apply(this, [stream]);\n };\n\n const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n this._streams = this._streams || {};\n this._reverseStreams = this._reverseStreams || {};\n\n origRemoveStream.apply(this, [(this._streams[stream.id] || stream)]);\n delete this._reverseStreams[(this._streams[stream.id] ?\n this._streams[stream.id].id : stream.id)];\n delete this._streams[stream.id];\n };\n\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, stream) {\n if (this.signalingState === 'closed') {\n throw new DOMException(\n 'The RTCPeerConnection\\'s signalingState is \\'closed\\'.',\n 'InvalidStateError');\n }\n const streams = [].slice.call(arguments, 1);\n if (streams.length !== 1 ||\n !streams[0].getTracks().find(t => t === track)) {\n // this is not fully correct but all we can manage without\n // [[associated MediaStreams]] internal slot.\n throw new DOMException(\n 'The adapter.js addTrack polyfill only supports a single ' +\n ' stream which is associated with the specified track.',\n 'NotSupportedError');\n }\n\n const alreadyExists = this.getSenders().find(s => s.track === track);\n if (alreadyExists) {\n throw new DOMException('Track already exists.',\n 'InvalidAccessError');\n }\n\n this._streams = this._streams || {};\n this._reverseStreams = this._reverseStreams || {};\n const oldStream = this._streams[stream.id];\n if (oldStream) {\n // this is using odd Chrome behaviour, use with caution:\n // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815\n // Note: we rely on the high-level addTrack/dtmf shim to\n // create the sender with a dtmf sender.\n oldStream.addTrack(track);\n\n // Trigger ONN async.\n Promise.resolve().then(() => {\n this.dispatchEvent(new Event('negotiationneeded'));\n });\n } else {\n const newStream = new window.MediaStream([track]);\n this._streams[stream.id] = newStream;\n this._reverseStreams[newStream.id] = stream;\n this.addStream(newStream);\n }\n return this.getSenders().find(s => s.track === track);\n };\n\n // replace the internal stream id with the external one and\n // vice versa.\n function replaceInternalStreamId(pc, description) {\n let sdp = description.sdp;\n Object.keys(pc._reverseStreams || []).forEach(internalId => {\n const externalStream = pc._reverseStreams[internalId];\n const internalStream = pc._streams[externalStream.id];\n sdp = sdp.replace(new RegExp(internalStream.id, 'g'),\n externalStream.id);\n });\n return new RTCSessionDescription({\n type: description.type,\n sdp\n });\n }\n function replaceExternalStreamId(pc, description) {\n let sdp = description.sdp;\n Object.keys(pc._reverseStreams || []).forEach(internalId => {\n const externalStream = pc._reverseStreams[internalId];\n const internalStream = pc._streams[externalStream.id];\n sdp = sdp.replace(new RegExp(externalStream.id, 'g'),\n internalStream.id);\n });\n return new RTCSessionDescription({\n type: description.type,\n sdp\n });\n }\n ['createOffer', 'createAnswer'].forEach(function(method) {\n const nativeMethod = window.RTCPeerConnection.prototype[method];\n const methodObj = {[method]() {\n const args = arguments;\n const isLegacyCall = arguments.length &&\n typeof arguments[0] === 'function';\n if (isLegacyCall) {\n return nativeMethod.apply(this, [\n (description) => {\n const desc = replaceInternalStreamId(this, description);\n args[0].apply(null, [desc]);\n },\n (err) => {\n if (args[1]) {\n args[1].apply(null, err);\n }\n }, arguments[2]\n ]);\n }\n return nativeMethod.apply(this, arguments)\n .then(description => replaceInternalStreamId(this, description));\n }};\n window.RTCPeerConnection.prototype[method] = methodObj[method];\n });\n\n const origSetLocalDescription =\n window.RTCPeerConnection.prototype.setLocalDescription;\n window.RTCPeerConnection.prototype.setLocalDescription =\n function setLocalDescription() {\n if (!arguments.length || !arguments[0].type) {\n return origSetLocalDescription.apply(this, arguments);\n }\n arguments[0] = replaceExternalStreamId(this, arguments[0]);\n return origSetLocalDescription.apply(this, arguments);\n };\n\n // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier\n\n const origLocalDescription = Object.getOwnPropertyDescriptor(\n window.RTCPeerConnection.prototype, 'localDescription');\n Object.defineProperty(window.RTCPeerConnection.prototype,\n 'localDescription', {\n get() {\n const description = origLocalDescription.get.apply(this);\n if (description.type === '') {\n return description;\n }\n return replaceInternalStreamId(this, description);\n }\n });\n\n window.RTCPeerConnection.prototype.removeTrack =\n function removeTrack(sender) {\n if (this.signalingState === 'closed') {\n throw new DOMException(\n 'The RTCPeerConnection\\'s signalingState is \\'closed\\'.',\n 'InvalidStateError');\n }\n // We can not yet check for sender instanceof RTCRtpSender\n // since we shim RTPSender. So we check if sender._pc is set.\n if (!sender._pc) {\n throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' +\n 'does not implement interface RTCRtpSender.', 'TypeError');\n }\n const isLocal = sender._pc === this;\n if (!isLocal) {\n throw new DOMException('Sender was not created by this connection.',\n 'InvalidAccessError');\n }\n\n // Search for the native stream the senders track belongs to.\n this._streams = this._streams || {};\n let stream;\n Object.keys(this._streams).forEach(streamid => {\n const hasTrack = this._streams[streamid].getTracks()\n .find(track => sender.track === track);\n if (hasTrack) {\n stream = this._streams[streamid];\n }\n });\n\n if (stream) {\n if (stream.getTracks().length === 1) {\n // if this is the last track of the stream, remove the stream. This\n // takes care of any shimmed _senders.\n this.removeStream(this._reverseStreams[stream.id]);\n } else {\n // relying on the same odd chrome behaviour as above.\n stream.removeTrack(sender.track);\n }\n this.dispatchEvent(new Event('negotiationneeded'));\n }\n };\n}\n\nfunction shimPeerConnection(window, browserDetails) {\n if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) {\n // very basic support for old versions.\n window.RTCPeerConnection = window.webkitRTCPeerConnection;\n }\n if (!window.RTCPeerConnection) {\n return;\n }\n\n // shim implicit creation of RTCSessionDescription/RTCIceCandidate\n if (browserDetails.version < 53) {\n ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate']\n .forEach(function(method) {\n const nativeMethod = window.RTCPeerConnection.prototype[method];\n const methodObj = {[method]() {\n arguments[0] = new ((method === 'addIceCandidate') ?\n window.RTCIceCandidate :\n window.RTCSessionDescription)(arguments[0]);\n return nativeMethod.apply(this, arguments);\n }};\n window.RTCPeerConnection.prototype[method] = methodObj[method];\n });\n }\n}\n\n// Attempt to fix ONN in plan-b mode.\nfunction fixNegotiationNeeded(window, browserDetails) {\n _utils_js__WEBPACK_IMPORTED_MODULE_0__.wrapPeerConnectionEvent(window, 'negotiationneeded', e => {\n const pc = e.target;\n if (browserDetails.version < 72 || (pc.getConfiguration &&\n pc.getConfiguration().sdpSemantics === 'plan-b')) {\n if (pc.signalingState !== 'stable') {\n return;\n }\n }\n return e;\n });\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/chrome/chrome_shim.js?");
605
-
606
- /***/ }),
607
-
608
- /***/ "./node_modules/webrtc-adapter/src/js/chrome/getdisplaymedia.js":
609
- /*!**********************************************************************!*\
610
- !*** ./node_modules/webrtc-adapter/src/js/chrome/getdisplaymedia.js ***!
611
- \**********************************************************************/
612
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
613
-
614
- "use strict";
615
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ shimGetDisplayMedia: function() { return /* binding */ shimGetDisplayMedia; }\n/* harmony export */ });\n/*\n * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n\nfunction shimGetDisplayMedia(window, getSourceId) {\n if (window.navigator.mediaDevices &&\n 'getDisplayMedia' in window.navigator.mediaDevices) {\n return;\n }\n if (!(window.navigator.mediaDevices)) {\n return;\n }\n // getSourceId is a function that returns a promise resolving with\n // the sourceId of the screen/window/tab to be shared.\n if (typeof getSourceId !== 'function') {\n console.error('shimGetDisplayMedia: getSourceId argument is not ' +\n 'a function');\n return;\n }\n window.navigator.mediaDevices.getDisplayMedia =\n function getDisplayMedia(constraints) {\n return getSourceId(constraints)\n .then(sourceId => {\n const widthSpecified = constraints.video && constraints.video.width;\n const heightSpecified = constraints.video &&\n constraints.video.height;\n const frameRateSpecified = constraints.video &&\n constraints.video.frameRate;\n constraints.video = {\n mandatory: {\n chromeMediaSource: 'desktop',\n chromeMediaSourceId: sourceId,\n maxFrameRate: frameRateSpecified || 3\n }\n };\n if (widthSpecified) {\n constraints.video.mandatory.maxWidth = widthSpecified;\n }\n if (heightSpecified) {\n constraints.video.mandatory.maxHeight = heightSpecified;\n }\n return window.navigator.mediaDevices.getUserMedia(constraints);\n });\n };\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/chrome/getdisplaymedia.js?");
616
-
617
- /***/ }),
618
-
619
- /***/ "./node_modules/webrtc-adapter/src/js/chrome/getusermedia.js":
620
- /*!*******************************************************************!*\
621
- !*** ./node_modules/webrtc-adapter/src/js/chrome/getusermedia.js ***!
622
- \*******************************************************************/
623
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
624
-
625
- "use strict";
626
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ shimGetUserMedia: function() { return /* binding */ shimGetUserMedia; }\n/* harmony export */ });\n/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils.js */ \"./node_modules/webrtc-adapter/src/js/utils.js\");\n/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n\n\nconst logging = _utils_js__WEBPACK_IMPORTED_MODULE_0__.log;\n\nfunction shimGetUserMedia(window, browserDetails) {\n const navigator = window && window.navigator;\n\n if (!navigator.mediaDevices) {\n return;\n }\n\n const constraintsToChrome_ = function(c) {\n if (typeof c !== 'object' || c.mandatory || c.optional) {\n return c;\n }\n const cc = {};\n Object.keys(c).forEach(key => {\n if (key === 'require' || key === 'advanced' || key === 'mediaSource') {\n return;\n }\n const r = (typeof c[key] === 'object') ? c[key] : {ideal: c[key]};\n if (r.exact !== undefined && typeof r.exact === 'number') {\n r.min = r.max = r.exact;\n }\n const oldname_ = function(prefix, name) {\n if (prefix) {\n return prefix + name.charAt(0).toUpperCase() + name.slice(1);\n }\n return (name === 'deviceId') ? 'sourceId' : name;\n };\n if (r.ideal !== undefined) {\n cc.optional = cc.optional || [];\n let oc = {};\n if (typeof r.ideal === 'number') {\n oc[oldname_('min', key)] = r.ideal;\n cc.optional.push(oc);\n oc = {};\n oc[oldname_('max', key)] = r.ideal;\n cc.optional.push(oc);\n } else {\n oc[oldname_('', key)] = r.ideal;\n cc.optional.push(oc);\n }\n }\n if (r.exact !== undefined && typeof r.exact !== 'number') {\n cc.mandatory = cc.mandatory || {};\n cc.mandatory[oldname_('', key)] = r.exact;\n } else {\n ['min', 'max'].forEach(mix => {\n if (r[mix] !== undefined) {\n cc.mandatory = cc.mandatory || {};\n cc.mandatory[oldname_(mix, key)] = r[mix];\n }\n });\n }\n });\n if (c.advanced) {\n cc.optional = (cc.optional || []).concat(c.advanced);\n }\n return cc;\n };\n\n const shimConstraints_ = function(constraints, func) {\n if (browserDetails.version >= 61) {\n return func(constraints);\n }\n constraints = JSON.parse(JSON.stringify(constraints));\n if (constraints && typeof constraints.audio === 'object') {\n const remap = function(obj, a, b) {\n if (a in obj && !(b in obj)) {\n obj[b] = obj[a];\n delete obj[a];\n }\n };\n constraints = JSON.parse(JSON.stringify(constraints));\n remap(constraints.audio, 'autoGainControl', 'googAutoGainControl');\n remap(constraints.audio, 'noiseSuppression', 'googNoiseSuppression');\n constraints.audio = constraintsToChrome_(constraints.audio);\n }\n if (constraints && typeof constraints.video === 'object') {\n // Shim facingMode for mobile & surface pro.\n let face = constraints.video.facingMode;\n face = face && ((typeof face === 'object') ? face : {ideal: face});\n const getSupportedFacingModeLies = browserDetails.version < 66;\n\n if ((face && (face.exact === 'user' || face.exact === 'environment' ||\n face.ideal === 'user' || face.ideal === 'environment')) &&\n !(navigator.mediaDevices.getSupportedConstraints &&\n navigator.mediaDevices.getSupportedConstraints().facingMode &&\n !getSupportedFacingModeLies)) {\n delete constraints.video.facingMode;\n let matches;\n if (face.exact === 'environment' || face.ideal === 'environment') {\n matches = ['back', 'rear'];\n } else if (face.exact === 'user' || face.ideal === 'user') {\n matches = ['front'];\n }\n if (matches) {\n // Look for matches in label, or use last cam for back (typical).\n return navigator.mediaDevices.enumerateDevices()\n .then(devices => {\n devices = devices.filter(d => d.kind === 'videoinput');\n let dev = devices.find(d => matches.some(match =>\n d.label.toLowerCase().includes(match)));\n if (!dev && devices.length && matches.includes('back')) {\n dev = devices[devices.length - 1]; // more likely the back cam\n }\n if (dev) {\n constraints.video.deviceId = face.exact ? {exact: dev.deviceId} :\n {ideal: dev.deviceId};\n }\n constraints.video = constraintsToChrome_(constraints.video);\n logging('chrome: ' + JSON.stringify(constraints));\n return func(constraints);\n });\n }\n }\n constraints.video = constraintsToChrome_(constraints.video);\n }\n logging('chrome: ' + JSON.stringify(constraints));\n return func(constraints);\n };\n\n const shimError_ = function(e) {\n if (browserDetails.version >= 64) {\n return e;\n }\n return {\n name: {\n PermissionDeniedError: 'NotAllowedError',\n PermissionDismissedError: 'NotAllowedError',\n InvalidStateError: 'NotAllowedError',\n DevicesNotFoundError: 'NotFoundError',\n ConstraintNotSatisfiedError: 'OverconstrainedError',\n TrackStartError: 'NotReadableError',\n MediaDeviceFailedDueToShutdown: 'NotAllowedError',\n MediaDeviceKillSwitchOn: 'NotAllowedError',\n TabCaptureError: 'AbortError',\n ScreenCaptureError: 'AbortError',\n DeviceCaptureError: 'AbortError'\n }[e.name] || e.name,\n message: e.message,\n constraint: e.constraint || e.constraintName,\n toString() {\n return this.name + (this.message && ': ') + this.message;\n }\n };\n };\n\n const getUserMedia_ = function(constraints, onSuccess, onError) {\n shimConstraints_(constraints, c => {\n navigator.webkitGetUserMedia(c, onSuccess, e => {\n if (onError) {\n onError(shimError_(e));\n }\n });\n });\n };\n navigator.getUserMedia = getUserMedia_.bind(navigator);\n\n // Even though Chrome 45 has navigator.mediaDevices and a getUserMedia\n // function which returns a Promise, it does not accept spec-style\n // constraints.\n if (navigator.mediaDevices.getUserMedia) {\n const origGetUserMedia = navigator.mediaDevices.getUserMedia.\n bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = function(cs) {\n return shimConstraints_(cs, c => origGetUserMedia(c).then(stream => {\n if (c.audio && !stream.getAudioTracks().length ||\n c.video && !stream.getVideoTracks().length) {\n stream.getTracks().forEach(track => {\n track.stop();\n });\n throw new DOMException('', 'NotFoundError');\n }\n return stream;\n }, e => Promise.reject(shimError_(e))));\n };\n }\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/chrome/getusermedia.js?");
627
-
628
- /***/ }),
629
-
630
- /***/ "./node_modules/webrtc-adapter/src/js/common_shim.js":
631
- /*!***********************************************************!*\
632
- !*** ./node_modules/webrtc-adapter/src/js/common_shim.js ***!
633
- \***********************************************************/
634
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
635
-
636
- "use strict";
637
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ removeExtmapAllowMixed: function() { return /* binding */ removeExtmapAllowMixed; },\n/* harmony export */ shimAddIceCandidateNullOrEmpty: function() { return /* binding */ shimAddIceCandidateNullOrEmpty; },\n/* harmony export */ shimConnectionState: function() { return /* binding */ shimConnectionState; },\n/* harmony export */ shimMaxMessageSize: function() { return /* binding */ shimMaxMessageSize; },\n/* harmony export */ shimRTCIceCandidate: function() { return /* binding */ shimRTCIceCandidate; },\n/* harmony export */ shimSendThrowTypeError: function() { return /* binding */ shimSendThrowTypeError; }\n/* harmony export */ });\n/* harmony import */ var sdp__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! sdp */ \"./node_modules/sdp/sdp.js\");\n/* harmony import */ var sdp__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(sdp__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils */ \"./node_modules/webrtc-adapter/src/js/utils.js\");\n/*\n * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n\n\n\n\n\nfunction shimRTCIceCandidate(window) {\n // foundation is arbitrarily chosen as an indicator for full support for\n // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface\n if (!window.RTCIceCandidate || (window.RTCIceCandidate && 'foundation' in\n window.RTCIceCandidate.prototype)) {\n return;\n }\n\n const NativeRTCIceCandidate = window.RTCIceCandidate;\n window.RTCIceCandidate = function RTCIceCandidate(args) {\n // Remove the a= which shouldn't be part of the candidate string.\n if (typeof args === 'object' && args.candidate &&\n args.candidate.indexOf('a=') === 0) {\n args = JSON.parse(JSON.stringify(args));\n args.candidate = args.candidate.substr(2);\n }\n\n if (args.candidate && args.candidate.length) {\n // Augment the native candidate with the parsed fields.\n const nativeCandidate = new NativeRTCIceCandidate(args);\n const parsedCandidate = sdp__WEBPACK_IMPORTED_MODULE_0___default().parseCandidate(args.candidate);\n const augmentedCandidate = Object.assign(nativeCandidate,\n parsedCandidate);\n\n // Add a serializer that does not serialize the extra attributes.\n augmentedCandidate.toJSON = function toJSON() {\n return {\n candidate: augmentedCandidate.candidate,\n sdpMid: augmentedCandidate.sdpMid,\n sdpMLineIndex: augmentedCandidate.sdpMLineIndex,\n usernameFragment: augmentedCandidate.usernameFragment,\n };\n };\n return augmentedCandidate;\n }\n return new NativeRTCIceCandidate(args);\n };\n window.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype;\n\n // Hook up the augmented candidate in onicecandidate and\n // addEventListener('icecandidate', ...)\n _utils__WEBPACK_IMPORTED_MODULE_1__.wrapPeerConnectionEvent(window, 'icecandidate', e => {\n if (e.candidate) {\n Object.defineProperty(e, 'candidate', {\n value: new window.RTCIceCandidate(e.candidate),\n writable: 'false'\n });\n }\n return e;\n });\n}\n\nfunction shimMaxMessageSize(window, browserDetails) {\n if (!window.RTCPeerConnection) {\n return;\n }\n\n if (!('sctp' in window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'sctp', {\n get() {\n return typeof this._sctp === 'undefined' ? null : this._sctp;\n }\n });\n }\n\n const sctpInDescription = function(description) {\n if (!description || !description.sdp) {\n return false;\n }\n const sections = sdp__WEBPACK_IMPORTED_MODULE_0___default().splitSections(description.sdp);\n sections.shift();\n return sections.some(mediaSection => {\n const mLine = sdp__WEBPACK_IMPORTED_MODULE_0___default().parseMLine(mediaSection);\n return mLine && mLine.kind === 'application'\n && mLine.protocol.indexOf('SCTP') !== -1;\n });\n };\n\n const getRemoteFirefoxVersion = function(description) {\n // TODO: Is there a better solution for detecting Firefox?\n const match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\\d+)/);\n if (match === null || match.length < 2) {\n return -1;\n }\n const version = parseInt(match[1], 10);\n // Test for NaN (yes, this is ugly)\n return version !== version ? -1 : version;\n };\n\n const getCanSendMaxMessageSize = function(remoteIsFirefox) {\n // Every implementation we know can send at least 64 KiB.\n // Note: Although Chrome is technically able to send up to 256 KiB, the\n // data does not reach the other peer reliably.\n // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419\n let canSendMaxMessageSize = 65536;\n if (browserDetails.browser === 'firefox') {\n if (browserDetails.version < 57) {\n if (remoteIsFirefox === -1) {\n // FF < 57 will send in 16 KiB chunks using the deprecated PPID\n // fragmentation.\n canSendMaxMessageSize = 16384;\n } else {\n // However, other FF (and RAWRTC) can reassemble PPID-fragmented\n // messages. Thus, supporting ~2 GiB when sending.\n canSendMaxMessageSize = 2147483637;\n }\n } else if (browserDetails.version < 60) {\n // Currently, all FF >= 57 will reset the remote maximum message size\n // to the default value when a data channel is created at a later\n // stage. :(\n // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831\n canSendMaxMessageSize =\n browserDetails.version === 57 ? 65535 : 65536;\n } else {\n // FF >= 60 supports sending ~2 GiB\n canSendMaxMessageSize = 2147483637;\n }\n }\n return canSendMaxMessageSize;\n };\n\n const getMaxMessageSize = function(description, remoteIsFirefox) {\n // Note: 65536 bytes is the default value from the SDP spec. Also,\n // every implementation we know supports receiving 65536 bytes.\n let maxMessageSize = 65536;\n\n // FF 57 has a slightly incorrect default remote max message size, so\n // we need to adjust it here to avoid a failure when sending.\n // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697\n if (browserDetails.browser === 'firefox'\n && browserDetails.version === 57) {\n maxMessageSize = 65535;\n }\n\n const match = sdp__WEBPACK_IMPORTED_MODULE_0___default().matchPrefix(description.sdp,\n 'a=max-message-size:');\n if (match.length > 0) {\n maxMessageSize = parseInt(match[0].substr(19), 10);\n } else if (browserDetails.browser === 'firefox' &&\n remoteIsFirefox !== -1) {\n // If the maximum message size is not present in the remote SDP and\n // both local and remote are Firefox, the remote peer can receive\n // ~2 GiB.\n maxMessageSize = 2147483637;\n }\n return maxMessageSize;\n };\n\n const origSetRemoteDescription =\n window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription() {\n this._sctp = null;\n // Chrome decided to not expose .sctp in plan-b mode.\n // As usual, adapter.js has to do an 'ugly worakaround'\n // to cover up the mess.\n if (browserDetails.browser === 'chrome' && browserDetails.version >= 76) {\n const {sdpSemantics} = this.getConfiguration();\n if (sdpSemantics === 'plan-b') {\n Object.defineProperty(this, 'sctp', {\n get() {\n return typeof this._sctp === 'undefined' ? null : this._sctp;\n },\n enumerable: true,\n configurable: true,\n });\n }\n }\n\n if (sctpInDescription(arguments[0])) {\n // Check if the remote is FF.\n const isFirefox = getRemoteFirefoxVersion(arguments[0]);\n\n // Get the maximum message size the local peer is capable of sending\n const canSendMMS = getCanSendMaxMessageSize(isFirefox);\n\n // Get the maximum message size of the remote peer.\n const remoteMMS = getMaxMessageSize(arguments[0], isFirefox);\n\n // Determine final maximum message size\n let maxMessageSize;\n if (canSendMMS === 0 && remoteMMS === 0) {\n maxMessageSize = Number.POSITIVE_INFINITY;\n } else if (canSendMMS === 0 || remoteMMS === 0) {\n maxMessageSize = Math.max(canSendMMS, remoteMMS);\n } else {\n maxMessageSize = Math.min(canSendMMS, remoteMMS);\n }\n\n // Create a dummy RTCSctpTransport object and the 'maxMessageSize'\n // attribute.\n const sctp = {};\n Object.defineProperty(sctp, 'maxMessageSize', {\n get() {\n return maxMessageSize;\n }\n });\n this._sctp = sctp;\n }\n\n return origSetRemoteDescription.apply(this, arguments);\n };\n}\n\nfunction shimSendThrowTypeError(window) {\n if (!(window.RTCPeerConnection &&\n 'createDataChannel' in window.RTCPeerConnection.prototype)) {\n return;\n }\n\n // Note: Although Firefox >= 57 has a native implementation, the maximum\n // message size can be reset for all data channels at a later stage.\n // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831\n\n function wrapDcSend(dc, pc) {\n const origDataChannelSend = dc.send;\n dc.send = function send() {\n const data = arguments[0];\n const length = data.length || data.size || data.byteLength;\n if (dc.readyState === 'open' &&\n pc.sctp && length > pc.sctp.maxMessageSize) {\n throw new TypeError('Message too large (can send a maximum of ' +\n pc.sctp.maxMessageSize + ' bytes)');\n }\n return origDataChannelSend.apply(dc, arguments);\n };\n }\n const origCreateDataChannel =\n window.RTCPeerConnection.prototype.createDataChannel;\n window.RTCPeerConnection.prototype.createDataChannel =\n function createDataChannel() {\n const dataChannel = origCreateDataChannel.apply(this, arguments);\n wrapDcSend(dataChannel, this);\n return dataChannel;\n };\n _utils__WEBPACK_IMPORTED_MODULE_1__.wrapPeerConnectionEvent(window, 'datachannel', e => {\n wrapDcSend(e.channel, e.target);\n return e;\n });\n}\n\n\n/* shims RTCConnectionState by pretending it is the same as iceConnectionState.\n * See https://bugs.chromium.org/p/webrtc/issues/detail?id=6145#c12\n * for why this is a valid hack in Chrome. In Firefox it is slightly incorrect\n * since DTLS failures would be hidden. See\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1265827\n * for the Firefox tracking bug.\n */\nfunction shimConnectionState(window) {\n if (!window.RTCPeerConnection ||\n 'connectionState' in window.RTCPeerConnection.prototype) {\n return;\n }\n const proto = window.RTCPeerConnection.prototype;\n Object.defineProperty(proto, 'connectionState', {\n get() {\n return {\n completed: 'connected',\n checking: 'connecting'\n }[this.iceConnectionState] || this.iceConnectionState;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(proto, 'onconnectionstatechange', {\n get() {\n return this._onconnectionstatechange || null;\n },\n set(cb) {\n if (this._onconnectionstatechange) {\n this.removeEventListener('connectionstatechange',\n this._onconnectionstatechange);\n delete this._onconnectionstatechange;\n }\n if (cb) {\n this.addEventListener('connectionstatechange',\n this._onconnectionstatechange = cb);\n }\n },\n enumerable: true,\n configurable: true\n });\n\n ['setLocalDescription', 'setRemoteDescription'].forEach((method) => {\n const origMethod = proto[method];\n proto[method] = function() {\n if (!this._connectionstatechangepoly) {\n this._connectionstatechangepoly = e => {\n const pc = e.target;\n if (pc._lastConnectionState !== pc.connectionState) {\n pc._lastConnectionState = pc.connectionState;\n const newEvent = new Event('connectionstatechange', e);\n pc.dispatchEvent(newEvent);\n }\n return e;\n };\n this.addEventListener('iceconnectionstatechange',\n this._connectionstatechangepoly);\n }\n return origMethod.apply(this, arguments);\n };\n });\n}\n\nfunction removeExtmapAllowMixed(window, browserDetails) {\n /* remove a=extmap-allow-mixed for webrtc.org < M71 */\n if (!window.RTCPeerConnection) {\n return;\n }\n if (browserDetails.browser === 'chrome' && browserDetails.version >= 71) {\n return;\n }\n if (browserDetails.browser === 'safari' && browserDetails.version >= 605) {\n return;\n }\n const nativeSRD = window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription(desc) {\n if (desc && desc.sdp && desc.sdp.indexOf('\\na=extmap-allow-mixed') !== -1) {\n const sdp = desc.sdp.split('\\n').filter((line) => {\n return line.trim() !== 'a=extmap-allow-mixed';\n }).join('\\n');\n // Safari enforces read-only-ness of RTCSessionDescription fields.\n if (window.RTCSessionDescription &&\n desc instanceof window.RTCSessionDescription) {\n arguments[0] = new window.RTCSessionDescription({\n type: desc.type,\n sdp,\n });\n } else {\n desc.sdp = sdp;\n }\n }\n return nativeSRD.apply(this, arguments);\n };\n}\n\nfunction shimAddIceCandidateNullOrEmpty(window, browserDetails) {\n // Support for addIceCandidate(null or undefined)\n // as well as addIceCandidate({candidate: \"\", ...})\n // https://bugs.chromium.org/p/chromium/issues/detail?id=978582\n // Note: must be called before other polyfills which change the signature.\n if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) {\n return;\n }\n const nativeAddIceCandidate =\n window.RTCPeerConnection.prototype.addIceCandidate;\n if (!nativeAddIceCandidate || nativeAddIceCandidate.length === 0) {\n return;\n }\n window.RTCPeerConnection.prototype.addIceCandidate =\n function addIceCandidate() {\n if (!arguments[0]) {\n if (arguments[1]) {\n arguments[1].apply(null);\n }\n return Promise.resolve();\n }\n // Firefox 68+ emits and processes {candidate: \"\", ...}, ignore\n // in older versions.\n // Native support for ignoring exists for Chrome M77+.\n // Safari ignores as well, exact version unknown but works in the same\n // version that also ignores addIceCandidate(null).\n if (((browserDetails.browser === 'chrome' && browserDetails.version < 78)\n || (browserDetails.browser === 'firefox'\n && browserDetails.version < 68)\n || (browserDetails.browser === 'safari'))\n && arguments[0] && arguments[0].candidate === '') {\n return Promise.resolve();\n }\n return nativeAddIceCandidate.apply(this, arguments);\n };\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/common_shim.js?");
638
-
639
- /***/ }),
640
-
641
- /***/ "./node_modules/webrtc-adapter/src/js/edge/edge_shim.js":
642
- /*!**************************************************************!*\
643
- !*** ./node_modules/webrtc-adapter/src/js/edge/edge_shim.js ***!
644
- \**************************************************************/
645
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
646
-
647
- "use strict";
648
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ shimGetDisplayMedia: function() { return /* reexport safe */ _getdisplaymedia__WEBPACK_IMPORTED_MODULE_4__.shimGetDisplayMedia; },\n/* harmony export */ shimGetUserMedia: function() { return /* reexport safe */ _getusermedia__WEBPACK_IMPORTED_MODULE_3__.shimGetUserMedia; },\n/* harmony export */ shimPeerConnection: function() { return /* binding */ shimPeerConnection; },\n/* harmony export */ shimReplaceTrack: function() { return /* binding */ shimReplaceTrack; }\n/* harmony export */ });\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ \"./node_modules/webrtc-adapter/src/js/utils.js\");\n/* harmony import */ var _filtericeservers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./filtericeservers */ \"./node_modules/webrtc-adapter/src/js/edge/filtericeservers.js\");\n/* harmony import */ var rtcpeerconnection_shim__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rtcpeerconnection-shim */ \"./node_modules/rtcpeerconnection-shim/rtcpeerconnection.js\");\n/* harmony import */ var rtcpeerconnection_shim__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(rtcpeerconnection_shim__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _getusermedia__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getusermedia */ \"./node_modules/webrtc-adapter/src/js/edge/getusermedia.js\");\n/* harmony import */ var _getdisplaymedia__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./getdisplaymedia */ \"./node_modules/webrtc-adapter/src/js/edge/getdisplaymedia.js\");\n/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n\n\n\n\n\n\n\n\n\nfunction shimPeerConnection(window, browserDetails) {\n if (window.RTCIceGatherer) {\n if (!window.RTCIceCandidate) {\n window.RTCIceCandidate = function RTCIceCandidate(args) {\n return args;\n };\n }\n if (!window.RTCSessionDescription) {\n window.RTCSessionDescription = function RTCSessionDescription(args) {\n return args;\n };\n }\n // this adds an additional event listener to MediaStrackTrack that signals\n // when a tracks enabled property was changed. Workaround for a bug in\n // addStream, see below. No longer required in 15025+\n if (browserDetails.version < 15025) {\n const origMSTEnabled = Object.getOwnPropertyDescriptor(\n window.MediaStreamTrack.prototype, 'enabled');\n Object.defineProperty(window.MediaStreamTrack.prototype, 'enabled', {\n set(value) {\n origMSTEnabled.set.call(this, value);\n const ev = new Event('enabled');\n ev.enabled = value;\n this.dispatchEvent(ev);\n }\n });\n }\n }\n\n // ORTC defines the DTMF sender a bit different.\n // https://github.com/w3c/ortc/issues/714\n if (window.RTCRtpSender && !('dtmf' in window.RTCRtpSender.prototype)) {\n Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {\n get() {\n if (this._dtmf === undefined) {\n if (this.track.kind === 'audio') {\n this._dtmf = new window.RTCDtmfSender(this);\n } else if (this.track.kind === 'video') {\n this._dtmf = null;\n }\n }\n return this._dtmf;\n }\n });\n }\n // Edge currently only implements the RTCDtmfSender, not the\n // RTCDTMFSender alias. See http://draft.ortc.org/#rtcdtmfsender2*\n if (window.RTCDtmfSender && !window.RTCDTMFSender) {\n window.RTCDTMFSender = window.RTCDtmfSender;\n }\n\n const RTCPeerConnectionShim = rtcpeerconnection_shim__WEBPACK_IMPORTED_MODULE_2___default()(window,\n browserDetails.version);\n window.RTCPeerConnection = function RTCPeerConnection(config) {\n if (config && config.iceServers) {\n config.iceServers = (0,_filtericeservers__WEBPACK_IMPORTED_MODULE_1__.filterIceServers)(config.iceServers,\n browserDetails.version);\n _utils__WEBPACK_IMPORTED_MODULE_0__.log('ICE servers after filtering:', config.iceServers);\n }\n return new RTCPeerConnectionShim(config);\n };\n window.RTCPeerConnection.prototype = RTCPeerConnectionShim.prototype;\n}\n\nfunction shimReplaceTrack(window) {\n // ORTC has replaceTrack -- https://github.com/w3c/ortc/issues/614\n if (window.RTCRtpSender &&\n !('replaceTrack' in window.RTCRtpSender.prototype)) {\n window.RTCRtpSender.prototype.replaceTrack =\n window.RTCRtpSender.prototype.setTrack;\n }\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/edge/edge_shim.js?");
649
-
650
- /***/ }),
651
-
652
- /***/ "./node_modules/webrtc-adapter/src/js/edge/filtericeservers.js":
653
- /*!*********************************************************************!*\
654
- !*** ./node_modules/webrtc-adapter/src/js/edge/filtericeservers.js ***!
655
- \*********************************************************************/
656
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
657
-
658
- "use strict";
659
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ filterIceServers: function() { return /* binding */ filterIceServers; }\n/* harmony export */ });\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ \"./node_modules/webrtc-adapter/src/js/utils.js\");\n/*\n * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n\n\n\n// Edge does not like\n// 1) stun: filtered after 14393 unless ?transport=udp is present\n// 2) turn: that does not have all of turn:host:port?transport=udp\n// 3) turn: with ipv6 addresses\n// 4) turn: occurring muliple times\nfunction filterIceServers(iceServers, edgeVersion) {\n let hasTurn = false;\n iceServers = JSON.parse(JSON.stringify(iceServers));\n return iceServers.filter(server => {\n if (server && (server.urls || server.url)) {\n let urls = server.urls || server.url;\n if (server.url && !server.urls) {\n _utils__WEBPACK_IMPORTED_MODULE_0__.deprecated('RTCIceServer.url', 'RTCIceServer.urls');\n }\n const isString = typeof urls === 'string';\n if (isString) {\n urls = [urls];\n }\n urls = urls.filter(url => {\n // filter STUN unconditionally.\n if (url.indexOf('stun:') === 0) {\n return false;\n }\n\n const validTurn = url.startsWith('turn') &&\n !url.startsWith('turn:[') &&\n url.includes('transport=udp');\n if (validTurn && !hasTurn) {\n hasTurn = true;\n return true;\n }\n return validTurn && !hasTurn;\n });\n\n delete server.url;\n server.urls = isString ? urls[0] : urls;\n return !!urls.length;\n }\n });\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/edge/filtericeservers.js?");
660
-
661
- /***/ }),
662
-
663
- /***/ "./node_modules/webrtc-adapter/src/js/edge/getdisplaymedia.js":
664
- /*!********************************************************************!*\
665
- !*** ./node_modules/webrtc-adapter/src/js/edge/getdisplaymedia.js ***!
666
- \********************************************************************/
667
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
668
-
669
- "use strict";
670
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ shimGetDisplayMedia: function() { return /* binding */ shimGetDisplayMedia; }\n/* harmony export */ });\n/*\n * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n\n\nfunction shimGetDisplayMedia(window) {\n if (!('getDisplayMedia' in window.navigator)) {\n return;\n }\n if (!(window.navigator.mediaDevices)) {\n return;\n }\n if (window.navigator.mediaDevices &&\n 'getDisplayMedia' in window.navigator.mediaDevices) {\n return;\n }\n window.navigator.mediaDevices.getDisplayMedia =\n window.navigator.getDisplayMedia.bind(window.navigator);\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/edge/getdisplaymedia.js?");
671
-
672
- /***/ }),
673
-
674
- /***/ "./node_modules/webrtc-adapter/src/js/edge/getusermedia.js":
675
- /*!*****************************************************************!*\
676
- !*** ./node_modules/webrtc-adapter/src/js/edge/getusermedia.js ***!
677
- \*****************************************************************/
678
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
679
-
680
- "use strict";
681
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ shimGetUserMedia: function() { return /* binding */ shimGetUserMedia; }\n/* harmony export */ });\n/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n\n\nfunction shimGetUserMedia(window) {\n const navigator = window && window.navigator;\n\n const shimError_ = function(e) {\n return {\n name: {PermissionDeniedError: 'NotAllowedError'}[e.name] || e.name,\n message: e.message,\n constraint: e.constraint,\n toString() {\n return this.name;\n }\n };\n };\n\n // getUserMedia error shim.\n const origGetUserMedia = navigator.mediaDevices.getUserMedia.\n bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = function(c) {\n return origGetUserMedia(c).catch(e => Promise.reject(shimError_(e)));\n };\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/edge/getusermedia.js?");
682
-
683
- /***/ }),
684
-
685
- /***/ "./node_modules/webrtc-adapter/src/js/firefox/firefox_shim.js":
686
- /*!********************************************************************!*\
687
- !*** ./node_modules/webrtc-adapter/src/js/firefox/firefox_shim.js ***!
688
- \********************************************************************/
689
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
690
-
691
- "use strict";
692
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ shimAddTransceiver: function() { return /* binding */ shimAddTransceiver; },\n/* harmony export */ shimCreateAnswer: function() { return /* binding */ shimCreateAnswer; },\n/* harmony export */ shimCreateOffer: function() { return /* binding */ shimCreateOffer; },\n/* harmony export */ shimGetDisplayMedia: function() { return /* reexport safe */ _getdisplaymedia__WEBPACK_IMPORTED_MODULE_2__.shimGetDisplayMedia; },\n/* harmony export */ shimGetParameters: function() { return /* binding */ shimGetParameters; },\n/* harmony export */ shimGetUserMedia: function() { return /* reexport safe */ _getusermedia__WEBPACK_IMPORTED_MODULE_1__.shimGetUserMedia; },\n/* harmony export */ shimOnTrack: function() { return /* binding */ shimOnTrack; },\n/* harmony export */ shimPeerConnection: function() { return /* binding */ shimPeerConnection; },\n/* harmony export */ shimRTCDataChannel: function() { return /* binding */ shimRTCDataChannel; },\n/* harmony export */ shimReceiverGetStats: function() { return /* binding */ shimReceiverGetStats; },\n/* harmony export */ shimRemoveStream: function() { return /* binding */ shimRemoveStream; },\n/* harmony export */ shimSenderGetStats: function() { return /* binding */ shimSenderGetStats; }\n/* harmony export */ });\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ \"./node_modules/webrtc-adapter/src/js/utils.js\");\n/* harmony import */ var _getusermedia__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getusermedia */ \"./node_modules/webrtc-adapter/src/js/firefox/getusermedia.js\");\n/* harmony import */ var _getdisplaymedia__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getdisplaymedia */ \"./node_modules/webrtc-adapter/src/js/firefox/getdisplaymedia.js\");\n/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n\n\n\n\n\n\nfunction shimOnTrack(window) {\n if (typeof window === 'object' && window.RTCTrackEvent &&\n ('receiver' in window.RTCTrackEvent.prototype) &&\n !('transceiver' in window.RTCTrackEvent.prototype)) {\n Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {\n get() {\n return {receiver: this.receiver};\n }\n });\n }\n}\n\nfunction shimPeerConnection(window, browserDetails) {\n if (typeof window !== 'object' ||\n !(window.RTCPeerConnection || window.mozRTCPeerConnection)) {\n return; // probably media.peerconnection.enabled=false in about:config\n }\n if (!window.RTCPeerConnection && window.mozRTCPeerConnection) {\n // very basic support for old versions.\n window.RTCPeerConnection = window.mozRTCPeerConnection;\n }\n\n if (browserDetails.version < 53) {\n // shim away need for obsolete RTCIceCandidate/RTCSessionDescription.\n ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate']\n .forEach(function(method) {\n const nativeMethod = window.RTCPeerConnection.prototype[method];\n const methodObj = {[method]() {\n arguments[0] = new ((method === 'addIceCandidate') ?\n window.RTCIceCandidate :\n window.RTCSessionDescription)(arguments[0]);\n return nativeMethod.apply(this, arguments);\n }};\n window.RTCPeerConnection.prototype[method] = methodObj[method];\n });\n }\n\n const modernStatsTypes = {\n inboundrtp: 'inbound-rtp',\n outboundrtp: 'outbound-rtp',\n candidatepair: 'candidate-pair',\n localcandidate: 'local-candidate',\n remotecandidate: 'remote-candidate'\n };\n\n const nativeGetStats = window.RTCPeerConnection.prototype.getStats;\n window.RTCPeerConnection.prototype.getStats = function getStats() {\n const [selector, onSucc, onErr] = arguments;\n return nativeGetStats.apply(this, [selector || null])\n .then(stats => {\n if (browserDetails.version < 53 && !onSucc) {\n // Shim only promise getStats with spec-hyphens in type names\n // Leave callback version alone; misc old uses of forEach before Map\n try {\n stats.forEach(stat => {\n stat.type = modernStatsTypes[stat.type] || stat.type;\n });\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n // Avoid TypeError: \"type\" is read-only, in old versions. 34-43ish\n stats.forEach((stat, i) => {\n stats.set(i, Object.assign({}, stat, {\n type: modernStatsTypes[stat.type] || stat.type\n }));\n });\n }\n }\n return stats;\n })\n .then(onSucc, onErr);\n };\n}\n\nfunction shimSenderGetStats(window) {\n if (!(typeof window === 'object' && window.RTCPeerConnection &&\n window.RTCRtpSender)) {\n return;\n }\n if (window.RTCRtpSender && 'getStats' in window.RTCRtpSender.prototype) {\n return;\n }\n const origGetSenders = window.RTCPeerConnection.prototype.getSenders;\n if (origGetSenders) {\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n const senders = origGetSenders.apply(this, []);\n senders.forEach(sender => sender._pc = this);\n return senders;\n };\n }\n\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n if (origAddTrack) {\n window.RTCPeerConnection.prototype.addTrack = function addTrack() {\n const sender = origAddTrack.apply(this, arguments);\n sender._pc = this;\n return sender;\n };\n }\n window.RTCRtpSender.prototype.getStats = function getStats() {\n return this.track ? this._pc.getStats(this.track) :\n Promise.resolve(new Map());\n };\n}\n\nfunction shimReceiverGetStats(window) {\n if (!(typeof window === 'object' && window.RTCPeerConnection &&\n window.RTCRtpSender)) {\n return;\n }\n if (window.RTCRtpSender && 'getStats' in window.RTCRtpReceiver.prototype) {\n return;\n }\n const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;\n if (origGetReceivers) {\n window.RTCPeerConnection.prototype.getReceivers = function getReceivers() {\n const receivers = origGetReceivers.apply(this, []);\n receivers.forEach(receiver => receiver._pc = this);\n return receivers;\n };\n }\n _utils__WEBPACK_IMPORTED_MODULE_0__.wrapPeerConnectionEvent(window, 'track', e => {\n e.receiver._pc = e.srcElement;\n return e;\n });\n window.RTCRtpReceiver.prototype.getStats = function getStats() {\n return this._pc.getStats(this.track);\n };\n}\n\nfunction shimRemoveStream(window) {\n if (!window.RTCPeerConnection ||\n 'removeStream' in window.RTCPeerConnection.prototype) {\n return;\n }\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n _utils__WEBPACK_IMPORTED_MODULE_0__.deprecated('removeStream', 'removeTrack');\n this.getSenders().forEach(sender => {\n if (sender.track && stream.getTracks().includes(sender.track)) {\n this.removeTrack(sender);\n }\n });\n };\n}\n\nfunction shimRTCDataChannel(window) {\n // rename DataChannel to RTCDataChannel (native fix in FF60):\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1173851\n if (window.DataChannel && !window.RTCDataChannel) {\n window.RTCDataChannel = window.DataChannel;\n }\n}\n\nfunction shimAddTransceiver(window) {\n // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647\n // Firefox ignores the init sendEncodings options passed to addTransceiver\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918\n if (!(typeof window === 'object' && window.RTCPeerConnection)) {\n return;\n }\n const origAddTransceiver = window.RTCPeerConnection.prototype.addTransceiver;\n if (origAddTransceiver) {\n window.RTCPeerConnection.prototype.addTransceiver =\n function addTransceiver() {\n this.setParametersPromises = [];\n const initParameters = arguments[1];\n const shouldPerformCheck = initParameters &&\n 'sendEncodings' in initParameters;\n if (shouldPerformCheck) {\n // If sendEncodings params are provided, validate grammar\n initParameters.sendEncodings.forEach((encodingParam) => {\n if ('rid' in encodingParam) {\n const ridRegex = /^[a-z0-9]{0,16}$/i;\n if (!ridRegex.test(encodingParam.rid)) {\n throw new TypeError('Invalid RID value provided.');\n }\n }\n if ('scaleResolutionDownBy' in encodingParam) {\n if (!(parseFloat(encodingParam.scaleResolutionDownBy) >= 1.0)) {\n throw new RangeError('scale_resolution_down_by must be >= 1.0');\n }\n }\n if ('maxFramerate' in encodingParam) {\n if (!(parseFloat(encodingParam.maxFramerate) >= 0)) {\n throw new RangeError('max_framerate must be >= 0.0');\n }\n }\n });\n }\n const transceiver = origAddTransceiver.apply(this, arguments);\n if (shouldPerformCheck) {\n // Check if the init options were applied. If not we do this in an\n // asynchronous way and save the promise reference in a global object.\n // This is an ugly hack, but at the same time is way more robust than\n // checking the sender parameters before and after the createOffer\n // Also note that after the createoffer we are not 100% sure that\n // the params were asynchronously applied so we might miss the\n // opportunity to recreate offer.\n const {sender} = transceiver;\n const params = sender.getParameters();\n if (!('encodings' in params) ||\n // Avoid being fooled by patched getParameters() below.\n (params.encodings.length === 1 &&\n Object.keys(params.encodings[0]).length === 0)) {\n params.encodings = initParameters.sendEncodings;\n sender.sendEncodings = initParameters.sendEncodings;\n this.setParametersPromises.push(sender.setParameters(params)\n .then(() => {\n delete sender.sendEncodings;\n }).catch(() => {\n delete sender.sendEncodings;\n })\n );\n }\n }\n return transceiver;\n };\n }\n}\n\nfunction shimGetParameters(window) {\n if (!(typeof window === 'object' && window.RTCRtpSender)) {\n return;\n }\n const origGetParameters = window.RTCRtpSender.prototype.getParameters;\n if (origGetParameters) {\n window.RTCRtpSender.prototype.getParameters =\n function getParameters() {\n const params = origGetParameters.apply(this, arguments);\n if (!('encodings' in params)) {\n params.encodings = [].concat(this.sendEncodings || [{}]);\n }\n return params;\n };\n }\n}\n\nfunction shimCreateOffer(window) {\n // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647\n // Firefox ignores the init sendEncodings options passed to addTransceiver\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918\n if (!(typeof window === 'object' && window.RTCPeerConnection)) {\n return;\n }\n const origCreateOffer = window.RTCPeerConnection.prototype.createOffer;\n window.RTCPeerConnection.prototype.createOffer = function createOffer() {\n if (this.setParametersPromises && this.setParametersPromises.length) {\n return Promise.all(this.setParametersPromises)\n .then(() => {\n return origCreateOffer.apply(this, arguments);\n })\n .finally(() => {\n this.setParametersPromises = [];\n });\n }\n return origCreateOffer.apply(this, arguments);\n };\n}\n\nfunction shimCreateAnswer(window) {\n // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647\n // Firefox ignores the init sendEncodings options passed to addTransceiver\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918\n if (!(typeof window === 'object' && window.RTCPeerConnection)) {\n return;\n }\n const origCreateAnswer = window.RTCPeerConnection.prototype.createAnswer;\n window.RTCPeerConnection.prototype.createAnswer = function createAnswer() {\n if (this.setParametersPromises && this.setParametersPromises.length) {\n return Promise.all(this.setParametersPromises)\n .then(() => {\n return origCreateAnswer.apply(this, arguments);\n })\n .finally(() => {\n this.setParametersPromises = [];\n });\n }\n return origCreateAnswer.apply(this, arguments);\n };\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/firefox/firefox_shim.js?");
693
-
694
- /***/ }),
695
-
696
- /***/ "./node_modules/webrtc-adapter/src/js/firefox/getdisplaymedia.js":
697
- /*!***********************************************************************!*\
698
- !*** ./node_modules/webrtc-adapter/src/js/firefox/getdisplaymedia.js ***!
699
- \***********************************************************************/
700
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
701
-
702
- "use strict";
703
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ shimGetDisplayMedia: function() { return /* binding */ shimGetDisplayMedia; }\n/* harmony export */ });\n/*\n * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n\n\nfunction shimGetDisplayMedia(window, preferredMediaSource) {\n if (window.navigator.mediaDevices &&\n 'getDisplayMedia' in window.navigator.mediaDevices) {\n return;\n }\n if (!(window.navigator.mediaDevices)) {\n return;\n }\n window.navigator.mediaDevices.getDisplayMedia =\n function getDisplayMedia(constraints) {\n if (!(constraints && constraints.video)) {\n const err = new DOMException('getDisplayMedia without video ' +\n 'constraints is undefined');\n err.name = 'NotFoundError';\n // from https://heycam.github.io/webidl/#idl-DOMException-error-names\n err.code = 8;\n return Promise.reject(err);\n }\n if (constraints.video === true) {\n constraints.video = {mediaSource: preferredMediaSource};\n } else {\n constraints.video.mediaSource = preferredMediaSource;\n }\n return window.navigator.mediaDevices.getUserMedia(constraints);\n };\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/firefox/getdisplaymedia.js?");
704
-
705
- /***/ }),
706
-
707
- /***/ "./node_modules/webrtc-adapter/src/js/firefox/getusermedia.js":
708
- /*!********************************************************************!*\
709
- !*** ./node_modules/webrtc-adapter/src/js/firefox/getusermedia.js ***!
710
- \********************************************************************/
711
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
712
-
713
- "use strict";
714
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ shimGetUserMedia: function() { return /* binding */ shimGetUserMedia; }\n/* harmony export */ });\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ \"./node_modules/webrtc-adapter/src/js/utils.js\");\n/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n\n\n\n\nfunction shimGetUserMedia(window, browserDetails) {\n const navigator = window && window.navigator;\n const MediaStreamTrack = window && window.MediaStreamTrack;\n\n navigator.getUserMedia = function(constraints, onSuccess, onError) {\n // Replace Firefox 44+'s deprecation warning with unprefixed version.\n _utils__WEBPACK_IMPORTED_MODULE_0__.deprecated('navigator.getUserMedia',\n 'navigator.mediaDevices.getUserMedia');\n navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);\n };\n\n if (!(browserDetails.version > 55 &&\n 'autoGainControl' in navigator.mediaDevices.getSupportedConstraints())) {\n const remap = function(obj, a, b) {\n if (a in obj && !(b in obj)) {\n obj[b] = obj[a];\n delete obj[a];\n }\n };\n\n const nativeGetUserMedia = navigator.mediaDevices.getUserMedia.\n bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = function(c) {\n if (typeof c === 'object' && typeof c.audio === 'object') {\n c = JSON.parse(JSON.stringify(c));\n remap(c.audio, 'autoGainControl', 'mozAutoGainControl');\n remap(c.audio, 'noiseSuppression', 'mozNoiseSuppression');\n }\n return nativeGetUserMedia(c);\n };\n\n if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) {\n const nativeGetSettings = MediaStreamTrack.prototype.getSettings;\n MediaStreamTrack.prototype.getSettings = function() {\n const obj = nativeGetSettings.apply(this, arguments);\n remap(obj, 'mozAutoGainControl', 'autoGainControl');\n remap(obj, 'mozNoiseSuppression', 'noiseSuppression');\n return obj;\n };\n }\n\n if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) {\n const nativeApplyConstraints =\n MediaStreamTrack.prototype.applyConstraints;\n MediaStreamTrack.prototype.applyConstraints = function(c) {\n if (this.kind === 'audio' && typeof c === 'object') {\n c = JSON.parse(JSON.stringify(c));\n remap(c, 'autoGainControl', 'mozAutoGainControl');\n remap(c, 'noiseSuppression', 'mozNoiseSuppression');\n }\n return nativeApplyConstraints.apply(this, [c]);\n };\n }\n }\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/firefox/getusermedia.js?");
715
-
716
- /***/ }),
717
-
718
- /***/ "./node_modules/webrtc-adapter/src/js/safari/safari_shim.js":
719
- /*!******************************************************************!*\
720
- !*** ./node_modules/webrtc-adapter/src/js/safari/safari_shim.js ***!
721
- \******************************************************************/
722
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
723
-
724
- "use strict";
725
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ shimAudioContext: function() { return /* binding */ shimAudioContext; },\n/* harmony export */ shimCallbacksAPI: function() { return /* binding */ shimCallbacksAPI; },\n/* harmony export */ shimConstraints: function() { return /* binding */ shimConstraints; },\n/* harmony export */ shimCreateOfferLegacy: function() { return /* binding */ shimCreateOfferLegacy; },\n/* harmony export */ shimGetUserMedia: function() { return /* binding */ shimGetUserMedia; },\n/* harmony export */ shimLocalStreamsAPI: function() { return /* binding */ shimLocalStreamsAPI; },\n/* harmony export */ shimRTCIceServerUrls: function() { return /* binding */ shimRTCIceServerUrls; },\n/* harmony export */ shimRemoteStreamsAPI: function() { return /* binding */ shimRemoteStreamsAPI; },\n/* harmony export */ shimTrackEventTransceiver: function() { return /* binding */ shimTrackEventTransceiver; }\n/* harmony export */ });\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ \"./node_modules/webrtc-adapter/src/js/utils.js\");\n/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n\n\n\nfunction shimLocalStreamsAPI(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.getLocalStreams =\n function getLocalStreams() {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n return this._localStreams;\n };\n }\n if (!('addStream' in window.RTCPeerConnection.prototype)) {\n const _addTrack = window.RTCPeerConnection.prototype.addTrack;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n if (!this._localStreams.includes(stream)) {\n this._localStreams.push(stream);\n }\n // Try to emulate Chrome's behaviour of adding in audio-video order.\n // Safari orders by track id.\n stream.getAudioTracks().forEach(track => _addTrack.call(this, track,\n stream));\n stream.getVideoTracks().forEach(track => _addTrack.call(this, track,\n stream));\n };\n\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, ...streams) {\n if (streams) {\n streams.forEach((stream) => {\n if (!this._localStreams) {\n this._localStreams = [stream];\n } else if (!this._localStreams.includes(stream)) {\n this._localStreams.push(stream);\n }\n });\n }\n return _addTrack.apply(this, arguments);\n };\n }\n if (!('removeStream' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n const index = this._localStreams.indexOf(stream);\n if (index === -1) {\n return;\n }\n this._localStreams.splice(index, 1);\n const tracks = stream.getTracks();\n this.getSenders().forEach(sender => {\n if (tracks.includes(sender.track)) {\n this.removeTrack(sender);\n }\n });\n };\n }\n}\n\nfunction shimRemoteStreamsAPI(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.getRemoteStreams =\n function getRemoteStreams() {\n return this._remoteStreams ? this._remoteStreams : [];\n };\n }\n if (!('onaddstream' in window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', {\n get() {\n return this._onaddstream;\n },\n set(f) {\n if (this._onaddstream) {\n this.removeEventListener('addstream', this._onaddstream);\n this.removeEventListener('track', this._onaddstreampoly);\n }\n this.addEventListener('addstream', this._onaddstream = f);\n this.addEventListener('track', this._onaddstreampoly = (e) => {\n e.streams.forEach(stream => {\n if (!this._remoteStreams) {\n this._remoteStreams = [];\n }\n if (this._remoteStreams.includes(stream)) {\n return;\n }\n this._remoteStreams.push(stream);\n const event = new Event('addstream');\n event.stream = stream;\n this.dispatchEvent(event);\n });\n });\n }\n });\n const origSetRemoteDescription =\n window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription() {\n const pc = this;\n if (!this._onaddstreampoly) {\n this.addEventListener('track', this._onaddstreampoly = function(e) {\n e.streams.forEach(stream => {\n if (!pc._remoteStreams) {\n pc._remoteStreams = [];\n }\n if (pc._remoteStreams.indexOf(stream) >= 0) {\n return;\n }\n pc._remoteStreams.push(stream);\n const event = new Event('addstream');\n event.stream = stream;\n pc.dispatchEvent(event);\n });\n });\n }\n return origSetRemoteDescription.apply(pc, arguments);\n };\n }\n}\n\nfunction shimCallbacksAPI(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n const prototype = window.RTCPeerConnection.prototype;\n const origCreateOffer = prototype.createOffer;\n const origCreateAnswer = prototype.createAnswer;\n const setLocalDescription = prototype.setLocalDescription;\n const setRemoteDescription = prototype.setRemoteDescription;\n const addIceCandidate = prototype.addIceCandidate;\n\n prototype.createOffer =\n function createOffer(successCallback, failureCallback) {\n const options = (arguments.length >= 2) ? arguments[2] : arguments[0];\n const promise = origCreateOffer.apply(this, [options]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n\n prototype.createAnswer =\n function createAnswer(successCallback, failureCallback) {\n const options = (arguments.length >= 2) ? arguments[2] : arguments[0];\n const promise = origCreateAnswer.apply(this, [options]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n\n let withCallback = function(description, successCallback, failureCallback) {\n const promise = setLocalDescription.apply(this, [description]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.setLocalDescription = withCallback;\n\n withCallback = function(description, successCallback, failureCallback) {\n const promise = setRemoteDescription.apply(this, [description]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.setRemoteDescription = withCallback;\n\n withCallback = function(candidate, successCallback, failureCallback) {\n const promise = addIceCandidate.apply(this, [candidate]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.addIceCandidate = withCallback;\n}\n\nfunction shimGetUserMedia(window) {\n const navigator = window && window.navigator;\n\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n // shim not needed in Safari 12.1\n const mediaDevices = navigator.mediaDevices;\n const _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices);\n navigator.mediaDevices.getUserMedia = (constraints) => {\n return _getUserMedia(shimConstraints(constraints));\n };\n }\n\n if (!navigator.getUserMedia && navigator.mediaDevices &&\n navigator.mediaDevices.getUserMedia) {\n navigator.getUserMedia = function getUserMedia(constraints, cb, errcb) {\n navigator.mediaDevices.getUserMedia(constraints)\n .then(cb, errcb);\n }.bind(navigator);\n }\n}\n\nfunction shimConstraints(constraints) {\n if (constraints && constraints.video !== undefined) {\n return Object.assign({},\n constraints,\n {video: _utils__WEBPACK_IMPORTED_MODULE_0__.compactObject(constraints.video)}\n );\n }\n\n return constraints;\n}\n\nfunction shimRTCIceServerUrls(window) {\n if (!window.RTCPeerConnection) {\n return;\n }\n // migrate from non-spec RTCIceServer.url to RTCIceServer.urls\n const OrigPeerConnection = window.RTCPeerConnection;\n window.RTCPeerConnection =\n function RTCPeerConnection(pcConfig, pcConstraints) {\n if (pcConfig && pcConfig.iceServers) {\n const newIceServers = [];\n for (let i = 0; i < pcConfig.iceServers.length; i++) {\n let server = pcConfig.iceServers[i];\n if (!server.hasOwnProperty('urls') &&\n server.hasOwnProperty('url')) {\n _utils__WEBPACK_IMPORTED_MODULE_0__.deprecated('RTCIceServer.url', 'RTCIceServer.urls');\n server = JSON.parse(JSON.stringify(server));\n server.urls = server.url;\n delete server.url;\n newIceServers.push(server);\n } else {\n newIceServers.push(pcConfig.iceServers[i]);\n }\n }\n pcConfig.iceServers = newIceServers;\n }\n return new OrigPeerConnection(pcConfig, pcConstraints);\n };\n window.RTCPeerConnection.prototype = OrigPeerConnection.prototype;\n // wrap static methods. Currently just generateCertificate.\n if ('generateCertificate' in OrigPeerConnection) {\n Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {\n get() {\n return OrigPeerConnection.generateCertificate;\n }\n });\n }\n}\n\nfunction shimTrackEventTransceiver(window) {\n // Add event.transceiver member over deprecated event.receiver\n if (typeof window === 'object' && window.RTCTrackEvent &&\n 'receiver' in window.RTCTrackEvent.prototype &&\n !('transceiver' in window.RTCTrackEvent.prototype)) {\n Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {\n get() {\n return {receiver: this.receiver};\n }\n });\n }\n}\n\nfunction shimCreateOfferLegacy(window) {\n const origCreateOffer = window.RTCPeerConnection.prototype.createOffer;\n window.RTCPeerConnection.prototype.createOffer =\n function createOffer(offerOptions) {\n if (offerOptions) {\n if (typeof offerOptions.offerToReceiveAudio !== 'undefined') {\n // support bit values\n offerOptions.offerToReceiveAudio =\n !!offerOptions.offerToReceiveAudio;\n }\n const audioTransceiver = this.getTransceivers().find(transceiver =>\n transceiver.receiver.track.kind === 'audio');\n if (offerOptions.offerToReceiveAudio === false && audioTransceiver) {\n if (audioTransceiver.direction === 'sendrecv') {\n if (audioTransceiver.setDirection) {\n audioTransceiver.setDirection('sendonly');\n } else {\n audioTransceiver.direction = 'sendonly';\n }\n } else if (audioTransceiver.direction === 'recvonly') {\n if (audioTransceiver.setDirection) {\n audioTransceiver.setDirection('inactive');\n } else {\n audioTransceiver.direction = 'inactive';\n }\n }\n } else if (offerOptions.offerToReceiveAudio === true &&\n !audioTransceiver) {\n this.addTransceiver('audio');\n }\n\n if (typeof offerOptions.offerToReceiveVideo !== 'undefined') {\n // support bit values\n offerOptions.offerToReceiveVideo =\n !!offerOptions.offerToReceiveVideo;\n }\n const videoTransceiver = this.getTransceivers().find(transceiver =>\n transceiver.receiver.track.kind === 'video');\n if (offerOptions.offerToReceiveVideo === false && videoTransceiver) {\n if (videoTransceiver.direction === 'sendrecv') {\n if (videoTransceiver.setDirection) {\n videoTransceiver.setDirection('sendonly');\n } else {\n videoTransceiver.direction = 'sendonly';\n }\n } else if (videoTransceiver.direction === 'recvonly') {\n if (videoTransceiver.setDirection) {\n videoTransceiver.setDirection('inactive');\n } else {\n videoTransceiver.direction = 'inactive';\n }\n }\n } else if (offerOptions.offerToReceiveVideo === true &&\n !videoTransceiver) {\n this.addTransceiver('video');\n }\n }\n return origCreateOffer.apply(this, arguments);\n };\n}\n\nfunction shimAudioContext(window) {\n if (typeof window !== 'object' || window.AudioContext) {\n return;\n }\n window.AudioContext = window.webkitAudioContext;\n}\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/safari/safari_shim.js?");
726
-
727
- /***/ }),
728
-
729
- /***/ "./node_modules/webrtc-adapter/src/js/utils.js":
730
- /*!*****************************************************!*\
731
- !*** ./node_modules/webrtc-adapter/src/js/utils.js ***!
732
- \*****************************************************/
733
- /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
734
-
735
- "use strict";
736
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ compactObject: function() { return /* binding */ compactObject; },\n/* harmony export */ deprecated: function() { return /* binding */ deprecated; },\n/* harmony export */ detectBrowser: function() { return /* binding */ detectBrowser; },\n/* harmony export */ disableLog: function() { return /* binding */ disableLog; },\n/* harmony export */ disableWarnings: function() { return /* binding */ disableWarnings; },\n/* harmony export */ extractVersion: function() { return /* binding */ extractVersion; },\n/* harmony export */ filterStats: function() { return /* binding */ filterStats; },\n/* harmony export */ log: function() { return /* binding */ log; },\n/* harmony export */ walkStats: function() { return /* binding */ walkStats; },\n/* harmony export */ wrapPeerConnectionEvent: function() { return /* binding */ wrapPeerConnectionEvent; }\n/* harmony export */ });\n/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n /* eslint-env node */\n\n\nlet logDisabled_ = true;\nlet deprecationWarnings_ = true;\n\n/**\n * Extract browser version out of the provided user agent string.\n *\n * @param {!string} uastring userAgent string.\n * @param {!string} expr Regular expression used as match criteria.\n * @param {!number} pos position in the version string to be returned.\n * @return {!number} browser version.\n */\nfunction extractVersion(uastring, expr, pos) {\n const match = uastring.match(expr);\n return match && match.length >= pos && parseInt(match[pos], 10);\n}\n\n// Wraps the peerconnection event eventNameToWrap in a function\n// which returns the modified event object (or false to prevent\n// the event).\nfunction wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) {\n if (!window.RTCPeerConnection) {\n return;\n }\n const proto = window.RTCPeerConnection.prototype;\n const nativeAddEventListener = proto.addEventListener;\n proto.addEventListener = function(nativeEventName, cb) {\n if (nativeEventName !== eventNameToWrap) {\n return nativeAddEventListener.apply(this, arguments);\n }\n const wrappedCallback = (e) => {\n const modifiedEvent = wrapper(e);\n if (modifiedEvent) {\n if (cb.handleEvent) {\n cb.handleEvent(modifiedEvent);\n } else {\n cb(modifiedEvent);\n }\n }\n };\n this._eventMap = this._eventMap || {};\n if (!this._eventMap[eventNameToWrap]) {\n this._eventMap[eventNameToWrap] = new Map();\n }\n this._eventMap[eventNameToWrap].set(cb, wrappedCallback);\n return nativeAddEventListener.apply(this, [nativeEventName,\n wrappedCallback]);\n };\n\n const nativeRemoveEventListener = proto.removeEventListener;\n proto.removeEventListener = function(nativeEventName, cb) {\n if (nativeEventName !== eventNameToWrap || !this._eventMap\n || !this._eventMap[eventNameToWrap]) {\n return nativeRemoveEventListener.apply(this, arguments);\n }\n if (!this._eventMap[eventNameToWrap].has(cb)) {\n return nativeRemoveEventListener.apply(this, arguments);\n }\n const unwrappedCb = this._eventMap[eventNameToWrap].get(cb);\n this._eventMap[eventNameToWrap].delete(cb);\n if (this._eventMap[eventNameToWrap].size === 0) {\n delete this._eventMap[eventNameToWrap];\n }\n if (Object.keys(this._eventMap).length === 0) {\n delete this._eventMap;\n }\n return nativeRemoveEventListener.apply(this, [nativeEventName,\n unwrappedCb]);\n };\n\n Object.defineProperty(proto, 'on' + eventNameToWrap, {\n get() {\n return this['_on' + eventNameToWrap];\n },\n set(cb) {\n if (this['_on' + eventNameToWrap]) {\n this.removeEventListener(eventNameToWrap,\n this['_on' + eventNameToWrap]);\n delete this['_on' + eventNameToWrap];\n }\n if (cb) {\n this.addEventListener(eventNameToWrap,\n this['_on' + eventNameToWrap] = cb);\n }\n },\n enumerable: true,\n configurable: true\n });\n}\n\nfunction disableLog(bool) {\n if (typeof bool !== 'boolean') {\n return new Error('Argument type: ' + typeof bool +\n '. Please use a boolean.');\n }\n logDisabled_ = bool;\n return (bool) ? 'adapter.js logging disabled' :\n 'adapter.js logging enabled';\n}\n\n/**\n * Disable or enable deprecation warnings\n * @param {!boolean} bool set to true to disable warnings.\n */\nfunction disableWarnings(bool) {\n if (typeof bool !== 'boolean') {\n return new Error('Argument type: ' + typeof bool +\n '. Please use a boolean.');\n }\n deprecationWarnings_ = !bool;\n return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled');\n}\n\nfunction log() {\n if (typeof window === 'object') {\n if (logDisabled_) {\n return;\n }\n if (typeof console !== 'undefined' && typeof console.log === 'function') {\n console.log.apply(console, arguments);\n }\n }\n}\n\n/**\n * Shows a deprecation warning suggesting the modern and spec-compatible API.\n */\nfunction deprecated(oldMethod, newMethod) {\n if (!deprecationWarnings_) {\n return;\n }\n console.warn(oldMethod + ' is deprecated, please use ' + newMethod +\n ' instead.');\n}\n\n/**\n * Browser detector.\n *\n * @return {object} result containing browser and version\n * properties.\n */\nfunction detectBrowser(window) {\n // Returned result object.\n const result = {browser: null, version: null};\n\n // Fail early if it's not a browser\n if (typeof window === 'undefined' || !window.navigator) {\n result.browser = 'Not a browser.';\n return result;\n }\n\n const {navigator} = window;\n\n if (navigator.mozGetUserMedia) { // Firefox.\n result.browser = 'firefox';\n result.version = extractVersion(navigator.userAgent,\n /Firefox\\/(\\d+)\\./, 1);\n } else if (navigator.webkitGetUserMedia ||\n (window.isSecureContext === false && window.webkitRTCPeerConnection &&\n !window.RTCIceGatherer)) {\n // Chrome, Chromium, Webview, Opera.\n // Version matches Chrome/WebRTC version.\n // Chrome 74 removed webkitGetUserMedia on http as well so we need the\n // more complicated fallback to webkitRTCPeerConnection.\n result.browser = 'chrome';\n result.version = extractVersion(navigator.userAgent,\n /Chrom(e|ium)\\/(\\d+)\\./, 2);\n } else if (navigator.mediaDevices &&\n navigator.userAgent.match(/Edge\\/(\\d+).(\\d+)$/)) { // Edge.\n result.browser = 'edge';\n result.version = extractVersion(navigator.userAgent,\n /Edge\\/(\\d+).(\\d+)$/, 2);\n } else if (window.RTCPeerConnection &&\n navigator.userAgent.match(/AppleWebKit\\/(\\d+)\\./)) { // Safari.\n result.browser = 'safari';\n result.version = extractVersion(navigator.userAgent,\n /AppleWebKit\\/(\\d+)\\./, 1);\n result.supportsUnifiedPlan = window.RTCRtpTransceiver &&\n 'currentDirection' in window.RTCRtpTransceiver.prototype;\n } else { // Default fallthrough: not supported.\n result.browser = 'Not a supported browser.';\n return result;\n }\n\n return result;\n}\n\n/**\n * Checks if something is an object.\n *\n * @param {*} val The something you want to check.\n * @return true if val is an object, false otherwise.\n */\nfunction isObject(val) {\n return Object.prototype.toString.call(val) === '[object Object]';\n}\n\n/**\n * Remove all empty objects and undefined values\n * from a nested object -- an enhanced and vanilla version\n * of Lodash's `compact`.\n */\nfunction compactObject(data) {\n if (!isObject(data)) {\n return data;\n }\n\n return Object.keys(data).reduce(function(accumulator, key) {\n const isObj = isObject(data[key]);\n const value = isObj ? compactObject(data[key]) : data[key];\n const isEmptyObject = isObj && !Object.keys(value).length;\n if (value === undefined || isEmptyObject) {\n return accumulator;\n }\n return Object.assign(accumulator, {[key]: value});\n }, {});\n}\n\n/* iterates the stats graph recursively. */\nfunction walkStats(stats, base, resultSet) {\n if (!base || resultSet.has(base.id)) {\n return;\n }\n resultSet.set(base.id, base);\n Object.keys(base).forEach(name => {\n if (name.endsWith('Id')) {\n walkStats(stats, stats.get(base[name]), resultSet);\n } else if (name.endsWith('Ids')) {\n base[name].forEach(id => {\n walkStats(stats, stats.get(id), resultSet);\n });\n }\n });\n}\n\n/* filter getStats for a sender/receiver track. */\nfunction filterStats(result, track, outbound) {\n const streamStatsType = outbound ? 'outbound-rtp' : 'inbound-rtp';\n const filteredResult = new Map();\n if (track === null) {\n return filteredResult;\n }\n const trackStats = [];\n result.forEach(value => {\n if (value.type === 'track' &&\n value.trackIdentifier === track.id) {\n trackStats.push(value);\n }\n });\n trackStats.forEach(trackStat => {\n result.forEach(stats => {\n if (stats.type === streamStatsType && stats.trackId === trackStat.id) {\n walkStats(result, stats, filteredResult);\n }\n });\n });\n return filteredResult;\n}\n\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/webrtc-adapter/src/js/utils.js?");
737
-
738
- /***/ }),
739
-
740
533
  /***/ "./node_modules/core-js/internals/a-callable.js":
741
534
  /*!******************************************************!*\
742
535
  !*** ./node_modules/core-js/internals/a-callable.js ***!
@@ -3298,17 +3091,6 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac
3298
3091
  "use strict";
3299
3092
  eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ a: function() { return /* binding */ reverseTransformCache; },\n/* harmony export */ i: function() { return /* binding */ instanceOfAny; },\n/* harmony export */ r: function() { return /* binding */ replaceTraps; },\n/* harmony export */ u: function() { return /* binding */ unwrap; },\n/* harmony export */ w: function() { return /* binding */ wrap; }\n/* harmony export */ });\nconst instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n return (idbProxyableTypes ||\n (idbProxyableTypes = [\n IDBDatabase,\n IDBObjectStore,\n IDBIndex,\n IDBCursor,\n IDBTransaction,\n ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n return (cursorAdvanceMethods ||\n (cursorAdvanceMethods = [\n IDBCursor.prototype.advance,\n IDBCursor.prototype.continue,\n IDBCursor.prototype.continuePrimaryKey,\n ]));\n}\nconst cursorRequestMap = new WeakMap();\nconst transactionDoneMap = new WeakMap();\nconst transactionStoreNamesMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n const promise = new Promise((resolve, reject) => {\n const unlisten = () => {\n request.removeEventListener('success', success);\n request.removeEventListener('error', error);\n };\n const success = () => {\n resolve(wrap(request.result));\n unlisten();\n };\n const error = () => {\n reject(request.error);\n unlisten();\n };\n request.addEventListener('success', success);\n request.addEventListener('error', error);\n });\n promise\n .then((value) => {\n // Since cursoring reuses the IDBRequest (*sigh*), we cache it for later retrieval\n // (see wrapFunction).\n if (value instanceof IDBCursor) {\n cursorRequestMap.set(value, request);\n }\n // Catching to avoid \"Uncaught Promise exceptions\"\n })\n .catch(() => { });\n // This mapping exists in reverseTransformCache but doesn't doesn't exist in transformCache. This\n // is because we create many promises from a single IDBRequest.\n reverseTransformCache.set(promise, request);\n return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n // Early bail if we've already created a done promise for this transaction.\n if (transactionDoneMap.has(tx))\n return;\n const done = new Promise((resolve, reject) => {\n const unlisten = () => {\n tx.removeEventListener('complete', complete);\n tx.removeEventListener('error', error);\n tx.removeEventListener('abort', error);\n };\n const complete = () => {\n resolve();\n unlisten();\n };\n const error = () => {\n reject(tx.error || new DOMException('AbortError', 'AbortError'));\n unlisten();\n };\n tx.addEventListener('complete', complete);\n tx.addEventListener('error', error);\n tx.addEventListener('abort', error);\n });\n // Cache it for later retrieval.\n transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n get(target, prop, receiver) {\n if (target instanceof IDBTransaction) {\n // Special handling for transaction.done.\n if (prop === 'done')\n return transactionDoneMap.get(target);\n // Polyfill for objectStoreNames because of Edge.\n if (prop === 'objectStoreNames') {\n return target.objectStoreNames || transactionStoreNamesMap.get(target);\n }\n // Make tx.store return the only store in the transaction, or undefined if there are many.\n if (prop === 'store') {\n return receiver.objectStoreNames[1]\n ? undefined\n : receiver.objectStore(receiver.objectStoreNames[0]);\n }\n }\n // Else transform whatever we get back.\n return wrap(target[prop]);\n },\n set(target, prop, value) {\n target[prop] = value;\n return true;\n },\n has(target, prop) {\n if (target instanceof IDBTransaction &&\n (prop === 'done' || prop === 'store')) {\n return true;\n }\n return prop in target;\n },\n};\nfunction replaceTraps(callback) {\n idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n // Due to expected object equality (which is enforced by the caching in `wrap`), we\n // only create one new func per func.\n // Edge doesn't support objectStoreNames (booo), so we polyfill it here.\n if (func === IDBDatabase.prototype.transaction &&\n !('objectStoreNames' in IDBTransaction.prototype)) {\n return function (storeNames, ...args) {\n const tx = func.call(unwrap(this), storeNames, ...args);\n transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);\n return wrap(tx);\n };\n }\n // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n // with real promises, so each advance methods returns a new promise for the cursor object, or\n // undefined if the end of the cursor has been reached.\n if (getCursorAdvanceMethods().includes(func)) {\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n func.apply(unwrap(this), args);\n return wrap(cursorRequestMap.get(this));\n };\n }\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n return wrap(func.apply(unwrap(this), args));\n };\n}\nfunction transformCachableValue(value) {\n if (typeof value === 'function')\n return wrapFunction(value);\n // This doesn't return, it just creates a 'done' promise for the transaction,\n // which is later returned for transaction.done (see idbObjectHandler).\n if (value instanceof IDBTransaction)\n cacheDonePromiseForTransaction(value);\n if (instanceOfAny(value, getIdbProxyableTypes()))\n return new Proxy(value, idbProxyTraps);\n // Return the same value back if we're not going to transform it.\n return value;\n}\nfunction wrap(value) {\n // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n if (value instanceof IDBRequest)\n return promisifyRequest(value);\n // If we've already transformed this value before, reuse the transformed value.\n // This is faster, but it also provides object equality.\n if (transformCache.has(value))\n return transformCache.get(value);\n const newValue = transformCachableValue(value);\n // Not all types are transformed.\n // These may be primitive types, so they can't be WeakMap keys.\n if (newValue !== value) {\n transformCache.set(value, newValue);\n reverseTransformCache.set(newValue, value);\n }\n return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\n\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/idb/build/wrap-idb-value.js?");
3300
3093
 
3301
- /***/ }),
3302
-
3303
- /***/ "./node_modules/peerjs/dist/bundler.mjs":
3304
- /*!**********************************************!*\
3305
- !*** ./node_modules/peerjs/dist/bundler.mjs ***!
3306
- \**********************************************/
3307
- /***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
3308
-
3309
- "use strict";
3310
- eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Peer: function() { return /* binding */ $26088d7da5b03f69$export$ecd1fc136c422448; },\n/* harmony export */ \"default\": function() { return /* binding */ $70d766613f57b014$export$2e2bcd8739ae039; },\n/* harmony export */ util: function() { return /* binding */ $06cb531ed7840f78$export$7debb50ef11d5e0b; }\n/* harmony export */ });\n/* harmony import */ var peerjs_js_binarypack__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! peerjs-js-binarypack */ \"./node_modules/peerjs-js-binarypack/lib/binarypack.js\");\n/* harmony import */ var webrtc_adapter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! webrtc-adapter */ \"./node_modules/webrtc-adapter/src/js/adapter_core.js\");\n\n\n\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\n\nvar $af8cf1f663f490f4$var$webRTCAdapter = //@ts-ignore\nwebrtc_adapter__WEBPACK_IMPORTED_MODULE_1__[\"default\"][\"default\"] || webrtc_adapter__WEBPACK_IMPORTED_MODULE_1__[\"default\"];\nvar $af8cf1f663f490f4$export$25be9502477c137d = new /** @class */ (function() {\n function class_1() {\n this.isIOS = [\n \"iPad\",\n \"iPhone\",\n \"iPod\"\n ].includes(navigator.platform);\n this.supportedBrowsers = [\n \"firefox\",\n \"chrome\",\n \"safari\"\n ];\n this.minFirefoxVersion = 59;\n this.minChromeVersion = 72;\n this.minSafariVersion = 605;\n }\n class_1.prototype.isWebRTCSupported = function() {\n return typeof RTCPeerConnection !== \"undefined\";\n };\n class_1.prototype.isBrowserSupported = function() {\n var browser = this.getBrowser();\n var version = this.getVersion();\n var validBrowser = this.supportedBrowsers.includes(browser);\n if (!validBrowser) return false;\n if (browser === \"chrome\") return version >= this.minChromeVersion;\n if (browser === \"firefox\") return version >= this.minFirefoxVersion;\n if (browser === \"safari\") return !this.isIOS && version >= this.minSafariVersion;\n return false;\n };\n class_1.prototype.getBrowser = function() {\n return $af8cf1f663f490f4$var$webRTCAdapter.browserDetails.browser;\n };\n class_1.prototype.getVersion = function() {\n return $af8cf1f663f490f4$var$webRTCAdapter.browserDetails.version || 0;\n };\n class_1.prototype.isUnifiedPlanSupported = function() {\n var browser = this.getBrowser();\n var version = $af8cf1f663f490f4$var$webRTCAdapter.browserDetails.version || 0;\n if (browser === \"chrome\" && version < this.minChromeVersion) return false;\n if (browser === \"firefox\" && version >= this.minFirefoxVersion) return true;\n if (!window.RTCRtpTransceiver || !(\"currentDirection\" in RTCRtpTransceiver.prototype)) return false;\n var tempPc;\n var supported = false;\n try {\n tempPc = new RTCPeerConnection();\n tempPc.addTransceiver(\"audio\");\n supported = true;\n } catch (e) {} finally{\n if (tempPc) tempPc.close();\n }\n return supported;\n };\n class_1.prototype.toString = function() {\n return \"Supports:\\n browser:\".concat(this.getBrowser(), \"\\n version:\").concat(this.getVersion(), \"\\n isIOS:\").concat(this.isIOS, \"\\n isWebRTCSupported:\").concat(this.isWebRTCSupported(), \"\\n isBrowserSupported:\").concat(this.isBrowserSupported(), \"\\n isUnifiedPlanSupported:\").concat(this.isUnifiedPlanSupported());\n };\n return class_1;\n}())();\n\n\nvar $06cb531ed7840f78$var$DEFAULT_CONFIG = {\n iceServers: [\n {\n urls: \"stun:stun.l.google.com:19302\"\n },\n {\n urls: [\n \"turn:eu-0.turn.peerjs.com:3478\",\n \"turn:us-0.turn.peerjs.com:3478\", \n ],\n username: \"peerjs\",\n credential: \"peerjsp\"\n }, \n ],\n sdpSemantics: \"unified-plan\"\n};\nvar $06cb531ed7840f78$var$Util = /** @class */ function() {\n function Util() {\n this.CLOUD_HOST = \"0.peerjs.com\";\n this.CLOUD_PORT = 443;\n // Browsers that need chunking:\n this.chunkedBrowsers = {\n Chrome: 1,\n chrome: 1\n };\n this.chunkedMTU = 16300; // The original 60000 bytes setting does not work when sending data from Firefox to Chrome, which is \"cut off\" after 16384 bytes and delivered individually.\n // Returns browser-agnostic default config\n this.defaultConfig = $06cb531ed7840f78$var$DEFAULT_CONFIG;\n this.browser = $af8cf1f663f490f4$export$25be9502477c137d.getBrowser();\n this.browserVersion = $af8cf1f663f490f4$export$25be9502477c137d.getVersion();\n // Lists which features are supported\n this.supports = function() {\n var supported = {\n browser: $af8cf1f663f490f4$export$25be9502477c137d.isBrowserSupported(),\n webRTC: $af8cf1f663f490f4$export$25be9502477c137d.isWebRTCSupported(),\n audioVideo: false,\n data: false,\n binaryBlob: false,\n reliable: false\n };\n if (!supported.webRTC) return supported;\n var pc;\n try {\n pc = new RTCPeerConnection($06cb531ed7840f78$var$DEFAULT_CONFIG);\n supported.audioVideo = true;\n var dc = void 0;\n try {\n dc = pc.createDataChannel(\"_PEERJSTEST\", {\n ordered: true\n });\n supported.data = true;\n supported.reliable = !!dc.ordered;\n // Binary test\n try {\n dc.binaryType = \"blob\";\n supported.binaryBlob = !$af8cf1f663f490f4$export$25be9502477c137d.isIOS;\n } catch (e) {}\n } catch (e) {} finally{\n if (dc) dc.close();\n }\n } catch (e) {} finally{\n if (pc) pc.close();\n }\n return supported;\n }();\n this.pack = peerjs_js_binarypack__WEBPACK_IMPORTED_MODULE_0__.pack;\n this.unpack = peerjs_js_binarypack__WEBPACK_IMPORTED_MODULE_0__.unpack;\n // Binary stuff\n this._dataCount = 1;\n }\n Util.prototype.noop = function() {};\n // Ensure alphanumeric ids\n Util.prototype.validateId = function(id) {\n // Allow empty ids\n return !id || /^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.test(id);\n };\n Util.prototype.chunk = function(blob) {\n var chunks = [];\n var size = blob.size;\n var total = Math.ceil(size / $06cb531ed7840f78$export$7debb50ef11d5e0b.chunkedMTU);\n var index = 0;\n var start = 0;\n while(start < size){\n var end = Math.min(size, start + $06cb531ed7840f78$export$7debb50ef11d5e0b.chunkedMTU);\n var b = blob.slice(start, end);\n var chunk = {\n __peerData: this._dataCount,\n n: index,\n data: b,\n total: total\n };\n chunks.push(chunk);\n start = end;\n index++;\n }\n this._dataCount++;\n return chunks;\n };\n Util.prototype.blobToArrayBuffer = function(blob, cb) {\n var fr = new FileReader();\n fr.onload = function(evt) {\n if (evt.target) cb(evt.target.result);\n };\n fr.readAsArrayBuffer(blob);\n return fr;\n };\n Util.prototype.binaryStringToArrayBuffer = function(binary) {\n var byteArray = new Uint8Array(binary.length);\n for(var i = 0; i < binary.length; i++)byteArray[i] = binary.charCodeAt(i) & 0xff;\n return byteArray.buffer;\n };\n Util.prototype.randomToken = function() {\n return Math.random().toString(36).slice(2);\n };\n Util.prototype.isSecure = function() {\n return location.protocol === \"https:\";\n };\n return Util;\n}();\nvar $06cb531ed7840f78$export$7debb50ef11d5e0b = new $06cb531ed7840f78$var$Util();\n\n\nvar $26088d7da5b03f69$exports = {};\n\n$parcel$export($26088d7da5b03f69$exports, \"Peer\", () => $26088d7da5b03f69$export$ecd1fc136c422448, (v) => $26088d7da5b03f69$export$ecd1fc136c422448 = v);\nvar $ac9b757d51178e15$exports = {};\n'use strict';\nvar $ac9b757d51178e15$var$has = Object.prototype.hasOwnProperty, $ac9b757d51178e15$var$prefix = '~';\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @private\n */ function $ac9b757d51178e15$var$Events() {}\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n $ac9b757d51178e15$var$Events.prototype = Object.create(null);\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new $ac9b757d51178e15$var$Events().__proto__) $ac9b757d51178e15$var$prefix = false;\n}\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @private\n */ function $ac9b757d51178e15$var$EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n/**\n * Add a listener for a given event.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} context The context to invoke the listener with.\n * @param {Boolean} once Specify if the listener is a one-time listener.\n * @returns {EventEmitter}\n * @private\n */ function $ac9b757d51178e15$var$addListener(emitter, event, fn, context, once) {\n if (typeof fn !== 'function') throw new TypeError('The listener must be a function');\n var listener = new $ac9b757d51178e15$var$EE(fn, context || emitter, once), evt = $ac9b757d51178e15$var$prefix ? $ac9b757d51178e15$var$prefix + event : event;\n if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;\n else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);\n else emitter._events[evt] = [\n emitter._events[evt],\n listener\n ];\n return emitter;\n}\n/**\n * Clear event by name.\n *\n * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.\n * @param {(String|Symbol)} evt The Event name.\n * @private\n */ function $ac9b757d51178e15$var$clearEvent(emitter, evt) {\n if (--emitter._eventsCount === 0) emitter._events = new $ac9b757d51178e15$var$Events();\n else delete emitter._events[evt];\n}\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @public\n */ function $ac9b757d51178e15$var$EventEmitter() {\n this._events = new $ac9b757d51178e15$var$Events();\n this._eventsCount = 0;\n}\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @public\n */ $ac9b757d51178e15$var$EventEmitter.prototype.eventNames = function eventNames() {\n var names = [], events, name;\n if (this._eventsCount === 0) return names;\n for(name in events = this._events)if ($ac9b757d51178e15$var$has.call(events, name)) names.push($ac9b757d51178e15$var$prefix ? name.slice(1) : name);\n if (Object.getOwnPropertySymbols) return names.concat(Object.getOwnPropertySymbols(events));\n return names;\n};\n/**\n * Return the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Array} The registered listeners.\n * @public\n */ $ac9b757d51178e15$var$EventEmitter.prototype.listeners = function listeners(event) {\n var evt = $ac9b757d51178e15$var$prefix ? $ac9b757d51178e15$var$prefix + event : event, handlers = this._events[evt];\n if (!handlers) return [];\n if (handlers.fn) return [\n handlers.fn\n ];\n for(var i = 0, l = handlers.length, ee = new Array(l); i < l; i++)ee[i] = handlers[i].fn;\n return ee;\n};\n/**\n * Return the number of listeners listening to a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Number} The number of listeners.\n * @public\n */ $ac9b757d51178e15$var$EventEmitter.prototype.listenerCount = function listenerCount(event) {\n var evt = $ac9b757d51178e15$var$prefix ? $ac9b757d51178e15$var$prefix + event : event, listeners = this._events[evt];\n if (!listeners) return 0;\n if (listeners.fn) return 1;\n return listeners.length;\n};\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @public\n */ $ac9b757d51178e15$var$EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = $ac9b757d51178e15$var$prefix ? $ac9b757d51178e15$var$prefix + event : event;\n if (!this._events[evt]) return false;\n var listeners = this._events[evt], len = arguments.length, args, i;\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n switch(len){\n case 1:\n return listeners.fn.call(listeners.context), true;\n case 2:\n return listeners.fn.call(listeners.context, a1), true;\n case 3:\n return listeners.fn.call(listeners.context, a1, a2), true;\n case 4:\n return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5:\n return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6:\n return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n for(i = 1, args = new Array(len - 1); i < len; i++)args[i - 1] = arguments[i];\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length, j;\n for(i = 0; i < length; i++){\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n switch(len){\n case 1:\n listeners[i].fn.call(listeners[i].context);\n break;\n case 2:\n listeners[i].fn.call(listeners[i].context, a1);\n break;\n case 3:\n listeners[i].fn.call(listeners[i].context, a1, a2);\n break;\n case 4:\n listeners[i].fn.call(listeners[i].context, a1, a2, a3);\n break;\n default:\n if (!args) for(j = 1, args = new Array(len - 1); j < len; j++)args[j - 1] = arguments[j];\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n return true;\n};\n/**\n * Add a listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */ $ac9b757d51178e15$var$EventEmitter.prototype.on = function on(event, fn, context) {\n return $ac9b757d51178e15$var$addListener(this, event, fn, context, false);\n};\n/**\n * Add a one-time listener for a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn The listener function.\n * @param {*} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @public\n */ $ac9b757d51178e15$var$EventEmitter.prototype.once = function once(event, fn, context) {\n return $ac9b757d51178e15$var$addListener(this, event, fn, context, true);\n};\n/**\n * Remove the listeners of a given event.\n *\n * @param {(String|Symbol)} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {*} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @public\n */ $ac9b757d51178e15$var$EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = $ac9b757d51178e15$var$prefix ? $ac9b757d51178e15$var$prefix + event : event;\n if (!this._events[evt]) return this;\n if (!fn) {\n $ac9b757d51178e15$var$clearEvent(this, evt);\n return this;\n }\n var listeners = this._events[evt];\n if (listeners.fn) {\n if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) $ac9b757d51178e15$var$clearEvent(this, evt);\n } else {\n for(var i = 0, events = [], length = listeners.length; i < length; i++)if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) events.push(listeners[i]);\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else $ac9b757d51178e15$var$clearEvent(this, evt);\n }\n return this;\n};\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {(String|Symbol)} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @public\n */ $ac9b757d51178e15$var$EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n if (event) {\n evt = $ac9b757d51178e15$var$prefix ? $ac9b757d51178e15$var$prefix + event : event;\n if (this._events[evt]) $ac9b757d51178e15$var$clearEvent(this, evt);\n } else {\n this._events = new $ac9b757d51178e15$var$Events();\n this._eventsCount = 0;\n }\n return this;\n};\n//\n// Alias methods names because people roll like that.\n//\n$ac9b757d51178e15$var$EventEmitter.prototype.off = $ac9b757d51178e15$var$EventEmitter.prototype.removeListener;\n$ac9b757d51178e15$var$EventEmitter.prototype.addListener = $ac9b757d51178e15$var$EventEmitter.prototype.on;\n//\n// Expose the prefix.\n//\n$ac9b757d51178e15$var$EventEmitter.prefixed = $ac9b757d51178e15$var$prefix;\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\n$ac9b757d51178e15$var$EventEmitter.EventEmitter = $ac9b757d51178e15$var$EventEmitter;\n$ac9b757d51178e15$exports = $ac9b757d51178e15$var$EventEmitter;\n\n\n\nvar $1615705ecc6adca3$exports = {};\n\n$parcel$export($1615705ecc6adca3$exports, \"LogLevel\", () => $1615705ecc6adca3$export$243e62d78d3b544d, (v) => $1615705ecc6adca3$export$243e62d78d3b544d = v);\n$parcel$export($1615705ecc6adca3$exports, \"default\", () => $1615705ecc6adca3$export$2e2bcd8739ae039, (v) => $1615705ecc6adca3$export$2e2bcd8739ae039 = v);\nvar $1615705ecc6adca3$var$__read = false || function(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while((n === void 0 || n-- > 0) && !(r = i.next()).done)ar.push(r.value);\n } catch (error) {\n e = {\n error: error\n };\n } finally{\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n } finally{\n if (e) throw e.error;\n }\n }\n return ar;\n};\nvar $1615705ecc6adca3$var$__spreadArray = false || function(to, from, pack) {\n if (pack || arguments.length === 2) {\n for(var i = 0, l = from.length, ar; i < l; i++)if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n};\nvar $1615705ecc6adca3$var$LOG_PREFIX = \"PeerJS: \";\nvar $1615705ecc6adca3$export$243e62d78d3b544d;\n(function($1615705ecc6adca3$export$243e62d78d3b544d) {\n $1615705ecc6adca3$export$243e62d78d3b544d[$1615705ecc6adca3$export$243e62d78d3b544d[\"Disabled\"] = 0] = \"Disabled\";\n $1615705ecc6adca3$export$243e62d78d3b544d[$1615705ecc6adca3$export$243e62d78d3b544d[\"Errors\"] = 1] = \"Errors\";\n $1615705ecc6adca3$export$243e62d78d3b544d[$1615705ecc6adca3$export$243e62d78d3b544d[\"Warnings\"] = 2] = \"Warnings\";\n $1615705ecc6adca3$export$243e62d78d3b544d[$1615705ecc6adca3$export$243e62d78d3b544d[\"All\"] = 3] = \"All\";\n})($1615705ecc6adca3$export$243e62d78d3b544d || ($1615705ecc6adca3$export$243e62d78d3b544d = {}));\nvar $1615705ecc6adca3$var$Logger = /** @class */ function() {\n function Logger() {\n this._logLevel = $1615705ecc6adca3$export$243e62d78d3b544d.Disabled;\n }\n Object.defineProperty(Logger.prototype, \"logLevel\", {\n get: function() {\n return this._logLevel;\n },\n set: function(logLevel) {\n this._logLevel = logLevel;\n },\n enumerable: false,\n configurable: true\n });\n Logger.prototype.log = function() {\n var args = [];\n for(var _i = 0; _i < arguments.length; _i++)args[_i] = arguments[_i];\n if (this._logLevel >= $1615705ecc6adca3$export$243e62d78d3b544d.All) this._print.apply(this, $1615705ecc6adca3$var$__spreadArray([\n $1615705ecc6adca3$export$243e62d78d3b544d.All\n ], $1615705ecc6adca3$var$__read(args), false));\n };\n Logger.prototype.warn = function() {\n var args = [];\n for(var _i = 0; _i < arguments.length; _i++)args[_i] = arguments[_i];\n if (this._logLevel >= $1615705ecc6adca3$export$243e62d78d3b544d.Warnings) this._print.apply(this, $1615705ecc6adca3$var$__spreadArray([\n $1615705ecc6adca3$export$243e62d78d3b544d.Warnings\n ], $1615705ecc6adca3$var$__read(args), false));\n };\n Logger.prototype.error = function() {\n var args = [];\n for(var _i = 0; _i < arguments.length; _i++)args[_i] = arguments[_i];\n if (this._logLevel >= $1615705ecc6adca3$export$243e62d78d3b544d.Errors) this._print.apply(this, $1615705ecc6adca3$var$__spreadArray([\n $1615705ecc6adca3$export$243e62d78d3b544d.Errors\n ], $1615705ecc6adca3$var$__read(args), false));\n };\n Logger.prototype.setLogFunction = function(fn) {\n this._print = fn;\n };\n Logger.prototype._print = function(logLevel) {\n var rest = [];\n for(var _i = 1; _i < arguments.length; _i++)rest[_i - 1] = arguments[_i];\n var copy = $1615705ecc6adca3$var$__spreadArray([\n $1615705ecc6adca3$var$LOG_PREFIX\n ], $1615705ecc6adca3$var$__read(rest), false);\n for(var i in copy)if (copy[i] instanceof Error) copy[i] = \"(\" + copy[i].name + \") \" + copy[i].message;\n if (logLevel >= $1615705ecc6adca3$export$243e62d78d3b544d.All) console.log.apply(console, $1615705ecc6adca3$var$__spreadArray([], $1615705ecc6adca3$var$__read(copy), false));\n else if (logLevel >= $1615705ecc6adca3$export$243e62d78d3b544d.Warnings) console.warn.apply(console, $1615705ecc6adca3$var$__spreadArray([\n \"WARNING\"\n ], $1615705ecc6adca3$var$__read(copy), false));\n else if (logLevel >= $1615705ecc6adca3$export$243e62d78d3b544d.Errors) console.error.apply(console, $1615705ecc6adca3$var$__spreadArray([\n \"ERROR\"\n ], $1615705ecc6adca3$var$__read(copy), false));\n };\n return Logger;\n}();\nvar $1615705ecc6adca3$export$2e2bcd8739ae039 = new $1615705ecc6adca3$var$Logger();\n\n\nvar $31d11a8d122cb4b7$exports = {};\n\n$parcel$export($31d11a8d122cb4b7$exports, \"Socket\", () => $31d11a8d122cb4b7$export$4798917dbf149b79, (v) => $31d11a8d122cb4b7$export$4798917dbf149b79 = v);\n\n\nvar $60fadef21a2daafc$export$3157d57b4135e3bc;\n(function($60fadef21a2daafc$export$3157d57b4135e3bc) {\n $60fadef21a2daafc$export$3157d57b4135e3bc[\"Data\"] = \"data\";\n $60fadef21a2daafc$export$3157d57b4135e3bc[\"Media\"] = \"media\";\n})($60fadef21a2daafc$export$3157d57b4135e3bc || ($60fadef21a2daafc$export$3157d57b4135e3bc = {}));\nvar $60fadef21a2daafc$export$9547aaa2e39030ff;\n(function($60fadef21a2daafc$export$9547aaa2e39030ff) {\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"BrowserIncompatible\"] = \"browser-incompatible\";\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"Disconnected\"] = \"disconnected\";\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"InvalidID\"] = \"invalid-id\";\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"InvalidKey\"] = \"invalid-key\";\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"Network\"] = \"network\";\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"PeerUnavailable\"] = \"peer-unavailable\";\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"SslUnavailable\"] = \"ssl-unavailable\";\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"ServerError\"] = \"server-error\";\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"SocketError\"] = \"socket-error\";\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"SocketClosed\"] = \"socket-closed\";\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"UnavailableID\"] = \"unavailable-id\";\n $60fadef21a2daafc$export$9547aaa2e39030ff[\"WebRTC\"] = \"webrtc\";\n})($60fadef21a2daafc$export$9547aaa2e39030ff || ($60fadef21a2daafc$export$9547aaa2e39030ff = {}));\nvar $60fadef21a2daafc$export$89f507cf986a947;\n(function($60fadef21a2daafc$export$89f507cf986a947) {\n $60fadef21a2daafc$export$89f507cf986a947[\"Binary\"] = \"binary\";\n $60fadef21a2daafc$export$89f507cf986a947[\"BinaryUTF8\"] = \"binary-utf8\";\n $60fadef21a2daafc$export$89f507cf986a947[\"JSON\"] = \"json\";\n})($60fadef21a2daafc$export$89f507cf986a947 || ($60fadef21a2daafc$export$89f507cf986a947 = {}));\nvar $60fadef21a2daafc$export$3b5c4a4b6354f023;\n(function($60fadef21a2daafc$export$3b5c4a4b6354f023) {\n $60fadef21a2daafc$export$3b5c4a4b6354f023[\"Message\"] = \"message\";\n $60fadef21a2daafc$export$3b5c4a4b6354f023[\"Disconnected\"] = \"disconnected\";\n $60fadef21a2daafc$export$3b5c4a4b6354f023[\"Error\"] = \"error\";\n $60fadef21a2daafc$export$3b5c4a4b6354f023[\"Close\"] = \"close\";\n})($60fadef21a2daafc$export$3b5c4a4b6354f023 || ($60fadef21a2daafc$export$3b5c4a4b6354f023 = {}));\nvar $60fadef21a2daafc$export$adb4a1754da6f10d;\n(function($60fadef21a2daafc$export$adb4a1754da6f10d) {\n $60fadef21a2daafc$export$adb4a1754da6f10d[\"Heartbeat\"] = \"HEARTBEAT\";\n $60fadef21a2daafc$export$adb4a1754da6f10d[\"Candidate\"] = \"CANDIDATE\";\n $60fadef21a2daafc$export$adb4a1754da6f10d[\"Offer\"] = \"OFFER\";\n $60fadef21a2daafc$export$adb4a1754da6f10d[\"Answer\"] = \"ANSWER\";\n $60fadef21a2daafc$export$adb4a1754da6f10d[\"Open\"] = \"OPEN\";\n $60fadef21a2daafc$export$adb4a1754da6f10d[\"Error\"] = \"ERROR\";\n $60fadef21a2daafc$export$adb4a1754da6f10d[\"IdTaken\"] = \"ID-TAKEN\";\n $60fadef21a2daafc$export$adb4a1754da6f10d[\"InvalidKey\"] = \"INVALID-KEY\";\n $60fadef21a2daafc$export$adb4a1754da6f10d[\"Leave\"] = \"LEAVE\";\n $60fadef21a2daafc$export$adb4a1754da6f10d[\"Expire\"] = \"EXPIRE\";\n})($60fadef21a2daafc$export$adb4a1754da6f10d || ($60fadef21a2daafc$export$adb4a1754da6f10d = {}));\n\n\nvar $0d1ed891c5cb27c0$exports = {};\n$0d1ed891c5cb27c0$exports = JSON.parse(\"{\\\"name\\\":\\\"peerjs\\\",\\\"version\\\":\\\"1.4.7\\\",\\\"keywords\\\":[\\\"peerjs\\\",\\\"webrtc\\\",\\\"p2p\\\",\\\"rtc\\\"],\\\"description\\\":\\\"PeerJS client\\\",\\\"homepage\\\":\\\"https://peerjs.com\\\",\\\"bugs\\\":{\\\"url\\\":\\\"https://github.com/peers/peerjs/issues\\\"},\\\"repository\\\":{\\\"type\\\":\\\"git\\\",\\\"url\\\":\\\"https://github.com/peers/peerjs\\\"},\\\"license\\\":\\\"MIT\\\",\\\"contributors\\\":[\\\"Michelle Bu <michelle@michellebu.com>\\\",\\\"afrokick <devbyru@gmail.com>\\\",\\\"ericz <really.ez@gmail.com>\\\",\\\"Jairo <kidandcat@gmail.com>\\\",\\\"Jonas Gloning <34194370+jonasgloning@users.noreply.github.com>\\\",\\\"Jairo Caro-Accino Viciana <jairo@galax.be>\\\",\\\"Carlos Caballero <carlos.caballero.gonzalez@gmail.com>\\\",\\\"hc <hheennrryy@gmail.com>\\\",\\\"Muhammad Asif <capripio@gmail.com>\\\",\\\"PrashoonB <prashoonbhattacharjee@gmail.com>\\\",\\\"Harsh Bardhan Mishra <47351025+HarshCasper@users.noreply.github.com>\\\",\\\"akotynski <aleksanderkotbury@gmail.com>\\\",\\\"lmb <i@lmb.io>\\\",\\\"Jairooo <jairocaro@msn.com>\\\",\\\"Moritz Stückler <moritz.stueckler@gmail.com>\\\",\\\"Simon <crydotsnakegithub@gmail.com>\\\",\\\"Denis Lukov <denismassters@gmail.com>\\\",\\\"Philipp Hancke <fippo@andyet.net>\\\",\\\"Hans Oksendahl <hansoksendahl@gmail.com>\\\",\\\"Jess <jessachandler@gmail.com>\\\",\\\"khankuan <khankuan@gmail.com>\\\",\\\"DUODVK <kurmanov.work@gmail.com>\\\",\\\"XiZhao <kwang1imsa@gmail.com>\\\",\\\"Matthias Lohr <matthias@lohr.me>\\\",\\\"=frank tree <=frnktrb@googlemail.com>\\\",\\\"Andre Eckardt <aeckardt@outlook.com>\\\",\\\"Chris Cowan <agentme49@gmail.com>\\\",\\\"Alex Chuev <alex@chuev.com>\\\",\\\"alxnull <alxnull@e.mail.de>\\\",\\\"Yemel Jardi <angel.jardi@gmail.com>\\\",\\\"Ben Parnell <benjaminparnell.94@gmail.com>\\\",\\\"Benny Lichtner <bennlich@gmail.com>\\\",\\\"fresheneesz <bitetrudpublic@gmail.com>\\\",\\\"bob.barstead@exaptive.com <bob.barstead@exaptive.com>\\\",\\\"chandika <chandika@gmail.com>\\\",\\\"emersion <contact@emersion.fr>\\\",\\\"Christopher Van <cvan@users.noreply.github.com>\\\",\\\"eddieherm <edhermoso@gmail.com>\\\",\\\"Eduardo Pinho <enet4mikeenet@gmail.com>\\\",\\\"Evandro Zanatta <ezanatta@tray.net.br>\\\",\\\"Gardner Bickford <gardner@users.noreply.github.com>\\\",\\\"Gian Luca <gianluca.cecchi@cynny.com>\\\",\\\"PatrickJS <github@gdi2290.com>\\\",\\\"jonnyf <github@jonathanfoss.co.uk>\\\",\\\"Hizkia Felix <hizkifw@gmail.com>\\\",\\\"Hristo Oskov <hristo.oskov@gmail.com>\\\",\\\"Isaac Madwed <i.madwed@gmail.com>\\\",\\\"Ilya Konanykhin <ilya.konanykhin@gmail.com>\\\",\\\"jasonbarry <jasbarry@me.com>\\\",\\\"Jonathan Burke <jonathan.burke.1311@googlemail.com>\\\",\\\"Josh Hamit <josh.hamit@gmail.com>\\\",\\\"Jordan Austin <jrax86@gmail.com>\\\",\\\"Joel Wetzell <jwetzell@yahoo.com>\\\",\\\"xizhao <kevin.wang@cloudera.com>\\\",\\\"Alberto Torres <kungfoobar@gmail.com>\\\",\\\"Jonathan Mayol <mayoljonathan@gmail.com>\\\",\\\"Jefferson Felix <me@jsfelix.dev>\\\",\\\"Rolf Erik Lekang <me@rolflekang.com>\\\",\\\"Kevin Mai-Husan Chia <mhchia@users.noreply.github.com>\\\",\\\"Pepijn de Vos <pepijndevos@gmail.com>\\\",\\\"JooYoung <qkdlql@naver.com>\\\",\\\"Tobias Speicher <rootcommander@gmail.com>\\\",\\\"Steve Blaurock <sblaurock@gmail.com>\\\",\\\"Kyrylo Shegeda <shegeda@ualberta.ca>\\\",\\\"Diwank Singh Tomer <singh@diwank.name>\\\",\\\"Sören Balko <Soeren.Balko@gmail.com>\\\",\\\"Arpit Solanki <solankiarpit1997@gmail.com>\\\",\\\"Yuki Ito <yuki@gnnk.net>\\\",\\\"Artur Zayats <zag2art@gmail.com>\\\"],\\\"funding\\\":{\\\"type\\\":\\\"opencollective\\\",\\\"url\\\":\\\"https://opencollective.com/peer\\\"},\\\"collective\\\":{\\\"type\\\":\\\"opencollective\\\",\\\"url\\\":\\\"https://opencollective.com/peer\\\"},\\\"files\\\":[\\\"dist/*\\\"],\\\"sideEffects\\\":[\\\"lib/global.ts\\\",\\\"lib/supports.ts\\\"],\\\"main\\\":\\\"dist/bundler.cjs\\\",\\\"module\\\":\\\"dist/bundler.mjs\\\",\\\"browser-minified\\\":\\\"dist/peerjs.min.js\\\",\\\"browser-unminified\\\":\\\"dist/peerjs.js\\\",\\\"types\\\":\\\"dist/types.d.ts\\\",\\\"engines\\\":{\\\"node\\\":\\\">= 10\\\"},\\\"targets\\\":{\\\"types\\\":{\\\"source\\\":\\\"lib/exports.ts\\\"},\\\"main\\\":{\\\"source\\\":\\\"lib/exports.ts\\\",\\\"sourceMap\\\":{\\\"inlineSources\\\":true}},\\\"module\\\":{\\\"source\\\":\\\"lib/exports.ts\\\",\\\"includeNodeModules\\\":[\\\"eventemitter3\\\"],\\\"sourceMap\\\":{\\\"inlineSources\\\":true}},\\\"browser-minified\\\":{\\\"context\\\":\\\"browser\\\",\\\"outputFormat\\\":\\\"global\\\",\\\"optimize\\\":true,\\\"engines\\\":{\\\"browsers\\\":\\\"cover 99%, not dead\\\"},\\\"source\\\":\\\"lib/global.ts\\\"},\\\"browser-unminified\\\":{\\\"context\\\":\\\"browser\\\",\\\"outputFormat\\\":\\\"global\\\",\\\"optimize\\\":false,\\\"engines\\\":{\\\"browsers\\\":\\\"cover 99%, not dead\\\"},\\\"source\\\":\\\"lib/global.ts\\\"}},\\\"scripts\\\":{\\\"contributors\\\":\\\"git-authors-cli --print=false && prettier --write package.json && git add package.json package-lock.json && git commit -m \\\\\\\"chore(contributors): update and sort contributors list\\\\\\\"\\\",\\\"check\\\":\\\"tsc --noEmit\\\",\\\"watch\\\":\\\"parcel watch\\\",\\\"build\\\":\\\"rm -rf dist && parcel build\\\",\\\"prepublishOnly\\\":\\\"npm run build\\\",\\\"test\\\":\\\"mocha -r ts-node/register -r jsdom-global/register test/**/*.ts\\\",\\\"format\\\":\\\"prettier --write .\\\",\\\"semantic-release\\\":\\\"semantic-release\\\"},\\\"devDependencies\\\":{\\\"@parcel/config-default\\\":\\\"^2.5.0\\\",\\\"@parcel/packager-ts\\\":\\\"^2.5.0\\\",\\\"@parcel/transformer-typescript-tsc\\\":\\\"^2.5.0\\\",\\\"@parcel/transformer-typescript-types\\\":\\\"^2.5.0\\\",\\\"@semantic-release/changelog\\\":\\\"^6.0.1\\\",\\\"@semantic-release/git\\\":\\\"^10.0.1\\\",\\\"@types/chai\\\":\\\"^4.3.0\\\",\\\"@types/mocha\\\":\\\"^9.1.0\\\",\\\"@types/node\\\":\\\"^17.0.18\\\",\\\"chai\\\":\\\"^4.3.6\\\",\\\"git-authors-cli\\\":\\\"^1.0.40\\\",\\\"jsdom\\\":\\\"^19.0.0\\\",\\\"jsdom-global\\\":\\\"^3.0.2\\\",\\\"mocha\\\":\\\"^9.2.0\\\",\\\"mock-socket\\\":\\\"8.0.5\\\",\\\"parcel\\\":\\\"^2.5.0\\\",\\\"parcel-transformer-tsc-sourcemaps\\\":\\\"^1.0.2\\\",\\\"prettier\\\":\\\"^2.6.2\\\",\\\"semantic-release\\\":\\\"^19.0.2\\\",\\\"standard\\\":\\\"^16.0.4\\\",\\\"ts-node\\\":\\\"^10.5.0\\\",\\\"typescript\\\":\\\"^4.5.5\\\"},\\\"dependencies\\\":{\\\"@swc/helpers\\\":\\\"^0.3.13\\\",\\\"eventemitter3\\\":\\\"^4.0.7\\\",\\\"peerjs-js-binarypack\\\":\\\"1.0.1\\\",\\\"webrtc-adapter\\\":\\\"^7.7.1\\\"}}\");\n\n\nvar $31d11a8d122cb4b7$var$__extends = false || function() {\n var extendStatics = function(d1, b1) {\n extendStatics = Object.setPrototypeOf || ({\n __proto__: []\n }) instanceof Array && function(d, b) {\n d.__proto__ = b;\n } || function(d, b) {\n for(var p in b)if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n };\n return extendStatics(d1, b1);\n };\n return function(d, b) {\n if (typeof b !== \"function\" && b !== null) throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\nvar $31d11a8d122cb4b7$var$__read = false || function(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while((n === void 0 || n-- > 0) && !(r = i.next()).done)ar.push(r.value);\n } catch (error) {\n e = {\n error: error\n };\n } finally{\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n } finally{\n if (e) throw e.error;\n }\n }\n return ar;\n};\nvar $31d11a8d122cb4b7$var$__spreadArray = false || function(to, from, pack) {\n if (pack || arguments.length === 2) {\n for(var i = 0, l = from.length, ar; i < l; i++)if (ar || !(i in from)) {\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\n ar[i] = from[i];\n }\n }\n return to.concat(ar || Array.prototype.slice.call(from));\n};\nvar $31d11a8d122cb4b7$var$__values = false || function(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function() {\n if (o && i >= o.length) o = void 0;\n return {\n value: o && o[i++],\n done: !o\n };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n};\n/**\n * An abstraction on top of WebSockets to provide fastest\n * possible connection for peers.\n */ var $31d11a8d122cb4b7$export$4798917dbf149b79 = /** @class */ function(_super) {\n $31d11a8d122cb4b7$var$__extends($31d11a8d122cb4b7$export$4798917dbf149b79, _super);\n function $31d11a8d122cb4b7$export$4798917dbf149b79(secure, host, port, path, key, pingInterval) {\n if (pingInterval === void 0) pingInterval = 5000;\n var _this = _super.call(this) || this;\n _this.pingInterval = pingInterval;\n _this._disconnected = true;\n _this._messagesQueue = [];\n var wsProtocol = secure ? \"wss://\" : \"ws://\";\n _this._baseUrl = wsProtocol + host + \":\" + port + path + \"peerjs?key=\" + key;\n return _this;\n }\n $31d11a8d122cb4b7$export$4798917dbf149b79.prototype.start = function(id, token) {\n var _this = this;\n this._id = id;\n var wsUrl = \"\".concat(this._baseUrl, \"&id=\").concat(id, \"&token=\").concat(token);\n if (!!this._socket || !this._disconnected) return;\n this._socket = new WebSocket(wsUrl + \"&version=\" + $0d1ed891c5cb27c0$exports.version);\n this._disconnected = false;\n this._socket.onmessage = function(event) {\n var data;\n try {\n data = JSON.parse(event.data);\n $1615705ecc6adca3$exports.default.log(\"Server message received:\", data);\n } catch (e) {\n $1615705ecc6adca3$exports.default.log(\"Invalid server message\", event.data);\n return;\n }\n _this.emit($60fadef21a2daafc$export$3b5c4a4b6354f023.Message, data);\n };\n this._socket.onclose = function(event) {\n if (_this._disconnected) return;\n $1615705ecc6adca3$exports.default.log(\"Socket closed.\", event);\n _this._cleanup();\n _this._disconnected = true;\n _this.emit($60fadef21a2daafc$export$3b5c4a4b6354f023.Disconnected);\n };\n // Take care of the queue of connections if necessary and make sure Peer knows\n // socket is open.\n this._socket.onopen = function() {\n if (_this._disconnected) return;\n _this._sendQueuedMessages();\n $1615705ecc6adca3$exports.default.log(\"Socket open\");\n _this._scheduleHeartbeat();\n };\n };\n $31d11a8d122cb4b7$export$4798917dbf149b79.prototype._scheduleHeartbeat = function() {\n var _this = this;\n this._wsPingTimer = setTimeout(function() {\n _this._sendHeartbeat();\n }, this.pingInterval);\n };\n $31d11a8d122cb4b7$export$4798917dbf149b79.prototype._sendHeartbeat = function() {\n if (!this._wsOpen()) {\n $1615705ecc6adca3$exports.default.log(\"Cannot send heartbeat, because socket closed\");\n return;\n }\n var message = JSON.stringify({\n type: $60fadef21a2daafc$export$adb4a1754da6f10d.Heartbeat\n });\n this._socket.send(message);\n this._scheduleHeartbeat();\n };\n /** Is the websocket currently open? */ $31d11a8d122cb4b7$export$4798917dbf149b79.prototype._wsOpen = function() {\n return !!this._socket && this._socket.readyState === 1;\n };\n /** Send queued messages. */ $31d11a8d122cb4b7$export$4798917dbf149b79.prototype._sendQueuedMessages = function() {\n var e_1, _a;\n //Create copy of queue and clear it,\n //because send method push the message back to queue if smth will go wrong\n var copiedQueue = $31d11a8d122cb4b7$var$__spreadArray([], $31d11a8d122cb4b7$var$__read(this._messagesQueue), false);\n this._messagesQueue = [];\n try {\n for(var copiedQueue_1 = $31d11a8d122cb4b7$var$__values(copiedQueue), copiedQueue_1_1 = copiedQueue_1.next(); !copiedQueue_1_1.done; copiedQueue_1_1 = copiedQueue_1.next()){\n var message = copiedQueue_1_1.value;\n this.send(message);\n }\n } catch (e_1_1) {\n e_1 = {\n error: e_1_1\n };\n } finally{\n try {\n if (copiedQueue_1_1 && !copiedQueue_1_1.done && (_a = copiedQueue_1.return)) _a.call(copiedQueue_1);\n } finally{\n if (e_1) throw e_1.error;\n }\n }\n };\n /** Exposed send for DC & Peer. */ $31d11a8d122cb4b7$export$4798917dbf149b79.prototype.send = function(data) {\n if (this._disconnected) return;\n // If we didn't get an ID yet, we can't yet send anything so we should queue\n // up these messages.\n if (!this._id) {\n this._messagesQueue.push(data);\n return;\n }\n if (!data.type) {\n this.emit($60fadef21a2daafc$export$3b5c4a4b6354f023.Error, \"Invalid message\");\n return;\n }\n if (!this._wsOpen()) return;\n var message = JSON.stringify(data);\n this._socket.send(message);\n };\n $31d11a8d122cb4b7$export$4798917dbf149b79.prototype.close = function() {\n if (this._disconnected) return;\n this._cleanup();\n this._disconnected = true;\n };\n $31d11a8d122cb4b7$export$4798917dbf149b79.prototype._cleanup = function() {\n if (this._socket) {\n this._socket.onopen = this._socket.onmessage = this._socket.onclose = null;\n this._socket.close();\n this._socket = undefined;\n }\n clearTimeout(this._wsPingTimer);\n };\n return $31d11a8d122cb4b7$export$4798917dbf149b79;\n}($ac9b757d51178e15$exports.EventEmitter);\n\n\nvar $353dee38f9ab557b$exports = {};\n\n$parcel$export($353dee38f9ab557b$exports, \"MediaConnection\", () => $353dee38f9ab557b$export$4a84e95a2324ac29, (v) => $353dee38f9ab557b$export$4a84e95a2324ac29 = v);\n\n\nvar $77f14d3e81888156$exports = {};\n\n$parcel$export($77f14d3e81888156$exports, \"Negotiator\", () => $77f14d3e81888156$export$89e6bb5ad64bf4a, (v) => $77f14d3e81888156$export$89e6bb5ad64bf4a = v);\n\n\n\nvar $77f14d3e81888156$var$__assign = false || function() {\n $77f14d3e81888156$var$__assign = Object.assign || function(t) {\n for(var s, i = 1, n = arguments.length; i < n; i++){\n s = arguments[i];\n for(var p in s)if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n };\n return $77f14d3e81888156$var$__assign.apply(this, arguments);\n};\nvar $77f14d3e81888156$var$__awaiter = false || function(thisArg, _arguments, P, generator) {\n function adopt(value) {\n return value instanceof P ? value : new P(function(resolve) {\n resolve(value);\n });\n }\n return new (P || (P = Promise))(function(resolve, reject) {\n function fulfilled(value) {\n try {\n step(generator.next(value));\n } catch (e) {\n reject(e);\n }\n }\n function rejected(value) {\n try {\n step(generator[\"throw\"](value));\n } catch (e) {\n reject(e);\n }\n }\n function step(result) {\n result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);\n }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar $77f14d3e81888156$var$__generator = false || function(thisArg, body) {\n var _ = {\n label: 0,\n sent: function() {\n if (t[0] & 1) throw t[1];\n return t[1];\n },\n trys: [],\n ops: []\n }, f, y, t, g;\n return g = {\n next: verb(0),\n \"throw\": verb(1),\n \"return\": verb(2)\n }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() {\n return this;\n }), g;\n function verb(n) {\n return function(v) {\n return step([\n n,\n v\n ]);\n };\n }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while(_)try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [\n op[0] & 2,\n t.value\n ];\n switch(op[0]){\n case 0:\n case 1:\n t = op;\n break;\n case 4:\n _.label++;\n return {\n value: op[1],\n done: false\n };\n case 5:\n _.label++;\n y = op[1];\n op = [\n 0\n ];\n continue;\n case 7:\n op = _.ops.pop();\n _.trys.pop();\n continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {\n _ = 0;\n continue;\n }\n if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {\n _.label = op[1];\n break;\n }\n if (op[0] === 6 && _.label < t[1]) {\n _.label = t[1];\n t = op;\n break;\n }\n if (t && _.label < t[2]) {\n _.label = t[2];\n _.ops.push(op);\n break;\n }\n if (t[2]) _.ops.pop();\n _.trys.pop();\n continue;\n }\n op = body.call(thisArg, _);\n } catch (e) {\n op = [\n 6,\n e\n ];\n y = 0;\n } finally{\n f = t = 0;\n }\n if (op[0] & 5) throw op[1];\n return {\n value: op[0] ? op[1] : void 0,\n done: true\n };\n }\n};\n/**\n * Manages all negotiations between Peers.\n */ var $77f14d3e81888156$export$89e6bb5ad64bf4a = /** @class */ function() {\n function $77f14d3e81888156$export$89e6bb5ad64bf4a(connection) {\n this.connection = connection;\n }\n /** Returns a PeerConnection object set up correctly (for data, media). */ $77f14d3e81888156$export$89e6bb5ad64bf4a.prototype.startConnection = function(options) {\n var peerConnection = this._startPeerConnection();\n // Set the connection's PC.\n this.connection.peerConnection = peerConnection;\n if (this.connection.type === $60fadef21a2daafc$export$3157d57b4135e3bc.Media && options._stream) this._addTracksToConnection(options._stream, peerConnection);\n // What do we need to do now?\n if (options.originator) {\n if (this.connection.type === $60fadef21a2daafc$export$3157d57b4135e3bc.Data) {\n var dataConnection = this.connection;\n var config = {\n ordered: !!options.reliable\n };\n var dataChannel = peerConnection.createDataChannel(dataConnection.label, config);\n dataConnection.initialize(dataChannel);\n }\n this._makeOffer();\n } else this.handleSDP(\"OFFER\", options.sdp);\n };\n /** Start a PC. */ $77f14d3e81888156$export$89e6bb5ad64bf4a.prototype._startPeerConnection = function() {\n $1615705ecc6adca3$exports.default.log(\"Creating RTCPeerConnection.\");\n var peerConnection = new RTCPeerConnection(this.connection.provider.options.config);\n this._setupListeners(peerConnection);\n return peerConnection;\n };\n /** Set up various WebRTC listeners. */ $77f14d3e81888156$export$89e6bb5ad64bf4a.prototype._setupListeners = function(peerConnection) {\n var _this = this;\n var peerId = this.connection.peer;\n var connectionId = this.connection.connectionId;\n var connectionType = this.connection.type;\n var provider = this.connection.provider;\n // ICE CANDIDATES.\n $1615705ecc6adca3$exports.default.log(\"Listening for ICE candidates.\");\n peerConnection.onicecandidate = function(evt) {\n if (!evt.candidate || !evt.candidate.candidate) return;\n $1615705ecc6adca3$exports.default.log(\"Received ICE candidates for \".concat(peerId, \":\"), evt.candidate);\n provider.socket.send({\n type: $60fadef21a2daafc$export$adb4a1754da6f10d.Candidate,\n payload: {\n candidate: evt.candidate,\n type: connectionType,\n connectionId: connectionId\n },\n dst: peerId\n });\n };\n peerConnection.oniceconnectionstatechange = function() {\n switch(peerConnection.iceConnectionState){\n case \"failed\":\n $1615705ecc6adca3$exports.default.log(\"iceConnectionState is failed, closing connections to \" + peerId);\n _this.connection.emit(\"error\", new Error(\"Negotiation of connection to \" + peerId + \" failed.\"));\n _this.connection.close();\n break;\n case \"closed\":\n $1615705ecc6adca3$exports.default.log(\"iceConnectionState is closed, closing connections to \" + peerId);\n _this.connection.emit(\"error\", new Error(\"Connection to \" + peerId + \" closed.\"));\n _this.connection.close();\n break;\n case \"disconnected\":\n $1615705ecc6adca3$exports.default.log(\"iceConnectionState changed to disconnected on the connection with \" + peerId);\n break;\n case \"completed\":\n peerConnection.onicecandidate = $06cb531ed7840f78$export$7debb50ef11d5e0b.noop;\n break;\n }\n _this.connection.emit(\"iceStateChanged\", peerConnection.iceConnectionState);\n };\n // DATACONNECTION.\n $1615705ecc6adca3$exports.default.log(\"Listening for data channel\");\n // Fired between offer and answer, so options should already be saved\n // in the options hash.\n peerConnection.ondatachannel = function(evt) {\n $1615705ecc6adca3$exports.default.log(\"Received data channel\");\n var dataChannel = evt.channel;\n var connection = provider.getConnection(peerId, connectionId);\n connection.initialize(dataChannel);\n };\n // MEDIACONNECTION.\n $1615705ecc6adca3$exports.default.log(\"Listening for remote stream\");\n peerConnection.ontrack = function(evt) {\n $1615705ecc6adca3$exports.default.log(\"Received remote stream\");\n var stream = evt.streams[0];\n var connection = provider.getConnection(peerId, connectionId);\n if (connection.type === $60fadef21a2daafc$export$3157d57b4135e3bc.Media) {\n var mediaConnection = connection;\n _this._addStreamToMediaConnection(stream, mediaConnection);\n }\n };\n };\n $77f14d3e81888156$export$89e6bb5ad64bf4a.prototype.cleanup = function() {\n $1615705ecc6adca3$exports.default.log(\"Cleaning up PeerConnection to \" + this.connection.peer);\n var peerConnection = this.connection.peerConnection;\n if (!peerConnection) return;\n this.connection.peerConnection = null;\n //unsubscribe from all PeerConnection's events\n peerConnection.onicecandidate = peerConnection.oniceconnectionstatechange = peerConnection.ondatachannel = peerConnection.ontrack = function() {};\n var peerConnectionNotClosed = peerConnection.signalingState !== \"closed\";\n var dataChannelNotClosed = false;\n if (this.connection.type === $60fadef21a2daafc$export$3157d57b4135e3bc.Data) {\n var dataConnection = this.connection;\n var dataChannel = dataConnection.dataChannel;\n if (dataChannel) dataChannelNotClosed = !!dataChannel.readyState && dataChannel.readyState !== \"closed\";\n }\n if (peerConnectionNotClosed || dataChannelNotClosed) peerConnection.close();\n };\n $77f14d3e81888156$export$89e6bb5ad64bf4a.prototype._makeOffer = function() {\n return $77f14d3e81888156$var$__awaiter(this, void 0, Promise, function() {\n var peerConnection, provider, offer, payload, dataConnection, err_2, err_1_1;\n return $77f14d3e81888156$var$__generator(this, function(_a) {\n switch(_a.label){\n case 0:\n peerConnection = this.connection.peerConnection;\n provider = this.connection.provider;\n _a.label = 1;\n case 1:\n _a.trys.push([\n 1,\n 7,\n ,\n 8\n ]);\n return [\n 4 /*yield*/ ,\n peerConnection.createOffer(this.connection.options.constraints)\n ];\n case 2:\n offer = _a.sent();\n $1615705ecc6adca3$exports.default.log(\"Created offer.\");\n if (this.connection.options.sdpTransform && typeof this.connection.options.sdpTransform === \"function\") offer.sdp = this.connection.options.sdpTransform(offer.sdp) || offer.sdp;\n _a.label = 3;\n case 3:\n _a.trys.push([\n 3,\n 5,\n ,\n 6\n ]);\n return [\n 4 /*yield*/ ,\n peerConnection.setLocalDescription(offer)\n ];\n case 4:\n _a.sent();\n $1615705ecc6adca3$exports.default.log(\"Set localDescription:\", offer, \"for:\".concat(this.connection.peer));\n payload = {\n sdp: offer,\n type: this.connection.type,\n connectionId: this.connection.connectionId,\n metadata: this.connection.metadata,\n browser: $06cb531ed7840f78$export$7debb50ef11d5e0b.browser\n };\n if (this.connection.type === $60fadef21a2daafc$export$3157d57b4135e3bc.Data) {\n dataConnection = this.connection;\n payload = $77f14d3e81888156$var$__assign($77f14d3e81888156$var$__assign({}, payload), {\n label: dataConnection.label,\n reliable: dataConnection.reliable,\n serialization: dataConnection.serialization\n });\n }\n provider.socket.send({\n type: $60fadef21a2daafc$export$adb4a1754da6f10d.Offer,\n payload: payload,\n dst: this.connection.peer\n });\n return [\n 3 /*break*/ ,\n 6\n ];\n case 5:\n err_2 = _a.sent();\n // TODO: investigate why _makeOffer is being called from the answer\n if (err_2 != \"OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer\") {\n provider.emitError($60fadef21a2daafc$export$9547aaa2e39030ff.WebRTC, err_2);\n $1615705ecc6adca3$exports.default.log(\"Failed to setLocalDescription, \", err_2);\n }\n return [\n 3 /*break*/ ,\n 6\n ];\n case 6:\n return [\n 3 /*break*/ ,\n 8\n ];\n case 7:\n err_1_1 = _a.sent();\n provider.emitError($60fadef21a2daafc$export$9547aaa2e39030ff.WebRTC, err_1_1);\n $1615705ecc6adca3$exports.default.log(\"Failed to createOffer, \", err_1_1);\n return [\n 3 /*break*/ ,\n 8\n ];\n case 8:\n return [\n 2 /*return*/ \n ];\n }\n });\n });\n };\n $77f14d3e81888156$export$89e6bb5ad64bf4a.prototype._makeAnswer = function() {\n return $77f14d3e81888156$var$__awaiter(this, void 0, Promise, function() {\n var peerConnection, provider, answer, err_3, err_1_2;\n return $77f14d3e81888156$var$__generator(this, function(_a) {\n switch(_a.label){\n case 0:\n peerConnection = this.connection.peerConnection;\n provider = this.connection.provider;\n _a.label = 1;\n case 1:\n _a.trys.push([\n 1,\n 7,\n ,\n 8\n ]);\n return [\n 4 /*yield*/ ,\n peerConnection.createAnswer()\n ];\n case 2:\n answer = _a.sent();\n $1615705ecc6adca3$exports.default.log(\"Created answer.\");\n if (this.connection.options.sdpTransform && typeof this.connection.options.sdpTransform === \"function\") answer.sdp = this.connection.options.sdpTransform(answer.sdp) || answer.sdp;\n _a.label = 3;\n case 3:\n _a.trys.push([\n 3,\n 5,\n ,\n 6\n ]);\n return [\n 4 /*yield*/ ,\n peerConnection.setLocalDescription(answer)\n ];\n case 4:\n _a.sent();\n $1615705ecc6adca3$exports.default.log(\"Set localDescription:\", answer, \"for:\".concat(this.connection.peer));\n provider.socket.send({\n type: $60fadef21a2daafc$export$adb4a1754da6f10d.Answer,\n payload: {\n sdp: answer,\n type: this.connection.type,\n connectionId: this.connection.connectionId,\n browser: $06cb531ed7840f78$export$7debb50ef11d5e0b.browser\n },\n dst: this.connection.peer\n });\n return [\n 3 /*break*/ ,\n 6\n ];\n case 5:\n err_3 = _a.sent();\n provider.emitError($60fadef21a2daafc$export$9547aaa2e39030ff.WebRTC, err_3);\n $1615705ecc6adca3$exports.default.log(\"Failed to setLocalDescription, \", err_3);\n return [\n 3 /*break*/ ,\n 6\n ];\n case 6:\n return [\n 3 /*break*/ ,\n 8\n ];\n case 7:\n err_1_2 = _a.sent();\n provider.emitError($60fadef21a2daafc$export$9547aaa2e39030ff.WebRTC, err_1_2);\n $1615705ecc6adca3$exports.default.log(\"Failed to create answer, \", err_1_2);\n return [\n 3 /*break*/ ,\n 8\n ];\n case 8:\n return [\n 2 /*return*/ \n ];\n }\n });\n });\n };\n /** Handle an SDP. */ $77f14d3e81888156$export$89e6bb5ad64bf4a.prototype.handleSDP = function(type, sdp) {\n return $77f14d3e81888156$var$__awaiter(this, void 0, Promise, function() {\n var peerConnection, provider, self, err_4;\n return $77f14d3e81888156$var$__generator(this, function(_a) {\n switch(_a.label){\n case 0:\n sdp = new RTCSessionDescription(sdp);\n peerConnection = this.connection.peerConnection;\n provider = this.connection.provider;\n $1615705ecc6adca3$exports.default.log(\"Setting remote description\", sdp);\n self = this;\n _a.label = 1;\n case 1:\n _a.trys.push([\n 1,\n 5,\n ,\n 6\n ]);\n return [\n 4 /*yield*/ ,\n peerConnection.setRemoteDescription(sdp)\n ];\n case 2:\n _a.sent();\n $1615705ecc6adca3$exports.default.log(\"Set remoteDescription:\".concat(type, \" for:\").concat(this.connection.peer));\n if (!(type === \"OFFER\")) return [\n 3 /*break*/ ,\n 4\n ];\n return [\n 4 /*yield*/ ,\n self._makeAnswer()\n ];\n case 3:\n _a.sent();\n _a.label = 4;\n case 4:\n return [\n 3 /*break*/ ,\n 6\n ];\n case 5:\n err_4 = _a.sent();\n provider.emitError($60fadef21a2daafc$export$9547aaa2e39030ff.WebRTC, err_4);\n $1615705ecc6adca3$exports.default.log(\"Failed to setRemoteDescription, \", err_4);\n return [\n 3 /*break*/ ,\n 6\n ];\n case 6:\n return [\n 2 /*return*/ \n ];\n }\n });\n });\n };\n /** Handle a candidate. */ $77f14d3e81888156$export$89e6bb5ad64bf4a.prototype.handleCandidate = function(ice) {\n return $77f14d3e81888156$var$__awaiter(this, void 0, Promise, function() {\n var candidate, sdpMLineIndex, sdpMid, peerConnection, provider, err_5;\n return $77f14d3e81888156$var$__generator(this, function(_a) {\n switch(_a.label){\n case 0:\n $1615705ecc6adca3$exports.default.log(\"handleCandidate:\", ice);\n candidate = ice.candidate;\n sdpMLineIndex = ice.sdpMLineIndex;\n sdpMid = ice.sdpMid;\n peerConnection = this.connection.peerConnection;\n provider = this.connection.provider;\n _a.label = 1;\n case 1:\n _a.trys.push([\n 1,\n 3,\n ,\n 4\n ]);\n return [\n 4 /*yield*/ ,\n peerConnection.addIceCandidate(new RTCIceCandidate({\n sdpMid: sdpMid,\n sdpMLineIndex: sdpMLineIndex,\n candidate: candidate\n }))\n ];\n case 2:\n _a.sent();\n $1615705ecc6adca3$exports.default.log(\"Added ICE candidate for:\".concat(this.connection.peer));\n return [\n 3 /*break*/ ,\n 4\n ];\n case 3:\n err_5 = _a.sent();\n provider.emitError($60fadef21a2daafc$export$9547aaa2e39030ff.WebRTC, err_5);\n $1615705ecc6adca3$exports.default.log(\"Failed to handleCandidate, \", err_5);\n return [\n 3 /*break*/ ,\n 4\n ];\n case 4:\n return [\n 2 /*return*/ \n ];\n }\n });\n });\n };\n $77f14d3e81888156$export$89e6bb5ad64bf4a.prototype._addTracksToConnection = function(stream, peerConnection) {\n $1615705ecc6adca3$exports.default.log(\"add tracks from stream \".concat(stream.id, \" to peer connection\"));\n if (!peerConnection.addTrack) return $1615705ecc6adca3$exports.default.error(\"Your browser does't support RTCPeerConnection#addTrack. Ignored.\");\n stream.getTracks().forEach(function(track) {\n peerConnection.addTrack(track, stream);\n });\n };\n $77f14d3e81888156$export$89e6bb5ad64bf4a.prototype._addStreamToMediaConnection = function(stream, mediaConnection) {\n $1615705ecc6adca3$exports.default.log(\"add stream \".concat(stream.id, \" to media connection \").concat(mediaConnection.connectionId));\n mediaConnection.addStream(stream);\n };\n return $77f14d3e81888156$export$89e6bb5ad64bf4a;\n}();\n\n\n\nvar $0b3b332fd86c5202$exports = {};\n\n$parcel$export($0b3b332fd86c5202$exports, \"BaseConnection\", () => $0b3b332fd86c5202$export$23a2a68283c24d80, (v) => $0b3b332fd86c5202$export$23a2a68283c24d80 = v);\n\nvar $0b3b332fd86c5202$var$__extends = false || function() {\n var extendStatics = function(d1, b1) {\n extendStatics = Object.setPrototypeOf || ({\n __proto__: []\n }) instanceof Array && function(d, b) {\n d.__proto__ = b;\n } || function(d, b) {\n for(var p in b)if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n };\n return extendStatics(d1, b1);\n };\n return function(d, b) {\n if (typeof b !== \"function\" && b !== null) throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\nvar $0b3b332fd86c5202$export$23a2a68283c24d80 = /** @class */ function(_super) {\n $0b3b332fd86c5202$var$__extends($0b3b332fd86c5202$export$23a2a68283c24d80, _super);\n function $0b3b332fd86c5202$export$23a2a68283c24d80(peer, provider, options) {\n var _this = _super.call(this) || this;\n _this.peer = peer;\n _this.provider = provider;\n _this.options = options;\n _this._open = false;\n _this.metadata = options.metadata;\n return _this;\n }\n Object.defineProperty($0b3b332fd86c5202$export$23a2a68283c24d80.prototype, \"open\", {\n get: function() {\n return this._open;\n },\n enumerable: false,\n configurable: true\n });\n return $0b3b332fd86c5202$export$23a2a68283c24d80;\n}($ac9b757d51178e15$exports.EventEmitter);\n\n\nvar $353dee38f9ab557b$var$__extends = false || function() {\n var extendStatics = function(d1, b1) {\n extendStatics = Object.setPrototypeOf || ({\n __proto__: []\n }) instanceof Array && function(d, b) {\n d.__proto__ = b;\n } || function(d, b) {\n for(var p in b)if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n };\n return extendStatics(d1, b1);\n };\n return function(d, b) {\n if (typeof b !== \"function\" && b !== null) throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\nvar $353dee38f9ab557b$var$__assign = false || function() {\n $353dee38f9ab557b$var$__assign = Object.assign || function(t) {\n for(var s, i = 1, n = arguments.length; i < n; i++){\n s = arguments[i];\n for(var p in s)if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n };\n return $353dee38f9ab557b$var$__assign.apply(this, arguments);\n};\nvar $353dee38f9ab557b$var$__values = false || function(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function() {\n if (o && i >= o.length) o = void 0;\n return {\n value: o && o[i++],\n done: !o\n };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n};\n/**\n * Wraps the streaming interface between two Peers.\n */ var $353dee38f9ab557b$export$4a84e95a2324ac29 = /** @class */ function(_super) {\n $353dee38f9ab557b$var$__extends($353dee38f9ab557b$export$4a84e95a2324ac29, _super);\n function $353dee38f9ab557b$export$4a84e95a2324ac29(peerId, provider, options) {\n var _this = _super.call(this, peerId, provider, options) || this;\n _this._localStream = _this.options._stream;\n _this.connectionId = _this.options.connectionId || $353dee38f9ab557b$export$4a84e95a2324ac29.ID_PREFIX + $06cb531ed7840f78$export$7debb50ef11d5e0b.randomToken();\n _this._negotiator = new $77f14d3e81888156$exports.Negotiator(_this);\n if (_this._localStream) _this._negotiator.startConnection({\n _stream: _this._localStream,\n originator: true\n });\n return _this;\n }\n Object.defineProperty($353dee38f9ab557b$export$4a84e95a2324ac29.prototype, \"type\", {\n get: function() {\n return $60fadef21a2daafc$export$3157d57b4135e3bc.Media;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($353dee38f9ab557b$export$4a84e95a2324ac29.prototype, \"localStream\", {\n get: function() {\n return this._localStream;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($353dee38f9ab557b$export$4a84e95a2324ac29.prototype, \"remoteStream\", {\n get: function() {\n return this._remoteStream;\n },\n enumerable: false,\n configurable: true\n });\n $353dee38f9ab557b$export$4a84e95a2324ac29.prototype.addStream = function(remoteStream) {\n $1615705ecc6adca3$exports.default.log(\"Receiving stream\", remoteStream);\n this._remoteStream = remoteStream;\n _super.prototype.emit.call(this, \"stream\", remoteStream); // Should we call this `open`?\n };\n $353dee38f9ab557b$export$4a84e95a2324ac29.prototype.handleMessage = function(message) {\n var type = message.type;\n var payload = message.payload;\n switch(message.type){\n case $60fadef21a2daafc$export$adb4a1754da6f10d.Answer:\n // Forward to negotiator\n this._negotiator.handleSDP(type, payload.sdp);\n this._open = true;\n break;\n case $60fadef21a2daafc$export$adb4a1754da6f10d.Candidate:\n this._negotiator.handleCandidate(payload.candidate);\n break;\n default:\n $1615705ecc6adca3$exports.default.warn(\"Unrecognized message type:\".concat(type, \" from peer:\").concat(this.peer));\n break;\n }\n };\n $353dee38f9ab557b$export$4a84e95a2324ac29.prototype.answer = function(stream, options) {\n var e_1, _a;\n if (options === void 0) options = {};\n if (this._localStream) {\n $1615705ecc6adca3$exports.default.warn(\"Local stream already exists on this MediaConnection. Are you answering a call twice?\");\n return;\n }\n this._localStream = stream;\n if (options && options.sdpTransform) this.options.sdpTransform = options.sdpTransform;\n this._negotiator.startConnection($353dee38f9ab557b$var$__assign($353dee38f9ab557b$var$__assign({}, this.options._payload), {\n _stream: stream\n }));\n // Retrieve lost messages stored because PeerConnection not set up.\n var messages = this.provider._getMessages(this.connectionId);\n try {\n for(var messages_1 = $353dee38f9ab557b$var$__values(messages), messages_1_1 = messages_1.next(); !messages_1_1.done; messages_1_1 = messages_1.next()){\n var message = messages_1_1.value;\n this.handleMessage(message);\n }\n } catch (e_1_1) {\n e_1 = {\n error: e_1_1\n };\n } finally{\n try {\n if (messages_1_1 && !messages_1_1.done && (_a = messages_1.return)) _a.call(messages_1);\n } finally{\n if (e_1) throw e_1.error;\n }\n }\n this._open = true;\n };\n /**\n * Exposed functionality for users.\n */ /** Allows user to close connection. */ $353dee38f9ab557b$export$4a84e95a2324ac29.prototype.close = function() {\n if (this._negotiator) {\n this._negotiator.cleanup();\n this._negotiator = null;\n }\n this._localStream = null;\n this._remoteStream = null;\n if (this.provider) {\n this.provider._removeConnection(this);\n this.provider = null;\n }\n if (this.options && this.options._stream) this.options._stream = null;\n if (!this.open) return;\n this._open = false;\n _super.prototype.emit.call(this, \"close\");\n };\n $353dee38f9ab557b$export$4a84e95a2324ac29.ID_PREFIX = \"mc_\";\n return $353dee38f9ab557b$export$4a84e95a2324ac29;\n}($0b3b332fd86c5202$exports.BaseConnection);\n\n\nvar $3356170d7bce7f20$exports = {};\n\n$parcel$export($3356170d7bce7f20$exports, \"DataConnection\", () => $3356170d7bce7f20$export$d365f7ad9d7df9c9, (v) => $3356170d7bce7f20$export$d365f7ad9d7df9c9 = v);\n\n\n\n\n\nvar $3014d862dcc9946b$exports = {};\n\n$parcel$export($3014d862dcc9946b$exports, \"EncodingQueue\", () => $3014d862dcc9946b$export$c6913ae0ed687038, (v) => $3014d862dcc9946b$export$c6913ae0ed687038 = v);\n\n\nvar $3014d862dcc9946b$var$__extends = false || function() {\n var extendStatics = function(d1, b1) {\n extendStatics = Object.setPrototypeOf || ({\n __proto__: []\n }) instanceof Array && function(d, b) {\n d.__proto__ = b;\n } || function(d, b) {\n for(var p in b)if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n };\n return extendStatics(d1, b1);\n };\n return function(d, b) {\n if (typeof b !== \"function\" && b !== null) throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\nvar $3014d862dcc9946b$export$c6913ae0ed687038 = /** @class */ function(_super) {\n $3014d862dcc9946b$var$__extends($3014d862dcc9946b$export$c6913ae0ed687038, _super);\n function $3014d862dcc9946b$export$c6913ae0ed687038() {\n var _this = _super.call(this) || this;\n _this.fileReader = new FileReader();\n _this._queue = [];\n _this._processing = false;\n _this.fileReader.onload = function(evt) {\n _this._processing = false;\n if (evt.target) _this.emit(\"done\", evt.target.result);\n _this.doNextTask();\n };\n _this.fileReader.onerror = function(evt) {\n $1615705ecc6adca3$exports.default.error(\"EncodingQueue error:\", evt);\n _this._processing = false;\n _this.destroy();\n _this.emit(\"error\", evt);\n };\n return _this;\n }\n Object.defineProperty($3014d862dcc9946b$export$c6913ae0ed687038.prototype, \"queue\", {\n get: function() {\n return this._queue;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($3014d862dcc9946b$export$c6913ae0ed687038.prototype, \"size\", {\n get: function() {\n return this.queue.length;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($3014d862dcc9946b$export$c6913ae0ed687038.prototype, \"processing\", {\n get: function() {\n return this._processing;\n },\n enumerable: false,\n configurable: true\n });\n $3014d862dcc9946b$export$c6913ae0ed687038.prototype.enque = function(blob) {\n this.queue.push(blob);\n if (this.processing) return;\n this.doNextTask();\n };\n $3014d862dcc9946b$export$c6913ae0ed687038.prototype.destroy = function() {\n this.fileReader.abort();\n this._queue = [];\n };\n $3014d862dcc9946b$export$c6913ae0ed687038.prototype.doNextTask = function() {\n if (this.size === 0) return;\n if (this.processing) return;\n this._processing = true;\n this.fileReader.readAsArrayBuffer(this.queue.shift());\n };\n return $3014d862dcc9946b$export$c6913ae0ed687038;\n}($ac9b757d51178e15$exports.EventEmitter);\n\n\nvar $3356170d7bce7f20$var$__extends = false || function() {\n var extendStatics = function(d1, b1) {\n extendStatics = Object.setPrototypeOf || ({\n __proto__: []\n }) instanceof Array && function(d, b) {\n d.__proto__ = b;\n } || function(d, b) {\n for(var p in b)if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n };\n return extendStatics(d1, b1);\n };\n return function(d, b) {\n if (typeof b !== \"function\" && b !== null) throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\nvar $3356170d7bce7f20$var$__values = false || function(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function() {\n if (o && i >= o.length) o = void 0;\n return {\n value: o && o[i++],\n done: !o\n };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n};\n/**\n * Wraps a DataChannel between two Peers.\n */ var $3356170d7bce7f20$export$d365f7ad9d7df9c9 = /** @class */ function(_super) {\n $3356170d7bce7f20$var$__extends($3356170d7bce7f20$export$d365f7ad9d7df9c9, _super);\n function $3356170d7bce7f20$export$d365f7ad9d7df9c9(peerId, provider, options) {\n var _this = _super.call(this, peerId, provider, options) || this;\n _this.stringify = JSON.stringify;\n _this.parse = JSON.parse;\n _this._buffer = [];\n _this._bufferSize = 0;\n _this._buffering = false;\n _this._chunkedData = {};\n _this._encodingQueue = new $3014d862dcc9946b$exports.EncodingQueue();\n _this.connectionId = _this.options.connectionId || $3356170d7bce7f20$export$d365f7ad9d7df9c9.ID_PREFIX + $06cb531ed7840f78$export$7debb50ef11d5e0b.randomToken();\n _this.label = _this.options.label || _this.connectionId;\n _this.serialization = _this.options.serialization || $60fadef21a2daafc$export$89f507cf986a947.Binary;\n _this.reliable = !!_this.options.reliable;\n _this._encodingQueue.on(\"done\", function(ab) {\n _this._bufferedSend(ab);\n });\n _this._encodingQueue.on(\"error\", function() {\n $1615705ecc6adca3$exports.default.error(\"DC#\".concat(_this.connectionId, \": Error occured in encoding from blob to arraybuffer, close DC\"));\n _this.close();\n });\n _this._negotiator = new $77f14d3e81888156$exports.Negotiator(_this);\n _this._negotiator.startConnection(_this.options._payload || {\n originator: true\n });\n return _this;\n }\n Object.defineProperty($3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype, \"type\", {\n get: function() {\n return $60fadef21a2daafc$export$3157d57b4135e3bc.Data;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype, \"dataChannel\", {\n get: function() {\n return this._dc;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype, \"bufferSize\", {\n get: function() {\n return this._bufferSize;\n },\n enumerable: false,\n configurable: true\n });\n /** Called by the Negotiator when the DataChannel is ready. */ $3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype.initialize = function(dc) {\n this._dc = dc;\n this._configureDataChannel();\n };\n $3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype._configureDataChannel = function() {\n var _this = this;\n if (!$06cb531ed7840f78$export$7debb50ef11d5e0b.supports.binaryBlob || $06cb531ed7840f78$export$7debb50ef11d5e0b.supports.reliable) this.dataChannel.binaryType = \"arraybuffer\";\n this.dataChannel.onopen = function() {\n $1615705ecc6adca3$exports.default.log(\"DC#\".concat(_this.connectionId, \" dc connection success\"));\n _this._open = true;\n _this.emit(\"open\");\n };\n this.dataChannel.onmessage = function(e) {\n $1615705ecc6adca3$exports.default.log(\"DC#\".concat(_this.connectionId, \" dc onmessage:\"), e.data);\n _this._handleDataMessage(e);\n };\n this.dataChannel.onclose = function() {\n $1615705ecc6adca3$exports.default.log(\"DC#\".concat(_this.connectionId, \" dc closed for:\"), _this.peer);\n _this.close();\n };\n };\n // Handles a DataChannel message.\n $3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype._handleDataMessage = function(_a) {\n var _this = this;\n var data = _a.data;\n var datatype = data.constructor;\n var isBinarySerialization = this.serialization === $60fadef21a2daafc$export$89f507cf986a947.Binary || this.serialization === $60fadef21a2daafc$export$89f507cf986a947.BinaryUTF8;\n var deserializedData = data;\n if (isBinarySerialization) {\n if (datatype === Blob) {\n // Datatype should never be blob\n $06cb531ed7840f78$export$7debb50ef11d5e0b.blobToArrayBuffer(data, function(ab) {\n var unpackedData = $06cb531ed7840f78$export$7debb50ef11d5e0b.unpack(ab);\n _this.emit(\"data\", unpackedData);\n });\n return;\n } else if (datatype === ArrayBuffer) deserializedData = $06cb531ed7840f78$export$7debb50ef11d5e0b.unpack(data);\n else if (datatype === String) {\n // String fallback for binary data for browsers that don't support binary yet\n var ab1 = $06cb531ed7840f78$export$7debb50ef11d5e0b.binaryStringToArrayBuffer(data);\n deserializedData = $06cb531ed7840f78$export$7debb50ef11d5e0b.unpack(ab1);\n }\n } else if (this.serialization === $60fadef21a2daafc$export$89f507cf986a947.JSON) deserializedData = this.parse(data);\n // Check if we've chunked--if so, piece things back together.\n // We're guaranteed that this isn't 0.\n if (deserializedData.__peerData) {\n this._handleChunk(deserializedData);\n return;\n }\n _super.prototype.emit.call(this, \"data\", deserializedData);\n };\n $3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype._handleChunk = function(data) {\n var id = data.__peerData;\n var chunkInfo = this._chunkedData[id] || {\n data: [],\n count: 0,\n total: data.total\n };\n chunkInfo.data[data.n] = data.data;\n chunkInfo.count++;\n this._chunkedData[id] = chunkInfo;\n if (chunkInfo.total === chunkInfo.count) {\n // Clean up before making the recursive call to `_handleDataMessage`.\n delete this._chunkedData[id];\n // We've received all the chunks--time to construct the complete data.\n var data_1 = new Blob(chunkInfo.data);\n this._handleDataMessage({\n data: data_1\n });\n }\n };\n /**\n * Exposed functionality for users.\n */ /** Allows user to close connection. */ $3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype.close = function() {\n this._buffer = [];\n this._bufferSize = 0;\n this._chunkedData = {};\n if (this._negotiator) {\n this._negotiator.cleanup();\n this._negotiator = null;\n }\n if (this.provider) {\n this.provider._removeConnection(this);\n this.provider = null;\n }\n if (this.dataChannel) {\n this.dataChannel.onopen = null;\n this.dataChannel.onmessage = null;\n this.dataChannel.onclose = null;\n this._dc = null;\n }\n if (this._encodingQueue) {\n this._encodingQueue.destroy();\n this._encodingQueue.removeAllListeners();\n this._encodingQueue = null;\n }\n if (!this.open) return;\n this._open = false;\n _super.prototype.emit.call(this, \"close\");\n };\n /** Allows user to send data. */ $3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype.send = function(data, chunked) {\n if (!this.open) {\n _super.prototype.emit.call(this, \"error\", new Error(\"Connection is not open. You should listen for the `open` event before sending messages.\"));\n return;\n }\n if (this.serialization === $60fadef21a2daafc$export$89f507cf986a947.JSON) this._bufferedSend(this.stringify(data));\n else if (this.serialization === $60fadef21a2daafc$export$89f507cf986a947.Binary || this.serialization === $60fadef21a2daafc$export$89f507cf986a947.BinaryUTF8) {\n var blob = $06cb531ed7840f78$export$7debb50ef11d5e0b.pack(data);\n if (!chunked && blob.size > $06cb531ed7840f78$export$7debb50ef11d5e0b.chunkedMTU) {\n this._sendChunks(blob);\n return;\n }\n if (!$06cb531ed7840f78$export$7debb50ef11d5e0b.supports.binaryBlob) // We only do this if we really need to (e.g. blobs are not supported),\n // because this conversion is costly.\n this._encodingQueue.enque(blob);\n else this._bufferedSend(blob);\n } else this._bufferedSend(data);\n };\n $3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype._bufferedSend = function(msg) {\n if (this._buffering || !this._trySend(msg)) {\n this._buffer.push(msg);\n this._bufferSize = this._buffer.length;\n }\n };\n // Returns true if the send succeeds.\n $3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype._trySend = function(msg) {\n var _this = this;\n if (!this.open) return false;\n if (this.dataChannel.bufferedAmount > $3356170d7bce7f20$export$d365f7ad9d7df9c9.MAX_BUFFERED_AMOUNT) {\n this._buffering = true;\n setTimeout(function() {\n _this._buffering = false;\n _this._tryBuffer();\n }, 50);\n return false;\n }\n try {\n this.dataChannel.send(msg);\n } catch (e) {\n $1615705ecc6adca3$exports.default.error(\"DC#:\".concat(this.connectionId, \" Error when sending:\"), e);\n this._buffering = true;\n this.close();\n return false;\n }\n return true;\n };\n // Try to send the first message in the buffer.\n $3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype._tryBuffer = function() {\n if (!this.open) return;\n if (this._buffer.length === 0) return;\n var msg = this._buffer[0];\n if (this._trySend(msg)) {\n this._buffer.shift();\n this._bufferSize = this._buffer.length;\n this._tryBuffer();\n }\n };\n $3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype._sendChunks = function(blob) {\n var e_1, _a;\n var blobs = $06cb531ed7840f78$export$7debb50ef11d5e0b.chunk(blob);\n $1615705ecc6adca3$exports.default.log(\"DC#\".concat(this.connectionId, \" Try to send \").concat(blobs.length, \" chunks...\"));\n try {\n for(var blobs_1 = $3356170d7bce7f20$var$__values(blobs), blobs_1_1 = blobs_1.next(); !blobs_1_1.done; blobs_1_1 = blobs_1.next()){\n var blob_1 = blobs_1_1.value;\n this.send(blob_1, true);\n }\n } catch (e_1_1) {\n e_1 = {\n error: e_1_1\n };\n } finally{\n try {\n if (blobs_1_1 && !blobs_1_1.done && (_a = blobs_1.return)) _a.call(blobs_1);\n } finally{\n if (e_1) throw e_1.error;\n }\n }\n };\n $3356170d7bce7f20$export$d365f7ad9d7df9c9.prototype.handleMessage = function(message) {\n var payload = message.payload;\n switch(message.type){\n case $60fadef21a2daafc$export$adb4a1754da6f10d.Answer:\n this._negotiator.handleSDP(message.type, payload.sdp);\n break;\n case $60fadef21a2daafc$export$adb4a1754da6f10d.Candidate:\n this._negotiator.handleCandidate(payload.candidate);\n break;\n default:\n $1615705ecc6adca3$exports.default.warn(\"Unrecognized message type:\", message.type, \"from peer:\", this.peer);\n break;\n }\n };\n $3356170d7bce7f20$export$d365f7ad9d7df9c9.ID_PREFIX = \"dc_\";\n $3356170d7bce7f20$export$d365f7ad9d7df9c9.MAX_BUFFERED_AMOUNT = 8388608;\n return $3356170d7bce7f20$export$d365f7ad9d7df9c9;\n}($0b3b332fd86c5202$exports.BaseConnection);\n\n\n\nvar $9e85b3e1327369e6$exports = {};\n\n$parcel$export($9e85b3e1327369e6$exports, \"API\", () => $9e85b3e1327369e6$export$2c4e825dc9120f87, (v) => $9e85b3e1327369e6$export$2c4e825dc9120f87 = v);\n\n\n\nvar $9e85b3e1327369e6$var$__awaiter = false || function(thisArg, _arguments, P, generator) {\n function adopt(value) {\n return value instanceof P ? value : new P(function(resolve) {\n resolve(value);\n });\n }\n return new (P || (P = Promise))(function(resolve, reject) {\n function fulfilled(value) {\n try {\n step(generator.next(value));\n } catch (e) {\n reject(e);\n }\n }\n function rejected(value) {\n try {\n step(generator[\"throw\"](value));\n } catch (e) {\n reject(e);\n }\n }\n function step(result) {\n result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);\n }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar $9e85b3e1327369e6$var$__generator = false || function(thisArg, body) {\n var _ = {\n label: 0,\n sent: function() {\n if (t[0] & 1) throw t[1];\n return t[1];\n },\n trys: [],\n ops: []\n }, f, y, t, g;\n return g = {\n next: verb(0),\n \"throw\": verb(1),\n \"return\": verb(2)\n }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() {\n return this;\n }), g;\n function verb(n) {\n return function(v) {\n return step([\n n,\n v\n ]);\n };\n }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while(_)try {\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [\n op[0] & 2,\n t.value\n ];\n switch(op[0]){\n case 0:\n case 1:\n t = op;\n break;\n case 4:\n _.label++;\n return {\n value: op[1],\n done: false\n };\n case 5:\n _.label++;\n y = op[1];\n op = [\n 0\n ];\n continue;\n case 7:\n op = _.ops.pop();\n _.trys.pop();\n continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {\n _ = 0;\n continue;\n }\n if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {\n _.label = op[1];\n break;\n }\n if (op[0] === 6 && _.label < t[1]) {\n _.label = t[1];\n t = op;\n break;\n }\n if (t && _.label < t[2]) {\n _.label = t[2];\n _.ops.push(op);\n break;\n }\n if (t[2]) _.ops.pop();\n _.trys.pop();\n continue;\n }\n op = body.call(thisArg, _);\n } catch (e) {\n op = [\n 6,\n e\n ];\n y = 0;\n } finally{\n f = t = 0;\n }\n if (op[0] & 5) throw op[1];\n return {\n value: op[0] ? op[1] : void 0,\n done: true\n };\n }\n};\nvar $9e85b3e1327369e6$export$2c4e825dc9120f87 = /** @class */ function() {\n function $9e85b3e1327369e6$export$2c4e825dc9120f87(_options) {\n this._options = _options;\n }\n $9e85b3e1327369e6$export$2c4e825dc9120f87.prototype._buildRequest = function(method) {\n var protocol = this._options.secure ? \"https\" : \"http\";\n var _a = this._options, host = _a.host, port = _a.port, path = _a.path, key = _a.key;\n var url = new URL(\"\".concat(protocol, \"://\").concat(host, \":\").concat(port).concat(path).concat(key, \"/\").concat(method));\n // TODO: Why timestamp, why random?\n url.searchParams.set(\"ts\", \"\".concat(Date.now()).concat(Math.random()));\n url.searchParams.set(\"version\", $0d1ed891c5cb27c0$exports.version);\n return fetch(url.href, {\n referrerPolicy: this._options.referrerPolicy\n });\n };\n /** Get a unique ID from the server via XHR and initialize with it. */ $9e85b3e1327369e6$export$2c4e825dc9120f87.prototype.retrieveId = function() {\n return $9e85b3e1327369e6$var$__awaiter(this, void 0, Promise, function() {\n var response, error_1, pathError;\n return $9e85b3e1327369e6$var$__generator(this, function(_a) {\n switch(_a.label){\n case 0:\n _a.trys.push([\n 0,\n 2,\n ,\n 3\n ]);\n return [\n 4 /*yield*/ ,\n this._buildRequest(\"id\")\n ];\n case 1:\n response = _a.sent();\n if (response.status !== 200) throw new Error(\"Error. Status:\".concat(response.status));\n return [\n 2 /*return*/ ,\n response.text()\n ];\n case 2:\n error_1 = _a.sent();\n $1615705ecc6adca3$exports.default.error(\"Error retrieving ID\", error_1);\n pathError = \"\";\n if (this._options.path === \"/\" && this._options.host !== $06cb531ed7840f78$export$7debb50ef11d5e0b.CLOUD_HOST) pathError = \" If you passed in a `path` to your self-hosted PeerServer, you'll also need to pass in that same path when creating a new Peer.\";\n throw new Error(\"Could not get an ID from the server.\" + pathError);\n case 3:\n return [\n 2 /*return*/ \n ];\n }\n });\n });\n };\n /** @deprecated */ $9e85b3e1327369e6$export$2c4e825dc9120f87.prototype.listAllPeers = function() {\n return $9e85b3e1327369e6$var$__awaiter(this, void 0, Promise, function() {\n var response, helpfulError, error_2;\n return $9e85b3e1327369e6$var$__generator(this, function(_a) {\n switch(_a.label){\n case 0:\n _a.trys.push([\n 0,\n 2,\n ,\n 3\n ]);\n return [\n 4 /*yield*/ ,\n this._buildRequest(\"peers\")\n ];\n case 1:\n response = _a.sent();\n if (response.status !== 200) {\n if (response.status === 401) {\n helpfulError = \"\";\n if (this._options.host === $06cb531ed7840f78$export$7debb50ef11d5e0b.CLOUD_HOST) helpfulError = \"It looks like you're using the cloud server. You can email team@peerjs.com to enable peer listing for your API key.\";\n else helpfulError = \"You need to enable `allow_discovery` on your self-hosted PeerServer to use this feature.\";\n throw new Error(\"It doesn't look like you have permission to list peers IDs. \" + helpfulError);\n }\n throw new Error(\"Error. Status:\".concat(response.status));\n }\n return [\n 2 /*return*/ ,\n response.json()\n ];\n case 2:\n error_2 = _a.sent();\n $1615705ecc6adca3$exports.default.error(\"Error retrieving list peers\", error_2);\n throw new Error(\"Could not get list peers from the server.\" + error_2);\n case 3:\n return [\n 2 /*return*/ \n ];\n }\n });\n });\n };\n return $9e85b3e1327369e6$export$2c4e825dc9120f87;\n}();\n\n\nvar $26088d7da5b03f69$var$__extends = false || function() {\n var extendStatics = function(d1, b1) {\n extendStatics = Object.setPrototypeOf || ({\n __proto__: []\n }) instanceof Array && function(d, b) {\n d.__proto__ = b;\n } || function(d, b) {\n for(var p in b)if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p];\n };\n return extendStatics(d1, b1);\n };\n return function(d, b) {\n if (typeof b !== \"function\" && b !== null) throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\n extendStatics(d, b);\n function __() {\n this.constructor = d;\n }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n}();\nvar $26088d7da5b03f69$var$__assign = false || function() {\n $26088d7da5b03f69$var$__assign = Object.assign || function(t) {\n for(var s, i = 1, n = arguments.length; i < n; i++){\n s = arguments[i];\n for(var p in s)if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\n }\n return t;\n };\n return $26088d7da5b03f69$var$__assign.apply(this, arguments);\n};\nvar $26088d7da5b03f69$var$__values = false || function(o) {\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\n if (m) return m.call(o);\n if (o && typeof o.length === \"number\") return {\n next: function() {\n if (o && i >= o.length) o = void 0;\n return {\n value: o && o[i++],\n done: !o\n };\n }\n };\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\n};\nvar $26088d7da5b03f69$var$__read = false || function(o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while((n === void 0 || n-- > 0) && !(r = i.next()).done)ar.push(r.value);\n } catch (error) {\n e = {\n error: error\n };\n } finally{\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n } finally{\n if (e) throw e.error;\n }\n }\n return ar;\n};\nvar $26088d7da5b03f69$var$PeerOptions = /** @class */ function() {\n function PeerOptions() {}\n return PeerOptions;\n}();\n/**\n * A peer who can initiate connections with other peers.\n */ var $26088d7da5b03f69$export$ecd1fc136c422448 = /** @class */ function(_super) {\n $26088d7da5b03f69$var$__extends($26088d7da5b03f69$export$ecd1fc136c422448, _super);\n function $26088d7da5b03f69$export$ecd1fc136c422448(id1, options) {\n var _this = _super.call(this) || this;\n _this._id = null;\n _this._lastServerId = null;\n // States.\n _this._destroyed = false; // Connections have been killed\n _this._disconnected = false; // Connection to PeerServer killed but P2P connections still active\n _this._open = false; // Sockets and such are not yet open.\n _this._connections = new Map(); // All connections for this peer.\n _this._lostMessages = new Map(); // src => [list of messages]\n var userId;\n // Deal with overloading\n if (id1 && id1.constructor == Object) options = id1;\n else if (id1) userId = id1.toString();\n // Configurize options\n options = $26088d7da5b03f69$var$__assign({\n debug: 0,\n host: $06cb531ed7840f78$export$7debb50ef11d5e0b.CLOUD_HOST,\n port: $06cb531ed7840f78$export$7debb50ef11d5e0b.CLOUD_PORT,\n path: \"/\",\n key: $26088d7da5b03f69$export$ecd1fc136c422448.DEFAULT_KEY,\n token: $06cb531ed7840f78$export$7debb50ef11d5e0b.randomToken(),\n config: $06cb531ed7840f78$export$7debb50ef11d5e0b.defaultConfig,\n referrerPolicy: \"strict-origin-when-cross-origin\"\n }, options);\n _this._options = options;\n // Detect relative URL host.\n if (_this._options.host === \"/\") _this._options.host = window.location.hostname;\n // Set path correctly.\n if (_this._options.path) {\n if (_this._options.path[0] !== \"/\") _this._options.path = \"/\" + _this._options.path;\n if (_this._options.path[_this._options.path.length - 1] !== \"/\") _this._options.path += \"/\";\n }\n // Set whether we use SSL to same as current host\n if (_this._options.secure === undefined && _this._options.host !== $06cb531ed7840f78$export$7debb50ef11d5e0b.CLOUD_HOST) _this._options.secure = $06cb531ed7840f78$export$7debb50ef11d5e0b.isSecure();\n else if (_this._options.host == $06cb531ed7840f78$export$7debb50ef11d5e0b.CLOUD_HOST) _this._options.secure = true;\n // Set a custom log function if present\n if (_this._options.logFunction) $1615705ecc6adca3$exports.default.setLogFunction(_this._options.logFunction);\n $1615705ecc6adca3$exports.default.logLevel = _this._options.debug || 0;\n _this._api = new $9e85b3e1327369e6$exports.API(options);\n _this._socket = _this._createServerConnection();\n // Sanity checks\n // Ensure WebRTC supported\n if (!$06cb531ed7840f78$export$7debb50ef11d5e0b.supports.audioVideo && !$06cb531ed7840f78$export$7debb50ef11d5e0b.supports.data) {\n _this._delayedAbort($60fadef21a2daafc$export$9547aaa2e39030ff.BrowserIncompatible, \"The current browser does not support WebRTC\");\n return _this;\n }\n // Ensure alphanumeric id\n if (!!userId && !$06cb531ed7840f78$export$7debb50ef11d5e0b.validateId(userId)) {\n _this._delayedAbort($60fadef21a2daafc$export$9547aaa2e39030ff.InvalidID, \"ID \\\"\".concat(userId, \"\\\" is invalid\"));\n return _this;\n }\n if (userId) _this._initialize(userId);\n else _this._api.retrieveId().then(function(id) {\n return _this._initialize(id);\n }).catch(function(error) {\n return _this._abort($60fadef21a2daafc$export$9547aaa2e39030ff.ServerError, error);\n });\n return _this;\n }\n Object.defineProperty($26088d7da5b03f69$export$ecd1fc136c422448.prototype, \"id\", {\n /**\n * The brokering ID of this peer\n */ get: function() {\n return this._id;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($26088d7da5b03f69$export$ecd1fc136c422448.prototype, \"options\", {\n get: function() {\n return this._options;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($26088d7da5b03f69$export$ecd1fc136c422448.prototype, \"open\", {\n get: function() {\n return this._open;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($26088d7da5b03f69$export$ecd1fc136c422448.prototype, \"socket\", {\n get: function() {\n return this._socket;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($26088d7da5b03f69$export$ecd1fc136c422448.prototype, \"connections\", {\n /**\n * A hash of all connections associated with this peer, keyed by the remote peer's ID.\n * @deprecated\n * Return type will change from Object to Map<string,[]>\n */ get: function() {\n var e_1, _a;\n var plainConnections = Object.create(null);\n try {\n for(var _b = $26088d7da5b03f69$var$__values(this._connections), _c = _b.next(); !_c.done; _c = _b.next()){\n var _d = $26088d7da5b03f69$var$__read(_c.value, 2), k = _d[0], v = _d[1];\n plainConnections[k] = v;\n }\n } catch (e_1_1) {\n e_1 = {\n error: e_1_1\n };\n } finally{\n try {\n if (_c && !_c.done && (_a = _b.return)) _a.call(_b);\n } finally{\n if (e_1) throw e_1.error;\n }\n }\n return plainConnections;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($26088d7da5b03f69$export$ecd1fc136c422448.prototype, \"destroyed\", {\n /**\n * true if this peer and all of its connections can no longer be used.\n */ get: function() {\n return this._destroyed;\n },\n enumerable: false,\n configurable: true\n });\n Object.defineProperty($26088d7da5b03f69$export$ecd1fc136c422448.prototype, \"disconnected\", {\n /**\n * false if there is an active connection to the PeerServer.\n */ get: function() {\n return this._disconnected;\n },\n enumerable: false,\n configurable: true\n });\n $26088d7da5b03f69$export$ecd1fc136c422448.prototype._createServerConnection = function() {\n var _this = this;\n var socket = new $31d11a8d122cb4b7$exports.Socket(this._options.secure, this._options.host, this._options.port, this._options.path, this._options.key, this._options.pingInterval);\n socket.on($60fadef21a2daafc$export$3b5c4a4b6354f023.Message, function(data) {\n _this._handleMessage(data);\n });\n socket.on($60fadef21a2daafc$export$3b5c4a4b6354f023.Error, function(error) {\n _this._abort($60fadef21a2daafc$export$9547aaa2e39030ff.SocketError, error);\n });\n socket.on($60fadef21a2daafc$export$3b5c4a4b6354f023.Disconnected, function() {\n if (_this.disconnected) return;\n _this.emitError($60fadef21a2daafc$export$9547aaa2e39030ff.Network, \"Lost connection to server.\");\n _this.disconnect();\n });\n socket.on($60fadef21a2daafc$export$3b5c4a4b6354f023.Close, function() {\n if (_this.disconnected) return;\n _this._abort($60fadef21a2daafc$export$9547aaa2e39030ff.SocketClosed, \"Underlying socket is already closed.\");\n });\n return socket;\n };\n /** Initialize a connection with the server. */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype._initialize = function(id) {\n this._id = id;\n this.socket.start(id, this._options.token);\n };\n /** Handles messages from the server. */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype._handleMessage = function(message) {\n var e_2, _a;\n var type = message.type;\n var payload = message.payload;\n var peerId = message.src;\n switch(type){\n case $60fadef21a2daafc$export$adb4a1754da6f10d.Open:\n this._lastServerId = this.id;\n this._open = true;\n this.emit(\"open\", this.id);\n break;\n case $60fadef21a2daafc$export$adb4a1754da6f10d.Error:\n this._abort($60fadef21a2daafc$export$9547aaa2e39030ff.ServerError, payload.msg);\n break;\n case $60fadef21a2daafc$export$adb4a1754da6f10d.IdTaken:\n this._abort($60fadef21a2daafc$export$9547aaa2e39030ff.UnavailableID, \"ID \\\"\".concat(this.id, \"\\\" is taken\"));\n break;\n case $60fadef21a2daafc$export$adb4a1754da6f10d.InvalidKey:\n this._abort($60fadef21a2daafc$export$9547aaa2e39030ff.InvalidKey, \"API KEY \\\"\".concat(this._options.key, \"\\\" is invalid\"));\n break;\n case $60fadef21a2daafc$export$adb4a1754da6f10d.Leave:\n $1615705ecc6adca3$exports.default.log(\"Received leave message from \".concat(peerId));\n this._cleanupPeer(peerId);\n this._connections.delete(peerId);\n break;\n case $60fadef21a2daafc$export$adb4a1754da6f10d.Expire:\n this.emitError($60fadef21a2daafc$export$9547aaa2e39030ff.PeerUnavailable, \"Could not connect to peer \".concat(peerId));\n break;\n case $60fadef21a2daafc$export$adb4a1754da6f10d.Offer:\n // we should consider switching this to CALL/CONNECT, but this is the least breaking option.\n var connectionId = payload.connectionId;\n var connection = this.getConnection(peerId, connectionId);\n if (connection) {\n connection.close();\n $1615705ecc6adca3$exports.default.warn(\"Offer received for existing Connection ID:\".concat(connectionId));\n }\n // Create a new connection.\n if (payload.type === $60fadef21a2daafc$export$3157d57b4135e3bc.Media) {\n var mediaConnection = new $353dee38f9ab557b$exports.MediaConnection(peerId, this, {\n connectionId: connectionId,\n _payload: payload,\n metadata: payload.metadata\n });\n connection = mediaConnection;\n this._addConnection(peerId, connection);\n this.emit(\"call\", mediaConnection);\n } else if (payload.type === $60fadef21a2daafc$export$3157d57b4135e3bc.Data) {\n var dataConnection = new $3356170d7bce7f20$exports.DataConnection(peerId, this, {\n connectionId: connectionId,\n _payload: payload,\n metadata: payload.metadata,\n label: payload.label,\n serialization: payload.serialization,\n reliable: payload.reliable\n });\n connection = dataConnection;\n this._addConnection(peerId, connection);\n this.emit(\"connection\", dataConnection);\n } else {\n $1615705ecc6adca3$exports.default.warn(\"Received malformed connection type:\".concat(payload.type));\n return;\n }\n // Find messages.\n var messages = this._getMessages(connectionId);\n try {\n for(var messages_1 = $26088d7da5b03f69$var$__values(messages), messages_1_1 = messages_1.next(); !messages_1_1.done; messages_1_1 = messages_1.next()){\n var message_1 = messages_1_1.value;\n connection.handleMessage(message_1);\n }\n } catch (e_2_1) {\n e_2 = {\n error: e_2_1\n };\n } finally{\n try {\n if (messages_1_1 && !messages_1_1.done && (_a = messages_1.return)) _a.call(messages_1);\n } finally{\n if (e_2) throw e_2.error;\n }\n }\n break;\n default:\n if (!payload) {\n $1615705ecc6adca3$exports.default.warn(\"You received a malformed message from \".concat(peerId, \" of type \").concat(type));\n return;\n }\n var connectionId = payload.connectionId;\n var connection = this.getConnection(peerId, connectionId);\n if (connection && connection.peerConnection) // Pass it on.\n connection.handleMessage(message);\n else if (connectionId) // Store for possible later use\n this._storeMessage(connectionId, message);\n else $1615705ecc6adca3$exports.default.warn(\"You received an unrecognized message:\", message);\n break;\n }\n };\n /** Stores messages without a set up connection, to be claimed later. */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype._storeMessage = function(connectionId, message) {\n if (!this._lostMessages.has(connectionId)) this._lostMessages.set(connectionId, []);\n this._lostMessages.get(connectionId).push(message);\n };\n /** Retrieve messages from lost message store */ //TODO Change it to private\n $26088d7da5b03f69$export$ecd1fc136c422448.prototype._getMessages = function(connectionId) {\n var messages = this._lostMessages.get(connectionId);\n if (messages) {\n this._lostMessages.delete(connectionId);\n return messages;\n }\n return [];\n };\n /**\n * Connects to the remote peer specified by id and returns a data connection.\n * @param peer The brokering ID of the remote peer (their peer.id).\n * @param options for specifying details about Peer Connection\n */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype.connect = function(peer, options) {\n if (options === void 0) options = {};\n if (this.disconnected) {\n $1615705ecc6adca3$exports.default.warn(\"You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect, or call reconnect on this peer if you believe its ID to still be available.\");\n this.emitError($60fadef21a2daafc$export$9547aaa2e39030ff.Disconnected, \"Cannot connect to new Peer after disconnecting from server.\");\n return;\n }\n var dataConnection = new $3356170d7bce7f20$exports.DataConnection(peer, this, options);\n this._addConnection(peer, dataConnection);\n return dataConnection;\n };\n /**\n * Calls the remote peer specified by id and returns a media connection.\n * @param peer The brokering ID of the remote peer (their peer.id).\n * @param stream The caller's media stream\n * @param options Metadata associated with the connection, passed in by whoever initiated the connection.\n */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype.call = function(peer, stream, options) {\n if (options === void 0) options = {};\n if (this.disconnected) {\n $1615705ecc6adca3$exports.default.warn(\"You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect.\");\n this.emitError($60fadef21a2daafc$export$9547aaa2e39030ff.Disconnected, \"Cannot connect to new Peer after disconnecting from server.\");\n return;\n }\n if (!stream) {\n $1615705ecc6adca3$exports.default.error(\"To call a peer, you must provide a stream from your browser's `getUserMedia`.\");\n return;\n }\n var mediaConnection = new $353dee38f9ab557b$exports.MediaConnection(peer, this, $26088d7da5b03f69$var$__assign($26088d7da5b03f69$var$__assign({}, options), {\n _stream: stream\n }));\n this._addConnection(peer, mediaConnection);\n return mediaConnection;\n };\n /** Add a data/media connection to this peer. */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype._addConnection = function(peerId, connection) {\n $1615705ecc6adca3$exports.default.log(\"add connection \".concat(connection.type, \":\").concat(connection.connectionId, \" to peerId:\").concat(peerId));\n if (!this._connections.has(peerId)) this._connections.set(peerId, []);\n this._connections.get(peerId).push(connection);\n };\n //TODO should be private\n $26088d7da5b03f69$export$ecd1fc136c422448.prototype._removeConnection = function(connection) {\n var connections = this._connections.get(connection.peer);\n if (connections) {\n var index = connections.indexOf(connection);\n if (index !== -1) connections.splice(index, 1);\n }\n //remove from lost messages\n this._lostMessages.delete(connection.connectionId);\n };\n /** Retrieve a data/media connection for this peer. */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype.getConnection = function(peerId, connectionId) {\n var e_3, _a;\n var connections = this._connections.get(peerId);\n if (!connections) return null;\n try {\n for(var connections_1 = $26088d7da5b03f69$var$__values(connections), connections_1_1 = connections_1.next(); !connections_1_1.done; connections_1_1 = connections_1.next()){\n var connection = connections_1_1.value;\n if (connection.connectionId === connectionId) return connection;\n }\n } catch (e_3_1) {\n e_3 = {\n error: e_3_1\n };\n } finally{\n try {\n if (connections_1_1 && !connections_1_1.done && (_a = connections_1.return)) _a.call(connections_1);\n } finally{\n if (e_3) throw e_3.error;\n }\n }\n return null;\n };\n $26088d7da5b03f69$export$ecd1fc136c422448.prototype._delayedAbort = function(type, message) {\n var _this = this;\n setTimeout(function() {\n _this._abort(type, message);\n }, 0);\n };\n /**\n * Emits an error message and destroys the Peer.\n * The Peer is not destroyed if it's in a disconnected state, in which case\n * it retains its disconnected state and its existing connections.\n */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype._abort = function(type, message) {\n $1615705ecc6adca3$exports.default.error(\"Aborting!\");\n this.emitError(type, message);\n if (!this._lastServerId) this.destroy();\n else this.disconnect();\n };\n /** Emits a typed error message. */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype.emitError = function(type, err) {\n $1615705ecc6adca3$exports.default.error(\"Error:\", err);\n var error;\n if (typeof err === \"string\") error = new Error(err);\n else error = err;\n error.type = type;\n this.emit(\"error\", error);\n };\n /**\n * Destroys the Peer: closes all active connections as well as the connection\n * to the server.\n * Warning: The peer can no longer create or accept connections after being\n * destroyed.\n */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype.destroy = function() {\n if (this.destroyed) return;\n $1615705ecc6adca3$exports.default.log(\"Destroy peer with ID:\".concat(this.id));\n this.disconnect();\n this._cleanup();\n this._destroyed = true;\n this.emit(\"close\");\n };\n /** Disconnects every connection on this peer. */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype._cleanup = function() {\n var e_4, _a;\n try {\n for(var _b = $26088d7da5b03f69$var$__values(this._connections.keys()), _c = _b.next(); !_c.done; _c = _b.next()){\n var peerId = _c.value;\n this._cleanupPeer(peerId);\n this._connections.delete(peerId);\n }\n } catch (e_4_1) {\n e_4 = {\n error: e_4_1\n };\n } finally{\n try {\n if (_c && !_c.done && (_a = _b.return)) _a.call(_b);\n } finally{\n if (e_4) throw e_4.error;\n }\n }\n this.socket.removeAllListeners();\n };\n /** Closes all connections to this peer. */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype._cleanupPeer = function(peerId) {\n var e_5, _a;\n var connections = this._connections.get(peerId);\n if (!connections) return;\n try {\n for(var connections_2 = $26088d7da5b03f69$var$__values(connections), connections_2_1 = connections_2.next(); !connections_2_1.done; connections_2_1 = connections_2.next()){\n var connection = connections_2_1.value;\n connection.close();\n }\n } catch (e_5_1) {\n e_5 = {\n error: e_5_1\n };\n } finally{\n try {\n if (connections_2_1 && !connections_2_1.done && (_a = connections_2.return)) _a.call(connections_2);\n } finally{\n if (e_5) throw e_5.error;\n }\n }\n };\n /**\n * Disconnects the Peer's connection to the PeerServer. Does not close any\n * active connections.\n * Warning: The peer can no longer create or accept connections after being\n * disconnected. It also cannot reconnect to the server.\n */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype.disconnect = function() {\n if (this.disconnected) return;\n var currentId = this.id;\n $1615705ecc6adca3$exports.default.log(\"Disconnect peer with ID:\".concat(currentId));\n this._disconnected = true;\n this._open = false;\n this.socket.close();\n this._lastServerId = currentId;\n this._id = null;\n this.emit(\"disconnected\", currentId);\n };\n /** Attempts to reconnect with the same ID. */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype.reconnect = function() {\n if (this.disconnected && !this.destroyed) {\n $1615705ecc6adca3$exports.default.log(\"Attempting reconnection to server with ID \".concat(this._lastServerId));\n this._disconnected = false;\n this._initialize(this._lastServerId);\n } else if (this.destroyed) throw new Error(\"This peer cannot reconnect to the server. It has already been destroyed.\");\n else if (!this.disconnected && !this.open) // Do nothing. We're still connecting the first time.\n $1615705ecc6adca3$exports.default.error(\"In a hurry? We're still trying to make the initial connection!\");\n else throw new Error(\"Peer \".concat(this.id, \" cannot reconnect because it is not disconnected from the server!\"));\n };\n /**\n * Get a list of available peer IDs. If you're running your own server, you'll\n * want to set allow_discovery: true in the PeerServer options. If you're using\n * the cloud server, email team@peerjs.com to get the functionality enabled for\n * your key.\n */ $26088d7da5b03f69$export$ecd1fc136c422448.prototype.listAllPeers = function(cb) {\n var _this = this;\n if (cb === void 0) cb = function(_) {};\n this._api.listAllPeers().then(function(peers) {\n return cb(peers);\n }).catch(function(error) {\n return _this._abort($60fadef21a2daafc$export$9547aaa2e39030ff.ServerError, error);\n });\n };\n $26088d7da5b03f69$export$ecd1fc136c422448.DEFAULT_KEY = \"peerjs\";\n return $26088d7da5b03f69$export$ecd1fc136c422448;\n}($ac9b757d51178e15$exports.EventEmitter);\n\n\nvar $70d766613f57b014$export$2e2bcd8739ae039 = $26088d7da5b03f69$exports.Peer;\n\n\n\n//# sourceMappingURL=bundler.mjs.map\n\n\n//# sourceURL=webpack://speakerCalibrator/./node_modules/peerjs/dist/bundler.mjs?");
3311
-
3312
3094
  /***/ })
3313
3095
 
3314
3096
  /******/ });