stormcloud-video-player 0.8.69 → 0.8.70

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.
@@ -2483,7 +2483,7 @@ function createHlsAdPlayer(contentVideo, options) {
2483
2483
  img.onload = null;
2484
2484
  img.onerror = null;
2485
2485
  inFlightBeacons.delete(img);
2486
- console.log("[HlsAdPlayer] Tracking pixel settled (".concat(outcome, "): ").concat(trackingUrl));
2486
+ console.log("[HlsAdPlayer] Tracking pixel settled (".concat(outcome, "): ").concat(trackingHost));
2487
2487
  if (outcome !== "load") {
2488
2488
  logFunnel("tracking_request_settled", {
2489
2489
  reason: outcome,
@@ -2501,7 +2501,7 @@ function createHlsAdPlayer(contentVideo, options) {
2501
2501
  return release("timeout");
2502
2502
  }, BEACON_TIMEOUT_MS);
2503
2503
  img.src = trackingUrl;
2504
- console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(trackingUrl));
2504
+ console.log("[HlsAdPlayer] Fired tracking pixel: ".concat(trackingHost));
2505
2505
  logFunnel("tracking_request_created", {
2506
2506
  trackingHost: trackingHost,
2507
2507
  errorCode: options2 === null || options2 === void 0 ? void 0 : options2.errorCode
@@ -2955,7 +2955,7 @@ function createHlsAdPlayer(contentVideo, options) {
2955
2955
  });
2956
2956
  }
2957
2957
  if (parsed.type === "wrapper") {
2958
- console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(parsed.vastAdTagUri));
2958
+ console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(redactUrl(parsed.vastAdTagUri)));
2959
2959
  }
2960
2960
  return parsed;
2961
2961
  }
