stormcloud-video-player 0.3.53 → 0.3.55

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.
@@ -152,12 +152,22 @@ function _object_spread_props(target, source) {
152
152
  }
153
153
  function _object_without_properties(source, excluded) {
154
154
  if (source == null) return {};
155
- var target = _object_without_properties_loose(source, excluded);
156
- var key, i;
155
+ var target = {}, sourceKeys, key, i;
156
+ if (typeof Reflect !== "undefined" && Reflect.ownKeys) {
157
+ sourceKeys = Reflect.ownKeys(Object(source));
158
+ for(i = 0; i < sourceKeys.length; i++){
159
+ key = sourceKeys[i];
160
+ if (excluded.indexOf(key) >= 0) continue;
161
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
162
+ target[key] = source[key];
163
+ }
164
+ return target;
165
+ }
166
+ target = _object_without_properties_loose(source, excluded);
157
167
  if (Object.getOwnPropertySymbols) {
158
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
159
- for(i = 0; i < sourceSymbolKeys.length; i++){
160
- key = sourceSymbolKeys[i];
168
+ sourceKeys = Object.getOwnPropertySymbols(source);
169
+ for(i = 0; i < sourceKeys.length; i++){
170
+ key = sourceKeys[i];
161
171
  if (excluded.indexOf(key) >= 0) continue;
162
172
  if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
163
173
  target[key] = source[key];
@@ -167,12 +177,11 @@ function _object_without_properties(source, excluded) {
167
177
  }
168
178
  function _object_without_properties_loose(source, excluded) {
169
179
  if (source == null) return {};
170
- var target = {};
171
- var sourceKeys = Object.keys(source);
172
- var key, i;
180
+ var target = {}, sourceKeys = Object.getOwnPropertyNames(source), key, i;
173
181
  for(i = 0; i < sourceKeys.length; i++){
174
182
  key = sourceKeys[i];
175
183
  if (excluded.indexOf(key) >= 0) continue;
184
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
176
185
  target[key] = source[key];
177
186
  }
178
187
  return target;
@@ -204,9 +213,17 @@ function _ts_generator(thisArg, body) {
204
213
  },
205
214
  trys: [],
206
215
  ops: []
207
- }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
208
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
209
- return this;
216
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
217
+ return d(g, "next", {
218
+ value: verb(0)
219
+ }), d(g, "throw", {
220
+ value: verb(1)
221
+ }), d(g, "return", {
222
+ value: verb(2)
223
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
224
+ value: function() {
225
+ return this;
226
+ }
210
227
  }), g;
211
228
  function verb(n) {
212
229
  return function(v) {
@@ -306,20 +323,20 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
306
323
  var __getOwnPropNames = Object.getOwnPropertyNames;
307
324
  var __getProtoOf = Object.getPrototypeOf;
308
325
  var __hasOwnProp = Object.prototype.hasOwnProperty;
309
- var __export = function(target, all) {
326
+ var __export = function __export(target, all) {
310
327
  for(var name in all)__defProp(target, name, {
311
328
  get: all[name],
312
329
  enumerable: true
313
330
  });
314
331
  };
315
- var __copyProps = function(to, from, except, desc) {
332
+ var __copyProps = function __copyProps(to, from, except, desc) {
316
333
  if (from && (typeof from === "undefined" ? "undefined" : _type_of(from)) === "object" || typeof from === "function") {
317
334
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
318
335
  try {
319
336
  var _loop = function() {
320
337
  var key = _step.value;
321
338
  if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
322
- get: function() {
339
+ get: function get() {
323
340
  return from[key];
324
341
  },
325
342
  enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
@@ -343,7 +360,7 @@ var __copyProps = function(to, from, except, desc) {
343
360
  }
344
361
  return to;
345
362
  };
346
- var __toESM = function(mod, isNodeMode, target) {
363
+ var __toESM = function __toESM(mod, isNodeMode, target) {
347
364
  return target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(// If the importer is in node compatibility mode or this is not an ESM
348
365
  // file that has been converted to a CommonJS file using a Babel-
349
366
  // compatible transform (i.e. "__esModule" has not been set), then set
@@ -353,7 +370,7 @@ var __toESM = function(mod, isNodeMode, target) {
353
370
  enumerable: true
354
371
  }) : target, mod);
355
372
  };
356
- var __toCommonJS = function(mod) {
373
+ var __toCommonJS = function __toCommonJS(mod) {
357
374
  return __copyProps(__defProp({}, "__esModule", {
358
375
  value: true
359
376
  }), mod);
@@ -361,7 +378,7 @@ var __toCommonJS = function(mod) {
361
378
  // src/ui/StormcloudVideoPlayer.tsx
362
379
  var StormcloudVideoPlayer_exports = {};
363
380
  __export(StormcloudVideoPlayer_exports, {
364
- StormcloudVideoPlayerComponent: function() {
381
+ StormcloudVideoPlayerComponent: function StormcloudVideoPlayerComponent1() {
365
382
  return StormcloudVideoPlayerComponent;
366
383
  }
367
384
  });
@@ -696,7 +713,7 @@ function createImaController(video, options) {
696
713
  var fn = _step.value;
697
714
  try {
698
715
  fn(payload);
699
- } catch (e) {}
716
+ } catch (unused) {}
700
717
  }
701
718
  } catch (err) {
702
719
  _didIteratorError = true;
@@ -734,7 +751,7 @@ function createImaController(video, options) {
734
751
  console.error("StormcloudVideoPlayer: The host page is inside a sandboxed iframe without 'allow-scripts'. Google IMA cannot run ads within sandboxed frames. Remove the sandbox attribute or include 'allow-scripts allow-same-origin'.");
735
752
  }
736
753
  }
737
- } catch (e) {}
754
+ } catch (unused) {}
738
755
  if (typeof window !== "undefined" && ((_window_google = window.google) === null || _window_google === void 0 ? void 0 : _window_google.ima)) return Promise.resolve();
739
756
  var existing = document.querySelector('script[data-ima="true"]');
740
757
  if (existing) {
@@ -776,9 +793,6 @@ function createImaController(video, options) {
776
793
  var adDisplayContainer;
777
794
  var adContainerEl;
778
795
  var lastAdTagUrl;
779
- var retryAttempts = 0;
780
- var maxRetries = 2;
781
- var backoffBaseMs = 500;
782
796
  var adsLoadedPromise;
783
797
  var adsLoadedResolve;
784
798
  var adsLoadedReject;
@@ -982,7 +996,7 @@ function createImaController(video, options) {
982
996
  if (adsManager) {
983
997
  try {
984
998
  adsManager.destroy();
985
- } catch (e) {}
999
+ } catch (unused) {}
986
1000
  adsManager = void 0;
987
1001
  }
988
1002
  if (adVideoElement) {
@@ -993,7 +1007,7 @@ function createImaController(video, options) {
993
1007
  if (adsLoader) {
994
1008
  try {
995
1009
  adsLoader.destroy();
996
- } catch (e) {}
1010
+ } catch (unused) {}
997
1011
  adsLoader = void 0;
998
1012
  }
999
1013
  }
@@ -1011,7 +1025,7 @@ function createImaController(video, options) {
1011
1025
  try {
1012
1026
  var _adDisplayContainer_initialize;
1013
1027
  (_adDisplayContainer_initialize = adDisplayContainer.initialize) === null || _adDisplayContainer_initialize === void 0 ? void 0 : _adDisplayContainer_initialize.call(adDisplayContainer);
1014
- } catch (e) {}
1028
+ } catch (unused) {}
1015
1029
  }
1016
1030
  }).catch(function() {});
1017
1031
  },
@@ -1075,7 +1089,6 @@ function createImaController(video, options) {
1075
1089
  _state.sent();
1076
1090
  google = window.google;
1077
1091
  lastAdTagUrl = vastTagUrl;
1078
- retryAttempts = 0;
1079
1092
  if (!adDisplayContainer) {
1080
1093
  container = document.createElement("div");
1081
1094
  container.style.position = "absolute";
@@ -1159,32 +1172,23 @@ function createImaController(video, options) {
1159
1172
  }
1160
1173
  }, 300);
1161
1174
  }
1162
- hideContentVideo();
1175
+ showContentVideo();
1163
1176
  if (adsLoadedReject) {
1164
1177
  adsLoadedReject(new Error("Ad playback error"));
1165
1178
  adsLoadedReject = void 0;
1166
1179
  adsLoadedResolve = void 0;
1167
1180
  }
1168
- if (lastAdTagUrl && retryAttempts < maxRetries && !isNoFill) {
1169
- var delay = backoffBaseMs * Math.pow(2, retryAttempts++);
1170
- window.setTimeout(function() {
1171
- try {
1172
- makeAdsRequest(google, lastAdTagUrl);
1173
- } catch (e) {}
1174
- }, delay);
1175
- } else {
1176
- emit("ad_error", {
1177
- code: errorCode,
1178
- vastErrorCode: vastErrorCode,
1179
- message: errorMessage,
1180
- cause: innerError,
1181
- isNoFill: isNoFill
1182
- });
1183
- if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1184
- if (video.paused) {
1185
- var _video_play;
1186
- (_video_play = video.play()) === null || _video_play === void 0 ? void 0 : _video_play.catch(function() {});
1187
- }
1181
+ emit("ad_error", {
1182
+ code: errorCode,
1183
+ vastErrorCode: vastErrorCode,
1184
+ message: errorMessage,
1185
+ cause: innerError,
1186
+ isNoFill: isNoFill
1187
+ });
1188
+ if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
1189
+ if (video.paused) {
1190
+ var _video_play;
1191
+ (_video_play = video.play()) === null || _video_play === void 0 ? void 0 : _video_play.catch(function() {});
1188
1192
  }
1189
1193
  }
1190
1194
  });
@@ -1202,7 +1206,7 @@ function createImaController(video, options) {
1202
1206
  if (adsManager) {
1203
1207
  try {
1204
1208
  adsManager.setVolume(adVolume);
1205
- } catch (e) {}
1209
+ } catch (unused) {}
1206
1210
  }
1207
1211
  emit("content_pause");
1208
1212
  });
@@ -1216,7 +1220,7 @@ function createImaController(video, options) {
1216
1220
  if (adsManager) {
1217
1221
  try {
1218
1222
  adsManager.setVolume(originalMutedState ? 0 : adVolume);
1219
- } catch (e) {}
1223
+ } catch (unused) {}
1220
1224
  }
1221
1225
  }
1222
1226
  if (adContainerEl) {
@@ -1230,7 +1234,7 @@ function createImaController(video, options) {
1230
1234
  adsManager.addEventListener(AdEvent.CONTENT_RESUME_REQUESTED, function() {
1231
1235
  adPlaying = false;
1232
1236
  setAdPlayingFlag(false);
1233
- hideContentVideo();
1237
+ showContentVideo();
1234
1238
  emit("content_resume");
1235
1239
  });
1236
1240
  adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, function() {
@@ -1246,7 +1250,7 @@ function createImaController(video, options) {
1246
1250
  }
1247
1251
  }, 300);
1248
1252
  }
1249
- hideContentVideo();
1253
+ showContentVideo();
1250
1254
  emit("all_ads_completed");
1251
1255
  });
1252
1256
  if (adsLoadedResolve) {
@@ -1268,7 +1272,7 @@ function createImaController(video, options) {
1268
1272
  }
1269
1273
  }, 300);
1270
1274
  }
1271
- hideContentVideo();
1275
+ showContentVideo();
1272
1276
  if (adsLoadedReject) {
1273
1277
  adsLoadedReject(new Error("Failed to setup ads manager"));
1274
1278
  adsLoadedReject = void 0;
@@ -1311,7 +1315,7 @@ function createImaController(video, options) {
1311
1315
  }
1312
1316
  }, 300);
1313
1317
  }
1314
- hideContentVideo();
1318
+ showContentVideo();
1315
1319
  if (adsLoadedReject) {
1316
1320
  adsLoadedReject(new Error(isNoFill ? "No ads available" : "Ads loader error"));
1317
1321
  adsLoadedReject = void 0;
@@ -1377,7 +1381,7 @@ function createImaController(video, options) {
1377
1381
  }
1378
1382
  try {
1379
1383
  adsManager.setVolume(originalMutedState ? 0 : adVolume);
1380
- } catch (e) {}
1384
+ } catch (unused) {}
1381
1385
  adsManager.start();
1382
1386
  return [
1383
1387
  2,
@@ -1459,7 +1463,7 @@ function createImaController(video, options) {
1459
1463
  try {
1460
1464
  ;
1461
1465
  adsManager === null || adsManager === void 0 ? void 0 : (_adsManager_stop = adsManager.stop) === null || _adsManager_stop === void 0 ? void 0 : _adsManager_stop.call(adsManager);
1462
- } catch (e) {}
1466
+ } catch (unused) {}
1463
1467
  destroyAdsManager();
1464
1468
  return [
1465
1469
  2
@@ -1490,7 +1494,7 @@ function createImaController(video, options) {
1490
1494
  try {
1491
1495
  var _adsLoader_destroy;
1492
1496
  adsLoader === null || adsLoader === void 0 ? void 0 : (_adsLoader_destroy = adsLoader.destroy) === null || _adsLoader_destroy === void 0 ? void 0 : _adsLoader_destroy.call(adsLoader);
1493
- } catch (e) {}
1497
+ } catch (unused) {}
1494
1498
  adDisplayContainer = void 0;
1495
1499
  adsLoader = void 0;
1496
1500
  contentVideoHidden = false;
@@ -1539,7 +1543,7 @@ function createImaController(video, options) {
1539
1543
  if (adsManager && adPlaying) {
1540
1544
  try {
1541
1545
  adsManager.setVolume(clampedVolume);
1542
- } catch (e) {}
1546
+ } catch (unused) {}
1543
1547
  }
1544
1548
  },
1545
1549
  getAdVolume: function getAdVolume() {
@@ -2643,9 +2647,6 @@ function sendInitialTracking(licenseKey) {
2643
2647
  headers = {
2644
2648
  "Content-Type": "application/json"
2645
2649
  };
2646
- if (licenseKey) {
2647
- headers["Authorization"] = "Bearer ".concat(licenseKey);
2648
- }
2649
2650
  return [
2650
2651
  4,
2651
2652
  fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track", {
@@ -2751,6 +2752,234 @@ function sendHeartbeat(licenseKey) {
2751
2752
  });
2752
2753
  })();
2753
2754
  }
