stormcloud-video-player 0.8.59 → 0.8.61

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 (82) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +1369 -1369
  3. package/dist/stormcloud-vp.min.js +3 -1
  4. package/lib/Player.cjs +548 -0
  5. package/lib/Player.cjs.map +1 -0
  6. package/lib/Player.d.cts +146 -0
  7. package/lib/{index.js → StormcloudPlayer.cjs} +1193 -1908
  8. package/lib/StormcloudPlayer.cjs.map +1 -0
  9. package/lib/{index.d.ts → StormcloudPlayer.d.cts} +7 -400
  10. package/lib/index.cjs +1064 -280
  11. package/lib/index.cjs.map +1 -1
  12. package/lib/index.d.cts +18 -4032
  13. package/lib/patterns.cjs +111 -0
  14. package/lib/patterns.cjs.map +1 -0
  15. package/lib/patterns.d.cts +14 -0
  16. package/lib/player/AdBreakOrchestrator.cjs +51 -16
  17. package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
  18. package/lib/player/AdBreakOrchestrator.d.cts +3 -1
  19. package/lib/player/AdConfigManager.cjs +206 -26
  20. package/lib/player/AdConfigManager.cjs.map +1 -1
  21. package/lib/player/AdConfigManager.d.cts +1 -1
  22. package/lib/player/AdTimingService.cjs.map +1 -1
  23. package/lib/player/AdTimingService.d.cts +1 -1
  24. package/lib/player/HlsEngine.cjs.map +1 -1
  25. package/lib/player/HlsEngine.d.cts +1 -1
  26. package/lib/player/PlaceholderLayer.cjs.map +1 -1
  27. package/lib/player/PlayerControls.cjs.map +1 -1
  28. package/lib/player/PlayerControls.d.cts +1 -1
  29. package/lib/player/Scte35CueManager.cjs.map +1 -1
  30. package/lib/player/Scte35CueManager.d.cts +1 -1
  31. package/lib/player/Scte35Parser.cjs.map +1 -1
  32. package/lib/player/Scte35Parser.d.cts +1 -1
  33. package/lib/player/StormcloudVideoPlayer.cjs +1060 -278
  34. package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
  35. package/lib/player/StormcloudVideoPlayer.d.cts +1 -1
  36. package/lib/player/playerTypes.cjs.map +1 -1
  37. package/lib/player/playerTypes.d.cts +1 -1
  38. package/lib/players/FilePlayer.cjs.map +1 -1
  39. package/lib/players/HlsPlayer.cjs +1060 -278
  40. package/lib/players/HlsPlayer.cjs.map +1 -1
  41. package/lib/players/HlsPlayer.d.cts +1 -1
  42. package/lib/players/index.cjs +1060 -278
  43. package/lib/players/index.cjs.map +1 -1
  44. package/lib/props.cjs +186 -0
  45. package/lib/props.cjs.map +1 -0
  46. package/lib/props.d.cts +62 -0
  47. package/lib/sdk/hlsAdPlayer.cjs +884 -234
  48. package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
  49. package/lib/sdk/hlsAdPlayer.d.cts +1 -1
  50. package/lib/sdk/pal.cjs +9 -5
  51. package/lib/sdk/pal.cjs.map +1 -1
  52. package/lib/sdk/pal.d.cts +1 -0
  53. package/lib/types.cjs +49 -0
  54. package/lib/types.cjs.map +1 -0
  55. package/lib/{types-52ASml2N.d.cts → types.d.cts} +48 -1
  56. package/lib/ui/StormcloudVideoPlayer.cjs +1064 -280
  57. package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
  58. package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
  59. package/lib/utils/browserCompat.cjs.map +1 -1
  60. package/lib/utils/ctvVastSignals.cjs +178 -19
  61. package/lib/utils/ctvVastSignals.cjs.map +1 -1
  62. package/lib/utils/devUrl.cjs.map +1 -1
  63. package/lib/utils/polyfills.cjs.map +1 -1
  64. package/lib/utils/tracking.cjs +45 -16
  65. package/lib/utils/tracking.cjs.map +1 -1
  66. package/lib/utils/tracking.d.cts +1 -1
  67. package/lib/utils/trackingIngest.cjs.map +1 -1
  68. package/lib/utils/vastEnvironmentSignals.cjs +192 -20
  69. package/lib/utils/vastEnvironmentSignals.cjs.map +1 -1
  70. package/lib/utils/vastEnvironmentSignals.d.cts +13 -2
  71. package/lib/utils/vastMacros.cjs +50 -4
  72. package/lib/utils/vastMacros.cjs.map +1 -1
  73. package/lib/utils/vastMacros.d.cts +2 -0
  74. package/lib/utils/vastTrackingMacros.cjs +5 -0
  75. package/lib/utils/vastTrackingMacros.cjs.map +1 -1
  76. package/lib/utils/vastTrackingMacros.d.cts +2 -0
  77. package/lib/utils.cjs +292 -0
  78. package/lib/utils.cjs.map +1 -0
  79. package/lib/utils.d.cts +17 -0
  80. package/package.json +91 -91
  81. package/rollup.config.js +90 -90
  82. package/lib/index.js.map +0 -1
