diff --git "a/lib/wavesurfer.js" "b/lib/wavesurfer.js" new file mode 100644--- /dev/null +++ "b/lib/wavesurfer.js" @@ -0,0 +1,6469 @@ +/*! + * wavesurfer.js 5.1.0 (2021-06-20) + * https://wavesurfer-js.org + * @license BSD-3-Clause + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define("WaveSurfer", [], factory); + else if(typeof exports === 'object') + exports["WaveSurfer"] = factory(); + else + root["WaveSurfer"] = factory(); +})(this, function() { +return /******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ "./src/drawer.canvasentry.js": +/*!***********************************!*\ + !*** ./src/drawer.canvasentry.js ***! + \***********************************/ +/***/ ((module, exports, __webpack_require__) => { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.default = void 0; + +var _style = _interopRequireDefault(__webpack_require__(/*! ./util/style */ "./src/util/style.js")); + +var _getId = _interopRequireDefault(__webpack_require__(/*! ./util/get-id */ "./src/util/get-id.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +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); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +/** + * The `CanvasEntry` class represents an element consisting of a wave `canvas` + * and an (optional) progress wave `canvas`. + * + * The `MultiCanvas` renderer uses one or more `CanvasEntry` instances to + * render a waveform, depending on the zoom level. + */ +var CanvasEntry = /*#__PURE__*/function () { + function CanvasEntry() { + _classCallCheck(this, CanvasEntry); + + /** + * The wave node + * + * @type {HTMLCanvasElement} + */ + this.wave = null; + /** + * The wave canvas rendering context + * + * @type {CanvasRenderingContext2D} + */ + + this.waveCtx = null; + /** + * The (optional) progress wave node + * + * @type {HTMLCanvasElement} + */ + + this.progress = null; + /** + * The (optional) progress wave canvas rendering context + * + * @type {CanvasRenderingContext2D} + */ + + this.progressCtx = null; + /** + * Start of the area the canvas should render, between 0 and 1 + * + * @type {number} + */ + + this.start = 0; + /** + * End of the area the canvas should render, between 0 and 1 + * + * @type {number} + */ + + this.end = 1; + /** + * Unique identifier for this entry + * + * @type {string} + */ + + this.id = (0, _getId.default)(typeof this.constructor.name !== 'undefined' ? this.constructor.name.toLowerCase() + '_' : 'canvasentry_'); + /** + * Canvas 2d context attributes + * + * @type {object} + */ + + this.canvasContextAttributes = {}; + } + /** + * Store the wave canvas element and create the 2D rendering context + * + * @param {HTMLCanvasElement} element The wave `canvas` element. + */ + + + _createClass(CanvasEntry, [{ + key: "initWave", + value: function initWave(element) { + this.wave = element; + this.waveCtx = this.wave.getContext('2d', this.canvasContextAttributes); + } + /** + * Store the progress wave canvas element and create the 2D rendering + * context + * + * @param {HTMLCanvasElement} element The progress wave `canvas` element. + */ + + }, { + key: "initProgress", + value: function initProgress(element) { + this.progress = element; + this.progressCtx = this.progress.getContext('2d', this.canvasContextAttributes); + } + /** + * Update the dimensions + * + * @param {number} elementWidth Width of the entry + * @param {number} totalWidth Total width of the multi canvas renderer + * @param {number} width The new width of the element + * @param {number} height The new height of the element + */ + + }, { + key: "updateDimensions", + value: function updateDimensions(elementWidth, totalWidth, width, height) { + // where the canvas starts and ends in the waveform, represented as a + // decimal between 0 and 1 + this.start = this.wave.offsetLeft / totalWidth || 0; + this.end = this.start + elementWidth / totalWidth; // set wave canvas dimensions + + this.wave.width = width; + this.wave.height = height; + var elementSize = { + width: elementWidth + 'px' + }; + (0, _style.default)(this.wave, elementSize); + + if (this.hasProgressCanvas) { + // set progress canvas dimensions + this.progress.width = width; + this.progress.height = height; + (0, _style.default)(this.progress, elementSize); + } + } + /** + * Clear the wave and progress rendering contexts + */ + + }, { + key: "clearWave", + value: function clearWave() { + // wave + this.waveCtx.clearRect(0, 0, this.waveCtx.canvas.width, this.waveCtx.canvas.height); // progress + + if (this.hasProgressCanvas) { + this.progressCtx.clearRect(0, 0, this.progressCtx.canvas.width, this.progressCtx.canvas.height); + } + } + /** + * Set the fill styles for wave and progress + * + * @param {string} waveColor Fill color for the wave canvas + * @param {?string} progressColor Fill color for the progress canvas + */ + + }, { + key: "setFillStyles", + value: function setFillStyles(waveColor, progressColor) { + this.waveCtx.fillStyle = waveColor; + + if (this.hasProgressCanvas) { + this.progressCtx.fillStyle = progressColor; + } + } + /** + * Set the canvas transforms for wave and progress + * + * @param {boolean} vertical Whether to render vertically + */ + + }, { + key: "applyCanvasTransforms", + value: function applyCanvasTransforms(vertical) { + if (vertical) { + // Reflect the waveform across the line y = -x + this.waveCtx.setTransform(0, 1, 1, 0, 0, 0); + + if (this.hasProgressCanvas) { + this.progressCtx.setTransform(0, 1, 1, 0, 0, 0); + } + } + } + /** + * Draw a rectangle for wave and progress + * + * @param {number} x X start position + * @param {number} y Y start position + * @param {number} width Width of the rectangle + * @param {number} height Height of the rectangle + * @param {number} radius Radius of the rectangle + */ + + }, { + key: "fillRects", + value: function fillRects(x, y, width, height, radius) { + this.fillRectToContext(this.waveCtx, x, y, width, height, radius); + + if (this.hasProgressCanvas) { + this.fillRectToContext(this.progressCtx, x, y, width, height, radius); + } + } + /** + * Draw the actual rectangle on a `canvas` element + * + * @param {CanvasRenderingContext2D} ctx Rendering context of target canvas + * @param {number} x X start position + * @param {number} y Y start position + * @param {number} width Width of the rectangle + * @param {number} height Height of the rectangle + * @param {number} radius Radius of the rectangle + */ + + }, { + key: "fillRectToContext", + value: function fillRectToContext(ctx, x, y, width, height, radius) { + if (!ctx) { + return; + } + + if (radius) { + this.drawRoundedRect(ctx, x, y, width, height, radius); + } else { + ctx.fillRect(x, y, width, height); + } + } + /** + * Draw a rounded rectangle on Canvas + * + * @param {CanvasRenderingContext2D} ctx Canvas context + * @param {number} x X-position of the rectangle + * @param {number} y Y-position of the rectangle + * @param {number} width Width of the rectangle + * @param {number} height Height of the rectangle + * @param {number} radius Radius of the rectangle + * + * @return {void} + * @example drawRoundedRect(ctx, 50, 50, 5, 10, 3) + */ + + }, { + key: "drawRoundedRect", + value: function drawRoundedRect(ctx, x, y, width, height, radius) { + if (height === 0) { + return; + } // peaks are float values from -1 to 1. Use absolute height values in + // order to correctly calculate rounded rectangle coordinates + + + if (height < 0) { + height *= -1; + y -= height; + } + + ctx.beginPath(); + ctx.moveTo(x + radius, y); + ctx.lineTo(x + width - radius, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + radius); + ctx.lineTo(x + width, y + height - radius); + ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); + ctx.lineTo(x + radius, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - radius); + ctx.lineTo(x, y + radius); + ctx.quadraticCurveTo(x, y, x + radius, y); + ctx.closePath(); + ctx.fill(); + } + /** + * Render the actual wave and progress lines + * + * @param {number[]} peaks Array with peaks data + * @param {number} absmax Maximum peak value (absolute) + * @param {number} halfH Half the height of the waveform + * @param {number} offsetY Offset to the top + * @param {number} start The x-offset of the beginning of the area that + * should be rendered + * @param {number} end The x-offset of the end of the area that + * should be rendered + */ + + }, { + key: "drawLines", + value: function drawLines(peaks, absmax, halfH, offsetY, start, end) { + this.drawLineToContext(this.waveCtx, peaks, absmax, halfH, offsetY, start, end); + + if (this.hasProgressCanvas) { + this.drawLineToContext(this.progressCtx, peaks, absmax, halfH, offsetY, start, end); + } + } + /** + * Render the actual waveform line on a `canvas` element + * + * @param {CanvasRenderingContext2D} ctx Rendering context of target canvas + * @param {number[]} peaks Array with peaks data + * @param {number} absmax Maximum peak value (absolute) + * @param {number} halfH Half the height of the waveform + * @param {number} offsetY Offset to the top + * @param {number} start The x-offset of the beginning of the area that + * should be rendered + * @param {number} end The x-offset of the end of the area that + * should be rendered + */ + + }, { + key: "drawLineToContext", + value: function drawLineToContext(ctx, peaks, absmax, halfH, offsetY, start, end) { + if (!ctx) { + return; + } + + var length = peaks.length / 2; + var first = Math.round(length * this.start); // use one more peak value to make sure we join peaks at ends -- unless, + // of course, this is the last canvas + + var last = Math.round(length * this.end) + 1; + var canvasStart = first; + var canvasEnd = last; + var scale = this.wave.width / (canvasEnd - canvasStart - 1); // optimization + + var halfOffset = halfH + offsetY; + var absmaxHalf = absmax / halfH; + ctx.beginPath(); + ctx.moveTo((canvasStart - first) * scale, halfOffset); + ctx.lineTo((canvasStart - first) * scale, halfOffset - Math.round((peaks[2 * canvasStart] || 0) / absmaxHalf)); + var i, peak, h; + + for (i = canvasStart; i < canvasEnd; i++) { + peak = peaks[2 * i] || 0; + h = Math.round(peak / absmaxHalf); + ctx.lineTo((i - first) * scale + this.halfPixel, halfOffset - h); + } // draw the bottom edge going backwards, to make a single + // closed hull to fill + + + var j = canvasEnd - 1; + + for (j; j >= canvasStart; j--) { + peak = peaks[2 * j + 1] || 0; + h = Math.round(peak / absmaxHalf); + ctx.lineTo((j - first) * scale + this.halfPixel, halfOffset - h); + } + + ctx.lineTo((canvasStart - first) * scale, halfOffset - Math.round((peaks[2 * canvasStart + 1] || 0) / absmaxHalf)); + ctx.closePath(); + ctx.fill(); + } + /** + * Destroys this entry + */ + + }, { + key: "destroy", + value: function destroy() { + this.waveCtx = null; + this.wave = null; + this.progressCtx = null; + this.progress = null; + } + /** + * Return image data of the wave `canvas` element + * + * When using a `type` of `'blob'`, this will return a `Promise` that + * resolves with a `Blob` instance. + * + * @param {string} format='image/png' An optional value of a format type. + * @param {number} quality=0.92 An optional value between 0 and 1. + * @param {string} type='dataURL' Either 'dataURL' or 'blob'. + * @return {string|Promise} When using the default `'dataURL'` `type` this + * returns a data URL. When using the `'blob'` `type` this returns a + * `Promise` that resolves with a `Blob` instance. + */ + + }, { + key: "getImage", + value: function getImage(format, quality, type) { + var _this = this; + + if (type === 'blob') { + return new Promise(function (resolve) { + _this.wave.toBlob(resolve, format, quality); + }); + } else if (type === 'dataURL') { + return this.wave.toDataURL(format, quality); + } + } + }]); + + return CanvasEntry; +}(); + +exports.default = CanvasEntry; +module.exports = exports.default; + +/***/ }), + +/***/ "./src/drawer.js": +/*!***********************!*\ + !*** ./src/drawer.js ***! + \***********************/ +/***/ ((module, exports, __webpack_require__) => { + +"use strict"; + + +function _typeof(obj) { "@babel/helpers - typeof"; 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); } + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.default = void 0; + +var util = _interopRequireWildcard(__webpack_require__(/*! ./util */ "./src/util/index.js")); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +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); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +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); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +/** + * Parent class for renderers + * + * @extends {Observer} + */ +var Drawer = /*#__PURE__*/function (_util$Observer) { + _inherits(Drawer, _util$Observer); + + var _super = _createSuper(Drawer); + + /** + * @param {HTMLElement} container The container node of the wavesurfer instance + * @param {WavesurferParams} params The wavesurfer initialisation options + */ + function Drawer(container, params) { + var _this; + + _classCallCheck(this, Drawer); + + _this = _super.call(this); + _this.container = util.withOrientation(container, params.vertical); + /** + * @type {WavesurferParams} + */ + + _this.params = params; + /** + * The width of the renderer + * @type {number} + */ + + _this.width = 0; + /** + * The height of the renderer + * @type {number} + */ + + _this.height = params.height * _this.params.pixelRatio; + _this.lastPos = 0; + /** + * The `` element which is added to the container + * @type {HTMLElement} + */ + + _this.wrapper = null; + return _this; + } + /** + * Alias of `util.style` + * + * @param {HTMLElement} el The element that the styles will be applied to + * @param {Object} styles The map of propName: attribute, both are used as-is + * @return {HTMLElement} el + */ + + + _createClass(Drawer, [{ + key: "style", + value: function style(el, styles) { + return util.style(el, styles); + } + /** + * Create the wrapper `` element, style it and set up the events for + * interaction + */ + + }, { + key: "createWrapper", + value: function createWrapper() { + this.wrapper = util.withOrientation(this.container.appendChild(document.createElement('wave')), this.params.vertical); + this.style(this.wrapper, { + display: 'block', + position: 'relative', + userSelect: 'none', + webkitUserSelect: 'none', + height: this.params.height + 'px' + }); + + if (this.params.fillParent || this.params.scrollParent) { + this.style(this.wrapper, { + width: '100%', + overflowX: this.params.hideScrollbar ? 'hidden' : 'auto', + overflowY: 'hidden' + }); + } + + this.setupWrapperEvents(); + } + /** + * Handle click event + * + * @param {Event} e Click event + * @param {?boolean} noPrevent Set to true to not call `e.preventDefault()` + * @return {number} Playback position from 0 to 1 + */ + + }, { + key: "handleEvent", + value: function handleEvent(e, noPrevent) { + !noPrevent && e.preventDefault(); + var clientX = util.withOrientation(e.targetTouches ? e.targetTouches[0] : e, this.params.vertical).clientX; + var bbox = this.wrapper.getBoundingClientRect(); + var nominalWidth = this.width; + var parentWidth = this.getWidth(); + var progressPixels = this.getProgressPixels(bbox, clientX); + var progress; + + if (!this.params.fillParent && nominalWidth < parentWidth) { + progress = progressPixels * (this.params.pixelRatio / nominalWidth) || 0; + } else { + progress = (progressPixels + this.wrapper.scrollLeft) / this.wrapper.scrollWidth || 0; + } + + return util.clamp(progress, 0, 1); + } + }, { + key: "getProgressPixels", + value: function getProgressPixels(wrapperBbox, clientX) { + if (this.params.rtl) { + return wrapperBbox.right - clientX; + } else { + return clientX - wrapperBbox.left; + } + } + }, { + key: "setupWrapperEvents", + value: function setupWrapperEvents() { + var _this2 = this; + + this.wrapper.addEventListener('click', function (e) { + var orientedEvent = util.withOrientation(e, _this2.params.vertical); + var scrollbarHeight = _this2.wrapper.offsetHeight - _this2.wrapper.clientHeight; + + if (scrollbarHeight !== 0) { + // scrollbar is visible. Check if click was on it + var bbox = _this2.wrapper.getBoundingClientRect(); + + if (orientedEvent.clientY >= bbox.bottom - scrollbarHeight) { + // ignore mousedown as it was on the scrollbar + return; + } + } + + if (_this2.params.interact) { + _this2.fireEvent('click', e, _this2.handleEvent(e)); + } + }); + this.wrapper.addEventListener('dblclick', function (e) { + if (_this2.params.interact) { + _this2.fireEvent('dblclick', e, _this2.handleEvent(e)); + } + }); + this.wrapper.addEventListener('scroll', function (e) { + return _this2.fireEvent('scroll', e); + }); + } + /** + * Draw peaks on the canvas + * + * @param {number[]|Number.} peaks Can also be an array of arrays + * for split channel rendering + * @param {number} length The width of the area that should be drawn + * @param {number} start The x-offset of the beginning of the area that + * should be rendered + * @param {number} end The x-offset of the end of the area that should be + * rendered + */ + + }, { + key: "drawPeaks", + value: function drawPeaks(peaks, length, start, end) { + if (!this.setWidth(length)) { + this.clearWave(); + } + + this.params.barWidth ? this.drawBars(peaks, 0, start, end) : this.drawWave(peaks, 0, start, end); + } + /** + * Scroll to the beginning + */ + + }, { + key: "resetScroll", + value: function resetScroll() { + if (this.wrapper !== null) { + this.wrapper.scrollLeft = 0; + } + } + /** + * Recenter the view-port at a certain percent of the waveform + * + * @param {number} percent Value from 0 to 1 on the waveform + */ + + }, { + key: "recenter", + value: function recenter(percent) { + var position = this.wrapper.scrollWidth * percent; + this.recenterOnPosition(position, true); + } + /** + * Recenter the view-port on a position, either scroll there immediately or + * in steps of 5 pixels + * + * @param {number} position X-offset in pixels + * @param {boolean} immediate Set to true to immediately scroll somewhere + */ + + }, { + key: "recenterOnPosition", + value: function recenterOnPosition(position, immediate) { + var scrollLeft = this.wrapper.scrollLeft; + var half = ~~(this.wrapper.clientWidth / 2); + var maxScroll = this.wrapper.scrollWidth - this.wrapper.clientWidth; + var target = position - half; + var offset = target - scrollLeft; + + if (maxScroll == 0) { + // no need to continue if scrollbar is not there + return; + } // if the cursor is currently visible... + + + if (!immediate && -half <= offset && offset < half) { + // set rate at which waveform is centered + var rate = this.params.autoCenterRate; // make rate depend on width of view and length of waveform + + rate /= half; + rate *= maxScroll; + offset = Math.max(-rate, Math.min(rate, offset)); + target = scrollLeft + offset; + } // limit target to valid range (0 to maxScroll) + + + target = Math.max(0, Math.min(maxScroll, target)); // no use attempting to scroll if we're not moving + + if (target != scrollLeft) { + this.wrapper.scrollLeft = target; + } + } + /** + * Get the current scroll position in pixels + * + * @return {number} Horizontal scroll position in pixels + */ + + }, { + key: "getScrollX", + value: function getScrollX() { + var x = 0; + + if (this.wrapper) { + var pixelRatio = this.params.pixelRatio; + x = Math.round(this.wrapper.scrollLeft * pixelRatio); // In cases of elastic scroll (safari with mouse wheel) you can + // scroll beyond the limits of the container + // Calculate and floor the scrollable extent to make sure an out + // of bounds value is not returned + // Ticket #1312 + + if (this.params.scrollParent) { + var maxScroll = ~~(this.wrapper.scrollWidth * pixelRatio - this.getWidth()); + x = Math.min(maxScroll, Math.max(0, x)); + } + } + + return x; + } + /** + * Get the width of the container + * + * @return {number} The width of the container + */ + + }, { + key: "getWidth", + value: function getWidth() { + return Math.round(this.container.clientWidth * this.params.pixelRatio); + } + /** + * Set the width of the container + * + * @param {number} width The new width of the container + * @return {boolean} Whether the width of the container was updated or not + */ + + }, { + key: "setWidth", + value: function setWidth(width) { + if (this.width == width) { + return false; + } + + this.width = width; + + if (this.params.fillParent || this.params.scrollParent) { + this.style(this.wrapper, { + width: '' + }); + } else { + var newWidth = ~~(this.width / this.params.pixelRatio) + 'px'; + this.style(this.wrapper, { + width: newWidth + }); + } + + this.updateSize(); + return true; + } + /** + * Set the height of the container + * + * @param {number} height The new height of the container. + * @return {boolean} Whether the height of the container was updated or not + */ + + }, { + key: "setHeight", + value: function setHeight(height) { + if (height == this.height) { + return false; + } + + this.height = height; + this.style(this.wrapper, { + height: ~~(this.height / this.params.pixelRatio) + 'px' + }); + this.updateSize(); + return true; + } + /** + * Called by wavesurfer when progress should be rendered + * + * @param {number} progress From 0 to 1 + */ + + }, { + key: "progress", + value: function progress(_progress) { + var minPxDelta = 1 / this.params.pixelRatio; + var pos = Math.round(_progress * this.width) * minPxDelta; + + if (pos < this.lastPos || pos - this.lastPos >= minPxDelta) { + this.lastPos = pos; + + if (this.params.scrollParent && this.params.autoCenter) { + var newPos = ~~(this.wrapper.scrollWidth * _progress); + this.recenterOnPosition(newPos, this.params.autoCenterImmediately); + } + + this.updateProgress(pos); + } + } + /** + * This is called when wavesurfer is destroyed + */ + + }, { + key: "destroy", + value: function destroy() { + this.unAll(); + + if (this.wrapper) { + if (this.wrapper.parentNode == this.container.domElement) { + this.container.removeChild(this.wrapper.domElement); + } + + this.wrapper = null; + } + } + /* Renderer-specific methods */ + + /** + * Called after cursor related params have changed. + * + * @abstract + */ + + }, { + key: "updateCursor", + value: function updateCursor() {} + /** + * Called when the size of the container changes so the renderer can adjust + * + * @abstract + */ + + }, { + key: "updateSize", + value: function updateSize() {} + /** + * Draw a waveform with bars + * + * @abstract + * @param {number[]|Number.} peaks Can also be an array of arrays for split channel + * rendering + * @param {number} channelIndex The index of the current channel. Normally + * should be 0 + * @param {number} start The x-offset of the beginning of the area that + * should be rendered + * @param {number} end The x-offset of the end of the area that should be + * rendered + */ + + }, { + key: "drawBars", + value: function drawBars(peaks, channelIndex, start, end) {} + /** + * Draw a waveform + * + * @abstract + * @param {number[]|Number.} peaks Can also be an array of arrays for split channel + * rendering + * @param {number} channelIndex The index of the current channel. Normally + * should be 0 + * @param {number} start The x-offset of the beginning of the area that + * should be rendered + * @param {number} end The x-offset of the end of the area that should be + * rendered + */ + + }, { + key: "drawWave", + value: function drawWave(peaks, channelIndex, start, end) {} + /** + * Clear the waveform + * + * @abstract + */ + + }, { + key: "clearWave", + value: function clearWave() {} + /** + * Render the new progress + * + * @abstract + * @param {number} position X-Offset of progress position in pixels + */ + + }, { + key: "updateProgress", + value: function updateProgress(position) {} + }]); + + return Drawer; +}(util.Observer); + +exports.default = Drawer; +module.exports = exports.default; + +/***/ }), + +/***/ "./src/drawer.multicanvas.js": +/*!***********************************!*\ + !*** ./src/drawer.multicanvas.js ***! + \***********************************/ +/***/ ((module, exports, __webpack_require__) => { + +"use strict"; + + +function _typeof(obj) { "@babel/helpers - typeof"; 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); } + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.default = void 0; + +var _drawer = _interopRequireDefault(__webpack_require__(/*! ./drawer */ "./src/drawer.js")); + +var util = _interopRequireWildcard(__webpack_require__(/*! ./util */ "./src/util/index.js")); + +var _drawer2 = _interopRequireDefault(__webpack_require__(/*! ./drawer.canvasentry */ "./src/drawer.canvasentry.js")); + +function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } + +function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && 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; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +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); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +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); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +/** + * MultiCanvas renderer for wavesurfer. Is currently the default and sole + * builtin renderer. + * + * A `MultiCanvas` consists of one or more `CanvasEntry` instances, depending + * on the zoom level. + */ +var MultiCanvas = /*#__PURE__*/function (_Drawer) { + _inherits(MultiCanvas, _Drawer); + + var _super = _createSuper(MultiCanvas); + + /** + * @param {HTMLElement} container The container node of the wavesurfer instance + * @param {WavesurferParams} params The wavesurfer initialisation options + */ + function MultiCanvas(container, params) { + var _this; + + _classCallCheck(this, MultiCanvas); + + _this = _super.call(this, container, params); + /** + * @type {number} + */ + + _this.maxCanvasWidth = params.maxCanvasWidth; + /** + * @type {number} + */ + + _this.maxCanvasElementWidth = Math.round(params.maxCanvasWidth / params.pixelRatio); + /** + * Whether or not the progress wave is rendered. If the `waveColor` + * and `progressColor` are the same color it is not. + * + * @type {boolean} + */ + + _this.hasProgressCanvas = params.waveColor != params.progressColor; + /** + * @type {number} + */ + + _this.halfPixel = 0.5 / params.pixelRatio; + /** + * List of `CanvasEntry` instances. + * + * @type {Array} + */ + + _this.canvases = []; + /** + * @type {HTMLElement} + */ + + _this.progressWave = null; + /** + * Class used to generate entries. + * + * @type {function} + */ + + _this.EntryClass = _drawer2.default; + /** + * Canvas 2d context attributes. + * + * @type {object} + */ + + _this.canvasContextAttributes = params.drawingContextAttributes; + /** + * Overlap added between entries to prevent vertical white stripes + * between `canvas` elements. + * + * @type {number} + */ + + _this.overlap = 2 * Math.ceil(params.pixelRatio / 2); + /** + * The radius of the wave bars. Makes bars rounded + * + * @type {number} + */ + + _this.barRadius = params.barRadius || 0; + /** + * Whether to render the waveform vertically. Defaults to false. + * + * @type {boolean} + */ + + _this.vertical = params.vertical; + return _this; + } + /** + * Initialize the drawer + */ + + + _createClass(MultiCanvas, [{ + key: "init", + value: function init() { + this.createWrapper(); + this.createElements(); + } + /** + * Create the canvas elements and style them + * + */ + + }, { + key: "createElements", + value: function createElements() { + this.progressWave = util.withOrientation(this.wrapper.appendChild(document.createElement('wave')), this.params.vertical); + this.style(this.progressWave, { + position: 'absolute', + zIndex: 3, + left: 0, + top: 0, + bottom: 0, + overflow: 'hidden', + width: '0', + display: 'none', + boxSizing: 'border-box', + borderRightStyle: 'solid', + pointerEvents: 'none' + }); + this.addCanvas(); + this.updateCursor(); + } + /** + * Update cursor style + */ + + }, { + key: "updateCursor", + value: function updateCursor() { + this.style(this.progressWave, { + borderRightWidth: this.params.cursorWidth + 'px', + borderRightColor: this.params.cursorColor + }); + } + /** + * Adjust to the updated size by adding or removing canvases + */ + + }, { + key: "updateSize", + value: function updateSize() { + var _this2 = this; + + var totalWidth = Math.round(this.width / this.params.pixelRatio); + var requiredCanvases = Math.ceil(totalWidth / (this.maxCanvasElementWidth + this.overlap)); // add required canvases + + while (this.canvases.length < requiredCanvases) { + this.addCanvas(); + } // remove older existing canvases, if any + + + while (this.canvases.length > requiredCanvases) { + this.removeCanvas(); + } + + var canvasWidth = this.maxCanvasWidth + this.overlap; + var lastCanvas = this.canvases.length - 1; + this.canvases.forEach(function (entry, i) { + if (i == lastCanvas) { + canvasWidth = _this2.width - _this2.maxCanvasWidth * lastCanvas; + } + + _this2.updateDimensions(entry, canvasWidth, _this2.height); + + entry.clearWave(); + }); + } + /** + * Add a canvas to the canvas list + * + */ + + }, { + key: "addCanvas", + value: function addCanvas() { + var entry = new this.EntryClass(); + entry.canvasContextAttributes = this.canvasContextAttributes; + entry.hasProgressCanvas = this.hasProgressCanvas; + entry.halfPixel = this.halfPixel; + var leftOffset = this.maxCanvasElementWidth * this.canvases.length; // wave + + var wave = util.withOrientation(this.wrapper.appendChild(document.createElement('canvas')), this.params.vertical); + this.style(wave, { + position: 'absolute', + zIndex: 2, + left: leftOffset + 'px', + top: 0, + bottom: 0, + height: '100%', + pointerEvents: 'none' + }); + entry.initWave(wave); // progress + + if (this.hasProgressCanvas) { + var progress = util.withOrientation(this.progressWave.appendChild(document.createElement('canvas')), this.params.vertical); + this.style(progress, { + position: 'absolute', + left: leftOffset + 'px', + top: 0, + bottom: 0, + height: '100%' + }); + entry.initProgress(progress); + } + + this.canvases.push(entry); + } + /** + * Pop single canvas from the list + * + */ + + }, { + key: "removeCanvas", + value: function removeCanvas() { + var lastEntry = this.canvases[this.canvases.length - 1]; // wave + + lastEntry.wave.parentElement.removeChild(lastEntry.wave.domElement); // progress + + if (this.hasProgressCanvas) { + lastEntry.progress.parentElement.removeChild(lastEntry.progress.domElement); + } // cleanup + + + if (lastEntry) { + lastEntry.destroy(); + lastEntry = null; + } + + this.canvases.pop(); + } + /** + * Update the dimensions of a canvas element + * + * @param {CanvasEntry} entry Target entry + * @param {number} width The new width of the element + * @param {number} height The new height of the element + */ + + }, { + key: "updateDimensions", + value: function updateDimensions(entry, width, height) { + var elementWidth = Math.round(width / this.params.pixelRatio); + var totalWidth = Math.round(this.width / this.params.pixelRatio); // update canvas dimensions + + entry.updateDimensions(elementWidth, totalWidth, width, height); // style element + + this.style(this.progressWave, { + display: 'block' + }); + } + /** + * Clear the whole multi-canvas + */ + + }, { + key: "clearWave", + value: function clearWave() { + var _this3 = this; + + util.frame(function () { + _this3.canvases.forEach(function (entry) { + return entry.clearWave(); + }); + })(); + } + /** + * Draw a waveform with bars + * + * @param {number[]|Number.} peaks Can also be an array of arrays + * for split channel rendering + * @param {number} channelIndex The index of the current channel. Normally + * should be 0. Must be an integer. + * @param {number} start The x-offset of the beginning of the area that + * should be rendered + * @param {number} end The x-offset of the end of the area that should be + * rendered + * @returns {void} + */ + + }, { + key: "drawBars", + value: function drawBars(peaks, channelIndex, start, end) { + var _this4 = this; + + return this.prepareDraw(peaks, channelIndex, start, end, function (_ref) { + var absmax = _ref.absmax, + hasMinVals = _ref.hasMinVals, + height = _ref.height, + offsetY = _ref.offsetY, + halfH = _ref.halfH, + peaks = _ref.peaks, + ch = _ref.channelIndex; + + // if drawBars was called within ws.empty we don't pass a start and + // don't want anything to happen + if (start === undefined) { + return; + } // Skip every other value if there are negatives. + + + var peakIndexScale = hasMinVals ? 2 : 1; + var length = peaks.length / peakIndexScale; + var bar = _this4.params.barWidth * _this4.params.pixelRatio; + var gap = _this4.params.barGap === null ? Math.max(_this4.params.pixelRatio, ~~(bar / 2)) : Math.max(_this4.params.pixelRatio, _this4.params.barGap * _this4.params.pixelRatio); + var step = bar + gap; + var scale = length / _this4.width; + var first = start; + var last = end; + var i = first; + + for (i; i < last; i += step) { + var peak = peaks[Math.floor(i * scale * peakIndexScale)] || 0; + var h = Math.round(peak / absmax * halfH); + /* in case of silences, allow the user to specify that we + * always draw *something* (normally a 1px high bar) */ + + if (h == 0 && _this4.params.barMinHeight) { + h = _this4.params.barMinHeight; + } + + _this4.fillRect(i + _this4.halfPixel, halfH - h + offsetY, bar + _this4.halfPixel, h * 2, _this4.barRadius, ch); + } + }); + } + /** + * Draw a waveform + * + * @param {number[]|Number.} peaks Can also be an array of arrays + * for split channel rendering + * @param {number} channelIndex The index of the current channel. Normally + * should be 0 + * @param {number?} start The x-offset of the beginning of the area that + * should be rendered (If this isn't set only a flat line is rendered) + * @param {number?} end The x-offset of the end of the area that should be + * rendered + * @returns {void} + */ + + }, { + key: "drawWave", + value: function drawWave(peaks, channelIndex, start, end) { + var _this5 = this; + + return this.prepareDraw(peaks, channelIndex, start, end, function (_ref2) { + var absmax = _ref2.absmax, + hasMinVals = _ref2.hasMinVals, + height = _ref2.height, + offsetY = _ref2.offsetY, + halfH = _ref2.halfH, + peaks = _ref2.peaks, + channelIndex = _ref2.channelIndex; + + if (!hasMinVals) { + var reflectedPeaks = []; + var len = peaks.length; + var i = 0; + + for (i; i < len; i++) { + reflectedPeaks[2 * i] = peaks[i]; + reflectedPeaks[2 * i + 1] = -peaks[i]; + } + + peaks = reflectedPeaks; + } // if drawWave was called within ws.empty we don't pass a start and + // end and simply want a flat line + + + if (start !== undefined) { + _this5.drawLine(peaks, absmax, halfH, offsetY, start, end, channelIndex); + } // always draw a median line + + + _this5.fillRect(0, halfH + offsetY - _this5.halfPixel, _this5.width, _this5.halfPixel, _this5.barRadius, channelIndex); + }); + } + /** + * Tell the canvas entries to render their portion of the waveform + * + * @param {number[]} peaks Peaks data + * @param {number} absmax Maximum peak value (absolute) + * @param {number} halfH Half the height of the waveform + * @param {number} offsetY Offset to the top + * @param {number} start The x-offset of the beginning of the area that + * should be rendered + * @param {number} end The x-offset of the end of the area that + * should be rendered + * @param {channelIndex} channelIndex The channel index of the line drawn + */ + + }, { + key: "drawLine", + value: function drawLine(peaks, absmax, halfH, offsetY, start, end, channelIndex) { + var _this6 = this; + + var _ref3 = this.params.splitChannelsOptions.channelColors[channelIndex] || {}, + waveColor = _ref3.waveColor, + progressColor = _ref3.progressColor; + + this.canvases.forEach(function (entry, i) { + _this6.setFillStyles(entry, waveColor, progressColor); + + _this6.applyCanvasTransforms(entry, _this6.params.vertical); + + entry.drawLines(peaks, absmax, halfH, offsetY, start, end); + }); + } + /** + * Draw a rectangle on the multi-canvas + * + * @param {number} x X-position of the rectangle + * @param {number} y Y-position of the rectangle + * @param {number} width Width of the rectangle + * @param {number} height Height of the rectangle + * @param {number} radius Radius of the rectangle + * @param {channelIndex} channelIndex The channel index of the bar drawn + */ + + }, { + key: "fillRect", + value: function fillRect(x, y, width, height, radius, channelIndex) { + var startCanvas = Math.floor(x / this.maxCanvasWidth); + var endCanvas = Math.min(Math.ceil((x + width) / this.maxCanvasWidth) + 1, this.canvases.length); + var i = startCanvas; + + for (i; i < endCanvas; i++) { + var entry = this.canvases[i]; + var leftOffset = i * this.maxCanvasWidth; + var intersection = { + x1: Math.max(x, i * this.maxCanvasWidth), + y1: y, + x2: Math.min(x + width, i * this.maxCanvasWidth + entry.wave.width), + y2: y + height + }; + + if (intersection.x1 < intersection.x2) { + var _ref4 = this.params.splitChannelsOptions.channelColors[channelIndex] || {}, + waveColor = _ref4.waveColor, + progressColor = _ref4.progressColor; + + this.setFillStyles(entry, waveColor, progressColor); + this.applyCanvasTransforms(entry, this.params.vertical); + entry.fillRects(intersection.x1 - leftOffset, intersection.y1, intersection.x2 - intersection.x1, intersection.y2 - intersection.y1, radius); + } + } + } + /** + * Returns whether to hide the channel from being drawn based on params. + * + * @param {number} channelIndex The index of the current channel. + * @returns {bool} True to hide the channel, false to draw. + */ + + }, { + key: "hideChannel", + value: function hideChannel(channelIndex) { + return this.params.splitChannels && this.params.splitChannelsOptions.filterChannels.includes(channelIndex); + } + /** + * Performs preparation tasks and calculations which are shared by `drawBars` + * and `drawWave` + * + * @param {number[]|Number.} peaks Can also be an array of arrays for + * split channel rendering + * @param {number} channelIndex The index of the current channel. Normally + * should be 0 + * @param {number?} start The x-offset of the beginning of the area that + * should be rendered. If this isn't set only a flat line is rendered + * @param {number?} end The x-offset of the end of the area that should be + * rendered + * @param {function} fn The render function to call, e.g. `drawWave` + * @param {number} drawIndex The index of the current channel after filtering. + * @param {number?} normalizedMax Maximum modulation value across channels for use with relativeNormalization. Ignored when undefined + * @returns {void} + */ + + }, { + key: "prepareDraw", + value: function prepareDraw(peaks, channelIndex, start, end, fn, drawIndex, normalizedMax) { + var _this7 = this; + + return util.frame(function () { + // Split channels and call this function with the channelIndex set + if (peaks[0] instanceof Array) { + var channels = peaks; + + if (_this7.params.splitChannels) { + var filteredChannels = channels.filter(function (c, i) { + return !_this7.hideChannel(i); + }); + + if (!_this7.params.splitChannelsOptions.overlay) { + _this7.setHeight(Math.max(filteredChannels.length, 1) * _this7.params.height * _this7.params.pixelRatio); + } + + var overallAbsMax; + + if (_this7.params.splitChannelsOptions && _this7.params.splitChannelsOptions.relativeNormalization) { + // calculate maximum peak across channels to use for normalization + overallAbsMax = util.max(channels.map(function (channelPeaks) { + return util.absMax(channelPeaks); + })); + } + + return channels.forEach(function (channelPeaks, i) { + return _this7.prepareDraw(channelPeaks, i, start, end, fn, filteredChannels.indexOf(channelPeaks), overallAbsMax); + }); + } + + peaks = channels[0]; + } // Return and do not draw channel peaks if hidden. + + + if (_this7.hideChannel(channelIndex)) { + return; + } // calculate maximum modulation value, either from the barHeight + // parameter or if normalize=true from the largest value in the peak + // set + + + var absmax = 1 / _this7.params.barHeight; + + if (_this7.params.normalize) { + absmax = normalizedMax === undefined ? util.absMax(peaks) : normalizedMax; + } // Bar wave draws the bottom only as a reflection of the top, + // so we don't need negative values + + + var hasMinVals = [].some.call(peaks, function (val) { + return val < 0; + }); + var height = _this7.params.height * _this7.params.pixelRatio; + var halfH = height / 2; + var offsetY = height * drawIndex || 0; // Override offsetY if overlay is true + + if (_this7.params.splitChannelsOptions && _this7.params.splitChannelsOptions.overlay) { + offsetY = 0; + } + + return fn({ + absmax: absmax, + hasMinVals: hasMinVals, + height: height, + offsetY: offsetY, + halfH: halfH, + peaks: peaks, + channelIndex: channelIndex + }); + })(); + } + /** + * Set the fill styles for a certain entry (wave and progress) + * + * @param {CanvasEntry} entry Target entry + * @param {string} waveColor Wave color to draw this entry + * @param {string} progressColor Progress color to draw this entry + */ + + }, { + key: "setFillStyles", + value: function setFillStyles(entry) { + var waveColor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.params.waveColor; + var progressColor = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.params.progressColor; + entry.setFillStyles(waveColor, progressColor); + } + /** + * Set the canvas transforms for a certain entry (wave and progress) + * + * @param {CanvasEntry} entry Target entry + * @param {boolean} vertical Whether to render the waveform vertically + */ + + }, { + key: "applyCanvasTransforms", + value: function applyCanvasTransforms(entry) { + var vertical = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + entry.applyCanvasTransforms(vertical); + } + /** + * Return image data of the multi-canvas + * + * When using a `type` of `'blob'`, this will return a `Promise`. + * + * @param {string} format='image/png' An optional value of a format type. + * @param {number} quality=0.92 An optional value between 0 and 1. + * @param {string} type='dataURL' Either 'dataURL' or 'blob'. + * @return {string|string[]|Promise} When using the default `'dataURL'` + * `type` this returns a single data URL or an array of data URLs, + * one for each canvas. When using the `'blob'` `type` this returns a + * `Promise` that resolves with an array of `Blob` instances, one for each + * canvas. + */ + + }, { + key: "getImage", + value: function getImage(format, quality, type) { + if (type === 'blob') { + return Promise.all(this.canvases.map(function (entry) { + return entry.getImage(format, quality, type); + })); + } else if (type === 'dataURL') { + var images = this.canvases.map(function (entry) { + return entry.getImage(format, quality, type); + }); + return images.length > 1 ? images : images[0]; + } + } + /** + * Render the new progress + * + * @param {number} position X-offset of progress position in pixels + */ + + }, { + key: "updateProgress", + value: function updateProgress(position) { + this.style(this.progressWave, { + width: position + 'px' + }); + } + }]); + + return MultiCanvas; +}(_drawer.default); + +exports.default = MultiCanvas; +module.exports = exports.default; + +/***/ }), + +/***/ "./src/mediaelement-webaudio.js": +/*!**************************************!*\ + !*** ./src/mediaelement-webaudio.js ***! + \**************************************/ +/***/ ((module, exports, __webpack_require__) => { + +"use strict"; + + +function _typeof(obj) { "@babel/helpers - typeof"; 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); } + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports.default = void 0; + +var _mediaelement = _interopRequireDefault(__webpack_require__(/*! ./mediaelement */ "./src/mediaelement.js")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +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); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +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); } + +function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } + +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); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +/** + * MediaElementWebAudio backend: load audio via an HTML5 audio tag, but playback with the WebAudio API. + * The advantage here is that the html5