2755
+ var TRACK_API_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track";
2756
+ function mapToAdTrackingSource(source, adPlayerType) {
2757
+ if (source === "prebid" || source === "ima" || source === "hls") {
2758
+ return source;
2759
+ }
2760
+ if (source === "preload" || source === "ssp") {
2761
+ return source === "ssp" ? "prebid" : "ima";
2762
+ }
2763
+ return adPlayerType === "hls" ? "hls" : "ima";
2764
+ }
2765
+ function postAdTracking(licenseKey, body) {
2766
+ return _async_to_generator(function() {
2767
+ var headers, response;
2768
+ return _ts_generator(this, function(_state) {
2769
+ switch(_state.label){
2770
+ case 0:
2771
+ headers = {
2772
+ "Content-Type": "application/json"
2773
+ };
2774
+ if (licenseKey) {
2775
+ headers["Authorization"] = "Bearer ".concat(licenseKey);
2776
+ }
2777
+ return [
2778
+ 4,
2779
+ fetch(TRACK_API_URL, {
2780
+ method: "POST",
2781
+ headers: headers,
2782
+ body: JSON.stringify(body)
2783
+ })
2784
+ ];
2785
+ case 1:
2786
+ response = _state.sent();
2787
+ if (!response.ok) {
2788
+ throw new Error("HTTP error! status: ".concat(response.status));
2789
+ }
2790
+ return [
2791
+ 4,
2792
+ response.json()
2793
+ ];
2794
+ case 2:
2795
+ _state.sent();
2796
+ return [
2797
+ 2
2798
+ ];
2799
+ }
2800
+ });
2801
+ })();
2802
+ }
2803
+ function sendAdDetectTracking(licenseKey, payload) {
2804
+ return _async_to_generator(function() {
2805
+ var _payload_source, _payload_timestamp, clientInfo, browserId, adDetectInfo, body, error;
2806
+ return _ts_generator(this, function(_state) {
2807
+ switch(_state.label){
2808
+ case 0:
2809
+ _state.trys.push([
2810
+ 0,
2811
+ 3,
2812
+ ,
2813
+ 4
2814
+ ]);
2815
+ clientInfo = getClientInfo();
2816
+ return [
2817
+ 4,
2818
+ getBrowserID(clientInfo)
2819
+ ];
2820
+ case 1:
2821
+ browserId = _state.sent();
2822
+ adDetectInfo = _object_spread({
2823
+ source: (_payload_source = payload.source) !== null && _payload_source !== void 0 ? _payload_source : "scte35",
2824
+ timestamp: (_payload_timestamp = payload.timestamp) !== null && _payload_timestamp !== void 0 ? _payload_timestamp : /* @__PURE__ */ new Date().toISOString()
2825
+ }, payload.durationSeconds != null && {
2826
+ durationSeconds: payload.durationSeconds
2827
+ }, payload.ptsSeconds != null && {
2828
+ ptsSeconds: payload.ptsSeconds
2829
+ }, payload.detectedAtFragmentSn != null && {
2830
+ detectedAtFragmentSn: payload.detectedAtFragmentSn
2831
+ });
2832
+ body = _object_spread_props(_object_spread({
2833
+ browserId: browserId
2834
+ }, clientInfo, licenseKey && {
2835
+ licenseKey: licenseKey
2836
+ }), {
2837
+ adDetectInfo: adDetectInfo
2838
+ });
2839
+ return [
2840
+ 4,
2841
+ postAdTracking(licenseKey, body)
2842
+ ];
2843
+ case 2:
2844
+ _state.sent();
2845
+ return [
2846
+ 3,
2847
+ 4
2848
+ ];
2849
+ case 3:
2850
+ error = _state.sent();
2851
+ console.error("[StormcloudVideoPlayer] Error sending ad-detect tracking:", error);
2852
+ return [
2853
+ 3,
2854
+ 4
2855
+ ];
2856
+ case 4:
2857
+ return [
2858
+ 2
2859
+ ];
2860
+ }
2861
+ });
2862
+ })();
2863
+ }
2864
+ function sendAdLoadedTracking(licenseKey, payload, adPlayerType) {
2865
+ return _async_to_generator(function() {
2866
+ var clientInfo, browserId, source, adLoadedInfo, body, error;
2867
+ return _ts_generator(this, function(_state) {
2868
+ switch(_state.label){
2869
+ case 0:
2870
+ _state.trys.push([
2871
+ 0,
2872
+ 3,
2873
+ ,
2874
+ 4
2875
+ ]);
2876
+ clientInfo = getClientInfo();
2877
+ return [
2878
+ 4,
2879
+ getBrowserID(clientInfo)
2880
+ ];
2881
+ case 1:
2882
+ browserId = _state.sent();
2883
+ source = mapToAdTrackingSource(payload.source, adPlayerType);
2884
+ adLoadedInfo = _object_spread({
2885
+ source: source,
2886
+ timestamp: /* @__PURE__ */ new Date().toISOString()
2887
+ }, payload.vastUrl != null && {
2888
+ vastUrl: payload.vastUrl
2889
+ }, payload.durationSeconds != null && {
2890
+ durationSeconds: payload.durationSeconds
2891
+ });
2892
+ body = _object_spread_props(_object_spread({
2893
+ browserId: browserId
2894
+ }, clientInfo, licenseKey && {
2895
+ licenseKey: licenseKey
2896
+ }), {
2897
+ adLoadedInfo: adLoadedInfo
2898
+ });
2899
+ return [
2900
+ 4,
2901
+ postAdTracking(licenseKey, body)
2902
+ ];
2903
+ case 2:
2904
+ _state.sent();
2905
+ return [
2906
+ 3,
2907
+ 4
2908
+ ];
2909
+ case 3:
2910
+ error = _state.sent();
2911
+ console.error("[StormcloudVideoPlayer] Error sending ad-loaded tracking:", error);
2912
+ return [
2913
+ 3,
2914
+ 4
2915
+ ];
2916
+ case 4:
2917
+ return [
2918
+ 2
2919
+ ];
2920
+ }
2921
+ });
2922
+ })();
2923
+ }
2924
+ function sendAdImpressionTracking(licenseKey, payload, adPlayerType) {
2925
+ return _async_to_generator(function() {
2926
+ var clientInfo, browserId, source, adImpressionInfo, body, error;
2927
+ return _ts_generator(this, function(_state) {
2928
+ switch(_state.label){
2929
+ case 0:
2930
+ _state.trys.push([
2931
+ 0,
2932
+ 3,
2933
+ ,
2934
+ 4
2935
+ ]);
2936
+ clientInfo = getClientInfo();
2937
+ return [
2938
+ 4,
2939
+ getBrowserID(clientInfo)
2940
+ ];
2941
+ case 1:
2942
+ browserId = _state.sent();
2943
+ source = mapToAdTrackingSource(payload.source, adPlayerType);
2944
+ adImpressionInfo = _object_spread({
2945
+ source: source,
2946
+ adIndex: payload.adIndex,
2947
+ timestamp: /* @__PURE__ */ new Date().toISOString()
2948
+ }, payload.durationSeconds != null && {
2949
+ durationSeconds: payload.durationSeconds
2950
+ });
2951
+ body = _object_spread_props(_object_spread({
2952
+ browserId: browserId
2953
+ }, clientInfo, licenseKey && {
2954
+ licenseKey: licenseKey
2955
+ }), {
2956
+ adImpressionInfo: adImpressionInfo
2957
+ });
2958
+ return [
2959
+ 4,
2960
+ postAdTracking(licenseKey, body)
2961
+ ];
2962
+ case 2:
2963
+ _state.sent();
2964
+ return [
2965
+ 3,
2966
+ 4
2967
+ ];
2968
+ case 3:
2969
+ error = _state.sent();
2970
+ console.error("[StormcloudVideoPlayer] Error sending ad-impression tracking:", error);
2971
+ return [
2972
+ 3,
2973
+ 4
2974
+ ];
2975
+ case 4:
2976
+ return [
2977
+ 2
2978
+ ];
2979
+ }
2980
+ });
2981
+ })();
2982
+ }
2754
2983
  // src/utils/polyfills.ts
2755
2984
  function polyfillURLSearchParams() {
2756
2985
  if (typeof URLSearchParams !== "undefined") {
@@ -3032,18 +3261,26 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3032
3261
  this.maxPlaceholderDurationMs = 5e3;
3033
3262
  this.isShowingPlaceholder = false;
3034
3263
  this.totalAdRequestsInBreak = 0;
3035
- this.maxTotalAdRequestsPerBreak = 20;
3264
+ this.maxTotalAdRequestsPerBreak = 10;
3036
3265
  this.pendingAdBreak = null;
3037
3266
  this.consecutiveFailures = 0;
3038
3267
  this.maxConsecutiveFailures = 5;
3039
3268
  this.lastAdRequestTime = 0;
3040
- this.minAdRequestIntervalMs = 2500;
3269
+ this.minAdRequestIntervalMs = 3e3;
3041
3270
  this.backoffBaseMs = 1e3;
3042
3271
  this.maxBackoffMs = 15e3;
3272
+ this.globalConsecutiveNoFills = 0;
3273
+ this.globalNoFillThreshold = 3;
3274
+ this.globalNoFillCooldownUntil = 0;
3275
+ this.globalNoFillBackoffBaseMs = 5e3;
3276
+ this.globalNoFillBackoffMaxMs = 6e4;
3277
+ this.globalLastGamRequestTime = 0;
3278
+ this.globalMinGamIntervalMs = 3e3;
3043
3279
  this.preloadPool = [];
3044
- this.maxPreloadPoolSize = 3;
3280
+ this.maxPreloadPoolSize = 2;
3045
3281
  this.preloadPoolActive = false;
3046
3282
  this.preloadPoolLoopRunning = false;
3283
+ this.adDetectSentForCurrentBreak = false;
3047
3284
  this.continuousFetchLoopRunning = false;
3048
3285
  initializePolyfills();
3049
3286
  var browserOverrides = getBrowserConfigOverrides();
@@ -3184,7 +3421,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3184
3421
  });
