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
@@ -429,21 +429,20 @@ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
429
429
  "adid"
430
430
  ]);
431
431
  function resolveVastEnvironmentSignals(isCtv) {
432
- var _ref;
433
432
  var bridgeSignals = readNativeBridgeSignals();
434
433
  var platformDevice = readPlatformNativeDeviceId();
435
- var realDeviceId = bridgeSignals.deviceId || (isCtv ? readStoredDeviceId() : void 0) || platformDevice.deviceId;
434
+ var bridgeDeviceId = validDeviceId(bridgeSignals.deviceId);
435
+ var realDeviceId = bridgeDeviceId || (isCtv ? validDeviceId(readStoredDeviceId()) : void 0) || validDeviceId(platformDevice.deviceId);
436
436
  var deviceId = realDeviceId;
437
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
438
- var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
439
- var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
437
+ var deviceIdType = (bridgeDeviceId ? bridgeSignals.deviceIdType : void 0) || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
438
+ var platformLat = bridgeDeviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
439
+ var limitAdTracking = deviceId != null ? platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking() : void 0;
440
440
  if (!deviceId && isCtv) {
441
441
  var dpid = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);
442
442
  if (dpid) {
443
- var _ref1;
444
443
  deviceId = dpid;
445
444
  deviceIdType = "dpid";
446
- limitAdTracking = (_ref1 = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref1 !== void 0 ? _ref1 : false;
445
+ limitAdTracking = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking();
447
446
  }
448
447
  }
449
448
  var deviceTypeHint = resolveDeviceTypeHint(isCtv);
@@ -808,6 +807,9 @@ function isMacroPlaceholder(value) {
808
807
  var t = value.trim();
809
808
  return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
810
809
  }
810
+ function validDeviceId(value) {
811
+ return value && !isMacroPlaceholder(value) ? value : void 0;
812
+ }
811
813
  function isZeroedAdId(value) {
812
814
  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
813
815
  }
@@ -1340,6 +1342,199 @@ function ensureVideoAdType(rawUrl) {
1340
1342
  return rawUrl;
1341
1343
  }
1342
1344
  }
1345
+ var SCVP_MACRO_DETECT = /\[SCVP-|%5BSCVP-|\(SCVP-|%28SCVP-/i;
1346
+ var SCVP_MACRO_PATTERN = /\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\)/gi;
1347
+ var SCVP_WHOLE_VALUE_PATTERN = /^\s*(?:\[SCVP-([A-Z0-9-]+)\]|\(SCVP-([A-Z0-9-]+)\))\s*$/i;
1348
+ var NESTED_QUERY_PARAM_KEYS = /* @__PURE__ */ new Set([
1349
+ "cust_params"
1350
+ ]);
1351
+ var SCVP_POD_MACROS = /* @__PURE__ */ new Set([
1352
+ "PMND",
1353
+ "PMXD",
1354
+ "PMAD"
1355
+ ]);
1356
+ function hasScvpMacros(url) {
1357
+ return !!url && SCVP_MACRO_DETECT.test(url);
1358
+ }
1359
+ function safeDecode(value) {
1360
+ try {
1361
+ return decodeURIComponent(value.replace(/\+/g, " "));
1362
+ } catch (unused) {
1363
+ return value;
1364
+ }
1365
+ }
1366
+ function findScvpMacroNames(url) {
1367
+ if (!url) return [];
1368
+ var names = /* @__PURE__ */ new Set();
1369
+ var text = url;
1370
+ for(var pass = 0; pass < 3; pass++){
1371
+ text.replace(SCVP_MACRO_PATTERN, function(_m, bracketName, parenName) {
1372
+ names.add(String(bracketName || parenName).toUpperCase());
1373
+ return "";
1374
+ });
1375
+ var decoded = safeDecode(text);
1376
+ if (decoded === text) break;
1377
+ text = decoded;
1378
+ }
1379
+ return Array.from(names);
1380
+ }
1381
+ function resolveScvpMacroValues(ctx) {
1382
+ var _ctx_deviceId, _ctx_deviceIdType, _ctx_consent, _ctx_consent1, _ctx_consent2;
1383
+ var values = /* @__PURE__ */ new Map();
1384
+ var set = function set(name, value) {
1385
+ if (value == null) return;
1386
+ var str = String(value).trim();
1387
+ if (str) values.set(name, str);
1388
+ };
1389
+ var toFlag = function toFlag(value) {
1390
+ return value == null ? void 0 : value ? "1" : "0";
1391
+ };
1392
+ var deviceId = (_ctx_deviceId = ctx.deviceId) === null || _ctx_deviceId === void 0 ? void 0 : _ctx_deviceId.trim();
1393
+ var deviceIdType = deviceId ? ((_ctx_deviceIdType = ctx.deviceIdType) === null || _ctx_deviceIdType === void 0 ? void 0 : _ctx_deviceIdType.trim()) || inferDeviceIdType() : void 0;
1394
+ if (deviceId && deviceIdType) {
1395
+ var _toFlag;
1396
+ set("RDID", deviceId);
1397
+ set("IDTYPE", deviceIdType);
1398
+ set("IS-LAT", (_toFlag = toFlag(ctx.limitAdTracking)) !== null && _toFlag !== void 0 ? _toFlag : "0");
1399
+ }
1400
+ set("SID", ctx.sessionId);
1401
+ set("DTH", ctx.deviceTypeHint);
1402
+ set("GIVN", ctx.palNonce);
1403
+ set("CT-TI", ctx.programTitle);
1404
+ set("CT-CH", ctx.channelName);
1405
+ set("POD", ctx.pod);
1406
+ set("CORRELATOR", ctx.correlator);
1407
+ set("SCOR", ctx.streamCorrelator);
1408
+ set("VPMUTE", toFlag(ctx.adWillPlayMuted));
1409
+ if (ctx.adWillAutoPlay != null) {
1410
+ set("VPA", ctx.adWillAutoPlay ? "auto" : "click");
1411
+ }
1412
+ set("GDPR", (_ctx_consent = ctx.consent) === null || _ctx_consent === void 0 ? void 0 : _ctx_consent.gdpr);
1413
+ set("GDPR-CONSENT", (_ctx_consent1 = ctx.consent) === null || _ctx_consent1 === void 0 ? void 0 : _ctx_consent1.gdprConsent);
1414
+ set("US-PRIVACY", (_ctx_consent2 = ctx.consent) === null || _ctx_consent2 === void 0 ? void 0 : _ctx_consent2.usPrivacy);
1415
+ return values;
1416
+ }
1417
+ var keepNone = function keepNone() {
1418
+ return false;
1419
+ };
1420
+ function substituteScvpParams(params, values, unresolved, keep, nested) {
1421
+ var out = [];
1422
+ var replaceMacro = function replaceMacro(match, bracketName, parenName) {
1423
+ var name = String(bracketName || parenName).toUpperCase();
1424
+ var value = values.get(name);
1425
+ if (value != null) return value;
1426
+ if (keep(name)) return match;
1427
+ unresolved.add(name);
1428
+ return "";
1429
+ };
1430
+ params.forEach(function(value, key) {
1431
+ var whole = value.match(SCVP_WHOLE_VALUE_PATTERN);
1432
+ if (whole) {
1433
+ var name = String(whole[1] || whole[2]).toUpperCase();
1434
+ var resolved = values.get(name);
1435
+ if (resolved != null) {
1436
+ out.push([
1437
+ key,
1438
+ resolved
1439
+ ]);
1440
+ } else if (keep(name)) {
1441
+ out.push([
1442
+ key,
1443
+ value
1444
+ ]);
1445
+ } else {
1446
+ unresolved.add(name);
1447
+ }
1448
+ return;
1449
+ }
1450
+ if (!SCVP_MACRO_DETECT.test(value)) {
1451
+ out.push([
1452
+ key,
1453
+ value
1454
+ ]);
1455
+ return;
1456
+ }
1457
+ if (!nested && NESTED_QUERY_PARAM_KEYS.has(key)) {
1458
+ var inner = substituteScvpParams(new URLSearchParams(value), values, unresolved, keep, true);
1459
+ if (inner.length > 0) {
1460
+ out.push([
1461
+ key,
1462
+ inner.map(function(param) {
1463
+ var _param = _sliced_to_array(param, 2), k = _param[0], v = _param[1];
1464
+ return "".concat(encodeURIComponent(k), "=").concat(encodeURIComponent(v));
1465
+ }).join("&")
1466
+ ]);
1467
+ }
1468
+ return;
1469
+ }
1470
+ out.push([
1471
+ key,
1472
+ value.replace(SCVP_MACRO_PATTERN, replaceMacro)
1473
+ ]);
1474
+ });
1475
+ return out;
1476
+ }
1477
+ function substituteScvpMacros(baseUrl, values) {
1478
+ var keep = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : keepNone;
1479
+ var unresolved = /* @__PURE__ */ new Set();
1480
+ var url;
1481
+ try {
1482
+ url = new URL(normalizeVastTagUrl(baseUrl));
1483
+ } catch (unused) {
1484
+ var replaced = baseUrl.replace(SCVP_MACRO_PATTERN, function(match, bracketName, parenName) {
1485
+ var name = String(bracketName || parenName).toUpperCase();
1486
+ var value = values.get(name);
1487
+ if (value != null) return encodeURIComponent(value);
1488
+ if (keep(name)) return match;
1489
+ unresolved.add(name);
1490
+ return "";
1491
+ });
1492
+ return {
1493
+ url: replaced,
1494
+ unresolved: Array.from(unresolved)
1495
+ };
1496
+ }
1497
+ var entries = substituteScvpParams(url.searchParams, values, unresolved, keep, false);
1498
+ var search = new URLSearchParams();
1499
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1500
+ try {
1501
+ for(var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1502
+ var _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], value = _step_value[1];
1503
+ search.append(key, value);
1504
+ }
1505
+ } catch (err) {
1506
+ _didIteratorError = true;
1507
+ _iteratorError = err;
1508
+ } finally{
1509
+ try {
1510
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1511
+ _iterator.return();
1512
+ }
1513
+ } finally{
1514
+ if (_didIteratorError) {
1515
+ throw _iteratorError;
1516
+ }
1517
+ }
1518
+ }
1519
+ url.search = search.toString();
1520
+ return {
1521
+ url: url.toString(),
1522
+ unresolved: Array.from(unresolved)
1523
+ };
1524
+ }
1525
+ function applyScvpMacros(baseUrl, ctx) {
1526
+ var deferred = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : /* @__PURE__ */ new Set();
1527
+ return substituteScvpMacros(baseUrl, resolveScvpMacroValues(ctx), function(name) {
1528
+ return deferred.has(name);
1529
+ });
1530
+ }
1531
+ function stripScvpMacros(url) {
1532
+ if (findScvpMacroNames(url).length === 0) return {
1533
+ url: url,
1534
+ unresolved: []
1535
+ };
1536
+ return substituteScvpMacros(url, /* @__PURE__ */ new Map());
1537
+ }
1343
1538
  function applyVastMacros(baseUrl, ctx) {
1344
1539
  var expandedUrl = expandInlineMacroPlaceholders(baseUrl, ctx);
1345
1540
  var url;
@@ -1381,15 +1576,6 @@ function applyVastMacros(baseUrl, ctx) {
1381
1576
  }
1382
1577
  params.delete("ppos");
1383
1578
  params.delete("lip");
1384
- if (ctx.podMinDurationMs != null) {
1385
- params.set("pmnd", String(Math.max(0, Math.round(ctx.podMinDurationMs))));
1386
- }
1387
- if (ctx.podMaxDurationMs != null) {
1388
- params.set("pmxd", String(Math.max(0, Math.round(ctx.podMaxDurationMs))));
1389
- }
1390
- if (ctx.podMaxAds != null) {
1391
- params.set("pmad", String(Math.max(1, Math.round(ctx.podMaxAds))));
1392
- }
1393
1579
  var existingUrl = params.get("url") || "";
1394
1580
  if (EXAMPLE_COM_URL.test(existingUrl)) {
1395
1581
  params.delete("url");
@@ -2219,6 +2405,309 @@ function substituteVastTrackingMacros(url) {
2219
2405
  return KNOWN_VAST_MACROS.has(name) ? "" : match;
2220
2406
  });
2221
2407
  }
