stormcloud-video-player 0.8.73 → 0.8.75

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.
Files changed (61) hide show
  1. package/README.md +10 -70
  2. package/dist/stormcloud-vp.min.js +1 -1
  3. package/lib/Player.d.cts +2 -1
  4. package/lib/StormcloudPlayer.cjs +988 -273
  5. package/lib/StormcloudPlayer.cjs.map +1 -1
  6. package/lib/StormcloudPlayer.d.cts +1 -0
  7. package/lib/index.cjs +999 -278
  8. package/lib/index.cjs.map +1 -1
  9. package/lib/index.d.cts +1 -0
  10. package/lib/index.d.ts +40 -3
  11. package/lib/index.js +992 -279
  12. package/lib/index.js.map +1 -1
  13. package/lib/player/AdBreakOrchestrator.cjs +767 -67
  14. package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
  15. package/lib/player/AdBreakOrchestrator.d.cts +7 -9
  16. package/lib/player/AdConfigManager.cjs +315 -62
  17. package/lib/player/AdConfigManager.cjs.map +1 -1
  18. package/lib/player/AdConfigManager.d.cts +7 -12
  19. package/lib/player/AdTimingService.cjs +37 -1
  20. package/lib/player/AdTimingService.cjs.map +1 -1
  21. package/lib/player/AdTimingService.d.cts +8 -1
  22. package/lib/player/EdgePodRequest.d.cts +1 -0
  23. package/lib/player/FloorLadder.d.cts +1 -0
  24. package/lib/player/HlsEngine.d.cts +1 -0
  25. package/lib/player/OptimizedPodRequest.cjs +719 -0
  26. package/lib/player/OptimizedPodRequest.cjs.map +1 -0
  27. package/lib/player/OptimizedPodRequest.d.cts +101 -0
  28. package/lib/player/PlayerControls.d.cts +1 -0
  29. package/lib/player/Scte35CueManager.d.cts +1 -0
  30. package/lib/player/Scte35Parser.d.cts +1 -0
  31. package/lib/player/StormcloudVideoPlayer.cjs +988 -273
  32. package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
  33. package/lib/player/StormcloudVideoPlayer.d.cts +1 -0
  34. package/lib/player/playerTypes.d.cts +1 -0
  35. package/lib/players/HlsPlayer.cjs +988 -273
  36. package/lib/players/HlsPlayer.cjs.map +1 -1
  37. package/lib/players/HlsPlayer.d.cts +1 -0
  38. package/lib/players/index.cjs +988 -273
  39. package/lib/players/index.cjs.map +1 -1
  40. package/lib/props.d.cts +1 -0
  41. package/lib/sdk/hlsAdPlayer.cjs +316 -51
  42. package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
  43. package/lib/sdk/hlsAdPlayer.d.cts +3 -1
  44. package/lib/sdk/pal.cjs +108 -83
  45. package/lib/sdk/pal.cjs.map +1 -1
  46. package/lib/sdk/pal.d.cts +1 -0
  47. package/lib/types.d.cts +9 -2
  48. package/lib/ui/StormcloudVideoPlayer.cjs +991 -278
  49. package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
  50. package/lib/ui/StormcloudVideoPlayer.d.cts +1 -0
  51. package/lib/utils/ctvVastSignals.cjs +9 -7
  52. package/lib/utils/ctvVastSignals.cjs.map +1 -1
  53. package/lib/utils/tracking.cjs +17 -3
  54. package/lib/utils/tracking.cjs.map +1 -1
  55. package/lib/utils/tracking.d.cts +2 -1
  56. package/lib/utils/vastEnvironmentSignals.cjs +9 -7
  57. package/lib/utils/vastEnvironmentSignals.cjs.map +1 -1
  58. package/lib/utils/vastMacros.cjs +251 -10
  59. package/lib/utils/vastMacros.cjs.map +1 -1
  60. package/lib/utils/vastMacros.d.cts +13 -4
  61. package/package.json +5 -3
@@ -465,21 +465,20 @@ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
465
465
  "adid"
466
466
  ]);
467
467
  function resolveVastEnvironmentSignals(isCtv) {
468
- var _ref;
469
468
  var bridgeSignals = readNativeBridgeSignals();
470
469
  var platformDevice = readPlatformNativeDeviceId();
471
- var realDeviceId = bridgeSignals.deviceId || (isCtv ? readStoredDeviceId() : void 0) || platformDevice.deviceId;
470
+ var bridgeDeviceId = validDeviceId(bridgeSignals.deviceId);
471
+ var realDeviceId = bridgeDeviceId || (isCtv ? validDeviceId(readStoredDeviceId()) : void 0) || validDeviceId(platformDevice.deviceId);
472
472
  var deviceId = realDeviceId;
473
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
474
- var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
475
- var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
473
+ var deviceIdType = (bridgeDeviceId ? bridgeSignals.deviceIdType : void 0) || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
474
+ var platformLat = bridgeDeviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
475
+ var limitAdTracking = deviceId != null ? platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking() : void 0;
476
476
  if (!deviceId && isCtv) {
477
477
  var dpid = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);
478
478
  if (dpid) {
479
- var _ref1;
480
479
  deviceId = dpid;
481
480
  deviceIdType = "dpid";
482
- limitAdTracking = (_ref1 = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref1 !== void 0 ? _ref1 : false;
481
+ limitAdTracking = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking();
483
482
  }
484
483
  }
485
484
  var deviceTypeHint = resolveDeviceTypeHint(isCtv);
@@ -844,6 +843,9 @@ function isMacroPlaceholder(value) {
844
843
  var t = value.trim();
845
844
  return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
846
845
  }
846
+ function validDeviceId(value) {
847
+ return value && !isMacroPlaceholder(value) ? value : void 0;
848
+ }
847
849
  function isZeroedAdId(value) {
848
850
  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
849
851
  }
@@ -1376,6 +1378,199 @@ function ensureVideoAdType(rawUrl) {
1376
1378
  return rawUrl;
1377
1379
  }
1378
1380
  }
1381
+ var SCVP_MACRO_DETECT = /\[SCVP-|%5BSCVP-|\(SCVP-|%28SCVP-/i;
1382
+ var SCVP_MACRO_PATTERN = /\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\)/gi;
1383
+ var SCVP_WHOLE_VALUE_PATTERN = /^\s*(?:\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\))\s*$/i;
1384
+ var NESTED_QUERY_PARAM_KEYS = /* @__PURE__ */ new Set([
1385
+ "cust_params"
1386
+ ]);
1387
+ var SCVP_POD_MACROS = /* @__PURE__ */ new Set([
1388
+ "PMND",
1389
+ "PMXD",
1390
+ "PMAD"
1391
+ ]);
1392
+ function hasScvpMacros(url) {
1393
+ return !!url && SCVP_MACRO_DETECT.test(url);
1394
+ }
1395
+ function safeDecode(value) {
1396
+ try {
1397
+ return decodeURIComponent(value.replace(/\+/g, " "));
1398
+ } catch (unused) {
1399
+ return value;
1400
+ }
1401
+ }
1402
+ function findScvpMacroNames(url) {
1403
+ if (!url) return [];
1404
+ var names = /* @__PURE__ */ new Set();
1405
+ var text = url;
1406
+ for(var pass = 0; pass < 3; pass++){
1407
+ text.replace(SCVP_MACRO_PATTERN, function(_m, bracketName, parenName) {
1408
+ names.add(String(bracketName || parenName).toUpperCase());
1409
+ return "";
1410
+ });
1411
+ var decoded = safeDecode(text);
1412
+ if (decoded === text) break;
1413
+ text = decoded;
1414
+ }
1415
+ return Array.from(names);
1416
+ }
1417
+ function resolveScvpMacroValues(ctx) {
1418
+ var _ctx_deviceId, _ctx_deviceIdType, _ctx_consent, _ctx_consent1, _ctx_consent2;
1419
+ var values = /* @__PURE__ */ new Map();
1420
+ var set = function set(name, value) {
1421
+ if (value == null) return;
1422
+ var str = String(value).trim();
1423
+ if (str) values.set(name, str);
1424
+ };
1425
+ var toFlag = function toFlag(value) {
1426
+ return value == null ? void 0 : value ? "1" : "0";
1427
+ };
1428
+ var deviceId = (_ctx_deviceId = ctx.deviceId) === null || _ctx_deviceId === void 0 ? void 0 : _ctx_deviceId.trim();
1429
+ var deviceIdType = deviceId ? ((_ctx_deviceIdType = ctx.deviceIdType) === null || _ctx_deviceIdType === void 0 ? void 0 : _ctx_deviceIdType.trim()) || inferDeviceIdType() : void 0;
1430
+ if (deviceId && deviceIdType) {
1431
+ var _toFlag;
1432
+ set("RDID", deviceId);
1433
+ set("IDTYPE", deviceIdType);
1434
+ set("IS-LAT", (_toFlag = toFlag(ctx.limitAdTracking)) !== null && _toFlag !== void 0 ? _toFlag : "0");
1435
+ }
1436
+ set("SID", ctx.sessionId);
1437
+ set("DTH", ctx.deviceTypeHint);
1438
+ set("GIVN", ctx.palNonce);
1439
+ set("CT-TI", ctx.programTitle);
1440
+ set("CT-CH", ctx.channelName);
1441
+ set("POD", ctx.pod);
1442
+ set("CORRELATOR", ctx.correlator);
1443
+ set("SCOR", ctx.streamCorrelator);
1444
+ set("VPMUTE", toFlag(ctx.adWillPlayMuted));
1445
+ if (ctx.adWillAutoPlay != null) {
1446
+ set("VPA", ctx.adWillAutoPlay ? "auto" : "click");
1447
+ }
1448
+ set("GDPR", (_ctx_consent = ctx.consent) === null || _ctx_consent === void 0 ? void 0 : _ctx_consent.gdpr);
1449
+ set("GDPR-CONSENT", (_ctx_consent1 = ctx.consent) === null || _ctx_consent1 === void 0 ? void 0 : _ctx_consent1.gdprConsent);
1450
+ set("US-PRIVACY", (_ctx_consent2 = ctx.consent) === null || _ctx_consent2 === void 0 ? void 0 : _ctx_consent2.usPrivacy);
1451
+ return values;
1452
+ }
1453
+ var keepNone = function keepNone() {
1454
+ return false;
1455
+ };
1456
+ function substituteScvpParams(params, values, unresolved, keep, nested) {
1457
+ var out = [];
1458
+ var replaceMacro = function replaceMacro(match, bracketName, parenName) {
1459
+ var name = String(bracketName || parenName).toUpperCase();
1460
+ var value = values.get(name);
1461
+ if (value != null) return value;
1462
+ if (keep(name)) return match;
1463
+ unresolved.add(name);
1464
+ return "";
1465
+ };
1466
+ params.forEach(function(value, key) {
1467
+ var whole = value.match(SCVP_WHOLE_VALUE_PATTERN);
1468
+ if (whole) {
1469
+ var name = String(whole[1] || whole[2]).toUpperCase();
1470
+ var resolved = values.get(name);
1471
+ if (resolved != null) {
1472
+ out.push([
1473
+ key,
1474
+ resolved
1475
+ ]);
1476
+ } else if (keep(name)) {
1477
+ out.push([
1478
+ key,
1479
+ value
1480
+ ]);
1481
+ } else {
1482
+ unresolved.add(name);
1483
+ }
1484
+ return;
1485
+ }
1486
+ if (!SCVP_MACRO_DETECT.test(value)) {
1487
+ out.push([
1488
+ key,
1489
+ value
1490
+ ]);
1491
+ return;
1492
+ }
1493
+ if (!nested && NESTED_QUERY_PARAM_KEYS.has(key)) {
1494
+ var inner = substituteScvpParams(new URLSearchParams(value), values, unresolved, keep, true);
1495
+ if (inner.length > 0) {
1496
+ out.push([
1497
+ key,
1498
+ inner.map(function(param) {
1499
+ var _param = _sliced_to_array(param, 2), k = _param[0], v = _param[1];
1500
+ return "".concat(encodeURIComponent(k), "=").concat(encodeURIComponent(v));
1501
+ }).join("&")
1502
+ ]);
1503
+ }
1504
+ return;
1505
+ }
1506
+ out.push([
1507
+ key,
1508
+ value.replace(SCVP_MACRO_PATTERN, replaceMacro)
1509
+ ]);
1510
+ });
1511
+ return out;
1512
+ }
1513
+ function substituteScvpMacros(baseUrl, values) {
1514
+ var keep = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : keepNone;
1515
+ var unresolved = /* @__PURE__ */ new Set();
1516
+ var url;
1517
+ try {
1518
+ url = new URL(normalizeVastTagUrl(baseUrl));
1519
+ } catch (unused) {
1520
+ var replaced = baseUrl.replace(SCVP_MACRO_PATTERN, function(match, bracketName, parenName) {
1521
+ var name = String(bracketName || parenName).toUpperCase();
1522
+ var value = values.get(name);
1523
+ if (value != null) return encodeURIComponent(value);
1524
+ if (keep(name)) return match;
1525
+ unresolved.add(name);
1526
+ return "";
1527
+ });
1528
+ return {
1529
+ url: replaced,
1530
+ unresolved: Array.from(unresolved)
1531
+ };
1532
+ }
1533
+ var entries = substituteScvpParams(url.searchParams, values, unresolved, keep, false);
1534
+ var search = new URLSearchParams();
1535
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1536
+ try {
1537
+ for(var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1538
+ var _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], value = _step_value[1];
1539
+ search.append(key, value);
1540
+ }
1541
+ } catch (err) {
1542
+ _didIteratorError = true;
1543
+ _iteratorError = err;
1544
+ } finally{
1545
+ try {
1546
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1547
+ _iterator.return();
1548
+ }
1549
+ } finally{
1550
+ if (_didIteratorError) {
1551
+ throw _iteratorError;
1552
+ }
1553
+ }
1554
+ }
1555
+ url.search = search.toString();
1556
+ return {
1557
+ url: url.toString(),
1558
+ unresolved: Array.from(unresolved)
1559
+ };
1560
+ }
1561
+ function applyScvpMacros(baseUrl, ctx) {
1562
+ var deferred = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : /* @__PURE__ */ new Set();
1563
+ return substituteScvpMacros(baseUrl, resolveScvpMacroValues(ctx), function(name) {
1564
+ return deferred.has(name);
1565
+ });
1566
+ }
1567
+ function stripScvpMacros(url) {
1568
+ if (findScvpMacroNames(url).length === 0) return {
1569
+ url: url,
1570
+ unresolved: []
1571
+ };
1572
+ return substituteScvpMacros(url, /* @__PURE__ */ new Map());
1573
+ }
1379
1574
  function applyVastMacros(baseUrl, ctx) {
1380
1575
  var expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);