3185
3422
  this.hls.on(import_hls2.default.Events.MANIFEST_PARSED, function(_, data) {
3186
3423
  return _async_to_generator(function() {
3187
- var _this_hls_levels, _this_hls, _this_hls_levels_some, adBehavior, _this_config_minSegmentsBeforePlay, minSegments, _this_video_play;
3424
+ var _this_config_minSegmentsBeforePlay, _ref, _this_hls_levels, _this_hls, adBehavior, minSegments, _this_video_play;
3188
3425
  return _ts_generator(this, function(_state) {
3189
3426
  switch(_state.label){
3190
3427
  case 0:
@@ -3193,10 +3430,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3193
3430
  } else {
3194
3431
  ;
3195
3432
  ;
3196
- this.isLiveStream = (_this_hls_levels_some = (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : (_this_hls_levels = _this_hls.levels) === null || _this_hls_levels === void 0 ? void 0 : _this_hls_levels.some(function(level) {
3433
+ this.isLiveStream = (_ref = (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : (_this_hls_levels = _this_hls.levels) === null || _this_hls_levels === void 0 ? void 0 : _this_hls_levels.some(function(level) {
3197
3434
  var _level_details, _level_details1;
3198
3435
  return (level === null || level === void 0 ? void 0 : (_level_details = level.details) === null || _level_details === void 0 ? void 0 : _level_details.live) === true || (level === null || level === void 0 ? void 0 : (_level_details1 = level.details) === null || _level_details1 === void 0 ? void 0 : _level_details1.type) === "LIVE";
3199
- })) !== null && _this_hls_levels_some !== void 0 ? _this_hls_levels_some : false;
3436
+ })) !== null && _ref !== void 0 ? _ref : false;
3200
3437
  }
3201
3438
  if (this.config.debugAdTiming) {
3202
3439
  adBehavior = this.shouldContinueLiveStreamDuringAds() ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
@@ -3260,9 +3497,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3260
3497
  var tag = "";
3261
3498
  var value = "";
3262
3499
  if (Array.isArray(entry)) {
3263
- var _entry_;
3500
+ var _entry_, _entry_1;
3264
3501
  tag = String((_entry_ = entry[0]) !== null && _entry_ !== void 0 ? _entry_ : "");
3265
- var _entry_1;
3266
3502
  value = String((_entry_1 = entry[1]) !== null && _entry_1 !== void 0 ? _entry_1 : "");
3267
3503
  } else if (typeof entry === "string") {
3268
3504
  var idx = entry.indexOf(":");
@@ -3385,9 +3621,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3385
3621
  var tag = "";
3386
3622
  var value = "";
3387
3623
  if (Array.isArray(entry)) {
3388
- var _entry_;
3624
+ var _entry_, _entry_1;
3389
3625
  tag = String((_entry_ = entry[0]) !== null && _entry_ !== void 0 ? _entry_ : "");
3390
- var _entry_1;
3391
3626
  value = String((_entry_1 = entry[1]) !== null && _entry_1 !== void 0 ? _entry_1 : "");
3392
3627
  } else if (typeof entry === "string") {
3393
3628
  var idx = entry.indexOf(":");
@@ -3437,10 +3672,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3437
3672
  }
3438
3673
  });
3439
3674
  } else if (tag.includes("EXT-X-DATERANGE")) {
3675
+ var _attrs_CLASS;
3440
3676
  var attrs = _this.parseAttributeList(value);
3441
3677
  var hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
3442
3678
  var hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
3443
- var _attrs_CLASS;
3444
3679
  var klass = String((_attrs_CLASS = attrs["CLASS"]) !== null && _attrs_CLASS !== void 0 ? _attrs_CLASS : "");
3445
3680
  var duration = _this.toNumber(attrs["DURATION"]);
3446
3681
  if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
@@ -3515,6 +3750,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3515
3750
  value: function attachImaEventListeners() {
3516
3751
  var _this = this;
3517
3752
  this.ima.on("all_ads_completed", function() {
3753
+ sendAdImpressionTracking(_this.config.licenseKey, {
3754
+ adIndex: _this.currentAdIndex
3755
+ }, _this.config.adPlayerType).catch(function() {});
3518
3756
  var remaining = _this.getRemainingAdMs();
3519
3757
  _this.consecutiveFailures = 0;
3520
3758
  if (_this.config.debugAdTiming) {
@@ -3554,6 +3792,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3554
3792
  _this.clearAdRequestWatchdog();
3555
3793
  _this.activeAdRequestToken = null;
3556
3794
  _this.showAds = true;
3795
+ _this.resetGamNoFillCounter();
3557
3796
  if (_this.inAdBreak && _this.expectedAdBreakDurationMs != null) {
3558
3797
  if (_this.adStopTimerId == null) {
3559
3798
  _this.currentAdBreakStartWallClockMs = Date.now();
@@ -3576,6 +3815,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3576
3815
  }
3577
3816
  });
3578
3817
  this.ima.on("content_resume", function() {
3818
+ sendAdImpressionTracking(_this.config.licenseKey, {
3819
+ adIndex: _this.currentAdIndex
3820
+ }, _this.config.adPlayerType).catch(function() {});
3579
3821
  if (!_this.video.muted) {
3580
3822
  _this.video.muted = true;
3581
3823
  _this.video.volume = 0;
@@ -3842,11 +4084,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3842
4084
  }
3843
4085
  var daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
3844
4086
  if (daterangeMatch) {
3845
- var _daterangeMatch_;
4087
+ var _daterangeMatch_, _attrs_CLASS;
3846
4088
  var attrs = this.parseAttributeList((_daterangeMatch_ = daterangeMatch[1]) !== null && _daterangeMatch_ !== void 0 ? _daterangeMatch_ : "");
3847
4089
  var hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
3848
4090
  var hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
3849
- var _attrs_CLASS;
3850
4091
  var klass = String((_attrs_CLASS = attrs["CLASS"]) !== null && _attrs_CLASS !== void 0 ? _attrs_CLASS : "");
3851
4092
  var duration = this.toNumber(attrs["DURATION"]);
3852
4093
  if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
@@ -3922,7 +4163,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3922
4163
  var out = "";
3923
4164
  for(var i = 0; i < value.length; i++)out += String.fromCharCode(value[i]);
3924
4165
  return out;
3925
- } catch (e) {
4166
+ } catch (unused) {
3926
4167
  return void 0;
3927
4168
  }
3928
4169
  }
@@ -3941,6 +4182,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3941
4182
  });
3942
4183
  }
3943
4184
  if (marker.type === "start") {
4185
+ var _this_config_immediateManifestAds;
3944
4186
  var _this_pendingAdBreak;
3945
4187
  if (!this.video.muted) {
3946
4188
  this.video.muted = true;
@@ -3959,13 +4201,19 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3959
4201
  }
3960
4202
  return;
3961
4203
  }
4204
+ if (!this.adDetectSentForCurrentBreak) {
4205
+ this.adDetectSentForCurrentBreak = true;
4206
+ var detectPayload = {};
4207
+ if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
4208
+ if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
4209
+ sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
4210
+ }
3962
4211
  var hasPrefetchedAds = this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0;
3963
4212
  this.inAdBreak = true;
3964
4213
  var durationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : ((_this_pendingAdBreak = this.pendingAdBreak) === null || _this_pendingAdBreak === void 0 ? void 0 : _this_pendingAdBreak.marker.durationSeconds) != null ? this.pendingAdBreak.marker.durationSeconds * 1e3 : void 0;
3965
4214
  this.expectedAdBreakDurationMs = durationMs;
3966
4215
  this.currentAdBreakStartWallClockMs = Date.now();
3967
4216
  var isManifestMarker = this.isManifestBasedMarker(marker);
3968
- var _this_config_immediateManifestAds;
3969
4217
  var forceImmediate = (_this_config_immediateManifestAds = this.config.immediateManifestAds) !== null && _this_config_immediateManifestAds !== void 0 ? _this_config_immediateManifestAds : true;
3970
4218
  if (this.config.debugAdTiming) {
3971
4219
  console.log("[StormcloudVideoPlayer] Ad start decision:", {
@@ -4120,9 +4368,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4120
4368
  var regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
4121
4369
  var match;
4122
4370
  while((match = regex.exec(value)) !== null){
4123
- var _match_;
4371
+ var _match_, _ref, _match_1;
4124
4372
  var key = (_match_ = match[1]) !== null && _match_ !== void 0 ? _match_ : "";
4125
- var _match_1, _ref;
4126
4373
  var rawVal = (_ref = (_match_1 = match[3]) !== null && _match_1 !== void 0 ? _match_1 : match[4]) !== null && _ref !== void 0 ? _ref : "";
4127
4374
  if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
4128
4375
  rawVal = rawVal.slice(1, -1);
@@ -4467,13 +4714,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4467
4714
  {
4468
4715
  key: "shouldShowNativeControls",
4469
4716
  value: function shouldShowNativeControls() {
4717
+ var _this_config_showCustomControls;
4470
4718
  var streamType = this.getStreamType();
4471
4719
  if (streamType === "other") {
4472
- var _this_config_showCustomControls;
4473
- return !((_this_config_showCustomControls = this.config.showCustomControls) !== null && _this_config_showCustomControls !== void 0 ? _this_config_showCustomControls : false);
4720
+ var _this_config_showCustomControls1;
4721
+ return !((_this_config_showCustomControls1 = this.config.showCustomControls) !== null && _this_config_showCustomControls1 !== void 0 ? _this_config_showCustomControls1 : false);
4474
4722
  }
4475
- var _this_config_showCustomControls1;
4476
- return !!(this.config.allowNativeHls && !((_this_config_showCustomControls1 = this.config.showCustomControls) !== null && _this_config_showCustomControls1 !== void 0 ? _this_config_showCustomControls1 : false));
4723
+ return !!(this.config.allowNativeHls && !((_this_config_showCustomControls = this.config.showCustomControls) !== null && _this_config_showCustomControls !== void 0 ? _this_config_showCustomControls : false));
4477
4724
  }
4478
4725
  },
4479
4726
  {
@@ -4518,6 +4765,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4518
4765
  isFetching: false,
4519
4766
  fetchStartTime: Date.now()
4520
4767
  });
4768
+ this.adDetectSentForCurrentBreak = true;
4769
+ var detectPayload = {};
4770
+ if (marker.durationSeconds != null) detectPayload.durationSeconds = marker.durationSeconds;
4771
+ if (marker.ptsSeconds != null) detectPayload.ptsSeconds = marker.ptsSeconds;
4772
+ if (fragmentSn !== void 0) detectPayload.detectedAtFragmentSn = fragmentSn;
4773
+ sendAdDetectTracking(this.config.licenseKey, detectPayload).catch(function() {});
4521
4774
  if (this.config.debugAdTiming) {
4522
4775
  console.log("[PREFETCH] \uD83D\uDD04 Starting ad prefetch for upcoming ad break");
4523
4776
  console.log("[PREFETCH] \uD83D\uDCCB Pre-generated ".concat(generatedUrls.length, " VAST URLs"));
@@ -4581,6 +4834,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4581
4834
  var _this, loadPromise;
4582
4835
  return _ts_generator(this, function(_state) {
4583
4836
  _this = this;
4837
+ if (this.isGamInCooldown()) {
4838
+ if (this.config.debugAdTiming) {
4839
+ console.log("[CIRCUIT-BREAKER] GAM in cooldown, skipping preload");
4840
+ }
4841
+ return [
4842
+ 2
4843
+ ];
4844
+ }
4584
4845
  if (this.preloadPool.some(function(entry) {
4585
4846
  return entry.vastUrl === vastUrl;
4586
4847
  }) || this.failedVastUrls.has(vastUrl) || this.isUrlInCooldown(vastUrl)) {
@@ -4610,26 +4871,32 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4610
4871
  case 1:
4611
4872
  _state.trys.push([
4612
4873
  1,
4613
- 4,
4874
+ 5,
4614
4875
  ,
4615
- 5
4876
+ 6
4616
4877
  ]);
4617
4878
  continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();
4618
4879
  preloadIma = this.createAdPlayer(continueLiveStreamDuringAds);
4619
4880
  preloadIma.initialize();
4620
- errorListener = function(payload) {
4881
+ errorListener = function errorListener(payload) {
4621
4882
  hasAdError = true;
4622
4883
  adErrorPayload = payload;
4623
4884
  };
4624
4885
  preloadIma.on("ad_error", errorListener);
4625
- errorListenerCleanup = function() {
4886
+ errorListenerCleanup = function errorListenerCleanup() {
4626
4887
  return preloadIma.off("ad_error", errorListener);
4627
4888
  };
4628
4889
  return [
4629
4890
  4,
4630
- preloadIma.requestAds(vastUrl)
4891
+ this.enforceGlobalRateLimit()
4631
4892
  ];
4632
4893
  case 2:
4894
+ _state.sent();
4895
+ return [
4896
+ 4,
4897
+ preloadIma.requestAds(vastUrl)
4898
+ ];
4899
+ case 3:
4633
4900
  _state.sent();
4634
4901
  preloadIma.pause();
4635
4902
  return [
@@ -4638,7 +4905,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4638
4905
  return setTimeout(resolve, 1500);
4639
4906
  })
4640
4907
  ];
4641
- case 3:
4908
+ case 4:
4642
4909
  _state.sent();
4643
4910
  preloadIma.pause();
4644
4911
  if (hasAdError) {
@@ -4647,6 +4914,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4647
4914
  errorListenerCleanup();
4648
4915
  }
4649
4916
  preloadIma.destroy();
4917
+ this.recordGamNoFill();
4650
4918
  if (isNoFill) {
4651
4919
  if (this.config.debugAdTiming) {
4652
4920
  console.log("[PRELOAD-POOL] ⚠️ Ad preload returned no-fill: ".concat(vastUrl));
@@ -4673,7 +4941,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4673
4941
  isReady: true,
4674
4942
  loadPromise: Promise.resolve()
4675
4943
  };
4676
- lateErrorListener = function(payload) {
4944
+ lateErrorListener = function lateErrorListener(payload) {
4677
4945
  var index = _this.preloadPool.findIndex(function(entry) {
4678
4946
  return entry.vastUrl === vastUrl;
4679
4947
  });
@@ -4684,7 +4952,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4684
4952
  }
4685
4953
  try {
4686
4954
  preloadIma.destroy();
4687
- } catch (e) {}
4955
+ } catch (unused) {}
4688
4956
  }
4689
4957
  };
4690
4958
  preloadIma.on("ad_error", lateErrorListener);
@@ -4697,13 +4965,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4697
4965
  }
4698
4966
  return [
4699
4967
  3,
4700
- 5
4968
+ 6
4701
4969
  ];
4702
- case 4:
4970
+ case 5:
4703
4971
  error = _state.sent();
4704
4972
  if (errorListenerCleanup) {
4705
4973
  errorListenerCleanup();
4706
4974
  }
4975
+ this.recordGamNoFill();
4707
4976
  if (this.config.debugAdTiming) {
4708
4977
  console.warn("[PRELOAD-POOL] ⚠️ Failed to preload ad: ".concat(vastUrl), error);
4709
4978
  }
@@ -4714,9 +4983,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4714
4983
  }
4715
4984
  return [
4716
4985
  3,
4717
- 5
4986
+ 6
4718
4987
  ];
4719
- case 5:
4988
+ case 6:
4720
4989
  return [
4721
4990
  2
4722
4991
  ];
@@ -4755,6 +5024,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4755
5024
  3,
4756
5025
  10
4757
5026
  ];
5027
+ if (this.isGamInCooldown()) {
5028
+ if (this.config.debugAdTiming) {
5029
+ console.log("[CIRCUIT-BREAKER] GAM in cooldown, stopping preload pool loop");
5030
+ }
5031
+ return [
5032
+ 3,
5033
+ 10
5034
+ ];
5035
+ }
4758
5036
  if (!(!this.inAdBreak && this.preloadPool.length >= this.maxPreloadPoolSize)) return [
4759
5037
  3,
4760
5038
  3
@@ -4787,7 +5065,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4787
5065
  3,
4788
5066
  8
4789
5067
  ];
4790
- if (!this.preloadPoolActive) {
5068
+ if (!this.preloadPoolActive || this.isGamInCooldown()) {
4791
5069
  return [
4792
5070
  3,
4793
5071
  8
@@ -4968,6 +5246,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4968
5246
  firstAdUrl = preloaded.vastUrl;
4969
5247
  preloadedController = preloaded.imaController;
4970
5248
  usePreloadedAd = true;
5249
+ sendAdLoadedTracking(this.config.licenseKey, {
5250
+ source: "preload",
5251
+ vastUrl: firstAdUrl
5252
+ }, this.config.adPlayerType).catch(function() {});
4971
5253
  if (this.config.debugAdTiming) {
4972
5254
  console.log("[CONTINUOUS-FETCH] \uD83D\uDE80 Using preloaded ad from pool (preloaded in advance, ready immediately!)");
4973
5255
  console.log("[CONTINUOUS-FETCH] Pool still has ".concat(this.preloadPool.length, " preloaded ads ready"));
@@ -5003,9 +5285,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5003
5285
  case 1:
5004
5286
  _state.trys.push([
5005
5287
  1,
5006
- 7,
5288
+ 8,
5007
5289
  ,
5008
- 13
5290
+ 14
5009
5291
  ]);
5010
5292
  if (!(usePreloadedAd && preloadedController)) return [
5011
5293
  3,
@@ -5041,16 +5323,26 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5041
5323
  this.ima.setAdVolume(adVolume);
5042
5324
  return [
5043
5325
  3,
5044
- 6
5326
+ 7
5045
5327
  ];
5046
5328
  case 3:
5329
+ return [
5330
+ 4,
5331
+ this.enforceGlobalRateLimit()
5332
+ ];
5333
+ case 4:
5334
+ _state.sent();
5047
5335
  this.lastAdRequestTime = Date.now();
5048
5336
  return [
5049
5337
  4,
5050
5338
  this.ima.requestAds(firstAdUrl)
5051
5339
  ];
5052
- case 4:
5340
+ case 5:
5053
5341
  _state.sent();
5342
+ sendAdLoadedTracking(this.config.licenseKey, {
5343
+ source: "ssp",
5344
+ vastUrl: firstAdUrl
5345
+ }, this.config.adPlayerType).catch(function() {});
5054
5346
  if (this.config.debugAdTiming) {
5055
5347
  console.log("[CONTINUOUS-FETCH] \u2705 First ad request successful, starting playback");
5056
5348
  }
@@ -5064,7 +5356,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5064
5356
  4,
5065
5357
  this.ima.play()
5066
5358
  ];
5067
- case 5:
5359
+ case 6:
5068
5360
  _state.sent();
5069
5361
  if (this.expectedAdBreakDurationMs != null) {
5070
5362
  this.currentAdBreakStartWallClockMs = Date.now();
@@ -5072,36 +5364,36 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5072
5364
  }
5073
5365
  adVolume1 = currentMuted ? 0 : currentVolume;
5074
5366
  this.ima.setAdVolume(adVolume1);
5075
- _state.label = 6;
5076
- case 6:
5367
+ _state.label = 7;
5368
+ case 7:
5077
5369
  return [
5078
5370
  3,
5079
- 13
5371
+ 14
5080
5372
  ];
5081
- case 7:
5373
+ case 8:
5082
5374
  error = _state.sent();
5083
5375
  if (this.config.debugAdTiming) {
5084
5376
  console.warn("[CONTINUOUS-FETCH] \u26A0\uFE0F First ad request failed:", error);
5085
5377
  }
5086
5378
  if (!!usePreloadedAd) return [
5087
5379
  3,
5088
- 11
5380
+ 12
5089
5381
  ];
5090
5382
  fallbackPreloaded = this.getPreloadedAd();
5091
5383
  if (!fallbackPreloaded) return [
5092
5384
  3,
5093
- 11
5385
+ 12
5094
5386
  ];
5095
5387
  if (this.config.debugAdTiming) {
5096
5388
  console.log("[CONTINUOUS-FETCH] \uD83D\uDD04 First ad failed, using preloaded fallback");
5097
5389
  }
5098
- _state.label = 8;
5099
- case 8:
5390
+ _state.label = 9;
5391
+ case 9:
5100
5392
  _state.trys.push([
5101
- 8,
5102
- 10,
5393
+ 9,
5394
+ 11,
5103
5395
  ,
5104
- 11
5396
+ 12
5105
5397
  ]);
5106
5398
  this.ima.destroy();
5107
5399
  this.video.muted = true;
@@ -5120,7 +5412,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5120
5412
  4,
5121
5413
  this.ima.play()
5122
5414
  ];
5123
- case 9:
5415
+ case 10:
5124
5416
  _state.sent();
5125
5417
  if (this.expectedAdBreakDurationMs != null) {
5126
5418
  this.currentAdBreakStartWallClockMs = Date.now();
@@ -5131,16 +5423,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5131
5423
  return [
5132
5424
  2
5133
5425
  ];
5134
- case 10:
5426
+ case 11:
5135
5427
  fallbackError = _state.sent();
5136
5428
  if (this.config.debugAdTiming) {
5137
5429
  console.warn("[CONTINUOUS-FETCH] \u26A0\uFE0F Preloaded fallback also failed:", fallbackError);
5138
5430
  }
5139
5431
  return [
5140
5432
  3,
5141
- 11
5433
+ 12
5142
5434
  ];
5143
- case 11:
5435
+ case 12:
5144
5436
  if (this.isTemporaryAdError(error)) {
5145
5437
  this.temporaryFailureUrls.set(firstAdUrl, Date.now());
5146
5438
  if (this.config.debugAdTiming) {
@@ -5158,13 +5450,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5158
5450
  4,
5159
5451
  this.tryNextAvailableAdWithRateLimit()
5160
5452
  ];
5161
- case 12:
5453
+ case 13:
5162
5454
  _state.sent();
5163
5455
  return [
5164
5456
  3,
5165
- 13
5457
+ 14
5166
5458
  ];
5167
- case 13:
5459
+ case 14:
5168
5460
  return [
5169
5461
  2
5170
5462
  ];
@@ -5215,6 +5507,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5215
5507
  "break"
5216
5508
  ];
5217
5509
  }
5510
+ if (_this.isGamInCooldown()) {
5511
+ if (_this.config.debugAdTiming) {
5512
+ console.log("[CIRCUIT-BREAKER] GAM in cooldown, stopping URL generation");
5513
+ }
5514
+ return [
5515
+ 2,
5516
+ "break"
5517
+ ];
5518
+ }
5218
5519
  if (_this.consecutiveFailures >= _this.maxConsecutiveFailures) {
5219
5520
  if (_this.config.debugAdTiming) {
5220
5521
  console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Too many consecutive failures (".concat(_this.consecutiveFailures, "), stopping URL generation"));
@@ -5411,16 +5712,25 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5411
5712
  2
5412
5713
  ];
5413
5714
  }
5414
- if (this.consecutiveFailures >= this.maxConsecutiveFailures) {
5715
+ if (this.isGamInCooldown()) {
5415
5716
  if (this.config.debugAdTiming) {
5416
- console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Too many consecutive failures (".concat(this.consecutiveFailures, "), ending ad break"));
5717
+ console.log("[CIRCUIT-BREAKER] GAM in cooldown, ending ad break gracefully");
5417
5718
  }
5418
5719
  this.handleAdPodComplete();
5419
5720
  return [
5420
5721
  2
5421
5722
  ];
5422
5723
  }
5423
- this.cleanupTemporaryFailures();
5724
+ if (this.consecutiveFailures >= this.maxConsecutiveFailures) {
5725
+ if (this.config.debugAdTiming) {
5726
+ console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Too many consecutive failures (".concat(this.consecutiveFailures, "), ending ad break"));
5727
+ }
5728
+ this.handleAdPodComplete();
5729
+ return [
5730
+ 2
5731
+ ];
5732
+ }
5733
+ this.cleanupTemporaryFailures();
5424
5734
  preloaded = this.getPreloadedAd();
5425
5735
  if (!preloaded) return [
5426
5736
  3,
@@ -5429,6 +5739,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5429
5739
  if (this.config.debugAdTiming) {
5430
5740
  console.log("[CONTINUOUS-FETCH] \uD83C\uDFAF Using preloaded ad from pool (".concat(this.preloadPool.length, " remaining in pool)"));
5431
5741
  }
5742
+ sendAdLoadedTracking(this.config.licenseKey, {
5743
+ source: "preload",
5744
+ vastUrl: preloaded.vastUrl
5745
+ }, this.config.adPlayerType).catch(function() {});
5432
5746
  _state.label = 1;
5433
5747
  case 1:
5434
5748
  _state.trys.push([
@@ -5607,6 +5921,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5607
5921
  case 0:
5608
5922
  remaining = this.getRemainingAdMs();
5609
5923
  waitTime = Math.min(this.maxPlaceholderDurationMs, remaining);
5924
+ if (this.isGamInCooldown()) {
5925
+ if (this.config.debugAdTiming) {
5926
+ console.log("[CIRCUIT-BREAKER] GAM in cooldown, skipping placeholder wait");
5927
+ }
5928
+ this.handleAdPodComplete();
5929
+ return [
5930
+ 2
5931
+ ];
5932
+ }
5610
5933
  if (this.consecutiveFailures >= this.maxConsecutiveFailures) {
5611
5934
  if (this.config.debugAdTiming) {
5612
5935
  console.log("[CONTINUOUS-FETCH] \uD83D\uDED1 Skipping placeholder - too many consecutive failures");
@@ -5870,11 +6193,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5870
6193
  {
5871
6194
  key: "ensureAdStoppedByTimer",
5872
6195
  value: function ensureAdStoppedByTimer() {
6196
+ var _this_config_adBreakCheckIntervalMs, _this_expectedAdBreakDurationMs;
5873
6197
  if (!this.inAdBreak) return;
5874
6198
  this.adStopTimerId = void 0;
5875
6199
  var adPlaying = this.ima.isAdPlaying();
5876
6200
  var pendingAds = this.adPodQueue.length > 0;
5877
- var _this_config_adBreakCheckIntervalMs;
5878
6201
  var checkIntervalMs = Math.max(250, Math.floor((_this_config_adBreakCheckIntervalMs = this.config.adBreakCheckIntervalMs) !== null && _this_config_adBreakCheckIntervalMs !== void 0 ? _this_config_adBreakCheckIntervalMs : 1e3));
5879
6202
  var maxExtensionMsConfig = this.config.maxAdBreakExtensionMs;
5880
6203
  var maxExtensionMs = typeof maxExtensionMsConfig === "number" && maxExtensionMsConfig > 0 ? maxExtensionMsConfig : 6e4;
@@ -5882,7 +6205,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5882
6205
  if (this.currentAdBreakStartWallClockMs != null) {
5883
6206
  elapsedSinceStartMs = Date.now() - this.currentAdBreakStartWallClockMs;
5884
6207
  }
5885
- var _this_expectedAdBreakDurationMs;
5886
6208
  var expectedDurationMs = (_this_expectedAdBreakDurationMs = this.expectedAdBreakDurationMs) !== null && _this_expectedAdBreakDurationMs !== void 0 ? _this_expectedAdBreakDurationMs : 0;
5887
6209
  var overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
5888
6210
  var shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
@@ -5996,6 +6318,73 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5996
6318
  }
5997
6319
  }
5998
6320
  },
6321
+ {
6322
+ key: "isGamInCooldown",
6323
+ value: function isGamInCooldown() {
6324
+ return Date.now() < this.globalNoFillCooldownUntil;
6325
+ }
6326
+ },
6327
+ {
6328
+ key: "recordGamNoFill",
6329
+ value: function recordGamNoFill() {
6330
+ this.globalConsecutiveNoFills++;
6331
+ if (this.globalConsecutiveNoFills >= this.globalNoFillThreshold) {
6332
+ var exponent = this.globalConsecutiveNoFills - this.globalNoFillThreshold;
6333
+ var backoff = Math.min(this.globalNoFillBackoffBaseMs * Math.pow(2, exponent), this.globalNoFillBackoffMaxMs);
6334
+ this.globalNoFillCooldownUntil = Date.now() + backoff;
6335
+ if (this.config.debugAdTiming) {
6336
+ console.log("[CIRCUIT-BREAKER] GAM cooldown activated: ".concat(backoff, "ms (").concat(this.globalConsecutiveNoFills, " consecutive no-fills)"));
6337
+ }
6338
+ }
6339
+ }
6340
+ },
6341
+ {
6342
+ key: "resetGamNoFillCounter",
6343
+ value: function resetGamNoFillCounter() {
6344
+ if (this.globalConsecutiveNoFills > 0 && this.config.debugAdTiming) {
6345
+ console.log("[CIRCUIT-BREAKER] Resetting no-fill counter (was ".concat(this.globalConsecutiveNoFills, ")"));
6346
+ }
6347
+ this.globalConsecutiveNoFills = 0;
6348
+ this.globalNoFillCooldownUntil = 0;
6349
+ }
6350
+ },
6351
+ {
6352
+ key: "enforceGlobalRateLimit",
6353
+ value: function enforceGlobalRateLimit() {
6354
+ return _async_to_generator(function() {
6355
+ var now, elapsed, waitMs;
6356
+ return _ts_generator(this, function(_state) {
6357
+ switch(_state.label){
6358
+ case 0:
6359
+ now = Date.now();
6360
+ elapsed = now - this.globalLastGamRequestTime;
6361
+ if (!(elapsed < this.globalMinGamIntervalMs)) return [
6362
+ 3,
6363
+ 2
6364
+ ];
6365
+ waitMs = this.globalMinGamIntervalMs - elapsed;
6366
+ if (this.config.debugAdTiming) {
6367
+ console.log("[RATE-LIMIT] Waiting ".concat(waitMs, "ms before next GAM request"));
6368
+ }
6369
+ return [
6370
+ 4,
6371
+ new Promise(function(resolve) {
6372
+ return setTimeout(resolve, waitMs);
6373
+ })
6374
+ ];
6375
+ case 1:
6376
+ _state.sent();
6377
+ _state.label = 2;
6378
+ case 2:
6379
+ this.globalLastGamRequestTime = Date.now();
6380
+ return [
6381
+ 2
6382
+ ];
6383
+ }
6384
+ });
6385
+ }).call(this);
6386
+ }
6387
+ },
5999
6388
  {
6000
6389
  key: "playSingleAd",
6001
6390
  value: function playSingleAd(vastTagUrl) {
@@ -6027,6 +6416,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6027
6416
  }
6028
6417
  throw new Error("Too many consecutive failures");
6029
6418
  }
6419
+ if (this.isGamInCooldown()) {
6420
+ if (this.config.debugAdTiming) {
6421
+ console.warn("[CIRCUIT-BREAKER] GAM in cooldown, skipping ad request");
6422
+ }
6423
+ throw new Error("GAM in cooldown");
6424
+ }
6030
6425
  this.recreateImaController();
6031
6426
  requestToken = ++this.adRequestTokenCounter;
6032
6427
  this.activeAdRequestToken = requestToken;
@@ -6035,37 +6430,47 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6035
6430
  case 1:
6036
6431
  _state.trys.push([
6037
6432
  1,
6038
- 11,
6433
+ 12,
6039
6434
  ,
6040
- 16
6435
+ 17
6041
6436
  ]);
6437
+ return [
6438
+ 4,
6439
+ this.enforceGlobalRateLimit()
6440
+ ];
6441
+ case 2:
6442
+ _state.sent();
6042
6443
  this.lastAdRequestTime = Date.now();
6043
6444
  return [
6044
6445
  4,
6045
6446
  this.ima.requestAds(vastTagUrl)
6046
6447
  ];
6047
- case 2:
6448
+ case 3:
6048
6449
  _state.sent();
6450
+ sendAdLoadedTracking(this.config.licenseKey, {
6451
+ source: "ssp",
6452
+ vastUrl: vastTagUrl
6453
+ }, this.config.adPlayerType).catch(function() {});
6049
6454
  this.clearAdRequestWatchdog();
6050
6455
  if (this.activeAdRequestToken !== requestToken) {
6051
6456
  return [
6052
6457
  2
6053
6458
  ];
6054
6459
  }
6055
- _state.label = 3;
6056
- case 3:
6460
+ _state.label = 4;
6461
+ case 4:
6057
6462
  _state.trys.push([
6058
- 3,
6059
- 5,
6463
+ 4,
6464
+ 6,
6060
6465
  ,
6061
- 10
6466
+ 11
6062
6467
  ]);
6063
6468
  this.startAdFailsafeTimer(requestToken);
6064
6469
  return [
6065
6470
  4,
6066
6471
  this.ima.play()
6067
6472
  ];
6068
- case 4:
6473
+ case 5:
6069
6474
  _state.sent();
6070
6475
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6071
6476
  this.currentAdBreakStartWallClockMs = Date.now();
@@ -6079,9 +6484,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6079
6484
  this.temporaryFailureUrls.delete(vastTagUrl);
6080
6485
  return [
6081
6486
  3,
6082
- 10
6487
+ 11
6083
6488
  ];
6084
- case 5:
6489
+ case 6:
6085
6490
  playError = _state.sent();
6086
6491
  if (this.config.debugAdTiming) {
6087
6492
  console.error("[AD-ERROR] Failed to play ad:", playError);
@@ -6089,18 +6494,18 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6089
6494
  preloadedFallback = this.getPreloadedAd();
6090
6495
  if (!preloadedFallback) return [
6091
6496
  3,
6092
- 9
6497
+ 10
6093
6498
  ];
6094
6499
  if (this.config.debugAdTiming) {
6095
6500
  console.log("[AD-ERROR] Play failed, trying preloaded fallback ad");
6096
6501
  }
6097
- _state.label = 6;
6098
- case 6:
6502
+ _state.label = 7;
6503
+ case 7:
6099
6504
  _state.trys.push([
6100
- 6,
6101
- 8,
6505
+ 7,
6506
+ 9,
6102
6507
  ,
6103
- 9
6508
+ 10
6104
6509
  ]);
6105
6510
  this.clearAdFailsafeTimer();
6106
6511
  this.ima.destroy();
@@ -6116,7 +6521,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6116
6521
  4,
6117
6522
  this.ima.play()
6118
6523
  ];
6119
- case 7:
6524
+ case 8:
6120
6525
  _state.sent();
6121
6526
  if (this.expectedAdBreakDurationMs != null && this.adStopTimerId == null) {
6122
6527
  this.currentAdBreakStartWallClockMs = Date.now();
@@ -6129,16 +6534,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6129
6534
  return [
6130
6535
  2
6131
6536
  ];
6132
- case 8:
6537
+ case 9:
6133
6538
  fallbackError = _state.sent();
6134
6539
  if (this.config.debugAdTiming) {
6135
6540
  console.warn("[AD-ERROR] Preloaded fallback also failed:", fallbackError);
6136
6541
  }
6137
6542
  return [
6138
6543
  3,
6139
- 9
6544
+ 10
6140
6545
  ];
6141
- case 9:
6546
+ case 10:
6142
6547
  if (this.isTemporaryAdError(playError)) {
6143
6548
  this.temporaryFailureUrls.set(vastTagUrl, Date.now());
6144
6549
  if (this.config.debugAdTiming) {
@@ -6155,12 +6560,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6155
6560
  this.activeAdRequestToken = null;
6156
6561
  }
6157
6562
  throw playError;
6158
- case 10:
6563
+ case 11:
6159
6564
  return [
6160
6565
  3,
6161
- 16
6566
+ 17
6162
6567
  ];
6163
- case 11:
6568
+ case 12:
6164
6569
  error = _state.sent();
6165
6570
  errorMessage = (error === null || error === void 0 ? void 0 : error.message) || "";
6166
6571
  if (this.config.debugAdTiming) {
@@ -6169,18 +6574,18 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6169
6574
  preloadedFallback1 = this.getPreloadedAd();
6170
6575
  if (!preloadedFallback1) return [
6171
6576
  3,
6172
- 15
6577
+ 16
6173
6578
  ];
6174
6579
  if (this.config.debugAdTiming) {
6175
6580
  console.log("[AD-ERROR] Request failed, trying preloaded fallback ad");
6176
6581
  }
6177
- _state.label = 12;
6178
- case 12:
6582
+ _state.label = 13;
6583
+ case 13:
6179
6584
  _state.trys.push([
6180
- 12,
6181
- 14,
6585
+ 13,
6586
+ 15,
6182
6587
  ,
6183
- 15
6588
+ 16
6184
6589
  ]);
6185
6590
  this.clearAdRequestWatchdog();
6186
6591
  this.clearAdFailsafeTimer();
@@ -6197,7 +6602,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6197
6602
  4,
6198
6603
  this.ima.play()
6199
6604
  ];
6200
- case 13:
6605
+ case 14:
6201
6606
  _state.sent();
6202
6607
  currentMuted2 = this.video.muted;
6203
6608
  currentVolume2 = this.video.volume;
@@ -6206,16 +6611,16 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6206
6611
  return [
6207
6612
  2
6208
6613
  ];
6209
- case 14:
6614
+ case 15:
6210
6615
  fallbackError1 = _state.sent();
6211
6616
  if (this.config.debugAdTiming) {
6212
6617
  console.warn("[AD-ERROR] Preloaded fallback also failed:", fallbackError1);
6213
6618
  }
6214
6619
  return [
6215
6620
  3,
6216
- 15
6621
+ 16
6217
6622
  ];
6218
- case 15:
6623
+ case 16:
6219
6624
  if (this.isTemporaryAdError(error)) {
6220
6625
  this.temporaryFailureUrls.set(vastTagUrl, Date.now());
6221
6626
  if (this.config.debugAdTiming) {
@@ -6233,7 +6638,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6233
6638
  this.activeAdRequestToken = null;
6234
6639
  }
6235
6640
  throw error;
6236
- case 16:
6641
+ case 17:
6237
6642
  return [
6238
6643
  2
6239
6644
  ];
@@ -6260,6 +6665,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6260
6665
  }
6261
6666
  this.adRequestQueue = [];
6262
6667
  this.inAdBreak = false;
6668
+ this.adDetectSentForCurrentBreak = false;
6263
6669
  this.expectedAdBreakDurationMs = void 0;
6264
6670
  this.currentAdBreakStartWallClockMs = void 0;
6265
6671
  this.clearAdStartTimer();
@@ -6269,6 +6675,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6269
6675
  this.currentAdIndex = 0;
6270
6676
  this.totalAdsInBreak = 0;
6271
6677
  this.consecutiveFailures = 0;
6678
+ this.globalConsecutiveNoFills = 0;
6272
6679
  this.ima.stop().catch(function() {});
6273
6680
  var restoredMuted = this.ima.getOriginalMutedState();
6274
6681
  var restoredVolume = this.ima.getOriginalVolume();
@@ -6300,6 +6707,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6300
6707
  key: "handleAdFailure",
6301
6708
  value: function handleAdFailure() {
6302
6709
  this.consecutiveFailures++;
6710
+ this.recordGamNoFill();
6303
6711
  var remaining = this.getRemainingAdMs();
6304
6712
  if (this.config.debugAdTiming) {
6305
6713
  console.log("[CONTINUOUS-FETCH] Ad failure: remaining=".concat(remaining, "ms, queued ads=").concat(this.adRequestQueue.length, ", consecutiveFailures=").concat(this.consecutiveFailures), this.adRequestQueue.length > 0 ? {
@@ -6327,8 +6735,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6327
6735
  key: "startAdRequestWatchdog",
6328
6736
  value: function startAdRequestWatchdog(token) {
6329
6737
  var _this = this;
6330
- this.clearAdRequestWatchdog();
6331
6738
  var _this_config_adFailsafeTimeoutMs;
6739
+ this.clearAdRequestWatchdog();
6332
6740
  var timeoutMs = (_this_config_adFailsafeTimeoutMs = this.config.adFailsafeTimeoutMs) !== null && _this_config_adFailsafeTimeoutMs !== void 0 ? _this_config_adFailsafeTimeoutMs : 1e4;
6333
6741
  this.adRequestWatchdogToken = token;
6334
6742
  this.adRequestWatchdogId = window.setTimeout(function() {
@@ -6371,8 +6779,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6371
6779
  key: "startAdFailsafeTimer",
6372
6780
  value: function startAdFailsafeTimer(token) {
6373
6781
  var _this = this;
6374
- this.clearAdFailsafeTimer();
6375
6782
  var _this_config_adFailsafeTimeoutMs;
6783
+ this.clearAdFailsafeTimer();
6376
6784
  var failsafeMs = (_this_config_adFailsafeTimeoutMs = this.config.adFailsafeTimeoutMs) !== null && _this_config_adFailsafeTimeoutMs !== void 0 ? _this_config_adFailsafeTimeoutMs : 1e4;
6377
6785
  this.adFailsafeToken = token;
6378
6786
  this.adFailsafeTimerId = window.setTimeout(function() {
@@ -6697,6 +7105,7 @@ var CRITICAL_PROPS = [
6697
7105
  "driftToleranceMs",
6698
7106
  "vastMode"
6699
7107
  ];
7108
+ var CONTROLS_HIDE_DELAY = 3e3;
6700
7109
  var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6701
7110
  var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, driftToleranceMs = props.driftToleranceMs, immediateManifestAds = props.immediateManifestAds, debugAdTiming = props.debugAdTiming, showCustomControls = props.showCustomControls, hideLoadingIndicator = props.hideLoadingIndicator, onVolumeToggle = props.onVolumeToggle, onFullscreenToggle = props.onFullscreenToggle, onControlClick = props.onControlClick, onReady = props.onReady, wrapperClassName = props.wrapperClassName, wrapperStyle = props.wrapperStyle, className = props.className, style = props.style, controls = props.controls, playsInline = props.playsInline, preload = props.preload, poster = props.poster, children = props.children, licenseKey = props.licenseKey, vastMode = props.vastMode, vastTagUrl = props.vastTagUrl, adPlayerType = props.adPlayerType, minSegmentsBeforePlay = props.minSegmentsBeforePlay, restVideoAttrs = _object_without_properties(props, [
6702
7111
  "src",
@@ -6731,6 +7140,8 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6731
7140
  var videoRef = (0, import_react.useRef)(null);
6732
7141
  var playerRef = (0, import_react.useRef)(null);
6733
7142
  var bufferingTimeoutRef = (0, import_react.useRef)(null);
7143
+ var controlsTimerRef = (0, import_react.useRef)(null);
7144
+ var wrapperRef = (0, import_react.useRef)(null);
6734
7145
  var _import_react_default_useState = _sliced_to_array(import_react.default.useState({
6735
7146
  showAds: false,
6736
7147
  currentIndex: 0,
@@ -6750,23 +7161,51 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6750
7161
  var _import_react_default_useState12 = _sliced_to_array(import_react.default.useState(false), 2), isBuffering = _import_react_default_useState12[0], setIsBuffering = _import_react_default_useState12[1];
6751
7162
  var _import_react_default_useState13 = _sliced_to_array(import_react.default.useState(false), 2), showCenterPlay = _import_react_default_useState13[0], setShowCenterPlay = _import_react_default_useState13[1];
6752
7163
  var _import_react_default_useState14 = _sliced_to_array(import_react.default.useState(false), 2), showLicenseWarning = _import_react_default_useState14[0], setShowLicenseWarning = _import_react_default_useState14[1];
6753
- var _import_react_default_useState15 = _sliced_to_array(import_react.default.useState(typeof window !== "undefined" ? window.innerWidth : 1920), 2), viewportWidth = _import_react_default_useState15[0], setViewportWidth = _import_react_default_useState15[1];
6754
- var _import_react_default_useState16 = _sliced_to_array(import_react.default.useState(typeof window !== "undefined" ? window.innerHeight > window.innerWidth : false), 2), isPortrait = _import_react_default_useState16[0], setIsPortrait = _import_react_default_useState16[1];
6755
- var getResponsiveScale = function() {
7164
+ var _import_react_default_useState15 = _sliced_to_array(import_react.default.useState(true), 2), controlsVisible = _import_react_default_useState15[0], setControlsVisible = _import_react_default_useState15[1];
7165
+ var _import_react_default_useState16 = _sliced_to_array(import_react.default.useState(typeof window !== "undefined" ? window.innerWidth : 1920), 2), viewportWidth = _import_react_default_useState16[0], setViewportWidth = _import_react_default_useState16[1];
7166
+ var _import_react_default_useState17 = _sliced_to_array(import_react.default.useState(typeof window !== "undefined" ? window.innerHeight > window.innerWidth : false), 2), isPortrait = _import_react_default_useState17[0], setIsPortrait = _import_react_default_useState17[1];
7167
+ var getResponsiveScale = function getResponsiveScale() {
6756
7168
  if (viewportWidth < 480) return 0.7;
6757
7169
  if (viewportWidth < 768) return 0.8;
6758
7170
  if (viewportWidth < 1024) return 0.9;
6759
7171
  return 1;
6760
7172
  };
6761
7173
  var responsiveScale = getResponsiveScale();
6762
- var formatTime = function(seconds) {
7174
+ var resetControlsTimer = (0, import_react.useCallback)(function() {
7175
+ if (controlsTimerRef.current) {
7176
+ clearTimeout(controlsTimerRef.current);
7177
+ }
7178
+ setControlsVisible(true);
7179
+ controlsTimerRef.current = window.setTimeout(function() {
7180
+ if (!showVolumeSlider && !showSpeedMenu) {
7181
+ setControlsVisible(false);
7182
+ }
7183
+ }, CONTROLS_HIDE_DELAY);
7184
+ }, [
7185
+ showVolumeSlider,
7186
+ showSpeedMenu
7187
+ ]);
7188
+ var handleWrapperMouseMove = (0, import_react.useCallback)(function() {
7189
+ resetControlsTimer();
7190
+ }, [
7191
+ resetControlsTimer
7192
+ ]);
7193
+ var handleWrapperMouseLeave = (0, import_react.useCallback)(function() {
7194
+ if (!showVolumeSlider && !showSpeedMenu) {
7195
+ setControlsVisible(false);
7196
+ }
7197
+ }, [
7198
+ showVolumeSlider,
7199
+ showSpeedMenu
7200
+ ]);
7201
+ var formatTime = function formatTime(seconds) {
6763
7202
  if (!isFinite(seconds)) return "0:00:00";
6764
7203
  var hours = Math.floor(seconds / 3600);
6765
7204
  var minutes = Math.floor(seconds % 3600 / 60);
6766
7205
  var remainingSeconds = Math.floor(seconds % 60);
6767
7206
  return "".concat(hours, ":").concat(minutes.toString().padStart(2, "0"), ":").concat(remainingSeconds.toString().padStart(2, "0"));
6768
7207
  };
6769
- var handlePlayPause = function() {
7208
+ var handlePlayPause = function handlePlayPause() {
6770
7209
  if (videoRef.current) {
6771
7210
  if (videoRef.current.paused) {
6772
7211
  var hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== "" || videoRef.current.readyState >= 1;
@@ -6784,8 +7223,9 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6784
7223
  setShowCenterPlay(true);
6785
7224
  }
6786
7225
  }
7226
+ resetControlsTimer();
6787
7227
  };
6788
- var handleCenterPlayClick = function() {
7228
+ var handleCenterPlayClick = function handleCenterPlayClick() {
6789
7229
  if (videoRef.current && videoRef.current.paused) {
6790
7230
  var hasValidSource = videoRef.current.src || videoRef.current.currentSrc && videoRef.current.currentSrc !== "" || videoRef.current.readyState >= 1;
6791
7231
  if (hasValidSource) {
@@ -6799,7 +7239,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6799
7239
  }
6800
7240
  }
6801
7241
  };
6802
- var handleTimelineSeek = function(e) {
7242
+ var handleTimelineSeek = function handleTimelineSeek(e) {
6803
7243
  if (videoRef.current && duration > 0 && isFinite(duration)) {
6804
7244
  var rect = e.currentTarget.getBoundingClientRect();
6805
7245
  var clickX = e.clientX - rect.left;
@@ -6809,14 +7249,15 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6809
7249
  videoRef.current.currentTime = newTime;
6810
7250
  }
6811
7251
  }
7252
+ resetControlsTimer();
6812
7253
  };
6813
- var handleVolumeChange = function(newVolume) {
7254
+ var handleVolumeChange = function handleVolumeChange(newVolume) {
6814
7255
  if (playerRef.current && isFinite(newVolume)) {
6815
7256
  var clampedVolume = Math.max(0, Math.min(1, newVolume));
6816
7257
  playerRef.current.setVolume(clampedVolume);
6817
7258
  }
6818
7259
  };
6819
- var handlePlaybackRateChange = function(rate) {
7260
+ var handlePlaybackRateChange = function handlePlaybackRateChange(rate) {
6820
7261
  if (videoRef.current && isFinite(rate) && rate > 0) {
6821
7262
  videoRef.current.playbackRate = rate;
6822
7263
  }
@@ -6853,7 +7294,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6853
7294
  if (playerRef.current) {
6854
7295
  try {
6855
7296
  playerRef.current.destroy();
6856
- } catch (e) {}
7297
+ } catch (unused) {}
6857
7298
  playerRef.current = null;
6858
7299
  }
6859
7300
  var cfg = {
@@ -6893,7 +7334,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6893
7334
  return function() {
6894
7335
  try {
6895
7336
  player.destroy();
6896
- } catch (e) {}
7337
+ } catch (unused) {}
6897
7338
  playerRef.current = null;
6898
7339
  };
6899
7340
  }, [
@@ -6917,7 +7358,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6917
7358
  ]);
6918
7359
  (0, import_react.useEffect)(function() {
6919
7360
  if (!playerRef.current) return;
6920
- var checkAdStatus = function() {
7361
+ var checkAdStatus = function checkAdStatus() {
6921
7362
  if (playerRef.current) {
6922
7363
  var _videoRef_current_dataset, _videoRef_current;
6923
7364
  var showAdsFromMethod = playerRef.current.isShowingAds();
@@ -6947,7 +7388,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6947
7388
  }, []);
6948
7389
  (0, import_react.useEffect)(function() {
6949
7390
  if (typeof window === "undefined" || !playerRef.current) return;
6950
- var handleResize = function() {
7391
+ var handleResize = function handleResize() {
6951
7392
  if (playerRef.current && videoRef.current) {
6952
7393
  if (typeof playerRef.current.resize === "function") {
6953
7394
  playerRef.current.resize();
@@ -6963,8 +7404,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6963
7404
  }, []);
6964
7405
  (0, import_react.useEffect)(function() {
6965
7406
  if (!playerRef.current || !videoRef.current) return;
6966
- var updateStates = function() {
6967
- var _videoRef_current;
7407
+ var updateStates = function updateStates() {
6968
7408
  if (playerRef.current && videoRef.current) {
6969
7409
  setIsMuted(playerRef.current.isMuted());
6970
7410
  setIsPlaying(!videoRef.current.paused);
@@ -6977,12 +7417,11 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6977
7417
  var rateValue = videoRef.current.playbackRate;
6978
7418
  setPlaybackRate(isFinite(rateValue) && rateValue > 0 ? rateValue : 1);
6979
7419
  }
6980
- setIsFullscreen(document.fullscreenElement === ((_videoRef_current = videoRef.current) === null || _videoRef_current === void 0 ? void 0 : _videoRef_current.parentElement));
7420
+ setIsFullscreen(document.fullscreenElement === wrapperRef.current);
6981
7421
  };
6982
7422
  var interval = setInterval(updateStates, 200);
6983
- var handleFullscreenChange = function() {
6984
- var _videoRef_current;
6985
- setIsFullscreen(document.fullscreenElement === ((_videoRef_current = videoRef.current) === null || _videoRef_current === void 0 ? void 0 : _videoRef_current.parentElement));
7423
+ var handleFullscreenChange = function handleFullscreenChange() {
7424
+ setIsFullscreen(document.fullscreenElement === wrapperRef.current);
6986
7425
  };
6987
7426
  document.addEventListener("fullscreenchange", handleFullscreenChange);
6988
7427
  return function() {
@@ -6992,7 +7431,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
6992
7431
  }, []);
6993
7432
  (0, import_react.useEffect)(function() {
6994
7433
  if (!videoRef.current) return;
6995
- var handleLoadedMetadata = function() {
7434
+ var handleLoadedMetadata = function handleLoadedMetadata() {
6996
7435
  if (videoRef.current) {
6997
7436
  var video2 = videoRef.current;
6998
7437
  void video2.offsetHeight;
@@ -7002,19 +7441,19 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7002
7441
  console.log("[StormcloudUI] Video event: loadedmetadata, readyState:", (_videoRef_current = videoRef.current) === null || _videoRef_current === void 0 ? void 0 : _videoRef_current.readyState);
7003
7442
  }
7004
7443
  };
7005
- var handleLoadedData = function() {
7444
+ var handleLoadedData = function handleLoadedData() {
7006
7445
  if (debugAdTiming) {
7007
7446
  var _videoRef_current;
7008
7447
  console.log("[StormcloudUI] Video event: loadeddata, readyState:", (_videoRef_current = videoRef.current) === null || _videoRef_current === void 0 ? void 0 : _videoRef_current.readyState);
7009
7448
  }
7010
7449
  };
7011
- var handleLoadStart = function() {
7450
+ var handleLoadStart = function handleLoadStart() {
7012
7451
  if (debugAdTiming) {
7013
7452
  var _videoRef_current;
7014
7453
  console.log("[StormcloudUI] Video event: loadstart, readyState:", (_videoRef_current = videoRef.current) === null || _videoRef_current === void 0 ? void 0 : _videoRef_current.readyState);
7015
7454
  }
7016
7455
  };
7017
- var handleCanPlay = function() {
7456
+ var handleCanPlay = function handleCanPlay() {
7018
7457
  setIsLoading(false);
7019
7458
  if (bufferingTimeoutRef.current) {
7020
7459
  clearTimeout(bufferingTimeoutRef.current);
@@ -7026,7 +7465,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7026
7465
  console.log("[StormcloudUI] Video event: canplay, readyState:", (_videoRef_current = videoRef.current) === null || _videoRef_current === void 0 ? void 0 : _videoRef_current.readyState, "- clearing loading state, isLoading=false");
7027
7466
  }
7028
7467
  };
7029
- var handleCanPlayThrough = function() {
7468
+ var handleCanPlayThrough = function handleCanPlayThrough() {
7030
7469
  setIsLoading(false);
7031
7470
  if (bufferingTimeoutRef.current) {
7032
7471
  clearTimeout(bufferingTimeoutRef.current);
@@ -7038,7 +7477,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7038
7477
  console.log("[StormcloudUI] Video event: canplaythrough, readyState:", (_videoRef_current = videoRef.current) === null || _videoRef_current === void 0 ? void 0 : _videoRef_current.readyState, "- clearing loading state, isLoading=false");
7039
7478
  }
7040
7479
  };
7041
- var handleWaiting = function() {
7480
+ var handleWaiting = function handleWaiting() {
7042
7481
  if (bufferingTimeoutRef.current) {
7043
7482
  clearTimeout(bufferingTimeoutRef.current);
7044
7483
  }
@@ -7054,7 +7493,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7054
7493
  console.log("[StormcloudUI] Video event: waiting, readyState:", (_videoRef_current = videoRef.current) === null || _videoRef_current === void 0 ? void 0 : _videoRef_current.readyState, "- buffering delay started (300ms)");
7055
7494
  }
7056
7495
  };
7057
- var handlePlaying = function() {
7496
+ var handlePlaying = function handlePlaying() {
7058
7497
  setIsLoading(false);
7059
7498
  if (bufferingTimeoutRef.current) {
7060
7499
  clearTimeout(bufferingTimeoutRef.current);
@@ -7067,7 +7506,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7067
7506
  console.log("[StormcloudUI] Video event: playing, readyState:", (_videoRef_current = videoRef.current) === null || _videoRef_current === void 0 ? void 0 : _videoRef_current.readyState, "- playback started, isLoading=false, isBuffering=false");
7068
7507
  }
7069
7508
  };
7070
- var handlePause = function() {
7509
+ var handlePause = function handlePause() {
7071
7510
  var _playerRef_current, _videoRef_current_dataset, _videoRef_current;
7072
7511
  var isAdActive = ((_playerRef_current = playerRef.current) === null || _playerRef_current === void 0 ? void 0 : _playerRef_current.isShowingAds()) || ((_videoRef_current = videoRef.current) === null || _videoRef_current === void 0 ? void 0 : (_videoRef_current_dataset = _videoRef_current.dataset) === null || _videoRef_current_dataset === void 0 ? void 0 : _videoRef_current_dataset.stormcloudAdPlaying) === "true";
7073
7512
  if (playerRef.current && !isAdActive) {
@@ -7076,7 +7515,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7076
7515
  setShowCenterPlay(false);
7077
7516
  }
7078
7517
  };
7079
- var handleEnded = function() {
7518
+ var handleEnded = function handleEnded() {
7080
7519
  setShowCenterPlay(true);
7081
7520
  };
7082
7521
  var video = videoRef.current;
@@ -7110,13 +7549,25 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7110
7549
  }, [
7111
7550
  debugAdTiming
7112
7551
  ]);
7552
+ (0, import_react.useEffect)(function() {
7553
+ return function() {
7554
+ if (controlsTimerRef.current) {
7555
+ clearTimeout(controlsTimerRef.current);
7556
+ }
7557
+ };
7558
+ }, []);
7559
+ var progressPercent = duration > 0 ? currentTime / duration * 100 : 0;
7560
+ var VolumeIcon = isMuted || volume === 0 ? import_fa.FaVolumeMute : volume < 0.5 ? import_fa.FaVolumeDown : import_fa.FaVolumeUp;
7113
7561
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
7114
7562
  children: [
7115
7563
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", {
7116
- children: "\n @keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n }\n \n .stormcloud-loading-hidden .stormcloud-loading-indicator {\n display: none !important;\n }\n \n .stormcloud-video-wrapper:fullscreen {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n .stormcloud-video-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n \n *:fullscreen {\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n }\n "
7564
+ children: "\n @keyframes sc-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n @keyframes sc-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.6; }\n }\n @keyframes sc-fade-in {\n from { opacity: 0; transform: translateY(8px); }\n to { opacity: 1; transform: translateY(0); }\n }\n .sc-wrapper:fullscreen,\n .sc-wrapper:has(*:fullscreen) {\n border-radius: 0 !important;\n box-shadow: none !important;\n width: 100vw !important;\n height: 100vh !important;\n max-width: 100vw !important;\n max-height: 100vh !important;\n position: fixed !important;\n top: 0 !important;\n left: 0 !important;\n z-index: 999999 !important;\n background: #000 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n .sc-ctrl-btn {\n background: none;\n border: none;\n color: #fff;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n padding: 8px;\n transition: background 0.15s ease, opacity 0.15s ease;\n opacity: 0.9;\n }\n .sc-ctrl-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n .sc-ctrl-btn:active {\n opacity: 0.7;\n }\n .sc-controls-bar {\n transition: opacity 0.35s ease, transform 0.35s ease;\n }\n .sc-progress-track:hover .sc-progress-thumb {\n transform: translate(-50%, -50%) scale(1) !important;\n }\n .sc-loading-hidden .sc-loading-indicator {\n display: none !important;\n }\n "
7117
7565
  }),
7118
7566
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7119
- className: "stormcloud-video-wrapper ".concat(wrapperClassName || ""),
7567
+ ref: wrapperRef,
7568
+ className: "sc-wrapper ".concat(wrapperClassName || ""),
7569
+ onMouseMove: handleWrapperMouseMove,
7570
+ onMouseLeave: handleWrapperMouseLeave,
7120
7571
  style: _object_spread({
7121
7572
  display: "flex",
7122
7573
  alignItems: "center",
@@ -7131,7 +7582,7 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7131
7582
  maxWidth: isFullscreen ? "100vw" : "100%",
7132
7583
  maxHeight: isFullscreen ? "100vh" : "none",
7133
7584
  zIndex: isFullscreen ? 999999 : void 0,
7134
- backgroundColor: isFullscreen ? "#000" : void 0,
7585
+ backgroundColor: "#000",
7135
7586
  borderRadius: isFullscreen ? 0 : void 0,
7136
7587
  boxShadow: isFullscreen ? "none" : void 0
7137
7588
  }, wrapperStyle),
@@ -7157,16 +7608,16 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7157
7608
  children: children
7158
7609
  })),
7159
7610
  (isLoading || isBuffering) && !hideLoadingIndicator && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaSpinner, {
7160
- className: "stormcloud-loading-indicator",
7161
- size: 42,
7162
- color: "white",
7611
+ className: "sc-loading-indicator",
7612
+ size: 40,
7613
+ color: "rgba(255, 255, 255, 0.85)",
7163
7614
  style: {
7164
7615
  position: "absolute",
7165
- top: "calc(50% - 21px)",
7166
- left: "calc(50% - 21px)",
7616
+ top: "calc(50% - 20px)",
7617
+ left: "calc(50% - 20px)",
7167
7618
  zIndex: 20,
7168
- animation: "spin 1s linear infinite",
7169
- filter: "drop-shadow(0 3px 6px rgba(0, 0, 0, 0.8))"
7619
+ animation: "sc-spin 0.9s linear infinite",
7620
+ filter: "drop-shadow(0 2px 8px rgba(0, 0, 0, 0.6))"
7170
7621
  }
7171
7622
  }),
7172
7623
  showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
@@ -7176,13 +7627,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7176
7627
  left: "50%",
7177
7628
  transform: "translate(-50%, -50%)",
7178
7629
  zIndex: 25,
7179
- background: "linear-gradient(135deg, rgba(220, 38, 38, 0.95) 0%, rgba(185, 28, 28, 0.9) 100%)",
7630
+ background: "rgba(220, 38, 38, 0.92)",
7631
+ backdropFilter: "blur(24px)",
7180
7632
  color: "white",
7181
- padding: "24px 32px",
7182
- borderRadius: "16px",
7183
- backdropFilter: "blur(20px)",
7184
- border: "2px solid rgba(255, 255, 255, 0.2)",
7185
- boxShadow: "0 20px 60px rgba(0, 0, 0, 0.6), inset 0 2px 0 rgba(255, 255, 255, 0.2)",
7633
+ padding: "28px 36px",
7634
+ borderRadius: "14px",
7635
+ border: "1px solid rgba(255, 255, 255, 0.15)",
7636
+ boxShadow: "0 24px 64px rgba(0, 0, 0, 0.5)",
7186
7637
  textAlign: "center",
7187
7638
  maxWidth: "400px",
7188
7639
  margin: "0 16px"
@@ -7190,20 +7641,18 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7190
7641
  children: [
7191
7642
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7192
7643
  style: {
7193
- fontSize: "20px",
7194
- fontWeight: "bold",
7195
- marginBottom: "12px",
7196
- color: "#ffffff",
7197
- textShadow: "0 2px 4px rgba(0, 0, 0, 0.5)"
7644
+ fontSize: "18px",
7645
+ fontWeight: "700",
7646
+ marginBottom: "10px",
7647
+ letterSpacing: "-0.02em"
7198
7648
  },
7199
7649
  children: "License Key Required"
7200
7650
  }),
7201
7651
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7202
7652
  style: {
7203
- fontSize: "14px",
7204
- lineHeight: "1.5",
7205
- color: "rgba(255, 255, 255, 0.9)",
7206
- textShadow: "0 1px 2px rgba(0, 0, 0, 0.3)"
7653
+ fontSize: "13px",
7654
+ lineHeight: "1.6",
7655
+ color: "rgba(255, 255, 255, 0.85)"
7207
7656
  },
7208
7657
  children: [
7209
7658
  "Please provide a valid license key to use the Stormcloud Video Player.",
@@ -7222,836 +7671,550 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
7222
7671
  transform: "translate(-50%, -50%)",
7223
7672
  zIndex: 15,
7224
7673
  cursor: "pointer",
7225
- background: "linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)",
7674
+ background: "rgba(0, 0, 0, 0.55)",
7675
+ backdropFilter: "blur(8px)",
7226
7676
  borderRadius: "50%",
7227
- width: "100px",
7228
- height: "100px",
7677
+ width: "".concat(92 * responsiveScale, "px"),
7678
+ height: "".concat(92 * responsiveScale, "px"),
7229
7679
  display: "flex",
7230
7680
  alignItems: "center",
7231
7681
  justifyContent: "center",
7232
- backdropFilter: "blur(20px)",
7233
- border: "3px solid rgba(255, 255, 255, 0.8)",
7234
- boxShadow: "0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)",
7235
- transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)"
7682
+ transition: "background 0.2s ease, transform 0.2s ease",
7683
+ animation: "sc-fade-in 0.2s ease"
7236
7684
  },
7237
- onMouseEnter: function(e) {
7238
- var target = e.currentTarget;
7239
- target.style.transform = "translate(-50%, -50%)";
7240
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(40, 40, 40, 0.9) 100%)";
7241
- target.style.boxShadow = "0 16px 48px rgba(0, 0, 0, 0.9), inset 0 2px 0 rgba(255, 255, 255, 0.4)";
7242
- target.style.borderColor = "rgba(255, 255, 255, 0.9)";
7685
+ onMouseEnter: function onMouseEnter(e) {
7686
+ e.currentTarget.style.background = "rgba(0, 0, 0, 0.72)";
7687
+ e.currentTarget.style.transform = "translate(-50%, -50%) scale(1.06)";
7243
7688
  },
7244
- onMouseLeave: function(e) {
7245
- var target = e.currentTarget;
7246
- target.style.transform = "translate(-50%, -50%)";
7247
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.8) 100%)";
7248
- target.style.boxShadow = "0 12px 40px rgba(0, 0, 0, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.3)";
7249
- target.style.borderColor = "rgba(255, 255, 255, 0.8)";
7689
+ onMouseLeave: function onMouseLeave(e) {
7690
+ e.currentTarget.style.background = "rgba(0, 0, 0, 0.55)";
7691
+ e.currentTarget.style.transform = "translate(-50%, -50%) scale(1)";
7250
7692
  },
7251
7693
  title: "Play",
7252
7694
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaPlay, {
7253
- size: 36,
7695
+ size: Math.max(24, 32 * responsiveScale),
7254
7696
  color: "white",
7255
7697
  style: {
7256
- marginLeft: "6px",
7257
- filter: "drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))"
7698
+ marginLeft: "4px"
7258
7699
  }
7259
7700
  })
7260
7701
  }),
7261
- shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, {
7262
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7263
- style: {
7264
- position: "absolute",
7265
- bottom: 0,
7266
- left: 0,
7267
- right: 0,
7268
- background: "linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.8) 100%)",
7269
- padding: "20px 16px 16px",
7270
- zIndex: 10
7271
- },
7272
- children: [
7273
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7274
- style: {
7275
- width: "100%",
7276
- height: "8px",
7277
- background: "linear-gradient(90deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0.1) 100%)",
7278
- borderRadius: "8px",
7279
- marginBottom: "16px",
7280
- cursor: "pointer",
7281
- position: "relative",
7282
- backdropFilter: "blur(5px)",
7283
- border: "1px solid rgba(255, 255, 255, 0.1)",
7284
- boxShadow: "inset 0 2px 4px rgba(0, 0, 0, 0.2)"
7285
- },
7286
- onClick: handleTimelineSeek,
7287
- children: [
7288
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7289
- style: {
7290
- height: "100%",
7291
- background: "linear-gradient(90deg, rgba(139, 92, 246, 0.9) 0%, rgba(59, 130, 246, 0.8) 50%, rgba(34, 197, 94, 0.9) 100%)",
7292
- borderRadius: "8px",
7293
- width: "".concat(duration > 0 ? currentTime / duration * 100 : 0, "%"),
7294
- transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
7295
- boxShadow: "0 2px 8px rgba(139, 92, 246, 0.4)"
7296
- }
7297
- }),
7298
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7299
- style: {
7300
- position: "absolute",
7301
- top: "-6px",
7302
- right: "".concat(duration > 0 ? 100 - currentTime / duration * 100 : 100, "%"),
7303
- width: "20px",
7304
- height: "20px",
7305
- background: "linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(240, 240, 240, 0.9) 100%)",
7306
- borderRadius: "50%",
7307
- border: "3px solid rgba(139, 92, 246, 0.8)",
7308
- boxShadow: "0 4px 16px rgba(139, 92, 246, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.8)",
7309
- transform: "translateX(50%)",
7310
- transition: "all 0.2s cubic-bezier(0.4, 0, 0.2, 1)"
7311
- }
7312
- })
7313
- ]
7314
- }),
7315
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7316
- style: {
7317
- display: "flex",
7318
- alignItems: "center",
7319
- justifyContent: "space-between",
7320
- color: "white",
7321
- flexWrap: viewportWidth < 768 ? "wrap" : "nowrap",
7322
- gap: "".concat(8 * responsiveScale, "px")
7323
- },
7324
- children: [
7325
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7326
- style: {
7327
- display: "flex",
7328
- alignItems: "center",
7329
- gap: "".concat(12 * responsiveScale, "px"),
7330
- flexWrap: viewportWidth < 480 ? "wrap" : "nowrap"
7331
- },
7332
- children: [
7333
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
7334
- onClick: handlePlayPause,
7702
+ shouldShowEnhancedControls && !showLicenseWarning ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7703
+ className: "sc-controls-bar",
7704
+ style: {
7705
+ position: "absolute",
7706
+ bottom: 0,
7707
+ left: 0,
7708
+ right: 0,
7709
+ background: "linear-gradient(0deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.35) 60%, transparent 100%)",
7710
+ padding: "".concat(20 * responsiveScale, "px ").concat(12 * responsiveScale, "px ").concat(8 * responsiveScale, "px"),
7711
+ zIndex: 10,
7712
+ opacity: controlsVisible || adStatus.showAds ? 1 : 0,
7713
+ transform: controlsVisible || adStatus.showAds ? "translateY(0)" : "translateY(6px)",
7714
+ pointerEvents: controlsVisible || adStatus.showAds ? "auto" : "none"
7715
+ },
7716
+ children: [
7717
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7718
+ className: "sc-progress-track",
7719
+ style: {
7720
+ width: "100%",
7721
+ height: "3px",
7722
+ background: "rgba(255, 255, 255, 0.2)",
7723
+ borderRadius: "1.5px",
7724
+ marginBottom: "".concat(8 * responsiveScale, "px"),
7725
+ cursor: "pointer",
7726
+ position: "relative",
7727
+ transition: "height 0.1s ease"
7728
+ },
7729
+ onClick: handleTimelineSeek,
7730
+ onMouseEnter: function onMouseEnter(e) {
7731
+ e.currentTarget.style.height = "5px";
7732
+ },
7733
+ onMouseLeave: function onMouseLeave(e) {
7734
+ e.currentTarget.style.height = "3px";
7735
+ },
7736
+ children: [
7737
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7738
+ style: {
7739
+ position: "absolute",
7740
+ top: 0,
7741
+ left: 0,
7742
+ bottom: 0,
7743
+ background: adStatus.showAds ? "#f5c518" : "#ff0000",
7744
+ borderRadius: "1.5px",
7745
+ width: "".concat(progressPercent, "%"),
7746
+ transition: "width 0.15s linear"
7747
+ }
7748
+ }),
7749
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7750
+ className: "sc-progress-thumb",
7751
+ style: {
7752
+ position: "absolute",
7753
+ top: "50%",
7754
+ left: "".concat(progressPercent, "%"),
7755
+ transform: "translate(-50%, -50%) scale(0)",
7756
+ width: "13px",
7757
+ height: "13px",
7758
+ background: adStatus.showAds ? "#f5c518" : "#ff0000",
7759
+ borderRadius: "50%",
7760
+ boxShadow: "0 0 4px rgba(0, 0, 0, 0.3)",
7761
+ transition: "transform 0.1s ease, left 0.15s linear"
7762
+ }
7763
+ })
7764
+ ]
7765
+ }),
7766
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7767
+ style: {
7768
+ display: "flex",
7769
+ alignItems: "center",
7770
+ justifyContent: "space-between",
7771
+ color: "white",
7772
+ gap: "".concat(8 * responsiveScale, "px")
7773
+ },
7774
+ children: [
7775
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7776
+ style: {
7777
+ display: "flex",
7778
+ alignItems: "center",
7779
+ gap: "".concat(8 * responsiveScale, "px")
7780
+ },
7781
+ children: [
7782
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
7783
+ className: "sc-ctrl-btn",
7784
+ onClick: handlePlayPause,
7785
+ style: {
7786
+ padding: "".concat(8 * responsiveScale, "px"),
7787
+ borderRadius: "50%",
7788
+ minWidth: "".concat(36 * responsiveScale, "px"),
7789
+ minHeight: "".concat(36 * responsiveScale, "px")
7790
+ },
7791
+ title: isPlaying ? "Pause" : "Play",
7792
+ children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaPause, {
7793
+ size: Math.max(14, 18 * responsiveScale)
7794
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaPlay, {
7795
+ size: Math.max(14, 18 * responsiveScale),
7335
7796
  style: {
7336
- background: "linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)",
7337
- backdropFilter: "blur(12px)",
7338
- border: "".concat(2 * responsiveScale, "px solid rgba(255, 255, 255, 0.3)"),
7339
- color: "#ffffff",
7340
- cursor: "pointer",
7341
- padding: "".concat(10 * responsiveScale, "px"),
7342
- borderRadius: "".concat(16 * responsiveScale, "px"),
7343
- display: "flex",
7344
- alignItems: "center",
7345
- justifyContent: "center",
7346
- transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
7347
- boxShadow: "0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)",
7348
- minWidth: "".concat(48 * responsiveScale, "px"),
7349
- minHeight: "".concat(48 * responsiveScale, "px")
7350
- },
7351
- onMouseEnter: function(e) {
7352
- var target = e.target;
7353
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)";
7354
- target.style.boxShadow = "0 12px 48px rgba(0, 0, 0, 0.6), 0 6px 24px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.4)";
7355
- },
7356
- onMouseLeave: function(e) {
7357
- var target = e.target;
7358
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)";
7359
- target.style.boxShadow = "0 8px 32px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.3)";
7360
- },
7361
- title: isPlaying ? "Pause" : "Play",
7362
- children: isPlaying ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaPause, {
7363
- size: Math.max(16, 20 * responsiveScale),
7797
+ marginLeft: "2px"
7798
+ }
7799
+ })
7800
+ }),
7801
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7802
+ style: {
7803
+ display: "flex",
7804
+ alignItems: "center"
7805
+ },
7806
+ onMouseEnter: function onMouseEnter() {
7807
+ return setShowVolumeSlider(true);
7808
+ },
7809
+ onMouseLeave: function onMouseLeave() {
7810
+ return setShowVolumeSlider(false);
7811
+ },
7812
+ children: [
7813
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
7814
+ className: "sc-ctrl-btn",
7815
+ onClick: function onClick() {
7816
+ if (playerRef.current) playerRef.current.toggleMute();
7817
+ onVolumeToggle === null || onVolumeToggle === void 0 ? void 0 : onVolumeToggle();
7818
+ resetControlsTimer();
7819
+ },
7364
7820
  style: {
7365
- filter: "drop-shadow(0 0 0 transparent)"
7366
- }
7367
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaPlay, {
7368
- size: Math.max(16, 20 * responsiveScale),
7821
+ padding: "".concat(8 * responsiveScale, "px"),
7822
+ borderRadius: "50%",
7823
+ minWidth: "".concat(36 * responsiveScale, "px"),
7824
+ minHeight: "".concat(36 * responsiveScale, "px")
7825
+ },
7826
+ title: isMuted ? "Unmute" : "Mute",
7827
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VolumeIcon, {
7828
+ size: Math.max(14, 18 * responsiveScale)
7829
+ })
7830
+ }),
7831
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7369
7832
  style: {
7370
- filter: "drop-shadow(0 0 0 transparent)"
7371
- }
7372
- })
7373
- }),
7374
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7375
- style: {
7376
- position: "relative",
7377
- display: "flex",
7378
- alignItems: "center",
7379
- padding: "8px",
7380
- margin: "-8px"
7381
- },
7382
- onMouseEnter: function() {
7383
- return setShowVolumeSlider(true);
7384
- },
7385
- onMouseLeave: function() {
7386
- return setShowVolumeSlider(false);
7387
- },
7388
- children: [
7389
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
7390
- onClick: function() {
7391
- if (playerRef.current) {
7392
- playerRef.current.toggleMute();
7393
- }
7394
- if (onVolumeToggle) {
7395
- onVolumeToggle();
7396
- }
7397
- },
7833
+ width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
7834
+ overflow: "hidden",
7835
+ transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
7836
+ display: "flex",
7837
+ alignItems: "center",
7838
+ paddingLeft: showVolumeSlider ? "2px" : "0",
7839
+ paddingRight: showVolumeSlider ? "4px" : "0"
7840
+ },
7841
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7398
7842
  style: {
7399
- background: "linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)",
7400
- backdropFilter: "blur(10px)",
7401
- border: "".concat(2 * responsiveScale, "px solid rgba(255, 255, 255, 0.3)"),
7402
- color: "#ffffff",
7843
+ position: "relative",
7844
+ width: "".concat(56 * responsiveScale, "px"),
7845
+ height: "3px",
7403
7846
  cursor: "pointer",
7404
- padding: "".concat(8 * responsiveScale, "px"),
7405
- borderRadius: "".concat(16 * responsiveScale, "px"),
7406
- display: "flex",
7407
- alignItems: "center",
7408
- justifyContent: "center",
7409
- transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
7410
- boxShadow: "0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)",
7411
- minWidth: "".concat(44 * responsiveScale, "px"),
7412
- minHeight: "".concat(44 * responsiveScale, "px")
7847
+ borderRadius: "1.5px"
7413
7848
  },
7414
- onMouseEnter: function(e) {
7415
- var target = e.target;
7416
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)";
7417
- target.style.boxShadow = "0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)";
7849
+ onMouseDown: function onMouseDown(e) {
7850
+ e.preventDefault();
7851
+ var el = e.currentTarget;
7852
+ var move = function move(ev) {
7853
+ var r2 = el.getBoundingClientRect();
7854
+ handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r2.left) / r2.width)));
7855
+ };
7856
+ var up = function up1() {
7857
+ document.removeEventListener("mousemove", move);
7858
+ document.removeEventListener("mouseup", up);
7859
+ };
7860
+ document.addEventListener("mousemove", move);
7861
+ document.addEventListener("mouseup", up);
7862
+ var r = el.getBoundingClientRect();
7863
+ handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));
7418
7864
  },
7419
- onMouseLeave: function(e) {
7420
- var target = e.target;
7421
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)";
7422
- target.style.boxShadow = "0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)";
7865
+ onClick: function onClick(e) {
7866
+ e.stopPropagation();
7867
+ var r = e.currentTarget.getBoundingClientRect();
7868
+ handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));
7423
7869
  },
7424
- title: isMuted ? "Unmute" : "Mute",
7425
- children: isMuted || volume === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaVolumeMute, {
7426
- size: Math.max(14, 16 * responsiveScale),
7427
- style: {
7428
- filter: "drop-shadow(0 0 0 transparent)"
7429
- }
7430
- }) : volume < 0.5 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaVolumeDown, {
7431
- size: Math.max(14, 16 * responsiveScale),
7432
- style: {
7433
- filter: "drop-shadow(0 0 0 transparent)"
7434
- }
7435
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaVolumeUp, {
7436
- size: Math.max(14, 16 * responsiveScale),
7437
- style: {
7438
- filter: "drop-shadow(0 0 0 transparent)"
7439
- }
7440
- })
7441
- }),
7442
- showVolumeSlider && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
7443
7870
  children: [
7444
7871
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7445
7872
  style: {
7446
7873
  position: "absolute",
7447
- bottom: "100%",
7448
- left: "50%",
7449
- transform: "translateX(-50%)",
7450
- width: "60px",
7451
- height: "20px",
7452
- marginBottom: "-16px",
7453
- zIndex: 9
7454
- },
7455
- onMouseEnter: function() {
7456
- return setShowVolumeSlider(true);
7457
- },
7458
- onMouseLeave: function() {
7459
- return setShowVolumeSlider(false);
7874
+ inset: 0,
7875
+ background: "rgba(255, 255, 255, 0.2)",
7876
+ borderRadius: "1.5px"
7877
+ }
7878
+ }),
7879
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7880
+ style: {
7881
+ position: "absolute",
7882
+ top: 0,
7883
+ left: 0,
7884
+ bottom: 0,
7885
+ width: "".concat((isMuted ? 0 : volume) * 100, "%"),
7886
+ background: "#fff",
7887
+ borderRadius: "1.5px",
7888
+ transition: "width 0.1s ease-out"
7460
7889
  }
7461
7890
  }),
7462
7891
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7463
7892
  style: {
7464
7893
  position: "absolute",
7465
- bottom: "100%",
7466
- left: "50%",
7467
- transform: "translateX(-50%)",
7468
- marginBottom: "4px",
7469
- background: "linear-gradient(135deg, rgba(0, 0, 0, 0.88) 0%, rgba(20, 20, 20, 0.92) 100%)",
7470
- backdropFilter: "blur(15px)",
7471
- padding: "10px 14px",
7472
- borderRadius: "14px",
7473
- border: "1px solid rgba(255, 255, 255, 0.15)",
7474
- display: "flex",
7475
- flexDirection: "column",
7476
- alignItems: "center",
7477
- justifyContent: "center",
7478
- height: "128px",
7479
- boxShadow: "0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)",
7480
- zIndex: 10,
7481
- transition: "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out"
7482
- },
7483
- onMouseEnter: function(e) {
7484
- setShowVolumeSlider(true);
7485
- e.currentTarget.style.boxShadow = "0 16px 48px rgba(0, 0, 0, 0.6), 0 6px 16px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 0 24px rgba(59, 130, 246, 0.3)";
7486
- e.currentTarget.style.borderColor = "rgba(59, 130, 246, 0.4)";
7487
- },
7488
- onMouseLeave: function(e) {
7489
- setShowVolumeSlider(false);
7490
- e.currentTarget.style.boxShadow = "0 12px 40px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.15)";
7491
- e.currentTarget.style.borderColor = "rgba(255, 255, 255, 0.15)";
7492
- },
7493
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7494
- style: {
7495
- position: "relative",
7496
- width: "8px",
7497
- height: "104px",
7498
- cursor: "pointer",
7499
- transition: "transform 0.2s ease-in-out"
7500
- },
7501
- onMouseEnter: function(e) {},
7502
- onMouseLeave: function(e) {},
7503
- onMouseDown: function(e) {
7504
- e.preventDefault();
7505
- var sliderElement = e.currentTarget;
7506
- var handleMouseMove = function(moveEvent) {
7507
- if (!sliderElement) return;
7508
- var rect2 = sliderElement.getBoundingClientRect();
7509
- var y2 = moveEvent.clientY - rect2.top;
7510
- var percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));
7511
- handleVolumeChange(percentage2);
7512
- };
7513
- var handleMouseUp = function() {
7514
- document.removeEventListener("mousemove", handleMouseMove);
7515
- document.removeEventListener("mouseup", handleMouseUp);
7516
- };
7517
- document.addEventListener("mousemove", handleMouseMove);
7518
- document.addEventListener("mouseup", handleMouseUp);
7519
- var rect = sliderElement.getBoundingClientRect();
7520
- var y = e.clientY - rect.top;
7521
- var percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
7522
- handleVolumeChange(percentage);
7523
- },
7524
- onClick: function(e) {
7525
- e.stopPropagation();
7526
- var rect = e.currentTarget.getBoundingClientRect();
7527
- var y = e.clientY - rect.top;
7528
- var percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
7529
- handleVolumeChange(percentage);
7530
- },
7531
- children: [
7532
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7533
- style: {
7534
- position: "absolute",
7535
- bottom: "0",
7536
- left: "0",
7537
- width: "100%",
7538
- height: "100%",
7539
- background: "linear-gradient(180deg, rgba(255, 255, 255, 0.4) 0%, rgba(255, 255, 255, 0.15) 100%)",
7540
- borderRadius: "4px",
7541
- boxShadow: "inset 0 1px 3px rgba(0, 0, 0, 0.2)"
7542
- }
7543
- }),
7544
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7545
- style: {
7546
- position: "absolute",
7547
- bottom: "0",
7548
- left: "0",
7549
- width: "100%",
7550
- height: "".concat((isMuted ? 0 : volume) * 100, "%"),
7551
- background: "linear-gradient(180deg, rgba(96, 165, 250, 1) 0%, rgba(59, 130, 246, 0.95) 50%, rgba(37, 99, 235, 0.9) 100%)",
7552
- borderRadius: "4px",
7553
- transition: "height 0.15s ease-out, box-shadow 0.2s ease-in-out",
7554
- boxShadow: "0 0 8px rgba(59, 130, 246, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.3)"
7555
- }
7556
- }),
7557
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7558
- style: {
7559
- position: "absolute",
7560
- bottom: "calc(".concat((isMuted ? 0 : volume) * 100, "% - 7px)"),
7561
- left: "50%",
7562
- transform: "translateX(-50%)",
7563
- width: "14px",
7564
- height: "14px",
7565
- background: "linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)",
7566
- borderRadius: "50%",
7567
- boxShadow: "0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)",
7568
- transition: "bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out",
7569
- cursor: "grab"
7570
- },
7571
- onMouseEnter: function(e) {
7572
- e.currentTarget.style.boxShadow = "0 3px 10px rgba(0, 0, 0, 0.4), 0 0 0 3px rgba(59, 130, 246, 0.5), 0 0 20px rgba(59, 130, 246, 0.6)";
7573
- e.currentTarget.style.cursor = "grab";
7574
- },
7575
- onMouseLeave: function(e) {
7576
- e.currentTarget.style.boxShadow = "0 2px 6px rgba(0, 0, 0, 0.3), 0 0 0 2px rgba(59, 130, 246, 0.3), 0 0 12px rgba(59, 130, 246, 0.4)";
7577
- },
7578
- onMouseDown: function(e) {
7579
- e.currentTarget.style.cursor = "grabbing";
7580
- },
7581
- onMouseUp: function(e) {
7582
- e.currentTarget.style.cursor = "grab";
7583
- }
7584
- })
7585
- ]
7586
- })
7894
+ top: "50%",
7895
+ left: "".concat((isMuted ? 0 : volume) * 100, "%"),
7896
+ transform: "translate(-50%, -50%)",
7897
+ width: "12px",
7898
+ height: "12px",
7899
+ background: "#fff",
7900
+ borderRadius: "50%",
7901
+ boxShadow: "0 0 3px rgba(0, 0, 0, 0.3)",
7902
+ transition: "left 0.1s ease-out"
7903
+ }
7587
7904
  })
7588
7905
  ]
7589
7906
  })
7590
- ]
7591
- }),
7592
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7593
- style: {
7594
- fontSize: "".concat(14 * responsiveScale, "px"),
7595
- fontFamily: "monospace",
7596
- color: "rgba(255, 255, 255, 0.9)",
7597
- display: viewportWidth < 480 ? "none" : "block"
7598
- },
7599
- children: [
7600
- formatTime(currentTime),
7601
- " / ",
7602
- formatTime(duration)
7603
- ]
7604
- })
7605
- ]
7606
- }),
7607
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7608
- style: {
7609
- display: "flex",
7610
- alignItems: "center",
7611
- gap: "".concat(12 * responsiveScale, "px")
7612
- },
7613
- children: [
7614
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7615
- style: {
7616
- position: "relative",
7617
- display: viewportWidth < 600 ? "none" : "block"
7618
- },
7619
- children: [
7620
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
7621
- onClick: function() {
7622
- return setShowSpeedMenu(!showSpeedMenu);
7623
- },
7624
- style: {
7625
- background: "linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)",
7626
- backdropFilter: "blur(10px)",
7627
- border: "".concat(2 * responsiveScale, "px solid rgba(255, 255, 255, 0.3)"),
7628
- color: "#ffffff",
7629
- cursor: "pointer",
7630
- padding: "".concat(8 * responsiveScale, "px ").concat(14 * responsiveScale, "px"),
7631
- borderRadius: "".concat(14 * responsiveScale, "px"),
7632
- fontSize: "".concat(14 * responsiveScale, "px"),
7633
- fontFamily: "monospace",
7634
- fontWeight: "700",
7635
- transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
7636
- boxShadow: "0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)",
7637
- minWidth: "".concat(56 * responsiveScale, "px"),
7638
- minHeight: "".concat(40 * responsiveScale, "px")
7639
- },
7640
- onMouseEnter: function(e) {
7641
- var target = e.target;
7642
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)";
7643
- target.style.boxShadow = "0 10px 32px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)";
7644
- },
7645
- onMouseLeave: function(e) {
7646
- var target = e.target;
7647
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)";
7648
- target.style.boxShadow = "0 6px 24px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)";
7649
- },
7650
- title: "Playback Speed",
7651
- children: [
7652
- playbackRate,
7653
- "x"
7654
- ]
7655
- }),
7656
- showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7657
- style: {
7658
- position: "absolute",
7659
- bottom: "100%",
7660
- right: 0,
7661
- marginBottom: "12px",
7662
- background: "linear-gradient(135deg, rgba(0, 0, 0, 0.9) 0%, rgba(20, 20, 20, 0.95) 100%)",
7663
- backdropFilter: "blur(20px)",
7664
- borderRadius: "12px",
7665
- border: "1px solid rgba(255, 255, 255, 0.1)",
7666
- overflow: "hidden",
7667
- minWidth: "90px",
7668
- boxShadow: "0 16px 48px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.1)"
7669
- },
7670
- children: [
7671
- 0.25,
7672
- 0.5,
7673
- 0.75,
7674
- 1,
7675
- 1.25,
7676
- 1.5,
7677
- 1.75,
7678
- 2
7679
- ].map(function(speed) {
7680
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
7681
- onClick: function() {
7682
- return handlePlaybackRateChange(speed);
7683
- },
7684
- style: {
7685
- display: "block",
7686
- width: "100%",
7687
- padding: "10px 16px",
7688
- background: playbackRate === speed ? "linear-gradient(135deg, rgba(99, 102, 241, 0.8) 0%, rgba(139, 92, 246, 0.6) 100%)" : "transparent",
7689
- border: "none",
7690
- color: "white",
7691
- cursor: "pointer",
7692
- fontSize: "13px",
7693
- fontFamily: "monospace",
7694
- fontWeight: "600",
7695
- textAlign: "center",
7696
- transition: "all 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
7697
- borderBottom: speed !== 2 ? "1px solid rgba(255, 255, 255, 0.05)" : "none"
7698
- },
7699
- onMouseEnter: function(e) {
7700
- if (playbackRate !== speed) {
7701
- e.target.style.background = "linear-gradient(135deg, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0.05) 100%)";
7702
- }
7703
- },
7704
- onMouseLeave: function(e) {
7705
- if (playbackRate !== speed) {
7706
- e.target.style.background = "transparent";
7707
- }
7708
- },
7709
- children: [
7710
- speed,
7711
- "x"
7712
- ]
7713
- }, speed);
7714
- })
7715
- })
7716
- ]
7717
- }),
7718
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
7719
- onClick: function() {
7720
- if (onFullscreenToggle) {
7721
- onFullscreenToggle();
7722
- } else if (playerRef.current) {
7723
- playerRef.current.toggleFullscreen().catch(function(err) {
7724
- console.error("Fullscreen error:", err);
7725
- });
7726
- }
7727
- },
7728
- style: {
7729
- background: "linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)",
7730
- backdropFilter: "blur(10px)",
7731
- border: "".concat(2 * responsiveScale, "px solid rgba(255, 255, 255, 0.3)"),
7732
- color: "#ffffff",
7733
- cursor: "pointer",
7734
- padding: "".concat(8 * responsiveScale, "px"),
7735
- borderRadius: "".concat(16 * responsiveScale, "px"),
7736
- display: "flex",
7737
- alignItems: "center",
7738
- justifyContent: "center",
7739
- transition: "all 0.3s cubic-bezier(0.4, 0, 0.2, 1)",
7740
- boxShadow: "0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)",
7741
- minWidth: "".concat(44 * responsiveScale, "px"),
7742
- minHeight: "".concat(44 * responsiveScale, "px")
7743
- },
7744
- onMouseEnter: function(e) {
7745
- var target = e.target;
7746
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.7) 100%)";
7747
- target.style.boxShadow = "0 10px 36px rgba(0, 0, 0, 0.6), 0 5px 16px rgba(0, 0, 0, 0.4), inset 0 2px 0 rgba(255, 255, 255, 0.35)";
7748
- },
7749
- onMouseLeave: function(e) {
7750
- var target = e.target;
7751
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.7) 0%, rgba(0, 0, 0, 0.6) 100%)";
7752
- target.style.boxShadow = "0 6px 28px rgba(0, 0, 0, 0.4), 0 3px 12px rgba(0, 0, 0, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.25)";
7753
- },
7754
- title: isFullscreen ? "Exit Fullscreen" : "Enter Fullscreen",
7755
- children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCompress, {
7756
- size: Math.max(14, 16 * responsiveScale),
7907
+ })
7908
+ ]
7909
+ }),
7910
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7911
+ style: {
7912
+ fontSize: "".concat(13 * responsiveScale, "px"),
7913
+ fontFamily: "Roboto, 'Segoe UI', Arial, sans-serif",
7914
+ color: "rgba(255, 255, 255, 0.9)",
7915
+ display: viewportWidth < 480 ? "none" : "block",
7916
+ fontVariantNumeric: "tabular-nums",
7917
+ userSelect: "none",
7918
+ marginLeft: "".concat(4 * responsiveScale, "px")
7919
+ },
7920
+ children: [
7921
+ formatTime(currentTime),
7922
+ " ",
7923
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
7757
7924
  style: {
7758
- filter: "drop-shadow(0 0 0 transparent)"
7759
- }
7760
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaExpand, {
7761
- size: Math.max(14, 16 * responsiveScale),
7925
+ color: "rgba(255,255,255,0.5)"
7926
+ },
7927
+ children: "/"
7928
+ }),
7929
+ " ",
7930
+ formatTime(duration)
7931
+ ]
7932
+ })
7933
+ ]
7934
+ }),
7935
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7936
+ style: {
7937
+ display: "flex",
7938
+ alignItems: "center",
7939
+ gap: "".concat(8 * responsiveScale, "px")
7940
+ },
7941
+ children: [
7942
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7943
+ style: {
7944
+ position: "relative",
7945
+ display: viewportWidth < 600 ? "none" : "block"
7946
+ },
7947
+ children: [
7948
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
7949
+ className: "sc-ctrl-btn",
7950
+ onClick: function onClick() {
7951
+ setShowSpeedMenu(!showSpeedMenu);
7952
+ resetControlsTimer();
7953
+ },
7762
7954
  style: {
7763
- filter: "drop-shadow(0 0 0 transparent)"
7764
- }
7955
+ padding: "".concat(6 * responsiveScale, "px ").concat(10 * responsiveScale, "px"),
7956
+ borderRadius: "".concat(6 * responsiveScale, "px"),
7957
+ fontSize: "".concat(13 * responsiveScale, "px"),
7958
+ fontFamily: "'SF Mono', 'Cascadia Code', monospace",
7959
+ fontWeight: "600",
7960
+ minHeight: "".concat(32 * responsiveScale, "px")
7961
+ },
7962
+ title: "Playback Speed",
7963
+ children: [
7964
+ playbackRate,
7965
+ "x"
7966
+ ]
7967
+ }),
7968
+ showSpeedMenu && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7969
+ style: {
7970
+ position: "absolute",
7971
+ bottom: "100%",
7972
+ right: 0,
7973
+ marginBottom: "8px",
7974
+ background: "rgba(0, 0, 0, 0.8)",
7975
+ backdropFilter: "blur(24px)",
7976
+ WebkitBackdropFilter: "blur(24px)",
7977
+ borderRadius: "10px",
7978
+ border: "1px solid rgba(255, 255, 255, 0.1)",
7979
+ overflow: "hidden",
7980
+ minWidth: "80px",
7981
+ boxShadow: "0 12px 40px rgba(0, 0, 0, 0.5)",
7982
+ animation: "sc-fade-in 0.15s ease"
7983
+ },
7984
+ children: [
7985
+ 0.25,
7986
+ 0.5,
7987
+ 0.75,
7988
+ 1,
7989
+ 1.25,
7990
+ 1.5,
7991
+ 1.75,
7992
+ 2
7993
+ ].map(function(speed) {
7994
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
7995
+ onClick: function onClick() {
7996
+ return handlePlaybackRateChange(speed);
7997
+ },
7998
+ style: {
7999
+ display: "block",
8000
+ width: "100%",
8001
+ padding: "".concat(8 * responsiveScale, "px ").concat(14 * responsiveScale, "px"),
8002
+ background: playbackRate === speed ? "rgba(255, 255, 255, 0.12)" : "transparent",
8003
+ border: "none",
8004
+ color: playbackRate === speed ? "#fff" : "rgba(255, 255, 255, 0.7)",
8005
+ cursor: "pointer",
8006
+ fontSize: "".concat(12 * responsiveScale, "px"),
8007
+ fontFamily: "'SF Mono', monospace",
8008
+ fontWeight: playbackRate === speed ? "700" : "500",
8009
+ textAlign: "center",
8010
+ transition: "background 0.15s ease, color 0.15s ease"
8011
+ },
8012
+ onMouseEnter: function onMouseEnter(e) {
8013
+ if (playbackRate !== speed) {
8014
+ e.target.style.background = "rgba(255, 255, 255, 0.08)";
8015
+ e.target.style.color = "#fff";
8016
+ }
8017
+ },
8018
+ onMouseLeave: function onMouseLeave(e) {
8019
+ if (playbackRate !== speed) {
8020
+ e.target.style.background = "transparent";
8021
+ e.target.style.color = "rgba(255, 255, 255, 0.7)";
8022
+ }
8023
+ },
8024
+ children: [
8025
+ speed,
8026
+ "x"
8027
+ ]
8028
+ }, speed);
8029
+ })
7765
8030
  })