2408
+ // src/player/OptimizedPodRequest.ts
2409
+ var DEFAULT_REQUEST_SAFETY_MS = 1500;
2410
+ var GAM_AD_OPPORTUNITY_DURATION_MS = 3e4;
2411
+ var POD_PARAM_KEYS = [
2412
+ "pmnd",
2413
+ "pmxd",
2414
+ "pmad"
2415
+ ];
2416
+ var POSITIVE_INT = /^[1-9]\d*$/;
2417
+ var NON_NEGATIVE_INT = /^(0|[1-9]\d*)$/;
2418
+ function nonNegativeInt(value) {
2419
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.floor(value) : void 0;
2420
+ }
2421
+ function positiveInt(value) {
2422
+ return typeof value === "number" && Number.isFinite(value) && value >= 1 ? Math.floor(value) : void 0;
2423
+ }
2424
+ function resolveAdPodConfig(config) {
2425
+ var _config_adPodConfig, _nonNegativeInt, _nonNegativeInt1, _positiveInt;
2426
+ var pod = (_config_adPodConfig = config.adPodConfig) !== null && _config_adPodConfig !== void 0 ? _config_adPodConfig : {};
2427
+ return {
2428
+ requestSafetyMs: (_nonNegativeInt = nonNegativeInt(pod.requestSafetyMs)) !== null && _nonNegativeInt !== void 0 ? _nonNegativeInt : DEFAULT_REQUEST_SAFETY_MS,
2429
+ minPodDurationMs: (_nonNegativeInt1 = nonNegativeInt(pod.minPodDurationMs)) !== null && _nonNegativeInt1 !== void 0 ? _nonNegativeInt1 : 0,
2430
+ maxAdsPerBreak: pod.maxAdsPerBreak === void 0 ? positiveInt(config.podMaxAds) : positiveInt(pod.maxAdsPerBreak),
2431
+ maxPodDurationMs: (_positiveInt = positiveInt(pod.maxPodDurationMs)) !== null && _positiveInt !== void 0 ? _positiveInt : positiveInt(config.podMaxDurationMs),
2432
+ exactDuration: config.podExactDuration === true
2433
+ };
2434
+ }
2435
+ function measureBreakCapacity(timing, nowMonoMs) {
2436
+ var _timing_breakEndMonoMs;
2437
+ var scheduled = timing.scheduledBreakDurationMs;
2438
+ if (scheduled == null || !(scheduled > 0) || timing.breakStartMonoMs == null) {
2439
+ return void 0;
2440
+ }
2441
+ var endMonoMs = (_timing_breakEndMonoMs = timing.breakEndMonoMs) !== null && _timing_breakEndMonoMs !== void 0 ? _timing_breakEndMonoMs : timing.breakStartMonoMs + scheduled;
2442
+ var untilEnd = Math.min(scheduled, endMonoMs - nowMonoMs);
2443
+ var unplayed = scheduled - Math.max(0, timing.playedDurationMs);
2444
+ return {
2445
+ scheduledBreakDurationMs: scheduled,
2446
+ elapsedBeforeGamRequestMs: Math.max(0, nowMonoMs - timing.breakStartMonoMs),
2447
+ remainingAtGamDispatchMs: Math.max(0, Math.min(untilEnd, unplayed))
2448
+ };
2449
+ }
2450
+ function resolvePodParams(input) {
2451
+ var capacity = input.capacity, config = input.config;
2452
+ var pmxd;
2453
+ var source;
2454
+ if (capacity) {
2455
+ pmxd = Math.floor(capacity.remainingAtGamDispatchMs - config.requestSafetyMs);
2456
+ source = "break_remaining";
2457
+ } else if (config.maxPodDurationMs != null) {
2458
+ pmxd = config.maxPodDurationMs;
2459
+ source = "configured_cap";
2460
+ } else if (input.tagMaxDurationMs != null) {
2461
+ pmxd = input.tagMaxDurationMs;
2462
+ source = "tag_cap";
2463
+ } else {
2464
+ return {
2465
+ kind: "omit"
2466
+ };
2467
+ }
2468
+ var minUsable = Math.max(1, Math.floor(input.minUsablePmxdMs));
2469
+ if (!Number.isFinite(pmxd) || pmxd < minUsable) {
2470
+ return {
2471
+ kind: "abort",
2472
+ reason: capacity ? "insufficient_break_capacity" : "invalid_pod_cap",
2473
+ pmxdCandidateMs: Number.isFinite(pmxd) ? pmxd : 0
2474
+ };
2475
+ }
2476
+ var pmnd = config.exactDuration ? pmxd : Math.min(config.minPodDurationMs, pmxd);
2477
+ return {
2478
+ kind: "send",
2479
+ params: {
2480
+ pmnd: pmnd,
2481
+ pmxd: pmxd,
2482
+ pmad: config.maxAdsPerBreak
2483
+ },
2484
+ source: source
2485
+ };
2486
+ }
2487
+ function podRequestAborted(reason, message, diagnostics) {
2488
+ var error = new Error("Optimized pod request not sent (".concat(reason, "): ").concat(message));
2489
+ error.podRequestAborted = true;
2490
+ error.reason = reason;
2491
+ error.diagnostics = diagnostics;
2492
+ return error;
2493
+ }
2494
+ function isPodRequestAbortedError(error) {
2495
+ return !!error && error.podRequestAborted === true;
2496
+ }
2497
+ function firstPositiveIntParam(params, key) {
2498
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2499
+ try {
2500
+ for(var _iterator = params.getAll(key)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2501
+ var value = _step.value;
2502
+ if (POSITIVE_INT.test(value.trim())) return Number(value.trim());
2503
+ }
2504
+ } catch (err) {
2505
+ _didIteratorError = true;
2506
+ _iteratorError = err;
2507
+ } finally{
2508
+ try {
2509
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2510
+ _iterator.return();
2511
+ }
2512
+ } finally{
2513
+ if (_didIteratorError) {
2514
+ throw _iteratorError;
2515
+ }
2516
+ }
2517
+ }
2518
+ return void 0;
2519
+ }
2520
+ function isOptimizedPodUrl(url) {
2521
+ if (findScvpMacroNames(url).some(function(name) {
2522
+ return SCVP_POD_MACROS.has(name);
2523
+ })) return true;
2524
+ try {
2525
+ var params = new URL(url).searchParams;
2526
+ return POD_PARAM_KEYS.some(function(key) {
2527
+ return params.has(key);
2528
+ });
2529
+ } catch (unused) {
2530
+ return false;
2531
+ }
2532
+ }
2533
+ function finalizeGamRequestUrl(rawUrl, ctx) {
2534
+ var nowEpochMs = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : Date.now();
2535
+ var optimizedPod = isOptimizedPodUrl(rawUrl);
2536
+ var capacity = ctx.capacity;
2537
+ var base = {
2538
+ breakId: ctx.breakId,
2539
+ optimizedPod: optimizedPod,
2540
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2541
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2542
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2543
+ safetyReserveMs: ctx.config.requestSafetyMs
2544
+ };
2545
+ var decision = {
2546
+ kind: "omit"
2547
+ };
2548
+ if (optimizedPod) {
2549
+ var tagMaxDurationMs;
2550
+ try {
2551
+ tagMaxDurationMs = firstPositiveIntParam(new URL(rawUrl).searchParams, "pmxd");
2552
+ } catch (unused) {}
2553
+ decision = resolvePodParams({
2554
+ capacity: capacity,
2555
+ config: ctx.config,
2556
+ minUsablePmxdMs: ctx.minUsablePmxdMs,
2557
+ tagMaxDurationMs: tagMaxDurationMs
2558
+ });
2559
+ if (decision.kind === "abort") {
2560
+ throw podRequestAborted(decision.reason, "pmxd would be ".concat(decision.pmxdCandidateMs, "ms (minimum ").concat(ctx.minUsablePmxdMs, "ms)"), base);
2561
+ }
2562
+ }
2563
+ var pod = decision.kind === "send" ? decision.params : void 0;
2564
+ var values = /* @__PURE__ */ new Map();
2565
+ if (pod) {
2566
+ values.set("PMND", String(pod.pmnd));
2567
+ values.set("PMXD", String(pod.pmxd));
2568
+ if (pod.pmad != null) values.set("PMAD", String(pod.pmad));
2569
+ }
2570
+ var substituted = substituteScvpMacros(rawUrl, values);
2571
+ var finalUrl;
2572
+ try {
2573
+ var url = new URL(normalizeVastTagUrl(substituted.url));
2574
+ if (pod) {
2575
+ url.searchParams.set("pmnd", String(pod.pmnd));
2576
+ url.searchParams.set("pmxd", String(pod.pmxd));
2577
+ if (pod.pmad != null) url.searchParams.set("pmad", String(pod.pmad));
2578
+ else url.searchParams.delete("pmad");
2579
+ } else {
2580
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2581
+ try {
2582
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2583
+ var key = _step.value;
2584
+ url.searchParams.delete(key);
2585
+ }
2586
+ } catch (err) {
2587
+ _didIteratorError = true;
2588
+ _iteratorError = err;
2589
+ } finally{
2590
+ try {
2591
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2592
+ _iterator.return();
2593
+ }
2594
+ } finally{
2595
+ if (_didIteratorError) {
2596
+ throw _iteratorError;
2597
+ }
2598
+ }
2599
+ }
2600
+ }
2601
+ finalUrl = url.toString();
2602
+ } catch (unused) {
2603
+ throw podRequestAborted("invalid_url", "GAM request URL could not be parsed", base);
2604
+ }
2605
+ var problems = validateGamRequestUrl(finalUrl, {
2606
+ optimizedPod: !!pod,
2607
+ remainingMs: decision.kind === "send" && decision.source === "break_remaining" ? capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs : void 0
2608
+ });
2609
+ if (problems.length > 0) {
2610
+ throw podRequestAborted("invalid_url", problems.join("; "), base);
2611
+ }
2612
+ var givn = null;
2613
+ try {
2614
+ givn = new URL(finalUrl).searchParams.get("givn");
2615
+ } catch (unused) {}
2616
+ return {
2617
+ url: finalUrl,
2618
+ diagnostics: {
2619
+ breakId: ctx.breakId,
2620
+ optimizedPod: !!pod,
2621
+ pmxdSource: decision.kind === "send" ? decision.source : void 0,
2622
+ scteBreakDurationMs: capacity === null || capacity === void 0 ? void 0 : capacity.scheduledBreakDurationMs,
2623
+ elapsedBeforeGamRequestMs: capacity === null || capacity === void 0 ? void 0 : capacity.elapsedBeforeGamRequestMs,
2624
+ remainingAtGamDispatchMs: capacity === null || capacity === void 0 ? void 0 : capacity.remainingAtGamDispatchMs,
2625
+ safetyReserveMs: ctx.config.requestSafetyMs,
2626
+ pmndSent: pod === null || pod === void 0 ? void 0 : pod.pmnd,
2627
+ pmxdSent: pod === null || pod === void 0 ? void 0 : pod.pmxd,
2628
+ pmadSent: pod === null || pod === void 0 ? void 0 : pod.pmad,
2629
+ palNoncePresent: !!givn,
2630
+ gamRequestDispatchTimestamp: new Date(nowEpochMs).toISOString(),
2631
+ strippedMacros: substituted.unresolved.filter(function(name) {
2632
+ return !SCVP_POD_MACROS.has(name);
2633
+ })
2634
+ }
2635
+ };
2636
+ }
2637
+ function validateGamRequestUrl(url, expect) {
2638
+ var problems = [];
2639
+ var leftover = findScvpMacroNames(url);
2640
+ if (leftover.length > 0) problems.push("unresolved SCVP macros: ".concat(leftover.join(", ")));
2641
+ var params;
2642
+ try {
2643
+ params = new URL(url).searchParams;
2644
+ } catch (unused) {
2645
+ return problems.concat("URL could not be parsed");
2646
+ }
2647
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2648
+ try {
2649
+ for(var _iterator = POD_PARAM_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2650
+ var key = _step.value;
2651
+ if (params.getAll(key).length > 1) problems.push("duplicate ".concat(key));
2652
+ }
2653
+ } catch (err) {
2654
+ _didIteratorError = true;
2655
+ _iteratorError = err;
2656
+ } finally{
2657
+ try {
2658
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2659
+ _iterator.return();
2660
+ }
2661
+ } finally{
2662
+ if (_didIteratorError) {
2663
+ throw _iteratorError;
2664
+ }
2665
+ }
2666
+ }
2667
+ if (!expect.optimizedPod) {
2668
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
2669
+ try {
2670
+ for(var _iterator1 = POD_PARAM_KEYS[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
2671
+ var key1 = _step1.value;
2672
+ if (params.has(key1)) problems.push("".concat(key1, " present on a non-pod request"));
2673
+ }
2674
+ } catch (err) {
2675
+ _didIteratorError1 = true;
2676
+ _iteratorError1 = err;
2677
+ } finally{
2678
+ try {
2679
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
2680
+ _iterator1.return();
2681
+ }
2682
+ } finally{
2683
+ if (_didIteratorError1) {
2684
+ throw _iteratorError1;
2685
+ }
2686
+ }
2687
+ }
2688
+ return problems;
2689
+ }
2690
+ var pmxd = params.get("pmxd");
2691
+ var pmnd = params.get("pmnd");
2692
+ var pmad = params.get("pmad");
2693
+ if (pmxd == null || !POSITIVE_INT.test(pmxd)) problems.push("pmxd must be a positive integer (got ".concat(pmxd, ")"));
2694
+ if (pmnd == null || !NON_NEGATIVE_INT.test(pmnd)) problems.push("pmnd must be a non-negative integer (got ".concat(pmnd, ")"));
2695
+ if (pmxd != null && pmnd != null && Number(pmnd) > Number(pmxd)) problems.push("pmnd exceeds pmxd");
2696
+ if (pmad != null && !POSITIVE_INT.test(pmad)) problems.push("pmad must be a positive integer or absent (got ".concat(pmad, ")"));
2697
+ if (expect.remainingMs != null && pmxd != null && Number(pmxd) > expect.remainingMs) {
2698
+ problems.push("pmxd ".concat(pmxd, " exceeds remaining break ").concat(expect.remainingMs, "ms"));
2699
+ }
2700
+ return problems;
2701
+ }
2702
+ function computePodResponseDiagnostics(pmxdSent, vastAdCount, totalVastCreativeDurationMs) {
2703
+ var estimatedUnusedPodMs = Math.max(0, pmxdSent - totalVastCreativeDurationMs);
2704
+ return {
2705
+ vastAdCount: vastAdCount,
2706
+ totalVastCreativeDurationMs: totalVastCreativeDurationMs,
2707
+ estimatedUnusedPodMs: estimatedUnusedPodMs,
2708
+ estimatedUnmatchedCount: Math.floor(estimatedUnusedPodMs / GAM_AD_OPPORTUNITY_DURATION_MS)
2709
+ };
2710
+ }
2222
2711
  // src/sdk/hlsAdPlayer.ts
