stormcloud-video-player 0.7.11 → 0.7.13

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.
@@ -1429,7 +1429,6 @@ function createAdStormPlayer(contentVideo, options) {
1429
1429
  contentVideo.muted = originalMutedState;
1430
1430
  contentVideo.volume = originalVolume;
1431
1431
  currentAd = void 0;
1432
- tornDown = false;
1433
1432
  return [
1434
1433
  2,
1435
1434
  Promise.resolve()
@@ -1544,6 +1543,15 @@ function createAdStormPlayer(contentVideo, options) {
1544
1543
  if (!token) return [
1545
1544
  2
1546
1545
  ];
1546
+ if (currentAd) {
1547
+ preloadSlots.set(token, {
1548
+ ad: currentAd
1549
+ });
1550
+ currentAd = void 0;
1551
+ return [
1552
+ 2
1553
+ ];
1554
+ }
1547
1555
  requestContext = typeof arg1 === "string" ? arg2 : arg1;
1548
1556
  return [
1549
1557
  4,
@@ -2037,56 +2045,6 @@ function sendInitialTracking(licenseKey) {
2037
2045
  });
2038
2046
  })();
2039
2047
  }
2040
- function sendAdDetectTracking(licenseKey, adDetectInfo) {
2041
- return _async_to_generator(function() {
2042
- var clientInfo, browserId, trackingData, error;
2043
- return _ts_generator(this, function(_state) {
2044
- switch(_state.label){
2045
- case 0:
2046
- _state.trys.push([
2047
- 0,
2048
- 3,
2049
- ,
2050
- 4
2051
- ]);
2052
- clientInfo = getClientInfo();
2053
- return [
2054
- 4,
2055
- getBrowserID(clientInfo)
2056
- ];
2057
- case 1:
2058
- browserId = _state.sent();
2059
- trackingData = _object_spread({
2060
- browserId: browserId
2061
- }, clientInfo);
2062
- return [
2063
- 4,
2064
- sendTrackRequest(licenseKey, _object_spread_props(_object_spread({}, trackingData), {
2065
- licenseKey: licenseKey,
2066
- adDetectInfo: adDetectInfo
2067
- }))
2068
- ];
2069
- case 2:
2070
- _state.sent();
2071
- return [
2072
- 3,
2073
- 4
2074
- ];
2075
- case 3:
2076
- error = _state.sent();
2077
- console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2078
- return [
2079
- 3,
2080
- 4
2081
- ];
2082
- case 4:
2083
- return [
2084
- 2
2085
- ];
2086
- }
2087
- });
2088
- })();
2089
- }
2090
2048
  function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
2091
2049
  return _async_to_generator(function() {
2092
2050
  var clientInfo, browserId, trackingData, error;
@@ -2771,7 +2729,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2771
2729
  this.continuousFetchLoopPromise = null;
2772
2730
  this.attached = false;
2773
2731
  this.inAdBreak = false;
2774
- this.ptsDriftEmaMs = 0;
2775
2732
  this.adPodQueue = [];
2776
2733
  this.lastHeartbeatTime = 0;
2777
2734
  this.currentAdIndex = 0;
@@ -2795,7 +2752,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2795
2752
  this.totalAdRequestsInBreak = 0;
2796
2753
  this.maxTotalAdRequestsPerBreak = 20;
2797
2754
  this.pendingAdBreak = null;
2798
- this.savedMutedStateBeforeScte = null;
2755
+ this.savedMutedStateBeforeAd = null;
2799
2756
  this.consecutiveFailures = 0;
2800
2757
  this.maxConsecutiveFailures = 5;
2801
2758
  this.lastAdRequestTime = 0;
@@ -2808,7 +2765,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
2808
2765
  this.adRequestRetryBackoffMs = 1500;
2809
2766
  this.preloadedTokens = [];
2810
2767
  this.debugLogEntries = [];
2811
- this.scteMarkerHistory = [];
2812
2768
  this.adInsertionDebugHistory = [];
2813
2769
  initializePolyfills();
2814
2770
  var browserOverrides = getBrowserConfigOverrides();
@@ -3097,18 +3053,44 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3097
3053
  _this.pushAdInsertionDebug("ad_triggered", segmentName, {
3098
3054
  detail: "ad break started (60s)"
3099
3055
  });
3100
- var marker = {
3101
- type: "start",
3102
- durationSeconds: 60,
3103
- raw: {
3104
- apiInsertionPoint: _this.lastAdInsertionPoint
3105
- }
3106
- };
3107
- _this.onScte35Marker(marker);
3056
+ void _this.handleAdStart(60);
3108
3057
  }, offsetMs);
3109
3058
  }
3110
3059
  }
3111
3060
  });