8031
+ ]
8032
+ }),
8033
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
8034
+ className: "sc-ctrl-btn",
8035
+ onClick: function onClick() {
8036
+ if (onFullscreenToggle) {
8037
+ onFullscreenToggle();
8038
+ } else if (wrapperRef.current) {
8039
+ if (!document.fullscreenElement) {
8040
+ wrapperRef.current.requestFullscreen().catch(function() {});
8041
+ } else {
8042
+ document.exitFullscreen().catch(function() {});
8043
+ }
8044
+ }
8045
+ resetControlsTimer();
8046
+ },
8047
+ style: {
8048
+ padding: "".concat(8 * responsiveScale, "px"),
8049
+ borderRadius: "50%",
8050
+ minWidth: "".concat(36 * responsiveScale, "px"),
8051
+ minHeight: "".concat(36 * responsiveScale, "px")
8052
+ },
8053
+ title: isFullscreen ? "Exit Fullscreen" : "Enter Fullscreen",
8054
+ children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCompress, {
8055
+ size: Math.max(14, 18 * responsiveScale)
8056
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaExpand, {
8057
+ size: Math.max(14, 18 * responsiveScale)
7766
8058
  })
7767
- ]
7768
- })
7769
- ]
7770
- })
7771
- ]
7772
- })
8059
+ })
8060
+ ]
8061
+ })
8062
+ ]
8063
+ })
8064
+ ]
7773
8065
  }) : showCustomControls && !showLicenseWarning && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
