tag rather than using window.open \n // because it works better in standalone mode and WebView\n this.clickUIOnMobile = document.createElement('a');\n this.clickUIOnMobile.className = 'rmp-ad-click-ui-mobile';\n this.clickUIOnMobile.textContent = this.params.labels.textForClickUIOnMobile;\n this.clickUIOnMobile.addEventListener('touchend', this.onClickThrough);\n this.clickUIOnMobile.href = this.creative.clickThroughUrl;\n this.clickUIOnMobile.target = '_blank';\n this.adContainer.appendChild(this.clickUIOnMobile);\n};\n\nconst _onContextMenu = function (event) {\n if (event) {\n event.stopPropagation();\n event.preventDefault();\n }\n};\n\nconst _setCanBeSkippedUI = function () {\n FW.setStyle(this.skipWaiting, { display: 'none' });\n FW.setStyle(this.skipMessage, { display: 'block' });\n FW.setStyle(this.skipIcon, { display: 'block' });\n};\n\nconst _updateWaitingForCanBeSkippedUI = function (delta) {\n if (Math.round(delta) > 0) {\n this.skipWaiting.textContent = this.params.labels.skipMessage + ' ' + Math.round(delta) + 's';\n }\n};\n\nconst _onTimeupdateCheckSkip = function () {\n if (this.skipButton.style.display === 'none') {\n FW.setStyle(this.skipButton, { display: 'block' });\n }\n this.vastPlayerCurrentTime = this.vastPlayer.currentTime;\n if (FW.isNumber(this.vastPlayerCurrentTime) && this.vastPlayerCurrentTime > 0) {\n if (this.vastPlayerCurrentTime >= this.creative.skipoffset) {\n this.vastPlayer.removeEventListener('timeupdate', this.onTimeupdateCheckSkip);\n _setCanBeSkippedUI.call(this);\n this.skippableAdCanBeSkipped = true;\n Utils.createApiEvent.call(this, 'adskippablestatechanged');\n } else if (this.creative.skipoffset - this.vastPlayerCurrentTime > 0) {\n _updateWaitingForCanBeSkippedUI.call(this, this.creative.skipoffset - this.vastPlayerCurrentTime);\n }\n }\n};\n\nconst _onClickSkip = function (event) {\n if (event) {\n event.stopPropagation();\n if (event.type === 'touchend') {\n event.preventDefault();\n }\n }\n if (this.skippableAdCanBeSkipped) {\n // create API event \n Utils.createApiEvent.call(this, 'adskipped');\n // request ping for skip event\n TRACKING_EVENTS.dispatch.call(this, 'skip');\n // resume content\n VAST_PLAYER.resumeContent.call(this);\n }\n};\n\nconst _appendSkip = function () {\n this.skipButton = document.createElement('div');\n this.skipButton.className = 'rmp-ad-container-skip';\n FW.setStyle(this.skipButton, { display: 'none' });\n Utils.makeButtonAccessible(this.skipButton, this.params.labels.skipMessage);\n\n this.skipWaiting = document.createElement('div');\n this.skipWaiting.className = 'rmp-ad-container-skip-waiting';\n _updateWaitingForCanBeSkippedUI.call(this, this.creative.skipoffset);\n FW.setStyle(this.skipWaiting, { display: 'block' });\n\n this.skipMessage = document.createElement('div');\n this.skipMessage.className = 'rmp-ad-container-skip-message';\n this.skipMessage.textContent = this.params.labels.skipMessage;\n FW.setStyle(this.skipMessage, { display: 'none' });\n\n this.skipIcon = document.createElement('div');\n this.skipIcon.className = 'rmp-ad-container-skip-icon';\n FW.setStyle(this.skipIcon, { display: 'none' });\n\n this.onClickSkip = _onClickSkip.bind(this);\n this.skipButton.addEventListener('click', this.onClickSkip);\n this.skipButton.addEventListener('touchend', this.onClickSkip);\n this.skipButton.appendChild(this.skipWaiting);\n this.skipButton.appendChild(this.skipMessage);\n this.skipButton.appendChild(this.skipIcon);\n this.adContainer.appendChild(this.skipButton);\n this.onTimeupdateCheckSkip = _onTimeupdateCheckSkip.bind(this);\n this.vastPlayer.addEventListener('timeupdate', this.onTimeupdateCheckSkip);\n};\n\nconst _onHlsJSError = function (event, data) {\n if (data.fatal) {\n switch (data.type) {\n case Hls.ErrorTypes.NETWORK_ERROR:\n // try to recover network error\n this.hlsJS[this.hlsJSIndex].startLoad();\n break;\n case Hls.ErrorTypes.MEDIA_ERROR:\n this.hlsJS[this.hlsJSIndex].recoverMediaError();\n break;\n default:\n Utils.processVastErrors.call(this, 900, true);\n break;\n }\n }\n};\n\nLINEAR.update = function (url, type) {\n console.log(\n `${FW.consolePrepend} update vast player for linear creative of type ${type} located at ${url}`,\n FW.consoleStyle,\n ''\n );\n\n this.onDurationChange = _onDurationChange.bind(this);\n this.vastPlayer.addEventListener('durationchange', this.onDurationChange, { once: true });\n\n // when creative is loaded play it \n this.onLoadedmetadataPlay = _onLoadedmetadataPlay.bind(this);\n this.vastPlayer.addEventListener('loadedmetadata', this.onLoadedmetadataPlay, { once: true });\n\n // prevent built in menu to show on right click\n this.onContextMenu = _onContextMenu.bind(this);\n this.vastPlayer.addEventListener('contextmenu', this.onContextMenu);\n\n this.onPlaybackError = _onPlaybackError.bind(this);\n\n // start creativeLoadTimeout\n this.creativeLoadTimeoutCallback = setTimeout(() => {\n Utils.processVastErrors.call(this, 402, true);\n }, this.params.creativeLoadTimeout);\n // load ad asset\n if (this.useContentPlayerForAds) {\n this.contentPlayer.addEventListener('error', this.onPlaybackError);\n this.contentPlayer.src = url;\n } else {\n if (this.params.useHlsJS && type === 'application/vnd.apple.mpegurl' && typeof window.Hls !== 'undefined' &&\n Hls.isSupported()) {\n this.readingHlsJS = true;\n const hlsJSConfig = {\n autoStartLoad: true,\n debug: this.params.debugHlsJS,\n capLevelToPlayerSize: true,\n testBandwidth: true,\n progressive: false,\n lowLatencyMode: false,\n enableWebVTT: false,\n enableIMSC1: false,\n enableCEA708Captions: false\n };\n this.hlsJS[this.hlsJSIndex] = new Hls(hlsJSConfig);\n this.hlsJS[this.hlsJSIndex].on(Hls.Events.ERROR, _onHlsJSError.bind(this));\n this.hlsJS[this.hlsJSIndex].loadSource(url);\n this.hlsJS[this.hlsJSIndex].attachMedia(this.vastPlayer);\n } else {\n if (typeof this.creative.simid === 'undefined' || (this.creative.simid && !this.params.enableSimid)) {\n this.vastPlayer.addEventListener('error', this.onPlaybackError);\n this.vastPlayer.src = url;\n // we need this extra load for Chrome data saver mode in mobile or desktop\n this.vastPlayer.load();\n } else {\n if (this.simidPlayer) {\n this.simidPlayer.stopAd();\n }\n this.simidPlayer = new SimidPlayer(\n this.creative.isLinear,\n this.creative.simid,\n url,\n this.creative.adId,\n this.creative.id,\n this.ad.adServingId,\n this.creative.clickThroughUrl,\n this\n );\n this.simidPlayer.initializeAd();\n this.simidPlayer.playAd();\n }\n }\n }\n\n // clickthrough interaction\n this.onClickThrough = _onClickThrough.bind(this);\n if (this.creative.clickThroughUrl) {\n if (ENV.isMobile) {\n _appendClickUIOnMobile.call(this);\n } else {\n this.vastPlayer.addEventListener('click', this.onClickThrough);\n }\n }\n\n // skippable - only where vast player is different from \n // content player\n if (this.creative.isSkippableAd) {\n _appendSkip.call(this);\n }\n};\n\nLINEAR.parse = function (icons, adParameters, mediaFiles) {\n if (icons.length > 0) {\n ICONS.parse.call(this, icons);\n }\n // check for AdParameters tag in case we have a VPAID creative\n this.adParametersData = '';\n if (adParameters !== null) {\n this.adParametersData = adParameters;\n }\n let mediaFileItems = [];\n for (let i = 0; i < mediaFiles.length; i++) {\n const currentMediaFile = mediaFiles[i];\n const mediaFileValue = currentMediaFile.fileURL;\n const type = currentMediaFile.mimeType;\n if (mediaFileValue === null || type === null) {\n continue;\n }\n const newMediaFileItem = {};\n newMediaFileItem.url = mediaFileValue;\n newMediaFileItem.type = type;\n if (currentMediaFile.codec !== null) {\n newMediaFileItem.codec = currentMediaFile.codec;\n }\n // check for potential VPAID - we have a VPAID JS - we break\n // for VPAID we may not have a width, height or delivery\n if (this.params.enableVpaid && currentMediaFile.apiFramework &&\n VPAID_PATTERN.test(currentMediaFile.apiFramework) && JS_PATTERN.test(type)) {\n\n console.log(`${FW.consolePrepend} VPAID creative detected`, FW.consoleStyle, '');\n\n mediaFileItems = [newMediaFileItem];\n this.isVPAID = true;\n break;\n }\n newMediaFileItem.width = currentMediaFile.width;\n newMediaFileItem.height = currentMediaFile.height;\n newMediaFileItem.bitrate = currentMediaFile.bitrate;\n mediaFileItems.push(newMediaFileItem);\n }\n // we support HLS; MP4; WebM: VPAID so let us fecth for those\n const creatives = [];\n for (let j = 0; j < mediaFileItems.length; j++) {\n const currentMediaFileItem = mediaFileItems[j];\n const type = currentMediaFileItem.type;\n const url = currentMediaFileItem.url;\n if (this.isVPAID && url) {\n VPAID.loadCreative.call(this, url, this.params.vpaidSettings);\n this.creative.type = type;\n return;\n }\n // we have HLS > use hls.js where no native support for HLS is available or native HLS otherwise (Apple devices mainly)\n if (type === 'application/vnd.apple.mpegurl' &&\n (ENV.checkCanPlayType(type) ||\n (typeof window.Hls !== 'undefined' && Hls.isSupported()))) {\n VAST_PLAYER.append.call(this, url, type);\n this.creative.type = type;\n return;\n }\n // we have DASH and DASH is natively supported > use DASH\n if (ENV.checkCanPlayType('application/dash+xml')) {\n VAST_PLAYER.append.call(this, url, type);\n this.creative.type = type;\n return;\n }\n // we gather MP4, WebM, OGG and remaining files\n creatives.push(currentMediaFileItem);\n }\n let retainedCreatives = [];\n // first we check for the common formats below ... \n const __filterCommonCreatives = function (i, creative) {\n if (creative.codec && creative.type === COMMON_VIDEO_FORMATS[i]) {\n return ENV.checkCanPlayType(creative.type, creative.codec);\n } else if (creative.type === COMMON_VIDEO_FORMATS[i]) {\n return ENV.checkCanPlayType(creative.type);\n }\n return false;\n };\n for (let k = 0; k < COMMON_VIDEO_FORMATS.length; k++) {\n retainedCreatives = creatives.filter(__filterCommonCreatives.bind(null, k));\n if (retainedCreatives.length > 0) {\n break;\n }\n }\n // ... if none of the common format work, then we check for exotic format\n // first we check for those with codec information as it provides more accurate support indication ...\n if (retainedCreatives.length === 0) {\n const __filterCodecCreatives = function (codec, type, creative) {\n return creative.codec === codec && creative.type === type;\n };\n creatives.forEach(creative => {\n if (creative.codec && creative.type && ENV.checkCanPlayType(creative.type, creative.codec)) {\n retainedCreatives = creatives.filter(__filterCodecCreatives.bind(null, creative.codec, creative.type));\n }\n });\n }\n // ... if codec information are not available then we go first type matching\n if (retainedCreatives.length === 0) {\n const __filterTypeCreatives = function (type, creative) {\n return creative.type === type;\n };\n creatives.forEach(creative => {\n if (creative.type && ENV.checkCanPlayType(creative.type)) {\n retainedCreatives = creatives.filter(__filterTypeCreatives.bind(null, creative.type));\n }\n });\n }\n\n // still no match for supported format - we exit\n if (retainedCreatives.length === 0) {\n // None of the MediaFile provided are supported by the player\n Utils.processVastErrors.call(this, 403, true);\n return;\n }\n\n // sort supported creatives by width\n retainedCreatives.sort((a, b) => {\n return a.width - b.width;\n });\n\n console.log(`${FW.consolePrepend} available linear creative follows`, FW.consoleStyle, '');\n console.log(retainedCreatives);\n\n // we have files matching device capabilities\n // select the best one based on player current width\n let finalCreative;\n let validCreativesByWidth = [];\n let validCreativesByBitrate = [];\n if (retainedCreatives.length > 1) {\n const containerWidth = FW.getWidth(this.container) * ENV.devicePixelRatio;\n const containerHeight = FW.getHeight(this.container) * ENV.devicePixelRatio;\n if (containerWidth > 0 && containerHeight > 0) {\n validCreativesByWidth = retainedCreatives.filter((creative) => {\n return containerWidth >= creative.width && containerHeight >= creative.height;\n });\n }\n\n console.log(`${FW.consolePrepend} validCreativesByWidth follow`, FW.consoleStyle, '');\n console.log(validCreativesByWidth);\n\n // if no match by size \n if (validCreativesByWidth.length === 0) {\n validCreativesByWidth = [retainedCreatives[0]];\n }\n\n // filter by bitrate to provide best quality\n const rmpConnection = new RmpConnection();\n let availableBandwidth = rmpConnection.bandwidthData.estimate;\n\n console.log(`${FW.consolePrepend} availableBandwidth is ${availableBandwidth} Mbps`, FW.consoleStyle, '');\n\n if (availableBandwidth > -1 && validCreativesByWidth.length > 1) {\n // sort supported creatives by bitrates\n validCreativesByWidth.sort((a, b) => {\n return a.bitrate - b.bitrate;\n });\n // convert to kbps\n availableBandwidth = Math.round(availableBandwidth * 1000);\n validCreativesByBitrate = validCreativesByWidth.filter((creative) => {\n return availableBandwidth >= creative.bitrate;\n });\n\n console.log(`${FW.consolePrepend} validCreativesByBitrate follow`, FW.consoleStyle, '');\n console.log(validCreativesByBitrate);\n\n // pick max available bitrate\n finalCreative = validCreativesByBitrate[validCreativesByBitrate.length - 1];\n }\n }\n\n // if no match by bitrate \n if (!finalCreative) {\n if (validCreativesByWidth.length > 0) {\n finalCreative = validCreativesByWidth[validCreativesByWidth.length - 1];\n } else {\n retainedCreatives.sort((a, b) => {\n return a.bitrate - b.bitrate;\n });\n finalCreative = retainedCreatives[retainedCreatives.length - 1];\n }\n }\n\n console.log(`${FW.consolePrepend} selected linear creative follows`, FW.consoleStyle, '');\n console.log(finalCreative);\n\n this.creative.mediaUrl = finalCreative.url;\n this.creative.height = finalCreative.height;\n this.creative.width = finalCreative.width;\n this.creative.type = finalCreative.type;\n VAST_PLAYER.append.call(this, finalCreative.url, finalCreative.type);\n};\n\nexport default LINEAR;\n","import FW from '../framework/fw';\nimport ENV from '../framework/env';\nimport Utils from '../framework/utils';\nimport CONTENT_PLAYER from '../players/content-player';\nimport VPAID from '../players/vpaid';\nimport ICONS from '../creatives/icons';\nimport TRACKING_EVENTS from '../tracking/tracking-events';\nimport NON_LINEAR from '../creatives/non-linear';\nimport LINEAR from '../creatives/linear';\n\nconst VAST_PLAYER = {};\n\nconst _unwireVastPlayerEvents = function () {\n console.log(`${FW.consolePrepend} reset - unwireVastPlayerEvents`, FW.consoleStyle, '');\n\n if (this.nonLinearContainer) {\n this.nonLinearInnerElement.removeEventListener('load', this.onNonLinearLoadSuccess);\n this.nonLinearInnerElement.removeEventListener('error', this.onNonLinearLoadError);\n this.nonLinearATag.removeEventListener('click', this.onNonLinearClickThrough);\n this.nonLinearATag.removeEventListener('touchend', this.onNonLinearClickThrough);\n this.nonLinearClose.removeEventListener('click', this.onClickCloseNonLinear);\n this.nonLinearClose.removeEventListener('touchend', this.onClickCloseNonLinear);\n this.trackingTags.forEach(trackingTag => {\n this.nonLinearContainer.removeEventListener(trackingTag.event, this.onEventPingTracking);\n });\n }\n if (this.vastPlayer) {\n this.vastPlayer.removeEventListener('error', this.onPlaybackError);\n // vastPlayer content pause/resume events\n this.vastPlayer.removeEventListener('durationchange', this.onDurationChange);\n this.vastPlayer.removeEventListener('loadedmetadata', this.onLoadedmetadataPlay);\n this.vastPlayer.removeEventListener('contextmenu', this.onContextMenu);\n // unwire HTML5 video events\n this.vastPlayer.removeEventListener('pause', this.onPause);\n this.vastPlayer.removeEventListener('play', this.onPlay);\n this.vastPlayer.removeEventListener('playing', this.onPlaying);\n this.vastPlayer.removeEventListener('ended', this.onEnded);\n this.vastPlayer.removeEventListener('volumechange', this.onVolumeChange);\n this.vastPlayer.removeEventListener('timeupdate', this.onTimeupdate);\n\n // unwire HTML5 VAST events\n this.trackingTags.forEach(trackingTag => {\n this.vastPlayer.removeEventListener(trackingTag.event, this.onEventPingTracking);\n });\n // remove clicktrough handling\n this.vastPlayer.removeEventListener('click', this.onClickThrough);\n this.vastPlayer.removeEventListener('playing', this.onPlayingAppendIcons);\n // skip\n this.vastPlayer.removeEventListener('timeupdate', this.onTimeupdateCheckSkip);\n }\n if (this.skipButton) {\n this.skipButton.removeEventListener('click', this.onClickSkip);\n this.skipButton.removeEventListener('touchend', this.onClickSkip);\n }\n // click UI on mobile\n if (this.clickUIOnMobile) {\n this.clickUIOnMobile.removeEventListener('touchend', this.onClickThrough);\n }\n if (this.contentPlayer) {\n this.contentPlayer.removeEventListener('error', this.onPlaybackError);\n }\n};\n\nVAST_PLAYER.destroy = function () {\n console.log(`${FW.consolePrepend} start destroying vast player`, FW.consoleStyle, '');\n\n // destroy icons if any \n if (this.iconsData.length > 0) {\n ICONS.destroy.call(this);\n }\n if (this.isVPAID) {\n VPAID.destroy.call(this);\n }\n // unwire events\n _unwireVastPlayerEvents.call(this);\n // remove clickUI on mobile\n if (this.clickUIOnMobile) {\n FW.removeElement(this.clickUIOnMobile);\n }\n if (this.creative.isSkippableAd) {\n FW.removeElement(this.skipButton);\n }\n // hide rmp-ad-container\n FW.hide(this.adContainer);\n // unwire anti-seek logic (iOS)\n clearInterval(this.antiSeekLogicInterval);\n // reset creativeLoadTimeout\n clearTimeout(this.creativeLoadTimeoutCallback);\n if (this.useContentPlayerForAds) {\n if (!this.params.outstream) {\n if (this.nonLinearContainer) {\n FW.removeElement(this.nonLinearContainer);\n } else {\n // when content is restored we need to seek to previously known currentTime\n // this must happen on playing event\n // the below is some hack I come up with because Safari is confused with \n // what it is asked to do when post roll come into play\n if (this.currentContentCurrentTime > 4000) {\n this.needsSeekAdjust = true;\n if (this.contentPlayerCompleted) {\n this.needsSeekAdjust = false;\n }\n if (!this.seekAdjustAttached) {\n this.seekAdjustAttached = true;\n this.contentPlayer.addEventListener('playing', () => {\n if (this.needsSeekAdjust) {\n this.needsSeekAdjust = false;\n CONTENT_PLAYER.seekTo.call(this, this.currentContentCurrentTime);\n }\n });\n }\n }\n\n console.log(\n `${FW.consolePrepend} recovering content ${this.currentContentSrc} at time ${this.currentContentCurrentTime}`,\n FW.consoleStyle,\n ''\n );\n\n this.contentPlayer.src = this.currentContentSrc;\n }\n } else {\n // specific handling for outstream ad === flush buffer and do not attempt to resume content\n try {\n if (this.contentPlayer) {\n this.contentPlayer.pause();\n // empty buffer\n this.contentPlayer.removeAttribute('src');\n this.contentPlayer.load();\n\n console.log(`${FW.consolePrepend} flushing contentPlayer buffer after outstream ad`, FW.consoleStyle, '');\n }\n } catch (error) {\n console.warn(error);\n }\n }\n } else {\n // flush vastPlayer\n try {\n if (this.vastPlayer) {\n this.vastPlayer.pause();\n if (this.readingHlsJS) {\n this.readingHlsJS = false;\n this.hlsJS[this.hlsJSIndex].destroy();\n this.hlsJSIndex++;\n } else {\n // empty buffer\n this.vastPlayer.removeAttribute('src');\n this.vastPlayer.load();\n }\n FW.hide(this.vastPlayer);\n\n console.log(`${FW.consolePrepend} flushing vastPlayer buffer after ad`, FW.consoleStyle, '');\n }\n if (this.nonLinearContainer) {\n FW.removeElement(this.nonLinearContainer);\n }\n } catch (error) {\n console.warn(error);\n }\n }\n Utils.resetVariablesForNewLoadAds.call(this);\n Utils.createApiEvent.call(this, 'addestroyed');\n};\n\nVAST_PLAYER.init = function () {\n this.adContainer = document.createElement('div');\n this.adContainer.className = 'rmp-ad-container';\n this.contentWrapper.appendChild(this.adContainer);\n FW.hide(this.adContainer);\n if (!this.useContentPlayerForAds) {\n this.vastPlayer = document.createElement('video');\n FW.logVideoEvents(this.vastPlayer, 'vast');\n // disable casting of video ads for Android\n if (ENV.isAndroid[0] && typeof this.vastPlayer.disableRemotePlayback !== 'undefined') {\n this.vastPlayer.disableRemotePlayback = true;\n }\n this.vastPlayer.className = 'rmp-ad-vast-video-player';\n if (this.params.showControlsForVastPlayer) {\n this.vastPlayer.controls = true;\n } else {\n this.vastPlayer.controls = false;\n }\n\n // this.contentPlayer.muted may not be set because of a bug in some version of Chromium\n if (this.contentPlayer.hasAttribute('muted')) {\n this.contentPlayer.muted = true;\n }\n if (this.contentPlayer.muted) {\n this.vastPlayer.muted = true;\n }\n // black poster based 64 png\n this.vastPlayer.poster = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=';\n // note to myself: we use setAttribute for non-standard attribute (instead of . notation)\n this.vastPlayer.setAttribute('x-webkit-airplay', 'allow');\n if (typeof this.contentPlayer.playsInline === 'boolean' && this.contentPlayer.playsInline) {\n this.vastPlayer.playsInline = true;\n }\n this.vastPlayer.defaultPlaybackRate = 1;\n // append to rmp-ad-container\n FW.hide(this.vastPlayer);\n this.adContainer.appendChild(this.vastPlayer);\n } else {\n this.vastPlayer = this.contentPlayer;\n }\n // we track ended state for content player\n this.contentPlayer.addEventListener('ended', () => {\n if (this.adOnStage) {\n return;\n }\n this.contentPlayerCompleted = true;\n });\n // we need to preload as much creative data as possible\n // also on macOS and iOS Safari we need to force preload to avoid \n // playback issues\n this.vastPlayer.preload = 'auto';\n // we need to init the vast player video tag\n // according to https://developers.google.com/interactive-media-ads/docs/sdks/html5/mobile_video\n // to initialize the content element, a call to the load() method is sufficient.\n if (ENV.isMobile) {\n // on Android both this.contentPlayer (to resume content)\n // and this.vastPlayer (to start ads) needs to be init\n // on iOS only init this.vastPlayer (as same as this.contentPlayer)\n if (!this.useContentPlayerForAds) {\n this.contentPlayer.load();\n }\n this.vastPlayer.load();\n } else {\n // due to autoplay being blocked on macOS Safari 11+\n // we also need to init player on this browser\n // this also work on previous version of Safari\n if (this.useContentPlayerForAds) {\n this.vastPlayer.load();\n }\n }\n this.rmpVastInitialized = true;\n};\n\nVAST_PLAYER.append = function (url, type) {\n // in case loadAds is called several times - rmpVastInitialized is already true\n // but we still need to locate the vastPlayer\n if (!this.vastPlayer) {\n if (this.useContentPlayerForAds) {\n this.vastPlayer = this.contentPlayer;\n } else {\n // we use existing rmp-ad-vast-video-player as it is already \n // available and initialized (no need for user interaction)\n let existingVastPlayer = null;\n if (this.adContainer) {\n existingVastPlayer = this.adContainer.querySelector('.rmp-ad-vast-video-player');\n }\n if (existingVastPlayer === null) {\n Utils.processVastErrors.call(this, 900, true);\n return;\n }\n this.vastPlayer = existingVastPlayer;\n }\n }\n CONTENT_PLAYER.pause.call(this);\n if (!this.creative.isLinear) {\n // we do not display non-linear ads with outstream ad \n // they won't fit the format\n if (this.params.outstream) {\n\n console.log(\n `${FW.consolePrepend} non-linear creative detected for outstream ad mode - discarding creative`,\n FW.consoleStyle,\n ''\n );\n\n Utils.processVastErrors.call(this, 201, true);\n return;\n } else {\n NON_LINEAR.update.call(this);\n }\n } else {\n if (url && type) {\n LINEAR.update.call(this, url, type);\n }\n }\n // wire tracking events\n TRACKING_EVENTS.wire.call(this);\n\n // append icons - only where vast player is different from \n // content player\n if (!this.useContentPlayerForAds && this.iconsData.length > 0) {\n ICONS.append.call(this);\n }\n};\n\nVAST_PLAYER.setVolume = function (level) {\n if (this.vastPlayer) {\n this.vastPlayer.volume = level;\n }\n};\n\nVAST_PLAYER.getVolume = function () {\n if (this.vastPlayer) {\n return this.vastPlayer.volume;\n }\n return -1;\n};\n\nVAST_PLAYER.setMute = function (muted) {\n if (this.vastPlayer) {\n if (muted && !this.vastPlayer.muted) {\n this.vastPlayer.muted = true;\n } else if (!muted && this.vastPlayer.muted) {\n this.vastPlayer.muted = false;\n }\n }\n};\n\nVAST_PLAYER.getMute = function () {\n if (this.vastPlayer) {\n return this.vastPlayer.muted;\n }\n return false;\n};\n\nVAST_PLAYER.play = function (firstVastPlayerPlayRequest) {\n if (this.vastPlayer && this.vastPlayer.paused) {\n Utils.playPromise.call(this, 'vast', firstVastPlayerPlayRequest);\n }\n};\n\nVAST_PLAYER.pause = function () {\n if (this.vastPlayer && !this.vastPlayer.paused) {\n this.vastPlayer.pause();\n }\n};\n\nVAST_PLAYER.getDuration = function () {\n if (this.vastPlayer) {\n const duration = this.vastPlayer.duration;\n if (FW.isNumber(duration)) {\n return Math.round(duration * 1000);\n }\n }\n return -1;\n};\n\nVAST_PLAYER.getCurrentTime = function () {\n if (this.vastPlayer) {\n const currentTime = this.vastPlayer.currentTime;\n if (FW.isNumber(currentTime)) {\n return Math.round(currentTime * 1000);\n }\n }\n return -1;\n};\n\nVAST_PLAYER.resumeContent = function () {\n\n console.log(`${FW.consolePrepend} VAST_PLAYER.resumeContent requested`, FW.consoleStyle, '');\n\n VAST_PLAYER.destroy.call(this);\n this.readingHlsJS = false;\n // if this.contentPlayerCompleted = true - we are in a post-roll situation\n // in that case we must not resume content once the post-roll has completed\n // you can use setContentPlayerCompleted/getContentPlayerCompleted to support \n // custom use-cases when dynamically changing source for content\n // no need to resume content for outstream ads\n if (!this.contentPlayerCompleted && !this.params.outstream) {\n console.log(\n `${FW.consolePrepend} CONTENT_PLAYER.play requested after VAST_PLAYER.resumeContent`,\n FW.consoleStyle,\n ''\n );\n CONTENT_PLAYER.play.call(this);\n }\n this.contentPlayerCompleted = false;\n};\n\nexport default VAST_PLAYER;\n","import FW from './fw';\nimport ENV from './env';\nimport VAST_PLAYER from '../players/vast-player';\nimport TRACKING_EVENTS from '../tracking/tracking-events';\n\n// Indicates that the error was encountered when the ad was being loaded. \n// Possible causes: there was no response from the ad server, malformed ad response was returned ...\n// 300, 301, 302, 303, 304 Wrapper errors are managed in ast-client-js\nconst LOAD_ERROR_LIST = [\n 303,\n 900,\n 1001\n];\n\n// Indicates that the error was encountered after the ad loaded, during ad play. \n// Possible causes: ad assets could not be loaded, etc.\nconst PLAY_ERROR_LIST = [\n 201, 204, 205,\n 400, 401, 402, 403,\n 501, 502, 503,\n 603,\n 901,\n 1002\n];\n\nconst VAST_ERRORS_LIST = [{\n code: 201,\n description: 'Video player expecting different linearity.'\n}, {\n code: 204,\n description: 'Ad category was required but not provided.'\n}, {\n code: 205,\n description: 'Inline Category violates Wrapper BlockedAdCategories.'\n}, {\n code: 303,\n description: 'No VAST response after one or more Wrappers.'\n}, {\n code: 400,\n description: 'General Linear error. Video player is unable to display the Linear Ad.'\n}, {\n code: 401,\n description: 'File not found. Unable to find Linear/MediaFile from URI.'\n}, {\n code: 402,\n description: 'Timeout of MediaFile URI.'\n}, {\n code: 403,\n description: 'Couldn\\'t find MediaFile that is supported by this video player, based on the attributes of the MediaFile element.'\n}, {\n code: 501,\n description: 'Unable to display NonLinear Ad because creative dimensions do not align with creative display area (i.e. creative dimension too large).'\n}, {\n code: 502,\n description: 'Unable to fetch NonLinearAds/NonLinear resource.'\n}, {\n code: 503,\n description: 'Couldn\\'t find NonLinear resource with supported type.'\n}, {\n code: 603,\n description: 'Unable to fetch CompanionAds/Companion resource.'\n}, {\n code: 900,\n description: 'Undefined Error.'\n}, {\n code: 901,\n description: 'General VPAID error.'\n}, {\n code: 1001,\n description: 'Invalid input for loadAds method'\n}, {\n code: 1002,\n description: 'Required DOMParser API is not available'\n}, {\n code: 1100,\n description: 'SIMID error: UNSPECIFIED_CREATIVE_ERROR'\n}, {\n code: 1101,\n description: 'SIMID error: CANNOT_LOAD_RESOURCE'\n}, {\n code: 1102,\n description: 'SIMID error: PLAYBACK_AREA_UNUSABLE'\n}, {\n code: 1103,\n description: 'SIMID error: INCORRECT_VERSION'\n}, {\n code: 1104,\n description: 'SIMID error: TECHNICAL_ERROR'\n}, {\n code: 1105,\n description: 'SIMID error: EXPAND_NOT_POSSIBLE'\n}, {\n code: 1106,\n description: 'SIMID error: PAUSE_NOT_HONORED'\n}, {\n code: 1107,\n description: 'SIMID error: PLAYMODE_NOT_ADEQUATE'\n}, {\n code: 1108,\n description: 'SIMID error: CREATIVE_INTERNAL_ERROR'\n}, {\n code: 1109,\n description: 'SIMID error: DEVICE_NOT_SUPPORTED'\n}, {\n code: 1110,\n description: 'SIMID error: MESSAGES_NOT_FOLLOWING_SPEC'\n}, {\n code: 1111,\n description: 'SIMID error: PLAYER_RESPONSE_TIMEOUT'\n}, {\n code: 1200,\n description: 'SIMID error: UNSPECIFIED_PLAYER_ERROR'\n}, {\n code: 1201,\n description: 'SIMID error: WRONG_VERSION'\n}, {\n code: 1202,\n description: 'SIMID error: UNSUPPORTED_TIME'\n}, {\n code: 1203,\n description: 'SIMID error: UNSUPPORTED_FUNCTIONALITY_REQUEST'\n}, {\n code: 1204,\n description: 'SIMID error: UNSUPPORTED_ACTIONS'\n}, {\n code: 1205,\n description: 'SIMID error: POSTMESSAGE_CHANNEL_OVERLOADED'\n}, {\n code: 1206,\n description: 'SIMID error: VIDEO_COULD_NOT_LOAD'\n}, {\n code: 1207,\n description: 'SIMID error: VIDEO_TIME_OUT'\n}, {\n code: 1208,\n description: 'SIMID error: RESPONSE_TIMEOUT'\n}, {\n code: 1209,\n description: 'SIMID error: MEDIA_NOT_SUPPORTED'\n}, {\n code: 1210,\n description: 'SIMID error: SPEC_NOT_FOLLOWED_ON_INIT'\n}, {\n code: 1211,\n description: 'SIMID error: SPEC_NOT_FOLLOWED_ON_MESSAGES'\n}];\n\nexport default class Utils {\n\n static filterParams(inputParams) {\n const defaultParams = {\n ajaxTimeout: 5000,\n creativeLoadTimeout: 8000,\n ajaxWithCredentials: false,\n maxNumRedirects: 4,\n labels: {\n skipMessage: 'Skip ad',\n closeAd: 'Close ad',\n textForClickUIOnMobile: 'Learn more'\n },\n outstream: false,\n showControlsForVastPlayer: false,\n vastXmlInput: false,\n enableVpaid: true,\n enableSimid: false,\n vpaidSettings: {\n width: 640,\n height: 360,\n viewMode: 'normal',\n desiredBitrate: 500\n },\n useHlsJS: false,\n debugHlsJS: false,\n forceUseContentPlayerForAds: false,\n // OM SDK params\n omidSupport: false,\n omidAllowedVendors: [],\n omidUnderEvaluation: false,\n omidRunValidationScript: false,\n omidAutoplay: false,\n partnerName: 'rmp-vast',\n partnerVersion: RMP_VAST_VERSION\n };\n this.params = defaultParams;\n if (inputParams && typeof inputParams === 'object') {\n const keys = Object.keys(inputParams);\n keys.forEach(key => {\n if (typeof inputParams[key] === typeof this.params[key]) {\n if ((FW.isNumber(inputParams[key]) && inputParams[key] > 0) || typeof inputParams[key] !== 'number') {\n if (key === 'vpaidSettings') {\n if (FW.isNumber(inputParams.vpaidSettings.width) && inputParams.vpaidSettings.width > 0) {\n this.params.vpaidSettings.width = inputParams.vpaidSettings.width;\n }\n if (FW.isNumber(inputParams.vpaidSettings.height) && inputParams.vpaidSettings.height > 0) {\n this.params.vpaidSettings.height = inputParams.vpaidSettings.height;\n }\n if (typeof inputParams.vpaidSettings.viewMode === 'string' && inputParams.vpaidSettings.viewMode === 'fullscreen') {\n this.params.vpaidSettings.viewMode = inputParams.vpaidSettings.viewMode;\n }\n if (FW.isNumber(inputParams.vpaidSettings.desiredBitrate) && inputParams.vpaidSettings.desiredBitrate > 0) {\n this.params.vpaidSettings.desiredBitrate = inputParams.vpaidSettings.desiredBitrate;\n }\n } else {\n this.params[key] = inputParams[key];\n }\n }\n }\n });\n }\n }\n\n static createApiEvent(event) {\n // adloaded, addurationchange, adclick, adimpression, adstarted, \n // adtagloaded, adtagstartloading, adpaused, adresumed \n // advolumemuted, advolumechanged, adcomplete, adskipped, \n // adskippablestatechanged, adclosed\n // adfirstquartile, admidpoint, adthirdquartile, aderror, \n // addestroyed\n // adlinearchange, adexpandedchange, adremainingtimechange \n // adinteraction, adsizechange\n if (Array.isArray(event)) {\n event.forEach(currentEvent => {\n if (currentEvent) {\n console.log(currentEvent);\n this.dispatch(currentEvent);\n }\n });\n } else if (event) {\n console.log(event);\n this.dispatch(event);\n }\n }\n\n static playPromise(whichPlayer, firstPlayerPlayRequest) {\n let targetPlayer;\n switch (whichPlayer) {\n case 'content':\n targetPlayer = this.contentPlayer;\n break;\n case 'vast':\n targetPlayer = this.vastPlayer;\n break;\n default:\n break;\n }\n if (targetPlayer) {\n const playPromise = targetPlayer.play();\n // most modern browsers support play as a Promise\n // this lets us handle autoplay rejection \n // https://developers.google.com/web/updates/2016/03/play-returns-promise\n if (playPromise !== undefined) {\n playPromise.then(() => {\n\n console.log(\n `${FW.consolePrepend} playPromise on ${whichPlayer} player has succeeded`,\n FW.consoleStyle,\n ''\n );\n\n if (firstPlayerPlayRequest) {\n Utils.createApiEvent.call(this, 'adinitialplayrequestsucceeded');\n }\n }).catch(error => {\n console.warn(error);\n\n if (firstPlayerPlayRequest && whichPlayer === 'vast' && this.creative.isLinear) {\n console.log(\n `${FW.consolePrepend} initial play promise on VAST player has been rejected`,\n FW.consoleStyle,\n ''\n );\n\n Utils.processVastErrors.call(this, 400, true);\n Utils.createApiEvent.call(this, 'adinitialplayrequestfailed');\n } else if (firstPlayerPlayRequest && whichPlayer === 'content' && !this.creative.isLinear) {\n console.log(\n `${FW.consolePrepend} initial play promise on content player has been rejected`,\n FW.consoleStyle,\n ''\n );\n\n Utils.createApiEvent.call(this, 'adinitialplayrequestfailed');\n } else {\n console.log(\n `${FW.consolePrepend} playPromise on ${whichPlayer} player has been rejected`,\n FW.consoleStyle,\n ''\n );\n }\n });\n }\n }\n }\n\n static makeButtonAccessible(element, ariaLabel) {\n // make skip button accessible\n element.tabIndex = 0;\n element.setAttribute('role', 'button');\n element.addEventListener('keyup', (event) => {\n const code = event.which;\n // 13 = Return, 32 = Space\n if ((code === 13) || (code === 32)) {\n event.stopPropagation();\n event.preventDefault();\n FW.createSyntheticEvent('click', element);\n }\n });\n if (ariaLabel) {\n element.setAttribute('aria-label', ariaLabel);\n }\n }\n\n static initInstanceVariables() {\n this.adContainer = null;\n this.rmpVastInitialized = false;\n this.useContentPlayerForAds = false;\n this.contentPlayerCompleted = false;\n this.currentContentSrc = '';\n this.currentContentCurrentTime = -1;\n this.needsSeekAdjust = false;\n this.seekAdjustAttached = false;\n this.firstVastPlayerPlayRequest = true;\n this.firstContentPlayerPlayRequest = true;\n this.params = {};\n this.events = {};\n this.onFullscreenchange = FW.nullFn;\n this.contentWrapper = null;\n this.contentPlayer = null;\n this.id = null;\n this.container = null;\n this.isInFullscreen = false;\n // adpod\n this.adPod = false;\n this.adPodLength = 0;\n this.adSequence = 0;\n // on iOS we use content player to play ads\n // to avoid issues related to fullscreen management and autoplay\n // as fullscreen on iOS is handled by the default OS player\n if (ENV.isIos[0]) {\n this.useContentPlayerForAds = true;\n console.log(`${FW.consolePrepend} vast player will be content player`, FW.consoleStyle, '');\n }\n }\n\n static resetVariablesForNewLoadAds() {\n this.off('adstarted', this.attachViewableObserver);\n // init internal methods \n this.onLoadedmetadataPlay = FW.nullFn;\n this.onPlaybackError = FW.nullFn;\n // init internal tracking events methods\n this.onPause = FW.nullFn;\n this.onPlay = FW.nullFn;\n this.onPlaying = FW.nullFn;\n this.onEnded = FW.nullFn;\n this.onVolumeChange = FW.nullFn;\n this.onTimeupdate = FW.nullFn;\n this.onEventPingTracking = FW.nullFn;\n this.onClickThrough = FW.nullFn;\n this.onPlayingAppendIcons = FW.nullFn;\n this.onDurationChange = FW.nullFn;\n this.onTimeupdateCheckSkip = FW.nullFn;\n this.onClickSkip = FW.nullFn;\n this.onNonLinearLoadSuccess = FW.nullFn;\n this.onNonLinearLoadError = FW.nullFn;\n this.onNonLinearClickThrough = FW.nullFn;\n this.onContextMenu = FW.nullFn;\n // init internal variables\n this.adTagUrl = '';\n this.vastPlayer = null;\n this.vpaidSlot = null;\n this.trackingTags = [];\n this.vastErrorTags = [];\n this.adErrorTags = [];\n this.vastPlayerMuted = false;\n this.vastPlayerDuration = -1;\n this.vastPlayerCurrentTime = -1;\n this.firstQuartileEventFired = false;\n this.midpointEventFired = false;\n this.thirdQuartileEventFired = false;\n this.vastPlayerPaused = false;\n this.vastErrorCode = -1;\n this.adErrorType = '';\n this.vastErrorMessage = '';\n this.adOnStage = false;\n // hls.js\n this.hlsJS = [];\n this.hlsJSIndex = 0;\n this.readingHlsJS = false;\n // VAST ICONS\n this.iconsData = [];\n // players\n this.clickUIOnMobile = null;\n this.customPlaybackCurrentTime = 0;\n this.antiSeekLogicInterval = null;\n this.creativeLoadTimeoutCallback = null;\n // VAST 4\n this.ad = {};\n this.creative = {};\n this.attachViewableObserver = null;\n this.viewableObserver = null;\n this.viewablePreviousRatio = 0.5;\n this.regulationsInfo = {};\n this.requireCategory = false;\n // skip\n this.progressEvents = [];\n this.skipButton = null;\n this.skipWaiting = null;\n this.skipMessage = null;\n this.skipIcon = null;\n this.skippableAdCanBeSkipped = false;\n // non linear\n this.nonLinearContainer = null;\n this.nonLinearATag = null;\n this.nonLinearInnerElement = null;\n this.onClickCloseNonLinear = FW.nullFn;\n this.nonLinearMinSuggestedDuration = 0;\n // companion ads\n this.validCompanionAds = [];\n this.companionAdsRequiredAttribute = '';\n this.companionAdsList = [];\n // VPAID\n this.isVPAID = false;\n this.vpaidCreative = null;\n this.vpaidScript = null;\n this.vpaidIframe = null;\n this.vpaidLoadTimeout = null;\n this.initAdTimeout = null;\n this.startAdTimeout = null;\n this.vpaidAvailableInterval = null;\n this.adStoppedTimeout = null;\n this.adSkippedTimeout = null;\n this.adParametersData = '';\n this.vpaidCurrentVolume = 1;\n this.vpaidPaused = true;\n this.vpaidCreativeUrl = '';\n this.vpaidAdRemainingTimeInterval = null;\n this.vpaidRemainingTime = -1;\n this.vpaidVersion = -1;\n this.vpaid1AdDuration = -1;\n this.initialWidth = 640;\n this.initialHeight = 360;\n this.initialViewMode = 'normal';\n this.desiredBitrate = 500;\n this.vpaidAdLoaded = false;\n this.vpaidAdStarted = false;\n this.vpaidCallbacks = {};\n // SIMID\n this.simidPlayer = null;\n }\n\n // attach fullscreen states\n // this assumes we have a polyfill for fullscreenchange event \n // see app/js/app.js\n // we need this to handle VAST fullscreen events\n static _onFullscreenchange(event) {\n if (event && event.type) {\n console.log(`${FW.consolePrepend} event is ${event.type}`, FW.consoleStyle, '');\n\n if (event.type === 'fullscreenchange') {\n if (this.isInFullscreen) {\n this.isInFullscreen = false;\n if (this.adOnStage && this.creative.isLinear) {\n TRACKING_EVENTS.dispatch.call(this, ['exitFullscreen', 'playerCollapse']);\n }\n } else {\n this.isInFullscreen = true;\n if (this.adOnStage && this.creative.isLinear) {\n TRACKING_EVENTS.dispatch.call(this, ['fullscreen', 'playerExpand']);\n }\n }\n } else if (event.type === 'webkitbeginfullscreen') {\n // iOS uses webkitbeginfullscreen\n if (this.adOnStage && this.creative.isLinear) {\n TRACKING_EVENTS.dispatch.call(this, ['fullscreen', 'playerExpand']);\n }\n this.isInFullscreen = true;\n } else if (event.type === 'webkitendfullscreen') {\n // iOS uses webkitendfullscreen\n if (this.adOnStage && this.creative.isLinear) {\n TRACKING_EVENTS.dispatch.call(this, ['exitFullscreen', 'playerCollapse']);\n }\n this.isInFullscreen = false;\n }\n }\n }\n\n static handleFullscreen() {\n // if we have native fullscreen support we handle fullscreen events\n if (ENV.hasNativeFullscreenSupport) {\n this.onFullscreenchange = Utils._onFullscreenchange.bind(this);\n // for our beloved iOS \n if (ENV.isIos[0]) {\n this.contentPlayer.addEventListener('webkitbeginfullscreen', this.onFullscreenchange);\n this.contentPlayer.addEventListener('webkitendfullscreen', this.onFullscreenchange);\n } else {\n document.addEventListener('fullscreenchange', this.onFullscreenchange);\n }\n }\n }\n\n static _updateVastError(errorCode) {\n const error = VAST_ERRORS_LIST.filter((value) => {\n return value.code === errorCode;\n });\n if (error.length > 0) {\n this.vastErrorCode = error[0].code;\n this.vastErrorMessage = error[0].description;\n } else {\n this.vastErrorCode = -1;\n this.vastErrorMessage = 'Error getting VAST error';\n }\n if (this.vastErrorCode > -1) {\n if (LOAD_ERROR_LIST.indexOf(this.vastErrorCode) > -1) {\n this.adErrorType = 'adLoadError';\n } else if (PLAY_ERROR_LIST.indexOf(this.vastErrorCode) > -1) {\n this.adErrorType = 'adPlayError';\n }\n }\n\n console.log(`${FW.consolePrepend} VAST error code is ${this.vastErrorCode}`, FW.consoleStyle, '');\n console.log(`${FW.consolePrepend} VAST error message is ${this.vastErrorMessage}`, FW.consoleStyle, '');\n console.log(`${FW.consolePrepend} Ad error type is ${this.adErrorType}`, FW.consoleStyle, '');\n }\n\n static processVastErrors(errorCode, ping) {\n if (ping) {\n TRACKING_EVENTS.error.call(this, errorCode);\n }\n Utils._updateVastError.call(this, errorCode);\n Utils.createApiEvent.call(this, 'aderror');\n VAST_PLAYER.resumeContent.call(this);\n }\n}\n","import FW from '../framework/fw';\nimport TRACKING_EVENTS from '../tracking/tracking-events';\n\nconst VIDEO_EVENT_TYPES = [\n 'error',\n 'loadeddata',\n 'pause',\n 'play',\n 'timeupdate',\n 'volumechange',\n 'click',\n];\n\nconst CONTENT_URL = document.location.href;\n// we support Access Modes Creative Access a.k.a full (we do not support Domain Access for now)\nconst ACCESS_MODE = 'full';\nconst OMSDK_SERVICE_WINDOW = window.top;\n\nclass OmSdkManager {\n\n constructor(adVerifications, contentPlayer, vastPlayer, params, isSkippableAd, skipTimeOffset) {\n this.adEvents = null;\n this.mediaEvents = null;\n this.adSession = null;\n this.VastProperties = null;\n this.lastVideoTime = -1;\n this.contentPlayer = contentPlayer;\n this.vastPlayer = vastPlayer;\n this.adVerifications = adVerifications;\n this.params = params;\n this.isSkippableAd = isSkippableAd;\n this.skipTimeOffset = skipTimeOffset;\n this.onFullscreenChange = null;\n\n console.log(\n `${FW.consolePrepend}${FW.consolePrepend2} create new class Instance`,\n FW.consoleStyle,\n FW.consoleStyle2,\n ''\n );\n }\n\n init() {\n // handle VAST player events\n VIDEO_EVENT_TYPES.forEach((eventType) => {\n this.vastPlayer.addEventListener(\n eventType,\n (event) => this._vastPlayerDidDispatchEvent(event)\n );\n });\n // handle fullscreenchange \n this.onFullscreenChange = this._onFullscreenChange.bind(this);\n document.addEventListener('fullscreenchange', this.onFullscreenChange);\n // Service Script To incorporate omweb-v1.js, use a
+
diff --git a/test/spec/simidSpec/simid-survey.html b/test/spec/simidSpec/simid-survey.html
new file mode 100644
index 0000000..8527d1d
--- /dev/null
+++ b/test/spec/simidSpec/simid-survey.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+ simid-survey
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ To pass test answer the survey questions.
+
+
+
+
+
\ No newline at end of file
diff --git a/test/spec/simidSpec/spec/simid-survey.js b/test/spec/simidSpec/spec/simid-survey.js
new file mode 100644
index 0000000..9ef9204
--- /dev/null
+++ b/test/spec/simidSpec/spec/simid-survey.js
@@ -0,0 +1,78 @@
+const ADTAG = 'https://www.radiantmediaplayer.com/vast/tags/simid-survey.xml';
+
+// official test tags from https://github.com/InteractiveAdvertisingBureau/SIMID
+//ADTAG = 'https://www.radiantmediaplayer.com/vast/tags/simid.xml';
+//ADTAG = 'https://www.radiantmediaplayer.com/vast/tags/simid-error-interactive-creative-file.xml';
+//ADTAG = 'https://www.radiantmediaplayer.com/vast/tags/simid-survey.xml';
+//ADTAG = 'https://www.radiantmediaplayer.com/vast/tags/simid-selector.xml';
+//ADTAG = 'https://www.radiantmediaplayer.com/vast/tags/simid-error-interactive-media-file.xml';
+//ADTAG = 'https://www.radiantmediaplayer.com/vast/tags/simid-extender.xml';
+//ADTAG = 'https://www.radiantmediaplayer.com/vast/tags/simid-map.xml';
+//ADTAG = 'https://www.radiantmediaplayer.com/vast/tags/simid-non-linear.xml';
+
+describe('Test for simid-survey', function () {
+
+ const id = 'rmp';
+ const container = document.getElementById(id);
+ const video = document.querySelector('.rmp-video');
+ const params = {
+ enableSimid: true
+ };
+ const rmpVast = new RmpVast(id, params);
+ const env = rmpVast.getEnvironment();
+ video.muted = true;
+ if (env.isAndroid[0] || env.isIos[0]) {
+ container.style.width = '320px';
+ container.style.height = '180px';
+ }
+ const title = document.getElementsByTagName('title')[0];
+
+ it('should load and play simid-survey', function (done) {
+ let validSteps = 0;
+
+ const _incrementAndLog = function (event) {
+ validSteps++;
+ if (event && event.type) {
+ console.log(event.type);
+ }
+ };
+
+ rmpVast.on('adloaded', function (e) {
+ _incrementAndLog(e);
+ });
+ rmpVast.on('addurationchange', function (e) {
+ _incrementAndLog(e);
+ });
+ rmpVast.on('adstarted', function (e) {
+ if (env.isAndroid[0] || env.isIos[0]) {
+ rmpVast.resizeAd(320, 180, 'normal');
+ }
+ _incrementAndLog(e);
+ });
+ rmpVast.on('adtagstartloading', function (e) {
+ _incrementAndLog(e);
+ });
+ rmpVast.on('adtagloaded', function (e) {
+ _incrementAndLog(e);
+ });
+ rmpVast.on('addestroyed', function (e) {
+ _incrementAndLog(e);
+ let timeupdateCount = 0;
+ video.addEventListener('timeupdate', function (e) {
+ timeupdateCount++;
+ if (timeupdateCount === 5) {
+ _incrementAndLog(e);
+ if (validSteps === 7) {
+ expect(validSteps).toBe(7);
+ title.textContent = 'Test completed';
+ done();
+ }
+ }
+ });
+ });
+
+ rmpVast.loadAds(ADTAG);
+ });
+
+
+});
diff --git a/types/assets/@dailymotion/vast-client/src/companion_ad.d.ts b/types/assets/@dailymotion/vast-client/src/companion_ad.d.ts
index 3bd10d1..f7f5228 100644
--- a/types/assets/@dailymotion/vast-client/src/companion_ad.d.ts
+++ b/types/assets/@dailymotion/vast-client/src/companion_ad.d.ts
@@ -8,14 +8,13 @@ export function createCompanionAd(creativeAttributes?: {}): {
expandedWidth: any;
expandedHeight: any;
apiFramework: any;
- adSlotID: any;
+ adSlotId: any;
pxratio: any;
renderingMode: any;
staticResources: any[];
htmlResources: any[];
iframeResources: any[];
adParameters: any;
- xmlEncoded: any;
altText: any;
companionClickThroughURLTemplate: any;
companionClickTrackingURLTemplates: any[];
diff --git a/types/assets/@dailymotion/vast-client/src/companion_ad.d.ts.map b/types/assets/@dailymotion/vast-client/src/companion_ad.d.ts.map
index 06ee7ad..b445b3d 100644
--- a/types/assets/@dailymotion/vast-client/src/companion_ad.d.ts.map
+++ b/types/assets/@dailymotion/vast-client/src/companion_ad.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"companion_ad.d.ts","sourceRoot":"","sources":["../../../../../src/assets/@dailymotion/vast-client/src/companion_ad.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;EAwBC;AAED,gDAEC"}
\ No newline at end of file
+{"version":3,"file":"companion_ad.d.ts","sourceRoot":"","sources":["../../../../../src/assets/@dailymotion/vast-client/src/companion_ad.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;EAuBC;AAED,gDAEC"}
\ No newline at end of file
diff --git a/types/assets/@dailymotion/vast-client/src/icon.d.ts b/types/assets/@dailymotion/vast-client/src/icon.d.ts
index f059675..f54154b 100644
--- a/types/assets/@dailymotion/vast-client/src/icon.d.ts
+++ b/types/assets/@dailymotion/vast-client/src/icon.d.ts
@@ -15,5 +15,6 @@ export function createIcon(): {
iconClickThroughURLTemplate: any;
iconClickTrackingURLTemplates: any[];
iconViewTrackingURLTemplate: any;
+ iconClickFallbackImages: any[];
};
//# sourceMappingURL=icon.d.ts.map
\ No newline at end of file
diff --git a/types/assets/@dailymotion/vast-client/src/icon.d.ts.map b/types/assets/@dailymotion/vast-client/src/icon.d.ts.map
index cd1cfd6..6725ce4 100644
--- a/types/assets/@dailymotion/vast-client/src/icon.d.ts.map
+++ b/types/assets/@dailymotion/vast-client/src/icon.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../../../src/assets/@dailymotion/vast-client/src/icon.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;EAmBC"}
\ No newline at end of file
+{"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../../../../src/assets/@dailymotion/vast-client/src/icon.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;EAoBC"}
\ No newline at end of file
diff --git a/types/assets/@dailymotion/vast-client/src/parser/ad_parser.d.ts.map b/types/assets/@dailymotion/vast-client/src/parser/ad_parser.d.ts.map
index 4e467cc..eb84022 100644
--- a/types/assets/@dailymotion/vast-client/src/parser/ad_parser.d.ts.map
+++ b/types/assets/@dailymotion/vast-client/src/parser/ad_parser.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"ad_parser.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/parser/ad_parser.js"],"names":[],"mappings":"AAOA;;GAEG;AAEH;;;;;;;GAOG;AACH,+GAFY,MAAO,SAAS,CAmC3B;AAyPD;;;;GAIG;AACH,6DAFY,UAAa,CAiDxB;AAED;;;;GAIG;AACH,gEAHY,MAAM,IAAI,CAAC,GACX,UAAa,CAqBxB;AAED;;;;GAIG;AACH,2EAgCC"}
\ No newline at end of file
+{"version":3,"file":"ad_parser.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/parser/ad_parser.js"],"names":[],"mappings":"AAOA;;GAEG;AAEH;;;;;;;GAOG;AACH,+GAFY,MAAO,SAAS,CAmC3B;AA4PD;;;;GAIG;AACH,6DAFY,UAAa,CAiDxB;AAED;;;;GAIG;AACH,gEAHY,MAAM,IAAI,CAAC,GACX,UAAa,CAqBxB;AAED;;;;GAIG;AACH,2EAkBC"}
\ No newline at end of file
diff --git a/types/assets/@dailymotion/vast-client/src/parser/creative_linear_parser.d.ts.map b/types/assets/@dailymotion/vast-client/src/parser/creative_linear_parser.d.ts.map
index 2341ad2..1cbd6dd 100644
--- a/types/assets/@dailymotion/vast-client/src/parser/creative_linear_parser.d.ts.map
+++ b/types/assets/@dailymotion/vast-client/src/parser/creative_linear_parser.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"creative_linear_parser.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/parser/creative_linear_parser.js"],"names":[],"mappings":"AAQA;;GAEG;AAEH;;;;;GAKG;AACH,8EAHY,GAAG,OAoLd"}
\ No newline at end of file
+{"version":3,"file":"creative_linear_parser.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/parser/creative_linear_parser.js"],"names":[],"mappings":"AAQA;;GAEG;AAEH;;;;;GAKG;AACH,8EAHY,GAAG,OAuLd"}
\ No newline at end of file
diff --git a/types/assets/@dailymotion/vast-client/src/parser/creative_non_linear_parser.d.ts.map b/types/assets/@dailymotion/vast-client/src/parser/creative_non_linear_parser.d.ts.map
index 4ceecb4..437922c 100644
--- a/types/assets/@dailymotion/vast-client/src/parser/creative_non_linear_parser.d.ts.map
+++ b/types/assets/@dailymotion/vast-client/src/parser/creative_non_linear_parser.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"creative_non_linear_parser.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/parser/creative_non_linear_parser.js"],"names":[],"mappings":"AAIA;;GAEG;AAEH;;;;;GAKG;AACH,wDAJY,GAAG,sBACH,GAAG,OA4Fd"}
\ No newline at end of file
+{"version":3,"file":"creative_non_linear_parser.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/parser/creative_non_linear_parser.js"],"names":[],"mappings":"AAIA;;GAEG;AAEH;;;;;GAKG;AACH,wDAJY,GAAG,sBACH,GAAG,OA+Fd"}
\ No newline at end of file
diff --git a/types/assets/@dailymotion/vast-client/src/parser/parser_utils.d.ts b/types/assets/@dailymotion/vast-client/src/parser/parser_utils.d.ts
index e6647e0..97e9f3f 100644
--- a/types/assets/@dailymotion/vast-client/src/parser/parser_utils.d.ts
+++ b/types/assets/@dailymotion/vast-client/src/parser/parser_utils.d.ts
@@ -1,3 +1,9 @@
+/**
+ * Parses a String duration into a Number.
+ * @param {String} durationString - The dureation represented as a string.
+ * @return {Number}
+ */
+export function parseDuration(durationString: string): number;
export namespace parserUtils {
export { childByName };
export { childrenByName };
@@ -61,12 +67,6 @@ declare function copyNodeAttribute(attributeName: string, nodeSource: any, nodeD
* @returns {Object}
*/
declare function parseAttributes(element: Element): any;
-/**
- * Parses a String duration into a Number.
- * @param {String} durationString - The dureation represented as a string.
- * @return {Number}
- */
-declare function parseDuration(durationString: string): number;
/**
* Splits an Array of ads into an Array of Arrays of ads.
* Each subarray contains either one ad or multiple ads (an AdPod)
diff --git a/types/assets/@dailymotion/vast-client/src/parser/parser_utils.d.ts.map b/types/assets/@dailymotion/vast-client/src/parser/parser_utils.d.ts.map
index 747f10c..2da9822 100644
--- a/types/assets/@dailymotion/vast-client/src/parser/parser_utils.d.ts.map
+++ b/types/assets/@dailymotion/vast-client/src/parser/parser_utils.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"parser_utils.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/parser/parser_utils.js"],"names":[],"mappings":";;;;;;;;;;;;;AAEA;;GAEG;AAEH;;;;;GAKG;AACH,mCAJY,IAAI,iBAEJ,MAAO,SAAS,CAY3B;AAED;;;;;GAKG;AACH,sCAJY,IAAI,uBAgBf;AAED;;;;;GAKG;AACH,wFAiBC;AAED;;;;GAIG;AACH,8DAEC;AAED;;;;GAIG;AACH,kDAEC;AAED;;;;;GAKG;AACH,uGAKC;AAED;;;;;GAKG;AACH,0CAHW,OAAO,OAUjB;AAED;;;;GAIG;AACH,+DAiCC;AAED;;;;;GAKG;AACH,8CA0BC;AAED;;;;GAIG;AACH,kFAmBC;AAED;;;;;GAKG;AACH,mEAFY,IAAI,CAyHf"}
\ No newline at end of file
+{"version":3,"file":"parser_utils.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/parser/parser_utils.js"],"names":[],"mappings":"AAmHA;;;;GAIG;AACH,8DAiCC;;;;;;;;;;;;;;AAvJD;;GAEG;AAEH;;;;;GAKG;AACH,mCAJY,IAAI,iBAEJ,MAAO,SAAS,CAY3B;AAED;;;;;GAKG;AACH,sCAJY,IAAI,uBAgBf;AAED;;;;;GAKG;AACH,wFAiBC;AAED;;;;GAIG;AACH,8DAEC;AAED;;;;GAIG;AACH,kDAEC;AAED;;;;;GAKG;AACH,uGAKC;AAED;;;;;GAKG;AACH,0CAHW,OAAO,OAUjB;AA0CD;;;;;GAKG;AACH,8CA0BC;AAED;;;;GAIG;AACH,kFAmBC;AAED;;;;;GAKG;AACH,mEAFY,IAAI,CAsIf"}
\ No newline at end of file
diff --git a/types/assets/@dailymotion/vast-client/src/parser/vast_parser.d.ts b/types/assets/@dailymotion/vast-client/src/parser/vast_parser.d.ts
index ade1a76..d219de3 100644
--- a/types/assets/@dailymotion/vast-client/src/parser/vast_parser.d.ts
+++ b/types/assets/@dailymotion/vast-client/src/parser/vast_parser.d.ts
@@ -6,7 +6,6 @@
*/
export class VASTParser extends EventEmitter {
remainingAds: any[];
- parentURLs: any[];
errorURLTemplates: any[];
rootErrorURLTemplates: any[];
maxWrapperDepth: any;
diff --git a/types/assets/@dailymotion/vast-client/src/parser/vast_parser.d.ts.map b/types/assets/@dailymotion/vast-client/src/parser/vast_parser.d.ts.map
index dfd051d..41eaf65 100644
--- a/types/assets/@dailymotion/vast-client/src/parser/vast_parser.d.ts.map
+++ b/types/assets/@dailymotion/vast-client/src/parser/vast_parser.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"vast_parser.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/parser/vast_parser.js"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH;IAQI,oBAAsB;IACtB,kBAAoB;IACpB,yBAA2B;IAC3B,6BAA+B;IAC/B,qBAA2B;IAC3B,0BAA4B;IAC5B,oBAAyB;IACzB,mBAAwB;IAG1B;;;;OAIG;IACH,wCAFY,IAAI,CAMf;IAED;;;OAGG;IACH,2BAFY,IAAI,CAIf;IAED;;;OAGG;IACH,kCAEC;IAED;;;OAGG;IACH,2BAFY,IAAI,CAIf;IAED;;;;;;;OAOG;IACH,mEAFY,IAAI,CAQf;IAED;;;OAGG;IACH,8BAEC;IAED;;;OAGG;IACH,8BAEC;IAED;;;;;;;;;;OAUG;IACH,mGA8CC;IAED;;;OAGG;IACH,uCAeC;IAJC,gBAAiB;IACjB,gBAAwE;IACxE,iBAAuB;IAIzB;;;;OAIG;IACH,4CAmBC;IAED;;;;;;;;;OASG;IACH,0DAkBC;IAED;;;;;;;;;OASG;IACH,qDAQC;IAED;;;;OAIG;IACH,mCASC;IAED;;;;;;;;;OASG;IACH,uHAkFC;IAED;;;;;;;;;OASG;IACH,kKAyDC;IAED;;;;;;OAMG;IACH,8EA6BC;IAED;;;;;;;OAOG;IACH,kFAwEC;IAED;;;OAGG;IACH,kDA0BC;CACF;6BA/kB4B,uBAAuB"}
\ No newline at end of file
+{"version":3,"file":"vast_parser.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/parser/vast_parser.js"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH;IAQI,oBAAsB;IACtB,yBAA2B;IAC3B,6BAA+B;IAC/B,qBAA2B;IAC3B,0BAA4B;IAC5B,oBAAyB;IACzB,mBAAwB;IAG1B;;;;OAIG;IACH,wCAFY,IAAI,CAMf;IAED;;;OAGG;IACH,2BAFY,IAAI,CAIf;IAED;;;OAGG;IACH,kCAEC;IAED;;;OAGG;IACH,2BAFY,IAAI,CAIf;IAED;;;;;;;OAOG;IACH,mEAFY,IAAI,CAQf;IAED;;;OAGG;IACH,8BAEC;IAED;;;OAGG;IACH,8BAEC;IAED;;;;;;;;;;OAUG;IACH,mGA6CC;IAED;;;OAGG;IACH,uCAcC;IAJC,gBAAiB;IACjB,gBAAwE;IACxE,iBAAuB;IAIzB;;;;OAIG;IACH,4CAkBC;IAED;;;;;;;;;OASG;IACH,0DAkBC;IAED;;;;;;;;;OASG;IACH,qDAQC;IAED;;;;OAIG;IACH,mCASC;IAED;;;;;;;;;OASG;IACH,uHAkFC;IAED;;;;;;;;;OASG;IACH,kKAyDC;IAED;;;;;;OAMG;IACH,8EA4BC;IAED;;;;;;;OAOG;IACH,kFAoEC;IAED;;;OAGG;IACH,kDA0BC;CACF;6BAtkB4B,uBAAuB"}
\ No newline at end of file
diff --git a/types/assets/@dailymotion/vast-client/src/util/event_emitter.d.ts b/types/assets/@dailymotion/vast-client/src/util/event_emitter.d.ts
index 2edb31d..373c1e1 100644
--- a/types/assets/@dailymotion/vast-client/src/util/event_emitter.d.ts
+++ b/types/assets/@dailymotion/vast-client/src/util/event_emitter.d.ts
@@ -29,7 +29,7 @@ export class EventEmitter {
* Synchronously calls each of the handlers registered for the named event,
* in the order they were registered, passing the supplied arguments to each.
* @param {String} event
- * @param {any[]} args
+ * @param {...any} args list of arguments that will be used by the event handler
* @returns {Boolean} true if the event had handlers, false otherwise.
*/
emit(event: string, ...args: any[]): boolean;
diff --git a/types/assets/@dailymotion/vast-client/src/util/event_emitter.d.ts.map b/types/assets/@dailymotion/vast-client/src/util/event_emitter.d.ts.map
index f1a8276..7ef3d6c 100644
--- a/types/assets/@dailymotion/vast-client/src/util/event_emitter.d.ts.map
+++ b/types/assets/@dailymotion/vast-client/src/util/event_emitter.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"event_emitter.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/util/event_emitter.js"],"names":[],"mappings":"AAAA;IAEI,iBAAmB;IAGrB;;;;;;;;OAQG;IACH,sCAFa,YAAY,CAmBxB;IAED;;;;;;OAMG;IACH,wCAFa,YAAY,CAIxB;IAED;;;;;OAKG;IACH,uCAFa,YAAY,CAQxB;IAED;;;;;;OAMG;IACH,6BAHY,GAAG,EAAE,WAgBhB;IAED;;;;OAIG;IACH,mCAFa,YAAY,CAUxB;IAED;;;;OAIG;IACH,qCAEC;IAED;;;;OAIG;IACH,0BAFa,UAAU,CAStB;IAED;;;OAGG;IACH,cAFa,QAAQ,CAIpB;CACF"}
\ No newline at end of file
+{"version":3,"file":"event_emitter.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/util/event_emitter.js"],"names":[],"mappings":"AAAA;IAEI,iBAAmB;IAGrB;;;;;;;;OAQG;IACH,sCAFa,YAAY,CAmBxB;IAED;;;;;;OAMG;IACH,wCAFa,YAAY,CAIxB;IAED;;;;;OAKG;IACH,uCAFa,YAAY,CAQxB;IAED;;;;;;OAMG;IACH,6BAHe,GAAG,aAgBjB;IAED;;;;OAIG;IACH,mCAFa,YAAY,CAUxB;IAED;;;;OAIG;IACH,qCAEC;IAED;;;;OAIG;IACH,0BAFa,UAAU,CAStB;IAED;;;OAGG;IACH,cAFa,QAAQ,CAIpB;CACF"}
\ No newline at end of file
diff --git a/types/assets/@dailymotion/vast-client/src/util/util.d.ts b/types/assets/@dailymotion/vast-client/src/util/util.d.ts
index 23995b1..3322d16 100644
--- a/types/assets/@dailymotion/vast-client/src/util/util.d.ts
+++ b/types/assets/@dailymotion/vast-client/src/util/util.d.ts
@@ -2,15 +2,16 @@ export namespace util {
export { track };
export { resolveURLTemplates };
export { extractURLsFromTemplates };
+ export { filterValidUrlTemplates };
export { containsTemplateObject };
export { isTemplateObjectEqual };
export { encodeURIComponentRFC3986 };
export { replaceUrlMacros };
- export { leftpad };
- export { range };
export { isNumeric };
export { flatten };
export { joinArrayOfUniqueTemplateObjs };
+ export { isValidTimeValue };
+ export { addLeadingZeros };
}
declare function track(URLTemplates: any, macros: any, options: any): void;
/**
@@ -30,6 +31,16 @@ declare function resolveURLTemplates(URLTemplates: any[], macros?: any, options?
* @param {Array|String} URLTemplates - An array|string of url templates.
*/
declare function extractURLsFromTemplates(URLTemplates: any[] | string): string | any[];
+/**
+ * Filter URLTemplates elements to keep only valid and safe URL templates.
+ * To be valid, urls should:
+ * - have the same protocol as the client
+ * or
+ * - be protocol-relative urls
+ *
+ * @param {Array} URLTemplates - A Array of string/object containing urls templates.
+ */
+declare function filterValidUrlTemplates(URLTemplates: any[]): boolean | any[];
/**
* Returns a boolean after checking if the object exists in the array.
* true - if the object exists, false otherwise
@@ -56,8 +67,6 @@ declare function encodeURIComponentRFC3986(str: any): string;
* @param {Object} macros - Object of macros to be replaced in the tracking calls
*/
declare function replaceUrlMacros(url: string, macros: any): string;
-declare function leftpad(input: any, len?: number): string;
-declare function range(left: any, right: any, inclusive: any): any[];
declare function isNumeric(n: any): boolean;
declare function flatten(arr: any): any;
/**
@@ -69,5 +78,23 @@ declare function flatten(arr: any): any;
* @return {Array}
*/
declare function joinArrayOfUniqueTemplateObjs(arr1?: any[], arr2?: any[]): any[];
+/**
+ * Check if a provided value is a valid time value according to the IAB definition
+ * Check if a provided value is a valid time value according to the IAB definition: Must be a positive number or -1.
+ * if not implemented by ad unit or -2 if value is unknown.
+ * @param {Number} time
+ *
+ * @return {Boolean}
+ */
+declare function isValidTimeValue(time: number): boolean;
+/**
+ * Return a string of the input number with leading zeros defined by the length param
+ *
+ * @param {Number} input - number to convert
+ * @param {Number} length - length of the desired string
+ *
+ * @return {String}
+ */
+declare function addLeadingZeros(input: number, length?: number): string;
export {};
//# sourceMappingURL=util.d.ts.map
\ No newline at end of file
diff --git a/types/assets/@dailymotion/vast-client/src/util/util.d.ts.map b/types/assets/@dailymotion/vast-client/src/util/util.d.ts.map
index 506ca5d..4c6c93f 100644
--- a/types/assets/@dailymotion/vast-client/src/util/util.d.ts.map
+++ b/types/assets/@dailymotion/vast-client/src/util/util.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/util/util.js"],"names":[],"mappings":";;;;;;;;;;;;;;AAEA,2EASC;AAED;;;;;;GAMG;AACH,iGAmCC;AAsDD;;;;;;;GAOG;AACH,wDAFW,cAAY,kBAWtB;AAED;;;;;;GAMG;AACH,wEAOC;AAED;;;;;;GAMG;AACH,sEAgBC;AAGD,6DAKC;AAtHD;;;;;;;GAOG;AACH,oEAuBC;AAyFD,2DAUC;AAED,qEASC;AAED,4CAEC;AAED,wCAMC;AAED;;;;;;;GAOG;AACH,kFAWC"}
\ No newline at end of file
+{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../../../src/assets/@dailymotion/vast-client/src/util/util.js"],"names":[],"mappings":";;;;;;;;;;;;;;;AAEA,2EASC;AAED;;;;;;GAMG;AACH,iGAiCC;AAsDD;;;;;;;GAOG;AACH,wDAFW,cAAY,kBAWtB;AAED;;;;;;;;GAQG;AACH,+EAQC;AAOD;;;;;;GAMG;AACH,wEAOC;AAED;;;;;;GAMG;AACH,sEAgBC;AAGD,6DAKC;AA9ID;;;;;;;GAOG;AACH,oEAuBC;AA6HD,4CAEC;AAED,wCAMC;AAED;;;;;;;GAOG;AACH,kFAWC;AAED;;;;;;;GAOG;AACH,yDAEC;AAvDD;;;;;;;GAOG;AACH,yEAEC"}
\ No newline at end of file
diff --git a/types/js/index.d.ts b/types/js/index.d.ts
index 83d2c2f..f1de9e4 100644
--- a/types/js/index.d.ts
+++ b/types/js/index.d.ts
@@ -362,7 +362,7 @@ export default class RmpVast {
* @param {number} inputWidth
* @param {number} inputHeight
* @typedef {object} Companion
- * @property {string} adSlotID
+ * @property {string} adSlotId
* @property {string} altText
* @property {string} companionClickThroughUrl
* @property {string} companionClickTrackingUrl
@@ -373,7 +373,7 @@ export default class RmpVast {
* @return {Companion[]}
*/
getCompanionAdsList(inputWidth: number, inputHeight: number): {
- adSlotID: string;
+ adSlotId: string;
altText: string;
companionClickThroughUrl: string;
companionClickTrackingUrl: string;
diff --git a/types/js/index.d.ts.map b/types/js/index.d.ts.map
index fa63580..5078a04 100644
--- a/types/js/index.d.ts.map
+++ b/types/js/index.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/js/index.js"],"names":[],"mappings":"AAsBA;;;;EAIE;AACF;IAEE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2CG;IACH,gBA1CW,MAAM;;;;;sBAWH,MAAM;;;;;8BAEN,MAAM;;;;;8BAEN,OAAO;;;;;0BAEP,MAAM;;;;oBAEN,OAAO;;;;oCACP,OAAO;;;;uBACP,OAAO;;;;sBACP,OAAO;;;;;;oBApBP,MAAM;qBACN,MAAM;uBACN,MAAM;6BACN,MAAM;;;;;mBAoBN,OAAO;;;;qBACP,OAAO;;;;sCACP,OAAO;;;;sBACP,OAAO;;;;;6BACP,MAAM,EAAE;;;;8BAER,OAAO;;;;;;uBACP,OAAO;;;;sBAGP,MAAM;;;;yBACN,MAAM;;;;;;0BA7BN,MAAM;sBACN,MAAM;qCACN,MAAM;;OAwEnB;IAhCC,WAAY;IACZ,uBAAiD;IAKjD,wBAAkE;IAClE,uBAA+D;IAoB7D,gCAAkC;IAS5B,oBAAY,MAAM,QAAQ,MAAM,GAAK,IAAI,CAAA;IAenD;;OAEG;IACH,YAUC;IAIS,cAAY,MAAM,uBAAyB,IAAI,CAAA;IAYzD;;OAEG;IACH,aAMC;IAIS,eAAY,MAAM,uBAAyB,IAAI,CAAA;IAYzD;;OAEG;IACH,aAYC;IAIS,eAAY,MAAM,uBAAyB,IAAI,CAAA;IAYzD;;;;;;;;;;;;OAYG;IACH;0BAXc,MAAM;wBACN,MAAM;kBACN,OAAO;;;uBAGP,OAAO;mBACP,OAAO;kBACP,OAAO;oCACP,OAAO;MAKpB;IAED;;OAEG;IACH,2BAUC;IAED;;OAEG;IACH,wBAsEC;IApEC,yBAA2B;IAC3B,mCAAuC;IAqEzC;;OAEG;IACH,yBASC;IAFG,2BAAoD;IAIxD;;OAEG;IACH,gCAcC;IANG,uCAA2F;IAQ/F;;OAEG;IACH,gCAgCC;IAFC,4BAAqE;IAIvE;;OAEG;IACH,iBAyLC;IA5IO,eAAkB;IA4BhB,oBAA8B;IA0B9B,mBAAmB;IAwF7B;;OAEG;IACH,0BAoBC;IAED;;OAEG;IACH,oBAsDC;IAjCG,iBAAwB;IAmC5B;;;;;;;;;OASG;IACH,kBATW,MAAM;QAEmB,WAAW,GAApC,MAAM;QACmB,eAAe,GAAxC,MAAM;QACmB,WAAW,GAApC,MAAM;yBAEN,OAAO,GACN,IAAI,CAmEf;IA3CG,yBAA2B;IA2B3B,uBAA+C;IAI/C,+BAAmD;IAe7C,QAAM,IAAI,CAAA;IAeV,SAAM,IAAI,CAAA;IAeV,eAAM,OAAO,CAAA;IAcb,iBAAQ,MAAM,GAAK,IAAI,CAAA;IAwBvB,aAAM,MAAM,CAAA;IAcZ,eAAQ,OAAO,GAAK,IAAI,CAAA;IAqBxB,WAAM,OAAO,CAAA;IAiBb,iBAAM,OAAO,CAAA;IAOb,WAAM,IAAI,CAAA;IAkBV,WAAM,IAAI,CAAA;IAcV,UAAM,IAAI,CAAA;IAgBV,eAAM,MAAM,CAAA;IAOZ,iBAAM,MAAM,CAAA;IAgBZ,eAAM,OAAO,CAAA;IASvB;;;;;OAKG;IACH;eAJc,MAAM;iBACN,MAAM;MAiBnB;IAED;;;;;OAKG;IACH;oBAJc,MAAM;eACN,MAAM;QAUnB;IAGS,oBAAM,MAAM,CAAA;IAUZ,cAAM,MAAM,CAAA;IAUZ,oBAAM,MAAM,CAAA;IAStB;;;;;OAKG;IACH;YAJc,MAAM;eACN,MAAM;MAanB;IAED;;;;;;OAMG;IACH;eALc,MAAM;eACN,MAAM;kBACN,MAAM;MAcnB;IAGS,eAAM,MAAM,CAAA;IAUZ,oBAAM,MAAM,CAAA;IAStB;;;;;OAKG;IACH;mBAJc,MAAM;eACN,MAAM;QASnB;IAED;;;;;OAKG;IACH;mBAJc,MAAM;eACN,MAAM;QASnB;IAGS,iBAAM,MAAM,CAAA;IAkBZ,oBAAM,MAAM,CAAA;IAmBZ,sBAAM,MAAM,CAAA;IAuBZ,gBAAM,OAAO,CAAA;IAOb,mBAAM,MAAM,CAAA;IAcZ,oBAAM,MAAM,CAAA;IAcZ,sBAAM,MAAM,CAAA;IAUZ,qBAAM,MAAM,CAAA;IAUZ,oBAAM,OAAO,CAAA;IAUb,6BAAM,OAAO,CAAA;IAMvB;;;OAGG;IACH,iCAHW,OAAO,GACN,IAAI,CAMf;IAFG,gCAAmC;IAK7B,qBAAM,MAAM,CAAA;IAOZ,sBAAM,MAAM,CAAA;IAOZ,kBAAM,MAAM,CAAA;IAOZ,iCAAM,OAAO,CAAA;IAOb,uBAAM,OAAO,CAAA;IAiBvB;;OAEG;IACH,iBAFY,gBAAgB,GAAC,IAAI,CAIhC;IAED;;OAEG;IACH,oBAFY,gBAAgB,GAAC,IAAI,CAIhC;IAED;;;;;;;;;;;;;OAaG;IACH,gCAbW,MAAM,eACN,MAAM;kBAEH,MAAM;iBACN,MAAM;kCACN,MAAM;mCACN,MAAM;gBACN,MAAM;eACN,MAAM;kBACN,MAAM;2BACN,MAAM,EAAE;QAmBrB;IALK,wBAA6C;IAOnD;;;OAGG;IACH,sBAHW,MAAM,GACL,WAAW,GAAC,IAAI,CAqF3B;IAGS,oCAAM,MAAM,CAAA;IAUZ,cAAM,IAAI,CAAA;IAUV,kBAAM,OAAO,CAAA;IAMvB;;;;;OAKG;IACH;2BAJc,MAAM;qBACN,MAAM;MAcnB;IAIS,gBAAQ,MAAM,UAAU,MAAM,YAAY,MAAM,GAAK,IAAI,CAAA;IASzD,YAAM,IAAI,CAAA;IASV,cAAM,IAAI,CAAA;IASV,iBAAM,OAAO,CAAA;IAUb,wBAAM,MAAM,CAAA;CAQvB"}
\ No newline at end of file
+{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/js/index.js"],"names":[],"mappings":"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"}
\ No newline at end of file