@openplayerjs/ads 3.1.2 → 3.3.0
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.
- package/README.md +103 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.js +639 -103
- package/dist/index.js.map +1 -1
- package/dist/openplayer-ads.js +1 -1
- package/dist/openplayer-ads.js.map +1 -1
- package/dist/types/ad-dom.d.ts.map +1 -1
- package/dist/types/ads.d.ts.map +1 -1
- package/dist/types/schedule.d.ts +1 -1
- package/dist/types/simid.d.ts +126 -9
- package/dist/types/simid.d.ts.map +1 -1
- package/dist/types/vast-parser.d.ts +1 -1
- package/dist/types/vast-parser.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -15,7 +15,7 @@ function _mergeNamespaces(n, m) {
|
|
|
15
15
|
return Object.freeze(n);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
function e$1(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,adId:e.adId||null,sequence:e.sequence||null,apiFramework:e.apiFramework||null,universalAdIds:[],creativeExtensions:[]}}const t$1=["ADCATEGORIES","ADCOUNT","ADPLAYHEAD","ADSERVINGID","ADTYPE","APIFRAMEWORKS","APPBUNDLE","ASSETURI","BLOCKEDADCATEGORIES","BREAKMAXADLENGTH","BREAKMAXADS","BREAKMAXDURATION","BREAKMINADLENGTH","BREAKMINDURATION","BREAKPOSITION","CLICKPOS","CLICKTYPE","CLIENTUA","CONTENTID","CONTENTPLAYHEAD","CONTENTURI","DEVICEIP","DEVICEUA","DOMAIN","EXTENSIONS","GDPRCONSENT","IFA","IFATYPE","INVENTORYSTATE","LATLONG","LIMITADTRACKING","MEDIAMIME","MEDIAPLAYHEAD","OMIDPARTNER","PAGEURL","PLACEMENTTYPE","PLAYERCAPABILITIES","PLAYERSIZE","PLAYERSTATE","PODSEQUENCE","REGULATIONS","SERVERSIDE","SERVERUA","TRANSACTIONID","UNIVERSALADID","VASTVERSIONS","VERIFICATIONVENDORS"];function r$1(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=[],n=s$1(e);!t.ERRORCODE||r.isCustomCode||/^[0-9]{3}$/.test(t.ERRORCODE)||(t.ERRORCODE=900),t.CACHEBUSTING=d(Math.round(1e8*Math.random())),t.TIMESTAMP=(new Date).toISOString(),t.RANDOM=t.random=t.CACHEBUSTING;for(const e in t)t[e]=c(t[e]);for(const e in n){const r=n[e];"string"==typeof r&&a.push(i$1(r,t));}return a}function i$1(e,r){const i=(e=a$1(e,r)).match(/[^[\]]+(?=])/g);if(!i)return e;let s=i.filter((e=>t$1.indexOf(e)>-1));return 0===s.length?e:(s=s.reduce(((e,t)=>(e[t]=-1,e)),{}),a$1(e,s))}function a$1(e,t){let r=e;for(const e in t){const i=t[e];r=r.replace(new RegExp("(?:\\[|%%)(".concat(e,")(?:\\]|%%)"),"g"),i);}return r}function s$1(e){return Array.isArray(e)?e.map((e=>e&&e.hasOwnProperty("url")?e.url:e)):e}function n$1(e){return /^(https?:\/\/|\/\/)/.test(e)}function o$1(e,t){for(let r=0;r<t.length;r++)if(l(t[r],e))return true;return false}function l(e,t){if(e&&t){const r=Object.getOwnPropertyNames(e),i=Object.getOwnPropertyNames(t);return r.length===i.length&&(e.id===t.id&&e.url===t.url)}return false}function c(e){return encodeURIComponent(e).replace(/[!'()*]/g,(e=>"%".concat(e.charCodeAt(0).toString(16))))}function d(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:8;return e.toString().padStart(t,"0")}const u={track:function(e,t,i){r$1(e,t,i).forEach((e=>{if("undefined"!=typeof window&&null!==window){(new Image).src=e;}}));},resolveURLTemplates:r$1,extractURLsFromTemplates:s$1,filterUrlTemplates:function(e){return e.reduce(((e,t)=>{const r=t.url||t;return n$1(r)?e.validUrls.push(r):e.invalidUrls.push(r),e}),{validUrls:[],invalidUrls:[]})},containsTemplateObject:o$1,isTemplateObjectEqual:l,encodeURIComponentRFC3986:c,replaceUrlMacros:i$1,isNumeric:function(e){return !isNaN(parseFloat(e))&&isFinite(e)},flatten:function e(t){return t.reduce(((t,r)=>t.concat(Array.isArray(r)?e(r):r)),[])},joinArrayOfUniqueTemplateObjs:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];const r=Array.isArray(e)?e:[],i=Array.isArray(t)?t:[];return r.concat(i).reduce(((e,t)=>(o$1(t,e)||e.push(t),e)),[])},isValidTimeValue:function(e){return Number.isFinite(e)&&e>=-2},addLeadingZeros:d,isValidUrl:n$1,isBrowserEnvironment:function(){return "undefined"!=typeof window},formatMacrosValues:function(e){return "object"!=typeof e?e:JSON.stringify(e)}};function h(e){return ["true","TRUE","True","1"].includes(e)}function p(e){if(null==e)return -1;if(u.isNumeric(e))return parseInt(e);const t=e.split(":");if(3!==t.length)return -1;const r=t[2].split(".");let i=parseInt(r[0]);2===r.length&&(i+=parseFloat("0.".concat(r[1])));const a=parseInt(60*t[1]),s=parseInt(60*t[0]*60);return isNaN(s)||isNaN(a)||isNaN(i)||a>3600||i>60?-1:s+a+i}const m={childByName:function(e,t){return Array.from(e.childNodes).find((e=>e.nodeName===t))},childrenByName:function(e,t){return Array.from(e.childNodes).filter((e=>e.nodeName===t))},resolveVastAdTagURI:function(e,t){if(!t)return e;if(e.startsWith("//")){const{protocol:t}=location;return "".concat(t).concat(e)}if(!e.includes("://")){const r=t.slice(0,t.lastIndexOf("/"));return "".concat(r,"/").concat(e)}return e},parseBoolean:h,parseNodeText:function(e){return e&&(e.textContent||e.text||"").trim()},copyNodeAttribute:function(e,t,r){const i=t.getAttribute(e);i&&r.setAttribute(e,i);},parseAttributes:function(e){return Array.from(e.attributes).reduce(((e,t)=>(e[t.nodeName]=t.nodeValue,e)),{})},parseDuration:p,getStandAloneAds:function(){return (arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).filter((e=>!parseInt(e.sequence,10)))},getSortedAdPods:function(){return (arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).filter((e=>parseInt(e.sequence,10))).sort(((e,t)=>e.sequence-t.sequence))},assignAttributes:function(e,t){e&&Array.from(e).forEach((e=>{let{nodeName:r,nodeValue:i}=e;if(r&&i&&t.hasOwnProperty(r)){let e=i;"boolean"==typeof t[r]&&(e=h(e)),t[r]=e;}}));},mergeWrapperAdData:function(e,t){var r;e.errorURLTemplates=t.errorURLTemplates.concat(e.errorURLTemplates),e.impressionURLTemplates=t.impressionURLTemplates.concat(e.impressionURLTemplates),e.extensions=t.extensions.concat(e.extensions),t.viewableImpression.length>0&&(e.viewableImpression=[...e.viewableImpression,...t.viewableImpression]),e.followAdditionalWrappers=t.followAdditionalWrappers,e.allowMultipleAds=t.allowMultipleAds,e.fallbackOnNoAd=t.fallbackOnNoAd;const i=(t.creatives||[]).filter((e=>e&&"companion"===e.type)),a=i.reduce(((e,t)=>((t.variations||[]).forEach((t=>{(t.companionClickTrackingURLTemplates||[]).forEach((t=>{u.containsTemplateObject(t,e)||e.push(t);}));})),e)),[]);e.creatives=i.concat(e.creatives);const s=t.videoClickTrackingURLTemplates&&t.videoClickTrackingURLTemplates.length,n=t.videoCustomClickURLTemplates&&t.videoCustomClickURLTemplates.length;if(e.creatives.forEach((e=>{if(t.trackingEvents&&t.trackingEvents[e.type])for(const r in t.trackingEvents[e.type]){const i=t.trackingEvents[e.type][r];Array.isArray(e.trackingEvents[r])||(e.trackingEvents[r]=[]),e.trackingEvents[r]=e.trackingEvents[r].concat(i);}"linear"===e.type&&(s&&(e.videoClickTrackingURLTemplates=e.videoClickTrackingURLTemplates.concat(t.videoClickTrackingURLTemplates)),n&&(e.videoCustomClickURLTemplates=e.videoCustomClickURLTemplates.concat(t.videoCustomClickURLTemplates)),!t.videoClickThroughURLTemplate||null!==e.videoClickThroughURLTemplate&&void 0!==e.videoClickThroughURLTemplate||(e.videoClickThroughURLTemplate=t.videoClickThroughURLTemplate)),"companion"===e.type&&a.length&&(e.variations||[]).forEach((e=>{e.companionClickTrackingURLTemplates=u.joinArrayOfUniqueTemplateObjs(e.companionClickTrackingURLTemplates,a);}));})),t.adVerifications&&(e.adVerifications=e.adVerifications.concat(t.adVerifications)),t.blockedAdCategories&&(e.blockedAdCategories=e.blockedAdCategories.concat(t.blockedAdCategories)),null!==(r=t.creatives)&&void 0!==r&&r.length){const r=t.creatives.filter((e=>{var t;return (null===(t=e.icons)||void 0===t?void 0:t.length)&&!e.mediaFiles.length}));r.length&&(e.creatives=e.creatives.concat(r));}}};function g(t,r){const i=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"companion",required:null,variations:[]}}(r);return i.required=t.getAttribute("required")||null,i.variations=m.childrenByName(t,"Companion").map((e=>{const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,adType:"companionAd",width:e.width||0,height:e.height||0,assetWidth:e.assetWidth||null,assetHeight:e.assetHeight||null,expandedWidth:e.expandedWidth||null,expandedHeight:e.expandedHeight||null,apiFramework:e.apiFramework||null,adSlotId:e.adSlotId||null,pxratio:e.pxratio||"1",renderingMode:e.renderingMode||"default",staticResources:[],htmlResources:[],iframeResources:[],adParameters:null,altText:null,companionClickThroughURLTemplate:null,companionClickTrackingURLTemplates:[],trackingEvents:{}}}(m.parseAttributes(e));t.htmlResources=m.childrenByName(e,"HTMLResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat(r):e}),[]),t.iframeResources=m.childrenByName(e,"IFrameResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat(r):e}),[]),t.staticResources=m.childrenByName(e,"StaticResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat({url:r,creativeType:t.getAttribute("creativeType")||null}):e}),[]),t.altText=m.parseNodeText(m.childByName(e,"AltText"))||null;const r=m.childByName(e,"TrackingEvents");r&&m.childrenByName(r,"Tracking").forEach((e=>{const r=e.getAttribute("event"),i=m.parseNodeText(e);r&&i&&(Array.isArray(t.trackingEvents[r])||(t.trackingEvents[r]=[]),t.trackingEvents[r].push(i));})),t.companionClickTrackingURLTemplates=m.childrenByName(e,"CompanionClickTracking").map((e=>({id:e.getAttribute("id")||null,url:m.parseNodeText(e)}))),t.companionClickThroughURLTemplate=m.parseNodeText(m.childByName(e,"CompanionClickThrough"))||null;const i=m.childByName(e,"AdParameters");return i&&(t.adParameters={value:m.parseNodeText(i),xmlEncoded:i.getAttribute("xmlEncoded")||null}),t})),i}function v(t,r){let i;const a=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"linear",duration:0,skipDelay:null,mediaFiles:[],mezzanine:null,interactiveCreativeFile:null,closedCaptionFiles:[],videoClickThroughURLTemplate:null,videoClickTrackingURLTemplates:[],videoCustomClickURLTemplates:[],adParameters:null,icons:[],trackingEvents:{}}}(r);a.duration=m.parseDuration(m.parseNodeText(m.childByName(t,"Duration")));const s=t.getAttribute("skipoffset");if(null==s)a.skipDelay=null;else if("%"===s.charAt(s.length-1)&&-1!==a.duration){const e=parseInt(s,10);a.skipDelay=a.duration*(e/100);}else a.skipDelay=m.parseDuration(s);const n=m.childByName(t,"VideoClicks");if(n){const e=m.childByName(n,"ClickThrough");a.videoClickThroughURLTemplate=e?{id:e.getAttribute("id")||null,url:m.parseNodeText(e)}:null,m.childrenByName(n,"ClickTracking").forEach((e=>{a.videoClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});})),m.childrenByName(n,"CustomClick").forEach((e=>{a.videoCustomClickURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});}));}const o=m.childByName(t,"AdParameters");o&&(a.adParameters={value:m.parseNodeText(o),xmlEncoded:o.getAttribute("xmlEncoded")||null}),m.childrenByName(t,"TrackingEvents").forEach((e=>{m.childrenByName(e,"Tracking").forEach((e=>{let t=e.getAttribute("event");const r=m.parseNodeText(e);if(t&&r){if("progress"===t){if(i=e.getAttribute("offset"),!i)return;t="%"===i.charAt(i.length-1)?"progress-".concat(i):"progress-".concat(m.parseDuration(i));}Array.isArray(a.trackingEvents[t])||(a.trackingEvents[t]=[]),a.trackingEvents[t].push(r);}}));})),m.childrenByName(t,"MediaFiles").forEach((e=>{m.childrenByName(e,"MediaFile").forEach((e=>{a.mediaFiles.push(function(e){const t={id:null,fileURL:null,fileSize:0,deliveryType:"progressive",mimeType:null,mediaType:null,codec:null,bitrate:0,minBitrate:0,maxBitrate:0,width:0,height:0,apiFramework:null,scalable:null,maintainAspectRatio:null};t.id=e.getAttribute("id"),t.fileURL=m.parseNodeText(e),t.deliveryType=e.getAttribute("delivery"),t.codec=e.getAttribute("codec"),t.mimeType=e.getAttribute("type"),t.mediaType=e.getAttribute("mediaType")||"2D",t.apiFramework=e.getAttribute("apiFramework"),t.fileSize=parseInt(e.getAttribute("fileSize")||0),t.bitrate=parseInt(e.getAttribute("bitrate")||0),t.minBitrate=parseInt(e.getAttribute("minBitrate")||0),t.maxBitrate=parseInt(e.getAttribute("maxBitrate")||0),t.width=parseInt(e.getAttribute("width")||0),t.height=parseInt(e.getAttribute("height")||0);const r=e.getAttribute("scalable");r&&"string"==typeof r&&(t.scalable=m.parseBoolean(r));const i=e.getAttribute("maintainAspectRatio");i&&"string"==typeof i&&(t.maintainAspectRatio=m.parseBoolean(i));return t}(e));}));const t=m.childByName(e,"InteractiveCreativeFile");t&&(a.interactiveCreativeFile=function(e){const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {type:e.type||null,apiFramework:e.apiFramework||null,variableDuration:m.parseBoolean(e.variableDuration),fileURL:null}}(m.parseAttributes(e));return t.fileURL=m.parseNodeText(e),t}(t));const r=m.childByName(e,"ClosedCaptionFiles");r&&m.childrenByName(r,"ClosedCaptionFile").forEach((e=>{const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {type:e.type||null,language:e.language||null,fileURL:null}}(m.parseAttributes(e));t.fileURL=m.parseNodeText(e),a.closedCaptionFiles.push(t);}));const i=m.childByName(e,"Mezzanine"),s=function(e,t){const r={};let i=false;return t.forEach((t=>{e&&e.getAttribute(t)?r[t]=e.getAttribute(t):i=true;})),i?null:r}(i,["delivery","type","width","height"]);if(s){const e={id:null,fileURL:null,delivery:null,codec:null,type:null,width:0,height:0,fileSize:0,mediaType:"2D"};e.id=i.getAttribute("id"),e.fileURL=m.parseNodeText(i),e.delivery=s.delivery,e.codec=i.getAttribute("codec"),e.type=s.type,e.width=parseInt(s.width,10),e.height=parseInt(s.height,10),e.fileSize=parseInt(i.getAttribute("fileSize"),10),e.mediaType=i.getAttribute("mediaType")||"2D",a.mezzanine=e;}}));const l=m.childByName(t,"Icons");return l&&m.childrenByName(l,"Icon").forEach((e=>{a.icons.push(function(e){const t={program:null,height:0,width:0,xPosition:0,yPosition:0,apiFramework:null,offset:null,duration:0,type:null,staticResource:null,htmlResource:null,iframeResource:null,pxratio:"1",iconClickThroughURLTemplate:null,iconClickTrackingURLTemplates:[],iconViewTrackingURLTemplate:null,iconClickFallbackImages:[],altText:null,hoverText:null};t.program=e.getAttribute("program"),t.height=parseInt(e.getAttribute("height")||0),t.width=parseInt(e.getAttribute("width")||0),t.xPosition=function(e){if(-1!==["left","right"].indexOf(e))return e;return parseInt(e||0)}(e.getAttribute("xPosition")),t.yPosition=function(e){if(-1!==["top","bottom"].indexOf(e))return e;return parseInt(e||0)}(e.getAttribute("yPosition")),t.apiFramework=e.getAttribute("apiFramework"),t.pxratio=e.getAttribute("pxratio")||"1",t.offset=m.parseDuration(e.getAttribute("offset")),t.duration=m.parseDuration(e.getAttribute("duration")),t.altText=e.getAttribute("altText"),t.hoverText=e.getAttribute("hoverText"),m.childrenByName(e,"HTMLResource").forEach((e=>{t.type=e.getAttribute("creativeType")||"text/html",t.htmlResource=m.parseNodeText(e);})),m.childrenByName(e,"IFrameResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.iframeResource=m.parseNodeText(e);})),m.childrenByName(e,"StaticResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.staticResource=m.parseNodeText(e);}));const r=m.childByName(e,"IconClicks");if(r){t.iconClickThroughURLTemplate=m.parseNodeText(m.childByName(r,"IconClickThrough")),m.childrenByName(r,"IconClickTracking").forEach((e=>{t.iconClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});}));const e=m.childByName(r,"IconClickFallbackImages");e&&m.childrenByName(e,"IconClickFallbackImage").forEach((e=>{t.iconClickFallbackImages.push({url:m.parseNodeText(e)||null,width:e.getAttribute("width")||null,height:e.getAttribute("height")||null});}));}return t.iconViewTrackingURLTemplate=m.parseNodeText(m.childByName(e,"IconViewTracking")),t}(e));})),a}function f(t,r){const i=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"nonlinear",variations:[],trackingEvents:{}}}(r);return m.childrenByName(t,"TrackingEvents").forEach((e=>{let t,r;m.childrenByName(e,"Tracking").forEach((e=>{t=e.getAttribute("event"),r=m.parseNodeText(e),t&&r&&(Array.isArray(i.trackingEvents[t])||(i.trackingEvents[t]=[]),i.trackingEvents[t].push(r));}));})),m.childrenByName(t,"NonLinear").forEach((e=>{const t={id:null,width:0,height:0,expandedWidth:0,expandedHeight:0,scalable:true,maintainAspectRatio:true,minSuggestedDuration:0,apiFramework:"static",adType:"nonLinearAd",type:null,staticResource:null,htmlResource:null,iframeResource:null,nonlinearClickThroughURLTemplate:null,nonlinearClickTrackingURLTemplates:[],adParameters:null};t.id=e.getAttribute("id")||null,t.width=e.getAttribute("width"),t.height=e.getAttribute("height"),t.expandedWidth=e.getAttribute("expandedWidth"),t.expandedHeight=e.getAttribute("expandedHeight"),t.scalable=m.parseBoolean(e.getAttribute("scalable")),t.maintainAspectRatio=m.parseBoolean(e.getAttribute("maintainAspectRatio")),t.minSuggestedDuration=m.parseDuration(e.getAttribute("minSuggestedDuration")),t.apiFramework=e.getAttribute("apiFramework"),m.childrenByName(e,"HTMLResource").forEach((e=>{t.type=e.getAttribute("creativeType")||"text/html",t.htmlResource=m.parseNodeText(e);})),m.childrenByName(e,"IFrameResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.iframeResource=m.parseNodeText(e);})),m.childrenByName(e,"StaticResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.staticResource=m.parseNodeText(e);}));const r=m.childByName(e,"AdParameters");r&&(t.adParameters={value:m.parseNodeText(r),xmlEncoded:r.getAttribute("xmlEncoded")||null}),t.nonlinearClickThroughURLTemplate=m.parseNodeText(m.childByName(e,"NonLinearClickThrough")),m.childrenByName(e,"NonLinearClickTracking").forEach((e=>{t.nonlinearClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});})),i.variations.push(t);})),i}function T(e){const t=[];return e.forEach((e=>{const r=A(e);r&&t.push(r);})),t}function A(e){if("#comment"===e.nodeName)return null;const t={name:null,value:null,attributes:{},children:[]},r=e.attributes,i=e.childNodes;if(t.name=e.nodeName,e.attributes)for(const e in r)if(r.hasOwnProperty(e)){const i=r[e];i.nodeName&&i.nodeValue&&(t.attributes[i.nodeName]=i.nodeValue);}for(const e in i)if(i.hasOwnProperty(e)){const r=A(i[e]);r&&t.children.push(r);}if(0===t.children.length||1===t.children.length&&["#cdata-section","#text"].indexOf(t.children[0].name)>=0){const r=m.parseNodeText(e);""!==r&&(t.value=r),t.children=[];}return null===(a=t).value&&0===Object.keys(a.attributes).length&&0===a.children.length?null:t;var a;}function R(e){return e.getAttribute("AdID")||e.getAttribute("adID")||e.getAttribute("adId")||null}const k={Wrapper:{subElements:["VASTAdTagURI","Impression"]},BlockedAdCategories:{attributes:["authority"]},InLine:{subElements:["AdSystem","AdTitle","Impression","AdServingId","Creatives"]},Category:{attributes:["authority"]},Pricing:{attributes:["model","currency"]},Verification:{oneOfinLineResources:["JavaScriptResource","ExecutableResource"],attributes:["vendor"]},UniversalAdId:{attributes:["idRegistry"]},JavaScriptResource:{attributes:["apiFramework","browserOptional"]},ExecutableResource:{attributes:["apiFramework","type"]},Tracking:{attributes:["event"]},Creatives:{subElements:["Creative"]},Creative:{subElements:["UniversalAdId"]},Linear:{subElements:["MediaFiles","Duration"]},MediaFiles:{subElements:["MediaFile"]},MediaFile:{attributes:["delivery","type","width","height"]},Mezzanine:{attributes:["delivery","type","width","height"]},NonLinear:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"],attributes:["width","height"]},Companion:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"],attributes:["width","height"]},StaticResource:{attributes:["creativeType"]},Icons:{subElements:["Icon"]},Icon:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"]}};function y(e,t){if(!k[e.nodeName]||!k[e.nodeName].attributes)return;const r=k[e.nodeName].attributes.filter((t=>!e.getAttribute(t)));r.length>0&&N({name:e.nodeName,parentName:e.parentNode.nodeName,attributes:r},t);}function E(e,t,r){const i=k[e.nodeName],a=!r&&"Wrapper"!==e.nodeName;if(!i||a)return;if(i.subElements){const r=i.subElements.filter((t=>!m.childByName(e,t)));r.length>0&&N({name:e.nodeName,parentName:e.parentNode.nodeName,subElements:r},t);}if(!r||!i.oneOfinLineResources)return;i.oneOfinLineResources.some((t=>m.childByName(e,t)))||N({name:e.nodeName,parentName:e.parentNode.nodeName,oneOfResources:i.oneOfinLineResources},t);}function b(e){return e.children&&0!==e.children.length}function N(e,t){let{name:r,parentName:i,attributes:a,subElements:s,oneOfResources:n}=e,o="Element '".concat(r,"'");o+=a?" missing required attribute(s) '".concat(a.join(", "),"' "):s?" missing required sub element(s) '".concat(s.join(", "),"' "):n?" must provide one of the following '".concat(n.join(", "),"' "):" is empty",t("VAST-warning",{message:o,parentElement:i,specVersion:4.1});}const w={verifyRequiredValues:function e(t,r,i){if(t&&t.nodeName)if("InLine"===t.nodeName&&(i=true),y(t,r),b(t)){E(t,r,i);for(let a=0;a<t.children.length;a++)e(t.children[a],r,i);}else 0===m.parseNodeText(t).length&&N({name:t.nodeName,parentName:t.parentNode.nodeName},r);},hasSubElements:b,emitMissingValueWarning:N,verifyRequiredAttributes:y,verifyRequiredSubElements:E};function L(e,t){let{allowMultipleAds:r,followAdditionalWrappers:i}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=Array.from(e.childNodes).filter((e=>{const t=e.nodeName.toLowerCase();return "inline"===t||false!==i&&"wrapper"===t}));for(const i of a){if(m.copyNodeAttribute("id",e,i),m.copyNodeAttribute("sequence",e,i),m.copyNodeAttribute("adType",e,i),"Wrapper"===i.nodeName)return {ad:I(i,t),type:"WRAPPER"};if("InLine"===i.nodeName)return {ad:C(i,t,{allowMultipleAds:r}),type:"INLINE"};const a=i.nodeName.toLowerCase();t("VAST-warning",{message:"<".concat(i.nodeName,"inline"===a?"> must be written <InLine>":"> must be written <Wrapper>"),wrongNode:i});}}function C(e,t){let{allowMultipleAds:r}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return false===r&&e.getAttribute("sequence")?null:U(e,t)}function U(e,t){let r=[];t&&w.verifyRequiredValues(e,t);const i=Array.from(e.childNodes),a=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,sequence:e.sequence||null,adType:e.adType||null,adServingId:null,categories:[],expires:null,viewableImpression:[],system:null,title:null,description:null,advertiser:null,pricing:null,survey:null,errorURLTemplates:[],impressionURLTemplates:[],creatives:[],extensions:[],adVerifications:[],blockedAdCategories:[],followAdditionalWrappers:true,allowMultipleAds:false,fallbackOnNoAd:null}}(m.parseAttributes(e));return i.forEach((e=>{switch(e.nodeName){case "Error":a.errorURLTemplates.push(m.parseNodeText(e));break;case "Impression":a.impressionURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});break;case "Creatives":a.creatives=function(e){const t=[];return e.forEach((e=>{const r={id:e.getAttribute("id")||null,adId:R(e),sequence:e.getAttribute("sequence")||null,apiFramework:e.getAttribute("apiFramework")||null},i=[];let a;m.childrenByName(e,"UniversalAdId").forEach((e=>{const t={idRegistry:e.getAttribute("idRegistry")||"unknown",value:m.parseNodeText(e)};i.push(t);}));const s=m.childByName(e,"CreativeExtensions");s&&(a=T(m.childrenByName(s,"CreativeExtension")));for(const s in e.childNodes){const n=e.childNodes[s];let o;switch(n.nodeName){case "Linear":o=v(n,r);break;case "NonLinearAds":o=f(n,r);break;case "CompanionAds":o=g(n,r);}o&&(i&&(o.universalAdIds=i),a&&(o.creativeExtensions=a),t.push(o));}})),t}(m.childrenByName(e,"Creative"));break;case "Extensions":{const t=m.childrenByName(e,"Extension");a.extensions=T(t),a.adVerifications.length||(r=function(e){let t=null,r=[];e.some((e=>t=m.childByName(e,"AdVerifications"))),t&&(r=x(m.childrenByName(t,"Verification")));return r}(t));break}case "AdVerifications":a.adVerifications=x(m.childrenByName(e,"Verification"));break;case "AdSystem":a.system={value:m.parseNodeText(e),version:e.getAttribute("version")||null};break;case "AdTitle":a.title=m.parseNodeText(e);break;case "AdServingId":a.adServingId=m.parseNodeText(e);break;case "Category":a.categories.push({authority:e.getAttribute("authority")||null,value:m.parseNodeText(e)});break;case "Expires":a.expires=parseInt(m.parseNodeText(e),10);break;case "ViewableImpression":a.viewableImpression.push(function(e){const t=(e,t)=>{const r=m.parseNodeText(t);return r&&e.push(r),e};return {id:e.getAttribute("id")||null,viewable:m.childrenByName(e,"Viewable").reduce(t,[]),notViewable:m.childrenByName(e,"NotViewable").reduce(t,[]),viewUndetermined:m.childrenByName(e,"ViewUndetermined").reduce(t,[])}}(e));break;case "Description":a.description=m.parseNodeText(e);break;case "Advertiser":a.advertiser={id:e.getAttribute("id")||null,value:m.parseNodeText(e)};break;case "Pricing":a.pricing={value:m.parseNodeText(e),model:e.getAttribute("model")||null,currency:e.getAttribute("currency")||null};break;case "Survey":a.survey={value:m.parseNodeText(e),type:e.getAttribute("type")||null};break;case "BlockedAdCategories":a.blockedAdCategories.push({authority:e.getAttribute("authority")||null,value:m.parseNodeText(e)});}})),r.length&&(a.adVerifications=a.adVerifications.concat(r)),a}function I(e,t){const r=U(e,t),i=e.getAttribute("followAdditionalWrappers"),a=e.getAttribute("allowMultipleAds"),s=e.getAttribute("fallbackOnNoAd");r.followAdditionalWrappers=!i||m.parseBoolean(i),r.allowMultipleAds=!!a&&m.parseBoolean(a),r.fallbackOnNoAd=s?m.parseBoolean(s):null;let n=m.childByName(e,"VASTAdTagURI");if(n?r.nextWrapperURL=m.parseNodeText(n):(n=m.childByName(e,"VASTAdTagURL"),n&&(r.nextWrapperURL=m.parseNodeText(m.childByName(n,"URL")))),r.creatives.forEach((e=>{if(["linear","nonlinear"].includes(e.type)){if(e.trackingEvents){r.trackingEvents||(r.trackingEvents={}),r.trackingEvents[e.type]||(r.trackingEvents[e.type]={});for(const t in e.trackingEvents){const i=e.trackingEvents[t];Array.isArray(r.trackingEvents[e.type][t])||(r.trackingEvents[e.type][t]=[]),i.forEach((i=>{r.trackingEvents[e.type][t].push(i);}));}}e.videoClickTrackingURLTemplates&&(Array.isArray(r.videoClickTrackingURLTemplates)||(r.videoClickTrackingURLTemplates=[]),e.videoClickTrackingURLTemplates.forEach((e=>{r.videoClickTrackingURLTemplates.push(e);}))),e.videoClickThroughURLTemplate&&(r.videoClickThroughURLTemplate=e.videoClickThroughURLTemplate),e.videoCustomClickURLTemplates&&(Array.isArray(r.videoCustomClickURLTemplates)||(r.videoCustomClickURLTemplates=[]),e.videoCustomClickURLTemplates.forEach((e=>{r.videoCustomClickURLTemplates.push(e);})));}})),r.nextWrapperURL)return r}function x(e){const t=[];return e.forEach((e=>{const r={resource:null,vendor:null,browserOptional:false,apiFramework:null,type:null,parameters:null,trackingEvents:{}},i=Array.from(e.childNodes);m.assignAttributes(e.attributes,r),i.forEach((e=>{let{nodeName:t,textContent:i,attributes:a}=e;switch(t){case "JavaScriptResource":case "ExecutableResource":r.resource=i.trim(),m.assignAttributes(a,r);break;case "VerificationParameters":r.parameters=i.trim();}}));const a=m.childByName(e,"TrackingEvents");a&&m.childrenByName(a,"Tracking").forEach((e=>{const t=e.getAttribute("event"),i=m.parseNodeText(e);t&&i&&(Array.isArray(r.trackingEvents[t])||(r.trackingEvents[t]=[]),r.trackingEvents[t].push(i));})),t.push(r);})),t}class S{constructor(){this._handlers=[];}on(e,t){if("function"!=typeof t)throw new TypeError("The handler argument must be of type Function. Received type ".concat(typeof t));if(!e)throw new TypeError("The event argument must be of type String. Received type ".concat(typeof e));return this._handlers.push({event:e,handler:t}),this}once(e,t){return this.on(e,function(e,t,r){const i={fired:false,wrapFn:void 0};function a(){i.fired||(e.off(t,i.wrapFn),i.fired=true,r.bind(e)(...arguments));}return i.wrapFn=a,a}(this,e,t))}off(e,t){return this._handlers=this._handlers.filter((r=>r.event!==e||r.handler!==t)),this}emit(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),i=1;i<t;i++)r[i-1]=arguments[i];let a=false;return this._handlers.forEach((t=>{"*"===t.event&&(a=true,t.handler(e,...r)),t.event===e&&(a=true,t.handler(...r));})),a}removeAllListeners(e){return e?(this._handlers=this._handlers.filter((t=>t.event!==e)),this):(this._handlers=[],this)}listenerCount(e){return this._handlers.filter((t=>t.event===e)).length}listeners(e){return this._handlers.reduce(((t,r)=>(r.event===e&&t.push(r.handler),t)),[])}eventNames(){return this._handlers.map((e=>e.event))}}let V=0,D=0;const O=(e,t)=>{if(!e||!t||e<=0||t<=0)return;D=(D*V+8*e/t)/++V;},F={ERRORCODE:900,extensions:[]},P="VAST response version not supported";class B extends S{constructor(){let{fetcher:e}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};super(),this.maxWrapperDepth=null,this.rootErrorURLTemplates=[],this.errorURLTemplates=[],this.remainingAds=[],this.parsingOptions={},this.fetcher=e||null,this.keepFailedAdPod=false;}trackVastError(e,t){for(var r=arguments.length,i=new Array(r>2?r-2:0),a=2;a<r;a++)i[a-2]=arguments[a];this.emit("VAST-error",Object.assign({},F,t,...i)),u.track(e,t);}getErrorURLTemplates(){return this.rootErrorURLTemplates.concat(this.errorURLTemplates)}getEstimatedBitrate(){return D}initParsingStatus(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.maxWrapperDepth=e.wrapperLimit||10,this.parsingOptions={allowMultipleAds:e.allowMultipleAds},this.keepFailedAdPod=e.keepFailedAdPod||false,this.rootURL="",this.resetParsingStatus(),O(e.byteLength,e.requestDuration);}resetParsingStatus(){this.errorURLTemplates=[],this.rootErrorURLTemplates=[],this.vastVersion=null;}getRemainingAds(e){if(0===this.remainingAds.length)return Promise.reject(new Error("No more ads are available for the given VAST"));const t=e?this.remainingAds:[this.remainingAds.shift()];return this.errorURLTemplates=[],this.resolveAds(t,{wrapperDepth:0,url:this.rootURL}).then((e=>this.buildVASTResponse(e)))}parseVAST(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this.initParsingStatus(t),t.isRootVAST=true,this.parse(e,t).then((e=>this.buildVASTResponse(e)))}buildVASTResponse(e){const t=function(e){let{ads:t,errorURLTemplates:r,version:i}=e;return {ads:t||[],errorURLTemplates:r||[],version:i||null}}({ads:e,errorURLTemplates:this.getErrorURLTemplates(),version:this.vastVersion});return this.completeWrapperResolving(t),t}parseVastXml(e,t){let{isRootVAST:r=false,url:i=null,wrapperDepth:a=0,allowMultipleAds:s,followAdditionalWrappers:n}=t;if(!e||!e.documentElement||"VAST"!==e.documentElement.nodeName){var o;this.emit("VAST-ad-parsed",{type:"ERROR",url:i,wrapperDepth:a});const t="VideoAdServingTemplate"===(null==e||null===(o=e.documentElement)||void 0===o?void 0:o.nodeName);throw new Error(t?P:"Invalid VAST XMLDocument")}const l=[],c=e.documentElement.childNodes,d=e.documentElement.getAttribute("version");r&&d&&(this.vastVersion=d);for(const e in c){const t=c[e];if("Error"===t.nodeName){const e=m.parseNodeText(t);r?this.rootErrorURLTemplates.push(e):this.errorURLTemplates.push(e);}else if("Ad"===t.nodeName){if(this.vastVersion&&parseFloat(this.vastVersion)<3)s=true;else if(false===s&&l.length>1)break;const e=L(t,this.emit.bind(this),{allowMultipleAds:s,followAdditionalWrappers:n});e.ad?(l.push(e.ad),this.emit("VAST-ad-parsed",{type:e.type,url:i,wrapperDepth:a,adIndex:l.length-1,vastVersion:d})):this.trackVastError(this.getErrorURLTemplates(),{ERRORCODE:101});}}return l}parse(e){let{url:t=null,resolveAll:r=true,wrapperSequence:i=null,previousUrl:a=null,wrapperDepth:s=0,isRootVAST:n=false,followAdditionalWrappers:o,allowMultipleAds:l}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=[];this.vastVersion&&parseFloat(this.vastVersion)<3&&n&&(l=true);try{c=this.parseVastXml(e,{isRootVAST:n,url:t,wrapperDepth:s,allowMultipleAds:l,followAdditionalWrappers:o});}catch(e){return Promise.reject(e)}if(1===c.length&&null!=i&&(c[0].sequence=i),false===r){const e=m.getSortedAdPods(c),t=m.getStandAloneAds(c);e.length?c=e:t.length&&(c=[t.shift()]),this.remainingAds=t;}return this.resolveAds(c,{wrapperDepth:s,previousUrl:a,url:t})}resolveAds(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],{wrapperDepth:t,previousUrl:r,url:i}=arguments.length>1?arguments[1]:void 0;const a=[];return r=i,e.forEach((e=>{const i=this.resolveWrappers(e,t,r);a.push(i);})),Promise.all(a).then((e=>u.flatten(e)))}resolveWrappers(e,t,r){const i={...e};return new Promise((e=>{var a;if(t++,!i.nextWrapperURL)return delete i.nextWrapperURL,e(i);if(!this.fetcher)return i.VASTAdTagURI=i.nextWrapperURL,delete i.nextWrapperURL,e(i);if(t>=this.maxWrapperDepth)return i.errorCode=302,delete i.nextWrapperURL,e(i);i.nextWrapperURL=m.resolveVastAdTagURI(i.nextWrapperURL,r);const s=null!==(a=this.parsingOptions.allowMultipleAds)&&void 0!==a?a:i.allowMultipleAds,n=i.sequence;this.fetcher.fetchVAST({url:i.nextWrapperURL,emitter:this.emit.bind(this),maxWrapperDepth:this.maxWrapperDepth}).then((a=>this.parse(a,{url:i.nextWrapperURL,previousUrl:r,wrapperSequence:n,wrapperDepth:t,followAdditionalWrappers:i.followAdditionalWrappers,allowMultipleAds:s}).then((t=>{if(delete i.nextWrapperURL,0===t.length)return i.creatives=[],e(i);t.forEach((e=>{e&&m.mergeWrapperAdData(e,i);})),e(t);})))).catch((t=>{i.errorCode=t.message===P?102:301,i.errorMessage=t.message,e(i);}));}))}completeWrapperResolving(e){if(0===e.ads.length)this.trackVastError(e.errorURLTemplates,{ERRORCODE:303});else for(let t=e.ads.length-1;t>=0;t--){const r=e.ads[t],i=!r.creatives.some((e=>{var t,r;return (null===(t=e.mediaFiles)||void 0===t?void 0:t.length)>0||(null===(r=e.variations)||void 0===r?void 0:r.length)>0}));!r.errorCode&&!i||r.VASTAdTagURI||(this.trackVastError(r.errorURLTemplates.concat(e.errorURLTemplates),{ERRORCODE:r.errorCode||303},{ERRORMESSAGE:r.errorMessage||""},{extensions:r.extensions},{system:r.system}),this.keepFailedAdPod&&r.sequence?r.hasFailed=true:e.ads.splice(t,1));}}}let M=null;const W={data:{},length:0,getItem(e){return this.data[e]},setItem(e,t){this.data[e]=t,this.length=Object.keys(this.data).length;},removeItem(e){delete this.data[e],this.length=Object.keys(this.data).length;},clear(){this.data={},this.length=0;}};class j{constructor(){this.storage=this.initStorage();}initStorage(){if(M)return M;try{M="undefined"!=typeof window&&null!==window?window.localStorage||window.sessionStorage:null;}catch(e){M=null;}return M&&!this.isStorageDisabled(M)||(M=W,M.clear()),M}isStorageDisabled(e){const t="__VASTStorage__";try{if(e.setItem(t,t),e.getItem(t)!==t)return e.removeItem(t),!0}catch(e){return true}return e.removeItem(t),false}getItem(e){return this.storage.getItem(e)}setItem(e,t){return this.storage.setItem(e,t)}removeItem(e){return this.storage.removeItem(e)}clear(){return this.storage.clear()}}const q=12e4;const K={get:async function(e,t){try{const r=new AbortController,i=setTimeout((()=>{throw r.abort(),new Error("URLHandler: Request timed out after ".concat(t.timeout||q," ms (408)"))}),t.timeout||q),a=await fetch(e,{...t,signal:r.signal,credentials:t.withCredentials?"include":"omit"}).finally((()=>{clearTimeout(i);})),s=function(e){return u.isBrowserEnvironment()&&"https:"===window.location.protocol&&e.url.includes("http://")?"URLHandler: Cannot go from HTTPS to HTTP.":200===e.status&&e.ok?null:"URLHandler: ".concat(e.statusText," (").concat(e.status,")")}(a);return s?{error:new Error(s),statusCode:a.status}:async function(e){const t=await e.text();let r;r=u.isBrowserEnvironment()?new DOMParser:new((await Promise.resolve().then(function () { return index$1; })).DOMParser);return {xml:r.parseFromString(t,"text/xml"),details:{byteLength:t.length,statusCode:e.status,rawXml:t}}}(a)}catch(e){return {error:e,statusCode:"AbortError"===e.name?408:null}}}};class H{constructor(){this.URLTemplateFilters=[];}setOptions(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.urlHandler=e.urlHandler||e.urlhandler||K,this.fetchingOptions={...e.fetchOptions,timeout:e.timeout||q,withCredentials:Boolean(e.withCredentials)};}addURLTemplateFilter(e){"function"==typeof e&&this.URLTemplateFilters.push(e);}removeLastURLTemplateFilter(){this.URLTemplateFilters.pop();}countURLTemplateFilters(){return this.URLTemplateFilters.length}clearURLTemplateFilters(){this.URLTemplateFilters=[];}async fetchVAST(e){var t;let{url:r,maxWrapperDepth:i,emitter:a,wrapperDepth:s=0,previousUrl:n=null,wrapperAd:o=null}=e;const l=Date.now();this.URLTemplateFilters.forEach((e=>{r=e(r);})),a("VAST-resolving",{url:r,previousUrl:n,wrapperDepth:s,maxWrapperDepth:i,timeout:this.fetchingOptions.timeout,wrapperAd:o});const c=await this.urlHandler.get(r,this.fetchingOptions),d=Math.round(Date.now()-l);if(a("VAST-resolved",{url:r,previousUrl:n,wrapperDepth:s,error:(null==c?void 0:c.error)||null,duration:d,statusCode:(null==c?void 0:c.statusCode)||null,...null==c?void 0:c.details}),O(null==c||null===(t=c.details)||void 0===t?void 0:t.byteLength,d),c.error)throw new Error(c.error);return c.xml}}class _{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:new j;this.cappingFreeLunch=e,this.cappingMinimumTimeInterval=t,this.fetcher=new H,this.vastParser=new B({fetcher:this.fetcher}),this.storage=r,void 0===this.lastSuccessfulAd&&(this.lastSuccessfulAd=0),void 0===this.totalCalls&&(this.totalCalls=0),void 0===this.totalCallsTimeout&&(this.totalCallsTimeout=0);}addURLTemplateFilter(e){this.fetcher.addURLTemplateFilter(e);}removeLastURLTemplateFilter(){this.fetcher.removeLastURLTemplateFilter();}countURLTemplateFilters(){return this.fetcher.countURLTemplateFilters()}clearURLTemplateFilters(){this.fetcher.clearURLTemplateFilters();}getParser(){return this.vastParser}get lastSuccessfulAd(){return this.storage.getItem("vast-client-last-successful-ad")}set lastSuccessfulAd(e){this.storage.setItem("vast-client-last-successful-ad",e);}get totalCalls(){return this.storage.getItem("vast-client-total-calls")}set totalCalls(e){this.storage.setItem("vast-client-total-calls",e);}get totalCallsTimeout(){return this.storage.getItem("vast-client-total-calls-timeout")}set totalCallsTimeout(e){this.storage.setItem("vast-client-total-calls-timeout",e);}hasRemainingAds(){return this.vastParser.remainingAds.length>0}getNextAds(e){return this.vastParser.getRemainingAds(e)}parseVAST(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this.fetcher.setOptions(t),this.vastParser.parseVAST(e,t)}get(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=Date.now();return t.hasOwnProperty("resolveAll")||(t.resolveAll=false),this.totalCallsTimeout<r?(this.totalCalls=1,this.totalCallsTimeout=r+36e5):this.totalCalls++,new Promise(((i,a)=>{if(this.cappingFreeLunch>=this.totalCalls)return a(new Error("VAST call canceled – FreeLunch capping not reached yet ".concat(this.totalCalls,"/").concat(this.cappingFreeLunch)));const s=r-this.lastSuccessfulAd;if(s<0)this.lastSuccessfulAd=0;else if(s<this.cappingMinimumTimeInterval)return a(new Error("VAST call canceled – (".concat(this.cappingMinimumTimeInterval,")ms minimum interval reached")));this.vastParser.initParsingStatus(t),this.fetcher.setOptions(t),this.vastParser.rootURL=e,this.fetcher.fetchVAST({url:e,emitter:this.vastParser.emit.bind(this.vastParser),maxWrapperDepth:this.vastParser.maxWrapperDepth}).then((r=>(t.previousUrl=e,t.isRootVAST=true,t.url=e,this.vastParser.parse(r,t).then((e=>{const t=this.vastParser.buildVASTResponse(e);i(t);}))))).catch((e=>a(e)));}))}}class z extends S{constructor(e,t,r){var i;let a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,s=arguments.length>4&&void 0!==arguments[4]&&arguments[4];super(),this.ad=t,this.creative=r,this.variation=a,this.muted=s,this.impressed=false,this.skippable=false,this.trackingEvents={},this.trackedProgressEvents=[],this.lastPercentage=0,this._alreadyTriggeredQuartiles={},this.emitAlwaysEvents=["creativeView","start","firstQuartile","midpoint","thirdQuartile","complete","resume","pause","rewind","skip","closeLinear","close"];for(const e in this.creative.trackingEvents){const t=this.creative.trackingEvents[e];this.trackingEvents[e]=t.slice(0);}this.viewableImpressionTrackers=(null===(i=this.ad.viewableImpression)||void 0===i?void 0:i.reduce(((e,t)=>(e.notViewable.push(...t.notViewable),e.viewUndetermined.push(...t.viewUndetermined),e.viewable.push(...t.viewable),e)),{notViewable:[],viewUndetermined:[],viewable:[]}))||{},Object.entries(this.viewableImpressionTrackers).forEach((e=>{let[t,r]=e;r.length&&(this.trackingEvents[t]=r);})),!function(e){return "linear"===e.type}(this.creative)?this._initVariationTracking():this._initLinearTracking(),e&&this.on("start",(()=>{e.lastSuccessfulAd=Date.now();}));}_initLinearTracking(){this.linear=true,this.skipDelay=this.creative.skipDelay,this.setDuration(this.creative.duration),this.clickThroughURLTemplate=this.creative.videoClickThroughURLTemplate,this.clickTrackingURLTemplates=this.creative.videoClickTrackingURLTemplates;}_initVariationTracking(){if(this.linear=false,this.skipDelay=-1,this.variation){for(const e in this.variation.trackingEvents){const t=this.variation.trackingEvents[e];this.trackingEvents[e]?this.trackingEvents[e]=this.trackingEvents[e].concat(t.slice(0)):this.trackingEvents[e]=t.slice(0);}"nonLinearAd"===this.variation.adType?(this.clickThroughURLTemplate=this.variation.nonlinearClickThroughURLTemplate,this.clickTrackingURLTemplates=this.variation.nonlinearClickTrackingURLTemplates,this.setDuration(this.variation.minSuggestedDuration)):function(e){return "companionAd"===e.adType}(this.variation)&&(this.clickThroughURLTemplate=this.variation.companionClickThroughURLTemplate,this.clickTrackingURLTemplates=this.variation.companionClickTrackingURLTemplates);}}setDuration(e){u.isValidTimeValue(e)?(this.assetDuration=e,this.quartiles={firstQuartile:Math.round(25*this.assetDuration)/100,midpoint:Math.round(50*this.assetDuration)/100,thirdQuartile:Math.round(75*this.assetDuration)/100}):this.emit("TRACKER-error",{message:"the duration provided is not valid. duration: ".concat(e)});}setProgress(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(!u.isValidTimeValue(e)||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given setProgress parameter has the wrong type. progress: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});const i=this.skipDelay||-1;if(-1===i||this.skippable||(i>e?this.emit("skip-countdown",i-e):(this.skippable=true,this.emit("skip-countdown",0))),this.assetDuration>0){const i=Math.round(e/this.assetDuration*100),a=[];if(e>0){a.push("start");for(let e=this.lastPercentage;e<i;e++)a.push("progress-".concat(e+1,"%"));a.push("progress-".concat(e));for(const t in this.quartiles)this.isQuartileReached(t,this.quartiles[t],e)&&(a.push(t),this._alreadyTriggeredQuartiles[t]=true);this.lastPercentage=i;}a.forEach((e=>{this.track(e,{macros:t,once:r});})),e<this.progress&&(this.track("rewind",{macros:t}),this.trackedProgressEvents&&this.trackedProgressEvents.splice(0));}this.progress=e;}isQuartileReached(e,t,r){let i=false;return t<=r&&!this._alreadyTriggeredQuartiles[e]&&(i=true),i}setMuted(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.muted!==e&&this.track(e?"mute":"unmute",{macros:t}),this.muted=e):this.emit("TRACKER-error",{message:"One given setMuted parameter has the wrong type. muted: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setPaused(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.paused!==e&&this.track(e?"pause":"resume",{macros:t}),this.paused=e):this.emit("TRACKER-error",{message:"One given setPaused parameter has the wrong type. paused: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setFullscreen(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.fullscreen!==e&&this.track(e?"fullscreen":"exitFullscreen",{macros:t}),this.fullscreen=e):this.emit("TRACKER-error",{message:"One given setFullScreen parameter has the wrong type. fullscreen: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setExpand(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.expanded!==e&&(this.track(e?"expand":"collapse",{macros:t}),this.track(e?"playerExpand":"playerCollapse",{macros:t})),this.expanded=e):this.emit("TRACKER-error",{message:"One given setExpand parameter has the wrong type. expanded: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setSkipDelay(e){u.isValidTimeValue(e)?this.skipDelay=e:this.emit("TRACKER-error",{message:"setSkipDelay parameter does not have a valid value. duration: ".concat(e)});}trackImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.impressed||(this.impressed=true,this.trackURLs(this.ad.impressionURLTemplates,e),this.track("creativeView",{macros:e})):this.emit("TRACKER-error",{message:"trackImpression parameter has the wrong type. macros: ".concat(e)});}trackViewableImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("viewable",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackViewableImpression given macros has the wrong type. macros: ".concat(e)});}trackNotViewableImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("notViewable",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackNotViewableImpression given macros has the wrong type. macros: ".concat(e)});}trackUndeterminedImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("viewUndetermined",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackUndeterminedImpression given macros has the wrong type. macros: ".concat(e)});}error(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e&&"boolean"==typeof t?this.trackURLs(this.ad.errorURLTemplates,e,{isCustomCode:t}):this.emit("TRACKER-error",{message:"One given error parameter has the wrong type. macros: ".concat(u.formatMacrosValues(e),", isCustomCode: ").concat(t)});}errorWithCode(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"string"==typeof e&&"boolean"==typeof t?(this.error({ERRORCODE:e},t),console.log("The method errorWithCode is deprecated, please use vast tracker error method instead")):this.emit("TRACKER-error",{message:"One given errorWithCode parameter has the wrong type. errorCode: ".concat(e,", isCustomCode: ").concat(t)});}complete(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("complete",{macros:e}):this.emit("TRACKER-error",{message:"complete given macros has the wrong type. macros: ".concat(e)});}notUsed(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?(this.track("notUsed",{macros:e}),this.trackingEvents=[]):this.emit("TRACKER-error",{message:"notUsed given macros has the wrong type. macros: ".concat(e)});}otherAdInteraction(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("otherAdInteraction",{macros:e}):this.emit("TRACKER-error",{message:"otherAdInteraction given macros has the wrong type. macros: ".concat(e)});}acceptInvitation(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("acceptInvitation",{macros:e}):this.emit("TRACKER-error",{message:"acceptInvitation given macros has the wrong type. macros: ".concat(e)});}adExpand(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("adExpand",{macros:e}):this.emit("TRACKER-error",{message:"adExpand given macros has the wrong type. macros: ".concat(e)});}adCollapse(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("adCollapse",{macros:e}):this.emit("TRACKER-error",{message:"adCollapse given macros has the wrong type. macros: ".concat(e)});}minimize(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("minimize",{macros:e}):this.emit("TRACKER-error",{message:"minimize given macros has the wrong type. macros: ".concat(e)});}verificationNotExecuted(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("string"!=typeof e||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given verificationNotExecuted parameter has to wrong type. vendor: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});if(!this.ad||!this.ad.adVerifications||!this.ad.adVerifications.length)throw new Error("No adVerifications provided");if(!e)throw new Error("No vendor provided, unable to find associated verificationNotExecuted");const r=this.ad.adVerifications.find((t=>t.vendor===e));if(!r)throw new Error("No associated verification element found for vendor: ".concat(e));const i=r.trackingEvents;if(i&&i.verificationNotExecuted){const e=i.verificationNotExecuted;this.trackURLs(e,t),this.emit("verificationNotExecuted",{trackingURLTemplates:e});}}overlayViewDuration(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"string"==typeof e&&"object"==typeof t?(t.ADPLAYHEAD=e,this.track("overlayViewDuration",{macros:t})):this.emit("TRACKER-error",{message:"One given overlayViewDuration parameters has the wrong type. formattedDuration: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}close(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track(this.linear?"closeLinear":"close",{macros:e}):this.emit("TRACKER-error",{message:"close given macros has the wrong type. macros: ".concat(e)});}skip(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("skip",{macros:e}):this.emit("TRACKER-error",{message:"skip given macros has the wrong type. macros: ".concat(e)});}load(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("loaded",{macros:e}):this.emit("TRACKER-error",{message:"load given macros has the wrong type. macros: ".concat(e)});}click(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(null!==e&&"string"!=typeof e||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given click parameter has the wrong type. fallbackClickThroughURL: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});this.clickTrackingURLTemplates&&this.clickTrackingURLTemplates.length&&this.trackURLs(this.clickTrackingURLTemplates,t);const r=this.clickThroughURLTemplate||e,i={...t};if(r){this.progress&&(i.ADPLAYHEAD=this.progressFormatted());const e=u.resolveURLTemplates([r],i)[0];this.emit("clickthrough",e);}}trackProgressEvents(e,t,r){const i=parseFloat(e.split("-")[1]);Object.entries(this.trackingEvents).filter((e=>{let[t]=e;return t.startsWith("progress-")})).map((e=>{let[t,r]=e;return {name:t,time:parseFloat(t.split("-")[1]),urls:r}})).filter((e=>{let{time:t}=e;return t<=i&&t>this.progress})).forEach((e=>{let{name:i,urls:a}=e;!r&&this.trackedProgressEvents.includes(i)||(this.emit(i,{trackingURLTemplates:a}),this.trackURLs(a,t),r?delete this.trackingEvents[i]:this.trackedProgressEvents.push(i));}));}track(e){let{macros:t={},once:r=false}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("object"!=typeof t)return void this.emit("TRACKER-error",{message:"track given macros has the wrong type. macros: ".concat(t)});"closeLinear"===e&&!this.trackingEvents[e]&&this.trackingEvents.close&&(e="close"),e.startsWith("progress-")&&!e.endsWith("%")&&this.trackProgressEvents(e,t,r);const i=this.trackingEvents[e],a=this.emitAlwaysEvents.indexOf(e)>-1;i?(this.emit(e,{trackingURLTemplates:i}),this.trackURLs(i,t)):a&&this.emit(e,null),r&&(delete this.trackingEvents[e],a&&this.emitAlwaysEvents.splice(this.emitAlwaysEvents.indexOf(e),1));}trackURLs(e){var t;let r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{validUrls:a,invalidUrls:s}=u.filterUrlTemplates(e);s.length&&this.emit("TRACKER-error",{message:"Provided urls are malformed. url: ".concat(s)});const n={...r};this.linear&&(this.creative&&this.creative.mediaFiles&&this.creative.mediaFiles[0]&&this.creative.mediaFiles[0].fileURL&&(n.ASSETURI=this.creative.mediaFiles[0].fileURL),this.progress&&(n.ADPLAYHEAD=this.progressFormatted())),null!==(t=this.creative)&&void 0!==t&&null!==(t=t.universalAdIds)&&void 0!==t&&t.length&&(n.UNIVERSALADID=this.creative.universalAdIds.map((e=>e.idRegistry.concat(" ",e.value))).join(",")),this.ad&&(this.ad.sequence&&(n.PODSEQUENCE=this.ad.sequence),this.ad.adType&&(n.ADTYPE=this.ad.adType),this.ad.adServingId&&(n.ADSERVINGID=this.ad.adServingId),this.ad.categories&&this.ad.categories.length&&(n.ADCATEGORIES=this.ad.categories.map((e=>e.value)).join(",")),this.ad.blockedAdCategories&&this.ad.blockedAdCategories.length&&(n.BLOCKEDADCATEGORIES=this.ad.blockedAdCategories.map((e=>e.value)).join(","))),u.track(a,n,i);}convertToTimecode(e){if(!u.isValidTimeValue(e))return "";const t=1e3*e,r=Math.floor(t/36e5),i=Math.floor(t/6e4%60),a=Math.floor(t/1e3%60),s=Math.floor(t%1e3);return "".concat(u.addLeadingZeros(r,2),":").concat(u.addLeadingZeros(i,2),":").concat(u.addLeadingZeros(a,2),".").concat(u.addLeadingZeros(s,3))}progressFormatted(){return this.convertToTimecode(this.progress)}}
|
|
18
|
+
function e$1(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,adId:e.adId||null,sequence:e.sequence||null,apiFramework:e.apiFramework||null,universalAdIds:[],creativeExtensions:[]}}const t$1=["ADCATEGORIES","ADCOUNT","ADPLAYHEAD","ADSERVINGID","ADTYPE","APIFRAMEWORKS","APPBUNDLE","ASSETURI","BLOCKEDADCATEGORIES","BREAKMAXADLENGTH","BREAKMAXADS","BREAKMAXDURATION","BREAKMINADLENGTH","BREAKMINDURATION","BREAKPOSITION","CLICKPOS","CLICKTYPE","CLIENTUA","CONTENTID","CONTENTPLAYHEAD","CONTENTURI","DEVICEIP","DEVICEUA","DOMAIN","EXTENSIONS","GDPRCONSENT","IFA","IFATYPE","INVENTORYSTATE","LATLONG","LIMITADTRACKING","MEDIAMIME","MEDIAPLAYHEAD","OMIDPARTNER","PAGEURL","PLACEMENTTYPE","PLAYERCAPABILITIES","PLAYERSIZE","PLAYERSTATE","PODSEQUENCE","REGULATIONS","SERVERSIDE","SERVERUA","TRANSACTIONID","UNIVERSALADID","VASTVERSIONS","VERIFICATIONVENDORS"];function r$1(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=[],n=s$1(e);!t.ERRORCODE||r.isCustomCode||/^[0-9]{3}$/.test(t.ERRORCODE)||(t.ERRORCODE=900),t.CACHEBUSTING=d(Math.round(1e8*Math.random())),t.TIMESTAMP=(new Date).toISOString(),t.RANDOM=t.random=t.CACHEBUSTING;for(const e in t)t[e]=c(t[e]);for(const e in n){const r=n[e];"string"==typeof r&&a.push(i$1(r,t));}return a}function i$1(e,r){const i=(e=a$1(e,r)).match(/[^[\]]+(?=])/g);if(!i)return e;let s=i.filter((e=>t$1.indexOf(e)>-1));return 0===s.length?e:(s=s.reduce(((e,t)=>(e[t]=-1,e)),{}),a$1(e,s))}function a$1(e,t){let r=e;for(const e in t){const i=t[e];r=r.replace(new RegExp("(?:\\[|%%)(".concat(e,")(?:\\]|%%)"),"g"),i);}return r}function s$1(e){return Array.isArray(e)?e.map((e=>e&&e.hasOwnProperty("url")?e.url:e)):e}function n$1(e){return /^(https?:\/\/|\/\/)/.test(e)}function o$1(e,t){for(let r=0;r<t.length;r++)if(l(t[r],e))return true;return false}function l(e,t){if(e&&t){const r=Object.getOwnPropertyNames(e),i=Object.getOwnPropertyNames(t);return r.length===i.length&&(e.id===t.id&&e.url===t.url)}return false}function c(e){return encodeURIComponent(e).replace(/[!'()*]/g,(e=>"%".concat(e.charCodeAt(0).toString(16))))}function d(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:8;return e.toString().padStart(t,"0")}const u={track:function(e,t,i){r$1(e,t,i).forEach((e=>{if("undefined"!=typeof window&&null!==window){(new Image).src=e;}}));},resolveURLTemplates:r$1,extractURLsFromTemplates:s$1,filterUrlTemplates:function(e){return e.reduce(((e,t)=>{const r=t.url||t;return n$1(r)?e.validUrls.push(r):e.invalidUrls.push(r),e}),{validUrls:[],invalidUrls:[]})},containsTemplateObject:o$1,isTemplateObjectEqual:l,encodeURIComponentRFC3986:c,replaceUrlMacros:i$1,isNumeric:function(e){return !isNaN(parseFloat(e))&&isFinite(e)},flatten:function e(t){return t.reduce(((t,r)=>t.concat(Array.isArray(r)?e(r):r)),[])},joinArrayOfUniqueTemplateObjs:function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];const r=Array.isArray(e)?e:[],i=Array.isArray(t)?t:[];return r.concat(i).reduce(((e,t)=>(o$1(t,e)||e.push(t),e)),[])},isValidTimeValue:function(e){return Number.isFinite(e)&&e>=-2},addLeadingZeros:d,isValidUrl:n$1,isBrowserEnvironment:function(){return "undefined"!=typeof window},formatMacrosValues:function(e){return "object"!=typeof e?e:JSON.stringify(e)}};function h(e){return ["true","TRUE","True","1"].includes(e)}function p(e){if(null==e)return -1;if(u.isNumeric(e))return parseInt(e);const t=e.split(":");if(3!==t.length)return -1;const r=t[2].split(".");let i=parseInt(r[0]);2===r.length&&(i+=parseFloat("0.".concat(r[1])));const a=parseInt(60*t[1]),s=parseInt(60*t[0]*60);return isNaN(s)||isNaN(a)||isNaN(i)||a>3600||i>60?-1:s+a+i}const m={childByName:function(e,t){return Array.from(e.childNodes).find((e=>e.nodeName===t))},childrenByName:function(e,t){return Array.from(e.childNodes).filter((e=>e.nodeName===t))},resolveVastAdTagURI:function(e,t){if(!t)return e;if(e.startsWith("//")){const{protocol:t}=location;return "".concat(t).concat(e)}if(!e.includes("://")){const r=t.slice(0,t.lastIndexOf("/"));return "".concat(r,"/").concat(e)}return e},parseBoolean:h,parseNodeText:function(e){return e&&(e.textContent||e.text||"").trim()},copyNodeAttribute:function(e,t,r){const i=t.getAttribute(e);i&&r.setAttribute(e,i);},parseAttributes:function(e){return Array.from(e.attributes).reduce(((e,t)=>(e[t.nodeName]=t.nodeValue,e)),{})},parseDuration:p,getStandAloneAds:function(){return (arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).filter((e=>!parseInt(e.sequence,10)))},getSortedAdPods:function(){return (arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]).filter((e=>parseInt(e.sequence,10))).sort(((e,t)=>e.sequence-t.sequence))},assignAttributes:function(e,t){e&&Array.from(e).forEach((e=>{let{nodeName:r,nodeValue:i}=e;if(r&&i&&t.hasOwnProperty(r)){let e=i;"boolean"==typeof t[r]&&(e=h(e)),t[r]=e;}}));},mergeWrapperAdData:function(e,t){var r;e.errorURLTemplates=t.errorURLTemplates.concat(e.errorURLTemplates),e.impressionURLTemplates=t.impressionURLTemplates.concat(e.impressionURLTemplates),e.extensions=t.extensions.concat(e.extensions),t.viewableImpression.length>0&&(e.viewableImpression=[...e.viewableImpression,...t.viewableImpression]),e.followAdditionalWrappers=t.followAdditionalWrappers,e.allowMultipleAds=t.allowMultipleAds,e.fallbackOnNoAd=t.fallbackOnNoAd;const i=(t.creatives||[]).filter((e=>e&&"companion"===e.type)),a=i.reduce(((e,t)=>((t.variations||[]).forEach((t=>{(t.companionClickTrackingURLTemplates||[]).forEach((t=>{u.containsTemplateObject(t,e)||e.push(t);}));})),e)),[]);e.creatives=i.concat(e.creatives);const s=t.videoClickTrackingURLTemplates&&t.videoClickTrackingURLTemplates.length,n=t.videoCustomClickURLTemplates&&t.videoCustomClickURLTemplates.length;if(e.creatives.forEach((e=>{if(t.trackingEvents&&t.trackingEvents[e.type])for(const r in t.trackingEvents[e.type]){const i=t.trackingEvents[e.type][r];Array.isArray(e.trackingEvents[r])||(e.trackingEvents[r]=[]),e.trackingEvents[r]=e.trackingEvents[r].concat(i);}"linear"===e.type&&(s&&(e.videoClickTrackingURLTemplates=e.videoClickTrackingURLTemplates.concat(t.videoClickTrackingURLTemplates)),n&&(e.videoCustomClickURLTemplates=e.videoCustomClickURLTemplates.concat(t.videoCustomClickURLTemplates)),!t.videoClickThroughURLTemplate||null!==e.videoClickThroughURLTemplate&&void 0!==e.videoClickThroughURLTemplate||(e.videoClickThroughURLTemplate=t.videoClickThroughURLTemplate)),"companion"===e.type&&a.length&&(e.variations||[]).forEach((e=>{e.companionClickTrackingURLTemplates=u.joinArrayOfUniqueTemplateObjs(e.companionClickTrackingURLTemplates,a);}));})),t.adVerifications&&(e.adVerifications=e.adVerifications.concat(t.adVerifications)),t.blockedAdCategories&&(e.blockedAdCategories=e.blockedAdCategories.concat(t.blockedAdCategories)),null!==(r=t.creatives)&&void 0!==r&&r.length){const r=t.creatives.filter((e=>{var t;return (null===(t=e.icons)||void 0===t?void 0:t.length)&&!e.mediaFiles.length}));r.length&&(e.creatives=e.creatives.concat(r));}}};function g(t,r){const i=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"companion",required:null,variations:[]}}(r);return i.required=t.getAttribute("required")||null,i.variations=m.childrenByName(t,"Companion").map((e=>{const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,adType:"companionAd",width:e.width||0,height:e.height||0,assetWidth:e.assetWidth||null,assetHeight:e.assetHeight||null,expandedWidth:e.expandedWidth||null,expandedHeight:e.expandedHeight||null,apiFramework:e.apiFramework||null,adSlotId:e.adSlotId||null,pxratio:e.pxratio||"1",renderingMode:e.renderingMode||"default",staticResources:[],htmlResources:[],iframeResources:[],adParameters:null,altText:null,companionClickThroughURLTemplate:null,companionClickTrackingURLTemplates:[],trackingEvents:{}}}(m.parseAttributes(e));t.htmlResources=m.childrenByName(e,"HTMLResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat(r):e}),[]),t.iframeResources=m.childrenByName(e,"IFrameResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat(r):e}),[]),t.staticResources=m.childrenByName(e,"StaticResource").reduce(((e,t)=>{const r=m.parseNodeText(t);return r?e.concat({url:r,creativeType:t.getAttribute("creativeType")||null}):e}),[]),t.altText=m.parseNodeText(m.childByName(e,"AltText"))||null;const r=m.childByName(e,"TrackingEvents");r&&m.childrenByName(r,"Tracking").forEach((e=>{const r=e.getAttribute("event"),i=m.parseNodeText(e);r&&i&&(Array.isArray(t.trackingEvents[r])||(t.trackingEvents[r]=[]),t.trackingEvents[r].push(i));})),t.companionClickTrackingURLTemplates=m.childrenByName(e,"CompanionClickTracking").map((e=>({id:e.getAttribute("id")||null,url:m.parseNodeText(e)}))),t.companionClickThroughURLTemplate=m.parseNodeText(m.childByName(e,"CompanionClickThrough"))||null;const i=m.childByName(e,"AdParameters");return i&&(t.adParameters={value:m.parseNodeText(i),xmlEncoded:i.getAttribute("xmlEncoded")||null}),t})),i}function v(t,r){let i;const a=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"linear",duration:0,skipDelay:null,mediaFiles:[],mezzanine:null,interactiveCreativeFile:null,closedCaptionFiles:[],videoClickThroughURLTemplate:null,videoClickTrackingURLTemplates:[],videoCustomClickURLTemplates:[],adParameters:null,icons:[],trackingEvents:{}}}(r);a.duration=m.parseDuration(m.parseNodeText(m.childByName(t,"Duration")));const s=t.getAttribute("skipoffset");if(null==s)a.skipDelay=null;else if("%"===s.charAt(s.length-1)&&-1!==a.duration){const e=parseInt(s,10);a.skipDelay=a.duration*(e/100);}else a.skipDelay=m.parseDuration(s);const n=m.childByName(t,"VideoClicks");if(n){const e=m.childByName(n,"ClickThrough");a.videoClickThroughURLTemplate=e?{id:e.getAttribute("id")||null,url:m.parseNodeText(e)}:null,m.childrenByName(n,"ClickTracking").forEach((e=>{a.videoClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});})),m.childrenByName(n,"CustomClick").forEach((e=>{a.videoCustomClickURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});}));}const o=m.childByName(t,"AdParameters");o&&(a.adParameters={value:m.parseNodeText(o),xmlEncoded:o.getAttribute("xmlEncoded")||null}),m.childrenByName(t,"TrackingEvents").forEach((e=>{m.childrenByName(e,"Tracking").forEach((e=>{let t=e.getAttribute("event");const r=m.parseNodeText(e);if(t&&r){if("progress"===t){if(i=e.getAttribute("offset"),!i)return;t="%"===i.charAt(i.length-1)?"progress-".concat(i):"progress-".concat(m.parseDuration(i));}Array.isArray(a.trackingEvents[t])||(a.trackingEvents[t]=[]),a.trackingEvents[t].push(r);}}));})),m.childrenByName(t,"MediaFiles").forEach((e=>{m.childrenByName(e,"MediaFile").forEach((e=>{a.mediaFiles.push(function(e){const t={id:null,fileURL:null,fileSize:0,deliveryType:"progressive",mimeType:null,mediaType:null,codec:null,bitrate:0,minBitrate:0,maxBitrate:0,width:0,height:0,apiFramework:null,scalable:null,maintainAspectRatio:null};t.id=e.getAttribute("id"),t.fileURL=m.parseNodeText(e),t.deliveryType=e.getAttribute("delivery"),t.codec=e.getAttribute("codec"),t.mimeType=e.getAttribute("type"),t.mediaType=e.getAttribute("mediaType")||"2D",t.apiFramework=e.getAttribute("apiFramework"),t.fileSize=parseInt(e.getAttribute("fileSize")||0),t.bitrate=parseInt(e.getAttribute("bitrate")||0),t.minBitrate=parseInt(e.getAttribute("minBitrate")||0),t.maxBitrate=parseInt(e.getAttribute("maxBitrate")||0),t.width=parseInt(e.getAttribute("width")||0),t.height=parseInt(e.getAttribute("height")||0);const r=e.getAttribute("scalable");r&&"string"==typeof r&&(t.scalable=m.parseBoolean(r));const i=e.getAttribute("maintainAspectRatio");i&&"string"==typeof i&&(t.maintainAspectRatio=m.parseBoolean(i));return t}(e));}));const t=m.childByName(e,"InteractiveCreativeFile");t&&(a.interactiveCreativeFile=function(e){const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {type:e.type||null,apiFramework:e.apiFramework||null,variableDuration:m.parseBoolean(e.variableDuration),fileURL:null}}(m.parseAttributes(e));return t.fileURL=m.parseNodeText(e),t}(t));const r=m.childByName(e,"ClosedCaptionFiles");r&&m.childrenByName(r,"ClosedCaptionFile").forEach((e=>{const t=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {type:e.type||null,language:e.language||null,fileURL:null}}(m.parseAttributes(e));t.fileURL=m.parseNodeText(e),a.closedCaptionFiles.push(t);}));const i=m.childByName(e,"Mezzanine"),s=function(e,t){const r={};let i=false;return t.forEach((t=>{e&&e.getAttribute(t)?r[t]=e.getAttribute(t):i=true;})),i?null:r}(i,["delivery","type","width","height"]);if(s){const e={id:null,fileURL:null,delivery:null,codec:null,type:null,width:0,height:0,fileSize:0,mediaType:"2D"};e.id=i.getAttribute("id"),e.fileURL=m.parseNodeText(i),e.delivery=s.delivery,e.codec=i.getAttribute("codec"),e.type=s.type,e.width=parseInt(s.width,10),e.height=parseInt(s.height,10),e.fileSize=parseInt(i.getAttribute("fileSize"),10),e.mediaType=i.getAttribute("mediaType")||"2D",a.mezzanine=e;}}));const l=m.childByName(t,"Icons");return l&&m.childrenByName(l,"Icon").forEach((e=>{a.icons.push(function(e){const t={program:null,height:0,width:0,xPosition:0,yPosition:0,apiFramework:null,offset:null,duration:0,type:null,staticResource:null,htmlResource:null,iframeResource:null,pxratio:"1",iconClickThroughURLTemplate:null,iconClickTrackingURLTemplates:[],iconViewTrackingURLTemplate:null,iconClickFallbackImages:[],altText:null,hoverText:null};t.program=e.getAttribute("program"),t.height=parseInt(e.getAttribute("height")||0),t.width=parseInt(e.getAttribute("width")||0),t.xPosition=function(e){if(-1!==["left","right"].indexOf(e))return e;return parseInt(e||0)}(e.getAttribute("xPosition")),t.yPosition=function(e){if(-1!==["top","bottom"].indexOf(e))return e;return parseInt(e||0)}(e.getAttribute("yPosition")),t.apiFramework=e.getAttribute("apiFramework"),t.pxratio=e.getAttribute("pxratio")||"1",t.offset=m.parseDuration(e.getAttribute("offset")),t.duration=m.parseDuration(e.getAttribute("duration")),t.altText=e.getAttribute("altText"),t.hoverText=e.getAttribute("hoverText"),m.childrenByName(e,"HTMLResource").forEach((e=>{t.type=e.getAttribute("creativeType")||"text/html",t.htmlResource=m.parseNodeText(e);})),m.childrenByName(e,"IFrameResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.iframeResource=m.parseNodeText(e);})),m.childrenByName(e,"StaticResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.staticResource=m.parseNodeText(e);}));const r=m.childByName(e,"IconClicks");if(r){t.iconClickThroughURLTemplate=m.parseNodeText(m.childByName(r,"IconClickThrough")),m.childrenByName(r,"IconClickTracking").forEach((e=>{t.iconClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});}));const e=m.childByName(r,"IconClickFallbackImages");e&&m.childrenByName(e,"IconClickFallbackImage").forEach((e=>{t.iconClickFallbackImages.push({url:m.parseNodeText(e)||null,width:e.getAttribute("width")||null,height:e.getAttribute("height")||null});}));}return t.iconViewTrackingURLTemplate=m.parseNodeText(m.childByName(e,"IconViewTracking")),t}(e));})),a}function f(t,r){const i=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{id:r,adId:i,sequence:a,apiFramework:s}=e$1(t);return {id:r,adId:i,sequence:a,apiFramework:s,type:"nonlinear",variations:[],trackingEvents:{}}}(r);return m.childrenByName(t,"TrackingEvents").forEach((e=>{let t,r;m.childrenByName(e,"Tracking").forEach((e=>{t=e.getAttribute("event"),r=m.parseNodeText(e),t&&r&&(Array.isArray(i.trackingEvents[t])||(i.trackingEvents[t]=[]),i.trackingEvents[t].push(r));}));})),m.childrenByName(t,"NonLinear").forEach((e=>{const t={id:null,width:0,height:0,expandedWidth:0,expandedHeight:0,scalable:true,maintainAspectRatio:true,minSuggestedDuration:0,apiFramework:"static",adType:"nonLinearAd",type:null,staticResource:null,htmlResource:null,iframeResource:null,nonlinearClickThroughURLTemplate:null,nonlinearClickTrackingURLTemplates:[],adParameters:null};t.id=e.getAttribute("id")||null,t.width=e.getAttribute("width"),t.height=e.getAttribute("height"),t.expandedWidth=e.getAttribute("expandedWidth"),t.expandedHeight=e.getAttribute("expandedHeight"),t.scalable=m.parseBoolean(e.getAttribute("scalable")),t.maintainAspectRatio=m.parseBoolean(e.getAttribute("maintainAspectRatio")),t.minSuggestedDuration=m.parseDuration(e.getAttribute("minSuggestedDuration")),t.apiFramework=e.getAttribute("apiFramework"),m.childrenByName(e,"HTMLResource").forEach((e=>{t.type=e.getAttribute("creativeType")||"text/html",t.htmlResource=m.parseNodeText(e);})),m.childrenByName(e,"IFrameResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.iframeResource=m.parseNodeText(e);})),m.childrenByName(e,"StaticResource").forEach((e=>{t.type=e.getAttribute("creativeType")||0,t.staticResource=m.parseNodeText(e);}));const r=m.childByName(e,"AdParameters");r&&(t.adParameters={value:m.parseNodeText(r),xmlEncoded:r.getAttribute("xmlEncoded")||null}),t.nonlinearClickThroughURLTemplate=m.parseNodeText(m.childByName(e,"NonLinearClickThrough")),m.childrenByName(e,"NonLinearClickTracking").forEach((e=>{t.nonlinearClickTrackingURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});})),i.variations.push(t);})),i}function T(e){const t=[];return e.forEach((e=>{const r=A(e);r&&t.push(r);})),t}function A(e){if("#comment"===e.nodeName)return null;const t={name:null,value:null,attributes:{},children:[]},r=e.attributes,i=e.childNodes;if(t.name=e.nodeName,e.attributes)for(const e in r)if(r.hasOwnProperty(e)){const i=r[e];i.nodeName&&i.nodeValue&&(t.attributes[i.nodeName]=i.nodeValue);}for(const e in i)if(i.hasOwnProperty(e)){const r=A(i[e]);r&&t.children.push(r);}if(0===t.children.length||1===t.children.length&&["#cdata-section","#text"].indexOf(t.children[0].name)>=0){const r=m.parseNodeText(e);""!==r&&(t.value=r),t.children=[];}return null===(a=t).value&&0===Object.keys(a.attributes).length&&0===a.children.length?null:t;var a;}function R(e){return e.getAttribute("AdID")||e.getAttribute("adID")||e.getAttribute("adId")||null}const k={Wrapper:{subElements:["VASTAdTagURI","Impression"]},BlockedAdCategories:{attributes:["authority"]},InLine:{subElements:["AdSystem","AdTitle","Impression","AdServingId","Creatives"]},Category:{attributes:["authority"]},Pricing:{attributes:["model","currency"]},Verification:{oneOfinLineResources:["JavaScriptResource","ExecutableResource"],attributes:["vendor"]},UniversalAdId:{attributes:["idRegistry"]},JavaScriptResource:{attributes:["apiFramework","browserOptional"]},ExecutableResource:{attributes:["apiFramework","type"]},Tracking:{attributes:["event"]},Creatives:{subElements:["Creative"]},Creative:{subElements:["UniversalAdId"]},Linear:{subElements:["MediaFiles","Duration"]},MediaFiles:{subElements:["MediaFile"]},MediaFile:{attributes:["delivery","type","width","height"]},Mezzanine:{attributes:["delivery","type","width","height"]},NonLinear:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"],attributes:["width","height"]},Companion:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"],attributes:["width","height"]},StaticResource:{attributes:["creativeType"]},Icons:{subElements:["Icon"]},Icon:{oneOfinLineResources:["StaticResource","IFrameResource","HTMLResource"]}};function y(e,t){if(!k[e.nodeName]||!k[e.nodeName].attributes)return;const r=k[e.nodeName].attributes.filter((t=>!e.getAttribute(t)));r.length>0&&N({name:e.nodeName,parentName:e.parentNode.nodeName,attributes:r},t);}function E(e,t,r){const i=k[e.nodeName],a=!r&&"Wrapper"!==e.nodeName;if(!i||a)return;if(i.subElements){const r=i.subElements.filter((t=>!m.childByName(e,t)));r.length>0&&N({name:e.nodeName,parentName:e.parentNode.nodeName,subElements:r},t);}if(!r||!i.oneOfinLineResources)return;i.oneOfinLineResources.some((t=>m.childByName(e,t)))||N({name:e.nodeName,parentName:e.parentNode.nodeName,oneOfResources:i.oneOfinLineResources},t);}function b(e){return e.children&&0!==e.children.length}function N(e,t){let{name:r,parentName:i,attributes:a,subElements:s,oneOfResources:n}=e,o="Element '".concat(r,"'");o+=a?" missing required attribute(s) '".concat(a.join(", "),"' "):s?" missing required sub element(s) '".concat(s.join(", "),"' "):n?" must provide one of the following '".concat(n.join(", "),"' "):" is empty",t("VAST-warning",{message:o,parentElement:i,specVersion:4.1});}const w={verifyRequiredValues:function e(t,r,i){if(t&&t.nodeName)if("InLine"===t.nodeName&&(i=true),y(t,r),b(t)){E(t,r,i);for(let a=0;a<t.children.length;a++)e(t.children[a],r,i);}else 0===m.parseNodeText(t).length&&N({name:t.nodeName,parentName:t.parentNode.nodeName},r);},hasSubElements:b,emitMissingValueWarning:N,verifyRequiredAttributes:y,verifyRequiredSubElements:E};function L(e,t){let{allowMultipleAds:r,followAdditionalWrappers:i}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=Array.from(e.childNodes).filter((e=>{const t=e.nodeName.toLowerCase();return "inline"===t||false!==i&&"wrapper"===t}));for(const i of a){if(m.copyNodeAttribute("id",e,i),m.copyNodeAttribute("sequence",e,i),m.copyNodeAttribute("adType",e,i),"Wrapper"===i.nodeName)return {ad:I(i,t),type:"WRAPPER"};if("InLine"===i.nodeName)return {ad:C(i,t,{allowMultipleAds:r}),type:"INLINE"};const a=i.nodeName.toLowerCase();t("VAST-warning",{message:"<".concat(i.nodeName,"inline"===a?"> must be written <InLine>":"> must be written <Wrapper>"),wrongNode:i});}}function C(e,t){let{allowMultipleAds:r}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return false===r&&e.getAttribute("sequence")?null:U(e,t)}function U(e,t){let r=[];t&&w.verifyRequiredValues(e,t);const i=Array.from(e.childNodes),a=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return {id:e.id||null,sequence:e.sequence||null,adType:e.adType||null,adServingId:null,categories:[],expires:null,viewableImpression:[],system:null,title:null,description:null,advertiser:null,pricing:null,survey:null,errorURLTemplates:[],impressionURLTemplates:[],creatives:[],extensions:[],adVerifications:[],blockedAdCategories:[],followAdditionalWrappers:true,allowMultipleAds:false,fallbackOnNoAd:null}}(m.parseAttributes(e));return i.forEach((e=>{switch(e.nodeName){case "Error":a.errorURLTemplates.push(m.parseNodeText(e));break;case "Impression":a.impressionURLTemplates.push({id:e.getAttribute("id")||null,url:m.parseNodeText(e)});break;case "Creatives":a.creatives=function(e){const t=[];return e.forEach((e=>{const r={id:e.getAttribute("id")||null,adId:R(e),sequence:e.getAttribute("sequence")||null,apiFramework:e.getAttribute("apiFramework")||null},i=[];let a;m.childrenByName(e,"UniversalAdId").forEach((e=>{const t={idRegistry:e.getAttribute("idRegistry")||"unknown",value:m.parseNodeText(e)};i.push(t);}));const s=m.childByName(e,"CreativeExtensions");s&&(a=T(m.childrenByName(s,"CreativeExtension")));for(const s in e.childNodes){const n=e.childNodes[s];let o;switch(n.nodeName){case "Linear":o=v(n,r);break;case "NonLinearAds":o=f(n,r);break;case "CompanionAds":o=g(n,r);}o&&(i&&(o.universalAdIds=i),a&&(o.creativeExtensions=a),t.push(o));}})),t}(m.childrenByName(e,"Creative"));break;case "Extensions":{const t=m.childrenByName(e,"Extension");a.extensions=T(t),a.adVerifications.length||(r=function(e){let t=null,r=[];e.some((e=>t=m.childByName(e,"AdVerifications"))),t&&(r=x(m.childrenByName(t,"Verification")));return r}(t));break}case "AdVerifications":a.adVerifications=x(m.childrenByName(e,"Verification"));break;case "AdSystem":a.system={value:m.parseNodeText(e),version:e.getAttribute("version")||null};break;case "AdTitle":a.title=m.parseNodeText(e);break;case "AdServingId":a.adServingId=m.parseNodeText(e);break;case "Category":a.categories.push({authority:e.getAttribute("authority")||null,value:m.parseNodeText(e)});break;case "Expires":a.expires=parseInt(m.parseNodeText(e),10);break;case "ViewableImpression":a.viewableImpression.push(function(e){const t=(e,t)=>{const r=m.parseNodeText(t);return r&&e.push(r),e};return {id:e.getAttribute("id")||null,viewable:m.childrenByName(e,"Viewable").reduce(t,[]),notViewable:m.childrenByName(e,"NotViewable").reduce(t,[]),viewUndetermined:m.childrenByName(e,"ViewUndetermined").reduce(t,[])}}(e));break;case "Description":a.description=m.parseNodeText(e);break;case "Advertiser":a.advertiser={id:e.getAttribute("id")||null,value:m.parseNodeText(e)};break;case "Pricing":a.pricing={value:m.parseNodeText(e),model:e.getAttribute("model")||null,currency:e.getAttribute("currency")||null};break;case "Survey":a.survey={value:m.parseNodeText(e),type:e.getAttribute("type")||null};break;case "BlockedAdCategories":a.blockedAdCategories.push({authority:e.getAttribute("authority")||null,value:m.parseNodeText(e)});}})),r.length&&(a.adVerifications=a.adVerifications.concat(r)),a}function I(e,t){const r=U(e,t),i=e.getAttribute("followAdditionalWrappers"),a=e.getAttribute("allowMultipleAds"),s=e.getAttribute("fallbackOnNoAd");r.followAdditionalWrappers=!i||m.parseBoolean(i),r.allowMultipleAds=!!a&&m.parseBoolean(a),r.fallbackOnNoAd=s?m.parseBoolean(s):null;let n=m.childByName(e,"VASTAdTagURI");if(n?r.nextWrapperURL=m.parseNodeText(n):(n=m.childByName(e,"VASTAdTagURL"),n&&(r.nextWrapperURL=m.parseNodeText(m.childByName(n,"URL")))),r.creatives.forEach((e=>{if(["linear","nonlinear"].includes(e.type)){if(e.trackingEvents){r.trackingEvents||(r.trackingEvents={}),r.trackingEvents[e.type]||(r.trackingEvents[e.type]={});for(const t in e.trackingEvents){const i=e.trackingEvents[t];Array.isArray(r.trackingEvents[e.type][t])||(r.trackingEvents[e.type][t]=[]),i.forEach((i=>{r.trackingEvents[e.type][t].push(i);}));}}e.videoClickTrackingURLTemplates&&(Array.isArray(r.videoClickTrackingURLTemplates)||(r.videoClickTrackingURLTemplates=[]),e.videoClickTrackingURLTemplates.forEach((e=>{r.videoClickTrackingURLTemplates.push(e);}))),e.videoClickThroughURLTemplate&&(r.videoClickThroughURLTemplate=e.videoClickThroughURLTemplate),e.videoCustomClickURLTemplates&&(Array.isArray(r.videoCustomClickURLTemplates)||(r.videoCustomClickURLTemplates=[]),e.videoCustomClickURLTemplates.forEach((e=>{r.videoCustomClickURLTemplates.push(e);})));}})),r.nextWrapperURL)return r}function x(e){const t=[];return e.forEach((e=>{const r={resource:null,vendor:null,browserOptional:false,apiFramework:null,type:null,parameters:null,trackingEvents:{}},i=Array.from(e.childNodes);m.assignAttributes(e.attributes,r),i.forEach((e=>{let{nodeName:t,textContent:i,attributes:a}=e;switch(t){case "JavaScriptResource":case "ExecutableResource":r.resource=i.trim(),m.assignAttributes(a,r);break;case "VerificationParameters":r.parameters=i.trim();}}));const a=m.childByName(e,"TrackingEvents");a&&m.childrenByName(a,"Tracking").forEach((e=>{const t=e.getAttribute("event"),i=m.parseNodeText(e);t&&i&&(Array.isArray(r.trackingEvents[t])||(r.trackingEvents[t]=[]),r.trackingEvents[t].push(i));})),t.push(r);})),t}class S{constructor(){this._handlers=[];}on(e,t){if("function"!=typeof t)throw new TypeError("The handler argument must be of type Function. Received type ".concat(typeof t));if(!e)throw new TypeError("The event argument must be of type String. Received type ".concat(typeof e));return this._handlers.push({event:e,handler:t}),this}once(e,t){return this.on(e,function(e,t,r){const i={fired:false,wrapFn:void 0};function a(){i.fired||(e.off(t,i.wrapFn),i.fired=true,r.bind(e)(...arguments));}return i.wrapFn=a,a}(this,e,t))}off(e,t){return this._handlers=this._handlers.filter((r=>r.event!==e||r.handler!==t)),this}emit(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),i=1;i<t;i++)r[i-1]=arguments[i];let a=false;return this._handlers.forEach((t=>{"*"===t.event&&(a=true,t.handler(e,...r)),t.event===e&&(a=true,t.handler(...r));})),a}removeAllListeners(e){return e?(this._handlers=this._handlers.filter((t=>t.event!==e)),this):(this._handlers=[],this)}listenerCount(e){return this._handlers.filter((t=>t.event===e)).length}listeners(e){return this._handlers.reduce(((t,r)=>(r.event===e&&t.push(r.handler),t)),[])}eventNames(){return this._handlers.map((e=>e.event))}}let D=0,V=0;const O=(e,t)=>{if(!e||!t||e<=0||t<=0)return;V=(V*D+8*e/t)/++D;},F={ERRORCODE:900,extensions:[]},P="VAST response version not supported";class B extends S{constructor(){let{fetcher:e}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};super(),this.maxWrapperDepth=null,this.rootErrorURLTemplates=[],this.errorURLTemplates=[],this.remainingAds=[],this.parsingOptions={},this.fetcher=e||null,this.keepFailedAdPod=false;}trackVastError(e,t){for(var r=arguments.length,i=new Array(r>2?r-2:0),a=2;a<r;a++)i[a-2]=arguments[a];this.emit("VAST-error",Object.assign({},F,t,...i)),u.track(e,t);}getErrorURLTemplates(){return this.rootErrorURLTemplates.concat(this.errorURLTemplates)}getEstimatedBitrate(){return V}initParsingStatus(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.maxWrapperDepth=e.wrapperLimit||10,this.parsingOptions={allowMultipleAds:e.allowMultipleAds},this.keepFailedAdPod=e.keepFailedAdPod||false,this.rootURL="",this.resetParsingStatus(),O(e.byteLength,e.requestDuration);}resetParsingStatus(){this.errorURLTemplates=[],this.rootErrorURLTemplates=[],this.vastVersion=null;}getRemainingAds(e){if(0===this.remainingAds.length)return Promise.reject(new Error("No more ads are available for the given VAST"));const t=e?this.remainingAds:[this.remainingAds.shift()];return this.errorURLTemplates=[],this.resolveAds(t,{wrapperDepth:0,url:this.rootURL}).then((e=>this.buildVASTResponse(e)))}parseVAST(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this.initParsingStatus(t),t.isRootVAST=true,this.parse(e,t).then((e=>this.buildVASTResponse(e)))}buildVASTResponse(e){const t=function(e){let{ads:t,errorURLTemplates:r,version:i}=e;return {ads:t||[],errorURLTemplates:r||[],version:i||null}}({ads:e,errorURLTemplates:this.getErrorURLTemplates(),version:this.vastVersion});return this.completeWrapperResolving(t),t}parseVastXml(e,t){let{isRootVAST:r=false,url:i=null,wrapperDepth:a=0,allowMultipleAds:s,followAdditionalWrappers:n}=t;if(!e||!e.documentElement||"VAST"!==e.documentElement.nodeName){var o;this.emit("VAST-ad-parsed",{type:"ERROR",url:i,wrapperDepth:a});const t="VideoAdServingTemplate"===(null==e||null===(o=e.documentElement)||void 0===o?void 0:o.nodeName);throw new Error(t?P:"Invalid VAST XMLDocument")}const l=[],c=e.documentElement.childNodes,d=e.documentElement.getAttribute("version");r&&d&&(this.vastVersion=d);for(const e in c){const t=c[e];if("Error"===t.nodeName){const e=m.parseNodeText(t);r?this.rootErrorURLTemplates.push(e):this.errorURLTemplates.push(e);}else if("Ad"===t.nodeName){if(this.vastVersion&&parseFloat(this.vastVersion)<3)s=true;else if(false===s&&l.length>1)break;const e=L(t,this.emit.bind(this),{allowMultipleAds:s,followAdditionalWrappers:n});e.ad?(l.push(e.ad),this.emit("VAST-ad-parsed",{type:e.type,url:i,wrapperDepth:a,adIndex:l.length-1,vastVersion:d})):this.trackVastError(this.getErrorURLTemplates(),{ERRORCODE:101});}}return l}parse(e){let{url:t=null,resolveAll:r=true,wrapperSequence:i=null,previousUrl:a=null,wrapperDepth:s=0,isRootVAST:n=false,followAdditionalWrappers:o,allowMultipleAds:l}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=[];this.vastVersion&&parseFloat(this.vastVersion)<3&&n&&(l=true);try{c=this.parseVastXml(e,{isRootVAST:n,url:t,wrapperDepth:s,allowMultipleAds:l,followAdditionalWrappers:o});}catch(e){return Promise.reject(e)}if(1===c.length&&null!=i&&(c[0].sequence=i),false===r){const e=m.getSortedAdPods(c),t=m.getStandAloneAds(c);e.length?c=e:t.length&&(c=[t.shift()]),this.remainingAds=t;}return this.resolveAds(c,{wrapperDepth:s,previousUrl:a,url:t})}resolveAds(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],{wrapperDepth:t,previousUrl:r,url:i}=arguments.length>1?arguments[1]:void 0;const a=[];return r=i,e.forEach((e=>{const i=this.resolveWrappers(e,t,r);a.push(i);})),Promise.all(a).then((e=>u.flatten(e)))}resolveWrappers(e,t,r){const i={...e};return new Promise((e=>{var a;if(t++,!i.nextWrapperURL)return delete i.nextWrapperURL,e(i);if(!this.fetcher)return i.VASTAdTagURI=i.nextWrapperURL,delete i.nextWrapperURL,e(i);if(t>=this.maxWrapperDepth)return i.errorCode=302,delete i.nextWrapperURL,e(i);i.nextWrapperURL=m.resolveVastAdTagURI(i.nextWrapperURL,r);const s=null!==(a=this.parsingOptions.allowMultipleAds)&&void 0!==a?a:i.allowMultipleAds,n=i.sequence;this.fetcher.fetchVAST({url:i.nextWrapperURL,emitter:this.emit.bind(this),maxWrapperDepth:this.maxWrapperDepth,wrapperDepth:t,previousUrl:r,wrapperAd:i}).then((a=>this.parse(a,{url:i.nextWrapperURL,previousUrl:r,wrapperSequence:n,wrapperDepth:t,followAdditionalWrappers:i.followAdditionalWrappers,allowMultipleAds:s}).then((t=>{if(delete i.nextWrapperURL,0===t.length)return i.creatives=[],e(i);t.forEach((e=>{e&&m.mergeWrapperAdData(e,i);})),e(t);})))).catch((t=>{i.errorCode=t.message===P?102:301,i.errorMessage=t.message,e(i);}));}))}completeWrapperResolving(e){if(0===e.ads.length)this.trackVastError(e.errorURLTemplates,{ERRORCODE:303});else for(let t=e.ads.length-1;t>=0;t--){const r=e.ads[t],i=!r.creatives.some((e=>{var t,r;return (null===(t=e.mediaFiles)||void 0===t?void 0:t.length)>0||(null===(r=e.variations)||void 0===r?void 0:r.length)>0}));!r.errorCode&&!i||r.VASTAdTagURI||(this.trackVastError(r.errorURLTemplates.concat(e.errorURLTemplates),{ERRORCODE:r.errorCode||303},{ERRORMESSAGE:r.errorMessage||""},{extensions:r.extensions},{system:r.system}),this.keepFailedAdPod&&r.sequence?r.hasFailed=true:e.ads.splice(t,1));}}}let M=null;const W={data:{},length:0,getItem(e){return this.data[e]},setItem(e,t){this.data[e]=t,this.length=Object.keys(this.data).length;},removeItem(e){delete this.data[e],this.length=Object.keys(this.data).length;},clear(){this.data={},this.length=0;}};class j{constructor(){this.storage=this.initStorage();}initStorage(){if(M)return M;try{M="undefined"!=typeof window&&null!==window?window.localStorage||window.sessionStorage:null;}catch(e){M=null;}return M&&!this.isStorageDisabled(M)||(M=W,M.clear()),M}isStorageDisabled(e){const t="__VASTStorage__";try{if(e.setItem(t,t),e.getItem(t)!==t)return e.removeItem(t),!0}catch(e){return true}return e.removeItem(t),false}getItem(e){return this.storage.getItem(e)}setItem(e,t){return this.storage.setItem(e,t)}removeItem(e){return this.storage.removeItem(e)}clear(){return this.storage.clear()}}const q=12e4;const K={get:async function(e,t){try{const r=new AbortController,i=setTimeout((()=>{throw r.abort(),new Error("URLHandler: Request timed out after ".concat(t.timeout||q," ms (408)"))}),t.timeout||q),a=await fetch(e,{...t,signal:r.signal,credentials:t.withCredentials?"include":"omit"}).finally((()=>{clearTimeout(i);})),s=function(e){return u.isBrowserEnvironment()&&"https:"===window.location.protocol&&e.url.includes("http://")?"URLHandler: Cannot go from HTTPS to HTTP.":200===e.status&&e.ok?null:"URLHandler: ".concat(e.statusText," (").concat(e.status,")")}(a);return s?{error:new Error(s),statusCode:a.status}:async function(e){const t=await e.text();let r;r=u.isBrowserEnvironment()?new DOMParser:new((await Promise.resolve().then(function () { return index$1; })).DOMParser);return {xml:r.parseFromString(t,"text/xml"),details:{byteLength:t.length,statusCode:e.status,rawXml:t}}}(a)}catch(e){return {error:e,statusCode:"AbortError"===e.name?408:null}}}};class H{constructor(){this.URLTemplateFilters=[];}setOptions(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};this.urlHandler=e.urlHandler||e.urlhandler||K,this.fetchingOptions={...e.fetchOptions,timeout:e.timeout||q,withCredentials:Boolean(e.withCredentials)};}addURLTemplateFilter(e){"function"==typeof e&&this.URLTemplateFilters.push(e);}removeLastURLTemplateFilter(){this.URLTemplateFilters.pop();}countURLTemplateFilters(){return this.URLTemplateFilters.length}clearURLTemplateFilters(){this.URLTemplateFilters=[];}async fetchVAST(e){var t;let{url:r,maxWrapperDepth:i,emitter:a,wrapperDepth:s=0,previousUrl:n=null,wrapperAd:o=null}=e;const l=Date.now();this.URLTemplateFilters.forEach((e=>{r=e(r);})),a("VAST-resolving",{url:r,previousUrl:n,wrapperDepth:s,maxWrapperDepth:i,timeout:this.fetchingOptions.timeout,wrapperAd:o});const c=await this.urlHandler.get(r,this.fetchingOptions),d=Math.round(Date.now()-l);if(a("VAST-resolved",{url:r,previousUrl:n,wrapperDepth:s,error:(null==c?void 0:c.error)||null,duration:d,statusCode:(null==c?void 0:c.statusCode)||null,...null==c?void 0:c.details}),O(null==c||null===(t=c.details)||void 0===t?void 0:t.byteLength,d),c.error)throw new Error(c.error);return c.xml}}class _{constructor(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:new j;this.cappingFreeLunch=e,this.cappingMinimumTimeInterval=t,this.fetcher=new H,this.vastParser=new B({fetcher:this.fetcher}),this.storage=r,void 0===this.lastSuccessfulAd&&(this.lastSuccessfulAd=0),void 0===this.totalCalls&&(this.totalCalls=0),void 0===this.totalCallsTimeout&&(this.totalCallsTimeout=0);}addURLTemplateFilter(e){this.fetcher.addURLTemplateFilter(e);}removeLastURLTemplateFilter(){this.fetcher.removeLastURLTemplateFilter();}countURLTemplateFilters(){return this.fetcher.countURLTemplateFilters()}clearURLTemplateFilters(){this.fetcher.clearURLTemplateFilters();}getParser(){return this.vastParser}get lastSuccessfulAd(){return this.storage.getItem("vast-client-last-successful-ad")}set lastSuccessfulAd(e){this.storage.setItem("vast-client-last-successful-ad",e);}get totalCalls(){return this.storage.getItem("vast-client-total-calls")}set totalCalls(e){this.storage.setItem("vast-client-total-calls",e);}get totalCallsTimeout(){return this.storage.getItem("vast-client-total-calls-timeout")}set totalCallsTimeout(e){this.storage.setItem("vast-client-total-calls-timeout",e);}hasRemainingAds(){return this.vastParser.remainingAds.length>0}getNextAds(e){return this.vastParser.getRemainingAds(e)}parseVAST(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return this.fetcher.setOptions(t),this.vastParser.parseVAST(e,t)}get(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const r=Date.now();return t.hasOwnProperty("resolveAll")||(t.resolveAll=false),this.totalCallsTimeout<r?(this.totalCalls=1,this.totalCallsTimeout=r+36e5):this.totalCalls++,new Promise(((i,a)=>{if(this.cappingFreeLunch>=this.totalCalls)return a(new Error("VAST call canceled – FreeLunch capping not reached yet ".concat(this.totalCalls,"/").concat(this.cappingFreeLunch)));const s=r-this.lastSuccessfulAd;if(s<0)this.lastSuccessfulAd=0;else if(s<this.cappingMinimumTimeInterval)return a(new Error("VAST call canceled – (".concat(this.cappingMinimumTimeInterval,")ms minimum interval reached")));this.vastParser.initParsingStatus(t),this.fetcher.setOptions(t),this.vastParser.rootURL=e,this.fetcher.fetchVAST({url:e,emitter:this.vastParser.emit.bind(this.vastParser),maxWrapperDepth:this.vastParser.maxWrapperDepth}).then((r=>(t.previousUrl=e,t.isRootVAST=true,t.url=e,this.vastParser.parse(r,t).then((e=>{const t=this.vastParser.buildVASTResponse(e);i(t);}))))).catch((e=>a(e)));}))}}class z extends S{constructor(e,t,r){var i;let a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,s=arguments.length>4&&void 0!==arguments[4]&&arguments[4];super(),this.ad=t,this.creative=r,this.variation=a,this.muted=s,this.impressed=false,this.skippable=false,this.trackingEvents={},this.trackedProgressEvents=[],this.lastPercentage=0,this._alreadyTriggeredQuartiles={},this.emitAlwaysEvents=["creativeView","start","firstQuartile","midpoint","thirdQuartile","complete","resume","pause","rewind","skip","closeLinear","close"];for(const e in this.creative.trackingEvents){const t=this.creative.trackingEvents[e];this.trackingEvents[e]=t.slice(0);}this.viewableImpressionTrackers=(null===(i=this.ad.viewableImpression)||void 0===i?void 0:i.reduce(((e,t)=>(e.notViewable.push(...t.notViewable),e.viewUndetermined.push(...t.viewUndetermined),e.viewable.push(...t.viewable),e)),{notViewable:[],viewUndetermined:[],viewable:[]}))||{},Object.entries(this.viewableImpressionTrackers).forEach((e=>{let[t,r]=e;r.length&&(this.trackingEvents[t]=r);})),!function(e){return "linear"===e.type}(this.creative)?this._initVariationTracking():this._initLinearTracking(),e&&this.on("start",(()=>{e.lastSuccessfulAd=Date.now();}));}_initLinearTracking(){this.linear=true,this.skipDelay=this.creative.skipDelay,this.setDuration(this.creative.duration),this.clickThroughURLTemplate=this.creative.videoClickThroughURLTemplate,this.clickTrackingURLTemplates=this.creative.videoClickTrackingURLTemplates;}_initVariationTracking(){if(this.linear=false,this.skipDelay=-1,this.variation){for(const e in this.variation.trackingEvents){const t=this.variation.trackingEvents[e];this.trackingEvents[e]?this.trackingEvents[e]=this.trackingEvents[e].concat(t.slice(0)):this.trackingEvents[e]=t.slice(0);}"nonLinearAd"===this.variation.adType?(this.clickThroughURLTemplate=this.variation.nonlinearClickThroughURLTemplate,this.clickTrackingURLTemplates=this.variation.nonlinearClickTrackingURLTemplates,this.setDuration(this.variation.minSuggestedDuration)):function(e){return "companionAd"===e.adType}(this.variation)&&(this.clickThroughURLTemplate=this.variation.companionClickThroughURLTemplate,this.clickTrackingURLTemplates=this.variation.companionClickTrackingURLTemplates);}}setDuration(e){u.isValidTimeValue(e)?(this.assetDuration=e,this.quartiles={firstQuartile:Math.round(25*this.assetDuration)/100,midpoint:Math.round(50*this.assetDuration)/100,thirdQuartile:Math.round(75*this.assetDuration)/100}):this.emit("TRACKER-error",{message:"the duration provided is not valid. duration: ".concat(e)});}setProgress(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(!u.isValidTimeValue(e)||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given setProgress parameter has the wrong type. progress: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});const i=this.skipDelay||-1;if(-1===i||this.skippable||(i>e?this.emit("skip-countdown",i-e):(this.skippable=true,this.emit("skip-countdown",0))),this.assetDuration>0){const i=Math.round(e/this.assetDuration*100),a=[];if(e>0){a.push("start");for(let e=this.lastPercentage;e<i;e++)a.push("progress-".concat(e+1,"%"));a.push("progress-".concat(e));for(const t in this.quartiles)this.isQuartileReached(t,this.quartiles[t],e)&&(a.push(t),this._alreadyTriggeredQuartiles[t]=true);this.lastPercentage=i;}a.forEach((e=>{this.track(e,{macros:t,once:r});})),e<this.progress&&(this.track("rewind",{macros:t}),this.trackedProgressEvents&&this.trackedProgressEvents.splice(0));}this.progress=e;}isQuartileReached(e,t,r){let i=false;return t<=r&&!this._alreadyTriggeredQuartiles[e]&&(i=true),i}setMuted(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.muted!==e&&this.track(e?"mute":"unmute",{macros:t}),this.muted=e):this.emit("TRACKER-error",{message:"One given setMuted parameter has the wrong type. muted: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setPaused(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.paused!==e&&this.track(e?"pause":"resume",{macros:t}),this.paused=e):this.emit("TRACKER-error",{message:"One given setPaused parameter has the wrong type. paused: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setFullscreen(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.fullscreen!==e&&this.track(e?"fullscreen":"exitFullscreen",{macros:t}),this.fullscreen=e):this.emit("TRACKER-error",{message:"One given setFullScreen parameter has the wrong type. fullscreen: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setExpand(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"boolean"==typeof e&&"object"==typeof t?(this.expanded!==e&&(this.track(e?"expand":"collapse",{macros:t}),this.track(e?"playerExpand":"playerCollapse",{macros:t})),this.expanded=e):this.emit("TRACKER-error",{message:"One given setExpand parameter has the wrong type. expanded: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}setSkipDelay(e){u.isValidTimeValue(e)?this.skipDelay=e:this.emit("TRACKER-error",{message:"setSkipDelay parameter does not have a valid value. duration: ".concat(e)});}trackImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.impressed||(this.impressed=true,this.trackURLs(this.ad.impressionURLTemplates,e),this.track("creativeView",{macros:e})):this.emit("TRACKER-error",{message:"trackImpression parameter has the wrong type. macros: ".concat(e)});}trackViewableImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("viewable",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackViewableImpression given macros has the wrong type. macros: ".concat(e)});}trackNotViewableImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("notViewable",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackNotViewableImpression given macros has the wrong type. macros: ".concat(e)});}trackUndeterminedImpression(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e?this.track("viewUndetermined",{macros:e,once:t}):this.emit("TRACKER-error",{message:"trackUndeterminedImpression given macros has the wrong type. macros: ".concat(e)});}error(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"object"==typeof e&&"boolean"==typeof t?this.trackURLs(this.ad.errorURLTemplates,e,{isCustomCode:t}):this.emit("TRACKER-error",{message:"One given error parameter has the wrong type. macros: ".concat(u.formatMacrosValues(e),", isCustomCode: ").concat(t)});}errorWithCode(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];"string"==typeof e&&"boolean"==typeof t?(this.error({ERRORCODE:e},t),console.log("The method errorWithCode is deprecated, please use vast tracker error method instead")):this.emit("TRACKER-error",{message:"One given errorWithCode parameter has the wrong type. errorCode: ".concat(e,", isCustomCode: ").concat(t)});}complete(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("complete",{macros:e}):this.emit("TRACKER-error",{message:"complete given macros has the wrong type. macros: ".concat(e)});}notUsed(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?(this.track("notUsed",{macros:e}),this.trackingEvents=[]):this.emit("TRACKER-error",{message:"notUsed given macros has the wrong type. macros: ".concat(e)});}otherAdInteraction(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("otherAdInteraction",{macros:e}):this.emit("TRACKER-error",{message:"otherAdInteraction given macros has the wrong type. macros: ".concat(e)});}acceptInvitation(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("acceptInvitation",{macros:e}):this.emit("TRACKER-error",{message:"acceptInvitation given macros has the wrong type. macros: ".concat(e)});}adExpand(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("adExpand",{macros:e}):this.emit("TRACKER-error",{message:"adExpand given macros has the wrong type. macros: ".concat(e)});}adCollapse(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("adCollapse",{macros:e}):this.emit("TRACKER-error",{message:"adCollapse given macros has the wrong type. macros: ".concat(e)});}minimize(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("minimize",{macros:e}):this.emit("TRACKER-error",{message:"minimize given macros has the wrong type. macros: ".concat(e)});}verificationNotExecuted(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("string"!=typeof e||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given verificationNotExecuted parameter has to wrong type. vendor: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});if(!this.ad||!this.ad.adVerifications||!this.ad.adVerifications.length)throw new Error("No adVerifications provided");if(!e)throw new Error("No vendor provided, unable to find associated verificationNotExecuted");const r=this.ad.adVerifications.find((t=>t.vendor===e));if(!r)throw new Error("No associated verification element found for vendor: ".concat(e));const i=r.trackingEvents;if(i&&i.verificationNotExecuted){const e=i.verificationNotExecuted;this.trackURLs(e,t),this.emit("verificationNotExecuted",{trackingURLTemplates:e});}}overlayViewDuration(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"string"==typeof e&&"object"==typeof t?(t.ADPLAYHEAD=e,this.track("overlayViewDuration",{macros:t})):this.emit("TRACKER-error",{message:"One given overlayViewDuration parameters has the wrong type. formattedDuration: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});}close(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track(this.linear?"closeLinear":"close",{macros:e}):this.emit("TRACKER-error",{message:"close given macros has the wrong type. macros: ".concat(e)});}skip(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("skip",{macros:e}):this.emit("TRACKER-error",{message:"skip given macros has the wrong type. macros: ".concat(e)});}load(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};"object"==typeof e?this.track("loaded",{macros:e}):this.emit("TRACKER-error",{message:"load given macros has the wrong type. macros: ".concat(e)});}click(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(null!==e&&"string"!=typeof e||"object"!=typeof t)return void this.emit("TRACKER-error",{message:"One given click parameter has the wrong type. fallbackClickThroughURL: ".concat(e,", macros: ").concat(u.formatMacrosValues(t))});this.clickTrackingURLTemplates&&this.clickTrackingURLTemplates.length&&this.trackURLs(this.clickTrackingURLTemplates,t);const r=this.clickThroughURLTemplate||e,i={...t};if(r){this.progress&&(i.ADPLAYHEAD=this.progressFormatted());const e=u.resolveURLTemplates([r],i)[0];this.emit("clickthrough",e);}}trackProgressEvents(e,t,r){const i=parseFloat(e.split("-")[1]);Object.entries(this.trackingEvents).filter((e=>{let[t]=e;return t.startsWith("progress-")})).map((e=>{let[t,r]=e;return {name:t,time:parseFloat(t.split("-")[1]),urls:r}})).filter((e=>{let{time:t}=e;return t<=i&&t>this.progress})).forEach((e=>{let{name:i,urls:a}=e;!r&&this.trackedProgressEvents.includes(i)||(this.emit(i,{trackingURLTemplates:a}),this.trackURLs(a,t),r?delete this.trackingEvents[i]:this.trackedProgressEvents.push(i));}));}track(e){let{macros:t={},once:r=false}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if("object"!=typeof t)return void this.emit("TRACKER-error",{message:"track given macros has the wrong type. macros: ".concat(t)});"closeLinear"===e&&!this.trackingEvents[e]&&this.trackingEvents.close&&(e="close"),e.startsWith("progress-")&&!e.endsWith("%")&&this.trackProgressEvents(e,t,r);const i=this.trackingEvents[e],a=this.emitAlwaysEvents.indexOf(e)>-1;i?(this.emit(e,{trackingURLTemplates:i}),this.trackURLs(i,t)):a&&this.emit(e,null),r&&(delete this.trackingEvents[e],a&&this.emitAlwaysEvents.splice(this.emitAlwaysEvents.indexOf(e),1));}trackURLs(e){var t;let r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{validUrls:a,invalidUrls:s}=u.filterUrlTemplates(e);s.length&&this.emit("TRACKER-error",{message:"Provided urls are malformed. url: ".concat(s)});const n={...r};this.linear&&(this.creative&&this.creative.mediaFiles&&this.creative.mediaFiles[0]&&this.creative.mediaFiles[0].fileURL&&(n.ASSETURI=this.creative.mediaFiles[0].fileURL),this.progress&&(n.ADPLAYHEAD=this.progressFormatted())),null!==(t=this.creative)&&void 0!==t&&null!==(t=t.universalAdIds)&&void 0!==t&&t.length&&(n.UNIVERSALADID=this.creative.universalAdIds.map((e=>e.idRegistry.concat(" ",e.value))).join(",")),this.ad&&(this.ad.sequence&&(n.PODSEQUENCE=this.ad.sequence),this.ad.adType&&(n.ADTYPE=this.ad.adType),this.ad.adServingId&&(n.ADSERVINGID=this.ad.adServingId),this.ad.categories&&this.ad.categories.length&&(n.ADCATEGORIES=this.ad.categories.map((e=>e.value)).join(",")),this.ad.blockedAdCategories&&this.ad.blockedAdCategories.length&&(n.BLOCKEDADCATEGORIES=this.ad.blockedAdCategories.map((e=>e.value)).join(","))),u.track(a,n,i);}convertToTimecode(e){if(!u.isValidTimeValue(e))return "";const t=1e3*e,r=Math.floor(t/36e5),i=Math.floor(t/6e4%60),a=Math.floor(t/1e3%60),s=Math.floor(t%1e3);return "".concat(u.addLeadingZeros(r,2),":").concat(u.addLeadingZeros(i,2),":").concat(u.addLeadingZeros(a,2),".").concat(u.addLeadingZeros(s,3))}progressFormatted(){return this.convertToTimecode(this.progress)}}
|
|
19
19
|
|
|
20
20
|
// ─── Utility ─────────────────────────────────────────────────────────────────
|
|
21
21
|
function toXmlDocument(xml) {
|
|
@@ -147,8 +147,17 @@ function extractSimidUrl(creative, rawDoc) {
|
|
|
147
147
|
// Path 1: parsed library object
|
|
148
148
|
// vast-client may expose InteractiveCreativeFile as interactiveCreativeFiles[] or inside mediaFiles[]
|
|
149
149
|
const mediaFiles = [
|
|
150
|
-
...(creative?.mediaFiles ||
|
|
151
|
-
|
|
150
|
+
...(creative?.mediaFiles ||
|
|
151
|
+
creative?.MediaFiles ||
|
|
152
|
+
creative?.linear?.mediaFiles ||
|
|
153
|
+
creative?.linear?.MediaFiles ||
|
|
154
|
+
[]),
|
|
155
|
+
...(creative?.interactiveCreativeFiles ||
|
|
156
|
+
creative?.linear?.interactiveCreativeFiles ||
|
|
157
|
+
creative?.linear?.InteractiveCreativeFiles || [creative?.interactiveCreativeFile] || [
|
|
158
|
+
creative?.InteractiveCreativeFile,
|
|
159
|
+
] ||
|
|
160
|
+
[]),
|
|
152
161
|
];
|
|
153
162
|
for (const mf of mediaFiles) {
|
|
154
163
|
const framework = String(mf?.apiFramework || mf?.APIFramework || '').toLowerCase();
|
|
@@ -189,7 +198,11 @@ function extractAdVerifications(parsed, rawDoc) {
|
|
|
189
198
|
const verifications = ad?.adVerifications || ad?.AdVerifications || [];
|
|
190
199
|
for (const v of verifications) {
|
|
191
200
|
const vendor = String(v?.vendor || v?.Vendor || '');
|
|
192
|
-
const resources = v?.resource ||
|
|
201
|
+
const resources = v?.resource ||
|
|
202
|
+
v?.resources ||
|
|
203
|
+
v?.JavaScriptResource ||
|
|
204
|
+
v?.javaScriptResource ||
|
|
205
|
+
(v?.javascriptResource ? [v.javascriptResource] : []);
|
|
193
206
|
const resArr = Array.isArray(resources) ? resources : [resources];
|
|
194
207
|
for (const r of resArr) {
|
|
195
208
|
const scriptUrl = String(r?.uri || r?.url || r?.browserOptional?.value || r?.value || r || '').trim();
|
|
@@ -208,7 +221,9 @@ function extractAdVerifications(parsed, rawDoc) {
|
|
|
208
221
|
try {
|
|
209
222
|
return Array.from(root.getElementsByTagNameNS('*', tag));
|
|
210
223
|
}
|
|
211
|
-
catch {
|
|
224
|
+
catch {
|
|
225
|
+
/* ignore */
|
|
226
|
+
}
|
|
212
227
|
try {
|
|
213
228
|
return Array.from(root.getElementsByTagName(tag));
|
|
214
229
|
}
|
|
@@ -395,7 +410,9 @@ function collectNonLinearFromXml(doc) {
|
|
|
395
410
|
return arr;
|
|
396
411
|
}
|
|
397
412
|
}
|
|
398
|
-
catch {
|
|
413
|
+
catch {
|
|
414
|
+
/* ignore */
|
|
415
|
+
}
|
|
399
416
|
try {
|
|
400
417
|
return Array.from(root.getElementsByTagName(localName));
|
|
401
418
|
}
|
|
@@ -425,7 +442,9 @@ function collectNonLinearFromXml(doc) {
|
|
|
425
442
|
});
|
|
426
443
|
}
|
|
427
444
|
}
|
|
428
|
-
catch {
|
|
445
|
+
catch {
|
|
446
|
+
/* ignore */
|
|
447
|
+
}
|
|
429
448
|
const nlEls = byLocalName(doc, 'NonLinear');
|
|
430
449
|
for (const nl of nlEls) {
|
|
431
450
|
const w = Number(nl.getAttribute('width') || 0);
|
|
@@ -496,8 +515,21 @@ function setSafeHTMLFn(el, html) {
|
|
|
496
515
|
const tpl = document.createElement('template');
|
|
497
516
|
tpl.innerHTML = String(html || '');
|
|
498
517
|
const blockedTags = new Set([
|
|
499
|
-
'SCRIPT',
|
|
500
|
-
'
|
|
518
|
+
'SCRIPT',
|
|
519
|
+
'IFRAME',
|
|
520
|
+
'OBJECT',
|
|
521
|
+
'EMBED',
|
|
522
|
+
'LINK',
|
|
523
|
+
'STYLE',
|
|
524
|
+
'SVG',
|
|
525
|
+
'MATH',
|
|
526
|
+
'FORM',
|
|
527
|
+
'INPUT',
|
|
528
|
+
'TEXTAREA',
|
|
529
|
+
'SELECT',
|
|
530
|
+
'OPTION',
|
|
531
|
+
'META',
|
|
532
|
+
'BASE',
|
|
501
533
|
]);
|
|
502
534
|
const walker = document.createTreeWalker(tpl.content, NodeFilter.SHOW_ELEMENT);
|
|
503
535
|
const toRemove = [];
|
|
@@ -681,8 +713,21 @@ class AdDomManager {
|
|
|
681
713
|
const tpl = document.createElement('template');
|
|
682
714
|
tpl.innerHTML = String(html || '');
|
|
683
715
|
const blockedTags = new Set([
|
|
684
|
-
'SCRIPT',
|
|
685
|
-
'
|
|
716
|
+
'SCRIPT',
|
|
717
|
+
'IFRAME',
|
|
718
|
+
'OBJECT',
|
|
719
|
+
'EMBED',
|
|
720
|
+
'LINK',
|
|
721
|
+
'STYLE',
|
|
722
|
+
'SVG',
|
|
723
|
+
'MATH',
|
|
724
|
+
'FORM',
|
|
725
|
+
'INPUT',
|
|
726
|
+
'TEXTAREA',
|
|
727
|
+
'SELECT',
|
|
728
|
+
'OPTION',
|
|
729
|
+
'META',
|
|
730
|
+
'BASE',
|
|
686
731
|
]);
|
|
687
732
|
const walker = document.createTreeWalker(tpl.content, NodeFilter.SHOW_ELEMENT);
|
|
688
733
|
const toRemove = [];
|
|
@@ -722,7 +767,9 @@ class AdDomManager {
|
|
|
722
767
|
return;
|
|
723
768
|
window.open(url.toString(), '_blank', 'noopener,noreferrer');
|
|
724
769
|
}
|
|
725
|
-
catch {
|
|
770
|
+
catch {
|
|
771
|
+
/* ignore */
|
|
772
|
+
}
|
|
726
773
|
}
|
|
727
774
|
// ─── Skip UI ─────────────────────────────────────────────────────────────────
|
|
728
775
|
ensureSkipDom() {
|
|
@@ -733,7 +780,7 @@ class AdDomManager {
|
|
|
733
780
|
const btn = document.createElement('button');
|
|
734
781
|
btn.type = 'button';
|
|
735
782
|
btn.className = 'op-ads__skip-btn';
|
|
736
|
-
btn.textContent = 'Skip Ad';
|
|
783
|
+
btn.textContent = this.cfg.labels?.skip || 'Skip Ad';
|
|
737
784
|
wrap.appendChild(btn);
|
|
738
785
|
this.overlay.appendChild(wrap);
|
|
739
786
|
const onClick = (e) => {
|
|
@@ -777,7 +824,8 @@ class AdDomManager {
|
|
|
777
824
|
if (this.skipWrap)
|
|
778
825
|
this.skipWrap.style.display = 'block';
|
|
779
826
|
if (this.skipBtn) {
|
|
780
|
-
this.skipBtn.textContent =
|
|
827
|
+
this.skipBtn.textContent =
|
|
828
|
+
remaining <= 0.05 ? this.cfg.labels?.skip || 'Skip Ad' : Math.ceil(remaining).toString();
|
|
781
829
|
this.skipBtn.style.pointerEvents = remaining <= 0.05 ? 'auto' : 'none';
|
|
782
830
|
}
|
|
783
831
|
};
|
|
@@ -798,7 +846,9 @@ class AdDomManager {
|
|
|
798
846
|
try {
|
|
799
847
|
this.getTracker()?.trackSkip?.();
|
|
800
848
|
}
|
|
801
|
-
catch {
|
|
849
|
+
catch {
|
|
850
|
+
/* ignore */
|
|
851
|
+
}
|
|
802
852
|
const brk = currentBreakMeta ? { kind: currentBreakMeta.kind, id: currentBreakMeta.breakId } : null;
|
|
803
853
|
emitSkip({ break: brk, reason });
|
|
804
854
|
const v = adVideo;
|
|
@@ -808,7 +858,9 @@ class AdDomManager {
|
|
|
808
858
|
v.currentTime = Math.max(0, v.duration - 0.001);
|
|
809
859
|
v.dispatchEvent(new Event('ended'));
|
|
810
860
|
}
|
|
811
|
-
catch {
|
|
861
|
+
catch {
|
|
862
|
+
/* ignore */
|
|
863
|
+
}
|
|
812
864
|
}
|
|
813
865
|
}
|
|
814
866
|
// ─── Overlay cleanup ──────────────────────────────────────────────────────────
|
|
@@ -860,9 +912,18 @@ class AdDomManager {
|
|
|
860
912
|
wrap.className = 'op-ads__companion';
|
|
861
913
|
wrap.style.position = 'relative';
|
|
862
914
|
wrap.style.cursor = click ? 'pointer' : 'default';
|
|
863
|
-
const staticRes = companion?.staticResource ||
|
|
864
|
-
|
|
865
|
-
|
|
915
|
+
const staticRes = companion?.staticResource ||
|
|
916
|
+
companion?.StaticResource ||
|
|
917
|
+
companion?.staticResources?.[0] ||
|
|
918
|
+
companion?.StaticResources?.[0];
|
|
919
|
+
const iframeRes = companion?.iFrameResource ||
|
|
920
|
+
companion?.IFrameResource ||
|
|
921
|
+
companion?.iFrameResources?.[0] ||
|
|
922
|
+
companion?.IFrameResources?.[0];
|
|
923
|
+
const htmlRes = companion?.htmlResource ||
|
|
924
|
+
companion?.HTMLResource ||
|
|
925
|
+
companion?.htmlResources?.[0] ||
|
|
926
|
+
companion?.HTMLResources?.[0];
|
|
866
927
|
let node = null;
|
|
867
928
|
if (staticRes) {
|
|
868
929
|
const img = document.createElement('img');
|
|
@@ -895,7 +956,9 @@ class AdDomManager {
|
|
|
895
956
|
this.getTracker()?.trackClick?.();
|
|
896
957
|
this.getTracker()?.trackClickThrough?.();
|
|
897
958
|
}
|
|
898
|
-
catch {
|
|
959
|
+
catch {
|
|
960
|
+
/* ignore */
|
|
961
|
+
}
|
|
899
962
|
e.preventDefault();
|
|
900
963
|
e.stopPropagation();
|
|
901
964
|
};
|
|
@@ -989,7 +1052,9 @@ class AdDomManager {
|
|
|
989
1052
|
this.getTracker()?.trackClick?.();
|
|
990
1053
|
this.getTracker()?.trackClickThrough?.();
|
|
991
1054
|
}
|
|
992
|
-
catch {
|
|
1055
|
+
catch {
|
|
1056
|
+
/* ignore */
|
|
1057
|
+
}
|
|
993
1058
|
e.preventDefault();
|
|
994
1059
|
e.stopPropagation();
|
|
995
1060
|
};
|
|
@@ -1941,32 +2006,66 @@ class AdScheduler {
|
|
|
1941
2006
|
}
|
|
1942
2007
|
|
|
1943
2008
|
/**
|
|
1944
|
-
* SimidSession —
|
|
2009
|
+
* SimidSession — IAB SIMID 1.2 (Secure Interactive Media Interface Definition) implementation.
|
|
1945
2010
|
*
|
|
1946
|
-
*
|
|
1947
|
-
*
|
|
1948
|
-
*
|
|
1949
|
-
*
|
|
1950
|
-
*
|
|
2011
|
+
* SIMID 1.2 session initialization sequence:
|
|
2012
|
+
* 1. Creative → Player : createSession (with sessionId)
|
|
2013
|
+
* 2. Player → Creative: resolve (acks createSession)
|
|
2014
|
+
* 3. Player → Creative: SIMID:Player:init (environmentData + creativeData)
|
|
2015
|
+
* 4. Creative → Player : resolve (acks init)
|
|
2016
|
+
* 5. Creative → Player : SIMID:Creative:ready
|
|
2017
|
+
* 6. Player → Creative: SIMID:Player:startCreative
|
|
2018
|
+
* 7. Creative → Player : resolve (acks startCreative)
|
|
2019
|
+
*
|
|
2020
|
+
* Message format notes:
|
|
2021
|
+
* - Some SIMID creatives post messages as JSON-encoded strings rather than plain objects.
|
|
2022
|
+
* handleMessage() handles both via parseMessageData().
|
|
2023
|
+
* - The outgoing format mirrors the incoming format: if the creative sends JSON strings
|
|
2024
|
+
* (i.e. JSON.parse(event.data) is used on the creative side), the player also sends
|
|
2025
|
+
* JSON strings so they parse correctly. Format is auto-detected on the first message.
|
|
2026
|
+
* - Older creatives may skip createSession and go straight to SIMID:Creative:ready.
|
|
2027
|
+
* onCreativeReady() falls back to sending init + startCreative in that case.
|
|
1951
2028
|
*
|
|
1952
2029
|
* Spec: https://iabtechlab.com/standards/simid/
|
|
1953
2030
|
*/
|
|
1954
2031
|
// ─── Message type constants ───────────────────────────────────────────────────
|
|
1955
2032
|
const SIMID_PLAYER = {
|
|
1956
2033
|
INIT: 'SIMID:Player:init',
|
|
1957
|
-
|
|
2034
|
+
START_CREATIVE: 'SIMID:Player:startCreative',
|
|
1958
2035
|
AD_PROGRESS: 'SIMID:Player:adProgress',
|
|
1959
2036
|
AD_PAUSED: 'SIMID:Player:adPaused',
|
|
1960
2037
|
AD_PLAYING: 'SIMID:Player:adPlaying',
|
|
1961
2038
|
AD_STOPPED: 'SIMID:Player:adStopped',
|
|
1962
2039
|
AD_SKIPPED: 'SIMID:Player:adSkipped',
|
|
1963
2040
|
AD_VOLUME: 'SIMID:Player:adVolume',
|
|
2041
|
+
AD_DURATION_CHANGE: 'SIMID:Player:adDurationChange',
|
|
1964
2042
|
RESIZE: 'SIMID:Player:resize',
|
|
1965
2043
|
FATAL: 'SIMID:Player:fatal',
|
|
1966
2044
|
LOG: 'SIMID:Player:log',
|
|
2045
|
+
APP_BACKGROUNDED: 'SIMID:Player:appBackgrounded',
|
|
2046
|
+
APP_FOREGROUNDED: 'SIMID:Player:appForegrounded',
|
|
2047
|
+
/** Player resolves a creative request (spec type: "resolve") */
|
|
2048
|
+
RESOLVE: 'resolve',
|
|
2049
|
+
/** Player rejects a creative request (spec type: "reject") */
|
|
2050
|
+
REJECT: 'reject',
|
|
2051
|
+
};
|
|
2052
|
+
/** SIMID 1.2 media event types — player bridges ad video DOM events to these postMessages. */
|
|
2053
|
+
const SIMID_MEDIA = {
|
|
2054
|
+
DURATION_CHANGE: 'SIMID:Media:durationchange',
|
|
2055
|
+
ENDED: 'SIMID:Media:ended',
|
|
2056
|
+
ERROR: 'SIMID:Media:error',
|
|
2057
|
+
PAUSE: 'SIMID:Media:pause',
|
|
2058
|
+
PLAY: 'SIMID:Media:play',
|
|
2059
|
+
PLAYING: 'SIMID:Media:playing',
|
|
2060
|
+
SEEKED: 'SIMID:Media:seeked',
|
|
2061
|
+
SEEKING: 'SIMID:Media:seeking',
|
|
2062
|
+
STALLED: 'SIMID:Media:stalled',
|
|
2063
|
+
TIME_UPDATE: 'SIMID:Media:timeupdate',
|
|
2064
|
+
VOLUME_CHANGE: 'SIMID:Media:volumechange',
|
|
1967
2065
|
};
|
|
1968
2066
|
const SIMID_CREATIVE = {
|
|
1969
2067
|
READY: 'SIMID:Creative:ready',
|
|
2068
|
+
GET_MEDIA_STATE: 'SIMID:Creative:getMediaState',
|
|
1970
2069
|
RESOLVE: 'SIMID:Creative:resolve',
|
|
1971
2070
|
REJECT: 'SIMID:Creative:reject',
|
|
1972
2071
|
REQUEST_FULLSCREEN: 'SIMID:Creative:requestFullscreen',
|
|
@@ -1977,11 +2076,13 @@ const SIMID_CREATIVE = {
|
|
|
1977
2076
|
REQUEST_STOP: 'SIMID:Creative:requestStop',
|
|
1978
2077
|
REQUEST_PAUSE: 'SIMID:Creative:requestPause',
|
|
1979
2078
|
REQUEST_PLAY: 'SIMID:Creative:requestPlay',
|
|
2079
|
+
REQUEST_CHANGE_AD_DURATION: 'SIMID:Creative:requestChangeAdDuration',
|
|
1980
2080
|
FATAL: 'SIMID:Creative:fatal',
|
|
1981
2081
|
LOG: 'SIMID:Creative:log',
|
|
1982
2082
|
};
|
|
2083
|
+
// ─── SimidSession ─────────────────────────────────────────────────────────────
|
|
1983
2084
|
class SimidSession {
|
|
1984
|
-
constructor(iframe, adVideo, callbacks) {
|
|
2085
|
+
constructor(iframe, adVideo, callbacks, creativeInfo) {
|
|
1985
2086
|
Object.defineProperty(this, "iframe", {
|
|
1986
2087
|
enumerable: true,
|
|
1987
2088
|
configurable: true,
|
|
@@ -2000,7 +2101,13 @@ class SimidSession {
|
|
|
2000
2101
|
writable: true,
|
|
2001
2102
|
value: callbacks
|
|
2002
2103
|
});
|
|
2003
|
-
Object.defineProperty(this, "
|
|
2104
|
+
Object.defineProperty(this, "creativeInfo", {
|
|
2105
|
+
enumerable: true,
|
|
2106
|
+
configurable: true,
|
|
2107
|
+
writable: true,
|
|
2108
|
+
value: creativeInfo
|
|
2109
|
+
});
|
|
2110
|
+
Object.defineProperty(this, "msgCounter", {
|
|
2004
2111
|
enumerable: true,
|
|
2005
2112
|
configurable: true,
|
|
2006
2113
|
writable: true,
|
|
@@ -2018,6 +2125,24 @@ class SimidSession {
|
|
|
2018
2125
|
writable: true,
|
|
2019
2126
|
value: void 0
|
|
2020
2127
|
});
|
|
2128
|
+
Object.defineProperty(this, "sessionId", {
|
|
2129
|
+
enumerable: true,
|
|
2130
|
+
configurable: true,
|
|
2131
|
+
writable: true,
|
|
2132
|
+
value: ''
|
|
2133
|
+
});
|
|
2134
|
+
Object.defineProperty(this, "initSent", {
|
|
2135
|
+
enumerable: true,
|
|
2136
|
+
configurable: true,
|
|
2137
|
+
writable: true,
|
|
2138
|
+
value: false
|
|
2139
|
+
});
|
|
2140
|
+
Object.defineProperty(this, "initPromise", {
|
|
2141
|
+
enumerable: true,
|
|
2142
|
+
configurable: true,
|
|
2143
|
+
writable: true,
|
|
2144
|
+
value: null
|
|
2145
|
+
});
|
|
2021
2146
|
Object.defineProperty(this, "started", {
|
|
2022
2147
|
enumerable: true,
|
|
2023
2148
|
configurable: true,
|
|
@@ -2030,53 +2155,210 @@ class SimidSession {
|
|
|
2030
2155
|
writable: true,
|
|
2031
2156
|
value: false
|
|
2032
2157
|
});
|
|
2158
|
+
Object.defineProperty(this, "mediaListeners", {
|
|
2159
|
+
enumerable: true,
|
|
2160
|
+
configurable: true,
|
|
2161
|
+
writable: true,
|
|
2162
|
+
value: []
|
|
2163
|
+
});
|
|
2164
|
+
Object.defineProperty(this, "visibilityHandler", {
|
|
2165
|
+
enumerable: true,
|
|
2166
|
+
configurable: true,
|
|
2167
|
+
writable: true,
|
|
2168
|
+
value: null
|
|
2169
|
+
});
|
|
2170
|
+
/**
|
|
2171
|
+
* Detected outgoing message format.
|
|
2172
|
+
* 'plain' — post plain JS objects (spec default, works with most creatives)
|
|
2173
|
+
* 'json-string' — post JSON.stringify(payload) as the message value; used when the
|
|
2174
|
+
* creative calls JSON.parse(event.data) to deserialise incoming messages
|
|
2175
|
+
* (e.g. Google's compiled SIMID sample creative)
|
|
2176
|
+
*/
|
|
2177
|
+
Object.defineProperty(this, "outgoingFormat", {
|
|
2178
|
+
enumerable: true,
|
|
2179
|
+
configurable: true,
|
|
2180
|
+
writable: true,
|
|
2181
|
+
value: 'plain'
|
|
2182
|
+
});
|
|
2183
|
+
Object.defineProperty(this, "_targetOrigin", {
|
|
2184
|
+
enumerable: true,
|
|
2185
|
+
configurable: true,
|
|
2186
|
+
writable: true,
|
|
2187
|
+
value: null
|
|
2188
|
+
});
|
|
2033
2189
|
this.messageListener = this.handleMessage.bind(this);
|
|
2034
2190
|
window.addEventListener('message', this.messageListener);
|
|
2191
|
+
this.bindMediaEvents();
|
|
2035
2192
|
}
|
|
2036
|
-
// ─── Internal
|
|
2193
|
+
// ─── Internal messaging helpers ───────────────────────────────────────────
|
|
2037
2194
|
nextMsgId() {
|
|
2038
|
-
return ++this.
|
|
2195
|
+
return ++this.msgCounter;
|
|
2039
2196
|
}
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2197
|
+
/**
|
|
2198
|
+
* Returns the target origin for postMessage calls to the creative iframe.
|
|
2199
|
+
* Lazily derived from iframe.src so we don't need a constructor argument.
|
|
2200
|
+
* Falls back to '*' only when the src is not an absolute URL (e.g. data: URIs
|
|
2201
|
+
* used in tests), which is an acceptable edge case.
|
|
2202
|
+
*/
|
|
2203
|
+
getTargetOrigin() {
|
|
2204
|
+
if (this._targetOrigin !== null)
|
|
2205
|
+
return this._targetOrigin;
|
|
2206
|
+
try {
|
|
2207
|
+
const origin = new URL(this.iframe.src, window.location.href).origin;
|
|
2208
|
+
// data: and blob: URLs produce the string "null" as their origin — treat as wildcard.
|
|
2209
|
+
this._targetOrigin = origin === 'null' ? '*' : origin;
|
|
2210
|
+
}
|
|
2211
|
+
catch {
|
|
2212
|
+
this._targetOrigin = '*';
|
|
2213
|
+
}
|
|
2214
|
+
return this._targetOrigin;
|
|
2215
|
+
}
|
|
2216
|
+
/**
|
|
2217
|
+
* Post a payload to the creative's iframe using the detected outgoing format.
|
|
2218
|
+
* - 'plain': postMessage(payload, origin)
|
|
2219
|
+
* - 'json-string': postMessage(JSON.stringify(payload), origin)
|
|
2220
|
+
*/
|
|
2221
|
+
postMsg(payload) {
|
|
2222
|
+
const data = this.outgoingFormat === 'json-string' ? JSON.stringify(payload) : payload;
|
|
2223
|
+
this.iframe.contentWindow?.postMessage(data, this.getTargetOrigin());
|
|
2224
|
+
}
|
|
2225
|
+
/**
|
|
2226
|
+
* Send a player→creative message that expects a resolve/reject response.
|
|
2227
|
+
* Returns a promise that resolves/rejects when the creative responds.
|
|
2228
|
+
*/
|
|
2229
|
+
send(type, args) {
|
|
2230
|
+
const messageId = this.nextMsgId();
|
|
2231
|
+
const payload = {
|
|
2232
|
+
type,
|
|
2233
|
+
messageId,
|
|
2234
|
+
sessionId: this.sessionId || undefined,
|
|
2235
|
+
timestamp: Date.now(),
|
|
2236
|
+
args: args ?? {},
|
|
2237
|
+
};
|
|
2043
2238
|
return new Promise((resolve, reject) => {
|
|
2044
|
-
this.pending.set(
|
|
2239
|
+
this.pending.set(messageId, { resolve, reject });
|
|
2045
2240
|
try {
|
|
2046
|
-
this.
|
|
2241
|
+
this.postMsg(payload);
|
|
2047
2242
|
}
|
|
2048
2243
|
catch (e) {
|
|
2049
|
-
this.pending.delete(
|
|
2244
|
+
this.pending.delete(messageId);
|
|
2050
2245
|
reject(e);
|
|
2051
2246
|
}
|
|
2052
2247
|
});
|
|
2053
2248
|
}
|
|
2249
|
+
/**
|
|
2250
|
+
* Send a resolve response to the creative for a message it sent us.
|
|
2251
|
+
* Per spec: type="resolve", args={ messageId: <original>, value: <payload> }
|
|
2252
|
+
*/
|
|
2253
|
+
sendResolve(resolvedMessageId, value) {
|
|
2254
|
+
try {
|
|
2255
|
+
this.postMsg({
|
|
2256
|
+
type: SIMID_PLAYER.RESOLVE,
|
|
2257
|
+
messageId: this.nextMsgId(),
|
|
2258
|
+
sessionId: this.sessionId || undefined,
|
|
2259
|
+
timestamp: Date.now(),
|
|
2260
|
+
args: { messageId: resolvedMessageId, value: value ?? {} },
|
|
2261
|
+
});
|
|
2262
|
+
}
|
|
2263
|
+
catch {
|
|
2264
|
+
/* ignore */
|
|
2265
|
+
}
|
|
2266
|
+
}
|
|
2267
|
+
/**
|
|
2268
|
+
* Send a reject response to the creative for a message it sent us.
|
|
2269
|
+
*/
|
|
2270
|
+
sendReject(resolvedMessageId, errorCode, message) {
|
|
2271
|
+
try {
|
|
2272
|
+
this.postMsg({
|
|
2273
|
+
type: SIMID_PLAYER.REJECT,
|
|
2274
|
+
messageId: this.nextMsgId(),
|
|
2275
|
+
sessionId: this.sessionId || undefined,
|
|
2276
|
+
timestamp: Date.now(),
|
|
2277
|
+
args: { messageId: resolvedMessageId, value: { errorCode, message } },
|
|
2278
|
+
});
|
|
2279
|
+
}
|
|
2280
|
+
catch {
|
|
2281
|
+
/* ignore */
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
// ─── Message parsing ──────────────────────────────────────────────────────
|
|
2285
|
+
/**
|
|
2286
|
+
* Parse a raw postMessage payload into a SimidMessage.
|
|
2287
|
+
* Handles both plain objects and JSON-encoded strings.
|
|
2288
|
+
* Auto-detects the outgoing format from the first valid message received.
|
|
2289
|
+
*/
|
|
2290
|
+
parseMessageData(raw) {
|
|
2291
|
+
if (typeof raw === 'string') {
|
|
2292
|
+
let parsed;
|
|
2293
|
+
try {
|
|
2294
|
+
parsed = JSON.parse(raw);
|
|
2295
|
+
}
|
|
2296
|
+
catch {
|
|
2297
|
+
return null;
|
|
2298
|
+
}
|
|
2299
|
+
if (!parsed?.type)
|
|
2300
|
+
return null;
|
|
2301
|
+
// Creative sends JSON strings → it expects JSON strings back.
|
|
2302
|
+
if (this.outgoingFormat === 'plain')
|
|
2303
|
+
this.outgoingFormat = 'json-string';
|
|
2304
|
+
return parsed;
|
|
2305
|
+
}
|
|
2306
|
+
if (raw && typeof raw === 'object')
|
|
2307
|
+
return raw;
|
|
2308
|
+
return null;
|
|
2309
|
+
}
|
|
2310
|
+
// ─── Message dispatch ─────────────────────────────────────────────────────
|
|
2054
2311
|
handleMessage(event) {
|
|
2055
2312
|
if (this.destroyed)
|
|
2056
2313
|
return;
|
|
2057
|
-
const data = event.data;
|
|
2058
|
-
if (!data ||
|
|
2314
|
+
const data = this.parseMessageData(event.data);
|
|
2315
|
+
if (!data || !data.type)
|
|
2059
2316
|
return;
|
|
2317
|
+
// Support both SIMID 1.2 (messageId) and legacy (msgId) fields.
|
|
2318
|
+
const incomingId = data.messageId ?? data.msgId ?? 0;
|
|
2060
2319
|
switch (data.type) {
|
|
2320
|
+
// ── SIMID 1.2 session init ───────────────────────────────────────────
|
|
2321
|
+
case 'createSession':
|
|
2322
|
+
this.onCreateSession(incomingId, data.sessionId || '');
|
|
2323
|
+
break;
|
|
2324
|
+
case SIMID_CREATIVE.GET_MEDIA_STATE:
|
|
2325
|
+
this.sendResolve(incomingId, this.getMediaState());
|
|
2326
|
+
break;
|
|
2061
2327
|
case SIMID_CREATIVE.READY:
|
|
2062
|
-
this.onCreativeReady(
|
|
2328
|
+
void this.onCreativeReady();
|
|
2063
2329
|
break;
|
|
2330
|
+
// ── Promise resolution ───────────────────────────────────────────────
|
|
2331
|
+
// IAB reference creatives (simid_protocol.js) and Google's compiled sample send
|
|
2332
|
+
// type="resolve" / type="reject" when acknowledging player messages.
|
|
2333
|
+
// Some third-party implementations send type="SIMID:Creative:resolve" / "SIMID:Creative:reject".
|
|
2334
|
+
// Both forms are handled here.
|
|
2335
|
+
case 'resolve': // IAB reference implementation pattern
|
|
2336
|
+
// falls through
|
|
2064
2337
|
case SIMID_CREATIVE.RESOLVE: {
|
|
2065
|
-
|
|
2338
|
+
// `resolves` (top-level) or args.messageId both point to our outgoing messageId.
|
|
2339
|
+
const resolvedId = data.resolves ?? data.args?.messageId;
|
|
2340
|
+
const pending = resolvedId != null ? this.pending.get(resolvedId) : undefined;
|
|
2066
2341
|
if (pending) {
|
|
2067
|
-
this.pending.delete(
|
|
2068
|
-
pending.resolve(data.args);
|
|
2342
|
+
this.pending.delete(resolvedId);
|
|
2343
|
+
pending.resolve(data.args?.value ?? data.args);
|
|
2069
2344
|
}
|
|
2070
2345
|
break;
|
|
2071
2346
|
}
|
|
2347
|
+
case 'reject': // IAB reference implementation pattern
|
|
2348
|
+
// falls through
|
|
2072
2349
|
case SIMID_CREATIVE.REJECT: {
|
|
2073
|
-
const
|
|
2350
|
+
const rejectedId = data.rejects ?? data.args?.messageId;
|
|
2351
|
+
const pending = rejectedId != null ? this.pending.get(rejectedId) : undefined;
|
|
2074
2352
|
if (pending) {
|
|
2075
|
-
this.pending.delete(
|
|
2076
|
-
pending.reject({
|
|
2353
|
+
this.pending.delete(rejectedId);
|
|
2354
|
+
pending.reject({
|
|
2355
|
+
errorCode: data.errorCode ?? data.args?.value?.errorCode,
|
|
2356
|
+
reason: data.reason ?? data.args?.value?.message,
|
|
2357
|
+
});
|
|
2077
2358
|
}
|
|
2078
2359
|
break;
|
|
2079
2360
|
}
|
|
2361
|
+
// ── Creative → Player commands ───────────────────────────────────────
|
|
2080
2362
|
case SIMID_CREATIVE.REQUEST_SKIP:
|
|
2081
2363
|
this.callbacks.onSkip();
|
|
2082
2364
|
break;
|
|
@@ -2100,17 +2382,29 @@ class SimidSession {
|
|
|
2100
2382
|
this.callbacks.onTrackingEvent(trackingEvent, data.args);
|
|
2101
2383
|
break;
|
|
2102
2384
|
}
|
|
2103
|
-
case SIMID_CREATIVE.REQUEST_FULLSCREEN:
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
container
|
|
2385
|
+
case SIMID_CREATIVE.REQUEST_FULLSCREEN: {
|
|
2386
|
+
const container = this.iframe.closest('.op-ads') ?? this.iframe.parentElement;
|
|
2387
|
+
if (container?.requestFullscreen) {
|
|
2388
|
+
container.requestFullscreen().catch(() => this.sendReject(incomingId, 403, 'Fullscreen denied'));
|
|
2389
|
+
}
|
|
2390
|
+
else {
|
|
2391
|
+
this.sendReject(incomingId, 403, 'Fullscreen not supported');
|
|
2107
2392
|
}
|
|
2108
|
-
catch { /* ignore */ }
|
|
2109
2393
|
break;
|
|
2394
|
+
}
|
|
2110
2395
|
case SIMID_CREATIVE.REQUEST_RESIZE:
|
|
2111
|
-
// Best-effort: notify the creative of current dimensions.
|
|
2112
2396
|
void this.resize(this.iframe.offsetWidth || window.innerWidth, this.iframe.offsetHeight || window.innerHeight);
|
|
2113
2397
|
break;
|
|
2398
|
+
case SIMID_CREATIVE.REQUEST_CHANGE_AD_DURATION: {
|
|
2399
|
+
const durationChange = Number(data.args?.durationChange ?? data.args?.duration ?? 0);
|
|
2400
|
+
if (this.callbacks.onRequestChangeAdDuration) {
|
|
2401
|
+
this.callbacks.onRequestChangeAdDuration(durationChange, () => this.sendResolve(incomingId, {}), (errorCode, reason) => this.sendReject(incomingId, errorCode, reason));
|
|
2402
|
+
}
|
|
2403
|
+
else {
|
|
2404
|
+
this.sendReject(incomingId, 403, 'requestChangeAdDuration not supported');
|
|
2405
|
+
}
|
|
2406
|
+
break;
|
|
2407
|
+
}
|
|
2114
2408
|
case SIMID_CREATIVE.FATAL:
|
|
2115
2409
|
this.callbacks.onFatal(data.errorCode ?? 901, data.reason ?? 'Creative fatal error');
|
|
2116
2410
|
break;
|
|
@@ -2119,63 +2413,177 @@ class SimidSession {
|
|
|
2119
2413
|
break;
|
|
2120
2414
|
}
|
|
2121
2415
|
}
|
|
2122
|
-
// ───
|
|
2123
|
-
|
|
2416
|
+
// ─── Session initialization ───────────────────────────────────────────────
|
|
2417
|
+
/**
|
|
2418
|
+
* SIMID 1.2: creative sends createSession first.
|
|
2419
|
+
* Player responds with resolve, then immediately sends init.
|
|
2420
|
+
*/
|
|
2421
|
+
onCreateSession(messageId, sessionId) {
|
|
2422
|
+
if (sessionId)
|
|
2423
|
+
this.sessionId = sessionId;
|
|
2424
|
+
this.sendResolve(messageId);
|
|
2425
|
+
if (!this.initSent) {
|
|
2426
|
+
this.initSent = true;
|
|
2427
|
+
this.initPromise = this.send(SIMID_PLAYER.INIT, {
|
|
2428
|
+
creativeData: this.buildCreativeData(),
|
|
2429
|
+
environmentData: this.buildEnvironmentData(),
|
|
2430
|
+
})
|
|
2431
|
+
.then(() => {
|
|
2432
|
+
// Creative resolved SIMID:Player:init → send startCreative immediately.
|
|
2433
|
+
// Creatives that never send SIMID:Creative:ready (e.g. Google's compiled sample)
|
|
2434
|
+
// rely on this path to trigger the interactive content.
|
|
2435
|
+
if (!this.started && !this.destroyed) {
|
|
2436
|
+
this.started = true;
|
|
2437
|
+
return this.send(SIMID_PLAYER.START_CREATIVE).catch(() => undefined);
|
|
2438
|
+
}
|
|
2439
|
+
})
|
|
2440
|
+
.catch(() => undefined);
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
/**
|
|
2444
|
+
* Creative signals it is ready for startCreative.
|
|
2445
|
+
* If no createSession was received (older creatives), init is sent here as a fallback.
|
|
2446
|
+
*/
|
|
2447
|
+
async onCreativeReady() {
|
|
2124
2448
|
if (this.started)
|
|
2125
2449
|
return;
|
|
2126
2450
|
this.started = true;
|
|
2451
|
+
try {
|
|
2452
|
+
if (!this.initSent) {
|
|
2453
|
+
// Fallback: older creatives that skip createSession.
|
|
2454
|
+
this.initSent = true;
|
|
2455
|
+
await this.send(SIMID_PLAYER.INIT, {
|
|
2456
|
+
creativeData: this.buildCreativeData(),
|
|
2457
|
+
environmentData: this.buildEnvironmentData(),
|
|
2458
|
+
});
|
|
2459
|
+
}
|
|
2460
|
+
else if (this.initPromise) {
|
|
2461
|
+
// Wait for the in-flight init to be acknowledged before startCreative.
|
|
2462
|
+
await this.initPromise;
|
|
2463
|
+
}
|
|
2464
|
+
await this.send(SIMID_PLAYER.START_CREATIVE);
|
|
2465
|
+
}
|
|
2466
|
+
catch {
|
|
2467
|
+
/* Creative may reject — continue ad playback regardless */
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
// ─── Data builders ────────────────────────────────────────────────────────
|
|
2471
|
+
buildEnvironmentData() {
|
|
2127
2472
|
const v = this.adVideo;
|
|
2128
|
-
const
|
|
2129
|
-
const
|
|
2130
|
-
const
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2473
|
+
const playerRect = this.iframe.getBoundingClientRect();
|
|
2474
|
+
const videoRect = v.getBoundingClientRect();
|
|
2475
|
+
const pw = Math.round(playerRect.width) || v.offsetWidth || 640;
|
|
2476
|
+
const ph = Math.round(playerRect.height) || v.offsetHeight || 360;
|
|
2477
|
+
const vw = Math.round(videoRect.width) || pw;
|
|
2478
|
+
const vh = Math.round(videoRect.height) || ph;
|
|
2479
|
+
const vol = v.muted ? 0 : Number.isFinite(v.volume) ? v.volume : 1;
|
|
2480
|
+
return {
|
|
2481
|
+
// ── SIMID 1.2 required fields ────────────────────────────────────────
|
|
2482
|
+
videoDimensions: {
|
|
2483
|
+
x: Math.round(videoRect.left),
|
|
2484
|
+
y: Math.round(videoRect.top),
|
|
2485
|
+
width: vw,
|
|
2486
|
+
height: vh,
|
|
2487
|
+
},
|
|
2488
|
+
creativeDimensions: {
|
|
2489
|
+
x: Math.round(playerRect.left),
|
|
2490
|
+
y: Math.round(playerRect.top),
|
|
2491
|
+
width: pw,
|
|
2492
|
+
height: ph,
|
|
2493
|
+
},
|
|
2494
|
+
fullscreen: !!document.fullscreenElement,
|
|
2136
2495
|
fullscreenAllowed: true,
|
|
2496
|
+
variableDurationAllowed: typeof this.callbacks.onRequestChangeAdDuration === 'function',
|
|
2497
|
+
skippableState: 'notSkippable',
|
|
2498
|
+
version: '1.2',
|
|
2499
|
+
// ── SIMID 1.2 optional fields ────────────────────────────────────────
|
|
2500
|
+
siteUrl: typeof window !== 'undefined' ? window.location.href : '',
|
|
2501
|
+
muted: v.muted,
|
|
2502
|
+
volume: vol,
|
|
2503
|
+
// ── Legacy compatibility (older SIMID creatives) ─────────────────────
|
|
2504
|
+
playerWidth: pw,
|
|
2505
|
+
playerHeight: ph,
|
|
2506
|
+
videoDuration: Number.isFinite(v.duration) ? v.duration : 0,
|
|
2507
|
+
videoVolume: vol,
|
|
2137
2508
|
};
|
|
2138
|
-
try {
|
|
2139
|
-
await this.send(SIMID_PLAYER.INIT, { creativeData, environmentData }, msg.msgId ? undefined : this.nextMsgId());
|
|
2140
|
-
await this.send(SIMID_PLAYER.START_AD);
|
|
2141
|
-
}
|
|
2142
|
-
catch { /* Creative may reject — continue ad playback regardless */ }
|
|
2143
2509
|
}
|
|
2144
|
-
|
|
2510
|
+
buildCreativeData() {
|
|
2511
|
+
return {
|
|
2512
|
+
adParameters: this.creativeInfo?.adParameters ?? '',
|
|
2513
|
+
clickThruUrl: this.creativeInfo?.clickThruUri ?? '',
|
|
2514
|
+
clickThruUri: this.creativeInfo?.clickThruUri ?? '',
|
|
2515
|
+
};
|
|
2516
|
+
}
|
|
2517
|
+
/** Current media state snapshot, used to respond to SIMID:Creative:getMediaState. */
|
|
2518
|
+
getMediaState() {
|
|
2519
|
+
const v = this.adVideo;
|
|
2520
|
+
return {
|
|
2521
|
+
currentSrc: v.currentSrc || v.src || '',
|
|
2522
|
+
currentTime: v.currentTime,
|
|
2523
|
+
duration: Number.isFinite(v.duration) ? v.duration : 0,
|
|
2524
|
+
ended: v.ended,
|
|
2525
|
+
muted: v.muted,
|
|
2526
|
+
paused: v.paused,
|
|
2527
|
+
volume: v.volume,
|
|
2528
|
+
fullscreen: !!document.fullscreenElement,
|
|
2529
|
+
};
|
|
2530
|
+
}
|
|
2531
|
+
// ─── Player → Creative public API ─────────────────────────────────────────
|
|
2532
|
+
/** Manually send SIMID:Player:init (e.g. when not using the automatic handshake). */
|
|
2145
2533
|
init(creativeData, environmentData) {
|
|
2146
2534
|
return this.send(SIMID_PLAYER.INIT, { creativeData, environmentData });
|
|
2147
2535
|
}
|
|
2536
|
+
/** Manually send SIMID:Player:startCreative. */
|
|
2148
2537
|
start() {
|
|
2149
|
-
return this.send(SIMID_PLAYER.
|
|
2538
|
+
return this.send(SIMID_PLAYER.START_CREATIVE);
|
|
2150
2539
|
}
|
|
2151
2540
|
progress(currentTime, duration) {
|
|
2152
2541
|
if (this.destroyed)
|
|
2153
2542
|
return;
|
|
2154
|
-
const msg = {
|
|
2155
|
-
type: SIMID_PLAYER.AD_PROGRESS,
|
|
2156
|
-
msgId: this.nextMsgId(),
|
|
2157
|
-
args: { currentTime, duration, remainingTime: Math.max(0, duration - currentTime) },
|
|
2158
|
-
};
|
|
2159
2543
|
try {
|
|
2160
|
-
this.
|
|
2544
|
+
this.postMsg({
|
|
2545
|
+
type: SIMID_PLAYER.AD_PROGRESS,
|
|
2546
|
+
messageId: this.nextMsgId(),
|
|
2547
|
+
sessionId: this.sessionId || undefined,
|
|
2548
|
+
timestamp: Date.now(),
|
|
2549
|
+
args: { currentTime, duration, remainingTime: Math.max(0, duration - currentTime) },
|
|
2550
|
+
});
|
|
2551
|
+
}
|
|
2552
|
+
catch {
|
|
2553
|
+
/* ignore */
|
|
2161
2554
|
}
|
|
2162
|
-
catch { /* ignore */ }
|
|
2163
2555
|
}
|
|
2164
2556
|
pause() {
|
|
2165
2557
|
if (this.destroyed)
|
|
2166
2558
|
return;
|
|
2167
2559
|
try {
|
|
2168
|
-
this.
|
|
2560
|
+
this.postMsg({
|
|
2561
|
+
type: SIMID_PLAYER.AD_PAUSED,
|
|
2562
|
+
messageId: this.nextMsgId(),
|
|
2563
|
+
sessionId: this.sessionId || undefined,
|
|
2564
|
+
timestamp: Date.now(),
|
|
2565
|
+
args: {},
|
|
2566
|
+
});
|
|
2567
|
+
}
|
|
2568
|
+
catch {
|
|
2569
|
+
/* ignore */
|
|
2169
2570
|
}
|
|
2170
|
-
catch { /* ignore */ }
|
|
2171
2571
|
}
|
|
2172
2572
|
resume() {
|
|
2173
2573
|
if (this.destroyed)
|
|
2174
2574
|
return;
|
|
2175
2575
|
try {
|
|
2176
|
-
this.
|
|
2576
|
+
this.postMsg({
|
|
2577
|
+
type: SIMID_PLAYER.AD_PLAYING,
|
|
2578
|
+
messageId: this.nextMsgId(),
|
|
2579
|
+
sessionId: this.sessionId || undefined,
|
|
2580
|
+
timestamp: Date.now(),
|
|
2581
|
+
args: {},
|
|
2582
|
+
});
|
|
2583
|
+
}
|
|
2584
|
+
catch {
|
|
2585
|
+
/* ignore */
|
|
2177
2586
|
}
|
|
2178
|
-
catch { /* ignore */ }
|
|
2179
2587
|
}
|
|
2180
2588
|
stop() {
|
|
2181
2589
|
if (this.destroyed)
|
|
@@ -2186,21 +2594,49 @@ class SimidSession {
|
|
|
2186
2594
|
if (this.destroyed)
|
|
2187
2595
|
return;
|
|
2188
2596
|
try {
|
|
2189
|
-
this.
|
|
2597
|
+
this.postMsg({
|
|
2598
|
+
type: SIMID_PLAYER.AD_SKIPPED,
|
|
2599
|
+
messageId: this.nextMsgId(),
|
|
2600
|
+
sessionId: this.sessionId || undefined,
|
|
2601
|
+
timestamp: Date.now(),
|
|
2602
|
+
args: {},
|
|
2603
|
+
});
|
|
2604
|
+
}
|
|
2605
|
+
catch {
|
|
2606
|
+
/* ignore */
|
|
2190
2607
|
}
|
|
2191
|
-
catch { /* ignore */ }
|
|
2192
2608
|
}
|
|
2193
2609
|
volumeChange(volume, muted) {
|
|
2194
2610
|
if (this.destroyed)
|
|
2195
2611
|
return;
|
|
2196
2612
|
try {
|
|
2197
|
-
this.
|
|
2613
|
+
this.postMsg({
|
|
2198
2614
|
type: SIMID_PLAYER.AD_VOLUME,
|
|
2199
|
-
|
|
2615
|
+
messageId: this.nextMsgId(),
|
|
2616
|
+
sessionId: this.sessionId || undefined,
|
|
2617
|
+
timestamp: Date.now(),
|
|
2200
2618
|
args: { volume, muted },
|
|
2201
|
-
}
|
|
2619
|
+
});
|
|
2620
|
+
}
|
|
2621
|
+
catch {
|
|
2622
|
+
/* ignore */
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
adDurationChange(duration) {
|
|
2626
|
+
if (this.destroyed)
|
|
2627
|
+
return;
|
|
2628
|
+
try {
|
|
2629
|
+
this.postMsg({
|
|
2630
|
+
type: SIMID_PLAYER.AD_DURATION_CHANGE,
|
|
2631
|
+
messageId: this.nextMsgId(),
|
|
2632
|
+
sessionId: this.sessionId || undefined,
|
|
2633
|
+
timestamp: Date.now(),
|
|
2634
|
+
args: { duration },
|
|
2635
|
+
});
|
|
2636
|
+
}
|
|
2637
|
+
catch {
|
|
2638
|
+
/* ignore */
|
|
2202
2639
|
}
|
|
2203
|
-
catch { /* ignore */ }
|
|
2204
2640
|
}
|
|
2205
2641
|
resize(width, height) {
|
|
2206
2642
|
return this.send(SIMID_PLAYER.RESIZE, { width, height });
|
|
@@ -2209,20 +2645,91 @@ class SimidSession {
|
|
|
2209
2645
|
if (this.destroyed)
|
|
2210
2646
|
return;
|
|
2211
2647
|
try {
|
|
2212
|
-
this.
|
|
2648
|
+
this.postMsg({
|
|
2213
2649
|
type: SIMID_PLAYER.FATAL,
|
|
2214
|
-
|
|
2650
|
+
messageId: this.nextMsgId(),
|
|
2651
|
+
sessionId: this.sessionId || undefined,
|
|
2652
|
+
timestamp: Date.now(),
|
|
2215
2653
|
args: { errorCode, reason },
|
|
2216
|
-
}
|
|
2654
|
+
});
|
|
2655
|
+
}
|
|
2656
|
+
catch {
|
|
2657
|
+
/* ignore */
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
// ─── Media event bridging ─────────────────────────────────────────────────
|
|
2661
|
+
/**
|
|
2662
|
+
* Bridge ad video DOM events to SIMID:Media:* postMessages and
|
|
2663
|
+
* document visibility changes to SIMID:Player:appBackgrounded/Foregrounded.
|
|
2664
|
+
* Called once from the constructor; listeners are cleaned up in destroy().
|
|
2665
|
+
*/
|
|
2666
|
+
bindMediaEvents() {
|
|
2667
|
+
const v = this.adVideo;
|
|
2668
|
+
const mediaEventMap = [
|
|
2669
|
+
['durationchange', SIMID_MEDIA.DURATION_CHANGE],
|
|
2670
|
+
['ended', SIMID_MEDIA.ENDED],
|
|
2671
|
+
['error', SIMID_MEDIA.ERROR],
|
|
2672
|
+
['pause', SIMID_MEDIA.PAUSE],
|
|
2673
|
+
['play', SIMID_MEDIA.PLAY],
|
|
2674
|
+
['playing', SIMID_MEDIA.PLAYING],
|
|
2675
|
+
['seeked', SIMID_MEDIA.SEEKED],
|
|
2676
|
+
['seeking', SIMID_MEDIA.SEEKING],
|
|
2677
|
+
['stalled', SIMID_MEDIA.STALLED],
|
|
2678
|
+
['timeupdate', SIMID_MEDIA.TIME_UPDATE],
|
|
2679
|
+
['volumechange', SIMID_MEDIA.VOLUME_CHANGE],
|
|
2680
|
+
];
|
|
2681
|
+
for (const [domEvent, simidType] of mediaEventMap) {
|
|
2682
|
+
const handler = () => {
|
|
2683
|
+
if (this.destroyed)
|
|
2684
|
+
return;
|
|
2685
|
+
try {
|
|
2686
|
+
this.postMsg({
|
|
2687
|
+
type: simidType,
|
|
2688
|
+
messageId: this.nextMsgId(),
|
|
2689
|
+
sessionId: this.sessionId || undefined,
|
|
2690
|
+
timestamp: Date.now(),
|
|
2691
|
+
args: this.getMediaState(),
|
|
2692
|
+
});
|
|
2693
|
+
}
|
|
2694
|
+
catch {
|
|
2695
|
+
/* ignore */
|
|
2696
|
+
}
|
|
2697
|
+
};
|
|
2698
|
+
v.addEventListener(domEvent, handler);
|
|
2699
|
+
this.mediaListeners.push({ event: domEvent, handler });
|
|
2217
2700
|
}
|
|
2218
|
-
|
|
2701
|
+
this.visibilityHandler = () => {
|
|
2702
|
+
if (this.destroyed)
|
|
2703
|
+
return;
|
|
2704
|
+
const type = document.hidden ? SIMID_PLAYER.APP_BACKGROUNDED : SIMID_PLAYER.APP_FOREGROUNDED;
|
|
2705
|
+
try {
|
|
2706
|
+
this.postMsg({
|
|
2707
|
+
type,
|
|
2708
|
+
messageId: this.nextMsgId(),
|
|
2709
|
+
sessionId: this.sessionId || undefined,
|
|
2710
|
+
timestamp: Date.now(),
|
|
2711
|
+
args: {},
|
|
2712
|
+
});
|
|
2713
|
+
}
|
|
2714
|
+
catch {
|
|
2715
|
+
/* ignore */
|
|
2716
|
+
}
|
|
2717
|
+
};
|
|
2718
|
+
document.addEventListener('visibilitychange', this.visibilityHandler);
|
|
2219
2719
|
}
|
|
2220
2720
|
destroy() {
|
|
2221
2721
|
if (this.destroyed)
|
|
2222
2722
|
return;
|
|
2223
2723
|
this.destroyed = true;
|
|
2224
2724
|
window.removeEventListener('message', this.messageListener);
|
|
2225
|
-
|
|
2725
|
+
for (const { event, handler } of this.mediaListeners) {
|
|
2726
|
+
this.adVideo.removeEventListener(event, handler);
|
|
2727
|
+
}
|
|
2728
|
+
this.mediaListeners = [];
|
|
2729
|
+
if (this.visibilityHandler) {
|
|
2730
|
+
document.removeEventListener('visibilitychange', this.visibilityHandler);
|
|
2731
|
+
this.visibilityHandler = null;
|
|
2732
|
+
}
|
|
2226
2733
|
for (const [, p] of this.pending) {
|
|
2227
2734
|
p.reject({ errorCode: 900, reason: 'SimidSession destroyed' });
|
|
2228
2735
|
}
|
|
@@ -2295,16 +2802,6 @@ function extendAds(player, plugin) {
|
|
|
2295
2802
|
}
|
|
2296
2803
|
|
|
2297
2804
|
class AdsPlugin {
|
|
2298
|
-
get dom() {
|
|
2299
|
-
if (!this._dom) {
|
|
2300
|
-
const overlay = document.createElement('div');
|
|
2301
|
-
this._dom = new AdDomManager(overlay, this.cfg, () => this.adVideo, () => this.tracker, () => { });
|
|
2302
|
-
}
|
|
2303
|
-
return this._dom;
|
|
2304
|
-
}
|
|
2305
|
-
set dom(v) {
|
|
2306
|
-
this._dom = v;
|
|
2307
|
-
}
|
|
2308
2805
|
constructor(config = {}) {
|
|
2309
2806
|
Object.defineProperty(this, "name", {
|
|
2310
2807
|
enumerable: true,
|
|
@@ -2522,6 +3019,7 @@ class AdsPlugin {
|
|
|
2522
3019
|
companionSelector: config.companionSelector,
|
|
2523
3020
|
adSourcesMode: config.adSourcesMode ?? 'waterfall',
|
|
2524
3021
|
omid: config.omid ?? {},
|
|
3022
|
+
labels: config.labels ?? {},
|
|
2525
3023
|
};
|
|
2526
3024
|
}
|
|
2527
3025
|
setup(ctx) {
|
|
@@ -2604,6 +3102,16 @@ class AdsPlugin {
|
|
|
2604
3102
|
this.dom.ensureOverlayMounted(this.ctx.core.media);
|
|
2605
3103
|
this.dom.mountSimidIframe(simidUrl);
|
|
2606
3104
|
}
|
|
3105
|
+
get dom() {
|
|
3106
|
+
if (!this._dom) {
|
|
3107
|
+
const overlay = document.createElement('div');
|
|
3108
|
+
this._dom = new AdDomManager(overlay, this.cfg, () => this.adVideo, () => this.tracker, () => { });
|
|
3109
|
+
}
|
|
3110
|
+
return this._dom;
|
|
3111
|
+
}
|
|
3112
|
+
set dom(v) {
|
|
3113
|
+
this._dom = v;
|
|
3114
|
+
}
|
|
2607
3115
|
// ─── Preroll interception ─────────────────────────────────────────────────────
|
|
2608
3116
|
bindPrerollInterceptors() {
|
|
2609
3117
|
const { events, core } = this.ctx;
|
|
@@ -2958,6 +3466,14 @@ class AdsPlugin {
|
|
|
2958
3466
|
const simidUrl = extractSimidUrl(item.creative, rawDoc);
|
|
2959
3467
|
if (simidUrl && this.adVideo) {
|
|
2960
3468
|
const iframe = this.dom.mountSimidIframe(simidUrl);
|
|
3469
|
+
const clickThruRaw = item.creative?.videoClickThroughURLTemplate?.url ??
|
|
3470
|
+
item.creative?.videoClickThroughURLTemplate ??
|
|
3471
|
+
item.creative?.videoClicks?.clickThrough ??
|
|
3472
|
+
'';
|
|
3473
|
+
const simidCreativeInfo = {
|
|
3474
|
+
adParameters: String(item.creative?.linear?.adParameters?.value ?? item.creative?.adParameters?.value ?? ''),
|
|
3475
|
+
clickThruUri: typeof clickThruRaw === 'string' ? clickThruRaw : String(clickThruRaw || ''),
|
|
3476
|
+
};
|
|
2961
3477
|
this.simidSession = new SimidSession(iframe, this.adVideo, {
|
|
2962
3478
|
onSkip: () => this.requestSkip('api'),
|
|
2963
3479
|
onStop: () => {
|
|
@@ -2992,7 +3508,15 @@ class AdsPlugin {
|
|
|
2992
3508
|
this.simidSession?.destroy();
|
|
2993
3509
|
this.simidSession = undefined;
|
|
2994
3510
|
},
|
|
2995
|
-
|
|
3511
|
+
onRequestChangeAdDuration: (durationChange, resolve, _reject) => {
|
|
3512
|
+
// Accept the request; notify the creative of the new total duration.
|
|
3513
|
+
resolve();
|
|
3514
|
+
const v = this.adVideo;
|
|
3515
|
+
if (v && Number.isFinite(v.duration)) {
|
|
3516
|
+
this.simidSession?.adDurationChange(v.duration + durationChange);
|
|
3517
|
+
}
|
|
3518
|
+
},
|
|
3519
|
+
}, simidCreativeInfo);
|
|
2996
3520
|
this.sessionUnsubs.push(() => {
|
|
2997
3521
|
this.simidSession?.destroy();
|
|
2998
3522
|
this.simidSession = undefined;
|
|
@@ -3010,6 +3534,9 @@ class AdsPlugin {
|
|
|
3010
3534
|
}
|
|
3011
3535
|
this.bus.emit('ads:allAdsCompleted', { break: meta });
|
|
3012
3536
|
this.ctx.events.emit('ads.allAdsCompleted', { break: meta });
|
|
3537
|
+
const announcer = this.overlay && this.overlay.querySelector('.op-ads__sr-announcer');
|
|
3538
|
+
if (announcer)
|
|
3539
|
+
announcer.textContent = this.cfg.labels?.adEnded || 'Advertisement ended';
|
|
3013
3540
|
this.finish({
|
|
3014
3541
|
resume: meta.kind !== 'postroll' && (this.userPlayIntent || this.resumeAfter),
|
|
3015
3542
|
suppressResume: opts?.suppressResumeOnSuccess,
|
|
@@ -3032,6 +3559,15 @@ class AdsPlugin {
|
|
|
3032
3559
|
this.overlay.replaceChildren();
|
|
3033
3560
|
this.overlay.style.display = 'block';
|
|
3034
3561
|
this.active = true;
|
|
3562
|
+
if (!this.overlay.querySelector('.op-ads__sr-announcer')) {
|
|
3563
|
+
const announcer = document.createElement('div');
|
|
3564
|
+
announcer.className = 'op-ads__sr-announcer op-player__sr-only';
|
|
3565
|
+
announcer.setAttribute('role', 'status');
|
|
3566
|
+
announcer.setAttribute('aria-live', 'polite');
|
|
3567
|
+
announcer.setAttribute('aria-atomic', 'true');
|
|
3568
|
+
announcer.textContent = this.cfg.labels?.advertisement || 'Advertisement';
|
|
3569
|
+
this.overlay.appendChild(announcer);
|
|
3570
|
+
}
|
|
3035
3571
|
const items = collectNonLinearCreatives(parsed);
|
|
3036
3572
|
if (!items.length)
|
|
3037
3573
|
return;
|