8066
+ className: "sc-controls-bar",
7774
8067
  style: {
7775
8068
  position: "absolute",
7776
8069
  bottom: "".concat(10 * responsiveScale, "px"),
7777
8070
  right: "".concat(10 * responsiveScale, "px"),
7778
- transform: "none",
7779
8071
  display: "flex",
7780
8072
  flexDirection: isPortrait ? "column" : "row",
7781
- gap: "".concat(10 * responsiveScale, "px"),
7782
- zIndex: 10
8073
+ gap: "".concat(8 * responsiveScale, "px"),
8074
+ zIndex: 10,
8075
+ opacity: controlsVisible ? 1 : 0,
8076
+ transform: controlsVisible ? "translateY(0)" : "translateY(4px)",
8077
+ pointerEvents: controlsVisible ? "auto" : "none"
7783
8078
  },
7784
8079
  children: [
7785
8080
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
7786
8081
  style: {
7787
- position: "relative",
7788
8082
  display: "flex",
7789
8083
  alignItems: "center",
7790
- padding: "8px",
7791
- margin: "-8px"
8084
+ background: "rgba(0, 0, 0, 0.6)",
8085
+ borderRadius: "".concat(18 * responsiveScale, "px"),
8086
+ padding: "2px"
7792
8087
  },
7793
- onMouseEnter: function() {
8088
+ onMouseEnter: function onMouseEnter() {
7794
8089
  return setShowVolumeSlider(true);
7795
8090
  },
7796
- onMouseLeave: function() {
8091
+ onMouseLeave: function onMouseLeave() {
7797
8092
  return setShowVolumeSlider(false);
7798
8093
  },
7799
8094
  children: [
7800
8095
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
7801
- onClick: function() {
7802
- if (playerRef.current) {
7803
- playerRef.current.toggleMute();
7804
- }
7805
- if (onVolumeToggle) {
7806
- onVolumeToggle();
7807
- }
7808
- },
7809
- onMouseEnter: function(e) {
7810
- var target = e.currentTarget;
7811
- target.style.boxShadow = "0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)";
7812
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)";
7813
- },
7814
- onMouseLeave: function(e) {
7815
- var target = e.currentTarget;
7816
- target.style.boxShadow = "0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)";
7817
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)";
8096
+ className: "sc-ctrl-btn",
8097
+ onClick: function onClick() {
8098
+ if (playerRef.current) playerRef.current.toggleMute();
8099
+ onVolumeToggle === null || onVolumeToggle === void 0 ? void 0 : onVolumeToggle();
8100
+ resetControlsTimer();
7818
8101
  },
7819
8102
  style: {
7820
- background: "linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)",
7821
- color: "#ffffff",
7822
- border: "none",
7823
- borderRadius: "".concat(18 * responsiveScale, "px"),
7824
8103
  padding: "".concat(8 * responsiveScale, "px"),
7825
- cursor: "pointer",
7826
- display: "flex",
7827
- alignItems: "center",
7828
- justifyContent: "center",
7829
- backdropFilter: "blur(20px)",
7830
- boxShadow: "0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)",
7831
- transition: "all 0.4s cubic-bezier(0.4, 0, 0.2, 1)",
7832
- minWidth: "".concat(46 * responsiveScale, "px"),
7833
- minHeight: "".concat(46 * responsiveScale, "px")
8104
+ borderRadius: "50%",
8105
+ minWidth: "".concat(36 * responsiveScale, "px"),
8106
+ minHeight: "".concat(36 * responsiveScale, "px")
7834
8107
  },
7835
8108
  title: isMuted ? "Unmute" : "Mute",
7836
- children: isMuted || volume === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaVolumeMute, {
7837
- size: Math.max(14, 16 * responsiveScale),
7838
- style: {
7839
- filter: "drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))",
7840
- color: "#ffffff"
7841
- }
7842
- }) : volume < 0.5 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaVolumeDown, {
7843
- size: Math.max(14, 16 * responsiveScale),
7844
- style: {
7845
- filter: "drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))",
7846
- color: "#ffffff"
7847
- }
7848
- }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaVolumeUp, {
7849
- size: Math.max(14, 16 * responsiveScale),
7850
- style: {
7851
- filter: "drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))",
7852
- color: "#ffffff"
7853
- }
8109
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VolumeIcon, {
8110
+ size: Math.max(14, 18 * responsiveScale)
7854
8111
  })
7855
8112
  }),
