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
@@ -432,21 +432,20 @@ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
432
432
  "adid"
433
433
  ]);
434
434
  function resolveVastEnvironmentSignals(isCtv) {
435
- var _ref;
436
435
  var bridgeSignals = readNativeBridgeSignals();
437
436
  var platformDevice = readPlatformNativeDeviceId();
438
- var realDeviceId = bridgeSignals.deviceId || (isCtv ? readStoredDeviceId() : void 0) || platformDevice.deviceId;
437
+ var bridgeDeviceId = validDeviceId(bridgeSignals.deviceId);
438
+ var realDeviceId = bridgeDeviceId || (isCtv ? validDeviceId(readStoredDeviceId()) : void 0) || validDeviceId(platformDevice.deviceId);
439
439
  var deviceId = realDeviceId;
440
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
441
- var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
442
- var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
440
+ var deviceIdType = (bridgeDeviceId ? bridgeSignals.deviceIdType : void 0) || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
441
+ var platformLat = bridgeDeviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
442
+ var limitAdTracking = deviceId != null ? platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking() : void 0;
443
443
  if (!deviceId && isCtv) {
444
444
  var dpid = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);
445
445
  if (dpid) {
446
- var _ref1;
447
446
  deviceId = dpid;
448
447
  deviceIdType = "dpid";
449
- limitAdTracking = (_ref1 = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref1 !== void 0 ? _ref1 : false;
448
+ limitAdTracking = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking();
450
449
  }
451
450
  }
452
451
  var deviceTypeHint = resolveDeviceTypeHint(isCtv);
@@ -811,6 +810,9 @@ function isMacroPlaceholder(value) {
811
810
  var t = value.trim();
812
811
  return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
813
812
  }
813
+ function validDeviceId(value) {
814
+ return value && !isMacroPlaceholder(value) ? value : void 0;
815
+ }
814
816
  function isZeroedAdId(value) {
815
817
  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
816
818
  }
@@ -1343,6 +1345,199 @@ function ensureVideoAdType(rawUrl) {
1343
1345
  return rawUrl;
1344
1346
  }
1345
1347
  }
1348
+ var SCVP_MACRO_DETECT = /\[SCVP-|%5BSCVP-|\(SCVP-|%28SCVP-/i;
1349
+ var SCVP_MACRO_PATTERN = /\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\)/gi;
1350
+ var SCVP_WHOLE_VALUE_PATTERN = /^\s*(?:\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\))\s*$/i;
1351
+ var NESTED_QUERY_PARAM_KEYS = /* @__PURE__ */ new Set([
1352
+ "cust_params"
1353
+ ]);
1354
+ var SCVP_POD_MACROS = /* @__PURE__ */ new Set([
1355
+ "PMND",
1356
+ "PMXD",
1357
+ "PMAD"
1358
+ ]);
1359
+ function hasScvpMacros(url) {
1360
+ return !!url && SCVP_MACRO_DETECT.test(url);
1361
+ }
1362
+ function safeDecode(value) {
1363
+ try {
1364
+ return decodeURIComponent(value.replace(/\+/g, " "));
1365
+ } catch (unused) {
1366
+ return value;
1367
+ }
1368
+ }
1369
+ function findScvpMacroNames(url) {
1370
+ if (!url) return [];
1371
+ var names = /* @__PURE__ */ new Set();
1372
+ var text = url;
1373
+ for(var pass = 0; pass < 3; pass++){
1374
+ text.replace(SCVP_MACRO_PATTERN, function(_m, bracketName, parenName) {
1375
+ names.add(String(bracketName || parenName).toUpperCase());
1376
+ return "";
1377
+ });
1378
+ var decoded = safeDecode(text);
1379
+ if (decoded === text) break;
1380
+ text = decoded;
1381
+ }
1382
+ return Array.from(names);
1383
+ }
1384
+ function resolveScvpMacroValues(ctx) {
1385
+ var _ctx_deviceId, _ctx_deviceIdType, _ctx_consent, _ctx_consent1, _ctx_consent2;
1386
+ var values = /* @__PURE__ */ new Map();
1387
+ var set = function set(name, value) {
1388
+ if (value == null) return;
1389
+ var str = String(value).trim();
1390
+ if (str) values.set(name, str);
1391
+ };
1392
+ var toFlag = function toFlag(value) {
1393
+ return value == null ? void 0 : value ? "1" : "0";
1394
+ };
1395
+ var deviceId = (_ctx_deviceId = ctx.deviceId) === null || _ctx_deviceId === void 0 ? void 0 : _ctx_deviceId.trim();
1396
+ var deviceIdType = deviceId ? ((_ctx_deviceIdType = ctx.deviceIdType) === null || _ctx_deviceIdType === void 0 ? void 0 : _ctx_deviceIdType.trim()) || inferDeviceIdType() : void 0;
1397
+ if (deviceId && deviceIdType) {
1398
+ var _toFlag;
1399
+ set("RDID", deviceId);
1400
+ set("IDTYPE", deviceIdType);
1401
+ set("IS-LAT", (_toFlag = toFlag(ctx.limitAdTracking)) !== null && _toFlag !== void 0 ? _toFlag : "0");
1402
+ }
1403
+ set("SID", ctx.sessionId);
1404
+ set("DTH", ctx.deviceTypeHint);
1405
+ set("GIVN", ctx.palNonce);
1406
+ set("CT-TI", ctx.programTitle);
1407
+ set("CT-CH", ctx.channelName);
1408
+ set("POD", ctx.pod);
1409
+ set("CORRELATOR", ctx.correlator);
1410
+ set("SCOR", ctx.streamCorrelator);
1411
+ set("VPMUTE", toFlag(ctx.adWillPlayMuted));
1412
+ if (ctx.adWillAutoPlay != null) {
1413
+ set("VPA", ctx.adWillAutoPlay ? "auto" : "click");
1414
+ }
1415
+ set("GDPR", (_ctx_consent = ctx.consent) === null || _ctx_consent === void 0 ? void 0 : _ctx_consent.gdpr);
1416
+ set("GDPR-CONSENT", (_ctx_consent1 = ctx.consent) === null || _ctx_consent1 === void 0 ? void 0 : _ctx_consent1.gdprConsent);
1417
+ set("US-PRIVACY", (_ctx_consent2 = ctx.consent) === null || _ctx_consent2 === void 0 ? void 0 : _ctx_consent2.usPrivacy);
1418
+ return values;
1419
+ }
1420
+ var keepNone = function keepNone() {
1421
+ return false;
1422
+ };
1423
+ function substituteScvpParams(params, values, unresolved, keep, nested) {
1424
+ var out = [];
1425
+ var replaceMacro = function replaceMacro(match, bracketName, parenName) {
1426
+ var name = String(bracketName || parenName).toUpperCase();
1427
+ var value = values.get(name);
1428
+ if (value != null) return value;
1429
+ if (keep(name)) return match;
1430
+ unresolved.add(name);
1431
+ return "";
1432
+ };
1433
+ params.forEach(function(value, key) {
1434
+ var whole = value.match(SCVP_WHOLE_VALUE_PATTERN);
1435
+ if (whole) {
1436
+ var name = String(whole[1] || whole[2]).toUpperCase();
1437
+ var resolved = values.get(name);
1438
+ if (resolved != null) {
1439
+ out.push([
1440
+ key,
1441
+ resolved
1442
+ ]);
1443
+ } else if (keep(name)) {
1444
+ out.push([
1445
+ key,
1446
+ value
1447
+ ]);
1448
+ } else {
1449
+ unresolved.add(name);
1450
+ }
1451
+ return;
1452
+ }
1453
+ if (!SCVP_MACRO_DETECT.test(value)) {
1454
+ out.push([
1455
+ key,
1456
+ value
1457
+ ]);
1458
+ return;
1459
+ }
1460
+ if (!nested && NESTED_QUERY_PARAM_KEYS.has(key)) {
1461
+ var inner = substituteScvpParams(new URLSearchParams(value), values, unresolved, keep, true);
1462
+ if (inner.length > 0) {
1463
+ out.push([
1464
+ key,
1465
+ inner.map(function(param) {
1466
+ var _param = _sliced_to_array(param, 2), k = _param[0], v = _param[1];
1467
+ return "".concat(encodeURIComponent(k), "=").concat(encodeURIComponent(v));
1468
+ }).join("&")
1469
+ ]);
1470
+ }
1471
+ return;
1472
+ }
1473
+ out.push([
1474
+ key,
1475
+ value.replace(SCVP_MACRO_PATTERN, replaceMacro)
1476
+ ]);
1477
+ });
1478
+ return out;
1479
+ }
1480
+ function substituteScvpMacros(baseUrl, values) {
1481
+ var keep = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : keepNone;
1482
+ var unresolved = /* @__PURE__ */ new Set();
1483
+ var url;
1484
+ try {
1485
+ url = new URL(normalizeVastTagUrl(baseUrl));
1486
+ } catch (unused) {
1487
+ var replaced = baseUrl.replace(SCVP_MACRO_PATTERN, function(match, bracketName, parenName) {
1488
+ var name = String(bracketName || parenName).toUpperCase();
1489
+ var value = values.get(name);
1490
+ if (value != null) return encodeURIComponent(value);
1491
+ if (keep(name)) return match;
1492
+ unresolved.add(name);
1493
+ return "";
1494
+ });
1495
+ return {
1496
+ url: replaced,
1497
+ unresolved: Array.from(unresolved)
1498
+ };
1499
+ }
1500
+ var entries = substituteScvpParams(url.searchParams, values, unresolved, keep, false);
1501
+ var search = new URLSearchParams();
1502
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1503
+ try {
1504
+ for(var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1505
+ var _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], value = _step_value[1];
1506
+ search.append(key, value);
1507
+ }
1508
+ } catch (err) {
1509
+ _didIteratorError = true;
1510
+ _iteratorError = err;
1511
+ } finally{
1512
+ try {
1513
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1514
+ _iterator.return();
1515
+ }
1516
+ } finally{
1517
+ if (_didIteratorError) {
1518
+ throw _iteratorError;
1519
+ }
1520
+ }
1521
+ }
1522
+ url.search = search.toString();
1523
+ return {
1524
+ url: url.toString(),
1525
+ unresolved: Array.from(unresolved)
1526
+ };
1527
+ }
1528
+ function applyScvpMacros(baseUrl, ctx) {
1529
+ var deferred = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : /* @__PURE__ */ new Set();
1530
+ return substituteScvpMacros(baseUrl, resolveScvpMacroValues(ctx), function(name) {
1531
+ return deferred.has(name);
1532
+ });
1533
+ }
1534
+ function stripScvpMacros(url) {
1535
+ if (findScvpMacroNames(url).length === 0) return {
1536
+ url: url,
1537
+ unresolved: []
1538
+ };
1539
+ return substituteScvpMacros(url, /* @__PURE__ */ new Map());
1540
+ }
1346
1541
  function applyVastMacros(baseUrl, ctx) {
1347
1542
  var expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);
