{"version":3,"file":"assets/app.18bd59569aa511565698.js","mappings":"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","sources":["webpack://web-game-player/webpack/runtime/chunk loaded","webpack://web-game-player/./src/WGP/_utils/utilities.ts","webpack://web-game-player/./src/WGP/_utils/index.ts","webpack://web-game-player/./src/WGP/_vendor/app-insights.ts","webpack://web-game-player/./src/WGP/_utils/telemetry.ts","webpack://web-game-player/./src/WGP/_utils/logger.ts","webpack://web-game-player/./src/WGP/_utils/overlay.ts","webpack://web-game-player/./src/WGP/_types/enums.ts","webpack://web-game-player/./src/WGP/_vendor/xandr.ts","webpack://web-game-player/./src/WGP/_services/ad-manager.ts","webpack://web-game-player/./src/WGP/_services/game-manager.ts","webpack://web-game-player/./src/WGP/_types/models.ts","webpack://web-game-player/./src/WGP/_services/event-manager.ts","webpack://web-game-player/./src/WGP/_services/loading-indicators.ts","webpack://web-game-player/./src/WGP/_vendor/placeholderVideo.ts","webpack://web-game-player/./src/WGP/_services/dependency-manager.ts","webpack://web-game-player/./src/WGP/wgp-app.ts","webpack://web-game-player/./src/WGP/_templates/ad-loading.tpl","webpack://web-game-player/./src/WGP/_templates/click-to-play.tpl","webpack://web-game-player/./src/WGP/_templates/game-over.tpl","webpack://web-game-player/./src/WGP/_templates/unsupported-browser.tpl","webpack://web-game-player/./src/WGP/_templates/unsupported-game.tpl","webpack://web-game-player/./src/main.ts","webpack://web-game-player/webpack/bootstrap","webpack://web-game-player/webpack/runtime/define property getters","webpack://web-game-player/webpack/runtime/global","webpack://web-game-player/webpack/runtime/hasOwnProperty shorthand","webpack://web-game-player/webpack/runtime/jsonp chunk loading","webpack://web-game-player/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport { detect } from 'detect-browser';\r\nimport { fromEvent, Subscription } from 'rxjs';\r\nimport { logger } from '.';\r\n\r\ndeclare global {\r\n interface Window {\r\n enableDeveloperMode: (debugKey: string) => void;\r\n disableDeveloperMode: () => void;\r\n }\r\n}\r\n\r\nexport default class Utilities {\r\n private static developerModeTimeoutHours = 1;\r\n\r\n public static findActiveVideo(doc: Document): HTMLVideoElement | null {\r\n let videoAd: HTMLVideoElement = doc.querySelector(\"video[src]:not([src=''])\");\r\n if (videoAd === null) {\r\n const frames = doc.querySelectorAll('iframe');\r\n for (let i = 0; !videoAd && i < frames.length; i += 1) {\r\n try {\r\n videoAd = Utilities.findActiveVideo(frames[i].contentDocument);\r\n } catch (err) {\r\n // must be a frame from another domain\r\n }\r\n }\r\n }\r\n return videoAd || null;\r\n }\r\n\r\n // Using this instread of URLSearchParams because it's case-insensitive\r\n public static getUrlSearchParam(name: string, flags?: [string], url?: string): string | null {\r\n const regex = `[\\\\?&]${name}=([^&#]*)`;\r\n const search = url || window.location.search;\r\n\r\n let rxflags = '';\r\n if (flags && flags.length > 0) {\r\n rxflags = flags.reduce((prev, cur) => prev.concat(cur));\r\n }\r\n\r\n const results = new RegExp(regex, rxflags).exec(search);\r\n\r\n return results ? results[1] : null;\r\n }\r\n\r\n // Case-sensitive\r\n public static hasUrlSearchParam(name: string): boolean {\r\n const urlSearchParams = new URLSearchParams(window.location.search);\r\n return urlSearchParams.has(name);\r\n }\r\n\r\n public static initalizeDeveloperMode(): void {\r\n try { // don't break the app if same-origin policy prohibits accessing window.parent...\r\n window.enableDeveloperMode = (debugKey: string) => {\r\n if (debugKey === __ENV__.runtime.debugKey) {\r\n localStorage.setItem('developerModeLastActivated', new Date().getTime().toString());\r\n logger.cLog(`Developer mode activated for ${this.developerModeTimeoutHours} hour(s)`);\r\n } else {\r\n logger.cLog('Debug Key Incorrect');\r\n }\r\n };\r\n window.disableDeveloperMode = () => {\r\n localStorage.removeItem('developerModeLastActivated');\r\n logger.cLog('Developer mode deactivated');\r\n };\r\n } catch (error) {\r\n logger.cLog(error);\r\n }\r\n }\r\n\r\n public static isDeveloperModeActive(): boolean {\r\n const hoursSinceDeveloperModeActivated = this.getHoursSinceDeveloperModeActivated();\r\n if (hoursSinceDeveloperModeActivated < this.developerModeTimeoutHours) {\r\n return true;\r\n }\r\n localStorage.removeItem('developerModeLastActivated');\r\n return false;\r\n }\r\n\r\n private static getHoursSinceDeveloperModeActivated(): number {\r\n const lastUpdated = new Date(parseInt(localStorage.getItem('developerModeLastActivated'), 10));\r\n if (lastUpdated instanceof Date && !Number.isNaN(lastUpdated.getTime())) {\r\n const now = new Date();\r\n\r\n const differenceInTime = now.getTime() - lastUpdated.getTime(); // ms\r\n const differenceInHours = differenceInTime / (1000 * 60 * 60); // ms=>secs * secs=>mins * mins=>hrs\r\n const differenceInHoursRounded = Math.round(differenceInHours * 100) / 100; // Two decimal places.\r\n\r\n return differenceInHoursRounded;\r\n }\r\n return this.developerModeTimeoutHours; // If developermode has not been activated, return the max timeout.\r\n }\r\n\r\n public static transition(\r\n element: HTMLElement,\r\n style: string,\r\n endState: string,\r\n animationTimeout: number,\r\n attribute?: string,\r\n ): Promise<void> {\r\n let animationTimeoutRef: NodeJS.Timeout;\r\n let endEventSubscription: Subscription;\r\n return new Promise<void>((resolve) => {\r\n const attr = attribute || 'display';\r\n const endEvent = fromEvent(element, 'animationend');\r\n element.classList.add(style);\r\n endEventSubscription = endEvent.subscribe(() => {\r\n element.style[attr] = endState;\r\n element.classList.remove(style);\r\n resolve();\r\n });\r\n animationTimeoutRef = setTimeout(\r\n () => {\r\n element.style[attr] = endState;\r\n element.classList.remove(style);\r\n resolve();\r\n },\r\n animationTimeout, // taking too long, resolve & continue\r\n );\r\n }).finally(() => {\r\n clearTimeout(animationTimeoutRef);\r\n animationTimeoutRef = null;\r\n endEventSubscription.unsubscribe();\r\n endEventSubscription = null;\r\n });\r\n }\r\n\r\n public static validateMcgId(mcgId: string): boolean {\r\n const hexadecimal32RegularExpression = /^[a-fA-F0-9]{32}$/g;\r\n const mcgIdArray = mcgId.split('_');\r\n const mcgIdUniqueVal = (mcgIdArray.length === 2) ? mcgIdArray[1] : mcgIdArray[0];\r\n\r\n return hexadecimal32RegularExpression.test(mcgIdUniqueVal);\r\n }\r\n\r\n // -- Browser types not covered yet, that detect() may find:\r\n // 'aol','yandexbrowser','kakaotalk','samsung','silk','miui','beaker','phantomjs','crios' ,'pie',\r\n // 'netfront','bb10','android','ios','facebook','instagram','ios-webview','curl','searchbot';\r\n\r\n public static isBrowserChrome = (name = ''): boolean => ['chrome', 'chromium-webview'].indexOf(name || detect().name) >= 0;\r\n\r\n public static isBrowserFirefox = (name = ''): boolean => ['firefox', 'fxios'].indexOf(name || detect().name) >= 0;\r\n\r\n public static isBrowserSafari = (name = ''): boolean => ['safari'].indexOf(name || detect().name) >= 0;\r\n\r\n public static isBrowserOpera = (name = ''): boolean => ['opera', 'opera-mini'].indexOf(name || detect().name) >= 0;\r\n\r\n public static isBrowserEdge = (name = ''): boolean => ['edge', 'edge-ios', 'edge-chromium'].indexOf(name || detect().name) >= 0;\r\n\r\n public static isBrowserInternetExplorer = (name = ''): boolean => ['ie'].indexOf(name || detect().name) >= 0;\r\n\r\n public static getBrowserName = (): string => {\r\n const browserName = detect().name;\r\n if (Utilities.isBrowserChrome(browserName)) { return 'Chrome'; }\r\n if (Utilities.isBrowserFirefox(browserName)) { return 'Firefox'; }\r\n if (Utilities.isBrowserSafari(browserName)) { return 'Safari'; }\r\n if (Utilities.isBrowserOpera(browserName)) { return 'Opera'; }\r\n if (Utilities.isBrowserEdge(browserName)) { return 'Edge'; }\r\n if (Utilities.isBrowserInternetExplorer(browserName)) { return 'Internet Explorer'; }\r\n return 'Unknown';\r\n };\r\n\r\n public static getBrowserVersion = (): string => detect().version;\r\n\r\n public static getBrowserPrimaryVersion = (): string => {\r\n const versionString = detect().version;\r\n return versionString.split('.')[0];\r\n };\r\n\r\n public static removeNode(nodes: Element[]): void {\r\n nodes.forEach((node) => {\r\n if (Object.prototype.hasOwnProperty.call(node, 'remove')) {\r\n node.remove();\r\n } else {\r\n node.parentNode.removeChild(node);\r\n }\r\n });\r\n }\r\n\r\n public static appendNode(parent: Element, child: Element): Element {\r\n if (Object.prototype.hasOwnProperty.call(parent, 'append')) {\r\n parent.append(child);\r\n return child;\r\n }\r\n\r\n return parent.appendChild(child);\r\n }\r\n\r\n public static prependNode(parent: Element, child: Element): Element {\r\n if (Object.prototype.hasOwnProperty.call(parent, 'prepend')) {\r\n parent.prepend(child);\r\n return child;\r\n }\r\n\r\n const firstChild = parent.firstElementChild;\r\n return parent.insertBefore(child, firstChild);\r\n }\r\n\r\n public static clientHasLocalStorage(): boolean {\r\n try {\r\n localStorage.setItem('test', 'test');\r\n if (localStorage.getItem('test') !== 'test') {\r\n localStorage.removeItem('test');\r\n return false;\r\n }\r\n localStorage.removeItem('test');\r\n return true;\r\n } catch (exception) {\r\n return false;\r\n }\r\n }\r\n\r\n public static getFormattedError(err: any): Error {\r\n if (err instanceof Error) {\r\n return err;\r\n }\r\n\r\n if (typeof err === 'string') {\r\n return new Error(err);\r\n }\r\n\r\n return new Error(JSON.stringify(err));\r\n }\r\n\r\n public static getCookieValue(cookieName: string): string {\r\n const name = `${cookieName}=`;\r\n const cookie = document.cookie\r\n .split(';')\r\n .find((row) => row.trim().startsWith(name));\r\n\r\n return typeof cookie === 'string' ? cookie.trim().substring(name.length) : '';\r\n }\r\n}\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport appInsights from '../_vendor/app-insights'; // re-exporting so we have all our app-insights-specific logic in one spot\r\nimport { Telemetry } from './telemetry';\r\nimport Logger from './logger';\r\nimport Overlay from './overlay';\r\n\r\nexport { SeverityLevel } from '../_vendor/app-insights';\r\n\r\n// eslint-disable-next-line new-cap\r\nconst telemetryClient = new appInsights();\r\nexport const telemetry = new Telemetry(\r\n telemetryClient.appInsightsClient,\r\n telemetryClient.loggingPrefix,\r\n);\r\nexport const logger = new Logger();\r\nexport const overlay = new Overlay();\r\nexport { default as Utilities } from './utilities';\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport { ApplicationInsights, ITelemetryItem } from '@microsoft/applicationinsights-web';\r\n\r\nexport { SeverityLevel } from '@microsoft/applicationinsights-web'; // Verbose, Information, Warning, Error, Critical\r\n\r\nexport default class AppInsightsClient {\r\n public appInsights: ApplicationInsights;\r\n\r\n public loggingPrefix: string;\r\n\r\n get appInsightsClient() {\r\n return this.appInsights;\r\n }\r\n\r\n constructor() {\r\n this.appInsights = new ApplicationInsights({\r\n config: {\r\n instrumentationKey: __ENV__.vendors.applicationInsights.appInsightsKey,\r\n namePrefix: __ENV__.vendors.applicationInsights.namePrefix,\r\n disableFetchTracking: false,\r\n disableAjaxTracking: true, // nothing but 3rd-party ad calls, save the storage space\r\n },\r\n });\r\n\r\n this.appInsights.loadAppInsights();\r\n this.appInsights.addTelemetryInitializer((envelope: ITelemetryItem): boolean => {\r\n // Filter out exception noise (e.g. antivirus spam)\r\n if (envelope.baseType === 'ExceptionData') {\r\n const envelopeMessage: string = envelope.data.message ? envelope.data.message : null;\r\n const envelopeUrl: string = envelope.data.url ? envelope.data.url : null;\r\n\r\n // Antivirus spam: https://github.com/getsentry/sentry/issues/4958\r\n if (envelopeMessage.includes('JSON syntax error') && envelopeUrl.includes('main.js?attr')) {\r\n return false;\r\n }\r\n }\r\n\r\n // Default: log event\r\n return true;\r\n });\r\n\r\n this.loggingPrefix = 'ApplicationInsightsEvent';\r\n }\r\n}\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport { logger } from './index';\r\nimport Utilities from './utilities';\r\nimport { SeverityLevel } from '../_types/enums';\r\n\r\ninterface ITrackName {\r\n name: string;\r\n}\r\n\r\ninterface ITrackProperty {\r\n [key: string]: string|number;\r\n}\r\n\r\ninterface ITrackMeasurement {\r\n [key: string]: number;\r\n}\r\n\r\nexport interface ITelemetry {\r\n gameID?: string;\r\n gameType?: string;\r\n gameVersion?: string;\r\n hostingEnvironment?: string;\r\n locale?: string;\r\n trafficSrc?: string;\r\n flushEvent(): void;\r\n trackEvent(\r\n name: ITrackName,\r\n properties?: ITrackProperty,\r\n measurements?: ITrackMeasurement,\r\n ): void;\r\n trackError(\r\n name: ITrackName,\r\n properties?: ITrackProperty,\r\n measurements?: ITrackMeasurement,\r\n ): void;\r\n trackPageView(\r\n name?: ITrackName,\r\n url?: string,\r\n properties?: ITrackProperty,\r\n measurements?: ITrackMeasurement,\r\n duration?: number,\r\n ): void;\r\n trackException(\r\n exception: Error,\r\n handledAt?: string,\r\n properties?: ITrackProperty,\r\n measurements?: ITrackMeasurement,\r\n severityLevel?: SeverityLevel,\r\n ): void;\r\n}\r\n\r\nexport class Telemetry implements ITelemetry {\r\n client: any;\r\n\r\n loggingPrefix: string;\r\n\r\n properties: any = {};\r\n\r\n set gameID(name: string) {\r\n this.properties.gameID = name;\r\n }\r\n\r\n set gameType(name: string) {\r\n this.properties.gameType = name;\r\n }\r\n\r\n set gameVersion(version: string) {\r\n this.properties.gameVersion = version;\r\n }\r\n\r\n set hostingEnvironment(environment: string) {\r\n this.properties.hostingEnvironment = environment;\r\n }\r\n\r\n set locale(locale: string) {\r\n this.properties.locale = locale;\r\n }\r\n\r\n set trafficSrc(src: string) {\r\n this.properties.trafficSrc = src;\r\n }\r\n\r\n constructor(client: any, loggingPrefix: string) {\r\n this.client = client;\r\n this.loggingPrefix = loggingPrefix;\r\n this.properties = {\r\n embedURL: window.location.href,\r\n slot: Utilities.getCookieValue('x-ms-routing-name') || 'production',\r\n version: __ENV__.runtime.version,\r\n };\r\n try { // don't break the app if same-origin policy prohibits accessing window.parent...\r\n this.properties.parentURL = window.parent.location.href;\r\n\r\n if (!this.properties.trafficSrc) {\r\n this.properties.trafficSrc = window.parent.document.referrer;\r\n }\r\n } catch (e) {\r\n // currently do nothing\r\n }\r\n }\r\n\r\n public trackEvent(name: ITrackName, properties?: ITrackProperty, measurements?: ITrackMeasurement): void {\r\n const props = { ...this.properties, ...properties };\r\n this.client.trackEvent(name, props, measurements);\r\n logger.cLog(`${this.loggingPrefix}: ${name.name}`, props, measurements);\r\n }\r\n\r\n // This is just a wrapper for logging to the error console\r\n public trackError(name: ITrackName, properties?: ITrackProperty, measurements?: ITrackMeasurement): void {\r\n const props = { ...this.properties, ...properties };\r\n this.client.trackEvent(name, props, measurements);\r\n logger.cError(`${this.loggingPrefix}: ${name.name}`, props, measurements);\r\n }\r\n\r\n public trackPageView(\r\n name?: ITrackName,\r\n url?: string,\r\n properties?: ITrackProperty,\r\n measurements?: ITrackMeasurement,\r\n duration?: number,\r\n ): void {\r\n const props = { ...this.properties, ...properties };\r\n this.client.trackPageView(name, url, props, measurements, duration);\r\n logger.cLog(`${this.loggingPrefix}: Page View`, name, url, props, measurements, duration);\r\n }\r\n\r\n public trackException(\r\n exception: Error,\r\n handledAt?: string,\r\n properties?: ITrackProperty,\r\n measurements?: ITrackMeasurement,\r\n severityLevel?: SeverityLevel,\r\n ): void {\r\n const props = { ...this.properties, ...properties };\r\n this.client.trackException(exception, handledAt, props, measurements, severityLevel);\r\n logger.cError(`${this.loggingPrefix}: Exception`, exception, handledAt, props, measurements, severityLevel);\r\n }\r\n\r\n public flushEvent(): void {\r\n this.client.flush();\r\n }\r\n}\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport { Utilities } from './index';\r\n\r\nexport default class Logger {\r\n debugMode: boolean;\r\n\r\n constructor() {\r\n this.debugMode = Utilities.isDeveloperModeActive();\r\n }\r\n\r\n public cLog(...logItems: any[]): void {\r\n this.logToConsole('info', logItems);\r\n }\r\n\r\n public cError(...logItems: any[]): void {\r\n this.logToConsole('error', logItems);\r\n }\r\n\r\n public cWarn(...logItems: any[]): void {\r\n this.logToConsole('warn', logItems);\r\n }\r\n\r\n private logToConsole(level: string, msg: any[]): void {\r\n if (__ENV__.runtime.dev || this.debugMode) {\r\n const output = msg.reduce((prev, cur) => {\r\n if (cur == null) { // using == instead of === here to capture both null and undefined values\r\n return prev;\r\n }\r\n\r\n return `${prev} ${JSON.stringify(cur)}`;\r\n });\r\n console[level](`@@WGP: ${output}`); // eslint-disable-line no-console\r\n }\r\n }\r\n}\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport { fromEvent } from 'rxjs';\r\n\r\nimport { Utilities } from './index';\r\n\r\nexport default class Overlay {\r\n private activeOverlays: string[] = [];\r\n\r\n private animationTimeout = 150;\r\n\r\n public showOverlay(\r\n template: string,\r\n parentSelector: string,\r\n clickSelector: string|null,\r\n overlayId: string,\r\n position: InsertPosition = 'beforeend',\r\n ): Promise<any> { // @todo: type this for real\r\n let overlayError: string;\r\n let overlayNode: HTMLElement;\r\n let clickElement: HTMLElement;\r\n\r\n // Create and validate overlay elements\r\n if (this.activeOverlays.includes(overlayId)) {\r\n overlayError = `Overlay '${overlayId}' already exists`;\r\n }\r\n\r\n if (!overlayError) {\r\n const container: HTMLElement = document.querySelector(parentSelector);\r\n if (!container) {\r\n overlayError = `Invalid parent selector '${parentSelector}'`;\r\n } else {\r\n container.insertAdjacentHTML(position, template);\r\n switch (position) {\r\n case 'afterbegin':\r\n overlayNode = <HTMLElement>container.firstElementChild;\r\n break;\r\n case 'afterend':\r\n overlayNode = <HTMLElement>container.nextElementSibling;\r\n break;\r\n case 'beforebegin':\r\n overlayNode = <HTMLElement>container.previousElementSibling;\r\n break;\r\n case 'beforeend':\r\n default:\r\n overlayNode = <HTMLElement>container.lastElementChild;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (!overlayError && clickSelector !== null) {\r\n clickElement = document.querySelector(clickSelector);\r\n if (!clickElement) {\r\n overlayError = `Invalid click selector '${clickSelector}'`;\r\n }\r\n }\r\n\r\n if (overlayError) {\r\n if (overlayNode) {\r\n Utilities.removeNode([overlayNode]);\r\n }\r\n return Promise.reject(\r\n new Error(overlayError),\r\n );\r\n }\r\n\r\n // Add overlayId to array, so we don't re-add an existing overlay\r\n this.activeOverlays.push(overlayId);\r\n\r\n return new Promise<void>((resolve) => {\r\n // Attach click event if desired\r\n if (clickElement) {\r\n const clickEvent = fromEvent(clickElement, 'click');\r\n const clickEventSubscription = clickEvent.subscribe(() => {\r\n Utilities.transition(overlayNode, 'fadeout', 'none', this.animationTimeout)\r\n .finally(() => {\r\n clickEventSubscription.unsubscribe();\r\n this.hideOverlay(overlayNode, overlayId);\r\n resolve();\r\n });\r\n });\r\n } else {\r\n resolve();\r\n }\r\n\r\n // Show the overlay if it's hidden\r\n if (overlayNode.style.display === 'none') {\r\n Utilities.transition(overlayNode, 'fadein', 'block', this.animationTimeout);\r\n }\r\n });\r\n }\r\n\r\n public hideOverlay(overlayNode: HTMLElement, overlayId: string): void {\r\n if (overlayNode && overlayNode instanceof Element) {\r\n Utilities.removeNode([overlayNode]);\r\n }\r\n\r\n const overlayIndex = this.activeOverlays.indexOf(overlayId);\r\n if (overlayIndex > -1) {\r\n this.activeOverlays.splice(overlayIndex, 1);\r\n }\r\n }\r\n}\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Ad error names for internal logic\r\n */\r\nexport enum AdErrorNames {\r\n AdAlreadyPlaying = 'AdAlreadyPlaying',\r\n AdCouldNotBePlayed = 'AdCouldNotBePlayed',\r\n AdPlaybackDisabled = 'AdPlaybackDisabled',\r\n AdPlaybackTimeout = 'AdPlaybackTimeout',\r\n AdResponseTimeout = 'AdResponseTimeout',\r\n}\r\n\r\n/**\r\n * Ad event names for internal ad manager logic\r\n */\r\nexport enum AdEventNames {\r\n adComplete = 'adComplete',\r\n adEventOther = 'adEventOther',\r\n adFirstQuartile = 'adFirstQuartile',\r\n adFourthQuartile = 'adFourthQuartile',\r\n adImpressionEnd = 'adImpressionEnd',\r\n adImpressionStart = 'adImpressionStart',\r\n adPlaybackError = 'adPlaybackError',\r\n adPaused = 'adPaused',\r\n adRequestCompleted = 'adRequestCompleted',\r\n adResumed = 'adResumed',\r\n adSecondQuartile = 'adSecondQuartile',\r\n adStarted = 'adStarted',\r\n adThirdQuartile = 'adThirdQuartile',\r\n}\r\n\r\n/**\r\n * Supported ad placement types\r\n */\r\nexport enum AdPlacementType {\r\n interstitial = 'interstitial',\r\n preroll = 'preroll',\r\n}\r\n\r\n/**\r\n * Supported ad vendors\r\n */\r\nexport enum AdVendors {\r\n freewheel = 'freewheel',\r\n inmobi = 'inmobi',\r\n spotx = 'spotx',\r\n}\r\n\r\n/**\r\n * Supported consent keys\r\n */\r\nexport enum ConsentKeys {\r\n isConsentRequired = 'isConsentRequired',\r\n required = 'required',\r\n advertising = 'advertising',\r\n analytics = 'analytics',\r\n socialMedia = 'socialMedia',\r\n}\r\n\r\n/**\r\n * Event names sent from player to game via ZoneAdWrapper\r\n */\r\nexport enum EmittableGameEvents {\r\n adLevels = 'adLevels',\r\n adInterval = 'adInterval',\r\n adPlaybackCompleted = 'adPlaybackCompleted',\r\n muteGame = 'muteGame',\r\n pauseGame = 'pauseGame',\r\n resumeGame = 'resumeGame',\r\n unpauseGame = 'unpauseGame',\r\n quitGame = 'quitGame',\r\n}\r\n\r\n/**\r\n * Valid event types\r\n */\r\nexport enum EventTypes {\r\n adEvent,\r\n gameEvent,\r\n}\r\n\r\n/**\r\n * Supported game types\r\n */\r\nexport enum GameTypes {\r\n firstParty = 'firstParty',\r\n thirdParty = 'thirdParty',\r\n}\r\n\r\n/**\r\n * Supported hosting environments\r\n */\r\nexport enum HostingEnvironments {\r\n msn = 'msn',\r\n zone = 'zone',\r\n edgeCasualGamesHub = 'edgeCasualGamesHub',\r\n}\r\n\r\n/**\r\n * Supported locales\r\n */\r\nexport enum Locales {\r\n enCA = 'en-ca',\r\n enIN = 'en-in',\r\n enUS = 'en-us',\r\n esES = 'es-es',\r\n esUS = 'es-us',\r\n frCA = 'fr-ca',\r\n}\r\n\r\n/**\r\n * Externally-provided settings (set via query string)\r\n */\r\nexport enum PublicSettings {\r\n hostingEnvironment = 'hostingEnvironment',\r\n locale = 'locale',\r\n mcgId = 'mcgId',\r\n setLang = 'setLang',\r\n preroll = 'preroll',\r\n trfSrc = 'trfSrc',\r\n consent = 'consent',\r\n}\r\n\r\n/**\r\n * Event names received by player from game via ZoneAdWrapper\r\n */\r\nexport enum ReceivableGameEvents {\r\n completedLevel = 'completedLevel',\r\n gameEnded = 'gameEnded',\r\n gameMuted = 'gameMuted',\r\n gamePaused = 'gamePaused',\r\n gameQuit = 'gameQuit',\r\n gameResumed = 'gameResumed',\r\n gameScore = 'gameScore',\r\n gameUnmuted = 'gameUnmuted',\r\n gameUnpaused = 'gameUnPaused',\r\n newGame = 'newGame',\r\n readyForComm = 'readyForComm',\r\n startAdPlayback = 'startAdPlayback',\r\n readyForAdPlayback = 'readyForAdPlayback',\r\n}\r\n\r\n/**\r\n * Re-exporting App Insights severity levels so they can be used more generically\r\n */\r\nexport { SeverityLevel } from '../_utils';\r\n\r\n/**\r\n * Standardized event names to send to our telemetry\r\n */\r\nexport enum TelemetryEventNames {\r\n GDK_GEQ = 'GDKGameEndedOrQuit',\r\n GDK_CL = 'GDKCompletedLevel',\r\n GDK_RC = 'GDKReadyToCommunicate',\r\n GDK_SAP = 'GDKStartAdPlayback',\r\n GDK_SR = 'GDKScoreReceived',\r\n HPL = 'HostingPageLoad',\r\n VA_AI = 'VideoAdvertisementAdInitiated',\r\n VA_APT = 'VideoAdvertisementAdPlayTimeout',\r\n VA_C = 'VideoAdvertisementComplete',\r\n VA_D = 'VideoAdvertisementDisabled',\r\n VA_E = 'VideoAdvertisementError',\r\n VA_IE = 'VideoAdvertisementImpressionEnd',\r\n VA_NRT = 'VideoAdvertisementNoResponseTimeout',\r\n VA_NVA = 'VideoAdvertisementNoVideoAvailable',\r\n VA_RI = 'VideoAdvertisementRequestInterstital',\r\n VA_RID = 'VideoAdvertisementRequestInterstitalDisabled',\r\n VA_RP = 'VideoAdvertisementRequestPreroll',\r\n VA_RPD = 'VideoAdvertisementRequestPrerollDisabled',\r\n VA_PT = 'VideoAdvertisementPlaybackTimeout',\r\n VAI_AB = 'VideoAdvertisementImpressionAutoplayBlocked',\r\n VAI_FiQC = 'VideoAdvertisementImpressionFirstQuartileComplete',\r\n VAI_FiQS = 'VideoAdvertisementImpressionFirstQuartileStart',\r\n VAI_FoQC = 'VideoAdvertisementImpressionFourthQuartileComplete',\r\n VAI_NA = 'VideoAdvertisementImpressionNoAd',\r\n VAI_O = 'VideoAdvertisementImpressionOther',\r\n VAI_PA = 'VideoAdvertisementImpressionPauseAd',\r\n VAI_SA = 'VideoAdvertisementImpressionSkipAd',\r\n VAI_SQC = 'VideoAdvertisementImpressionSecondQuartileComplete',\r\n VAI_TQC = 'VideoAdvertisementImpressionThirdQuartileComplete',\r\n LS_UE = 'LocalStorageUnavailableError',\r\n}\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport { Subject, Subscription } from 'rxjs';\r\n\r\nimport dependencyManager from '../_services/dependency-manager';\r\nimport { IEventManager, IMessageEvent } from '../_services/event-manager';\r\n\r\nimport { IVideoPlayback } from '../_types/interfaces/ads';\r\nimport {\r\n AdEventNames,\r\n AdPlacementType,\r\n EventTypes,\r\n Locales,\r\n TelemetryEventNames,\r\n} from '../_types/enums';\r\n\r\nimport { telemetry, Utilities, logger } from '../_utils';\r\n\r\ndeclare global {\r\n interface Window {\r\n apntag: any;\r\n }\r\n}\r\n\r\nenum XandrEventTypes {\r\n // APN Callback Events\r\n // See https://docs.xandr.com/bundle/seller-tag/page/seller-tag/on-event.html for eventType descriptions\r\n EVENT_AD_AVAILABLE = 'adAvailable',\r\n EVENT_AD_BAD_REQUEST = 'adBadRequest',\r\n EVENT_AD_COLLAPSE = 'adCollapse',\r\n EVENT_AD_ERROR = 'adError',\r\n EVENT_AD_LOADED = 'adLoaded',\r\n EVENT_AD_LOADED_MEDIATED = 'adLoadedMediated',\r\n EVENT_AD_NO_BID = 'adNoBid',\r\n EVENT_AD_NO_BID_MEDIATED = 'adNoBidMediated',\r\n EVENT_AD_REQUESTED = 'adRequested',\r\n EVENT_AD_REQUEST_FAILURE = 'adRequestFailure',\r\n\r\n // Bannerstream callback events\r\n // See https://docs.xandr.com/bundle/seller-tag/page/seller-tag/publisher-page-level-options-for-outstream.html for event descriptions\r\n // @todo: do we need all of VPAID / VAST / AdUnit events?\r\n EVENT_AD_COMPLETE = 'adComplete',\r\n EVENT_COMPLETE = 'complete',\r\n EVENT_ENDED = 'ended',\r\n EVENT_IMPRESSION = 'impression',\r\n EVENT_FIRST_QUARTILE = 'firstQuartile',\r\n EVENT_LOADED = 'loaded',\r\n EVENT_MIDPOINT = 'midpoint',\r\n EVENT_START = 'start',\r\n EVENT_THIRD_QUARTILE = 'thirdQuartile',\r\n EVENT_VIDEO_PAUSE = 'pause',\r\n EVENT_VIDEO_RESUME = 'resume',\r\n EVENT_VIDEO_SKIP = 'skip',\r\n EVENT_VOLUME_CHANGE = 'volume-change',\r\n}\r\n\r\nexport default class Xandr implements IVideoPlayback {\r\n private apntagRef: any;\r\n\r\n private apnPageOptions = {\r\n member: __ENV__.vendors.xandr.memberId,\r\n test: __ENV__.vendors.xandr?.testFlag,\r\n user: {\r\n externalUid: '',\r\n userIds: [{\r\n type: 'extendedIDs',\r\n eids: [{\r\n id: '',\r\n source: 'msft_muid',\r\n }],\r\n }],\r\n },\r\n };\r\n\r\n private astOptions = {\r\n targetId: __ENV__.vendors.xandr.videoContainerElementId,\r\n invCode: '',\r\n sizes: [640, 414],\r\n allowedFormats: ['video'],\r\n targetingParams: {},\r\n trafficSourceCode: '',\r\n rendererOptions: {\r\n cbNotification: this.setOutstreamCallbacks,\r\n playerTechnology: ['html5'],\r\n adText: 'Ad',\r\n showMute: true,\r\n showVolume: true,\r\n showProgressBar: true,\r\n autoInitialSize: true,\r\n allowFullscreen: true,\r\n playVideoVisibleThreshold: 0,\r\n sideStream: {\r\n enabled: false,\r\n },\r\n skippable: {\r\n videoThreshold: 15,\r\n videoOffset: 5,\r\n skipLocation: 'top-left',\r\n skipText: 'Video can be skipped in %%TIME%% seconds',\r\n skipButtonText: 'SKIP',\r\n },\r\n },\r\n };\r\n\r\n private astOptionsPlacement = __ENV__.vendors.xandr.placement;\r\n\r\n private astOptionsProviderId = __ENV__.vendors.xandr.providerId;\r\n\r\n private astOptionsRID = __ENV__.vendors.xandr.RID;\r\n\r\n private eventHubSubscription: Subscription;\r\n\r\n private placementLocale: string;\r\n\r\n private telemetryProperties = {\r\n adPlacementType: null,\r\n adSessionID: null, // Unique session identifier for play/ad session\r\n prevEvent: null,\r\n placementId: null,\r\n vendor: 'xandr',\r\n videoDuration: null,\r\n videoUrl: null,\r\n };\r\n\r\n private videoContainerElementId: string = __ENV__.vendors.xandr.videoContainerElementId;\r\n\r\n private videoContentContainerElementId: string = __ENV__.vendors.xandr.contentContainerId;\r\n\r\n private videoAdPauseDelta: number;\r\n\r\n private videoAdPauseTime: number;\r\n\r\n private videoAdResumeTime: number;\r\n\r\n private videoAdStartTime: number;\r\n\r\n private xandrASTScriptSrc = __ENV__.vendors.xandr.scriptSrc;\r\n\r\n private xandrASTScriptContainerId = __ENV__.vendors.xandr.scriptContainerId;\r\n\r\n private xandrEventLog: string[] = [];\r\n\r\n private get isApnTag(): boolean {\r\n return typeof this.apntagRef === 'object'\r\n && this.apntagRef?.loaded === true;\r\n }\r\n\r\n public eventHub: Subject<IMessageEvent> = new Subject();\r\n\r\n public set enableTestAd(testFlag: boolean) {\r\n this.apnPageOptions.test = testFlag ? 1 : 0;\r\n }\r\n\r\n public set locale(locale: string) {\r\n this.placementLocale = locale;\r\n }\r\n\r\n public set mcgId(mcgId: string) {\r\n // stub\r\n }\r\n\r\n public showPrerollClickToPlay = true;\r\n\r\n public vendorID = 'xandr';\r\n\r\n constructor(\r\n public eventManager: IEventManager = dependencyManager.eventManager,\r\n ) {\r\n this.eventManager.windowEvents.subscribe((event: IMessageEvent) => {\r\n // typescript is being silly here -- 'Object.values' returns an array, 'includes' checks its contents. There is no type mismatch.\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n if (Object.values(XandrEventTypes).includes(event.name)) {\r\n this.handleAdEvent(event);\r\n }\r\n });\r\n }\r\n\r\n /** PUBLIC METHODS -- AD SETUP AND TEARDOWN */\r\n\r\n public playAd(preroll: boolean): Promise<boolean> {\r\n this.setAstOptionProperties(preroll);\r\n\r\n this.telemetryProperties.adPlacementType = preroll ? AdPlacementType.preroll : AdPlacementType.interstitial;\r\n this.telemetryProperties.placementId = this.astOptions.invCode;\r\n\r\n // Re-initialize our timers\r\n this.videoAdPauseDelta = 0;\r\n this.videoAdPauseTime = 0;\r\n this.videoAdResumeTime = 0;\r\n this.videoAdStartTime = 0;\r\n\r\n return this.initXandrAST()\r\n .then(() => {\r\n const adContainer = this.createAdContainer();\r\n if (!(adContainer instanceof HTMLElement)) {\r\n throw new Error(`Couldn't create ad container #${this.videoContentContainerElementId}`);\r\n }\r\n\r\n return this.requestAds();\r\n })\r\n .then(() => true) // Success\r\n .catch((err: Error) => {\r\n const properties = {\r\n ...this.telemetryProperties,\r\n info: err.message,\r\n };\r\n telemetry.trackError({ name: TelemetryEventNames.VA_NVA }, properties);\r\n this.eventHub.next({ name: AdEventNames.adPlaybackError, data: {}, type: EventTypes.adEvent });\r\n return false; // Error playing the ad\r\n });\r\n }\r\n\r\n public cleanup(): void {\r\n telemetry.flushEvent();\r\n\r\n this.eventHubSubscription.unsubscribe();\r\n this.eventHubSubscription = null;\r\n\r\n Object.keys(this.telemetryProperties).filter((key) => key !== 'vendor').forEach((key) => {\r\n this.telemetryProperties[key] = null;\r\n });\r\n\r\n this.xandrEventLog = [];\r\n\r\n const nodes = [\r\n document.querySelector(`#${this.videoContainerElementId}`),\r\n document.querySelector(`#${this.videoContentContainerElementId}`),\r\n ];\r\n\r\n // Remove all non-zone image/iframe/script nodes that have been written into the page\r\n document.querySelectorAll('iframe, img, script').forEach((element: HTMLIFrameElement|HTMLImageElement|HTMLScriptElement) => {\r\n if (element.src) {\r\n const { host } = new URL(element.src);\r\n if (host !== window.location.host && !host.endsWith('zone.msn.com')) {\r\n nodes.push(element);\r\n }\r\n } else {\r\n nodes.push(element);\r\n }\r\n });\r\n\r\n Utilities.removeNode(\r\n nodes.filter((node) => node != null),\r\n );\r\n }\r\n\r\n /** PRIVATE METHODS -- AD CONFIGURATION */\r\n\r\n private async initXandrAST(): Promise<void | Error> {\r\n if (this.isApnTag) {\r\n logger.cLog('this.apntagRef already loaded');\r\n return Promise.resolve();\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n const xandrASTJs = document.createElement('script');\r\n xandrASTJs.src = this.xandrASTScriptSrc;\r\n xandrASTJs.id = this.xandrASTScriptContainerId;\r\n xandrASTJs.type = 'text/javascript';\r\n xandrASTJs.onload = resolve;\r\n xandrASTJs.onerror = reject;\r\n Utilities.appendNode(document.head, xandrASTJs);\r\n })\r\n .then(() => {\r\n // Make sure global apntag object is ready to go before continuing\r\n if (this.isApnTag) {\r\n return Promise.resolve();\r\n }\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n let apnLoadTimeoutCount = 0;\r\n const apnLoadTimeout = setInterval(\r\n () => {\r\n this.apntagRef = window.apntag;\r\n if (this.isApnTag) {\r\n clearInterval(apnLoadTimeout);\r\n resolve();\r\n } else {\r\n apnLoadTimeoutCount += 1;\r\n }\r\n\r\n if (apnLoadTimeoutCount >= 10) {\r\n clearInterval(apnLoadTimeout);\r\n reject();\r\n }\r\n },\r\n 500,\r\n );\r\n });\r\n })\r\n .catch((err) => Utilities.getFormattedError(err));\r\n }\r\n\r\n private createAdContainer(): HTMLElement {\r\n const adContainer = document.createElement('div');\r\n adContainer.setAttribute('id', this.videoContentContainerElementId); // adDiv\r\n adContainer.setAttribute('class', 'ad-player-container');\r\n\r\n const displayBase = document.createElement('div');\r\n displayBase.setAttribute('id', this.videoContainerElementId); // displayBase\r\n displayBase.setAttribute('style', 'width:100%; height:100%;');\r\n displayBase.setAttribute('data-setup', '{}');\r\n Utilities.appendNode(adContainer, displayBase);\r\n\r\n Utilities.appendNode(document.querySelector('#adContainer'), adContainer);\r\n return document.querySelector(`#${this.videoContentContainerElementId}`);\r\n }\r\n\r\n private requestAds(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n this.apntagRef.anq.push(() => {\r\n this.setApnPageOptions();\r\n\r\n const newApnPageOptions = { ...this.apnPageOptions };\r\n const newAstOptions = { ...this.astOptions };\r\n\r\n this.apntagRef.setPageOpts(newApnPageOptions);\r\n if (__ENV__.runtime.dev || Utilities.isDeveloperModeActive()) {\r\n this.apntagRef.debug = true;\r\n }\r\n\r\n this.apntagRef.defineTag(newAstOptions);\r\n\r\n this.setApnCallbacks();\r\n\r\n this.apntagRef.anq.push(() => {\r\n this.apntagRef.loadTags();\r\n });\r\n\r\n this.telemetryProperties.adSessionID = (Date.now() * 1000) + Math.round(Math.random() * 1000);\r\n });\r\n\r\n this.eventHubSubscription = this.eventHub.subscribe((event: IMessageEvent) => {\r\n switch (event.name) {\r\n case AdEventNames.adComplete:\r\n resolve();\r\n break;\r\n case AdEventNames.adPlaybackError:\r\n reject();\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n } catch (err) {\r\n reject(new Error(err));\r\n }\r\n });\r\n }\r\n\r\n /** AST SCRIPT CONFIGURATION */\r\n\r\n /**\r\n * Callback function for Xandr ast options cbNotification property\r\n * For more info see https://docs.xandr.com/bundle/seller-tag/page/seller-tag/publisher-page-level-options-for-outstream.html\r\n * @param type VPAID, VAST, AdUnit\r\n * @param name Name of event\r\n * @param id AST target element ID\r\n * @param eventData Event-specific data\r\n */\r\n private setOutstreamCallbacks(type, name, id, eventData): void {\r\n window.postMessage({\r\n name,\r\n data: {\r\n type,\r\n id,\r\n eventData: eventData || {},\r\n },\r\n });\r\n }\r\n\r\n private setApnCallbacks(): void {\r\n Object.values(XandrEventTypes).forEach((eventType) => {\r\n let callbackFunction = null;\r\n\r\n switch (eventType) {\r\n case XandrEventTypes.EVENT_AD_AVAILABLE:\r\n callbackFunction = (adObj) => {\r\n window.postMessage({ name: eventType, data: { targetId: this.astOptions.targetId, adObj } });\r\n this.apntagRef.anq.push(() => {\r\n // signal to script that this DOM elemetn has been loaded and is ready to be populated with an ad\r\n this.apntagRef.showTag(this.astOptions.targetId);\r\n });\r\n };\r\n break;\r\n case XandrEventTypes.EVENT_AD_BAD_REQUEST:\r\n case XandrEventTypes.EVENT_AD_REQUEST_FAILURE:\r\n callbackFunction = (adError) => {\r\n window.postMessage({ name: eventType, data: { targetId: this.astOptions.targetId, adError } });\r\n };\r\n break;\r\n case XandrEventTypes.EVENT_AD_ERROR:\r\n callbackFunction = (adError, adObj) => {\r\n window.postMessage({ name: eventType, data: { targetId: this.astOptions.targetId, adError, adObj } });\r\n };\r\n break;\r\n case XandrEventTypes.EVENT_AD_LOADED:\r\n case XandrEventTypes.EVENT_AD_LOADED_MEDIATED:\r\n case XandrEventTypes.EVENT_AD_NO_BID:\r\n case XandrEventTypes.EVENT_AD_NO_BID_MEDIATED:\r\n callbackFunction = (adObj) => {\r\n window.postMessage({ name: eventType, data: { targetId: this.astOptions.targetId, adObj } });\r\n };\r\n break;\r\n case XandrEventTypes.EVENT_AD_COLLAPSE:\r\n case XandrEventTypes.EVENT_AD_REQUESTED:\r\n callbackFunction = () => {\r\n window.postMessage({ name: eventType, data: { targetId: this.astOptions.targetId } });\r\n };\r\n break;\r\n default:\r\n break;\r\n }\r\n\r\n if (callbackFunction && typeof callbackFunction === 'function') {\r\n this.apntagRef.onEvent(\r\n eventType,\r\n this.astOptions.targetId,\r\n callbackFunction,\r\n );\r\n }\r\n });\r\n }\r\n\r\n private setApnPageOptions(): void {\r\n if (this.apnPageOptions.test !== 1) {\r\n delete this.apnPageOptions.test;\r\n }\r\n\r\n const apnPageOptionsUserId = Utilities.getCookieValue('MUID');\r\n if (apnPageOptionsUserId.length > 0) {\r\n this.apnPageOptions.user.externalUid = apnPageOptionsUserId;\r\n this.apnPageOptions.user.userIds.forEach((userId) => {\r\n userId.eids.forEach((eid) => {\r\n eid.id = apnPageOptionsUserId;\r\n });\r\n });\r\n } else {\r\n delete this.apnPageOptions.user;\r\n }\r\n }\r\n\r\n private setAstOptionProperties(preroll: boolean): void {\r\n let placementOptions = this.astOptionsPlacement.filter((placement) => placement.locale === this.placementLocale);\r\n\r\n if (placementOptions.length <= 0) {\r\n placementOptions = this.astOptionsPlacement.filter((placement) => placement.locale === Locales.enUS); // default\r\n }\r\n\r\n if (placementOptions.length > 1) {\r\n const adPlacementType = preroll ? AdPlacementType.preroll : AdPlacementType.interstitial;\r\n this.astOptions.invCode = placementOptions.find((placement) => placement.placementType === adPlacementType).placementId;\r\n } else {\r\n this.astOptions.invCode = placementOptions[0].placementId;\r\n }\r\n\r\n this.astOptions.trafficSourceCode = `pg:${this.astOptions.invCode};p:${this.astOptionsProviderId};r:${this.astOptionsRID}`;\r\n }\r\n\r\n /** EVENT HANDLING */\r\n\r\n private handleAdEvent(event: IMessageEvent): void {\r\n if (this.xandrEventLog.includes(event.name)) {\r\n // duplicate event, ignore\r\n logger.cWarn(`Already handled ${event.name}, skipping...`);\r\n return;\r\n }\r\n\r\n this.xandrEventLog.push(event.name);\r\n\r\n let eventType;\r\n let adError;\r\n if (event.data && typeof event.data === 'object') {\r\n ({ type: eventType, adError } = event.data);\r\n }\r\n\r\n // Only do this once, rather than every ad event call\r\n if (!this.telemetryProperties.videoDuration || !this.telemetryProperties.videoUrl) {\r\n const videoAd = Utilities.findActiveVideo(document);\r\n if (videoAd !== null) {\r\n this.telemetryProperties.videoDuration = videoAd.duration;\r\n this.telemetryProperties.videoUrl = videoAd.src;\r\n }\r\n }\r\n\r\n const properties = {\r\n ...this.telemetryProperties,\r\n eventType,\r\n split: 0,\r\n astEvent: event.name,\r\n };\r\n\r\n switch (event.name) {\r\n case XandrEventTypes.EVENT_AD_BAD_REQUEST:\r\n case XandrEventTypes.EVENT_AD_ERROR:\r\n case XandrEventTypes.EVENT_AD_NO_BID:\r\n case XandrEventTypes.EVENT_AD_NO_BID_MEDIATED:\r\n case XandrEventTypes.EVENT_AD_REQUEST_FAILURE: {\r\n const errorProperties = {\r\n ...properties,\r\n errorCode: adError?.code,\r\n errorInfo: adError?.exception,\r\n errorMessage: adError?.errMessage,\r\n };\r\n telemetry.trackError({ name: TelemetryEventNames.VA_E }, errorProperties);\r\n this.eventHub.next({ name: AdEventNames.adPlaybackError, data: {}, type: EventTypes.adEvent });\r\n\r\n break;\r\n }\r\n case XandrEventTypes.EVENT_AD_AVAILABLE:\r\n case XandrEventTypes.EVENT_AD_LOADED:\r\n case XandrEventTypes.EVENT_AD_LOADED_MEDIATED:\r\n telemetry.trackEvent({ name: TelemetryEventNames.VA_AI }, properties);\r\n // this.eventHub.next({ name: AdEventNames.adImpressionStart }); // @todo: clean up if not needed\r\n break;\r\n\r\n case XandrEventTypes.EVENT_START:\r\n this.videoAdStartTime = Date.now();\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_FiQS }, properties);\r\n this.eventHub.next({\r\n name: AdEventNames.adImpressionStart,\r\n data: { duration: properties.videoDuration },\r\n type: EventTypes.adEvent,\r\n });\r\n break;\r\n\r\n case XandrEventTypes.EVENT_FIRST_QUARTILE:\r\n properties.split = this.calculateSplit();\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_FiQC }, properties);\r\n this.eventHub.next({ name: AdEventNames.adFirstQuartile, data: { duration: properties.split }, type: EventTypes.adEvent });\r\n break;\r\n\r\n case XandrEventTypes.EVENT_MIDPOINT:\r\n properties.split = this.calculateSplit();\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_SQC }, properties);\r\n this.eventHub.next({ name: AdEventNames.adSecondQuartile, data: { duration: properties.split }, type: EventTypes.adEvent });\r\n break;\r\n\r\n case XandrEventTypes.EVENT_THIRD_QUARTILE:\r\n properties.split = this.calculateSplit();\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_TQC }, properties);\r\n this.eventHub.next({ name: AdEventNames.adThirdQuartile, data: { duration: properties.split }, type: EventTypes.adEvent });\r\n break;\r\n\r\n case XandrEventTypes.EVENT_COMPLETE:\r\n properties.split = this.calculateSplit();\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_FoQC }, properties);\r\n this.eventHub.next({ name: AdEventNames.adFourthQuartile, data: { duration: properties.split }, type: EventTypes.adEvent });\r\n this.eventHub.next({ name: AdEventNames.adComplete, data: {}, type: EventTypes.adEvent });\r\n break;\r\n\r\n case XandrEventTypes.EVENT_AD_COMPLETE:\r\n // this.eventHub.next({ name: AdEventNames.adComplete, data: {}, type: EventTypes.adEvent }); // @todo: clean up if not needed\r\n telemetry.trackEvent({ name: TelemetryEventNames.VA_C }, properties);\r\n break;\r\n\r\n case XandrEventTypes.EVENT_ENDED:\r\n telemetry.trackEvent({ name: TelemetryEventNames.VA_C }, properties);\r\n break;\r\n\r\n case XandrEventTypes.EVENT_VIDEO_PAUSE:\r\n this.videoAdPauseTime = Date.now();\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_PA }, properties);\r\n this.eventHub.next({ name: AdEventNames.adPaused, data: {}, type: EventTypes.adEvent });\r\n break;\r\n\r\n case XandrEventTypes.EVENT_VIDEO_RESUME:\r\n this.videoAdResumeTime = Date.now();\r\n this.eventHub.next({ name: AdEventNames.adResumed, data: {}, type: EventTypes.adEvent });\r\n break;\r\n\r\n // @todo: look into logging chrome event for blocked/heavy ads\r\n // case XandrEventTypes.EVENT_AD_AUTO_PLAY_BLOCKED:\r\n\r\n case XandrEventTypes.EVENT_VIDEO_SKIP:\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_SA }, properties);\r\n this.eventHub.next({ name: AdEventNames.adComplete, data: {}, type: EventTypes.adEvent });\r\n break;\r\n\r\n default:\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_O }, properties);\r\n break;\r\n }\r\n\r\n this.telemetryProperties.prevEvent = event.name;\r\n }\r\n\r\n /** UTILITIES */\r\n\r\n private calculateSplit(): number {\r\n this.videoAdPauseDelta += (this.videoAdResumeTime - this.videoAdPauseTime);\r\n this.videoAdPauseTime = 0;\r\n this.videoAdResumeTime = 0;\r\n return (Date.now() - (this.videoAdStartTime + this.videoAdPauseDelta)) / 1000;\r\n }\r\n}\r\n\r\nexport const transformEvent = (event: MessageEvent): IMessageEvent => {\r\n const messageEvent: IMessageEvent = {\r\n name: null,\r\n data: null,\r\n type: EventTypes.adEvent,\r\n };\r\n\r\n if (typeof event.data === 'object') {\r\n const { name, data } = event.data;\r\n if (Object.values(XandrEventTypes).includes(name)) {\r\n messageEvent.name = name;\r\n messageEvent.data = data;\r\n }\r\n }\r\n\r\n return messageEvent;\r\n};\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport { Observable, Subscription } from 'rxjs';\r\nimport { filter, map } from 'rxjs/operators';\r\n\r\nimport dependencyManager from './dependency-manager';\r\nimport { IMessageEvent } from './event-manager';\r\n\r\nimport { AdEventNames, AdErrorNames, TelemetryEventNames } from '../_types/enums';\r\nimport { IAdPlaybackResult, IVideoPlayback } from '../_types/interfaces/ads';\r\nimport { IAdsConfiguration } from '../_types/interfaces/player';\r\n\r\nimport { logger, telemetry } from '../_utils';\r\nimport { transformEvent as transformXandrEvent } from '../_vendor/xandr';\r\n\r\nexport interface IAdManager {\r\n adEvents: (adEventNames: AdEventNames[]) => Observable<any>;\r\n configurePlayers: (adsConfiguration: IAdsConfiguration) => void;\r\n isAdPlaying: boolean;\r\n playInterstitialAd: () => Promise<IAdPlaybackResult | Error>;\r\n playPrerollAd: () => Promise<IAdPlaybackResult | Error>;\r\n showPrerollClickToPlay: boolean;\r\n}\r\n\r\nexport class AdManager implements IAdManager {\r\n private _placeholderVideo: IVideoPlayback;\r\n\r\n private _xandr: IVideoPlayback;\r\n\r\n // @xxx\r\n // private adPlayTimeoutRef: {\r\n // [key: string]: NodeJS.Timeout,\r\n // } = {};\r\n private adPlayTimeoutRef: NodeJS.Timeout;\r\n\r\n private adPlayTimeoutSubscription: Subscription;\r\n\r\n private adResponseTimeout = 3; // seconds\r\n\r\n private adStartTimeoutRef: NodeJS.Timeout;\r\n\r\n private adStartTimeoutSubscription: Subscription;\r\n\r\n private adPartner: IVideoPlayback;\r\n\r\n private isPlaying = false;\r\n\r\n get isAdPlaying(): boolean {\r\n return this.isPlaying;\r\n }\r\n\r\n get showPrerollClickToPlay(): boolean {\r\n return this.adPartner.showPrerollClickToPlay;\r\n }\r\n\r\n constructor(\r\n public placeholderVideo = dependencyManager.placeholderVideo,\r\n // public xandr = dependencyManager.xandr,\r\n ) {\r\n this._placeholderVideo = placeholderVideo;\r\n // this._xandr = xandr;\r\n }\r\n\r\n public configurePlayers(adsConfiguration: IAdsConfiguration) {\r\n switch (adsConfiguration.adVendor) {\r\n case 'xandr':\r\n this.adPartner = this._xandr;\r\n this.adPartner.locale = adsConfiguration?.locale;\r\n if (typeof adsConfiguration?.enableTestAd === 'boolean') {\r\n this.adPartner.enableTestAd = adsConfiguration.enableTestAd;\r\n }\r\n break;\r\n default:\r\n this.adPartner = this._placeholderVideo;\r\n }\r\n }\r\n\r\n public playPrerollAd(): Promise<IAdPlaybackResult | Error> {\r\n return this.playAd(this.adPartner, true);\r\n }\r\n\r\n public playInterstitialAd(): Promise<IAdPlaybackResult | Error> {\r\n return this.playAd(this.adPartner, false);\r\n }\r\n\r\n public adEvents([...events]: AdEventNames[]): Observable<any> {\r\n return this.adPartner.eventHub.asObservable().pipe(\r\n map((event) => ({ name: event.name, data: event.data })),\r\n // typescript is being silly here -- 'events' is an array, 'includes' checks its contents. There is no type mismatch.\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n filter((event) => events.includes(event.name)),\r\n );\r\n }\r\n\r\n private playAd(partner: IVideoPlayback, preroll: boolean): Promise<IAdPlaybackResult | Error> {\r\n if (!this.isPlaying) {\r\n this.isPlaying = true;\r\n\r\n const adEventName = preroll ? TelemetryEventNames.VA_RP : TelemetryEventNames.VA_RI;\r\n telemetry.trackEvent({ name: adEventName });\r\n\r\n // Attempt to play ad\r\n // Reject & continue if we hit adStartTimeout or adPlayTimeout\r\n return Promise.race([this.adStartTimeout(), this.adPlayTimeout(), partner.playAd(preroll)])\r\n .then(() => <IAdPlaybackResult>{ success: true })\r\n .catch(() => {\r\n throw new Error(AdErrorNames.AdCouldNotBePlayed);\r\n })\r\n .finally(() => {\r\n partner.cleanup();\r\n this.cleanup();\r\n });\r\n }\r\n\r\n // An ad is already playing, so don't play another one\r\n logger.cError(AdErrorNames.AdAlreadyPlaying);\r\n return Promise.reject(new Error(AdErrorNames.AdAlreadyPlaying));\r\n }\r\n\r\n /**\r\n * Set ad start timeout -- if ad SDK has not loaded an ad w/in timeout window, proceed to gameplay\r\n * @returns Promise<Error>\r\n */\r\n private adStartTimeout(): Promise<Error> {\r\n return new Promise((resolve, reject) => {\r\n this.adStartTimeoutRef = setTimeout(\r\n () => {\r\n telemetry.trackError({ name: TelemetryEventNames.VA_NRT }); // @todo: clean up / centralize error telemetry\r\n clearTimeout(this.adStartTimeoutRef);\r\n reject(new Error(AdErrorNames.AdResponseTimeout));\r\n },\r\n this.adResponseTimeout * 1000,\r\n );\r\n\r\n // If we receive the adImpressionStart or adPlaybackError events, SDK has responded and we can clear the ad start timeout.\r\n this.adStartTimeoutSubscription = this.adEvents([\r\n AdEventNames.adImpressionStart, AdEventNames.adPlaybackError,\r\n ]).subscribe(() => {\r\n if (this.adStartTimeoutRef) {\r\n clearTimeout(this.adStartTimeoutRef);\r\n this.adStartTimeoutRef = null;\r\n }\r\n });\r\n });\r\n }\r\n\r\n private adPlayTimeout(): Promise<Error> {\r\n return new Promise((resolve, reject) => {\r\n this.adPlayTimeoutRef = setTimeout(\r\n () => {\r\n telemetry.trackError({ name: TelemetryEventNames.VA_APT }); // @todo: clean up / centralize error telemetry\r\n clearTimeout(this.adPlayTimeoutRef);\r\n reject(new Error(AdErrorNames.AdPlaybackTimeout));\r\n },\r\n 20 * 1000,\r\n );\r\n\r\n // If we receive the adComplete or adPlaybackError events, SDK has responded and we can clear the ad playback timeout.\r\n this.adPlayTimeoutSubscription = this.adEvents([\r\n AdEventNames.adComplete, AdEventNames.adPlaybackError,\r\n ]).subscribe(() => {\r\n if (this.adPlayTimeoutRef) {\r\n clearTimeout(this.adPlayTimeoutRef);\r\n this.adPlayTimeoutRef = null;\r\n }\r\n });\r\n });\r\n /* //@xxx\r\n return new Promise((resolve, reject) => {\r\n const splitTimeouts = {\r\n firstQSplit: 0.25,\r\n secondQSplit: 0.5,\r\n thirdQSplit: 0.75,\r\n fourthQSplit: 1,\r\n };\r\n\r\n this.adPlayTimeoutSubscription = this.adEvents([\r\n AdEventNames.adImpressionStart,\r\n AdEventNames.adFirstQuartile,\r\n AdEventNames.adSecondQuartile,\r\n AdEventNames.adThirdQuartile,\r\n AdEventNames.adFourthQuartile,\r\n AdEventNames.adPaused,\r\n AdEventNames.adResumed,\r\n ]).subscribe((event) => {\r\n let split = null;\r\n\r\n switch (event.name) {\r\n case AdEventNames.adImpressionStart: {\r\n const duration = event?.context?.duration;\r\n if (typeof duration === 'number' && duration > 0) {\r\n Object.keys(splitTimeouts).forEach((splitKey) => {\r\n if (!this.adPlayTimeoutRef[splitKey]) {\r\n const timeout = Math.ceil(duration * splitTimeouts[splitKey]) + 4; // seconds\r\n\r\n const myRef = setTimeout(\r\n () => {\r\n telemetry.trackError({ name: TelemetryEventNames.VA_NRT }, { splitTimeout: splitKey });\r\n clearTimeout(this.adPlayTimeoutRef[splitKey]);\r\n this.adPlayTimeoutRef[splitKey] = null;\r\n reject(new Error(AdErrorNames.AdPlaybackTimeout));\r\n },\r\n timeout * 1000,\r\n );\r\n this.adPlayTimeoutRef[splitKey] = myRef;\r\n }\r\n });\r\n }\r\n break;\r\n }\r\n case AdEventNames.adFirstQuartile:\r\n split = 'firstQSplit';\r\n break;\r\n case AdEventNames.adSecondQuartile:\r\n split = 'secondQSplit';\r\n break;\r\n case AdEventNames.adThirdQuartile:\r\n split = 'thirdQSplit';\r\n break;\r\n case AdEventNames.adFourthQuartile:\r\n split = 'fourthQSplit';\r\n break;\r\n case AdEventNames.adPaused:\r\n Object.keys(this.adPlayTimeoutRef).forEach((key) => {\r\n clearTimeout(this.adPlayTimeoutRef[key]);\r\n this.adPlayTimeoutRef[key] = null;\r\n });\r\n break;\r\n default:\r\n break;\r\n }\r\n\r\n if (split && this.adPlayTimeoutRef[split]) {\r\n clearTimeout(this.adPlayTimeoutRef[split]);\r\n this.adPlayTimeoutRef[split] = null;\r\n }\r\n });\r\n });\r\n */\r\n }\r\n\r\n private cleanup(): void {\r\n // Clean up timeouts just in case\r\n clearTimeout(this.adStartTimeoutRef);\r\n this.adStartTimeoutRef = null;\r\n // Object.keys(this.adPlayTimeoutRef).forEach((ref) => {\r\n // clearTimeout(this.adPlayTimeoutRef[ref]);\r\n // this.adPlayTimeoutRef[ref] = null;\r\n // });\r\n // @xxx\r\n clearTimeout(this.adPlayTimeoutRef);\r\n this.adPlayTimeoutRef = null;\r\n\r\n // Clean up subscriptions\r\n this.adStartTimeoutSubscription.unsubscribe();\r\n this.adStartTimeoutSubscription = null;\r\n this.adPlayTimeoutSubscription.unsubscribe();\r\n this.adPlayTimeoutSubscription = null;\r\n\r\n this.isPlaying = false;\r\n }\r\n}\r\n\r\n/**\r\n * Wrapper class for transforming/formatting ad events\r\n * @param event MessageEvent\r\n * @returns IMessageEvent\r\n */\r\nexport const transformEvent = (event: MessageEvent): IMessageEvent => transformXandrEvent(event); // @todo: make this generic\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport { filter } from 'rxjs/operators';\r\nimport dependencyManager from './dependency-manager';\r\nimport { IEventManager, IMessageEvent } from './event-manager';\r\nimport { ReceivableGameEvents, EmittableGameEvents, EventTypes } from '../_types/enums';\r\n\r\nexport interface IGameManager {\r\n muteGame: (target: HTMLElement) => Promise<IMessageEvent>;\r\n pauseGame: (target: HTMLElement) => Promise<IMessageEvent>;\r\n resumeGame: (target: HTMLElement) => Promise<IMessageEvent>;\r\n}\r\n\r\nexport class GameManager implements IGameManager {\r\n constructor(\r\n private eventManager: IEventManager = dependencyManager.eventManager,\r\n ) { }\r\n\r\n public pauseGame(target: HTMLIFrameElement): Promise<IMessageEvent> {\r\n return this.requestAction(target, EmittableGameEvents.pauseGame, ReceivableGameEvents.gamePaused);\r\n }\r\n\r\n public resumeGame(target: HTMLIFrameElement): Promise<IMessageEvent> {\r\n return this.requestAction(target, EmittableGameEvents.resumeGame, ReceivableGameEvents.gameResumed);\r\n }\r\n\r\n public muteGame(target: HTMLIFrameElement): Promise<IMessageEvent> {\r\n return this.requestAction(target, EmittableGameEvents.muteGame, ReceivableGameEvents.gameMuted);\r\n }\r\n\r\n private requestAction(\r\n target: HTMLIFrameElement,\r\n action: EmittableGameEvents,\r\n expectedResponse: ReceivableGameEvents,\r\n ): Promise<IMessageEvent> {\r\n return new Promise((resolve, reject) => { // @todo: consider using .promisify? http://bluebirdjs.com/docs/anti-patterns.html\r\n this.eventManager.send(target, action);\r\n this.eventManager.windowEvents.pipe(\r\n filter((e: IMessageEvent) => e.name === expectedResponse),\r\n )\r\n .subscribe((e) => resolve(e));\r\n\r\n setTimeout(\r\n () => reject(new Error(`Timed out waiting for ${action}`)),\r\n __ENV__.settings.games.pauseFailedTimeout,\r\n );\r\n });\r\n }\r\n}\r\n\r\nexport const transformEvent = (event: MessageEvent): IMessageEvent => {\r\n const messageEvent = {\r\n name: null,\r\n data: null,\r\n type: EventTypes.gameEvent,\r\n };\r\n\r\n if (typeof event.data === 'string') {\r\n const gameScore = event.data.match(/<score>([0-9]+)<\\/score>/);\r\n if (gameScore && gameScore.length === 2) {\r\n messageEvent.name = ReceivableGameEvents.gameScore;\r\n [, messageEvent.data] = gameScore;\r\n } else if (ReceivableGameEvents[event.data]) {\r\n messageEvent.name = event.data;\r\n }\r\n }\r\n\r\n return messageEvent;\r\n};\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Model definitions\r\n */\r\nexport default class Message {\r\n constructor(value, needsReconciliation, target, expectedResponse?: string) {\r\n this.sent = value;\r\n this.needsReconciliation = needsReconciliation;\r\n this.timeSent = Date.now();\r\n this.target = target;\r\n this.expectedResponse = expectedResponse;\r\n }\r\n\r\n id?:string;\r\n\r\n sent?: string;\r\n\r\n received?: any;\r\n\r\n needsReconciliation?: boolean;\r\n\r\n timeSent?: number;\r\n\r\n timeReceived?: number;\r\n\r\n complete?: boolean;\r\n\r\n target?: any;\r\n\r\n expectedResponse?: string;\r\n}\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport { Observable, fromEvent } from 'rxjs';\r\nimport { map, filter } from 'rxjs/operators';\r\n\r\nimport { transformEvent as transformAdEvent } from './ad-manager';\r\nimport { transformEvent as transformGameEvent } from './game-manager';\r\n\r\nimport Message from '../_types/models';\r\nimport {\r\n EmittableGameEvents,\r\n EventTypes,\r\n} from '../_types/enums';\r\n\r\nimport { logger } from '../_utils';\r\n\r\nexport interface IMessageEvent {\r\n name: string;\r\n data: string | { [key: string]: any } | null;\r\n type: EventTypes;\r\n}\r\n\r\nexport interface IEventManager {\r\n send: (target: Window | HTMLIFrameElement, message: EmittableGameEvents, extra?: string) => void;\r\n windowEvents: Observable<IMessageEvent>;\r\n}\r\n\r\nexport class EventManager implements IEventManager {\r\n windowEvents: Observable<IMessageEvent>;\r\n\r\n awaitingAck = [];\r\n\r\n constructor() {\r\n let eventStream;\r\n if (window.addEventListener) {\r\n eventStream = fromEvent(window, 'message');\r\n } else {\r\n eventStream = fromEvent(window, 'onmessage');\r\n }\r\n\r\n this.windowEvents = eventStream.pipe(\r\n // map((e: MessageEvent) => this.log(e)),\r\n map((e: MessageEvent) => this.reconcile(e)),\r\n map((e: MessageEvent) => this.transform(e)),\r\n filter((e: IMessageEvent) => this.isReceivableEvent(e)),\r\n );\r\n }\r\n\r\n send(target: Window | HTMLIFrameElement, message: EmittableGameEvents, extra?: string) {\r\n let msgExtra = '';\r\n let msgTarget;\r\n // prevent double send here\r\n if (target instanceof HTMLIFrameElement) {\r\n msgTarget = target.contentWindow;\r\n } else {\r\n msgTarget = target;\r\n }\r\n msgExtra = extra || '';\r\n msgTarget.postMessage(`${message}${msgExtra}`, '*');\r\n logger.cLog('sending event ', `${message}${msgExtra}`);\r\n if (message === EmittableGameEvents.pauseGame || message === EmittableGameEvents.resumeGame) {\r\n this.awaitingAck.push(new Message(message, true, msgTarget));\r\n }\r\n }\r\n\r\n log(e: MessageEvent): MessageEvent {\r\n logger.cLog('received event ', e.data);\r\n return e;\r\n }\r\n\r\n reconcile(e: MessageEvent): MessageEvent {\r\n this.awaitingAck.forEach((message: Message, i, arr) => {\r\n if (message.expectedResponse === e.data) {\r\n logger.cLog('Reconciled message', message.sent);\r\n arr.splice(i, 1);\r\n }\r\n return e;\r\n });\r\n return e;\r\n }\r\n\r\n transform(e: MessageEvent): IMessageEvent {\r\n const messageEvent: IMessageEvent = {\r\n name: 'noop',\r\n data: null,\r\n type: null,\r\n };\r\n\r\n // Game message event\r\n let { name, data, type } = transformGameEvent(e);\r\n\r\n if (name === null) {\r\n // Ad message event\r\n ({ name, data, type } = transformAdEvent(e));\r\n }\r\n\r\n if (typeof name === 'string') {\r\n messageEvent.name = name;\r\n messageEvent.data = data;\r\n messageEvent.type = type;\r\n }\r\n\r\n return messageEvent;\r\n }\r\n\r\n isReceivableEvent(e: IMessageEvent) {\r\n if (e.name !== 'noop') {\r\n logger.cLog('Received event ', e);\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n}\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport { Utilities } from '../_utils';\r\n\r\nexport interface ILoadingIndicators {\r\n removeLoader: () => void;\r\n showLoader: (bgColor?: [number, number, number, number]) => void;\r\n}\r\n\r\nexport class LoadingIndicators implements ILoadingIndicators {\r\n loadingIndicatorId = 'loading-indicator';\r\n\r\n activeLoader = false;\r\n\r\n constructor() { }\r\n\r\n public removeLoader() {\r\n const loadingIndicatorEl: HTMLElement = document.querySelector(`#${this.loadingIndicatorId}`);\r\n if (loadingIndicatorEl) {\r\n loadingIndicatorEl.style.display = 'none';\r\n Utilities.removeNode([loadingIndicatorEl]);\r\n }\r\n this.activeLoader = false;\r\n }\r\n\r\n public showLoader(bgColor?: [number, number, number, number]) {\r\n if (this.activeLoader) return;\r\n const loader = document.createElement('div');\r\n loader.setAttribute('id', this.loadingIndicatorId);\r\n\r\n let style = 'position:absolute;top:0;left:0;height:100%;width:100%;z-index:99999999;';\r\n const bgStyle = [0, 0, 0, 1].map((colorVal, index) => { // default black/opaque\r\n if (bgColor) {\r\n if (index < (bgColor.length - 1)) { // rgb color value\r\n if (typeof bgColor[index] === 'number' && bgColor[index] >= 0 && bgColor[index] <= 255) {\r\n return bgColor[index];\r\n }\r\n } else if (bgColor[index] >= 0 && bgColor[index] <= 1) {\r\n return bgColor[index];\r\n }\r\n }\r\n return colorVal; // default\r\n });\r\n style += `background:rgba(${bgStyle.join()});`;\r\n loader.setAttribute('style', style);\r\n\r\n loader.innerHTML = `\r\n <div class=\"lds-grid\">\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n </div>`;\r\n\r\n const styles = document.createElement('style');\r\n styles.innerHTML = `\r\n .lds-grid {\r\n z-index: 10100;\r\n position:absolute;\r\n left: calc(50%);\r\n top: calc(50% - 32px);\r\n -webkit-transform: translateX(-50%);\r\n transform: translateX(-50%);\r\n width: 64px;\r\n height: 64px;\r\n }\r\n .lds-grid div {\r\n position: absolute;\r\n width: 13px;\r\n height: 13px;\r\n border-radius: 50%;\r\n background: #fff;\r\n animation: lds-grid 1.2s linear infinite;\r\n }\r\n .lds-grid div:nth-child(1) {\r\n top: 6px;\r\n left: 6px;\r\n animation-delay: 0s;\r\n }\r\n .lds-grid div:nth-child(2) {\r\n top: 6px;\r\n left: 26px;\r\n animation-delay: -0.4s;\r\n }\r\n .lds-grid div:nth-child(3) {\r\n top: 6px;\r\n left: 45px;\r\n animation-delay: -0.8s;\r\n }\r\n .lds-grid div:nth-child(4) {\r\n top: 26px;\r\n left: 6px;\r\n animation-delay: -0.4s;\r\n }\r\n .lds-grid div:nth-child(5) {\r\n top: 26px;\r\n left: 26px;\r\n animation-delay: -0.8s;\r\n }\r\n .lds-grid div:nth-child(6) {\r\n top: 26px;\r\n left: 45px;\r\n animation-delay: -1.2s;\r\n }\r\n .lds-grid div:nth-child(7) {\r\n top: 45px;\r\n left: 6px;\r\n animation-delay: -0.8s;\r\n }\r\n .lds-grid div:nth-child(8) {\r\n top: 45px;\r\n left: 26px;\r\n animation-delay: -1.2s;\r\n }\r\n .lds-grid div:nth-child(9) {\r\n top: 45px;\r\n left: 45px;\r\n animation-delay: -1.6s;\r\n }\r\n @keyframes lds-grid {\r\n 0%, 100% {\r\n opacity: 1;\r\n }\r\n 50% {\r\n opacity: 0.5;\r\n }\r\n }\r\n `;\r\n\r\n const loaderElement = Utilities.prependNode(document.querySelector('#adContainer'), loader);\r\n Utilities.prependNode(loaderElement, styles);\r\n\r\n this.activeLoader = true;\r\n }\r\n}\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n from,\r\n fromEvent,\r\n mergeMap,\r\n Subject,\r\n Subscription,\r\n} from 'rxjs';\r\n\r\n// import dependencyManager from '../_services/dependency-manager';\r\nimport { IEventManager, IMessageEvent } from '../_services/event-manager';\r\n\r\nimport { IVideoPlayback } from '../_types/interfaces/ads';\r\nimport {\r\n AdEventNames,\r\n AdPlacementType,\r\n EventTypes,\r\n TelemetryEventNames,\r\n} from '../_types/enums';\r\n\r\nimport { telemetry, Utilities } from '../_utils';\r\n\r\nexport default class PlaceholderVideo implements IVideoPlayback {\r\n private eventHubSubscription: Subscription;\r\n\r\n private telemetryProperties = {\r\n adPlacementType: null,\r\n adSessionID: null, // Unique session identifier for play/ad session\r\n prevEvent: null,\r\n placementId: null,\r\n vendor: 'mcg_placeholder',\r\n videoDuration: null,\r\n videoUrl: __ENV__.vendors.placeholderVideo.videoUrl,\r\n videoEvent: null,\r\n };\r\n\r\n private videoElement: HTMLVideoElement;\r\n\r\n private videoElementSubscription;\r\n\r\n private videoElementPlayStarted = false;\r\n\r\n private videoElementPauseTimeout: NodeJS.Timeout;\r\n\r\n private videoElementRetryPlayTimeout: NodeJS.Timeout;\r\n\r\n public eventHub: Subject<IMessageEvent> = new Subject();\r\n\r\n public set enableTestAd(testFlag: boolean) {\r\n // stub\r\n }\r\n\r\n public set locale(locale: string) {\r\n // stub\r\n }\r\n\r\n public set mcgId(mcgId: string) {\r\n // stub\r\n }\r\n\r\n public showPrerollClickToPlay = true;\r\n\r\n public vendorID = 'mcg_placeholder';\r\n\r\n constructor() { }\r\n\r\n /** PUBLIC METHODS -- AD SETUP AND TEARDOWN */\r\n\r\n public playAd(preroll: boolean): Promise<boolean> {\r\n this.telemetryProperties.adPlacementType = preroll ? AdPlacementType.preroll : AdPlacementType.interstitial;\r\n const adContainer = this.createAdContainer();\r\n if (!(adContainer instanceof HTMLElement)) {\r\n return Promise.reject(new Error('Couldn\\'t create ad container #adDiv'));\r\n }\r\n\r\n return this.requestAds()\r\n .then(() => true) // Success\r\n .catch((err: Error) => {\r\n const properties = {\r\n ...this.telemetryProperties,\r\n info: err.message,\r\n };\r\n telemetry.trackError({ name: TelemetryEventNames.VA_NVA }, properties);\r\n this.eventHub.next({ name: AdEventNames.adPlaybackError, data: {}, type: EventTypes.adEvent });\r\n return false; // Error playing the ad\r\n });\r\n }\r\n\r\n public cleanup(): void {\r\n telemetry.flushEvent();\r\n\r\n this.eventHubSubscription.unsubscribe();\r\n this.eventHubSubscription = null;\r\n this.videoElementSubscription.unsubscribe();\r\n this.videoElementSubscription = null;\r\n clearTimeout(this.videoElementPauseTimeout);\r\n this.videoElementPauseTimeout = null;\r\n clearTimeout(this.videoElementRetryPlayTimeout);\r\n this.videoElementRetryPlayTimeout = null;\r\n\r\n Object.keys(this.telemetryProperties).filter((key) => key !== 'vendor').forEach((key) => {\r\n this.telemetryProperties[key] = null;\r\n });\r\n\r\n const nodes = [\r\n document.querySelector('#adDiv'),\r\n document.querySelector('#displayBase'),\r\n document.querySelector('#videoPlayer'),\r\n ];\r\n\r\n // Remove all non-zone image/iframe/script nodes that have been written into the page\r\n // @xxx - fix this, current version removes masque games from the page during interstitial ads\r\n // document.querySelectorAll('iframe, img, script').forEach((element: HTMLIFrameElement|HTMLImageElement|HTMLScriptElement) => {\r\n // if (element.src) {\r\n // const { host } = new URL(element.src);\r\n // if (host !== window.location.host && !host.endsWith('zone.msn.com')) {\r\n // nodes.push(element);\r\n // }\r\n // } else {\r\n // nodes.push(element);\r\n // }\r\n // });\r\n\r\n Utilities.removeNode(\r\n nodes.filter((node) => node != null),\r\n );\r\n }\r\n\r\n /** PRIVATE METHODS -- AD CONFIGURATION */\r\n\r\n private createAdContainer(): HTMLDivElement {\r\n const adContainer = document.createElement('div');\r\n adContainer.setAttribute('id', 'adDiv');\r\n adContainer.setAttribute('class', 'ad-player-container');\r\n\r\n const displayBase = document.createElement('div');\r\n displayBase.setAttribute('id', 'displayBase');\r\n displayBase.setAttribute('style', 'width:100%; height:100%;');\r\n displayBase.setAttribute('data-setup', '{}');\r\n\r\n this.videoElement = document.createElement('video');\r\n this.videoElement.setAttribute('id', 'videoPlayer');\r\n this.videoElement.setAttribute('style', 'background:#000000;width:100%;height:100%;');\r\n this.videoElement.setAttribute('autoplay', 'true');\r\n this.videoElement.setAttribute('muted', 'true');\r\n this.videoElement.setAttribute('playsinline', '');\r\n this.videoElement.setAttribute('src', __ENV__.vendors.placeholderVideo.videoUrl);\r\n\r\n Utilities.appendNode(displayBase, this.videoElement);\r\n Utilities.appendNode(adContainer, displayBase);\r\n\r\n Utilities.appendNode(document.querySelector('#adContainer'), adContainer);\r\n return adContainer;\r\n }\r\n\r\n private requestAds(): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n this.videoElementSubscription = from(['canplaythrough', 'ended', 'error', 'pause', 'play'])\r\n .pipe(\r\n mergeMap((event) => fromEvent(this.videoElement, event)),\r\n )\r\n .subscribe((event) => {\r\n this.handleAdEvent(event);\r\n });\r\n\r\n this.telemetryProperties.adSessionID = (Date.now() * 1000) + Math.round(Math.random() * 1000);\r\n\r\n this.eventHubSubscription = this.eventHub.subscribe((event: IMessageEvent) => {\r\n switch (event.name) {\r\n case AdEventNames.adComplete:\r\n resolve();\r\n break;\r\n case AdEventNames.adPlaybackError:\r\n reject();\r\n break;\r\n default:\r\n break;\r\n }\r\n });\r\n } catch (err) {\r\n reject(new Error(err));\r\n }\r\n });\r\n }\r\n\r\n /** EVENT HANDLING */\r\n\r\n private handleAdEvent(event: Event): void {\r\n const properties = this.telemetryProperties;\r\n properties.videoEvent = event.type;\r\n switch (event.type) {\r\n case 'error': {\r\n const errorProperties = {\r\n ...properties,\r\n // errorCode: adError?.code,\r\n // errorInfo: adError?.exception,\r\n // errorMessage: adError?.errMessage,\r\n };\r\n telemetry.trackError({ name: TelemetryEventNames.VA_E }, errorProperties);\r\n this.eventHub.next({ name: AdEventNames.adPlaybackError, data: {}, type: EventTypes.adEvent });\r\n\r\n break;\r\n }\r\n case 'canplaythrough':\r\n telemetry.trackEvent({ name: TelemetryEventNames.VA_AI }, properties);\r\n if (this.videoElement.paused || !this.videoElementPlayStarted) {\r\n const videoElementPlay = this.videoElement.play();\r\n if (videoElementPlay !== undefined) {\r\n videoElementPlay.catch((error) => {\r\n const errorMessage = new Error(error).message;\r\n telemetry.trackError(\r\n { name: TelemetryEventNames.VA_E },\r\n {\r\n ...properties,\r\n errorMessage,\r\n },\r\n );\r\n });\r\n }\r\n }\r\n break;\r\n\r\n case 'play':\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_FiQS }, properties);\r\n this.videoElementPlayStarted = true;\r\n this.eventHub.next({\r\n name: AdEventNames.adImpressionStart,\r\n data: { duration: 0 }, // leave this hard-coded so we don't trigger quartile split timeout\r\n type: EventTypes.adEvent,\r\n });\r\n break;\r\n\r\n case 'pause':\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_PA }, properties);\r\n this.videoElementRetryPlayTimeout = setTimeout(() => {\r\n const videoElementPlay = this.videoElement.play();\r\n if (videoElementPlay !== undefined) {\r\n videoElementPlay\r\n .then(() => {\r\n clearTimeout(this.videoElementPauseTimeout);\r\n this.videoElementPauseTimeout = null;\r\n })\r\n .catch((error) => {\r\n const errorMessage = new Error(error).message;\r\n telemetry.trackError(\r\n { name: TelemetryEventNames.VA_E },\r\n {\r\n ...properties,\r\n errorMessage,\r\n },\r\n );\r\n });\r\n }\r\n }, 1000);\r\n this.videoElementPauseTimeout = setTimeout(() => {\r\n telemetry.trackError(\r\n { name: TelemetryEventNames.VA_E },\r\n {\r\n ...properties,\r\n errorMessage: 'pause timeout',\r\n },\r\n );\r\n this.eventHub.next({ name: AdEventNames.adPlaybackError, data: {}, type: EventTypes.adEvent });\r\n }, 3000);\r\n break;\r\n\r\n case 'ended':\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_FoQC }, properties);\r\n this.eventHub.next({ name: AdEventNames.adComplete, data: {}, type: EventTypes.adEvent });\r\n break;\r\n\r\n default:\r\n telemetry.trackEvent({ name: TelemetryEventNames.VAI_O }, properties);\r\n break;\r\n }\r\n\r\n this.telemetryProperties.prevEvent = event.type;\r\n }\r\n}\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport { AdManager, IAdManager } from './ad-manager';\r\nimport { EventManager, IEventManager } from './event-manager';\r\nimport { GameManager, IGameManager } from './game-manager';\r\nimport { LoadingIndicators, ILoadingIndicators } from './loading-indicators';\r\nimport { IVideoPlayback } from '../_types/interfaces/ads';\r\nimport PlaceholderVideo from '../_vendor/placeholderVideo';\r\nimport Xandr from '../_vendor/xandr';\r\n\r\nexport interface IDependencyManager {\r\n adManager: IAdManager;\r\n eventManager: IEventManager;\r\n gameManager: IGameManager;\r\n loadingIndicators: ILoadingIndicators;\r\n placeholderVideo: IVideoPlayback;\r\n xandr: IVideoPlayback;\r\n}\r\n\r\nclass DependencyManager {\r\n _adManager: IAdManager | null = null;\r\n\r\n _eventManager: IEventManager | null = null;\r\n\r\n _gameManager: IGameManager | null = null;\r\n\r\n _loadingIndicators: LoadingIndicators | null = null;\r\n\r\n _placeholderVideo: IVideoPlayback | null = null;\r\n\r\n _xandr: IVideoPlayback | null = null;\r\n\r\n constructor() { }\r\n\r\n get adManager(): IAdManager {\r\n if (!this._adManager) {\r\n this._adManager = new AdManager();\r\n }\r\n return this._adManager;\r\n }\r\n\r\n get eventManager(): IEventManager {\r\n if (!this._eventManager) {\r\n this._eventManager = new EventManager();\r\n }\r\n return this._eventManager;\r\n }\r\n\r\n get gameManager(): IGameManager {\r\n if (!this._gameManager) {\r\n this._gameManager = new GameManager();\r\n }\r\n return this._gameManager;\r\n }\r\n\r\n get loadingIndicators(): LoadingIndicators {\r\n if (!this._loadingIndicators) {\r\n this._loadingIndicators = new LoadingIndicators();\r\n }\r\n return this._loadingIndicators;\r\n }\r\n\r\n get placeholderVideo(): IVideoPlayback {\r\n if (!this._placeholderVideo) {\r\n this._placeholderVideo = new PlaceholderVideo();\r\n }\r\n return this._placeholderVideo;\r\n }\r\n\r\n get xandr(): IVideoPlayback {\r\n if (!this._xandr) {\r\n this._xandr = new Xandr();\r\n }\r\n return this._xandr;\r\n }\r\n}\r\n\r\nexport default new DependencyManager();\r\n","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport './wgp-app.scss';\r\n\r\nimport * as Handlebars from 'handlebars/dist/handlebars';\r\n\r\nimport dependencyManager from './_services/dependency-manager';\r\nimport { IAdManager } from './_services/ad-manager';\r\nimport { IEventManager, IMessageEvent } from './_services/event-manager';\r\nimport { ILoadingIndicators } from './_services/loading-indicators';\r\n\r\nimport adLoadingTpl from './_templates/ad-loading.tpl';\r\nimport clickToPlayTpl from './_templates/click-to-play.tpl';\r\nimport gameOverTpl from './_templates/game-over.tpl';\r\nimport unsupportedBrowserTpl from './_templates/unsupported-browser.tpl';\r\nimport unsupportedGameTpl from './_templates/unsupported-game.tpl';\r\n\r\nimport {\r\n AdEventNames,\r\n ConsentKeys,\r\n EmittableGameEvents,\r\n GameTypes,\r\n HostingEnvironments,\r\n Locales,\r\n ReceivableGameEvents,\r\n TelemetryEventNames,\r\n} from './_types/enums';\r\nimport { IAdPlaybackResult } from './_types/interfaces/ads';\r\nimport { IPlayerSettings, IAdsConfiguration } from './_types/interfaces/player';\r\n\r\nimport {\r\n logger,\r\n telemetry,\r\n overlay,\r\n Utilities,\r\n} from './_utils';\r\n\r\nexport interface IWebGamePlayer {\r\n loadGamePlayer(): void;\r\n}\r\n\r\nexport default class WebGamePlayer implements IWebGamePlayer {\r\n private adLoadingTemplate: string = adLoadingTpl;\r\n\r\n private animationTimeout = 150;\r\n\r\n private clickToPlayTemplate: string = clickToPlayTpl;\r\n\r\n private prerollAdvertisementTimeoutActive = false;\r\n\r\n private duplicateAdRequestBufferActive = false;\r\n\r\n private duplicateAdRequestBufferLength = 2000;\r\n\r\n private gameFrame: HTMLIFrameElement = document.querySelector('#gameFrame');\r\n\r\n private gameOverTemplate: string = gameOverTpl;\r\n\r\n private settings: IPlayerSettings = { // default values\r\n enableTestAd: null,\r\n interstitialAdInterval: null,\r\n prerollAdInterval: null,\r\n interstitialAdSkipCount: 0,\r\n externalId: '',\r\n gameABTest: null, // @todo: consolidate game configuration settings\r\n gameDisplayName: '',\r\n gameType: GameTypes.firstParty,\r\n gameVersion: 'NA',\r\n hasScore: false,\r\n hostingEnvironment: HostingEnvironments.zone,\r\n language: Locales.enUS,\r\n levels: __ENV__.settings.games.levels,\r\n locale: Locales.enUS,\r\n maxWidth: __ENV__.settings.games.maxWidth,\r\n mcgId: '',\r\n minHeight: __ENV__.settings.games.minHeight,\r\n path: null,\r\n playInterstitial: null,\r\n playPreroll: null,\r\n setLang: false,\r\n support: {\r\n chrome: true,\r\n firefox: true,\r\n safari: true,\r\n opera: true,\r\n edge: true,\r\n internetExplorer: false,\r\n },\r\n consent: {\r\n isConsentRequired: false,\r\n required: true,\r\n advertising: true,\r\n analytics: true,\r\n socialMedia: true,\r\n },\r\n };\r\n\r\n private translations: any = __LANG__[Locales.enUS]; // default\r\n\r\n private unsupportedBrowserTemplate = unsupportedBrowserTpl;\r\n\r\n private unsupportedGameTemplate = unsupportedGameTpl;\r\n\r\n constructor(\r\n playerSettings: {\r\n externalId: string;\r\n title: string;\r\n path: string;\r\n trfSrc?: string;\r\n consent?: string;\r\n [key: string]: string | number | boolean;\r\n },\r\n private adManager: IAdManager = dependencyManager.adManager,\r\n private eventManager: IEventManager = dependencyManager.eventManager,\r\n private loadingIndicators: ILoadingIndicators = dependencyManager.loadingIndicators,\r\n ) {\r\n Utilities.initalizeDeveloperMode();\r\n\r\n // Merge config settings\r\n this.mergeSettings(playerSettings);\r\n\r\n const adsConfiguration: IAdsConfiguration = __ENV__.settings.ads.find(\r\n (config) => config.hostingEnvironment === this.settings.hostingEnvironment,\r\n );\r\n\r\n // Player settings\r\n this.setAdPlayerDependencies(adsConfiguration);\r\n this.initializeAdSkipCountLocalStorage(adsConfiguration);\r\n\r\n if (Object.keys(__LANG__).includes(this.settings.locale)) {\r\n this.translations = __LANG__[this.settings.locale];\r\n }\r\n if (Object.keys(__ENV__.settings.games.languageMap).includes(this.settings.locale)) {\r\n this.settings.language = __ENV__.settings.games.languageMap[this.settings.locale];\r\n } else {\r\n this.settings.language = this.settings.locale;\r\n }\r\n\r\n // Telemetry\r\n telemetry.gameID = playerSettings.externalId;\r\n telemetry.gameType = this.settings.gameType;\r\n telemetry.gameVersion = this.settings.gameVersion;\r\n telemetry.hostingEnvironment = this.settings.hostingEnvironment;\r\n telemetry.locale = this.settings.locale;\r\n if (playerSettings.trfSrc && (typeof playerSettings.trfSrc === 'string')) {\r\n telemetry.trafficSrc = decodeURIComponent(playerSettings.trfSrc);\r\n }\r\n telemetry.trackPageView();\r\n telemetry.trackEvent({ name: TelemetryEventNames.HPL });\r\n\r\n // App logic\r\n eventManager.windowEvents.subscribe((event: IMessageEvent) => {\r\n switch (event.name) {\r\n // Ready For Comm\r\n case ReceivableGameEvents.readyForComm:\r\n telemetry.trackEvent({ name: TelemetryEventNames.GDK_RC });\r\n\r\n // this has to happen for some games to emit level complete events\r\n eventManager.send(\r\n this.gameFrame,\r\n EmittableGameEvents.adLevels,\r\n `: ${this.settings.levels}`, // we have to pass this separately from the event, as it's dynamic\r\n );\r\n eventManager.send(\r\n this.gameFrame,\r\n EmittableGameEvents.adInterval,\r\n `: ${this.settings.interstitialAdInterval}`, // we have to pass this separately from the event, as it's dynamic\r\n );\r\n break;\r\n // Level Complete\r\n case ReceivableGameEvents.completedLevel:\r\n telemetry.trackEvent({ name: TelemetryEventNames.GDK_CL }); // We need to track this for 3rd-party game plays\r\n break;\r\n // Start Ad Playback\r\n case ReceivableGameEvents.startAdPlayback:\r\n telemetry.trackEvent({ name: TelemetryEventNames.GDK_SAP });\r\n this.playInterstitialAd();\r\n break;\r\n // Game Ended / Quit\r\n case ReceivableGameEvents.gameEnded:\r\n case ReceivableGameEvents.gameQuit:\r\n telemetry.trackEvent({ name: TelemetryEventNames.GDK_GEQ });\r\n // tslint:disable-next-line:no-boolean-literal-compare\r\n if (this.settings.hasScore !== true) {\r\n this.reloadGame();\r\n }\r\n break;\r\n // Game Score\r\n case ReceivableGameEvents.gameScore:\r\n telemetry.trackEvent({ name: TelemetryEventNames.GDK_SR });\r\n this.reloadGame(event.data);\r\n // tslint:disable-next-line:no-boolean-literal-compare\r\n if (this.settings.hasScore !== true) {\r\n logger.cError(\r\n // eslint-disable-next-line max-len\r\n `Unexpected value for this.settings.hasScore: ${this.settings.hasScore}. This may cause issues with game over/game restart`,\r\n );\r\n }\r\n break;\r\n default: break;\r\n }\r\n });\r\n }\r\n\r\n private initializeAdSkipCountLocalStorage(hostingEnvironment: IAdsConfiguration): void {\r\n if (hostingEnvironment.interstitialAdSkipCount) {\r\n if (Utilities.clientHasLocalStorage()) {\r\n const interstitialAdSkipCountString = localStorage.getItem('interstitialAdSkipCount');\r\n const interstitialAdSkipCountOriginalString = localStorage.getItem('interstitialAdSkipCountOriginal');\r\n\r\n if (interstitialAdSkipCountString && interstitialAdSkipCountOriginalString) {\r\n const interstitialAdSkipCount = parseInt(interstitialAdSkipCountString, 10);\r\n const interstitialAdSkipCountOriginal = parseInt(interstitialAdSkipCountOriginalString, 10);\r\n\r\n if (\r\n hostingEnvironment.interstitialAdSkipCount === interstitialAdSkipCountOriginal\r\n && interstitialAdSkipCount <= hostingEnvironment.interstitialAdSkipCount // Catch user modified localstorage\r\n ) {\r\n // If the original ad skip ammount hasn't changed we continue using the local storage value;\r\n this.settings.interstitialAdSkipCount = interstitialAdSkipCount;\r\n } else {\r\n // If the original ad skip ammount has changed we reset the localstorage value as new settings have arrived.\r\n localStorage.setItem('interstitialAdSkipCount', hostingEnvironment.interstitialAdSkipCount.toString());\r\n localStorage.setItem('interstitialAdSkipCountOriginal', hostingEnvironment.interstitialAdSkipCount.toString());\r\n\r\n this.settings.interstitialAdSkipCount = hostingEnvironment.interstitialAdSkipCount;\r\n }\r\n } else {\r\n localStorage.setItem('interstitialAdSkipCount', hostingEnvironment.interstitialAdSkipCount.toString());\r\n localStorage.setItem('interstitialAdSkipCountOriginal', hostingEnvironment.interstitialAdSkipCount.toString());\r\n\r\n this.settings.interstitialAdSkipCount = hostingEnvironment.interstitialAdSkipCount;\r\n }\r\n } else {\r\n telemetry.trackError({ name: TelemetryEventNames.LS_UE });\r\n this.settings.interstitialAdSkipCount = hostingEnvironment.interstitialAdSkipCount;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Initial game player load\r\n */\r\n public loadGamePlayer(): void {\r\n if (!this.gameFrame) {\r\n throw new Error('Game HTML not found!');\r\n }\r\n\r\n const browserName = Utilities.getBrowserName();\r\n const browserPrimaryVersionNumber = parseInt(Utilities.getBrowserPrimaryVersion(), 10);\r\n if (Utilities.isBrowserInternetExplorer() && (browserPrimaryVersionNumber < 11)) {\r\n this.showUnsupportedBrowser(browserName, browserPrimaryVersionNumber.toString());\r\n } else if (\r\n (Utilities.isBrowserChrome() && !this.settings.support.chrome)\r\n || (Utilities.isBrowserFirefox() && !this.settings.support.firefox)\r\n || (Utilities.isBrowserSafari() && !this.settings.support.safari)\r\n || (Utilities.isBrowserEdge() && !this.settings.support.edge)\r\n || (Utilities.isBrowserInternetExplorer() && !this.settings.support.internetExplorer)\r\n ) {\r\n this.showUnsupportedGame(this.settings.gameDisplayName, browserName);\r\n } else if (this.settings.playPreroll && !this.settings.consent.isConsentRequired) {\r\n if (this.adManager.showPrerollClickToPlay) {\r\n this.showClickToPlay()\r\n .then(() => this.playPrerollAd())\r\n .finally(() => {\r\n this.loadGame();\r\n });\r\n } else {\r\n this.playPrerollAd()\r\n .finally(() => {\r\n this.loadGame();\r\n });\r\n }\r\n } else {\r\n if (this.settings.consent.isConsentRequired) {\r\n logger.cLog('Consent is required, skipping preroll advertisement.');\r\n } else {\r\n // log skip of scheduled ad play\r\n telemetry.trackEvent({ name: TelemetryEventNames.VA_RPD });\r\n }\r\n\r\n if (this.adManager.showPrerollClickToPlay) {\r\n this.showClickToPlay()\r\n .then(() => {\r\n this.loadGame();\r\n });\r\n } else {\r\n this.loadGame();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Reload current game\r\n * Used for games that don't have their own notion of levels or ongoing play\r\n */\r\n private reloadGame(score?: string | object): void {\r\n const gameScore = typeof score === 'string' ? score : '0';\r\n this.hideGame();\r\n this.showGameOver(gameScore)\r\n .then(() => this.playReloadGamePrerollAd())\r\n .finally(() => this.loadGame(true));\r\n }\r\n\r\n playReloadGamePrerollAd(): Promise<IAdPlaybackResult | Error> {\r\n if (this.settings.playInterstitial && !this.prerollAdvertisementTimeoutActive && !this.settings.consent.isConsentRequired) {\r\n if (this.settings.interstitialAdSkipCount > 0 && !this.duplicateAdRequestBufferActive) {\r\n this.setPrerollAdvertisementTimeout();\r\n this.settings.interstitialAdSkipCount -= 1;\r\n localStorage.setItem('interstitialAdSkipCount', this.settings.interstitialAdSkipCount.toString());\r\n logger.cLog(`Skipping Reload Preroll Ad. Skips Remaining: ${this.settings.interstitialAdSkipCount}`);\r\n\r\n this.eventManager.send(this.gameFrame, EmittableGameEvents.adPlaybackCompleted); // Let game know interstitial ad is done\r\n return Promise.resolve(<IAdPlaybackResult>{ success: true });\r\n }\r\n\r\n this.loadingIndicators.showLoader();\r\n this.showAdPlayingText(true);\r\n return this.playPrerollAd();\r\n }\r\n\r\n if (this.settings.playInterstitial) {\r\n const logMsg = this.settings.consent.isConsentRequired\r\n ? 'Consent is required, skipping preroll advertisement.'\r\n : 'Preroll advertisement timeout is still active';\r\n logger.cLog(logMsg);\r\n } else {\r\n // log skip of scheduled ad play\r\n telemetry.trackEvent({ name: TelemetryEventNames.VA_RPD });\r\n }\r\n this.eventManager.send(this.gameFrame, EmittableGameEvents.adPlaybackCompleted); // Let game know interstitial ad is done\r\n return Promise.resolve(<IAdPlaybackResult>{ success: true });\r\n }\r\n\r\n setPrerollAdvertisementTimeout() {\r\n if (!this.prerollAdvertisementTimeoutActive && this.settings.prerollAdInterval > 0) {\r\n this.prerollAdvertisementTimeoutActive = true;\r\n setTimeout(() => { this.prerollAdvertisementTimeoutActive = false; }, this.settings.prerollAdInterval);\r\n }\r\n }\r\n\r\n /**\r\n * Game frame load\r\n */\r\n private loadGame(reload?: boolean): void {\r\n if (!reload) { // initial load, so set styles\r\n if (this.settings.maxWidth > 0) {\r\n this.gameFrame.style.maxWidth = `${this.settings.maxWidth}px`;\r\n }\r\n if (this.settings.minHeight > 0) {\r\n this.gameFrame.style.minHeight = `${this.settings.minHeight}px`;\r\n }\r\n }\r\n\r\n // @todo: find a more efficient way to do this\r\n let gamePath = this.settings.path;\r\n if (this.settings.setLang && this.settings.language) {\r\n const queryStart = gamePath.includes('?') ? '&' : '?';\r\n gamePath += `${queryStart}locale=${this.settings.language}`;\r\n }\r\n if (this.settings.gameABTest) {\r\n const queryStart = gamePath.includes('?') ? '&' : '?';\r\n gamePath += `${queryStart}abtest=${this.settings.gameABTest}`;\r\n }\r\n\r\n (this.gameFrame).src = gamePath;\r\n\r\n this.showGame();\r\n this.loadingIndicators.removeLoader();\r\n }\r\n\r\n private playPrerollAd(): Promise<IAdPlaybackResult | Error> {\r\n this.showAdPlayingText(true);\r\n this.loadingIndicators.showLoader();\r\n\r\n const adStartSubscription = this.adManager.adEvents([\r\n AdEventNames.adImpressionStart,\r\n AdEventNames.adPlaybackError,\r\n ]).subscribe(() => {\r\n // Remove loading indicator once ad is ready to play\r\n this.loadingIndicators.removeLoader();\r\n });\r\n\r\n return this.adManager.playPrerollAd()\r\n .catch(() => <IAdPlaybackResult> {\r\n success: false,\r\n })\r\n .finally(() => {\r\n this.setPrerollAdvertisementTimeout();\r\n this.removeAdPlayingText();\r\n adStartSubscription.unsubscribe();\r\n });\r\n }\r\n\r\n private playInterstitialAd(): Promise<IAdPlaybackResult> {\r\n if (!this.settings.playInterstitial || this.settings.consent.isConsentRequired) {\r\n if (this.settings.consent.isConsentRequired) {\r\n logger.cLog('Consent is required, skipping interstitial advertisement.');\r\n } else {\r\n // log skip of scheduled ad play\r\n telemetry.trackEvent({ name: TelemetryEventNames.VA_RID });\r\n }\r\n this.eventManager.send(this.gameFrame, EmittableGameEvents.adPlaybackCompleted);\r\n return Promise.resolve(<IAdPlaybackResult>{ success: true });\r\n }\r\n if (this.duplicateAdRequestBufferActive) { // This catches duplicate calls that drains adSkipsCount.\r\n logger.cLog(`Multiple Interstitial Ads Requested Within ${this.duplicateAdRequestBufferLength / 1000} Second(s) Limit`);\r\n return Promise.resolve(<IAdPlaybackResult>{ success: true });\r\n }\r\n if (this.settings.interstitialAdSkipCount > 0) {\r\n this.settings.interstitialAdSkipCount -= 1;\r\n localStorage.setItem('interstitialAdSkipCount', this.settings.interstitialAdSkipCount.toString());\r\n logger.cLog(`Skipping Interstitial Ad. Skips Remaining: ${this.settings.interstitialAdSkipCount}`);\r\n\r\n this.duplicateAdRequestBufferActive = true;\r\n setTimeout(() => { this.duplicateAdRequestBufferActive = false; }, this.duplicateAdRequestBufferLength);\r\n\r\n this.eventManager.send(this.gameFrame, EmittableGameEvents.adPlaybackCompleted); // Let game know interstitial ad is done\r\n return Promise.resolve(<IAdPlaybackResult>{ success: true });\r\n }\r\n\r\n this.loadingIndicators.showLoader();\r\n this.showAdPlayingText(false);\r\n this.hideGame();\r\n\r\n const adStartSubscription = this.adManager.adEvents([\r\n AdEventNames.adImpressionStart,\r\n AdEventNames.adPlaybackError,\r\n ]).subscribe(() => {\r\n // Remove loading indicator once ad is ready to play\r\n this.loadingIndicators.removeLoader();\r\n });\r\n\r\n return this.adManager.playInterstitialAd()\r\n .then((res: IAdPlaybackResult) => res)\r\n .catch(() => <IAdPlaybackResult> {\r\n success: false,\r\n })\r\n .finally(() => {\r\n if (!this.adManager.isAdPlaying) {\r\n this.eventManager.send(this.gameFrame, EmittableGameEvents.adPlaybackCompleted); // Let game know interstitial ad is done\r\n this.removeAdPlayingText();\r\n this.showGame();\r\n this.loadingIndicators.removeLoader();\r\n }\r\n adStartSubscription.unsubscribe();\r\n });\r\n }\r\n\r\n private showClickToPlay(): Promise<any> {\r\n const template = Handlebars.compile(this.clickToPlayTemplate);\r\n const htmlOut = template({\r\n c2p_title: this.settings.gameDisplayName,\r\n c2p_click: (!this.settings.gameDisplayName) ? this.translations.c2p_click : '',\r\n c2p_btn: this.translations.c2p_btn,\r\n });\r\n return overlay.showOverlay(\r\n htmlOut,\r\n '#gameContainer',\r\n '#btnPlayAgain',\r\n 'clickToPlay',\r\n )\r\n .catch((err: Error) => {\r\n logger.cError(err.message);\r\n });\r\n }\r\n\r\n private showGameOver(score?: string): Promise<any> {\r\n const template = Handlebars.compile(this.gameOverTemplate);\r\n const htmlOut = template({\r\n score,\r\n game_over_score: this.translations.game_over_score,\r\n game_over_enjoyed: this.translations.game_over_enjoyed,\r\n game_over_btn: this.translations.game_over_btn,\r\n\r\n });\r\n return overlay.showOverlay(\r\n htmlOut,\r\n '#gameContainer',\r\n '#btnPlayAgain',\r\n 'gameOver',\r\n )\r\n .catch((err: Error) => {\r\n logger.cError(err.message);\r\n });\r\n }\r\n\r\n private showUnsupportedBrowser(browserName: string, browserVersion: string): Promise<any> {\r\n const template = Handlebars.compile(this.unsupportedBrowserTemplate);\r\n const htmlOut = template({\r\n unsupported_browser_title: this.translations.unsupported_browser_title,\r\n unsupported_browser_1: this.translations.unsupported_browser_1,\r\n browserName,\r\n unsupported_browser_2: this.translations.unsupported_browser_2,\r\n browserVersion,\r\n unsupported_browser_3: this.translations.unsupported_browser_3,\r\n unsupported_browser_4: this.translations.unsupported_browser_4,\r\n });\r\n return overlay.showOverlay(\r\n htmlOut,\r\n '#gameContainer',\r\n null,\r\n 'unsupportedBrowser',\r\n )\r\n .catch((err: Error) => {\r\n logger.cError(err.message);\r\n });\r\n }\r\n\r\n private showUnsupportedGame(gameName: string, browserName: string): Promise<any> {\r\n const template = Handlebars.compile(this.unsupportedGameTemplate);\r\n const htmlOut = template({\r\n unsupported_game_title: this.translations.unsupported_game_title,\r\n unsupported_game_1: this.translations.unsupported_game_1,\r\n gameName,\r\n unsupported_game_2: this.translations.unsupported_game_2,\r\n browserName,\r\n unsupported_game_3: this.translations.unsupported_game_3,\r\n unsupported_game_4: this.translations.unsupported_game_4,\r\n });\r\n return overlay.showOverlay(\r\n htmlOut,\r\n '#gameContainer',\r\n null,\r\n 'unsupportedGame',\r\n )\r\n .catch((err: Error) => {\r\n logger.cError(err.message);\r\n });\r\n }\r\n\r\n private showAdPlayingText(isPreroll: boolean): Promise<any> {\r\n const template = Handlebars.compile(this.adLoadingTemplate);\r\n const htmlOut = template({\r\n isPreroll,\r\n ad_player_begin: this.translations.ad_player_begin,\r\n ad_player_continue: this.translations.ad_player_continue,\r\n });\r\n return overlay.showOverlay(\r\n htmlOut,\r\n '#fullContainer',\r\n null,\r\n 'adPlayingText',\r\n 'afterbegin',\r\n )\r\n .catch((err: Error) => {\r\n logger.cError(err.message);\r\n });\r\n }\r\n\r\n private removeAdPlayingText(): void {\r\n const adPlayingNode: HTMLElement = document.querySelector('#adPlayingText');\r\n if (adPlayingNode) {\r\n overlay.hideOverlay(adPlayingNode, 'adPlayingText');\r\n }\r\n }\r\n\r\n private showGame(): void {\r\n Utilities.transition(this.gameFrame, 'fadein', 'visible', this.animationTimeout, 'visibility');\r\n }\r\n\r\n private hideGame(): void {\r\n Utilities.transition(this.gameFrame, 'fadeout', 'hidden', this.animationTimeout, 'visibility');\r\n }\r\n\r\n private mergeSettings(playerSettings: object): void {\r\n const normalizedSettings: any = {}; // TODO: Add type interface\r\n Object.keys(playerSettings).forEach((prop) => {\r\n const propUpperCase = prop.toUpperCase();\r\n switch (propUpperCase) {\r\n case 'ADINTERVAL':\r\n normalizedSettings.INTERSTITIALADINTERVAL = playerSettings[prop];\r\n break;\r\n case 'INTERSTITIAL':\r\n normalizedSettings.PLAYINTERSTITIAL = playerSettings[prop];\r\n break;\r\n case 'PREROLL':\r\n normalizedSettings.PLAYPREROLL = playerSettings[prop];\r\n break;\r\n case 'TITLE':\r\n normalizedSettings.GAMEDISPLAYNAME = playerSettings[prop];\r\n break;\r\n case 'TYPE':\r\n normalizedSettings.GAMETYPE = playerSettings[prop];\r\n break;\r\n case 'VERSION':\r\n normalizedSettings.GAMEVERSION = playerSettings[prop];\r\n break;\r\n default:\r\n normalizedSettings[propUpperCase] = playerSettings[prop];\r\n break;\r\n }\r\n });\r\n\r\n Object.keys(this.settings).forEach((prop) => {\r\n const propUpperCase = prop.toUpperCase();\r\n if (Object.prototype.hasOwnProperty.call(normalizedSettings, propUpperCase)) {\r\n this.settings[prop] = this.validateSettings(prop, normalizedSettings[propUpperCase]);\r\n }\r\n });\r\n }\r\n\r\n private validateSettings(name: string, value: any): any {\r\n let newValue = null;\r\n switch (name) {\r\n case 'interstitialAdInterval':\r\n if (parseInt(value, 10) > 0) {\r\n newValue = value;\r\n }\r\n break;\r\n case 'externalId':\r\n case 'gameABTest':\r\n case 'gameDisplayName':\r\n newValue = value;\r\n break;\r\n case 'gameVersion':\r\n if (/^[\\w.]+$/.test(value)) {\r\n newValue = value;\r\n }\r\n break;\r\n case 'gameType':\r\n if (Object.values(GameTypes).includes(value)) {\r\n newValue = value;\r\n }\r\n break;\r\n case 'enableTestAd':\r\n case 'hasScore':\r\n case 'playInterstitial':\r\n case 'playPreroll':\r\n case 'setLang':\r\n if (typeof value === 'boolean') {\r\n newValue = value;\r\n }\r\n if (typeof value === 'string') {\r\n if (value.toUpperCase() === 'TRUE') {\r\n newValue = true;\r\n }\r\n if (value.toUpperCase() === 'FALSE') {\r\n newValue = false;\r\n }\r\n }\r\n break;\r\n case 'hostingEnvironment':\r\n if (Object.values(HostingEnvironments).includes(value)) {\r\n newValue = value;\r\n }\r\n break;\r\n case 'locale':\r\n if (Object.values(Locales).includes(value)) {\r\n newValue = value;\r\n }\r\n break;\r\n case 'mcgId':\r\n if (typeof value === 'string' && Utilities.validateMcgId(value)) {\r\n newValue = value;\r\n }\r\n break;\r\n case 'path':\r\n if (typeof value === 'string') {\r\n const gamePath = decodeURIComponent(value);\r\n if (this.isGamePathAllowed(gamePath)\r\n || (__ENV__.runtime.dev && !__ENV__.runtime.uat) // allow any path for local build\r\n || Utilities.isDeveloperModeActive()) {\r\n newValue = gamePath;\r\n }\r\n }\r\n break;\r\n case 'consent':\r\n newValue = {};\r\n Object.keys(ConsentKeys).forEach((consentKey) => {\r\n if (typeof value[consentKey] === 'boolean') { newValue[consentKey] = value[consentKey]; }\r\n });\r\n break;\r\n default: break;\r\n }\r\n\r\n return (newValue !== null && typeof newValue !== 'undefined') ? newValue : this.settings[name];\r\n }\r\n\r\n private isGamePathAllowed(gamePath: string): boolean {\r\n try {\r\n const parsedUrl = new URL(gamePath);\r\n return __ENV__.settings.games.validHostDomains\r\n .some((hostName) => {\r\n const rgxp = new RegExp(hostName, 'i');\r\n return rgxp.test(parsedUrl.hostname);\r\n });\r\n } catch (e) {\r\n // ignore invalid gamePath\r\n }\r\n return false;\r\n }\r\n\r\n private setAdPlayerDependencies(adsConfiguration: IAdsConfiguration): void {\r\n if (this.settings.playInterstitial === null) {\r\n this.settings.playInterstitial = adsConfiguration.playInterstitial;\r\n }\r\n if (this.settings.playPreroll === null) {\r\n this.settings.playPreroll = adsConfiguration.playPreroll;\r\n }\r\n if (this.settings.prerollAdInterval === null) {\r\n this.settings.prerollAdInterval = adsConfiguration.prerollAdInterval;\r\n }\r\n if (this.settings.interstitialAdInterval === null) {\r\n this.settings.interstitialAdInterval = adsConfiguration.interstitialAdInterval;\r\n }\r\n\r\n this.adManager.configurePlayers({\r\n ...adsConfiguration,\r\n enableTestAd: this.settings.enableTestAd,\r\n locale: this.settings.locale,\r\n });\r\n }\r\n}\r\n","export default \"{{!-- Copyright (C) Microsoft Corporation. All rights reserved. --}}\\r\\n<div id=\\\"adPlayingText\\\" class=\\\"ad-playing-text\\\" style=\\\"display: none;\\\">\\r\\n {{#if isPreroll}}\\r\\n {{ad_player_begin}}\\r\\n {{else}}\\r\\n {{ad_player_continue}}\\r\\n {{/if}}\\r\\n</div>\\r\\n\";","export default \"{{!-- Copyright (C) Microsoft Corporation. All rights reserved. --}}\\r\\n<div id=\\\"clickToPlay\\\" class=\\\"overlay click-to-play\\\">\\r\\n <div>\\r\\n <hr />\\r\\n <h1>{{c2p_title}}{{c2p_click}}</h1>\\r\\n <button id=\\\"btnPlayAgain\\\" class=\\\"btn btn-click-to-play\\\" type=\\\"button\\\">\\r\\n {{c2p_btn}}\\r\\n </button>\\r\\n <hr />\\r\\n </div>\\r\\n <a id=\\\"noticeLink\\\" class=\\\"notice-link\\\" href=\\\"/notice.html\\\" target=\\\"_blank\\\">Notice</a>\\r\\n</div>\\r\\n\";","export default \"{{!-- Copyright (C) Microsoft Corporation. All rights reserved. --}}\\r\\n<div id=\\\"gameOver\\\" class=\\\"overlay game-over\\\">\\r\\n <div>\\r\\n {{#if score}}\\r\\n <h1>{{game_over_score}} <span id=\\\"gameScore\\\">{{score}}</span></h1>\\r\\n <hr />\\r\\n {{/if}}\\r\\n <h2>{{game_over_enjoyed}}</h2>\\r\\n <button id=\\\"btnPlayAgain\\\" class=\\\"btn btn-play-again\\\" type=\\\"button\\\">\\r\\n {{game_over_btn}}\\r\\n </button>\\r\\n </div>\\r\\n</div>\";","export default \"{{!-- Copyright (C) Microsoft Corporation. All rights reserved. --}}\\r\\n<div id=\\\"unsupportedBrowser\\\" class=\\\"overlay unsupported-browser\\\">\\r\\n <div>\\r\\n <hr />\\r\\n <p>{{unsupported_browser_title}}</p>\\r\\n <p id=\\\"unsupportedBrowserText\\\" class=\\\"not-supported\\\">\\r\\n {{unsupported_browser_1}}{{browserName}}{{unsupported_browser_2}}{{browserVersion}}{{unsupported_browser_3}}\\r\\n <a href=\\\"https://www.microsoft.com/edge\\\" target=\\\"_blank\\\">Microsoft Edge</a>\\r\\n {{unsupported_browser_4}}\\r\\n </p>\\r\\n <hr />\\r\\n </div>\\r\\n <a id=\\\"noticeLink\\\" class=\\\"notice-link\\\" href=\\\"/notice.html\\\" target=\\\"_blank\\\">Notice</a>\\r\\n</div>\\r\\n\";","export default \"{{!-- Copyright (C) Microsoft Corporation. All rights reserved. --}}\\r\\n<div id=\\\"unsupportedGame\\\" class=\\\"overlay unsupported-browser\\\">\\r\\n <div>\\r\\n <hr />\\r\\n <h1>{{unsupported_game_title}}</h1>\\r\\n <p id=\\\"unsupportedGameText\\\" class=\\\"not-supported\\\">\\r\\n {{unsupported_game_1}}{{gameName}}{{unsupported_game_2}}{{browserName}}{{unsupported_game_3}}\\r\\n <a href=\\\"https://www.microsoft.com/edge\\\" target=\\\"_blank\\\">Microsoft Edge</a>\\r\\n {{unsupported_game_4}}\\r\\n </p>\\r\\n <hr />\\r\\n </div>\\r\\n <a id=\\\"noticeLink\\\" class=\\\"notice-link\\\" href=\\\"/notice.html\\\" target=\\\"_blank\\\">Notice</a>\\r\\n</div>\\r\\n\";","// Copyright (C) Microsoft Corporation. All rights reserved.\r\n\r\nimport './styles.scss';\r\nimport wgpApp from './WGP/wgp-app';\r\nimport dependencyManager from './WGP/_services/dependency-manager';\r\nimport { PublicSettings } from './WGP/_types/enums';\r\nimport { logger, telemetry, Utilities } from './WGP/_utils';\r\n\r\nwindow.addEventListener('unhandledrejection', (event) => {\r\n const message = 'Unhandled Promise Rejection';\r\n let error: Error;\r\n\r\n if ((typeof event === 'object') && event.reason && (event.reason instanceof Error)) {\r\n error = event.reason;\r\n } else {\r\n error = new Error(JSON.stringify(event));\r\n }\r\n\r\n window.onerror.apply(this, [message, window.location.href, null, null, error]);\r\n});\r\n\r\n// Get config and then bootstrap the player\r\nfunction getGameConfig(): Promise<any> {\r\n // See if encoded gameInfo was passed to us.\r\n const gameInfoBase64 = Utilities.getUrlSearchParam('gameInfo', ['i']);\r\n if (gameInfoBase64 && gameInfoBase64.length) {\r\n const gameInfo = JSON.parse(Buffer.from(gameInfoBase64, 'base64').toString('ascii'));\r\n if (gameInfo.consent) gameInfo.consent = JSON.parse(gameInfo.consent);\r\n return Promise.resolve(gameInfo);\r\n }\r\n\r\n // See if gamePath was passed to us.\r\n const gamePath = Utilities.getUrlSearchParam('gamePath', ['i']);\r\n if (gamePath && gamePath.length) {\r\n if (__ENV__.gameConfig) { // See if we have gameInfo available locally.\r\n const gameInfo = __ENV__.gameConfig.find((config) => config.externalId === gamePath);\r\n\r\n if (gameInfo) {\r\n return Promise.resolve(gameInfo);\r\n }\r\n } else { // Get config from DB\r\n const uri = `${__ENV__.connections.wgpGames.uri}/${gamePath}?_ts=${Date.now()}`; // cache bust query param\r\n\r\n // Get config\r\n return fetch(uri, {\r\n method: 'GET',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'x-functions-key': `${__ENV__.connections.wgpGames.key}`,\r\n },\r\n mode: 'cors',\r\n }).then((response) => {\r\n if (response.ok) {\r\n return <object>response.json();\r\n }\r\n\r\n throw new Error(`Config fetch failed: ${response.status} -- ${response.statusText} | ${uri}`);\r\n })\r\n .catch((error) => {\r\n throw error;\r\n });\r\n }\r\n }\r\n\r\n return Promise.reject(new Error(`Invalid game path: ${gamePath}`));\r\n}\r\n\r\n// Get config and then bootstrap the player\r\nfunction bootstrapWGP() {\r\n const loadingIndicator = dependencyManager.loadingIndicators;\r\n loadingIndicator.showLoader([128, 128, 128, 0.65]);\r\n\r\n // Allow query params to override config settings for dev/QA\r\n const queryVals = {};\r\n new URLSearchParams(window.location.search).forEach((val, key) => {\r\n if (__ENV__.runtime.dev\r\n || Utilities.isDeveloperModeActive()\r\n || Object.values(PublicSettings).map((validKey) => validKey.toUpperCase() === key.toUpperCase())) {\r\n queryVals[key] = val;\r\n }\r\n });\r\n\r\n getGameConfig().then((gameConfigJson) => {\r\n if (!Utilities.hasUrlSearchParam('healthCheck')) { // don't load player for health check queries\r\n const playerSettings = {\r\n ...gameConfigJson,\r\n ...queryVals,\r\n externalId: gameConfigJson.externalId, // don't allow query override\r\n };\r\n\r\n if (typeof gameConfigJson.setLang === 'boolean') {\r\n playerSettings.setLang = gameConfigJson.setLang; // don't allow query override if `setLang` is specified in the config\r\n }\r\n\r\n // eslint-disable-next-line new-cap\r\n const wgp = new wgpApp(playerSettings);\r\n // Load UI & start player\r\n if (document.readyState === 'loading') { // Loading hasn't finished yet\r\n document.addEventListener('DOMContentLoaded', () => {\r\n wgp.loadGamePlayer();\r\n });\r\n } else { // `DOMContentLoaded` has already fired\r\n wgp.loadGamePlayer();\r\n }\r\n }\r\n })\r\n .catch((error) => {\r\n const formattedError = Utilities.getFormattedError(error);\r\n telemetry.trackError({ name: 'getGameConfig error' }, { error: formattedError.message });\r\n })\r\n .finally(() => {\r\n loadingIndicator.removeLoader();\r\n });\r\n}\r\n\r\ntry {\r\n bootstrapWGP();\r\n} catch (exception) { // clean up any uncaught exceptions deeper in the code\r\n logger.cError(`Uncaught exception: ${exception}`);\r\n throw exception; // browser exception handling is usually better than the console\r\n}\r\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t143: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkweb_game_player\"] = self[\"webpackChunkweb_game_player\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [216], () => (__webpack_require__(71)))\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","Utilities","static","doc","videoAd","querySelector","frames","querySelectorAll","i","length","findActiveVideo","contentDocument","err","name","flags","url","regex","search","window","location","rxflags","reduce","prev","cur","concat","results","RegExp","exec","URLSearchParams","has","enableDeveloperMode","debugKey","localStorage","setItem","Date","getTime","toString","logger","cLog","this","developerModeTimeoutHours","disableDeveloperMode","removeItem","error","getHoursSinceDeveloperModeActivated","lastUpdated","parseInt","getItem","Number","isNaN","differenceInHours","Math","round","element","style","endState","animationTimeout","attribute","animationTimeoutRef","endEventSubscription","Promise","resolve","attr","endEvent","fromEvent","classList","add","subscribe","remove","setTimeout","finally","clearTimeout","unsubscribe","mcgId","mcgIdArray","split","mcgIdUniqueVal","test","nodes","forEach","node","Object","prototype","hasOwnProperty","call","parentNode","removeChild","parent","child","append","appendChild","prepend","firstChild","firstElementChild","insertBefore","exception","Error","JSON","stringify","cookieName","cookie","document","find","row","trim","startsWith","substring","isBrowserChrome","indexOf","isBrowserFirefox","isBrowserSafari","isBrowserOpera","isBrowserEdge","isBrowserInternetExplorer","getBrowserName","browserName","getBrowserVersion","version","getBrowserPrimaryVersion","telemetryClient","constructor","appInsights","config","instrumentationKey","namePrefix","disableFetchTracking","disableAjaxTracking","loadAppInsights","addTelemetryInitializer","envelope","baseType","envelopeMessage","data","message","envelopeUrl","includes","loggingPrefix","appInsightsClient","telemetry","client","properties","embedURL","href","slot","getCookieValue","parentURL","trafficSrc","referrer","e","gameID","gameType","gameVersion","hostingEnvironment","environment","locale","src","trackEvent","measurements","props","trackError","cError","trackPageView","duration","trackException","handledAt","severityLevel","flushEvent","flush","debugMode","isDeveloperModeActive","logItems","logToConsole","cWarn","level","msg","output","console","overlay","activeOverlays","showOverlay","template","parentSelector","clickSelector","overlayId","position","overlayError","overlayNode","clickElement","container","insertAdjacentHTML","nextElementSibling","previousElementSibling","lastElementChild","removeNode","reject","push","clickEventSubscription","transition","hideOverlay","display","Element","overlayIndex","splice","AdErrorNames","AdEventNames","AdPlacementType","AdVendors","ConsentKeys","EmittableGameEvents","EventTypes","GameTypes","HostingEnvironments","Locales","PublicSettings","ReceivableGameEvents","TelemetryEventNames","XandrEventTypes","Xandr","eventManager","apnPageOptions","member","testFlag","user","externalUid","userIds","type","eids","id","source","astOptions","targetId","invCode","sizes","allowedFormats","targetingParams","trafficSourceCode","rendererOptions","cbNotification","setOutstreamCallbacks","playerTechnology","adText","showMute","showVolume","showProgressBar","autoInitialSize","allowFullscreen","playVideoVisibleThreshold","sideStream","enabled","skippable","videoThreshold","videoOffset","skipLocation","skipText","skipButtonText","astOptionsPlacement","astOptionsProviderId","astOptionsRID","telemetryProperties","adPlacementType","adSessionID","prevEvent","placementId","vendor","videoDuration","videoUrl","videoContainerElementId","videoContentContainerElementId","xandrASTScriptSrc","xandrASTScriptContainerId","xandrEventLog","eventHub","Subject","showPrerollClickToPlay","vendorID","windowEvents","event","values","handleAdEvent","isApnTag","apntagRef","loaded","enableTestAd","placementLocale","playAd","preroll","setAstOptionProperties","interstitial","videoAdPauseDelta","videoAdPauseTime","videoAdResumeTime","videoAdStartTime","initXandrAST","then","createAdContainer","HTMLElement","requestAds","catch","info","VA_NVA","next","adPlaybackError","adEvent","cleanup","eventHubSubscription","keys","filter","key","host","URL","endsWith","async","xandrASTJs","createElement","onload","onerror","appendNode","head","apnLoadTimeoutCount","apnLoadTimeout","setInterval","apntag","clearInterval","getFormattedError","adContainer","setAttribute","displayBase","anq","setApnPageOptions","newApnPageOptions","newAstOptions","setPageOpts","debug","defineTag","setApnCallbacks","loadTags","now","random","adComplete","eventData","postMessage","eventType","callbackFunction","EVENT_AD_AVAILABLE","adObj","showTag","EVENT_AD_BAD_REQUEST","EVENT_AD_REQUEST_FAILURE","adError","EVENT_AD_ERROR","EVENT_AD_LOADED","EVENT_AD_LOADED_MEDIATED","EVENT_AD_NO_BID","EVENT_AD_NO_BID_MEDIATED","EVENT_AD_COLLAPSE","EVENT_AD_REQUESTED","onEvent","apnPageOptionsUserId","userId","eid","placementOptions","placement","enUS","placementType","astEvent","errorProperties","errorCode","code","errorInfo","errorMessage","errMessage","VA_E","VA_AI","EVENT_START","VAI_FiQS","adImpressionStart","EVENT_FIRST_QUARTILE","calculateSplit","VAI_FiQC","adFirstQuartile","EVENT_MIDPOINT","VAI_SQC","adSecondQuartile","EVENT_THIRD_QUARTILE","VAI_TQC","adThirdQuartile","EVENT_COMPLETE","VAI_FoQC","adFourthQuartile","EVENT_AD_COMPLETE","EVENT_ENDED","VA_C","EVENT_VIDEO_PAUSE","VAI_PA","adPaused","EVENT_VIDEO_RESUME","adResumed","EVENT_VIDEO_SKIP","VAI_SA","VAI_O","AdManager","placeholderVideo","adResponseTimeout","isPlaying","_placeholderVideo","isAdPlaying","adPartner","configurePlayers","adsConfiguration","adVendor","_xandr","playPrerollAd","playInterstitialAd","adEvents","events","asObservable","pipe","map","partner","adEventName","VA_RP","VA_RI","race","adStartTimeout","adPlayTimeout","success","AdCouldNotBePlayed","AdAlreadyPlaying","adStartTimeoutRef","VA_NRT","AdResponseTimeout","adStartTimeoutSubscription","adPlayTimeoutRef","VA_APT","AdPlaybackTimeout","adPlayTimeoutSubscription","GameManager","pauseGame","target","requestAction","gamePaused","resumeGame","gameResumed","muteGame","gameMuted","action","expectedResponse","send","Message","value","needsReconciliation","sent","timeSent","EventManager","eventStream","awaitingAck","addEventListener","reconcile","transform","isReceivableEvent","extra","msgTarget","msgExtra","HTMLIFrameElement","contentWindow","log","arr","messageEvent","gameEvent","gameScore","match","LoadingIndicators","loadingIndicatorId","activeLoader","removeLoader","loadingIndicatorEl","showLoader","bgColor","loader","colorVal","index","join","innerHTML","styles","loaderElement","prependNode","PlaceholderVideo","videoEvent","videoElementPlayStarted","videoElementSubscription","videoElementPauseTimeout","videoElementRetryPlayTimeout","videoElement","from","mergeMap","paused","videoElementPlay","play","undefined","_adManager","_eventManager","_gameManager","_loadingIndicators","adManager","gameManager","loadingIndicators","xandr","WebGamePlayer","playerSettings","adLoadingTemplate","clickToPlayTemplate","prerollAdvertisementTimeoutActive","duplicateAdRequestBufferActive","duplicateAdRequestBufferLength","gameFrame","gameOverTemplate","settings","interstitialAdInterval","prerollAdInterval","interstitialAdSkipCount","externalId","gameABTest","gameDisplayName","firstParty","hasScore","zone","language","levels","maxWidth","minHeight","path","playInterstitial","playPreroll","setLang","support","chrome","firefox","safari","opera","edge","internetExplorer","consent","isConsentRequired","required","advertising","analytics","socialMedia","translations","unsupportedBrowserTemplate","unsupportedGameTemplate","initalizeDeveloperMode","mergeSettings","setAdPlayerDependencies","initializeAdSkipCountLocalStorage","trfSrc","decodeURIComponent","HPL","readyForComm","GDK_RC","adLevels","adInterval","completedLevel","GDK_CL","startAdPlayback","GDK_SAP","gameEnded","gameQuit","GDK_GEQ","reloadGame","GDK_SR","clientHasLocalStorage","interstitialAdSkipCountString","interstitialAdSkipCountOriginalString","interstitialAdSkipCountOriginal","LS_UE","loadGamePlayer","browserPrimaryVersionNumber","showUnsupportedBrowser","showUnsupportedGame","showClickToPlay","loadGame","VA_RPD","score","hideGame","showGameOver","playReloadGamePrerollAd","setPrerollAdvertisementTimeout","adPlaybackCompleted","showAdPlayingText","logMsg","reload","gamePath","queryStart","showGame","adStartSubscription","removeAdPlayingText","VA_RID","res","htmlOut","c2p_title","c2p_click","c2p_btn","game_over_score","game_over_enjoyed","game_over_btn","browserVersion","unsupported_browser_title","unsupported_browser_1","unsupported_browser_2","unsupported_browser_3","unsupported_browser_4","gameName","unsupported_game_title","unsupported_game_1","unsupported_game_2","unsupported_game_3","unsupported_game_4","isPreroll","ad_player_begin","ad_player_continue","adPlayingNode","normalizedSettings","prop","propUpperCase","toUpperCase","INTERSTITIALADINTERVAL","PLAYINTERSTITIAL","PLAYPREROLL","GAMEDISPLAYNAME","GAMETYPE","GAMEVERSION","validateSettings","newValue","validateMcgId","isGamePathAllowed","consentKey","parsedUrl","some","hostName","hostname","reason","apply","loadingIndicator","queryVals","val","validKey","gameInfoBase64","getUrlSearchParam","gameInfo","parse","Buffer","gameConfig","uri","fetch","method","headers","mode","response","ok","json","status","statusText","getGameConfig","gameConfigJson","hasUrlSearchParam","wgp","readyState","formattedError","bootstrapWGP","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","exports","module","__webpack_modules__","m","O","result","chunkIds","fn","priority","notFulfilled","Infinity","fulfilled","j","every","r","d","definition","o","defineProperty","enumerable","get","g","globalThis","Function","obj","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","chunkLoadingGlobal","self","bind","__webpack_exports__"],"sourceRoot":""}