7856
- showVolumeSlider && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
7857
- children: [
7858
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7859
- style: {
7860
- position: "absolute",
7861
- bottom: "100%",
7862
- left: "50%",
7863
- transform: "translateX(-50%)",
7864
- width: "60px",
7865
- height: "20px",
7866
- marginBottom: "-16px",
7867
- zIndex: 9
7868
- },
7869
- onMouseEnter: function() {
7870
- return setShowVolumeSlider(true);
7871
- },
7872
- onMouseLeave: function() {
7873
- return setShowVolumeSlider(false);
7874
- }
7875
- }),
7876
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7877
- style: {
7878
- position: "absolute",
7879
- bottom: "100%",
7880
- left: "50%",
7881
- transform: "translateX(-50%)",
7882
- marginBottom: "4px",
7883
- background: "linear-gradient(135deg, rgba(0, 0, 0, 0.96) 0%, rgba(20, 20, 20, 0.92) 100%)",
7884
- backdropFilter: "blur(20px)",
7885
- padding: "10px 14px",
7886
- borderRadius: "14px",
7887
- border: "2px solid rgba(255, 255, 255, 0.7)",
7888
- display: "flex",
7889
- flexDirection: "column",
7890
- alignItems: "center",
7891
- justifyContent: "center",
7892
- height: "128px",
7893
- boxShadow: "0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)",
7894
- zIndex: 10,
7895
- transition: "transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, border-color 0.2s ease-in-out"
7896
- },
7897
- onMouseEnter: function(e) {
7898
- setShowVolumeSlider(true);
7899
- e.currentTarget.style.boxShadow = "0 16px 48px rgba(0, 0, 0, 0.9), 0 6px 16px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.4), 0 0 24px rgba(96, 165, 250, 0.4)";
7900
- e.currentTarget.style.borderColor = "rgba(96, 165, 250, 0.8)";
7901
- },
7902
- onMouseLeave: function(e) {
7903
- setShowVolumeSlider(false);
7904
- e.currentTarget.style.boxShadow = "0 12px 40px rgba(0, 0, 0, 0.85), 0 4px 12px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.35)";
7905
- e.currentTarget.style.borderColor = "rgba(255, 255, 255, 0.7)";
7906
- },
7907
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
8113
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
8114
+ style: {
8115
+ width: showVolumeSlider ? "".concat(62 * responsiveScale, "px") : "0px",
8116
+ overflow: "hidden",
8117
+ transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
8118
+ display: "flex",
8119
+ alignItems: "center",
8120
+ paddingLeft: showVolumeSlider ? "2px" : "0",
8121
+ paddingRight: showVolumeSlider ? "6px" : "0"
8122
+ },
8123
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
8124
+ style: {
8125
+ position: "relative",
8126
+ width: "".concat(56 * responsiveScale, "px"),
8127
+ height: "3px",
8128
+ cursor: "pointer",
8129
+ borderRadius: "1.5px"
8130
+ },
8131
+ onMouseDown: function onMouseDown(e) {
8132
+ e.preventDefault();
8133
+ var el = e.currentTarget;
8134
+ var move = function move(ev) {
8135
+ var r2 = el.getBoundingClientRect();
8136
+ handleVolumeChange(Math.max(0, Math.min(1, (ev.clientX - r2.left) / r2.width)));
8137
+ };
8138
+ var up = function up1() {
8139
+ document.removeEventListener("mousemove", move);
8140
+ document.removeEventListener("mouseup", up);
8141
+ };
8142
+ document.addEventListener("mousemove", move);
8143
+ document.addEventListener("mouseup", up);
8144
+ var r = el.getBoundingClientRect();
8145
+ handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));
8146
+ },
8147
+ onClick: function onClick(e) {
8148
+ e.stopPropagation();
8149
+ var r = e.currentTarget.getBoundingClientRect();
8150
+ handleVolumeChange(Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)));
8151
+ },
8152
+ children: [
8153
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7908
8154
  style: {
7909
- position: "relative",
7910
- width: "8px",
7911
- height: "104px",
7912
- cursor: "pointer",
7913
- transition: "transform 0.2s ease-in-out"
7914
- },
7915
- onMouseDown: function(e) {
7916
- e.preventDefault();
7917
- var sliderElement = e.currentTarget;
7918
- var handleMouseMove = function(moveEvent) {
7919
- if (!sliderElement) return;
7920
- var rect2 = sliderElement.getBoundingClientRect();
7921
- var y2 = moveEvent.clientY - rect2.top;
7922
- var percentage2 = 1 - Math.max(0, Math.min(1, y2 / rect2.height));
7923
- handleVolumeChange(percentage2);
7924
- };
7925
- var handleMouseUp = function() {
7926
- document.removeEventListener("mousemove", handleMouseMove);
7927
- document.removeEventListener("mouseup", handleMouseUp);
7928
- };
7929
- document.addEventListener("mousemove", handleMouseMove);
7930
- document.addEventListener("mouseup", handleMouseUp);
7931
- var rect = sliderElement.getBoundingClientRect();
7932
- var y = e.clientY - rect.top;
7933
- var percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
7934
- handleVolumeChange(percentage);
7935
- },
7936
- onClick: function(e) {
7937
- e.stopPropagation();
7938
- var rect = e.currentTarget.getBoundingClientRect();
7939
- var y = e.clientY - rect.top;
7940
- var percentage = 1 - Math.max(0, Math.min(1, y / rect.height));
7941
- handleVolumeChange(percentage);
7942
- },
7943
- children: [
7944
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7945
- style: {
7946
- position: "absolute",
7947
- bottom: "0",
7948
- left: "0",
7949
- width: "100%",
7950
- height: "100%",
7951
- background: "linear-gradient(180deg, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0.5) 100%)",
7952
- borderRadius: "4px",
7953
- border: "1px solid rgba(255, 255, 255, 0.4)",
7954
- boxShadow: "inset 0 1px 3px rgba(0, 0, 0, 0.3)"
7955
- }
7956
- }),
7957
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7958
- style: {
7959
- position: "absolute",
7960
- bottom: "0",
7961
- left: "0",
7962
- width: "100%",
7963
- height: "".concat((isMuted ? 0 : volume) * 100, "%"),
7964
- background: "linear-gradient(180deg, rgba(125, 211, 252, 1) 0%, rgba(96, 165, 250, 0.98) 50%, rgba(59, 130, 246, 0.95) 100%)",
7965
- borderRadius: "4px",
7966
- transition: "height 0.15s ease-out, box-shadow 0.2s ease-in-out",
7967
- boxShadow: "0 0 12px rgba(96, 165, 250, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.4)"
7968
- }
7969
- }),
7970
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
7971
- style: {
7972
- position: "absolute",
7973
- bottom: "calc(".concat((isMuted ? 0 : volume) * 100, "% - 8px)"),
7974
- left: "50%",
7975
- transform: "translateX(-50%)",
7976
- width: "16px",
7977
- height: "16px",
7978
- background: "linear-gradient(135deg, #ffffff 0%, #f0f9ff 100%)",
7979
- borderRadius: "50%",
7980
- border: "2px solid rgba(96, 165, 250, 0.9)",
7981
- boxShadow: "0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)",
7982
- transition: "bottom 0.15s ease-out, transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out, width 0.2s ease-in-out, height 0.2s ease-in-out",
7983
- cursor: "grab"
7984
- },
7985
- onMouseEnter: function(e) {
7986
- e.currentTarget.style.boxShadow = "0 4px 12px rgba(0, 0, 0, 0.6), 0 0 0 3px rgba(96, 165, 250, 0.6), 0 0 24px rgba(96, 165, 250, 0.7)";
7987
- e.currentTarget.style.cursor = "grab";
7988
- },
7989
- onMouseLeave: function(e) {
7990
- e.currentTarget.style.boxShadow = "0 3px 8px rgba(0, 0, 0, 0.5), 0 0 0 2px rgba(96, 165, 250, 0.4), 0 0 16px rgba(96, 165, 250, 0.5)";
7991
- },
7992
- onMouseDown: function(e) {
7993
- e.currentTarget.style.cursor = "grabbing";
7994
- },
7995
- onMouseUp: function(e) {
7996
- e.currentTarget.style.cursor = "grab";
7997
- }
7998
- })
7999
- ]
8155
+ position: "absolute",
8156
+ inset: 0,
8157
+ background: "rgba(255, 255, 255, 0.2)",
8158
+ borderRadius: "1.5px"
8159
+ }
8160
+ }),
8161
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
8162
+ style: {
8163
+ position: "absolute",
8164
+ top: 0,
8165
+ left: 0,
8166
+ bottom: 0,
8167
+ width: "".concat((isMuted ? 0 : volume) * 100, "%"),
8168
+ background: "#fff",
8169
+ borderRadius: "1.5px",
8170
+ transition: "width 0.1s ease-out"
8171
+ }
8172
+ }),
8173
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
8174
+ style: {
8175
+ position: "absolute",
8176
+ top: "50%",
8177
+ left: "".concat((isMuted ? 0 : volume) * 100, "%"),
8178
+ transform: "translate(-50%, -50%)",
8179
+ width: "12px",
8180
+ height: "12px",
8181
+ background: "#fff",
8182
+ borderRadius: "50%",
8183
+ boxShadow: "0 0 3px rgba(0, 0, 0, 0.3)",
8184
+ transition: "left 0.1s ease-out"
8185
+ }
8000
8186
  })