3061
+ this.hls.on(import_hls.default.Events.FRAG_PARSING_USERDATA, function(_evt, data) {
3062
+ var _ref;
3063
+ var samples = (_ref = data === null || data === void 0 ? void 0 : data.samples) !== null && _ref !== void 0 ? _ref : [];
3064
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
3065
+ try {
3066
+ for(var _iterator = samples[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
3067
+ var sample = _step.value;
3068
+ var _ref1, _ref2;
3069
+ var _data_frag, _data_frag1;
3070
+ var bytes = sample === null || sample === void 0 ? void 0 : sample.data;
3071
+ if (!bytes || bytes.length < 5) continue;
3072
+ var isSCTE35 = bytes[0] === 252;
3073
+ if (!isSCTE35) continue;
3074
+ var segName = (_ref1 = (_ref2 = data === null || data === void 0 ? void 0 : (_data_frag = data.frag) === null || _data_frag === void 0 ? void 0 : _data_frag.relurl) !== null && _ref2 !== void 0 ? _ref2 : data === null || data === void 0 ? void 0 : (_data_frag1 = data.frag) === null || _data_frag1 === void 0 ? void 0 : _data_frag1.url) !== null && _ref1 !== void 0 ? _ref1 : "";
3075
+ _this.pushAdInsertionDebug("scte35_inserted", segName, {
3076
+ detail: "len=".concat(bytes.length, "B")
3077
+ });
3078
+ }
3079
+ } catch (err) {
3080
+ _didIteratorError = true;
3081
+ _iteratorError = err;
3082
+ } finally{
3083
+ try {
3084
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
3085
+ _iterator.return();
3086
+ }
3087
+ } finally{
3088
+ if (_didIteratorError) {
3089
+ throw _iteratorError;
3090
+ }
3091
+ }
3092
+ }
3093
+ });
3112
3094
  this.hls.on(import_hls.default.Events.ERROR, function(_evt, data) {
3113
3095
  if (data === null || data === void 0 ? void 0 : data.fatal) {
3114
3096
  switch(data.type){
@@ -3183,8 +3165,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3183
3165
  _this.activeAdRequestToken = null;
3184
3166
  _this.showAds = true;
3185
3167
  if (_this.config.disableFiller) {
3186
- if (_this.savedMutedStateBeforeScte == null) {
3187
- _this.savedMutedStateBeforeScte = {
3168
+ if (_this.savedMutedStateBeforeAd == null) {
3169
+ _this.savedMutedStateBeforeAd = {
3188
3170
  muted: _this.video.muted,
3189
3171
  volume: _this.video.volume
3190
3172
  };
@@ -3212,10 +3194,10 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3212
3194
  });
3213
3195
  this.adLayer.on("content_resume", function() {
3214
3196
  var _ref, _ref1;
3215
- var _this_savedMutedStateBeforeScte, _this_savedMutedStateBeforeScte1;
3197
+ var _this_savedMutedStateBeforeAd, _this_savedMutedStateBeforeAd1;
3216
3198
  var remaining = _this.getRemainingAdMs();
3217
- var breakMuted = (_ref = (_this_savedMutedStateBeforeScte = _this.savedMutedStateBeforeScte) === null || _this_savedMutedStateBeforeScte === void 0 ? void 0 : _this_savedMutedStateBeforeScte.muted) !== null && _ref !== void 0 ? _ref : _this.adLayer.getOriginalMutedState();
3218
- var breakVolume = (_ref1 = (_this_savedMutedStateBeforeScte1 = _this.savedMutedStateBeforeScte) === null || _this_savedMutedStateBeforeScte1 === void 0 ? void 0 : _this_savedMutedStateBeforeScte1.volume) !== null && _ref1 !== void 0 ? _ref1 : _this.adLayer.getOriginalVolume();
3199
+ var breakMuted = (_ref = (_this_savedMutedStateBeforeAd = _this.savedMutedStateBeforeAd) === null || _this_savedMutedStateBeforeAd === void 0 ? void 0 : _this_savedMutedStateBeforeAd.muted) !== null && _ref !== void 0 ? _ref : _this.adLayer.getOriginalMutedState();
3200
+ var breakVolume = (_ref1 = (_this_savedMutedStateBeforeAd1 = _this.savedMutedStateBeforeAd) === null || _this_savedMutedStateBeforeAd1 === void 0 ? void 0 : _this_savedMutedStateBeforeAd1.volume) !== null && _ref1 !== void 0 ? _ref1 : _this.adLayer.getOriginalVolume();
3219
3201
  if (_this.config.debugAdTiming) {
3220
3202
  console.log("[StormcloudVideoPlayer] content_resume received, inAdBreak=%s, remaining=%s, preloadedTokens=%d, pendingNext=%s", _this.inAdBreak, remaining, _this.preloadedTokens.length, !!_this.pendingNextAdBids);
3221
3203
  }
@@ -3292,7 +3274,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3292
3274
  var remainingFinal = _this.getRemainingAdMs();
3293
3275
  if (_this.inAdBreak && remainingFinal > _this.MIN_AD_REMAINING_MS) {
3294
3276
  if (_this.config.debugAdTiming) {
3295
- console.log("[StormcloudVideoPlayer] content_resume: no more ads, showing filler for", remainingFinal, "ms");
3277
+ console.log("[StormcloudVideoPlayer] content_resume: ad ended/failed with time remaining, showing filler and continuing fetch for", remainingFinal, "ms");
3296
3278
  }
3297
3279
  if (!_this.config.disableFiller) {
3298
3280
  _this.showPlaceholderLayer();
@@ -3310,7 +3292,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3310
3292
  (_this_video_play = _this.video.play()) === null || _this_video_play === void 0 ? void 0 : _this_video_play.catch(function() {});
3311
3293
  }
3312
3294
  }
3313
- _this.stopContinuousFetching();
3295
+ _this.continuousFetchingActive = true;
3296
+ _this.startContinuousFetchLoop();
3314
3297
  return;
3315
3298
  }
3316
3299
  if (_this.config.debugAdTiming) {
@@ -3457,547 +3440,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
3457
3440
  return !!(this.config.allowNativeHls && canNative);
3458
3441
  }
3459
3442
  },
3460
- {
3461
- key: "onId3Tag",
3462
- value: function onId3Tag(tag) {
3463
- if (typeof tag.ptsSeconds === "number") {
3464
- this.updatePtsDrift(tag.ptsSeconds);
3465
- }
3466
- var marker = this.parseScte35FromId3(tag);
3467
- if (marker) {
3468
- this.onScte35Marker(marker);
3469
- }
3470
- }
3471
- },
3472
- {
3473
- key: "parseScte35FromId3",
3474
- value: function parseScte35FromId3(tag) {
3475
- var text = this.decodeId3ValueToText(tag.value);
3476
- if (!text) return void 0;
3477
- var cueOutMatch = text.match(/EXT-X-CUE-OUT(?::([^\r\n]*))?/i) || text.match(/CUE-OUT(?::([^\r\n]*))?/i);
3478
- if (cueOutMatch) {
3479
- var _cueOutMatch_;
3480
- var arg = ((_cueOutMatch_ = cueOutMatch[1]) !== null && _cueOutMatch_ !== void 0 ? _cueOutMatch_ : "").trim();
3481
- var dur = this.parseCueOutDuration(arg);
3482
- var marker = _object_spread_props(_object_spread({
3483
- type: "start"
3484
- }, tag.ptsSeconds !== void 0 ? {
3485
- ptsSeconds: tag.ptsSeconds
3486
- } : {}, dur !== void 0 ? {
3487
- durationSeconds: dur
3488
- } : {}), {
3489
- raw: {
3490
- id3: text
3491
- }
3492
- });
3493
- return marker;
3494
- }
3495
- var cueOutContMatch = text.match(/EXT-X-CUE-OUT-CONT:([^\r\n]*)/i);
3496
- if (cueOutContMatch) {
3497
- var _cueOutContMatch_;
3498
- var arg1 = ((_cueOutContMatch_ = cueOutContMatch[1]) !== null && _cueOutContMatch_ !== void 0 ? _cueOutContMatch_ : "").trim();
3499
- var cont = this.parseCueOutCont(arg1);
3500
- var marker1 = _object_spread_props(_object_spread({
3501
- type: "progress"
3502
- }, tag.ptsSeconds !== void 0 ? {
3503
- ptsSeconds: tag.ptsSeconds
3504
- } : {}, (cont === null || cont === void 0 ? void 0 : cont.duration) !== void 0 ? {
3505
- durationSeconds: cont.duration
3506
- } : {}), {
3507
- raw: {
3508
- id3: text
3509
- }
3510
- });
3511
- return marker1;
3512
- }
3513
- var cueInMatch = text.match(/EXT-X-CUE-IN\b/i) || text.match(/CUE-IN\b/i);
3514
- if (cueInMatch) {
3515
- var marker2 = _object_spread_props(_object_spread({
3516
- type: "end"
3517
- }, tag.ptsSeconds !== void 0 ? {
3518
- ptsSeconds: tag.ptsSeconds
3519
- } : {}), {
3520
- raw: {
3521
- id3: text
3522
- }
3523
- });
3524
- return marker2;
3525
- }
3526
- var daterangeMatch = text.match(/EXT-X-DATERANGE:([^\r\n]*)/i);
3527
- if (daterangeMatch) {
3528
- var _daterangeMatch_, _attrs_CLASS;
3529
- var attrs = this.parseAttributeList((_daterangeMatch_ = daterangeMatch[1]) !== null && _daterangeMatch_ !== void 0 ? _daterangeMatch_ : "");
3530
- var hasScteOut = "SCTE35-OUT" in attrs || attrs["SCTE35-OUT"] !== void 0;
3531
- var hasScteIn = "SCTE35-IN" in attrs || attrs["SCTE35-IN"] !== void 0;
3532
- var klass = String((_attrs_CLASS = attrs["CLASS"]) !== null && _attrs_CLASS !== void 0 ? _attrs_CLASS : "");
3533
- var duration = this.toNumber(attrs["DURATION"]);
3534
- if (hasScteOut || /com\.apple\.hls\.cue/i.test(klass)) {
3535
- var marker3 = _object_spread_props(_object_spread({
3536
- type: "start"
3537
- }, tag.ptsSeconds !== void 0 ? {
3538
- ptsSeconds: tag.ptsSeconds
3539
- } : {}, duration !== void 0 ? {
3540
- durationSeconds: duration
3541
- } : {}), {
3542
- raw: {
3543
- id3: text,
3544
- attrs: attrs
3545
- }
3546
- });
3547
- return marker3;
3548
- }
3549
- if (hasScteIn) {
3550
- var marker4 = _object_spread_props(_object_spread({
3551
- type: "end"
3552
- }, tag.ptsSeconds !== void 0 ? {
3553
- ptsSeconds: tag.ptsSeconds
3554
- } : {}), {
3555
- raw: {
3556
- id3: text,
3557
- attrs: attrs
3558
- }
3559
- });
3560
- return marker4;
3561
- }
3562
- }
3563
- if (/SCTE35-OUT/i.test(text)) {
3564
- var marker5 = _object_spread_props(_object_spread({
3565
- type: "start"
3566
- }, tag.ptsSeconds !== void 0 ? {
3567
- ptsSeconds: tag.ptsSeconds
3568
- } : {}), {
3569
- raw: {
3570
- id3: text
3571
- }
3572
- });
3573
- return marker5;
3574
- }
3575
- if (/SCTE35-IN/i.test(text)) {
3576
- var marker6 = _object_spread_props(_object_spread({
3577
- type: "end"
3578
- }, tag.ptsSeconds !== void 0 ? {
3579
- ptsSeconds: tag.ptsSeconds
3580
- } : {}), {
3581
- raw: {
3582
- id3: text
3583
- }
3584
- });
3585
- return marker6;
3586
- }
3587
- if (_instanceof(tag.value, Uint8Array)) {
3588
- var bin = this.parseScte35Binary(tag.value);
3589
- if (bin) return bin;
3590
- }
3591
- return void 0;
3592
- }
3593
- },
3594
- {
3595
- key: "decodeId3ValueToText",
3596
- value: function decodeId3ValueToText(value) {
3597
- try {
3598
- if (typeof value === "string") return value;
3599
- var decoder = new TextDecoder("utf-8", {
3600
- fatal: false
3601
- });
3602
- var text = decoder.decode(value);
3603
- if (text && /[\x20-\x7E]/.test(text)) return text;
3604
- var out = "";
3605
- for(var i = 0; i < value.length; i++)out += String.fromCharCode(value[i]);
3606
- return out;
3607
- } catch (unused) {
3608
- return void 0;
3609
- }
3610
- }
3611
- },
3612
- {
3613
- key: "onScte35Marker",
3614
- value: function onScte35Marker(marker) {
3615
- var _this = this;
3616
- if (this.config.disableAds) return;
3617
- this.pushScteMarker(marker);
3618
- this.pushDebugLog("info", "scte35", "SCTE-35 marker detected", {
3619
- type: marker.type,
3620
- ptsSeconds: marker.ptsSeconds,
3621
- durationSeconds: marker.durationSeconds,
3622
- currentTime: this.video.currentTime
3623
- });
3624
- if (this.config.debugAdTiming) {
3625
- console.log("[StormcloudVideoPlayer] SCTE-35 marker detected:", {
3626
- type: marker.type,
3627
- ptsSeconds: marker.ptsSeconds,
3628
- durationSeconds: marker.durationSeconds,
3629
- currentTime: this.video.currentTime,
3630
- raw: marker.raw,
3631
- hasPendingAdBreak: !!this.pendingAdBreak
3632
- });
3633
- }
3634
- if (marker.type === "start") {
3635
- var _this_config_immediateManifestAds;
3636
- var _this_pendingAdBreak;
3637
- if (this.savedMutedStateBeforeScte == null) {
3638
- this.savedMutedStateBeforeScte = {
3639
- muted: this.video.muted,
3640
- volume: this.video.volume
3641
- };
3642
- this.adLayer.updateOriginalMutedState(this.video.muted, this.video.volume);
3643
- }
3644
- if (!this.config.disableFiller && !this.video.muted && !this.adLayer.isAdPlaying()) {
3645
- this.video.muted = true;
3646
- this.video.volume = 0;
3647
- if (this.config.debugAdTiming) {
3648
- console.log("[StormcloudVideoPlayer] Muted video on SCTE start marker");
3649
- }
3650
- }
3651
- if (this.inAdBreak) {
3652
- if (marker.durationSeconds != null) {
3653
- var newDurationMs = marker.durationSeconds * 1e3;
3654
- if (this.expectedAdBreakDurationMs == null || newDurationMs > this.expectedAdBreakDurationMs) {
3655
- this.expectedAdBreakDurationMs = newDurationMs;
3656
- var elapsedMs = this.currentAdBreakStartWallClockMs != null ? Date.now() - this.currentAdBreakStartWallClockMs : 0;
3657
- var remainingMs = Math.max(0, newDurationMs - elapsedMs);
3658
- this.scheduleAdStopCountdown(remainingMs);
3659
- if (this.config.debugAdTiming) {
3660
- console.log("[StormcloudVideoPlayer] Updated ad break duration from subsequent marker: ".concat(newDurationMs, "ms, remaining: ").concat(remainingMs, "ms"));
3661
- }
3662
- }
3663
- }
3664
- return;
3665
- }
3666
- this.inAdBreak = true;
3667
- 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;
3668
- this.expectedAdBreakDurationMs = durationMs;
3669
- this.currentAdBreakStartWallClockMs = Date.now();
3670
- if (this.config.licenseKey) {
3671
- var _this_pendingAdBreak1;
3672
- var adDetectInfo = _object_spread({
3673
- source: "scte35",
3674
- timestamp: /* @__PURE__ */ new Date().toISOString()
3675
- }, marker.durationSeconds != null && {
3676
- durationSeconds: marker.durationSeconds
3677
- }, marker.ptsSeconds != null && {
3678
- ptsSeconds: marker.ptsSeconds
3679
- }, ((_this_pendingAdBreak1 = this.pendingAdBreak) === null || _this_pendingAdBreak1 === void 0 ? void 0 : _this_pendingAdBreak1.detectedAtFragmentSn) != null && {
3680
- detectedAtFragmentSn: this.pendingAdBreak.detectedAtFragmentSn
3681
- });
3682
- sendAdDetectTracking(this.config.licenseKey, adDetectInfo);
3683
- }
3684
- var isManifestMarker = this.isManifestBasedMarker(marker);
3685
- var forceImmediate = (_this_config_immediateManifestAds = this.config.immediateManifestAds) !== null && _this_config_immediateManifestAds !== void 0 ? _this_config_immediateManifestAds : true;
3686
- if (this.config.debugAdTiming) {
3687
- console.log("[StormcloudVideoPlayer] Ad start decision:", {
3688
- isManifestMarker: isManifestMarker,
3689
- forceImmediate: forceImmediate,
3690
- hasPts: typeof marker.ptsSeconds === "number"
3691
- });
3692
- }
3693
- if (isManifestMarker && forceImmediate) {
3694
- if (this.config.debugAdTiming) {
3695
- console.log("[StormcloudVideoPlayer] Starting ad immediately (manifest-based)");
3696
- }
3697
- this.clearAdStartTimer();
3698
- this.handleAdStart(marker);
3699
- } else if (typeof marker.ptsSeconds === "number") {
3700
- var _this_config_driftToleranceMs;
3701
- var tol = (_this_config_driftToleranceMs = this.config.driftToleranceMs) !== null && _this_config_driftToleranceMs !== void 0 ? _this_config_driftToleranceMs : 1e3;
3702
- var nowMs = this.video.currentTime * 1e3;
3703
- var estCurrentPtsMs = nowMs - this.ptsDriftEmaMs;
3704
- var deltaMs = Math.floor(marker.ptsSeconds * 1e3 - estCurrentPtsMs);
3705
- if (this.config.debugAdTiming) {
3706
- console.log("[StormcloudVideoPlayer] PTS-based timing calculation:", {
3707
- nowMs: nowMs,
3708
- estCurrentPtsMs: estCurrentPtsMs,
3709
- markerPtsMs: marker.ptsSeconds * 1e3,
3710
- deltaMs: deltaMs,
3711
- tolerance: tol
3712
- });
3713
- }
3714
- if (deltaMs > tol) {
3715
- if (this.config.debugAdTiming) {
3716
- console.log("[StormcloudVideoPlayer] Scheduling ad start in ".concat(deltaMs, "ms"));
3717
- }
3718
- this.scheduleAdStartIn(deltaMs);
3719
- } else {
3720
- if (this.config.debugAdTiming) {
3721
- console.log("[StormcloudVideoPlayer] Starting ad immediately (within tolerance)");
3722
- }
3723
- this.clearAdStartTimer();
3724
- this.handleAdStart(marker);
3725
- }
3726
- } else {
3727
- if (this.config.debugAdTiming) {
3728
- console.log("[StormcloudVideoPlayer] Starting ad immediately (fallback)");
3729
- }
3730
- this.clearAdStartTimer();
3731
- this.handleAdStart(marker);
3732
- }
3733
- if (this.expectedAdBreakDurationMs != null) {
3734
- this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
3735
- }
3736
- return;
3737
- }
3738
- if (marker.type === "progress" && this.inAdBreak) {
3739
- if (marker.durationSeconds != null) {
3740
- this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;
3741
- }
3742
- if (this.expectedAdBreakDurationMs != null && this.currentAdBreakStartWallClockMs != null) {
3743
- var elapsedMs1 = Date.now() - this.currentAdBreakStartWallClockMs;
3744
- var remainingMs1 = Math.max(0, this.expectedAdBreakDurationMs - elapsedMs1);
3745
- this.scheduleAdStopCountdown(remainingMs1);
3746
- }
3747
- if (!this.adLayer.isAdPlaying() && this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0) {
3748
- var bids = this.pendingNextAdBids;
3749
- this.pendingNextAdBids = null;
3750
- this.currentAdIndex++;
3751
- this.adLayer.playAd(bids).catch(function() {
3752
- return _this.handleAdFailure();
3753
- });
3754
- }
3755
- return;
3756
- }
3757
- if (marker.type === "end") {
3758
- var remaining = this.getRemainingAdMs();
3759
- var adPlaying = this.adLayer.isAdPlaying();
3760
- var hasQueuedAds = this.pendingNextAdBids != null && this.pendingNextAdBids.length > 0;
3761
- if (this.config.debugAdTiming) {
3762
- console.log("[StormcloudVideoPlayer] SCTE-35 end marker received:", {
3763
- inAdBreak: this.inAdBreak,
3764
- remaining: remaining,
3765
- adPlaying: adPlaying,
3766
- hasQueuedAds: hasQueuedAds,
3767
- activeAdRequest: this.activeAdRequestToken !== null
3768
- });
3769
- }
3770
- if (!this.inAdBreak) {
3771
- if (this.config.debugAdTiming) {
3772
- console.log("[StormcloudVideoPlayer] Ignoring SCTE-35 end marker - not in ad break");
3773
- }
3774
- return;
3775
- }
3776
- if (adPlaying || remaining > 500) {
3777
- if (this.config.debugAdTiming) {
3778
- console.log("[StormcloudVideoPlayer] Ignoring premature SCTE-35 end marker - ads still active or time remaining");
3779
- }
3780
- return;
3781
- }
3782
- this.inAdBreak = false;
3783
- this.expectedAdBreakDurationMs = void 0;
3784
- this.currentAdBreakStartWallClockMs = void 0;
3785
- this.clearAdStartTimer();
3786
- this.clearAdStopTimer();
3787
- if (adPlaying) {
3788
- this.adLayer.stop().catch(function() {});
3789
- }
3790
- this.handleAdPodComplete();
3791
- return;
3792
- }
3793
- }
3794
- },
3795
- {
3796
- key: "parseCueOutDuration",
3797
- value: function parseCueOutDuration(value) {
3798
- var num = parseFloat(value.trim());
3799
- if (!Number.isNaN(num)) return num;
3800
- var match = value.match(/(?:^|[,\s])DURATION\s*=\s*([0-9.]+)/i) || value.match(/Duration\s*=\s*([0-9.]+)/i);
3801
- if (match && match[1] != null) {
3802
- var dStr = match[1];
3803
- var d = parseFloat(dStr);
3804
- return Number.isNaN(d) ? void 0 : d;
3805
- }
3806
- return void 0;
3807
- }
3808
- },
3809
- {
3810
- key: "parseCueOutCont",
3811
- value: function parseCueOutCont(value) {
3812
- var res = {};
3813
- var elapsedMatch = value.match(/Elapsed\s*=\s*([0-9.]+)/i);
3814
- var durationMatch = value.match(/Duration\s*=\s*([0-9.]+)/i);
3815
- if (elapsedMatch && elapsedMatch[1] != null) {
3816
- var e = parseFloat(elapsedMatch[1]);
3817
- if (!Number.isNaN(e)) res.elapsed = e;
3818
- }
3819
- if (durationMatch && durationMatch[1] != null) {
3820
- var d = parseFloat(durationMatch[1]);
3821
- if (!Number.isNaN(d)) res.duration = d;
3822
- }
3823
- if (!("elapsed" in res) || !("duration" in res)) {
3824
- var slashMatch = value.match(/([0-9.]+)\s*\/\s*([0-9.]+)/);
3825
- if (slashMatch && slashMatch[1] && slashMatch[2]) {
3826
- var elapsed = parseFloat(slashMatch[1]);
3827
- var duration = parseFloat(slashMatch[2]);
3828
- if (!Number.isNaN(elapsed) && !("elapsed" in res)) res.elapsed = elapsed;
3829
- if (!Number.isNaN(duration) && !("duration" in res)) res.duration = duration;
3830
- }
3831
- }
3832
- if ("elapsed" in res || "duration" in res) return res;
3833
- return void 0;
3834
- }
3835
- },
3836
- {
3837
- key: "parseAttributeList",
3838
- value: function parseAttributeList(value) {
3839
- var attrs = {};
3840
- var regex = /([A-Z0-9-]+)=(("[^"]*")|([^",]*))(?:,|$)/gi;
3841
- var match;
3842
- while((match = regex.exec(value)) !== null){
3843
- var _match_, _ref, _match_1;
3844
- var key = (_match_ = match[1]) !== null && _match_ !== void 0 ? _match_ : "";
3845
- var rawVal = (_ref = (_match_1 = match[3]) !== null && _match_1 !== void 0 ? _match_1 : match[4]) !== null && _ref !== void 0 ? _ref : "";
3846
- if (rawVal.startsWith('"') && rawVal.endsWith('"')) {
3847
- rawVal = rawVal.slice(1, -1);
3848
- }
3849
- if (key) {
3850
- attrs[key] = rawVal;
3851
- }
3852
- }
3853
- return attrs;
3854
- }
3855
- },
3856
- {
3857
- key: "toNumber",
3858
- value: function toNumber(val) {
3859
- if (val == null) return void 0;
3860
- var n = typeof val === "string" ? parseFloat(val) : Number(val);
3861
- return Number.isNaN(n) ? void 0 : n;
3862
- }
3863
- },
3864
- {
3865
- key: "isManifestBasedMarker",
3866
- value: function isManifestBasedMarker(marker) {
3867
- var raw = marker.raw;
3868
- if (!raw) return false;
3869
- if (raw.tag) {
3870
- var tag = String(raw.tag);
3871
- return tag.includes("EXT-X-CUE-OUT") || tag.includes("EXT-X-CUE-IN") || tag.includes("EXT-X-DATERANGE");
3872
- }
3873
- if (raw.id3) return false;
3874
- if (raw.splice_command_type) return false;
3875
- return false;
3876
- }
3877
- },
3878
- {
3879
- key: "parseScte35Binary",
3880
- value: function parseScte35Binary(data) {
3881
- var BitReader = /*#__PURE__*/ function() {
3882
- function BitReader(buf) {
3883
- _class_call_check(this, BitReader);
3884
- this.buf = buf;
3885
- this.bytePos = 0;
3886
- this.bitPos = 0;
3887
- }
3888
- _create_class(BitReader, [
3889
- {
3890
- key: "readBits",
3891
- value: function readBits(numBits) {
3892
- var result = 0;
3893
- while(numBits > 0){
3894
- if (this.bytePos >= this.buf.length) return result;
3895
- var remainingInByte = 8 - this.bitPos;
3896
- var toRead = Math.min(numBits, remainingInByte);
3897
- var currentByte = this.buf[this.bytePos];
3898
- var shift = remainingInByte - toRead;
3899
- var mask = (1 << toRead) - 1 & 255;
3900
- var bits = currentByte >> shift & mask;
3901
- result = result << toRead | bits;
3902
- this.bitPos += toRead;
3903
- if (this.bitPos >= 8) {
3904
- this.bitPos = 0;
3905
- this.bytePos += 1;
3906
- }
3907
- numBits -= toRead;
3908
- }
3909
- return result >>> 0;
3910
- }
3911
- },
3912
- {
3913
- key: "skipBits",
3914
- value: function skipBits(n) {
3915
- this.readBits(n);
3916
- }
3917
- }
3918
- ]);
3919
- return BitReader;
3920
- }();
3921
- var r = new BitReader(data);
3922
- var tableId = r.readBits(8);
3923
- if (tableId !== 252) return void 0;
3924
- r.readBits(1);
3925
- r.readBits(1);
3926
- r.readBits(2);
3927
- var sectionLength = r.readBits(12);
3928
- r.readBits(8);
3929
- r.readBits(1);
3930
- r.readBits(6);
3931
- var ptsAdjHigh = r.readBits(1);
3932
- var ptsAdjLow = r.readBits(32);
3933
- void ptsAdjHigh;
3934
- void ptsAdjLow;
3935
- r.readBits(8);
3936
- r.readBits(12);
3937
- var spliceCommandLength = r.readBits(12);
3938
- var spliceCommandType = r.readBits(8);
3939
- if (spliceCommandType !== 5) {
3940
- return void 0;
3941
- }
3942
- r.readBits(32);
3943
- var cancel = r.readBits(1) === 1;
3944
- r.readBits(7);
3945
- if (cancel) return void 0;
3946
- var outOfNetwork = r.readBits(1) === 1;
3947
- var programSpliceFlag = r.readBits(1) === 1;
3948
- var durationFlag = r.readBits(1) === 1;
3949
- var spliceImmediateFlag = r.readBits(1) === 1;
3950
- r.readBits(4);
3951
- if (programSpliceFlag && !spliceImmediateFlag) {
3952
- var timeSpecifiedFlag = r.readBits(1) === 1;
3953
- if (timeSpecifiedFlag) {
3954
- r.readBits(6);
3955
- r.readBits(33);
3956
- } else {
3957
- r.readBits(7);
3958
- }
3959
- } else if (!programSpliceFlag) {
3960
- var componentCount = r.readBits(8);
3961
- for(var i = 0; i < componentCount; i++){
3962
- r.readBits(8);
3963
- if (!spliceImmediateFlag) {
3964
- var timeSpecifiedFlag1 = r.readBits(1) === 1;
3965
- if (timeSpecifiedFlag1) {
3966
- r.readBits(6);
3967
- r.readBits(33);
3968
- } else {
3969
- r.readBits(7);
3970
- }
3971
- }
3972
- }
3973
- }
3974
- var durationSeconds = void 0;
3975
- if (durationFlag) {
3976
- r.readBits(6);
3977
- r.readBits(1);
3978
- var high = r.readBits(1);
3979
- var low = r.readBits(32);
3980
- var durationTicks = high * 4294967296 + low;
3981
- durationSeconds = durationTicks / 9e4;
3982
- }
3983
- r.readBits(16);
3984
- r.readBits(8);
3985
- r.readBits(8);
3986
- if (outOfNetwork) {
3987
- var marker = _object_spread_props(_object_spread({
3988
- type: "start"
3989
- }, durationSeconds !== void 0 ? {
3990
- durationSeconds: durationSeconds
3991
- } : {}), {
3992
- raw: {
3993
- splice_command_type: 5
3994
- }
3995
- });
3996
- return marker;
3997
- }
3998
- return void 0;
3999
- }
4000
- },
4001
3443
  {
4002
3444
  key: "initializeTracking",
4003
3445
  value: function initializeTracking() {
@@ -4119,35 +3561,35 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4119
3561
  },
4120
3562
  {
4121
3563
  key: "startAdPrefetch",
4122
- value: function startAdPrefetch(marker, fragmentSn) {
3564
+ value: function startAdPrefetch(durationSeconds, fragmentSn) {
4123
3565
  if (this.config.disableAds) return;
4124
3566
  if (this.pendingAdBreak || this.inAdBreak) {
4125
3567
  return;
4126
3568
  }
4127
- this.pendingAdBreak = _object_spread_props(_object_spread({
4128
- marker: marker
4129
- }, fragmentSn !== void 0 ? {
3569
+ this.pendingAdBreak = _object_spread_props(_object_spread({}, durationSeconds !== void 0 ? {
3570
+ durationSeconds: durationSeconds
3571
+ } : {}, fragmentSn !== void 0 ? {
4130
3572
  detectedAtFragmentSn: fragmentSn
4131
3573
  } : {}), {
4132
3574
  isFetching: false,
4133
3575
  fetchStartTime: Date.now()
4134
3576
  });
4135
- void this.runAdPrefetch(marker);
3577
+ void this.runAdPrefetch(durationSeconds);
4136
3578
  if (this.config.debugAdTiming) {
4137
- console.log("[PREFETCH] Ad break marker registered, multi-ad prefetch started");
3579
+ console.log("[PREFETCH] Ad break registered, multi-ad prefetch started");
4138
3580
  }
4139
3581
  }
4140
3582
  },
4141
3583
  {
4142
3584
  key: "runAdPrefetch",
4143
- value: function runAdPrefetch(marker) {
3585
+ value: function runAdPrefetch(durationSeconds) {
4144
3586
  return _async_to_generator(function() {
4145
- var _this, _marker_durationSeconds, _ref, _firstBids_, durSec, context, firstBids, unused, adDurationSec, estimatedCount, firstToken, remaining, results, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, result, token;
3587
+ var _this, _ref, _firstBids_, durSec, context, firstBids, unused, adDurationSec, estimatedCount, firstToken, unused1, remaining, results, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, result, token, unused2, err;
4146
3588
  return _ts_generator(this, function(_state) {
4147
3589
  switch(_state.label){
4148
3590
  case 0:
4149
3591
  _this = this;
4150
- durSec = (_marker_durationSeconds = marker.durationSeconds) !== null && _marker_durationSeconds !== void 0 ? _marker_durationSeconds : 60;
3592
+ durSec = durationSeconds !== null && durationSeconds !== void 0 ? durationSeconds : 60;
4151
3593
  context = {
4152
3594
  breakDurationSec: durSec,
4153
3595
  remainingBreakSec: durSec
@@ -4187,6 +3629,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4187
3629
  if (this.config.debugAdTiming) {
4188
3630
  console.log("[PREFETCH] First VAST request returned no ad, aborting prefetch");
4189
3631
  }
3632
+ this.clearPendingAdBreak();
4190
3633
  return [
4191
3634
  2
4192
3635
  ];
@@ -4197,14 +3640,43 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4197
3640
  console.log("[PREFETCH] Ad duration=".concat(adDurationSec, "s, break=").concat(durSec, "s → ").concat(estimatedCount, " ad(s) needed"));
4198
3641
  }
4199
3642
  firstToken = "preload_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 7));
4200
- this.preloadedTokens.push(firstToken);
4201
- void this.adLayer.preloadAd(firstBids, firstToken);
3643
+ _state.label = 5;
3644
+ case 5:
3645
+ _state.trys.push([
3646
+ 5,
3647
+ 7,
3648
+ ,
3649
+ 8
3650
+ ]);
3651
+ return [
3652
+ 4,
3653
+ this.adLayer.preloadAd(firstBids, firstToken)
3654
+ ];
3655
+ case 6:
3656
+ _state.sent();
3657
+ if (!this.inAdBreak) {
3658
+ this.preloadedTokens.push(firstToken);
3659
+ if (this.config.debugAdTiming) {
3660
+ console.log("[PREFETCH] First ad preloaded and queued, token=".concat(firstToken));
3661
+ }
3662
+ }
3663
+ return [
3664
+ 3,
3665
+ 8
3666
+ ];
3667
+ case 7:
3668
+ unused1 = _state.sent();
4202
3669
  if (this.config.debugAdTiming) {
4203
- console.log("[PREFETCH] First ad preloading, token=".concat(firstToken));
3670
+ console.warn("[PREFETCH] First ad preload failed, token=".concat(firstToken));
4204
3671
  }
3672
+ return [
3673
+ 3,
3674
+ 8
3675
+ ];
3676
+ case 8:
4205
3677
  if (!(estimatedCount > 1)) return [
4206
3678
  3,
4207
- 6
3679
+ 19
4208
3680
  ];
4209
3681
  remaining = Array.from({
4210
3682
  length: estimatedCount - 1
@@ -4226,38 +3698,100 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4226
3698
  4,
4227
3699
  Promise.all(remaining)
4228
3700
  ];
4229
- case 5:
3701
+ case 9:
4230
3702
  results = _state.sent();
4231
3703
  _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
3704
+ _state.label = 10;
3705
+ case 10:
3706
+ _state.trys.push([
3707
+ 10,
3708
+ 17,
3709
+ 18,
3710
+ 19
3711
+ ]);
3712
+ _iterator = results[Symbol.iterator]();
3713
+ _state.label = 11;
3714
+ case 11:
3715
+ if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
3716
+ 3,
3717
+ 16
3718
+ ];
3719
+ result = _step.value;
3720
+ if (this.inAdBreak) return [
3721
+ 3,
3722
+ 16
3723
+ ];
3724
+ if (!(result.ok && result.value.length > 0)) return [
3725
+ 3,
3726
+ 15
3727
+ ];
3728
+ token = "preload_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 7));
3729
+ _state.label = 12;
3730
+ case 12:
3731
+ _state.trys.push([
3732
+ 12,
3733
+ 14,
3734
+ ,
3735
+ 15
3736
+ ]);
3737
+ return [
3738
+ 4,
3739
+ this.adLayer.preloadAd(result.value, token)
3740
+ ];
3741
+ case 13:
3742
+ _state.sent();
3743
+ if (!this.inAdBreak) {
3744
+ this.preloadedTokens.push(token);
3745
+ if (this.config.debugAdTiming) {
3746
+ console.log("[PREFETCH] Additional ad preloaded and queued, token=".concat(token));
3747
+ }
3748
+ }
3749
+ return [
3750
+ 3,
3751
+ 15
3752
+ ];
3753
+ case 14:
3754
+ unused2 = _state.sent();
3755
+ if (this.config.debugAdTiming) {
3756
+ console.warn("[PREFETCH] Additional ad preload failed, token=".concat(token));
3757
+ }
3758
+ return [
3759
+ 3,
3760
+ 15
3761
+ ];
3762
+ case 15:
3763
+ _iteratorNormalCompletion = true;
3764
+ return [
3765
+ 3,
3766
+ 11
3767
+ ];
3768
+ case 16:
3769
+ return [
3770
+ 3,
3771
+ 19
3772
+ ];
3773
+ case 17:
3774
+ err = _state.sent();
3775
+ _didIteratorError = true;
3776
+ _iteratorError = err;
3777
+ return [
3778
+ 3,
3779
+ 19
3780
+ ];
3781
+ case 18:
4232
3782
  try {
4233
- for(_iterator = results[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
4234
- result = _step.value;
4235
- if (this.inAdBreak) break;
4236
- if (result.ok && result.value.length > 0) {
4237
- token = "preload_".concat(Date.now(), "_").concat(Math.random().toString(36).slice(2, 7));
4238
- this.preloadedTokens.push(token);
4239
- void this.adLayer.preloadAd(result.value, token);
4240
- if (this.config.debugAdTiming) {
4241
- console.log("[PREFETCH] Additional ad preloading, token=".concat(token));
4242
- }
4243
- }
3783
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
3784
+ _iterator.return();
4244
3785
  }
4245
- } catch (err) {
4246
- _didIteratorError = true;
4247
- _iteratorError = err;
4248
3786
  } finally{
4249
- try {
4250
- if (!_iteratorNormalCompletion && _iterator.return != null) {
4251
- _iterator.return();
4252
- }
4253
- } finally{
4254
- if (_didIteratorError) {
4255
- throw _iteratorError;
4256
- }
3787
+ if (_didIteratorError) {
3788
+ throw _iteratorError;
4257
3789
  }
4258
3790
  }
4259
- _state.label = 6;
4260
- case 6:
3791
+ return [
3792
+ 7
3793
+ ];
3794
+ case 19:
4261
3795
  if (this.config.debugAdTiming) {
4262
3796
  console.log("[PREFETCH] Pre-fetch complete: ".concat(this.preloadedTokens.length, " ad(s) queued"));
4263
3797
  }
@@ -4329,7 +3863,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4329
3863
  key: "fetchAdInsertionPoint",
4330
3864
  value: function fetchAdInsertionPoint() {
4331
3865
  return _async_to_generator(function() {
4332
- var _this_lastAdInsertionPoint, resp, data, isNew, unused;
3866
+ var _this_lastAdInsertionPoint, _this_lastAdInsertionPoint1, resp, data, prevSegment, isNew, segmentChanged, unused;
4333
3867
  return _ts_generator(this, function(_state) {
4334
3868
  switch(_state.label){
4335
3869
  case 0:
@@ -4359,7 +3893,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4359
3893
  ];
4360
3894
  case 3:
4361
3895
  data = _state.sent();
4362
- isNew = data.updated_at !== ((_this_lastAdInsertionPoint = this.lastAdInsertionPoint) === null || _this_lastAdInsertionPoint === void 0 ? void 0 : _this_lastAdInsertionPoint.updated_at);
3896
+ prevSegment = (_this_lastAdInsertionPoint = this.lastAdInsertionPoint) === null || _this_lastAdInsertionPoint === void 0 ? void 0 : _this_lastAdInsertionPoint.segment_ts_name;
3897
+ isNew = data.updated_at !== ((_this_lastAdInsertionPoint1 = this.lastAdInsertionPoint) === null || _this_lastAdInsertionPoint1 === void 0 ? void 0 : _this_lastAdInsertionPoint1.updated_at);
3898
+ segmentChanged = prevSegment !== data.segment_ts_name;
4363
3899
  this.lastAdInsertionPoint = data;
4364
3900
  if (isNew) {
4365
3901
  this.pushAdInsertionDebug("api_response", data.segment_ts_name, {
@@ -4367,6 +3903,15 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4367
3903
  updatedAt: data.updated_at,
4368
3904
  detail: "project=".concat(data.project_id)
4369
3905
  });
3906
+ if (segmentChanged && (this.pendingAdBreak || this.adInsertionOffsetTimerId != null)) {
3907
+ this.clearAdInsertionOffsetTimer();
3908
+ this.clearPendingAdBreak();
3909
+ this.cancelAndClearPreloadedTokens();
3910
+ if (this.config.debugAdTiming) {
3911
+ console.log("[StormcloudVideoPlayer] Insertion segment changed (".concat(prevSegment, " → ").concat(data.segment_ts_name, "), stale pending state cleared"));
3912
+ }
3913
+ }
3914
+ this.checkAdInsertionInManifest();
4370
3915
  }
4371
3916
  if (this.config.debugAdTiming) {
4372
3917
  console.log("[StormcloudVideoPlayer] Ad insertion point API response:", data);
@@ -4396,6 +3941,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4396
3941
  {
4397
3942
  key: "checkAdInsertionInManifest",
4398
3943
  value: function checkAdInsertionInManifest() {
3944
+ var _this = this;
4399
3945
  var _this_hls;
4400
3946
  if (!this.lastAdInsertionPoint) return;
4401
3947
  if (this.inAdBreak || this.pendingAdBreak) return;
@@ -4415,22 +3961,42 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4415
3961
  for(var _iterator1 = fragments[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
4416
3962
  var frag = _step1.value;
4417
3963
  if (this.fragmentMatchesSegment(frag, segmentName)) {
4418
- var _ref;
3964
+ var _frag_start, _frag_duration, _ref;
3965
+ var currentTime = this.video.currentTime;
3966
+ var fragStart = (_frag_start = frag.start) !== null && _frag_start !== void 0 ? _frag_start : 0;
3967
+ var fragDuration = (_frag_duration = frag.duration) !== null && _frag_duration !== void 0 ? _frag_duration : 0;
3968
+ var isCurrentlyPlaying = fragDuration > 0 && currentTime >= fragStart && currentTime < fragStart + fragDuration;
4419
3969
  this.pushAdInsertionDebug("segment_found", segmentName, {
4420
- detail: "sn=".concat((_ref = frag === null || frag === void 0 ? void 0 : frag.sn) !== null && _ref !== void 0 ? _ref : "?")
3970
+ detail: "sn=".concat((_ref = frag === null || frag === void 0 ? void 0 : frag.sn) !== null && _ref !== void 0 ? _ref : "?", " ").concat(isCurrentlyPlaying ? "(playing)" : "(future)")
4421
3971
  });
4422
3972
  if (this.config.debugAdTiming) {
4423
- console.log('[StormcloudVideoPlayer] Ad insertion segment "'.concat(segmentName, '" found in manifest — starting pre-fetch'));
3973
+ console.log('[StormcloudVideoPlayer] Ad insertion segment "'.concat(segmentName, '" found in manifest — ') + (isCurrentlyPlaying ? "currently playing, scheduling directly" : "starting pre-fetch"));
3974
+ }
3975
+ this.startAdPrefetch(60, frag === null || frag === void 0 ? void 0 : frag.sn);
3976
+ if (isCurrentlyPlaying && !this.inAdBreak) {
3977
+ var _this_lastAdInsertionPoint_offset_seconds, _ref1;
3978
+ this.processedAdInsertionUpdatedAt = this.lastAdInsertionPoint.updated_at;
3979
+ var rawOffsetMs = ((_this_lastAdInsertionPoint_offset_seconds = this.lastAdInsertionPoint.offset_seconds) !== null && _this_lastAdInsertionPoint_offset_seconds !== void 0 ? _this_lastAdInsertionPoint_offset_seconds : 0) * 1e3;
3980
+ var elapsedInFragMs = (currentTime - fragStart) * 1e3;
3981
+ var remainingOffsetMs = Math.max(0, rawOffsetMs - elapsedInFragMs);
3982
+ this.pushAdInsertionDebug("segment_playing", segmentName, {
3983
+ offsetSeconds: this.lastAdInsertionPoint.offset_seconds,
3984
+ detail: "sn=".concat((_ref1 = frag === null || frag === void 0 ? void 0 : frag.sn) !== null && _ref1 !== void 0 ? _ref1 : "?", " (caught in manifest check)")
3985
+ });
3986
+ this.pushAdInsertionDebug("ad_scheduled", segmentName, {
3987
+ offsetSeconds: this.lastAdInsertionPoint.offset_seconds,
3988
+ detail: "in ".concat(remainingOffsetMs, "ms (adjusted for elapsed ").concat(Math.round(elapsedInFragMs), "ms)")
3989
+ });
3990
+ this.clearAdInsertionOffsetTimer();
3991
+ this.adInsertionOffsetTimerId = window.setTimeout(function() {
3992
+ _this.adInsertionOffsetTimerId = void 0;
3993
+ if (_this.inAdBreak) return;
3994
+ _this.pushAdInsertionDebug("ad_triggered", segmentName, {
3995
+ detail: "ad break started (60s, via manifest-check path)"
3996
+ });
3997
+ void _this.handleAdStart(60);
3998
+ }, remainingOffsetMs);
4424
3999
  }
4425
- var marker = {
4426
- type: "start",
4427
- durationSeconds: 60,
4428
- raw: {
4429
- apiInsertionPoint: this.lastAdInsertionPoint,
4430
- earlyDetection: true
4431
- }
4432
- };
4433
- this.startAdPrefetch(marker, frag === null || frag === void 0 ? void 0 : frag.sn);
4434
4000
  return;
4435
4001
  }
4436
4002
  }
@@ -4468,8 +4034,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4468
4034
  {
4469
4035
  key: "fragmentMatchesSegment",
4470
4036
  value: function fragmentMatchesSegment(frag, segmentName) {
4471
- var url = (frag === null || frag === void 0 ? void 0 : frag.url) || (frag === null || frag === void 0 ? void 0 : frag.relurl) || "";
4472
- return url.endsWith(segmentName) || url.includes("/" + segmentName);
4037
+ var _rawUrl_split_;
4038
+ var rawUrl = (frag === null || frag === void 0 ? void 0 : frag.url) || (frag === null || frag === void 0 ? void 0 : frag.relurl) || "";
4039
+ var url = (_rawUrl_split_ = rawUrl.split("?")[0]) !== null && _rawUrl_split_ !== void 0 ? _rawUrl_split_ : "";
4040
+ var name = segmentName.startsWith("/") ? segmentName : "/" + segmentName;
4041
+ return url.endsWith(name) || url.includes(name);
4473
4042
  }
4474
4043
  },
4475
4044
  {
@@ -4806,13 +4375,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4806
4375
  },
4807
4376
  {
4808
4377
  key: "handleAdStart",
4809
- value: function handleAdStart(_marker) {
4378
+ value: function handleAdStart(durationSeconds) {
4810
4379
  return _async_to_generator(function() {
4811
- var _this_savedMutedStateBeforeScte, adBreakDurationMs, mode, state, adBreakToken, adVolume, token, remaining, err;
4380
+ var _this_savedMutedStateBeforeAd, adBreakDurationMs, mode, state, adBreakToken, adVolume, token, remaining, err;
4812
4381
  return _ts_generator(this, function(_state) {
4813
4382
  switch(_state.label){
4814
4383
  case 0:
4815
- adBreakDurationMs = _marker.durationSeconds != null ? _marker.durationSeconds * 1e3 : void 0;
4384
+ adBreakDurationMs = durationSeconds != null ? durationSeconds * 1e3 : void 0;
4816
4385
  if (this.config.debugAdTiming) {
4817
4386
  mode = this.isLiveStream ? "LIVE" : "VOD";
4818
4387
  console.log("[CONTINUOUS-FETCH] \uD83D\uDCFA ".concat(mode, " MODE: Target duration=").concat(adBreakDurationMs, "ms"));
@@ -4823,13 +4392,13 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4823
4392
  this.pendingNextAdBids = null;
4824
4393
  this.isShowingPlaceholder = false;
4825
4394
  this.totalAdRequestsInBreak = 0;
4826
- if (this.savedMutedStateBeforeScte == null && !this.video.muted) {
4827
- this.savedMutedStateBeforeScte = {
4395
+ if (this.savedMutedStateBeforeAd == null && !this.video.muted) {
4396
+ this.savedMutedStateBeforeAd = {
4828
4397
  muted: false,
4829
4398
  volume: this.video.volume
4830
4399
  };
4831
4400
  }
4832
- state = (_this_savedMutedStateBeforeScte = this.savedMutedStateBeforeScte) !== null && _this_savedMutedStateBeforeScte !== void 0 ? _this_savedMutedStateBeforeScte : {
4401
+ state = (_this_savedMutedStateBeforeAd = this.savedMutedStateBeforeAd) !== null && _this_savedMutedStateBeforeAd !== void 0 ? _this_savedMutedStateBeforeAd : {
4833
4402
  muted: this.video.muted,
4834
4403
  volume: this.video.volume
4835
4404
  };
@@ -4856,6 +4425,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
4856
4425
  if (this.expectedAdBreakDurationMs == null && adBreakDurationMs != null) {
4857
4426
  this.expectedAdBreakDurationMs = adBreakDurationMs;
4858
4427
  }
4428
+ if (this.expectedAdBreakDurationMs != null) {
4429
+ this.scheduleAdStopCountdown(this.expectedAdBreakDurationMs);
4430
+ }
4859
4431
  this.clearPendingAdBreak();
4860
4432
  adBreakToken = Date.now();
4861
4433
  this.activeAdRequestToken = adBreakToken;
@@ -5354,49 +4926,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5354
4926
  this.handleAdPodComplete();
5355
4927
  }
5356
4928
  },
5357
- {
5358
- key: "scheduleAdStartIn",
5359
- value: function scheduleAdStartIn(delayMs) {
5360
- var _this = this;
5361
- this.clearAdStartTimer();
5362
- var ms = Math.max(0, Math.floor(delayMs));
5363
- if (ms === 0) {
5364
- this.handleAdStart({
5365
- type: "start"
5366
- }).catch(function() {});
5367
- return;
5368
- }
5369
- this.adStartTimerId = window.setTimeout(function() {
5370
- _this.handleAdStart({
5371
- type: "start"
5372
- }).catch(function() {});
5373
- }, ms);
5374
- }
5375
- },
5376
- {
5377
- key: "clearAdStartTimer",
5378
- value: function clearAdStartTimer() {
5379
- if (this.adStartTimerId != null) {
5380
- clearTimeout(this.adStartTimerId);
5381
- this.adStartTimerId = void 0;
5382
- }
5383
- }
5384
- },
5385
- {
5386
- key: "updatePtsDrift",
5387
- value: function updatePtsDrift(ptsSecondsSample) {
5388
- var sampleMs = (this.video.currentTime - ptsSecondsSample) * 1e3;
5389
- if (!Number.isFinite(sampleMs) || Math.abs(sampleMs) > 6e4) return;
5390
- var alpha = 0.1;
5391
- this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;
5392
- }
5393
- },
5394
4929
  {
5395
4930
  key: "handleAdPodComplete",
5396
4931
  value: function handleAdPodComplete() {
5397
4932
  var _this = this;
5398
4933
  var _ref, _ref1;
5399
- var _this_savedMutedStateBeforeScte, _this_savedMutedStateBeforeScte1;
4934
+ var _this_savedMutedStateBeforeAd, _this_savedMutedStateBeforeAd1;
5400
4935
  if (this.config.debugAdTiming) {
5401
4936
  console.log("[StormcloudVideoPlayer] \uD83C\uDFC1 Ad pod complete - cleaning up");
5402
4937
  }
@@ -5418,7 +4953,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5418
4953
  this.inAdBreak = false;
5419
4954
  this.expectedAdBreakDurationMs = void 0;
5420
4955
  this.currentAdBreakStartWallClockMs = void 0;
5421
- this.clearAdStartTimer();
5422
4956
  this.clearAdStopTimer();
5423
4957
  this.adPodQueue = [];
5424
4958
  this.showAds = false;
@@ -5426,8 +4960,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5426
4960
  this.totalAdsInBreak = 0;
5427
4961
  this.totalAdRequestsInBreak = 0;
5428
4962
  this.consecutiveFailures = 0;
5429
- var restoredMuted = (_ref = (_this_savedMutedStateBeforeScte = this.savedMutedStateBeforeScte) === null || _this_savedMutedStateBeforeScte === void 0 ? void 0 : _this_savedMutedStateBeforeScte.muted) !== null && _ref !== void 0 ? _ref : this.adLayer.getOriginalMutedState();
5430
- var restoredVolume = (_ref1 = (_this_savedMutedStateBeforeScte1 = this.savedMutedStateBeforeScte) === null || _this_savedMutedStateBeforeScte1 === void 0 ? void 0 : _this_savedMutedStateBeforeScte1.volume) !== null && _ref1 !== void 0 ? _ref1 : this.adLayer.getOriginalVolume();
4963
+ var restoredMuted = (_ref = (_this_savedMutedStateBeforeAd = this.savedMutedStateBeforeAd) === null || _this_savedMutedStateBeforeAd === void 0 ? void 0 : _this_savedMutedStateBeforeAd.muted) !== null && _ref !== void 0 ? _ref : this.adLayer.getOriginalMutedState();
4964
+ var restoredVolume = (_ref1 = (_this_savedMutedStateBeforeAd1 = this.savedMutedStateBeforeAd) === null || _this_savedMutedStateBeforeAd1 === void 0 ? void 0 : _this_savedMutedStateBeforeAd1.volume) !== null && _ref1 !== void 0 ? _ref1 : this.adLayer.getOriginalVolume();
5431
4965
  this.adLayer.updateOriginalMutedState(restoredMuted, restoredVolume);
5432
4966
  this.adLayer.stop().catch(function() {});
5433
4967
  if (this.video.muted !== restoredMuted) {
@@ -5536,7 +5070,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5536
5070
  }, delay);
5537
5071
  });
5538
5072
  }
5539
- this.savedMutedStateBeforeScte = null;
5073
+ this.savedMutedStateBeforeAd = null;
5540
5074
  }
5541
5075
  },
5542
5076
  {
@@ -5686,19 +5220,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5686
5220
  return Math.max(0, this.expectedAdBreakDurationMs - elapsed);
5687
5221
  }
5688
5222
  },
5689
- {
5690
- key: "pushScteMarker",
5691
- value: function pushScteMarker(marker) {
5692
- if (!this.config.debugAdTiming) return;
5693
- this.scteMarkerHistory.push({
5694
- timestampMs: Date.now(),
5695
- marker: marker
5696
- });
5697
- if (this.scteMarkerHistory.length > DEBUG_HISTORY_LIMIT) {
5698
- this.scteMarkerHistory = this.scteMarkerHistory.slice(-DEBUG_HISTORY_LIMIT);
5699
- }
5700
- }
5701
- },
5702
5223
  {
5703
5224
  key: "pushDebugLog",
5704
5225
  value: function pushDebugLog(level, category, message, details) {
@@ -5716,23 +5237,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
5716
5237
  }
5717
5238
  }
5718
5239
  },
5719
- {
5720
- key: "getRecentScteMarkers",
5721
- value: function getRecentScteMarkers() {
5722
- return this.scteMarkerHistory.map(function(entry) {
5723
- return _object_spread({
5724
- timestampMs: entry.timestampMs,
5725
- type: entry.marker.type
5726
- }, entry.marker.ptsSeconds !== void 0 ? {
5727
- ptsSeconds: entry.marker.ptsSeconds
5728
- } : {}, entry.marker.durationSeconds !== void 0 ? {
5729
- durationSeconds: entry.marker.durationSeconds
5730
- } : {}, entry.marker.raw !== void 0 ? {
5731
- raw: entry.marker.raw
5732
- } : {});
5733
- });
5734
- }
5735
- },
5736
5240
  {
5737
5241
  key: "pushAdInsertionDebug",
5738
5242
  value: function pushAdInsertionDebug(event, segmentName, opts) {
@@ -6029,7 +5533,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6029
5533
  this.clearAdInsertionOffsetTimer();
6030
5534
  this.stopContinuousFetching();
6031
5535
  this.stopFillerBreakTimer();
6032
- this.clearAdStartTimer();
6033
5536
  this.clearAdStopTimer();
6034
5537
  this.clearAdFailsafeTimer();
6035
5538
  this.clearAdRequestWatchdog();
@@ -6057,7 +5560,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
6057
5560
  (_this_adLayer = this.adLayer) === null || _this_adLayer === void 0 ? void 0 : _this_adLayer.destroy();
6058
5561
  this.consecutiveFailures = 0;
6059
5562
  this.debugLogEntries = [];
6060
- this.scteMarkerHistory = [];
6061
5563
  this.adInsertionDebugHistory = [];
6062
5564
  }
6063
5565
  }
@@ -7534,6 +7036,11 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7534
7036
  label: "API",
7535
7037
  color: "#60a5fa"
7536
7038
  };
7039
+ case "scte35_inserted":
7040
+ return {
7041
+ label: "SCTE-35",
7042
+ color: "#f43f5e"
7043
+ };
7537
7044
  case "segment_found":
7538
7045
  return {
7539
7046
  label: "FOUND",
@@ -7704,6 +7211,7 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
7704
7211
  if (minSegmentsBeforePlay !== void 0) cfg.minSegmentsBeforePlay = minSegmentsBeforePlay;
7705
7212
  if (disableAds !== void 0) cfg.disableAds = disableAds;
7706
7213
  cfg.disableFiller = disableFiller !== null && disableFiller !== void 0 ? disableFiller : true;
7214
+ if (swirlProjectId !== void 0) cfg.projectId = String(swirlProjectId);
7707
7215
  var player = new StormcloudVideoPlayer(cfg);
7708
7216
  playerRef.current = player;
7709
7217
  player.load().then(function() {
@@ -8577,9 +8085,13 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8577
8085
  overflowX: "hidden",
8578
8086
  height: "calc(100% - 46px)",
8579
8087
  display: "grid",
8580
- gap: "12px"
8088
+ gap: "12px",
8089
+ minWidth: 0
8581
8090
  },
8582
8091
  children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
8092
+ style: {
8093
+ minWidth: 0
8094
+ },
8583
8095
  children: [
8584
8096
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {
8585
8097
  style: {
@@ -8595,7 +8107,8 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8595
8107
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {
8596
8108
  style: {
8597
8109
  display: "grid",
8598
- gap: "6px"
8110
+ gap: "6px",
8111
+ minWidth: 0
8599
8112
  },
8600
8113
  children: debugMarkers.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", {
8601
8114
  style: {
@@ -8605,53 +8118,129 @@ var StormcloudVideoPlayerComponent = import_react2.default.memo(function(props)
8605
8118
  children: "No ad insertion events yet."
8606
8119
  }) : debugMarkers.map(function(entry, idx) {
8607
8120
  var evt = formatAdInsertionEvent(entry.event);
8121
+ var fileName = entry.segmentName ? entry.segmentName.split("/").pop() || entry.segmentName : "";
8608
8122
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
8609
8123
  style: {
8610
- display: "grid",
8611
- gridTemplateColumns: "56px 54px 1fr",
8612
- gap: "8px",
8613
- alignItems: "center",
8124
+ minWidth: 0,
8614
8125
  fontFamily: "'SF Mono', 'Cascadia Code', monospace",
8615
8126
  fontSize: "11px",
8616
8127
  background: "rgba(255,255,255,0.05)",
8617
8128
  border: "1px solid rgba(255,255,255,0.08)",
8618
8129
  borderRadius: "8px",
8619
- padding: "6px 8px"
8130
+ padding: "6px 8px",
8131
+ display: "flex",
8132
+ flexDirection: "column",
8133
+ gap: "4px"
8620
8134
  },
8621
8135
  children: [
8622
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {
8136
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
8623
8137
  style: {
8624
- color: "rgba(255,255,255,0.68)"
8138
+ display: "grid",
8139
+ gridTemplateColumns: "56px 54px minmax(0, 1fr) 20px",
8140
+ gap: "6px",
8141
+ alignItems: "center",
8142
+ minWidth: 0
8625
8143
  },
8626
- children: formatDebugClock(entry.timestampMs)
8144
+ children: [
8145
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {
8146
+ style: {
8147
+ color: "rgba(255,255,255,0.68)"
8148
+ },
8149
+ children: formatDebugClock(entry.timestampMs)
8150
+ }),
8151
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {
8152
+ style: {
8153
+ fontWeight: 700,
8154
+ color: evt.color,
8155
+ fontSize: "10px"
8156
+ },
8157
+ children: evt.label
8158
+ }),
8159
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {
8160
+ style: {
8161
+ color: "rgba(255,255,255,0.88)",
8162
+ overflow: "hidden",
8163
+ textOverflow: "ellipsis",
8164
+ whiteSpace: "nowrap",
8165
+ minWidth: 0
8166
+ },
8167
+ title: entry.segmentName,
8168
+ children: fileName
8169
+ }),
8170
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", {
8171
+ onClick: function onClick() {
8172
+ return navigator.clipboard.writeText(entry.segmentName);
8173
+ },
8174
+ title: entry.segmentName,
8175
+ style: {
8176
+ background: "none",
8177
+ border: "none",
8178
+ cursor: "pointer",
8179
+ padding: "2px",
8180
+ color: "rgba(255,255,255,0.45)",
8181
+ display: "flex",
8182
+ alignItems: "center",
8183
+ justifyContent: "center",
8184
+ borderRadius: "4px",
8185
+ flexShrink: 0
8186
+ },
8187
+ onMouseEnter: function onMouseEnter(e) {
8188
+ return e.currentTarget.style.color = "rgba(255,255,255,0.9)";
8189
+ },
8190
+ onMouseLeave: function onMouseLeave(e) {
8191
+ return e.currentTarget.style.color = "rgba(255,255,255,0.45)";
8192
+ },
8193
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_fa.FaCopy, {
8194
+ size: 10
8195
+ })
8196
+ })
8197
+ ]
8627
8198
  }),
8628
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {
8199
+ (entry.offsetSeconds != null || entry.detail || entry.updatedAt) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", {
8629
8200
  style: {
8630
- fontWeight: 700,
8631
- color: evt.color,
8201
+ display: "flex",
8202
+ flexWrap: "wrap",
8203
+ gap: "6px",
8204
+ paddingLeft: "0px",
8632
8205
  fontSize: "10px"
8633
8206
  },
8634
- children: evt.label
8635
- }),
8636
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {
8637
- style: {
8638
- color: "rgba(255,255,255,0.88)"
8639
- },
8640
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", {
8641
- style: {
8642
- display: "inline-block",
8643
- maxWidth: "100%",
8644
- verticalAlign: "bottom",
8645
- overflow: "hidden",
8646
- textOverflow: "ellipsis",
8647
- whiteSpace: "nowrap"
8648
- },
8649
- children: [
8650
- entry.segmentName,
8651
- entry.offsetSeconds != null ? " +".concat(entry.offsetSeconds, "s") : "",
8652
- entry.detail ? " (".concat(entry.detail, ")") : ""
8653
- ]
8654
- })
8207
+ children: [
8208
+ entry.offsetSeconds != null && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", {
8209
+ style: {
8210
+ color: "rgba(255,255,255,0.55)",
8211
+ background: "rgba(255,255,255,0.06)",
8212
+ borderRadius: "4px",
8213
+ padding: "1px 5px"
8214
+ },
8215
+ children: [
8216
+ "+",
8217
+ entry.offsetSeconds.toFixed(2),
8218
+ "s"
8219
+ ]
8220
+ }),
8221
+ entry.detail && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {
8222
+ style: {
8223
+ color: "rgba(255,255,255,0.55)",
8224
+ background: "rgba(255,255,255,0.06)",
8225
+ borderRadius: "4px",
8226
+ padding: "1px 5px",
8227
+ overflow: "hidden",
8228
+ textOverflow: "ellipsis",
8229
+ whiteSpace: "nowrap",
8230
+ maxWidth: "100%"
8231
+ },
8232
+ children: entry.detail
8233
+ }),
8234
+ entry.updatedAt && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", {
8235
+ style: {
8236
+ color: "rgba(255,255,255,0.38)",
8237
+ background: "rgba(255,255,255,0.04)",
8238
+ borderRadius: "4px",
8239
+ padding: "1px 5px"
8240
+ },
8241
+ children: formatAiRelativeTime(entry.updatedAt)
8242
+ })
8243
+ ]
8655
8244
  })
8656
8245
  ]
8657
8246
  }, "".concat(entry.timestampMs, "-").concat(idx));