2223
2712
  var LINEAR_TRACKING_EVENTS = [
2224
2713
  "creativeView",
@@ -2299,6 +2788,7 @@ function toVastMediaErrorCode(error) {
2299
2788
  return VAST_ERROR_MEDIA_DISPLAY;
2300
2789
  }
2301
2790
  }
2791
+ var gamCredentialsMode = "include";
2302
2792
  function createHlsAdPlayer(contentVideo, options) {
2303
2793
  var _contentVideo_AD_VIDEO_PROP, _contentVideo_AD_CONTAINER_PROP, _ref;
2304
2794
  var adPlaying = false;
@@ -3170,9 +3660,9 @@ function createHlsAdPlayer(contentVideo, options) {
3170
3660
  }
3171
3661
  }
3172
3662
  function fetchVastXml(vastTagUrl) {
3173
- var credentials = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "include", kind = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : "gam";
3663
+ 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;
3174
3664
  return _async_to_generator(function() {
3175
- var controller, timeoutId, startedAt, attempt, requestVast, response, error, error1;
3665
+ var controller, timeoutId, startedAt, attempt, resolveDispatchUrl, requestVast, response, error, error1;
3176
3666
  return _ts_generator(this, function(_state) {
3177
3667
  switch(_state.label){
3178
3668
  case 0:
@@ -3186,13 +3676,32 @@ function createHlsAdPlayer(contentVideo, options) {
3186
3676
  }, VAST_REQUEST_TIMEOUT_MS) : void 0;
3187
3677
  startedAt = Date.now();
3188
3678
  attempt = 0;
3679
+ resolveDispatchUrl = function resolveDispatchUrl() {
3680
+ if (kind === "wrapper") return vastTagUrl;
3681
+ if (finalizeRequestUrl) return finalizeRequestUrl(vastTagUrl, attempt);
3682
+ var _stripScvpMacros = stripScvpMacros(vastTagUrl), url = _stripScvpMacros.url, unresolved = _stripScvpMacros.unresolved;
3683
+ if (unresolved.length > 0) {
3684
+ console.warn("[HlsAdPlayer] Removed unresolved SCVP macros before dispatch:", unresolved.join(", "));
3685
+ }
3686
+ return url;
3687
+ };
3189
3688
  requestVast = function requestVast(creds) {
3190
3689
  return _async_to_generator(function() {
3191
- var response;
3690
+ var pending, response;
3192
3691
  return _ts_generator(this, function(_state) {
3193
3692
  switch(_state.label){
3194
3693
  case 0:
3195
3694
  attempt++;
3695
+ pending = fetch(resolveDispatchUrl(), _object_spread({
3696
+ mode: "cors",
3697
+ credentials: creds,
3698
+ headers: {
3699
+ "Accept": "application/xml, text/xml, */*"
3700
+ },
3701
+ referrerPolicy: "no-referrer-when-downgrade"
3702
+ }, controller ? {
3703
+ signal: controller.signal
3704
+ } : {}));
3196
3705
  if (kind !== "wrapper") {
3197
3706
  logFunnel("".concat(kind, "_http_request_sent"), {
3198
3707
  attempt: attempt,
@@ -3201,16 +3710,7 @@ function createHlsAdPlayer(contentVideo, options) {
3201
3710
  }
3202
3711
  return [
3203
3712
  4,
3204
- fetch(vastTagUrl, _object_spread({
3205
- mode: "cors",
3206
- credentials: creds,
3207
- headers: {
3208
- "Accept": "application/xml, text/xml, */*"
3209
- },
3210
- referrerPolicy: "no-referrer-when-downgrade"
3211
- }, controller ? {
3212
- signal: controller.signal
3213
- } : {}))
3713
+ pending
3214
3714
  ];
3215
3715
  case 1:
3216
3716
  response = _state.sent();
@@ -3234,9 +3734,9 @@ function createHlsAdPlayer(contentVideo, options) {
3234
3734
  case 1:
3235
3735
  _state.trys.push([
3236
3736
  1,
3237
- 10,
3238
- 11,
3239
- 12
3737
+ 7,
3738
+ 8,
3739
+ 9
3240
3740
  ]);
3241
3741
  _state.label = 2;
3242
3742
  case 2:
@@ -3244,7 +3744,7 @@ function createHlsAdPlayer(contentVideo, options) {
3244
3744
  2,
3245
3745
  4,
3246
3746
  ,
3247
- 8
3747
+ 5
3248
3748
  ]);
3249
3749
  return [
3250
3750
  4,
@@ -3254,36 +3754,21 @@ function createHlsAdPlayer(contentVideo, options) {
3254
3754
  response = _state.sent();
3255
3755
  return [
3256
3756
  3,
3257
- 8
3757
+ 5
3258
3758
  ];
3259
3759
  case 4:
3260
3760
  error = _state.sent();
3261
- if (!(credentials !== "omit" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted))) return [
3262
- 3,
3263
- 6
3264
- ];
3265
- console.warn('[HlsAdPlayer] VAST fetch failed with credentials="'.concat(credentials, '", retrying without credentials:'), error);
3266
- logFunnel("vast_credentials_retry", {
3267
- errorMessage: error === null || error === void 0 ? void 0 : error.message
3268
- });
3269
- return [
3270
- 4,
3271
- requestVast("omit")
3272
- ];
3273
- case 5:
3274
- response = _state.sent();
3275
- return [
3276
- 3,
3277
- 7
3278
- ];
3279
- case 6:
3761
+ if (kind === "gam" && !(controller === null || controller === void 0 ? void 0 : controller.signal.aborted) && !isPodRequestAbortedError(error)) {
3762
+ gamCredentialsMode = credentials === "include" ? "omit" : "include";
3763
+ console.warn('[HlsAdPlayer] GAM fetch failed with credentials="'.concat(credentials, '"; next GAM request will use credentials="').concat(gamCredentialsMode, '":'), error);
3764
+ logFunnel("gam_credentials_mode_changed", {
3765
+ from: credentials,
3766
+ to: gamCredentialsMode,
3767
+ errorMessage: error === null || error === void 0 ? void 0 : error.message
3768
+ });
3769
+ }
3280
3770
  throw error;
3281
- case 7:
3282
- return [
3283
- 3,
3284
- 8
3285
- ];
3286
- case 8:
3771
+ case 5:
3287
3772
  if (!response.ok) {
3288
3773
  throw new Error("Failed to fetch VAST: HTTP ".concat(response.status, " ").concat(response.statusText));
3289
3774
  }
@@ -3291,12 +3776,12 @@ function createHlsAdPlayer(contentVideo, options) {
3291
3776
  4,
3292
3777
  response.text()
3293
3778
  ];
3294
- case 9:
3779
+ case 6:
3295
3780
  return [
3296
3781
  2,
3297
3782
  _state.sent()
3298
3783
  ];
3299
- case 10:
3784
+ case 7:
3300
3785
  error1 = _state.sent();
3301
3786
  if (controller === null || controller === void 0 ? void 0 : controller.signal.aborted) {
3302
3787
  if (pendingRequestAbortReason) {
@@ -3305,13 +3790,13 @@ function createHlsAdPlayer(contentVideo, options) {
3305
3790
  throw new Error("VAST request timeout after ".concat(VAST_REQUEST_TIMEOUT_MS, "ms: ").concat(vastTagUrl));
3306
3791
  }
3307
3792
  throw error1;
3308
- case 11:
3793
+ case 8:
3309
3794
  if (timeoutId !== void 0) clearTimeout(timeoutId);
3310
3795
  if (controller) pendingVastRequests.delete(controller);
3311
3796
  return [
3312
3797
  7
3313
3798
  ];
3314
- case 12:
3799
+ case 9:
3315
3800
  return [
3316
3801
  2
3317
3802
  ];
@@ -3444,7 +3929,7 @@ function createHlsAdPlayer(contentVideo, options) {
3444
3929
  });
3445
3930
  }
3446
3931
  function fetchAndParsePod(vastTagUrl) {
3447
- var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam";
3932
+ var source = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "gam", finalizeRequestUrl = arguments.length > 2 ? arguments[2] : void 0;
3448
3933
  return _async_to_generator(function() {
3449
3934
  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;
3450
3935
  return _ts_generator(this, function(_state) {
@@ -3454,7 +3939,7 @@ function createHlsAdPlayer(contentVideo, options) {
3454
3939
  isEdge = source === "edge";
3455
3940
  return [
3456
3941
  4,
3457
- fetchVastXml(vastTagUrl, isEdge ? "omit" : "include", source)
3942
+ fetchVastXml(vastTagUrl, isEdge ? "omit" : gamCredentialsMode, source, finalizeRequestUrl)
3458
3943
  ];
3459
3944
  case 1:
3460
3945
  vastXml = _state.sent();
@@ -4777,7 +5262,7 @@ function createHlsAdPlayer(contentVideo, options) {
4777
5262
  case 2:
4778
5263
  return [
4779
5264
  4,
4780
- fetchAndParsePod(vastTagUrl, source)
5265
+ fetchAndParsePod(vastTagUrl, source, requestOptions === null || requestOptions === void 0 ? void 0 : requestOptions.finalizeRequestUrl)
4781
5266
  ];
4782
5267
  case 3:
4783
5268
  ads = _state.sent();
@@ -5354,95 +5839,38 @@ function getOrCreateNonceLoader(allowStorage) {
5354
5839
  function createPalNonceManager() {
5355
5840
  var currentNonce = "";
5356
5841
  var currentNonceManager;
5842
+ var pendingNonce;
5357
5843
  return {
5358
5844
  generateNonce: function generateNonce() {
5359
- return _async_to_generator(function() {
5360
- var options, _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5361
- var _arguments = arguments;
5362
- return _ts_generator(this, function(_state) {
5363
- switch(_state.label){
5364
- case 0:
5365
- options = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {};
5366
- _state.label = 1;
5367
- case 1:
5368
- _state.trys.push([
5369
- 1,
5370
- 4,
5371
- ,
5372
- 5
5373
- ]);
5374
- return [
5375
- 4,
5376
- loadPalSdk()
5377
- ];
5378
- case 2:
5379
- _state.sent();
5380
- loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5381
- goog = window.goog;
5382
- request = new goog.pal.NonceRequest();
5383
- request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5384
- request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5385
- request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5386
- request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5387
- request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5388
- request.iconsSupported = true;
5389
- request.playerType = "StormcloudVideoPlayer";
5390
- request.playerVersion = "1.0";
5391
- request.supportedApiFrameworks = "2,7,9";
5392
- request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5393
- request.videoWidth = options.videoWidth || 640;
5394
- request.videoHeight = options.videoHeight || 480;
5395
- if (options.ppid) request.ppid = options.ppid;
5396
- if (options.sessionId) request.sessionId = options.sessionId;
5397
- console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5398
- adWillAutoPlay: request.adWillAutoPlay,
5399
- adWillPlayMuted: request.adWillPlayMuted,
5400
- playerVolume: request.playerVolume,
5401
- continuousPlayback: request.continuousPlayback,
5402
- descriptionUrl: request.descriptionUrl,
5403
- iconsSupported: request.iconsSupported,
5404
- playerType: request.playerType,
5405
- playerVersion: request.playerVersion,
5406
- supportedApiFrameworks: request.supportedApiFrameworks,
5407
- url: request.url,
5408
- videoWidth: request.videoWidth,
5409
- videoHeight: request.videoHeight,
5410
- ppid: request.ppid,
5411
- sessionId: request.sessionId
5412
- }, null, 2));
5413
- return [
5414
- 4,
5415
- loader.loadNonceManager(request)
5416
- ];
5417
- case 3:
5418
- manager = _state.sent();
5419
- currentNonceManager = manager;
5420
- currentNonce = manager.getNonce();
5421
- console.log("[PAL] Nonce generated successfully");
5422
- return [
5423
- 2,
5424
- currentNonce
5425
- ];
5426
- case 4:
5427
- error = _state.sent();
5428
- console.warn("[PAL] Failed to generate nonce:", error);
5429
- currentNonce = "";
5430
- currentNonceManager = void 0;
5431
- return [
5432
- 2,
5433
- ""
5434
- ];
5435
- case 5:
5436
- return [
5437
- 2
5438
- ];
5439
- }
5440
- });
5441
- }).apply(this, arguments);
5845
+ var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
5846
+ var run = generate(options);
5847
+ pendingNonce = run;
5848
+ var settle = function settle() {
5849
+ if (pendingNonce === run) pendingNonce = void 0;
5850
+ };
5851
+ run.then(settle, settle);
5852
+ return run;
5442
5853
  },
5443
5854
  getCurrentNonce: function getCurrentNonce() {
5444
5855
  return currentNonce;
5445
5856
  },
5857
+ waitForNonce: function waitForNonce(maxWaitMs) {
5858
+ if (currentNonce) return Promise.resolve(currentNonce);
5859
+ var pending = pendingNonce;
5860
+ if (!pending || !(maxWaitMs > 0)) return Promise.resolve("");
5861
+ return new Promise(function(resolve) {
5862
+ var timer = setTimeout(function() {
5863
+ return resolve(currentNonce);
5864
+ }, maxWaitMs);
5865
+ pending.then(function(nonce) {
5866
+ clearTimeout(timer);
5867
+ resolve(nonce);
5868
+ }, function() {
5869
+ clearTimeout(timer);
5870
+ resolve("");
5871
+ });
5872
+ });
5873
+ },
5446
5874
  injectNonce: function injectNonce(vastTagUrl) {
5447
5875
  if (!currentNonce || !vastTagUrl) return vastTagUrl;
5448
5876
  try {
@@ -5479,8 +5907,90 @@ function createPalNonceManager() {
5479
5907
  reset: function reset() {
5480
5908
  currentNonce = "";
5481
5909
  currentNonceManager = void 0;
5910
+ pendingNonce = void 0;
5482
5911
  }
5483
5912
  };
5913
+ function generate(options) {
5914
+ return _async_to_generator(function() {
5915
+ var _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
5916
+ return _ts_generator(this, function(_state) {
5917
+ switch(_state.label){
5918
+ case 0:
5919
+ _state.trys.push([
5920
+ 0,
5921
+ 3,
5922
+ ,
5923
+ 4
5924
+ ]);
5925
+ return [
5926
+ 4,
5927
+ loadPalSdk()
5928
+ ];
5929
+ case 1:
5930
+ _state.sent();
5931
+ loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
5932
+ goog = window.goog;
5933
+ request = new goog.pal.NonceRequest();
5934
+ request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
5935
+ request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
5936
+ request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
5937
+ request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
5938
+ request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5939
+ request.iconsSupported = true;
5940
+ request.playerType = "StormcloudVideoPlayer";
5941
+ request.playerVersion = "1.0";
5942
+ request.supportedApiFrameworks = "2,7,9";
5943
+ request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
5944
+ request.videoWidth = options.videoWidth || 640;
5945
+ request.videoHeight = options.videoHeight || 480;
5946
+ if (options.ppid) request.ppid = options.ppid;
5947
+ if (options.sessionId) request.sessionId = options.sessionId;
5948
+ console.log("[PAL] NonceRequest before generateNonce:", JSON.stringify({
5949
+ adWillAutoPlay: request.adWillAutoPlay,
5950
+ adWillPlayMuted: request.adWillPlayMuted,
5951
+ playerVolume: request.playerVolume,
5952
+ continuousPlayback: request.continuousPlayback,
5953
+ descriptionUrl: request.descriptionUrl,
5954
+ iconsSupported: request.iconsSupported,
5955
+ playerType: request.playerType,
5956
+ playerVersion: request.playerVersion,
5957
+ supportedApiFrameworks: request.supportedApiFrameworks,
5958
+ url: request.url,
5959
+ videoWidth: request.videoWidth,
5960
+ videoHeight: request.videoHeight,
5961
+ ppid: request.ppid,
5962
+ sessionId: request.sessionId
5963
+ }, null, 2));
5964
+ return [
5965
+ 4,
5966
+ loader.loadNonceManager(request)
5967
+ ];
5968
+ case 2:
5969
+ manager = _state.sent();
5970
+ currentNonceManager = manager;
5971
+ currentNonce = manager.getNonce();
5972
+ console.log("[PAL] Nonce generated successfully");
5973
+ return [
5974
+ 2,
5975
+ currentNonce
5976
+ ];
5977
+ case 3:
5978
+ error = _state.sent();
5979
+ console.warn("[PAL] Failed to generate nonce:", error);
5980
+ currentNonce = "";
5981
+ currentNonceManager = void 0;
5982
+ return [
5983
+ 2,
5984
+ ""
5985
+ ];
5986
+ case 4:
5987
+ return [
5988
+ 2
5989
+ ];
5990
+ }
5991
+ });
5992
+ })();
5993
+ }
5484
5994
  }
5485
5995
  // src/utils/trackingIngest.ts
5486
5996
  var DEFAULT_TRACKING_INGEST_CONFIG = {
@@ -5563,7 +6073,14 @@ function ingestPlayerTracking(licenseKey, channel, body) {
5563
6073
  // src/utils/tracking.ts
5564
6074
  var cachedBrowserId = null;
5565
6075
  function buildAnalyticsContext(config) {
6076
+ var _config_contentNetwork, _config_channelName, _config_programTitle;
5566
6077
  var context = {};
6078
+ var contentNetwork = (_config_contentNetwork = config.contentNetwork) === null || _config_contentNetwork === void 0 ? void 0 : _config_contentNetwork.trim();
6079
+ var contentChannel = (_config_channelName = config.channelName) === null || _config_channelName === void 0 ? void 0 : _config_channelName.trim();
6080
+ var contentTitle = (_config_programTitle = config.programTitle) === null || _config_programTitle === void 0 ? void 0 : _config_programTitle.trim();
6081
+ if (contentNetwork) context.contentNetwork = contentNetwork;
6082
+ if (contentChannel) context.contentChannel = contentChannel;
6083
+ if (contentTitle) context.contentTitle = contentTitle;
5567
6084
  if (config.debugAdTiming) {
5568
6085
  context.debugAdTiming = true;
5569
6086
  }
@@ -6054,12 +6571,19 @@ function sendAdImpressionTracking(_0, _1) {
6054
6571
  4,
6055
6572
  ingestPlayerTracking(licenseKey, "impressions", {
6056
6573
  events: [
6057
- {
6574
+ _object_spread({
6058
6575
  player_id: metricEvent.player_id,
6059
6576
  ad_played_count: 1,
6060
6577
  ad_url: adImpressionInfo.adUrl,
6061
- capture_at: adImpressionInfo.timestamp
6062
- }
6578
+ capture_at: adImpressionInfo.timestamp,
6579
+ source: "gam"
6580
+ }, context.contentNetwork ? {
6581
+ content_network: context.contentNetwork
6582
+ } : {}, context.contentChannel ? {
6583
+ content_channel: context.contentChannel
6584
+ } : {}, context.contentTitle ? {
6585
+ content_title: context.contentTitle
6586
+ } : {})
6063
6587
  ]
6064
6588
  })
6065
6589
  ];
@@ -7408,6 +7932,21 @@ var Scte35CueManager = /*#__PURE__*/ function() {
7408
7932
  return Scte35CueManager;
7409
7933
  }();
7410
7934
  // src/player/AdConfigManager.ts
7935
+ function withDeferredPodParams(rawUrl, deferNonce) {
7936
+ try {
7937
+ var url = new URL(rawUrl);
7938
+ url.searchParams.set("pmnd", "[SCVP-PMND]");
7939
+ url.searchParams.set("pmxd", "[SCVP-PMXD]");
7940
+ url.searchParams.set("pmad", "[SCVP-PMAD]");
7941
+ if (deferNonce && !url.searchParams.get("givn")) {
7942
+ url.searchParams.delete("paln");
7943
+ url.searchParams.set("givn", "[SCVP-GIVN]");
7944
+ }
7945
+ return url.toString();
7946
+ } catch (unused) {
7947
+ return rawUrl;
7948
+ }
7949
+ }
7411
7950
  var AdConfigManager = /*#__PURE__*/ function() {
7412
7951
  function AdConfigManager(config, video) {
7413
7952
  _class_call_check(this, AdConfigManager);
@@ -7418,8 +7957,8 @@ var AdConfigManager = /*#__PURE__*/ function() {
7418
7957
  this.podCounter = 0;
7419
7958
  this.podAssignedByPrefetch = false;
7420
7959
  this.lastHeartbeatTime = 0;
7421
- this.defaultPodMaxAds = 6;
7422
- this.defaultPodMaxDurationMs = 12e4;
7960
+ this.defaultEdgePodMaxAds = 6;
7961
+ this.palNonceDispatchWaitMs = 1500;
7423
7962
  this.config = config;
7424
7963
  this.video = video;
7425
7964
  }
@@ -7447,7 +7986,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7447
7986
  key: "fetchAdConfiguration",
7448
7987
  value: function fetchAdConfiguration() {
7449
7988
  return _async_to_generator(function() {
7450
- 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;
7989
+ 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;
7451
7990
  return _ts_generator(this, function(_state) {
7452
7991
  switch(_state.label){
7453
7992
  case 0:
@@ -7468,28 +8007,6 @@ var AdConfigManager = /*#__PURE__*/ function() {
7468
8007
  2
7469
8008
  ];
7470
8009
  case 2:
7471
- vastMode = this.config.vastMode || "default";
7472
- if (this.debug) {
7473
- console.log("[StormcloudVideoPlayer] VAST mode:", vastMode);
7474
- }
7475
- if (vastMode === "adstorm") {
7476
- if (!this.config.licenseKey) {
7477
- if (this.debug) {
7478
- console.warn("[StormcloudVideoPlayer] AdStorm mode requires a license key");
7479
- }
7480
- return [
7481
- 2
7482
- ];
7483
- }
7484
- vastEndpoint = "https://adstorm.co/api-adstorm-dev/adstorm/vast/".concat(this.config.licenseKey);
7485
- this.apiVastTagUrl = vastEndpoint;
7486
- if (this.debug) {
7487
- console.log("[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):", vastEndpoint);
7488
- }
7489
- return [
7490
- 2
7491
- ];
7492
- }
7493
8010
  if (this.config.vastTagUrl) {
7494
8011
  this.apiVastTagUrl = normalizeVastTagUrl(this.config.vastTagUrl);
7495
8012
  if (this.debug) {
@@ -7499,7 +8016,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
7499
8016
  2
7500
8017
  ];
7501
8018
  }
7502
- apiUrl = "https://adstorm.co/api-adstorm-dev/adstorm/ads/web";
8019
+ apiUrl = "https://edge.stormcloudhub.com/api/v1/adstorm/ads/web";
7503
8020
  if (this.debug) {
7504
8021
  console.log("[StormcloudVideoPlayer] Fetching ad configuration from:", apiUrl);
7505
8022
  }
@@ -7846,16 +8363,16 @@ var AdConfigManager = /*#__PURE__*/ function() {
7846
8363
  }
7847
8364
  },
7848
8365
  {
7849
- key: "resolvePodParams",
7850
- value: function resolvePodParams(breakDurationMs) {
7851
- var maxDurationMs = breakDurationMs != null && breakDurationMs > 0 ? breakDurationMs : this.config.podMaxDurationMs != null && this.config.podMaxDurationMs > 0 ? this.config.podMaxDurationMs : this.defaultPodMaxDurationMs;
7852
- var maxAds = this.config.podMaxAds && this.config.podMaxAds > 0 ? this.config.podMaxAds : this.apiNumberAds && this.apiNumberAds > 0 ? this.apiNumberAds : this.defaultPodMaxAds;
7853
- var minDurationMs = this.config.podExactDuration && maxDurationMs != null ? maxDurationMs : 0;
7854
- return {
7855
- maxAds: maxAds,
7856
- minDurationMs: minDurationMs,
7857
- maxDurationMs: maxDurationMs
7858
- };
8366
+ key: "resolveAdPodConfig",
8367
+ value: function resolveAdPodConfig1() {
8368
+ return resolveAdPodConfig(this.config);
8369
+ }
8370
+ },
8371
+ {
8372
+ key: "resolveEdgeMaxAds",
8373
+ value: function resolveEdgeMaxAds() {
8374
+ var _this_resolveAdPodConfig_maxAdsPerBreak;
8375
+ 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;
7859
8376
  }
7860
8377
  },
7861
8378
  {
@@ -7872,17 +8389,13 @@ var AdConfigManager = /*#__PURE__*/ function() {
7872
8389
  },
7873
8390
  {
7874
8391
  key: "generatePodVastUrl",
7875
- value: function generatePodVastUrl(baseUrl, podParams, adPlayer, palNonce, inAdBreak) {
7876
- var _podParams_maxDurationMs;
8392
+ value: function generatePodVastUrl(baseUrl, adPlayer, palNonce, inAdBreak) {
7877
8393
  var adWillPlayMuted = inAdBreak ? adPlayer.getOriginalMutedState() : this.video.muted;
7878
8394
  var envSignals = resolveVastEnvironmentSignals(!!this.config.ctvAdRequest);
7879
- var urlWithMacros = applyVastMacros(baseUrl, _object_spread_props(_object_spread({
8395
+ var macroContext = _object_spread_props(_object_spread({
7880
8396
  correlator: this.viewCorrelator,
7881
8397
  streamCorrelator: this.streamCorrelator,
7882
8398
  pod: this.podCounter > 0 ? this.podCounter : void 0,
7883
- podMaxAds: podParams.maxAds,
7884
- podMinDurationMs: podParams.minDurationMs,
7885
- podMaxDurationMs: podParams.maxDurationMs,
7886
8399
  isCtv: envSignals.isCtv,
7887
8400
  pageUrl: !envSignals.isCtv && typeof window !== "undefined" ? toDevSafeUrl(window.location.href) : void 0,
7888
8401
  adWillPlayMuted: adWillPlayMuted,
@@ -7898,13 +8411,72 @@ var AdConfigManager = /*#__PURE__*/ function() {
7898
8411
  } : {}, this.config.channelName ? {
7899
8412
  channelName: this.config.channelName
7900
8413
  } : {}), {
7901
- consent: this.consentSignals
7902
- }));
7903
- var finalUrl = palNonce.injectNonce(ensureVideoAdType(urlWithMacros));
7904
- 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);
8414
+ consent: this.consentSignals,
8415
+ palNonce: palNonce.getCurrentNonce() || void 0
8416
+ });
8417
+ var nonceReady = !!macroContext.palNonce;
8418
+ var finalUrl;
8419
+ if (hasScvpMacros(baseUrl)) {
8420
+ var deferred = new Set(SCVP_POD_MACROS);
8421
+ if (!nonceReady) deferred.add("GIVN");
8422
+ var _applyScvpMacros = applyScvpMacros(baseUrl, macroContext, deferred), url = _applyScvpMacros.url, unresolved = _applyScvpMacros.unresolved;
8423
+ if (unresolved.length > 0) {
8424
+ console.warn("[StormcloudVideoPlayer] Unresolved SCVP macros (removed from request):", unresolved.join(", "));
8425
+ }
8426
+ finalUrl = ensureVideoAdType(url);
8427
+ } else {
8428
+ finalUrl = withDeferredPodParams(palNonce.injectNonce(ensureVideoAdType(applyVastMacros(baseUrl, macroContext))), !nonceReady);
8429
+ }
8430
+ console.log("[StormcloudVideoPlayer] Prepared optimized-pod request URL (pod=".concat(this.podCounter, "; pmnd/pmxd/pmad resolved at dispatch):"), finalUrl);
7905
8431
  return finalUrl;
7906
8432
  }
7907
8433
  },
8434
+ {
8435
+ key: "completeDeferredRequestSignals",
8436
+ value: function completeDeferredRequestSignals(url, palNonce) {
8437
+ return _async_to_generator(function() {
8438
+ var nonce, _tmp;
8439
+ return _ts_generator(this, function(_state) {
8440
+ switch(_state.label){
8441
+ case 0:
8442
+ if (findScvpMacroNames(url).indexOf("GIVN") === -1) return [
8443
+ 2,
8444
+ url
8445
+ ];
8446
+ _tmp = palNonce.getCurrentNonce();
8447
+ if (_tmp) return [
8448
+ 3,
8449
+ 2
8450
+ ];
8451
+ return [
8452
+ 4,
8453
+ palNonce.waitForNonce(this.palNonceDispatchWaitMs)
8454
+ ];
8455
+ case 1:
8456
+ _tmp = _state.sent();
8457
+ _state.label = 2;
8458
+ case 2:
8459
+ nonce = _tmp;
8460
+ if (!nonce) return [
8461
+ 2,
8462
+ url
8463
+ ];
8464
+ return [
8465
+ 2,
8466
+ substituteScvpMacros(url, /* @__PURE__ */ new Map([
8467
+ [
8468
+ "GIVN",
8469
+ nonce
8470
+ ]
8471
+ ]), function(name) {
8472
+ return name !== "GIVN";
8473
+ }).url
8474
+ ];
8475
+ }
8476
+ });
8477
+ }).call(this);
8478
+ }
8479
+ },
7908
8480
  {
7909
8481
  // --- Tracking ---
7910
8482
  key: "initializeTracking",
@@ -7952,6 +8524,9 @@ var AdConfigManager = /*#__PURE__*/ function() {
7952
8524
  return AdConfigManager;
7953
8525
  }();
7954
8526
  // src/player/AdTimingService.ts
8527
+ function monotonicNow() {
8528
+ return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
8529
+ }
7955
8530
  var AdTimingService = /*#__PURE__*/ function() {
7956
8531
  function AdTimingService(config, video, callbacks) {
7957
8532
  _class_call_check(this, AdTimingService);
@@ -8082,6 +8657,21 @@ var AdTimingService = /*#__PURE__*/ function() {
8082
8657
  },
8083
8658
  {
8084
8659
  // --- Duration boundary ---
8660
+ key: "beginBreakTiming",
8661
+ value: function beginBreakTiming(startWallClockMs) {
8662
+ this.currentAdBreakStartWallClockMs = startWallClockMs;
8663
+ this.breakStartMonoMs = monotonicNow() + (startWallClockMs - Date.now());
8664
+ this.breakEndMonoMs = void 0;
8665
+ }
8666
+ },
8667
+ {
8668
+ key: "markBreakEndedNow",
8669
+ value: function markBreakEndedNow() {
8670
+ this.scteAdBreakEndWallClockMs = Date.now();
8671
+ this.breakEndMonoMs = monotonicNow();
8672
+ }
8673
+ },
8674
+ {
8085
8675
  key: "setAdBreakDurationBoundary",
8086
8676
  value: function setAdBreakDurationBoundary(durationMs) {
8087
8677
  this.expectedAdBreakDurationMs = durationMs;
@@ -8090,6 +8680,18 @@ var AdTimingService = /*#__PURE__*/ function() {
8090
8680
  } else {
8091
8681
  this.scteAdBreakEndWallClockMs = void 0;
8092
8682
  }
8683
+ this.breakEndMonoMs = durationMs != null && this.breakStartMonoMs != null ? this.breakStartMonoMs + durationMs : void 0;
8684
+ }
8685
+ },
8686
+ {
8687
+ key: "getBreakTimingSnapshot",
8688
+ value: function getBreakTimingSnapshot() {
8689
+ return {
8690
+ scheduledBreakDurationMs: this.expectedAdBreakDurationMs,
8691
+ breakStartMonoMs: this.breakStartMonoMs,
8692
+ breakEndMonoMs: this.breakEndMonoMs,
8693
+ playedDurationMs: this.adBreakPlayedDurationMs
8694
+ };
8093
8695
  }
8094
8696
  },
8095
8697
  {
@@ -8503,6 +9105,8 @@ var AdTimingService = /*#__PURE__*/ function() {
8503
9105
  this.expectedAdBreakDurationMs = void 0;
8504
9106
  this.currentAdBreakStartWallClockMs = void 0;
8505
9107
  this.scteAdBreakEndWallClockMs = void 0;
9108
+ this.breakStartMonoMs = void 0;
9109
+ this.breakEndMonoMs = void 0;
8506
9110
  this.adBreakPlayedDurationMs = 0;
8507
9111
  this.currentAdIndex = 0;
8508
9112
  this.totalAdsInBreak = 0;
@@ -9516,9 +10120,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9516
10120
  // ───────────────────────────────────────────────────────────────
9517
10121
  key: "nextAdRequestUrl",
9518
10122
  value: function nextAdRequestUrl(baseVastUrl) {
9519
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
9520
- var breakDurationMs = remaining > 0 ? remaining : void 0;
9521
- return this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10123
+ return this.host.generatePodVastUrl(baseVastUrl);
9522
10124
  }
9523
10125
  },
9524
10126
  {
@@ -9781,7 +10383,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9781
10383
  key: "handleAdStart",
9782
10384
  value: function handleAdStart(marker) {
9783
10385
  return _async_to_generator(function() {
9784
- var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, hasPrefetchedUrl, mode, edgeUrl, outcome, podPlayed;
10386
+ var baseVastUrl, edgeConfigured, adBreakDurationMs, currentMuted, currentVolume, epoch, mode, edgeUrl, outcome, podPlayed;
9785
10387
  return _ts_generator(this, function(_state) {
9786
10388
  switch(_state.label){
9787
10389
  case 0:
@@ -9833,8 +10435,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9833
10435
  }
9834
10436
  this.noteOpportunity("scte35", this.cueManager.activeScte35BreakKey, "midroll");
9835
10437
  epoch = this.timing.adBreakEpoch;
9836
- hasPrefetchedUrl = !!(this.pendingAdBreak && this.pendingAdBreak.vastUrls.length > 0);
9837
- if (!(adBreakDurationMs == null && (!hasPrefetchedUrl || edgeConfigured))) return [
10438
+ if (!(adBreakDurationMs == null)) return [
9838
10439
  3,
9839
10440
  2
9840
10441
  ];
@@ -9890,7 +10491,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9890
10491
  }
9891
10492
  return [
9892
10493
  4,
9893
- this.startOptimizedPod(baseVastUrl, adBreakDurationMs)
10494
+ this.startOptimizedPod(baseVastUrl)
9894
10495
  ];
9895
10496
  case 6:
9896
10497
  podPlayed = _state.sent();
@@ -9958,9 +10559,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9958
10559
  value: // ───────────────────────────────────────────────────────────────
9959
10560
  // Optimized pod (single multi-ad request)
9960
10561
  // ───────────────────────────────────────────────────────────────
9961
- function startOptimizedPod(baseVastUrl, breakDurationMs) {
10562
+ function startOptimizedPod(baseVastUrl) {
9962
10563
  return _async_to_generator(function() {
9963
- var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _adPlayer_getPodAdCount, podCount, error;
10564
+ var podUrl, prefetched, epoch, generation, adPlayer, requestToken, requestUrl, _ref, _this_currentVastUrl, _adPlayer_getPodAdCount, finalizeRequestUrl, podCount, error;
9964
10565
  return _ts_generator(this, function(_state) {
9965
10566
  switch(_state.label){
9966
10567
  case 0:
@@ -9969,7 +10570,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9969
10570
  podUrl = this.pendingAdBreak.vastUrls[0];
9970
10571
  this.clearPendingAdBreak();
9971
10572
  } else {
9972
- podUrl = this.host.generatePodVastUrl(baseVastUrl, breakDurationMs);
10573
+ podUrl = this.host.generatePodVastUrl(baseVastUrl);
9973
10574
  }
9974
10575
  if (!podUrl) {
9975
10576
  return [
@@ -9993,9 +10594,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
9993
10594
  case 1:
9994
10595
  _state.trys.push([
9995
10596
  1,
9996
- 5,
10597
+ 9,
9997
10598
  ,
9998
- 6
10599
+ 10
9999
10600
  ]);
10000
10601
  return [
10001
10602
  4,
@@ -10007,15 +10608,46 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10007
10608
  2,
10008
10609
  true
10009
10610
  ];
10611
+ return [
10612
+ 4,
10613
+ this.host.completeGamRequestSignals(requestUrl)
10614
+ ];
10615
+ case 3:
10616
+ requestUrl = _state.sent();
10617
+ if (this.isStale(epoch, generation)) return [
10618
+ 2,
10619
+ true
10620
+ ];
10010
10621
  this.timing.startAdRequestWatchdog(requestToken);
10622
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
10623
+ _state.label = 4;
10624
+ case 4:
10625
+ _state.trys.push([
10626
+ 4,
10627
+ ,
10628
+ 6,
10629
+ 7
10630
+ ]);
10011
10631
  return [
10012
10632
  4,
10013
10633
  this.callController(function() {
10014
- return adPlayer.requestAds(requestUrl);
10634
+ return adPlayer.requestAds(requestUrl, {
10635
+ finalizeRequestUrl: finalizeRequestUrl
10636
+ });
10015
10637
  })
10016
10638
  ];
10017
- case 3:
10639
+ case 5:
10018
10640
  _state.sent();
10641
+ return [
10642
+ 3,
10643
+ 7
10644
+ ];
10645
+ case 6:
10646
+ this.recordPodResponseDiagnostics(requestToken, adPlayer);
10647
+ return [
10648
+ 7
10649
+ ];
10650
+ case 7:
10019
10651
  this.timing.clearAdRequestWatchdog();
10020
10652
  if (this.isStale(epoch, generation)) {
10021
10653
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -10043,7 +10675,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10043
10675
  }
10044
10676
  sendAdLoadedTracking(this.host.config.licenseKey, {
10045
10677
  source: "hls",
10046
- vastUrl: requestUrl,
10678
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
10047
10679
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
10048
10680
  }, this.analyticsContext).catch(function() {});
10049
10681
  this.timing.startAdFailsafeTimer(requestToken);
@@ -10053,7 +10685,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10053
10685
  return adPlayer.play();
10054
10686
  })
10055
10687
  ];
10056
- case 4:
10688
+ case 8:
10057
10689
  _state.sent();
10058
10690
  if (this.isStale(epoch, generation)) return [
10059
10691
  2,
@@ -10067,7 +10699,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10067
10699
  2,
10068
10700
  true
10069
10701
  ];
10070
- case 5:
10702
+ case 9:
10071
10703
  error = _state.sent();
10072
10704
  this.timing.clearAdRequestWatchdog();
10073
10705
  this.timing.clearAdFailsafeTimer();
@@ -10087,12 +10719,16 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10087
10719
  if (this.debug) {
10088
10720
  console.warn("[POD] Optimized pod request/play failed:", error);
10089
10721
  }
10722
+ if (this.handlePodRequestNotSent(error)) return [
10723
+ 2,
10724
+ false
10725
+ ];
10090
10726
  this.recordRequestFailure(error, podUrl);
10091
10727
  return [
10092
10728
  2,
10093
10729
  false
10094
10730
  ];
10095
- case 6:
10731
+ case 10:
10096
10732
  return [
10097
10733
  2
10098
10734
  ];
@@ -10138,17 +10774,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10138
10774
  }
10139
10775
  },
10140
10776
  {
10141
- /**
10142
- * Builds the next Edge request from the budget left right now, or marks Edge
10143
- * exhausted for this break. Synchronous on purpose: callers must reach the
10144
- * REQUESTING state in the same tick so a second completion event cannot race
10145
- * in a parallel request.
10146
- */ key: "prepareEdgePodRequest",
10777
+ key: "prepareEdgePodRequest",
10147
10778
  value: function prepareEdgePodRequest() {
10148
10779
  var baseUrl = this.host.getEdgePodBaseUrl();
10149
10780
  if (!baseUrl) return void 0;
10150
10781
  var remainingMs = this.timing.getRemainingAdMs();
10151
- var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak);
10782
+ var remainingAds = Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak);
10152
10783
  if (remainingAds < 1) {
10153
10784
  this.markEdgeExhausted("ad_capacity_reached", {
10154
10785
  adsInBreak: this.timing.totalAdsInBreak
@@ -10227,7 +10858,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10227
10858
  ];
10228
10859
  }
10229
10860
  remainingMs = this.timing.getRemainingAdMs();
10230
- remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolvePodParams().maxAds - this.timing.totalAdsInBreak));
10861
+ remainingAds = Math.max(1, Math.min(EDGE_POD_MAX_ADS, this.adConfig.resolveEdgeMaxAds() - this.timing.totalAdsInBreak));
10231
10862
  overrunAllowanceMs = Math.max(0, (_this_host_config_maxAdBreakExtensionMs = this.host.config.maxAdBreakExtensionMs) !== null && _this_host_config_maxAdBreakExtensionMs !== void 0 ? _this_host_config_maxAdBreakExtensionMs : 0);
10232
10863
  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;
10233
10864
  if (classifyEdgeVastResponse({
@@ -10574,7 +11205,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10574
11205
  {
10575
11206
  key: "noteVastUrlGenerated",
10576
11207
  value: function noteVastUrlGenerated(url, source) {
10577
- var _ref, _ref1, _ref2, _ref3, _ref4;
11208
+ var _ref, _ref1;
10578
11209
  var params;
10579
11210
  try {
10580
11211
  params = new URL(url).searchParams;
@@ -10584,9 +11215,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10584
11215
  requestId: void 0,
10585
11216
  source: source,
10586
11217
  pod: (_ref1 = params === null || params === void 0 ? void 0 : params.get("pod")) !== null && _ref1 !== void 0 ? _ref1 : void 0,
10587
- pmad: (_ref2 = params === null || params === void 0 ? void 0 : params.get("pmad")) !== null && _ref2 !== void 0 ? _ref2 : void 0,
10588
- pmnd: (_ref3 = params === null || params === void 0 ? void 0 : params.get("pmnd")) !== null && _ref3 !== void 0 ? _ref3 : void 0,
10589
- pmxd: (_ref4 = params === null || params === void 0 ? void 0 : params.get("pmxd")) !== null && _ref4 !== void 0 ? _ref4 : void 0,
11218
+ podParamsDeferredToDispatch: findScvpMacroNames(url).some(function(name) {
11219
+ return SCVP_POD_MACROS.has(name);
11220
+ }),
10590
11221
  adType: adType
10591
11222
  });
10592
11223
  if (adType === "audio" || adType === "audio_video") {
@@ -10627,10 +11258,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10627
11258
  if (diag && !diag.failureReason) {
10628
11259
  diag.failureReason = "".concat(outcome, ": ").concat(message);
10629
11260
  }
11261
+ var failureKey = (diag === null || diag === void 0 ? void 0 : diag.dispatchedUrl) && findScvpMacroNames(vastTagUrl).some(function(name) {
11262
+ return SCVP_POD_MACROS.has(name);
11263
+ }) ? diag.dispatchedUrl : vastTagUrl;
10630
11264
  if (this.timing.isTemporaryAdError(error)) {
10631
- this.timing.temporaryFailureUrls.set(vastTagUrl, Date.now());
11265
+ this.timing.temporaryFailureUrls.set(failureKey, Date.now());
10632
11266
  } else if (outcome !== "discarded_budget") {
10633
- this.timing.failedVastUrls.add(vastTagUrl);
11267
+ this.timing.failedVastUrls.add(failureKey);
10634
11268
  }
10635
11269
  this.countFunnelStage("request_outcome:".concat(outcome));
10636
11270
  this.logOrchestratorFunnel("request_outcome", _object_spread({
@@ -10656,6 +11290,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10656
11290
  switch(payload.stage){
10657
11291
  case "gam_http_request_sent":
10658
11292
  diag.gamRequestSent++;
11293
+ this.logPodDispatch(diag);
10659
11294
  break;
10660
11295
  case "edge_http_request_sent":
10661
11296
  diag.edgeRequestSent++;
@@ -10707,8 +11342,10 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10707
11342
  if (gamReturnedAdWithoutImpression) {
10708
11343
  this.countFunnelStage("gam_ad_without_impression");
10709
11344
  }
10710
- var startedAt = diag.startedAt, fields = _object_without_properties(diag, [
10711
- "startedAt"
11345
+ var startedAt = diag.startedAt, _dispatchedUrl = diag.dispatchedUrl, _logged = diag.podDispatchLogged, fields = _object_without_properties(diag, [
11346
+ "startedAt",
11347
+ "dispatchedUrl",
11348
+ "podDispatchLogged"
10712
11349
  ]);
10713
11350
  console.log("[AdBreak][REQUEST] summary", _object_spread_props(_object_spread({}, fields), {
10714
11351
  durationMs: Date.now() - startedAt,
@@ -10720,24 +11357,71 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10720
11357
  // ───────────────────────────────────────────────────────────────
10721
11358
  // Single ad playback
10722
11359
  // ───────────────────────────────────────────────────────────────
10723
- key: "withCurrentPodBudget",
10724
- value: function withCurrentPodBudget(rawVastTagUrl) {
10725
- var vastTagUrl = ensureVideoAdType(rawVastTagUrl);
10726
- var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
10727
- if (!(remaining > 0)) return vastTagUrl;
10728
- try {
10729
- var url = new URL(vastTagUrl);
10730
- if (!url.searchParams.has("pmxd")) return vastTagUrl;
10731
- var maxMs = Math.round(remaining);
10732
- url.searchParams.set("pmxd", String(maxMs));
10733
- var minMs = Number(url.searchParams.get("pmnd"));
10734
- if (Number.isFinite(minMs) && minMs > maxMs) {
10735
- url.searchParams.set("pmnd", String(maxMs));
10736
- }
10737
- return url.toString();
10738
- } catch (unused) {
10739
- return vastTagUrl;
10740
- }
11360
+ key: "createGamDispatchFinalizer",
11361
+ value: function createGamDispatchFinalizer(requestToken) {
11362
+ var _this = this;
11363
+ var breakId = this.timing.adBreakEpoch;
11364
+ var config = this.adConfig.resolveAdPodConfig();
11365
+ var minUsablePmxdMs = this.timing.getMinRemainingMsToStartAd();
11366
+ return function(url) {
11367
+ var capacity = measureBreakCapacity(_this.timing.getBreakTimingSnapshot(), monotonicNow());
11368
+ var diag = _this.requestDiagnostics.get(requestToken);
11369
+ try {
11370
+ var result = finalizeGamRequestUrl(url, {
11371
+ breakId: breakId,
11372
+ capacity: capacity,
11373
+ config: config,
11374
+ minUsablePmxdMs: minUsablePmxdMs
11375
+ });
11376
+ if (diag) {
11377
+ diag.pod = result.diagnostics;
11378
+ diag.dispatchedUrl = result.url;
11379
+ diag.podDispatchLogged = false;
11380
+ }
11381
+ _this.currentVastUrl = result.url;
11382
+ return result.url;
11383
+ } catch (error) {
11384
+ if (diag && isPodRequestAbortedError(error)) {
11385
+ diag.failureReason = "pod_request_not_sent:".concat(error.reason);
11386
+ }
11387
+ throw error;
11388
+ }
11389
+ };
11390
+ }
11391
+ },
11392
+ {
11393
+ key: "logPodDispatch",
11394
+ value: function logPodDispatch(diag) {
11395
+ if (!diag.pod || diag.podDispatchLogged) return;
11396
+ diag.podDispatchLogged = true;
11397
+ this.logOrchestratorFunnel(diag.pod.optimizedPod ? "optimized_pod_request_dispatched" : "gam_request_dispatched", _object_spread({}, diag.pod));
11398
+ }
11399
+ },
11400
+ {
11401
+ key: "recordPodResponseDiagnostics",
11402
+ value: function recordPodResponseDiagnostics(requestToken, adPlayer) {
11403
+ var _diag_vastAdCount, _ref;
11404
+ var _adPlayer_getPodTotalDurationMs;
11405
+ var diag = this.requestDiagnostics.get(requestToken);
11406
+ if (!(diag === null || diag === void 0 ? void 0 : diag.pod) || diag.pod.pmxdSent == null || diag.podResponse) return;
11407
+ if (diag.gamRequestSent === 0 && diag.vastHttpStatus == null) return;
11408
+ 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);
11409
+ this.logOrchestratorFunnel("optimized_pod_response", _object_spread({
11410
+ pmxdSent: diag.pod.pmxdSent
11411
+ }, diag.podResponse));
11412
+ }
11413
+ },
11414
+ {
11415
+ key: "handlePodRequestNotSent",
11416
+ value: function handlePodRequestNotSent(error) {
11417
+ if (!isPodRequestAbortedError(error) || error.reason === "invalid_url") return false;
11418
+ var aborted = error;
11419
+ this.countFunnelStage("request_outcome:pod_request_not_sent");
11420
+ this.logOrchestratorFunnel("pod_request_not_sent", _object_spread({
11421
+ reason: aborted.reason,
11422
+ errorMessage: aborted.message
11423
+ }, aborted.diagnostics));
11424
+ return true;
10741
11425
  }
10742
11426
  },
10743
11427
  {
@@ -10957,7 +11641,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10957
11641
  value: function playSingleAd(vastTagUrl) {
10958
11642
  var trigger = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "vmap";
10959
11643
  return _async_to_generator(function() {
10960
- var epoch, generation, requestToken, ap, budgetedUrl, requestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
11644
+ var epoch, generation, requestToken, ap, requestUrl, _this_currentVastUrl, finalizeRequestUrl, _ap_getLoadedAdDuration, adDurationS, remainingMs, error;
10961
11645
  return _ts_generator(this, function(_state) {
10962
11646
  switch(_state.label){
10963
11647
  case 0:
@@ -10995,19 +11679,18 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
10995
11679
  requestToken = ++this.timing.adRequestTokenCounter;
10996
11680
  this.timing.activeAdRequestToken = requestToken;
10997
11681
  ap = this.host.getAdPlayer();
10998
- budgetedUrl = this.withCurrentPodBudget(vastTagUrl);
10999
11682
  this.currentPodSource = "gam";
11000
11683
  this.setSlotState("REQUESTING", trigger);
11001
11684
  this.beginFunnelRequest(ap, requestToken, trigger);
11002
- requestUrl = this.applyOpportunityFloor(budgetedUrl);
11685
+ requestUrl = this.applyOpportunityFloor(ensureVideoAdType(vastTagUrl));
11003
11686
  this.currentVastUrl = requestUrl;
11004
11687
  _state.label = 1;
11005
11688
  case 1:
11006
11689
  _state.trys.push([
11007
11690
  1,
11008
- 5,
11691
+ 9,
11009
11692
  ,
11010
- 6
11693
+ 10
11011
11694
  ]);
11012
11695
  return [
11013
11696
  4,
@@ -11018,15 +11701,45 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11018
11701
  if (this.isStale(epoch, generation)) return [
11019
11702
  2
11020
11703
  ];
11704
+ return [
11705
+ 4,
11706
+ this.host.completeGamRequestSignals(requestUrl)
11707
+ ];
11708
+ case 3:
11709
+ requestUrl = _state.sent();
11710
+ if (this.isStale(epoch, generation)) return [
11711
+ 2
11712
+ ];
11021
11713
  this.timing.startAdRequestWatchdog(requestToken);
11714
+ finalizeRequestUrl = this.createGamDispatchFinalizer(requestToken);
11715
+ _state.label = 4;
11716
+ case 4:
11717
+ _state.trys.push([
11718
+ 4,
11719
+ ,
11720
+ 6,
11721
+ 7
11722
+ ]);
11022
11723
  return [
11023
11724
  4,
11024
11725
  this.callController(function() {
11025
- return ap.requestAds(requestUrl);
11726
+ return ap.requestAds(requestUrl, {
11727
+ finalizeRequestUrl: finalizeRequestUrl
11728
+ });
11026
11729
  })
11027
11730
  ];
11028
- case 3:
11731
+ case 5:
11029
11732
  _state.sent();
11733
+ return [
11734
+ 3,
11735
+ 7
11736
+ ];
11737
+ case 6:
11738
+ this.recordPodResponseDiagnostics(requestToken, ap);
11739
+ return [
11740
+ 7
11741
+ ];
11742
+ case 7:
11030
11743
  this.timing.clearAdRequestWatchdog();
11031
11744
  if (this.isStale(epoch, generation)) {
11032
11745
  this.logOrchestratorFunnel("stale_request_result_ignored", {
@@ -11038,7 +11751,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11038
11751
  }
11039
11752
  sendAdLoadedTracking(this.host.config.licenseKey, {
11040
11753
  source: "hls",
11041
- vastUrl: requestUrl,
11754
+ vastUrl: (_this_currentVastUrl = this.currentVastUrl) !== null && _this_currentVastUrl !== void 0 ? _this_currentVastUrl : requestUrl,
11042
11755
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
11043
11756
  }, this.analyticsContext).catch(function() {});
11044
11757
  if (!this.timing.ensureLoadedAdFitsBudget(ap)) {
@@ -11059,7 +11772,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11059
11772
  return ap.play();
11060
11773
  })
11061
11774
  ];
11062
- case 4:
11775
+ case 8:
11063
11776
  _state.sent();
11064
11777
  if (this.isStale(epoch, generation)) return [
11065
11778
  2
@@ -11071,9 +11784,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11071
11784
  this.timing.temporaryFailureUrls.delete(vastTagUrl);
11072
11785
  return [
11073
11786
  3,
11074
- 6
11787
+ 10
11075
11788
  ];
11076
- case 5:
11789
+ case 9:
11077
11790
  error = _state.sent();
11078
11791
  this.timing.clearAdRequestWatchdog();
11079
11792
  this.timing.clearAdFailsafeTimer();
@@ -11090,12 +11803,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11090
11803
  ];
11091
11804
  }
11092
11805
  if (this.debug) console.error("[AD-ERROR] Ad request failed:", error === null || error === void 0 ? void 0 : error.message);
11806
+ if (this.handlePodRequestNotSent(error)) throw error;
11093
11807
  this.recordRequestFailure(error, vastTagUrl);
11094
11808
  if ((error === null || error === void 0 ? void 0 : error.message) === "ad_duration_exceeds_budget") {
11095
11809
  this.recreateAdController("discarded_budget");
11096
11810
  }
11097
11811
  throw error;
11098
- case 6:
11812
+ case 10:
11099
11813
  return [
11100
11814
  2
11101
11815
  ];
@@ -11157,7 +11871,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
11157
11871
  playbackFailedAfterFill: count("request_outcome:playback_failed"),
11158
11872
  requestFailed: count("request_failed"),
11159
11873
  requestAbortedTimeout: count("request_aborted_timeout"),
11160
- credentialsRetries: count("vast_credentials_retry"),
11874
+ credentialsModeChanges: count("gam_credentials_mode_changed"),
11161
11875
  wrapperFailures: count("wrapper_fetch:failure"),
11162
11876
  noSupportedMedia: count("vast_no_supported_media"),
11163
11877
  vpaidOnly: count("vast_no_supported_media:vpaid"),
@@ -11693,8 +12407,11 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11693
12407
  requiresMediaPipelineResetAfterAds: function requiresMediaPipelineResetAfterAds1() {
11694
12408
  return requiresMediaPipelineResetAfterAds();
11695
12409
  },
11696
- generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
11697
- return _this.generatePodVastUrl(base, breakDurationMs);
12410
+ generatePodVastUrl: function generatePodVastUrl(base) {
12411
+ return _this.generatePodVastUrl(base);
12412
+ },
12413
+ completeGamRequestSignals: function completeGamRequestSignals(url) {
12414
+ return _this.adConfig.completeDeferredRequestSignals(url, _this.palNonce);
11698
12415
  },
11699
12416
  getEdgePodBaseUrl: function getEdgePodBaseUrl() {
11700
12417
  return _this.edgePodBaseUrl;
@@ -11818,9 +12535,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
11818
12535
  },
11819
12536
  {
11820
12537
  key: "generatePodVastUrl",
11821
- value: function generatePodVastUrl(baseUrl, breakDurationMs) {
11822
- var podParams = this.adConfig.resolvePodParams(breakDurationMs);
11823
- return this.adConfig.generatePodVastUrl(baseUrl, podParams, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
12538
+ value: function generatePodVastUrl(baseUrl) {
12539
+ return this.adConfig.generatePodVastUrl(baseUrl, this.adPlayer, this.palNonce, this.adBreak.inAdBreak);
11824
12540
  }
11825
12541
  },
11826
12542
  {
@@ -12174,7 +12890,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12174
12890
  activeAdRequest: this.timing.activeAdRequestToken !== null
12175
12891
  });
12176
12892
  }
12177
- this.timing.scteAdBreakEndWallClockMs = Date.now();
12893
+ this.timing.markBreakEndedNow();
12178
12894
  this.timing.clearAdStartTimer();
12179
12895
  this.timing.clearAdStopTimer();
12180
12896
  if (adPlaying) {
@@ -12201,7 +12917,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12201
12917
  this.adBreak.inAdBreak = true;
12202
12918
  this.cueManager.activeScte35BreakKey = cueKey !== null && cueKey !== void 0 ? cueKey : this.cueManager.pendingScte35CueKey;
12203
12919
  this.cueManager.scheduledScte35BreakKey = void 0;
12204
- this.timing.currentAdBreakStartWallClockMs = this.timing.resolveScteBreakStartWallClockMs(marker);
12920
+ this.timing.beginBreakTiming(this.timing.resolveScteBreakStartWallClockMs(marker));
12205
12921
  this.timing.setAdBreakDurationBoundary(durationMs);
12206
12922
  this.adBreak.handleAdStart(marker);
12207
12923
  this.timing.scheduleAdStopAtBreakBoundary();
@@ -12247,9 +12963,8 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12247
12963
  }
12248
12964
  this.adConfig.beginNewAdPod();
12249
12965
  this.adConfig.podAssignedByPrefetch = true;
12250
- var breakDurationMs = marker.durationSeconds != null ? marker.durationSeconds * 1e3 : void 0;
12251
12966
  var generatedUrls = [
12252
- this.generatePodVastUrl(baseVastUrl, breakDurationMs)
12967
+ this.generatePodVastUrl(baseVastUrl)
12253
12968
  ];
12254
12969
  this.adBreak.pendingAdBreak = _object_spread_props(_object_spread({
12255
12970
  marker: marker
@@ -12348,7 +13063,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
12348
13063
  this.adPlayer.updateOriginalMutedState(this.video.muted, this.video.volume);
12349
13064
  this.adBreak.showAds = true;
12350
13065
  this.adBreak.inAdBreak = true;
12351
- this.timing.currentAdBreakStartWallClockMs = Date.now();
13066
+ this.timing.beginBreakTiming(Date.now());
12352
13067
  if (durationMs > 0) {
12353
13068
  this.timing.setAdBreakDurationBoundary(durationMs);
12354
13069
  }