1381
1576
  var url;
@@ -1417,15 +1612,6 @@ function applyVastMacros(baseUrl, ctx) {
1417
1612
  }
1418
1613
  params.delete("ppos");
1419
1614
  params.delete("lip");
1420
- if (ctx.podMinDurationMs != null) {
1421
- params.set("pmnd", String(Math.max(0, Math.round(ctx.podMinDurationMs))));
1422
- }
1423
- if (ctx.podMaxDurationMs != null) {
1424
- params.set("pmxd", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));
1425
- }
1426
- if (ctx.podMaxAds != null) {
1427
- params.set("pmad", String(Math.max(1, Math.round(ctx.podMaxAds))));
1428
- }
1429
1615
  var existingUrl = params.get("url") || "";
1430
1616
  if (EXAMPLE_COM_URL.test(existingUrl)) {
1431
1617
  params.delete("url");
@@ -2255,6 +2441,309 @@ function substituteVastTrackingMacros(url) {
2255
2441
  return KNOWN_VAST_MACROS.has(name) ? "" : match;
2256
2442
  });
2257
2443
  }
2444
+ // src/player/OptimizedPodRequest.ts
2445
+ var DEFAULT_REQUEST_SAFETY_MS = 1500;
2446
+ var GAM_AD_OPPORTUNITY_DURATION_MS = 3e4;
2447
+ var POD_PARAM_KEYS = [
2448
+ "pmnd",
2449
+ "pmxd",
2450
+ "pmad"
2451
+ ];
2452
+ var POSITIVE_INT = /^[1-9]\d*$/;
2453
+ var NON_NEGATIVE_INT = /^(0|[1-9]\d*)$/;
2454
+ function nonNegativeInt(value) {
2455
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : void 0;
2456
+ }
2457
+ function positiveInt(value) {
2458
+ return typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : void 0;
2459
+ }
2460
+ function resolveAdPodConfig(config) {
2461
+ var _config_adPodConfig, _nonNegativeInt, _nonNegativeInt1, _positiveInt;
2462
+ var pod = (_config_adPodConfig = config.adPodConfig) !== null && _config_adPodConfig !== void 0 ? _config_adPodConfig : {};
2463
+ return {
2464
+ requestSafetyMs: (_nonNegativeInt = nonNegativeInt(pod.requestSafetyMs)) !== null && _nonNegativeInt !== void 0 ? _nonNegativeInt : DEFAULT_REQUEST_SAFETY_MS,
2465
+ minPodDurationMs: (_nonNegativeInt1 = nonNegativeInt(pod.minPodDurationMs)) !== null && _nonNegativeInt1 !== void 0 ? _nonNegativeInt1 : 0,
2466
+ maxAdsPerBreak: pod.maxAdsPerBreak === void 0 ? positiveInt(config.podMaxAds) : positiveInt(pod.maxAdsPerBreak),
2467
+ maxPodDurationMs: (_positiveInt = positiveInt(pod.maxPodDurationMs)) !== null && _positiveInt !== void 0 ? _positiveInt : positiveInt(config.podMaxDurationMs),
2468
+ exactDuration: config.podExactDuration === true
2469
+ };
2470
+ }
2471
+ function measureBreakCapacity(timing, nowMonoMs) {
2472
+ var _timing_breakEndMonoMs;
2473
+ var scheduled = timing.scheduledBreakDurationMs;
2474
+ if (scheduled == null || !(scheduled > 0) || timing.breakStartMonoMs == null) {
2475
+ return void 0;
2476
+ }
2477
+ var endMonoMs = (_timing_breakEndMonoMs = timing.breakEndMonoMs) !== null && _timing_breakEndMonoMs !== void 0 ? _timing_breakEndMonoMs : timing.breakStartMonoMs + scheduled;
2478
+ var untilEnd = Math.min(scheduled, endMonoMs - nowMonoMs);
2479
+ var unplayed = scheduled - Math.max(0, timing.playedDurationMs);
2480
+ return {
2481
+ scheduledBreakDurationMs: scheduled,
2482
+ elapsedBeforeGamRequestMs: Math.max(0, nowMonoMs - timing.breakStartMonoMs),
2483
+ remainingAtGamDispatchMs: Math.max(0, Math.min(untilEnd, unplayed))
2484
+ };
2485
+ }
2486
+ function resolvePodParams(input) {
2487
+ var capacity = input.capacity, config = input.config;
2488
+ var pmxd;
2489
+ var source;
2490
+ if (capacity) {
2491
+ pmxd = Math.floor(capacity.remainingAtGamDispatchMs - config.requestSafetyMs);
2492
+ source = "break_remaining";
2493
+ } else if (config.maxPodDurationMs != null) {
2494
+ pmxd = config.maxPodDurationMs;
2495
+ source = "configured_cap";
2496
+ } else if (input.tagMaxDurationMs != null) {
2497
+ pmxd = input.tagMaxDurationMs;
2498
+ source = "tag_cap";
2499
+ } else {
2500
+ return {
2501
+ kind: "omit"
2502
+ };
2503
+ }
2504
+ var minUsable = Math.max(1, Math.floor(input.minUsablePmxdMs));
2505
+ if (!Number.isFinite(pmxd) || pmxd < minUsable) {
2506
+ return {
2507
+ kind: "abort",
2508
+ reason: capacity ? "insufficient_break_capacity" : "invalid_pod_cap",
2509
+ pmxdCandidateMs: Number.isFinite(pmxd) ? pmxd : 0
2510
+ };
2511
+ }
2512
+ var pmnd = config.exactDuration ? pmxd : Math.min(config.minPodDurationMs, pmxd);
2513
+ return {
2514
+ kind: "send",
2515
+ params: {
2516
+ pmnd: pmnd,
2517
+ pmxd: pmxd,
2518
+ pmad: config.maxAdsPerBreak
2519
+ },
2520
+ source: source
2521
+ };
2522
+ }
2523
+ function podRequestAborted(reason, message, diagnostics) {
2524
+ var error = new Error("Optimized pod request not sent (".concat(reason, "): ").concat(message));
2525
+ error.podRequestAborted = true;
2526
+ error.reason = reason;
2527
+ error.diagnostics = diagnostics;
2528
+ return error;
2529
+ }
2530
+ function isPodRequestAbortedError(error) {
2531
+ return !!error && error.podRequestAborted === true;
2532
+ }
2533
+ function firstPositiveIntParam(params, key) {
2534
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2535
+ try {
2536
+ for(var _iterator = params.getAll(key)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2537
+ var value = _step.value;
2538
+ if (POSITIVE_INT.test(value.trim())) return Number(value.trim());
2539
+ }
2540
+ } catch (err) {
2541
+ _didIteratorError = true;
2542
+ _iteratorError = err;
2543
+ } finally{
2544
+ try {
2545
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2546
+ _iterator.return();
2547
+ }
2548
+ } finally{
2549
+ if (_didIteratorError) {
2550
+ throw _iteratorError;
2551
+ }
2552
+ }
2553
+ }
2554
+ return void 0;
2555
+ }
2556
+ function isOptimizedPodUrl(url) {
2557
+ if (findScvpMacroNames(url).some(function(name) {
2558
+ return SCVP_POD_MACROS.has(name);
2559
+ })) return true;
2560
+ try {
2561
+ var params = new URL(url).searchParams;
2562
+ return POD_PARAM_KEYS.some(function(key) {
2563
+ return params.has(key);
2564
+ });
2565
+ } catch (unused) {
2566
+ return false;
2567
+ }
2568
+ }
2569
+ function finalizeGamRequestUrl(rawUrl, ctx) {
2570
+ var nowEpochMs = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : Date.now();
2571
+ var optimizedPod = isOptimizedPodUrl(rawUrl);
2572
+ var capacity = ctx.capacity;
2573
+ var base = {
2574
+ breakId: ctx.breakId,
2575
+ optimizedPod: optimizedPod,
2576
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2577
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2578
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2579
+ safetyReserveMs: ctx.config.requestSafetyMs
2580
+ };
2581
+ var decision = {
2582
+ kind: "omit"
2583
+ };
2584
+ if (optimizedPod) {
2585
+ var tagMaxDurationMs;
2586
+ try {
2587
+ tagMaxDurationMs = firstPositiveIntParam(new URL(rawUrl).searchParams, "pmxd");
2588
+ } catch (unused) {}
2589
+ decision = resolvePodParams({
2590
+ capacity: capacity,
2591
+ config: ctx.config,
2592
+ minUsablePmxdMs: ctx.minUsablePmxdMs,
2593
+ tagMaxDurationMs: tagMaxDurationMs
2594
+ });
2595
+ if (decision.kind === "abort") {
2596
+ throw podRequestAborted(decision.reason, "pmxd would be ".concat(decision.pmxdCandidateMs, "ms (minimum ").concat(ctx.minUsablePmxdMs, "ms)"), base);
2597
+ }
2598
+ }
2599
+ var pod = decision.kind === "send" ? decision.params : void 0;
2600
+ var values = /* @__PURE__ */ new Map();
2601
+ if (pod) {
2602
+ values.set("PMND", String(pod.pmnd));
2603
+ values.set("PMXD", String(pod.pmxd));
2604
+ if (pod.pmad != null) values.set("PMAD", String(pod.pmad));
2605
+ }
2606
+ var substituted = substituteScvpMacros(rawUrl, values);
2607
+ var finalUrl;
2608
+ try {
2609
+ var url = new URL(normalizeVastTagUrl(substituted.url));
2610
+ if (pod) {
2611
+ url.searchParams.set("pmnd", String(pod.pmnd));
2612
+ url.searchParams.set("pmxd", String(pod.pmxd));
2613
+ if (pod.pmad != null) url.searchParams.set("pmad", String(pod.pmad));
2614
+ else url.searchParams.delete("pmad");
2615
+ } else {
2616
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2617
+ try {
2618
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2619
+ var key = _step.value;
2620
+ url.searchParams.delete(key);
2621
+ }
2622
+ } catch (err) {
2623
+ _didIteratorError = true;
2624
+ _iteratorError = err;
2625
+ } finally{
2626
+ try {
2627
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2628
+ _iterator.return();
2629
+ }
2630
+ } finally{
2631
+ if (_didIteratorError) {
2632
+ throw _iteratorError;
2633
+ }
2634
+ }
2635
+ }
2636
+ }
2637
+ finalUrl = url.toString();
2638
+ } catch (unused) {
2639
+ throw podRequestAborted("invalid_url", "GAM request URL could not be parsed", base);
2640
+ }
2641
+ var problems = validateGamRequestUrl(finalUrl, {
2642
+ optimizedPod: !!pod,
2643
+ remainingMs: decision.kind === "send" && decision.source === "break_remaining" ? capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs : void 0
2644
+ });
2645
+ if (problems.length > 0) {
2646
+ throw podRequestAborted("invalid_url", problems.join("; "), base);
2647
+ }
2648
+ var givn = null;
2649
+ try {
2650
+ givn = new URL(finalUrl).searchParams.get("givn");
2651
+ } catch (unused) {}
2652
+ return {
2653
+ url: finalUrl,
2654
+ diagnostics: {
2655
+ breakId: ctx.breakId,
2656
+ optimizedPod: !!pod,
2657
+ pmxdSource: decision.kind === "send" ? decision.source : void 0,
2658
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2659
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2660
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2661
+ safetyReserveMs: ctx.config.requestSafetyMs,
2662
+ pmndSent: pod === null || pod === void 0 ? void 0 : pod.pmnd,
2663
+ pmxdSent: pod === null || pod === void 0 ? void 0 : pod.pmxd,
2664
+ pmadSent: pod === null || pod === void 0 ? void 0 : pod.pmad,
2665
+ palNoncePresent: !!givn,
2666
+ gamRequestDispatchTimestamp: new Date(nowEpochMs).toISOString(),
2667
+ strippedMacros: substituted.unresolved.filter(function(name) {
2668
+ return !SCVP_POD_MACROS.has(name);
2669
+ })
2670
+ }
2671
+ };
2672
+ }
2673
+ function validateGamRequestUrl(url, expect) {
2674
+ var problems = [];
2675
+ var leftover = findScvpMacroNames(url);
2676
+ if (leftover.length > 0) problems.push("unresolved SCVP macros: ".concat(leftover.join(", ")));
2677
+ var params;
2678
+ try {
2679
+ params = new URL(url).searchParams;
2680
+ } catch (unused) {
2681
+ return problems.concat("URL could not be parsed");
2682
+ }
2683
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2684
+ try {
2685
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2686
+ var key = _step.value;
2687
+ if (params.getAll(key).length > 1) problems.push("duplicate ".concat(key));
2688
+ }
2689
+ } catch (err) {
2690
+ _didIteratorError = true;
2691
+ _iteratorError = err;
2692
+ } finally{
2693
+ try {
2694
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2695
+ _iterator.return();
2696
+ }
2697
+ } finally{
2698
+ if (_didIteratorError) {
2699
+ throw _iteratorError;
2700
+ }
2701
+ }
2702
+ }
2703
+ if (!expect.optimizedPod) {
2704
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
2705
+ try {
2706
+ for(var _iterator1 = POD_PARAM_KEYS[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
2707
+ var key1 = _step1.value;
2708
+ if (params.has(key1)) problems.push("".concat(key1, " present on a non-pod request"));
2709
+ }
2710
+ } catch (err) {
2711
+ _didIteratorError1 = true;
2712
+ _iteratorError1 = err;
2713
+ } finally{
2714
+ try {
2715
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
2716
+ _iterator1.return();
2717
+ }
2718
+ } finally{
2719
+ if (_didIteratorError1) {
2720
+ throw _iteratorError1;
2721
+ }
2722
+ }
2723
+ }
2724
+ return problems;
2725
+ }
2726
+ var pmxd = params.get("pmxd");
2727
+ var pmnd = params.get("pmnd");
2728
+ var pmad = params.get("pmad");
2729
+ if (pmxd == null || !POSITIVE_INT.test(pmxd)) problems.push("pmxd must be a positive integer (got ".concat(pmxd, ")"));
2730
+ if (pmnd == null || !NON_NEGATIVE_INT.test(pmnd)) problems.push("pmnd must be a non-negative integer (got ".concat(pmnd, ")"));
2731
+ if (pmxd != null && pmnd != null && Number(pmnd) > Number(pmxd)) problems.push("pmnd exceeds pmxd");
2732
+ if (pmad != null && !POSITIVE_INT.test(pmad)) problems.push("pmad must be a positive integer or absent (got ".concat(pmad, ")"));
2733
+ if (expect.remainingMs != null && pmxd != null && Number(pmxd) > expect.remainingMs) {
2734
+ problems.push("pmxd ".concat(pmxd, " exceeds remaining break ").concat(expect.remainingMs, "ms"));
2735
+ }
2736
+ return problems;
2737
+ }
2738
+ function computePodResponseDiagnostics(pmxdSent, vastAdCount, totalVastCreativeDurationMs) {
2739
+ var estimatedUnusedPodMs = Math.max(0, pmxdSent - totalVastCreativeDurationMs);
2740
+ return {
2741
+ vastAdCount: vastAdCount,
2742
+ totalVastCreativeDurationMs: totalVastCreativeDurationMs,
2743
+ estimatedUnusedPodMs: estimatedUnusedPodMs,
2744
+ estimatedUnmatchedCount: Math.floor(estimatedUnusedPodMs / GAM_AD_OPPORTUNITY_DURATION_MS)
2745
+ };
2746
+ }
2258
2747
  // src/sdk/hlsAdPlayer.ts