@@ -565,6 +565,7 @@ var KNOWN_VAST_MACROS = /* @__PURE__ */ new Set([
565
565
  "PLAYERSIZE",
566
566
  "PLAYERSTATE",
567
567
  "PODSEQUENCE",
568
+ "REASON",
568
569
  "REGULATIONS",
569
570
  "SERVERSIDE",
570
571
  "SERVERUA",
@@ -623,6 +624,10 @@ function resolveMacroValues(ctx) {
623
624
  if (ctx.podSequence != null) {
624
625
  set("PODSEQUENCE", String(ctx.podSequence));
625
626
  }
627
+ set("ADSERVINGID", ctx.adServingId);
628
+ if (ctx.reason != null && ctx.reason !== "") {
629
+ set("REASON", String(ctx.reason));
630
+ }
626
631
  return values;
627
632
  }
628
633
  function substituteVastTrackingMacros(url) {
@@ -639,10 +644,72 @@ function substituteVastTrackingMacros(url) {
639
644
  });
640
645
  }
641
646
  // src/sdk/hlsAdPlayer.ts
647
+ var LINEAR_TRACKING_EVENTS = [
648
+ "creativeView",
649
+ "loaded",
650
+ "start",
651
+ "firstQuartile",
652
+ "midpoint",
653
+ "thirdQuartile",
654
+ "complete",
655
+ "mute",
656
+ "unmute",
657
+ "pause",
658
+ "resume",
659
+ "fullscreen",
660
+ "exitFullscreen",
661
+ "playerExpand",
662
+ "playerCollapse",
663
+ "notUsed"
664
+ ];
665
+ function textOf(el) {
666
+ var _el_textContent;
667
+ var value = el === null || el === void 0 ? void 0 : (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
668
+ return value ? value : void 0;
669
+ }
670
+ function parseVastTime(value) {
671
+ if (!value) return void 0;
672
+ var parts = value.trim().split(":");
673
+ if (parts.length !== 3) return void 0;
674
+ var _parts_map = _sliced_to_array(parts.map(function(p) {
675
+ return parseFloat(p);
676
+ }), 3), h = _parts_map[0], m = _parts_map[1], s = _parts_map[2];
677
+ if (![
678
+ h,
679
+ m,
680
+ s
681
+ ].every(function(n) {
682
+ return n !== void 0 && Number.isFinite(n);
683
+ })) {
684
+ return void 0;
685
+ }
686
+ return h * 3600 + m * 60 + s;
687
+ }
688
+ function parseProgressOffset(offset) {
689
+ if (!offset) return void 0;
690
+ var trimmed = offset.trim();
691
+ if (trimmed.endsWith("%")) {
692
+ var percent = parseFloat(trimmed);
693
+ return Number.isFinite(percent) ? {
694
+ offsetPercent: percent
695
+ } : void 0;
696
+ }
697
+ var seconds = parseVastTime(trimmed);
698
+ return seconds !== void 0 ? {
699
+ offsetSeconds: seconds
700
+ } : void 0;
701
+ }
642
702
  var MAX_VAST_WRAPPER_DEPTH = 5;
643
703
  var BEACON_TIMEOUT_MS = 3e4;
644
704
  var inFlightBeacons = /* @__PURE__ */ new Set();
645
705
  var VAST_ERROR_MEDIA_DISPLAY = 405;
706
+ var VAST_ERROR_WRAPPER_TIMEOUT = 301;
707
+ var VAST_ERROR_WRAPPER_LIMIT = 302;
708
+ var VAST_ERROR_WRAPPER_NO_ADS = 303;
709
+ var VAST_ERROR_NO_SUPPORTED_MEDIA = 403;
710
+ var VERIFICATION_NOT_SUPPORTED_REASON = 2;
711
+ var VIEWABLE_MIN_VISIBLE_RATIO = 0.5;
712
+ var VIEWABLE_MIN_CONTINUOUS_S = 2;
646
713
  function toVastMediaErrorCode(error) {
647
714
  switch(error === null || error === void 0 ? void 0 : error.code){
648
715
  case 1:
@@ -670,6 +737,7 @@ function createHlsAdPlayer(contentVideo, options) {
670
737
  var adHls;
671
738
  var adContainerEl = (_contentVideo_AD_CONTAINER_PROP = contentVideo[AD_CONTAINER_PROP]) !== null && _contentVideo_AD_CONTAINER_PROP !== void 0 ? _contentVideo_AD_CONTAINER_PROP : void 0;
672
739
  var adEventHandlers = [];
740
+ var containerHandlers = [];
673
741
  var currentAd;
674
742
  var currentAdMediaFile;
675
743
  var podAds = [];
@@ -687,14 +755,28 @@ function createHlsAdPlayer(contentVideo, options) {
687
755
  var sawDecodedVideoFrame = false;
688
756
  var videoFrameCallbackHandle;
689
757
  var pendingPlayPromise;
690
- var trackingFired = {
691
- impression: false,
692
- start: false,
693
- firstQuartile: false,
694
- midpoint: false,
695
- thirdQuartile: false,
696
- complete: false
697
- };
758
+ function createTrackingState() {
759
+ return {
760
+ impression: false,
761
+ loaded: false,
762
+ start: false,
763
+ firstQuartile: false,
764
+ midpoint: false,
765
+ thirdQuartile: false,
766
+ complete: false,
767
+ viewabilitySettled: false,
768
+ lastMuted: void 0,
769
+ progressFired: /* @__PURE__ */ new Set()
770
+ };
771
+ }
772
+ var trackingFired = createTrackingState();
773
+ var resolvedAds = /* @__PURE__ */ new Set();
774
+ var viewObserver;
775
+ var visibleRatio = 0;
776
+ var continuousVisibleS = 0;
777
+ var lastViewSampleTime;
778
+ var lastPlayerExpanded = false;
779
+ var documentHandlers = [];
698
780
  function emit(event, payload) {
699
781
  var set = listeners.get(event);
700
782
  if (!set) return;
@@ -723,7 +805,11 @@ function createHlsAdPlayer(contentVideo, options) {
723
805
  }
724
806
  }
725
807
  }
726
- function buildTrackingMacroContext(errorCode) {
808
+ function buildTrackingMacroContext() {
809
+ var options2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
810
+ var _options2_ad;
811
+ var errorCode = options2.errorCode, reason = options2.reason;
812
+ var ad = (_options2_ad = options2.ad) !== null && _options2_ad !== void 0 ? _options2_ad : currentAd;
727
813
  var context = {
728
814
  adPlayheadSeconds: adVideoElement === null || adVideoElement === void 0 ? void 0 : adVideoElement.currentTime,
729
815
  contentPlayheadSeconds: contentVideo.currentTime,
@@ -744,11 +830,17 @@ function createHlsAdPlayer(contentVideo, options) {
744
830
  if (podAds.length > 0) {
745
831
  context.podSequence = podIndex + 1;
746
832
  }
833
+ if (ad === null || ad === void 0 ? void 0 : ad.adServingId) {
834
+ context.adServingId = ad.adServingId;
835
+ }
836
+ if (reason != null) {
837
+ context.reason = reason;
838
+ }
747
839
  return context;
748
840
  }
749
841
  function fireTrackingPixels(urls, options2) {
750
842
  if (!urls || urls.length === 0) return;
751
- var macroContext = buildTrackingMacroContext(options2 === null || options2 === void 0 ? void 0 : options2.errorCode);
843
+ var macroContext = buildTrackingMacroContext(options2);
752
844
  urls.forEach(function(url) {
753
845
  try {
754
846
  var trackingUrl = substituteVastTrackingMacros(url, macroContext);
@@ -859,8 +951,8 @@ function createHlsAdPlayer(contentVideo, options) {
859
951
  var url = (mediaFile.url.toLowerCase().split("?")[0] || "").trim();
860
952
  return type.startsWith("audio/") || url.endsWith(".mp3") || url.endsWith(".aac") || url.endsWith(".m4a") || url.endsWith(".ogg") || url.endsWith(".oga") || url.endsWith(".opus") || url.endsWith(".wav") || url.endsWith(".weba");
861
953
  }
862
- function collectVideoMediaFiles(scope, verbose) {
863
- var mediaFileElements = scope.querySelectorAll("MediaFile");
954
+ function collectVideoMediaFiles(linear, verbose) {
955
+ var mediaFileElements = linear.querySelectorAll(":scope > MediaFiles > MediaFile");
864
956
  var mediaFiles = [];
865
957
  if (verbose) {
866
958
  console.log("[HlsAdPlayer] Found ".concat(mediaFileElements.length, " MediaFile element(s) in VAST XML"));
@@ -880,6 +972,13 @@ function createHlsAdPlayer(contentVideo, options) {
880
972
  }
881
973
  return;
882
974
  }
975
+ var apiFramework = (mf.getAttribute("apiFramework") || "").toUpperCase();
976
+ if (apiFramework === "VPAID") {
977
+ if (verbose) {
978
+ console.log("[HlsAdPlayer] MediaFile ".concat(index, " ignored (VPAID creatives are not supported)"));
979
+ }
980
+ return;
981
+ }
883
982
  var bitrateAttr = mf.getAttribute("bitrate");
884
983
  var bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
885
984
  var mediaFile = {
@@ -910,114 +1009,144 @@ function createHlsAdPlayer(contentVideo, options) {
910
1009
  return mediaFiles;
911
1010
  }
912
1011
  function createEmptyTrackingUrls() {
913
- return {
1012
+ var urls = {
914
1013
  impression: [],
915
- start: [],
916
- firstQuartile: [],
917
- midpoint: [],
918
- thirdQuartile: [],
919
- complete: [],
920
- mute: [],
921
- unmute: [],
922
- pause: [],
923
- resume: [],
924
- fullscreen: [],
925
- exitFullscreen: [],
926
- skip: [],
927
- error: []
1014
+ clickTracking: [],
1015
+ error: [],
1016
+ viewable: [],
1017
+ notViewable: [],
1018
+ viewUndetermined: [],
1019
+ verificationNotExecuted: [],
1020
+ progress: []
928
1021
  };
1022
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1023
+ try {
1024
+ for(var _iterator = LINEAR_TRACKING_EVENTS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1025
+ var event = _step.value;
1026
+ urls[event] = [];
1027
+ }
1028
+ } catch (err) {
1029
+ _didIteratorError = true;
1030
+ _iteratorError = err;
1031
+ } finally{
1032
+ try {
1033
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1034
+ _iterator.return();
1035
+ }
1036
+ } finally{
1037
+ if (_didIteratorError) {
1038
+ throw _iteratorError;
1039
+ }
1040
+ }
1041
+ }
1042
+ return urls;
929
1043
  }
930
- function extractTrackingUrls(scope) {
931
- var trackingUrls = createEmptyTrackingUrls();
932
- scope.querySelectorAll("Impression").forEach(function(el) {
933
- var _el_textContent;
934
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
935
- if (url) trackingUrls.impression.push(url);
1044
+ function pushUrls(target, elements) {
1045
+ elements.forEach(function(el) {
1046
+ var url = textOf(el);
1047
+ if (url) target.push(url);
936
1048
  });
937
- scope.querySelectorAll("Tracking").forEach(function(el) {
938
- var _el_textContent;
1049
+ }
1050
+ function collectLinearTracking(linear, into) {
1051
+ linear.querySelectorAll(":scope > TrackingEvents > Tracking").forEach(function(el) {
939
1052
  var event = el.getAttribute("event");
940
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
941
- if (event && url) {
942
- var eventKey = event;
943
- if (trackingUrls[eventKey]) {
944
- trackingUrls[eventKey].push(url);
945
- }
1053
+ var url = textOf(el);
1054
+ if (!event || !url) return;
1055
+ if (event === "progress") {
1056
+ var offset = parseProgressOffset(el.getAttribute("offset"));
1057
+ if (offset) into.progress.push(_object_spread({
1058
+ url: url
1059
+ }, offset));
1060
+ return;
1061
+ }
1062
+ if (LINEAR_TRACKING_EVENTS.indexOf(event) !== -1) {
1063
+ into[event].push(url);
946
1064
  }
947
1065
  });
948
- scope.querySelectorAll("Error").forEach(function(el) {
949
- var _el_textContent;
950
- var url = (_el_textContent = el.textContent) === null || _el_textContent === void 0 ? void 0 : _el_textContent.trim();
951
- if (url) trackingUrls.error.push(url);
1066
+ pushUrls(into.clickTracking, linear.querySelectorAll(":scope > VideoClicks > ClickTracking"));
1067
+ }
1068
+ function collectAdLevelTracking(adBody, into) {
1069
+ pushUrls(into.impression, adBody.querySelectorAll(":scope > Impression"));
1070
+ pushUrls(into.error, adBody.querySelectorAll(":scope > Error"));
1071
+ pushUrls(into.viewable, adBody.querySelectorAll(":scope > ViewableImpression > Viewable"));
1072
+ pushUrls(into.notViewable, adBody.querySelectorAll(":scope > ViewableImpression > NotViewable"));
1073
+ pushUrls(into.viewUndetermined, adBody.querySelectorAll(":scope > ViewableImpression > ViewUndetermined"));
1074
+ adBody.querySelectorAll(':scope > AdVerifications > Verification, :scope > Extensions > Extension[type="AdVerifications"] > AdVerifications > Verification').forEach(function(verification) {
1075
+ pushUrls(into.verificationNotExecuted, verification.querySelectorAll(':scope > TrackingEvents > Tracking[event="verificationNotExecuted"]'));
952
1076
  });
953
- return trackingUrls;
954
1077
  }
955
1078
  function mergeTrackingUrls(target, source) {
956
- Object.keys(target).forEach(function(key) {
957
- if (source[key] && source[key].length > 0) {
958
- target[key] = target[key].concat(source[key]);
1079
+ var targetLists = target;
1080
+ var sourceLists = source;
1081
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1082
+ try {
1083
+ for(var _iterator = Object.keys(targetLists)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1084
+ var key = _step.value;
1085
+ var incoming = sourceLists[key];
1086
+ if (incoming && incoming.length > 0) {
1087
+ targetLists[key] = targetLists[key].concat(incoming);
1088
+ }
959
1089
  }
960
- });
1090
+ } catch (err) {
1091
+ _didIteratorError = true;
1092
+ _iteratorError = err;
1093
+ } finally{
1094
+ try {
1095
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1096
+ _iterator.return();
1097
+ }
1098
+ } finally{
1099
+ if (_didIteratorError) {
1100
+ throw _iteratorError;
1101
+ }
1102
+ }
1103
+ }
961
1104
  return target;
962
1105
  }
1106
+ function parseXml(xmlString) {
1107
+ var xmlDoc = new DOMParser().parseFromString(xmlString, "text/xml");
1108
+ var parserError = xmlDoc.querySelector("parsererror");
1109
+ if (parserError) {
1110
+ console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
1111
+ return null;
1112
+ }
1113
+ return xmlDoc;
1114
+ }
1115
+ function getAdSequence(adElement) {
1116
+ var sequence = parseInt(adElement.getAttribute("sequence") || "", 10);
1117
+ return Number.isFinite(sequence) ? sequence : void 0;
1118
+ }
1119
+ function emptyVastResult(root) {
1120
+ var errorUrls = [];
1121
+ pushUrls(errorUrls, root.querySelectorAll(":scope > Error"));
1122
+ return {
1123
+ type: "empty",
1124
+ errorUrls: errorUrls,
1125
+ errorCode: VAST_ERROR_WRAPPER_NO_ADS
1126
+ };
1127
+ }
963
1128
  function parseVastXml(xmlString) {
964
1129
  try {
965
- var _xmlDoc_querySelector, _xmlDoc_querySelector_textContent, _xmlDoc_querySelector1, _xmlDoc_querySelector_textContent1, _xmlDoc_querySelector2, _xmlDoc_querySelector3;
966
- var parser = new DOMParser();
967
- var xmlDoc = parser.parseFromString(xmlString, "text/xml");
968
- var parserError = xmlDoc.querySelector("parsererror");
969
- if (parserError) {
970
- console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
971
- return {
972
- type: "empty"
973
- };
974
- }
975
- var adElement = xmlDoc.querySelector("Ad");
1130
+ var _adElements_find;
1131
+ var xmlDoc = parseXml(xmlString);
1132
+ if (!xmlDoc) return {
1133
+ type: "empty"
1134
+ };
1135
+ var root = xmlDoc.documentElement;
1136
+ var adElements = Array.from(root.querySelectorAll(":scope > Ad"));
1137
+ var adElement = (_adElements_find = adElements.find(function(el) {
1138
+ return getAdSequence(el) === void 0;
1139
+ })) !== null && _adElements_find !== void 0 ? _adElements_find : adElements[0];
976
1140
  if (!adElement) {
977
- console.warn("[HlsAdPlayer] No Ad element found in VAST XML");
978
- return {
979
- type: "empty"
980
- };
1141
+ var _root_getAttribute;
1142
+ console.warn("[HlsAdPlayer] No Ad element found in VAST ".concat((_root_getAttribute = root.getAttribute("version")) !== null && _root_getAttribute !== void 0 ? _root_getAttribute : "", " response"));
1143
+ return emptyVastResult(root);
981
1144
  }
982
- var adId = adElement.getAttribute("id") || "unknown";
983
- var title = ((_xmlDoc_querySelector = xmlDoc.querySelector("AdTitle")) === null || _xmlDoc_querySelector === void 0 ? void 0 : _xmlDoc_querySelector.textContent) || "Ad";
984
- var clickThrough = (_xmlDoc_querySelector1 = xmlDoc.querySelector("ClickThrough")) === null || _xmlDoc_querySelector1 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent = _xmlDoc_querySelector1.textContent) === null || _xmlDoc_querySelector_textContent === void 0 ? void 0 : _xmlDoc_querySelector_textContent.trim();
985
- var wrapperUri = (_xmlDoc_querySelector2 = xmlDoc.querySelector("VASTAdTagURI")) === null || _xmlDoc_querySelector2 === void 0 ? void 0 : (_xmlDoc_querySelector_textContent1 = _xmlDoc_querySelector2.textContent) === null || _xmlDoc_querySelector_textContent1 === void 0 ? void 0 : _xmlDoc_querySelector_textContent1.trim();
986
- if (wrapperUri) {
987
- console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(wrapperUri));
988
- return {
989
- type: "wrapper",
990
- vastAdTagUri: wrapperUri,
991
- trackingUrls: extractTrackingUrls(xmlDoc),
992
- clickThrough: clickThrough
993
- };
994
- }
995
- var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
996
- var durationText = ((_xmlDoc_querySelector3 = xmlDoc.querySelector("Duration")) === null || _xmlDoc_querySelector3 === void 0 ? void 0 : _xmlDoc_querySelector3.textContent) || "00:00:30";
997
- var durationParts = durationText.split(":");
998
- var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
999
- var mediaFiles = collectVideoMediaFiles(xmlDoc, true);
1000
- if (mediaFiles.length === 0) {
1001
- if (isNoAdAvailable) {
1002
- console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
1003
- } else {
1004
- console.warn("[HlsAdPlayer] No supported media files found in VAST XML");
1005
- }
1006
- return {
1007
- type: "empty"
1008
- };
1145
+ var parsed = parseAdElement(adElement, true);
1146
+ if (parsed.type === "wrapper") {
1147
+ console.log("[HlsAdPlayer] VAST wrapper detected, following VASTAdTagURI: ".concat(parsed.vastAdTagUri));
1009
1148
  }
1010
- return {
1011
- type: "inline",
1012
- ad: {
1013
- id: adId,
1014
- title: title,
1015
- duration: duration,
1016
- mediaFiles: mediaFiles,
1017
- trackingUrls: extractTrackingUrls(xmlDoc),
1018
- clickThrough: clickThrough
1019
- }
1020
- };
1149
+ return parsed;
1021
1150
  } catch (error) {
1022
1151
  console.error("[HlsAdPlayer] Error parsing VAST XML:", error);
1023
1152
  return {
@@ -1026,48 +1155,101 @@ function createHlsAdPlayer(contentVideo, options) {
1026
1155
  }
1027
1156
  }
1028
1157
  function parseAdElement(adElement) {
1158
+ var verbose = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : false;
1029
1159
  try {
1030
- var _adElement_querySelector, _adElement_querySelector_textContent, _adElement_querySelector1, _adElement_querySelector_textContent1, _adElement_querySelector2, _adElement_querySelector3;
1031
- var adId = adElement.getAttribute("id") || "unknown";
1032
- var title = ((_adElement_querySelector = adElement.querySelector("AdTitle")) === null || _adElement_querySelector === void 0 ? void 0 : _adElement_querySelector.textContent) || "Ad";
1033
- var clickThrough = (_adElement_querySelector1 = adElement.querySelector("ClickThrough")) === null || _adElement_querySelector1 === void 0 ? void 0 : (_adElement_querySelector_textContent = _adElement_querySelector1.textContent) === null || _adElement_querySelector_textContent === void 0 ? void 0 : _adElement_querySelector_textContent.trim();
1034
- var wrapperUri = (_adElement_querySelector2 = adElement.querySelector("VASTAdTagURI")) === null || _adElement_querySelector2 === void 0 ? void 0 : (_adElement_querySelector_textContent1 = _adElement_querySelector2.textContent) === null || _adElement_querySelector_textContent1 === void 0 ? void 0 : _adElement_querySelector_textContent1.trim();
1035
- if (wrapperUri) {
1160
+ var _parseVastTime;
1161
+ var wrapper = adElement.querySelector(":scope > Wrapper");
1162
+ if (wrapper) {
1163
+ var vastAdTagUri = textOf(wrapper.querySelector(":scope > VASTAdTagURI"));
1164
+ if (!vastAdTagUri) {
1165
+ console.warn("[HlsAdPlayer] <Wrapper> has no VASTAdTagURI");
1166
+ return {
1167
+ type: "empty"
1168
+ };
1169
+ }
1170
+ var trackingUrls2 = createEmptyTrackingUrls();
1171
+ collectAdLevelTracking(wrapper, trackingUrls2);
1172
+ wrapper.querySelectorAll(":scope > Creatives > Creative > Linear").forEach(function(linear2) {
1173
+ return collectLinearTracking(linear2, trackingUrls2);
1174
+ });
1036
1175
  return {
1037
1176
  type: "wrapper",
1038
- vastAdTagUri: wrapperUri,
1039
- trackingUrls: extractTrackingUrls(adElement),
1040
- clickThrough: clickThrough
1177
+ vastAdTagUri: vastAdTagUri,
1178
+ trackingUrls: trackingUrls2,
1179
+ rules: {
1180
+ followAdditionalWrappers: wrapper.getAttribute("followAdditionalWrappers") !== "false"
1181
+ }
1041
1182
  };
1042
1183
  }
1043
- var isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
1044
- var durationText = ((_adElement_querySelector3 = adElement.querySelector("Duration")) === null || _adElement_querySelector3 === void 0 ? void 0 : _adElement_querySelector3.textContent) || "00:00:30";
1045
- var durationParts = durationText.split(":");
1046
- var duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
1047
- var mediaFiles = collectVideoMediaFiles(adElement, false);
1048
- if (mediaFiles.length === 0) {
1049
- if (isNoAdAvailable) {
1050
- console.warn("[HlsAdPlayer] Pod <Ad> indicates no ad available");
1051
- } else {
1052
- console.warn("[HlsAdPlayer] No supported media files in pod <Ad>");
1053
- }
1184
+ var inLine = adElement.querySelector(":scope > InLine");
1185
+ if (!inLine) {
1186
+ console.warn("[HlsAdPlayer] <Ad> has neither <InLine> nor <Wrapper>");
1054
1187
  return {
1055
1188
  type: "empty"
1056
1189
  };
1057
1190
  }
1191
+ var errorUrls = [];
1192
+ pushUrls(errorUrls, inLine.querySelectorAll(":scope > Error"));
1193
+ if (adElement.getAttribute("conditionalAd") === "true") {
1194
+ console.warn("[HlsAdPlayer] Skipping conditional <Ad> (VPAID-only)");
1195
+ return {
1196
+ type: "empty",
1197
+ errorUrls: errorUrls,
1198
+ errorCode: VAST_ERROR_NO_SUPPORTED_MEDIA
1199
+ };
1200
+ }
1201
+ var linear;
1202
+ var mediaFiles = [];
1203
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1204
+ try {
1205
+ for(var _iterator = Array.from(inLine.querySelectorAll(":scope > Creatives > Creative > Linear"))[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1206
+ var candidate = _step.value;
1207
+ var files = collectVideoMediaFiles(candidate, verbose);
1208
+ if (files.length > 0) {
1209
+ linear = candidate;
1210
+ mediaFiles = files;
1211
+ break;
1212
+ }
1213
+ }
1214
+ } catch (err) {
1215
+ _didIteratorError = true;
1216
+ _iteratorError = err;
1217
+ } finally{
1218
+ try {
1219
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1220
+ _iterator.return();
1221
+ }
1222
+ } finally{
1223
+ if (_didIteratorError) {
1224
+ throw _iteratorError;
1225
+ }
1226
+ }
1227
+ }
1228
+ if (!linear) {
1229
+ console.warn("[HlsAdPlayer] No supported linear media files in <Ad>");
1230
+ return {
1231
+ type: "empty",
1232
+ errorUrls: errorUrls,
1233
+ errorCode: VAST_ERROR_NO_SUPPORTED_MEDIA
1234
+ };
1235
+ }
1236
+ var trackingUrls = createEmptyTrackingUrls();
1237
+ collectAdLevelTracking(inLine, trackingUrls);
1238
+ collectLinearTracking(linear, trackingUrls);
1058
1239
  return {
1059
1240
  type: "inline",
1060
1241
  ad: {
1061
- id: adId,
1062
- title: title,
1063
- duration: duration,
1242
+ id: adElement.getAttribute("id") || "unknown",
1243
+ title: textOf(inLine.querySelector(":scope > AdTitle")) || "Ad",
1244
+ duration: (_parseVastTime = parseVastTime(textOf(linear.querySelector(":scope > Duration")))) !== null && _parseVastTime !== void 0 ? _parseVastTime : 30,
1064
1245
  mediaFiles: mediaFiles,
1065
- trackingUrls: extractTrackingUrls(adElement),
1066
- clickThrough: clickThrough
1246
+ trackingUrls: trackingUrls,
1247
+ clickThrough: textOf(linear.querySelector(":scope > VideoClicks > ClickThrough")),
1248
+ adServingId: textOf(inLine.querySelector(":scope > AdServingId"))
1067
1249
  }
1068
1250
  };
1069
1251
  } catch (error) {
1070
- console.error("[HlsAdPlayer] Error parsing pod <Ad> element:", error);
1252
+ console.error("[HlsAdPlayer] Error parsing <Ad> element:", error);
1071
1253
  return {
1072
1254
  type: "empty"
1073
1255
  };
@@ -1146,30 +1328,63 @@ function createHlsAdPlayer(contentVideo, options) {
1146
1328
  }
1147
1329
  function fetchAndParseVastAd(_0) {
1148
1330
  return _async_to_generator(function(vastTagUrl) {
1149
- var depth, accumulatedTracking, vastXml, parsed;
1331
+ var depth, accumulatedTracking, rules, vastXml, error, parsed, _parsed_errorUrls, _parsed_errorCode;
1150
1332
  var _arguments = arguments;
1151
1333
  return _ts_generator(this, function(_state) {
1152
1334
  switch(_state.label){
1153
1335
  case 0:
1154
- depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls();
1336
+ depth = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : 0, accumulatedTracking = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : createEmptyTrackingUrls(), rules = _arguments.length > 3 && _arguments[3] !== void 0 ? _arguments[3] : {
1337
+ followAdditionalWrappers: true
1338
+ };
1339
+ _state.label = 1;
1340
+ case 1:
1341
+ _state.trys.push([
1342
+ 1,
1343
+ 3,
1344
+ ,
1345
+ 4
1346
+ ]);
1155
1347
  return [
1156
1348
  4,
1157
1349
  fetchVastXml(vastTagUrl, depth === 0 ? "include" : "omit")
1158
1350
  ];
1159
- case 1:
1351
+ case 2:
1160
1352
  vastXml = _state.sent();
1353
+ return [
1354
+ 3,
1355
+ 4
1356
+ ];
1357
+ case 3:
1358
+ error = _state.sent();
1359
+ if (depth === 0) throw error;
1360
+ console.warn("[HlsAdPlayer] Wrapped VAST request failed:", error);
1361
+ fireTrackingPixels(accumulatedTracking.error, {
1362
+ errorCode: VAST_ERROR_WRAPPER_TIMEOUT
1363
+ });
1364
+ return [
1365
+ 2,
1366
+ null
1367
+ ];
1368
+ case 4:
1161
1369
  console.log("[HlsAdPlayer] VAST XML received");
1162
1370
  console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
1163
1371
  parsed = parseVastXml(vastXml);
1164
1372
  if (parsed.type === "empty") {
1373
+ ;
1374
+ fireTrackingPixels(((_parsed_errorUrls = parsed.errorUrls) !== null && _parsed_errorUrls !== void 0 ? _parsed_errorUrls : []).concat(accumulatedTracking.error), {
1375
+ errorCode: (_parsed_errorCode = parsed.errorCode) !== null && _parsed_errorCode !== void 0 ? _parsed_errorCode : VAST_ERROR_WRAPPER_NO_ADS
1376
+ });
1165
1377
  return [
1166
1378
  2,
1167
1379
  null
1168
1380
  ];
1169
1381
  }
1170
1382
  if (parsed.type === "wrapper") {
1171
- if (depth >= MAX_VAST_WRAPPER_DEPTH) {
1172
- console.warn("[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain"));
1383
+ if (depth >= MAX_VAST_WRAPPER_DEPTH || !rules.followAdditionalWrappers) {
1384
+ console.warn(rules.followAdditionalWrappers ? "[HlsAdPlayer] VAST wrapper depth limit (".concat(MAX_VAST_WRAPPER_DEPTH, ") reached, aborting redirect chain") : '[HlsAdPlayer] Parent wrapper set followAdditionalWrappers="false"; rejecting nested wrapper');
1385
+ fireTrackingPixels(accumulatedTracking.error.concat(parsed.trackingUrls.error), {
1386
+ errorCode: VAST_ERROR_WRAPPER_LIMIT
1387
+ });
1173
1388
  return [
1174
1389
  2,
1175
1390
  null
@@ -1178,7 +1393,7 @@ function createHlsAdPlayer(contentVideo, options) {
1178
1393
  mergeTrackingUrls(accumulatedTracking, parsed.trackingUrls);
1179
1394
  return [
1180
1395
  2,
1181
- fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking)
1396
+ fetchAndParseVastAd(parsed.vastAdTagUri, depth + 1, accumulatedTracking, parsed.rules)
1182
1397
  ];
1183
1398
  }
1184
1399
  mergeTrackingUrls(parsed.ad.trackingUrls, accumulatedTracking);
@@ -1192,7 +1407,7 @@ function createHlsAdPlayer(contentVideo, options) {
1192
1407
  }
1193
1408
  function fetchAndParsePod(vastTagUrl) {
1194
1409
  return _async_to_generator(function() {
1195
- var vastXml, trimmedXml, parser, xmlDoc, adElements, ads, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, adElement, parsed, resolved, error, err;
1410
+ var _root_getAttribute, vastXml, trimmedXml, xmlDoc, root, adElements, _root_getAttribute1, _empty_errorUrls, empty, _empty_errorCode, resolveAd, podElements, buffet, ads, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, adElement, ad, err, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, adElement1, ad1, err;
1196
1411
  return _ts_generator(this, function(_state) {
1197
1412
  switch(_state.label){
1198
1413
  case 0:
@@ -1211,125 +1426,212 @@ function createHlsAdPlayer(contentVideo, options) {
1211
1426
  []
1212
1427
  ];
1213
1428
  }
1214
- parser = new DOMParser();
1215
- xmlDoc = parser.parseFromString(vastXml, "text/xml");
1216
- if (xmlDoc.querySelector("parsererror")) {
1217
- console.error("[HlsAdPlayer] Pod VAST XML parsing error (malformed). Content (first 2000 chars):", vastXml.substring(0, 2e3));
1429
+ xmlDoc = parseXml(vastXml);
1430
+ if (!xmlDoc) {
1431
+ console.error("[HlsAdPlayer] Pod VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
1218
1432
  return [
1219
1433
  2,
1220
1434
  []
1221
1435
  ];
1222
1436
  }
1223
- adElements = Array.from(xmlDoc.querySelectorAll("Ad"));
1437
+ root = xmlDoc.documentElement;
1438
+ adElements = Array.from(root.querySelectorAll(":scope > Ad"));
1224
1439
  if (adElements.length === 0) {
1225
- console.warn("[HlsAdPlayer] No <Ad> elements found in pod VAST response (no fill). Content (first 2000 chars):", vastXml.substring(0, 2e3));
1440
+ ;
1441
+ ;
1442
+ console.warn("[HlsAdPlayer] No <Ad> elements in VAST ".concat((_root_getAttribute1 = root.getAttribute("version")) !== null && _root_getAttribute1 !== void 0 ? _root_getAttribute1 : "", " pod response (no fill)"));
1443
+ empty = emptyVastResult(root);
1444
+ if (empty.type === "empty" && ((_empty_errorUrls = empty.errorUrls) === null || _empty_errorUrls === void 0 ? void 0 : _empty_errorUrls.length)) {
1445
+ ;
1446
+ fireTrackingPixels(empty.errorUrls, {
1447
+ errorCode: (_empty_errorCode = empty.errorCode) !== null && _empty_errorCode !== void 0 ? _empty_errorCode : VAST_ERROR_WRAPPER_NO_ADS
1448
+ });
1449
+ }
1226
1450
  return [
1227
1451
  2,
1228
1452
  []
1229
1453
  ];
1230
1454
  }
1231
- adElements.sort(function(a, b) {
1232
- var aSeq = parseInt(a.getAttribute("sequence") || "", 10);
1233
- var bSeq = parseInt(b.getAttribute("sequence") || "", 10);
1234
- var aVal = Number.isFinite(aSeq) ? aSeq : Number.MAX_SAFE_INTEGER;
1235
- var bVal = Number.isFinite(bSeq) ? bSeq : Number.MAX_SAFE_INTEGER;
1236
- return aVal - bVal;
1455
+ resolveAd = function resolveAd(adElement) {
1456
+ return _async_to_generator(function() {
1457
+ var _parsed_errorUrls, parsed, _parsed_errorCode;
1458
+ return _ts_generator(this, function(_state) {
1459
+ parsed = parseAdElement(adElement);
1460
+ if (parsed.type === "inline") return [
1461
+ 2,
1462
+ parsed.ad
1463
+ ];
1464
+ if (parsed.type === "wrapper") {
1465
+ return [
1466
+ 2,
1467
+ fetchAndParseVastAd(parsed.vastAdTagUri, 1, parsed.trackingUrls, parsed.rules)
1468
+ ];
1469
+ }
1470
+ if ((_parsed_errorUrls = parsed.errorUrls) === null || _parsed_errorUrls === void 0 ? void 0 : _parsed_errorUrls.length) {
1471
+ ;
1472
+ fireTrackingPixels(parsed.errorUrls, {
1473
+ errorCode: (_parsed_errorCode = parsed.errorCode) !== null && _parsed_errorCode !== void 0 ? _parsed_errorCode : VAST_ERROR_NO_SUPPORTED_MEDIA
1474
+ });
1475
+ }
1476
+ return [
1477
+ 2,
1478
+ null
1479
+ ];
1480
+ });
1481
+ })();
1482
+ };
1483
+ podElements = adElements.filter(function(el) {
1484
+ return getAdSequence(el) !== void 0;
1485
+ }).sort(function(a, b) {
1486
+ return getAdSequence(a) - getAdSequence(b);
1487
+ });
1488
+ buffet = adElements.filter(function(el) {
1489
+ return getAdSequence(el) === void 0;
1237
1490
  });
1238
1491
  ads = [];
1492
+ if (!(podElements.length === 0)) return [
1493
+ 3,
1494
+ 10
1495
+ ];
1239
1496
  _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1240
1497
  _state.label = 2;
1241
1498
  case 2:
1242
1499
  _state.trys.push([
1243
1500
  2,
1244
- 10,
1245
- 11,
1246
- 12
1501
+ 7,
1502
+ 8,
1503
+ 9
1247
1504
  ]);
1248
- _iterator = adElements[Symbol.iterator]();
1505
+ _iterator = buffet[Symbol.iterator]();
1249
1506
  _state.label = 3;
1250
1507
  case 3:
1251
1508
  if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
1252
1509
  3,
1253
- 9
1510
+ 6
1254
1511
  ];
1255
1512
  adElement = _step.value;
1256
- parsed = parseAdElement(adElement);
1257
- if (!(parsed.type === "inline")) return [
1258
- 3,
1259
- 4
1260
- ];
1261
- ads.push(parsed.ad);
1262
1513
  return [
1263
- 3,
1264
- 8
1514
+ 4,
1515
+ resolveAd(adElement)
1265
1516
  ];
1266
1517
  case 4:
1267
- if (!(parsed.type === "wrapper")) return [
1268
- 3,
1269
- 8
1270
- ];
1518
+ ad = _state.sent();
1519
+ if (ad) ads.push(ad);
1271
1520
  _state.label = 5;
1272
1521
  case 5:
1273
- _state.trys.push([
1274
- 5,
1275
- 7,
1276
- ,
1277
- 8
1278
- ]);
1522
+ _iteratorNormalCompletion = true;
1279
1523
  return [
1280
- 4,
1281
- fetchAndParseVastAd(parsed.vastAdTagUri, 1, parsed.trackingUrls)
1524
+ 3,
1525
+ 3
1282
1526
  ];
1283
1527
  case 6:
1284
- resolved = _state.sent();
1285
- if (resolved) {
1286
- ads.push(resolved);
1287
- }
1288
1528
  return [
1289
1529
  3,
1290
- 8
1530
+ 9
1291
1531
  ];
1292
1532
  case 7:
1293
- error = _state.sent();
1294
- console.warn("[HlsAdPlayer] Failed to resolve wrapper <Ad> in pod:", error);
1533
+ err = _state.sent();
1534
+ _didIteratorError = true;
1535
+ _iteratorError = err;
1295
1536
  return [
1296
1537
  3,
1297
- 8
1538
+ 9
1298
1539
  ];
1299
1540
  case 8:
1300
- _iteratorNormalCompletion = true;
1541
+ try {
1542
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1543
+ _iterator.return();
1544
+ }
1545
+ } finally{
1546
+ if (_didIteratorError) {
1547
+ throw _iteratorError;
1548
+ }
1549
+ }
1301
1550
  return [
1302
- 3,
1303
- 3
1551
+ 7
1304
1552
  ];
1305
1553
  case 9:
1306
1554
  return [
1307
1555
  3,
1308
- 12
1556
+ 21
1309
1557
  ];
1310
1558
  case 10:
1311
- err = _state.sent();
1312
- _didIteratorError = true;
1313
- _iteratorError = err;
1559
+ _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
1560
+ _state.label = 11;
1561
+ case 11:
1562
+ _state.trys.push([
1563
+ 11,
1564
+ 19,
1565
+ 20,
1566
+ 21
1567
+ ]);
1568
+ _iterator1 = podElements[Symbol.iterator]();
1569
+ _state.label = 12;
1570
+ case 12:
1571
+ if (!!(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done)) return [
1572
+ 3,
1573
+ 18
1574
+ ];
1575
+ adElement1 = _step1.value;
1576
+ return [
1577
+ 4,
1578
+ resolveAd(adElement1)
1579
+ ];
1580
+ case 13:
1581
+ ad1 = _state.sent();
1582
+ _state.label = 14;
1583
+ case 14:
1584
+ if (!(!ad1 && buffet.length > 0)) return [
1585
+ 3,
1586
+ 16
1587
+ ];
1588
+ return [
1589
+ 4,
1590
+ resolveAd(buffet.shift())
1591
+ ];
1592
+ case 15:
1593
+ ad1 = _state.sent();
1594
+ return [
1595
+ 3,
1596
+ 14
1597
+ ];
1598
+ case 16:
1599
+ if (ad1) ads.push(ad1);
1600
+ _state.label = 17;
1601
+ case 17:
1602
+ _iteratorNormalCompletion1 = true;
1314
1603
  return [
1315
1604
  3,
1316
1605
  12
1317
1606
  ];
1318
- case 11:
1607
+ case 18:
1608
+ return [
1609
+ 3,
1610
+ 21
1611
+ ];
1612
+ case 19:
1613
+ err = _state.sent();
1614
+ _didIteratorError1 = true;
1615
+ _iteratorError1 = err;
1616
+ return [
1617
+ 3,
1618
+ 21
1619
+ ];
1620
+ case 20:
1319
1621
  try {
1320
- if (!_iteratorNormalCompletion && _iterator.return != null) {
1321
- _iterator.return();
1622
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
1623
+ _iterator1.return();
1322
1624
  }
1323
1625
  } finally{
1324
- if (_didIteratorError) {
1325
- throw _iteratorError;
1626
+ if (_didIteratorError1) {
1627
+ throw _iteratorError1;
1326
1628
  }
1327
1629
  }
1328
1630
  return [
1329
1631
  7
1330
1632
  ];
1331
- case 12:
1332
- console.log("[HlsAdPlayer] Parsed ".concat(ads.length, " ad(s) from pod VAST response"));
1633
+ case 21:
1634
+ console.log("[HlsAdPlayer] Parsed ".concat(ads.length, " ad(s) from VAST ").concat((_root_getAttribute = root.getAttribute("version")) !== null && _root_getAttribute !== void 0 ? _root_getAttribute : "", " pod response"));
1333
1635
  return [
1334
1636
  2,
1335
1637
  ads
@@ -1359,7 +1661,40 @@ function createHlsAdPlayer(contentVideo, options) {
1359
1661
  var onTimeUpdate = function onTimeUpdate() {
1360
1662
  if (!currentAd || !adVideoElement) return;
1361
1663
  noteAdProgress();
1362
- var progress = adVideoElement.currentTime / currentAd.duration;
1664
+ sampleViewability();
1665
+ var currentTime = adVideoElement.currentTime;
1666
+ if (trackingFired.start) {
1667
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1668
+ try {
1669
+ for(var _iterator = currentAd.trackingUrls.progress[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1670
+ var event = _step.value;
1671
+ var _event_offsetSeconds, _event_offsetPercent;
1672
+ if (trackingFired.progressFired.has(event)) continue;
1673
+ var threshold = (_event_offsetSeconds = event.offsetSeconds) !== null && _event_offsetSeconds !== void 0 ? _event_offsetSeconds : ((_event_offsetPercent = event.offsetPercent) !== null && _event_offsetPercent !== void 0 ? _event_offsetPercent : 0) / 100 * currentAd.duration;
1674
+ if (currentTime >= threshold) {
1675
+ trackingFired.progressFired.add(event);
1676
+ fireTrackingPixels([
1677
+ event.url
1678
+ ]);
1679
+ }
1680
+ }
1681
+ } catch (err) {
1682
+ _didIteratorError = true;
1683
+ _iteratorError = err;
1684
+ } finally{
1685
+ try {
1686
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1687
+ _iterator.return();
1688
+ }
1689
+ } finally{
1690
+ if (_didIteratorError) {
1691
+ throw _iteratorError;
1692
+ }
1693
+ }
1694
+ }
1695
+ }
1696
+ if (!(currentAd.duration > 0)) return;
1697
+ var progress = currentTime / currentAd.duration;
1363
1698
  if (progress >= 0.25 && !trackingFired.firstQuartile) {
1364
1699
  trackingFired.firstQuartile = true;
1365
1700
  fireTrackingPixels(currentAd.trackingUrls.firstQuartile);
@@ -1381,15 +1716,38 @@ function createHlsAdPlayer(contentVideo, options) {
1381
1716
  handleVideoDecodeFailure();
1382
1717
  }
1383
1718
  };
1719
+ var onCanPlay = function onCanPlay() {
1720
+ if (!currentAd || trackingFired.loaded) return;
1721
+ trackingFired.loaded = true;
1722
+ fireTrackingPixels(currentAd.trackingUrls.loaded);
1723
+ };
1384
1724
  var onPlaying = function onPlaying() {
1385
1725
  startStallWatchdog();
1386
- if (!currentAd || trackingFired.start) return;
1726
+ if (!currentAd || !adVideoElement) return;
1727
+ if (!trackingFired.impression) {
1728
+ trackingFired.impression = true;
1729
+ resolvedAds.add(currentAd);
1730
+ fireTrackingPixels(currentAd.trackingUrls.impression);
1731
+ fireTrackingPixels(currentAd.trackingUrls.creativeView);
1732
+ fireTrackingPixels(currentAd.trackingUrls.verificationNotExecuted, {
1733
+ reason: VERIFICATION_NOT_SUPPORTED_REASON
1734
+ });
1735
+ emit("ad_impression", {
1736
+ adId: currentAd.id,
1737
+ index: podIndex,
1738
+ total: podAds.length || 1
1739
+ });
1740
+ }
1741
+ if (trackingFired.start) return;
1387
1742
  trackingFired.start = true;
1743
+ trackingFired.lastMuted = adVideoElement.muted || adVideoElement.volume === 0;
1388
1744
  fireTrackingPixels(currentAd.trackingUrls.start);
1389
1745
  console.log("[HlsAdPlayer] Ad started playing");
1390
1746
  };
1391
1747
  var onEnded = function onEnded() {
1392
1748
  if (!currentAd || trackingFired.complete) return;
1749
+ sampleViewability();
1750
+ settleViewability();
1393
1751
  trackingFired.complete = true;
1394
1752
  fireTrackingPixels(currentAd.trackingUrls.complete);
1395
1753
  console.log("[HlsAdPlayer] Ad completed");
@@ -1401,11 +1759,7 @@ function createHlsAdPlayer(contentVideo, options) {
1401
1759
  var onError = function onError(e) {
1402
1760
  if (!adPlaying) return;
1403
1761
  console.error("[HlsAdPlayer] Ad video error:", e);
1404
- if (currentAd) {
1405
- fireTrackingPixels(currentAd.trackingUrls.error, {
1406
- errorCode: toVastMediaErrorCode(adVideoElement === null || adVideoElement === void 0 ? void 0 : adVideoElement.error)
1407
- });
1408
- }
1762
+ reportCurrentAdError(toVastMediaErrorCode(adVideoElement === null || adVideoElement === void 0 ? void 0 : adVideoElement.error));
1409
1763
  if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {
1410
1764
  return;
1411
1765
  }
@@ -1413,19 +1767,26 @@ function createHlsAdPlayer(contentVideo, options) {
1413
1767
  };
1414
1768
  var onVolumeChange = function onVolumeChange() {
1415
1769
  if (!currentAd || !adVideoElement) return;
1416
- if (adVideoElement.muted) {
1417
- fireTrackingPixels(currentAd.trackingUrls.mute);
1418
- } else {
1419
- fireTrackingPixels(currentAd.trackingUrls.unmute);
1770
+ var muted = adVideoElement.muted || adVideoElement.volume === 0;
1771
+ if (!trackingFired.start) {
1772
+ trackingFired.lastMuted = muted;
1773
+ return;
1420
1774
  }
1775
+ if (muted === trackingFired.lastMuted) return;
1776
+ trackingFired.lastMuted = muted;
1777
+ fireTrackingPixels(muted ? currentAd.trackingUrls.mute : currentAd.trackingUrls.unmute);
1778
+ };
1779
+ var isTrackablePlayback = function isTrackablePlayback() {
1780
+ return adPlaying && !!currentAd && !!adVideoElement && trackingFired.start && !trackingFired.complete && !adVideoElement.ended;
1421
1781
  };
1422
1782
  var onPause = function onPause() {
1423
- if (currentAd && adVideoElement && !adVideoElement.ended) {
1783
+ continuousVisibleS = 0;
1784
+ if (isTrackablePlayback()) {
1424
1785
  fireTrackingPixels(currentAd.trackingUrls.pause);
1425
1786
  }
1426
1787
  };
1427
1788
  var onPlay = function onPlay() {
1428
- if (currentAd && adVideoElement && adVideoElement.currentTime > 0) {
1789
+ if (isTrackablePlayback()) {
1429
1790
  fireTrackingPixels(currentAd.trackingUrls.resume);
1430
1791
  }
1431
1792
  };
@@ -1438,6 +1799,10 @@ function createHlsAdPlayer(contentVideo, options) {
1438
1799
  type: "loadedmetadata",
1439
1800
  handler: onLoadedMetadata
1440
1801
  },
1802
+ {
1803
+ type: "canplay",
1804
+ handler: onCanPlay
1805
+ },
1441
1806
  {
1442
1807
  type: "playing",
1443
1808
  handler: onPlaying
@@ -1509,6 +1874,229 @@ function createHlsAdPlayer(contentVideo, options) {
1509
1874
  }
1510
1875
  adEventHandlers = [];
1511
1876
  }
1877
+ function handleAdClick() {
1878
+ if (!adPlaying || !currentAd) return;
1879
+ fireTrackingPixels(currentAd.trackingUrls.clickTracking);
1880
+ emit("ad_click", {
1881
+ adId: currentAd.id,
1882
+ clickThrough: currentAd.clickThrough
1883
+ });
1884
+ if (currentAd.clickThrough) {
1885
+ try {
1886
+ window.open(currentAd.clickThrough, "_blank", "noopener");
1887
+ } catch (error) {
1888
+ console.warn("[HlsAdPlayer] Failed to open ClickThrough URL:", error);
1889
+ }
1890
+ }
1891
+ }
1892
+ function reportCurrentAdError(errorCode) {
1893
+ if (!currentAd) return;
1894
+ resolvedAds.add(currentAd);
1895
+ fireTrackingPixels(currentAd.trackingUrls.error, {
1896
+ errorCode: errorCode
1897
+ });
1898
+ }
1899
+ function fireNotUsedForUnplayedAds() {
1900
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1901
+ try {
1902
+ for(var _iterator = podAds[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1903
+ var ad = _step.value;
1904
+ if (resolvedAds.has(ad)) continue;
1905
+ resolvedAds.add(ad);
1906
+ fireTrackingPixels(ad.trackingUrls.notUsed, {
1907
+ ad: ad
1908
+ });
1909
+ }
1910
+ } catch (err) {
1911
+ _didIteratorError = true;
1912
+ _iteratorError = err;
1913
+ } finally{
1914
+ try {
1915
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1916
+ _iterator.return();
1917
+ }
1918
+ } finally{
1919
+ if (_didIteratorError) {
1920
+ throw _iteratorError;
1921
+ }
1922
+ }
1923
+ }
1924
+ }
1925
+ function sampleViewability() {
1926
+ if (!currentAd || !adVideoElement || !viewObserver || !trackingFired.impression || trackingFired.viewabilitySettled) {
1927
+ return;
1928
+ }
1929
+ var now = adVideoElement.currentTime;
1930
+ var inView = visibleRatio >= VIEWABLE_MIN_VISIBLE_RATIO && document.visibilityState === "visible" && !adVideoElement.paused;
1931
+ if (!inView) {
1932
+ continuousVisibleS = 0;
1933
+ } else if (lastViewSampleTime !== void 0 && now >= lastViewSampleTime) {
1934
+ continuousVisibleS += now - lastViewSampleTime;
1935
+ }
1936
+ lastViewSampleTime = now;
1937
+ if (continuousVisibleS >= VIEWABLE_MIN_CONTINUOUS_S) {
1938
+ trackingFired.viewabilitySettled = true;
1939
+ fireTrackingPixels(currentAd.trackingUrls.viewable);
1940
+ }
1941
+ }
1942
+ function settleViewability() {
1943
+ if (!currentAd || !trackingFired.impression || trackingFired.viewabilitySettled) {
1944
+ return;
1945
+ }
1946
+ trackingFired.viewabilitySettled = true;
1947
+ fireTrackingPixels(viewObserver ? currentAd.trackingUrls.notViewable : currentAd.trackingUrls.viewUndetermined);
1948
+ }
1949
+ function handleFullscreenChange() {
1950
+ var _document_fullscreenElement;
1951
+ if (!adPlaying || !currentAd || !adContainerEl || !trackingFired.start) return;
1952
+ var fullscreenEl = (_document_fullscreenElement = document.fullscreenElement) !== null && _document_fullscreenElement !== void 0 ? _document_fullscreenElement : document.webkitFullscreenElement;
1953
+ var expanded = !!fullscreenEl && fullscreenEl.contains(adContainerEl);
1954
+ if (expanded === lastPlayerExpanded) return;
1955
+ lastPlayerExpanded = expanded;
1956
+ var urls = currentAd.trackingUrls;
1957
+ fireTrackingPixels(expanded ? urls.fullscreen.concat(urls.playerExpand) : urls.exitFullscreen.concat(urls.playerCollapse));
1958
+ }
1959
+ function attachContainerHandlers() {
1960
+ if (!adContainerEl || containerHandlers.length > 0) return;
1961
+ var onClick = function onClick() {
1962
+ return handleAdClick();
1963
+ };
1964
+ var onInteraction = function onInteraction(event) {
1965
+ if (adPlaying) emit("ad_interaction", event);
1966
+ };
1967
+ containerHandlers = [
1968
+ {
1969
+ type: "click",
1970
+ handler: onClick
1971
+ },
1972
+ {
1973
+ type: "mousedown",
1974
+ handler: onInteraction
1975
+ },
1976
+ {
1977
+ type: "touchstart",
1978
+ handler: onInteraction
1979
+ }
1980
+ ];
1981
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1982
+ try {
1983
+ for(var _iterator = containerHandlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1984
+ var _step_value = _step.value, type = _step_value.type, handler = _step_value.handler;
1985
+ adContainerEl.addEventListener(type, handler);
1986
+ }
1987
+ } catch (err) {
1988
+ _didIteratorError = true;
1989
+ _iteratorError = err;
1990
+ } finally{
1991
+ try {
1992
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1993
+ _iterator.return();
1994
+ }
1995
+ } finally{
1996
+ if (_didIteratorError) {
1997
+ throw _iteratorError;
1998
+ }
1999
+ }
2000
+ }
2001
+ var onFullscreenChange = function onFullscreenChange() {
2002
+ return handleFullscreenChange();
2003
+ };
2004
+ documentHandlers = [
2005
+ {
2006
+ type: "fullscreenchange",
2007
+ handler: onFullscreenChange
2008
+ },
2009
+ {
2010
+ type: "webkitfullscreenchange",
2011
+ handler: onFullscreenChange
2012
+ }
2013
+ ];
2014
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
2015
+ try {
2016
+ for(var _iterator1 = documentHandlers[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
2017
+ var _step_value1 = _step1.value, type1 = _step_value1.type, handler1 = _step_value1.handler;
2018
+ document.addEventListener(type1, handler1);
2019
+ }
2020
+ } catch (err) {
2021
+ _didIteratorError1 = true;
2022
+ _iteratorError1 = err;
2023
+ } finally{
2024
+ try {
2025
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
2026
+ _iterator1.return();
2027
+ }
2028
+ } finally{
2029
+ if (_didIteratorError1) {
2030
+ throw _iteratorError1;
2031
+ }
2032
+ }
2033
+ }
2034
+ if (typeof IntersectionObserver !== "undefined") {
2035
+ viewObserver = new IntersectionObserver(function(entries) {
2036
+ var entry = entries[entries.length - 1];
2037
+ if (entry) {
2038
+ visibleRatio = entry.isIntersecting ? entry.intersectionRatio : 0;
2039
+ }
2040
+ }, {
2041
+ threshold: [
2042
+ 0,
2043
+ 0.25,
2044
+ 0.5,
2045
+ 0.75,
2046
+ 1
2047
+ ]
2048
+ });
2049
+ viewObserver.observe(adContainerEl);
2050
+ }
2051
+ }
2052
+ function detachContainerHandlers() {
2053
+ if (adContainerEl) {
2054
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2055
+ try {
2056
+ for(var _iterator = containerHandlers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2057
+ var _step_value = _step.value, type = _step_value.type, handler = _step_value.handler;
2058
+ adContainerEl.removeEventListener(type, handler);
2059
+ }
2060
+ } catch (err) {
2061
+ _didIteratorError = true;
2062
+ _iteratorError = err;
2063
+ } finally{
2064
+ try {
2065
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
2066
+ _iterator.return();
2067
+ }
2068
+ } finally{
2069
+ if (_didIteratorError) {
2070
+ throw _iteratorError;
2071
+ }
2072
+ }
2073
+ }
2074
+ }
2075
+ containerHandlers = [];
2076
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
2077
+ try {
2078
+ for(var _iterator1 = documentHandlers[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
2079
+ var _step_value1 = _step1.value, type1 = _step_value1.type, handler1 = _step_value1.handler;
2080
+ document.removeEventListener(type1, handler1);
2081
+ }
2082
+ } catch (err) {
2083
+ _didIteratorError1 = true;
2084
+ _iteratorError1 = err;
2085
+ } finally{
2086
+ try {
2087
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
2088
+ _iterator1.return();
2089
+ }
2090
+ } finally{
2091
+ if (_didIteratorError1) {
2092
+ throw _iteratorError1;
2093
+ }
2094
+ }
2095
+ }
2096
+ documentHandlers = [];
2097
+ viewObserver === null || viewObserver === void 0 ? void 0 : viewObserver.disconnect();
2098
+ viewObserver = void 0;
2099
+ }
1512
2100
  function setAdPlayingFlag(isPlaying) {
1513
2101
  if (isPlaying) {
1514
2102
  contentVideo.dataset.stormcloudAdPlaying = "true";
@@ -1516,15 +2104,10 @@ function createHlsAdPlayer(contentVideo, options) {
1516
2104
  delete contentVideo.dataset.stormcloudAdPlaying;
1517
2105
  }
1518
2106
  }
1519
- function resetQuartileTracking(preserveImpression) {
1520
- trackingFired = {
1521
- impression: preserveImpression ? trackingFired.impression : false,
1522
- start: false,
1523
- firstQuartile: false,
1524
- midpoint: false,
1525
- thirdQuartile: false,
1526
- complete: false
1527
- };
2107
+ function resetAdTracking() {
2108
+ trackingFired = createTrackingState();
2109
+ continuousVisibleS = 0;
2110
+ lastViewSampleTime = void 0;
1528
2111
  }
1529
2112
  function isRvfcSupported(video) {
1530
2113
  return typeof video.requestVideoFrameCallback === "function";
@@ -1630,13 +2213,12 @@ function createHlsAdPlayer(contentVideo, options) {
1630
2213
  if (podIndex >= podAds.length - 1) {
1631
2214
  return false;
1632
2215
  }
2216
+ settleViewability();
1633
2217
  podIndex++;
1634
2218
  currentAd = podAds[podIndex];
1635
2219
  currentAdMediaFile = void 0;
1636
- resetQuartileTracking(false);
2220
+ resetAdTracking();
1637
2221
  if (currentAd) {
1638
- fireTrackingPixels(currentAd.trackingUrls.impression);
1639
- trackingFired.impression = true;
1640
2222
  console.log("[HlsAdPlayer] Advancing to next pod ad (".concat(podIndex + 1, "/").concat(podAds.length, "): ").concat(currentAd.title, ", duration: ").concat(currentAd.duration, "s"));
1641
2223
  }
1642
2224
  clearStallWatchdog();
@@ -1674,11 +2256,7 @@ function createHlsAdPlayer(contentVideo, options) {
1674
2256
  function handleAdStall() {
1675
2257
  console.warn("[HlsAdPlayer] Ad playback stalled (no progress) - recovering to avoid a blank frame");
1676
2258
  clearStallWatchdog();
1677
- if (currentAd) {
1678
- fireTrackingPixels(currentAd.trackingUrls.error, {
1679
- errorCode: VAST_ERROR_MEDIA_DISPLAY
1680
- });
1681
- }
2259
+ reportCurrentAdError(VAST_ERROR_MEDIA_DISPLAY);
1682
2260
  if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {
1683
2261
  return;
1684
2262
  }
@@ -1744,11 +2322,7 @@ function createHlsAdPlayer(contentVideo, options) {
1744
2322
  function handleVideoDecodeFailure() {
1745
2323
  console.warn("[HlsAdPlayer] Ad audio is advancing but no video frames decoded (black screen) - skipping this creative");
1746
2324
  clearStallWatchdog();
1747
- if (currentAd) {
1748
- fireTrackingPixels(currentAd.trackingUrls.error, {
1749
- errorCode: VAST_ERROR_MEDIA_DISPLAY
1750
- });
1751
- }
2325
+ reportCurrentAdError(VAST_ERROR_MEDIA_DISPLAY);
1752
2326
  if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {
1753
2327
  return;
1754
2328
  }
@@ -1803,6 +2377,7 @@ function createHlsAdPlayer(contentVideo, options) {
1803
2377
  }
1804
2378
  function handleAdComplete() {
1805
2379
  console.log("[HlsAdPlayer] Handling ad completion");
2380
+ settleViewability();
1806
2381
  clearStallWatchdog();
1807
2382
  adPlaying = false;
1808
2383
  setAdPlayingFlag(false);
@@ -1826,6 +2401,7 @@ function createHlsAdPlayer(contentVideo, options) {
1826
2401
  }
1827
2402
  function handleAdError() {
1828
2403
  console.log("[HlsAdPlayer] Handling ad error");
2404
+ settleViewability();
1829
2405
  clearStallWatchdog();
1830
2406
  adPlaying = false;
1831
2407
  setAdPlayingFlag(false);
@@ -1858,6 +2434,7 @@ function createHlsAdPlayer(contentVideo, options) {
1858
2434
  adContainerEl = container;
1859
2435
  }
1860
2436
  contentVideo[AD_CONTAINER_PROP] = adContainerEl;
2437
+ attachContainerHandlers();
1861
2438
  },
1862
2439
  requestAds: function requestAds(vastTagUrl) {
1863
2440
  return _async_to_generator(function() {
@@ -1920,10 +2497,6 @@ function createHlsAdPlayer(contentVideo, options) {
1920
2497
  currentAd = ads[0];
1921
2498
  currentAdMediaFile = void 0;
1922
2499
  console.log("[HlsAdPlayer] Pod parsed: ".concat(ads.length, ' ad(s), first="').concat(currentAd === null || currentAd === void 0 ? void 0 : currentAd.title, '", duration=').concat(currentAd === null || currentAd === void 0 ? void 0 : currentAd.duration, "s"));
1923
- if (currentAd) {
1924
- fireTrackingPixels(currentAd.trackingUrls.impression);
1925
- trackingFired.impression = true;
1926
- }
1927
2500
  return [
1928
2501
  2,
1929
2502
  Promise.resolve()
@@ -1963,7 +2536,7 @@ function createHlsAdPlayer(contentVideo, options) {
1963
2536
  contentVideo[AD_VIDEO_PROP] = adVideoElement;
1964
2537
  }
1965
2538
  setupAdEventListeners();
1966
- resetQuartileTracking(true);
2539
+ resetAdTracking();
1967
2540
  contentVolume = contentVideo.volume;
1968
2541
  originalVolume = Math.max(0, Math.min(1, contentVolume || originalVolume));
1969
2542
  if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
@@ -2034,6 +2607,8 @@ function createHlsAdPlayer(contentVideo, options) {
2034
2607
  var previousMutedState;
2035
2608
  return _ts_generator(this, function(_state) {
2036
2609
  console.log("[HlsAdPlayer] Stopping ad");
2610
+ settleViewability();
2611
+ fireNotUsedForUnplayedAds();
2037
2612
  clearStallWatchdog();
2038
2613
  adPlaying = false;
2039
2614
  setAdPlayingFlag(false);
@@ -2064,6 +2639,8 @@ function createHlsAdPlayer(contentVideo, options) {
2064
2639
  },
2065
2640
  destroy: function destroy() {
2066
2641
  console.log("[HlsAdPlayer] Destroying");
2642
+ settleViewability();
2643
+ fireNotUsedForUnplayedAds();
2067
2644
  destroyed = true;
2068
2645
  clearStallWatchdog();
2069
2646
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
@@ -2092,6 +2669,7 @@ function createHlsAdPlayer(contentVideo, options) {
2092
2669
  contentVideo.muted = originalMutedState;
2093
2670
  contentVideo.volume = Math.max(0, Math.min(1, originalVolume));
2094
2671
  teardownAdEventListeners();
2672
+ detachContainerHandlers();
2095
2673
  releaseAdDecoder();
2096
2674
  currentAd = void 0;
2097
2675
  currentAdMediaFile = void 0;
@@ -2237,6 +2815,7 @@ function toDevSafeUrl(rawUrl) {
2237
2815
  // src/sdk/pal.ts
2238
2816
  var PAL_SDK_URL = "https://imasdk.googleapis.com/pal/sdkloader/pal.js";
2239
2817
  var _nonceLoader;
2818
+ var _nonceLoaderAllowStorage;
2240
2819
  var _palLoadPromise;
2241
2820
  function loadPalSdk() {
2242
2821
  var _window_goog;
@@ -2279,12 +2858,15 @@ function loadPalSdk() {
2279
2858
  });
2280
2859
  return _palLoadPromise;
2281
2860
  }
2282
- function getOrCreateNonceLoader() {
2283
- if (_nonceLoader) return _nonceLoader;
2861
+ function getOrCreateNonceLoader(allowStorage) {
2862
+ if (_nonceLoader && _nonceLoaderAllowStorage === allowStorage) {
2863
+ return _nonceLoader;
2864
+ }
2284
2865
  var goog = window.goog;
2285
2866
  var consentSettings = new goog.pal.ConsentSettings();
2286
- consentSettings.allowStorage = true;
2867
+ consentSettings.allowStorage = allowStorage;
2287
2868
  _nonceLoader = new goog.pal.NonceLoader(consentSettings);
2869
+ _nonceLoaderAllowStorage = allowStorage;
2288
2870
  return _nonceLoader;
2289
2871
  }
2290
2872
  function createPalNonceManager() {
@@ -2293,7 +2875,7 @@ function createPalNonceManager() {
2293
2875
  return {
2294
2876
  generateNonce: function generateNonce() {
2295
2877
  return _async_to_generator(function() {
2296
- var options, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
2878
+ var options, _options_allowStorage, _options_adWillAutoPlay, _options_adWillPlayMuted, _options_playerVolume, _options_continuousPlayback, loader, goog, request, manager, error;
2297
2879
  var _arguments = arguments;
2298
2880
  return _ts_generator(this, function(_state) {
2299
2881
  switch(_state.label){
@@ -2313,7 +2895,7 @@ function createPalNonceManager() {
2313
2895
  ];
2314
2896
  case 2:
2315
2897
  _state.sent();
2316
- loader = getOrCreateNonceLoader();
2898
+ loader = getOrCreateNonceLoader((_options_allowStorage = options.allowStorage) !== null && _options_allowStorage !== void 0 ? _options_allowStorage : true);
2317
2899
  goog = window.goog;
2318
2900
  request = new goog.pal.NonceRequest();
2319
2901
  request.adWillAutoPlay = (_options_adWillAutoPlay = options.adWillAutoPlay) !== null && _options_adWillAutoPlay !== void 0 ? _options_adWillAutoPlay : true;
@@ -2498,6 +3080,8 @@ function ingestPlayerTracking(licenseKey, channel, body) {
2498
3080
  }
2499
3081
  // src/utils/vastEnvironmentSignals.ts
2500
3082
  var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
3083
+ var WEB_SESSION_STORAGE_KEY = "stormcloud.web.sid";
3084
+ var inMemoryWebSessionId;
2501
3085
  var PLAYER_ID_STORAGE_KEY = "stormcloud.player.id";
2502
3086
  var DEVICE_ID_STORAGE_KEYS = [
2503
3087
  "rdid",
@@ -2519,7 +3103,7 @@ function resolveVastEnvironmentSignals(isCtv) {
2519
3103
  var _ref;
2520
3104
  var bridgeSignals = readNativeBridgeSignals();
2521
3105
  var platformDevice = readPlatformNativeDeviceId();
2522
- var realDeviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId;
3106
+ var realDeviceId = bridgeSignals.deviceId || (isCtv ? readStoredDeviceId() : void 0) || platformDevice.deviceId;
2523
3107
  var deviceId = realDeviceId;
2524
3108
  var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType();
2525
3109
  var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
@@ -2533,6 +3117,7 @@ function resolveVastEnvironmentSignals(isCtv) {
2533
3117
  limitAdTracking = (_ref1 = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref1 !== void 0 ? _ref1 : false;
2534
3118
  }
2535
3119
  }
3120
+ var deviceTypeHint = resolveDeviceTypeHint(isCtv);
2536
3121
  if (isCtv) {
2537
3122
  return _object_spread_props(_object_spread({
2538
3123
  isCtv: true,
@@ -2544,18 +3129,157 @@ function resolveVastEnvironmentSignals(isCtv) {
2544
3129
  } : {}, deviceId && limitAdTracking != null ? {
2545
3130
  limitAdTracking: limitAdTracking
2546
3131
  } : {}), {
2547
- deviceTypeHint: 5
3132
+ deviceTypeHint: deviceTypeHint
2548
3133
  });
2549
3134
  }
2550
- return _object_spread({
3135
+ var webSessionId = getOrCreateWebSessionId();
3136
+ return _object_spread_props(_object_spread({
2551
3137
  isCtv: false
2552
- }, deviceId ? {
3138
+ }, webSessionId ? {
3139
+ sessionId: webSessionId
3140
+ } : {}, deviceId ? {
2553
3141
  deviceId: deviceId
2554
3142
  } : {}, deviceId && deviceIdType ? {
2555
3143
  deviceIdType: deviceIdType
2556
3144
  } : {}, deviceId && limitAdTracking != null ? {
2557
3145
  limitAdTracking: limitAdTracking
2558
- } : {});
3146
+ } : {}), {
3147
+ deviceTypeHint: deviceTypeHint
3148
+ });
3149
+ }
3150
+ var DEVICE_TYPE_HINT = {
3151
+ FEATURE_PHONE: 1,
3152
+ SMARTPHONE: 2,
3153
+ DESKTOP: 3,
3154
+ TABLET: 4,
3155
+ CONNECTED_TV: 5,
3156
+ GAME_CONSOLE: 6,
3157
+ SET_TOP_BOX: 7
3158
+ };
3159
+ var DEVICE_TYPE_HINT_ALIASES = {
3160
+ featurephone: DEVICE_TYPE_HINT.FEATURE_PHONE,
3161
+ smartphone: DEVICE_TYPE_HINT.SMARTPHONE,
3162
+ mobile: DEVICE_TYPE_HINT.SMARTPHONE,
3163
+ phone: DEVICE_TYPE_HINT.SMARTPHONE,
3164
+ desktop: DEVICE_TYPE_HINT.DESKTOP,
3165
+ pc: DEVICE_TYPE_HINT.DESKTOP,
3166
+ tablet: DEVICE_TYPE_HINT.TABLET,
3167
+ ctv: DEVICE_TYPE_HINT.CONNECTED_TV,
3168
+ tv: DEVICE_TYPE_HINT.CONNECTED_TV,
3169
+ connectedtv: DEVICE_TYPE_HINT.CONNECTED_TV,
3170
+ smarttv: DEVICE_TYPE_HINT.CONNECTED_TV,
3171
+ console: DEVICE_TYPE_HINT.GAME_CONSOLE,
3172
+ gameconsole: DEVICE_TYPE_HINT.GAME_CONSOLE,
3173
+ stb: DEVICE_TYPE_HINT.SET_TOP_BOX,
3174
+ settopbox: DEVICE_TYPE_HINT.SET_TOP_BOX
3175
+ };
3176
+ var SET_TOP_BOX_UA = /LGSTB|\bSTB\b|STB\d|Set-?Top|SetTopBox|TV ?Box|Kaon|Humax|Arris|Technicolor|Sagemcom|Infomir|MAG\d{3}|KreaTV|Amino|Formuler|Dune ?HD|TiVo|MiBOX|Mi Box|SHIELD Android TV|\bAFT[A-Z]|Roku|AppleTV|Apple TV|CrKey/i;
3177
+ var GAME_CONSOLE_UA = /PlayStation|Xbox|Nintendo/i;
3178
+ var CONNECTED_TV_UA = /Web0S|webOS|Tizen|SMART-TV|SmartTV|NetCast|BRAVIA|HbbTV|VIDAA|Hisense|Philips|Viera|AQUOS|Android TV|Google TV|\bTV\b/i;
3179
+ var FEATURE_PHONE_UA = /KAIOS|MIDP|J2ME|Series40|Opera Mini/i;
3180
+ function resolveDeviceTypeHint(isCtv) {
3181
+ var override = readDeviceTypeHintOverride(isCtv);
3182
+ if (override != null) return override;
3183
+ return inferDeviceTypeHint(isCtv);
3184
+ }
3185
+ function inferDeviceTypeHint(isCtv) {
3186
+ var fallback = isCtv ? DEVICE_TYPE_HINT.CONNECTED_TV : DEVICE_TYPE_HINT.DESKTOP;
3187
+ if (typeof navigator === "undefined") return fallback;
3188
+ var ua = navigator.userAgent || "";
3189
+ var maxTouchPoints = navigator.maxTouchPoints || 0;
3190
+ if (SET_TOP_BOX_UA.test(ua)) return DEVICE_TYPE_HINT.SET_TOP_BOX;
3191
+ if (GAME_CONSOLE_UA.test(ua)) return DEVICE_TYPE_HINT.GAME_CONSOLE;
3192
+ if (CONNECTED_TV_UA.test(ua) && !/Mobile/i.test(ua)) {
3193
+ return DEVICE_TYPE_HINT.CONNECTED_TV;
3194
+ }
3195
+ if (FEATURE_PHONE_UA.test(ua)) return DEVICE_TYPE_HINT.FEATURE_PHONE;
3196
+ if (/iPad/i.test(ua) || /Macintosh/i.test(ua) && maxTouchPoints > 1) {
3197
+ return DEVICE_TYPE_HINT.TABLET;
3198
+ }
3199
+ if (/iPhone|iPod/i.test(ua)) return DEVICE_TYPE_HINT.SMARTPHONE;
3200
+ if (/Android/i.test(ua)) {
3201
+ if (/Mobile/i.test(ua)) return DEVICE_TYPE_HINT.SMARTPHONE;
3202
+ if (maxTouchPoints === 0) return DEVICE_TYPE_HINT.SET_TOP_BOX;
3203
+ return DEVICE_TYPE_HINT.TABLET;
3204
+ }
3205
+ if (/Mobile|Windows Phone|BlackBerry/i.test(ua)) return DEVICE_TYPE_HINT.SMARTPHONE;
3206
+ return fallback;
3207
+ }
3208
+ function readDeviceTypeHintOverride(isCtv) {
3209
+ if (typeof window === "undefined") return void 0;
3210
+ var keys = [
3211
+ "dth",
3212
+ "deviceTypeHint"
3213
+ ];
3214
+ var fromGlobal = normalizeDeviceTypeHint(window.__STORMCLOUD_DTH__);
3215
+ if (fromGlobal != null) return fromGlobal;
3216
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
3217
+ try {
3218
+ for(var _iterator = getNativeBridgeSources()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
3219
+ var source = _step.value;
3220
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
3221
+ try {
3222
+ for(var _iterator1 = keys[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
3223
+ var key = _step1.value;
3224
+ var value = source === null || source === void 0 ? void 0 : source[key];
3225
+ var normalized = normalizeDeviceTypeHint(typeof value === "function" ? safeCall(value, source) : value);
3226
+ if (normalized != null) return normalized;
3227
+ }
3228
+ } catch (err) {
3229
+ _didIteratorError1 = true;
3230
+ _iteratorError1 = err;
3231
+ } finally{
3232
+ try {
3233
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
3234
+ _iterator1.return();
3235
+ }
3236
+ } finally{
3237
+ if (_didIteratorError1) {
3238
+ throw _iteratorError1;
3239
+ }
3240
+ }
3241
+ }
3242
+ }
3243
+ } catch (err) {
3244
+ _didIteratorError = true;
3245
+ _iteratorError = err;
3246
+ } finally{
3247
+ try {
3248
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
3249
+ _iterator.return();
3250
+ }
3251
+ } finally{
3252
+ if (_didIteratorError) {
3253
+ throw _iteratorError;
3254
+ }
3255
+ }
3256
+ }
3257
+ if (!isCtv) return void 0;
3258
+ for(var _i = 0, _iter = [
3259
+ "stormcloud.dth",
3260
+ "dth"
3261
+ ]; _i < _iter.length; _i++){
3262
+ var key1 = _iter[_i];
3263
+ var normalized1 = normalizeDeviceTypeHint(readStoredString(key1));
3264
+ if (normalized1 != null) return normalized1;
3265
+ }
3266
+ return void 0;
3267
+ }
3268
+ function normalizeDeviceTypeHint(value) {
3269
+ if (typeof value === "number") {
3270
+ return Number.isInteger(value) && value >= 1 && value <= 7 ? value : void 0;
3271
+ }
3272
+ if (typeof value !== "string") return void 0;
3273
+ var trimmed = value.trim();
3274
+ if (/^[1-7]$/.test(trimmed)) return parseInt(trimmed, 10);
3275
+ return DEVICE_TYPE_HINT_ALIASES[trimmed.toLowerCase().replace(/[\s_-]/g, "")];
3276
+ }
3277
+ function safeCall(fn, thisArg) {
3278
+ try {
3279
+ return fn.call(thisArg);
3280
+ } catch (unused) {
3281
+ return void 0;
3282
+ }
2559
3283
  }
2560
3284
  function inferDeviceIdType() {
2561
3285
  if (typeof navigator === "undefined") {
@@ -2579,9 +3303,10 @@ function isEquivalentDeviceIdType(tagType, runtimeType) {
2579
3303
  return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);
2580
3304
  }
2581
3305
  function resolveNativeDeviceId() {
3306
+ var includeStored = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : true;
2582
3307
  var bridgeSignals = readNativeBridgeSignals();
2583
3308
  var platformDevice = readPlatformNativeDeviceId();
2584
- var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId;
3309
+ var deviceId = bridgeSignals.deviceId || (includeStored ? readStoredDeviceId() : void 0) || platformDevice.deviceId;
2585
3310
  if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {
2586
3311
  return void 0;
2587
3312
  }
@@ -2610,6 +3335,21 @@ function getOrCreateCtvSessionId() {
2610
3335
  writePersistentId(CTV_SESSION_STORAGE_KEY, sessionId);
2611
3336
  return sessionId;
2612
3337
  }
3338
+ function getOrCreateWebSessionId() {
3339
+ if (typeof window === "undefined") return void 0;
3340
+ try {
3341
+ var _window_sessionStorage;
3342
+ var existing = (_window_sessionStorage = window.sessionStorage) === null || _window_sessionStorage === void 0 ? void 0 : _window_sessionStorage.getItem(WEB_SESSION_STORAGE_KEY);
3343
+ if (existing && !isMacroPlaceholder(existing)) return existing;
3344
+ } catch (unused) {}
3345
+ var sessionId = inMemoryWebSessionId || createUuid();
3346
+ inMemoryWebSessionId = sessionId;
3347
+ try {
3348
+ var _window_sessionStorage1;
3349
+ (_window_sessionStorage1 = window.sessionStorage) === null || _window_sessionStorage1 === void 0 ? void 0 : _window_sessionStorage1.setItem(WEB_SESSION_STORAGE_KEY, sessionId);
3350
+ } catch (unused) {}
3351
+ return sessionId;
3352
+ }
2613
3353
  function readPersistentId(storageKey) {
2614
3354
  return readStoredString(storageKey) || readCookie(storageKey);
2615
3355
  }
@@ -2761,22 +3501,9 @@ function isZeroedAdId(value) {
2761
3501
  return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
2762
3502
  }
2763
3503
  function readNativeBridgeSignals() {
2764
- if (typeof window === "undefined") {
2765
- return {};
2766
- }
2767
- var candidates = [
2768
- window.__STORMCLOUD_CTV_AD_INFO__,
2769
- window.__STORMCLOUD_CTV__,
2770
- window.stormcloudCtv,
2771
- window.AiryTV,
2772
- window.Android,
2773
- window.webOS,
2774
- window.tizen,
2775
- window.amazon
2776
- ].filter(Boolean);
2777
3504
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2778
3505
  try {
2779
- for(var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
3506
+ for(var _iterator = getNativeBridgeSources()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2780
3507
  var source = _step.value;
2781
3508
  var contentUrl = readBridgeValue(source, [
2782
3509
  "contentUrl",
@@ -2851,6 +3578,21 @@ function readNativeBridgeSignals() {
2851
3578
  }
2852
3579
  return {};
2853
3580
  }
3581
+ function getNativeBridgeSources() {
3582
+ if (typeof window === "undefined") {
3583
+ return [];
3584
+ }
3585
+ return [
3586
+ window.__STORMCLOUD_CTV_AD_INFO__,
3587
+ window.__STORMCLOUD_CTV__,
3588
+ window.stormcloudCtv,
3589
+ window.AiryTV,
3590
+ window.Android,
3591
+ window.webOS,
3592
+ window.tizen,
3593
+ window.amazon
3594
+ ].filter(Boolean);
3595
+ }
2854
3596
  function readBridgeValue(source, keys) {
2855
3597
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2856
3598
  try {
@@ -3209,7 +3951,7 @@ function sha256Hex(input) {
3209
3951
  })();
3210
3952
  }
3211
3953
  function resolvePlayerIdentitySeed(clientInfo) {
3212
- var nativeDeviceId = resolveNativeDeviceId();
3954
+ var nativeDeviceId = resolveNativeDeviceId(clientInfo.isSmartTV);
3213
3955
  if (nativeDeviceId) {
3214
3956
  return "device:".concat(nativeDeviceId);
3215
3957
  }
@@ -3978,6 +4720,12 @@ function applyDeviceIdentityParams(params, ctx) {
3978
4720
  params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue : isMacroPlaceholder2(tagLat) ? "0" : tagLat);
3979
4721
  return;
3980
4722
  }
4723
+ if (!ctx.isCtv) {
4724
+ params.delete("rdid");
4725
+ params.delete("idtype");
4726
+ params.delete("is_lat");
4727
+ return;
4728
+ }
3981
4729
  var tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder2(tagRdid));
3982
4730
  var tagTypeValid = Boolean(tagType && !isMacroPlaceholder2(tagType));
3983
4731
  if (tagRdidValid && tagTypeValid && runtimeType && !isEquivalentDeviceIdType(tagType, runtimeType)) {
@@ -4132,15 +4880,24 @@ function applyVastMacros(baseUrl, ctx) {
4132
4880
  if (ctx.podMaxAds != null) {
4133
4881
  params.set("pmad", String(Math.max(1, Math.round(ctx.podMaxAds))));
4134
4882
  }
4135
- if (!ctx.isCtv && ctx.pageUrl) {
4136
- params.set("url", ctx.pageUrl);
4137
- params.set("description_url", ctx.pageUrl);
4138
- }
4139
4883
  var existingUrl = params.get("url") || "";
4140
4884
  if (EXAMPLE_COM_URL.test(existingUrl)) {
4141
4885
  params.delete("url");
4142
4886
  params.delete("description_url");
4143
4887
  }
4888
+ if (!ctx.isCtv && ctx.pageUrl) {
4889
+ if (isMacroPlaceholder2(params.get("url"))) {
4890
+ params.set("url", ctx.pageUrl);
4891
+ }
4892
+ if (isMacroPlaceholder2(params.get("description_url"))) {
4893
+ params.set("description_url", params.get("url") || ctx.pageUrl);
4894
+ }
4895
+ }
4896
+ if (!ctx.isCtv) {
4897
+ params.delete("an");
4898
+ params.delete("msid");
4899
+ params.delete("sid");
4900
+ }
4144
4901
  if (ctx.adWillPlayMuted != null) {
4145
4902
  params.set("vpmute", ctx.adWillPlayMuted ? "1" : "0");
4146
4903
  }
@@ -4174,6 +4931,9 @@ function applyVastMacros(baseUrl, ctx) {
4174
4931
  if (ctx.programTitle) {
4175
4932
  params.set("ct_ti", ctx.programTitle);
4176
4933
  }
4934
+ if (ctx.channelName) {
4935
+ params.set("ct_ch", ctx.channelName);
4936
+ }
4177
4937
  var staleKeys = [];
4178
4938
  params.forEach(function(value, key) {
4179
4939
  if (isMacroPlaceholder2(value)) {
@@ -4226,8 +4986,10 @@ function fetchConsentSignals() {
4226
4986
  tcfApi("addEventListener", 2, function(tcData, success) {
4227
4987
  if (settled) return;
4228
4988
  if (success && tcData && (tcData.eventStatus === "tcloaded" || tcData.eventStatus === "useractioncomplete")) {
4989
+ var _tcData_purpose_consents, _tcData_purpose;
4229
4990
  settled = true;
4230
4991
  signals.gdpr = tcData.gdprApplies ? "1" : "0";
4992
+ signals.storageAllowed = tcData.gdprApplies ? ((_tcData_purpose = tcData.purpose) === null || _tcData_purpose === void 0 ? void 0 : (_tcData_purpose_consents = _tcData_purpose.consents) === null || _tcData_purpose_consents === void 0 ? void 0 : _tcData_purpose_consents[1]) === true : true;
4231
4993
  if (typeof tcData.tcString === "string" && tcData.tcString) {
4232
4994
  signals.gdprConsent = tcData.tcString;
4233
4995
  }
@@ -5760,7 +6522,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
5760
6522
  pageUrl: !envSignals.isCtv && typeof window !== "undefined" ? toDevSafeUrl(window.location.href) : void 0,
5761
6523
  adWillPlayMuted: adWillPlayMuted,
5762
6524
  adWillAutoPlay: !!this.config.autoplay,
5763
- sessionId: envSignals.sessionId,
6525
+ sessionId: envSignals.isCtv || this.consentSignals.storageAllowed !== false ? envSignals.sessionId : void 0,
5764
6526
  deviceId: envSignals.deviceId,
5765
6527
  deviceIdType: envSignals.deviceIdType,
5766
6528
  limitAdTracking: envSignals.limitAdTracking,
@@ -5768,6 +6530,8 @@ var AdConfigManager = /*#__PURE__*/ function() {
5768
6530
  adTest: this.config.adTest
5769
6531
  }, this.config.programTitle ? {
5770
6532
  programTitle: this.config.programTitle
6533
+ } : {}, this.config.channelName ? {
6534
+ channelName: this.config.channelName
5771
6535
  } : {}), {
5772
6536
  consent: this.consentSignals
5773
6537
  }));
@@ -7307,6 +8071,12 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
7307
8071
  console.log("[POD] Playing pod ad ".concat((payload === null || payload === void 0 ? void 0 : payload.index) != null ? payload.index + 1 : "?", "/").concat((_ref = payload === null || payload === void 0 ? void 0 : payload.total) !== null && _ref !== void 0 ? _ref : "?"));
7308
8072
  }
7309
8073
  });
8074
+ adPlayer.on("ad_click", function() {
8075
+ _this.host.onAdClick();
8076
+ });
8077
+ adPlayer.on("ad_interaction", function(event) {
8078
+ if (event) _this.host.onAdInteraction(event);
8079
+ });
7310
8080
  adPlayer.on("all_ads_completed", function() {
7311
8081
  sendAdImpressionTracking(_this.host.config.licenseKey, {
7312
8082
  source: "hls",
@@ -8836,6 +9606,12 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8836
9606
  },
8837
9607
  generatePodVastUrl: function generatePodVastUrl(base, breakDurationMs) {
8838
9608
  return _this.generatePodVastUrl(base, breakDurationMs);
9609
+ },
9610
+ onAdClick: function onAdClick() {
9611
+ return _this.palNonce.sendAdClick();
9612
+ },
9613
+ onAdInteraction: function onAdInteraction(event) {
9614
+ return _this.palNonce.sendAdTouch(event);
8839
9615
  }
8840
9616
  }, this.timing, this.adConfig, this.cueManager, this.placeholder);
8841
9617
  }
@@ -8876,7 +9652,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8876
9652
  // ───────────────────────────────────────────────────────────────
8877
9653
  function load() {
8878
9654
  return _async_to_generator(function() {
8879
- var _this, _this_config_lowLatencyMode, error, palDescriptionUrl, continueLiveStreamDuringAds;
9655
+ var _this, error, palDescriptionUrl, continueLiveStreamDuringAds;
8880
9656
  return _ts_generator(this, function(_state) {
8881
9657
  switch(_state.label){
8882
9658
  case 0:
@@ -8912,19 +9688,25 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
8912
9688
  4
8913
9689
  ];
8914
9690
  case 4:
8915
- palDescriptionUrl = this.adConfig.getPalDescriptionUrl();
8916
- this.palNonce.generateNonce(_object_spread({
8917
- videoWidth: this.video.offsetWidth || this.video.clientWidth || 640,
8918
- videoHeight: this.video.offsetHeight || this.video.clientHeight || 480,
8919
- adWillAutoPlay: !!this.config.autoplay,
8920
- adWillPlayMuted: true,
8921
- playerVolume: 0,
8922
- continuousPlayback: (_this_config_lowLatencyMode = this.config.lowLatencyMode) !== null && _this_config_lowLatencyMode !== void 0 ? _this_config_lowLatencyMode : false
8923
- }, palDescriptionUrl ? {
8924
- descriptionUrl: palDescriptionUrl
8925
- } : {})).catch(function() {});
8926
- fetchConsentSignals().then(function(signals) {
9691
+ palDescriptionUrl = this.config.ctvAdRequest ? this.adConfig.getPalDescriptionUrl() : void 0;
9692
+ fetchConsentSignals().catch(function() {
9693
+ return {};
9694
+ }).then(function(signals) {
9695
+ var _this_config_lowLatencyMode;
8927
9696
  _this.adConfig.consentSignals = signals;
9697
+ var muted = _this.video.muted;
9698
+ return _this.palNonce.generateNonce(_object_spread({
9699
+ videoWidth: _this.video.offsetWidth || _this.video.clientWidth || 640,
9700
+ videoHeight: _this.video.offsetHeight || _this.video.clientHeight || 480,
9701
+ adWillAutoPlay: !!_this.config.autoplay,
9702
+ adWillPlayMuted: muted,
9703
+ playerVolume: muted ? 0 : _this.video.volume,
9704
+ continuousPlayback: (_this_config_lowLatencyMode = _this.config.lowLatencyMode) !== null && _this_config_lowLatencyMode !== void 0 ? _this_config_lowLatencyMode : false
9705
+ }, palDescriptionUrl ? {
9706
+ descriptionUrl: palDescriptionUrl
9707
+ } : {}, signals.storageAllowed != null ? {
9708
+ allowStorage: signals.storageAllowed
9709
+ } : {}));
8928
9710
  }).catch(function() {});
8929
9711
  this.adConfig.initializeTracking();
8930
9712
  if (!this.hlsEngine.shouldUseNativeHls(function() {