1348
1543
  var url;
@@ -1384,15 +1579,6 @@ function applyVastMacros(baseUrl, ctx) {
1384
1579
  }
1385
1580
  params.delete("ppos");
1386
1581
  params.delete("lip");
1387
- if (ctx.podMinDurationMs != null) {
1388
- params.set("pmnd", String(Math.max(0, Math.round(ctx.podMinDurationMs))));
1389
- }
1390
- if (ctx.podMaxDurationMs != null) {
1391
- params.set("pmxd", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));
1392
- }
1393
- if (ctx.podMaxAds != null) {
1394
- params.set("pmad", String(Math.max(1, Math.round(ctx.podMaxAds))));
1395
- }
1396
1582
  var existingUrl = params.get("url") || "";
1397
1583
  if (EXAMPLE_COM_URL.test(existingUrl)) {
1398
1584
  params.delete("url");
@@ -2222,6 +2408,309 @@ function substituteVastTrackingMacros(url) {
2222
2408
  return KNOWN_VAST_MACROS.has(name) ? "" : match;
2223
2409
  });
2224
2410
  }
2411
+ // src/player/OptimizedPodRequest.ts
2412
+ var DEFAULT_REQUEST_SAFETY_MS = 1500;
2413
+ var GAM_AD_OPPORTUNITY_DURATION_MS = 3e4;
2414
+ var POD_PARAM_KEYS = [
2415
+ "pmnd",
2416
+ "pmxd",
2417
+ "pmad"
2418
+ ];
2419
+ var POSITIVE_INT = /^[1-9]\d*$/;
2420
+ var NON_NEGATIVE_INT = /^(0|[1-9]\d*)$/;
2421
+ function nonNegativeInt(value) {
2422
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : void 0;
2423
+ }
2424
+ function positiveInt(value) {
2425
+ return typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : void 0;
2426
+ }
2427
+ function resolveAdPodConfig(config) {
2428
+ var _config_adPodConfig, _nonNegativeInt, _nonNegativeInt1, _positiveInt;
2429
+ var pod = (_config_adPodConfig = config.adPodConfig) !== null && _config_adPodConfig !== void 0 ? _config_adPodConfig : {};
2430
+ return {
2431
+ requestSafetyMs: (_nonNegativeInt = nonNegativeInt(pod.requestSafetyMs)) !== null && _nonNegativeInt !== void 0 ? _nonNegativeInt : DEFAULT_REQUEST_SAFETY_MS,
2432
+ minPodDurationMs: (_nonNegativeInt1 = nonNegativeInt(pod.minPodDurationMs)) !== null && _nonNegativeInt1 !== void 0 ? _nonNegativeInt1 : 0,
2433
+ maxAdsPerBreak: pod.maxAdsPerBreak === void 0 ? positiveInt(config.podMaxAds) : positiveInt(pod.maxAdsPerBreak),
2434
+ maxPodDurationMs: (_positiveInt = positiveInt(pod.maxPodDurationMs)) !== null && _positiveInt !== void 0 ? _positiveInt : positiveInt(config.podMaxDurationMs),
2435
+ exactDuration: config.podExactDuration === true
2436
+ };
2437
+ }
2438
+ function measureBreakCapacity(timing, nowMonoMs) {
2439
+ var _timing_breakEndMonoMs;
2440
+ var scheduled = timing.scheduledBreakDurationMs;
2441
+ if (scheduled == null || !(scheduled > 0) || timing.breakStartMonoMs == null) {
2442
+ return void 0;
2443
+ }
2444
+ var endMonoMs = (_timing_breakEndMonoMs = timing.breakEndMonoMs) !== null && _timing_breakEndMonoMs !== void 0 ? _timing_breakEndMonoMs : timing.breakStartMonoMs + scheduled;
2445
+ var untilEnd = Math.min(scheduled, endMonoMs - nowMonoMs);
2446
+ var unplayed = scheduled - Math.max(0, timing.playedDurationMs);
2447
+ return {
2448
+ scheduledBreakDurationMs: scheduled,
2449
+ elapsedBeforeGamRequestMs: Math.max(0, nowMonoMs - timing.breakStartMonoMs),
2450
+ remainingAtGamDispatchMs: Math.max(0, Math.min(untilEnd, unplayed))
2451
+ };
2452
+ }
2453
+ function resolvePodParams(input) {
2454
+ var capacity = input.capacity, config = input.config;
2455
+ var pmxd;
2456
+ var source;
2457
+ if (capacity) {
2458
+ pmxd = Math.floor(capacity.remainingAtGamDispatchMs - config.requestSafetyMs);
2459
+ source = "break_remaining";
2460
+ } else if (config.maxPodDurationMs != null) {
2461
+ pmxd = config.maxPodDurationMs;
2462
+ source = "configured_cap";
2463
+ } else if (input.tagMaxDurationMs != null) {
2464
+ pmxd = input.tagMaxDurationMs;
2465
+ source = "tag_cap";
2466
+ } else {
2467
+ return {
2468
+ kind: "omit"
2469
+ };
2470
+ }
2471
+ var minUsable = Math.max(1, Math.floor(input.minUsablePmxdMs));
2472
+ if (!Number.isFinite(pmxd) || pmxd < minUsable) {
2473
+ return {
2474
+ kind: "abort",
2475
+ reason: capacity ? "insufficient_break_capacity" : "invalid_pod_cap",
2476
+ pmxdCandidateMs: Number.isFinite(pmxd) ? pmxd : 0
2477
+ };
2478
+ }
2479
+ var pmnd = config.exactDuration ? pmxd : Math.min(config.minPodDurationMs, pmxd);
2480
+ return {
2481
+ kind: "send",
2482
+ params: {
2483
+ pmnd: pmnd,
2484
+ pmxd: pmxd,
2485
+ pmad: config.maxAdsPerBreak
2486
+ },
2487
+ source: source
2488
+ };
2489
+ }
2490
+ function podRequestAborted(reason, message, diagnostics) {
2491
+ var error = new Error("Optimized pod request not sent (".concat(reason, "): ").concat(message));
2492
+ error.podRequestAborted = true;
2493
+ error.reason = reason;
2494
+ error.diagnostics = diagnostics;
2495
+ return error;
2496
+ }
2497
+ function isPodRequestAbortedError(error) {
2498
+ return !!error && error.podRequestAborted === true;
2499
+ }
2500
+ function firstPositiveIntParam(params, key) {
2501
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2502
+ try {
2503
+ for(var _iterator = params.getAll(key)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2504
+ var value = _step.value;
2505
+ if (POSITIVE_INT.test(value.trim())) return Number(value.trim());
2506
+ }
2507
+ } catch (err) {
2508
+ _didIteratorError = true;
2509
+ _iteratorError = err;
2510
+ } finally{
2511
+ try {
2512
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2513
+ _iterator.return();
2514
+ }
2515
+ } finally{
2516
+ if (_didIteratorError) {
2517
+ throw _iteratorError;
2518
+ }
2519
+ }
2520
+ }
2521
+ return void 0;
2522
+ }
2523
+ function isOptimizedPodUrl(url) {
2524
+ if (findScvpMacroNames(url).some(function(name) {
2525
+ return SCVP_POD_MACROS.has(name);
2526
+ })) return true;
2527
+ try {
2528
+ var params = new URL(url).searchParams;
2529
+ return POD_PARAM_KEYS.some(function(key) {
2530
+ return params.has(key);
2531
+ });
2532
+ } catch (unused) {
2533
+ return false;
2534
+ }
2535
+ }
2536
+ function finalizeGamRequestUrl(rawUrl, ctx) {
2537
+ var nowEpochMs = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : Date.now();
2538
+ var optimizedPod = isOptimizedPodUrl(rawUrl);
2539
+ var capacity = ctx.capacity;
2540
+ var base = {
2541
+ breakId: ctx.breakId,
2542
+ optimizedPod: optimizedPod,
2543
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2544
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2545
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2546
+ safetyReserveMs: ctx.config.requestSafetyMs
2547
+ };
2548
+ var decision = {
2549
+ kind: "omit"
2550
+ };
2551
+ if (optimizedPod) {
2552
+ var tagMaxDurationMs;
2553
+ try {
2554
+ tagMaxDurationMs = firstPositiveIntParam(new URL(rawUrl).searchParams, "pmxd");
2555
+ } catch (unused) {}
2556
+ decision = resolvePodParams({
2557
+ capacity: capacity,
2558
+ config: ctx.config,
2559
+ minUsablePmxdMs: ctx.minUsablePmxdMs,
2560
+ tagMaxDurationMs: tagMaxDurationMs
2561
+ });
2562
+ if (decision.kind === "abort") {
2563
+ throw podRequestAborted(decision.reason, "pmxd would be ".concat(decision.pmxdCandidateMs, "ms (minimum ").concat(ctx.minUsablePmxdMs, "ms)"), base);
2564
+ }
2565
+ }
2566
+ var pod = decision.kind === "send" ? decision.params : void 0;
2567
+ var values = /* @__PURE__ */ new Map();
2568
+ if (pod) {
2569
+ values.set("PMND", String(pod.pmnd));
2570
+ values.set("PMXD", String(pod.pmxd));
2571
+ if (pod.pmad != null) values.set("PMAD", String(pod.pmad));
2572
+ }
2573
+ var substituted = substituteScvpMacros(rawUrl, values);
2574
+ var finalUrl;
2575
+ try {
2576
+ var url = new URL(normalizeVastTagUrl(substituted.url));
2577
+ if (pod) {
2578
+ url.searchParams.set("pmnd", String(pod.pmnd));
2579
+ url.searchParams.set("pmxd", String(pod.pmxd));
2580
+ if (pod.pmad != null) url.searchParams.set("pmad", String(pod.pmad));
2581
+ else url.searchParams.delete("pmad");
2582
+ } else {
2583
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2584
+ try {
2585
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2586
+ var key = _step.value;
2587
+ url.searchParams.delete(key);
2588
+ }
2589
+ } catch (err) {
2590
+ _didIteratorError = true;
2591
+ _iteratorError = err;
2592
+ } finally{
2593
+ try {
2594
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2595
+ _iterator.return();
2596
+ }
2597
+ } finally{
2598
+ if (_didIteratorError) {
2599
+ throw _iteratorError;
2600
+ }
2601
+ }
2602
+ }
2603
+ }
2604
+ finalUrl = url.toString();
2605
+ } catch (unused) {
2606
+ throw podRequestAborted("invalid_url", "GAM request URL could not be parsed", base);
2607
+ }
2608
+ var problems = validateGamRequestUrl(finalUrl, {
2609
+ optimizedPod: !!pod,
2610
+ remainingMs: decision.kind === "send" && decision.source === "break_remaining" ? capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs : void 0
2611
+ });
2612
+ if (problems.length > 0) {
2613
+ throw podRequestAborted("invalid_url", problems.join("; "), base);
2614
+ }
2615
+ var givn = null;
2616
+ try {
2617
+ givn = new URL(finalUrl).searchParams.get("givn");
2618
+ } catch (unused) {}
2619
+ return {
2620
+ url: finalUrl,
2621
+ diagnostics: {
2622
+ breakId: ctx.breakId,
2623
+ optimizedPod: !!pod,
2624
+ pmxdSource: decision.kind === "send" ? decision.source : void 0,
2625
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2626
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2627
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2628
+ safetyReserveMs: ctx.config.requestSafetyMs,
2629
+ pmndSent: pod === null || pod === void 0 ? void 0 : pod.pmnd,
2630
+ pmxdSent: pod === null || pod === void 0 ? void 0 : pod.pmxd,
2631
+ pmadSent: pod === null || pod === void 0 ? void 0 : pod.pmad,
2632
+ palNoncePresent: !!givn,
2633
+ gamRequestDispatchTimestamp: new Date(nowEpochMs).toISOString(),
2634
+ strippedMacros: substituted.unresolved.filter(function(name) {
2635
+ return !SCVP_POD_MACROS.has(name);
2636
+ })
2637
+ }
2638
+ };
2639
+ }
2640
+ function validateGamRequestUrl(url, expect) {
2641
+ var problems = [];
2642
+ var leftover = findScvpMacroNames(url);
2643
+ if (leftover.length > 0) problems.push("unresolved SCVP macros: ".concat(leftover.join(", ")));
2644
+ var params;
2645
+ try {
2646
+ params = new URL(url).searchParams;
2647
+ } catch (unused) {
2648
+ return problems.concat("URL could not be parsed");
2649
+ }
2650
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2651
+ try {
2652
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2653
+ var key = _step.value;
2654
+ if (params.getAll(key).length > 1) problems.push("duplicate ".concat(key));
2655
+ }
2656
+ } catch (err) {
2657
+ _didIteratorError = true;
2658
+ _iteratorError = err;
2659
+ } finally{
2660
+ try {
2661
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2662
+ _iterator.return();
2663
+ }
2664
+ } finally{
2665
+ if (_didIteratorError) {
2666
+ throw _iteratorError;
2667
+ }
2668
+ }
2669
+ }
2670
+ if (!expect.optimizedPod) {
2671
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
2672
+ try {
2673
+ for(var _iterator1 = POD_PARAM_KEYS[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
2674
+ var key1 = _step1.value;
2675
+ if (params.has(key1)) problems.push("".concat(key1, " present on a non-pod request"));
2676
+ }
2677
+ } catch (err) {
2678
+ _didIteratorError1 = true;
2679
+ _iteratorError1 = err;
2680
+ } finally{
2681
+ try {
2682
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
2683
+ _iterator1.return();
2684
+ }
2685
+ } finally{
2686
+ if (_didIteratorError1) {
2687
+ throw _iteratorError1;
2688
+ }
2689
+ }
2690
+ }
2691
+ return problems;
2692
+ }
2693
+ var pmxd = params.get("pmxd");
2694
+ var pmnd = params.get("pmnd");
2695
+ var pmad = params.get("pmad");
2696
+ if (pmxd == null || !POSITIVE_INT.test(pmxd)) problems.push("pmxd must be a positive integer (got ".concat(pmxd, ")"));
2697
+ if (pmnd == null || !NON_NEGATIVE_INT.test(pmnd)) problems.push("pmnd must be a non-negative integer (got ".concat(pmnd, ")"));
2698
+ if (pmxd != null && pmnd != null && Number(pmnd) > Number(pmxd)) problems.push("pmnd exceeds pmxd");
2699
+ if (pmad != null && !POSITIVE_INT.test(pmad)) problems.push("pmad must be a positive integer or absent (got ".concat(pmad, ")"));
2700
+ if (expect.remainingMs != null && pmxd != null && Number(pmxd) > expect.remainingMs) {
2701
+ problems.push("pmxd ".concat(pmxd, " exceeds remaining break ").concat(expect.remainingMs, "ms"));
2702
+ }
2703
+ return problems;
2704
+ }
2705
+ function computePodResponseDiagnostics(pmxdSent, vastAdCount, totalVastCreativeDurationMs) {
2706
+ var estimatedUnusedPodMs = Math.max(0, pmxdSent - totalVastCreativeDurationMs);
2707
+ return {
2708
+ vastAdCount: vastAdCount,
2709
+ totalVastCreativeDurationMs: totalVastCreativeDurationMs,
2710
+ estimatedUnusedPodMs: estimatedUnusedPodMs,
2711
+ estimatedUnmatchedCount: Math.floor(estimatedUnusedPodMs / GAM_AD_OPPORTUNITY_DURATION_MS)
2712
+ };
2713
+ }
2225
2714
  // src/sdk/hlsAdPlayer.ts