8001
- })
8002
- ]
8187
+ ]
8188
+ })
8003
8189
  })
8004
8190
  ]
8005
8191
  }),
8006
8192
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", {
8007
- onClick: function() {
8193
+ className: "sc-ctrl-btn",
8194
+ onClick: function onClick() {
8008
8195
  if (onFullscreenToggle) {
8009
8196
  onFullscreenToggle();
8010
- } else if (playerRef.current) {
8011
- playerRef.current.toggleFullscreen().catch(function(err) {
8012
- console.error("Fullscreen error:", err);
8013
- });
8197
+ } else if (wrapperRef.current) {
8198
+ if (!document.fullscreenElement) {
8199
+ wrapperRef.current.requestFullscreen().catch(function() {});
8200
+ } else {
8201
+ document.exitFullscreen().catch(function() {});
8202
+ }
8014
8203
  }
8015
- },
8016
- onMouseEnter: function(e) {
8017
- var target = e.currentTarget;
8018
- target.style.boxShadow = "0 14px 48px rgba(0, 0, 0, 0.7), 0 0 0 3px rgba(255, 255, 255, 0.8), inset 0 2px 0 rgba(255, 255, 255, 0.4)";
8019
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.85) 0%, rgba(0, 0, 0, 0.75) 100%)";
8020
- },
8021
- onMouseLeave: function(e) {
8022
- var target = e.currentTarget;
8023
- target.style.boxShadow = "0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)";
8024
- target.style.background = "linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)";
8204
+ resetControlsTimer();
8025
8205
  },
