stormcloud-video-player 0.8.73 → 0.8.74

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