@@ -3147,8 +3147,8 @@ function createHlsAdPlayer(contentVideo, options) {
3147
3147
  switch(_state.label){
3148
3148
  case 0:
3149
3149
  attempt++;
3150
- if (kind === "gam") {
3151
- logFunnel("gam_http_request_sent", {
3150
+ if (kind !== "wrapper") {
3151
+ logFunnel("".concat(kind, "_http_request_sent"), {
3152
3152
  attempt: attempt,
3153
3153
  credentials: creds
3154
3154
  });
@@ -3168,8 +3168,8 @@ function createHlsAdPlayer(contentVideo, options) {
3168
3168
  ];
3169
3169
  case 1:
3170
3170
  response = _state.sent();
3171
- if (kind === "gam") {
3172
- logFunnel("gam_response_received", {
3171
+ if (kind !== "wrapper") {
3172
+ logFunnel("".concat(kind, "_response_received"), {
3173
3173
  attempt: attempt,
3174
3174
  httpStatus: response.status,
3175
3175
  ok: response.ok,
@@ -3339,8 +3339,7 @@ function createHlsAdPlayer(contentVideo, options) {
3339
3339
  elapsedMs: Date.now() - fetchStartedAt
3340
3340
  });
3341
3341
  }
3342
- console.log("[HlsAdPlayer] VAST XML received");
3343
- console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
3342
+ console.log("[HlsAdPlayer] VAST XML received (length=".concat(vastXml.length, ")"));
3344
3343
  parsed = parseVastXml(vastXml);
3345
3344
  if (parsed.type === "empty") {
3346
3345
  ;
@@ -3381,16 +3380,35 @@ function createHlsAdPlayer(contentVideo, options) {
3381
3380
  });
3382
3381
  }).apply(this, arguments);
3383
3382
  }
3383
+ function isEdgeEmptySentinelAd(adElement) {
3384
+ var _textOf;
3385
+ if ((adElement.getAttribute("id") || "").trim().toLowerCase() === "empty") {
3386
+ return true;
3387
+ }
3388
+ var inLine = adElement.querySelector(":scope > InLine");
3389
+ if (!inLine) return false;
3390
+ if (/^no ad available$/i.test((_textOf = textOf(inLine.querySelector(":scope > AdTitle"))) !== null && _textOf !== void 0 ? _textOf : "")) {
3391
+ return true;
3392
+ }
3393
+ var durations = Array.from(inLine.querySelectorAll(":scope > Creatives > Creative > Linear > Duration")).map(function(el) {
3394
+ return parseVastTime(textOf(el));
3395
+ });
3396
+ return durations.length > 0 && durations.every(function(seconds) {
3397
+ return seconds === 0;
3398
+ });
3399
+ }
3384
3400
  function fetchAndParsePod(vastTagUrl) {
3401
+ var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam";
3385
3402
  return _async_to_generator(function() {
3386
- var _root_getAttribute, _root_getAttribute1, vastXml, trimmedXml, xmlDoc, root, adElements, _root_getAttribute2, _empty_errorUrls, empty, _empty_errorCode, resolveAd, podElements, buffet, resolveAll, ads, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, ad, err, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, ad1, err;
3403
+ var _root_getAttribute, _root_getAttribute1, isEdge, vastXml, trimmedXml, xmlDoc, root, adElements, _root_getAttribute2, _empty_errorUrls, empty, _empty_errorCode, resolveAd, candidates, podElements, buffet, resolveAll, ads, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, ad, err, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, ad1, err;
3387
3404
  return _ts_generator(this, function(_state) {
3388
3405
  switch(_state.label){
3389
3406
  case 0:
3390
3407
  lastPodAdElementCount = 0;
3408
+ isEdge = source === "edge";
3391
3409
  return [
3392
3410
  4,
3393
- fetchVastXml(vastTagUrl)
3411
+ fetchVastXml(vastTagUrl, isEdge ? "omit" : "include", source)
3394
3412
  ];
3395
3413
  case 1:
3396
3414
  vastXml = _state.sent();
@@ -3413,7 +3431,6 @@ function createHlsAdPlayer(contentVideo, options) {
3413
3431
  }
3414
3432
  xmlDoc = parseXml(vastXml);
3415
3433
  if (!xmlDoc) {
3416
- console.error("[HlsAdPlayer] Pod VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
3417
3434
  logFunnel("vast_parsed", {
3418
3435
  adElementCount: 0,
3419
3436
  reason: "xml_parse_error"
@@ -3485,12 +3502,24 @@ function createHlsAdPlayer(contentVideo, options) {
3485
3502
  });
3486
3503
  })();
3487
3504
  };
3488
- podElements = adElements.filter(function(el) {
3505
+ candidates = adElements;
3506
+ if (isEdge) {
3507
+ candidates = adElements.filter(function(el) {
3508
+ return !isEdgeEmptySentinelAd(el);
3509
+ });
3510
+ if (candidates.length < adElements.length) {
3511
+ logFunnel("edge_empty_sentinel", {
3512
+ sentinelCount: adElements.length - candidates.length,
3513
+ adElementCount: adElements.length
3514
+ });
3515
+ }
3516
+ }
3517
+ podElements = candidates.filter(function(el) {
3489
3518
  return getAdSequence(el) !== void 0;
3490
3519
  }).sort(function(a, b) {
3491
3520
  return getAdSequence(a) - getAdSequence(b);
3492
3521
  });
3493
- buffet = adElements.filter(function(el) {
3522
+ buffet = candidates.filter(function(el) {
3494
3523
  return getAdSequence(el) === void 0;
3495
3524
  });
3496
3525
  resolveAll = function resolveAll(elements) {
@@ -3647,7 +3676,9 @@ function createHlsAdPlayer(contentVideo, options) {
3647
3676
  lastPodAdElementCount = adElements.length;
3648
3677
  return [
3649
3678
  2,
3650
- ads
3679
+ isEdge ? ads.filter(function(ad) {
3680
+ return ad.duration > 0;
3681
+ }) : ads
3651
3682
  ];
3652
3683
  }
3653
3684
  });
@@ -4648,13 +4679,14 @@ function createHlsAdPlayer(contentVideo, options) {
4648
4679
  contentVideo[AD_CONTAINER_PROP] = adContainerEl;
4649
4680
  attachContainerHandlers();
4650
4681
  },
4651
- requestAds: function requestAds(vastTagUrl) {
4682
+ requestAds: function requestAds(vastTagUrl, requestOptions) {
4652
4683
  return _async_to_generator(function() {
4653
- var ads, preloaded, error;
4684
+ var _ref, source, ads, preloaded, error;
4654
4685
  return _ts_generator(this, function(_state) {
4655
4686
  switch(_state.label){
4656
4687
  case 0:
4657
- console.log("[HlsAdPlayer] Requesting ads:", vastTagUrl);
4688
+ source = (_ref = requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.source) !== null && _ref !== void 0 ? _ref : "gam";
4689
+ console.log("[HlsAdPlayer] Requesting ads (".concat(source, "):"), redactUrl(vastTagUrl));
4658
4690
  if (adPlaying) {
4659
4691
  console.warn("[HlsAdPlayer] Cannot request new ads while an ad is playing");
4660
4692
  return [
@@ -4699,7 +4731,7 @@ function createHlsAdPlayer(contentVideo, options) {
4699
4731
  case 2:
4700
4732
  return [
4701
4733
  4,
4702
- fetchAndParsePod(vastTagUrl)
4734
+ fetchAndParsePod(vastTagUrl, source)
4703
4735
  ];
4704
4736
  case 3:
4705
4737
  ads = _state.sent();
@@ -5109,6 +5141,75 @@ function createHlsAdPlayer(contentVideo, options) {
5109
5141
  return podAds.reduce(function(total, ad) {
5110
5142
  return total + (ad.duration > 0 ? ad.duration * 1e3 : 0);
5111
5143
  }, 0);
5144
+ },
5145
+ limitPodToBudget: function limitPodToBudget(maxDurationMs, maxAds) {
5146
+ if (adPlaying) return podAds.length;
5147
+ var kept = [];
5148
+ var dropped = [];
5149
+ var totalMs = 0;
5150
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
5151
+ try {
5152
+ for(var _iterator = podAds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
5153
+ var ad = _step.value;
5154
+ var durationMs = Math.round(ad.duration * 1e3);
5155
+ if (kept.length < maxAds && totalMs + durationMs <= maxDurationMs) {
5156
+ kept.push(ad);
5157
+ totalMs += durationMs;
5158
+ } else {
5159
+ dropped.push(ad);
5160
+ }
5161
+ }
5162
+ } catch (err) {
5163
+ _didIteratorError = true;
5164
+ _iteratorError = err;
5165
+ } finally{
5166
+ try {
5167
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
5168
+ _iterator.return();
5169
+ }
5170
+ } finally{
5171
+ if (_didIteratorError) {
5172
+ throw _iteratorError;
5173
+ }
5174
+ }
5175
+ }
5176
+ if (dropped.length > 0) {
5177
+ logFunnel("pod_trimmed_to_budget", {
5178
+ keptCount: kept.length,
5179
+ droppedCount: dropped.length,
5180
+ keptDurationMs: totalMs,
5181
+ maxDurationMs: maxDurationMs,
5182
+ maxAds: maxAds
5183
+ });
5184
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
5185
+ try {
5186
+ for(var _iterator1 = dropped[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
5187
+ var ad1 = _step1.value;
5188
+ resolvedAds.add(ad1);
5189
+ fireTrackingPixels(ad1.trackingUrls.notUsed, {
5190
+ ad: ad1
5191
+ });
5192
+ }
5193
+ } catch (err) {
5194
+ _didIteratorError1 = true;
5195
+ _iteratorError1 = err;
5196
+ } finally{
5197
+ try {
5198
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
5199
+ _iterator1.return();
5200
+ }
5201
+ } finally{
5202
+ if (_didIteratorError1) {
5203
+ throw _iteratorError1;
5204
+ }
5205
+ }
5206
+ }
5207
+ }
5208
+ podAds = kept;
5209
+ podIndex = 0;
5210
+ currentAd = kept[0];
5211
+ currentAdMediaFile = void 0;
5212
+ return kept.length;
5112
5213
  }
5113
5214
  };
5114
5215
  }
@@ -9107,6 +9208,59 @@ var HlsEngine = /*#__PURE__*/ function() {
9107
9208
  ]);
9108
9209
  return HlsEngine;
9109
9210
  }();
9211
+ // src/player/EdgePodRequest.ts
9212
+ var EDGE_POD_MAX_ADS = 10;
9213
+ var EDGE_POD_EXCEEDS_BUDGET = "edge_pod_exceeds_budget";
9214
+ function resolveEdgePodBaseUrl(config) {
9215
+ var _config_edgePodUrl;
9216
+ if (config.enableEdgePodRequest !== true) return void 0;
9217
+ var raw = (_config_edgePodUrl = config.edgePodUrl) === null || _config_edgePodUrl === void 0 ? void 0 : _config_edgePodUrl.trim();
9218
+ if (!raw) {
9219
+ console.warn("[AdBreak][EDGE] enableEdgePodRequest is true but edgePodUrl is missing; using GAM only");
9220
+ return void 0;
9221
+ }
9222
+ try {
9223
+ var url = new URL(raw);
9224
+ if (url.protocol !== "https:" && url.protocol !== "http:") {
9225
+ throw new Error("unsupported protocol ".concat(url.protocol));
9226
+ }
9227
+ return url.toString();
9228
+ } catch (unused) {
9229
+ console.warn("[AdBreak][EDGE] edgePodUrl is not a valid http(s) URL; using GAM only");
9230
+ return void 0;
9231
+ }
9232
+ }
9233
+ function buildEdgePodUrl(baseUrl, remainingMs, remainingAdLimit) {
9234
+ var url = new URL(baseUrl);
9235
+ var maxMs = Math.max(0, Math.floor(remainingMs));
9236
+ var maxAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, Math.floor(remainingAdLimit)));
9237
+ url.searchParams.set("pmxd", String(maxMs));
9238
+ url.searchParams.set("pmad", String(maxAds));
9239
+ url.searchParams.set("duration", String(Math.floor(maxMs / 1e3)));
9240
+ url.searchParams.set("count", String(maxAds));
9241
+ return url.toString();
9242
+ }
9243
+ function classifyEdgeVastResponse(result) {
9244
+ var _ref;
9245
+ var _result_error;
9246
+ if (result.error == null) {
9247
+ return result.podAdCount > 0 ? "fill" : "no_fill";
9248
+ }
9249
+ var message = (_ref = (_result_error = result.error) === null || _result_error === void 0 ? void 0 : _result_error.message) !== null && _ref !== void 0 ? _ref : String(result.error);
9250
+ if (/no ads available|fill rejected|no media file|no ad loaded/i.test(message) || message.includes(EDGE_POD_EXCEEDS_BUDGET)) {
9251
+ return "no_fill";
9252
+ }
9253
+ return "invalid";
9254
+ }
9255
+ function describeEdgeUrl(url) {
9256
+ try {
9257
+ var parsed = new URL(url);
9258
+ return "".concat(parsed.origin).concat(parsed.pathname);
9259
+ } catch (unused) {
9260
+ var _url_split_;
9261
+ return (_url_split_ = url.split("?")[0]) !== null && _url_split_ !== void 0 ? _url_split_ : "";
9262
+ }
9263
+ }
9110
9264
  // src/player/PlayerControls.ts
9111
9265
  function getAdAudioVolume(adPlayer) {
9112
9266
  return adPlayer.getOriginalMutedState() ? 0 : adPlayer.getOriginalVolume();
@@ -9265,6 +9419,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9265
9419
  this.controllerCallInFlight = false;
9266
9420
  this.playbackStartedForCurrentRequest = false;
9267
9421
  this.opportunityEpoch = -1;
9422
+ this.edgeExhaustedForBreak = false;
9423
+ this.edgeRequestsInBreak = 0;
9268
9424
  this.adPodQueue = [];
9269
9425
  this.defaultMinRemainingMsToRequestAd = 1e4;
9270
9426
  this.defaultMaxNoFillsPerBreak = 2;
@@ -9415,7 +9571,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9415
9571
  _this.timing.clearAdRequestWatchdog();
9416
9572
  _this.timing.activeAdRequestToken = null;
9417
9573
  _this.showAds = true;
9418
- _this.timing.resetGamNoFillCounter();
9574
+ if (_this.currentPodSource !== "edge") {
9575
+ _this.timing.resetGamNoFillCounter();
9576
+ }
9419
9577
  if (_this.inAdBreak && _this.timing.expectedAdBreakDurationMs != null && _this.timing.getAdBreakEndWallClockMs() == null) {
9420
9578
  _this.timing.scheduleAdStopAtBreakBoundary();
9421
9579
  if (_this.debug) {
@@ -9547,6 +9705,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9547
9705
  key: "beginVmapBreak",
9548
9706
  value: function beginVmapBreak(breakKey, position) {
9549
9707
  this.breakSource = "vmap";
9708
+ this.resetEdgeStateForBreak();
9550
9709
  this.followUpBaseVastUrl = void 0;
9551
9710
  this.unusableResponsesInBreak = 0;
9552
9711
  this.timing.totalAdRequestsInBreak = 0;
@@ -9558,7 +9717,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9558
9717
  key: "handleAdStart",
9559
9718
  value: function handleAdStart(marker) {
9560
9719
  return _async_to_generator(function() {
9561
- var baseVastUrl, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, podPlayed;
9720
+ var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
9562
9721
  return _ts_generator(this, function(_state) {
9563
9722
  switch(_state.label){
9564
9723
  case 0:
@@ -9572,7 +9731,8 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9572
9731
  ];
9573
9732
  }
9574
9733
  baseVastUrl = this.adConfig.apiVastTagUrl;
9575
- if (!baseVastUrl) {
9734
+ edgeConfigured = !!this.host.getEdgePodBaseUrl();
9735
+ if (!baseVastUrl && !edgeConfigured) {
9576
9736
  console.warn("[AdBreak] SCTE-35 break started but no direct VAST tag is configured");
9577
9737
  this.clearPendingAdBreak();
9578
9738
  return [
@@ -9588,6 +9748,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9588
9748
  this.breakSource = "scte35";
9589
9749
  this.followUpBaseVastUrl = baseVastUrl;
9590
9750
  this.unusableResponsesInBreak = 0;
9751
+ this.resetEdgeStateForBreak();
9591
9752
  this.setSlotState("NEEDS_NEXT_AD", "scte35_break_start");
9592
9753
  if (this.adConfig.podAssignedByPrefetch) {
9593
9754
  this.adConfig.podAssignedByPrefetch = false;
@@ -9609,7 +9770,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9609
9770
  this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
9610
9771
  epoch = this.timing.adBreakEpoch;
9611
9772
  hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
9612
- if (!(adBreakDurationMs == null && !hasPrefetchedUrl)) return [
9773
+ if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
9613
9774
  3,
9614
9775
  2
9615
9776
  ];
@@ -9628,11 +9789,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9628
9789
  mode = this.host.config.isLiveStream ? "LIVE" : "VOD";
9629
9790
  console.log("[AdBreak] ".concat(mode, " break start: target duration=").concat(adBreakDurationMs != null ? "".concat(adBreakDurationMs, "ms") : "unknown"));
9630
9791
  }
9792
+ if (!edgeConfigured) return [
9793
+ 3,
9794
+ 5
9795
+ ];
9796
+ edgeUrl = this.canRequestEdge() ? this.prepareEdgePodRequest() : void 0;
9797
+ if (!edgeUrl) return [
9798
+ 3,
9799
+ 4
9800
+ ];
9801
+ this.clearPendingAdBreak();
9631
9802
  return [
9632
9803
  4,
9633
- this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
9804
+ this.runEdgePod(edgeUrl, "edge_break_start")
9634
9805
  ];
9635
9806
  case 3:
9807
+ outcome = _state.sent();
9808
+ this.continueAfterEdgeOutcome(outcome, epoch);
9809
+ return [
9810
+ 2
9811
+ ];
9812
+ case 4:
9813
+ if (!this.edgeExhaustedForBreak) {
9814
+ this.markEdgeExhausted("not_eligible_at_break_start", {
9815
+ isLive: this.isLiveBreak(),
9816
+ durationMs: this.timing.expectedAdBreakDurationMs
9817
+ });
9818
+ }
9819
+ _state.label = 5;
9820
+ case 5:
9821
+ if (!baseVastUrl) {
9822
+ this.requestNextAd("no_gam_source");
9823
+ return [
9824
+ 2
9825
+ ];
9826
+ }
9827
+ return [
9828
+ 4,
9829
+ this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
9830
+ ];
9831
+ case 6:
9636
9832
  podPlayed = _state.sent();
9637
9833
  if (!podPlayed && this.inAdBreak && epoch === this.timing.adBreakEpoch) {
9638
9834
  this.setSlotState("NEEDS_NEXT_AD", "initial_request_failed");
@@ -9724,6 +9920,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9724
9920
  adPlayer = this.host.getAdPlayer();
9725
9921
  requestToken = ++this.timing.adRequestTokenCounter;
9726
9922
  this.timing.activeAdRequestToken = requestToken;
9923
+ this.currentPodSource = "gam";
9727
9924
  this.setSlotState("REQUESTING", "initial_pod");
9728
9925
  this.beginFunnelRequest(adPlayer, requestToken, "initial_pod");
9729
9926
  requestUrl = this.applyOpportunityFloor(podUrl);
@@ -9840,6 +10037,224 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9840
10037
  }).call(this);
9841
10038
  }
9842
10039
  },
10040
+ {
10041
+ // ───────────────────────────────────────────────────────────────
10042
+ // Edge-first pods (live SCTE-35 only, GAM fallback)
10043
+ // ───────────────────────────────────────────────────────────────
10044
+ key: "resetEdgeStateForBreak",
10045
+ value: function resetEdgeStateForBreak() {
10046
+ this.edgeExhaustedForBreak = false;
10047
+ this.edgeRequestsInBreak = 0;
10048
+ this.currentPodSource = void 0;
10049
+ }
10050
+ },
10051
+ {
10052
+ key: "isLiveBreak",
10053
+ value: function isLiveBreak() {
10054
+ return this.host.isLiveStream() || this.host.config.isLiveStream === true;
10055
+ }
10056
+ },
10057
+ {
10058
+ key: "canRequestEdge",
10059
+ value: function canRequestEdge() {
10060
+ return this.breakSource === "scte35" && !this.edgeExhaustedForBreak && !!this.host.getEdgePodBaseUrl() && this.isLiveBreak() && this.timing.expectedAdBreakDurationMs != null && this.edgeRequestsInBreak < this.timing.maxTotalAdRequestsPerBreak;
10061
+ }
10062
+ },
10063
+ {
10064
+ key: "markEdgeExhausted",
10065
+ value: function markEdgeExhausted(reason) {
10066
+ var extra = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {};
10067
+ this.edgeExhaustedForBreak = true;
10068
+ this.countFunnelStage("edge_fallback:".concat(reason));
10069
+ this.logOrchestratorFunnel("edge_exhausted", _object_spread({
10070
+ reason: reason,
10071
+ edgeRequests: this.edgeRequestsInBreak,
10072
+ remainingMs: this.timing.getRemainingAdMs()
10073
+ }, extra));
10074
+ }
10075
+ },
10076
+ {
10077
+ /**
10078
+ * Builds the next Edge request from the budget left right now, or marks Edge
10079
+ * exhausted for this break. Synchronous on purpose: callers must reach the
10080
+ * REQUESTING state in the same tick so a second completion event cannot race
10081
+ * in a parallel request.
10082
+ */ key: "prepareEdgePodRequest",
10083
+ value: function prepareEdgePodRequest() {
10084
+ var baseUrl = this.host.getEdgePodBaseUrl();
10085
+ if (!baseUrl) return void 0;
10086
+ var remainingMs = this.timing.getRemainingAdMs();
10087
+ var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
10088
+ if (remainingAds < 1) {
10089
+ this.markEdgeExhausted("ad_capacity_reached", {
10090
+ adsInBreak: this.timing.totalAdsInBreak
10091
+ });
10092
+ return void 0;
10093
+ }
10094
+ if (remainingMs < this.getMinRemainingMsToRequestAd()) {
10095
+ this.markEdgeExhausted("insufficient_break_time", {
10096
+ remainingMs: remainingMs
10097
+ });
10098
+ return void 0;
10099
+ }
10100
+ try {
10101
+ return buildEdgePodUrl(baseUrl, remainingMs, remainingAds);
10102
+ } catch (unused) {
10103
+ this.markEdgeExhausted("invalid_edge_url");
10104
+ return void 0;
10105
+ }
10106
+ }
10107
+ },
10108
+ {
10109
+ key: "runEdgePod",
10110
+ value: function runEdgePod(requestUrl, trigger) {
10111
+ return _async_to_generator(function() {
10112
+ var _params_get, _params_get1, epoch, generation, adPlayer, requestToken, params, _ref, _adPlayer_getPodAdCount, _adPlayer_getPodTotalDurationMs, remainingMs, remainingAds, podCount, error, errorMessage, classification, diag;
10113
+ return _ts_generator(this, function(_state) {
10114
+ switch(_state.label){
10115
+ case 0:
10116
+ epoch = this.timing.adBreakEpoch;
10117
+ this.recreateAdController("new_request");
10118
+ generation = this.controllerGeneration;
10119
+ adPlayer = this.host.getAdPlayer();
10120
+ requestToken = ++this.timing.adRequestTokenCounter;
10121
+ this.timing.activeAdRequestToken = requestToken;
10122
+ this.currentPodSource = "edge";
10123
+ this.edgeRequestsInBreak++;
10124
+ this.setSlotState("REQUESTING", trigger);
10125
+ this.beginFunnelRequest(adPlayer, requestToken, trigger, "edge");
10126
+ this.currentVastUrl = requestUrl;
10127
+ params = new URL(requestUrl).searchParams;
10128
+ this.logOrchestratorFunnel("edge_request_sent", {
10129
+ trigger: trigger,
10130
+ attempt: this.edgeRequestsInBreak,
10131
+ endpoint: describeEdgeUrl(requestUrl),
10132
+ pmxd: (_params_get = params.get("pmxd")) !== null && _params_get !== void 0 ? _params_get : void 0,
10133
+ pmad: (_params_get1 = params.get("pmad")) !== null && _params_get1 !== void 0 ? _params_get1 : void 0
10134
+ });
10135
+ _state.label = 1;
10136
+ case 1:
10137
+ _state.trys.push([
10138
+ 1,
10139
+ 4,
10140
+ ,
10141
+ 5
10142
+ ]);
10143
+ this.timing.startAdRequestWatchdog(requestToken);
10144
+ return [
10145
+ 4,
10146
+ this.callController(function() {
10147
+ return adPlayer.requestAds(requestUrl, {
10148
+ source: "edge"
10149
+ });
10150
+ })
10151
+ ];
10152
+ case 2:
10153
+ _state.sent();
10154
+ this.timing.clearAdRequestWatchdog();
10155
+ if (this.isStale(epoch, generation)) {
10156
+ this.logOrchestratorFunnel("stale_request_result_ignored", {
10157
+ requestId: requestToken,
10158
+ source: "edge"
10159
+ });
10160
+ return [
10161
+ 2,
10162
+ "stale"
10163
+ ];
10164
+ }
10165
+ remainingMs = this.timing.getRemainingAdMs();
10166
+ remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
10167
+ podCount = adPlayer.limitPodToBudget ? adPlayer.limitPodToBudget(remainingMs, remainingAds) : (_ref = (_adPlayer_getPodAdCount = adPlayer.getPodAdCount) === null || _adPlayer_getPodAdCount === void 0 ? void 0 : _adPlayer_getPodAdCount.call(adPlayer)) !== null && _ref !== void 0 ? _ref : 0;
10168
+ if (classifyEdgeVastResponse({
10169
+ podAdCount: podCount
10170
+ }) !== "fill") {
10171
+ throw new Error("".concat(EDGE_POD_EXCEEDS_BUDGET, ": no Edge ad fits ").concat(remainingMs, "ms"));
10172
+ }
10173
+ this.setSlotState("READY", "edge_vast_ready");
10174
+ this.logOrchestratorFunnel("edge_fill", {
10175
+ podAdCount: podCount,
10176
+ podDurationMs: (_adPlayer_getPodTotalDurationMs = adPlayer.getPodTotalDurationMs) === null || _adPlayer_getPodTotalDurationMs === void 0 ? void 0 : _adPlayer_getPodTotalDurationMs.call(adPlayer),
10177
+ remainingMs: remainingMs
10178
+ });
10179
+ sendAdLoadedTracking(this.host.config.licenseKey, {
10180
+ source: "hls",
10181
+ vastUrl: requestUrl,
10182
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
10183
+ }, this.analyticsContext).catch(function() {});
10184
+ this.timing.startAdFailsafeTimer(requestToken);
10185
+ return [
10186
+ 4,
10187
+ this.callController(function() {
10188
+ return adPlayer.play();
10189
+ })
10190
+ ];
10191
+ case 3:
10192
+ _state.sent();
10193
+ if (this.isStale(epoch, generation)) return [
10194
+ 2,
10195
+ "stale"
10196
+ ];
10197
+ if (this.timing.expectedAdBreakDurationMs != null && this.timing.getAdBreakEndWallClockMs() == null) {
10198
+ this.timing.scheduleAdStopAtBreakBoundary();
10199
+ }
10200
+ adPlayer.setAdVolume(getAdAudioVolume(adPlayer));
10201
+ return [
10202
+ 2,
10203
+ "fill"
10204
+ ];
10205
+ case 4:
10206
+ error = _state.sent();
10207
+ this.timing.clearAdRequestWatchdog();
10208
+ this.timing.clearAdFailsafeTimer();
10209
+ if (this.timing.activeAdRequestToken === requestToken) {
10210
+ this.timing.activeAdRequestToken = null;
10211
+ }
10212
+ errorMessage = error === null || error === void 0 ? void 0 : error.message;
10213
+ if (this.isStale(epoch, generation)) {
10214
+ this.logOrchestratorFunnel("stale_request_result_ignored", {
10215
+ requestId: requestToken,
10216
+ source: "edge",
10217
+ errorMessage: errorMessage
10218
+ });
10219
+ return [
10220
+ 2,
10221
+ "stale"
10222
+ ];
10223
+ }
10224
+ classification = classifyEdgeVastResponse({
10225
+ podAdCount: 0,
10226
+ error: error
10227
+ });
10228
+ diag = this.requestDiagnostics.get(requestToken);
10229
+ if (diag && !diag.failureReason) diag.failureReason = "edge_".concat(classification, ": ").concat(errorMessage);
10230
+ this.markEdgeExhausted("edge_".concat(classification), {
10231
+ errorMessage: errorMessage
10232
+ });
10233
+ return [
10234
+ 2,
10235
+ "fallback"
10236
+ ];
10237
+ case 5:
10238
+ return [
10239
+ 2
10240
+ ];
10241
+ }
10242
+ });
10243
+ }).call(this);
10244
+ }
10245
+ },
10246
+ {
10247
+ key: "continueAfterEdgeOutcome",
10248
+ value: function continueAfterEdgeOutcome(outcome, epoch) {
10249
+ if (outcome !== "fallback") return;
10250
+ if (!this.inAdBreak || epoch !== this.timing.adBreakEpoch) return;
10251
+ if (this.debug) {
10252
+ console.log("[AdBreak][EDGE] No usable Edge pod; checking with GAM for the remaining break");
10253
+ }
10254
+ this.setSlotState("NEEDS_NEXT_AD", "edge_fallback");
10255
+ this.requestNextAd("edge_fallback");
10256
+ }
10257
+ },
9843
10258
  {
9844
10259
  // ───────────────────────────────────────────────────────────────
9845
10260
  // Next-ad scheduling (single flight)
@@ -9895,7 +10310,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9895
10310
  value: function getStopRequestingReason(remainingMs) {
9896
10311
  if (this.breakSource === "vmap") {
9897
10312
  if (this.adPodQueue.length === 0) return "vmap_queue_empty";
9898
- } else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl) {
10313
+ } else if (this.breakSource !== "scte35" || !this.followUpBaseVastUrl && !this.canRequestEdge()) {
9899
10314
  return "no_follow_up_source";
9900
10315
  }
9901
10316
  if (this.timing.consecutiveFailures >= this.timing.maxConsecutiveFailures) {
@@ -9907,7 +10322,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9907
10322
  if (this.timing.totalAdRequestsInBreak >= this.timing.maxTotalAdRequestsPerBreak) {
9908
10323
  return "request_cap";
9909
10324
  }
9910
- if (this.timing.isGamInCooldown()) {
10325
+ if (!this.canRequestEdge() && this.timing.isGamInCooldown()) {
9911
10326
  return "gam_cooldown";
9912
10327
  }
9913
10328
  if (this.isBreakTimeBounded() && remainingMs < this.getMinRemainingMsToRequestAd()) {
@@ -10001,10 +10416,33 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10001
10416
  key: "requestFollowUpAd",
10002
10417
  value: function requestFollowUpAd(trigger) {
10003
10418
  return _async_to_generator(function() {
10004
- var url, epoch, unused;
10419
+ var edgeUrl, epoch2, outcome, url, epoch, unused;
10005
10420
  return _ts_generator(this, function(_state) {
10006
10421
  switch(_state.label){
10007
10422
  case 0:
10423
+ if (!this.canRequestEdge()) return [
10424
+ 3,
10425
+ 2
10426
+ ];
10427
+ edgeUrl = this.prepareEdgePodRequest();
10428
+ if (!edgeUrl) {
10429
+ this.requestNextAd("".concat(trigger, ":edge_unavailable"));
10430
+ return [
10431
+ 2
10432
+ ];
10433
+ }
10434
+ epoch2 = this.timing.adBreakEpoch;
10435
+ return [
10436
+ 4,
10437
+ this.runEdgePod(edgeUrl, "edge_".concat(trigger))
10438
+ ];
10439
+ case 1:
10440
+ outcome = _state.sent();
10441
+ this.continueAfterEdgeOutcome(outcome, epoch2);
10442
+ return [
10443
+ 2
10444
+ ];
10445
+ case 2:
10008
10446
  if (this.breakSource === "vmap") {
10009
10447
  url = this.adPodQueue.shift();
10010
10448
  } else if (this.followUpBaseVastUrl) {
@@ -10015,32 +10453,32 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10015
10453
  ];
10016
10454
  this.noteVastUrlGenerated(ensureVideoAdType(url), trigger);
10017
10455
  epoch = this.timing.adBreakEpoch;
10018
- _state.label = 1;
10019
- case 1:
10456
+ _state.label = 3;
10457
+ case 3:
10020
10458
  _state.trys.push([
10021
- 1,
10022
10459
  3,
10460
+ 5,
10023
10461
  ,
10024
- 4
10462
+ 6
10025
10463
  ]);
10026
10464
  return [
10027
10465
  4,
10028
10466
  this.playSingleAd(url, trigger)
10029
10467
  ];
10030
- case 2:
10468
+ case 4:
10031
10469
  _state.sent();
10032
10470
  return [
10033
10471
  3,
10034
- 4
10472
+ 6
10035
10473
  ];
10036
- case 3:
10474
+ case 5:
10037
10475
  unused = _state.sent();
10038
10476
  this.continueAfterRequestFailure(epoch);
10039
10477
  return [
10040
10478
  3,
10041
- 4
10479
+ 6
10042
10480
  ];
10043
- case 4:
10481
+ case 6:
10044
10482
  return [
10045
10483
  2
10046
10484
  ];
@@ -10153,7 +10591,11 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10153
10591
  case "gam_http_request_sent":
10154
10592
  diag.gamRequestSent++;
10155
10593
  break;
10594
+ case "edge_http_request_sent":
10595
+ diag.edgeRequestSent++;
10596
+ break;
10156
10597
  case "gam_response_received":
10598
+ case "edge_response_received":
10157
10599
  diag.vastHttpStatus = payload.httpStatus;
10158
10600
  break;
10159
10601
  case "vast_parsed":
@@ -10340,6 +10782,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10340
10782
  {
10341
10783
  key: "beginFunnelRequest",
10342
10784
  value: function beginFunnelRequest(adPlayer, requestToken, trigger) {
10785
+ var source = arguments.length > 3 && arguments[3] !== void 0 ? arguments[3] : "gam";
10343
10786
  var _adPlayer_setFunnelContext;
10344
10787
  if (this.controllerCallInFlight) {
10345
10788
  this.logOrchestratorFunnel("duplicate_request_detected", {
@@ -10354,7 +10797,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10354
10797
  requestId: requestToken,
10355
10798
  controllerId: this.controllerGeneration,
10356
10799
  trigger: trigger,
10800
+ source: source,
10357
10801
  gamRequestSent: 0,
10802
+ edgeRequestSent: 0,
10358
10803
  wrapperDepth: 0,
10359
10804
  inlineResolved: false,
10360
10805
  mediaCandidateCount: 0,
@@ -10485,6 +10930,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10485
10930
  this.timing.activeAdRequestToken = requestToken;
10486
10931
  ap = this.host.getAdPlayer();
10487
10932
  budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
10933
+ this.currentPodSource = "gam";
10488
10934
  this.setSlotState("REQUESTING", trigger);
10489
10935
  this.beginFunnelRequest(ap, requestToken, trigger);
10490
10936
  requestUrl = this.applyOpportunityFloor(budgetedUrl);
@@ -10632,6 +11078,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10632
11078
  requests: requests,
10633
11079
  requestRetries: requestRetries,
10634
11080
  gamResponses: count("gam_response_received"),
11081
+ edgeRequests: count("edge_request_sent"),
11082
+ edgeFills: count("edge_fill"),
11083
+ edgeEmptySentinels: count("edge_empty_sentinel"),
11084
+ edgeFallbacks: countPrefix("edge_fallback:"),
10635
11085
  requestsSuppressed: count("request_suppressed"),
10636
11086
  duplicates: count("duplicate_request_detected") + count("duplicate_break_start"),
10637
11087
  filled: count("vast_received"),
@@ -10728,6 +11178,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10728
11178
  this.breakSource = void 0;
10729
11179
  this.followUpBaseVastUrl = void 0;
10730
11180
  this.unusableResponsesInBreak = 0;
11181
+ this.resetEdgeStateForBreak();
10731
11182
  adPlayer.stop().catch(function() {});
10732
11183
  if (!alreadyEnded) this.logBreakFunnel(reason);
10733
11184
  this.opportunityFloor = void 0;
@@ -11041,7 +11492,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11041
11492
  });
11042
11493
  return;
11043
11494
  }
11044
- this.timing.consecutiveFailures++;
11495
+ if (this.currentPodSource === "edge") {
11496
+ this.markEdgeExhausted("edge_playback_failed", {
11497
+ reason: reason
11498
+ });
11499
+ } else {
11500
+ this.timing.consecutiveFailures++;
11501
+ }
11045
11502
  var diag = this.currentRequestId != null ? this.requestDiagnostics.get(this.currentRequestId) : void 0;
11046
11503
  if (diag && !diag.failureReason) diag.failureReason = reason;
11047
11504
  if (this.debug) {
@@ -11071,7 +11528,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11071
11528
  if (this.config.adFloorMaxCents != null) floorBounds.maxCents = this.config.adFloorMaxCents;
11072
11529
  if (this.config.adFloorStepCents != null) floorBounds.stepCents = this.config.adFloorStepCents;
11073
11530
  this.floorLadder = new FloorLadderController(this.config.adFloorLadder, floorBounds);
11531
+ this.floorLadderEnabled = this.config.adFloorLadderEnabled === true;
11074
11532
  this.warnOnInvalidFloorLadder(this.floorLadder.validate());
11533
+ this.edgePodBaseUrl = resolveEdgePodBaseUrl(this.config);
11075
11534
  this.adPlayer = this.createAdPlayer(false);
11076
11535
  this.palNonce = createPalNonceManager();
11077
11536
  this.cueManager = new Scte35CueManager(!!this.config.debugAdTiming, {
@@ -11171,11 +11630,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11171
11630
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
11172
11631
  return _this.generatePodVastUrl(base, breakDurationMs);
11173
11632
  },
11633
+ getEdgePodBaseUrl: function getEdgePodBaseUrl() {
11634
+ return _this.edgePodBaseUrl;
11635
+ },
11174
11636
  getFloorSnapshot: function getFloorSnapshot(position) {
11175
- return _this.floorLadder.snapshotFor({
11637
+ return _this.floorLadderEnabled ? _this.floorLadder.snapshotFor({
11176
11638
  position: position,
11177
11639
  isCtv: _this.isCtvEnvironment()
11178
- });
11640
+ }) : void 0;
11179
11641
  },
11180
11642
  onAdClick: function onAdClick() {
11181
11643
  return _this.palNonce.sendAdClick();
@@ -11226,11 +11688,24 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11226
11688
  return report;
11227
11689
  }
11228
11690
  },
11691
+ {
11692
+ key: "setAdFloorLadderEnabled",
11693
+ value: function setAdFloorLadderEnabled(enabled) {
11694
+ this.floorLadderEnabled = enabled;
11695
+ if (enabled) this.warnOnInvalidFloorLadder(this.floorLadder.validate());
11696
+ }
11697
+ },
11698
+ {
11699
+ key: "isAdFloorLadderEnabled",
11700
+ value: function isAdFloorLadderEnabled() {
11701
+ return this.floorLadderEnabled;
11702
+ }
11703
+ },
11229
11704
  {
11230
11705
  key: "warnOnInvalidFloorLadder",
11231
11706
  value: function warnOnInvalidFloorLadder(report) {
11232
11707
  var config = this.floorLadder.get();
11233
- if (report.ok || !config.enabled) return;
11708
+ if (report.ok || !this.floorLadderEnabled || !config.enabled) return;
11234
11709
  console.warn("[AdBreak][FLOOR] configuration has issues; invalid floors will not be sent", {
11235
11710
  errors: report.errors,
11236
11711
  configurationVersion: config.configurationVersion,
@@ -11963,6 +12438,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11963
12438
  this.timing.destroy();
11964
12439
  this.adBreak.clearPendingAdBreak();
11965
12440
  this.placeholder.destroy();
12441
+ 0;
11966
12442
  if (this.timeUpdateHandler) {
11967
12443
  this.video.removeEventListener("timeupdate", this.timeUpdateHandler);
11968
12444
  delete this.timeUpdateHandler;
@@ -12063,12 +12539,14 @@ var CRITICAL_PROPS = [
12063
12539
  "ctvAdRequest",
12064
12540
  "adFloorMinCents",
12065
12541
  "adFloorMaxCents",
12066
- "adFloorStepCents"
12542
+ "adFloorStepCents",
12543
+ "enableEdgePodRequest",
12544
+ "edgePodUrl"
12067
12545
  ];
12068
12546
  var CONTROLS_HIDE_DELAY = 3e3;
12069
12547
  var DEFAULT_PLAYER_ASPECT_RATIO = 16 / 9;
12070
12548
  var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
12071
- var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, isLiveStream = props.isLiveStream, 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, isVmap = props.isVmap, vmapUrl = props.vmapUrl, minSegmentsBeforePlay = props.minSegmentsBeforePlay, ctvAdRequest = props.ctvAdRequest, programTitle = props.programTitle, channelName = props.channelName, minRemainingMsToStartAd = props.minRemainingMsToStartAd, minRemainingMsToRequestAd = props.minRemainingMsToRequestAd, maxNoFillsPerBreak = props.maxNoFillsPerBreak, adFloorLadder = props.adFloorLadder, adFloorMinCents = props.adFloorMinCents, adFloorMaxCents = props.adFloorMaxCents, adFloorStepCents = props.adFloorStepCents, restVideoAttrs = _object_without_properties(props, [
12549
+ var src = props.src, autoplay = props.autoplay, muted = props.muted, lowLatencyMode = props.lowLatencyMode, allowNativeHls = props.allowNativeHls, isLiveStream = props.isLiveStream, 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, isVmap = props.isVmap, vmapUrl = props.vmapUrl, minSegmentsBeforePlay = props.minSegmentsBeforePlay, ctvAdRequest = props.ctvAdRequest, programTitle = props.programTitle, channelName = props.channelName, minRemainingMsToStartAd = props.minRemainingMsToStartAd, minRemainingMsToRequestAd = props.minRemainingMsToRequestAd, maxNoFillsPerBreak = props.maxNoFillsPerBreak, adFloorLadderEnabled = props.adFloorLadderEnabled, adFloorLadder = props.adFloorLadder, adFloorMinCents = props.adFloorMinCents, adFloorMaxCents = props.adFloorMaxCents, adFloorStepCents = props.adFloorStepCents, enableEdgePodRequest = props.enableEdgePodRequest, edgePodUrl = props.edgePodUrl, restVideoAttrs = _object_without_properties(props, [
12072
12550
  "src",
12073
12551
  "autoplay",
12074
12552
  "muted",
@@ -12105,10 +12583,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
12105
12583
  "minRemainingMsToStartAd",
12106
12584
  "minRemainingMsToRequestAd",
12107
12585
  "maxNoFillsPerBreak",
12586
+ "adFloorLadderEnabled",
12108
12587
  "adFloorLadder",
12109
12588
  "adFloorMinCents",
12110
12589
  "adFloorMaxCents",
12111
- "adFloorStepCents"
12590
+ "adFloorStepCents",
12591
+ "enableEdgePodRequest",
12592
+ "edgePodUrl"
12112
12593
  ]);
12113
12594
  var adFloorLadderKey = JSON.stringify(adFloorLadder !== null && adFloorLadder !== void 0 ? adFloorLadder : null);
12114
12595
  var videoRef = (0, import_react.useRef)(null);
@@ -12259,7 +12740,9 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
12259
12740
  vastMode,
12260
12741
  adFloorMinCents,
12261
12742
  adFloorMaxCents,
12262
- adFloorStepCents
12743
+ adFloorStepCents,
12744
+ enableEdgePodRequest,
12745
+ edgePodUrl
12263
12746
  ]);
12264
12747
  (0, import_react.useEffect)(function() {
12265
12748
  if (typeof window === "undefined") return;
@@ -12309,10 +12792,13 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
12309
12792
  if (minRemainingMsToStartAd !== void 0) cfg.minRemainingMsToStartAd = minRemainingMsToStartAd;
12310
12793
  if (minRemainingMsToRequestAd !== void 0) cfg.minRemainingMsToRequestAd = minRemainingMsToRequestAd;
12311
12794
  if (maxNoFillsPerBreak !== void 0) cfg.maxNoFillsPerBreak = maxNoFillsPerBreak;
12795
+ if (adFloorLadderEnabled !== void 0) cfg.adFloorLadderEnabled = adFloorLadderEnabled;
12312
12796
  if (adFloorLadder !== void 0) cfg.adFloorLadder = adFloorLadder;
12313
12797
  if (adFloorMinCents !== void 0) cfg.adFloorMinCents = adFloorMinCents;
12314
12798
  if (adFloorMaxCents !== void 0) cfg.adFloorMaxCents = adFloorMaxCents;
12315
12799
  if (adFloorStepCents !== void 0) cfg.adFloorStepCents = adFloorStepCents;
12800
+ if (enableEdgePodRequest !== void 0) cfg.enableEdgePodRequest = enableEdgePodRequest;
12801
+ if (edgePodUrl !== void 0) cfg.edgePodUrl = edgePodUrl;
12316
12802
  var player = new StormcloudVideoPlayer(cfg);
12317
12803
  playerRef.current = player;
12318
12804
  appliedFloorLadderKeyRef.current = adFloorLadderKey;
@@ -12361,6 +12847,14 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
12361
12847
  }, [
12362
12848
  adFloorLadderKey
12363
12849
  ]);
12850
+ (0, import_react.useEffect)(function() {
12851
+ if (!playerRef.current) return;
12852
+ var enabled = adFloorLadderEnabled === true;
12853
+ if (playerRef.current.isAdFloorLadderEnabled() === enabled) return;
12854
+ playerRef.current.setAdFloorLadderEnabled(enabled);
12855
+ }, [
12856
+ adFloorLadderEnabled
12857
+ ]);
12364
12858
  (0, import_react.useEffect)(function() {
12365
12859
  if (!playerRef.current) return;
12366
12860
  var checkAdStatus = function checkAdStatus() {
@@ -13437,6 +13931,9 @@ var StormcloudVideoPlayerComponent = import_react.default.memo(function(props) {
13437
13931
  }
13438
13932
  }
13439
13933
  }
13934
+ if (prevProps.adFloorLadderEnabled !== nextProps.adFloorLadderEnabled) {
13935
+ return false;
13936
+ }
13440
13937
  if (JSON.stringify((_prevProps_adFloorLadder = prevProps.adFloorLadder) !== null && _prevProps_adFloorLadder !== void 0 ? _prevProps_adFloorLadder : null) !== JSON.stringify((_nextProps_adFloorLadder = nextProps.adFloorLadder) !== null && _nextProps_adFloorLadder !== void 0 ? _nextProps_adFloorLadder : null)) {
13441
13938
  return false;
13442
13939
  }