8026
8206
  style: {
8027
- background: "linear-gradient(135deg, rgba(0, 0, 0, 0.75) 0%, rgba(0, 0, 0, 0.65) 100%)",
8028
- color: "#ffffff",
8029
- border: "none",
8030
- borderRadius: "".concat(18 * responsiveScale, "px"),
8031
8207
  padding: "".concat(8 * responsiveScale, "px"),
8032
- cursor: "pointer",
8033
- display: "flex",
8034
- alignItems: "center",
8035
- justifyContent: "center",
8036
- backdropFilter: "blur(20px)",
8037
- boxShadow: "0 10px 36px rgba(0, 0, 0, 0.6), 0 0 0 2px rgba(255, 255, 255, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.3)",
8038
- transition: "all 0.4s cubic-bezier(0.4, 0, 0.2, 1)",
8039
- minWidth: "".concat(46 * responsiveScale, "px"),
8040
- minHeight: "".concat(46 * responsiveScale, "px")
8208
+ borderRadius: "50%",
8209
+ minWidth: "".concat(36 * responsiveScale, "px"),
8210
+ minHeight: "".concat(36 * responsiveScale, "px"),
8211
+ background: "rgba(0, 0, 0, 0.6)"
8041
8212
  },
8042
8213
  title: isFullscreen ? "Exit Fullscreen" : "Enter Fullscreen",
8043
8214
  children: isFullscreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaCompress, {
8044
- size: Math.max(14, 16 * responsiveScale),
8045
- style: {
8046
- filter: "drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))",
8047
- color: "#ffffff"
8048
- }
8215
+ size: Math.max(14, 18 * responsiveScale)
8049
8216
  }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_fa.FaExpand, {
8050
- size: Math.max(14, 16 * responsiveScale),
8051
- style: {
8052
- filter: "drop-shadow(0 2px 4px rgba(0, 0, 0, 0.8))",
8053
- color: "#ffffff"
8054
- }
8217
+ size: Math.max(14, 18 * responsiveScale)
8055
8218
  })
8056
8219
  })
8057
8220
  ]