2259
2748
  var LINEAR_TRACKING_EVENTS = [
2260
2749
  "creativeView",
@@ -2335,6 +2824,7 @@ function toVastMediaErrorCode(error) {
2335
2824
  return VAST_ERROR_MEDIA_DISPLAY;
2336
2825
  }
2337
2826
  }
2827
+ var gamCredentialsMode = "include";
2338
2828
  function createHlsAdPlayer(contentVideo, options) {
2339
2829
  var _contentVideo_AD_VIDEO_PROP, _contentVideo_AD_CONTAINER_PROP, _ref;
2340
2830
  var adPlaying = false;
@@ -3206,9 +3696,9 @@ function createHlsAdPlayer(contentVideo, options) {
3206
3696
  }
3207
3697
  }
3208
3698
  function fetchVastXml(vastTagUrl) {
3209
- var credentials = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "include", kind = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "gam";
3699
+ var credentials = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "include", kind = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "gam", finalizeRequestUrl = arguments.length > 3 ? arguments[3] : void 0;
3210
3700
  return _async_to_generator(function() {
3211
- var controller, timeoutId, startedAt, attempt, requestVast, response, error, error1;
3701
+ var controller, timeoutId, startedAt, attempt, resolveDispatchUrl, requestVast, response, error, error1;
3212
3702
  return _ts_generator(this, function(_state) {
3213
3703
  switch(_state.label){
3214
3704
  case 0:
@@ -3222,13 +3712,32 @@ function createHlsAdPlayer(contentVideo, options) {
3222
3712
  }, VAST_REQUEST_TIMEOUT_MS) : void 0;
3223
3713
  startedAt = Date.now();
3224
3714
  attempt = 0;
3715
+ resolveDispatchUrl = function resolveDispatchUrl() {
3716
+ if (kind === "wrapper") return vastTagUrl;
3717
+ if (finalizeRequestUrl) return finalizeRequestUrl(vastTagUrl, attempt);
3718
+ var _stripScvpMacros = stripScvpMacros(vastTagUrl), url = _stripScvpMacros.url, unresolved = _stripScvpMacros.unresolved;
3719
+ if (unresolved.length > 0) {
3720
+ console.warn("[HlsAdPlayer] Removed unresolved SCVP macros before dispatch:", unresolved.join(", "));
3721
+ }
3722
+ return url;
3723
+ };
3225
3724
  requestVast = function requestVast(creds) {
3226
3725
  return _async_to_generator(function() {
3227
- var response;
3726
+ var pending, response;
3228
3727
  return _ts_generator(this, function(_state) {
3229
3728
  switch(_state.label){
3230
3729
  case 0:
3231
3730
  attempt++;
3731
+ pending = fetch(resolveDispatchUrl(), _object_spread({
3732
+ mode: "cors",
3733
+ credentials: creds,
3734
+ headers: {
3735
+ "Accept": "application/xml, text/xml, */*"
3736
+ },
3737
+ referrerPolicy: "no-referrer-when-downgrade"
3738
+ }, controller ? {
3739
+ signal: controller.signal
3740
+ } : {}));
3232
3741
  if (kind !== "wrapper") {
3233
3742
  logFunnel("".concat(kind, "_http_request_sent"), {
3234
3743
  attempt: attempt,
@@ -3237,16 +3746,7 @@ function createHlsAdPlayer(contentVideo, options) {
3237
3746
  }
3238
3747
  return [
3239
3748
  4,
3240
- fetch(vastTagUrl, _object_spread({
3241
- mode: "cors",
3242
- credentials: creds,
3243
- headers: {
3244
- "Accept": "application/xml, text/xml, */*"
3245
- },
3246
- referrerPolicy: "no-referrer-when-downgrade"
3247
- }, controller ? {
3248
- signal: controller.signal
3249
- } : {}))
3749
+ pending
3250
3750
  ];
3251
3751
  case 1:
3252
3752
  response = _state.sent();
@@ -3270,9 +3770,9 @@ function createHlsAdPlayer(contentVideo, options) {
3270
3770
  case 1:
3271
3771
  _state.trys.push([
3272
3772
  1,
3273
- 10,
3274
- 11,
3275
- 12
3773
+ 7,
3774
+ 8,
3775
+ 9
3276
3776
  ]);
3277
3777
  _state.label = 2;
3278
3778
  case 2:
@@ -3280,7 +3780,7 @@ function createHlsAdPlayer(contentVideo, options) {
3280
3780
  2,
3281
3781
  4,
3282
3782
  ,
3283
- 8
3783
+ 5
3284
3784
  ]);
3285
3785
  return [
3286
3786
  4,
@@ -3290,36 +3790,21 @@ function createHlsAdPlayer(contentVideo, options) {
3290
3790
  response = _state.sent();
3291
3791
  return [
3292
3792
  3,
3293
- 8
3793
+ 5
3294
3794
  ];
3295
3795
  case 4:
3296
3796
  error = _state.sent();
3297
- if (!(credentials !== "omit" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted))) return [
3298
- 3,
3299
- 6
3300
- ];
3301
- console.warn('[HlsAdPlayer] VAST fetch failed with credentials="'.concat(credentials, '", retrying without credentials:'), error);
3302
- logFunnel("vast_credentials_retry", {
3303
- errorMessage: error === null || error === void 0 ? void 0 : error.message
3304
- });
3305
- return [
3306
- 4,
3307
- requestVast("omit")
3308
- ];
3309
- case 5:
3310
- response = _state.sent();
3311
- return [
3312
- 3,
3313
- 7
3314
- ];
3315
- case 6:
3797
+ if (kind === "gam" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted) && !isPodRequestAbortedError(error)) {
3798
+ gamCredentialsMode = credentials === "include" ? "omit" : "include";
3799
+ console.warn('[HlsAdPlayer] GAM fetch failed with credentials="'.concat(credentials, '"; next GAM request will use credentials="').concat(gamCredentialsMode, '":'), error);
3800
+ logFunnel("gam_credentials_mode_changed", {
3801
+ from: credentials,
3802
+ to: gamCredentialsMode,
3803
+ errorMessage: error === null || error === void 0 ? void 0 : error.message
3804
+ });
3805
+ }
3316
3806
  throw error;
3317
- case 7:
3318
- return [
3319
- 3,
3320
- 8
3321
- ];
3322
- case 8:
3807
+ case 5:
3323
3808
  if (!response.ok) {
3324
3809
  throw new Error("Failed to fetch VAST: HTTP ".concat(response.status, " ").concat(response.statusText));
3325
3810
  }
@@ -3327,12 +3812,12 @@ function createHlsAdPlayer(contentVideo, options) {
3327
3812
  4,
3328
3813
  response.text()
3329
3814
  ];
3330
- case 9:
3815
+ case 6:
3331
3816
  return [
3332
3817
  2,
3333
3818
  _state.sent()
3334
3819
  ];
3335
- case 10:
3820
+ case 7:
3336
3821
  error1 = _state.sent();
3337
3822
  if (controller === null || controller === void 0 ? void 0 : controller.signal.aborted) {
3338
3823
  if (pendingRequestAbortReason) {
@@ -3341,13 +3826,13 @@ function createHlsAdPlayer(contentVideo, options) {
3341
3826
  throw new Error("VAST request timeout after ".concat(VAST_REQUEST_TIMEOUT_MS, "ms: ").concat(vastTagUrl));
3342
3827
  }
3343
3828
  throw error1;
3344
- case 11:
3829
+ case 8:
3345
3830
  if (timeoutId !== void 0) clearTimeout(timeoutId);
3346
3831
  if (controller) pendingVastRequests.delete(controller);
3347
3832
  return [
3348
3833
  7
3349
3834
  ];
3350
- case 12:
3835
+ case 9:
3351
3836
  return [
3352
3837
  2
3353
3838
  ];
@@ -3480,7 +3965,7 @@ function createHlsAdPlayer(contentVideo, options) {
3480
3965
  });
3481
3966
  }
3482
3967
  function fetchAndParsePod(vastTagUrl) {
3483
- var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam";
3968
+ var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam", finalizeRequestUrl = arguments.length > 2 ? arguments[2] : void 0;
3484
3969
  return _async_to_generator(function() {
3485
3970
  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;
3486
3971
  return _ts_generator(this, function(_state) {
@@ -3490,7 +3975,7 @@ function createHlsAdPlayer(contentVideo, options) {
3490
3975
  isEdge = source === "edge";
3491
3976
  return [
3492
3977
  4,
3493
- fetchVastXml(vastTagUrl, isEdge ? "omit" : "include", source)
3978
+ fetchVastXml(vastTagUrl, isEdge ? "omit" : gamCredentialsMode, source, finalizeRequestUrl)
3494
3979
  ];
3495
3980
  case 1:
3496
3981
  vastXml = _state.sent();
@@ -4813,7 +5298,7 @@ function createHlsAdPlayer(contentVideo, options) {
4813
5298
  case 2:
4814
5299
  return [
4815
5300
  4,
4816
- fetchAndParsePod(vastTagUrl, source)
5301
+ fetchAndParsePod(vastTagUrl, source, requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.finalizeRequestUrl)
4817
5302
  ];
4818
5303
  case 3:
4819
5304
  ads = _state.sent();
@@ -5390,95 +5875,38 @@ function getOrCreateNonceLoader(allowStorage) {
5390
5875
  function createPalNonceManager() {
5391
5876
  var currentNonce = "";
5392
5877
  var currentNonceManager;
5878
+ var pendingNonce;
5393
5879
  return {
5394
5880
  generateNonce: function generateNonce() {
5395
- return _async_to_generator(function() {
5396
- var options, _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5397
- var _arguments = arguments;
5398
- return _ts_generator(this, function(_state) {
5399
- switch(_state.label){
5400
- case 0:
5401
- options = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {};
5402
- _state.label = 1;
5403
- case 1:
5404
- _state.trys.push([
5405
- 1,
5406
- 4,
5407
- ,
5408
- 5
5409
- ]);
5410
- return [
5411
- 4,
5412
- loadPalSdk()
5413
- ];
5414
- case 2:
5415
- _state.sent();
5416
- loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5417
- goog = window.goog;
5418
- request = new goog.pal.NonceRequest();
5419
- request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5420
- request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5421
- request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5422
- request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5423
- request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5424
- request.iconsSupported = true;
5425
- request.playerType = "StormcloudVideoPlayer";
5426
- request.playerVersion = "1.0";
5427
- request.supportedApiFrameworks = "2,7,9";
5428
- request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5429
- request.videoWidth = options.videoWidth || 640;
5430
- request.videoHeight = options.videoHeight || 480;
5431
- if (options.ppid) request.ppid = options.ppid;
5432
- if (options.sessionId) request.sessionId = options.sessionId;
5433
- console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5434
- adWillAutoPlay: request.adWillAutoPlay,
5435
- adWillPlayMuted: request.adWillPlayMuted,
5436
- playerVolume: request.playerVolume,
5437
- continuousPlayback: request.continuousPlayback,
5438
- descriptionUrl: request.descriptionUrl,
5439
- iconsSupported: request.iconsSupported,
5440
- playerType: request.playerType,
5441
- playerVersion: request.playerVersion,
5442
- supportedApiFrameworks: request.supportedApiFrameworks,
5443
- url: request.url,
5444
- videoWidth: request.videoWidth,
5445
- videoHeight: request.videoHeight,
5446
- ppid: request.ppid,
5447
- sessionId: request.sessionId
5448
- }, null, 2));
5449
- return [
5450
- 4,
5451
- loader.loadNonceManager(request)
5452
- ];
5453
- case 3:
5454
- manager = _state.sent();
5455
- currentNonceManager = manager;
5456
- currentNonce = manager.getNonce();
5457
- console.log("[PAL] Nonce generated successfully");
5458
- return [
5459
- 2,
5460
- currentNonce
5461
- ];
5462
- case 4:
5463
- error = _state.sent();
5464
- console.warn("[PAL] Failed to generate nonce:", error);
5465
- currentNonce = "";
5466
- currentNonceManager = void 0;
5467
- return [
5468
- 2,
5469
- ""
5470
- ];
5471
- case 5:
5472
- return [
5473
- 2
5474
- ];
5475
- }
5476
- });
5477
- }).apply(this, arguments);
5881
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
5882
+ var run = generate(options);
5883
+ pendingNonce = run;
5884
+ var settle = function settle() {
5885
+ if (pendingNonce === run) pendingNonce = void 0;
5886
+ };
5887
+ run.then(settle, settle);
5888
+ return run;
5478
5889
  },
5479
5890
  getCurrentNonce: function getCurrentNonce() {
5480
5891
  return currentNonce;
5481
5892
  },
5893
+ waitForNonce: function waitForNonce(maxWaitMs) {
5894
+ if (currentNonce) return Promise.resolve(currentNonce);
5895
+ var pending = pendingNonce;
5896
+ if (!pending || !(maxWaitMs > 0)) return Promise.resolve("");
5897
+ return new Promise(function(resolve) {
5898
+ var timer = setTimeout(function() {
5899
+ return resolve(currentNonce);
5900
+ }, maxWaitMs);
5901
+ pending.then(function(nonce) {
5902
+ clearTimeout(timer);
5903
+ resolve(nonce);
5904
+ }, function() {
5905
+ clearTimeout(timer);
5906
+ resolve("");
5907
+ });
5908
+ });
5909
+ },
5482
5910
  injectNonce: function injectNonce(vastTagUrl) {
5483
5911
  if (!currentNonce || !vastTagUrl) return vastTagUrl;
5484
5912
  try {
@@ -5515,8 +5943,90 @@ function createPalNonceManager() {
5515
5943
  reset: function reset() {
5516
5944
  currentNonce = "";
5517
5945
  currentNonceManager = void 0;
5946
+ pendingNonce = void 0;
5518
5947
  }
5519
5948
  };
5949
+ function generate(options) {
5950
+ return _async_to_generator(function() {
5951
+ var _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5952
+ return _ts_generator(this, function(_state) {
5953
+ switch(_state.label){
5954
+ case 0:
5955
+ _state.trys.push([
5956
+ 0,
5957
+ 3,
5958
+ ,
5959
+ 4
5960
+ ]);
5961
+ return [
5962
+ 4,
5963
+ loadPalSdk()
5964
+ ];
5965
+ case 1:
5966
+ _state.sent();
5967
+ loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5968
+ goog = window.goog;
5969
+ request = new goog.pal.NonceRequest();
5970
+ request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5971
+ request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5972
+ request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5973
+ request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5974
+ request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5975
+ request.iconsSupported = true;
5976
+ request.playerType = "StormcloudVideoPlayer";
5977
+ request.playerVersion = "1.0";
5978
+ request.supportedApiFrameworks = "2,7,9";
5979
+ request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5980
+ request.videoWidth = options.videoWidth || 640;
5981
+ request.videoHeight = options.videoHeight || 480;
5982
+ if (options.ppid) request.ppid = options.ppid;
5983
+ if (options.sessionId) request.sessionId = options.sessionId;
5984
+ console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5985
+ adWillAutoPlay: request.adWillAutoPlay,
5986
+ adWillPlayMuted: request.adWillPlayMuted,
5987
+ playerVolume: request.playerVolume,
5988
+ continuousPlayback: request.continuousPlayback,
5989
+ descriptionUrl: request.descriptionUrl,
5990
+ iconsSupported: request.iconsSupported,
5991
+ playerType: request.playerType,
5992
+ playerVersion: request.playerVersion,
5993
+ supportedApiFrameworks: request.supportedApiFrameworks,
5994
+ url: request.url,
5995
+ videoWidth: request.videoWidth,
5996
+ videoHeight: request.videoHeight,
5997
+ ppid: request.ppid,
5998
+ sessionId: request.sessionId
5999
+ }, null, 2));
6000
+ return [
6001
+ 4,
6002
+ loader.loadNonceManager(request)
6003
+ ];
6004
+ case 2:
6005
+ manager = _state.sent();
6006
+ currentNonceManager = manager;
6007
+ currentNonce = manager.getNonce();
6008
+ console.log("[PAL] Nonce generated successfully");
6009
+ return [
6010
+ 2,
6011
+ currentNonce
6012
+ ];
6013
+ case 3:
6014
+ error = _state.sent();
6015
+ console.warn("[PAL] Failed to generate nonce:", error);
6016
+ currentNonce = "";
6017
+ currentNonceManager = void 0;
6018
+ return [
6019
+ 2,
6020
+ ""
6021
+ ];
6022
+ case 4:
6023
+ return [
6024
+ 2
6025
+ ];
6026
+ }
6027
+ });
6028
+ })();
6029
+ }
5520
6030
  }
5521
6031
  // src/utils/trackingIngest.ts
5522
6032
  var DEFAULT_TRACKING_INGEST_CONFIG = {
@@ -5599,7 +6109,14 @@ function ingestPlayerTracking(licenseKey, channel, body) {
5599
6109
  // src/utils/tracking.ts
5600
6110
  var cachedBrowserId = null;
5601
6111
  function buildAnalyticsContext(config) {
6112
+ var _config_contentNetwork, _config_channelName, _config_programTitle;
5602
6113
  var context = {};
6114
+ var contentNetwork = (_config_contentNetwork = config.contentNetwork) === null || _config_contentNetwork === void 0 ? void 0 : _config_contentNetwork.trim();
6115
+ var contentChannel = (_config_channelName = config.channelName) === null || _config_channelName === void 0 ? void 0 : _config_channelName.trim();
6116
+ var contentTitle = (_config_programTitle = config.programTitle) === null || _config_programTitle === void 0 ? void 0 : _config_programTitle.trim();
6117
+ if (contentNetwork) context.contentNetwork = contentNetwork;
6118
+ if (contentChannel) context.contentChannel = contentChannel;
6119
+ if (contentTitle) context.contentTitle = contentTitle;
5603
6120
  if (config.debugAdTiming) {
5604
6121
  context.debugAdTiming = true;
5605
6122
  }
@@ -6090,12 +6607,19 @@ function sendAdImpressionTracking(_0, _1) {
6090
6607
  4,
6091
6608
  ingestPlayerTracking(licenseKey, "impressions", {
6092
6609
  events: [
6093
- {
6610
+ _object_spread({
6094
6611
  player_id: metricEvent.player_id,
6095
6612
  ad_played_count: 1,
6096
6613
  ad_url: adImpressionInfo.adUrl,
6097
- capture_at: adImpressionInfo.timestamp
6098
- }
6614
+ capture_at: adImpressionInfo.timestamp,
6615
+ source: "gam"
6616
+ }, context.contentNetwork ? {
6617
+ content_network: context.contentNetwork
6618
+ } : {}, context.contentChannel ? {
6619
+ content_channel: context.contentChannel
6620
+ } : {}, context.contentTitle ? {
6621
+ content_title: context.contentTitle
6622
+ } : {})
6099
6623
  ]
6100
6624
  })
6101
6625
  ];
@@ -7444,6 +7968,21 @@ var Scte35CueManager = /*#__PURE__*/ function() {
7444
7968
  return Scte35CueManager;
7445
7969
  }();
7446
7970
  // src/player/AdConfigManager.ts
7971
+ function withDeferredPodParams(rawUrl, deferNonce) {
7972
+ try {
7973
+ var url = new URL(rawUrl);
7974
+ url.searchParams.set("pmnd", "[SCVP-PMND]");
7975
+ url.searchParams.set("pmxd", "[SCVP-PMXD]");
7976
+ url.searchParams.set("pmad", "[SCVP-PMAD]");
7977
+ if (deferNonce && !url.searchParams.get("givn")) {
7978
+ url.searchParams.delete("paln");
7979
+ url.searchParams.set("givn", "[SCVP-GIVN]");
7980
+ }
7981
+ return url.toString();
7982
+ } catch (unused) {
7983
+ return rawUrl;
7984
+ }
7985
+ }
7447
7986
  var AdConfigManager = /*#__PURE__*/ function() {
7448
7987
  function AdConfigManager(config, video) {
7449
7988
  _class_call_check(this, AdConfigManager);
@@ -7454,8 +7993,8 @@ var AdConfigManager = /*#__PURE__*/ function() {
7454
7993
  this.podCounter = 0;
7455
7994
  this.podAssignedByPrefetch = false;
7456
7995
  this.lastHeartbeatTime = 0;
7457
- this.defaultPodMaxAds = 6;
7458
- this.defaultPodMaxDurationMs = 12e4;
7996
+ this.defaultEdgePodMaxAds = 6;
7997
+ this.palNonceDispatchWaitMs = 1500;
7459
7998
  this.config = config;
7460
7999
  this.video = video;
7461
8000
  }
@@ -7483,7 +8022,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7483
8022
  key: "fetchAdConfiguration",
7484
8023
  value: function fetchAdConfiguration() {
7485
8024
  return _async_to_generator(function() {
7486
- var _data_response_ima_publisherdeskima, _data_response_ima, _data_response, _data_response_options_vast_cue_tones, _data_response_options_vast, _data_response_options, _data_response1, vastMode, vastEndpoint, apiUrl, headers, response, data, imaPayload, decodedPayload, numberAds;
8025
+ var _data_response_ima_publisherdeskima, _data_response_ima, _data_response, _data_response_options_vast_cue_tones, _data_response_options_vast, _data_response_options, _data_response1, apiUrl, headers, response, data, imaPayload, decodedPayload, numberAds;
7487
8026
  return _ts_generator(this, function(_state) {
7488
8027
  switch(_state.label){
7489
8028
  case 0:
@@ -7504,28 +8043,6 @@ var AdConfigManager = /*#__PURE__*/ function() {
7504
8043
  2
7505
8044
  ];
7506
8045
  case 2:
7507
- vastMode = this.config.vastMode || "default";
7508
- if (this.debug) {
7509
- console.log("[StormcloudVideoPlayer] VAST mode:", vastMode);
7510
- }
7511
- if (vastMode === "adstorm") {
7512
- if (!this.config.licenseKey) {
7513
- if (this.debug) {
7514
- console.warn("[StormcloudVideoPlayer] AdStorm mode requires a license key");
7515
- }
7516
- return [
7517
- 2
7518
- ];
7519
- }
7520
- vastEndpoint = "https://adstorm.co/api-adstorm-dev/adstorm/vast/".concat(this.config.licenseKey);
7521
- this.apiVastTagUrl = vastEndpoint;
7522
- if (this.debug) {
7523
- console.log("[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):", vastEndpoint);
7524
- }
7525
- return [
7526
- 2
7527
- ];
7528
- }
7529
8046
  if (this.config.vastTagUrl) {
7530
8047
  this.apiVastTagUrl = normalizeVastTagUrl(this.config.vastTagUrl);
7531
8048
  if (this.debug) {
@@ -7535,7 +8052,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7535
8052
  2
7536
8053
  ];
7537
8054
  }
7538
- apiUrl = "https://adstorm.co/api-adstorm-dev/adstorm/ads/web";
8055
+ apiUrl = "https://edge.stormcloudhub.com/api/v1/adstorm/ads/web";
7539
8056
  if (this.debug) {
7540
8057
  console.log("[StormcloudVideoPlayer] Fetching ad configuration from:", apiUrl);
7541
8058
  }
@@ -7882,16 +8399,16 @@ var AdConfigManager = /*#__PURE__*/ function() {
7882
8399
  }
7883
8400
  },
7884
8401
  {
7885
- key: "resolvePodParams",
7886
- value: function resolvePodParams(breakDurationMs) {
7887
- var maxDurationMs = breakDurationMs != null && breakDurationMs > 0 ? breakDurationMs : this.config.podMaxDurationMs != null && this.config.podMaxDurationMs > 0 ? this.config.podMaxDurationMs : this.defaultPodMaxDurationMs;
7888
- var maxAds = this.config.podMaxAds && this.config.podMaxAds > 0 ? this.config.podMaxAds : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultPodMaxAds;
7889
- var minDurationMs = this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;
7890
- return {
7891
- maxAds: maxAds,
7892
- minDurationMs: minDurationMs,
7893
- maxDurationMs: maxDurationMs
7894
- };
8402
+ key: "resolveAdPodConfig",
8403
+ value: function resolveAdPodConfig1() {
8404
+ return resolveAdPodConfig(this.config);
8405
+ }
8406
+ },
8407
+ {
8408
+ key: "resolveEdgeMaxAds",
8409
+ value: function resolveEdgeMaxAds() {
8410
+ var _this_resolveAdPodConfig_maxAdsPerBreak;
8411
+ return (_this_resolveAdPodConfig_maxAdsPerBreak = this.resolveAdPodConfig().maxAdsPerBreak) !== null && _this_resolveAdPodConfig_maxAdsPerBreak !== void 0 ? _this_resolveAdPodConfig_maxAdsPerBreak : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultEdgePodMaxAds;
7895
8412
  }
7896
8413
  },
7897
8414
  {
@@ -7908,17 +8425,13 @@ var AdConfigManager = /*#__PURE__*/ function() {
7908
8425
  },
7909
8426
  {
7910
8427
  key: "generatePodVastUrl",
7911
- value: function generatePodVastUrl(baseUrl, podParams, adPlayer, palNonce, inAdBreak) {
7912
- var _podParams_maxDurationMs;
8428
+ value: function generatePodVastUrl(baseUrl, adPlayer, palNonce, inAdBreak) {
7913
8429
  var adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;
7914
8430
  var envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);
7915
- var urlWithMacros = applyVastMacros(baseUrl, _object_spread_props(_object_spread({
8431
+ var macroContext = _object_spread_props(_object_spread({
7916
8432
  correlator: this.viewCorrelator,
7917
8433
  streamCorrelator: this.streamCorrelator,
7918
8434
  pod: this.podCounter > 0 ? this.podCounter : void 0,
7919
- podMaxAds: podParams.maxAds,
7920
- podMinDurationMs: podParams.minDurationMs,
7921
- podMaxDurationMs: podParams.maxDurationMs,
7922
8435
  isCtv: envSignals.isCtv,
7923
8436
  pageUrl: !envSignals.isCtv && typeof window !== "undefined" ? toDevSafeUrl(window.location.href) : void 0,
7924
8437
  adWillPlayMuted: adWillPlayMuted,
@@ -7934,13 +8447,72 @@ var AdConfigManager = /*#__PURE__*/ function() {
7934
8447
  } : {}, this.config.channelName ? {
7935
8448
  channelName: this.config.channelName
7936
8449
  } : {}), {
7937
- consent: this.consentSignals
7938
- }));
7939
- var finalUrl = palNonce.injectNonce(ensureVideoAdType(urlWithMacros));
7940
- console.log("[StormcloudVideoPlayer] Resolved optimized-pod request URL (pod=".concat(this.podCounter, ", pmad=").concat(podParams.maxAds, ", pmnd=").concat(podParams.minDurationMs, ", pmxd=").concat((_podParams_maxDurationMs = podParams.maxDurationMs) !== null && _podParams_maxDurationMs !== void 0 ? _podParams_maxDurationMs : "?", "):"), finalUrl);
8450
+ consent: this.consentSignals,
8451
+ palNonce: palNonce.getCurrentNonce() || void 0
8452
+ });
8453
+ var nonceReady = !!macroContext.palNonce;
8454
+ var finalUrl;
8455
+ if (hasScvpMacros(baseUrl)) {
8456
+ var deferred = new Set(SCVP_POD_MACROS);
8457
+ if (!nonceReady) deferred.add("GIVN");
8458
+ var _applyScvpMacros = applyScvpMacros(baseUrl, macroContext, deferred), url = _applyScvpMacros.url, unresolved = _applyScvpMacros.unresolved;
8459
+ if (unresolved.length > 0) {
8460
+ console.warn("[StormcloudVideoPlayer] Unresolved SCVP macros (removed from request):", unresolved.join(", "));
8461
+ }
8462
+ finalUrl = ensureVideoAdType(url);
8463
+ } else {
8464
+ finalUrl = withDeferredPodParams(palNonce.injectNonce(ensureVideoAdType(applyVastMacros(baseUrl, macroContext))), !nonceReady);
8465
+ }
8466
+ console.log("[StormcloudVideoPlayer] Prepared optimized-pod request URL (pod=".concat(this.podCounter, "; pmnd/pmxd/pmad resolved at dispatch):"), finalUrl);
7941
8467
  return finalUrl;
7942
8468
  }
7943
8469
  },
8470
+ {
8471
+ key: "completeDeferredRequestSignals",
8472
+ value: function completeDeferredRequestSignals(url, palNonce) {
8473
+ return _async_to_generator(function() {
8474
+ var nonce, _tmp;
8475
+ return _ts_generator(this, function(_state) {
8476
+ switch(_state.label){
8477
+ case 0:
8478
+ if (findScvpMacroNames(url).indexOf("GIVN") === -1) return [
8479
+ 2,
8480
+ url
8481
+ ];
8482
+ _tmp = palNonce.getCurrentNonce();
8483
+ if (_tmp) return [
8484
+ 3,
8485
+ 2
8486
+ ];
8487
+ return [
8488
+ 4,
8489
+ palNonce.waitForNonce(this.palNonceDispatchWaitMs)
8490
+ ];
8491
+ case 1:
8492
+ _tmp = _state.sent();
8493
+ _state.label = 2;
8494
+ case 2:
8495
+ nonce = _tmp;
8496
+ if (!nonce) return [
8497
+ 2,
8498
+ url
8499
+ ];
8500
+ return [
8501
+ 2,
8502
+ substituteScvpMacros(url, /* @__PURE__ */ new Map([
8503
+ [
8504
+ "GIVN",
8505
+ nonce
8506
+ ]
8507
+ ]), function(name) {
8508
+ return name !== "GIVN";
8509
+ }).url
8510
+ ];
8511
+ }
8512
+ });
8513
+ }).call(this);
8514
+ }
8515
+ },
7944
8516
  {
7945
8517
  // --- Tracking ---
7946
8518
  key: "initializeTracking",
@@ -7988,6 +8560,9 @@ var AdConfigManager = /*#__PURE__*/ function() {
7988
8560
  return AdConfigManager;
7989
8561
  }();
7990
8562
  // src/player/AdTimingService.ts
8563
+ function monotonicNow() {
8564
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
8565
+ }
7991
8566
  var AdTimingService = /*#__PURE__*/ function() {
7992
8567
  function AdTimingService(config, video, callbacks) {
7993
8568
  _class_call_check(this, AdTimingService);
@@ -8118,6 +8693,21 @@ var AdTimingService = /*#__PURE__*/ function() {
8118
8693
  },
8119
8694
  {
8120
8695
  // --- Duration boundary ---
8696
+ key: "beginBreakTiming",
8697
+ value: function beginBreakTiming(startWallClockMs) {
8698
+ this.currentAdBreakStartWallClockMs = startWallClockMs;
8699
+ this.breakStartMonoMs = monotonicNow() + (startWallClockMs - Date.now());
8700
+ this.breakEndMonoMs = void 0;
8701
+ }
8702
+ },
8703
+ {
8704
+ key: "markBreakEndedNow",
8705
+ value: function markBreakEndedNow() {
8706
+ this.scteAdBreakEndWallClockMs = Date.now();
8707
+ this.breakEndMonoMs = monotonicNow();
8708
+ }
8709
+ },
8710
+ {
8121
8711
  key: "setAdBreakDurationBoundary",
8122
8712
  value: function setAdBreakDurationBoundary(durationMs) {
8123
8713
  this.expectedAdBreakDurationMs = durationMs;
@@ -8126,6 +8716,18 @@ var AdTimingService = /*#__PURE__*/ function() {
8126
8716
  } else {
8127
8717
  this.scteAdBreakEndWallClockMs = void 0;
8128
8718
  }
8719
+ this.breakEndMonoMs = durationMs != null && this.breakStartMonoMs != null ? this.breakStartMonoMs + durationMs : void 0;
8720
+ }
8721
+ },
8722
+ {
8723
+ key: "getBreakTimingSnapshot",
8724
+ value: function getBreakTimingSnapshot() {
8725
+ return {
8726
+ scheduledBreakDurationMs: this.expectedAdBreakDurationMs,
8727
+ breakStartMonoMs: this.breakStartMonoMs,
8728
+ breakEndMonoMs: this.breakEndMonoMs,
8729
+ playedDurationMs: this.adBreakPlayedDurationMs
8730
+ };
8129
8731
  }
8130
8732
  },
8131
8733
  {
@@ -8539,6 +9141,8 @@ var AdTimingService = /*#__PURE__*/ function() {
8539
9141
  this.expectedAdBreakDurationMs = void 0;
8540
9142
  this.currentAdBreakStartWallClockMs = void 0;
8541
9143
  this.scteAdBreakEndWallClockMs = void 0;
9144
+ this.breakStartMonoMs = void 0;
9145
+ this.breakEndMonoMs = void 0;
8542
9146
  this.adBreakPlayedDurationMs = 0;
8543
9147
  this.currentAdIndex = 0;
8544
9148
  this.totalAdsInBreak = 0;
@@ -9552,9 +10156,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9552
10156
  // ───────────────────────────────────────────────────────────────
9553
10157
  key: "nextAdRequestUrl",
9554
10158
  value: function nextAdRequestUrl(baseVastUrl) {
9555
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
9556
- var breakDurationMs = remaining > 0 ? remaining : void 0;
9557
- return this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10159
+ return this.host.generatePodVastUrl(baseVastUrl);
9558
10160
  }
9559
10161
  },
9560
10162
  {
@@ -9817,7 +10419,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9817
10419
  key: "handleAdStart",
9818
10420
  value: function handleAdStart(marker) {
9819
10421
  return _async_to_generator(function() {
9820
- var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
10422
+ var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, mode, edgeUrl, outcome, podPlayed;
9821
10423
  return _ts_generator(this, function(_state) {
9822
10424
  switch(_state.label){
9823
10425
  case 0:
@@ -9869,8 +10471,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9869
10471
  }
9870
10472
  this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
9871
10473
  epoch = this.timing.adBreakEpoch;
9872
- hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
9873
- if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
10474
+ if (!(adBreakDurationMs == null)) return [
9874
10475
  3,
9875
10476
  2
9876
10477
  ];
@@ -9926,7 +10527,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9926
10527
  }
9927
10528
  return [
9928
10529
  4,
9929
- this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
10530
+ this.startOptimizedPod(baseVastUrl)
9930
10531
  ];
9931
10532
  case 6:
9932
10533
  podPlayed = _state.sent();
@@ -9994,9 +10595,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9994
10595
  value: // ───────────────────────────────────────────────────────────────
9995
10596
  // Optimized pod (single multi-ad request)
9996
10597
  // ───────────────────────────────────────────────────────────────
9997
- function startOptimizedPod(baseVastUrl, breakDurationMs) {
10598
+ function startOptimizedPod(baseVastUrl) {
9998
10599
  return _async_to_generator(function() {
9999
- var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _adPlayer_getPodAdCount, podCount, error;
10600
+ var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _this_currentVastUrl, _adPlayer_getPodAdCount, finalizeRequestUrl, podCount, error;
10000
10601
  return _ts_generator(this, function(_state) {
10001
10602
  switch(_state.label){
10002
10603
  case 0:
@@ -10005,7 +10606,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10005
10606
  podUrl = this.pendingAdBreak.vastUrls[0];
10006
10607
  this.clearPendingAdBreak();
10007
10608
  } else {
10008
- podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10609
+ podUrl = this.host.generatePodVastUrl(baseVastUrl);
10009
10610
  }
10010
10611
  if (!podUrl) {
10011
10612
  return [
@@ -10029,9 +10630,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10029
10630
  case 1:
10030
10631
  _state.trys.push([
10031
10632
  1,
10032
- 5,
10633
+ 9,
10033
10634
  ,
10034
- 6
10635
+ 10
10035
10636
  ]);
10036
10637
  return [
10037
10638
  4,
@@ -10043,15 +10644,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10043
10644
  2,
10044
10645
  true
10045
10646
  ];
10647
+ return [
10648
+ 4,
10649
+ this.host.completeGamRequestSignals(requestUrl)
10650
+ ];
10651
+ case 3:
10652
+ requestUrl = _state.sent();
10653
+ if (this.isStale(epoch, generation)) return [
10654
+ 2,
10655
+ true
10656
+ ];
10046
10657
  this.timing.startAdRequestWatchdog(requestToken);
10658
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
10659
+ _state.label = 4;
10660
+ case 4:
10661
+ _state.trys.push([
10662
+ 4,
10663
+ ,
10664
+ 6,
10665
+ 7
10666
+ ]);
10047
10667
  return [
10048
10668
  4,
10049
10669
  this.callController(function() {
10050
- return adPlayer.requestAds(requestUrl);
10670
+ return adPlayer.requestAds(requestUrl, {
10671
+ finalizeRequestUrl: finalizeRequestUrl
10672
+ });
10051
10673
  })
10052
10674
  ];
10053
- case 3:
10675
+ case 5:
10054
10676
  _state.sent();
10677
+ return [
10678
+ 3,
10679
+ 7
10680
+ ];
10681
+ case 6:
10682
+ this.recordPodResponseDiagnostics(requestToken, adPlayer);
10683
+ return [
10684
+ 7
10685
+ ];
10686
+ case 7:
10055
10687
  this.timing.clearAdRequestWatchdog();
10056
10688
  if (this.isStale(epoch, generation)) {
10057
10689
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -10079,7 +10711,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10079
10711
  }
10080
10712
  sendAdLoadedTracking(this.host.config.licenseKey, {
10081
10713
  source: "hls",
10082
- vastUrl: requestUrl,
10714
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
10083
10715
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
10084
10716
  }, this.analyticsContext).catch(function() {});
10085
10717
  this.timing.startAdFailsafeTimer(requestToken);
@@ -10089,7 +10721,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10089
10721
  return adPlayer.play();
10090
10722
  })
10091
10723
  ];
10092
- case 4:
10724
+ case 8:
10093
10725
  _state.sent();
10094
10726
  if (this.isStale(epoch, generation)) return [
10095
10727
  2,
@@ -10103,7 +10735,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10103
10735
  2,
10104
10736
  true
10105
10737
  ];
10106
- case 5:
10738
+ case 9:
10107
10739
  error = _state.sent();
10108
10740
  this.timing.clearAdRequestWatchdog();
10109
10741
  this.timing.clearAdFailsafeTimer();
@@ -10123,12 +10755,16 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10123
10755
  if (this.debug) {
10124
10756
  console.warn("[POD] Optimized pod request/play failed:", error);
10125
10757
  }
10758
+ if (this.handlePodRequestNotSent(error)) return [
10759
+ 2,
10760
+ false
10761
+ ];
10126
10762
  this.recordRequestFailure(error, podUrl);
10127
10763
  return [
10128
10764
  2,
10129
10765
  false
10130
10766
  ];
10131
- case 6:
10767
+ case 10:
10132
10768
  return [
10133
10769
  2
10134
10770
  ];
@@ -10174,17 +10810,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10174
10810
  }
10175
10811
  },
10176
10812
  {
10177
- /**
10178
- * Builds the next Edge request from the budget left right now, or marks Edge
10179
- * exhausted for this break. Synchronous on purpose: callers must reach the
10180
- * REQUESTING state in the same tick so a second completion event cannot race
10181
- * in a parallel request.
10182
- */ key: "prepareEdgePodRequest",
10813
+ key: "prepareEdgePodRequest",
10183
10814
  value: function prepareEdgePodRequest() {
10184
10815
  var baseUrl = this.host.getEdgePodBaseUrl();
10185
10816
  if (!baseUrl) return void 0;
10186
10817
  var remainingMs = this.timing.getRemainingAdMs();
10187
- var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
10818
+ var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak);
10188
10819
  if (remainingAds < 1) {
10189
10820
  this.markEdgeExhausted("ad_capacity_reached", {
10190
10821
  adsInBreak: this.timing.totalAdsInBreak
@@ -10263,7 +10894,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10263
10894
  ];
10264
10895
  }
10265
10896
  remainingMs = this.timing.getRemainingAdMs();
10266
- remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
10897
+ remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak));
10267
10898
  overrunAllowanceMs = Math.max(0, (_this_host_config_maxAdBreakExtensionMs = this.host.config.maxAdBreakExtensionMs) !== null && _this_host_config_maxAdBreakExtensionMs !== void 0 ? _this_host_config_maxAdBreakExtensionMs : 0);
10268
10899
  podCount = adPlayer.limitPodToBudget ? adPlayer.limitPodToBudget(remainingMs + overrunAllowanceMs, remainingAds) : (_ref = (_adPlayer_getPodAdCount = adPlayer.getPodAdCount) === null || _adPlayer_getPodAdCount === void 0 ? void 0 : _adPlayer_getPodAdCount.call(adPlayer)) !== null && _ref !== void 0 ? _ref : 0;
10269
10900
  if (classifyEdgeVastResponse({
@@ -10610,7 +11241,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10610
11241
  {
10611
11242
  key: "noteVastUrlGenerated",
10612
11243
  value: function noteVastUrlGenerated(url, source) {
10613
- var _ref, _ref1, _ref2, _ref3, _ref4;
11244
+ var _ref, _ref1;
10614
11245
  var params;
10615
11246
  try {
10616
11247
  params = new URL(url).searchParams;
@@ -10620,9 +11251,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10620
11251
  requestId: void 0,
10621
11252
  source: source,
10622
11253
  pod: (_ref1 = params === null || params === void 0 ? void 0 : params.get("pod")) !== null && _ref1 !== void 0 ? _ref1 : void 0,
10623
- pmad: (_ref2 = params === null || params === void 0 ? void 0 : params.get("pmad")) !== null && _ref2 !== void 0 ? _ref2 : void 0,
10624
- pmnd: (_ref3 = params === null || params === void 0 ? void 0 : params.get("pmnd")) !== null && _ref3 !== void 0 ? _ref3 : void 0,
10625
- pmxd: (_ref4 = params === null || params === void 0 ? void 0 : params.get("pmxd")) !== null && _ref4 !== void 0 ? _ref4 : void 0,
11254
+ podParamsDeferredToDispatch: findScvpMacroNames(url).some(function(name) {
11255
+ return SCVP_POD_MACROS.has(name);
11256
+ }),
10626
11257
  adType: adType
10627
11258
  });
10628
11259
  if (adType === "audio" || adType === "audio_video") {
@@ -10663,10 +11294,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10663
11294
  if (diag && !diag.failureReason) {
10664
11295
  diag.failureReason = "".concat(outcome, ": ").concat(message);
10665
11296
  }
11297
+ var failureKey = (diag === null || diag === void 0 ? void 0 : diag.dispatchedUrl) && findScvpMacroNames(vastTagUrl).some(function(name) {
11298
+ return SCVP_POD_MACROS.has(name);
11299
+ }) ? diag.dispatchedUrl : vastTagUrl;
10666
11300
  if (this.timing.isTemporaryAdError(error)) {
10667
- this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());
11301
+ this.timing.temporaryFailureUrls.set(failureKey, Date.now());
10668
11302
  } else if (outcome !== "discarded_budget") {
10669
- this.timing.failedVastUrls.add(vastTagUrl);
11303
+ this.timing.failedVastUrls.add(failureKey);
10670
11304
  }
10671
11305
  this.countFunnelStage("request_outcome:".concat(outcome));
10672
11306
  this.logOrchestratorFunnel("request_outcome", _object_spread({
@@ -10692,6 +11326,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10692
11326
  switch(payload.stage){
10693
11327
  case "gam_http_request_sent":
10694
11328
  diag.gamRequestSent++;
11329
+ this.logPodDispatch(diag);
10695
11330
  break;
10696
11331
  case "edge_http_request_sent":
10697
11332
  diag.edgeRequestSent++;
@@ -10743,8 +11378,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10743
11378
  if (gamReturnedAdWithoutImpression) {
10744
11379
  this.countFunnelStage("gam_ad_without_impression");
10745
11380
  }
10746
- var startedAt = diag.startedAt, fields = _object_without_properties(diag, [
10747
- "startedAt"
11381
+ var startedAt = diag.startedAt, _dispatchedUrl = diag.dispatchedUrl, _logged = diag.podDispatchLogged, fields = _object_without_properties(diag, [
11382
+ "startedAt",
11383
+ "dispatchedUrl",
11384
+ "podDispatchLogged"
10748
11385
  ]);
10749
11386
  console.log("[AdBreak][REQUEST] summary", _object_spread_props(_object_spread({}, fields), {
10750
11387
  durationMs: Date.now() - startedAt,
@@ -10756,24 +11393,71 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10756
11393
  // ───────────────────────────────────────────────────────────────
10757
11394
  // Single ad playback
10758
11395
  // ───────────────────────────────────────────────────────────────
10759
- key: "withCurrentPodBudget",
10760
- value: function withCurrentPodBudget(rawVastTagUrl) {
10761
- var vastTagUrl = ensureVideoAdType(rawVastTagUrl);
10762
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
10763
- if (!(remaining > 0)) return vastTagUrl;
10764
- try {
10765
- var url = new URL(vastTagUrl);
10766
- if (!url.searchParams.has("pmxd")) return vastTagUrl;
10767
- var maxMs = Math.round(remaining);
10768
- url.searchParams.set("pmxd", String(maxMs));
10769
- var minMs = Number(url.searchParams.get("pmnd"));
10770
- if (Number.isFinite(minMs) && minMs > maxMs) {
10771
- url.searchParams.set("pmnd", String(maxMs));
10772
- }
10773
- return url.toString();
10774
- } catch (unused) {
10775
- return vastTagUrl;
10776
- }
11396
+ key: "createGamDispatchFinalizer",
11397
+ value: function createGamDispatchFinalizer(requestToken) {
11398
+ var _this = this;
11399
+ var breakId = this.timing.adBreakEpoch;
11400
+ var config = this.adConfig.resolveAdPodConfig();
11401
+ var minUsablePmxdMs = this.timing.getMinRemainingMsToStartAd();
11402
+ return function(url) {
11403
+ var capacity = measureBreakCapacity(_this.timing.getBreakTimingSnapshot(), monotonicNow());
11404
+ var diag = _this.requestDiagnostics.get(requestToken);
11405
+ try {
11406
+ var result = finalizeGamRequestUrl(url, {
11407
+ breakId: breakId,
11408
+ capacity: capacity,
11409
+ config: config,
11410
+ minUsablePmxdMs: minUsablePmxdMs
11411
+ });
11412
+ if (diag) {
11413
+ diag.pod = result.diagnostics;
11414
+ diag.dispatchedUrl = result.url;
11415
+ diag.podDispatchLogged = false;
11416
+ }
11417
+ _this.currentVastUrl = result.url;
11418
+ return result.url;
11419
+ } catch (error) {
11420
+ if (diag && isPodRequestAbortedError(error)) {
11421
+ diag.failureReason = "pod_request_not_sent:".concat(error.reason);
11422
+ }
11423
+ throw error;
11424
+ }
11425
+ };
11426
+ }
11427
+ },
11428
+ {
11429
+ key: "logPodDispatch",
11430
+ value: function logPodDispatch(diag) {
11431
+ if (!diag.pod || diag.podDispatchLogged) return;
11432
+ diag.podDispatchLogged = true;
11433
+ this.logOrchestratorFunnel(diag.pod.optimizedPod ? "optimized_pod_request_dispatched" : "gam_request_dispatched", _object_spread({}, diag.pod));
11434
+ }
11435
+ },
11436
+ {
11437
+ key: "recordPodResponseDiagnostics",
11438
+ value: function recordPodResponseDiagnostics(requestToken, adPlayer) {
11439
+ var _diag_vastAdCount, _ref;
11440
+ var _adPlayer_getPodTotalDurationMs;
11441
+ var diag = this.requestDiagnostics.get(requestToken);
11442
+ if (!(diag === null || diag === void 0 ? void 0 : diag.pod) || diag.pod.pmxdSent == null || diag.podResponse) return;
11443
+ if (diag.gamRequestSent === 0 && diag.vastHttpStatus == null) return;
11444
+ diag.podResponse = computePodResponseDiagnostics(diag.pod.pmxdSent, (_diag_vastAdCount = diag.vastAdCount) !== null && _diag_vastAdCount !== void 0 ? _diag_vastAdCount : 0, (_ref = (_adPlayer_getPodTotalDurationMs = adPlayer.getPodTotalDurationMs) === null || _adPlayer_getPodTotalDurationMs === void 0 ? void 0 : _adPlayer_getPodTotalDurationMs.call(adPlayer)) !== null && _ref !== void 0 ? _ref : 0);
11445
+ this.logOrchestratorFunnel("optimized_pod_response", _object_spread({
11446
+ pmxdSent: diag.pod.pmxdSent
11447
+ }, diag.podResponse));
11448
+ }
11449
+ },
11450
+ {
11451
+ key: "handlePodRequestNotSent",
11452
+ value: function handlePodRequestNotSent(error) {
11453
+ if (!isPodRequestAbortedError(error) || error.reason === "invalid_url") return false;
11454
+ var aborted = error;
11455
+ this.countFunnelStage("request_outcome:pod_request_not_sent");
11456
+ this.logOrchestratorFunnel("pod_request_not_sent", _object_spread({
11457
+ reason: aborted.reason,
11458
+ errorMessage: aborted.message
11459
+ }, aborted.diagnostics));
11460
+ return true;
10777
11461
  }
10778
11462
  },
10779
11463
  {
@@ -10993,7 +11677,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10993
11677
  value: function playSingleAd(vastTagUrl) {
10994
11678
  var trigger = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "vmap";
10995
11679
  return _async_to_generator(function() {
10996
- var epoch, generation, requestToken, ap, budgetedUrl, requestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
11680
+ var epoch, generation, requestToken, ap, requestUrl, _this_currentVastUrl, finalizeRequestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
10997
11681
  return _ts_generator(this, function(_state) {
10998
11682
  switch(_state.label){
10999
11683
  case 0:
@@ -11031,19 +11715,18 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11031
11715
  requestToken = ++this.timing.adRequestTokenCounter;
11032
11716
  this.timing.activeAdRequestToken = requestToken;
11033
11717
  ap = this.host.getAdPlayer();
11034
- budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
11035
11718
  this.currentPodSource = "gam";
11036
11719
  this.setSlotState("REQUESTING", trigger);
11037
11720
  this.beginFunnelRequest(ap, requestToken, trigger);
11038
- requestUrl = this.applyOpportunityFloor(budgetedUrl);
11721
+ requestUrl = this.applyOpportunityFloor(ensureVideoAdType(vastTagUrl));
11039
11722
  this.currentVastUrl = requestUrl;
11040
11723
  _state.label = 1;
11041
11724
  case 1:
11042
11725
  _state.trys.push([
11043
11726
  1,
11044
- 5,
11727
+ 9,
11045
11728
  ,
11046
- 6
11729
+ 10
11047
11730
  ]);
11048
11731
  return [
11049
11732
  4,
@@ -11054,15 +11737,45 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11054
11737
  if (this.isStale(epoch, generation)) return [
11055
11738
  2
11056
11739
  ];
11740
+ return [
11741
+ 4,
11742
+ this.host.completeGamRequestSignals(requestUrl)
11743
+ ];
11744
+ case 3:
11745
+ requestUrl = _state.sent();
11746
+ if (this.isStale(epoch, generation)) return [
11747
+ 2
11748
+ ];
11057
11749
  this.timing.startAdRequestWatchdog(requestToken);
11750
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
11751
+ _state.label = 4;
11752
+ case 4:
11753
+ _state.trys.push([
11754
+ 4,
11755
+ ,
11756
+ 6,
11757
+ 7
11758
+ ]);
11058
11759
  return [
11059
11760
  4,
11060
11761
  this.callController(function() {
11061
- return ap.requestAds(requestUrl);
11762
+ return ap.requestAds(requestUrl, {
11763
+ finalizeRequestUrl: finalizeRequestUrl
11764
+ });
11062
11765
  })
11063
11766
  ];
11064
- case 3:
11767
+ case 5:
11065
11768
  _state.sent();
11769
+ return [
11770
+ 3,
11771
+ 7
11772
+ ];
11773
+ case 6:
11774
+ this.recordPodResponseDiagnostics(requestToken, ap);
11775
+ return [
11776
+ 7
11777
+ ];
11778
+ case 7:
11066
11779
  this.timing.clearAdRequestWatchdog();
11067
11780
  if (this.isStale(epoch, generation)) {
11068
11781
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -11074,7 +11787,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11074
11787
  }
11075
11788
  sendAdLoadedTracking(this.host.config.licenseKey, {
11076
11789
  source: "hls",
11077
- vastUrl: requestUrl,
11790
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
11078
11791
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11079
11792
  }, this.analyticsContext).catch(function() {});
11080
11793
  if (!this.timing.ensureLoadedAdFitsBudget(ap)) {
@@ -11095,7 +11808,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11095
11808
  return ap.play();
11096
11809
  })
11097
11810
  ];
11098
- case 4:
11811
+ case 8:
11099
11812
  _state.sent();
11100
11813
  if (this.isStale(epoch, generation)) return [
11101
11814
  2
@@ -11107,9 +11820,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11107
11820
  this.timing.temporaryFailureUrls.delete(vastTagUrl);
11108
11821
  return [
11109
11822
  3,
11110
- 6
11823
+ 10
11111
11824
  ];
11112
- case 5:
11825
+ case 9:
11113
11826
  error = _state.sent();
11114
11827
  this.timing.clearAdRequestWatchdog();
11115
11828
  this.timing.clearAdFailsafeTimer();
@@ -11126,12 +11839,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11126
11839
  ];
11127
11840
  }
11128
11841
  if (this.debug) console.error("[AD-ERROR] Ad request failed:", error === null || error === void 0 ? void 0 : error.message);
11842
+ if (this.handlePodRequestNotSent(error)) throw error;
11129
11843
  this.recordRequestFailure(error, vastTagUrl);
11130
11844
  if ((error === null || error === void 0 ? void 0 : error.message) === "ad_duration_exceeds_budget") {
11131
11845
  this.recreateAdController("discarded_budget");
11132
11846
  }
11133
11847
  throw error;
11134
- case 6:
11848
+ case 10:
11135
11849
  return [
11136
11850
  2
11137
11851
  ];
@@ -11193,7 +11907,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11193
11907
  playbackFailedAfterFill: count("request_outcome:playback_failed"),
11194
11908
  requestFailed: count("request_failed"),
11195
11909
  requestAbortedTimeout: count("request_aborted_timeout"),
11196
- credentialsRetries: count("vast_credentials_retry"),
11910
+ credentialsModeChanges: count("gam_credentials_mode_changed"),
11197
11911
  wrapperFailures: count("wrapper_fetch:failure"),
11198
11912
  noSupportedMedia: count("vast_no_supported_media"),
11199
11913
  vpaidOnly: count("vast_no_supported_media:vpaid"),
@@ -11729,8 +12443,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11729
12443
  requiresMediaPipelineResetAfterAds: function requiresMediaPipelineResetAfterAds1() {
11730
12444
  return requiresMediaPipelineResetAfterAds();
11731
12445
  },
11732
- generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
11733
- return _this.generatePodVastUrl(base, breakDurationMs);
12446
+ generatePodVastUrl: function generatePodVastUrl(base) {
12447
+ return _this.generatePodVastUrl(base);
12448
+ },
12449
+ completeGamRequestSignals: function completeGamRequestSignals(url) {
12450
+ return _this.adConfig.completeDeferredRequestSignals(url, _this.palNonce);
11734
12451
  },
11735
12452
  getEdgePodBaseUrl: function getEdgePodBaseUrl() {
11736
12453
  return _this.edgePodBaseUrl;
@@ -11854,9 +12571,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11854
12571
  },
11855
12572
  {
11856
12573
  key: "generatePodVastUrl",
11857
- value: function generatePodVastUrl(baseUrl, breakDurationMs) {
11858
- var podParams = this.adConfig.resolvePodParams(breakDurationMs);
11859
- return this.adConfig.generatePodVastUrl(baseUrl, podParams, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
12574
+ value: function generatePodVastUrl(baseUrl) {
12575
+ return this.adConfig.generatePodVastUrl(baseUrl, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
11860
12576
  }
11861
12577
  },
11862
12578
  {
@@ -12210,7 +12926,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12210
12926
  activeAdRequest: this.timing.activeAdRequestToken !== null
12211
12927
  });
12212
12928
  }
12213
- this.timing.scteAdBreakEndWallClockMs = Date.now();
12929
+ this.timing.markBreakEndedNow();
12214
12930
  this.timing.clearAdStartTimer();
12215
12931
  this.timing.clearAdStopTimer();
12216
12932
  if (adPlaying) {
@@ -12237,7 +12953,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12237
12953
  this.adBreak.inAdBreak = true;
12238
12954
  this.cueManager.activeScte35BreakKey = cueKey !== null && cueKey !== void 0 ? cueKey : this.cueManager.pendingScte35CueKey;
12239
12955
  this.cueManager.scheduledScte35BreakKey = void 0;
12240
- this.timing.currentAdBreakStartWallClockMs = this.timing.resolveScteBreakStartWallClockMs(marker);
12956
+ this.timing.beginBreakTiming(this.timing.resolveScteBreakStartWallClockMs(marker));
12241
12957
  this.timing.setAdBreakDurationBoundary(durationMs);
12242
12958
  this.adBreak.handleAdStart(marker);
12243
12959
  this.timing.scheduleAdStopAtBreakBoundary();
@@ -12283,9 +12999,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12283
12999
  }
12284
13000
  this.adConfig.beginNewAdPod();
12285
13001
  this.adConfig.podAssignedByPrefetch = true;
12286
- var breakDurationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;
12287
13002
  var generatedUrls = [
12288
- this.generatePodVastUrl(baseVastUrl, breakDurationMs)
13003
+ this.generatePodVastUrl(baseVastUrl)
12289
13004
  ];
12290
13005
  this.adBreak.pendingAdBreak = _object_spread_props(_object_spread({
12291
13006
  marker: marker
@@ -12384,7 +13099,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12384
13099
  this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);
12385
13100
  this.adBreak.showAds = true;
12386
13101
  this.adBreak.inAdBreak = true;
12387
- this.timing.currentAdBreakStartWallClockMs = Date.now();
13102
+ this.timing.beginBreakTiming(Date.now());
12388
13103
  if (durationMs > 0) {
12389
13104
  this.timing.setAdBreakDurationBoundary(durationMs);
12390
13105
  }