2226
2715
  var LINEAR_TRACKING_EVENTS = [
2227
2716
  "creativeView",
@@ -2302,6 +2791,7 @@ function toVastMediaErrorCode(error) {
2302
2791
  return VAST_ERROR_MEDIA_DISPLAY;
2303
2792
  }
2304
2793
  }
2794
+ var gamCredentialsMode = "include";
2305
2795
  function createHlsAdPlayer(contentVideo, options) {
2306
2796
  var _contentVideo_AD_VIDEO_PROP, _contentVideo_AD_CONTAINER_PROP, _ref;
2307
2797
  var adPlaying = false;
@@ -3173,9 +3663,9 @@ function createHlsAdPlayer(contentVideo, options) {
3173
3663
  }
3174
3664
  }
3175
3665
  function fetchVastXml(vastTagUrl) {
3176
- var credentials = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "include", kind = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "gam";
3666
+ 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;
3177
3667
  return _async_to_generator(function() {
3178
- var controller, timeoutId, startedAt, attempt, requestVast, response, error, error1;
3668
+ var controller, timeoutId, startedAt, attempt, resolveDispatchUrl, requestVast, response, error, error1;
3179
3669
  return _ts_generator(this, function(_state) {
3180
3670
  switch(_state.label){
3181
3671
  case 0:
@@ -3189,13 +3679,32 @@ function createHlsAdPlayer(contentVideo, options) {
3189
3679
  }, VAST_REQUEST_TIMEOUT_MS) : void 0;
3190
3680
  startedAt = Date.now();
3191
3681
  attempt = 0;
3682
+ resolveDispatchUrl = function resolveDispatchUrl() {
3683
+ if (kind === "wrapper") return vastTagUrl;
3684
+ if (finalizeRequestUrl) return finalizeRequestUrl(vastTagUrl, attempt);
3685
+ var _stripScvpMacros = stripScvpMacros(vastTagUrl), url = _stripScvpMacros.url, unresolved = _stripScvpMacros.unresolved;
3686
+ if (unresolved.length > 0) {
3687
+ console.warn("[HlsAdPlayer] Removed unresolved SCVP macros before dispatch:", unresolved.join(", "));
3688
+ }
3689
+ return url;
3690
+ };
3192
3691
  requestVast = function requestVast(creds) {
3193
3692
  return _async_to_generator(function() {
3194
- var response;
3693
+ var pending, response;
3195
3694
  return _ts_generator(this, function(_state) {
3196
3695
  switch(_state.label){
3197
3696
  case 0:
3198
3697
  attempt++;
3698
+ pending = fetch(resolveDispatchUrl(), _object_spread({
3699
+ mode: "cors",
3700
+ credentials: creds,
3701
+ headers: {
3702
+ "Accept": "application/xml, text/xml, */*"
3703
+ },
3704
+ referrerPolicy: "no-referrer-when-downgrade"
3705
+ }, controller ? {
3706
+ signal: controller.signal
3707
+ } : {}));
3199
3708
  if (kind !== "wrapper") {
3200
3709
  logFunnel("".concat(kind, "_http_request_sent"), {
3201
3710
  attempt: attempt,
@@ -3204,16 +3713,7 @@ function createHlsAdPlayer(contentVideo, options) {
3204
3713
  }
3205
3714
  return [
3206
3715
  4,
3207
- fetch(vastTagUrl, _object_spread({
3208
- mode: "cors",
3209
- credentials: creds,
3210
- headers: {
3211
- "Accept": "application/xml, text/xml, */*"
3212
- },
3213
- referrerPolicy: "no-referrer-when-downgrade"
3214
- }, controller ? {
3215
- signal: controller.signal
3216
- } : {}))
3716
+ pending
3217
3717
  ];
3218
3718
  case 1:
3219
3719
  response = _state.sent();
@@ -3237,9 +3737,9 @@ function createHlsAdPlayer(contentVideo, options) {
3237
3737
  case 1:
3238
3738
  _state.trys.push([
3239
3739
  1,
3240
- 10,
3241
- 11,
3242
- 12
3740
+ 7,
3741
+ 8,
3742
+ 9
3243
3743
  ]);
3244
3744
  _state.label = 2;
3245
3745
  case 2:
@@ -3247,7 +3747,7 @@ function createHlsAdPlayer(contentVideo, options) {
3247
3747
  2,
3248
3748
  4,
3249
3749
  ,
3250
- 8
3750
+ 5
3251
3751
  ]);
3252
3752
  return [
3253
3753
  4,
@@ -3257,36 +3757,21 @@ function createHlsAdPlayer(contentVideo, options) {
3257
3757
  response = _state.sent();
3258
3758
  return [
3259
3759
  3,
3260
- 8
3760
+ 5
3261
3761
  ];
3262
3762
  case 4:
3263
3763
  error = _state.sent();
3264
- if (!(credentials !== "omit" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted))) return [
3265
- 3,
3266
- 6
3267
- ];
3268
- console.warn('[HlsAdPlayer] VAST fetch failed with credentials="'.concat(credentials, '", retrying without credentials:'), error);
3269
- logFunnel("vast_credentials_retry", {
3270
- errorMessage: error === null || error === void 0 ? void 0 : error.message
3271
- });
3272
- return [
3273
- 4,
3274
- requestVast("omit")
3275
- ];
3276
- case 5:
3277
- response = _state.sent();
3278
- return [
3279
- 3,
3280
- 7
3281
- ];
3282
- case 6:
3764
+ if (kind === "gam" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted) && !isPodRequestAbortedError(error)) {
3765
+ gamCredentialsMode = credentials === "include" ? "omit" : "include";
3766
+ console.warn('[HlsAdPlayer] GAM fetch failed with credentials="'.concat(credentials, '"; next GAM request will use credentials="').concat(gamCredentialsMode, '":'), error);
3767
+ logFunnel("gam_credentials_mode_changed", {
3768
+ from: credentials,
3769
+ to: gamCredentialsMode,
3770
+ errorMessage: error === null || error === void 0 ? void 0 : error.message
3771
+ });
3772
+ }
3283
3773
  throw error;
3284
- case 7:
3285
- return [
3286
- 3,
3287
- 8
3288
- ];
3289
- case 8:
3774
+ case 5:
3290
3775
  if (!response.ok) {
3291
3776
  throw new Error("Failed to fetch VAST: HTTP ".concat(response.status, " ").concat(response.statusText));
3292
3777
  }
@@ -3294,12 +3779,12 @@ function createHlsAdPlayer(contentVideo, options) {
3294
3779
  4,
3295
3780
  response.text()
3296
3781
  ];
3297
- case 9:
3782
+ case 6:
3298
3783
  return [
3299
3784
  2,
3300
3785
  _state.sent()
3301
3786
  ];
3302
- case 10:
3787
+ case 7:
3303
3788
  error1 = _state.sent();
3304
3789
  if (controller === null || controller === void 0 ? void 0 : controller.signal.aborted) {
3305
3790
  if (pendingRequestAbortReason) {
@@ -3308,13 +3793,13 @@ function createHlsAdPlayer(contentVideo, options) {
3308
3793
  throw new Error("VAST request timeout after ".concat(VAST_REQUEST_TIMEOUT_MS, "ms: ").concat(vastTagUrl));
3309
3794
  }
3310
3795
  throw error1;
3311
- case 11:
3796
+ case 8:
3312
3797
  if (timeoutId !== void 0) clearTimeout(timeoutId);
3313
3798
  if (controller) pendingVastRequests.delete(controller);
3314
3799
  return [
3315
3800
  7
3316
3801
  ];
3317
- case 12:
3802
+ case 9:
3318
3803
  return [
3319
3804
  2
3320
3805
  ];
@@ -3447,7 +3932,7 @@ function createHlsAdPlayer(contentVideo, options) {
3447
3932
  });
3448
3933
  }
3449
3934
  function fetchAndParsePod(vastTagUrl) {
3450
- var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam";
3935
+ var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam", finalizeRequestUrl = arguments.length > 2 ? arguments[2] : void 0;
3451
3936
  return _async_to_generator(function() {
3452
3937
  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;
3453
3938
  return _ts_generator(this, function(_state) {
@@ -3457,7 +3942,7 @@ function createHlsAdPlayer(contentVideo, options) {
3457
3942
  isEdge = source === "edge";
3458
3943
  return [
3459
3944
  4,
3460
- fetchVastXml(vastTagUrl, isEdge ? "omit" : "include", source)
3945
+ fetchVastXml(vastTagUrl, isEdge ? "omit" : gamCredentialsMode, source, finalizeRequestUrl)
3461
3946
  ];
3462
3947
  case 1:
3463
3948
  vastXml = _state.sent();
@@ -4780,7 +5265,7 @@ function createHlsAdPlayer(contentVideo, options) {
4780
5265
  case 2:
4781
5266
  return [
4782
5267
  4,
4783
- fetchAndParsePod(vastTagUrl, source)
5268
+ fetchAndParsePod(vastTagUrl, source, requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.finalizeRequestUrl)
4784
5269
  ];
4785
5270
  case 3:
4786
5271
  ads = _state.sent();
@@ -5357,95 +5842,38 @@ function getOrCreateNonceLoader(allowStorage) {
5357
5842
  function createPalNonceManager() {
5358
5843
  var currentNonce = "";
5359
5844
  var currentNonceManager;
5845
+ var pendingNonce;
5360
5846
  return {
5361
5847
  generateNonce: function generateNonce() {
5362
- return _async_to_generator(function() {
5363
- var options, _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5364
- var _arguments = arguments;
5365
- return _ts_generator(this, function(_state) {
5366
- switch(_state.label){
5367
- case 0:
5368
- options = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {};
5369
- _state.label = 1;
5370
- case 1:
5371
- _state.trys.push([
5372
- 1,
5373
- 4,
5374
- ,
5375
- 5
5376
- ]);
5377
- return [
5378
- 4,
5379
- loadPalSdk()
5380
- ];
5381
- case 2:
5382
- _state.sent();
5383
- loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5384
- goog = window.goog;
5385
- request = new goog.pal.NonceRequest();
5386
- request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5387
- request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5388
- request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5389
- request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5390
- request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5391
- request.iconsSupported = true;
5392
- request.playerType = "StormcloudVideoPlayer";
5393
- request.playerVersion = "1.0";
5394
- request.supportedApiFrameworks = "2,7,9";
5395
- request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5396
- request.videoWidth = options.videoWidth || 640;
5397
- request.videoHeight = options.videoHeight || 480;
5398
- if (options.ppid) request.ppid = options.ppid;
5399
- if (options.sessionId) request.sessionId = options.sessionId;
5400
- console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5401
- adWillAutoPlay: request.adWillAutoPlay,
5402
- adWillPlayMuted: request.adWillPlayMuted,
5403
- playerVolume: request.playerVolume,
5404
- continuousPlayback: request.continuousPlayback,
5405
- descriptionUrl: request.descriptionUrl,
5406
- iconsSupported: request.iconsSupported,
5407
- playerType: request.playerType,
5408
- playerVersion: request.playerVersion,
5409
- supportedApiFrameworks: request.supportedApiFrameworks,
5410
- url: request.url,
5411
- videoWidth: request.videoWidth,
5412
- videoHeight: request.videoHeight,
5413
- ppid: request.ppid,
5414
- sessionId: request.sessionId
5415
- }, null, 2));
5416
- return [
5417
- 4,
5418
- loader.loadNonceManager(request)
5419
- ];
5420
- case 3:
5421
- manager = _state.sent();
5422
- currentNonceManager = manager;
5423
- currentNonce = manager.getNonce();
5424
- console.log("[PAL] Nonce generated successfully");
5425
- return [
5426
- 2,
5427
- currentNonce
5428
- ];
5429
- case 4:
5430
- error = _state.sent();
5431
- console.warn("[PAL] Failed to generate nonce:", error);
5432
- currentNonce = "";
5433
- currentNonceManager = void 0;
5434
- return [
5435
- 2,
5436
- ""
5437
- ];
5438
- case 5:
5439
- return [
5440
- 2
5441
- ];
5442
- }
5443
- });
5444
- }).apply(this, arguments);
5848
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
5849
+ var run = generate(options);
5850
+ pendingNonce = run;
5851
+ var settle = function settle() {
5852
+ if (pendingNonce === run) pendingNonce = void 0;
5853
+ };
5854
+ run.then(settle, settle);
5855
+ return run;
5445
5856
  },
5446
5857
  getCurrentNonce: function getCurrentNonce() {
5447
5858
  return currentNonce;
5448
5859
  },
5860
+ waitForNonce: function waitForNonce(maxWaitMs) {
5861
+ if (currentNonce) return Promise.resolve(currentNonce);
5862
+ var pending = pendingNonce;
5863
+ if (!pending || !(maxWaitMs > 0)) return Promise.resolve("");
5864
+ return new Promise(function(resolve) {
5865
+ var timer = setTimeout(function() {
5866
+ return resolve(currentNonce);
5867
+ }, maxWaitMs);
5868
+ pending.then(function(nonce) {
5869
+ clearTimeout(timer);
5870
+ resolve(nonce);
5871
+ }, function() {
5872
+ clearTimeout(timer);
5873
+ resolve("");
5874
+ });
5875
+ });
5876
+ },
5449
5877
  injectNonce: function injectNonce(vastTagUrl) {
5450
5878
  if (!currentNonce || !vastTagUrl) return vastTagUrl;
5451
5879
  try {
@@ -5482,8 +5910,90 @@ function createPalNonceManager() {
5482
5910
  reset: function reset() {
5483
5911
  currentNonce = "";
5484
5912
  currentNonceManager = void 0;
5913
+ pendingNonce = void 0;
5485
5914
  }
5486
5915
  };
5916
+ function generate(options) {
5917
+ return _async_to_generator(function() {
5918
+ var _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5919
+ return _ts_generator(this, function(_state) {
5920
+ switch(_state.label){
5921
+ case 0:
5922
+ _state.trys.push([
5923
+ 0,
5924
+ 3,
5925
+ ,
5926
+ 4
5927
+ ]);
5928
+ return [
5929
+ 4,
5930
+ loadPalSdk()
5931
+ ];
5932
+ case 1:
5933
+ _state.sent();
5934
+ loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5935
+ goog = window.goog;
5936
+ request = new goog.pal.NonceRequest();
5937
+ request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5938
+ request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5939
+ request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5940
+ request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5941
+ request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5942
+ request.iconsSupported = true;
5943
+ request.playerType = "StormcloudVideoPlayer";
5944
+ request.playerVersion = "1.0";
5945
+ request.supportedApiFrameworks = "2,7,9";
5946
+ request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5947
+ request.videoWidth = options.videoWidth || 640;
5948
+ request.videoHeight = options.videoHeight || 480;
5949
+ if (options.ppid) request.ppid = options.ppid;
5950
+ if (options.sessionId) request.sessionId = options.sessionId;
5951
+ console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5952
+ adWillAutoPlay: request.adWillAutoPlay,
5953
+ adWillPlayMuted: request.adWillPlayMuted,
5954
+ playerVolume: request.playerVolume,
5955
+ continuousPlayback: request.continuousPlayback,
5956
+ descriptionUrl: request.descriptionUrl,
5957
+ iconsSupported: request.iconsSupported,
5958
+ playerType: request.playerType,
5959
+ playerVersion: request.playerVersion,
5960
+ supportedApiFrameworks: request.supportedApiFrameworks,
5961
+ url: request.url,
5962
+ videoWidth: request.videoWidth,
5963
+ videoHeight: request.videoHeight,
5964
+ ppid: request.ppid,
5965
+ sessionId: request.sessionId
5966
+ }, null, 2));
5967
+ return [
5968
+ 4,
5969
+ loader.loadNonceManager(request)
5970
+ ];
5971
+ case 2:
5972
+ manager = _state.sent();
5973
+ currentNonceManager = manager;
5974
+ currentNonce = manager.getNonce();
5975
+ console.log("[PAL] Nonce generated successfully");
5976
+ return [
5977
+ 2,
5978
+ currentNonce
5979
+ ];
5980
+ case 3:
5981
+ error = _state.sent();
5982
+ console.warn("[PAL] Failed to generate nonce:", error);
5983
+ currentNonce = "";
5984
+ currentNonceManager = void 0;
5985
+ return [
5986
+ 2,
5987
+ ""
5988
+ ];
5989
+ case 4:
5990
+ return [
5991
+ 2
5992
+ ];
5993
+ }
5994
+ });
5995
+ })();
5996
+ }
5487
5997
  }
5488
5998
  // src/utils/trackingIngest.ts
5489
5999
  var DEFAULT_TRACKING_INGEST_CONFIG = {
@@ -5566,7 +6076,14 @@ function ingestPlayerTracking(licenseKey, channel, body) {
5566
6076
  // src/utils/tracking.ts
5567
6077
  var cachedBrowserId = null;
5568
6078
  function buildAnalyticsContext(config) {
6079
+ var _config_contentNetwork, _config_channelName, _config_programTitle;
5569
6080
  var context = {};
6081
+ var contentNetwork = (_config_contentNetwork = config.contentNetwork) === null || _config_contentNetwork === void 0 ? void 0 : _config_contentNetwork.trim();
6082
+ var contentChannel = (_config_channelName = config.channelName) === null || _config_channelName === void 0 ? void 0 : _config_channelName.trim();
6083
+ var contentTitle = (_config_programTitle = config.programTitle) === null || _config_programTitle === void 0 ? void 0 : _config_programTitle.trim();
6084
+ if (contentNetwork) context.contentNetwork = contentNetwork;
6085
+ if (contentChannel) context.contentChannel = contentChannel;
6086
+ if (contentTitle) context.contentTitle = contentTitle;
5570
6087
  if (config.debugAdTiming) {
5571
6088
  context.debugAdTiming = true;
5572
6089
  }
@@ -6057,12 +6574,19 @@ function sendAdImpressionTracking(_0, _1) {
6057
6574
  4,
6058
6575
  ingestPlayerTracking(licenseKey, "impressions", {
6059
6576
  events: [
6060
- {
6577
+ _object_spread({
6061
6578
  player_id: metricEvent.player_id,
6062
6579
  ad_played_count: 1,
6063
6580
  ad_url: adImpressionInfo.adUrl,
6064
- capture_at: adImpressionInfo.timestamp
6065
- }
6581
+ capture_at: adImpressionInfo.timestamp,
6582
+ source: "gam"
6583
+ }, context.contentNetwork ? {
6584
+ content_network: context.contentNetwork
6585
+ } : {}, context.contentChannel ? {
6586
+ content_channel: context.contentChannel
6587
+ } : {}, context.contentTitle ? {
6588
+ content_title: context.contentTitle
6589
+ } : {})
6066
6590
  ]
6067
6591
  })
6068
6592
  ];
@@ -7411,6 +7935,21 @@ var Scte35CueManager = /*#__PURE__*/ function() {
7411
7935
  return Scte35CueManager;
7412
7936
  }();
7413
7937
  // src/player/AdConfigManager.ts
7938
+ function withDeferredPodParams(rawUrl, deferNonce) {
7939
+ try {
7940
+ var url = new URL(rawUrl);
7941
+ url.searchParams.set("pmnd", "[SCVP-PMND]");
7942
+ url.searchParams.set("pmxd", "[SCVP-PMXD]");
7943
+ url.searchParams.set("pmad", "[SCVP-PMAD]");
7944
+ if (deferNonce && !url.searchParams.get("givn")) {
7945
+ url.searchParams.delete("paln");
7946
+ url.searchParams.set("givn", "[SCVP-GIVN]");
7947
+ }
7948
+ return url.toString();
7949
+ } catch (unused) {
7950
+ return rawUrl;
7951
+ }
7952
+ }
7414
7953
  var AdConfigManager = /*#__PURE__*/ function() {
7415
7954
  function AdConfigManager(config, video) {
7416
7955
  _class_call_check(this, AdConfigManager);
@@ -7421,8 +7960,8 @@ var AdConfigManager = /*#__PURE__*/ function() {
7421
7960
  this.podCounter = 0;
7422
7961
  this.podAssignedByPrefetch = false;
7423
7962
  this.lastHeartbeatTime = 0;
7424
- this.defaultPodMaxAds = 6;
7425
- this.defaultPodMaxDurationMs = 12e4;
7963
+ this.defaultEdgePodMaxAds = 6;
7964
+ this.palNonceDispatchWaitMs = 1500;
7426
7965
  this.config = config;
7427
7966
  this.video = video;
7428
7967
  }
@@ -7450,7 +7989,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7450
7989
  key: "fetchAdConfiguration",
7451
7990
  value: function fetchAdConfiguration() {
7452
7991
  return _async_to_generator(function() {
7453
- 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;
7992
+ 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;
7454
7993
  return _ts_generator(this, function(_state) {
7455
7994
  switch(_state.label){
7456
7995
  case 0:
@@ -7471,28 +8010,6 @@ var AdConfigManager = /*#__PURE__*/ function() {
7471
8010
  2
7472
8011
  ];
7473
8012
  case 2:
7474
- vastMode = this.config.vastMode || "default";
7475
- if (this.debug) {
7476
- console.log("[StormcloudVideoPlayer] VAST mode:", vastMode);
7477
- }
7478
- if (vastMode === "adstorm") {
7479
- if (!this.config.licenseKey) {
7480
- if (this.debug) {
7481
- console.warn("[StormcloudVideoPlayer] AdStorm mode requires a license key");
7482
- }
7483
- return [
7484
- 2
7485
- ];
7486
- }
7487
- vastEndpoint = "https://adstorm.co/api-adstorm-dev/adstorm/vast/".concat(this.config.licenseKey);
7488
- this.apiVastTagUrl = vastEndpoint;
7489
- if (this.debug) {
7490
- console.log("[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):", vastEndpoint);
7491
- }
7492
- return [
7493
- 2
7494
- ];
7495
- }
7496
8013
  if (this.config.vastTagUrl) {
7497
8014
  this.apiVastTagUrl = normalizeVastTagUrl(this.config.vastTagUrl);
7498
8015
  if (this.debug) {
@@ -7502,7 +8019,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7502
8019
  2
7503
8020
  ];
7504
8021
  }
7505
- apiUrl = "https://adstorm.co/api-adstorm-dev/adstorm/ads/web";
8022
+ apiUrl = "https://edge.stormcloudhub.com/api/v1/adstorm/ads/web";
7506
8023
  if (this.debug) {
7507
8024
  console.log("[StormcloudVideoPlayer] Fetching ad configuration from:", apiUrl);
7508
8025
  }
@@ -7849,16 +8366,16 @@ var AdConfigManager = /*#__PURE__*/ function() {
7849
8366
  }
7850
8367
  },
7851
8368
  {
7852
- key: "resolvePodParams",
7853
- value: function resolvePodParams(breakDurationMs) {
7854
- var maxDurationMs = breakDurationMs != null && breakDurationMs > 0 ? breakDurationMs : this.config.podMaxDurationMs != null && this.config.podMaxDurationMs > 0 ? this.config.podMaxDurationMs : this.defaultPodMaxDurationMs;
7855
- var maxAds = this.config.podMaxAds && this.config.podMaxAds > 0 ? this.config.podMaxAds : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultPodMaxAds;
7856
- var minDurationMs = this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;
7857
- return {
7858
- maxAds: maxAds,
7859
- minDurationMs: minDurationMs,
7860
- maxDurationMs: maxDurationMs
7861
- };
8369
+ key: "resolveAdPodConfig",
8370
+ value: function resolveAdPodConfig1() {
8371
+ return resolveAdPodConfig(this.config);
8372
+ }
8373
+ },
8374
+ {
8375
+ key: "resolveEdgeMaxAds",
8376
+ value: function resolveEdgeMaxAds() {
8377
+ var _this_resolveAdPodConfig_maxAdsPerBreak;
8378
+ 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;
7862
8379
  }
7863
8380
  },
7864
8381
  {
@@ -7875,17 +8392,13 @@ var AdConfigManager = /*#__PURE__*/ function() {
7875
8392
  },
7876
8393
  {
7877
8394
  key: "generatePodVastUrl",
7878
- value: function generatePodVastUrl(baseUrl, podParams, adPlayer, palNonce, inAdBreak) {
7879
- var _podParams_maxDurationMs;
8395
+ value: function generatePodVastUrl(baseUrl, adPlayer, palNonce, inAdBreak) {
7880
8396
  var adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;
7881
8397
  var envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);
7882
- var urlWithMacros = applyVastMacros(baseUrl, _object_spread_props(_object_spread({
8398
+ var macroContext = _object_spread_props(_object_spread({
7883
8399
  correlator: this.viewCorrelator,
7884
8400
  streamCorrelator: this.streamCorrelator,
7885
8401
  pod: this.podCounter > 0 ? this.podCounter : void 0,
7886
- podMaxAds: podParams.maxAds,
7887
- podMinDurationMs: podParams.minDurationMs,
7888
- podMaxDurationMs: podParams.maxDurationMs,
7889
8402
  isCtv: envSignals.isCtv,
7890
8403
  pageUrl: !envSignals.isCtv && typeof window !== "undefined" ? toDevSafeUrl(window.location.href) : void 0,
7891
8404
  adWillPlayMuted: adWillPlayMuted,
@@ -7901,13 +8414,72 @@ var AdConfigManager = /*#__PURE__*/ function() {
7901
8414
  } : {}, this.config.channelName ? {
7902
8415
  channelName: this.config.channelName
7903
8416
  } : {}), {
7904
- consent: this.consentSignals
7905
- }));
7906
- var finalUrl = palNonce.injectNonce(ensureVideoAdType(urlWithMacros));
7907
- 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);
8417
+ consent: this.consentSignals,
8418
+ palNonce: palNonce.getCurrentNonce() || void 0
8419
+ });
8420
+ var nonceReady = !!macroContext.palNonce;
8421
+ var finalUrl;
8422
+ if (hasScvpMacros(baseUrl)) {
8423
+ var deferred = new Set(SCVP_POD_MACROS);
8424
+ if (!nonceReady) deferred.add("GIVN");
8425
+ var _applyScvpMacros = applyScvpMacros(baseUrl, macroContext, deferred), url = _applyScvpMacros.url, unresolved = _applyScvpMacros.unresolved;
8426
+ if (unresolved.length > 0) {
8427
+ console.warn("[StormcloudVideoPlayer] Unresolved SCVP macros (removed from request):", unresolved.join(", "));
8428
+ }
8429
+ finalUrl = ensureVideoAdType(url);
8430
+ } else {
8431
+ finalUrl = withDeferredPodParams(palNonce.injectNonce(ensureVideoAdType(applyVastMacros(baseUrl, macroContext))), !nonceReady);
8432
+ }
8433
+ console.log("[StormcloudVideoPlayer] Prepared optimized-pod request URL (pod=".concat(this.podCounter, "; pmnd/pmxd/pmad resolved at dispatch):"), finalUrl);
7908
8434
  return finalUrl;
7909
8435
  }
7910
8436
  },
8437
+ {
8438
+ key: "completeDeferredRequestSignals",
8439
+ value: function completeDeferredRequestSignals(url, palNonce) {
8440
+ return _async_to_generator(function() {
8441
+ var nonce, _tmp;
8442
+ return _ts_generator(this, function(_state) {
8443
+ switch(_state.label){
8444
+ case 0:
8445
+ if (findScvpMacroNames(url).indexOf("GIVN") === -1) return [
8446
+ 2,
8447
+ url
8448
+ ];
8449
+ _tmp = palNonce.getCurrentNonce();
8450
+ if (_tmp) return [
8451
+ 3,
8452
+ 2
8453
+ ];
8454
+ return [
8455
+ 4,
8456
+ palNonce.waitForNonce(this.palNonceDispatchWaitMs)
8457
+ ];
8458
+ case 1:
8459
+ _tmp = _state.sent();
8460
+ _state.label = 2;
8461
+ case 2:
8462
+ nonce = _tmp;
8463
+ if (!nonce) return [
8464
+ 2,
8465
+ url
8466
+ ];
8467
+ return [
8468
+ 2,
8469
+ substituteScvpMacros(url, /* @__PURE__ */ new Map([
8470
+ [
8471
+ "GIVN",
8472
+ nonce
8473
+ ]
8474
+ ]), function(name) {
8475
+ return name !== "GIVN";
8476
+ }).url
8477
+ ];
8478
+ }
8479
+ });
8480
+ }).call(this);
8481
+ }
8482
+ },
7911
8483
  {
7912
8484
  // --- Tracking ---
7913
8485
  key: "initializeTracking",
@@ -7955,6 +8527,9 @@ var AdConfigManager = /*#__PURE__*/ function() {
7955
8527
  return AdConfigManager;
7956
8528
  }();
7957
8529
  // src/player/AdTimingService.ts
8530
+ function monotonicNow() {
8531
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
8532
+ }
7958
8533
  var AdTimingService = /*#__PURE__*/ function() {
7959
8534
  function AdTimingService(config, video, callbacks) {
7960
8535
  _class_call_check(this, AdTimingService);
@@ -8085,6 +8660,21 @@ var AdTimingService = /*#__PURE__*/ function() {
8085
8660
  },
8086
8661
  {
8087
8662
  // --- Duration boundary ---
8663
+ key: "beginBreakTiming",
8664
+ value: function beginBreakTiming(startWallClockMs) {
8665
+ this.currentAdBreakStartWallClockMs = startWallClockMs;
8666
+ this.breakStartMonoMs = monotonicNow() + (startWallClockMs - Date.now());
8667
+ this.breakEndMonoMs = void 0;
8668
+ }
8669
+ },
8670
+ {
8671
+ key: "markBreakEndedNow",
8672
+ value: function markBreakEndedNow() {
8673
+ this.scteAdBreakEndWallClockMs = Date.now();
8674
+ this.breakEndMonoMs = monotonicNow();
8675
+ }
8676
+ },
8677
+ {
8088
8678
  key: "setAdBreakDurationBoundary",
8089
8679
  value: function setAdBreakDurationBoundary(durationMs) {
8090
8680
  this.expectedAdBreakDurationMs = durationMs;
@@ -8093,6 +8683,18 @@ var AdTimingService = /*#__PURE__*/ function() {
8093
8683
  } else {
8094
8684
  this.scteAdBreakEndWallClockMs = void 0;
8095
8685
  }
8686
+ this.breakEndMonoMs = durationMs != null && this.breakStartMonoMs != null ? this.breakStartMonoMs + durationMs : void 0;
8687
+ }
8688
+ },
8689
+ {
8690
+ key: "getBreakTimingSnapshot",
8691
+ value: function getBreakTimingSnapshot() {
8692
+ return {
8693
+ scheduledBreakDurationMs: this.expectedAdBreakDurationMs,
8694
+ breakStartMonoMs: this.breakStartMonoMs,
8695
+ breakEndMonoMs: this.breakEndMonoMs,
8696
+ playedDurationMs: this.adBreakPlayedDurationMs
8697
+ };
8096
8698
  }
8097
8699
  },
8098
8700
  {
@@ -8506,6 +9108,8 @@ var AdTimingService = /*#__PURE__*/ function() {
8506
9108
  this.expectedAdBreakDurationMs = void 0;
8507
9109
  this.currentAdBreakStartWallClockMs = void 0;
8508
9110
  this.scteAdBreakEndWallClockMs = void 0;
9111
+ this.breakStartMonoMs = void 0;
9112
+ this.breakEndMonoMs = void 0;
8509
9113
  this.adBreakPlayedDurationMs = 0;
8510
9114
  this.currentAdIndex = 0;
8511
9115
  this.totalAdsInBreak = 0;
@@ -9519,9 +10123,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9519
10123
  // ───────────────────────────────────────────────────────────────
9520
10124
  key: "nextAdRequestUrl",
9521
10125
  value: function nextAdRequestUrl(baseVastUrl) {
9522
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
9523
- var breakDurationMs = remaining > 0 ? remaining : void 0;
9524
- return this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10126
+ return this.host.generatePodVastUrl(baseVastUrl);
9525
10127
  }
9526
10128
  },
9527
10129
  {
@@ -9784,7 +10386,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9784
10386
  key: "handleAdStart",
9785
10387
  value: function handleAdStart(marker) {
9786
10388
  return _async_to_generator(function() {
9787
- var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
10389
+ var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, mode, edgeUrl, outcome, podPlayed;
9788
10390
  return _ts_generator(this, function(_state) {
9789
10391
  switch(_state.label){
9790
10392
  case 0:
@@ -9836,8 +10438,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9836
10438
  }
9837
10439
  this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
9838
10440
  epoch = this.timing.adBreakEpoch;
9839
- hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
9840
- if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
10441
+ if (!(adBreakDurationMs == null)) return [
9841
10442
  3,
9842
10443
  2
9843
10444
  ];
@@ -9893,7 +10494,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9893
10494
  }
9894
10495
  return [
9895
10496
  4,
9896
- this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
10497
+ this.startOptimizedPod(baseVastUrl)
9897
10498
  ];
9898
10499
  case 6:
9899
10500
  podPlayed = _state.sent();
@@ -9961,9 +10562,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9961
10562
  value: // ───────────────────────────────────────────────────────────────
9962
10563
  // Optimized pod (single multi-ad request)
9963
10564
  // ───────────────────────────────────────────────────────────────
9964
- function startOptimizedPod(baseVastUrl, breakDurationMs) {
10565
+ function startOptimizedPod(baseVastUrl) {
9965
10566
  return _async_to_generator(function() {
9966
- var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _adPlayer_getPodAdCount, podCount, error;
10567
+ var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _this_currentVastUrl, _adPlayer_getPodAdCount, finalizeRequestUrl, podCount, error;
9967
10568
  return _ts_generator(this, function(_state) {
9968
10569
  switch(_state.label){
9969
10570
  case 0:
@@ -9972,7 +10573,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9972
10573
  podUrl = this.pendingAdBreak.vastUrls[0];
9973
10574
  this.clearPendingAdBreak();
9974
10575
  } else {
9975
- podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10576
+ podUrl = this.host.generatePodVastUrl(baseVastUrl);
9976
10577
  }
9977
10578
  if (!podUrl) {
9978
10579
  return [
@@ -9996,9 +10597,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9996
10597
  case 1:
9997
10598
  _state.trys.push([
9998
10599
  1,
9999
- 5,
10600
+ 9,
10000
10601
  ,
10001
- 6
10602
+ 10
10002
10603
  ]);
10003
10604
  return [
10004
10605
  4,
@@ -10010,15 +10611,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10010
10611
  2,
10011
10612
  true
10012
10613
  ];
10614
+ return [
10615
+ 4,
10616
+ this.host.completeGamRequestSignals(requestUrl)
10617
+ ];
10618
+ case 3:
10619
+ requestUrl = _state.sent();
10620
+ if (this.isStale(epoch, generation)) return [
10621
+ 2,
10622
+ true
10623
+ ];
10013
10624
  this.timing.startAdRequestWatchdog(requestToken);
10625
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
10626
+ _state.label = 4;
10627
+ case 4:
10628
+ _state.trys.push([
10629
+ 4,
10630
+ ,
10631
+ 6,
10632
+ 7
10633
+ ]);
10014
10634
  return [
10015
10635
  4,
10016
10636
  this.callController(function() {
10017
- return adPlayer.requestAds(requestUrl);
10637
+ return adPlayer.requestAds(requestUrl, {
10638
+ finalizeRequestUrl: finalizeRequestUrl
10639
+ });
10018
10640
  })
10019
10641
  ];
10020
- case 3:
10642
+ case 5:
10021
10643
  _state.sent();
10644
+ return [
10645
+ 3,
10646
+ 7
10647
+ ];
10648
+ case 6:
10649
+ this.recordPodResponseDiagnostics(requestToken, adPlayer);
10650
+ return [
10651
+ 7
10652
+ ];
10653
+ case 7:
10022
10654
  this.timing.clearAdRequestWatchdog();
10023
10655
  if (this.isStale(epoch, generation)) {
10024
10656
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -10046,7 +10678,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10046
10678
  }
10047
10679
  sendAdLoadedTracking(this.host.config.licenseKey, {
10048
10680
  source: "hls",
10049
- vastUrl: requestUrl,
10681
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
10050
10682
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
10051
10683
  }, this.analyticsContext).catch(function() {});
10052
10684
  this.timing.startAdFailsafeTimer(requestToken);
@@ -10056,7 +10688,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10056
10688
  return adPlayer.play();
10057
10689
  })
10058
10690
  ];
10059
- case 4:
10691
+ case 8:
10060
10692
  _state.sent();
10061
10693
  if (this.isStale(epoch, generation)) return [
10062
10694
  2,
@@ -10070,7 +10702,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10070
10702
  2,
10071
10703
  true
10072
10704
  ];
10073
- case 5:
10705
+ case 9:
10074
10706
  error = _state.sent();
10075
10707
  this.timing.clearAdRequestWatchdog();
10076
10708
  this.timing.clearAdFailsafeTimer();
@@ -10090,12 +10722,16 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10090
10722
  if (this.debug) {
10091
10723
  console.warn("[POD] Optimized pod request/play failed:", error);
10092
10724
  }
10725
+ if (this.handlePodRequestNotSent(error)) return [
10726
+ 2,
10727
+ false
10728
+ ];
10093
10729
  this.recordRequestFailure(error, podUrl);
10094
10730
  return [
10095
10731
  2,
10096
10732
  false
10097
10733
  ];
10098
- case 6:
10734
+ case 10:
10099
10735
  return [
10100
10736
  2
10101
10737
  ];
@@ -10141,17 +10777,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10141
10777
  }
10142
10778
  },
10143
10779
  {
10144
- /**
10145
- * Builds the next Edge request from the budget left right now, or marks Edge
10146
- * exhausted for this break. Synchronous on purpose: callers must reach the
10147
- * REQUESTING state in the same tick so a second completion event cannot race
10148
- * in a parallel request.
10149
- */ key: "prepareEdgePodRequest",
10780
+ key: "prepareEdgePodRequest",
10150
10781
  value: function prepareEdgePodRequest() {
10151
10782
  var baseUrl = this.host.getEdgePodBaseUrl();
10152
10783
  if (!baseUrl) return void 0;
10153
10784
  var remainingMs = this.timing.getRemainingAdMs();
10154
- var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
10785
+ var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak);
10155
10786
  if (remainingAds < 1) {
10156
10787
  this.markEdgeExhausted("ad_capacity_reached", {
10157
10788
  adsInBreak: this.timing.totalAdsInBreak
@@ -10230,7 +10861,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10230
10861
  ];
10231
10862
  }
10232
10863
  remainingMs = this.timing.getRemainingAdMs();
10233
- remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
10864
+ remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak));
10234
10865
  overrunAllowanceMs = Math.max(0, (_this_host_config_maxAdBreakExtensionMs = this.host.config.maxAdBreakExtensionMs) !== null && _this_host_config_maxAdBreakExtensionMs !== void 0 ? _this_host_config_maxAdBreakExtensionMs : 0);
10235
10866
  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;
10236
10867
  if (classifyEdgeVastResponse({
@@ -10577,7 +11208,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10577
11208
  {
10578
11209
  key: "noteVastUrlGenerated",
10579
11210
  value: function noteVastUrlGenerated(url, source) {
10580
- var _ref, _ref1, _ref2, _ref3, _ref4;
11211
+ var _ref, _ref1;
10581
11212
  var params;
10582
11213
  try {
10583
11214
  params = new URL(url).searchParams;
@@ -10587,9 +11218,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10587
11218
  requestId: void 0,
10588
11219
  source: source,
10589
11220
  pod: (_ref1 = params === null || params === void 0 ? void 0 : params.get("pod")) !== null && _ref1 !== void 0 ? _ref1 : void 0,
10590
- pmad: (_ref2 = params === null || params === void 0 ? void 0 : params.get("pmad")) !== null && _ref2 !== void 0 ? _ref2 : void 0,
10591
- pmnd: (_ref3 = params === null || params === void 0 ? void 0 : params.get("pmnd")) !== null && _ref3 !== void 0 ? _ref3 : void 0,
10592
- pmxd: (_ref4 = params === null || params === void 0 ? void 0 : params.get("pmxd")) !== null && _ref4 !== void 0 ? _ref4 : void 0,
11221
+ podParamsDeferredToDispatch: findScvpMacroNames(url).some(function(name) {
11222
+ return SCVP_POD_MACROS.has(name);
11223
+ }),
10593
11224
  adType: adType
10594
11225
  });
10595
11226
  if (adType === "audio" || adType === "audio_video") {
@@ -10630,10 +11261,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10630
11261
  if (diag && !diag.failureReason) {
10631
11262
  diag.failureReason = "".concat(outcome, ": ").concat(message);
10632
11263
  }
11264
+ var failureKey = (diag === null || diag === void 0 ? void 0 : diag.dispatchedUrl) && findScvpMacroNames(vastTagUrl).some(function(name) {
11265
+ return SCVP_POD_MACROS.has(name);
11266
+ }) ? diag.dispatchedUrl : vastTagUrl;
10633
11267
  if (this.timing.isTemporaryAdError(error)) {
10634
- this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());
11268
+ this.timing.temporaryFailureUrls.set(failureKey, Date.now());
10635
11269
  } else if (outcome !== "discarded_budget") {
10636
- this.timing.failedVastUrls.add(vastTagUrl);
11270
+ this.timing.failedVastUrls.add(failureKey);
10637
11271
  }
10638
11272
  this.countFunnelStage("request_outcome:".concat(outcome));
10639
11273
  this.logOrchestratorFunnel("request_outcome", _object_spread({
@@ -10659,6 +11293,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10659
11293
  switch(payload.stage){
10660
11294
  case "gam_http_request_sent":
10661
11295
  diag.gamRequestSent++;
11296
+ this.logPodDispatch(diag);
10662
11297
  break;
10663
11298
  case "edge_http_request_sent":
10664
11299
  diag.edgeRequestSent++;
@@ -10710,8 +11345,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10710
11345
  if (gamReturnedAdWithoutImpression) {
10711
11346
  this.countFunnelStage("gam_ad_without_impression");
10712
11347
  }
10713
- var startedAt = diag.startedAt, fields = _object_without_properties(diag, [
10714
- "startedAt"
11348
+ var startedAt = diag.startedAt, _dispatchedUrl = diag.dispatchedUrl, _logged = diag.podDispatchLogged, fields = _object_without_properties(diag, [
11349
+ "startedAt",
11350
+ "dispatchedUrl",
11351
+ "podDispatchLogged"
10715
11352
  ]);
10716
11353
  console.log("[AdBreak][REQUEST] summary", _object_spread_props(_object_spread({}, fields), {
10717
11354
  durationMs: Date.now() - startedAt,
@@ -10723,24 +11360,71 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10723
11360
  // ───────────────────────────────────────────────────────────────
10724
11361
  // Single ad playback
10725
11362
  // ───────────────────────────────────────────────────────────────
10726
- key: "withCurrentPodBudget",
10727
- value: function withCurrentPodBudget(rawVastTagUrl) {
10728
- var vastTagUrl = ensureVideoAdType(rawVastTagUrl);
10729
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
10730
- if (!(remaining > 0)) return vastTagUrl;
10731
- try {
10732
- var url = new URL(vastTagUrl);
10733
- if (!url.searchParams.has("pmxd")) return vastTagUrl;
10734
- var maxMs = Math.round(remaining);
10735
- url.searchParams.set("pmxd", String(maxMs));
10736
- var minMs = Number(url.searchParams.get("pmnd"));
10737
- if (Number.isFinite(minMs) && minMs > maxMs) {
10738
- url.searchParams.set("pmnd", String(maxMs));
10739
- }
10740
- return url.toString();
10741
- } catch (unused) {
10742
- return vastTagUrl;
10743
- }
11363
+ key: "createGamDispatchFinalizer",
11364
+ value: function createGamDispatchFinalizer(requestToken) {
11365
+ var _this = this;
11366
+ var breakId = this.timing.adBreakEpoch;
11367
+ var config = this.adConfig.resolveAdPodConfig();
11368
+ var minUsablePmxdMs = this.timing.getMinRemainingMsToStartAd();
11369
+ return function(url) {
11370
+ var capacity = measureBreakCapacity(_this.timing.getBreakTimingSnapshot(), monotonicNow());
11371
+ var diag = _this.requestDiagnostics.get(requestToken);
11372
+ try {
11373
+ var result = finalizeGamRequestUrl(url, {
11374
+ breakId: breakId,
11375
+ capacity: capacity,
11376
+ config: config,
11377
+ minUsablePmxdMs: minUsablePmxdMs
11378
+ });
11379
+ if (diag) {
11380
+ diag.pod = result.diagnostics;
11381
+ diag.dispatchedUrl = result.url;
11382
+ diag.podDispatchLogged = false;
11383
+ }
11384
+ _this.currentVastUrl = result.url;
11385
+ return result.url;
11386
+ } catch (error) {
11387
+ if (diag && isPodRequestAbortedError(error)) {
11388
+ diag.failureReason = "pod_request_not_sent:".concat(error.reason);
11389
+ }
11390
+ throw error;
11391
+ }
11392
+ };
11393
+ }
11394
+ },
11395
+ {
11396
+ key: "logPodDispatch",
11397
+ value: function logPodDispatch(diag) {
11398
+ if (!diag.pod || diag.podDispatchLogged) return;
11399
+ diag.podDispatchLogged = true;
11400
+ this.logOrchestratorFunnel(diag.pod.optimizedPod ? "optimized_pod_request_dispatched" : "gam_request_dispatched", _object_spread({}, diag.pod));
11401
+ }
11402
+ },
11403
+ {
11404
+ key: "recordPodResponseDiagnostics",
11405
+ value: function recordPodResponseDiagnostics(requestToken, adPlayer) {
11406
+ var _diag_vastAdCount, _ref;
11407
+ var _adPlayer_getPodTotalDurationMs;
11408
+ var diag = this.requestDiagnostics.get(requestToken);
11409
+ if (!(diag === null || diag === void 0 ? void 0 : diag.pod) || diag.pod.pmxdSent == null || diag.podResponse) return;
11410
+ if (diag.gamRequestSent === 0 && diag.vastHttpStatus == null) return;
11411
+ 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);
11412
+ this.logOrchestratorFunnel("optimized_pod_response", _object_spread({
11413
+ pmxdSent: diag.pod.pmxdSent
11414
+ }, diag.podResponse));
11415
+ }
11416
+ },
11417
+ {
11418
+ key: "handlePodRequestNotSent",
11419
+ value: function handlePodRequestNotSent(error) {
11420
+ if (!isPodRequestAbortedError(error) || error.reason === "invalid_url") return false;
11421
+ var aborted = error;
11422
+ this.countFunnelStage("request_outcome:pod_request_not_sent");
11423
+ this.logOrchestratorFunnel("pod_request_not_sent", _object_spread({
11424
+ reason: aborted.reason,
11425
+ errorMessage: aborted.message
11426
+ }, aborted.diagnostics));
11427
+ return true;
10744
11428
  }
10745
11429
  },
10746
11430
  {
@@ -10960,7 +11644,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10960
11644
  value: function playSingleAd(vastTagUrl) {
10961
11645
  var trigger = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "vmap";
10962
11646
  return _async_to_generator(function() {
10963
- var epoch, generation, requestToken, ap, budgetedUrl, requestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
11647
+ var epoch, generation, requestToken, ap, requestUrl, _this_currentVastUrl, finalizeRequestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
10964
11648
  return _ts_generator(this, function(_state) {
10965
11649
  switch(_state.label){
10966
11650
  case 0:
@@ -10998,19 +11682,18 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10998
11682
  requestToken = ++this.timing.adRequestTokenCounter;
10999
11683
  this.timing.activeAdRequestToken = requestToken;
11000
11684
  ap = this.host.getAdPlayer();
11001
- budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
11002
11685
  this.currentPodSource = "gam";
11003
11686
  this.setSlotState("REQUESTING", trigger);
11004
11687
  this.beginFunnelRequest(ap, requestToken, trigger);
11005
- requestUrl = this.applyOpportunityFloor(budgetedUrl);
11688
+ requestUrl = this.applyOpportunityFloor(ensureVideoAdType(vastTagUrl));
11006
11689
  this.currentVastUrl = requestUrl;
11007
11690
  _state.label = 1;
11008
11691
  case 1:
11009
11692
  _state.trys.push([
11010
11693
  1,
11011
- 5,
11694
+ 9,
11012
11695
  ,
11013
- 6
11696
+ 10
11014
11697
  ]);
11015
11698
  return [
11016
11699
  4,
@@ -11021,15 +11704,45 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11021
11704
  if (this.isStale(epoch, generation)) return [
11022
11705
  2
11023
11706
  ];
11707
+ return [
11708
+ 4,
11709
+ this.host.completeGamRequestSignals(requestUrl)
11710
+ ];
11711
+ case 3:
11712
+ requestUrl = _state.sent();
11713
+ if (this.isStale(epoch, generation)) return [
11714
+ 2
11715
+ ];
11024
11716
  this.timing.startAdRequestWatchdog(requestToken);
11717
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
11718
+ _state.label = 4;
11719
+ case 4:
11720
+ _state.trys.push([
11721
+ 4,
11722
+ ,
11723
+ 6,
11724
+ 7
11725
+ ]);
11025
11726
  return [
11026
11727
  4,
11027
11728
  this.callController(function() {
11028
- return ap.requestAds(requestUrl);
11729
+ return ap.requestAds(requestUrl, {
11730
+ finalizeRequestUrl: finalizeRequestUrl
11731
+ });
11029
11732
  })
11030
11733
  ];
11031
- case 3:
11734
+ case 5:
11032
11735
  _state.sent();
11736
+ return [
11737
+ 3,
11738
+ 7
11739
+ ];
11740
+ case 6:
11741
+ this.recordPodResponseDiagnostics(requestToken, ap);
11742
+ return [
11743
+ 7
11744
+ ];
11745
+ case 7:
11033
11746
  this.timing.clearAdRequestWatchdog();
11034
11747
  if (this.isStale(epoch, generation)) {
11035
11748
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -11041,7 +11754,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11041
11754
  }
11042
11755
  sendAdLoadedTracking(this.host.config.licenseKey, {
11043
11756
  source: "hls",
11044
- vastUrl: requestUrl,
11757
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
11045
11758
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11046
11759
  }, this.analyticsContext).catch(function() {});
11047
11760
  if (!this.timing.ensureLoadedAdFitsBudget(ap)) {
@@ -11062,7 +11775,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11062
11775
  return ap.play();
11063
11776
  })
11064
11777
  ];
11065
- case 4:
11778
+ case 8:
11066
11779
  _state.sent();
11067
11780
  if (this.isStale(epoch, generation)) return [
11068
11781
  2
@@ -11074,9 +11787,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11074
11787
  this.timing.temporaryFailureUrls.delete(vastTagUrl);
11075
11788
  return [
11076
11789
  3,
11077
- 6
11790
+ 10
11078
11791
  ];
11079
- case 5:
11792
+ case 9:
11080
11793
  error = _state.sent();
11081
11794
  this.timing.clearAdRequestWatchdog();
11082
11795
  this.timing.clearAdFailsafeTimer();
@@ -11093,12 +11806,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11093
11806
  ];
11094
11807
  }
11095
11808
  if (this.debug) console.error("[AD-ERROR] Ad request failed:", error === null || error === void 0 ? void 0 : error.message);
11809
+ if (this.handlePodRequestNotSent(error)) throw error;
11096
11810
  this.recordRequestFailure(error, vastTagUrl);
11097
11811
  if ((error === null || error === void 0 ? void 0 : error.message) === "ad_duration_exceeds_budget") {
11098
11812
  this.recreateAdController("discarded_budget");
11099
11813
  }
11100
11814
  throw error;
11101
- case 6:
11815
+ case 10:
11102
11816
  return [
11103
11817
  2
11104
11818
  ];
@@ -11160,7 +11874,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11160
11874
  playbackFailedAfterFill: count("request_outcome:playback_failed"),
11161
11875
  requestFailed: count("request_failed"),
11162
11876
  requestAbortedTimeout: count("request_aborted_timeout"),
11163
- credentialsRetries: count("vast_credentials_retry"),
11877
+ credentialsModeChanges: count("gam_credentials_mode_changed"),
11164
11878
  wrapperFailures: count("wrapper_fetch:failure"),
11165
11879
  noSupportedMedia: count("vast_no_supported_media"),
11166
11880
  vpaidOnly: count("vast_no_supported_media:vpaid"),
@@ -11696,8 +12410,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11696
12410
  requiresMediaPipelineResetAfterAds: function requiresMediaPipelineResetAfterAds1() {
11697
12411
  return requiresMediaPipelineResetAfterAds();
11698
12412
  },
11699
- generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
11700
- return _this.generatePodVastUrl(base, breakDurationMs);
12413
+ generatePodVastUrl: function generatePodVastUrl(base) {
12414
+ return _this.generatePodVastUrl(base);
12415
+ },
12416
+ completeGamRequestSignals: function completeGamRequestSignals(url) {
12417
+ return _this.adConfig.completeDeferredRequestSignals(url, _this.palNonce);
11701
12418
  },
11702
12419
  getEdgePodBaseUrl: function getEdgePodBaseUrl() {
11703
12420
  return _this.edgePodBaseUrl;
@@ -11821,9 +12538,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11821
12538
  },
11822
12539
  {
11823
12540
  key: "generatePodVastUrl",
11824
- value: function generatePodVastUrl(baseUrl, breakDurationMs) {
11825
- var podParams = this.adConfig.resolvePodParams(breakDurationMs);
11826
- return this.adConfig.generatePodVastUrl(baseUrl, podParams, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
12541
+ value: function generatePodVastUrl(baseUrl) {
12542
+ return this.adConfig.generatePodVastUrl(baseUrl, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
11827
12543
  }
11828
12544
  },
11829
12545
  {
@@ -12177,7 +12893,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12177
12893
  activeAdRequest: this.timing.activeAdRequestToken !== null
12178
12894
  });
12179
12895
  }
12180
- this.timing.scteAdBreakEndWallClockMs = Date.now();
12896
+ this.timing.markBreakEndedNow();
12181
12897
  this.timing.clearAdStartTimer();
12182
12898
  this.timing.clearAdStopTimer();
12183
12899
  if (adPlaying) {
@@ -12204,7 +12920,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12204
12920
  this.adBreak.inAdBreak = true;
12205
12921
  this.cueManager.activeScte35BreakKey = cueKey !== null && cueKey !== void 0 ? cueKey : this.cueManager.pendingScte35CueKey;
12206
12922
  this.cueManager.scheduledScte35BreakKey = void 0;
12207
- this.timing.currentAdBreakStartWallClockMs = this.timing.resolveScteBreakStartWallClockMs(marker);
12923
+ this.timing.beginBreakTiming(this.timing.resolveScteBreakStartWallClockMs(marker));
12208
12924
  this.timing.setAdBreakDurationBoundary(durationMs);
12209
12925
  this.adBreak.handleAdStart(marker);
12210
12926
  this.timing.scheduleAdStopAtBreakBoundary();
@@ -12250,9 +12966,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12250
12966
  }
12251
12967
  this.adConfig.beginNewAdPod();
12252
12968
  this.adConfig.podAssignedByPrefetch = true;
12253
- var breakDurationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;
12254
12969
  var generatedUrls = [
12255
- this.generatePodVastUrl(baseVastUrl, breakDurationMs)
12970
+ this.generatePodVastUrl(baseVastUrl)
12256
12971
  ];
12257
12972
  this.adBreak.pendingAdBreak = _object_spread_props(_object_spread({
12258
12973
  marker: marker
@@ -12351,7 +13066,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12351
13066
  this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);
12352
13067
  this.adBreak.showAds = true;
12353
13068
  this.adBreak.inAdBreak = true;
12354
- this.timing.currentAdBreakStartWallClockMs = Date.now();
13069
+ this.timing.beginBreakTiming(Date.now());
12355
13070
  if (durationMs > 0) {
12356
13071
  this.timing.setAdBreakDurationBoundary(durationMs);
12357
13072
  }