box-content-preview 3.83.0 → 3.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib/index.js CHANGED
@@ -955,6 +955,7 @@ __webpack_require__.d(__webpack_exports__, {
955
955
  wU: () => (/* binding */ decodeKeydown),
956
956
  Is: () => (/* binding */ findScriptLocation),
957
957
  kd: () => (/* binding */ getClosestPageToPinch),
958
+ RU: () => (/* binding */ getCurrentTimeMs),
958
959
  Yf: () => (/* binding */ getDistance),
959
960
  dJ: () => (/* binding */ getHeaders),
960
961
  t9: () => (/* binding */ getMidpoint),
@@ -1009,7 +1010,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
1009
1010
  const CLIENT_NAME = "box-content-preview"; // eslint-disable-line no-undef
1010
1011
  const CLIENT_NAME_KEY = 'box_client_name';
1011
1012
  const CLIENT_VERSION_KEY = 'box_client_version';
1012
- const CLIENT_VERSION = "3.83.0"; // eslint-disable-line no-undef
1013
+ const CLIENT_VERSION = "3.84.0"; // eslint-disable-line no-undef
1013
1014
  const HEADER_CLIENT_NAME = 'X-Box-Client-Name';
1014
1015
  const HEADER_CLIENT_VERSION = 'X-Box-Client-Version';
1015
1016
  const PROMISE_MAP = {};
@@ -1617,6 +1618,16 @@ function getDistance(x1, y1, x2, y2) {
1617
1618
  return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
1618
1619
  }
1619
1620
 
1621
+ /**
1622
+ * Monotonic clock in milliseconds. Falls back to wall time when performance is missing.
1623
+ *
1624
+ * @public
1625
+ * @return {number} Current time in milliseconds
1626
+ */
1627
+ function getCurrentTimeMs() {
1628
+ return typeof performance !== 'undefined' ? performance.now() : Date.now();
1629
+ }
1630
+
1620
1631
  /**
1621
1632
  * Returns the closest visible page to a pinch event
1622
1633
  *
@@ -3929,6 +3940,172 @@ let Menu = /*#__PURE__*/function (Menu) {
3929
3940
 
3930
3941
  /***/ },
3931
3942
 
3943
+ /***/ 4937
3944
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
3945
+
3946
+
3947
+ // EXPORTS
3948
+ __webpack_require__.d(__webpack_exports__, {
3949
+ A: () => (/* binding */ SliderControl)
3950
+ });
3951
+
3952
+ // EXTERNAL MODULE: external "react"
3953
+ var external_react_ = __webpack_require__(1649);
3954
+ // EXTERNAL MODULE: ./node_modules/classnames/index.js
3955
+ var classnames = __webpack_require__(2485);
3956
+ var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);
3957
+ // EXTERNAL MODULE: ./node_modules/lodash/noop.js
3958
+ var noop = __webpack_require__(3950);
3959
+ var noop_default = /*#__PURE__*/__webpack_require__.n(noop);
3960
+ // EXTERNAL MODULE: ./src/lib/util.js + 1 modules
3961
+ var util = __webpack_require__(4410);
3962
+ ;// ./src/lib/viewers/controls/slider/SliderControl.scss
3963
+ // extracted by mini-css-extract-plugin
3964
+
3965
+ ;// ./src/lib/viewers/controls/slider/SliderControl.tsx
3966
+ const _excluded = ["className", "max", "min", "onMove", "onUpdate", "step", "title", "track", "value"];
3967
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3968
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
3969
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
3970
+
3971
+
3972
+
3973
+
3974
+
3975
+ function SliderControl(_ref) {
3976
+ let {
3977
+ className,
3978
+ max = 100,
3979
+ min = 0,
3980
+ onMove = (noop_default()),
3981
+ onUpdate = (noop_default()),
3982
+ step = 1,
3983
+ title,
3984
+ track,
3985
+ value
3986
+ } = _ref,
3987
+ rest = _objectWithoutProperties(_ref, _excluded);
3988
+ const [isScrubbing, setIsScrubbing] = external_react_["default"].useState(false);
3989
+ const sliderElRef = external_react_["default"].useRef(null);
3990
+ const getPosition = external_react_["default"].useCallback(pageX => {
3991
+ const {
3992
+ current: sliderEl
3993
+ } = sliderElRef;
3994
+ if (!sliderEl) return 0;
3995
+ const {
3996
+ left: sliderLeft,
3997
+ width: sliderWidth
3998
+ } = sliderEl.getBoundingClientRect();
3999
+ return Math.max(0, Math.min(pageX - sliderLeft, sliderWidth));
4000
+ }, []);
4001
+ const getPositionValue = external_react_["default"].useCallback(pageX => {
4002
+ const {
4003
+ current: sliderEl
4004
+ } = sliderElRef;
4005
+ if (!sliderEl) return 0;
4006
+ const {
4007
+ width: sliderWidth
4008
+ } = sliderEl.getBoundingClientRect();
4009
+ const newValue = getPosition(pageX) / sliderWidth * max;
4010
+ return Math.max(min, Math.min(newValue, max));
4011
+ }, [getPosition, max, min]);
4012
+ const handleKeydown = event => {
4013
+ const key = (0,util/* decodeKeydown */.wU)(event);
4014
+ if (key === 'ArrowLeft') {
4015
+ event.stopPropagation(); // Prevents global key handling
4016
+ onUpdate(Math.max(min, Math.min(value - step, max)));
4017
+ }
4018
+ if (key === 'ArrowRight') {
4019
+ event.stopPropagation(); // Prevents global key handling
4020
+ onUpdate(Math.max(min, Math.min(value + step, max)));
4021
+ }
4022
+ };
4023
+ const handleMouseDown = ({
4024
+ button,
4025
+ ctrlKey,
4026
+ metaKey,
4027
+ pageX
4028
+ }) => {
4029
+ if (button > 1 || ctrlKey || metaKey) return;
4030
+ onUpdate(getPositionValue(pageX));
4031
+ setIsScrubbing(true);
4032
+ };
4033
+ const handleMouseMove = ({
4034
+ pageX
4035
+ }) => {
4036
+ const {
4037
+ current: sliderEl
4038
+ } = sliderElRef;
4039
+ const {
4040
+ width: sliderWidth
4041
+ } = sliderEl ? sliderEl.getBoundingClientRect() : {
4042
+ width: 0
4043
+ };
4044
+ onMove(getPositionValue(pageX), getPosition(pageX), sliderWidth);
4045
+ };
4046
+ const handleTouchStart = ({
4047
+ touches
4048
+ }) => {
4049
+ onUpdate(getPositionValue(touches[0].pageX));
4050
+ setIsScrubbing(true);
4051
+ };
4052
+ external_react_["default"].useEffect(() => {
4053
+ const handleDocumentMoveStop = () => setIsScrubbing(false);
4054
+ const handleDocumentMouseMove = event => {
4055
+ if (!isScrubbing || event.button > 1 || event.ctrlKey || event.metaKey) return;
4056
+ event.preventDefault();
4057
+ onUpdate(getPositionValue(event.pageX));
4058
+ };
4059
+ const handleDocumentTouchMove = event => {
4060
+ if (!isScrubbing || !event.touches || !event.touches[0]) return;
4061
+ event.preventDefault();
4062
+ onUpdate(getPositionValue(event.touches[0].pageX));
4063
+ };
4064
+ if (isScrubbing) {
4065
+ document.addEventListener('mousemove', handleDocumentMouseMove);
4066
+ document.addEventListener('mouseup', handleDocumentMoveStop);
4067
+ document.addEventListener('touchend', handleDocumentMoveStop);
4068
+ document.addEventListener('touchmove', handleDocumentTouchMove);
4069
+ }
4070
+ return () => {
4071
+ document.removeEventListener('mousemove', handleDocumentMouseMove);
4072
+ document.removeEventListener('mouseup', handleDocumentMoveStop);
4073
+ document.removeEventListener('touchend', handleDocumentMoveStop);
4074
+ document.removeEventListener('touchmove', handleDocumentTouchMove);
4075
+ };
4076
+ }, [isScrubbing, getPositionValue, onUpdate]);
4077
+ return /*#__PURE__*/external_react_["default"].createElement("div", _extends({
4078
+ ref: sliderElRef,
4079
+ "aria-label": title,
4080
+ "aria-valuemax": max,
4081
+ "aria-valuemin": min,
4082
+ "aria-valuenow": value,
4083
+ className: classnames_default()('bp-SliderControl', className, {
4084
+ 'bp-is-scrubbing': isScrubbing
4085
+ }),
4086
+ onKeyDown: handleKeydown,
4087
+ onMouseDown: handleMouseDown,
4088
+ onMouseMove: handleMouseMove,
4089
+ onTouchStart: handleTouchStart,
4090
+ role: "slider",
4091
+ tabIndex: 0
4092
+ }, rest), /*#__PURE__*/external_react_["default"].createElement("div", {
4093
+ className: "bp-SliderControl-track",
4094
+ "data-testid": "bp-slider-control-track",
4095
+ style: {
4096
+ backgroundImage: track
4097
+ }
4098
+ }), /*#__PURE__*/external_react_["default"].createElement("div", {
4099
+ className: "bp-SliderControl-thumb",
4100
+ "data-testid": "bp-slider-control-thumb",
4101
+ style: {
4102
+ left: `${value / max * 100}%`
4103
+ }
4104
+ }));
4105
+ }
4106
+
4107
+ /***/ },
4108
+
3932
4109
  /***/ 9974
