{"version":3,"file":"wavesurfer.min.js","sources":["../src/wavesurfer.js"],"sourcesContent":["/*!\n * wavesurfer.js 3.3.3 (2020-04-16)\n * https://github.com/katspaugh/wavesurfer.js\n * @license BSD-3-Clause\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n    if(typeof exports === 'object' && typeof module === 'object')\n        module.exports = factory();\n    else if(typeof define === 'function' && define.amd)\n        define([], factory);\n    else if(typeof exports === 'object')\n        exports[\"WaveSurfer\"] = factory();\n    else\n        root[\"WaveSurfer\"] = factory();\n})(window, function() {\n    return /******/ (function(modules) { // webpackBootstrap\n        /******/ \t// The module cache\n        /******/ \tvar installedModules = {};\n        /******/\n        /******/ \t// The require function\n        /******/ \tfunction __webpack_require__(moduleId) {\n            /******/\n            /******/ \t\t// Check if module is in cache\n            /******/ \t\tif(installedModules[moduleId]) {\n                /******/ \t\t\treturn installedModules[moduleId].exports;\n                /******/ \t\t}\n            /******/ \t\t// Create a new module (and put it into the cache)\n            /******/ \t\tvar module = installedModules[moduleId] = {\n                /******/ \t\t\ti: moduleId,\n                /******/ \t\t\tl: false,\n                /******/ \t\t\texports: {}\n                /******/ \t\t};\n            /******/\n            /******/ \t\t// Execute the module function\n            /******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n            /******/\n            /******/ \t\t// Flag the module as loaded\n            /******/ \t\tmodule.l = true;\n            /******/\n            /******/ \t\t// Return the exports of the module\n            /******/ \t\treturn module.exports;\n            /******/ \t}\n        /******/\n        /******/\n        /******/ \t// expose the modules object (__webpack_modules__)\n        /******/ \t__webpack_require__.m = modules;\n        /******/\n        /******/ \t// expose the module cache\n        /******/ \t__webpack_require__.c = installedModules;\n        /******/\n        /******/ \t// define getter function for harmony exports\n        /******/ \t__webpack_require__.d = function(exports, name, getter) {\n            /******/ \t\tif(!__webpack_require__.o(exports, name)) {\n                /******/ \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n                /******/ \t\t}\n            /******/ \t};\n        /******/\n        /******/ \t// define __esModule on exports\n        /******/ \t__webpack_require__.r = function(exports) {\n            /******/ \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n                /******/ \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n                /******/ \t\t}\n            /******/ \t\tObject.defineProperty(exports, '__esModule', { value: true });\n            /******/ \t};\n        /******/\n        /******/ \t// create a fake namespace object\n        /******/ \t// mode & 1: value is a module id, require it\n        /******/ \t// mode & 2: merge all properties of value into the ns\n        /******/ \t// mode & 4: return value when already ns object\n        /******/ \t// mode & 8|1: behave like require\n        /******/ \t__webpack_require__.t = function(value, mode) {\n            /******/ \t\tif(mode & 1) value = __webpack_require__(value);\n            /******/ \t\tif(mode & 8) return value;\n            /******/ \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n            /******/ \t\tvar ns = Object.create(null);\n            /******/ \t\t__webpack_require__.r(ns);\n            /******/ \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n            /******/ \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n            /******/ \t\treturn ns;\n            /******/ \t};\n        /******/\n        /******/ \t// getDefaultExport function for compatibility with non-harmony modules\n        /******/ \t__webpack_require__.n = function(module) {\n            /******/ \t\tvar getter = module && module.__esModule ?\n                /******/ \t\t\tfunction getDefault() { return module['default']; } :\n                /******/ \t\t\tfunction getModuleExports() { return module; };\n            /******/ \t\t__webpack_require__.d(getter, 'a', getter);\n            /******/ \t\treturn getter;\n            /******/ \t};\n        /******/\n        /******/ \t// Object.prototype.hasOwnProperty.call\n        /******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n        /******/\n        /******/ \t// __webpack_public_path__\n        /******/ \t__webpack_require__.p = \"\";\n        /******/\n        /******/\n        /******/ \t// Load entry module and return exports\n        /******/ \treturn __webpack_require__(__webpack_require__.s = \"./src/wavesurfer.js\");\n        /******/ })\n    /************************************************************************/\n    /******/ ({\n\n        /***/ \"./node_modules/debounce/index.js\":\n        /*!****************************************!*\\\n  !*** ./node_modules/debounce/index.js ***!\n  \\****************************************/\n        /*! no static exports found */\n        /***/ (function(module, exports) {\n\n            /**\n             * Returns a function, that, as long as it continues to be invoked, will not\n             * be triggered. The function will be called after it stops being called for\n             * N milliseconds. If `immediate` is passed, trigger the function on the\n             * leading edge, instead of the trailing. The function also has a property 'clear'\n             * that is a function which will clear the timer to prevent previously scheduled executions.\n             *\n             * @source underscore.js\n             * @see http://unscriptable.com/2009/03/20/debouncing-javascript-methods/\n             * @param {Function} function to wrap\n             * @param {Number} timeout in ms (`100`)\n             * @param {Boolean} whether to execute at the beginning (`false`)\n             * @api public\n             */\n            function debounce(func, wait, immediate){\n                var timeout, args, context, timestamp, result;\n                if (null == wait) wait = 100;\n\n                function later() {\n                    var last = Date.now() - timestamp;\n\n                    if (last < wait && last >= 0) {\n                        timeout = setTimeout(later, wait - last);\n                    } else {\n                        timeout = null;\n                        if (!immediate) {\n                            result = func.apply(context, args);\n                            context = args = null;\n                        }\n                    }\n                };\n\n                var debounced = function(){\n                    context = this;\n                    args = arguments;\n                    timestamp = Date.now();\n                    var callNow = immediate && !timeout;\n                    if (!timeout) timeout = setTimeout(later, wait);\n                    if (callNow) {\n                        result = func.apply(context, args);\n                        context = args = null;\n                    }\n\n                    return result;\n                };\n\n                debounced.clear = function() {\n                    if (timeout) {\n                        clearTimeout(timeout);\n                        timeout = null;\n                    }\n                };\n\n                debounced.flush = function() {\n                    if (timeout) {\n                        result = func.apply(context, args);\n                        context = args = null;\n\n                        clearTimeout(timeout);\n                        timeout = null;\n                    }\n                };\n\n                return debounced;\n            };\n\n// Adds compatibility for ES modules\n            debounce.debounce = debounce;\n\n            module.exports = debounce;\n\n\n            /***/ }),\n\n        /***/ \"./src/drawer.canvasentry.js\":\n        /*!***********************************!*\\\n  !*** ./src/drawer.canvasentry.js ***!\n  \\***********************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = void 0;\n\n            var _style = _interopRequireDefault(__webpack_require__(/*! ./util/style */ \"./src/util/style.js\"));\n\n            var _getId = _interopRequireDefault(__webpack_require__(/*! ./util/get-id */ \"./src/util/get-id.js\"));\n\n            function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n            function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n            function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\n            function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n            /**\n             * The `CanvasEntry` class represents an element consisting of a wave `canvas`\n             * and an (optional) progress wave `canvas`.\n             *\n             * The `MultiCanvas` renderer uses one or more `CanvasEntry` instances to\n             * render a waveform, depending on the zoom level.\n             */\n            var CanvasEntry =\n                /*#__PURE__*/\n                function () {\n                    function CanvasEntry() {\n                        _classCallCheck(this, CanvasEntry);\n\n                        /**\n                         * The wave node\n                         *\n                         * @type {HTMLCanvasElement}\n                         */\n                        this.wave = null;\n                        /**\n                         * The wave canvas rendering context\n                         *\n                         * @type {CanvasRenderingContext2D}\n                         */\n\n                        this.waveCtx = null;\n                        /**\n                         * The (optional) progress wave node\n                         *\n                         * @type {HTMLCanvasElement}\n                         */\n\n                        this.progress = null;\n                        /**\n                         * The (optional) progress wave canvas rendering context\n                         *\n                         * @type {CanvasRenderingContext2D}\n                         */\n\n                        this.progressCtx = null;\n                        /**\n                         * Start of the area the canvas should render, between 0 and 1\n                         *\n                         * @type {number}\n                         * @private\n                         */\n\n                        this.start = 0;\n                        /**\n                         * End of the area the canvas should render, between 0 and 1\n                         *\n                         * @type {number}\n                         * @private\n                         */\n\n                        this.end = 1;\n                        /**\n                         * Unique identifier for this entry\n                         *\n                         * @type {string}\n                         */\n\n                        this.id = (0, _getId.default)(typeof this.constructor.name !== 'undefined' ? this.constructor.name.toLowerCase() + '_' : 'canvasentry_');\n                        /**\n                         * Canvas 2d context attributes\n                         *\n                         * @type {object}\n                         */\n\n                        this.canvasContextAttributes = {};\n                    }\n                    /**\n                     * Store the wave canvas element and create the 2D rendering context\n                     *\n                     * @param {HTMLCanvasElement} element The wave `canvas` element.\n                     */\n\n\n                    _createClass(CanvasEntry, [{\n                        key: \"initWave\",\n                        value: function initWave(element) {\n                            this.wave = element;\n                            this.waveCtx = this.wave.getContext('2d', this.canvasContextAttributes);\n                        }\n                        /**\n                         * Store the progress wave canvas element and create the 2D rendering\n                         * context\n                         *\n                         * @param {HTMLCanvasElement} element The progress wave `canvas` element.\n                         */\n\n                    }, {\n                        key: \"initProgress\",\n                        value: function initProgress(element) {\n                            this.progress = element;\n                            this.progressCtx = this.progress.getContext('2d', this.canvasContextAttributes);\n                        }\n                        /**\n                         * Update the dimensions\n                         *\n                         * @param {number} elementWidth Width of the entry\n                         * @param {number} totalWidth Total width of the multi canvas renderer\n                         * @param {number} width The new width of the element\n                         * @param {number} height The new height of the element\n                         */\n\n                    }, {\n                        key: \"updateDimensions\",\n                        value: function updateDimensions(elementWidth, totalWidth, width, height) {\n                            // where the canvas starts and ends in the waveform, represented as a\n                            // decimal between 0 and 1\n                            this.start = this.wave.offsetLeft / totalWidth || 0;\n                            this.end = this.start + elementWidth / totalWidth; // set wave canvas dimensions\n\n                            this.wave.width = width;\n                            this.wave.height = height;\n                            var elementSize = {\n                                width: elementWidth + 'px'\n                            };\n                            (0, _style.default)(this.wave, elementSize);\n\n                            if (this.hasProgressCanvas) {\n                                // set progress canvas dimensions\n                                this.progress.width = width;\n                                this.progress.height = height;\n                                (0, _style.default)(this.progress, elementSize);\n                            }\n                        }\n                        /**\n                         * Clear the wave and progress rendering contexts\n                         */\n\n                    }, {\n                        key: \"clearWave\",\n                        value: function clearWave() {\n                            // wave\n                            this.waveCtx.clearRect(0, 0, this.waveCtx.canvas.width, this.waveCtx.canvas.height); // progress\n\n                            if (this.hasProgressCanvas) {\n                                this.progressCtx.clearRect(0, 0, this.progressCtx.canvas.width, this.progressCtx.canvas.height);\n                            }\n                        }\n                        /**\n                         * Set the fill styles for wave and progress\n                         *\n                         * @param {string} waveColor Fill color for the wave canvas\n                         * @param {?string} progressColor Fill color for the progress canvas\n                         */\n\n                    }, {\n                        key: \"setFillStyles\",\n                        value: function setFillStyles(waveColor, progressColor) {\n                            this.waveCtx.fillStyle = waveColor;\n\n                            if (this.hasProgressCanvas) {\n                                this.progressCtx.fillStyle = progressColor;\n                            }\n                        }\n                        /**\n                         * Draw a rectangle for wave and progress\n                         *\n                         * @param {number} x X start position\n                         * @param {number} y Y start position\n                         * @param {number} width Width of the rectangle\n                         * @param {number} height Height of the rectangle\n                         * @param {number} radius Radius of the rectangle\n                         */\n\n                    }, {\n                        key: \"fillRects\",\n                        value: function fillRects(x, y, width, height, radius) {\n                            this.fillRectToContext(this.waveCtx, x, y, width, height, radius);\n\n                            if (this.hasProgressCanvas) {\n                                this.fillRectToContext(this.progressCtx, x, y, width, height, radius);\n                            }\n                        }\n                        /**\n                         * Draw the actual rectangle on a `canvas` element\n                         *\n                         * @private\n                         * @param {CanvasRenderingContext2D} ctx Rendering context of target canvas\n                         * @param {number} x X start position\n                         * @param {number} y Y start position\n                         * @param {number} width Width of the rectangle\n                         * @param {number} height Height of the rectangle\n                         * @param {number} radius Radius of the rectangle\n                         */\n\n                    }, {\n                        key: \"fillRectToContext\",\n                        value: function fillRectToContext(ctx, x, y, width, height, radius) {\n                            if (!ctx) {\n                                return;\n                            }\n\n                            if (radius) {\n                                this.drawRoundedRect(ctx, x, y, width, height, radius);\n                            } else {\n                                ctx.fillRect(x, y, width, height);\n                            }\n                        }\n                        /**\n                         * Draw a rounded rectangle on Canvas\n                         *\n                         * @private\n                         * @param {CanvasRenderingContext2D} ctx Canvas context\n                         * @param {number} x X-position of the rectangle\n                         * @param {number} y Y-position of the rectangle\n                         * @param {number} width Width of the rectangle\n                         * @param {number} height Height of the rectangle\n                         * @param {number} radius Radius of the rectangle\n                         *\n                         * @return {void}\n                         * @example drawRoundedRect(ctx, 50, 50, 5, 10, 3)\n                         */\n\n                    }, {\n                        key: \"drawRoundedRect\",\n                        value: function drawRoundedRect(ctx, x, y, width, height, radius) {\n                            if (height === 0) {\n                                return;\n                            } // peaks are float values from -1 to 1. Use absolute height values in\n                            // order to correctly calculate rounded rectangle coordinates\n\n\n                            if (height < 0) {\n                                height *= -1;\n                                y -= height;\n                            }\n\n                            ctx.beginPath();\n                            ctx.moveTo(x + radius, y);\n                            ctx.lineTo(x + width - radius, y);\n                            ctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n                            ctx.lineTo(x + width, y + height - radius);\n                            ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n                            ctx.lineTo(x + radius, y + height);\n                            ctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n                            ctx.lineTo(x, y + radius);\n                            ctx.quadraticCurveTo(x, y, x + radius, y);\n                            ctx.closePath();\n                            ctx.fill();\n                        }\n                        /**\n                         * Render the actual wave and progress lines\n                         *\n                         * @param {number[]} peaks Array with peaks data\n                         * @param {number} absmax Maximum peak value (absolute)\n                         * @param {number} halfH Half the height of the waveform\n                         * @param {number} offsetY Offset to the top\n                         * @param {number} start The x-offset of the beginning of the area that\n                         * should be rendered\n                         * @param {number} end The x-offset of the end of the area that\n                         * should be rendered\n                         */\n\n                    }, {\n                        key: \"drawLines\",\n                        value: function drawLines(peaks, absmax, halfH, offsetY, start, end) {\n                            this.drawLineToContext(this.waveCtx, peaks, absmax, halfH, offsetY, start, end);\n\n                            if (this.hasProgressCanvas) {\n                                this.drawLineToContext(this.progressCtx, peaks, absmax, halfH, offsetY, start, end);\n                            }\n                        }\n                        /**\n                         * Render the actual waveform line on a `canvas` element\n                         *\n                         * @private\n                         * @param {CanvasRenderingContext2D} ctx Rendering context of target canvas\n                         * @param {number[]} peaks Array with peaks data\n                         * @param {number} absmax Maximum peak value (absolute)\n                         * @param {number} halfH Half the height of the waveform\n                         * @param {number} offsetY Offset to the top\n                         * @param {number} start The x-offset of the beginning of the area that\n                         * should be rendered\n                         * @param {number} end The x-offset of the end of the area that\n                         * should be rendered\n                         */\n\n                    }, {\n                        key: \"drawLineToContext\",\n                        value: function drawLineToContext(ctx, peaks, absmax, halfH, offsetY, start, end) {\n                            if (!ctx) {\n                                return;\n                            }\n\n                            var length = peaks.length / 2;\n                            var first = Math.round(length * this.start); // use one more peak value to make sure we join peaks at ends -- unless,\n                            // of course, this is the last canvas\n\n                            var last = Math.round(length * this.end) + 1;\n                            var canvasStart = first;\n                            var canvasEnd = last;\n                            var scale = this.wave.width / (canvasEnd - canvasStart - 1); // optimization\n\n                            var halfOffset = halfH + offsetY;\n                            var absmaxHalf = absmax / halfH;\n                            ctx.beginPath();\n                            ctx.moveTo((canvasStart - first) * scale, halfOffset);\n                            ctx.lineTo((canvasStart - first) * scale, halfOffset - Math.round((peaks[2 * canvasStart] || 0) / absmaxHalf));\n                            var i, peak, h;\n\n                            for (i = canvasStart; i < canvasEnd; i++) {\n                                peak = peaks[2 * i] || 0;\n                                h = Math.round(peak / absmaxHalf);\n                                ctx.lineTo((i - first) * scale + this.halfPixel, halfOffset - h);\n                            } // draw the bottom edge going backwards, to make a single\n                            // closed hull to fill\n\n\n                            var j = canvasEnd - 1;\n\n                            for (j; j >= canvasStart; j--) {\n                                peak = peaks[2 * j + 1] || 0;\n                                h = Math.round(peak / absmaxHalf);\n                                ctx.lineTo((j - first) * scale + this.halfPixel, halfOffset - h);\n                            }\n\n                            ctx.lineTo((canvasStart - first) * scale, halfOffset - Math.round((peaks[2 * canvasStart + 1] || 0) / absmaxHalf));\n                            ctx.closePath();\n                            ctx.fill();\n                        }\n                        /**\n                         * Destroys this entry\n                         */\n\n                    }, {\n                        key: \"destroy\",\n                        value: function destroy() {\n                            this.waveCtx = null;\n                            this.wave = null;\n                            this.progressCtx = null;\n                            this.progress = null;\n                        }\n                        /**\n                         * Return image data of the wave `canvas` element\n                         *\n                         * When using a `type` of `'blob'`, this will return a `Promise` that\n                         * resolves with a `Blob` instance.\n                         *\n                         * @param {string} format='image/png' An optional value of a format type.\n                         * @param {number} quality=0.92 An optional value between 0 and 1.\n                         * @param {string} type='dataURL' Either 'dataURL' or 'blob'.\n                         * @return {string|Promise} When using the default `'dataURL'` `type` this\n                         * returns a data URL. When using the `'blob'` `type` this returns a\n                         * `Promise` that resolves with a `Blob` instance.\n                         */\n\n                    }, {\n                        key: \"getImage\",\n                        value: function getImage(format, quality, type) {\n                            var _this = this;\n\n                            if (type === 'blob') {\n                                return new Promise(function (resolve) {\n                                    _this.wave.toBlob(resolve, format, quality);\n                                });\n                            } else if (type === 'dataURL') {\n                                return this.wave.toDataURL(format, quality);\n                            }\n                        }\n                    }]);\n\n                    return CanvasEntry;\n                }();\n\n            exports.default = CanvasEntry;\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/drawer.js\":\n        /*!***********************!*\\\n  !*** ./src/drawer.js ***!\n  \\***********************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = void 0;\n\n            var util = _interopRequireWildcard(__webpack_require__(/*! ./util */ \"./src/util/index.js\"));\n\n            function _getRequireWildcardCache() { if (typeof WeakMap !== \"function\") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }\n\n            function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \"object\" && typeof obj !== \"function\") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }\n\n            function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n            function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n            function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\n            function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n            function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\n            function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\n            function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n            function _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\n            function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n            /**\n             * Parent class for renderers\n             *\n             * @extends {Observer}\n             */\n            var Drawer =\n                /*#__PURE__*/\n                function (_util$Observer) {\n                    _inherits(Drawer, _util$Observer);\n\n                    /**\n                     * @param {HTMLElement} container The container node of the wavesurfer instance\n                     * @param {WavesurferParams} params The wavesurfer initialisation options\n                     */\n                    function Drawer(container, params) {\n                        var _this;\n\n                        _classCallCheck(this, Drawer);\n\n                        _this = _possibleConstructorReturn(this, _getPrototypeOf(Drawer).call(this));\n                        /** @private */\n\n                        _this.container = container;\n                        /**\n                         * @type {WavesurferParams}\n                         * @private\n                         */\n\n                        _this.params = params;\n                        /**\n                         * The width of the renderer\n                         * @type {number}\n                         */\n\n                        _this.width = 0;\n                        /**\n                         * The height of the renderer\n                         * @type {number}\n                         */\n\n                        _this.height = params.height * _this.params.pixelRatio;\n                        /** @private */\n\n                        _this.lastPos = 0;\n                        /**\n                         * The `<wave>` element which is added to the container\n                         * @type {HTMLElement}\n                         */\n\n                        _this.wrapper = null;\n                        return _this;\n                    }\n                    /**\n                     * Alias of `util.style`\n                     *\n                     * @param {HTMLElement} el The element that the styles will be applied to\n                     * @param {Object} styles The map of propName: attribute, both are used as-is\n                     * @return {HTMLElement} el\n                     */\n\n\n                    _createClass(Drawer, [{\n                        key: \"style\",\n                        value: function style(el, styles) {\n                            return util.style(el, styles);\n                        }\n                        /**\n                         * Create the wrapper `<wave>` element, style it and set up the events for\n                         * interaction\n                         */\n\n                    }, {\n                        key: \"createWrapper\",\n                        value: function createWrapper() {\n                            this.wrapper = this.container.appendChild(document.createElement('wave'));\n                            this.style(this.wrapper, {\n                                display: 'block',\n                                position: 'relative',\n                                userSelect: 'none',\n                                webkitUserSelect: 'none',\n                                height: this.params.height + 'px'\n                            });\n\n                            if (this.params.fillParent || this.params.scrollParent) {\n                                this.style(this.wrapper, {\n                                    width: '100%',\n                                    overflowX: this.params.hideScrollbar ? 'hidden' : 'auto',\n                                    overflowY: 'hidden'\n                                });\n                            }\n\n                            this.setupWrapperEvents();\n                        }\n                        /**\n                         * Handle click event\n                         *\n                         * @param {Event} e Click event\n                         * @param {?boolean} noPrevent Set to true to not call `e.preventDefault()`\n                         * @return {number} Playback position from 0 to 1\n                         */\n\n                    }, {\n                        key: \"handleEvent\",\n                        value: function handleEvent(e, noPrevent) {\n                            !noPrevent && e.preventDefault();\n                            var clientX = e.targetTouches ? e.targetTouches[0].clientX : e.clientX;\n                            var bbox = this.wrapper.getBoundingClientRect();\n                            var nominalWidth = this.width;\n                            var parentWidth = this.getWidth();\n                            var progress;\n\n                            if (!this.params.fillParent && nominalWidth < parentWidth) {\n                                progress = (this.params.rtl ? bbox.right - clientX : clientX - bbox.left) * (this.params.pixelRatio / nominalWidth) || 0;\n\n                                if (progress > 1) {\n                                    progress = 1;\n                                }\n                            } else {\n                                progress = ((this.params.rtl ? bbox.right - clientX : clientX - bbox.left) + this.wrapper.scrollLeft) / this.wrapper.scrollWidth || 0;\n                            }\n\n                            return progress;\n                        }\n                        /**\n                         * @private\n                         */\n\n                    }, {\n                        key: \"setupWrapperEvents\",\n                        value: function setupWrapperEvents() {\n                            var _this2 = this;\n\n                            this.wrapper.addEventListener('click', function (e) {\n                                var scrollbarHeight = _this2.wrapper.offsetHeight - _this2.wrapper.clientHeight;\n\n                                if (scrollbarHeight !== 0) {\n                                    // scrollbar is visible.  Check if click was on it\n                                    var bbox = _this2.wrapper.getBoundingClientRect();\n\n                                    if (e.clientY >= bbox.bottom - scrollbarHeight) {\n                                        // ignore mousedown as it was on the scrollbar\n                                        return;\n                                    }\n                                }\n\n                                if (_this2.params.interact) {\n                                    _this2.fireEvent('click', e, _this2.handleEvent(e));\n                                }\n                            });\n                            this.wrapper.addEventListener('dblclick', function (e) {\n                                if (_this2.params.interact) {\n                                    _this2.fireEvent('dblclick', e, _this2.handleEvent(e));\n                                }\n                            });\n                            this.wrapper.addEventListener('scroll', function (e) {\n                                return _this2.fireEvent('scroll', e);\n                            });\n                        }\n                        /**\n                         * Draw peaks on the canvas\n                         *\n                         * @param {number[]|Number.<Array[]>} peaks Can also be an array of arrays\n                         * for split channel rendering\n                         * @param {number} length The width of the area that should be drawn\n                         * @param {number} start The x-offset of the beginning of the area that\n                         * should be rendered\n                         * @param {number} end The x-offset of the end of the area that should be\n                         * rendered\n                         */\n\n                    }, {\n                        key: \"drawPeaks\",\n                        value: function drawPeaks(peaks, length, start, end) {\n                            if (!this.setWidth(length)) {\n                                this.clearWave();\n                            }\n\n                            this.params.barWidth ? this.drawBars(peaks, 0, start, end) : this.drawWave(peaks, 0, start, end);\n                        }\n                        /**\n                         * Scroll to the beginning\n                         */\n\n                    }, {\n                        key: \"resetScroll\",\n                        value: function resetScroll() {\n                            if (this.wrapper !== null) {\n                                this.wrapper.scrollLeft = 0;\n                            }\n                        }\n                        /**\n                         * Recenter the view-port at a certain percent of the waveform\n                         *\n                         * @param {number} percent Value from 0 to 1 on the waveform\n                         */\n\n                    }, {\n                        key: \"recenter\",\n                        value: function recenter(percent) {\n                            var position = this.wrapper.scrollWidth * percent;\n                            this.recenterOnPosition(position, true);\n                        }\n                        /**\n                         * Recenter the view-port on a position, either scroll there immediately or\n                         * in steps of 5 pixels\n                         *\n                         * @param {number} position X-offset in pixels\n                         * @param {boolean} immediate Set to true to immediately scroll somewhere\n                         */\n\n                    }, {\n                        key: \"recenterOnPosition\",\n                        value: function recenterOnPosition(position, immediate) {\n                            var scrollLeft = this.wrapper.scrollLeft;\n                            var half = ~~(this.wrapper.clientWidth / 2);\n                            var maxScroll = this.wrapper.scrollWidth - this.wrapper.clientWidth;\n                            var target = position - half;\n                            var offset = target - scrollLeft;\n\n                            if (maxScroll == 0) {\n                                // no need to continue if scrollbar is not there\n                                return;\n                            } // if the cursor is currently visible...\n\n\n                            if (!immediate && -half <= offset && offset < half) {\n                                // set rate at which waveform is centered\n                                var rate = this.params.autoCenterRate; // make rate depend on width of view and length of waveform\n\n                                rate /= half;\n                                rate *= maxScroll;\n                                offset = Math.max(-rate, Math.min(rate, offset));\n                                target = scrollLeft + offset;\n                            } // limit target to valid range (0 to maxScroll)\n\n\n                            target = Math.max(0, Math.min(maxScroll, target)); // no use attempting to scroll if we're not moving\n\n                            if (target != scrollLeft) {\n                                this.wrapper.scrollLeft = target;\n                            }\n                        }\n                        /**\n                         * Get the current scroll position in pixels\n                         *\n                         * @return {number} Horizontal scroll position in pixels\n                         */\n\n                    }, {\n                        key: \"getScrollX\",\n                        value: function getScrollX() {\n                            var x = 0;\n\n                            if (this.wrapper) {\n                                var pixelRatio = this.params.pixelRatio;\n                                x = Math.round(this.wrapper.scrollLeft * pixelRatio); // In cases of elastic scroll (safari with mouse wheel) you can\n                                // scroll beyond the limits of the container\n                                // Calculate and floor the scrollable extent to make sure an out\n                                // of bounds value is not returned\n                                // Ticket #1312\n\n                                if (this.params.scrollParent) {\n                                    var maxScroll = ~~(this.wrapper.scrollWidth * pixelRatio - this.getWidth());\n                                    x = Math.min(maxScroll, Math.max(0, x));\n                                }\n                            }\n\n                            return x;\n                        }\n                        /**\n                         * Get the width of the container\n                         *\n                         * @return {number} The width of the container\n                         */\n\n                    }, {\n                        key: \"getWidth\",\n                        value: function getWidth() {\n                            return Math.round(this.container.clientWidth * this.params.pixelRatio);\n                        }\n                        /**\n                         * Set the width of the container\n                         *\n                         * @param {number} width The new width of the container\n                         * @return {boolean} Whether the width of the container was updated or not\n                         */\n\n                    }, {\n                        key: \"setWidth\",\n                        value: function setWidth(width) {\n                            if (this.width == width) {\n                                return false;\n                            }\n\n                            this.width = width;\n\n                            if (this.params.fillParent || this.params.scrollParent) {\n                                this.style(this.wrapper, {\n                                    width: ''\n                                });\n                            } else {\n                                this.style(this.wrapper, {\n                                    width: ~~(this.width / this.params.pixelRatio) + 'px'\n                                });\n                            }\n\n                            this.updateSize();\n                            return true;\n                        }\n                        /**\n                         * Set the height of the container\n                         *\n                         * @param {number} height The new height of the container.\n                         * @return {boolean} Whether the height of the container was updated or not\n                         */\n\n                    }, {\n                        key: \"setHeight\",\n                        value: function setHeight(height) {\n                            if (height == this.height) {\n                                return false;\n                            }\n\n                            this.height = height;\n                            this.style(this.wrapper, {\n                                height: ~~(this.height / this.params.pixelRatio) + 'px'\n                            });\n                            this.updateSize();\n                            return true;\n                        }\n                        /**\n                         * Called by wavesurfer when progress should be rendered\n                         *\n                         * @param {number} progress From 0 to 1\n                         */\n\n                    }, {\n                        key: \"progress\",\n                        value: function progress(_progress) {\n                            var minPxDelta = 1 / this.params.pixelRatio;\n                            var pos = Math.round(_progress * this.width) * minPxDelta;\n\n                            if (pos < this.lastPos || pos - this.lastPos >= minPxDelta) {\n                                this.lastPos = pos;\n\n                                if (this.params.scrollParent && this.params.autoCenter) {\n                                    var newPos = ~~(this.wrapper.scrollWidth * _progress);\n                                    this.recenterOnPosition(newPos, this.params.autoCenterImmediately);\n                                }\n\n                                this.updateProgress(pos);\n                            }\n                        }\n                        /**\n                         * This is called when wavesurfer is destroyed\n                         */\n\n                    }, {\n                        key: \"destroy\",\n                        value: function destroy() {\n                            this.unAll();\n\n                            if (this.wrapper) {\n                                if (this.wrapper.parentNode == this.container) {\n                                    this.container.removeChild(this.wrapper);\n                                }\n\n                                this.wrapper = null;\n                            }\n                        }\n                        /* Renderer-specific methods */\n\n                        /**\n                         * Called after cursor related params have changed.\n                         *\n                         * @abstract\n                         */\n\n                    }, {\n                        key: \"updateCursor\",\n                        value: function updateCursor() {}\n                        /**\n                         * Called when the size of the container changes so the renderer can adjust\n                         *\n                         * @abstract\n                         */\n\n                    }, {\n                        key: \"updateSize\",\n                        value: function updateSize() {}\n                        /**\n                         * Draw a waveform with bars\n                         *\n                         * @abstract\n                         * @param {number[]|Number.<Array[]>} peaks Can also be an array of arrays for split channel\n                         * rendering\n                         * @param {number} channelIndex The index of the current channel. Normally\n                         * should be 0\n                         * @param {number} start The x-offset of the beginning of the area that\n                         * should be rendered\n                         * @param {number} end The x-offset of the end of the area that should be\n                         * rendered\n                         */\n\n                    }, {\n                        key: \"drawBars\",\n                        value: function drawBars(peaks, channelIndex, start, end) {}\n                        /**\n                         * Draw a waveform\n                         *\n                         * @abstract\n                         * @param {number[]|Number.<Array[]>} peaks Can also be an array of arrays for split channel\n                         * rendering\n                         * @param {number} channelIndex The index of the current channel. Normally\n                         * should be 0\n                         * @param {number} start The x-offset of the beginning of the area that\n                         * should be rendered\n                         * @param {number} end The x-offset of the end of the area that should be\n                         * rendered\n                         */\n\n                    }, {\n                        key: \"drawWave\",\n                        value: function drawWave(peaks, channelIndex, start, end) {}\n                        /**\n                         * Clear the waveform\n                         *\n                         * @abstract\n                         */\n\n                    }, {\n                        key: \"clearWave\",\n                        value: function clearWave() {}\n                        /**\n                         * Render the new progress\n                         *\n                         * @abstract\n                         * @param {number} position X-Offset of progress position in pixels\n                         */\n\n                    }, {\n                        key: \"updateProgress\",\n                        value: function updateProgress(position) {}\n                    }]);\n\n                    return Drawer;\n                }(util.Observer);\n\n            exports.default = Drawer;\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/drawer.multicanvas.js\":\n        /*!***********************************!*\\\n  !*** ./src/drawer.multicanvas.js ***!\n  \\***********************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = void 0;\n\n            var _drawer = _interopRequireDefault(__webpack_require__(/*! ./drawer */ \"./src/drawer.js\"));\n\n            var util = _interopRequireWildcard(__webpack_require__(/*! ./util */ \"./src/util/index.js\"));\n\n            var _drawer2 = _interopRequireDefault(__webpack_require__(/*! ./drawer.canvasentry */ \"./src/drawer.canvasentry.js\"));\n\n            function _getRequireWildcardCache() { if (typeof WeakMap !== \"function\") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }\n\n            function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \"object\" && typeof obj !== \"function\") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }\n\n            function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n            function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n            function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n            function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\n            function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n            function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\n            function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\n            function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n            function _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\n            function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n            /**\n             * MultiCanvas renderer for wavesurfer. Is currently the default and sole\n             * builtin renderer.\n             *\n             * A `MultiCanvas` consists of one or more `CanvasEntry` instances, depending\n             * on the zoom level.\n             */\n            var MultiCanvas =\n                /*#__PURE__*/\n                function (_Drawer) {\n                    _inherits(MultiCanvas, _Drawer);\n\n                    /**\n                     * @param {HTMLElement} container The container node of the wavesurfer instance\n                     * @param {WavesurferParams} params The wavesurfer initialisation options\n                     */\n                    function MultiCanvas(container, params) {\n                        var _this;\n\n                        _classCallCheck(this, MultiCanvas);\n\n                        _this = _possibleConstructorReturn(this, _getPrototypeOf(MultiCanvas).call(this, container, params));\n                        /**\n                         * @type {number}\n                         * @private\n                         */\n\n                        _this.maxCanvasWidth = params.maxCanvasWidth;\n                        /**\n                         * @private\n                         * @type {number}\n                         */\n\n                        _this.maxCanvasElementWidth = Math.round(params.maxCanvasWidth / params.pixelRatio);\n                        /**\n                         * Whether or not the progress wave is rendered. If the `waveColor`\n                         * and `progressColor` are the same color it is not.\n                         *\n                         * @type {boolean}\n                         */\n\n                        _this.hasProgressCanvas = params.waveColor != params.progressColor;\n                        /**\n                         * @private\n                         * @type {number}\n                         */\n\n                        _this.halfPixel = 0.5 / params.pixelRatio;\n                        /**\n                         * List of `CanvasEntry` instances.\n                         *\n                         * @private\n                         * @type {Array}\n                         */\n\n                        _this.canvases = [];\n                        /**\n                         * @private\n                         * @type {HTMLElement}\n                         */\n\n                        _this.progressWave = null;\n                        /**\n                         * Class used to generate entries.\n                         *\n                         * @private\n                         * @type {function}\n                         */\n\n                        _this.EntryClass = _drawer2.default;\n                        /**\n                         * Canvas 2d context attributes.\n                         *\n                         * @private\n                         * @type {object}\n                         */\n\n                        _this.canvasContextAttributes = params.drawingContextAttributes;\n                        /**\n                         * Overlap added between entries to prevent vertical white stripes\n                         * between `canvas` elements.\n                         *\n                         * @type {number}\n                         */\n\n                        _this.overlap = 2 * Math.ceil(params.pixelRatio / 2);\n                        /**\n                         * The radius of the wave bars. Makes bars rounded\n                         *\n                         * @private\n                         * @type {number}\n                         */\n\n                        _this.barRadius = params.barRadius || 0;\n                        return _this;\n                    }\n                    /**\n                     * Initialize the drawer\n                     */\n\n\n                    _createClass(MultiCanvas, [{\n                        key: \"init\",\n                        value: function init() {\n                            this.createWrapper();\n                            this.createElements();\n                        }\n                        /**\n                         * Create the canvas elements and style them\n                         *\n                         * @private\n                         */\n\n                    }, {\n                        key: \"createElements\",\n                        value: function createElements() {\n                            this.progressWave = this.wrapper.appendChild(this.style(document.createElement('wave'), {\n                                position: 'absolute',\n                                zIndex: 3,\n                                left: 0,\n                                top: 0,\n                                bottom: 0,\n                                overflow: 'hidden',\n                                width: '0',\n                                display: 'none',\n                                boxSizing: 'border-box',\n                                borderRightStyle: 'solid',\n                                pointerEvents: 'none'\n                            }));\n                            this.addCanvas();\n                            this.updateCursor();\n                        }\n                        /**\n                         * Update cursor style\n                         */\n\n                    }, {\n                        key: \"updateCursor\",\n                        value: function updateCursor() {\n                            this.style(this.progressWave, {\n                                borderRightWidth: this.params.cursorWidth + 'px',\n                                borderRightColor: this.params.cursorColor\n                            });\n                        }\n                        /**\n                         * Adjust to the updated size by adding or removing canvases\n                         */\n\n                    }, {\n                        key: \"updateSize\",\n                        value: function updateSize() {\n                            var _this2 = this;\n\n                            var totalWidth = Math.round(this.width / this.params.pixelRatio);\n                            var requiredCanvases = Math.ceil(totalWidth / (this.maxCanvasElementWidth + this.overlap)); // add required canvases\n\n                            while (this.canvases.length < requiredCanvases) {\n                                this.addCanvas();\n                            } // remove older existing canvases, if any\n\n\n                            while (this.canvases.length > requiredCanvases) {\n                                this.removeCanvas();\n                            }\n\n                            var canvasWidth = this.maxCanvasWidth + this.overlap;\n                            var lastCanvas = this.canvases.length - 1;\n                            this.canvases.forEach(function (entry, i) {\n                                if (i == lastCanvas) {\n                                    canvasWidth = _this2.width - _this2.maxCanvasWidth * lastCanvas;\n                                }\n\n                                _this2.updateDimensions(entry, canvasWidth, _this2.height);\n\n                                entry.clearWave();\n                            });\n                        }\n                        /**\n                         * Add a canvas to the canvas list\n                         *\n                         * @private\n                         */\n\n                    }, {\n                        key: \"addCanvas\",\n                        value: function addCanvas() {\n                            var entry = new this.EntryClass();\n                            entry.canvasContextAttributes = this.canvasContextAttributes;\n                            entry.hasProgressCanvas = this.hasProgressCanvas;\n                            entry.halfPixel = this.halfPixel;\n                            var leftOffset = this.maxCanvasElementWidth * this.canvases.length; // wave\n\n                            entry.initWave(this.wrapper.appendChild(this.style(document.createElement('canvas'), {\n                                position: 'absolute',\n                                zIndex: 2,\n                                left: leftOffset + 'px',\n                                top: 0,\n                                bottom: 0,\n                                height: '100%',\n                                pointerEvents: 'none'\n                            }))); // progress\n\n                            if (this.hasProgressCanvas) {\n                                entry.initProgress(this.progressWave.appendChild(this.style(document.createElement('canvas'), {\n                                    position: 'absolute',\n                                    left: leftOffset + 'px',\n                                    top: 0,\n                                    bottom: 0,\n                                    height: '100%'\n                                })));\n                            }\n\n                            this.canvases.push(entry);\n                        }\n                        /**\n                         * Pop single canvas from the list\n                         *\n                         * @private\n                         */\n\n                    }, {\n                        key: \"removeCanvas\",\n                        value: function removeCanvas() {\n                            var lastEntry = this.canvases[this.canvases.length - 1]; // wave\n\n                            lastEntry.wave.parentElement.removeChild(lastEntry.wave); // progress\n\n                            if (this.hasProgressCanvas) {\n                                lastEntry.progress.parentElement.removeChild(lastEntry.progress);\n                            } // cleanup\n\n\n                            if (lastEntry) {\n                                lastEntry.destroy();\n                                lastEntry = null;\n                            }\n\n                            this.canvases.pop();\n                        }\n                        /**\n                         * Update the dimensions of a canvas element\n                         *\n                         * @private\n                         * @param {CanvasEntry} entry Target entry\n                         * @param {number} width The new width of the element\n                         * @param {number} height The new height of the element\n                         */\n\n                    }, {\n                        key: \"updateDimensions\",\n                        value: function updateDimensions(entry, width, height) {\n                            var elementWidth = Math.round(width / this.params.pixelRatio);\n                            var totalWidth = Math.round(this.width / this.params.pixelRatio); // update canvas dimensions\n\n                            entry.updateDimensions(elementWidth, totalWidth, width, height); // style element\n\n                            this.style(this.progressWave, {\n                                display: 'block'\n                            });\n                        }\n                        /**\n                         * Clear the whole multi-canvas\n                         */\n\n                    }, {\n                        key: \"clearWave\",\n                        value: function clearWave() {\n                            var _this3 = this;\n\n                            util.frame(function () {\n                                _this3.canvases.forEach(function (entry) {\n                                    return entry.clearWave();\n                                });\n                            })();\n                        }\n                        /**\n                         * Draw a waveform with bars\n                         *\n                         * @param {number[]|Number.<Array[]>} peaks Can also be an array of arrays\n                         * for split channel rendering\n                         * @param {number} channelIndex The index of the current channel. Normally\n                         * should be 0. Must be an integer.\n                         * @param {number} start The x-offset of the beginning of the area that\n                         * should be rendered\n                         * @param {number} end The x-offset of the end of the area that should be\n                         * rendered\n                         * @returns {void}\n                         */\n\n                    }, {\n                        key: \"drawBars\",\n                        value: function drawBars(peaks, channelIndex, start, end) {\n                            var _this4 = this;\n\n                            return this.prepareDraw(peaks, channelIndex, start, end, function (_ref) {\n                                var absmax = _ref.absmax,\n                                    hasMinVals = _ref.hasMinVals,\n                                    height = _ref.height,\n                                    offsetY = _ref.offsetY,\n                                    halfH = _ref.halfH,\n                                    peaks = _ref.peaks;\n\n                                // if drawBars was called within ws.empty we don't pass a start and\n                                // don't want anything to happen\n                                if (start === undefined) {\n                                    return;\n                                } // Skip every other value if there are negatives.\n\n\n                                var peakIndexScale = hasMinVals ? 2 : 1;\n                                var length = peaks.length / peakIndexScale;\n                                var bar = _this4.params.barWidth * _this4.params.pixelRatio;\n                                var gap = _this4.params.barGap === null ? Math.max(_this4.params.pixelRatio, ~~(bar / 2)) : Math.max(_this4.params.pixelRatio, _this4.params.barGap * _this4.params.pixelRatio);\n                                var step = bar + gap;\n                                var scale = length / _this4.width;\n                                var first = start;\n                                var last = end;\n                                var i = first;\n\n                                for (i; i < last; i += step) {\n                                    var peak = peaks[Math.floor(i * scale * peakIndexScale)] || 0;\n                                    var h = Math.round(peak / absmax * halfH);\n                                    /* in case of silences, allow the user to specify that we\n           * always draw *something* (normally a 1px high bar) */\n\n                                    if (h == 0 && _this4.params.barMinHeight) h = _this4.params.barMinHeight;\n\n                                    _this4.fillRect(i + _this4.halfPixel, halfH - h + offsetY, bar + _this4.halfPixel, h * 2, _this4.barRadius);\n                                }\n                            });\n                        }\n                        /**\n                         * Draw a waveform\n                         *\n                         * @param {number[]|Number.<Array[]>} peaks Can also be an array of arrays\n                         * for split channel rendering\n                         * @param {number} channelIndex The index of the current channel. Normally\n                         * should be 0\n                         * @param {number?} start The x-offset of the beginning of the area that\n                         * should be rendered (If this isn't set only a flat line is rendered)\n                         * @param {number?} end The x-offset of the end of the area that should be\n                         * rendered\n                         * @returns {void}\n                         */\n\n                    }, {\n                        key: \"drawWave\",\n                        value: function drawWave(peaks, channelIndex, start, end) {\n                            var _this5 = this;\n\n                            return this.prepareDraw(peaks, channelIndex, start, end, function (_ref2) {\n                                var absmax = _ref2.absmax,\n                                    hasMinVals = _ref2.hasMinVals,\n                                    height = _ref2.height,\n                                    offsetY = _ref2.offsetY,\n                                    halfH = _ref2.halfH,\n                                    peaks = _ref2.peaks;\n\n                                if (!hasMinVals) {\n                                    var reflectedPeaks = [];\n                                    var len = peaks.length;\n                                    var i = 0;\n\n                                    for (i; i < len; i++) {\n                                        reflectedPeaks[2 * i] = peaks[i];\n                                        reflectedPeaks[2 * i + 1] = -peaks[i];\n                                    }\n\n                                    peaks = reflectedPeaks;\n                                } // if drawWave was called within ws.empty we don't pass a start and\n                                // end and simply want a flat line\n\n\n                                if (start !== undefined) {\n                                    _this5.drawLine(peaks, absmax, halfH, offsetY, start, end);\n                                } // always draw a median line\n\n\n                                _this5.fillRect(0, halfH + offsetY - _this5.halfPixel, _this5.width, _this5.halfPixel, _this5.barRadius);\n                            });\n                        }\n                        /**\n                         * Tell the canvas entries to render their portion of the waveform\n                         *\n                         * @private\n                         * @param {number[]} peaks Peaks data\n                         * @param {number} absmax Maximum peak value (absolute)\n                         * @param {number} halfH Half the height of the waveform\n                         * @param {number} offsetY Offset to the top\n                         * @param {number} start The x-offset of the beginning of the area that\n                         * should be rendered\n                         * @param {number} end The x-offset of the end of the area that\n                         * should be rendered\n                         */\n\n                    }, {\n                        key: \"drawLine\",\n                        value: function drawLine(peaks, absmax, halfH, offsetY, start, end) {\n                            var _this6 = this;\n\n                            this.canvases.forEach(function (entry) {\n                                _this6.setFillStyles(entry);\n\n                                entry.drawLines(peaks, absmax, halfH, offsetY, start, end);\n                            });\n                        }\n                        /**\n                         * Draw a rectangle on the multi-canvas\n                         *\n                         * @param {number} x X-position of the rectangle\n                         * @param {number} y Y-position of the rectangle\n                         * @param {number} width Width of the rectangle\n                         * @param {number} height Height of the rectangle\n                         * @param {number} radius Radius of the rectangle\n                         */\n\n                    }, {\n                        key: \"fillRect\",\n                        value: function fillRect(x, y, width, height, radius) {\n                            var startCanvas = Math.floor(x / this.maxCanvasWidth);\n                            var endCanvas = Math.min(Math.ceil((x + width) / this.maxCanvasWidth) + 1, this.canvases.length);\n                            var i = startCanvas;\n\n                            for (i; i < endCanvas; i++) {\n                                var entry = this.canvases[i];\n                                var leftOffset = i * this.maxCanvasWidth;\n                                var intersection = {\n                                    x1: Math.max(x, i * this.maxCanvasWidth),\n                                    y1: y,\n                                    x2: Math.min(x + width, i * this.maxCanvasWidth + entry.wave.width),\n                                    y2: y + height\n                                };\n\n                                if (intersection.x1 < intersection.x2) {\n                                    this.setFillStyles(entry);\n                                    entry.fillRects(intersection.x1 - leftOffset, intersection.y1, intersection.x2 - intersection.x1, intersection.y2 - intersection.y1, radius);\n                                }\n                            }\n                        }\n                        /**\n                         * Performs preparation tasks and calculations which are shared by `drawBars`\n                         * and `drawWave`\n                         *\n                         * @private\n                         * @param {number[]|Number.<Array[]>} peaks Can also be an array of arrays for\n                         * split channel rendering\n                         * @param {number} channelIndex The index of the current channel. Normally\n                         * should be 0\n                         * @param {number?} start The x-offset of the beginning of the area that\n                         * should be rendered. If this isn't set only a flat line is rendered\n                         * @param {number?} end The x-offset of the end of the area that should be\n                         * rendered\n                         * @param {function} fn The render function to call, e.g. `drawWave`\n                         * @returns {void}\n                         */\n\n                    }, {\n                        key: \"prepareDraw\",\n                        value: function prepareDraw(peaks, channelIndex, start, end, fn) {\n                            var _this7 = this;\n\n                            return util.frame(function () {\n                                // Split channels and call this function with the channelIndex set\n                                if (peaks[0] instanceof Array) {\n                                    var channels = peaks;\n\n                                    if (_this7.params.splitChannels) {\n                                        _this7.setHeight(channels.length * _this7.params.height * _this7.params.pixelRatio);\n\n                                        return channels.forEach(function (channelPeaks, i) {\n                                            return _this7.prepareDraw(channelPeaks, i, start, end, fn);\n                                        });\n                                    }\n\n                                    peaks = channels[0];\n                                } // calculate maximum modulation value, either from the barHeight\n                                // parameter or if normalize=true from the largest value in the peak\n                                // set\n\n\n                                var absmax = 1 / _this7.params.barHeight;\n\n                                if (_this7.params.normalize) {\n                                    var max = util.max(peaks);\n                                    var min = util.min(peaks);\n                                    absmax = -min > max ? -min : max;\n                                } // Bar wave draws the bottom only as a reflection of the top,\n                                // so we don't need negative values\n\n\n                                var hasMinVals = [].some.call(peaks, function (val) {\n                                    return val < 0;\n                                });\n                                var height = _this7.params.height * _this7.params.pixelRatio;\n                                var offsetY = height * channelIndex || 0;\n                                var halfH = height / 2;\n                                return fn({\n                                    absmax: absmax,\n                                    hasMinVals: hasMinVals,\n                                    height: height,\n                                    offsetY: offsetY,\n                                    halfH: halfH,\n                                    peaks: peaks\n                                });\n                            })();\n                        }\n                        /**\n                         * Set the fill styles for a certain entry (wave and progress)\n                         *\n                         * @private\n                         * @param {CanvasEntry} entry Target entry\n                         */\n\n                    }, {\n                        key: \"setFillStyles\",\n                        value: function setFillStyles(entry) {\n                            entry.setFillStyles(this.params.waveColor, this.params.progressColor);\n                        }\n                        /**\n                         * Return image data of the multi-canvas\n                         *\n                         * When using a `type` of `'blob'`, this will return a `Promise`.\n                         *\n                         * @param {string} format='image/png' An optional value of a format type.\n                         * @param {number} quality=0.92 An optional value between 0 and 1.\n                         * @param {string} type='dataURL' Either 'dataURL' or 'blob'.\n                         * @return {string|string[]|Promise} When using the default `'dataURL'`\n                         * `type` this returns a single data URL or an array of data URLs,\n                         * one for each canvas. When using the `'blob'` `type` this returns a\n                         * `Promise` that resolves with an array of `Blob` instances, one for each\n                         * canvas.\n                         */\n\n                    }, {\n                        key: \"getImage\",\n                        value: function getImage(format, quality, type) {\n                            if (type === 'blob') {\n                                return Promise.all(this.canvases.map(function (entry) {\n                                    return entry.getImage(format, quality, type);\n                                }));\n                            } else if (type === 'dataURL') {\n                                var images = this.canvases.map(function (entry) {\n                                    return entry.getImage(format, quality, type);\n                                });\n                                return images.length > 1 ? images : images[0];\n                            }\n                        }\n                        /**\n                         * Render the new progress\n                         *\n                         * @param {number} position X-offset of progress position in pixels\n                         */\n\n                    }, {\n                        key: \"updateProgress\",\n                        value: function updateProgress(position) {\n                            this.style(this.progressWave, {\n                                width: position + 'px'\n                            });\n                        }\n                    }]);\n\n                    return MultiCanvas;\n                }(_drawer.default);\n\n            exports.default = MultiCanvas;\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/mediaelement-webaudio.js\":\n        /*!**************************************!*\\\n  !*** ./src/mediaelement-webaudio.js ***!\n  \\**************************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = void 0;\n\n            var _mediaelement = _interopRequireDefault(__webpack_require__(/*! ./mediaelement */ \"./src/mediaelement.js\"));\n\n            function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n            function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n            function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n            function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\n            function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n            function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\n            function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\n            function _get(target, property, receiver) { if (typeof Reflect !== \"undefined\" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); }\n\n            function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }\n\n            function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n            function _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\n            function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n            /**\n             * MediaElementWebAudio backend: allows to load audio as HTML5 audio tag and use it with WebAudio API.\n             * Setting the MediaElementWebAudio backend, there is the possibility to load audio of big dimensions, using the WebAudio API features.\n             * The audio to load is an HTML5 audio tag, so you have to use the same methods of MediaElement backend for loading and playback.\n             * In this way, the audio resource is not loaded entirely from server, but in ranges, since you load an HTML5 audio tag.\n             * In this way, filters and other functionalities can be performed like with WebAudio backend, but without decoding\n             * internally audio data, that caused crashing of the browser. You have to give also peaks, so the audio data are not decoded.\n             *\n             * @since 3.2.0\n             */\n            var MediaElementWebAudio =\n                /*#__PURE__*/\n                function (_MediaElement) {\n                    _inherits(MediaElementWebAudio, _MediaElement);\n\n                    /**\n                     * Construct the backend\n                     *\n                     * @param {WavesurferParams} params Wavesurfer parameters\n                     */\n                    function MediaElementWebAudio(params) {\n                        var _this;\n\n                        _classCallCheck(this, MediaElementWebAudio);\n\n                        _this = _possibleConstructorReturn(this, _getPrototypeOf(MediaElementWebAudio).call(this, params));\n                        /** @private */\n\n                        _this.params = params;\n                        /** @private */\n\n                        _this.sourceMediaElement = null;\n                        return _this;\n                    }\n                    /**\n                     * Initialise the backend, called in `wavesurfer.createBackend()`\n                     */\n\n\n                    _createClass(MediaElementWebAudio, [{\n                        key: \"init\",\n                        value: function init() {\n                            this.setPlaybackRate(this.params.audioRate);\n                            this.createTimer();\n                            this.createVolumeNode();\n                            this.createScriptNode();\n                            this.createAnalyserNode();\n                        }\n                        /**\n                         * Private method called by both `load` (from url)\n                         * and `loadElt` (existing media element) methods.\n                         *\n                         * @param {HTMLMediaElement} media HTML5 Audio or Video element\n                         * @param {number[]|Number.<Array[]>} peaks Array of peak data\n                         * @private\n                         */\n\n                    }, {\n                        key: \"_load\",\n                        value: function _load(media, peaks) {\n                            _get(_getPrototypeOf(MediaElementWebAudio.prototype), \"_load\", this).call(this, media, peaks);\n\n                            this.createMediaElementSource(media);\n                        }\n                        /**\n                         * Create MediaElementSource node\n                         *\n                         * @since 3.2.0\n                         * @param {HTMLMediaElement} mediaElement HTML5 Audio to load\n                         */\n\n                    }, {\n                        key: \"createMediaElementSource\",\n                        value: function createMediaElementSource(mediaElement) {\n                            this.sourceMediaElement = this.ac.createMediaElementSource(mediaElement);\n                            this.sourceMediaElement.connect(this.analyser);\n                        }\n                    }]);\n\n                    return MediaElementWebAudio;\n                }(_mediaelement.default);\n\n            exports.default = MediaElementWebAudio;\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/mediaelement.js\":\n        /*!*****************************!*\\\n  !*** ./src/mediaelement.js ***!\n  \\*****************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = void 0;\n\n            var _webaudio = _interopRequireDefault(__webpack_require__(/*! ./webaudio */ \"./src/webaudio.js\"));\n\n            var util = _interopRequireWildcard(__webpack_require__(/*! ./util */ \"./src/util/index.js\"));\n\n            function _getRequireWildcardCache() { if (typeof WeakMap !== \"function\") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }\n\n            function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \"object\" && typeof obj !== \"function\") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }\n\n            function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n            function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n            function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n            function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\n            function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n            function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\n            function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\n            function _get(target, property, receiver) { if (typeof Reflect !== \"undefined\" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); }\n\n            function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }\n\n            function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n            function _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\n            function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n            /**\n             * MediaElement backend\n             */\n            var MediaElement =\n                /*#__PURE__*/\n                function (_WebAudio) {\n                    _inherits(MediaElement, _WebAudio);\n\n                    /**\n                     * Construct the backend\n                     *\n                     * @param {WavesurferParams} params Wavesurfer parameters\n                     */\n                    function MediaElement(params) {\n                        var _this;\n\n                        _classCallCheck(this, MediaElement);\n\n                        _this = _possibleConstructorReturn(this, _getPrototypeOf(MediaElement).call(this, params));\n                        /** @private */\n\n                        _this.params = params;\n                        /**\n                         * Initially a dummy media element to catch errors. Once `_load` is\n                         * called, this will contain the actual `HTMLMediaElement`.\n                         * @private\n                         */\n\n                        _this.media = {\n                            currentTime: 0,\n                            duration: 0,\n                            paused: true,\n                            playbackRate: 1,\n                            play: function play() {},\n                            pause: function pause() {},\n                            volume: 0\n                        };\n                        /** @private */\n\n                        _this.mediaType = params.mediaType.toLowerCase();\n                        /** @private */\n\n                        _this.elementPosition = params.elementPosition;\n                        /** @private */\n\n                        _this.peaks = null;\n                        /** @private */\n\n                        _this.playbackRate = 1;\n                        /** @private */\n\n                        _this.volume = 1;\n                        /** @private */\n\n                        _this.isMuted = false;\n                        /** @private */\n\n                        _this.buffer = null;\n                        /** @private */\n\n                        _this.onPlayEnd = null;\n                        /** @private */\n\n                        _this.mediaListeners = {};\n                        return _this;\n                    }\n                    /**\n                     * Initialise the backend, called in `wavesurfer.createBackend()`\n                     */\n\n\n                    _createClass(MediaElement, [{\n                        key: \"init\",\n                        value: function init() {\n                            this.setPlaybackRate(this.params.audioRate);\n                            this.createTimer();\n                        }\n                        /**\n                         * Attach event listeners to media element.\n                         */\n\n                    }, {\n                        key: \"_setupMediaListeners\",\n                        value: function _setupMediaListeners() {\n                            var _this2 = this;\n\n                            this.mediaListeners.error = function () {\n                                _this2.fireEvent('error', 'Error loading media element');\n                            };\n\n                            this.mediaListeners.canplay = function () {\n                                _this2.fireEvent('canplay');\n                            };\n\n                            this.mediaListeners.ended = function () {\n                                _this2.fireEvent('finish');\n                            }; // listen to and relay play, pause and seeked events to enable\n                            // playback control from the external media element\n\n\n                            this.mediaListeners.play = function () {\n                                _this2.fireEvent('play');\n                            };\n\n                            this.mediaListeners.pause = function () {\n                                _this2.fireEvent('pause');\n                            };\n\n                            this.mediaListeners.seeked = function (event) {\n                                _this2.fireEvent('seek');\n                            };\n\n                            this.mediaListeners.volumechange = function (event) {\n                                _this2.isMuted = _this2.media.muted;\n\n                                if (_this2.isMuted) {\n                                    _this2.volume = 0;\n                                } else {\n                                    _this2.volume = _this2.media.volume;\n                                }\n\n                                _this2.fireEvent('volume');\n                            }; // reset event listeners\n\n\n                            Object.keys(this.mediaListeners).forEach(function (id) {\n                                _this2.media.removeEventListener(id, _this2.mediaListeners[id]);\n\n                                _this2.media.addEventListener(id, _this2.mediaListeners[id]);\n                            });\n                        }\n                        /**\n                         * Create a timer to provide a more precise `audioprocess` event.\n                         */\n\n                    }, {\n                        key: \"createTimer\",\n                        value: function createTimer() {\n                            var _this3 = this;\n\n                            var onAudioProcess = function onAudioProcess() {\n                                if (_this3.isPaused()) {\n                                    return;\n                                }\n\n                                _this3.fireEvent('audioprocess', _this3.getCurrentTime()); // Call again in the next frame\n\n\n                                util.frame(onAudioProcess)();\n                            };\n\n                            this.on('play', onAudioProcess); // Update the progress one more time to prevent it from being stuck in\n                            // case of lower framerates\n\n                            this.on('pause', function () {\n                                _this3.fireEvent('audioprocess', _this3.getCurrentTime());\n                            });\n                        }\n                        /**\n                         * Create media element with url as its source,\n                         * and append to container element.\n                         *\n                         * @param {string} url Path to media file\n                         * @param {HTMLElement} container HTML element\n                         * @param {number[]|Number.<Array[]>} peaks Array of peak data\n                         * @param {string} preload HTML 5 preload attribute value\n                         * @throws Will throw an error if the `url` argument is not a valid media\n                         * element.\n                         */\n\n                    }, {\n                        key: \"load\",\n                        value: function load(url, container, peaks, preload) {\n                            var media = document.createElement(this.mediaType);\n                            media.controls = this.params.mediaControls;\n                            media.autoplay = this.params.autoplay || false;\n                            media.preload = preload == null ? 'auto' : preload;\n                            media.src = url;\n                            media.style.width = '100%';\n                            var prevMedia = container.querySelector(this.mediaType);\n\n                            if (prevMedia) {\n                                container.removeChild(prevMedia);\n                            }\n\n                            container.appendChild(media);\n\n                            this._load(media, peaks);\n                        }\n                        /**\n                         * Load existing media element.\n                         *\n                         * @param {HTMLMediaElement} elt HTML5 Audio or Video element\n                         * @param {number[]|Number.<Array[]>} peaks Array of peak data\n                         */\n\n                    }, {\n                        key: \"loadElt\",\n                        value: function loadElt(elt, peaks) {\n                            elt.controls = this.params.mediaControls;\n                            elt.autoplay = this.params.autoplay || false;\n\n                            this._load(elt, peaks);\n                        }\n                        /**\n                         * Method called by both `load` (from url)\n                         * and `loadElt` (existing media element) methods.\n                         *\n                         * @param {HTMLMediaElement} media HTML5 Audio or Video element\n                         * @param {number[]|Number.<Array[]>} peaks Array of peak data\n                         * @throws Will throw an error if the `media` argument is not a valid media\n                         * element.\n                         * @private\n                         */\n\n                    }, {\n                        key: \"_load\",\n                        value: function _load(media, peaks) {\n                            // verify media element is valid\n                            if (!(media instanceof HTMLMediaElement) || typeof media.addEventListener === 'undefined') {\n                                throw new Error('media parameter is not a valid media element');\n                            } // load must be called manually on iOS, otherwise peaks won't draw\n                            // until a user interaction triggers load --> 'ready' event\n\n\n                            if (typeof media.load == 'function') {\n                                // Resets the media element and restarts the media resource. Any\n                                // pending events are discarded. How much media data is fetched is\n                                // still affected by the preload attribute.\n                                media.load();\n                            }\n\n                            this.media = media;\n\n                            this._setupMediaListeners();\n\n                            this.peaks = peaks;\n                            this.onPlayEnd = null;\n                            this.buffer = null;\n                            this.isMuted = media.muted;\n                            this.setPlaybackRate(this.playbackRate);\n                            this.setVolume(this.volume);\n                        }\n                        /**\n                         * Used by `wavesurfer.isPlaying()` and `wavesurfer.playPause()`\n                         *\n                         * @return {boolean} Media paused or not\n                         */\n\n                    }, {\n                        key: \"isPaused\",\n                        value: function isPaused() {\n                            return !this.media || this.media.paused;\n                        }\n                        /**\n                         * Used by `wavesurfer.getDuration()`\n                         *\n                         * @return {number} Duration\n                         */\n\n                    }, {\n                        key: \"getDuration\",\n                        value: function getDuration() {\n                            if (this.explicitDuration) {\n                                return this.explicitDuration;\n                            }\n\n                            var duration = (this.buffer || this.media).duration;\n\n                            if (duration >= Infinity) {\n                                // streaming audio\n                                duration = this.media.seekable.end(0);\n                            }\n\n                            return duration;\n                        }\n                        /**\n                         * Returns the current time in seconds relative to the audio-clip's\n                         * duration.\n                         *\n                         * @return {number} Current time\n                         */\n\n                    }, {\n                        key: \"getCurrentTime\",\n                        value: function getCurrentTime() {\n                            return this.media && this.media.currentTime;\n                        }\n                        /**\n                         * Get the position from 0 to 1\n                         *\n                         * @return {number} Current position\n                         */\n\n                    }, {\n                        key: \"getPlayedPercents\",\n                        value: function getPlayedPercents() {\n                            return this.getCurrentTime() / this.getDuration() || 0;\n                        }\n                        /**\n                         * Get the audio source playback rate.\n                         *\n                         * @return {number} Playback rate\n                         */\n\n                    }, {\n                        key: \"getPlaybackRate\",\n                        value: function getPlaybackRate() {\n                            return this.playbackRate || this.media.playbackRate;\n                        }\n                        /**\n                         * Set the audio source playback rate.\n                         *\n                         * @param {number} value Playback rate\n                         */\n\n                    }, {\n                        key: \"setPlaybackRate\",\n                        value: function setPlaybackRate(value) {\n                            this.playbackRate = value || 1;\n                            this.media.playbackRate = this.playbackRate;\n                        }\n                        /**\n                         * Used by `wavesurfer.seekTo()`\n                         *\n                         * @param {number} start Position to start at in seconds\n                         */\n\n                    }, {\n                        key: \"seekTo\",\n                        value: function seekTo(start) {\n                            if (start != null) {\n                                this.media.currentTime = start;\n                            }\n\n                            this.clearPlayEnd();\n                        }\n                        /**\n                         * Plays the loaded audio region.\n                         *\n                         * @param {number} start Start offset in seconds, relative to the beginning\n                         * of a clip.\n                         * @param {number} end When to stop, relative to the beginning of a clip.\n                         * @emits MediaElement#play\n                         * @return {Promise} Result\n                         */\n\n                    }, {\n                        key: \"play\",\n                        value: function play(start, end) {\n                            this.seekTo(start);\n                            var promise = this.media.play();\n                            end && this.setPlayEnd(end);\n                            return promise;\n                        }\n                        /**\n                         * Pauses the loaded audio.\n                         *\n                         * @emits MediaElement#pause\n                         * @return {Promise} Result\n                         */\n\n                    }, {\n                        key: \"pause\",\n                        value: function pause() {\n                            var promise;\n\n                            if (this.media) {\n                                promise = this.media.pause();\n                            }\n\n                            this.clearPlayEnd();\n                            return promise;\n                        }\n                        /**\n                         * Set the play end\n                         *\n                         * @param {number} end Where to end\n                         */\n\n                    }, {\n                        key: \"setPlayEnd\",\n                        value: function setPlayEnd(end) {\n                            var _this4 = this;\n\n                            this.clearPlayEnd();\n\n                            this._onPlayEnd = function (time) {\n                                if (time >= end) {\n                                    _this4.pause();\n\n                                    _this4.seekTo(end);\n                                }\n                            };\n\n                            this.on('audioprocess', this._onPlayEnd);\n                        }\n                        /** @private */\n\n                    }, {\n                        key: \"clearPlayEnd\",\n                        value: function clearPlayEnd() {\n                            if (this._onPlayEnd) {\n                                this.un('audioprocess', this._onPlayEnd);\n                                this._onPlayEnd = null;\n                            }\n                        }\n                        /**\n                         * Compute the max and min value of the waveform when broken into\n                         * <length> subranges.\n                         *\n                         * @param {number} length How many subranges to break the waveform into.\n                         * @param {number} first First sample in the required range.\n                         * @param {number} last Last sample in the required range.\n                         * @return {number[]|Number.<Array[]>} Array of 2*<length> peaks or array of\n                         * arrays of peaks consisting of (max, min) values for each subrange.\n                         */\n\n                    }, {\n                        key: \"getPeaks\",\n                        value: function getPeaks(length, first, last) {\n                            if (this.buffer) {\n                                return _get(_getPrototypeOf(MediaElement.prototype), \"getPeaks\", this).call(this, length, first, last);\n                            }\n\n                            return this.peaks || [];\n                        }\n                        /**\n                         * Set the sink id for the media player\n                         *\n                         * @param {string} deviceId String value representing audio device id.\n                         * @returns {Promise} A Promise that resolves to `undefined` when there\n                         * are no errors.\n                         */\n\n                    }, {\n                        key: \"setSinkId\",\n                        value: function setSinkId(deviceId) {\n                            if (deviceId) {\n                                if (!this.media.setSinkId) {\n                                    return Promise.reject(new Error('setSinkId is not supported in your browser'));\n                                }\n\n                                return this.media.setSinkId(deviceId);\n                            }\n\n                            return Promise.reject(new Error('Invalid deviceId: ' + deviceId));\n                        }\n                        /**\n                         * Get the current volume\n                         *\n                         * @return {number} value A floating point value between 0 and 1.\n                         */\n\n                    }, {\n                        key: \"getVolume\",\n                        value: function getVolume() {\n                            return this.volume;\n                        }\n                        /**\n                         * Set the audio volume\n                         *\n                         * @param {number} value A floating point value between 0 and 1.\n                         */\n\n                    }, {\n                        key: \"setVolume\",\n                        value: function setVolume(value) {\n                            this.volume = value; // no need to change when it's already at that volume\n\n                            if (this.media.volume !== this.volume) {\n                                this.media.volume = this.volume;\n                            }\n                        }\n                        /**\n                         * This is called when wavesurfer is destroyed\n                         *\n                         */\n\n                    }, {\n                        key: \"destroy\",\n                        value: function destroy() {\n                            var _this5 = this;\n\n                            this.pause();\n                            this.unAll();\n                            this.destroyed = true; // cleanup media event listeners\n\n                            Object.keys(this.mediaListeners).forEach(function (id) {\n                                if (_this5.media) {\n                                    _this5.media.removeEventListener(id, _this5.mediaListeners[id]);\n                                }\n                            });\n\n                            if (this.params.removeMediaElementOnDestroy && this.media && this.media.parentNode) {\n                                this.media.parentNode.removeChild(this.media);\n                            }\n\n                            this.media = null;\n                        }\n                    }]);\n\n                    return MediaElement;\n                }(_webaudio.default);\n\n            exports.default = MediaElement;\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/peakcache.js\":\n        /*!**************************!*\\\n  !*** ./src/peakcache.js ***!\n  \\**************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = void 0;\n\n            function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n            function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\n            function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n            /**\n             * Caches the decoded peaks data to improve rendering speed for large audio\n             *\n             * Is used if the option parameter `partialRender` is set to `true`\n             */\n            var PeakCache =\n                /*#__PURE__*/\n                function () {\n                    /**\n                     * Instantiate cache\n                     */\n                    function PeakCache() {\n                        _classCallCheck(this, PeakCache);\n\n                        this.clearPeakCache();\n                    }\n                    /**\n                     * Empty the cache\n                     */\n\n\n                    _createClass(PeakCache, [{\n                        key: \"clearPeakCache\",\n                        value: function clearPeakCache() {\n                            /**\n                             * Flat array with entries that are always in pairs to mark the\n                             * beginning and end of each subrange.  This is a convenience so we can\n                             * iterate over the pairs for easy set difference operations.\n                             * @private\n                             */\n                            this.peakCacheRanges = [];\n                            /**\n                             * Length of the entire cachable region, used for resetting the cache\n                             * when this changes (zoom events, for instance).\n                             * @private\n                             */\n\n                            this.peakCacheLength = -1;\n                        }\n                        /**\n                         * Add a range of peaks to the cache\n                         *\n                         * @param {number} length The length of the range\n                         * @param {number} start The x offset of the start of the range\n                         * @param {number} end The x offset of the end of the range\n                         * @return {Number.<Array[]>} Array with arrays of numbers\n                         */\n\n                    }, {\n                        key: \"addRangeToPeakCache\",\n                        value: function addRangeToPeakCache(length, start, end) {\n                            if (length != this.peakCacheLength) {\n                                this.clearPeakCache();\n                                this.peakCacheLength = length;\n                            } // Return ranges that weren't in the cache before the call.\n\n\n                            var uncachedRanges = [];\n                            var i = 0; // Skip ranges before the current start.\n\n                            while (i < this.peakCacheRanges.length && this.peakCacheRanges[i] < start) {\n                                i++;\n                            } // If |i| is even, |start| falls after an existing range.  Otherwise,\n                            // |start| falls between an existing range, and the uncached region\n                            // starts when we encounter the next node in |peakCacheRanges| or\n                            // |end|, whichever comes first.\n\n\n                            if (i % 2 == 0) {\n                                uncachedRanges.push(start);\n                            }\n\n                            while (i < this.peakCacheRanges.length && this.peakCacheRanges[i] <= end) {\n                                uncachedRanges.push(this.peakCacheRanges[i]);\n                                i++;\n                            } // If |i| is even, |end| is after all existing ranges.\n\n\n                            if (i % 2 == 0) {\n                                uncachedRanges.push(end);\n                            } // Filter out the 0-length ranges.\n\n\n                            uncachedRanges = uncachedRanges.filter(function (item, pos, arr) {\n                                if (pos == 0) {\n                                    return item != arr[pos + 1];\n                                } else if (pos == arr.length - 1) {\n                                    return item != arr[pos - 1];\n                                }\n\n                                return item != arr[pos - 1] && item != arr[pos + 1];\n                            }); // Merge the two ranges together, uncachedRanges will either contain\n                            // wholly new points, or duplicates of points in peakCacheRanges.  If\n                            // duplicates are detected, remove both and extend the range.\n\n                            this.peakCacheRanges = this.peakCacheRanges.concat(uncachedRanges);\n                            this.peakCacheRanges = this.peakCacheRanges.sort(function (a, b) {\n                                return a - b;\n                            }).filter(function (item, pos, arr) {\n                                if (pos == 0) {\n                                    return item != arr[pos + 1];\n                                } else if (pos == arr.length - 1) {\n                                    return item != arr[pos - 1];\n                                }\n\n                                return item != arr[pos - 1] && item != arr[pos + 1];\n                            }); // Push the uncached ranges into an array of arrays for ease of\n                            // iteration in the functions that call this.\n\n                            var uncachedRangePairs = [];\n\n                            for (i = 0; i < uncachedRanges.length; i += 2) {\n                                uncachedRangePairs.push([uncachedRanges[i], uncachedRanges[i + 1]]);\n                            }\n\n                            return uncachedRangePairs;\n                        }\n                        /**\n                         * For testing\n                         *\n                         * @return {Number.<Array[]>} Array with arrays of numbers\n                         */\n\n                    }, {\n                        key: \"getCacheRanges\",\n                        value: function getCacheRanges() {\n                            var peakCacheRangePairs = [];\n                            var i;\n\n                            for (i = 0; i < this.peakCacheRanges.length; i += 2) {\n                                peakCacheRangePairs.push([this.peakCacheRanges[i], this.peakCacheRanges[i + 1]]);\n                            }\n\n                            return peakCacheRangePairs;\n                        }\n                    }]);\n\n                    return PeakCache;\n                }();\n\n            exports.default = PeakCache;\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/util/ajax.js\":\n        /*!**************************!*\\\n  !*** ./src/util/ajax.js ***!\n  \\**************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = ajax;\n\n            var _observer = _interopRequireDefault(__webpack_require__(/*! ./observer */ \"./src/util/observer.js\"));\n\n            function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n            /**\n             * Perform an ajax request using `XMLHttpRequest`.\n             *\n             * @deprecated Use `util.fetchFile` instead.\n             *\n             * @param {Object} options AJAX options to use. See example below for options.\n             * @returns {Observer} Observer instance\n             * @example\n             * // default options\n             * let options = {\n *     method: 'GET',\n *     url: undefined,\n *     responseType: 'json',\n *     xhr: {}\n * };\n             *\n             * // override default options\n             * options.url = '../media/demo.wav';\n             * options.responseType = 'arraybuffer';\n             * options.xhr = {\n *     requestHeaders: [\n *         {\n *             key: 'Authorization',\n *             value: 'my-token'\n *         }\n *     ],\n *     withCredentials: true\n * };\n             *\n             * // make ajax call\n             * let ajaxCall = util.ajax(options);\n             * ajaxCall.on('progress', e => {\n *     console.log('progress', e);\n * });\n             * ajaxCall.on('success', (data, e) => {\n *     console.log('success!', data);\n * });\n             * ajaxCall.on('error', e => {\n *     console.warn('ajax error: ' + e.target.statusText);\n * });\n             */\n            function ajax(options) {\n                var instance = new _observer.default();\n                var xhr = new XMLHttpRequest();\n                var fired100 = false;\n                xhr.open(options.method || 'GET', options.url, true);\n                xhr.responseType = options.responseType || 'json';\n\n                if (options.xhr) {\n                    if (options.xhr.requestHeaders) {\n                        // add custom request headers\n                        options.xhr.requestHeaders.forEach(function (header) {\n                            xhr.setRequestHeader(header.key, header.value);\n                        });\n                    }\n\n                    if (options.xhr.withCredentials) {\n                        // use credentials\n                        xhr.withCredentials = true;\n                    }\n                }\n\n                xhr.addEventListener('progress', function (e) {\n                    instance.fireEvent('progress', e);\n\n                    if (e.lengthComputable && e.loaded == e.total) {\n                        fired100 = true;\n                    }\n                });\n                xhr.addEventListener('load', function (e) {\n                    if (!fired100) {\n                        instance.fireEvent('progress', e);\n                    }\n\n                    instance.fireEvent('load', e);\n\n                    if (200 == xhr.status || 206 == xhr.status) {\n                        instance.fireEvent('success', xhr.response, e);\n                    } else {\n                        instance.fireEvent('error', e);\n                    }\n                });\n                xhr.addEventListener('error', function (e) {\n                    return instance.fireEvent('error', e);\n                });\n                xhr.send();\n                instance.xhr = xhr;\n                return instance;\n            }\n\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/util/extend.js\":\n        /*!****************************!*\\\n  !*** ./src/util/extend.js ***!\n  \\****************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = extend;\n\n            /* eslint no-console: [\"error\", { allow: [\"warn\"] }] */\n\n            /**\n             * Extend an object shallowly with others\n             *\n             * @param {Object} dest The target object\n             * @param {Object[]} sources The objects to use for extending\n             *\n             * @return {Object} Merged object\n             * @deprecated since version 3.3.0\n             */\n            function extend(dest) {\n                console.warn('util.extend is deprecated; use Object.assign instead');\n\n                for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n                    sources[_key - 1] = arguments[_key];\n                }\n\n                sources.forEach(function (source) {\n                    Object.keys(source).forEach(function (key) {\n                        dest[key] = source[key];\n                    });\n                });\n                return dest;\n            }\n\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/util/fetch.js\":\n        /*!***************************!*\\\n  !*** ./src/util/fetch.js ***!\n  \\***************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = fetchFile;\n\n            var _observer = _interopRequireDefault(__webpack_require__(/*! ./observer */ \"./src/util/observer.js\"));\n\n            function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n            function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n            function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\n            function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n            var ProgressHandler =\n                /*#__PURE__*/\n                function () {\n                    /**\n                     * Instantiate ProgressHandler\n                     *\n                     * @param {Observer} instance The `fetchFile` observer instance.\n                     * @param {Number} contentLength Content length.\n                     * @param {Response} response Response object.\n                     */\n                    function ProgressHandler(instance, contentLength, response) {\n                        _classCallCheck(this, ProgressHandler);\n\n                        this.instance = instance;\n                        this.instance._reader = response.body.getReader();\n                        this.total = parseInt(contentLength, 10);\n                        this.loaded = 0;\n                    }\n                    /**\n                     * A method that is called once, immediately after the `ReadableStream``\n                     * is constructed.\n                     *\n                     * @param {ReadableStreamDefaultController} controller Controller instance\n                     *     used to control the stream.\n                     */\n\n\n                    _createClass(ProgressHandler, [{\n                        key: \"start\",\n                        value: function start(controller) {\n                            var _this = this;\n\n                            var read = function read() {\n                                // instance._reader.read() returns a promise that resolves\n                                // when a value has been received\n                                _this.instance._reader.read().then(function (_ref) {\n                                    var done = _ref.done,\n                                        value = _ref.value;\n\n                                    // result objects contain two properties:\n                                    // done  - true if the stream has already given you all its data.\n                                    // value - some data. Always undefined when done is true.\n                                    if (done) {\n                                        // ensure onProgress called when content-length=0\n                                        if (_this.total === 0) {\n                                            _this.instance.onProgress.call(_this.instance, {\n                                                loaded: _this.loaded,\n                                                total: _this.total,\n                                                lengthComputable: false\n                                            });\n                                        } // no more data needs to be consumed, close the stream\n\n\n                                        controller.close();\n                                        return;\n                                    }\n\n                                    _this.loaded += value.byteLength;\n\n                                    _this.instance.onProgress.call(_this.instance, {\n                                        loaded: _this.loaded,\n                                        total: _this.total,\n                                        lengthComputable: !(_this.total === 0)\n                                    }); // enqueue the next data chunk into our target stream\n\n\n                                    controller.enqueue(value);\n                                    read();\n                                }).catch(function (error) {\n                                    controller.error(error);\n                                });\n                            };\n\n                            read();\n                        }\n                    }]);\n\n                    return ProgressHandler;\n                }();\n            /**\n             * Load a file using `fetch`.\n             *\n             * @param {object} options Request options to use. See example below.\n             * @returns {Observer} Observer instance\n             * @example\n             * // default options\n             * let options = {\n *     url: undefined,\n *     method: 'GET',\n *     mode: 'cors',\n *     credentials: 'same-origin',\n *     cache: 'default',\n *     responseType: 'json',\n *     requestHeaders: [],\n *     redirect: 'follow',\n *     referrer: 'client'\n * };\n             *\n             * // override some options\n             * options.url = '../media/demo.wav';\n\n             * // available types: 'arraybuffer', 'blob', 'json' or 'text'\n             * options.responseType = 'arraybuffer';\n             *\n             * // make fetch call\n             * let request = util.fetchFile(options);\n             *\n             * // listen for events\n             * request.on('progress', e => {\n *     console.log('progress', e);\n * });\n             *\n             * request.on('success', data => {\n *     console.log('success!', data);\n * });\n             *\n             * request.on('error', e => {\n *     console.warn('fetchFile error: ', e);\n * });\n             */\n\n\n            function fetchFile(options) {\n                if (!options) {\n                    throw new Error('fetch options missing');\n                } else if (!options.url) {\n                    throw new Error('fetch url missing');\n                }\n\n                var instance = new _observer.default();\n                var fetchHeaders = new Headers();\n                var fetchRequest = new Request(options.url); // add ability to abort\n\n                instance.controller = new AbortController(); // check if headers have to be added\n\n                if (options && options.requestHeaders) {\n                    // add custom request headers\n                    options.requestHeaders.forEach(function (header) {\n                        fetchHeaders.append(header.key, header.value);\n                    });\n                } // parse fetch options\n\n\n                var responseType = options.responseType || 'json';\n                var fetchOptions = {\n                    method: options.method || 'GET',\n                    headers: fetchHeaders,\n                    mode: options.mode || 'cors',\n                    credentials: options.credentials || 'same-origin',\n                    cache: options.cache || 'default',\n                    redirect: options.redirect || 'follow',\n                    referrer: options.referrer || 'client',\n                    signal: instance.controller.signal\n                };\n                fetch(fetchRequest, fetchOptions).then(function (response) {\n                    // store response reference\n                    instance.response = response;\n                    var progressAvailable = true;\n\n                    if (!response.body) {\n                        // ReadableStream is not yet supported in this browser\n                        // see https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream\n                        progressAvailable = false;\n                    } // Server must send CORS header \"Access-Control-Expose-Headers: content-length\"\n\n\n                    var contentLength = response.headers.get('content-length');\n\n                    if (contentLength === null) {\n                        // Content-Length server response header missing.\n                        // Don't evaluate download progress if we can't compare against a total size\n                        // see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Access-Control-Expose-Headers\n                        progressAvailable = false;\n                    }\n\n                    if (!progressAvailable) {\n                        // not able to check download progress so skip it\n                        return response;\n                    } // fire progress event when during load\n\n\n                    instance.onProgress = function (e) {\n                        instance.fireEvent('progress', e);\n                    };\n\n                    return new Response(new ReadableStream(new ProgressHandler(instance, contentLength, response)), fetchOptions);\n                }).then(function (response) {\n                    var errMsg;\n\n                    if (response.ok) {\n                        switch (responseType) {\n                            case 'arraybuffer':\n                                return response.arrayBuffer();\n\n                            case 'json':\n                                return response.json();\n\n                            case 'blob':\n                                return response.blob();\n\n                            case 'text':\n                                return response.text();\n\n                            default:\n                                errMsg = 'Unknown responseType: ' + responseType;\n                                break;\n                        }\n                    }\n\n                    if (!errMsg) {\n                        errMsg = 'HTTP error status: ' + response.status;\n                    }\n\n                    throw new Error(errMsg);\n                }).then(function (response) {\n                    instance.fireEvent('success', response);\n                }).catch(function (error) {\n                    instance.fireEvent('error', error);\n                }); // return the fetch request\n\n                instance.fetchRequest = fetchRequest;\n                return instance;\n            }\n\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/util/frame.js\":\n        /*!***************************!*\\\n  !*** ./src/util/frame.js ***!\n  \\***************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = frame;\n\n            var _requestAnimationFrame = _interopRequireDefault(__webpack_require__(/*! ./request-animation-frame */ \"./src/util/request-animation-frame.js\"));\n\n            function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n            /**\n             * Create a function which will be called at the next requestAnimationFrame\n             * cycle\n             *\n             * @param {function} func The function to call\n             *\n             * @return {func} The function wrapped within a requestAnimationFrame\n             */\n            function frame(func) {\n                return function () {\n                    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n                        args[_key] = arguments[_key];\n                    }\n\n                    return (0, _requestAnimationFrame.default)(function () {\n                        return func.apply(void 0, args);\n                    });\n                };\n            }\n\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/util/get-id.js\":\n        /*!****************************!*\\\n  !*** ./src/util/get-id.js ***!\n  \\****************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = getId;\n\n            /**\n             * Get a random prefixed ID\n             *\n             * @param {String} prefix Prefix to use. Default is `'wavesurfer_'`.\n             * @returns {String} Random prefixed ID\n             * @example\n             * console.log(getId()); // logs 'wavesurfer_b5pors4ru6g'\n             *\n             * let prefix = 'foo-';\n             * console.log(getId(prefix)); // logs 'foo-b5pors4ru6g'\n             */\n            function getId(prefix) {\n                if (prefix === undefined) {\n                    prefix = 'wavesurfer_';\n                }\n\n                return prefix + Math.random().toString(32).substring(2);\n            }\n\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/util/index.js\":\n        /*!***************************!*\\\n  !*** ./src/util/index.js ***!\n  \\***************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            Object.defineProperty(exports, \"ajax\", {\n                enumerable: true,\n                get: function get() {\n                    return _ajax.default;\n                }\n            });\n            Object.defineProperty(exports, \"getId\", {\n                enumerable: true,\n                get: function get() {\n                    return _getId.default;\n                }\n            });\n            Object.defineProperty(exports, \"max\", {\n                enumerable: true,\n                get: function get() {\n                    return _max.default;\n                }\n            });\n            Object.defineProperty(exports, \"min\", {\n                enumerable: true,\n                get: function get() {\n                    return _min.default;\n                }\n            });\n            Object.defineProperty(exports, \"Observer\", {\n                enumerable: true,\n                get: function get() {\n                    return _observer.default;\n                }\n            });\n            Object.defineProperty(exports, \"extend\", {\n                enumerable: true,\n                get: function get() {\n                    return _extend.default;\n                }\n            });\n            Object.defineProperty(exports, \"style\", {\n                enumerable: true,\n                get: function get() {\n                    return _style.default;\n                }\n            });\n            Object.defineProperty(exports, \"requestAnimationFrame\", {\n                enumerable: true,\n                get: function get() {\n                    return _requestAnimationFrame.default;\n                }\n            });\n            Object.defineProperty(exports, \"frame\", {\n                enumerable: true,\n                get: function get() {\n                    return _frame.default;\n                }\n            });\n            Object.defineProperty(exports, \"debounce\", {\n                enumerable: true,\n                get: function get() {\n                    return _debounce.default;\n                }\n            });\n            Object.defineProperty(exports, \"preventClick\", {\n                enumerable: true,\n                get: function get() {\n                    return _preventClick.default;\n                }\n            });\n            Object.defineProperty(exports, \"fetchFile\", {\n                enumerable: true,\n                get: function get() {\n                    return _fetch.default;\n                }\n            });\n\n            var _ajax = _interopRequireDefault(__webpack_require__(/*! ./ajax */ \"./src/util/ajax.js\"));\n\n            var _getId = _interopRequireDefault(__webpack_require__(/*! ./get-id */ \"./src/util/get-id.js\"));\n\n            var _max = _interopRequireDefault(__webpack_require__(/*! ./max */ \"./src/util/max.js\"));\n\n            var _min = _interopRequireDefault(__webpack_require__(/*! ./min */ \"./src/util/min.js\"));\n\n            var _observer = _interopRequireDefault(__webpack_require__(/*! ./observer */ \"./src/util/observer.js\"));\n\n            var _extend = _interopRequireDefault(__webpack_require__(/*! ./extend */ \"./src/util/extend.js\"));\n\n            var _style = _interopRequireDefault(__webpack_require__(/*! ./style */ \"./src/util/style.js\"));\n\n            var _requestAnimationFrame = _interopRequireDefault(__webpack_require__(/*! ./request-animation-frame */ \"./src/util/request-animation-frame.js\"));\n\n            var _frame = _interopRequireDefault(__webpack_require__(/*! ./frame */ \"./src/util/frame.js\"));\n\n            var _debounce = _interopRequireDefault(__webpack_require__(/*! debounce */ \"./node_modules/debounce/index.js\"));\n\n            var _preventClick = _interopRequireDefault(__webpack_require__(/*! ./prevent-click */ \"./src/util/prevent-click.js\"));\n\n            var _fetch = _interopRequireDefault(__webpack_require__(/*! ./fetch */ \"./src/util/fetch.js\"));\n\n            function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n            /***/ }),\n\n        /***/ \"./src/util/max.js\":\n        /*!*************************!*\\\n  !*** ./src/util/max.js ***!\n  \\*************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = max;\n\n            /**\n             * Get the largest value\n             *\n             * @param   {Array} values Array of numbers\n             * @returns {Number} Largest number found\n             * @example console.log(max([1, 2, 3])); // logs 3\n             */\n            function max(values) {\n                var largest = -Infinity;\n                Object.keys(values).forEach(function (i) {\n                    if (values[i] > largest) {\n                        largest = values[i];\n                    }\n                });\n                return largest;\n            }\n\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/util/min.js\":\n        /*!*************************!*\\\n  !*** ./src/util/min.js ***!\n  \\*************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = min;\n\n            /**\n             * Get the smallest value\n             *\n             * @param   {Array} values Array of numbers\n             * @returns {Number} Smallest number found\n             * @example console.log(min([1, 2, 3])); // logs 1\n             */\n            function min(values) {\n                var smallest = Number(Infinity);\n                Object.keys(values).forEach(function (i) {\n                    if (values[i] < smallest) {\n                        smallest = values[i];\n                    }\n                });\n                return smallest;\n            }\n\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/util/observer.js\":\n        /*!******************************!*\\\n  !*** ./src/util/observer.js ***!\n  \\******************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = void 0;\n\n            function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n            function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\n            function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n            /**\n             * @typedef {Object} ListenerDescriptor\n             * @property {string} name The name of the event\n             * @property {function} callback The callback\n             * @property {function} un The function to call to remove the listener\n             */\n\n            /**\n             * Observer class\n             */\n            var Observer =\n                /*#__PURE__*/\n                function () {\n                    /**\n                     * Instantiate Observer\n                     */\n                    function Observer() {\n                        _classCallCheck(this, Observer);\n\n                        /**\n                         * @private\n                         * @todo Initialise the handlers here already and remove the conditional\n                         * assignment in `on()`\n                         */\n                        this.handlers = null;\n                    }\n                    /**\n                     * Attach a handler function for an event.\n                     *\n                     * @param {string} event Name of the event to listen to\n                     * @param {function} fn The callback to trigger when the event is fired\n                     * @return {ListenerDescriptor} The event descriptor\n                     */\n\n\n                    _createClass(Observer, [{\n                        key: \"on\",\n                        value: function on(event, fn) {\n                            var _this = this;\n\n                            if (!this.handlers) {\n                                this.handlers = {};\n                            }\n\n                            var handlers = this.handlers[event];\n\n                            if (!handlers) {\n                                handlers = this.handlers[event] = [];\n                            }\n\n                            handlers.push(fn); // Return an event descriptor\n\n                            return {\n                                name: event,\n                                callback: fn,\n                                un: function un(e, fn) {\n                                    return _this.un(e, fn);\n                                }\n                            };\n                        }\n                        /**\n                         * Remove an event handler.\n                         *\n                         * @param {string} event Name of the event the listener that should be\n                         * removed listens to\n                         * @param {function} fn The callback that should be removed\n                         */\n\n                    }, {\n                        key: \"un\",\n                        value: function un(event, fn) {\n                            if (!this.handlers) {\n                                return;\n                            }\n\n                            var handlers = this.handlers[event];\n                            var i;\n\n                            if (handlers) {\n                                if (fn) {\n                                    for (i = handlers.length - 1; i >= 0; i--) {\n                                        if (handlers[i] == fn) {\n                                            handlers.splice(i, 1);\n                                        }\n                                    }\n                                } else {\n                                    handlers.length = 0;\n                                }\n                            }\n                        }\n                        /**\n                         * Remove all event handlers.\n                         */\n\n                    }, {\n                        key: \"unAll\",\n                        value: function unAll() {\n                            this.handlers = null;\n                        }\n                        /**\n                         * Attach a handler to an event. The handler is executed at most once per\n                         * event type.\n                         *\n                         * @param {string} event The event to listen to\n                         * @param {function} handler The callback that is only to be called once\n                         * @return {ListenerDescriptor} The event descriptor\n                         */\n\n                    }, {\n                        key: \"once\",\n                        value: function once(event, handler) {\n                            var _this2 = this;\n\n                            var fn = function fn() {\n                                for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n                                    args[_key] = arguments[_key];\n                                }\n\n                                /*  eslint-disable no-invalid-this */\n                                handler.apply(_this2, args);\n                                /*  eslint-enable no-invalid-this */\n\n                                setTimeout(function () {\n                                    _this2.un(event, fn);\n                                }, 0);\n                            };\n\n                            return this.on(event, fn);\n                        }\n                        /**\n                         * Manually fire an event\n                         *\n                         * @param {string} event The event to fire manually\n                         * @param {...any} args The arguments with which to call the listeners\n                         */\n\n                    }, {\n                        key: \"fireEvent\",\n                        value: function fireEvent(event) {\n                            for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n                                args[_key2 - 1] = arguments[_key2];\n                            }\n\n                            if (!this.handlers) {\n                                return;\n                            }\n\n                            var handlers = this.handlers[event];\n                            handlers && handlers.forEach(function (fn) {\n                                fn.apply(void 0, args);\n                            });\n                        }\n                    }]);\n\n                    return Observer;\n                }();\n\n            exports.default = Observer;\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/util/prevent-click.js\":\n        /*!***********************************!*\\\n  !*** ./src/util/prevent-click.js ***!\n  \\***********************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = preventClick;\n\n            /**\n             * Stops propagation of click event and removes event listener\n             *\n             * @private\n             * @param {object} event The click event\n             */\n            function preventClickHandler(event) {\n                event.stopPropagation();\n                document.body.removeEventListener('click', preventClickHandler, true);\n            }\n            /**\n             * Starts listening for click event and prevent propagation\n             *\n             * @param {object} values Values\n             */\n\n\n            function preventClick(values) {\n                document.body.addEventListener('click', preventClickHandler, true);\n            }\n\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/util/request-animation-frame.js\":\n        /*!*********************************************!*\\\n  !*** ./src/util/request-animation-frame.js ***!\n  \\*********************************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = void 0;\n\n            /* eslint-disable valid-jsdoc */\n\n            /**\n             * Returns the `requestAnimationFrame` function for the browser, or a shim with\n             * `setTimeout` if the function is not found\n             *\n             * @return {function} Available `requestAnimationFrame` function for the browser\n             */\n            var _default = (window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback, element) {\n                return setTimeout(callback, 1000 / 60);\n            }).bind(window);\n\n            exports.default = _default;\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/util/style.js\":\n        /*!***************************!*\\\n  !*** ./src/util/style.js ***!\n  \\***************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = style;\n\n            /**\n             * Apply a map of styles to an element\n             *\n             * @param {HTMLElement} el The element that the styles will be applied to\n             * @param {Object} styles The map of propName: attribute, both are used as-is\n             *\n             * @return {HTMLElement} el\n             */\n            function style(el, styles) {\n                Object.keys(styles).forEach(function (prop) {\n                    if (el.style[prop] !== styles[prop]) {\n                        el.style[prop] = styles[prop];\n                    }\n                });\n                return el;\n            }\n\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/wavesurfer.js\":\n        /*!***************************!*\\\n  !*** ./src/wavesurfer.js ***!\n  \\***************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = void 0;\n\n            var util = _interopRequireWildcard(__webpack_require__(/*! ./util */ \"./src/util/index.js\"));\n\n            var _drawer = _interopRequireDefault(__webpack_require__(/*! ./drawer.multicanvas */ \"./src/drawer.multicanvas.js\"));\n\n            var _webaudio = _interopRequireDefault(__webpack_require__(/*! ./webaudio */ \"./src/webaudio.js\"));\n\n            var _mediaelement = _interopRequireDefault(__webpack_require__(/*! ./mediaelement */ \"./src/mediaelement.js\"));\n\n            var _peakcache = _interopRequireDefault(__webpack_require__(/*! ./peakcache */ \"./src/peakcache.js\"));\n\n            var _mediaelementWebaudio = _interopRequireDefault(__webpack_require__(/*! ./mediaelement-webaudio */ \"./src/mediaelement-webaudio.js\"));\n\n            function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\n            function _getRequireWildcardCache() { if (typeof WeakMap !== \"function\") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }\n\n            function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \"object\" && typeof obj !== \"function\") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }\n\n            function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n            function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\n            function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n            function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\n            function _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\n            function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n            function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n            function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\n            function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n            /*\n * This work is licensed under a BSD-3-Clause License.\n */\n\n            /** @external {HTMLElement} https://developer.mozilla.org/en/docs/Web/API/HTMLElement */\n\n            /** @external {OfflineAudioContext} https://developer.mozilla.org/en-US/docs/Web/API/OfflineAudioContext */\n\n            /** @external {File} https://developer.mozilla.org/en-US/docs/Web/API/File */\n\n            /** @external {Blob} https://developer.mozilla.org/en-US/docs/Web/API/Blob */\n\n            /** @external {CanvasRenderingContext2D} https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D */\n\n            /** @external {MediaStreamConstraints} https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamConstraints */\n\n            /** @external {AudioNode} https://developer.mozilla.org/de/docs/Web/API/AudioNode */\n\n            /**\n             * @typedef {Object} WavesurferParams\n             * @property {AudioContext} audioContext=null Use your own previously\n             * initialized AudioContext or leave blank.\n             * @property {number} audioRate=1 Speed at which to play audio. Lower number is\n             * slower.\n             * @property {ScriptProcessorNode} audioScriptProcessor=null Use your own previously\n             * initialized ScriptProcessorNode or leave blank.\n             * @property {boolean} autoCenter=true If a scrollbar is present, center the\n             * waveform on current progress\n             * @property {number} autoCenterRate=5 If autoCenter is active, rate at which the\n             * waveform is centered\n             * @property {boolean} autoCenterImmediately=false If autoCenter is active, immediately\n             * center waveform on current progress\n             * @property {string} backend='WebAudio' `'WebAudio'|'MediaElement'|'MediaElementWebAudio'` In most cases\n             * you don't have to set this manually. MediaElement is a fallback for unsupported browsers.\n             * MediaElementWebAudio allows to use WebAudio API also with big audio files, loading audio like with\n             * MediaElement backend (HTML5 audio tag). You have to use the same methods of MediaElement backend for loading and\n             * playback, giving also peaks, so the audio data are not decoded. In this way you can use WebAudio features, like filters,\n             * also with audio with big duration. For example:\n             * ` wavesurfer.load(url | HTMLMediaElement, peaks, preload, duration);\n             *   wavesurfer.play();\n             *   wavesurfer.setFilter(customFilter);\n             * `\n             * @property {string} backgroundColor=null Change background color of the\n             * waveform container.\n             * @property {number} barHeight=1 The height of the wave bars.\n             * @property {number} barRadius=0 The radius of the wave bars. Makes bars rounded\n             * @property {number} barGap=null The optional spacing between bars of the wave,\n             * if not provided will be calculated in legacy format.\n             * @property {number} barWidth=null Draw the waveform using bars.\n             * @property {number} barMinHeight=null If specified, draw at least a bar of this height,\n             * eliminating waveform gaps\n             * @property {boolean} closeAudioContext=false Close and nullify all audio\n             * contexts when the destroy method is called.\n             * @property {!string|HTMLElement} container CSS selector or HTML element where\n             * the waveform should be drawn. This is the only required parameter.\n             * @property {string} cursorColor='#333' The fill color of the cursor indicating\n             * the playhead position.\n             * @property {number} cursorWidth=1 Measured in pixels.\n             * @property {object} drawingContextAttributes={desynchronized: false} Drawing context\n             * attributes.\n             * @property {number} duration=null Optional audio length so pre-rendered peaks\n             * can be display immediately for example.\n             * @property {boolean} fillParent=true Whether to fill the entire container or\n             * draw only according to `minPxPerSec`.\n             * @property {boolean} forceDecode=false Force decoding of audio using web audio\n             * when zooming to get a more detailed waveform.\n             * @property {number} height=128 The height of the waveform. Measured in\n             * pixels.\n             * @property {boolean} hideScrollbar=false Whether to hide the horizontal\n             * scrollbar when one would normally be shown.\n             * @property {boolean} interact=true Whether the mouse interaction will be\n             * enabled at initialization. You can switch this parameter at any time later\n             * on.\n             * @property {boolean} loopSelection=true (Use with regions plugin) Enable\n             * looping of selected regions\n             * @property {number} maxCanvasWidth=4000 Maximum width of a single canvas in\n             * pixels, excluding a small overlap (2 * `pixelRatio`, rounded up to the next\n             * even integer). If the waveform is longer than this value, additional canvases\n             * will be used to render the waveform, which is useful for very large waveforms\n             * that may be too wide for browsers to draw on a single canvas.\n             * @property {boolean} mediaControls=false (Use with backend `MediaElement` or `MediaElementWebAudio`)\n             * this enables the native controls for the media element\n             * @property {string} mediaType='audio' (Use with backend `MediaElement` or `MediaElementWebAudio`)\n             * `'audio'|'video'` ('video' only for `MediaElement`)\n             * @property {number} minPxPerSec=20 Minimum number of pixels per second of\n             * audio.\n             * @property {boolean} normalize=false If true, normalize by the maximum peak\n             * instead of 1.0.\n             * @property {boolean} partialRender=false Use the PeakCache to improve\n             * rendering speed of large waveforms\n             * @property {number} pixelRatio=window.devicePixelRatio The pixel ratio used to\n             * calculate display\n             * @property {PluginDefinition[]} plugins=[] An array of plugin definitions to\n             * register during instantiation, they will be directly initialised unless they\n             * are added with the `deferInit` property set to true.\n             * @property {string} progressColor='#555' The fill color of the part of the\n             * waveform behind the cursor. When `progressColor` and `waveColor` are the same\n             * the progress wave is not rendered at all.\n             * @property {boolean} removeMediaElementOnDestroy=true Set to false to keep the\n             * media element in the DOM when the player is destroyed. This is useful when\n             * reusing an existing media element via the `loadMediaElement` method.\n             * @property {Object} renderer=MultiCanvas Can be used to inject a custom\n             * renderer.\n             * @property {boolean|number} responsive=false If set to `true` resize the\n             * waveform, when the window is resized. This is debounced with a `100ms`\n             * timeout by default. If this parameter is a number it represents that timeout.\n             * @property {boolean} rtl=false If set to `true`, renders waveform from\n             * right-to-left.\n             * @property {boolean} scrollParent=false Whether to scroll the container with a\n             * lengthy waveform. Otherwise the waveform is shrunk to the container width\n             * (see fillParent).\n             * @property {number} skipLength=2 Number of seconds to skip with the\n             * skipForward() and skipBackward() methods.\n             * @property {boolean} splitChannels=false Render with separate waveforms for\n             * the channels of the audio\n             * @property {string} waveColor='#999' The fill color of the waveform after the\n             * cursor.\n             * @property {object} xhr={} XHR options. For example:\n             * `let xhr = {\n *     cache: 'default',\n *     mode: 'cors',\n *     method: 'GET',\n *     credentials: 'same-origin',\n *     redirect: 'follow',\n *     referrer: 'client',\n *     headers: [\n *         {\n *             key: 'Authorization',\n *             value: 'my-token'\n *         }\n *     ]\n * };`\n             */\n\n            /**\n             * @typedef {Object} PluginDefinition\n             * @desc The Object used to describe a plugin\n             * @example wavesurfer.addPlugin(pluginDefinition);\n             * @property {string} name The name of the plugin, the plugin instance will be\n             * added as a property to the wavesurfer instance under this name\n             * @property {?Object} staticProps The properties that should be added to the\n             * wavesurfer instance as static properties\n             * @property {?boolean} deferInit Don't initialise plugin\n             * automatically\n             * @property {Object} params={} The plugin parameters, they are the first parameter\n             * passed to the plugin class constructor function\n             * @property {PluginClass} instance The plugin instance factory, is called with\n             * the dependency specified in extends. Returns the plugin class.\n             */\n\n            /**\n             * @interface PluginClass\n             *\n             * @desc This is the interface which is implemented by all plugin classes. Note\n             * that this only turns into an observer after being passed through\n             * `wavesurfer.addPlugin`.\n             *\n             * @extends {Observer}\n             */\n            var PluginClass =\n                /*#__PURE__*/\n                function () {\n                    _createClass(PluginClass, [{\n                        key: \"create\",\n\n                        /**\n                         * Plugin definition factory\n                         *\n                         * This function must be used to create a plugin definition which can be\n                         * used by wavesurfer to correctly instantiate the plugin.\n                         *\n                         * It returns a `PluginDefinition` object representing the plugin.\n                         *\n                         * @param {Object} params={} The plugin params (specific to the plugin)\n                         */\n                        value: function create(params) {}\n                        /**\n                         * Construct the plugin\n                         *\n                         * @param {Object} params={} The plugin params (specific to the plugin)\n                         * @param {Object} ws The wavesurfer instance\n                         */\n\n                    }]);\n\n                    function PluginClass(params, ws) {\n                        _classCallCheck(this, PluginClass);\n                    }\n                    /**\n                     * Initialise the plugin\n                     *\n                     * Start doing something. This is called by\n                     * `wavesurfer.initPlugin(pluginName)`\n                     */\n\n\n                    _createClass(PluginClass, [{\n                        key: \"init\",\n                        value: function init() {}\n                        /**\n                         * Destroy the plugin instance\n                         *\n                         * Stop doing something. This is called by\n                         * `wavesurfer.destroyPlugin(pluginName)`\n                         */\n\n                    }, {\n                        key: \"destroy\",\n                        value: function destroy() {}\n                    }]);\n\n                    return PluginClass;\n                }();\n            /**\n             * WaveSurfer core library class\n             *\n             * @extends {Observer}\n             * @example\n             * const params = {\n *   container: '#waveform',\n *   waveColor: 'violet',\n *   progressColor: 'purple'\n * };\n             *\n             * // initialise like this\n             * const wavesurfer = WaveSurfer.create(params);\n             *\n             * // or like this ...\n             * const wavesurfer = new WaveSurfer(params);\n             * wavesurfer.init();\n             *\n             * // load audio file\n             * wavesurfer.load('example/media/demo.wav');\n             */\n\n\n            var WaveSurfer =\n                /*#__PURE__*/\n                function (_util$Observer) {\n                    _inherits(WaveSurfer, _util$Observer);\n\n                    _createClass(WaveSurfer, null, [{\n                        key: \"create\",\n\n                        /** @private */\n\n                        /** @private */\n\n                        /**\n                         * Instantiate this class, call its `init` function and returns it\n                         *\n                         * @param {WavesurferParams} params The wavesurfer parameters\n                         * @return {Object} WaveSurfer instance\n                         * @example const wavesurfer = WaveSurfer.create(params);\n                         */\n                        value: function create(params) {\n                            var wavesurfer = new WaveSurfer(params);\n                            return wavesurfer.init();\n                        }\n                        /**\n                         * The library version number is available as a static property of the\n                         * WaveSurfer class\n                         *\n                         * @type {String}\n                         * @example\n                         * console.log('Using wavesurfer.js ' + WaveSurfer.VERSION);\n                         */\n\n                    }]);\n\n                    /**\n                     * Initialise wavesurfer instance\n                     *\n                     * @param {WavesurferParams} params Instantiation options for wavesurfer\n                     * @example\n                     * const wavesurfer = new WaveSurfer(params);\n                     * @returns {this} Wavesurfer instance\n                     */\n                    function WaveSurfer(params) {\n                        var _this;\n\n                        _classCallCheck(this, WaveSurfer);\n\n                        _this = _possibleConstructorReturn(this, _getPrototypeOf(WaveSurfer).call(this));\n                        /**\n                         * Extract relevant parameters (or defaults)\n                         * @private\n                         */\n\n                        _this.defaultParams = {\n                            audioContext: null,\n                            audioScriptProcessor: null,\n                            audioRate: 1,\n                            autoCenter: true,\n                            autoCenterRate: 5,\n                            autoCenterImmediately: false,\n                            backend: 'WebAudio',\n                            backgroundColor: null,\n                            barHeight: 1,\n                            barRadius: 0,\n                            barGap: null,\n                            barMinHeight: null,\n                            container: null,\n                            cursorColor: '#333',\n                            cursorWidth: 1,\n                            dragSelection: true,\n                            drawingContextAttributes: {\n                                // Boolean that hints the user agent to reduce the latency\n                                // by desynchronizing the canvas paint cycle from the event\n                                // loop\n                                desynchronized: false\n                            },\n                            duration: null,\n                            fillParent: true,\n                            forceDecode: false,\n                            height: 128,\n                            hideScrollbar: false,\n                            interact: true,\n                            loopSelection: true,\n                            maxCanvasWidth: 4000,\n                            mediaContainer: null,\n                            mediaControls: false,\n                            mediaType: 'audio',\n                            minPxPerSec: 20,\n                            normalize: false,\n                            partialRender: false,\n                            pixelRatio: window.devicePixelRatio || screen.deviceXDPI / screen.logicalXDPI,\n                            plugins: [],\n                            progressColor: '#555',\n                            removeMediaElementOnDestroy: true,\n                            renderer: _drawer.default,\n                            responsive: false,\n                            rtl: false,\n                            scrollParent: false,\n                            skipLength: 2,\n                            splitChannels: false,\n                            waveColor: '#999',\n                            xhr: {}\n                        };\n                        _this.backends = {\n                            MediaElement: _mediaelement.default,\n                            WebAudio: _webaudio.default,\n                            MediaElementWebAudio: _mediaelementWebaudio.default\n                        };\n                        _this.util = util;\n                        _this.params = Object.assign({}, _this.defaultParams, params);\n                        /** @private */\n\n                        _this.container = 'string' == typeof params.container ? document.querySelector(_this.params.container) : _this.params.container;\n\n                        if (!_this.container) {\n                            throw new Error('Container element not found');\n                        }\n\n                        if (_this.params.mediaContainer == null) {\n                            /** @private */\n                            _this.mediaContainer = _this.container;\n                        } else if (typeof _this.params.mediaContainer == 'string') {\n                            /** @private */\n                            _this.mediaContainer = document.querySelector(_this.params.mediaContainer);\n                        } else {\n                            /** @private */\n                            _this.mediaContainer = _this.params.mediaContainer;\n                        }\n\n                        if (!_this.mediaContainer) {\n                            throw new Error('Media Container element not found');\n                        }\n\n                        if (_this.params.maxCanvasWidth <= 1) {\n                            throw new Error('maxCanvasWidth must be greater than 1');\n                        } else if (_this.params.maxCanvasWidth % 2 == 1) {\n                            throw new Error('maxCanvasWidth must be an even number');\n                        }\n\n                        if (_this.params.rtl === true) {\n                            util.style(_this.container, {\n                                transform: 'rotateY(180deg)'\n                            });\n                        }\n\n                        if (_this.params.backgroundColor) {\n                            _this.setBackgroundColor(_this.params.backgroundColor);\n                        }\n                        /**\n                         * @private Used to save the current volume when muting so we can\n                         * restore once unmuted\n                         * @type {number}\n                         */\n\n\n                        _this.savedVolume = 0;\n                        /**\n                         * @private The current muted state\n                         * @type {boolean}\n                         */\n\n                        _this.isMuted = false;\n                        /**\n                         * @private Will hold a list of event descriptors that need to be\n                         * canceled on subsequent loads of audio\n                         * @type {Object[]}\n                         */\n\n                        _this.tmpEvents = [];\n                        /**\n                         * @private Holds any running audio downloads\n                         * @type {Observer}\n                         */\n\n                        _this.currentRequest = null;\n                        /** @private */\n\n                        _this.arraybuffer = null;\n                        /** @private */\n\n                        _this.drawer = null;\n                        /** @private */\n\n                        _this.backend = null;\n                        /** @private */\n\n                        _this.peakCache = null; // cache constructor objects\n\n                        if (typeof _this.params.renderer !== 'function') {\n                            throw new Error('Renderer parameter is invalid');\n                        }\n                        /**\n                         * @private The uninitialised Drawer class\n                         */\n\n\n                        _this.Drawer = _this.params.renderer;\n                        /**\n                         * @private The uninitialised Backend class\n                         */\n                        // Back compat\n\n                        if (_this.params.backend == 'AudioElement') {\n                            _this.params.backend = 'MediaElement';\n                        }\n\n                        if ((_this.params.backend == 'WebAudio' || _this.params.backend === 'MediaElementWebAudio') && !_webaudio.default.prototype.supportsWebAudio.call(null)) {\n                            _this.params.backend = 'MediaElement';\n                        }\n\n                        _this.Backend = _this.backends[_this.params.backend];\n                        /**\n                         * @private map of plugin names that are currently initialised\n                         */\n\n                        _this.initialisedPluginList = {};\n                        /** @private */\n\n                        _this.isDestroyed = false;\n                        /**\n                         * Get the current ready status.\n                         *\n                         * @example const isReady = wavesurfer.isReady;\n                         * @return {boolean}\n                         */\n\n                        _this.isReady = false; // responsive debounced event listener. If this.params.responsive is not\n                        // set, this is never called. Use 100ms or this.params.responsive as\n                        // timeout for the debounce function.\n\n                        var prevWidth = 0;\n                        _this._onResize = util.debounce(function () {\n                            if (prevWidth != _this.drawer.wrapper.clientWidth && !_this.params.scrollParent) {\n                                prevWidth = _this.drawer.wrapper.clientWidth;\n\n                                _this.drawer.fireEvent('redraw');\n                            }\n                        }, typeof _this.params.responsive === 'number' ? _this.params.responsive : 100);\n                        return _possibleConstructorReturn(_this, _assertThisInitialized(_this));\n                    }\n                    /**\n                     * Initialise the wave\n                     *\n                     * @example\n                     * var wavesurfer = new WaveSurfer(params);\n                     * wavesurfer.init();\n                     * @return {this} The wavesurfer instance\n                     */\n\n\n                    _createClass(WaveSurfer, [{\n                        key: \"init\",\n                        value: function init() {\n                            this.registerPlugins(this.params.plugins);\n                            this.createDrawer();\n                            this.createBackend();\n                            this.createPeakCache();\n                            return this;\n                        }\n                        /**\n                         * Add and initialise array of plugins (if `plugin.deferInit` is falsey),\n                         * this function is called in the init function of wavesurfer\n                         *\n                         * @param {PluginDefinition[]} plugins An array of plugin definitions\n                         * @emits {WaveSurfer#plugins-registered} Called with the array of plugin definitions\n                         * @return {this} The wavesurfer instance\n                         */\n\n                    }, {\n                        key: \"registerPlugins\",\n                        value: function registerPlugins(plugins) {\n                            var _this2 = this;\n\n                            // first instantiate all the plugins\n                            plugins.forEach(function (plugin) {\n                                return _this2.addPlugin(plugin);\n                            }); // now run the init functions\n\n                            plugins.forEach(function (plugin) {\n                                // call init function of the plugin if deferInit is falsey\n                                // in that case you would manually use initPlugins()\n                                if (!plugin.deferInit) {\n                                    _this2.initPlugin(plugin.name);\n                                }\n                            });\n                            this.fireEvent('plugins-registered', plugins);\n                            return this;\n                        }\n                        /**\n                         * Get a map of plugin names that are currently initialised\n                         *\n                         * @example wavesurfer.getPlugins();\n                         * @return {Object} Object with plugin names\n                         */\n\n                    }, {\n                        key: \"getActivePlugins\",\n                        value: function getActivePlugins() {\n                            return this.initialisedPluginList;\n                        }\n                        /**\n                         * Add a plugin object to wavesurfer\n                         *\n                         * @param {PluginDefinition} plugin A plugin definition\n                         * @emits {WaveSurfer#plugin-added} Called with the name of the plugin that was added\n                         * @example wavesurfer.addPlugin(WaveSurfer.minimap());\n                         * @return {this} The wavesurfer instance\n                         */\n\n                    }, {\n                        key: \"addPlugin\",\n                        value: function addPlugin(plugin) {\n                            var _this3 = this;\n\n                            if (!plugin.name) {\n                                throw new Error('Plugin does not have a name!');\n                            }\n\n                            if (!plugin.instance) {\n                                throw new Error(\"Plugin \".concat(plugin.name, \" does not have an instance property!\"));\n                            } // staticProps properties are applied to wavesurfer instance\n\n\n                            if (plugin.staticProps) {\n                                Object.keys(plugin.staticProps).forEach(function (pluginStaticProp) {\n                                    /**\n                                     * Properties defined in a plugin definition's `staticProps` property are added as\n                                     * staticProps properties of the WaveSurfer instance\n                                     */\n                                    _this3[pluginStaticProp] = plugin.staticProps[pluginStaticProp];\n                                });\n                            }\n\n                            var Instance = plugin.instance; // turn the plugin instance into an observer\n\n                            var observerPrototypeKeys = Object.getOwnPropertyNames(util.Observer.prototype);\n                            observerPrototypeKeys.forEach(function (key) {\n                                Instance.prototype[key] = util.Observer.prototype[key];\n                            });\n                            /**\n                             * Instantiated plugin classes are added as a property of the wavesurfer\n                             * instance\n                             * @type {Object}\n                             */\n\n                            this[plugin.name] = new Instance(plugin.params || {}, this);\n                            this.fireEvent('plugin-added', plugin.name);\n                            return this;\n                        }\n                        /**\n                         * Initialise a plugin\n                         *\n                         * @param {string} name A plugin name\n                         * @emits WaveSurfer#plugin-initialised\n                         * @example wavesurfer.initPlugin('minimap');\n                         * @return {this} The wavesurfer instance\n                         */\n\n                    }, {\n                        key: \"initPlugin\",\n                        value: function initPlugin(name) {\n                            if (!this[name]) {\n                                throw new Error(\"Plugin \".concat(name, \" has not been added yet!\"));\n                            }\n\n                            if (this.initialisedPluginList[name]) {\n                                // destroy any already initialised plugins\n                                this.destroyPlugin(name);\n                            }\n\n                            this[name].init();\n                            this.initialisedPluginList[name] = true;\n                            this.fireEvent('plugin-initialised', name);\n                            return this;\n                        }\n                        /**\n                         * Destroy a plugin\n                         *\n                         * @param {string} name A plugin name\n                         * @emits WaveSurfer#plugin-destroyed\n                         * @example wavesurfer.destroyPlugin('minimap');\n                         * @returns {this} The wavesurfer instance\n                         */\n\n                    }, {\n                        key: \"destroyPlugin\",\n                        value: function destroyPlugin(name) {\n                            if (!this[name]) {\n                                throw new Error(\"Plugin \".concat(name, \" has not been added yet and cannot be destroyed!\"));\n                            }\n\n                            if (!this.initialisedPluginList[name]) {\n                                throw new Error(\"Plugin \".concat(name, \" is not active and cannot be destroyed!\"));\n                            }\n\n                            if (typeof this[name].destroy !== 'function') {\n                                throw new Error(\"Plugin \".concat(name, \" does not have a destroy function!\"));\n                            }\n\n                            this[name].destroy();\n                            delete this.initialisedPluginList[name];\n                            this.fireEvent('plugin-destroyed', name);\n                            return this;\n                        }\n                        /**\n                         * Destroy all initialised plugins. Convenience function to use when\n                         * wavesurfer is removed\n                         *\n                         * @private\n                         */\n\n                    }, {\n                        key: \"destroyAllPlugins\",\n                        value: function destroyAllPlugins() {\n                            var _this4 = this;\n\n                            Object.keys(this.initialisedPluginList).forEach(function (name) {\n                                return _this4.destroyPlugin(name);\n                            });\n                        }\n                        /**\n                         * Create the drawer and draw the waveform\n                         *\n                         * @private\n                         * @emits WaveSurfer#drawer-created\n                         */\n\n                    }, {\n                        key: \"createDrawer\",\n                        value: function createDrawer() {\n                            var _this5 = this;\n\n                            this.drawer = new this.Drawer(this.container, this.params);\n                            this.drawer.init();\n                            this.fireEvent('drawer-created', this.drawer);\n\n                            if (this.params.responsive !== false) {\n                                window.addEventListener('resize', this._onResize, true);\n                                window.addEventListener('orientationchange', this._onResize, true);\n                            }\n\n                            this.drawer.on('redraw', function () {\n                                _this5.drawBuffer();\n\n                                _this5.drawer.progress(_this5.backend.getPlayedPercents());\n                            }); // Click-to-seek\n\n                            this.drawer.on('click', function (e, progress) {\n                                setTimeout(function () {\n                                    return _this5.seekTo(progress);\n                                }, 0);\n                            }); // Relay the scroll event from the drawer\n\n                            this.drawer.on('scroll', function (e) {\n                                if (_this5.params.partialRender) {\n                                    _this5.drawBuffer();\n                                }\n\n                                _this5.fireEvent('scroll', e);\n                            });\n                        }\n                        /**\n                         * Create the backend\n                         *\n                         * @private\n                         * @emits WaveSurfer#backend-created\n                         */\n\n                    }, {\n                        key: \"createBackend\",\n                        value: function createBackend() {\n                            var _this6 = this;\n\n                            if (this.backend) {\n                                this.backend.destroy();\n                            }\n\n                            this.backend = new this.Backend(this.params);\n                            this.backend.init();\n                            this.fireEvent('backend-created', this.backend);\n                            this.backend.on('finish', function () {\n                                _this6.drawer.progress(_this6.backend.getPlayedPercents());\n\n                                _this6.fireEvent('finish');\n                            });\n                            this.backend.on('play', function () {\n                                return _this6.fireEvent('play');\n                            });\n                            this.backend.on('pause', function () {\n                                return _this6.fireEvent('pause');\n                            });\n                            this.backend.on('audioprocess', function (time) {\n                                _this6.drawer.progress(_this6.backend.getPlayedPercents());\n\n                                _this6.fireEvent('audioprocess', time);\n                            }); // only needed for MediaElement and MediaElementWebAudio backend\n\n                            if (this.params.backend === 'MediaElement' || this.params.backend === 'MediaElementWebAudio') {\n                                this.backend.on('seek', function () {\n                                    _this6.drawer.progress(_this6.backend.getPlayedPercents());\n                                });\n                                this.backend.on('volume', function () {\n                                    var newVolume = _this6.getVolume();\n\n                                    _this6.fireEvent('volume', newVolume);\n\n                                    if (_this6.backend.isMuted !== _this6.isMuted) {\n                                        _this6.isMuted = _this6.backend.isMuted;\n\n                                        _this6.fireEvent('mute', _this6.isMuted);\n                                    }\n                                });\n                            }\n                        }\n                        /**\n                         * Create the peak cache\n                         *\n                         * @private\n                         */\n\n                    }, {\n                        key: \"createPeakCache\",\n                        value: function createPeakCache() {\n                            if (this.params.partialRender) {\n                                this.peakCache = new _peakcache.default();\n                            }\n                        }\n                        /**\n                         * Get the duration of the audio clip\n                         *\n                         * @example const duration = wavesurfer.getDuration();\n                         * @return {number} Duration in seconds\n                         */\n\n                    }, {\n                        key: \"getDuration\",\n                        value: function getDuration() {\n                            return this.backend.getDuration();\n                        }\n                        /**\n                         * Get the current playback position\n                         *\n                         * @example const currentTime = wavesurfer.getCurrentTime();\n                         * @return {number} Playback position in seconds\n                         */\n\n                    }, {\n                        key: \"getCurrentTime\",\n                        value: function getCurrentTime() {\n                            return this.backend.getCurrentTime();\n                        }\n                        /**\n                         * Set the current play time in seconds.\n                         *\n                         * @param {number} seconds A positive number in seconds. E.g. 10 means 10\n                         * seconds, 60 means 1 minute\n                         */\n\n                    }, {\n                        key: \"setCurrentTime\",\n                        value: function setCurrentTime(seconds) {\n                            if (seconds >= this.getDuration()) {\n                                this.seekTo(1);\n                            } else {\n                                this.seekTo(seconds / this.getDuration());\n                            }\n                        }\n                        /**\n                         * Starts playback from the current position. Optional start and end\n                         * measured in seconds can be used to set the range of audio to play.\n                         *\n                         * @param {?number} start Position to start at\n                         * @param {?number} end Position to end at\n                         * @emits WaveSurfer#interaction\n                         * @return {Promise} Result of the backend play method\n                         * @example\n                         * // play from second 1 to 5\n                         * wavesurfer.play(1, 5);\n                         */\n\n                    }, {\n                        key: \"play\",\n                        value: function play(start, end) {\n                            var _this7 = this;\n\n                            this.fireEvent('interaction', function () {\n                                return _this7.play(start, end);\n                            });\n                            return this.backend.play(start, end);\n                        }\n                        /**\n                         * Set a point in seconds for playback to stop at.\n                         *\n                         * @param {number} position Position (in seconds) to stop at\n                         * @version 3.3.0\n                         */\n\n                    }, {\n                        key: \"setPlayEnd\",\n                        value: function setPlayEnd(position) {\n                            this.backend.setPlayEnd(position);\n                        }\n                        /**\n                         * Stops and pauses playback\n                         *\n                         * @example wavesurfer.pause();\n                         * @return {Promise} Result of the backend pause method\n                         */\n\n                    }, {\n                        key: \"pause\",\n                        value: function pause() {\n                            if (!this.backend.isPaused()) {\n                                return this.backend.pause();\n                            }\n                        }\n                        /**\n                         * Toggle playback\n                         *\n                         * @example wavesurfer.playPause();\n                         * @return {Promise} Result of the backend play or pause method\n                         */\n\n                    }, {\n                        key: \"playPause\",\n                        value: function playPause() {\n                            return this.backend.isPaused() ? this.play() : this.pause();\n                        }\n                        /**\n                         * Get the current playback state\n                         *\n                         * @example const isPlaying = wavesurfer.isPlaying();\n                         * @return {boolean} False if paused, true if playing\n                         */\n\n                    }, {\n                        key: \"isPlaying\",\n                        value: function isPlaying() {\n                            return !this.backend.isPaused();\n                        }\n                        /**\n                         * Skip backward\n                         *\n                         * @param {?number} seconds Amount to skip back, if not specified `skipLength`\n                         * is used\n                         * @example wavesurfer.skipBackward();\n                         */\n\n                    }, {\n                        key: \"skipBackward\",\n                        value: function skipBackward(seconds) {\n                            this.skip(-seconds || -this.params.skipLength);\n                        }\n                        /**\n                         * Skip forward\n                         *\n                         * @param {?number} seconds Amount to skip back, if not specified `skipLength`\n                         * is used\n                         * @example wavesurfer.skipForward();\n                         */\n\n                    }, {\n                        key: \"skipForward\",\n                        value: function skipForward(seconds) {\n                            this.skip(seconds || this.params.skipLength);\n                        }\n                        /**\n                         * Skip a number of seconds from the current position (use a negative value\n                         * to go backwards).\n                         *\n                         * @param {number} offset Amount to skip back or forwards\n                         * @example\n                         * // go back 2 seconds\n                         * wavesurfer.skip(-2);\n                         */\n\n                    }, {\n                        key: \"skip\",\n                        value: function skip(offset) {\n                            var duration = this.getDuration() || 1;\n                            var position = this.getCurrentTime() || 0;\n                            position = Math.max(0, Math.min(duration, position + (offset || 0)));\n                            this.seekAndCenter(position / duration);\n                        }\n                        /**\n                         * Seeks to a position and centers the view\n                         *\n                         * @param {number} progress Between 0 (=beginning) and 1 (=end)\n                         * @example\n                         * // seek and go to the middle of the audio\n                         * wavesurfer.seekTo(0.5);\n                         */\n\n                    }, {\n                        key: \"seekAndCenter\",\n                        value: function seekAndCenter(progress) {\n                            this.seekTo(progress);\n                            this.drawer.recenter(progress);\n                        }\n                        /**\n                         * Seeks to a position\n                         *\n                         * @param {number} progress Between 0 (=beginning) and 1 (=end)\n                         * @emits WaveSurfer#interaction\n                         * @emits WaveSurfer#seek\n                         * @example\n                         * // seek to the middle of the audio\n                         * wavesurfer.seekTo(0.5);\n                         */\n\n                    }, {\n                        key: \"seekTo\",\n                        value: function seekTo(progress) {\n                            var _this8 = this;\n\n                            // return an error if progress is not a number between 0 and 1\n                            if (typeof progress !== 'number' || !isFinite(progress) || progress < 0 || progress > 1) {\n                                throw new Error('Error calling wavesurfer.seekTo, parameter must be a number between 0 and 1!');\n                            }\n\n                            this.fireEvent('interaction', function () {\n                                return _this8.seekTo(progress);\n                            });\n                            var paused = this.backend.isPaused(); // avoid draw wrong position while playing backward seeking\n\n                            if (!paused) {\n                                this.backend.pause();\n                            } // avoid small scrolls while paused seeking\n\n\n                            var oldScrollParent = this.params.scrollParent;\n                            this.params.scrollParent = false;\n                            this.backend.seekTo(progress * this.getDuration());\n                            this.drawer.progress(progress);\n\n                            if (!paused) {\n                                this.backend.play();\n                            }\n\n                            this.params.scrollParent = oldScrollParent;\n                            this.fireEvent('seek', progress);\n                        }\n                        /**\n                         * Stops and goes to the beginning.\n                         *\n                         * @example wavesurfer.stop();\n                         */\n\n                    }, {\n                        key: \"stop\",\n                        value: function stop() {\n                            this.pause();\n                            this.seekTo(0);\n                            this.drawer.progress(0);\n                        }\n                        /**\n                         * Sets the ID of the audio device to use for output and returns a Promise.\n                         *\n                         * @param {string} deviceId String value representing underlying output\n                         * device\n                         * @returns {Promise} `Promise` that resolves to `undefined` when there are\n                         * no errors detected.\n                         */\n\n                    }, {\n                        key: \"setSinkId\",\n                        value: function setSinkId(deviceId) {\n                            return this.backend.setSinkId(deviceId);\n                        }\n                        /**\n                         * Set the playback volume.\n                         *\n                         * @param {number} newVolume A value between 0 and 1, 0 being no\n                         * volume and 1 being full volume.\n                         * @emits WaveSurfer#volume\n                         */\n\n                    }, {\n                        key: \"setVolume\",\n                        value: function setVolume(newVolume) {\n                            this.backend.setVolume(newVolume);\n                            this.fireEvent('volume', newVolume);\n                        }\n                        /**\n                         * Get the playback volume.\n                         *\n                         * @return {number} A value between 0 and 1, 0 being no\n                         * volume and 1 being full volume.\n                         */\n\n                    }, {\n                        key: \"getVolume\",\n                        value: function getVolume() {\n                            return this.backend.getVolume();\n                        }\n                        /**\n                         * Set the playback rate.\n                         *\n                         * @param {number} rate A positive number. E.g. 0.5 means half the normal\n                         * speed, 2 means double speed and so on.\n                         * @example wavesurfer.setPlaybackRate(2);\n                         */\n\n                    }, {\n                        key: \"setPlaybackRate\",\n                        value: function setPlaybackRate(rate) {\n                            this.backend.setPlaybackRate(rate);\n                        }\n                        /**\n                         * Get the playback rate.\n                         *\n                         * @return {number} The current playback rate.\n                         */\n\n                    }, {\n                        key: \"getPlaybackRate\",\n                        value: function getPlaybackRate() {\n                            return this.backend.getPlaybackRate();\n                        }\n                        /**\n                         * Toggle the volume on and off. If not currently muted it will save the\n                         * current volume value and turn the volume off. If currently muted then it\n                         * will restore the volume to the saved value, and then rest the saved\n                         * value.\n                         *\n                         * @example wavesurfer.toggleMute();\n                         */\n\n                    }, {\n                        key: \"toggleMute\",\n                        value: function toggleMute() {\n                            this.setMute(!this.isMuted);\n                        }\n                        /**\n                         * Enable or disable muted audio\n                         *\n                         * @param {boolean} mute Specify `true` to mute audio.\n                         * @emits WaveSurfer#volume\n                         * @emits WaveSurfer#mute\n                         * @example\n                         * // unmute\n                         * wavesurfer.setMute(false);\n                         * console.log(wavesurfer.getMute()) // logs false\n                         */\n\n                    }, {\n                        key: \"setMute\",\n                        value: function setMute(mute) {\n                            // ignore all muting requests if the audio is already in that state\n                            if (mute === this.isMuted) {\n                                this.fireEvent('mute', this.isMuted);\n                                return;\n                            }\n\n                            if (mute) {\n                                // If currently not muted then save current volume,\n                                // turn off the volume and update the mute properties\n                                this.savedVolume = this.backend.getVolume();\n                                this.backend.setVolume(0);\n                                this.isMuted = true;\n                                this.fireEvent('volume', 0);\n                            } else {\n                                // If currently muted then restore to the saved volume\n                                // and update the mute properties\n                                this.backend.setVolume(this.savedVolume);\n                                this.isMuted = false;\n                                this.fireEvent('volume', this.savedVolume);\n                            }\n\n                            this.fireEvent('mute', this.isMuted);\n                        }\n                        /**\n                         * Get the current mute status.\n                         *\n                         * @example const isMuted = wavesurfer.getMute();\n                         * @return {boolean} Current mute status\n                         */\n\n                    }, {\n                        key: \"getMute\",\n                        value: function getMute() {\n                            return this.isMuted;\n                        }\n                        /**\n                         * Get the list of current set filters as an array.\n                         *\n                         * Filters must be set with setFilters method first\n                         *\n                         * @return {array} List of enabled filters\n                         */\n\n                    }, {\n                        key: \"getFilters\",\n                        value: function getFilters() {\n                            return this.backend.filters || [];\n                        }\n                        /**\n                         * Toggles `scrollParent` and redraws\n                         *\n                         * @example wavesurfer.toggleScroll();\n                         */\n\n                    }, {\n                        key: \"toggleScroll\",\n                        value: function toggleScroll() {\n                            this.params.scrollParent = !this.params.scrollParent;\n                            this.drawBuffer();\n                        }\n                        /**\n                         * Toggle mouse interaction\n                         *\n                         * @example wavesurfer.toggleInteraction();\n                         */\n\n                    }, {\n                        key: \"toggleInteraction\",\n                        value: function toggleInteraction() {\n                            this.params.interact = !this.params.interact;\n                        }\n                        /**\n                         * Get the fill color of the waveform after the cursor.\n                         *\n                         * @return {string} A CSS color string.\n                         */\n\n                    }, {\n                        key: \"getWaveColor\",\n                        value: function getWaveColor() {\n                            return this.params.waveColor;\n                        }\n                        /**\n                         * Set the fill color of the waveform after the cursor.\n                         *\n                         * @param {string} color A CSS color string.\n                         * @example wavesurfer.setWaveColor('#ddd');\n                         */\n\n                    }, {\n                        key: \"setWaveColor\",\n                        value: function setWaveColor(color) {\n                            this.params.waveColor = color;\n                            this.drawBuffer();\n                        }\n                        /**\n                         * Get the fill color of the waveform behind the cursor.\n                         *\n                         * @return {string} A CSS color string.\n                         */\n\n                    }, {\n                        key: \"getProgressColor\",\n                        value: function getProgressColor() {\n                            return this.params.progressColor;\n                        }\n                        /**\n                         * Set the fill color of the waveform behind the cursor.\n                         *\n                         * @param {string} color A CSS color string.\n                         * @example wavesurfer.setProgressColor('#400');\n                         */\n\n                    }, {\n                        key: \"setProgressColor\",\n                        value: function setProgressColor(color) {\n                            this.params.progressColor = color;\n                            this.drawBuffer();\n                        }\n                        /**\n                         * Get the background color of the waveform container.\n                         *\n                         * @return {string} A CSS color string.\n                         */\n\n                    }, {\n                        key: \"getBackgroundColor\",\n                        value: function getBackgroundColor() {\n                            return this.params.backgroundColor;\n                        }\n                        /**\n                         * Set the background color of the waveform container.\n                         *\n                         * @param {string} color A CSS color string.\n                         * @example wavesurfer.setBackgroundColor('#FF00FF');\n                         */\n\n                    }, {\n                        key: \"setBackgroundColor\",\n                        value: function setBackgroundColor(color) {\n                            this.params.backgroundColor = color;\n                            util.style(this.container, {\n                                background: this.params.backgroundColor\n                            });\n                        }\n                        /**\n                         * Get the fill color of the cursor indicating the playhead\n                         * position.\n                         *\n                         * @return {string} A CSS color string.\n                         */\n\n                    }, {\n                        key: \"getCursorColor\",\n                        value: function getCursorColor() {\n                            return this.params.cursorColor;\n                        }\n                        /**\n                         * Set the fill color of the cursor indicating the playhead\n                         * position.\n                         *\n                         * @param {string} color A CSS color string.\n                         * @example wavesurfer.setCursorColor('#222');\n                         */\n\n                    }, {\n                        key: \"setCursorColor\",\n                        value: function setCursorColor(color) {\n                            this.params.cursorColor = color;\n                            this.drawer.updateCursor();\n                        }\n                        /**\n                         * Get the height of the waveform.\n                         *\n                         * @return {number} Height measured in pixels.\n                         */\n\n                    }, {\n                        key: \"getHeight\",\n                        value: function getHeight() {\n                            return this.params.height;\n                        }\n                        /**\n                         * Set the height of the waveform.\n                         *\n                         * @param {number} height Height measured in pixels.\n                         * @example wavesurfer.setHeight(200);\n                         */\n\n                    }, {\n                        key: \"setHeight\",\n                        value: function setHeight(height) {\n                            this.params.height = height;\n                            this.drawer.setHeight(height * this.params.pixelRatio);\n                            this.drawBuffer();\n                        }\n                        /**\n                         * Get the correct peaks for current wave view-port and render wave\n                         *\n                         * @private\n                         * @emits WaveSurfer#redraw\n                         */\n\n                    }, {\n                        key: \"drawBuffer\",\n                        value: function drawBuffer() {\n                            var nominalWidth = Math.round(this.getDuration() * this.params.minPxPerSec * this.params.pixelRatio);\n                            var parentWidth = this.drawer.getWidth();\n                            var width = nominalWidth; // always start at 0 after zooming for scrolling : issue redraw left part\n\n                            var start = 0;\n                            var end = Math.max(start + parentWidth, width); // Fill container\n\n                            if (this.params.fillParent && (!this.params.scrollParent || nominalWidth < parentWidth)) {\n                                width = parentWidth;\n                                start = 0;\n                                end = width;\n                            }\n\n                            var peaks;\n\n                            if (this.params.partialRender) {\n                                var newRanges = this.peakCache.addRangeToPeakCache(width, start, end);\n                                var i;\n\n                                for (i = 0; i < newRanges.length; i++) {\n                                    peaks = this.backend.getPeaks(width, newRanges[i][0], newRanges[i][1]);\n                                    this.drawer.drawPeaks(peaks, width, newRanges[i][0], newRanges[i][1]);\n                                }\n                            } else {\n                                peaks = this.backend.getPeaks(width, start, end);\n                                this.drawer.drawPeaks(peaks, width, start, end);\n                            }\n\n                            this.fireEvent('redraw', peaks, width);\n                        }\n                        /**\n                         * Horizontally zooms the waveform in and out. It also changes the parameter\n                         * `minPxPerSec` and enables the `scrollParent` option. Calling the function\n                         * with a falsey parameter will reset the zoom state.\n                         *\n                         * @param {?number} pxPerSec Number of horizontal pixels per second of\n                         * audio, if none is set the waveform returns to unzoomed state\n                         * @emits WaveSurfer#zoom\n                         * @example wavesurfer.zoom(20);\n                         */\n\n                    }, {\n                        key: \"zoom\",\n                        value: function zoom(pxPerSec) {\n                            if (!pxPerSec) {\n                                this.params.minPxPerSec = this.defaultParams.minPxPerSec;\n                                this.params.scrollParent = false;\n                            } else {\n                                this.params.minPxPerSec = pxPerSec;\n                                this.params.scrollParent = true;\n                            }\n\n                            this.drawBuffer();\n                            this.drawer.progress(this.backend.getPlayedPercents());\n                            this.drawer.recenter(this.getCurrentTime() / this.getDuration());\n                            this.fireEvent('zoom', pxPerSec);\n                        }\n                        /**\n                         * Decode buffer and load\n                         *\n                         * @private\n                         * @param {ArrayBuffer} arraybuffer Buffer to process\n                         */\n\n                    }, {\n                        key: \"loadArrayBuffer\",\n                        value: function loadArrayBuffer(arraybuffer) {\n                            var _this9 = this;\n\n                            this.decodeArrayBuffer(arraybuffer, function (data) {\n                                if (!_this9.isDestroyed) {\n                                    _this9.loadDecodedBuffer(data);\n                                }\n                            });\n                        }\n                        /**\n                         * Directly load an externally decoded AudioBuffer\n                         *\n                         * @private\n                         * @param {AudioBuffer} buffer Buffer to process\n                         * @emits WaveSurfer#ready\n                         */\n\n                    }, {\n                        key: \"loadDecodedBuffer\",\n                        value: function loadDecodedBuffer(buffer) {\n                            this.backend.load(buffer);\n                            this.drawBuffer();\n                            this.isReady = true;\n                            this.fireEvent('ready');\n                        }\n                        /**\n                         * Loads audio data from a Blob or File object\n                         *\n                         * @param {Blob|File} blob Audio data\n                         * @example\n                         */\n\n                    }, {\n                        key: \"loadBlob\",\n                        value: function loadBlob(blob) {\n                            var _this10 = this;\n\n                            // Create file reader\n                            var reader = new FileReader();\n                            reader.addEventListener('progress', function (e) {\n                                return _this10.onProgress(e);\n                            });\n                            reader.addEventListener('load', function (e) {\n                                return _this10.loadArrayBuffer(e.target.result);\n                            });\n                            reader.addEventListener('error', function () {\n                                return _this10.fireEvent('error', 'Error reading file');\n                            });\n                            reader.readAsArrayBuffer(blob);\n                            this.empty();\n                        }\n                        /**\n                         * Loads audio and re-renders the waveform.\n                         *\n                         * @param {string|HTMLMediaElement} url The url of the audio file or the\n                         * audio element with the audio\n                         * @param {number[]|Number.<Array[]>} peaks Wavesurfer does not have to decode\n                         * the audio to render the waveform if this is specified\n                         * @param {?string} preload (Use with backend `MediaElement` and `MediaElementWebAudio`)\n                         * `'none'|'metadata'|'auto'` Preload attribute for the media element\n                         * @param {?number} duration The duration of the audio. This is used to\n                         * render the peaks data in the correct size for the audio duration (as\n                         * befits the current `minPxPerSec` and zoom value) without having to decode\n                         * the audio.\n                         * @returns {void}\n                         * @throws Will throw an error if the `url` argument is empty.\n                         * @example\n                         * // uses fetch or media element to load file (depending on backend)\n                         * wavesurfer.load('http://example.com/demo.wav');\n                         *\n                         * // setting preload attribute with media element backend and supplying\n                         * // peaks\n                         * wavesurfer.load(\n                         *   'http://example.com/demo.wav',\n                         *   [0.0218, 0.0183, 0.0165, 0.0198, 0.2137, 0.2888],\n                         *   true\n                         * );\n                         */\n\n                    }, {\n                        key: \"load\",\n                        value: function load(url, peaks, preload, duration) {\n                            if (!url) {\n                                throw new Error('url parameter cannot be empty');\n                            }\n\n                            this.empty();\n\n                            if (preload) {\n                                // check whether the preload attribute will be usable and if not log\n                                // a warning listing the reasons why not and nullify the variable\n                                var preloadIgnoreReasons = {\n                                    \"Preload is not 'auto', 'none' or 'metadata'\": ['auto', 'metadata', 'none'].indexOf(preload) === -1,\n                                    'Peaks are not provided': !peaks,\n                                    \"Backend is not of type 'MediaElement' or 'MediaElementWebAudio'\": ['MediaElement', 'MediaElementWebAudio'].indexOf(this.params.backend) === -1,\n                                    'Url is not of type string': typeof url !== 'string'\n                                };\n                                var activeReasons = Object.keys(preloadIgnoreReasons).filter(function (reason) {\n                                    return preloadIgnoreReasons[reason];\n                                });\n\n                                if (activeReasons.length) {\n                                    // eslint-disable-next-line no-console\n                                    console.warn('Preload parameter of wavesurfer.load will be ignored because:\\n\\t- ' + activeReasons.join('\\n\\t- ')); // stop invalid values from being used\n\n                                    preload = null;\n                                }\n                            }\n\n                            switch (this.params.backend) {\n                                case 'WebAudio':\n                                    return this.loadBuffer(url, peaks, duration);\n\n                                case 'MediaElement':\n                                case 'MediaElementWebAudio':\n                                    return this.loadMediaElement(url, peaks, preload, duration);\n                            }\n                        }\n                        /**\n                         * Loads audio using Web Audio buffer backend.\n                         *\n                         * @private\n                         * @param {string} url URL of audio file\n                         * @param {number[]|Number.<Array[]>} peaks Peaks data\n                         * @param {?number} duration Optional duration of audio file\n                         * @returns {void}\n                         */\n\n                    }, {\n                        key: \"loadBuffer\",\n                        value: function loadBuffer(url, peaks, duration) {\n                            var _this11 = this;\n\n                            var load = function load(action) {\n                                if (action) {\n                                    _this11.tmpEvents.push(_this11.once('ready', action));\n                                }\n\n                                return _this11.getArrayBuffer(url, function (data) {\n                                    return _this11.loadArrayBuffer(data);\n                                });\n                            };\n\n                            if (peaks) {\n                                this.backend.setPeaks(peaks, duration);\n                                this.drawBuffer();\n                                this.tmpEvents.push(this.once('interaction', load));\n                            } else {\n                                return load();\n                            }\n                        }\n                        /**\n                         * Either create a media element, or load an existing media element.\n                         *\n                         * @private\n                         * @param {string|HTMLMediaElement} urlOrElt Either a path to a media file, or an\n                         * existing HTML5 Audio/Video Element\n                         * @param {number[]|Number.<Array[]>} peaks Array of peaks. Required to bypass web audio\n                         * dependency\n                         * @param {?boolean} preload Set to true if the preload attribute of the\n                         * audio element should be enabled\n                         * @param {?number} duration Optional duration of audio file\n                         */\n\n                    }, {\n                        key: \"loadMediaElement\",\n                        value: function loadMediaElement(urlOrElt, peaks, preload, duration) {\n                            var _this12 = this;\n\n                            var url = urlOrElt;\n\n                            if (typeof urlOrElt === 'string') {\n                                this.backend.load(url, this.mediaContainer, peaks, preload);\n                            } else {\n                                var elt = urlOrElt;\n                                this.backend.loadElt(elt, peaks); // If peaks are not provided,\n                                // url = element.src so we can get peaks with web audio\n\n                                url = elt.src;\n                            }\n\n                            this.tmpEvents.push(this.backend.once('canplay', function () {\n                                // ignore when backend was already destroyed\n                                if (!_this12.backend.destroyed) {\n                                    _this12.drawBuffer();\n\n                                    _this12.isReady = true;\n\n                                    _this12.fireEvent('ready');\n                                }\n                            }), this.backend.once('error', function (err) {\n                                return _this12.fireEvent('error', err);\n                            })); // If no pre-decoded peaks provided or pre-decoded peaks are\n                            // provided with forceDecode flag, attempt to download the\n                            // audio file and decode it with Web Audio.\n\n                            if (peaks) {\n                                this.backend.setPeaks(peaks, duration);\n                            }\n\n                            if ((!peaks || this.params.forceDecode) && this.backend.supportsWebAudio()) {\n                                this.getArrayBuffer(url, function (arraybuffer) {\n                                    _this12.decodeArrayBuffer(arraybuffer, function (buffer) {\n                                        _this12.backend.buffer = buffer;\n\n                                        _this12.backend.setPeaks(null);\n\n                                        _this12.drawBuffer();\n\n                                        _this12.fireEvent('waveform-ready');\n                                    });\n                                });\n                            }\n                        }\n                        /**\n                         * Decode an array buffer and pass data to a callback\n                         *\n                         * @private\n                         * @param {Object} arraybuffer The array buffer to decode\n                         * @param {function} callback The function to call on complete\n                         */\n\n                    }, {\n                        key: \"decodeArrayBuffer\",\n                        value: function decodeArrayBuffer(arraybuffer, callback) {\n                            var _this13 = this;\n\n                            this.arraybuffer = arraybuffer;\n                            this.backend.decodeArrayBuffer(arraybuffer, function (data) {\n                                // Only use the decoded data if we haven't been destroyed or\n                                // another decode started in the meantime\n                                if (!_this13.isDestroyed && _this13.arraybuffer == arraybuffer) {\n                                    callback(data);\n                                    _this13.arraybuffer = null;\n                                }\n                            }, function () {\n                                return _this13.fireEvent('error', 'Error decoding audiobuffer');\n                            });\n                        }\n                        /**\n                         * Load an array buffer using fetch and pass the result to a callback\n                         *\n                         * @param {string} url The URL of the file object\n                         * @param {function} callback The function to call on complete\n                         * @returns {util.fetchFile} fetch call\n                         * @private\n                         */\n\n                    }, {\n                        key: \"getArrayBuffer\",\n                        value: function getArrayBuffer(url, callback) {\n                            var _this14 = this;\n\n                            var options = Object.assign({\n                                url: url,\n                                responseType: 'arraybuffer'\n                            }, this.params.xhr);\n                            var request = util.fetchFile(options);\n                            this.currentRequest = request;\n                            this.tmpEvents.push(request.on('progress', function (e) {\n                                _this14.onProgress(e);\n                            }), request.on('success', function (data) {\n                                callback(data);\n                                _this14.currentRequest = null;\n                            }), request.on('error', function (e) {\n                                _this14.fireEvent('error', e);\n\n                                _this14.currentRequest = null;\n                            }));\n                            return request;\n                        }\n                        /**\n                         * Called while the audio file is loading\n                         *\n                         * @private\n                         * @param {Event} e Progress event\n                         * @emits WaveSurfer#loading\n                         */\n\n                    }, {\n                        key: \"onProgress\",\n                        value: function onProgress(e) {\n                            var percentComplete;\n\n                            if (e.lengthComputable) {\n                                percentComplete = e.loaded / e.total;\n                            } else {\n                                // Approximate progress with an asymptotic\n                                // function, and assume downloads in the 1-3 MB range.\n                                percentComplete = e.loaded / (e.loaded + 1000000);\n                            }\n\n                            this.fireEvent('loading', Math.round(percentComplete * 100), e.target);\n                        }\n                        /**\n                         * Exports PCM data into a JSON array and opens in a new window.\n                         *\n                         * @param {number} length=1024 The scale in which to export the peaks\n                         * @param {number} accuracy=10000\n                         * @param {?boolean} noWindow Set to true to disable opening a new\n                         * window with the JSON\n                         * @param {number} start Start index\n                         * @param {number} end End index\n                         * @return {Promise} Promise that resolves with array of peaks\n                         */\n\n                    }, {\n                        key: \"exportPCM\",\n                        value: function exportPCM(length, accuracy, noWindow, start, end) {\n                            length = length || 1024;\n                            start = start || 0;\n                            accuracy = accuracy || 10000;\n                            noWindow = noWindow || false;\n                            var peaks = this.backend.getPeaks(length, start, end);\n                            var arr = [].map.call(peaks, function (val) {\n                                return Math.round(val * accuracy) / accuracy;\n                            });\n                            return new Promise(function (resolve, reject) {\n                                var json = JSON.stringify(arr);\n\n                                if (!noWindow) {\n                                    window.open('data:application/json;charset=utf-8,' + encodeURIComponent(json));\n                                }\n\n                                resolve(json);\n                            });\n                        }\n                        /**\n                         * Save waveform image as data URI.\n                         *\n                         * The default format is `'image/png'`. Other supported types are\n                         * `'image/jpeg'` and `'image/webp'`.\n                         *\n                         * @param {string} format='image/png' A string indicating the image format.\n                         * The default format type is `'image/png'`.\n                         * @param {number} quality=1 A number between 0 and 1 indicating the image\n                         * quality to use for image formats that use lossy compression such as\n                         * `'image/jpeg'`` and `'image/webp'`.\n                         * @param {string} type Image data type to return. Either 'dataURL' (default)\n                         * or 'blob'.\n                         * @return {string|string[]|Promise} When using `'dataURL'` type this returns\n                         * a single data URL or an array of data URLs, one for each canvas. When using\n                         * `'blob'` type this returns a `Promise` resolving with an array of `Blob`\n                         * instances, one for each canvas.\n                         */\n\n                    }, {\n                        key: \"exportImage\",\n                        value: function exportImage(format, quality, type) {\n                            if (!format) {\n                                format = 'image/png';\n                            }\n\n                            if (!quality) {\n                                quality = 1;\n                            }\n\n                            if (!type) {\n                                type = 'dataURL';\n                            }\n\n                            return this.drawer.getImage(format, quality, type);\n                        }\n                        /**\n                         * Cancel any fetch request currently in progress\n                         */\n\n                    }, {\n                        key: \"cancelAjax\",\n                        value: function cancelAjax() {\n                            if (this.currentRequest && this.currentRequest.controller) {\n                                this.currentRequest.controller.abort();\n                                this.currentRequest = null;\n                            }\n                        }\n                        /**\n                         * @private\n                         */\n\n                    }, {\n                        key: \"clearTmpEvents\",\n                        value: function clearTmpEvents() {\n                            this.tmpEvents.forEach(function (e) {\n                                return e.un();\n                            });\n                        }\n                        /**\n                         * Display empty waveform.\n                         */\n\n                    }, {\n                        key: \"empty\",\n                        value: function empty() {\n                            if (!this.backend.isPaused()) {\n                                this.stop();\n                                this.backend.disconnectSource();\n                            }\n\n                            this.isReady = false;\n                            this.cancelAjax();\n                            this.clearTmpEvents(); // empty drawer\n\n                            this.drawer.progress(0);\n                            this.drawer.setWidth(0);\n                            this.drawer.drawPeaks({\n                                length: this.drawer.getWidth()\n                            }, 0);\n                        }\n                        /**\n                         * Remove events, elements and disconnect WebAudio nodes.\n                         *\n                         * @emits WaveSurfer#destroy\n                         */\n\n                    }, {\n                        key: \"destroy\",\n                        value: function destroy() {\n                            this.destroyAllPlugins();\n                            this.fireEvent('destroy');\n                            this.cancelAjax();\n                            this.clearTmpEvents();\n                            this.unAll();\n\n                            if (this.params.responsive !== false) {\n                                window.removeEventListener('resize', this._onResize, true);\n                                window.removeEventListener('orientationchange', this._onResize, true);\n                            }\n\n                            if (this.backend) {\n                                this.backend.destroy();\n                            }\n\n                            if (this.drawer) {\n                                this.drawer.destroy();\n                            }\n\n                            this.isDestroyed = true;\n                            this.isReady = false;\n                            this.arraybuffer = null;\n                        }\n                    }]);\n\n                    return WaveSurfer;\n                }(util.Observer);\n\n            exports.default = WaveSurfer;\n            WaveSurfer.VERSION = \"3.3.3\";\n            WaveSurfer.util = util;\n            module.exports = exports.default;\n\n            /***/ }),\n\n        /***/ \"./src/webaudio.js\":\n        /*!*************************!*\\\n  !*** ./src/webaudio.js ***!\n  \\*************************/\n        /*! no static exports found */\n        /***/ (function(module, exports, __webpack_require__) {\n\n            \"use strict\";\n\n\n            Object.defineProperty(exports, \"__esModule\", {\n                value: true\n            });\n            exports.default = void 0;\n\n            var util = _interopRequireWildcard(__webpack_require__(/*! ./util */ \"./src/util/index.js\"));\n\n            function _getRequireWildcardCache() { if (typeof WeakMap !== \"function\") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }\n\n            function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== \"object\" && typeof obj !== \"function\") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }\n\n            function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n            function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n            function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n            function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\n            function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\n            function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n            function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\n            function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n            function _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\n            function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\n// using constants to prevent someone writing the string wrong\n            var PLAYING = 'playing';\n            var PAUSED = 'paused';\n            var FINISHED = 'finished';\n            /**\n             * WebAudio backend\n             *\n             * @extends {Observer}\n             */\n\n            var WebAudio =\n                /*#__PURE__*/\n                function (_util$Observer) {\n                    _inherits(WebAudio, _util$Observer);\n\n                    _createClass(WebAudio, [{\n                        key: \"supportsWebAudio\",\n\n                        /** scriptBufferSize: size of the processing buffer */\n\n                        /** audioContext: allows to process audio with WebAudio API */\n\n                        /** @private */\n\n                        /** @private */\n\n                        /**\n                         * Does the browser support this backend\n                         *\n                         * @return {boolean} Whether or not this browser supports this backend\n                         */\n                        value: function supportsWebAudio() {\n                            return !!(window.AudioContext || window.webkitAudioContext);\n                        }\n                        /**\n                         * Get the audio context used by this backend or create one\n                         *\n                         * @return {AudioContext} Existing audio context, or creates a new one\n                         */\n\n                    }, {\n                        key: \"getAudioContext\",\n                        value: function getAudioContext() {\n                            if (!window.WaveSurferAudioContext) {\n                                window.WaveSurferAudioContext = new (window.AudioContext || window.webkitAudioContext)();\n                            }\n\n                            return window.WaveSurferAudioContext;\n                        }\n                        /**\n                         * Get the offline audio context used by this backend or create one\n                         *\n                         * @param {number} sampleRate The sample rate to use\n                         * @return {OfflineAudioContext} Existing offline audio context, or creates\n                         * a new one\n                         */\n\n                    }, {\n                        key: \"getOfflineAudioContext\",\n                        value: function getOfflineAudioContext(sampleRate) {\n                            if (!window.WaveSurferOfflineAudioContext) {\n                                window.WaveSurferOfflineAudioContext = new (window.OfflineAudioContext || window.webkitOfflineAudioContext)(1, 2, sampleRate);\n                            }\n\n                            return window.WaveSurferOfflineAudioContext;\n                        }\n                        /**\n                         * Construct the backend\n                         *\n                         * @param {WavesurferParams} params Wavesurfer parameters\n                         */\n\n                    }]);\n\n                    function WebAudio(params) {\n                        var _this$stateBehaviors, _this$states;\n\n                        var _this;\n\n                        _classCallCheck(this, WebAudio);\n\n                        _this = _possibleConstructorReturn(this, _getPrototypeOf(WebAudio).call(this));\n                        /** @private */\n\n                        _this.audioContext = null;\n                        _this.offlineAudioContext = null;\n                        _this.stateBehaviors = (_this$stateBehaviors = {}, _defineProperty(_this$stateBehaviors, PLAYING, {\n                            init: function init() {\n                                this.addOnAudioProcess();\n                            },\n                            getPlayedPercents: function getPlayedPercents() {\n                                var duration = this.getDuration();\n                                return this.getCurrentTime() / duration || 0;\n                            },\n                            getCurrentTime: function getCurrentTime() {\n                                return this.startPosition + this.getPlayedTime();\n                            }\n                        }), _defineProperty(_this$stateBehaviors, PAUSED, {\n                            init: function init() {\n                                this.removeOnAudioProcess();\n                            },\n                            getPlayedPercents: function getPlayedPercents() {\n                                var duration = this.getDuration();\n                                return this.getCurrentTime() / duration || 0;\n                            },\n                            getCurrentTime: function getCurrentTime() {\n                                return this.startPosition;\n                            }\n                        }), _defineProperty(_this$stateBehaviors, FINISHED, {\n                            init: function init() {\n                                this.removeOnAudioProcess();\n                                this.fireEvent('finish');\n                            },\n                            getPlayedPercents: function getPlayedPercents() {\n                                return 1;\n                            },\n                            getCurrentTime: function getCurrentTime() {\n                                return this.getDuration();\n                            }\n                        }), _this$stateBehaviors);\n                        _this.params = params;\n                        /** ac: Audio Context instance */\n\n                        _this.ac = params.audioContext || (_this.supportsWebAudio() ? _this.getAudioContext() : {});\n                        /**@private */\n\n                        _this.lastPlay = _this.ac.currentTime;\n                        /** @private */\n\n                        _this.startPosition = 0;\n                        /** @private */\n\n                        _this.scheduledPause = null;\n                        /** @private */\n\n                        _this.states = (_this$states = {}, _defineProperty(_this$states, PLAYING, Object.create(_this.stateBehaviors[PLAYING])), _defineProperty(_this$states, PAUSED, Object.create(_this.stateBehaviors[PAUSED])), _defineProperty(_this$states, FINISHED, Object.create(_this.stateBehaviors[FINISHED])), _this$states);\n                        /** @private */\n\n                        _this.buffer = null;\n                        /** @private */\n\n                        _this.filters = [];\n                        /** gainNode: allows to control audio volume */\n\n                        _this.gainNode = null;\n                        /** @private */\n\n                        _this.mergedPeaks = null;\n                        /** @private */\n\n                        _this.offlineAc = null;\n                        /** @private */\n\n                        _this.peaks = null;\n                        /** @private */\n\n                        _this.playbackRate = 1;\n                        /** analyser: provides audio analysis information */\n\n                        _this.analyser = null;\n                        /** scriptNode: allows processing audio */\n\n                        _this.scriptNode = null;\n                        /** @private */\n\n                        _this.source = null;\n                        /** @private */\n\n                        _this.splitPeaks = [];\n                        /** @private */\n\n                        _this.state = null;\n                        /** @private */\n\n                        _this.explicitDuration = params.duration;\n                        /**\n                         * Boolean indicating if the backend was destroyed.\n                         */\n\n                        _this.destroyed = false;\n                        return _this;\n                    }\n                    /**\n                     * Initialise the backend, called in `wavesurfer.createBackend()`\n                     */\n\n\n                    _createClass(WebAudio, [{\n                        key: \"init\",\n                        value: function init() {\n                            this.createVolumeNode();\n                            this.createScriptNode();\n                            this.createAnalyserNode();\n                            this.setState(PAUSED);\n                            this.setPlaybackRate(this.params.audioRate);\n                            this.setLength(0);\n                        }\n                        /** @private */\n\n                    }, {\n                        key: \"disconnectFilters\",\n                        value: function disconnectFilters() {\n                            if (this.filters) {\n                                this.filters.forEach(function (filter) {\n                                    filter && filter.disconnect();\n                                });\n                                this.filters = null; // Reconnect direct path\n\n                                this.analyser.connect(this.gainNode);\n                            }\n                        }\n                        /**\n                         * @private\n                         *\n                         * @param {string} state The new state\n                         */\n\n                    }, {\n                        key: \"setState\",\n                        value: function setState(state) {\n                            if (this.state !== this.states[state]) {\n                                this.state = this.states[state];\n                                this.state.init.call(this);\n                            }\n                        }\n                        /**\n                         * Unpacked `setFilters()`\n                         *\n                         * @param {...AudioNode} filters One or more filters to set\n                         */\n\n                    }, {\n                        key: \"setFilter\",\n                        value: function setFilter() {\n                            for (var _len = arguments.length, filters = new Array(_len), _key = 0; _key < _len; _key++) {\n                                filters[_key] = arguments[_key];\n                            }\n\n                            this.setFilters(filters);\n                        }\n                        /**\n                         * Insert custom Web Audio nodes into the graph\n                         *\n                         * @param {AudioNode[]} filters Packed filters array\n                         * @example\n                         * const lowpass = wavesurfer.backend.ac.createBiquadFilter();\n                         * wavesurfer.backend.setFilter(lowpass);\n                         */\n\n                    }, {\n                        key: \"setFilters\",\n                        value: function setFilters(filters) {\n                            // Remove existing filters\n                            this.disconnectFilters(); // Insert filters if filter array not empty\n\n                            if (filters && filters.length) {\n                                this.filters = filters; // Disconnect direct path before inserting filters\n\n                                this.analyser.disconnect(); // Connect each filter in turn\n\n                                filters.reduce(function (prev, curr) {\n                                    prev.connect(curr);\n                                    return curr;\n                                }, this.analyser).connect(this.gainNode);\n                            }\n                        }\n                        /** Create ScriptProcessorNode to process audio */\n\n                    }, {\n                        key: \"createScriptNode\",\n                        value: function createScriptNode() {\n                            if (this.params.audioScriptProcessor) {\n                                this.scriptNode = this.params.audioScriptProcessor;\n                            } else {\n                                if (this.ac.createScriptProcessor) {\n                                    this.scriptNode = this.ac.createScriptProcessor(WebAudio.scriptBufferSize);\n                                } else {\n                                    this.scriptNode = this.ac.createJavaScriptNode(WebAudio.scriptBufferSize);\n                                }\n                            }\n\n                            this.scriptNode.connect(this.ac.destination);\n                        }\n                        /** @private */\n\n                    }, {\n                        key: \"addOnAudioProcess\",\n                        value: function addOnAudioProcess() {\n                            var _this2 = this;\n\n                            this.scriptNode.onaudioprocess = function () {\n                                var time = _this2.getCurrentTime();\n\n                                if (time >= _this2.getDuration()) {\n                                    _this2.setState(FINISHED);\n\n                                    _this2.fireEvent('pause');\n                                } else if (time >= _this2.scheduledPause) {\n                                    _this2.pause();\n                                } else if (_this2.state === _this2.states[PLAYING]) {\n                                    _this2.fireEvent('audioprocess', time);\n                                }\n                            };\n                        }\n                        /** @private */\n\n                    }, {\n                        key: \"removeOnAudioProcess\",\n                        value: function removeOnAudioProcess() {\n                            this.scriptNode.onaudioprocess = function () {};\n                        }\n                        /** Create analyser node to perform audio analysis */\n\n                    }, {\n                        key: \"createAnalyserNode\",\n                        value: function createAnalyserNode() {\n                            this.analyser = this.ac.createAnalyser();\n                            this.analyser.connect(this.gainNode);\n                        }\n                        /**\n                         * Create the gain node needed to control the playback volume.\n                         *\n                         */\n\n                    }, {\n                        key: \"createVolumeNode\",\n                        value: function createVolumeNode() {\n                            // Create gain node using the AudioContext\n                            if (this.ac.createGain) {\n                                this.gainNode = this.ac.createGain();\n                            } else {\n                                this.gainNode = this.ac.createGainNode();\n                            } // Add the gain node to the graph\n\n\n                            this.gainNode.connect(this.ac.destination);\n                        }\n                        /**\n                         * Set the sink id for the media player\n                         *\n                         * @param {string} deviceId String value representing audio device id.\n                         * @returns {Promise} A Promise that resolves to `undefined` when there\n                         * are no errors.\n                         */\n\n                    }, {\n                        key: \"setSinkId\",\n                        value: function setSinkId(deviceId) {\n                            if (deviceId) {\n                                /**\n                                 * The webaudio API doesn't currently support setting the device\n                                 * output. Here we create an HTMLAudioElement, connect the\n                                 * webaudio stream to that element and setSinkId there.\n                                 */\n                                var audio = new window.Audio();\n\n                                if (!audio.setSinkId) {\n                                    return Promise.reject(new Error('setSinkId is not supported in your browser'));\n                                }\n\n                                audio.autoplay = true;\n                                var dest = this.ac.createMediaStreamDestination();\n                                this.gainNode.disconnect();\n                                this.gainNode.connect(dest);\n                                audio.srcObject = dest.stream;\n                                return audio.setSinkId(deviceId);\n                            } else {\n                                return Promise.reject(new Error('Invalid deviceId: ' + deviceId));\n                            }\n                        }\n                        /**\n                         * Set the audio volume\n                         *\n                         * @param {number} value A floating point value between 0 and 1.\n                         */\n\n                    }, {\n                        key: \"setVolume\",\n                        value: function setVolume(value) {\n                            this.gainNode.gain.setValueAtTime(value, this.ac.currentTime);\n                        }\n                        /**\n                         * Get the current volume\n                         *\n                         * @return {number} value A floating point value between 0 and 1.\n                         */\n\n                    }, {\n                        key: \"getVolume\",\n                        value: function getVolume() {\n                            return this.gainNode.gain.value;\n                        }\n                        /**\n                         * Decode an array buffer and pass data to a callback\n                         *\n                         * @private\n                         * @param {ArrayBuffer} arraybuffer The array buffer to decode\n                         * @param {function} callback The function to call on complete.\n                         * @param {function} errback The function to call on error.\n                         */\n\n                    }, {\n                        key: \"decodeArrayBuffer\",\n                        value: function decodeArrayBuffer(arraybuffer, callback, errback) {\n                            if (!this.offlineAc) {\n                                this.offlineAc = this.getOfflineAudioContext(this.ac && this.ac.sampleRate ? this.ac.sampleRate : 44100);\n                            }\n\n                            this.offlineAc.decodeAudioData(arraybuffer, function (data) {\n                                return callback(data);\n                            }, errback);\n                        }\n                        /**\n                         * Set pre-decoded peaks\n                         *\n                         * @param {number[]|Number.<Array[]>} peaks Peaks data\n                         * @param {?number} duration Explicit duration\n                         */\n\n                    }, {\n                        key: \"setPeaks\",\n                        value: function setPeaks(peaks, duration) {\n                            if (duration != null) {\n                                this.explicitDuration = duration;\n                            }\n\n                            this.peaks = peaks;\n                        }\n                        /**\n                         * Set the rendered length (different from the length of the audio)\n                         *\n                         * @param {number} length The rendered length\n                         */\n\n                    }, {\n                        key: \"setLength\",\n                        value: function setLength(length) {\n                            // No resize, we can preserve the cached peaks.\n                            if (this.mergedPeaks && length == 2 * this.mergedPeaks.length - 1 + 2) {\n                                return;\n                            }\n\n                            this.splitPeaks = [];\n                            this.mergedPeaks = []; // Set the last element of the sparse array so the peak arrays are\n                            // appropriately sized for other calculations.\n\n                            var channels = this.buffer ? this.buffer.numberOfChannels : 1;\n                            var c;\n\n                            for (c = 0; c < channels; c++) {\n                                this.splitPeaks[c] = [];\n                                this.splitPeaks[c][2 * (length - 1)] = 0;\n                                this.splitPeaks[c][2 * (length - 1) + 1] = 0;\n                            }\n\n                            this.mergedPeaks[2 * (length - 1)] = 0;\n                            this.mergedPeaks[2 * (length - 1) + 1] = 0;\n                        }\n                        /**\n                         * Compute the max and min value of the waveform when broken into <length> subranges.\n                         *\n                         * @param {number} length How many subranges to break the waveform into.\n                         * @param {number} first First sample in the required range.\n                         * @param {number} last Last sample in the required range.\n                         * @return {number[]|Number.<Array[]>} Array of 2*<length> peaks or array of arrays of\n                         * peaks consisting of (max, min) values for each subrange.\n                         */\n\n                    }, {\n                        key: \"getPeaks\",\n                        value: function getPeaks(length, first, last) {\n                            if (this.peaks) {\n                                return this.peaks;\n                            }\n\n                            if (!this.buffer) {\n                                return [];\n                            }\n\n                            first = first || 0;\n                            last = last || length - 1;\n                            this.setLength(length);\n\n                            if (!this.buffer) {\n                                return this.params.splitChannels ? this.splitPeaks : this.mergedPeaks;\n                            }\n                            /**\n                             * The following snippet fixes a buffering data issue on the Safari\n                             * browser which returned undefined It creates the missing buffer based\n                             * on 1 channel, 4096 samples and the sampleRate from the current\n                             * webaudio context 4096 samples seemed to be the best fit for rendering\n                             * will review this code once a stable version of Safari TP is out\n                             */\n\n\n                            if (!this.buffer.length) {\n                                var newBuffer = this.createBuffer(1, 4096, this.sampleRate);\n                                this.buffer = newBuffer.buffer;\n                            }\n\n                            var sampleSize = this.buffer.length / length;\n                            var sampleStep = ~~(sampleSize / 10) || 1;\n                            var channels = this.buffer.numberOfChannels;\n                            var c;\n\n                            for (c = 0; c < channels; c++) {\n                                var peaks = this.splitPeaks[c];\n                                var chan = this.buffer.getChannelData(c);\n                                var i = void 0;\n\n                                for (i = first; i <= last; i++) {\n                                    var start = ~~(i * sampleSize);\n                                    var end = ~~(start + sampleSize);\n                                    var min = 0;\n                                    var max = 0;\n                                    var j = void 0;\n\n                                    for (j = start; j < end; j += sampleStep) {\n                                        var value = chan[j];\n\n                                        if (value > max) {\n                                            max = value;\n                                        }\n\n                                        if (value < min) {\n                                            min = value;\n                                        }\n                                    }\n\n                                    peaks[2 * i] = max;\n                                    peaks[2 * i + 1] = min;\n\n                                    if (c == 0 || max > this.mergedPeaks[2 * i]) {\n                                        this.mergedPeaks[2 * i] = max;\n                                    }\n\n                                    if (c == 0 || min < this.mergedPeaks[2 * i + 1]) {\n                                        this.mergedPeaks[2 * i + 1] = min;\n                                    }\n                                }\n                            }\n\n                            return this.params.splitChannels ? this.splitPeaks : this.mergedPeaks;\n                        }\n                        /**\n                         * Get the position from 0 to 1\n                         *\n                         * @return {number} Position\n                         */\n\n                    }, {\n                        key: \"getPlayedPercents\",\n                        value: function getPlayedPercents() {\n                            return this.state.getPlayedPercents.call(this);\n                        }\n                        /** @private */\n\n                    }, {\n                        key: \"disconnectSource\",\n                        value: function disconnectSource() {\n                            if (this.source) {\n                                this.source.disconnect();\n                            }\n                        }\n                        /**\n                         * This is called when wavesurfer is destroyed\n                         */\n\n                    }, {\n                        key: \"destroy\",\n                        value: function destroy() {\n                            if (!this.isPaused()) {\n                                this.pause();\n                            }\n\n                            this.unAll();\n                            this.buffer = null;\n                            this.destroyed = true;\n                            this.disconnectFilters();\n                            this.disconnectSource();\n                            this.gainNode.disconnect();\n                            this.scriptNode.disconnect();\n                            this.analyser.disconnect(); // close the audioContext if closeAudioContext option is set to true\n\n                            if (this.params.closeAudioContext) {\n                                // check if browser supports AudioContext.close()\n                                if (typeof this.ac.close === 'function' && this.ac.state != 'closed') {\n                                    this.ac.close();\n                                } // clear the reference to the audiocontext\n\n\n                                this.ac = null; // clear the actual audiocontext, either passed as param or the\n                                // global singleton\n\n                                if (!this.params.audioContext) {\n                                    window.WaveSurferAudioContext = null;\n                                } else {\n                                    this.params.audioContext = null;\n                                } // clear the offlineAudioContext\n\n\n                                window.WaveSurferOfflineAudioContext = null;\n                            }\n                        }\n                        /**\n                         * Loaded a decoded audio buffer\n                         *\n                         * @param {Object} buffer Decoded audio buffer to load\n                         */\n\n                    }, {\n                        key: \"load\",\n                        value: function load(buffer) {\n                            this.startPosition = 0;\n                            this.lastPlay = this.ac.currentTime;\n                            this.buffer = buffer;\n                            this.createSource();\n                        }\n                        /** @private */\n\n                    }, {\n                        key: \"createSource\",\n                        value: function createSource() {\n                            this.disconnectSource();\n                            this.source = this.ac.createBufferSource(); // adjust for old browsers\n\n                            this.source.start = this.source.start || this.source.noteGrainOn;\n                            this.source.stop = this.source.stop || this.source.noteOff;\n                            this.source.playbackRate.setValueAtTime(this.playbackRate, this.ac.currentTime);\n                            this.source.buffer = this.buffer;\n                            this.source.connect(this.analyser);\n                        }\n                        /**\n                         * Used by `wavesurfer.isPlaying()` and `wavesurfer.playPause()`\n                         *\n                         * @return {boolean} Whether or not this backend is currently paused\n                         */\n\n                    }, {\n                        key: \"isPaused\",\n                        value: function isPaused() {\n                            return this.state !== this.states[PLAYING];\n                        }\n                        /**\n                         * Used by `wavesurfer.getDuration()`\n                         *\n                         * @return {number} Duration of loaded buffer\n                         */\n\n                    }, {\n                        key: \"getDuration\",\n                        value: function getDuration() {\n                            if (this.explicitDuration) {\n                                return this.explicitDuration;\n                            }\n\n                            if (!this.buffer) {\n                                return 0;\n                            }\n\n                            return this.buffer.duration;\n                        }\n                        /**\n                         * Used by `wavesurfer.seekTo()`\n                         *\n                         * @param {number} start Position to start at in seconds\n                         * @param {number} end Position to end at in seconds\n                         * @return {{start: number, end: number}} Object containing start and end\n                         * positions\n                         */\n\n                    }, {\n                        key: \"seekTo\",\n                        value: function seekTo(start, end) {\n                            if (!this.buffer) {\n                                return;\n                            }\n\n                            this.scheduledPause = null;\n\n                            if (start == null) {\n                                start = this.getCurrentTime();\n\n                                if (start >= this.getDuration()) {\n                                    start = 0;\n                                }\n                            }\n\n                            if (end == null) {\n                                end = this.getDuration();\n                            }\n\n                            this.startPosition = start;\n                            this.lastPlay = this.ac.currentTime;\n\n                            if (this.state === this.states[FINISHED]) {\n                                this.setState(PAUSED);\n                            }\n\n                            return {\n                                start: start,\n                                end: end\n                            };\n                        }\n                        /**\n                         * Get the playback position in seconds\n                         *\n                         * @return {number} The playback position in seconds\n                         */\n\n                    }, {\n                        key: \"getPlayedTime\",\n                        value: function getPlayedTime() {\n                            return (this.ac.currentTime - this.lastPlay) * this.playbackRate;\n                        }\n                        /**\n                         * Plays the loaded audio region.\n                         *\n                         * @param {number} start Start offset in seconds, relative to the beginning\n                         * of a clip.\n                         * @param {number} end When to stop relative to the beginning of a clip.\n                         */\n\n                    }, {\n                        key: \"play\",\n                        value: function play(start, end) {\n                            if (!this.buffer) {\n                                return;\n                            } // need to re-create source on each playback\n\n\n                            this.createSource();\n                            var adjustedTime = this.seekTo(start, end);\n                            start = adjustedTime.start;\n                            end = adjustedTime.end;\n                            this.scheduledPause = end;\n                            this.source.start(0, start);\n\n                            if (this.ac.state == 'suspended') {\n                                this.ac.resume && this.ac.resume();\n                            }\n\n                            this.setState(PLAYING);\n                            this.fireEvent('play');\n                        }\n                        /**\n                         * Pauses the loaded audio.\n                         */\n\n                    }, {\n                        key: \"pause\",\n                        value: function pause() {\n                            this.scheduledPause = null;\n                            this.startPosition += this.getPlayedTime();\n                            this.source && this.source.stop(0);\n                            this.setState(PAUSED);\n                            this.fireEvent('pause');\n                        }\n                        /**\n                         * Returns the current time in seconds relative to the audio-clip's\n                         * duration.\n                         *\n                         * @return {number} The current time in seconds\n                         */\n\n                    }, {\n                        key: \"getCurrentTime\",\n                        value: function getCurrentTime() {\n                            return this.state.getCurrentTime.call(this);\n                        }\n                        /**\n                         * Returns the current playback rate. (0=no playback, 1=normal playback)\n                         *\n                         * @return {number} The current playback rate\n                         */\n\n                    }, {\n                        key: \"getPlaybackRate\",\n                        value: function getPlaybackRate() {\n                            return this.playbackRate;\n                        }\n                        /**\n                         * Set the audio source playback rate.\n                         *\n                         * @param {number} value The playback rate to use\n                         */\n\n                    }, {\n                        key: \"setPlaybackRate\",\n                        value: function setPlaybackRate(value) {\n                            value = value || 1;\n\n                            if (this.isPaused()) {\n                                this.playbackRate = value;\n                            } else {\n                                this.pause();\n                                this.playbackRate = value;\n                                this.play();\n                            }\n                        }\n                        /**\n                         * Set a point in seconds for playback to stop at.\n                         *\n                         * @param {number} end Position to end at\n                         * @version 3.3.0\n                         */\n\n                    }, {\n                        key: \"setPlayEnd\",\n                        value: function setPlayEnd(end) {\n                            this.scheduledPause = end;\n                        }\n                    }]);\n\n                    return WebAudio;\n                }(util.Observer);\n\n            exports.default = WebAudio;\n            WebAudio.scriptBufferSize = 256;\n            module.exports = exports.default;\n\n            /***/ })\n\n        /******/ });\n});\n//# sourceMappingURL=wavesurfer.js.map"],"names":["root","factory","window","modules","installedModules","__webpack_require__","moduleId","exports","module","i","l","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","debounce","func","wait","immediate","timeout","args","context","timestamp","result","later","last","Date","now","setTimeout","apply","debounced","this","arguments","callNow","clear","clearTimeout","flush","default","_style","_interopRequireDefault","_getId","obj","_defineProperties","target","props","length","descriptor","configurable","writable","CanvasEntry","instance","Constructor","TypeError","_classCallCheck","wave","waveCtx","progress","progressCtx","start","end","id","constructor","toLowerCase","canvasContextAttributes","protoProps","staticProps","element","getContext","elementWidth","totalWidth","width","height","offsetLeft","elementSize","hasProgressCanvas","clearRect","canvas","waveColor","progressColor","fillStyle","x","y","radius","fillRectToContext","ctx","drawRoundedRect","fillRect","beginPath","moveTo","lineTo","quadraticCurveTo","closePath","fill","peaks","absmax","halfH","offsetY","drawLineToContext","peak","h","first","Math","round","canvasStart","canvasEnd","scale","halfOffset","absmaxHalf","halfPixel","j","format","quality","type","_this","Promise","resolve","toBlob","toDataURL","util","_typeof","cache","_getRequireWildcardCache","has","newObj","hasPropertyDescriptor","getOwnPropertyDescriptor","desc","set","_interopRequireWildcard","WeakMap","iterator","_possibleConstructorReturn","self","ReferenceError","_assertThisInitialized","_getPrototypeOf","setPrototypeOf","getPrototypeOf","__proto__","_setPrototypeOf","Drawer","_util$Observer","container","params","pixelRatio","lastPos","wrapper","subClass","superClass","_inherits","el","styles","style","appendChild","document","createElement","display","position","userSelect","webkitUserSelect","fillParent","scrollParent","overflowX","hideScrollbar","overflowY","setupWrapperEvents","e","noPrevent","preventDefault","clientX","targetTouches","bbox","getBoundingClientRect","nominalWidth","parentWidth","getWidth","rtl","right","left","scrollLeft","scrollWidth","_this2","addEventListener","scrollbarHeight","offsetHeight","clientHeight","clientY","bottom","interact","fireEvent","handleEvent","setWidth","clearWave","barWidth","drawBars","drawWave","percent","recenterOnPosition","half","clientWidth","maxScroll","offset","rate","autoCenterRate","max","min","updateSize","_progress","minPxDelta","pos","autoCenter","newPos","autoCenterImmediately","updateProgress","unAll","parentNode","removeChild","channelIndex","Observer","_drawer","_drawer2","MultiCanvas","_Drawer","maxCanvasWidth","maxCanvasElementWidth","canvases","progressWave","EntryClass","drawingContextAttributes","overlap","ceil","barRadius","createWrapper","createElements","zIndex","top","overflow","boxSizing","borderRightStyle","pointerEvents","addCanvas","updateCursor","borderRightWidth","cursorWidth","borderRightColor","cursorColor","requiredCanvases","removeCanvas","canvasWidth","lastCanvas","forEach","entry","updateDimensions","leftOffset","initWave","initProgress","push","lastEntry","parentElement","destroy","pop","_this3","frame","_this4","prepareDraw","_ref","hasMinVals","undefined","peakIndexScale","bar","step","barGap","floor","barMinHeight","_this5","_ref2","reflectedPeaks","len","drawLine","_this6","setFillStyles","drawLines","startCanvas","endCanvas","intersection","x1","y1","x2","y2","fillRects","fn","_this7","Array","channels","splitChannels","setHeight","channelPeaks","barHeight","normalize","some","val","all","map","getImage","images","_get","receiver","Reflect","base","_superPropBase","MediaElementWebAudio","_MediaElement","sourceMediaElement","setPlaybackRate","audioRate","createTimer","createVolumeNode","createScriptNode","createAnalyserNode","media","createMediaElementSource","mediaElement","ac","connect","analyser","_webaudio","MediaElement","_WebAudio","currentTime","duration","paused","playbackRate","play","pause","volume","mediaType","elementPosition","isMuted","buffer","onPlayEnd","mediaListeners","error","canplay","ended","seeked","event","volumechange","muted","keys","removeEventListener","on","onAudioProcess","isPaused","getCurrentTime","url","preload","controls","mediaControls","autoplay","src","prevMedia","querySelector","_load","elt","HTMLMediaElement","Error","load","_setupMediaListeners","setVolume","explicitDuration","Infinity","seekable","getDuration","clearPlayEnd","seekTo","promise","setPlayEnd","_onPlayEnd","time","un","deviceId","setSinkId","reject","destroyed","removeMediaElementOnDestroy","PeakCache","clearPeakCache","peakCacheRanges","peakCacheLength","uncachedRanges","filter","item","arr","concat","sort","a","b","uncachedRangePairs","peakCacheRangePairs","options","_observer","xhr","XMLHttpRequest","fired100","open","method","responseType","requestHeaders","header","setRequestHeader","withCredentials","lengthComputable","loaded","total","status","response","send","dest","console","warn","_len","sources","_key","source","fetchHeaders","Headers","fetchRequest","Request","controller","AbortController","append","fetchOptions","headers","credentials","redirect","referrer","signal","fetch","then","progressAvailable","body","contentLength","onProgress","Response","ReadableStream","ProgressHandler","errMsg","ok","arrayBuffer","json","blob","text","catch","_reader","getReader","parseInt","read","done","close","byteLength","enqueue","_requestAnimationFrame","prefix","random","toString","substring","_ajax","_max","_min","_extend","_frame","_debounce","_preventClick","_fetch","values","largest","smallest","Number","handlers","callback","splice","handler","_len2","_key2","preventClickHandler","stopPropagation","_default","requestAnimationFrame","webkitRequestAnimationFrame","mozRequestAnimationFrame","oRequestAnimationFrame","msRequestAnimationFrame","prop","_mediaelement","_peakcache","_mediaelementWebaudio","_createClass","PluginClass","ws","WaveSurfer","defaultParams","audioContext","audioScriptProcessor","backend","backgroundColor","dragSelection","desynchronized","forceDecode","loopSelection","mediaContainer","minPxPerSec","partialRender","devicePixelRatio","screen","deviceXDPI","logicalXDPI","plugins","renderer","responsive","skipLength","backends","WebAudio","assign","transform","setBackgroundColor","savedVolume","tmpEvents","currentRequest","arraybuffer","drawer","peakCache","supportsWebAudio","Backend","initialisedPluginList","isDestroyed","isReady","prevWidth","_onResize","init","registerPlugins","createDrawer","createBackend","createPeakCache","plugin","addPlugin","deferInit","initPlugin","pluginStaticProp","Instance","getOwnPropertyNames","destroyPlugin","drawBuffer","getPlayedPercents","newVolume","getVolume","seconds","skip","seekAndCenter","recenter","_this8","isFinite","oldScrollParent","getPlaybackRate","setMute","mute","filters","color","background","newRanges","addRangeToPeakCache","getPeaks","drawPeaks","pxPerSec","_this9","decodeArrayBuffer","data","loadDecodedBuffer","_this10","reader","FileReader","loadArrayBuffer","readAsArrayBuffer","empty","preloadIgnoreReasons","indexOf","activeReasons","reason","join","loadBuffer","loadMediaElement","_this11","action","once","getArrayBuffer","setPeaks","urlOrElt","_this12","loadElt","err","_this13","_this14","request","fetchFile","percentComplete","accuracy","noWindow","JSON","stringify","encodeURIComponent","abort","stop","disconnectSource","cancelAjax","clearTmpEvents","destroyAllPlugins","VERSION","_defineProperty","_this$stateBehaviors","_this$states","offlineAudioContext","stateBehaviors","addOnAudioProcess","startPosition","getPlayedTime","removeOnAudioProcess","getAudioContext","lastPlay","scheduledPause","states","gainNode","mergedPeaks","offlineAc","scriptNode","splitPeaks","state","AudioContext","webkitAudioContext","WaveSurferAudioContext","sampleRate","WaveSurferOfflineAudioContext","OfflineAudioContext","webkitOfflineAudioContext","setState","setLength","disconnect","setFilters","disconnectFilters","reduce","prev","curr","createScriptProcessor","scriptBufferSize","createJavaScriptNode","destination","onaudioprocess","createAnalyser","createGain","createGainNode","audio","Audio","createMediaStreamDestination","srcObject","stream","gain","setValueAtTime","errback","getOfflineAudioContext","decodeAudioData","numberOfChannels","newBuffer","createBuffer","sampleSize","sampleStep","chan","getChannelData","closeAudioContext","createSource","createBufferSource","noteGrainOn","noteOff","adjustedTime","resume","define","amd"],"mappings":"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"}