stormcloud-video-player 0.7.14 → 0.7.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.cts CHANGED
@@ -157,6 +157,7 @@ declare class StormcloudVideoPlayer {
157
157
  private pendingAdBreak;
158
158
  private prefetchTimerId;
159
159
  private savedMutedStateBeforeAd;
160
+ private adLayerInitialized;
160
161
  private consecutiveFailures;
161
162
  private readonly maxConsecutiveFailures;
162
163
  private lastAdRequestTime;
@@ -192,6 +193,8 @@ declare class StormcloudVideoPlayer {
192
193
  getRemainingAdSeconds(): number;
193
194
  isAdPlaying(): boolean;
194
195
  isShowingAds(): boolean;
196
+ private initializeAdLayer;
197
+ setDisableAds(disabled: boolean): void;
195
198
  private syncMainContentAudioWhenVisible;
196
199
  getStreamType(): "hls" | "other";
197
200
  shouldShowNativeControls(): boolean;
@@ -4027,6 +4030,14 @@ interface SwirlScrollerConfig {
4027
4030
  auto_refresh?: boolean;
4028
4031
  use_custom_text?: boolean;
4029
4032
  custom_text?: string;
4033
+ label?: string;
4034
+ label_line2?: string;
4035
+ label_color?: string;
4036
+ label_text_color?: string;
4037
+ accent_color?: string;
4038
+ show_accent_line?: boolean;
4039
+ separator_char?: string;
4040
+ preset?: string;
4030
4041
  }
4031
4042
  type SwirlOverlayType = "image" | "text" | "scroller" | "shape" | "score_bug" | "lower_third" | "qr_code" | "coming_up_next" | "contextual_trigger" | "odds_betting" | "breaking_news" | "countdown";
4032
4043
  interface SwirlOverlay {
package/lib/index.d.ts CHANGED
@@ -157,6 +157,7 @@ declare class StormcloudVideoPlayer {
157
157
  private pendingAdBreak;
158
158
  private prefetchTimerId;
159
159
  private savedMutedStateBeforeAd;
160
+ private adLayerInitialized;
160
161
  private consecutiveFailures;
161
162
  private readonly maxConsecutiveFailures;
162
163
  private lastAdRequestTime;
@@ -192,6 +193,8 @@ declare class StormcloudVideoPlayer {
192
193
  getRemainingAdSeconds(): number;
193
194
  isAdPlaying(): boolean;
194
195
  isShowingAds(): boolean;
196
+ private initializeAdLayer;
197
+ setDisableAds(disabled: boolean): void;
195
198
  private syncMainContentAudioWhenVisible;
196
199
  getStreamType(): "hls" | "other";
197
200
  shouldShowNativeControls(): boolean;
@@ -4027,6 +4030,14 @@ interface SwirlScrollerConfig {
4027
4030
  auto_refresh?: boolean;
4028
4031
  use_custom_text?: boolean;
4029
4032
  custom_text?: string;
4033
+ label?: string;
4034
+ label_line2?: string;
4035
+ label_color?: string;
4036
+ label_text_color?: string;
4037
+ accent_color?: string;
4038
+ show_accent_line?: boolean;
4039
+ separator_char?: string;
4040
+ preset?: string;
4030
4041
  }
4031
4042
  type SwirlOverlayType = "image" | "text" | "scroller" | "shape" | "score_bug" | "lower_third" | "qr_code" | "coming_up_next" | "contextual_trigger" | "odds_betting" | "breaking_news" | "countdown";
4032
4043
  interface SwirlOverlay {
package/lib/index.js CHANGED
@@ -2765,6 +2765,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2765
2765
  this.maxTotalAdRequestsPerBreak = 20;
2766
2766
  this.pendingAdBreak = null;
2767
2767
  this.savedMutedStateBeforeAd = null;
2768
+ this.adLayerInitialized = false;
2768
2769
  this.consecutiveFailures = 0;
2769
2770
  this.maxConsecutiveFailures = 5;
2770
2771
  this.lastAdRequestTime = 0;
@@ -3413,12 +3414,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3413
3414
  this.video.autoplay = !!this.config.autoplay;
3414
3415
  this.video.muted = !!this.config.muted;
3415
3416
  if (!this.config.disableAds) {
3416
- this.adLayer.initialize();
3417
- if (!this.config.disableFiller) {
3418
- this.ensureFillerVideo();
3419
- }
3420
- this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);
3421
- this.attachAdLayerEventListeners();
3417
+ this.initializeAdLayer();
3422
3418
  }
3423
3419
  this.timeUpdateHandler = function() {
3424
3420
  _this.onTimeUpdate(_this.video.currentTime);
@@ -3519,6 +3515,31 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3519
3515
  return this.showAds;
3520
3516
  }
3521
3517
  },
3518
+ {
3519
+ key: "initializeAdLayer",
3520
+ value: function initializeAdLayer() {
3521
+ if (this.adLayerInitialized) return;
3522
+ this.adLayer.initialize();
3523
+ if (!this.config.disableFiller) {
3524
+ this.ensureFillerVideo();
3525
+ }
3526
+ this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);
3527
+ this.attachAdLayerEventListeners();
3528
+ this.adLayerInitialized = true;
3529
+ }
3530
+ },
3531
+ {
3532
+ key: "setDisableAds",
3533
+ value: function setDisableAds(disabled) {
3534
+ this.config.disableAds = disabled;
3535
+ if (!disabled && this.attached) {
3536
+ this.initializeAdLayer();
3537
+ }
3538
+ if (this.config.debugAdTiming) {
3539
+ console.log("[StormcloudVideoPlayer] setDisableAds:", disabled);
3540
+ }
3541
+ }
3542
+ },
3522
3543
  {
3523
3544
  key: "syncMainContentAudioWhenVisible",
3524
3545
  value: function syncMainContentAudioWhenVisible() {
@@ -5588,7 +5609,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5588
5609
  // src/ui/StormcloudVideoPlayer.tsx
5589
5610
  import { FaPlay, FaPause, FaVolumeUp, FaVolumeMute, FaVolumeDown, FaExpand, FaCompress, FaCog, FaTimes, FaCopy } from "react-icons/fa";
5590
5611
  // src/ui/OverlayRenderer.tsx
5591
- import React, { useEffect, useRef, useState, useCallback, useMemo } from "react";
5612
+ import React, { useEffect, useRef, useState, useCallback, useMemo, useId } from "react";
5592
5613
  // src/utils/overlays.ts
5593
5614
  var OVERLAY_API_BASE = "https://adstorm.co/api-adstorm-dev";
5594
5615
  function timeStringToSeconds(timeStr) {
@@ -5753,60 +5774,303 @@ function TextOverlay(param) {
5753
5774
  children: text
5754
5775
  });
5755
5776
  }
5777
+ function fetchRSSItems(rssUrl, maxItems) {
5778
+ return _async_to_generator(function() {
5779
+ var resp, data, parser, doc;
5780
+ return _ts_generator(this, function(_state) {
5781
+ switch(_state.label){
5782
+ case 0:
5783
+ return [
5784
+ 4,
5785
+ fetch("https://api.allorigins.win/get?url=".concat(encodeURIComponent(rssUrl)))
5786
+ ];
5787
+ case 1:
5788
+ resp = _state.sent();
5789
+ return [
5790
+ 4,
5791
+ resp.json()
5792
+ ];
5793
+ case 2:
5794
+ data = _state.sent();
5795
+ if (!data.contents) throw new Error("No content from RSS feed");
5796
+ parser = new DOMParser();
5797
+ doc = parser.parseFromString(data.contents, "text/xml");
5798
+ if (doc.querySelector("parsererror")) throw new Error("Invalid RSS XML");
5799
+ return [
5800
+ 2,
5801
+ Array.from(doc.querySelectorAll("item")).map(function(item) {
5802
+ var _item_querySelector, _item_querySelector1, _item_querySelector2, _item_querySelector3, _item_querySelector4;
5803
+ return {
5804
+ title: (((_item_querySelector = item.querySelector("title")) === null || _item_querySelector === void 0 ? void 0 : _item_querySelector.textContent) || "").replace(/<[^>]*>/g, "").trim(),
5805
+ description: (((_item_querySelector1 = item.querySelector("description")) === null || _item_querySelector1 === void 0 ? void 0 : _item_querySelector1.textContent) || "").replace(/<[^>]*>/g, "").trim(),
5806
+ pubDate: ((_item_querySelector2 = item.querySelector("pubDate")) === null || _item_querySelector2 === void 0 ? void 0 : _item_querySelector2.textContent) || "",
5807
+ author: ((_item_querySelector3 = item.querySelector("author, dc\\:creator")) === null || _item_querySelector3 === void 0 ? void 0 : _item_querySelector3.textContent) || "",
5808
+ category: ((_item_querySelector4 = item.querySelector("category")) === null || _item_querySelector4 === void 0 ? void 0 : _item_querySelector4.textContent) || ""
5809
+ };
5810
+ }).filter(function(i) {
5811
+ return i.title;
5812
+ }).slice(0, maxItems)
5813
+ ];
5814
+ }
5815
+ });
5816
+ })();
5817
+ }
5756
5818
  function ScrollerOverlay(param) {
5757
5819
  var overlay = param.overlay;
5758
- var _ref, _ref1, _ref2, _ref3, _ref4;
5820
+ var _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _ref10, _ref11, _ref12;
5759
5821
  var cfg = overlay.scroller_config;
5760
- var text = (cfg === null || cfg === void 0 ? void 0 : cfg.use_custom_text) && cfg.custom_text ? cfg.custom_text : overlay.content || (cfg === null || cfg === void 0 ? void 0 : cfg.custom_text) || "";
5761
- var scrollSpeed = (_ref = cfg === null || cfg === void 0 ? void 0 : cfg.scroll_speed) !== null && _ref !== void 0 ? _ref : 50;
5762
- var direction = (_ref1 = cfg === null || cfg === void 0 ? void 0 : cfg.direction) !== null && _ref1 !== void 0 ? _ref1 : "left";
5763
- var fontSize = (cfg === null || cfg === void 0 ? void 0 : cfg.font_size) ? "".concat(cfg.font_size, "px") : "clamp(10px, 1.2vw, 18px)";
5822
+ var uid = useId().replace(/:/g, "");
5823
+ var _useState = _sliced_to_array(useState([]), 2), rssItems = _useState[0], setRssItems = _useState[1];
5824
+ var _useState1 = _sliced_to_array(useState(false), 2), rssLoading = _useState1[0], setRssLoading = _useState1[1];
5825
+ var rssUrl = (cfg === null || cfg === void 0 ? void 0 : cfg.rss_url) || "";
5826
+ var maxItems = (_ref = cfg === null || cfg === void 0 ? void 0 : cfg.max_items) !== null && _ref !== void 0 ? _ref : 10;
5827
+ var autoRefresh = (cfg === null || cfg === void 0 ? void 0 : cfg.auto_refresh) !== false;
5828
+ var updateInterval = (_ref1 = cfg === null || cfg === void 0 ? void 0 : cfg.update_interval) !== null && _ref1 !== void 0 ? _ref1 : 5;
5829
+ useEffect(function() {
5830
+ if (!rssUrl || (cfg === null || cfg === void 0 ? void 0 : cfg.use_custom_text) && (cfg === null || cfg === void 0 ? void 0 : cfg.custom_text)) return;
5831
+ var cancelled = false;
5832
+ setRssLoading(true);
5833
+ fetchRSSItems(rssUrl, maxItems).then(function(items) {
5834
+ if (!cancelled) setRssItems(items);
5835
+ }).catch(function() {}).finally(function() {
5836
+ if (!cancelled) setRssLoading(false);
5837
+ });
5838
+ return function() {
5839
+ cancelled = true;
5840
+ };
5841
+ }, [
5842
+ rssUrl,
5843
+ maxItems,
5844
+ cfg === null || cfg === void 0 ? void 0 : cfg.use_custom_text,
5845
+ cfg === null || cfg === void 0 ? void 0 : cfg.custom_text
5846
+ ]);
5847
+ useEffect(function() {
5848
+ if (!rssUrl || !autoRefresh || (cfg === null || cfg === void 0 ? void 0 : cfg.use_custom_text) && (cfg === null || cfg === void 0 ? void 0 : cfg.custom_text)) return;
5849
+ var interval = setInterval(function() {
5850
+ fetchRSSItems(rssUrl, maxItems).then(setRssItems).catch(function() {});
5851
+ }, updateInterval * 60 * 1e3);
5852
+ return function() {
5853
+ return clearInterval(interval);
5854
+ };
5855
+ }, [
5856
+ rssUrl,
5857
+ autoRefresh,
5858
+ updateInterval,
5859
+ maxItems,
5860
+ cfg === null || cfg === void 0 ? void 0 : cfg.use_custom_text,
5861
+ cfg === null || cfg === void 0 ? void 0 : cfg.custom_text
5862
+ ]);
5863
+ var sep = (_ref2 = cfg === null || cfg === void 0 ? void 0 : cfg.separator_char) !== null && _ref2 !== void 0 ? _ref2 : "\u25C6";
5864
+ var segments;
5865
+ if ((cfg === null || cfg === void 0 ? void 0 : cfg.use_custom_text) && (cfg === null || cfg === void 0 ? void 0 : cfg.custom_text)) {
5866
+ segments = [
5867
+ cfg.custom_text
5868
+ ];
5869
+ } else if (rssItems.length > 0) {
5870
+ segments = rssItems.map(function(item) {
5871
+ var parts = [];
5872
+ if ((cfg === null || cfg === void 0 ? void 0 : cfg.show_title) !== false && item.title) parts.push(item.title);
5873
+ if ((cfg === null || cfg === void 0 ? void 0 : cfg.show_description) && item.description) parts.push(item.description);
5874
+ if ((cfg === null || cfg === void 0 ? void 0 : cfg.show_timestamp) && item.pubDate) {
5875
+ try {
5876
+ parts.push(new Date(item.pubDate).toLocaleDateString());
5877
+ } catch (unused) {}
5878
+ }
5879
+ if ((cfg === null || cfg === void 0 ? void 0 : cfg.show_author) && item.author) parts.push("— ".concat(item.author));
5880
+ if ((cfg === null || cfg === void 0 ? void 0 : cfg.show_category) && item.category) parts.push("[".concat(item.category, "]"));
5881
+ return parts.join(" ");
5882
+ });
5883
+ } else if (rssLoading) {
5884
+ segments = [
5885
+ "Loading feed\u2026"
5886
+ ];
5887
+ } else if (overlay.content) {
5888
+ segments = [
5889
+ overlay.content
5890
+ ];
5891
+ } else {
5892
+ segments = rssUrl ? [
5893
+ "Fetching RSS feed\u2026"
5894
+ ] : [
5895
+ "RSS Ticker"
5896
+ ];
5897
+ }
5898
+ var scrollSpeed = (_ref3 = cfg === null || cfg === void 0 ? void 0 : cfg.scroll_speed) !== null && _ref3 !== void 0 ? _ref3 : 40;
5899
+ var direction = (_ref4 = cfg === null || cfg === void 0 ? void 0 : cfg.direction) !== null && _ref4 !== void 0 ? _ref4 : "left";
5900
+ var fontSize = (_ref5 = cfg === null || cfg === void 0 ? void 0 : cfg.font_size) !== null && _ref5 !== void 0 ? _ref5 : 15;
5764
5901
  var fontFamily = (cfg === null || cfg === void 0 ? void 0 : cfg.font_family) || "Roboto, 'Segoe UI', Arial, sans-serif";
5765
- var fontWeight = (cfg === null || cfg === void 0 ? void 0 : cfg.font_weight) || "600";
5902
+ var fontWeight = (cfg === null || cfg === void 0 ? void 0 : cfg.font_weight) || "700";
5766
5903
  var textColor = (cfg === null || cfg === void 0 ? void 0 : cfg.text_color) || "#ffffff";
5767
- var bgColor = (cfg === null || cfg === void 0 ? void 0 : cfg.background_color) || "transparent";
5768
- var bgOpacity = (cfg === null || cfg === void 0 ? void 0 : cfg.background_opacity) !== void 0 ? cfg.background_opacity / 100 : 0;
5769
- var borderColor = (cfg === null || cfg === void 0 ? void 0 : cfg.border_color) || "transparent";
5770
- var borderWidth = (_ref2 = cfg === null || cfg === void 0 ? void 0 : cfg.border_width) !== null && _ref2 !== void 0 ? _ref2 : 0;
5771
- var borderRadius = (_ref3 = cfg === null || cfg === void 0 ? void 0 : cfg.border_radius) !== null && _ref3 !== void 0 ? _ref3 : 0;
5772
- var padding = (_ref4 = cfg === null || cfg === void 0 ? void 0 : cfg.padding) !== null && _ref4 !== void 0 ? _ref4 : 4;
5773
- var isVertical = direction === "up" || direction === "down";
5904
+ var bgColor = (cfg === null || cfg === void 0 ? void 0 : cfg.background_color) || "#0d0d1a";
5905
+ var bgOpacity = (cfg === null || cfg === void 0 ? void 0 : cfg.background_opacity) !== void 0 ? cfg.background_opacity / 100 : 0.95;
5906
+ var borderRadius = (_ref6 = cfg === null || cfg === void 0 ? void 0 : cfg.border_radius) !== null && _ref6 !== void 0 ? _ref6 : 0;
5907
+ var itemSpacing = (_ref7 = cfg === null || cfg === void 0 ? void 0 : cfg.item_spacing) !== null && _ref7 !== void 0 ? _ref7 : 60;
5908
+ var label = (_ref8 = cfg === null || cfg === void 0 ? void 0 : cfg.label) !== null && _ref8 !== void 0 ? _ref8 : "NEWS";
5909
+ var labelLine2 = (_ref9 = cfg === null || cfg === void 0 ? void 0 : cfg.label_line2) !== null && _ref9 !== void 0 ? _ref9 : "";
5910
+ var labelColor = (_ref10 = cfg === null || cfg === void 0 ? void 0 : cfg.label_color) !== null && _ref10 !== void 0 ? _ref10 : "#f97316";
5911
+ var labelTextColor = (_ref11 = cfg === null || cfg === void 0 ? void 0 : cfg.label_text_color) !== null && _ref11 !== void 0 ? _ref11 : "#ffffff";
5912
+ var accentColor = (_ref12 = cfg === null || cfg === void 0 ? void 0 : cfg.accent_color) !== null && _ref12 !== void 0 ? _ref12 : labelColor;
5913
+ var showAccentLine = (cfg === null || cfg === void 0 ? void 0 : cfg.show_accent_line) !== false;
5914
+ var isHorizontal = direction === "left" || direction === "right";
5774
5915
  var isReverse = direction === "right" || direction === "down";
5775
- var durationSec = Math.max(3, 120 - scrollSpeed);
5776
- var animId = "sc-scroller-".concat(overlay.id);
5777
- var keyframes = isVertical ? "@keyframes ".concat(animId, " {\n 0% { transform: translateY(").concat(isReverse ? "-100%" : "100%", "); }\n 100% { transform: translateY(").concat(isReverse ? "100%" : "-100%", "); }\n }") : "@keyframes ".concat(animId, " {\n 0% { transform: translateX(").concat(isReverse ? "-100%" : "100%", "); }\n 100% { transform: translateX(").concat(isReverse ? "100%" : "-100%", "); }\n }");
5916
+ var fullText = segments.join(" ".concat(sep, " "));
5917
+ var durationSec = Math.max(6, fullText.length * 9 / scrollSpeed);
5918
+ var animId = "sc-ticker-".concat(overlay.id, "-").concat(uid);
5919
+ var keyframes = isHorizontal ? "@keyframes ".concat(animId, " {\n ").concat(isReverse ? "0% { transform: translateX(-50%); } 100% { transform: translateX(0%); }" : "0% { transform: translateX(0); } 100% { transform: translateX(-50%); }", "\n }") : "@keyframes ".concat(animId, " {\n ").concat(isReverse ? "0% { transform: translateY(-50%); } 100% { transform: translateY(0%); }" : "0% { transform: translateY(0); } 100% { transform: translateY(-50%); }", "\n }");
5778
5920
  return /* @__PURE__ */ jsxs(Fragment, {
5779
5921
  children: [
5780
5922
  /* @__PURE__ */ jsx("style", {
5781
5923
  children: keyframes
5782
5924
  }),
5783
- /* @__PURE__ */ jsx("div", {
5925
+ /* @__PURE__ */ jsxs("div", {
5784
5926
  style: {
5785
5927
  width: "100%",
5786
5928
  height: "100%",
5787
- overflow: "hidden",
5788
5929
  display: "flex",
5789
- alignItems: "center",
5790
- backgroundColor: bgOpacity > 0 ? "rgba(".concat(hexToRgb(bgColor), ", ").concat(bgOpacity, ")") : void 0,
5791
- border: borderWidth > 0 ? "".concat(borderWidth, "px solid ").concat(borderColor) : void 0,
5930
+ flexDirection: "column",
5931
+ overflow: "hidden",
5792
5932
  borderRadius: borderRadius > 0 ? "".concat(borderRadius, "px") : void 0,
5793
- padding: "".concat(padding, "px"),
5794
- boxSizing: "border-box",
5795
- pointerEvents: "none"
5933
+ backgroundColor: "rgba(".concat(hexToRgb(bgColor), ", ").concat(bgOpacity, ")"),
5934
+ fontFamily: fontFamily,
5935
+ fontSize: "".concat(fontSize, "px"),
5936
+ fontWeight: fontWeight,
5937
+ color: textColor,
5938
+ pointerEvents: "none",
5939
+ userSelect: "none"
5796
5940
  },
5797
- children: /* @__PURE__ */ jsx("div", {
5798
- style: {
5799
- whiteSpace: "nowrap",
5800
- fontSize: fontSize,
5801
- fontFamily: fontFamily,
5802
- fontWeight: fontWeight,
5803
- color: textColor,
5804
- animation: "".concat(animId, " ").concat(durationSec, "s linear infinite"),
5805
- textShadow: "0 1px 4px rgba(0,0,0,0.5)",
5806
- userSelect: "none"
5807
- },
5808
- children: text
5809
- })
5941
+ children: [
5942
+ showAccentLine && /* @__PURE__ */ jsx("div", {
5943
+ style: {
5944
+ height: 3,
5945
+ background: accentColor,
5946
+ flexShrink: 0,
5947
+ width: "100%"
5948
+ }
5949
+ }),
5950
+ /* @__PURE__ */ jsxs("div", {
5951
+ style: {
5952
+ display: "flex",
5953
+ flex: 1,
5954
+ overflow: "hidden",
5955
+ minHeight: 0
5956
+ },
5957
+ children: [
5958
+ label && /* @__PURE__ */ jsxs("div", {
5959
+ style: {
5960
+ background: labelColor,
5961
+ color: labelTextColor,
5962
+ padding: "0 14px",
5963
+ display: "flex",
5964
+ flexDirection: "column",
5965
+ alignItems: "center",
5966
+ justifyContent: "center",
5967
+ flexShrink: 0,
5968
+ minWidth: 72,
5969
+ textAlign: "center",
5970
+ gap: 1
5971
+ },
5972
+ children: [
5973
+ /* @__PURE__ */ jsx("span", {
5974
+ style: {
5975
+ fontWeight: 800,
5976
+ fontSize: "0.82em",
5977
+ letterSpacing: "0.05em",
5978
+ lineHeight: 1.1,
5979
+ textTransform: "uppercase",
5980
+ whiteSpace: "nowrap"
5981
+ },
5982
+ children: label
5983
+ }),
5984
+ labelLine2 && /* @__PURE__ */ jsx("span", {
5985
+ style: {
5986
+ fontWeight: 500,
5987
+ fontSize: "0.62em",
5988
+ letterSpacing: "0.03em",
5989
+ lineHeight: 1.1,
5990
+ opacity: 0.85,
5991
+ whiteSpace: "nowrap"
5992
+ },
5993
+ children: labelLine2
5994
+ })
5995
+ ]
5996
+ }),
5997
+ label && /* @__PURE__ */ jsx("div", {
5998
+ style: {
5999
+ width: 3,
6000
+ background: accentColor,
6001
+ flexShrink: 0
6002
+ }
6003
+ }),
6004
+ /* @__PURE__ */ jsx("div", {
6005
+ style: {
6006
+ flex: 1,
6007
+ overflow: "hidden",
6008
+ position: "relative",
6009
+ display: "flex",
6010
+ alignItems: "center"
6011
+ },
6012
+ children: isHorizontal ? /* @__PURE__ */ jsx("div", {
6013
+ style: {
6014
+ display: "inline-flex",
6015
+ whiteSpace: "nowrap",
6016
+ animation: "".concat(animId, " ").concat(durationSec, "s linear infinite"),
6017
+ willChange: "transform"
6018
+ },
6019
+ children: [
6020
+ 0,
6021
+ 1
6022
+ ].map(function(copy) {
6023
+ return /* @__PURE__ */ jsx("span", {
6024
+ style: {
6025
+ paddingRight: "".concat(itemSpacing, "px")
6026
+ },
6027
+ children: segments.map(function(seg, i) {
6028
+ return /* @__PURE__ */ jsxs(React.Fragment, {
6029
+ children: [
6030
+ i > 0 && /* @__PURE__ */ jsx("span", {
6031
+ style: {
6032
+ opacity: 0.5,
6033
+ margin: "0 8px"
6034
+ },
6035
+ children: sep
6036
+ }),
6037
+ /* @__PURE__ */ jsx("span", {
6038
+ style: {
6039
+ textShadow: "0 1px 3px rgba(0,0,0,0.6)"
6040
+ },
6041
+ children: seg
6042
+ })
6043
+ ]
6044
+ }, i);
6045
+ })
6046
+ }, copy);
6047
+ })
6048
+ }) : /* @__PURE__ */ jsx("div", {
6049
+ style: {
6050
+ display: "flex",
6051
+ flexDirection: "column",
6052
+ whiteSpace: "nowrap",
6053
+ animation: "".concat(animId, " ").concat(durationSec, "s linear infinite"),
6054
+ willChange: "transform"
6055
+ },
6056
+ children: [
6057
+ 0,
6058
+ 1
6059
+ ].map(function(copy) {
6060
+ return segments.map(function(seg, i) {
6061
+ return /* @__PURE__ */ jsx("div", {
6062
+ style: {
6063
+ paddingBottom: "".concat(itemSpacing / 4, "px")
6064
+ },
6065
+ children: seg
6066
+ }, "".concat(copy, "-").concat(i));
6067
+ });
6068
+ })
6069
+ })
6070
+ })
6071
+ ]
6072
+ })
6073
+ ]
5810
6074
  })
5811
6075
  ]
5812
6076
  });
@@ -7021,12 +7285,13 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
7021
7285
  var _React2_useState21 = _sliced_to_array(React2.useState(false), 2), showDebugPanel = _React2_useState21[0], setShowDebugPanel = _React2_useState21[1];
7022
7286
  var _React2_useState22 = _sliced_to_array(React2.useState([]), 2), debugMarkers = _React2_useState22[0], setDebugMarkers = _React2_useState22[1];
7023
7287
  var _React2_useState23 = _sliced_to_array(React2.useState(false), 2), showAiPanel = _React2_useState23[0], setShowAiPanel = _React2_useState23[1];
7024
- var _React2_useState24 = _sliced_to_array(React2.useState({
7288
+ var _React2_useState24 = _sliced_to_array(React2.useState(disableAds !== null && disableAds !== void 0 ? disableAds : false), 2), adsDisabled = _React2_useState24[0], setAdsDisabled = _React2_useState24[1];
7289
+ var _React2_useState25 = _sliced_to_array(React2.useState({
7025
7290
  context: null,
7026
7291
  isLoading: false,
7027
7292
  error: null,
7028
7293
  lastPolledAt: null
7029
- }), 2), aiLiveContext = _React2_useState24[0], setAiLiveContext = _React2_useState24[1];
7294
+ }), 2), aiLiveContext = _React2_useState25[0], setAiLiveContext = _React2_useState25[1];
7030
7295
  var getResponsiveScale = function getResponsiveScale() {
7031
7296
  if (viewportWidth < 480) return 0.7;
7032
7297
  if (viewportWidth < 768) return 0.8;
@@ -8513,6 +8778,31 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
8513
8778
  gap: "".concat(8 * responsiveScale, "px")
8514
8779
  },
8515
8780
  children: [
8781
+ /* @__PURE__ */ jsx2("button", {
8782
+ className: "sc-ctrl-btn",
8783
+ onClick: function onClick() {
8784
+ var _playerRef_current;
8785
+ var next = !adsDisabled;
8786
+ setAdsDisabled(next);
8787
+ (_playerRef_current = playerRef.current) === null || _playerRef_current === void 0 ? void 0 : _playerRef_current.setDisableAds(next);
8788
+ resetControlsTimer();
8789
+ },
8790
+ style: {
8791
+ padding: "".concat(8 * responsiveScale, "px"),
8792
+ borderRadius: "50%",
8793
+ minWidth: "".concat(36 * responsiveScale, "px"),
8794
+ minHeight: "".concat(36 * responsiveScale, "px"),
8795
+ background: adsDisabled ? "rgba(239, 68, 68, 0.28)" : "transparent",
8796
+ fontFamily: "'SF Mono', 'Cascadia Code', monospace",
8797
+ fontSize: "".concat(12 * responsiveScale, "px"),
8798
+ fontWeight: 700,
8799
+ letterSpacing: "0.03em",
8800
+ color: adsDisabled ? "rgba(252, 165, 165, 0.9)" : "rgba(255, 255, 255, 0.75)",
8801
+ textDecoration: adsDisabled ? "line-through" : "none"
8802
+ },
8803
+ title: adsDisabled ? "Enable ads" : "Disable ads",
8804
+ children: "AD"
8805
+ }),
8516
8806
  swirlProjectId && /* @__PURE__ */ jsx2("button", {
8517
8807
  className: "sc-ctrl-btn",
8518
8808
  onClick: function onClick() {
@@ -8806,6 +9096,31 @@ var StormcloudVideoPlayerComponent = React2.memo(function(props) {
8806
9096
  })
8807
9097
  ]
8808
9098
  }),
9099
+ /* @__PURE__ */ jsx2("button", {
9100
+ className: "sc-ctrl-btn",
9101
+ onClick: function onClick() {
9102
+ var _playerRef_current;
9103
+ var next = !adsDisabled;
9104
+ setAdsDisabled(next);
9105
+ (_playerRef_current = playerRef.current) === null || _playerRef_current === void 0 ? void 0 : _playerRef_current.setDisableAds(next);
9106
+ resetControlsTimer();
9107
+ },
9108
+ style: {
9109
+ padding: "".concat(8 * responsiveScale, "px"),
9110
+ borderRadius: "50%",
9111
+ minWidth: "".concat(36 * responsiveScale, "px"),
9112
+ minHeight: "".concat(36 * responsiveScale, "px"),
9113
+ background: adsDisabled ? "rgba(239, 68, 68, 0.28)" : "rgba(0, 0, 0, 0.6)",
9114
+ fontFamily: "'SF Mono', 'Cascadia Code', monospace",
9115
+ fontSize: "".concat(12 * responsiveScale, "px"),
9116
+ fontWeight: 700,
9117
+ letterSpacing: "0.03em",
9118
+ color: adsDisabled ? "rgba(252, 165, 165, 0.9)" : "rgba(255, 255, 255, 0.75)",
9119
+ textDecoration: adsDisabled ? "line-through" : "none"
9120
+ },
9121
+ title: adsDisabled ? "Enable ads" : "Disable ads",
9122
+ children: "AD"
9123
+ }),
8809
9124
  swirlProjectId && /* @__PURE__ */ jsx2("button", {
8810
9125
  className: "sc-ctrl-btn",
8811
9126
  onClick: function onClick() {