3933
4110
  (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
3934
4111
 
@@ -3941,7 +4118,7 @@ function getPdfjsWorkerSrc() {
3941
4118
 
3942
4119
  /***/ },
3943
4120
 
3944
- /***/ 7893
4121
+ /***/ 3845
3945
4122
  (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
3946
4123
 
3947
4124
 
@@ -3967,6 +4144,8 @@ var TimestampControl = __webpack_require__(3904);
3967
4144
  var VolumeControls = __webpack_require__(3945);
3968
4145
  // EXTERNAL MODULE: ./src/lib/icons/play_48px.svg
3969
4146
  var play_48px = __webpack_require__(3493);
4147
+ // EXTERNAL MODULE: ./src/lib/viewers/media/waveform/constants.ts
4148
+ var constants = __webpack_require__(4929);
3970
4149
  ;// ./src/lib/viewers/media/waveform/peaks.ts
3971
4150
  const PLACEHOLDER_PEAK_AMPLITUDE = 0;
3972
4151
  const PLACEHOLDER_PEAK_COUNT = 2000;
@@ -4063,10 +4242,126 @@ function morphPeaks(from, to, elapsedMs) {
4063
4242
  }
4064
4243
  return out;
4065
4244
  }
4245
+ ;// ./src/lib/viewers/media/waveform/viewport.ts
4246
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4247
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4248
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
4249
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
4250
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4251
+
4252
+ function createWaveformViewport({
4253
+ durationSec,
4254
+ heightPx,
4255
+ maxZoom,
4256
+ scrollLeftPx,
4257
+ widthPx,
4258
+ zoomLevel
4259
+ }) {
4260
+ const zoom = Number.isFinite(zoomLevel) && zoomLevel > 0 ? zoomLevel : constants/* WAVEFORM_ZOOM_MIN */.LW;
4261
+ const viewDurationSec = durationSec > 0 ? durationSec / zoom : 0; // seconds visible at this zoom
4262
+ const pixelsPerSecond = viewDurationSec > 0 && widthPx > 0 ? widthPx / viewDurationSec : 0;
4263
+ const maxStartSec = Math.max(0, durationSec - viewDurationSec); // last start that still fills the window
4264
+ const startSec = pixelsPerSecond > 0 ? Math.min(maxStartSec, Math.max(0, scrollLeftPx / pixelsPerSecond)) : 0;
4265
+ return {
4266
+ durationSec,
4267
+ endSec: startSec + viewDurationSec,
4268
+ heightPx,
4269
+ maxZoom,
4270
+ pixelsPerSecond,
4271
+ scrollLeftPx,
4272
+ startSec,
4273
+ widthPx,
4274
+ zoomLevel: zoom
4275
+ };
4276
+ }
4277
+
4278
+ /** Same viewport with a different scroll, so start/end times update. */
4279
+ function getViewportAtScroll(viewport, scrollLeftPx) {
4280
+ return createWaveformViewport(_objectSpread(_objectSpread({}, viewport), {}, {
4281
+ scrollLeftPx
4282
+ }));
4283
+ }
4284
+
4285
+ /** How many CSS pixels from the left of the visible window this time sits. */
4286
+ function positionPxFromTime(timeSec, viewport) {
4287
+ return (timeSec - viewport.startSec) * viewport.pixelsPerSecond;
4288
+ }
4289
+
4290
+ /** Media time under a point this many CSS pixels from the left of the visible window. */
4291
+ function timeFromPositionPx(positionPx, viewport) {
4292
+ if (!(viewport.pixelsPerSecond > 0)) {
4293
+ return viewport.startSec;
4294
+ }
4295
+ return viewport.startSec + positionPx / viewport.pixelsPerSecond;
4296
+ }
4297
+
4298
+ /** True when this time sits inside the visible window. */
4299
+ function isTimeInView(timeSec, viewport) {
4300
+ return timeSec >= viewport.startSec && timeSec <= viewport.endSec;
4301
+ }
4302
+
4303
+ /** UI max zoom: 24×, ~1 peak per CSS pixel, and a minimum visible window. */
4304
+ function getWaveformZoomMax({
4305
+ durationSec,
4306
+ peakCount,
4307
+ viewWidthPx
4308
+ }) {
4309
+ if (!(peakCount > 0) || !(viewWidthPx > 0)) {
4310
+ return constants/* WAVEFORM_ZOOM_MIN */.LW;
4311
+ }
4312
+ const peakLimitedMax = Math.floor(peakCount / viewWidthPx);
4313
+ const durationLimitedMax = durationSec > 0 ? durationSec / constants/* WAVEFORM_MIN_VIEW_WINDOW_SEC */.Kl : constants/* WAVEFORM_ZOOM_MIN */.LW;
4314
+ return Math.max(constants/* WAVEFORM_ZOOM_MIN */.LW, Math.min(constants/* WAVEFORM_ZOOM_MAX */.tK, peakLimitedMax, durationLimitedMax));
4315
+ }
4316
+
4317
+ /** Keep zoom between 1× and this file's max. */
4318
+ function clampWaveformZoom(zoomLevel, maxZoom = constants/* WAVEFORM_ZOOM_MIN */.LW) {
4319
+ const max = Math.max(constants/* WAVEFORM_ZOOM_MIN */.LW, maxZoom);
4320
+ if (!Number.isFinite(zoomLevel)) {
4321
+ return constants/* WAVEFORM_ZOOM_MIN */.LW;
4322
+ }
4323
+ return Math.min(max, Math.max(constants/* WAVEFORM_ZOOM_MIN */.LW, zoomLevel));
4324
+ }
4325
+
4326
+ /** WaveSurfer zoom density. 0 = fit the whole file in the view. */
4327
+ function getZoomedPixelsPerSecond({
4328
+ durationSec,
4329
+ maxZoom = constants/* WAVEFORM_ZOOM_MIN */.LW,
4330
+ viewWidthPx,
4331
+ zoomLevel
4332
+ }) {
4333
+ const zoom = clampWaveformZoom(zoomLevel, maxZoom);
4334
+ if (zoom <= constants/* WAVEFORM_ZOOM_MIN */.LW || !(durationSec > 0) || !(viewWidthPx > 0)) {
4335
+ return 0;
4336
+ }
4337
+ return viewWidthPx / durationSec * zoom;
4338
+ }
4339
+
4340
+ /** Map zoom (1…max) onto the 0–100 slider. */
4341
+ function sliderValueFromZoom(zoomLevel, maxZoom = constants/* WAVEFORM_ZOOM_MIN */.LW) {
4342
+ const max = Math.max(constants/* WAVEFORM_ZOOM_MIN */.LW, maxZoom);
4343
+ const zoom = clampWaveformZoom(zoomLevel, max);
4344
+ if (max <= constants/* WAVEFORM_ZOOM_MIN */.LW) {
4345
+ return 0;
4346
+ }
4347
+ return (zoom - constants/* WAVEFORM_ZOOM_MIN */.LW) / (max - constants/* WAVEFORM_ZOOM_MIN */.LW) * constants/* WAVEFORM_ZOOM_SLIDER_MAX */.nh;
4348
+ }
4349
+
4350
+ /** Inverse of sliderValueFromZoom. */
4351
+ function zoomFromSliderValue(value, maxZoom = constants/* WAVEFORM_ZOOM_MIN */.LW) {
4352
+ const max = Math.max(constants/* WAVEFORM_ZOOM_MIN */.LW, maxZoom);
4353
+ if (max <= constants/* WAVEFORM_ZOOM_MIN */.LW) {
4354
+ return constants/* WAVEFORM_ZOOM_MIN */.LW;
4355
+ }
4356
+ const t = Math.min(constants/* WAVEFORM_ZOOM_SLIDER_MAX */.nh, Math.max(0, value)) / constants/* WAVEFORM_ZOOM_SLIDER_MAX */.nh;
4357
+ return clampWaveformZoom(constants/* WAVEFORM_ZOOM_MIN */.LW + t * (max - constants/* WAVEFORM_ZOOM_MIN */.LW), max);
4358
+ }
4066
4359
  ;// ./node_modules/wavesurfer.js/dist/wavesurfer.esm.js
4067
4360
  function t(t,e,i,n){return new(i||(i=Promise))((function(s,r){function o(t){try{l(n.next(t))}catch(t){r(t)}}function a(t){try{l(n.throw(t))}catch(t){r(t)}}function l(t){var e;t.done?s(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(o,a)}l((n=n.apply(t,e||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class e{constructor(){this.listeners={}}on(t,e,i){if(this.listeners[t]||(this.listeners[t]=new Set),null==i?void 0:i.once){const i=(...n)=>{this.un(t,i),e(...n)};return this.listeners[t].add(i),()=>this.un(t,i)}return this.listeners[t].add(e),()=>this.un(t,e)}un(t,e){var i;null===(i=this.listeners[t])||void 0===i||i.delete(e)}once(t,e){return this.on(t,e,{once:!0})}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}const i={decode:function(e,i){return t(this,void 0,void 0,(function*(){const t=new AudioContext({sampleRate:i});try{return yield t.decodeAudioData(e)}finally{"closed"!==t.state&&(yield t.close().catch((()=>{})))}}))},createBuffer:function(t,e){if(!t||0===t.length)throw new Error("channelData must be a non-empty array");if(e<=0)throw new Error("duration must be greater than 0");if("number"==typeof t[0]&&(t=[t]),!t[0]||0===t[0].length)throw new Error("channelData must contain non-empty channel arrays");!function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let n=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>n&&(n=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=n}}(t);const i=t.map((t=>t instanceof Float32Array?t:Float32Array.from(t)));return{duration:e,length:i[0].length,sampleRate:i[0].length/e,numberOfChannels:i.length,getChannelData:t=>{const e=i[t];if(!e)throw new Error(`Channel ${t} not found`);return e},copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}};function n(t,e){const i=e.xmlns?document.createElementNS(e.xmlns,t):document.createElement(t);for(const[t,s]of Object.entries(e))if("children"===t&&s)for(const[t,e]of Object.entries(s))e instanceof Node?i.appendChild(e):"string"==typeof e?i.appendChild(document.createTextNode(e)):i.appendChild(n(t,e));else"style"===t?Object.assign(i.style,s):"textContent"===t?i.textContent=s:i.setAttribute(t,s.toString());return i}function s(t,e,i){const s=n(t,e||{});return null==i||i.appendChild(s),s}function r(t){return t instanceof HTMLElement||"object"==typeof t&&null!==t&&t.nodeType===Node.ELEMENT_NODE&&"object"==typeof t.style}var o=Object.freeze({__proto__:null,createElement:s,default:s,isHTMLElement:r});const a={fetchBlob:function(e,i,n){return t(this,void 0,void 0,(function*(){var s;const r=yield fetch(e,n);if(r.status>=400)throw new Error(`Failed to fetch ${e}: ${r.status} (${r.statusText})`);return function(e,i,n){t(this,void 0,void 0,(function*(){var t;if(!e.body||!e.headers)return;const s=e.body.getReader(),r=Number(e.headers.get("Content-Length"))||0;let o=0;const a=()=>{s.cancel()};if(n){if(n.aborted)return void s.cancel();n.addEventListener("abort",a,{once:!0})}try{for(;;){const e=yield s.read();if(e.done)break;if(o+=(null===(t=e.value)||void 0===t?void 0:t.length)||0,r>0){const t=Math.round(o/r*100);i(t)}}}catch(t){if(t instanceof DOMException&&"AbortError"===t.name)return;console.warn("Progress tracking error:",t)}finally{n&&n.removeEventListener("abort",a)}}))}(r.clone(),i,null!==(s=null==n?void 0:n.signal)&&void 0!==s?s:void 0),r.blob()}))}};function l(t){let e=t;const i=new Set;return{get value(){return e},set(t){Object.is(e,t)||(e=t,i.forEach((t=>t(e))))},update(t){this.set(t(e))},subscribe:t=>(i.add(t),()=>i.delete(t))}}function h(t,e){const i=l(t());return e.forEach((e=>e.subscribe((()=>{const e=t();Object.is(i.value,e)||i.set(e)})))),{get value(){return i.value},subscribe:t=>i.subscribe(t)}}function c(t,e){let i;const n=()=>{i&&(i(),i=void 0),i=t()},s=e.map((t=>t.subscribe(n)));return n(),()=>{i&&(i(),i=void 0),s.forEach((t=>t()))}}class u extends e{get isPlayingSignal(){return this._isPlaying}get currentTimeSignal(){return this._currentTime}get durationSignal(){return this._duration}get volumeSignal(){return this._volume}get mutedSignal(){return this._muted}get playbackRateSignal(){return this._playbackRate}get seekingSignal(){return this._seeking}constructor(t){super(),this.isExternalMedia=!1,this._ownBlobUrl=null,this.reactiveMediaEventCleanups=[],t.media?(this.media=t.media,this.isExternalMedia=!0):this.media=document.createElement("audio"),this._isPlaying=l(!1),this._currentTime=l(0),this._duration=l(0),this._volume=l(this.media.volume),this._muted=l(this.media.muted),this._playbackRate=l(this.media.playbackRate||1),this._seeking=l(!1),this.setupReactiveMediaEvents(),t.mediaControls&&(this.media.controls=!0),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&this.onMediaEvent("canplay",(()=>{null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}),{once:!0})}setupReactiveMediaEvents(){this.reactiveMediaEventCleanups.push(this.onMediaEvent("play",(()=>{this._isPlaying.set(!0)}))),this.reactiveMediaEventCleanups.push(this.onMediaEvent("pause",(()=>{this._isPlaying.set(!1)}))),this.reactiveMediaEventCleanups.push(this.onMediaEvent("ended",(()=>{this._isPlaying.set(!1)}))),this.reactiveMediaEventCleanups.push(this.onMediaEvent("timeupdate",(()=>{this._currentTime.set(this.media.currentTime)}))),this.reactiveMediaEventCleanups.push(this.onMediaEvent("durationchange",(()=>{this._duration.set(this.media.duration||0)}))),this.reactiveMediaEventCleanups.push(this.onMediaEvent("loadedmetadata",(()=>{this._duration.set(this.media.duration||0)}))),this.reactiveMediaEventCleanups.push(this.onMediaEvent("seeking",(()=>{this._seeking.set(!0)}))),this.reactiveMediaEventCleanups.push(this.onMediaEvent("seeked",(()=>{this._seeking.set(!1)}))),this.reactiveMediaEventCleanups.push(this.onMediaEvent("volumechange",(()=>{this._volume.set(this.media.volume),this._muted.set(this.media.muted)}))),this.reactiveMediaEventCleanups.push(this.onMediaEvent("ratechange",(()=>{this._playbackRate.set(this.media.playbackRate)})))}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e,i)}getSrc(){return this.media.currentSrc||this.media.src||""}revokeSrc(){this._ownBlobUrl&&(URL.revokeObjectURL(this._ownBlobUrl),this._ownBlobUrl=null)}canPlayType(t){return""!==this.media.canPlayType(t)}setSrc(t,e){const i=this.getSrc();if(t&&i===t)return;this.revokeSrc();const n=e instanceof Blob&&(this.canPlayType(e.type)||!t)?URL.createObjectURL(e):t;if(n!==t&&(this._ownBlobUrl=n),i&&this.media.removeAttribute("src"),n||t)try{this.media.src=n}catch(e){this.media.src=t}}destroy(){this.reactiveMediaEventCleanups.forEach((t=>t())),this.reactiveMediaEventCleanups=[],this.revokeSrc(),this.unAll(),this.isExternalMedia||(this.media.pause(),this.media.removeAttribute("src"),this.media.load(),this.media.remove())}setMediaElement(t){this.reactiveMediaEventCleanups.forEach((t=>t())),this.reactiveMediaEventCleanups=[],this.media=t,this.setupReactiveMediaEvents()}play(){return t(this,void 0,void 0,(function*(){try{return yield this.media.play()}catch(t){if(t instanceof DOMException&&"AbortError"===t.name)return;throw t}}))}pause(){this.media.pause()}isPlaying(){return!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=Math.max(0,Math.min(t,this.getDuration()))}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}isSeeking(){return this.media.seeking}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}}function d({maxTop:t,maxBottom:e,halfHeight:i,vScale:n,barMinHeight:s=0,barAlign:r}){let o=Math.round(t*i*n);let a=o+Math.round(e*i*n)||1;return a<s&&(a=s,r||(o=a/2)),{topHeight:o,totalHeight:a}}function p({barAlign:t,halfHeight:e,topHeight:i,totalHeight:n,canvasHeight:s}){return"top"===t?0:"bottom"===t?s-n:e-i}function m(t,e,i){const n=e-t.left,s=i-t.top;return[n/t.width,s/t.height]}function g(t){return Boolean(t.barWidth||t.barGap||t.barAlign)}function f(t,e){if(!g(e))return t;const i=e.barWidth||.5,n=i+(e.barGap||i/2);return 0===n?t:Math.floor(t/n)*n}function v({scrollLeft:t,totalWidth:e,numCanvases:i}){if(0===e)return[0];const n=t/e,s=Math.floor(n*i);return[s-1,s,s+1]}function b(t){const e=t._cleanup;"function"==typeof e&&e()}function y(t){const e=l({scrollLeft:t.scrollLeft,scrollWidth:t.scrollWidth,clientWidth:t.clientWidth}),i=h((()=>function(t){const{scrollLeft:e,scrollWidth:i,clientWidth:n}=t;if(0===i)return{startX:0,endX:1};const s=e/i,r=(e+n)/i;return{startX:Math.max(0,Math.min(1,s)),endX:Math.max(0,Math.min(1,r))}}(e.value)),[e]),n=h((()=>function(t){return{left:t.scrollLeft,right:t.scrollLeft+t.clientWidth}}(e.value)),[e]),s=()=>{e.set({scrollLeft:t.scrollLeft,scrollWidth:t.scrollWidth,clientWidth:t.clientWidth})};t.addEventListener("scroll",s,{passive:!0});return{scrollData:e,percentages:i,bounds:n,cleanup:()=>{t.removeEventListener("scroll",s),b(e)}}}class C extends e{constructor(t,e){super(),this.timeouts=[],this.isScrollable=!1,this.audioData=null,this.resizeObserver=null,this.lastContainerWidth=0,this.isDragging=!1,this.subscriptions=[],this.unsubscribeOnScroll=[],this.dragStream=null,this.scrollStream=null,this.containerInlinePadding=0,this.onClickWrapper=t=>{const e=this.wrapper.getBoundingClientRect(),[i,n]=m(e,t.clientX,t.clientY);this.emit("click",i,n)},this.onDblClickWrapper=t=>{const e=this.wrapper.getBoundingClientRect(),[i,n]=m(e,t.clientX,t.clientY);this.emit("dblclick",i,n)},this.subscriptions=[],this.options=t;const i=this.parentFromOptionsContainer(t.container);this.parent=i;const[n,s]=this.initHtml();i.appendChild(n),this.container=n,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.calculateInlinePadding(),e&&s.appendChild(e),this.initEvents()}parentFromOptionsContainer(t){let e;if("string"==typeof t?e=document.querySelector(t):r(t)&&(e=t),!e)throw new Error("Container not found");return e}initEvents(){this.wrapper.addEventListener("click",this.onClickWrapper),this.wrapper.addEventListener("dblclick",this.onDblClickWrapper),!0!==this.options.dragToSeek&&"object"!=typeof this.options.dragToSeek||this.initDrag(),this.scrollStream=y(this.scrollContainer);const t=c((()=>{const{startX:t,endX:e}=this.scrollStream.percentages.value,{left:i,right:n}=this.scrollStream.bounds.value;this.emit("scroll",t,e,i,n)}),[this.scrollStream.percentages,this.scrollStream.bounds]);if(this.subscriptions.push(t),"function"==typeof ResizeObserver){const t=this.createDelay(100);this.resizeObserver=new ResizeObserver((()=>{t().then((()=>this.onContainerResize())).catch((()=>{}))})),this.resizeObserver.observe(this.scrollContainer)}}onContainerResize(){const t=this.parent.clientWidth;this.calculateInlinePadding(),t===this.lastContainerWidth&&"auto"!==this.options.height||(this.lastContainerWidth=t,this.reRender(),this.emit("resize"))}initDrag(){if(this.dragStream)return;this.dragStream=function(t,e={}){const{threshold:i=3,mouseButton:n=0,touchDelay:s=100}=e,r=l(null),o=new Map,a=matchMedia("(pointer: coarse)").matches;let h=()=>{};const c=e=>{if(e.button!==n)return;if(o.has(e.pointerId))return;if(o.set(e.pointerId,e),o.size>1)return;const l=e.pointerId;let c=e.clientX,u=e.clientY,d=!1;const p=Date.now(),m=t.getBoundingClientRect(),{left:g,top:f}=m,v=t=>{if(t.pointerId!==l)return;if(t.defaultPrevented||o.size>1)return;if(a&&Date.now()-p<s)return;const e=t.clientX,n=t.clientY,h=e-c,m=n-u;(d||Math.abs(h)>i||Math.abs(m)>i)&&(t.preventDefault(),t.stopPropagation(),d||(r.set({type:"start",x:c-g,y:u-f}),d=!0),r.set({type:"move",x:e-g,y:n-f,deltaX:h,deltaY:m}),c=e,u=n)},b=t=>{if(o.delete(t.pointerId)){if(t.pointerId===l&&d){const e=t.clientX,i=t.clientY;r.set({type:"end",x:e-g,y:i-f})}0===o.size&&h()}},y=t=>{t.relatedTarget&&t.relatedTarget!==document.documentElement||b(t)},C=t=>{d&&(t.stopPropagation(),t.preventDefault())},S=t=>{t.defaultPrevented||o.size>1||d&&t.preventDefault()};document.addEventListener("pointermove",v),document.addEventListener("pointerup",b),document.addEventListener("pointerout",y),document.addEventListener("pointercancel",y),document.addEventListener("touchmove",S,{passive:!1}),document.addEventListener("click",C,{capture:!0}),h=()=>{document.removeEventListener("pointermove",v),document.removeEventListener("pointerup",b),document.removeEventListener("pointerout",y),document.removeEventListener("pointercancel",y),document.removeEventListener("touchmove",S),setTimeout((()=>{document.removeEventListener("click",C,{capture:!0})}),10)}};return t.addEventListener("pointerdown",c),{signal:r,cleanup:()=>{h(),t.removeEventListener("pointerdown",c),o.clear(),b(r)}}}(this.wrapper);const t=c((()=>{const t=this.dragStream.signal.value;if(!t)return;const e=this.wrapper.getBoundingClientRect().width,i=(n=t.x/e)<0?0:n>1?1:n;var n;"start"===t.type?(this.isDragging=!0,this.emit("dragstart",i)):"move"===t.type?this.emit("drag",i):"end"===t.type&&(this.isDragging=!1,this.emit("dragend",i))}),[this.dragStream.signal]);this.subscriptions.push(t)}calculateInlinePadding(){const{paddingLeft:t,paddingRight:e}=getComputedStyle(this.scrollContainer),i=parseFloat(t)+parseFloat(e);this.containerInlinePadding=Number.isNaN(i)?0:i}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"}),i=this.options.cspNonce&&"string"==typeof this.options.cspNonce?this.options.cspNonce.replace(/"/g,""):"";return e.innerHTML=`\n <style${i?` nonce="${i}"`:""}>\n :host {\n user-select: none;\n min-width: 1px;\n }\n :host audio {\n display: block;\n width: 100%;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n min-height: ${this.getHeight(this.options.height,this.options.splitChannels)}px;\n pointer-events: none;\n }\n :host .canvases > div {\n position: relative;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .progress > div {\n position: relative;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper" part="wrapper">\n <div class="canvases" part="canvases"></div>\n <div class="progress" part="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){var e;if(this.options.container!==t.container){const e=this.parentFromOptionsContainer(t.container);e.appendChild(this.container),this.parent=e}!0===t.dragToSeek||"object"==typeof this.options.dragToSeek?this.initDrag():(null===(e=this.dragStream)||void 0===e||e.cleanup(),this.dragStream=null),this.options=t,this.reRender()}getWrapper(){return this.wrapper}getWidth(){return this.scrollContainer.clientWidth-this.containerInlinePadding}getScroll(){return this.scrollContainer.scrollLeft}setScroll(t){this.scrollContainer.scrollLeft=t}setScrollPercentage(t){const{scrollWidth:e}=this.scrollContainer,i=e*t;this.setScroll(i)}destroy(){var t;this.wrapper.removeEventListener("click",this.onClickWrapper),this.wrapper.removeEventListener("dblclick",this.onDblClickWrapper),this.timeouts.forEach((t=>t())),this.timeouts=[],this.subscriptions.forEach((t=>t())),this.container.remove(),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),null===(t=this.unsubscribeOnScroll)||void 0===t||t.forEach((t=>t())),this.unsubscribeOnScroll=[],this.dragStream&&(this.dragStream.cleanup(),this.dragStream=null),this.scrollStream&&(this.scrollStream.cleanup(),this.scrollStream=null)}createDelay(t=10){let e,i;const n=()=>{e&&(clearTimeout(e),e=void 0),i&&(i(),i=void 0)};return this.timeouts.push(n),()=>new Promise(((s,r)=>{n(),i=r,e=setTimeout((()=>{e=void 0,i=void 0,s()}),t)}))}getHeight(t,e){var i;const n=(null===(i=this.audioData)||void 0===i?void 0:i.numberOfChannels)||1;return function({optionsHeight:t,optionsSplitChannels:e,parentHeight:i,numberOfChannels:n,defaultHeight:s=128}){if(null==t)return s;const r=Number(t);if(!isNaN(r))return r;if("auto"===t){const t=i||s;return(null==e?void 0:e.every((t=>!t.overlay)))?t/n:t}return s}({optionsHeight:t,optionsSplitChannels:e,parentHeight:this.parent.clientHeight,numberOfChannels:n,defaultHeight:128})}convertColorValues(t,e){return function(t,e,i){if(!Array.isArray(t))return t||"";if(0===t.length)return"#999";if(t.length<2)return t[0]||"";const n=document.createElement("canvas"),s=n.getContext("2d");if(!s)return t[0]||"";const r=i||n.height*e,o=s.createLinearGradient(0,0,0,r),a=1/(t.length-1);return t.forEach(((t,e)=>{o.addColorStop(e*a,t)})),o}(t,this.getPixelRatio(),null==e?void 0:e.canvas.height)}getPixelRatio(){return t=window.devicePixelRatio,Math.max(1,t||1);// removed by dead control flow
4068
4361
  var t; }renderBarWaveform(t,e,i,n){const{width:s,height:r}=i.canvas,{halfHeight:o,barWidth:a,barRadius:l,barIndexScale:h,barSpacing:c,barMinHeight:u}=function({width:t,height:e,length:i,options:n,pixelRatio:s}){const r=e/2,o=n.barWidth?n.barWidth*s:1,a=n.barGap?n.barGap*s:n.barWidth?o/2:0,l=o+a||1;return{halfHeight:r,barWidth:o,barGap:a,barRadius:n.barRadius||0,barMinHeight:n.barMinHeight?n.barMinHeight*s:0,barIndexScale:i>0?t/l/i:0,barSpacing:l}}({width:s,height:r,length:(t[0]||[]).length,options:e,pixelRatio:this.getPixelRatio()}),m=function({channelData:t,barIndexScale:e,barSpacing:i,barWidth:n,halfHeight:s,vScale:r,canvasHeight:o,barAlign:a,barMinHeight:l}){const h=t[0]||[],c=t[1]||h,u=h.length,m=[];let g=0,f=0,v=0;for(let t=0;t<=u;t++){const u=Math.round(t*e);if(u>g){const{topHeight:t,totalHeight:e}=d({maxTop:f,maxBottom:v,halfHeight:s,vScale:r,barMinHeight:l,barAlign:a}),h=p({barAlign:a,halfHeight:s,topHeight:t,totalHeight:e,canvasHeight:o});m.push({x:g*i,y:h,width:n,height:e}),g=u,f=0,v=0}const b=Math.abs(h[t]||0),y=Math.abs(c[t]||0);b>f&&(f=b),y>v&&(v=y)}return m}({channelData:t,barIndexScale:h,barSpacing:c,barWidth:a,halfHeight:o,vScale:n,canvasHeight:r,barAlign:e.barAlign,barMinHeight:u});i.beginPath();for(const t of m)l&&"roundRect"in i?i.roundRect(t.x,t.y,t.width,t.height,l):i.rect(t.x,t.y,t.width,t.height);i.fill(),i.closePath()}renderLineWaveform(t,e,i,n){const{width:s,height:r}=i.canvas,o=function({channelData:t,width:e,height:i,vScale:n}){const s=i/2,r=t[0]||[];return[r,t[1]||r].map(((t,i)=>{const r=t.length,o=r?e/r:0,a=s,l=0===i?-1:1,h=[{x:0,y:a}];let c=0,u=0;for(let e=0;e<=r;e++){const i=Math.round(e*o);if(i>c){const t=a+(Math.round(u*s*n)||1)*l;h.push({x:c,y:t}),c=i,u=0}const r=Math.abs(t[e]||0);r>u&&(u=r)}return h.push({x:c,y:a}),h}))}({channelData:t,width:s,height:r,vScale:n});i.beginPath();for(const t of o)if(t.length){i.moveTo(t[0].x,t[0].y);for(let e=1;e<t.length;e++){const n=t[e];i.lineTo(n.x,n.y)}}i.fill(),i.closePath()}renderWaveform(t,e,i){if(i.fillStyle=this.convertColorValues(e.waveColor,i),e.renderFunction)return void e.renderFunction(t,i);const n=function({channelData:t,barHeight:e,normalize:i,maxPeak:n}){var s;const r=e||1;if(!i)return r;const o=t[0];if(!o||0===o.length)return r;let a=null!=n?n:0;if(!n)for(let t=0;t<o.length;t++){const e=null!==(s=o[t])&&void 0!==s?s:0,i=Math.abs(e);i>a&&(a=i)}return a?r/a:r}({channelData:t,barHeight:e.barHeight,normalize:e.normalize,maxPeak:e.maxPeak});g(e)?this.renderBarWaveform(t,e,i,n):this.renderLineWaveform(t,e,i,n)}renderSingleCanvas(t,e,i,n,s,r,o){const a=this.getPixelRatio(),l=document.createElement("canvas");l.width=Math.round(i*a),l.height=Math.round(n*a),l.style.width=`${i}px`,l.style.height=`${n}px`,l.style.left=`${Math.round(s)}px`,r.appendChild(l);const h=l.getContext("2d");if(e.renderFunction?(h.fillStyle=this.convertColorValues(e.waveColor,h),e.renderFunction(t,h)):this.renderWaveform(t,e,h),l.width>0&&l.height>0){const t=l.cloneNode(),i=t.getContext("2d");i.drawImage(l,0,0),i.globalCompositeOperation="source-in",i.fillStyle=this.convertColorValues(e.progressColor,i),i.fillRect(0,0,l.width,l.height),o.appendChild(t)}}renderMultiCanvas(t,e,i,n,s,r){const o=this.getPixelRatio(),{clientWidth:a}=this.scrollContainer,l=i/o,h=function({clientWidth:t,totalWidth:e,options:i}){return f(Math.min(8e3,t,e),i)}({clientWidth:a,totalWidth:l,options:e});let c={};if(0===h)return;const u=i=>{if(i<0||i>=d)return;if(c[i])return;c[i]=!0;const o=i*h;let a=Math.min(l-o,h);if(a=f(a,e),a<=0)return;const u=function({channelData:t,offset:e,clampedWidth:i,totalWidth:n}){return t.map((t=>{const s=Math.floor(e/n*t.length),r=Math.floor((e+i)/n*t.length);return t.slice(s,r)}))}({channelData:t,offset:o,clampedWidth:a,totalWidth:l});this.renderSingleCanvas(u,e,a,n,o,s,r)},d=Math.ceil(l/h);if(!this.isScrollable){for(let t=0;t<d;t++)u(t);return}if(v({scrollLeft:this.scrollContainer.scrollLeft,totalWidth:l,numCanvases:d}).forEach((t=>u(t))),d>1){const t=this.on("scroll",(()=>{const{scrollLeft:t}=this.scrollContainer;Object.keys(c).length>10&&(s.innerHTML="",r.innerHTML="",c={}),v({scrollLeft:t,totalWidth:l,numCanvases:d}).forEach((t=>u(t)))}));this.unsubscribeOnScroll.push(t)}}renderChannel(t,e,i,n){var{overlay:s}=e,r=function(t,e){var i={};for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&e.indexOf(n)<0&&(i[n]=t[n]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var s=0;for(n=Object.getOwnPropertySymbols(t);s<n.length;s++)e.indexOf(n[s])<0&&Object.prototype.propertyIsEnumerable.call(t,n[s])&&(i[n[s]]=t[n[s]])}return i}(e,["overlay"]);const o=document.createElement("div"),a=this.getHeight(r.height,r.splitChannels);o.style.height=`${a}px`,s&&n>0&&(o.style.marginTop=`-${a}px`),this.canvasWrapper.style.minHeight=`${a}px`,this.canvasWrapper.appendChild(o);const l=o.cloneNode();this.progressWrapper.appendChild(l),this.renderMultiCanvas(t,r,i,a,o,l)}render(e){return t(this,void 0,void 0,(function*(){var t;this.timeouts.forEach((t=>t())),this.timeouts=[],this.unsubscribeOnScroll.forEach((t=>t())),this.unsubscribeOnScroll=[],this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="",null!=this.options.width&&(this.scrollContainer.style.width="number"==typeof this.options.width?`${this.options.width}px`:this.options.width);const i=this.getPixelRatio(),n=this.scrollContainer.clientWidth-this.containerInlinePadding,{scrollWidth:s,isScrollable:r,useParentWidth:o,width:a}=function({duration:t,minPxPerSec:e=0,parentWidth:i,fillParent:n,pixelRatio:s}){const r=Math.ceil(t*e),o=r>i,a=Boolean(n&&!o);return{scrollWidth:r,isScrollable:o,useParentWidth:a,width:(a?i:r)*s}}({duration:e.duration,minPxPerSec:this.options.minPxPerSec||0,parentWidth:n,fillParent:this.options.fillParent,pixelRatio:i});if(this.isScrollable=r,this.wrapper.style.width=o?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrollable?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.audioData=e,this.emit("render"),this.options.splitChannels)for(let i=0;i<e.numberOfChannels;i++){const n=Object.assign(Object.assign({},this.options),null===(t=this.options.splitChannels)||void 0===t?void 0:t[i]);this.renderChannel([e.getChannelData(i)],n,a,i)}else{const t=[e.getChannelData(0)];e.numberOfChannels>1&&t.push(e.getChannelData(1)),this.renderChannel(t,this.options,a,0)}Promise.resolve().then((()=>this.emit("rendered")))}))}reRender(){if(this.unsubscribeOnScroll.forEach((t=>t())),this.unsubscribeOnScroll=[],!this.audioData)return;const{scrollWidth:t}=this.scrollContainer,{right:e}=this.progressWrapper.getBoundingClientRect();if(this.render(this.audioData),!this.isScrollable&&this.scrollContainer.scrollLeft)this.scrollContainer.scrollLeft=0;else if(this.isScrollable&&t!==this.scrollContainer.scrollWidth){const{right:t}=this.progressWrapper.getBoundingClientRect(),i=function(t){const e=2*t;return(e<0?Math.floor(e):Math.ceil(e))/2}(t-e);this.scrollContainer.scrollLeft+=i}}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){var i;const{scrollLeft:n,scrollWidth:s,clientWidth:r}=this.scrollContainer,o=t*s,a=n,l=n+r,h=r/2;if(this.isDragging){const t=30;o+t>l?this.scrollContainer.scrollLeft+=t:o-t<a&&(this.scrollContainer.scrollLeft-=t)}else{(o<a||o>l)&&(this.scrollContainer.scrollLeft=o-(this.options.autoCenter?h:0));const t=o-n-h;if(e&&this.options.autoCenter&&t>0){const e=null===(i=this.audioData)||void 0===i?void 0:i.duration;if(void 0===e||e<=0)return void(this.scrollContainer.scrollLeft+=t);const n=s/e;this.scrollContainer.scrollLeft+=n<=600?Math.min(t,10):t}}}renderProgress(t,e){if(isNaN(t))return;const i=100*t;this.canvasWrapper.style.clipPath=`polygon(${i}% 0%, 100% 0%, 100% 100%, ${i}% 100%)`,this.progressWrapper.style.width=`${i}%`,this.cursor.style.left=`${i}%`,this.cursor.style.transform=this.options.cursorWidth?`translateX(-${t*this.options.cursorWidth}px)`:"",this.isScrollable&&this.options.autoScroll&&this.audioData&&this.audioData.duration>0&&this.scrollIntoView(t,e)}exportImage(e,i,n){return t(this,void 0,void 0,(function*(){const t=this.canvasWrapper.querySelectorAll("canvas");if(!t.length)throw new Error("No waveform data");if("dataURL"===n){const n=Array.from(t).map((t=>t.toDataURL(e,i)));return Promise.resolve(n)}return Promise.all(Array.from(t).map((t=>new Promise(((n,s)=>{t.toBlob((t=>{t?n(t):s(new Error("Could not export image"))}),e,i)})))))}))}}class S extends e{constructor(){super(...arguments),this.animationFrameId=null,this.isRunning=!1}start(){if(this.isRunning)return;this.isRunning=!0;const t=()=>{this.isRunning&&(this.emit("tick"),this.animationFrameId=requestAnimationFrame(t))};t()}stop(){this.isRunning=!1,null!==this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}destroy(){this.stop(),this.unAll()}}class E extends e{constructor(t){super(),this.bufferNode=null,this.playStartTime=0,this.playbackPosition=0,this._muted=!1,this._playbackRate=1,this._duration=void 0,this.buffer=null,this.currentSrc="",this.paused=!0,this.crossOrigin=null,this.seeking=!1,this.autoplay=!1,this.addEventListener=this.on,this.removeEventListener=this.un,this._destroyed=!1,function(){const t=globalThis.navigator;if(null==t?void 0:t.audioSession)try{t.audioSession.type="playback"}catch(t){console.warn("Setting navigator.audioSession.type failed:",t)}}(),this.audioContext=t||new AudioContext,this.gainNode=this.audioContext.createGain(),this.gainNode.connect(this.audioContext.destination)}load(){return t(this,void 0,void 0,(function*(){}))}remove(){this.destroy()}destroy(){if(!this._destroyed){if(this._destroyed=!0,this.currentSrc="",this.bufferNode){this.bufferNode.onended=null;try{this.bufferNode.stop()}catch(t){}this.bufferNode.disconnect(),this.bufferNode=null}this.gainNode.disconnect(),"function"==typeof this.audioContext.close&&Promise.resolve(this.audioContext.close.call(this.audioContext)).catch((()=>{})),this.buffer=null,this.unAll()}}get src(){return this.currentSrc}set src(t){if(this.currentSrc=t,this._duration=void 0,!t)return this.buffer=null,void this.emit("emptied");fetch(t).then((e=>{if(e.status>=400)throw new Error(`Failed to fetch ${t}: ${e.status} (${e.statusText})`);return e.arrayBuffer()})).then((e=>this.currentSrc!==t?null:this.audioContext.decodeAudioData(e))).then((e=>{this.currentSrc===t&&(this.buffer=e,this.emit("loadedmetadata"),this.emit("canplay"),this.autoplay&&this.play())})).catch((t=>{console.error("WebAudioPlayer load error:",t)}))}_play(){if(!this.paused)return;this.paused=!1,this.bufferNode&&(this.bufferNode.onended=null,this.bufferNode.disconnect()),this.bufferNode=this.audioContext.createBufferSource(),this.buffer&&(this.bufferNode.buffer=this.buffer),this.bufferNode.playbackRate.value=this._playbackRate,this.bufferNode.connect(this.gainNode);let t=this.playbackPosition;(t>=this.duration||t<0)&&(t=0,this.playbackPosition=0),this.bufferNode.start(this.audioContext.currentTime,t),this.playStartTime=this.audioContext.currentTime,this.bufferNode.onended=()=>{!this.paused&&this.duration-this.currentTime<.01&&(this.pause(),this.emit("ended"))}}_pause(){if(this.paused=!0,this.bufferNode){this.bufferNode.onended=null;try{this.bufferNode.stop()}catch(t){}}this.playbackPosition+=(this.audioContext.currentTime-this.playStartTime)*this._playbackRate}play(){return t(this,void 0,void 0,(function*(){this.paused&&(this._play(),this.emit("play"))}))}pause(){this.paused||(this._pause(),this.emit("pause"))}stopAt(t){const e=(t-this.currentTime)/this._playbackRate,i=this.bufferNode;null==i||i.stop(this.audioContext.currentTime+e),null==i||i.addEventListener("ended",(()=>{i===this.bufferNode&&(this.bufferNode=null,this.pause(),this.playbackPosition=Math.min(t,this.duration),this.emit("timeupdate"))}),{once:!0})}setSinkId(e){return t(this,void 0,void 0,(function*(){return this.audioContext.setSinkId(e)}))}get playbackRate(){return this._playbackRate}set playbackRate(t){const e=!this.paused;e&&this._pause(),this._playbackRate=t,e&&this._play(),this.bufferNode&&(this.bufferNode.playbackRate.value=t)}get currentTime(){return this.paused?this.playbackPosition:this.playbackPosition+(this.audioContext.currentTime-this.playStartTime)*this._playbackRate}set currentTime(t){const e=!this.paused;e&&this._pause(),this.playbackPosition=t,e&&this._play(),this.emit("seeking"),this.emit("timeupdate")}get duration(){var t,e;return null!==(t=this._duration)&&void 0!==t?t:(null===(e=this.buffer)||void 0===e?void 0:e.duration)||0}set duration(t){this._duration=t}get volume(){return this.gainNode.gain.value}set volume(t){this.gainNode.gain.value=t,this.emit("volumechange")}get muted(){return this._muted}set muted(t){this._muted!==t&&(this._muted=t,this._muted?this.gainNode.disconnect():this.gainNode.connect(this.audioContext.destination))}canPlayType(t){return/^(audio|video)\//.test(t)}getGainNode(){return this.gainNode}getChannelData(){const t=[];if(!this.buffer)return t;const e=this.buffer.numberOfChannels;for(let i=0;i<e;i++)t.push(this.buffer.getChannelData(i));return t}removeAttribute(t){switch(t){case"src":this.src="";break;case"playbackRate":this.playbackRate=0;break;case"currentTime":this.currentTime=0;break;case"duration":this.duration=0;break;case"volume":this.volume=0;break;case"muted":this.muted=!1}}}const P={waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,dragToSeek:!1,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class w extends u{static create(t){return new w(t)}getState(){return this.wavesurferState}getRenderer(){return this.renderer}constructor(t){const e=t.media||("WebAudio"===t.backend?new E:void 0);super({media:e,mediaControls:t.mediaControls,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.stopAtPosition=null,this.subscriptions=[],this.mediaSubscriptions=[],this.abortController=null,this._isDestroyed=!1,this._loadVersion=0,this.reactiveCleanups=[],this.options=Object.assign({},P,t);const{state:i,actions:n}=function(t){var e,i,n,s,r,o;const a=null!==(e=null==t?void 0:t.currentTime)&&void 0!==e?e:l(0),c=null!==(i=null==t?void 0:t.duration)&&void 0!==i?i:l(0),u=null!==(n=null==t?void 0:t.isPlaying)&&void 0!==n?n:l(!1),d=null!==(s=null==t?void 0:t.isSeeking)&&void 0!==s?s:l(!1),p=null!==(r=null==t?void 0:t.volume)&&void 0!==r?r:l(1),m=null!==(o=null==t?void 0:t.playbackRate)&&void 0!==o?o:l(1),g=l(null),f=l(null),v=l(""),b=l(0),y=l(0),C=h((()=>!u.value),[u]),S=h((()=>null!==g.value),[g]),E=h((()=>S.value&&c.value>0),[S,c]),P=h((()=>a.value),[a]),w=h((()=>c.value>0?a.value/c.value:0),[a,c]);return{state:{currentTime:a,duration:c,isPlaying:u,isPaused:C,isSeeking:d,volume:p,playbackRate:m,audioBuffer:g,peaks:f,url:v,zoom:b,scrollPosition:y,canPlay:S,isReady:E,progress:P,progressPercent:w},actions:{setCurrentTime:t=>{const e=Math.max(0,Math.min(c.value||1/0,t));a.set(e)},setDuration:t=>{c.set(Math.max(0,t))},setPlaying:t=>{u.set(t)},setSeeking:t=>{d.set(t)},setVolume:t=>{const e=Math.max(0,Math.min(1,t));p.set(e)},setPlaybackRate:t=>{const e=Math.max(.1,Math.min(16,t));m.set(e)},setAudioBuffer:t=>{g.set(t),t&&c.set(t.duration)},setPeaks:t=>{f.set(t)},setUrl:t=>{v.set(t)},setZoom:t=>{b.set(Math.max(0,t))},setScrollPosition:t=>{y.set(Math.max(0,t))}}}}({isPlaying:this.isPlayingSignal,currentTime:this.currentTimeSignal,duration:this.durationSignal,volume:this.volumeSignal,playbackRate:this.playbackRateSignal,isSeeking:this.seekingSignal});this.wavesurferState=i,this.wavesurferActions=n,this.timer=new S;const s=e?void 0:this.getMediaElement();this.renderer=new C(this.options,s),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initReactiveState(),this.initPlugins();const r=this.options.url||this.getSrc()||"";Promise.resolve().then((()=>{this.emit("init");const{peaks:t,duration:e}=this.options;(r||t&&e)&&this.load(r,t,e).catch((()=>{}))}))}updateProgress(t=this.getCurrentTime()){return this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),t}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{if(!this.isSeeking()){const t=this.updateProgress();if(this.emit("timeupdate",t),this.emit("audioprocess",t),null!=this.stopAtPosition&&this.isPlaying()&&t>=this.stopAtPosition){const t=this.stopAtPosition;this.pause(),this.setTime(t)}}})))}initReactiveState(){this.reactiveCleanups.push(function(t,e){const i=[];i.push(c((()=>{const i=t.isPlaying.value;e.emit(i?"play":"pause")}),[t.isPlaying])),i.push(c((()=>{const i=t.currentTime.value;e.emit("timeupdate",i),t.isPlaying.value&&e.emit("audioprocess",i)}),[t.currentTime,t.isPlaying])),i.push(c((()=>{t.isSeeking.value&&e.emit("seeking",t.currentTime.value)}),[t.isSeeking,t.currentTime]));let n=!1;i.push(c((()=>{t.isReady.value&&!n&&(n=!0,e.emit("ready",t.duration.value))}),[t.isReady,t.duration])),i.push(c((()=>{null===t.audioBuffer.value&&(n=!1)}),[t.audioBuffer]));let s=!1;return i.push(c((()=>{const i=t.isPlaying.value,n=t.currentTime.value,r=t.duration.value,o=r>0&&n>=r;s&&!i&&o&&e.emit("finish"),s=i&&o}),[t.isPlaying,t.currentTime,t.duration])),i.push(c((()=>{const i=t.zoom.value;i>0&&e.emit("zoom",i)}),[t.zoom])),()=>{i.forEach((t=>t()))}}(this.wavesurferState,{emit:this.emit.bind(this)}))}initPlayerEvents(){this.isPlaying()&&(this.emit("play"),this.timer.start()),this.mediaSubscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.updateProgress();this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop(),this.stopAtPosition=null})),this.onMediaEvent("emptied",(()=>{this.timer.stop(),this.stopAtPosition=null})),this.onMediaEvent("ended",(()=>{this.emit("timeupdate",this.getDuration()),this.emit("finish"),this.stopAtPosition=null})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})),this.onMediaEvent("error",(()=>{var t;this.emit("error",null!==(t=this.getMediaElement().error)&&void 0!==t?t:new Error("Media error")),this.stopAtPosition=null})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",((t,e)=>{this.options.interact&&(this.seekTo(t),this.emit("interaction",t*this.getDuration()),this.emit("click",t,e))})),this.renderer.on("dblclick",((t,e)=>{this.emit("dblclick",t,e)})),this.renderer.on("scroll",((t,e,i,n)=>{const s=this.getDuration();this.emit("scroll",t*s,e*s,i,n)})),this.renderer.on("render",(()=>{this.emit("redraw")})),this.renderer.on("rendered",(()=>{this.emit("redrawcomplete")})),this.renderer.on("dragstart",(t=>{this.emit("dragstart",t)})),this.renderer.on("dragend",(t=>{this.emit("dragend",t)})),this.renderer.on("resize",(()=>{this.emit("resize")})));{let t;const e=this.renderer.on("drag",(e=>{var i;if(!this.options.interact)return;this.renderer.renderProgress(e),clearTimeout(t);let n=0;const s=this.options.dragToSeek;this.isPlaying()?n=0:!0===s?n=200:s&&"object"==typeof s&&(n=null!==(i=s.debounceTime)&&void 0!==i?i:200),t=setTimeout((()=>{this.seekTo(e)}),n),this.emit("interaction",e*this.getDuration()),this.emit("drag",e)}));this.subscriptions.push((()=>{clearTimeout(t),e()}))}}initPlugins(){var t;(null===(t=this.options.plugins)||void 0===t?void 0:t.length)&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}unsubscribePlayerEvents(){this.mediaSubscriptions.forEach((t=>t())),this.mediaSubscriptions=[]}setOptions(t){this.options=Object.assign({},this.options,t),t.duration&&!t.peaks&&(this.decodedData=i.createBuffer(this.exportPeaks(),t.duration)),t.peaks&&t.duration&&(this.decodedData=i.createBuffer(t.peaks,t.duration)),this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate),null!=t.mediaControls&&(this.getMediaElement().controls=t.mediaControls)}registerPlugin(t){if(this.plugins.includes(t))return t;t._init(this),this.plugins.push(t);const e=t.once("destroy",(()=>{this.plugins=this.plugins.filter((e=>e!==t)),this.subscriptions=this.subscriptions.filter((t=>t!==e))}));return this.subscriptions.push(e),t}unregisterPlugin(t){this.plugins=this.plugins.filter((e=>e!==t)),t.destroy()}getWrapper(){return this.renderer.getWrapper()}getWidth(){return this.renderer.getWidth()}getScroll(){return this.renderer.getScroll()}setScroll(t){return this.renderer.setScroll(t)}setScrollTime(t){const e=t/this.getDuration();this.renderer.setScrollPercentage(e)}getActivePlugins(){return this.plugins}loadAudio(e,n,s,r){return t(this,void 0,void 0,(function*(){var t;const o=++this._loadVersion;if(this._isDestroyed=!1,this.emit("load",e),!this.options.media&&this.isPlaying()&&this.pause(),this.decodedData=null,this.stopAtPosition=null,null===(t=this.abortController)||void 0===t||t.abort(),this.abortController=null,!n&&!s){const t=this.options.fetchParams||{};window.AbortController&&!t.signal&&(this.abortController=new AbortController,t.signal=this.abortController.signal);const i=t=>this.emit("loading",t);if(n=yield a.fetchBlob(e,i,t),this._isDestroyed||o!==this._loadVersion)return;const s=this.options.blobMimeType;s&&(n=new Blob([n],{type:s}))}if(this._isDestroyed||o!==this._loadVersion)return;this.setSrc(e,n);const l=yield new Promise((t=>{const e=r||this.getDuration();e?t(e):this.mediaSubscriptions.push(this.onMediaEvent("loadedmetadata",(()=>t(this.getDuration())),{once:!0}))}));if(!this._isDestroyed&&o===this._loadVersion){if(!e&&!n){const t=this.getMediaElement();t instanceof E&&(t.duration=l)}if(s)this.decodedData=i.createBuffer(s,l||0);else if(n){const t=yield n.arrayBuffer();if(this._isDestroyed||o!==this._loadVersion)return;this.decodedData=yield i.decode(t,this.options.sampleRate)}this._isDestroyed||o!==this._loadVersion||(this.decodedData&&(this.emit("decode",this.getDuration()),this.renderer.render(this.decodedData)),this.emit("ready",this.getDuration()))}}))}load(e,i,n){return t(this,void 0,void 0,(function*(){try{return yield this.loadAudio(e,void 0,i,n)}catch(t){throw this.emit("error",t),t}}))}loadBlob(e,i,n){return t(this,void 0,void 0,(function*(){try{return yield this.loadAudio("",e,i,n)}catch(t){throw this.emit("error",t),t}}))}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}exportPeaks({channels:t=2,maxLength:e=8e3,precision:i=1e4}={}){if(!this.decodedData)throw new Error("The audio has not been decoded yet");const n=Math.min(t,this.decodedData.numberOfChannels),s=[];for(let t=0;t<n;t++){const n=this.decodedData.getChannelData(t),r=[],o=n.length/e;for(let t=0;t<e;t++){const e=n.slice(Math.floor(t*o),Math.ceil((t+1)*o));let s=0;for(let t=0;t<e.length;t++){const i=e[t];Math.abs(i)>Math.abs(s)&&(s=i)}r.push(Math.round(s*i)/i)}s.push(r)}return s}getDuration(){let t=super.getDuration()||0;return 0!==t&&t!==1/0||!this.decodedData||(t=this.decodedData.duration),t}toggleInteraction(t){this.options.interact=t}setTime(t){this.stopAtPosition=null,super.setTime(t),this.updateProgress(t),this.emit("timeupdate",t)}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}play(e,i){const n=Object.create(null,{play:{get:()=>super.play}});return t(this,void 0,void 0,(function*(){null!=e&&this.setTime(e);const t=yield n.play.call(this);return null!=i&&(this.media instanceof E?this.media.stopAt(i):this.stopAtPosition=i),t}))}playPause(){return t(this,void 0,void 0,(function*(){return this.isPlaying()?this.pause():this.play()}))}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}setMediaElement(t){this.unsubscribePlayerEvents(),super.setMediaElement(t),this.initPlayerEvents()}exportImage(){return t(this,arguments,void 0,(function*(t="image/png",e=1,i="dataURL"){return this.renderer.exportImage(t,e,i)}))}destroy(){var t;this._isDestroyed=!0,this.emit("destroy"),null===(t=this.abortController)||void 0===t||t.abort(),this.plugins.forEach((t=>t.destroy())),this.subscriptions.forEach((t=>t())),this.unsubscribePlayerEvents(),this.reactiveCleanups.forEach((t=>t())),this.reactiveCleanups=[],this.timer.destroy(),this.renderer.destroy(),super.destroy()}}w.BasePlugin=class extends e{constructor(t){super(),this.subscriptions=[],this.isDestroyed=!1,this.options=t}onInit(){}_init(t){this.isDestroyed&&(this.subscriptions=[],this.isDestroyed=!1),this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.subscriptions=[],this.isDestroyed=!0,this.wavesurfer=void 0}},w.dom=o;
4069
4362
 
4363
+ // EXTERNAL MODULE: ./src/lib/util.js + 1 modules
4364
+ var util = __webpack_require__(4410);
4070
4365
  ;// ./src/lib/viewers/media/waveform/colors.ts
4071
4366
  /**
4072
4367
  * Figma Audio Player waveform tokens as opaque fills.
@@ -4085,14 +4380,6 @@ const WAVEFORM_COLOR_HOVER_PLAYED = whiteOnBlack(0.9);
4085
4380
  const WAVEFORM_COLOR_HOVER_AREA = whiteOnBlack(0.6);
4086
4381
  const WAVEFORM_COLOR_HOVER_UNPLAYED = whiteOnBlack(0.3);
4087
4382
  const WAVEFORM_COLOR_HOVER_BUFFER = whiteOnBlack(0.16);
4088
-
4089
- /** One canvas linear-gradient stop. `offset` is 0–1 along the bar. */
4090
-
4091
- /**
4092
- * Wavesurfer's two paints: left of the playhead (`progressColor`) and right of it (`waveColor`).
4093
- * A string is a solid fill; a stop list is a left-to-right step gradient.
4094
- */
4095
-
4096
4383
  /** Pin a value to the closed interval [0, 1]. */
4097
4384
  function clampTo0And1(value) {
4098
4385
  if (!Number.isFinite(value) || value < 0) {
@@ -4227,29 +4514,144 @@ function toCanvasFill(color, widthPx) {
4227
4514
  });
4228
4515
  return gradient;
4229
4516
  }
4517
+
4518
+ /** Untinted bar pixels for each WaveSurfer tile, so hover can re-tint without stacking. */
4519
+ const tileBarSnapshots = new WeakMap();
4520
+
4521
+ /** Restore the last bar snapshot, or take a new one after WaveSurfer redraws. */
4522
+ function restoreOrSnapshotTile(canvas, context, replaceSnapshot) {
4523
+ if (!(canvas.width > 0) || !(canvas.height > 0) || !context.getImageData) {
4524
+ return;
4525
+ }
4526
+ const stored = tileBarSnapshots.get(canvas);
4527
+ if (!replaceSnapshot && stored && context.putImageData) {
4528
+ context.putImageData(stored, 0, 0);
4529
+ return;
4530
+ }
4531
+ try {
4532
+ tileBarSnapshots.set(canvas, context.getImageData(0, 0, canvas.width, canvas.height));
4533
+ } catch {
4534
+ // Tainted or zero-size canvases cannot snapshot; tint in place.
4535
+ }
4536
+ }
4537
+
4538
+ /** CSS width of a tile canvas (style.width, then clientWidth, then bitmap width). */
4539
+ function tileWidthCss(canvas) {
4540
+ const styled = parseFloat(canvas.style.width);
4541
+ if (styled > 0) {
4542
+ return styled;
4543
+ }
4544
+ if (canvas.clientWidth > 0) {
4545
+ return canvas.clientWidth;
4546
+ }
4547
+ return canvas.width;
4548
+ }
4549
+
4550
+ /** Solid color, or a gradient aligned to the full waveform and shifted to this tile. */
4551
+ function fillForTile(context, color, totalWidthCss, offsetCss, canvas) {
4552
+ if (typeof color === 'string') {
4553
+ return color;
4554
+ }
4555
+ const cssWidth = tileWidthCss(canvas);
4556
+ const scale = cssWidth > 0 ? canvas.width / cssWidth : 1;
4557
+ if (!(totalWidthCss > 0) || !(scale > 0)) {
4558
+ return color[0] ? color[0].color : WAVEFORM_COLOR_UNPLAYED;
4559
+ }
4560
+ const x0 = -offsetCss * scale || 0;
4561
+ const x1 = (totalWidthCss - offsetCss) * scale;
4562
+ const gradient = context.createLinearGradient(x0, 0, x1, 0);
4563
+ let lastOffset = -1;
4564
+ color.forEach(stop => {
4565
+ let offset = clampTo0And1(stop.offset);
4566
+ if (offset <= lastOffset) {
4567
+ offset = Math.min(1, lastOffset + 1e-6);
4568
+ }
4569
+ lastOffset = offset;
4570
+ gradient.addColorStop(offset, stop.color);
4571
+ });
4572
+ return gradient;
4573
+ }
4574
+
4575
+ /**
4576
+ * Wavesurfer splits a zoomed waveform into viewport-sized tiles and paints each
4577
+ * from x=0. Re-tint with a gradient in global waveform space so hover/buffer
4578
+ * colors do not repeat on the last tile.
4579
+ */
4580
+ function tintWaveformTiles({
4581
+ fills,
4582
+ host,
4583
+ replaceSnapshot = false,
4584
+ totalWidthCss
4585
+ }) {
4586
+ if (!(totalWidthCss > 0) || !host.querySelectorAll) {
4587
+ return;
4588
+ }
4589
+ const groups = [{
4590
+ canvases: host.querySelectorAll('.canvases canvas'),
4591
+ color: fills.waveColor
4592
+ }, {
4593
+ canvases: host.querySelectorAll('.progress canvas'),
4594
+ color: fills.progressColor
4595
+ }];
4596
+ groups.forEach(({
4597
+ canvases,
4598
+ color
4599
+ }) => {
4600
+ canvases.forEach(canvas => {
4601
+ const context = canvas.getContext('2d');
4602
+ if (!context) {
4603
+ return;
4604
+ }
4605
+ restoreOrSnapshotTile(canvas, context, replaceSnapshot);
4606
+ const offsetCss = parseFloat(canvas.style.left) || 0;
4607
+ context.save();
4608
+ context.globalCompositeOperation = 'source-in';
4609
+ context.fillStyle = fillForTile(context, color, totalWidthCss, offsetCss, canvas);
4610
+ context.fillRect(0, 0, canvas.width, canvas.height);
4611
+ context.restore();
4612
+ });
4613
+ });
4614
+ }
4230
4615
  ;// ./src/lib/viewers/media/waveform/WaveformView.scss
4231
4616
  // extracted by mini-css-extract-plugin
4232
4617
 
4233
4618
  ;// ./src/lib/viewers/media/waveform/WaveformView.tsx
4619
+ function WaveformView_ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4620
+ function WaveformView_objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? WaveformView_ownKeys(Object(t), !0).forEach(function (r) { WaveformView_defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : WaveformView_ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4621
+ function WaveformView_defineProperty(e, r, t) { return (r = WaveformView_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
4622
+ function WaveformView_toPropertyKey(t) { var i = WaveformView_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
4623
+ function WaveformView_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
4234
4624
 
4235
4625
 
4236
4626
 
4237
4627
 
4238
4628
 
4239
- const WAVEFORM_BAR_GAP = 2;
4240
- const WAVEFORM_BAR_WIDTH = 2;
4241
- const WAVEFORM_BAR_RADIUS = WAVEFORM_BAR_WIDTH / 2;
4242
- /** Total bar height so the top and bottom radii meet as a circle on the mirror. */
4243
- const WAVEFORM_BAR_MIN_HEIGHT = WAVEFORM_BAR_WIDTH;
4244
- const WAVEFORM_HEIGHT = 140;
4245
- function leftPercent(timeSec, durationSec) {
4246
- const progress = durationSec > 0 ? Math.min(1, Math.max(0, timeSec / durationSec)) : 0;
4247
- return `${progress * 100}%`;
4248
- }
4249
- function fillWidth(widthCssPx) {
4629
+
4630
+
4631
+
4632
+
4633
+ /** Pointer X in the view and the media time under it; zoom keeps this point fixed. */
4634
+
4635
+ /** CSS width × devicePixelRatio, for canvas gradient fills. */
4636
+ function devicePixelWidth(widthCssPx) {
4250
4637
  const pixelRatio = typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1;
4251
4638
  return widthCssPx * pixelRatio;
4252
4639
  }
4640
+ function prefersReducedMotion() {
4641
+ return typeof window !== 'undefined' && typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
4642
+ }
4643
+ function getScrollLeft(wavesurfer, fallback = 0) {
4644
+ return wavesurfer && wavesurfer.getScroll ? wavesurfer.getScroll() : fallback;
4645
+ }
4646
+
4647
+ /** CSS left % of the playhead from the left of the visible window. */
4648
+ function timeLeftPercent(timeSec, durationSec, viewport) {
4649
+ if (viewport.widthPx > 0 && viewport.pixelsPerSecond > 0) {
4650
+ return `${positionPxFromTime(timeSec, viewport) / viewport.widthPx * 100}%`;
4651
+ }
4652
+ const progress = durationSec > 0 ? Math.min(1, Math.max(0, timeSec / durationSec)) : 0;
4653
+ return `${progress * 100}%`;
4654
+ }
4253
4655
  function applyPeaks(wavesurfer, peaks, durationSec) {
4254
4656
  if (!wavesurfer.load) {
4255
4657
  return;
@@ -4257,6 +4659,44 @@ function applyPeaks(wavesurfer, peaks, durationSec) {
4257
4659
  wavesurfer.load('', toChannels(peaks), durationSec);
4258
4660
  }
4259
4661
 
4662
+ /** Tint WaveSurfer's zoomed tiles with played/unplayed/hover/buffer colors. */
4663
+ function tintZoomedWaveform(wavesurfer, fills, replaceSnapshot = false) {
4664
+ const wrapper = wavesurfer.getWrapper ? wavesurfer.getWrapper() : null;
4665
+ if (!wrapper || !(wrapper.clientWidth > 0)) {
4666
+ return;
4667
+ }
4668
+ tintWaveformTiles({
4669
+ fills,
4670
+ host: wrapper,
4671
+ replaceSnapshot,
4672
+ totalWidthCss: wrapper.clientWidth
4673
+ });
4674
+ }
4675
+ function touchDistance(touches) {
4676
+ if (touches.length < 2) {
4677
+ return 0;
4678
+ }
4679
+ const dx = touches[0].clientX - touches[1].clientX;
4680
+ const dy = touches[0].clientY - touches[1].clientY;
4681
+ return Math.hypot(dx, dy);
4682
+ }
4683
+
4684
+ /** Time under the pointer, plus its X in the view, so zoom can keep that point fixed. */
4685
+ function zoomOriginAtPointer(pointerX, wavesurfer, durationSec, fallbackWidth) {
4686
+ if (!(fallbackWidth > 0) || !(durationSec > 0) || !Number.isFinite(pointerX)) {
4687
+ return null;
4688
+ }
4689
+ const wrapper = wavesurfer && wavesurfer.getWrapper ? wavesurfer.getWrapper() : null;
4690
+ const fullWidth = wrapper && wrapper.clientWidth ? wrapper.clientWidth : fallbackWidth;
4691
+ if (!(fullWidth > 0)) {
4692
+ return null;
4693
+ }
4694
+ return {
4695
+ pointerX,
4696
+ timeSec: (getScrollLeft(wavesurfer) + pointerX) / fullWidth * durationSec
4697
+ };
4698
+ }
4699
+
4260
4700
  /**
4261
4701
  * Renders V1 peaks with wavesurfer. Does not fetch audio or attach a media element.
4262
4702
  */
@@ -4264,42 +4704,114 @@ function WaveformView({
4264
4704
  bufferedRange,
4265
4705
  currentTime = 0,
4266
4706
  durationSec,
4267
- height = WAVEFORM_HEIGHT,
4707
+ height = constants/* WAVEFORM_HEIGHT */.oN,
4268
4708
  interactive = true,
4269
4709
  mediaEl,
4270
4710
  onSeek,
4271
- peaks
4711
+ onViewportChange,
4712
+ onZoomChange,
4713
+ peaks,
4714
+ zoomLevel: zoomLevelProp
4272
4715
  }) {
4273
4716
  const containerRef = (0,external_react_.useRef)(null);
4717
+ const trackRef = (0,external_react_.useRef)(null);
4274
4718
  const playheadRef = (0,external_react_.useRef)(null);
4275
- const playheadRafRef = (0,external_react_.useRef)(0);
4719
+ const playheadAnimationRef = (0,external_react_.useRef)(0);
4276
4720
  const wavesurferRef = (0,external_react_.useRef)(null);
4277
4721
  const onSeekRef = (0,external_react_.useRef)(onSeek);
4278
4722
  const interactiveRef = (0,external_react_.useRef)(interactive);
4723
+ const hasZoomHandlersRef = (0,external_react_.useRef)(false);
4279
4724
  const currentTimeRef = (0,external_react_.useRef)(currentTime);
4280
4725
  const peaksRef = (0,external_react_.useRef)(peaks);
4281
4726
  const displayedPeaksRef = (0,external_react_.useRef)(null);
4282
- const peakTransitionRafRef = (0,external_react_.useRef)(0);
4727
+ const peakTransitionAnimationRef = (0,external_react_.useRef)(0);
4283
4728
  const durationSecRef = (0,external_react_.useRef)(durationSec);
4729
+ const zoomOriginRef = (0,external_react_.useRef)(null);
4730
+ const pinchStartRef = (0,external_react_.useRef)(null);
4731
+ const bufferProgressRef = (0,external_react_.useRef)(0);
4732
+ const hoverProgressRef = (0,external_react_.useRef)(null);
4733
+ const programmaticScrollRef = (0,external_react_.useRef)(false);
4734
+ const onViewportChangeRef = (0,external_react_.useRef)(onViewportChange);
4284
4735
  onSeekRef.current = onSeek;
4285
4736
  interactiveRef.current = interactive;
4286
4737
  currentTimeRef.current = currentTime;
4287
4738
  peaksRef.current = peaks;
4288
4739
  durationSecRef.current = durationSec;
4740
+ onViewportChangeRef.current = onViewportChange;
4741
+ const [internalZoom, setInternalZoom] = (0,external_react_.useState)(constants/* WAVEFORM_ZOOM_MIN */.LW);
4289
4742
  const [hoverProgress, setHoverProgress] = (0,external_react_.useState)(null);
4290
4743
  const [canvasWidthPx, setCanvasWidthPx] = (0,external_react_.useState)(0);
4744
+ const [scrollLeft, setScrollLeft] = (0,external_react_.useState)(0);
4745
+ const isControlled = typeof zoomLevelProp === 'number';
4746
+ const maxZoom = getWaveformZoomMax({
4747
+ durationSec,
4748
+ peakCount: peaks.length,
4749
+ viewWidthPx: canvasWidthPx
4750
+ });
4751
+ hasZoomHandlersRef.current = maxZoom > constants/* WAVEFORM_ZOOM_MIN */.LW && (typeof onZoomChange === 'function' || typeof zoomLevelProp !== 'number');
4752
+ const zoomLevel = clampWaveformZoom(isControlled ? zoomLevelProp : internalZoom, maxZoom);
4753
+ const zoomRef = (0,external_react_.useRef)(zoomLevel);
4754
+ zoomRef.current = zoomLevel;
4755
+ const prevZoomRef = (0,external_react_.useRef)(null);
4756
+ const isZoomed = zoomLevel > constants/* WAVEFORM_ZOOM_MIN */.LW;
4291
4757
  const bufferProgress = getBufferedProgress(bufferedRange, durationSec);
4758
+ bufferProgressRef.current = bufferProgress;
4759
+ hoverProgressRef.current = hoverProgress;
4760
+ const viewport = (0,external_react_.useMemo)(() => createWaveformViewport({
4761
+ durationSec,
4762
+ heightPx: height,
4763
+ maxZoom,
4764
+ scrollLeftPx: scrollLeft,
4765
+ widthPx: canvasWidthPx,
4766
+ zoomLevel
4767
+ }), [canvasWidthPx, durationSec, height, maxZoom, scrollLeft, zoomLevel]);
4768
+ const viewportRef = (0,external_react_.useRef)(viewport);
4769
+ viewportRef.current = viewport;
4770
+ const setZoomLevel = (0,external_react_.useCallback)(nextZoom => {
4771
+ const zoom = clampWaveformZoom(nextZoom, maxZoom);
4772
+ if (!isControlled) {
4773
+ setInternalZoom(zoom);
4774
+ }
4775
+ onZoomChange?.(zoom);
4776
+ }, [isControlled, maxZoom, onZoomChange]);
4777
+ const syncViewport = (0,external_react_.useCallback)(() => {
4778
+ const wavesurfer = wavesurferRef.current;
4779
+ if (!wavesurfer) {
4780
+ return;
4781
+ }
4782
+ const scrollLeftPx = getScrollLeft(wavesurfer);
4783
+ viewportRef.current = getViewportAtScroll(viewportRef.current, scrollLeftPx);
4784
+ onViewportChangeRef.current?.(viewportRef.current);
4785
+ setScrollLeft(scrollLeftPx);
4786
+ }, []);
4292
4787
  const updatePlayheadPosition = (0,external_react_.useCallback)(timeSec => {
4293
4788
  const playhead = playheadRef.current;
4294
4789
  if (!playhead) {
4295
4790
  return;
4296
4791
  }
4297
- playhead.style.left = leftPercent(timeSec, durationSecRef.current);
4792
+ playhead.style.left = timeLeftPercent(timeSec, durationSecRef.current, viewportRef.current);
4298
4793
  const wavesurfer = wavesurferRef.current;
4299
4794
  if (wavesurfer && wavesurfer.setTime) {
4300
4795
  wavesurfer.setTime(timeSec);
4301
4796
  }
4302
4797
  }, []);
4798
+ const applyScrollLeft = (0,external_react_.useCallback)((scrollLeftPx, shouldCommitState) => {
4799
+ const wavesurfer = wavesurferRef.current;
4800
+ if (!wavesurfer || !wavesurfer.setScroll) {
4801
+ return;
4802
+ }
4803
+ programmaticScrollRef.current = true;
4804
+ wavesurfer.setScroll(scrollLeftPx);
4805
+ viewportRef.current = getViewportAtScroll(viewportRef.current, getScrollLeft(wavesurfer, scrollLeftPx));
4806
+ window.requestAnimationFrame(() => {
4807
+ // Keep the flag through delayed `scroll` after a zoom setScroll.
4808
+ programmaticScrollRef.current = false;
4809
+ });
4810
+ if (shouldCommitState) {
4811
+ onViewportChangeRef.current?.(viewportRef.current);
4812
+ setScrollLeft(getScrollLeft(wavesurfer, scrollLeftPx));
4813
+ }
4814
+ }, []);
4303
4815
  (0,external_react_.useEffect)(() => {
4304
4816
  const container = containerRef.current;
4305
4817
  if (!container) {
@@ -4307,10 +4819,10 @@ function WaveformView({
4307
4819
  }
4308
4820
  const wavesurfer = w.create({
4309
4821
  autoScroll: false,
4310
- barGap: WAVEFORM_BAR_GAP,
4311
- barMinHeight: WAVEFORM_BAR_MIN_HEIGHT,
4312
- barRadius: WAVEFORM_BAR_RADIUS,
4313
- barWidth: WAVEFORM_BAR_WIDTH,
4822
+ barGap: constants/* WAVEFORM_BAR_GAP */.Lu,
4823
+ barMinHeight: constants/* WAVEFORM_BAR_MIN_HEIGHT */.XS,
4824
+ barRadius: constants/* WAVEFORM_BAR_RADIUS */.DY,
4825
+ barWidth: constants/* WAVEFORM_BAR_WIDTH */.zo,
4314
4826
  container,
4315
4827
  cursorWidth: 0,
4316
4828
  duration: durationSecRef.current,
@@ -4329,16 +4841,39 @@ function WaveformView({
4329
4841
  }
4330
4842
  onSeekRef.current?.(relativeX * durationSecRef.current);
4331
4843
  });
4844
+ const unsubscribeScroll = wavesurfer.on('scroll', () => {
4845
+ if (programmaticScrollRef.current) {
4846
+ viewportRef.current = getViewportAtScroll(viewportRef.current, getScrollLeft(wavesurfer));
4847
+ return;
4848
+ }
4849
+ syncViewport();
4850
+ });
4851
+ const unsubscribeZoom = wavesurfer.on('zoom', () => {
4852
+ syncViewport();
4853
+ });
4854
+ const unsubscribeRedraw = wavesurfer.on('redrawcomplete', () => {
4855
+ if (!(zoomRef.current > constants/* WAVEFORM_ZOOM_MIN */.LW)) {
4856
+ return;
4857
+ }
4858
+ tintZoomedWaveform(wavesurfer, getWaveformFills({
4859
+ bufferProgress: bufferProgressRef.current,
4860
+ hoverProgress: hoverProgressRef.current
4861
+ }), true);
4862
+ });
4332
4863
  wavesurferRef.current = wavesurfer;
4333
4864
  displayedPeaksRef.current = peaksRef.current;
4865
+ syncViewport();
4334
4866
  return () => {
4335
- window.cancelAnimationFrame(peakTransitionRafRef.current);
4867
+ window.cancelAnimationFrame(peakTransitionAnimationRef.current);
4336
4868
  unsubscribeClick();
4869
+ unsubscribeScroll();
4870
+ unsubscribeZoom();
4871
+ unsubscribeRedraw();
4337
4872
  wavesurfer.destroy();
4338
4873
  wavesurferRef.current = null;
4339
4874
  displayedPeaksRef.current = null;
4340
4875
  };
4341
- }, [height]);
4876
+ }, [height, syncViewport]);
4342
4877
  (0,external_react_.useLayoutEffect)(() => {
4343
4878
  const el = containerRef.current;
4344
4879
  if (!el) {
@@ -4349,10 +4884,24 @@ function WaveformView({
4349
4884
  entries.forEach(entry => {
4350
4885
  setCanvasWidthPx(entry.contentRect.width);
4351
4886
  });
4887
+ syncViewport();
4352
4888
  });
4353
4889
  observer.observe(el);
4354
4890
  return () => observer.disconnect();
4355
- }, []);
4891
+ }, [syncViewport]);
4892
+ (0,external_react_.useEffect)(() => {
4893
+ const rawZoom = isControlled ? zoomLevelProp : internalZoom;
4894
+ const clamped = clampWaveformZoom(typeof rawZoom === 'number' ? rawZoom : constants/* WAVEFORM_ZOOM_MIN */.LW, maxZoom);
4895
+ if (clamped === rawZoom) {
4896
+ return;
4897
+ }
4898
+ if (!isControlled) {
4899
+ setInternalZoom(clamped);
4900
+ }
4901
+ }, [internalZoom, isControlled, maxZoom, zoomLevelProp]);
4902
+ (0,external_react_.useEffect)(() => {
4903
+ onViewportChange?.(viewport);
4904
+ }, [onViewportChange, viewport]);
4356
4905
  (0,external_react_.useEffect)(() => {
4357
4906
  const wavesurfer = wavesurferRef.current;
4358
4907
  if (!wavesurfer || !wavesurfer.setOptions) {
@@ -4362,13 +4911,48 @@ function WaveformView({
4362
4911
  interact: interactive
4363
4912
  });
4364
4913
  }, [interactive]);
4914
+ (0,external_react_.useEffect)(() => {
4915
+ const wavesurfer = wavesurferRef.current;
4916
+ const container = containerRef.current;
4917
+ if (!wavesurfer || !wavesurfer.setOptions || !container) {
4918
+ return;
4919
+ }
4920
+ const viewWidthPx = wavesurfer.getWidth ? wavesurfer.getWidth() : container.clientWidth;
4921
+ const minPxPerSec = getZoomedPixelsPerSecond({
4922
+ durationSec,
4923
+ maxZoom,
4924
+ viewWidthPx,
4925
+ zoomLevel
4926
+ });
4927
+ wavesurfer.setOptions(WaveformView_objectSpread({
4928
+ autoScroll: false,
4929
+ minPxPerSec
4930
+ }, zoomLevel > constants/* WAVEFORM_ZOOM_MIN */.LW ? {
4931
+ progressColor: WAVEFORM_COLOR_PLAYED,
4932
+ waveColor: WAVEFORM_COLOR_UNPLAYED
4933
+ } : {}));
4934
+ const origin = zoomOriginRef.current;
4935
+ zoomOriginRef.current = null;
4936
+ const didZoomChange = prevZoomRef.current !== zoomLevel;
4937
+ prevZoomRef.current = zoomLevel;
4938
+ if (minPxPerSec > 0) {
4939
+ if (origin) {
4940
+ applyScrollLeft(origin.timeSec * minPxPerSec - origin.pointerX, true);
4941
+ } else if (didZoomChange) {
4942
+ const maxScroll = Math.max(0, durationSec * minPxPerSec - viewWidthPx);
4943
+ applyScrollLeft(Math.min(maxScroll, Math.max(0, currentTimeRef.current * minPxPerSec - viewWidthPx / 2)), true);
4944
+ }
4945
+ }
4946
+ wavesurfer.setTime(currentTimeRef.current);
4947
+ syncViewport();
4948
+ }, [applyScrollLeft, durationSec, maxZoom, syncViewport, zoomLevel]);
4365
4949
  (0,external_react_.useLayoutEffect)(() => {
4366
4950
  if (mediaEl && !mediaEl.paused) {
4367
4951
  updatePlayheadPosition(mediaEl.currentTime);
4368
4952
  return;
4369
4953
  }
4370
4954
  updatePlayheadPosition(currentTime);
4371
- }, [currentTime, durationSec, mediaEl, updatePlayheadPosition]);
4955
+ }, [currentTime, durationSec, mediaEl, updatePlayheadPosition, viewport]);
4372
4956
  (0,external_react_.useEffect)(() => {
4373
4957
  const media = mediaEl;
4374
4958
  if (!media) {
@@ -4378,14 +4962,14 @@ function WaveformView({
4378
4962
  if (!media.paused) {
4379
4963
  updatePlayheadPosition(media.currentTime);
4380
4964
  }
4381
- playheadRafRef.current = window.requestAnimationFrame(tick);
4965
+ playheadAnimationRef.current = window.requestAnimationFrame(tick);
4382
4966
  };
4383
4967
  const startLoop = () => {
4384
- window.cancelAnimationFrame(playheadRafRef.current);
4385
- playheadRafRef.current = window.requestAnimationFrame(tick);
4968
+ window.cancelAnimationFrame(playheadAnimationRef.current);
4969
+ playheadAnimationRef.current = window.requestAnimationFrame(tick);
4386
4970
  };
4387
4971
  const stopLoop = () => {
4388
- window.cancelAnimationFrame(playheadRafRef.current);
4972
+ window.cancelAnimationFrame(playheadAnimationRef.current);
4389
4973
  updatePlayheadPosition(media.currentTime);
4390
4974
  };
4391
4975
  const handleSeeked = () => {
@@ -4395,11 +4979,13 @@ function WaveformView({
4395
4979
  startLoop();
4396
4980
  }
4397
4981
  media.addEventListener('play', startLoop);
4982
+ media.addEventListener('playing', startLoop);
4398
4983
  media.addEventListener('pause', stopLoop);
4399
4984
  media.addEventListener('seeked', handleSeeked);
4400
4985
  return () => {
4401
- window.cancelAnimationFrame(playheadRafRef.current);
4986
+ window.cancelAnimationFrame(playheadAnimationRef.current);
4402
4987
  media.removeEventListener('play', startLoop);
4988
+ media.removeEventListener('playing', startLoop);
4403
4989
  media.removeEventListener('pause', stopLoop);
4404
4990
  media.removeEventListener('seeked', handleSeeked);
4405
4991
  };
@@ -4409,28 +4995,27 @@ function WaveformView({
4409
4995
  if (!wavesurfer || !wavesurfer.setOptions || !(durationSec > 0)) {
4410
4996
  return undefined;
4411
4997
  }
4998
+ window.cancelAnimationFrame(peakTransitionAnimationRef.current);
4412
4999
  const fromPeaks = displayedPeaksRef.current;
4413
- const reduceMotion = typeof window !== 'undefined' && typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
4414
- window.cancelAnimationFrame(peakTransitionRafRef.current);
4415
- if (!fromPeaks || fromPeaks === peaks || reduceMotion) {
5000
+ if (!fromPeaks || fromPeaks === peaks || prefersReducedMotion()) {
4416
5001
  displayedPeaksRef.current = peaks;
4417
5002
  applyPeaks(wavesurfer, peaks, durationSec);
4418
5003
  return undefined;
4419
5004
  }
4420
- const start = typeof performance !== 'undefined' ? performance.now() : Date.now();
5005
+ const start = (0,util/* getCurrentTimeMs */.RU)();
4421
5006
  const tick = now => {
4422
5007
  const elapsedMs = now - start;
4423
5008
  const framePeaks = morphPeaks(fromPeaks, peaks, elapsedMs);
4424
5009
  displayedPeaksRef.current = framePeaks;
4425
5010
  applyPeaks(wavesurfer, framePeaks, durationSec);
4426
5011
  if (elapsedMs < WAVEFORM_PEAK_TRANSITION_MS) {
4427
- peakTransitionRafRef.current = window.requestAnimationFrame(tick);
5012
+ peakTransitionAnimationRef.current = window.requestAnimationFrame(tick);
4428
5013
  } else {
4429
5014
  displayedPeaksRef.current = peaks;
4430
5015
  }
4431
5016
  };
4432
- peakTransitionRafRef.current = window.requestAnimationFrame(tick);
4433
- return () => window.cancelAnimationFrame(peakTransitionRafRef.current);
5017
+ peakTransitionAnimationRef.current = window.requestAnimationFrame(tick);
5018
+ return () => window.cancelAnimationFrame(peakTransitionAnimationRef.current);
4434
5019
  }, [durationSec, peaks]);
4435
5020
  (0,external_react_.useEffect)(() => {
4436
5021
  const wavesurfer = wavesurferRef.current;
@@ -4441,12 +5026,91 @@ function WaveformView({
4441
5026
  bufferProgress,
4442
5027
  hoverProgress
4443
5028
  });
5029
+ if (isZoomed) {
5030
+ tintZoomedWaveform(wavesurfer, fills);
5031
+ return;
5032
+ }
4444
5033
  wavesurfer.setOptions({
4445
- progressColor: toCanvasFill(fills.progressColor, fillWidth(canvasWidthPx)),
4446
- waveColor: toCanvasFill(fills.waveColor, fillWidth(canvasWidthPx))
5034
+ progressColor: toCanvasFill(fills.progressColor, devicePixelWidth(canvasWidthPx)),
5035
+ waveColor: toCanvasFill(fills.waveColor, devicePixelWidth(canvasWidthPx))
4447
5036
  });
4448
5037
  wavesurfer.setTime(currentTimeRef.current);
4449
- }, [bufferProgress, canvasWidthPx, hoverProgress]);
5038
+ }, [bufferProgress, canvasWidthPx, hoverProgress, isZoomed]);
5039
+ (0,external_react_.useEffect)(() => {
5040
+ const track = trackRef.current;
5041
+ if (!track) {
5042
+ return undefined;
5043
+ }
5044
+
5045
+ /** Remember the time under this pointer so pinch/wheel zoom stays anchored. */
5046
+ const captureZoomOrigin = clientX => {
5047
+ const rect = track.getBoundingClientRect();
5048
+ zoomOriginRef.current = zoomOriginAtPointer(clientX - rect.left, wavesurferRef.current, durationSec, rect.width);
5049
+ };
5050
+
5051
+ /** Zoom origin at the midpoint of a two-finger pinch. */
5052
+ const zoomOriginFromPinch = touches => {
5053
+ if (touches.length < 2) {
5054
+ return null;
5055
+ }
5056
+ const rect = track.getBoundingClientRect();
5057
+ const pointerX = (touches[0].clientX + touches[1].clientX) / 2 - rect.left;
5058
+ return zoomOriginAtPointer(pointerX, wavesurferRef.current, durationSec, rect.width);
5059
+ };
5060
+
5061
+ /** Ctrl/meta + wheel zooms around the pointer. */
5062
+ const onZoomWheel = event => {
5063
+ if (!interactiveRef.current || !hasZoomHandlersRef.current || !event.ctrlKey && !event.metaKey) {
5064
+ return;
5065
+ }
5066
+ event.preventDefault();
5067
+ captureZoomOrigin(event.clientX);
5068
+ setZoomLevel(zoomRef.current * Math.exp(-event.deltaY * 0.01));
5069
+ };
5070
+ const onTouchStart = event => {
5071
+ if (!interactiveRef.current || !hasZoomHandlersRef.current || event.touches.length !== 2) {
5072
+ pinchStartRef.current = null;
5073
+ return;
5074
+ }
5075
+ zoomOriginRef.current = zoomOriginFromPinch(event.touches);
5076
+ pinchStartRef.current = {
5077
+ distance: touchDistance(event.touches),
5078
+ zoom: zoomRef.current
5079
+ };
5080
+ };
5081
+ const onTouchMove = event => {
5082
+ const pinch = pinchStartRef.current;
5083
+ if (!interactiveRef.current || !hasZoomHandlersRef.current || !pinch || event.touches.length !== 2 || !(pinch.distance > 0)) {
5084
+ return;
5085
+ }
5086
+ event.preventDefault();
5087
+ zoomOriginRef.current = zoomOriginFromPinch(event.touches);
5088
+ setZoomLevel(pinch.zoom * (touchDistance(event.touches) / pinch.distance));
5089
+ };
5090
+ const onTouchEnd = event => {
5091
+ if (event.touches.length < 2) {
5092
+ pinchStartRef.current = null;
5093
+ }
5094
+ };
5095
+ track.addEventListener('wheel', onZoomWheel, {
5096
+ passive: false
5097
+ });
5098
+ track.addEventListener('touchstart', onTouchStart, {
5099
+ passive: true
5100
+ });
5101
+ track.addEventListener('touchmove', onTouchMove, {
5102
+ passive: false
5103
+ });
5104
+ track.addEventListener('touchend', onTouchEnd);
5105
+ track.addEventListener('touchcancel', onTouchEnd);
5106
+ return () => {
5107
+ track.removeEventListener('wheel', onZoomWheel);
5108
+ track.removeEventListener('touchstart', onTouchStart);
5109
+ track.removeEventListener('touchmove', onTouchMove);
5110
+ track.removeEventListener('touchend', onTouchEnd);
5111
+ track.removeEventListener('touchcancel', onTouchEnd);
5112
+ };
5113
+ }, [durationSec, setZoomLevel]);
4450
5114
  const onHoverMove = (0,external_react_.useCallback)(event => {
4451
5115
  if (!interactive) {
4452
5116
  return;
@@ -4455,20 +5119,26 @@ function WaveformView({
4455
5119
  if (!(rect.width > 0) || !(durationSec > 0)) {
4456
5120
  return;
4457
5121
  }
4458
- const x = event.clientX - rect.left;
4459
- if (!Number.isFinite(x)) {
5122
+ const pointerX = event.clientX - rect.left;
5123
+ if (!Number.isFinite(pointerX)) {
4460
5124
  return;
4461
5125
  }
4462
- setHoverProgress(Math.min(1, Math.max(0, x / rect.width)));
5126
+ const vp = viewportRef.current;
5127
+ if (vp.pixelsPerSecond > 0) {
5128
+ setHoverProgress(Math.min(1, Math.max(0, timeFromPositionPx(pointerX, vp) / durationSec)));
5129
+ return;
5130
+ }
5131
+ setHoverProgress(Math.min(1, Math.max(0, pointerX / rect.width)));
4463
5132
  }, [durationSec, interactive]);
4464
5133
  const onHoverLeave = (0,external_react_.useCallback)(() => {
4465
5134
  setHoverProgress(null);
4466
5135
  }, []);
4467
- const hoverLeft = hoverProgress == null ? null : `${hoverProgress * 100}%`;
5136
+ const hoverLeft = hoverProgress == null ? null : timeLeftPercent(hoverProgress * durationSec, durationSec, viewportRef.current);
4468
5137
  return /*#__PURE__*/external_react_["default"].createElement("div", {
4469
- className: `bp-WaveformView${interactive ? '' : ' bp-WaveformView--inert'}`,
5138
+ className: `bp-WaveformView${interactive ? '' : ' bp-WaveformView--inert'}${isZoomed ? ' bp-WaveformView--zoomed' : ''}`,
4470
5139
  "data-testid": "bp-waveform-view"
4471
5140
  }, /*#__PURE__*/external_react_["default"].createElement("div", {
5141
+ ref: trackRef,
4472
5142
  className: "bp-WaveformView-track",
4473
5143
  onMouseLeave: interactive ? onHoverLeave : undefined,
4474
5144
  onMouseMove: interactive ? onHoverMove : undefined
@@ -4491,6 +5161,139 @@ function WaveformView({
4491
5161
  "data-testid": "bp-waveform-hover-time"
4492
5162
  }, formatTime(hoverProgress * durationSec)))));
4493
5163
  }
5164
+ // EXTERNAL MODULE: ./node_modules/classnames/index.js
5165
+ var classnames = __webpack_require__(2485);
5166
+ var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);
5167
+ ;// ./src/lib/viewers/controls/icons/IconZoom24.tsx
5168
+
5169
+ function IconZoom24() {
5170
+ return /*#__PURE__*/external_react_.createElement("svg", {
5171
+ focusable: false,
5172
+ height: 24,
5173
+ viewBox: "0 0 24 24",
5174
+ width: 24
5175
+ }, /*#__PURE__*/external_react_.createElement("path", {
5176
+ d: "M2 12h20M6 8l-4 4 4 4M18 8l4 4-4 4",
5177
+ fill: "none",
5178
+ stroke: "currentColor",
5179
+ strokeLinecap: "round",
5180
+ strokeLinejoin: "round",
5181
+ strokeWidth: "2"
5182
+ }));
5183
+ }
5184
+ /* harmony default export */ const icons_IconZoom24 = (IconZoom24);
5185
+ // EXTERNAL MODULE: ./src/lib/viewers/controls/media/MediaToggle.tsx
5186
+ var MediaToggle = __webpack_require__(8997);
5187
+ // EXTERNAL MODULE: ./src/lib/viewers/controls/slider/SliderControl.tsx + 1 modules
5188
+ var SliderControl = __webpack_require__(4937);
5189
+ ;// ./src/lib/viewers/media/waveform/WaveformZoomControl.scss
5190
+ // extracted by mini-css-extract-plugin
5191
+
5192
+ ;// ./src/lib/viewers/media/waveform/WaveformZoomControl.tsx
5193
+
5194
+
5195
+
5196
+
5197
+
5198
+
5199
+
5200
+
5201
+ function WaveformZoomControl({
5202
+ isRevealed = false,
5203
+ maxZoom,
5204
+ onZoomChange,
5205
+ zoomLevel
5206
+ }) {
5207
+ const [isHovered, setHovered] = (0,external_react_.useState)(false);
5208
+ const [isFocused, setFocused] = (0,external_react_.useState)(false);
5209
+ const dismissTimerRef = (0,external_react_.useRef)(0);
5210
+ const flyoutRef = (0,external_react_.useRef)(null);
5211
+ const shouldFocusSliderRef = (0,external_react_.useRef)(false);
5212
+ const sliderId = `bp-waveform-zoom-slider${(0,external_react_.useId)()}`;
5213
+ const zoom = clampWaveformZoom(zoomLevel, maxZoom);
5214
+ const zoomValue = Math.round(sliderValueFromZoom(zoom, maxZoom));
5215
+ const isOpen = isHovered || isFocused || isRevealed;
5216
+ const clearDismiss = (0,external_react_.useCallback)(() => {
5217
+ window.clearTimeout(dismissTimerRef.current);
5218
+ dismissTimerRef.current = 0;
5219
+ }, []);
5220
+ (0,external_react_.useEffect)(() => () => window.clearTimeout(dismissTimerRef.current), []);
5221
+ (0,external_react_.useLayoutEffect)(() => {
5222
+ if (!isOpen || !shouldFocusSliderRef.current) {
5223
+ return;
5224
+ }
5225
+ shouldFocusSliderRef.current = false;
5226
+ flyoutRef.current?.querySelector('[role="slider"]')?.focus();
5227
+ }, [isOpen]);
5228
+ const handleSlider = (0,external_react_.useCallback)(newValue => {
5229
+ onZoomChange(zoomFromSliderValue(newValue, maxZoom));
5230
+ }, [maxZoom, onZoomChange]);
5231
+ const handleToggleClick = (0,external_react_.useCallback)(() => {
5232
+ clearDismiss();
5233
+ if (isOpen) {
5234
+ shouldFocusSliderRef.current = false;
5235
+ setFocused(false);
5236
+ setHovered(false);
5237
+ return;
5238
+ }
5239
+ shouldFocusSliderRef.current = true;
5240
+ setFocused(true);
5241
+ }, [clearDismiss, isOpen]);
5242
+ return /*#__PURE__*/external_react_["default"].createElement("div", {
5243
+ className: classnames_default()('bp-WaveformZoomControl', {
5244
+ 'bp-is-open': isOpen
5245
+ }),
5246
+ "data-testid": "bp-waveform-zoom",
5247
+ onBlur: event => {
5248
+ if (event.currentTarget.contains(event.relatedTarget)) {
5249
+ return;
5250
+ }
5251
+ setFocused(false);
5252
+ },
5253
+ onFocus: () => {
5254
+ clearDismiss();
5255
+ setFocused(true);
5256
+ },
5257
+ onMouseEnter: () => {
5258
+ clearDismiss();
5259
+ setHovered(true);
5260
+ },
5261
+ onMouseLeave: () => {
5262
+ clearDismiss();
5263
+ dismissTimerRef.current = window.setTimeout(() => {
5264
+ setHovered(false);
5265
+ }, constants/* WAVEFORM_ZOOM_DISMISS_MS */.m6);
5266
+ }
5267
+ }, /*#__PURE__*/external_react_["default"].createElement("div", {
5268
+ ref: flyoutRef,
5269
+ "aria-hidden": !isOpen,
5270
+ className: classnames_default()('bp-WaveformZoomControl-flyout', {
5271
+ 'bp-is-open': isOpen
5272
+ })
5273
+ }, /*#__PURE__*/external_react_["default"].createElement(SliderControl/* default */.A, {
5274
+ "aria-hidden": !isOpen,
5275
+ className: "bp-WaveformZoomControl-slider",
5276
+ "data-resin-target": "waveformZoomSlider",
5277
+ id: sliderId,
5278
+ max: constants/* WAVEFORM_ZOOM_SLIDER_MAX */.nh,
5279
+ min: 0,
5280
+ onUpdate: handleSlider,
5281
+ step: 1,
5282
+ style: {
5283
+ '--bp-zoom-t': zoomValue / constants/* WAVEFORM_ZOOM_SLIDER_MAX */.nh
5284
+ },
5285
+ tabIndex: isOpen ? 0 : -1,
5286
+ title: "Zoom Slider",
5287
+ value: zoomValue
5288
+ })), /*#__PURE__*/external_react_["default"].createElement(MediaToggle/* default */.A, {
5289
+ "aria-controls": sliderId,
5290
+ "aria-expanded": isOpen,
5291
+ className: "bp-WaveformZoomControl-toggle",
5292
+ "data-resin-target": "waveformZoom",
5293
+ onClick: handleToggleClick,
5294
+ title: "Zoom"
5295
+ }, /*#__PURE__*/external_react_["default"].createElement(icons_IconZoom24, null)));
5296
+ }
4494
5297
  ;// ./src/lib/viewers/media/MP3ControlsV2.scss
4495
5298
  // extracted by mini-css-extract-plugin
4496
5299
 
@@ -4505,6 +5308,9 @@ function WaveformView({
4505
5308
 
4506
5309
 
4507
5310
 
5311
+
5312
+
5313
+
4508
5314
  const PLACEHOLDER_PEAKS = placeholderPeaks();
4509
5315
  function MP3ControlsV2({
4510
5316
  autoplay,
@@ -4524,11 +5330,34 @@ function MP3ControlsV2({
4524
5330
  volume
4525
5331
  }) {
4526
5332
  const durationValue = typeof durationTime === 'number' && isFinite_default()(durationTime) ? durationTime : 0;
5333
+ const [zoomLevel, setZoomLevel] = (0,external_react_.useState)(constants/* WAVEFORM_ZOOM_MIN */.LW);
5334
+ const [maxZoom, setMaxZoom] = (0,external_react_.useState)(constants/* WAVEFORM_ZOOM_MIN */.LW);
5335
+ const [isZoomRevealed, setIsZoomRevealed] = (0,external_react_.useState)(false);
5336
+ const zoomRevealTimerRef = (0,external_react_.useRef)(0);
4527
5337
  const hasRealPeaks = !!(peaks && peaks.length);
4528
5338
  const waveformPeaks = hasRealPeaks ? peaks : PLACEHOLDER_PEAKS;
4529
5339
  const hasMetadata = durationValue > 0;
4530
5340
  const waveformDurationSec = hasMetadata ? durationValue : PLACEHOLDER_DURATION_SEC;
4531
5341
  const [playRequested, setPlayRequested] = (0,external_react_.useState)(false);
5342
+ const handleViewportChange = (0,external_react_.useCallback)(viewport => {
5343
+ setMaxZoom(viewport.maxZoom);
5344
+ }, []);
5345
+ const revealZoomControl = (0,external_react_.useCallback)(() => {
5346
+ setIsZoomRevealed(true);
5347
+ window.clearTimeout(zoomRevealTimerRef.current);
5348
+ zoomRevealTimerRef.current = window.setTimeout(() => {
5349
+ setIsZoomRevealed(false);
5350
+ zoomRevealTimerRef.current = 0;
5351
+ }, constants/* WAVEFORM_ZOOM_DISMISS_MS */.m6);
5352
+ }, []);
5353
+ const handleWaveformZoom = (0,external_react_.useCallback)(nextZoom => {
5354
+ setZoomLevel(nextZoom);
5355
+ revealZoomControl();
5356
+ }, [revealZoomControl]);
5357
+ (0,external_react_.useEffect)(() => {
5358
+ setZoomLevel(prev => clampWaveformZoom(prev, maxZoom));
5359
+ }, [maxZoom]);
5360
+ (0,external_react_.useEffect)(() => () => window.clearTimeout(zoomRevealTimerRef.current), []);
4532
5361
  (0,external_react_.useEffect)(() => {
4533
5362
  if (isPlaying) {
4534
5363
  setPlayRequested(true);
@@ -4541,6 +5370,8 @@ function MP3ControlsV2({
4541
5370
  const isWaveformInteractive = playRequested && hasMetadata;
4542
5371
  const isWaitingToPlay = playRequested && !hasMetadata;
4543
5372
  const showPlayOverlay = !playRequested && !isPlaying;
5373
+ const hasZoomHandlers = hasRealPeaks && !showPlayOverlay;
5374
+ const hasZoomControl = hasZoomHandlers && hasMetadata && maxZoom > constants/* WAVEFORM_ZOOM_MIN */.LW;
4544
5375
  return /*#__PURE__*/external_react_["default"].createElement("div", {
4545
5376
  className: "bp-MP3ControlsV2",
4546
5377
  "data-testid": "media-controls-wrapper-v2"
@@ -4553,8 +5384,18 @@ function MP3ControlsV2({
4553
5384
  interactive: isWaveformInteractive,
4554
5385
  mediaEl: mediaEl,
4555
5386
  onSeek: isWaveformInteractive ? onTimeChange : undefined,
4556
- peaks: waveformPeaks
4557
- }), showPlayOverlay && /*#__PURE__*/external_react_["default"].createElement("button", {
5387
+ onViewportChange: hasRealPeaks ? handleViewportChange : undefined,
5388
+ onZoomChange: hasZoomHandlers ? handleWaveformZoom : undefined,
5389
+ peaks: waveformPeaks,
5390
+ zoomLevel: hasZoomHandlers ? zoomLevel : constants/* WAVEFORM_ZOOM_MIN */.LW
5391
+ }), hasZoomControl && /*#__PURE__*/external_react_["default"].createElement("div", {
5392
+ className: "bp-MP3ControlsV2-waveformZoom"
5393
+ }, /*#__PURE__*/external_react_["default"].createElement(WaveformZoomControl, {
5394
+ isRevealed: isZoomRevealed,
5395
+ maxZoom: maxZoom,
5396
+ onZoomChange: setZoomLevel,
5397
+ zoomLevel: zoomLevel
5398
+ })), showPlayOverlay && /*#__PURE__*/external_react_["default"].createElement("button", {
4558
5399
  className: "bp-MP3ControlsV2-playOverlay"
4559
5400
  // Static SVG from the icons module, same asset video uses for the overlay.
4560
5401
  // eslint-disable-next-line react/no-danger
@@ -4667,22 +5508,30 @@ function isFpsAvailable(player) {
4667
5508
 
4668
5509
  /***/ },
4669
5510
 
4670
- /***/ 9514
5511
+ /***/ 4929
4671
5512
  (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
4672
5513
 
4673
-
4674
- // EXPORTS
4675
- __webpack_require__.d(__webpack_exports__, {
4676
- decodeToPeaks: () => (/* binding */ decodeToPeaks),
4677
- extractPeaks: () => (/* binding */ extractPeaks),
4678
- getDecodeDecision: () => (/* binding */ getDecodeDecision),
4679
- loadPeaks: () => (/* binding */ loadPeaks),
4680
- runClientDecode: () => (/* binding */ runClientDecode)
4681
- });
4682
- // ESM COMPAT FLAG
4683
- __webpack_require__.r(__webpack_exports__);
4684
-
4685
- ;// ./src/lib/viewers/media/waveform/constants.ts
5514
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
5515
+ /* harmony export */ DY: () => (/* binding */ WAVEFORM_BAR_RADIUS),
5516
+ /* harmony export */ EB: () => (/* binding */ CLIENT_DECODE_MAX_COMPRESSED_BYTES),
5517
+ /* harmony export */ FY: () => (/* binding */ MAX_PEAK_COUNT),
5518
+ /* harmony export */ GQ: () => (/* binding */ DURATION_MISMATCH_TOLERANCE_SEC),
5519
+ /* harmony export */ Kl: () => (/* binding */ WAVEFORM_MIN_VIEW_WINDOW_SEC),
5520
+ /* harmony export */ LW: () => (/* binding */ WAVEFORM_ZOOM_MIN),
5521
+ /* harmony export */ Lu: () => (/* binding */ WAVEFORM_BAR_GAP),
5522
+ /* harmony export */ XS: () => (/* binding */ WAVEFORM_BAR_MIN_HEIGHT),
5523
+ /* harmony export */ f3: () => (/* binding */ CLIENT_DECODE_PEAK_COUNT),
5524
+ /* harmony export */ i8: () => (/* binding */ PEAK_UNIT_MAX),
5525
+ /* harmony export */ m6: () => (/* binding */ WAVEFORM_ZOOM_DISMISS_MS),
5526
+ /* harmony export */ mJ: () => (/* binding */ PEAK_UNIT_MIN),
5527
+ /* harmony export */ nG: () => (/* binding */ CLIENT_DECODE_MAX_DURATION_SEC),
5528
+ /* harmony export */ nh: () => (/* binding */ WAVEFORM_ZOOM_SLIDER_MAX),
5529
+ /* harmony export */ oN: () => (/* binding */ WAVEFORM_HEIGHT),
5530
+ /* harmony export */ qY: () => (/* binding */ MAX_PAYLOAD_BYTES),
5531
+ /* harmony export */ sh: () => (/* binding */ WAVEFORM_PAYLOAD_VERSION),
5532
+ /* harmony export */ tK: () => (/* binding */ WAVEFORM_ZOOM_MAX),
5533
+ /* harmony export */ zo: () => (/* binding */ WAVEFORM_BAR_WIDTH)
5534
+ /* harmony export */ });
4686
5535
  /** Current waveform payload schema version. Bump only with a migration path. */
4687
5536
  const WAVEFORM_PAYLOAD_VERSION = 1;
4688
5537
 
@@ -4707,6 +5556,40 @@ const CLIENT_DECODE_MAX_DURATION_SEC = 5 * 60;
4707
5556
 
4708
5557
  /** Default overview resolution for client-generated peaks. */
4709
5558
  const CLIENT_DECODE_PEAK_COUNT = 16384;
5559
+ const WAVEFORM_ZOOM_MIN = 1;
5560
+ const WAVEFORM_ZOOM_MAX = 24;
5561
+ /** Visible window never shorter than this. */
5562
+ const WAVEFORM_MIN_VIEW_WINDOW_SEC = 4;
5563
+ const WAVEFORM_ZOOM_SLIDER_MAX = 100;
5564
+ const WAVEFORM_ZOOM_DISMISS_MS = 250;
5565
+ const WAVEFORM_BAR_GAP = 2;
5566
+ const WAVEFORM_BAR_WIDTH = 2;
5567
+ const WAVEFORM_BAR_RADIUS = WAVEFORM_BAR_WIDTH / 2;
5568
+ /** Total bar height so the top and bottom radii meet as a circle on the mirror. */
5569
+ const WAVEFORM_BAR_MIN_HEIGHT = WAVEFORM_BAR_WIDTH;
5570
+ const WAVEFORM_HEIGHT = 140;
5571
+
5572
+ /***/ },
5573
+
5574
+ /***/ 546
5575
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5576
+
5577
+
5578
+ // EXPORTS
5579
+ __webpack_require__.d(__webpack_exports__, {
5580
+ decodeToPeaks: () => (/* binding */ decodeToPeaks),
5581
+ extractPeaks: () => (/* binding */ extractPeaks),
5582
+ getDecodeDecision: () => (/* binding */ getDecodeDecision),
5583
+ loadPeaks: () => (/* binding */ loadPeaks),
5584
+ runClientDecode: () => (/* binding */ runClientDecode)
5585
+ });
5586
+ // ESM COMPAT FLAG
5587
+ __webpack_require__.r(__webpack_exports__);
5588
+
5589
+ // EXTERNAL MODULE: ./src/lib/util.js + 1 modules
5590
+ var util = __webpack_require__(4410);
5591
+ // EXTERNAL MODULE: ./src/lib/viewers/media/waveform/constants.ts
5592
+ var constants = __webpack_require__(4929);
4710
5593
  ;// ./src/lib/viewers/media/waveform/types.ts
4711
5594
  /**
4712
5595
  * Box V1 is the in-viewer form: unsigned mono peaks in [0, 1] (peak envelope, mono_max).
@@ -4733,6 +5616,15 @@ function isWaveformErrorCode(value) {
4733
5616
  * Async boundary for waveform data. Implementations may fetch fixtures, decode client-side,
4734
5617
  * or load Conversion reps — callers only observe WaveformLoadState.
4735
5618
  */
5619
+
5620
+ /** Visible slice of the timeline. Emitted whenever zoom, scroll, or width changes. */
5621
+
5622
+ /** One canvas linear-gradient stop. `offset` is 0–1 along the bar. */
5623
+
5624
+ /**
5625
+ * Wavesurfer's two paints: left of the playhead (`progressColor`) and right of it (`waveColor`).
5626
+ * A string is a solid fill; a stop list is a left-to-right step gradient.
5627
+ */
4736
5628
  ;// ./src/lib/viewers/media/waveform/createWaveformLoader.ts
4737
5629
  /* unused harmony import specifier */ var isRetryableWaveformError;
4738
5630
  /* unused harmony import specifier */ var validateWaveformPayload;
@@ -4950,7 +5842,7 @@ function asWaveformPayloadV1(raw) {
4950
5842
  durationSec,
4951
5843
  peaks
4952
5844
  } = raw;
4953
- if (version !== WAVEFORM_PAYLOAD_VERSION || typeof durationSec !== 'number' || !Array.isArray(peaks)) {
5845
+ if (version !== constants/* WAVEFORM_PAYLOAD_VERSION */.sh || typeof durationSec !== 'number' || !Array.isArray(peaks)) {
4954
5846
  return null;
4955
5847
  }
4956
5848
  const peakScale = readOptionalPolicy(raw, 'peakScale', DEFAULT_PEAK_SCALE);
@@ -4963,7 +5855,7 @@ function asWaveformPayloadV1(raw) {
4963
5855
  return null;
4964
5856
  }
4965
5857
  return {
4966
- version: WAVEFORM_PAYLOAD_VERSION,
5858
+ version: constants/* WAVEFORM_PAYLOAD_VERSION */.sh,
4967
5859
  durationSec,
4968
5860
  peaks: peaks,
4969
5861
  peakScale: peakScale ?? DEFAULT_PEAK_SCALE,
@@ -4991,14 +5883,14 @@ function readPayloadObject(raw, maxPayloadBytes, isPayloadByteCheckSkipped = fal
4991
5883
  };
4992
5884
  }
4993
5885
  function checkVersion(raw) {
4994
- if (raw.version === WAVEFORM_PAYLOAD_VERSION) {
5886
+ if (raw.version === constants/* WAVEFORM_PAYLOAD_VERSION */.sh) {
4995
5887
  return null;
4996
5888
  }
4997
5889
  const {
4998
5890
  version
4999
5891
  } = raw;
5000
- if (typeof version === 'number' && version > WAVEFORM_PAYLOAD_VERSION) {
5001
- return fail('UNSUPPORTED_VERSION', `Unsupported waveform version ${version}; max supported is ${WAVEFORM_PAYLOAD_VERSION}`);
5892
+ if (typeof version === 'number' && version > constants/* WAVEFORM_PAYLOAD_VERSION */.sh) {
5893
+ return fail('UNSUPPORTED_VERSION', `Unsupported waveform version ${version}; max supported is ${constants/* WAVEFORM_PAYLOAD_VERSION */.sh}`);
5002
5894
  }
5003
5895
  return fail('INVALID_PAYLOAD', 'Missing or invalid version field');
5004
5896
  }
@@ -5006,7 +5898,7 @@ function checkDuration(payload, expectedDurationSec) {
5006
5898
  if (!Number.isFinite(payload.durationSec) || payload.durationSec <= 0) {
5007
5899
  return fail('INVALID_DURATION', 'durationSec must be a positive finite number');
5008
5900
  }
5009
- if (expectedDurationSec !== undefined && Number.isFinite(expectedDurationSec) && Math.abs(payload.durationSec - expectedDurationSec) > DURATION_MISMATCH_TOLERANCE_SEC) {
5901
+ if (expectedDurationSec !== undefined && Number.isFinite(expectedDurationSec) && Math.abs(payload.durationSec - expectedDurationSec) > constants/* DURATION_MISMATCH_TOLERANCE_SEC */.GQ) {
5010
5902
  return fail('DURATION_MISMATCH', `Payload duration ${payload.durationSec}s differs from media duration ${expectedDurationSec}s`, true);
5011
5903
  }
5012
5904
  return null;
@@ -5024,8 +5916,8 @@ function normalizePeaks(peaks, maxPeakCount) {
5024
5916
  if (!Number.isFinite(value)) {
5025
5917
  return fail('NON_FINITE_PEAK', `Peak at index ${i} is not finite`);
5026
5918
  }
5027
- if (value < PEAK_UNIT_MIN || value > PEAK_UNIT_MAX) {
5028
- return fail('PEAK_OUT_OF_RANGE', `Peak at index ${i} is outside [${PEAK_UNIT_MIN}, ${PEAK_UNIT_MAX}]`);
5919
+ if (value < constants/* PEAK_UNIT_MIN */.mJ || value > constants/* PEAK_UNIT_MAX */.i8) {
5920
+ return fail('PEAK_OUT_OF_RANGE', `Peak at index ${i} is outside [${constants/* PEAK_UNIT_MIN */.mJ}, ${constants/* PEAK_UNIT_MAX */.i8}]`);
5029
5921
  }
5030
5922
  normalized[i] = value;
5031
5923
  }
@@ -5040,8 +5932,8 @@ function normalizePeaks(peaks, maxPeakCount) {
5040
5932
  * Wire JSON requires version, durationSec, and peaks. sampleCount and source are ignored.
5041
5933
  */
5042
5934
  function validateWaveformPayload_validateWaveformPayload(raw, options = {}) {
5043
- const maxPeakCount = options.maxPeakCount ?? MAX_PEAK_COUNT;
5044
- const maxPayloadBytes = options.maxPayloadBytes ?? MAX_PAYLOAD_BYTES;
5935
+ const maxPeakCount = options.maxPeakCount ?? constants/* MAX_PEAK_COUNT */.FY;
5936
+ const maxPayloadBytes = options.maxPayloadBytes ?? constants/* MAX_PAYLOAD_BYTES */.qY;
5045
5937
  const objectResult = readPayloadObject(raw, maxPayloadBytes, options.isPayloadByteCheckSkipped === true);
5046
5938
  if (!objectResult.ok) {
5047
5939
  return objectResult;
@@ -5065,7 +5957,7 @@ function validateWaveformPayload_validateWaveformPayload(raw, options = {}) {
5065
5957
  return {
5066
5958
  ok: true,
5067
5959
  payload: {
5068
- version: WAVEFORM_PAYLOAD_VERSION,
5960
+ version: constants/* WAVEFORM_PAYLOAD_VERSION */.sh,
5069
5961
  durationSec: payload.durationSec,
5070
5962
  peaks: peaksResult.peaks,
5071
5963
  peakScale: payload.peakScale ?? DEFAULT_PEAK_SCALE,
@@ -5088,13 +5980,11 @@ function decode_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; va
5088
5980
 
5089
5981
 
5090
5982
 
5983
+
5091
5984
  const EMPTY_TIMINGS = {
5092
5985
  attemptMs: null,
5093
5986
  extractMs: null
5094
5987
  };
5095
- function getCurrentTimeMs() {
5096
- return typeof performance !== 'undefined' ? performance.now() : Date.now();
5097
- }
5098
5988
  function createAbortError() {
5099
5989
  return new DOMException('Aborted', 'AbortError');
5100
5990
  }
@@ -5187,8 +6077,8 @@ function decodeWithContext(context, buffer, signal) {
5187
6077
  * skips decode so playback is never blocked by expanding the full audio buffer.
5188
6078
  */
5189
6079
  function getDecodeDecision(media, caps = {}) {
5190
- const maxCompressedBytes = caps.maxCompressedBytes ?? CLIENT_DECODE_MAX_COMPRESSED_BYTES;
5191
- const maxDurationSec = caps.maxDurationSec ?? CLIENT_DECODE_MAX_DURATION_SEC;
6080
+ const maxCompressedBytes = caps.maxCompressedBytes ?? constants/* CLIENT_DECODE_MAX_COMPRESSED_BYTES */.EB;
6081
+ const maxDurationSec = caps.maxDurationSec ?? constants/* CLIENT_DECODE_MAX_DURATION_SEC */.nG;
5192
6082
  const {
5193
6083
  compressedBytes,
5194
6084
  durationSec
@@ -5220,7 +6110,7 @@ function getDecodeDecision(media, caps = {}) {
5220
6110
  * Collapse audio channels to one unsigned peak per time bucket (max abs, then clamp to unit).
5221
6111
  * Accepts an AudioBuffer so callers can extract before closing the AudioContext.
5222
6112
  */
5223
- function extractPeaks(audio, peakCount = CLIENT_DECODE_PEAK_COUNT) {
6113
+ function extractPeaks(audio, peakCount = constants/* CLIENT_DECODE_PEAK_COUNT */.f3) {
5224
6114
  const channels = Array.isArray(audio) ? audio : Array.from({
5225
6115
  length: audio.numberOfChannels
5226
6116
  }, (_, channelIndex) => audio.getChannelData(channelIndex));
@@ -5245,7 +6135,7 @@ function extractPeaks(audio, peakCount = CLIENT_DECODE_PEAK_COUNT) {
5245
6135
  }
5246
6136
  }
5247
6137
  }
5248
- peaks[i] = Math.min(PEAK_UNIT_MAX, Math.max(PEAK_UNIT_MIN, maxAbs));
6138
+ peaks[i] = Math.min(constants/* PEAK_UNIT_MAX */.i8, Math.max(constants/* PEAK_UNIT_MIN */.mJ, maxAbs));
5249
6139
  }
5250
6140
  return peaks;
5251
6141
  }
@@ -5254,7 +6144,7 @@ function extractPeaks(audio, peakCount = CLIENT_DECODE_PEAK_COUNT) {
5254
6144
  * Decode compressed audio and extract unit peaks while the AudioBuffer is live.
5255
6145
  * Does not attach a media element or fetch a URL. Does not copy channel data.
5256
6146
  */
5257
- async function decodeToPeaks(arrayBuffer, signal, peakCount = CLIENT_DECODE_PEAK_COUNT) {
6147
+ async function decodeToPeaks(arrayBuffer, signal, peakCount = constants/* CLIENT_DECODE_PEAK_COUNT */.f3) {
5258
6148
  if (signal?.aborted) {
5259
6149
  throw createAbortError();
5260
6150
  }
@@ -5268,12 +6158,12 @@ async function decodeToPeaks(arrayBuffer, signal, peakCount = CLIENT_DECODE_PEAK
5268
6158
  if (signal?.aborted) {
5269
6159
  throw createAbortError();
5270
6160
  }
5271
- const extractStarted = getCurrentTimeMs();
6161
+ const extractStarted = (0,util/* getCurrentTimeMs */.RU)();
5272
6162
  const peaks = extractPeaks(audioBuffer, peakCount);
5273
6163
  return {
5274
6164
  durationSec: audioBuffer.duration,
5275
6165
  peaks,
5276
- extractMs: getCurrentTimeMs() - extractStarted
6166
+ extractMs: (0,util/* getCurrentTimeMs */.RU)() - extractStarted
5277
6167
  };
5278
6168
  } catch (error) {
5279
6169
  if (signal?.aborted || isAbortError(error)) {
@@ -5309,7 +6199,7 @@ async function runClientDecode(options) {
5309
6199
  };
5310
6200
  }
5311
6201
  const signal = options.signal ?? new AbortController().signal;
5312
- const decodeStarted = getCurrentTimeMs();
6202
+ const decodeStarted = (0,util/* getCurrentTimeMs */.RU)();
5313
6203
  let decodeOutput;
5314
6204
  try {
5315
6205
  decodeOutput = await options.decode(signal);
@@ -5328,12 +6218,12 @@ async function runClientDecode(options) {
5328
6218
  retryable: validateWaveformPayload_isRetryableWaveformError(waveformError.code),
5329
6219
  isDecodeSkipped: false,
5330
6220
  timings: {
5331
- attemptMs: getCurrentTimeMs() - decodeStarted,
6221
+ attemptMs: (0,util/* getCurrentTimeMs */.RU)() - decodeStarted,
5332
6222
  extractMs: null
5333
6223
  }
5334
6224
  };
5335
6225
  }
5336
- const attemptMs = getCurrentTimeMs() - decodeStarted;
6226
+ const attemptMs = (0,util/* getCurrentTimeMs */.RU)() - decodeStarted;
5337
6227
  if (signal.aborted) {
5338
6228
  return {
5339
6229
  status: 'cancelled',
@@ -5345,7 +6235,7 @@ async function runClientDecode(options) {
5345
6235
  };
5346
6236
  }
5347
6237
  const validation = validateWaveformPayload_validateWaveformPayload({
5348
- version: WAVEFORM_PAYLOAD_VERSION,
6238
+ version: constants/* WAVEFORM_PAYLOAD_VERSION */.sh,
5349
6239
  durationSec: options.durationSec ?? decodeOutput.durationSec,
5350
6240
  peaks: decodeOutput.peaks
5351
6241
  }, {
@@ -12161,7 +13051,7 @@ var x = (y) => {
12161
13051
  var x = {}; __webpack_require__.d(x, y); return x
12162
13052
  }
12163
13053
  var y = (x) => (() => (x))
12164
- module.exports = x({ ["createElement"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.createElement), ["default"]: () => (__WEBPACK_EXTERNAL_MODULE_react__["default"]), ["useCallback"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useCallback), ["useEffect"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useEffect), ["useLayoutEffect"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useLayoutEffect), ["useRef"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useRef), ["useState"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useState) });
13054
+ module.exports = x({ ["createElement"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.createElement), ["default"]: () => (__WEBPACK_EXTERNAL_MODULE_react__["default"]), ["useCallback"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useCallback), ["useEffect"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useEffect), ["useId"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useId), ["useLayoutEffect"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useLayoutEffect), ["useMemo"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useMemo), ["useRef"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useRef), ["useState"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useState) });
12165
13055
 
12166
13056
  /***/ },
12167
13057
 
@@ -21055,7 +21945,7 @@ class Browser {
21055
21945
  ;// ./src/lib/Logger.js
21056
21946
  /* eslint-disable no-undef */
21057
21947
  const CLIENT_NAME = "box-content-preview";
21058
- const CLIENT_VERSION = "3.83.0";
21948
+ const CLIENT_VERSION = "3.84.0";
21059
21949
  /* eslint-enable no-undef */
21060
21950
 
21061
21951
  class Logger {
@@ -33569,150 +34459,8 @@ function Filmstrip({
33569
34459
  "data-testid": "bp-Filmstrip-time"
33570
34460
  }, (0,DurationLabels/* formatTime */.f)(time)));
33571
34461
  }
33572
- ;// ./src/lib/viewers/controls/slider/SliderControl.scss
33573
- // extracted by mini-css-extract-plugin
33574
-
33575
- ;// ./src/lib/viewers/controls/slider/SliderControl.tsx
33576
- const SliderControl_excluded = ["className", "max", "min", "onMove", "onUpdate", "step", "title", "track", "value"];
33577
- function SliderControl_extends() { return SliderControl_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, SliderControl_extends.apply(null, arguments); }
33578
- function SliderControl_objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = SliderControl_objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
33579
- function SliderControl_objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
33580
-
33581
-
33582
-
33583
-
33584
-
33585
- function SliderControl(_ref) {
33586
- let {
33587
- className,
33588
- max = 100,
33589
- min = 0,
33590
- onMove = (noop_default()),
33591
- onUpdate = (noop_default()),
33592
- step = 1,
33593
- title,
33594
- track,
33595
- value
33596
- } = _ref,
33597
- rest = SliderControl_objectWithoutProperties(_ref, SliderControl_excluded);
33598
- const [isScrubbing, setIsScrubbing] = external_react_["default"].useState(false);
33599
- const sliderElRef = external_react_["default"].useRef(null);
33600
- const getPosition = external_react_["default"].useCallback(pageX => {
33601
- const {
33602
- current: sliderEl
33603
- } = sliderElRef;
33604
- if (!sliderEl) return 0;
33605
- const {
33606
- left: sliderLeft,
33607
- width: sliderWidth
33608
- } = sliderEl.getBoundingClientRect();
33609
- return Math.max(0, Math.min(pageX - sliderLeft, sliderWidth));
33610
- }, []);
33611
- const getPositionValue = external_react_["default"].useCallback(pageX => {
33612
- const {
33613
- current: sliderEl
33614
- } = sliderElRef;
33615
- if (!sliderEl) return 0;
33616
- const {
33617
- width: sliderWidth
33618
- } = sliderEl.getBoundingClientRect();
33619
- const newValue = getPosition(pageX) / sliderWidth * max;
33620
- return Math.max(min, Math.min(newValue, max));
33621
- }, [getPosition, max, min]);
33622
- const handleKeydown = event => {
33623
- const key = (0,util/* decodeKeydown */.wU)(event);
33624
- if (key === 'ArrowLeft') {
33625
- event.stopPropagation(); // Prevents global key handling
33626
- onUpdate(Math.max(min, Math.min(value - step, max)));
33627
- }
33628
- if (key === 'ArrowRight') {
33629
- event.stopPropagation(); // Prevents global key handling
33630
- onUpdate(Math.max(min, Math.min(value + step, max)));
33631
- }
33632
- };
33633
- const handleMouseDown = ({
33634
- button,
33635
- ctrlKey,
33636
- metaKey,
33637
- pageX
33638
- }) => {
33639
- if (button > 1 || ctrlKey || metaKey) return;
33640
- onUpdate(getPositionValue(pageX));
33641
- setIsScrubbing(true);
33642
- };
33643
- const handleMouseMove = ({
33644
- pageX
33645
- }) => {
33646
- const {
33647
- current: sliderEl
33648
- } = sliderElRef;
33649
- const {
33650
- width: sliderWidth
33651
- } = sliderEl ? sliderEl.getBoundingClientRect() : {
33652
- width: 0
33653
- };
33654
- onMove(getPositionValue(pageX), getPosition(pageX), sliderWidth);
33655
- };
33656
- const handleTouchStart = ({
33657
- touches
33658
- }) => {
33659
- onUpdate(getPositionValue(touches[0].pageX));
33660
- setIsScrubbing(true);
33661
- };
33662
- external_react_["default"].useEffect(() => {
33663
- const handleDocumentMoveStop = () => setIsScrubbing(false);
33664
- const handleDocumentMouseMove = event => {
33665
- if (!isScrubbing || event.button > 1 || event.ctrlKey || event.metaKey) return;
33666
- event.preventDefault();
33667
- onUpdate(getPositionValue(event.pageX));
33668
- };
33669
- const handleDocumentTouchMove = event => {
33670
- if (!isScrubbing || !event.touches || !event.touches[0]) return;
33671
- event.preventDefault();
33672
- onUpdate(getPositionValue(event.touches[0].pageX));
33673
- };
33674
- if (isScrubbing) {
33675
- document.addEventListener('mousemove', handleDocumentMouseMove);
33676
- document.addEventListener('mouseup', handleDocumentMoveStop);
33677
- document.addEventListener('touchend', handleDocumentMoveStop);
33678
- document.addEventListener('touchmove', handleDocumentTouchMove);
33679
- }
33680
- return () => {
33681
- document.removeEventListener('mousemove', handleDocumentMouseMove);
33682
- document.removeEventListener('mouseup', handleDocumentMoveStop);
33683
- document.removeEventListener('touchend', handleDocumentMoveStop);
33684
- document.removeEventListener('touchmove', handleDocumentTouchMove);
33685
- };
33686
- }, [isScrubbing, getPositionValue, onUpdate]);
33687
- return /*#__PURE__*/external_react_["default"].createElement("div", SliderControl_extends({
33688
- ref: sliderElRef,
33689
- "aria-label": title,
33690
- "aria-valuemax": max,
33691
- "aria-valuemin": min,
33692
- "aria-valuenow": value,
33693
- className: classnames_default()('bp-SliderControl', className, {
33694
- 'bp-is-scrubbing': isScrubbing
33695
- }),
33696
- onKeyDown: handleKeydown,
33697
- onMouseDown: handleMouseDown,
33698
- onMouseMove: handleMouseMove,
33699
- onTouchStart: handleTouchStart,
33700
- role: "slider",
33701
- tabIndex: 0
33702
- }, rest), /*#__PURE__*/external_react_["default"].createElement("div", {
33703
- className: "bp-SliderControl-track",
33704
- "data-testid": "bp-slider-control-track",
33705
- style: {
33706
- backgroundImage: track
33707
- }
33708
- }), /*#__PURE__*/external_react_["default"].createElement("div", {
33709
- className: "bp-SliderControl-thumb",
33710
- "data-testid": "bp-slider-control-thumb",
33711
- style: {
33712
- left: `${value / max * 100}%`
33713
- }
33714
- }));
33715
- }
34462
+ // EXTERNAL MODULE: ./src/lib/viewers/controls/slider/SliderControl.tsx + 1 modules
34463
+ var SliderControl = __webpack_require__(4937);
33716
34464
  ;// ./src/lib/viewers/controls/media/TimeControls.scss
33717
34465
  // extracted by mini-css-extract-plugin
33718
34466
 
@@ -33772,7 +34520,7 @@ function TimeControls({
33772
34520
  durationTime: durationTime,
33773
34521
  fps: fps,
33774
34522
  mediaEl: mediaEl
33775
- }), /*#__PURE__*/external_react_["default"].createElement(SliderControl, {
34523
+ }), /*#__PURE__*/external_react_["default"].createElement(SliderControl/* default */.A, {
33776
34524
  className: "bp-TimeControls-slider",
33777
34525
  "data-resin-target": "timeScrubber",
33778
34526
  max: durationValue,
@@ -34004,7 +34752,7 @@ class MP3Viewer extends media_MediaBaseViewer {
34004
34752
  * @return {Promise<{ default: Function }>} MP3ControlsV2 module
34005
34753
  */
34006
34754
  importV2Controls() {
34007
- return Promise.resolve(/* import() */).then(__webpack_require__.bind(__webpack_require__, 7893));
34755
+ return Promise.resolve(/* import() */).then(__webpack_require__.bind(__webpack_require__, 3845));
34008
34756
  }
34009
34757
 
34010
34758
  /**
@@ -34012,7 +34760,7 @@ class MP3Viewer extends media_MediaBaseViewer {
34012
34760
  */
34013
34761
  async importWaveformDecode() {
34014
34762
  if (!this.waveformDecodeImport) {
34015
- this.waveformDecodeImport = Promise.resolve(/* import() */).then(__webpack_require__.bind(__webpack_require__, 9514));
34763
+ this.waveformDecodeImport = Promise.resolve(/* import() */).then(__webpack_require__.bind(__webpack_require__, 546));
34016
34764
  }
34017
34765
  try {
34018
34766
  return await this.waveformDecodeImport;
@@ -36300,7 +37048,7 @@ function TimeControlsV2({
36300
37048
  style: trackMask ? {
36301
37049
  '--bp-track-mask': trackMask
36302
37050
  } : undefined
36303
- }, /*#__PURE__*/external_react_["default"].createElement(SliderControl, {
37051
+ }, /*#__PURE__*/external_react_["default"].createElement(SliderControl/* default */.A, {
36304
37052
  className: "bp-TimeControlsV2-slider",
36305
37053
  "data-resin-target": "timeScrubber",
36306
37054
  max: durationValue,