{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/AppError/AppErrorTracker.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/isomorphic-util/src/DOMHelpersCore.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/constants/Constants.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/isomorphic-util/src/DOMHelpers.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/app/HeadData.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/reducers/ActionDispatchHelper.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/reducers/ActionSenderBase.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/reducers/ActionDispatchCancellationToken.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/reducers/ActionSender.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/reducers/GlobalActionSender.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/reducers/ActionMap.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/render-cache/src/Constants.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/UrlUtility.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-constants/src/AppTypes.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/AppError/AppErrors.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/app/AppEnvironment.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/isomorphic-util/src/requestData.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/constants/ConnectorConstants.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/webstorage/LocalStorage.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/webstorage/WebStorage.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/Parsing.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/render-cache/src/Helper.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/Utility.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/logging/Logger.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/auth/src/AadAuthHelper.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/reducers/DynamicReducer.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/pages/PageHelper.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/pages/PageBase.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-base/src/utilities/ColumnWidths.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/milestone-data/src/MilestoneData.actions.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/performance/PerfTimeline.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/performance/PageTimings.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/CookieUtility.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/app/Environment.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-constants/src/PageTypes.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/milestone-data/src/data-model/ExperienceLoadingState.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/pages/index.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-base/src/utilities/BreakpointManager.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/app/Enterprise.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/telemetry-contracts/src/telemetry-statics/Telemetry.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/reducers/DataConnectorInjector.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/performance/PerfMarker.ts","webpack:///./src/integration/RequireAsync.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/oneservice/src/OneServiceUtility.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-constants/src/ConnectorNamespaces.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/src/Icon.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/src/Icon.styles.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/src/index.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/app/Market.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/src/icons/GlyphInline.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/logging/LiteLogger.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/logging/Util.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/app/HostPage.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-constants/src/AuthCookieNames.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/wpo-common/src/WpoHelper.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/telemetry-contracts/src/telemetry-contracts/TelemetryConstants.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/ServerCacheMock.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/page-lifecycle-helpers/src/PageInvalidationReasons.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/WebWorkerUtility.ts","webpack:///./src/integration/PrimeTrack.ts","webpack:///./src/integration/PrimeTelemetry.ts","webpack:///./src/integration/PrimeTrackExtensionComplete.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/views-helpers/src/IntraArticle.types.ts","webpack:///./src/integration/MediatorEventNames.ts","webpack:///./src/integration/PrimeMediator.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/SingletonResetManager.ts","webpack:///./src/integration/SubnavTabId.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/logging/ErrorHelper.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/PageUtility.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/reducers/ActionHandler.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/telemetry-contracts/src/telemetry-contracts/TelemetryEnums.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/AdChoices.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/AlertWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BingCardDefaultHotelImage.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BingHotelSeePrice.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BingLogo.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BingRatingDarkLightStar.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BingRatingDarkStar.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BingRatingLightStar.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BlowingHail.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BlowingHailWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BlowingHailV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BlowingSnow.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BlowingSnowWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/BlowingSnowV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Check.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Chevron.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ChevronDown.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ChevronRight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ChevronWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/CircleChevron.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/CircleClose.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ClearNight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ClearNightWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ClearNightV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Close.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/CloseThin.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Cloudy.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/CloudyWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/CloudyV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Comment.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Copy.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/DarkModeHotel.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/DayTime.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Delete.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Discover.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Dislike.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/DislikeText.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Disliked.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/DislikedLight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/DislikedText.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Docx.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Download.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/DownloadNoFill.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Edit.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/EditNoFill.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Edited.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/EditedNoFill.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Ellipses.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/EllipsesLight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/EmptyDiscoverDark.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/EmptyDiscoverLight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Excel.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Facebook.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/FacebookCircle.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/FacebookText.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/FacebookTextBlack.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Fog.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/FogWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/FogV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Folder.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/FolderNoFill.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/FolderOpen.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Form.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Forward.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/FreezingRain.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/FreezingRainWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/FreezingRainV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/GalleryFullscreen.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/GalleryMediaIcon.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/GeneralErrorDark.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/GeneralErrorLight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/GenericFile.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/GridView.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HailDay.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HailDayWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HailDayV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HailNight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HailNightWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HailNightV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HazeSmoke.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HazeSmokeWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HazeSmokeV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HeavySnow.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HeavySnowWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HeavySnowV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Hide.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HideStory.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HideStoryV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Hotel.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HurricaneFull.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Hurricane.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Hurricane1.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Hurricane2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Hurricane3.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Hurricane4.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Hurricane5.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HurricaneTC.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HurricaneTD.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/HurricaneTS.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Information.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/InteractionRequiredDark.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/InteractionRequiredLight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Interested.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ListMenu.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LightRain.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LightRainWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LightRainV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LightSnow.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LightSnowWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LightSnowV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Like.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LikeText.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Liked.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LikedText.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Line.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Link.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LinkedIn.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LinkedInBlack.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LinkedInText.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LocaleLanguage.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Locate.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LocateWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/LocationDetect.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Mail.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MailBlack.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MailRoundedCorners.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MailNoFill.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ManagedBriefcase.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ManagedBriefcaseNoFill.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MapZoomIn.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MapZoomOut.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Message.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MessageNoFill.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Messages.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MicrosoftLogo.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MicrosoftNews.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MicrosoftNewsFull.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MicrosoftNewsFull_FR.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MicrosoftNewsFull_ZH.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ModerateRain.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ModerateRainWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ModerateRainV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/More.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Movie.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/MsnLogo.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/NightTime.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Office.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/OfficeFormsLogo.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/OneDrive.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/OneNote.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Onetoc.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Open.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/OpenSquared.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Outlook.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/PartlyCloudyDay.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/PartlyCloudyDayWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/PartlyCloudyDayV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/PartlyCloudyNight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/PartlyCloudyNightWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/PartlyCloudyNightV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Pdf.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/People.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Pencil.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Pin.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/PowerBI.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/PowerPoint.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Pptx.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/PriceDrop.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/PriceDropBlue.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Project.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Radar.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainShowersDay.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainShowersDayWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainShowersDayV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainShowersNight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainShowersNightWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainShowersNightV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainSnow.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainSnowV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainSnowShowersDay.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainSnowShowersDayWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainSnowShowersNight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainSnowShowersNightWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainSnowShowersNightV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/RainSnowWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Refresh.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Remove.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Save.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Saved.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SetHome.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Search.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Share.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ShareRoundedCorners.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ShareLight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ShareNoFill.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Sharepoint.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Shopping.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ShoppingDealsDark.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ShoppingDealsLight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Skype.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SkypeOffice.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SnowShowersDay.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SnowShowersDayWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SnowShowersDayV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SnowShowersNight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SnowShowersNightWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SnowShowersNightV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Star.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/StarFill.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/StarFollow.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/StarFollowBlue.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Stars.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SunnyDay.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SunnyDayWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SunnyDayV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Sway.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/SwayApp.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Teams.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ThumbnailView.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Thunderstorms.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ThunderstormsWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/ThunderstormsV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Trending.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Twitter.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/TwitterBlack.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/TwitterNoFill.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/TwitterText.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Unpin.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Upload.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/VerticalSeparator.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/VideoMediaIcon.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/VideoPlay.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/VideoFallback.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Visio.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Vkcom.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Vsdx.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WaterDropL2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherAlert.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherBarometer.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherCloud.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherDewpoint.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherWarning.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherWatch.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherAdvisory.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherExpand.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherIcon.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherMapPause.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherMapPlay.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherPrecipitation.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherSatellite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherTemperature.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherVisiblity.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherWind.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeatherWindDir.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeeklyAdsDark.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WeeklyAdsLight.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WhatsApp.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WhatsAppBlack.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Windy.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WindyWhite.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/WindyV2.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Word.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/World.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Xlsx.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/icon/icons/Yammer.svg","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/public-path/index.ts","webpack:///./src/publicPath.ts","webpack:///./src/integration/SubnavTabName.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/services/ExponentialBackoffRetry.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/oneservice/src/ServiceRequest.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/actions/CommonActions.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/config/configs/ExperienceState.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/config/configs/ChildExperiencesDeferRenderType.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/milestone-data/src/data-model/PageRevealRegistrationInterface.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/config/configs/ChildExperienceValidator.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/config-validator/src/ConfigProcessor.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/performance/PerfTimelineImpl.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/performance/ExperienceDiagnostics.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-connector/src/experience-loader/ExperienceLoader.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-connector/src/connectors/ComponentConnector.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-connector/src/connectors/ComponentConnector.constants.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/telemetry-core/src/react/ComponentTracker.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-connector/src/connectors/ExperiencePerfTimeline.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/views-helpers/src/ViewsStringResource.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/node_modules/@msnews/ssr-server/dist/interop/RequestData.js","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/isomorphic-util/src/SSRInteropContract.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/request/RequestContext.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/IndexedDb.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-base/src/utilities/FastBreakpointManager.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/oneservice/src/UrlUtility.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/milestone-data/src/data-management/MilestoneTrackerHelper.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/telemetry-core/src/tracking/TelemetryObject.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/render-cache/src/PersistRenderCache.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/ServerCache.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-constants/src/ExperienceIds.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-redux/src/connectors/DataConnector.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/milestone-data/src/data-model/ExperienceDeferralHandlerSignature.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/milestone-data/src/data-model/ExperienceMilestoneEventTypes.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/app/ScreenWidth.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/config/configs/ExperienceCompositionTypes.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/config/configs/composition/ChildrenTypes.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/bundles/Bundles.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/milestone-data/src/data-model/ExperienceDeferralEventTypes.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/milestone-data/src/data-management/ExperienceDeferralDependencyTrackerState.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/milestone-data/src/MilestoneData.Helper.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/milestone-data/src/MilestoneData.constants.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/page-lifecycle-helpers/src/PrerenderActionHelpers.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/page-lifecycle-helpers/src/PageVisibilityActionHelpers.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/page-lifecycle-helpers/src/PageLifecycleConstants.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experimentation-helpers/src/GetPeregrineFlights.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/config/Resolver.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/performance/PerfMarkerWait.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/performance/PerfMarkerConstants.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/diagnostics/src/performance/PerfTracker.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/experiences-base/src/base/BaseExperience.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/UrlSearchParamsHelper.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/services/ImageServiceConfig.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/image-url-generator/ImageUrlGenerator.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/views-helpers/src/SocialMediaConfig.ts","webpack:///./src/integration/Constants.ts","webpack:///./src/integration/Mediator.ts","webpack:///./src/integration/SubnavTabHelper.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/pop-over/src/PopOver.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/pop-over/src/PopOver.styles.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/pop-over/src/index.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/ZIndex.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/card-context-menu/src/CardContextMenu.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/card-context-menu/src/CardContextMenu.style.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/card-context-menu/src/index.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/social-media-icon/src/SocialMediaIcon.styles.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/social-media-icon/src/SocialMediaIcon.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/social-media-icon/src/index.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/utilities/ShallowCompare.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/share-dialog/src/ShareDialog.styles.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/share-dialog/src/StringResource.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/share-dialog/src/ShareDialog.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/share-dialog/src/index.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/core/src/telemetry-base/TelemetryBase.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/components/article-card/src/ArticleCard.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/libs/views-helpers/src/SocialMediaHelper.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/ContentActionsToolbar.constants.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/components/sharing-toolbar/SharingToolbar.props.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/ContentActionsToolbar.actions.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/components/sharing-toolbar/SharingToolbar.constants.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/ContentActionsToolbar.inspector.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/services/ContentActionsToolbarServiceClient.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/ContentActionsToolbar.connector.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/ContentActionsToolbar.telemetry.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/ContentActionsToolbar.props.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/ContentActionsToolbar.reducer.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/components/sharing-toolbar/SharingToolbar.styles.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/components/dialog-article-card/DialogArticleCard.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/components/dialog-article-card/DialogArticleCard.styles.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/components/dialog-article-card/index.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/components/sharing-toolbar/SharingToolbar.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/components/sharing-toolbar/index.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/ContentActionsToolbar.tsx","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/ContentActionsToolbar.styles.ts","webpack:///C:/agents/peregrineAgent_selfhoste0001Y5_a0/_work/1/s/experiences/content-actions-toolbar/src/index.ts","webpack:///./src/content-actions-toolbar/ContentActionsToolbar.ts"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","23","exports","module","l","e","promises","installedChunkData","promise","Promise","resolve","reject","onScriptComplete","script","document","createElement","charset","timeout","nc","setAttribute","src","p","jsonpScriptSrc","error","Error","event","onerror","onload","clearTimeout","chunk","errorType","type","realSrc","target","message","name","request","undefined","setTimeout","head","appendChild","all","m","c","d","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","oe","err","console","jsonpArray","window","oldJsonpFunction","slice","Severity","canUseDOM","ariaLabelAttribute","rootElementId","htmlElementIds","html","body","applicationCacheConstants","manifestAttributeName","pagesRefreshData","legacyStoredHeadDataKey","legacyStoredLastUsedActivityIdKey","clientSettings","pagetypeSettings","info","js","dir","serviceUrl","telemetryId","trackPageProduct","trackPageType","minimumHostPagePathSegments","anonCookieName","appAnonCookieExistsCookieName","childCookieName","nurturingAcceptedStateKey","oneServiceHeaders","activityId","authorization","oneServiceQueryStringKeys","apiKey","complexInfoPaneEnabled","contentType","delta","disableTypeSerialization","infopaneCount","fdhead","feedLayoutRequestType","filter","ids","location","market","ocid","parentContentId","parentNamespace","parentTitle","queryQ","query","queryType","qScope","responseSchema","select","session","signInCookieName","skip","source","timeOut","top","user","wrapOData","AriaRoles","DeviceOrientation","EnterpriseOneServiceApi","CoreLocalStorageKeys","pageVersions","defaultOneServiceApiKey","getLocationHref","href","url","getLocationHostname","hostname","getLocationOrigin","origin","getLocationSearch","search","getDocumentElementById","elementId","getElementById","getDocumentElementsByTagName","tagName","getElementsByTagName","getIndexedDB","indexedDB","getInnerWidth","innerWidth","getDevicePixelRatio","devicePixelRatio","createScriptTag","id","loadAsync","scriptElement","async","NONCE_ID","nonce","LocalStorageKey","HeadData","clientData","enableCMSPPEConfigs","this","initializeHeadData","locale","marketDir","currentFlights","userIsSignedIn","isPreload","isPrerender","isAppcache","isEnterprise","isOfficeDefaultPivot","isServiceWorkerCache","lastKnownAppVersion","ssoComplete","aadState","_instance","headData","initializeFromData","newRidNeeded","lastUsedActivityIdBacking","locationSearch","htmlElement","headElement","initializeFromDom","getAttribute","navigator","serviceWorker","controller","initializeFromStorage","initializeLastUsedActivityId","clientSettingsLocaleExists","language","toLowerCase","toLocaleLowerCase","setQueryItemProvidedValues","headDataJs","headJs","anonckname","signedin","getQueryParameterByName","visibilityState","setIsEnterprise","setIsOfficeDefaultPivot","storageKey","getStoredActivityIdKey","storedActivityIdJson","getItem","fetchAndUpgradeOldStorage","StoredActivityId","ts","setItem","JSON","stringify","removeItem","getStoredHeadDataKey","storedHeadDataJson","StoredHeadData","headDataResponse","localStorageKey","legacyLocalStorageKey","responsesFromStorage","parsedResponseFromStorage","pageType","entries","itemToReturn","pagetype","setFlights","clientInfo","dataClientSettings","calculateForwardableParams","pageTypeFromSettings","storedVersions","getObject","bundleInfo","currentDomVersion","v","setObject","log","logPrefix","currentPageStoredHeadData","storedHeadData","populateFromApiResponse","response","responseClientSettings","responseFlights","pageGenTime","domQueryParams","queryparams","currentPageVersion","assign","params","lowerCaseParams","availableParams","map","paramValue","encodeURIComponent","x","forwardablequeryparams","join","lastUsedAid","lastUsedActivityId","currentAid","aid","pageGenTimestamp","getTime","flightString","exec","IsEnterprise","includes","audienceMode","Enterprise","queryItems","getParamsWithItems","cmsItem","find","item","setCurrentFlightsTestOverride","flights","IsOfficeDefaultPivot","getHeadData","getInstance","resetInstance","getActionPayload","connector","args","experienceInstanceId","stateKey","namespace","dispatchAction","payload","store","dispatch","PageBase","observers","cancellationToken","isCancelled","isCancellationRequested","perfTimeline","tryGetPerfTimeline","actionEndMeasure","startMeasure","endMeasure","getDispatchResult","forEach","filterConnector","observer","dispatchConnector","renderActionPayload","ConnectorConstants","renderAction","super","connectorInstance","rootReducer","connectors","locationHref","defaultExpirationTimeMs","defaultForceExpirationTimeMs","expirationPrefix","forceTimestampPrefix","jssMapSuffix","keysPrefix","normalizedUrlConfigkey","storagePrefix","riverRcClassName","UrlUtility","primeForbiddenCharacters","getParamsFromUrl","decodeComponents","getParams","split","decodeURIComponentWithPlusSign","val","replace","decodeURIComponent","queryString","startsWith","substring","queryArray","ndx","parts","queryKey","queryValue","newParam","existingParam","entry","encodeURIComponentForPrime","uriComponent","findIndex","hrefParamsObj","paramsObj","paramArray","keyValuePair","getParamsObj","isValidUrl","validateScheme","indexOf","keyValueArrayToQueryString","kv","isKeyValuePair","joinSubpathToURL","subPath","trimmedEndSlashFromHref","trimmedStartSlashFromSubpath","URL","updateSearchParam","searchParams","set","appendSearchParam","fallback","append","getAbsoluteUrl","partialUrl","AppType","severity","Alert","pb","build","BUILD_NUMBER","updateAppErrorsPropertyBag","newPbInfo","getAppErrorsPropertyBag","createError","baseError","customMessage","NoAlert","OneServiceCardProviderAppErrors","EmptyMyFeed","OneServiceResponseWasNullOrErroneous","ErrorFetchingOneServiceResponse","HighImpact","InvalidJsonInOneServiceResponse","InvalidFeedListInOneServiceResponse","RiverConfigurationIssue","QueryInterestContentFetchError","StaticContentLoaded","ContentPreviewAppErrors","ErrorWhileFetchingContentPreviewContent","InvalidResponseFromContentPreviewFetch","InvalidResponseFromContentPreviewResponseJson","ErrorWhileInitializingAsyncContentPreviewContent","InvalidOrMissingContentId","MissingDataForExternalContent","MissingPartnerLink","RiverSourceFile","RiverAppErrors","UnknownMetadataReceivedFromRiverCardProvider","RiverContentProviderFetchException","SkipPositionedCardsFallbackStrategyFailed","InvalidConfig","MissingExperienceTypeMap","ChildLoadError","InitialDataLoadError","DuplicateInstanceIdWarning","FullHeightFallbackStrategyFailed","UserInitiatedPageRefreshErrors","Default","SportsCardError","SportsLeaguePdpFetchError","SportsLeaguePdpInvalidResponse","SportsPlayersPdpFetchError","SportsPlayersPdpInvalidResponse","SportsTeamsPdpFetchError","SportsTeamsPdpInvalidResponse","SportsCardConfigFetchError","SportsCardGetFavoriteTeamDataError","SportsCardGetPlayerBioError","SportsCardGetLeaguesGamesArrayError","SportsCardGetPdpDataFailure","SportsCardGetLeagueSeasonYearDataFailure","SportsCardGetLocalizedTeamNameDataFailure","SportsCardGetTeamDataFailure","SportsCardGetLeagueDataFailure","MoneyCardError","MoneyQuoteSummaryGetError","MoneyQuoteSummariesGetError","MoneyPdpDataGetErrorFromService","MoneyPdpInvalidResponseFromService","MoneyQuoteSummaryGetErrorFromService","MoneyQuoteSummaryInvalidResponseFromService","TrendingNewsErrors","DataFetchError","BackupDataFetchError","GridSectionAppErrors","GridSectionCardGenerationError","MeControlAppErrors","SSOFailedError","MeControlLoadFailedError","PageClickTrackerErrors","InvalidResponse","FetchFailure","CoachmarkAppErrors","GeneralError","NotPlaceable","NotFoundComponent","CoachmarkDataConnectorUndefined","InvalidCTAType","CTATypeNotDefined","ConfigDataUndefined","FailedToFetchConfigData","ExceptionFetchingConfigData","EventNotDefined","CoachmarkStateNotDefined","CoachmarkDataAppErrors","InvalidCoachmarkMessage","IrisDataConnectorUndefined","ErrorFoundForSurface","TelemetryInfoUndefined","EventTypeUndefined","IrisActionUndefined","SpotlightPreviewAppErrors","ErrorWhileFetchingSpotlightPreviewCardInfo","NoServiceContextMetadata","SpotlightErrors","UnknownError","ContentFetchError","PartnerFetchFail","CardActionErrors","CardActionBaseExperienceError","CardActionPostActionError","CardActionDeleteActionError","CardActionGetActionError","CookieRelatedErrors","SharedStateConnectorNull","OverlayErrors","LoadExperienceError","ViewsCommonAppErrors","InvalidIntraArticleDataError","InvalidDocumentContentError","ViewsPaddleDataLoadError","ViewsErrorPage","ProviderMapperError","ContentActionsToolbarAppErrors","ContentActionsSharingToolbarLoadError","ContentActionsArticleDatafetchError","ContentActionsBaseExperienceError","ContentActionsGetDocumentDataError","ContentActionsGetContentStatusActionError","ContentActionsDeleteActionError","ContentActionsPostActionError","ContentActionsExperienceLoadError","ContentActionsFlipToolbarError","ContentActionsContentStatusFetchError","ContentActionsContentPreviewFetchError","ContentSharingToolbarAppErrors","ContentSharingToolbarInitializationError","ContentProviderAppErrors","InvalidSourceIdError","ProviderDetailsFetchError","ProviderFeedFetchError","InvalidLayoutTemplate","refreshHeadDataFile","ViewsGalleryAppErrors","InvalidGalleryIdError","GalleryDataLoadError","GalleryImagesLoadError","VideoListAppErrors","VideoListDataLoadError","ViewsArticleAppErrors","InvalidArticleIdError","ArticleDataLoadError","IntraArticleComponentLoadError","InlineGalleryInvokeError","InterestsSearchAppErrors","ErrorResponseFromOneService","ErrorResponseFromOneServiceIsInvalid","InvalidUrlFoundForElement","SelectedItemNotFoundInSuggestions","SelectedItemIsInvalid","InterestsAppErrors","InterestsRetrieveTopicsError","InterestsRetrieveFollowedTopicsError","InterestsRetrieveMutedPublishersError","InterestsUnMutePublisherError","InterestsFollowTopicError","InterestsUnfollowTopicError","InterestsTopicStateUndefined","InterestsShouldHaveRendered","InterestsRetrieveTopicError","InterestsRetrieveSavedStoriesError","InterestsSavedStoriesInvalidConfigError","InterestsSavedStoriesChildLoadError","InterestsSavedStoriesInvalidJsonError","InterestsSavedStoriesInvalidListError","InterestsRetrieveRecommendedTopicsError","UndefinedTopicDataConnector","InterestsRetrieveReadStoriesError","InterestsReadStoriesInvalidConfigError","InterestsReadStoriesChildLoadError","InterestsReadStoriesInvalidJsonError","InterestsReadStoriesInvalidListError","FailedRestoringDefaultTopicsError","TopicsFailedIndexedDBConnection","TopicsFailedGettingIndexedDB","TopicsFailedUpdatingIndexedDB","ComponentConnector","ComponentConnectorAppErrors","DuplicateChildInstanceFound","BundleLoadError","ChildConfigInfoListNull","ListStartPositionInvalid","ChildDelayLoadError","ExperienceDependencyTimeout","LoadDataConnectorConfigFailed","LoadDataConnectorFailed","ChildWithInvalidExperience","ExperienceLoaderAppErrors","InsufficientLoadArgs","ConnectComponentFailureError","LoadComponentFailureError","SearchError","MissingFormCode","RecommendedSearchErrors","ResponseParsingFailed","InvalidJsonResponse","ServiceCallFailed","RenderFailed","Timeout","PollsCardAppErrors","Critical","PollsListFetchError","PollDataFetchError","PollsCardInvalidPoll","PollsCardInvalidQuizPoll","PollsCardVoteError","PollsCardMapStateToPropsError","PollsUnknownError","PollsResultPercentageError","PollAutoCuratedErrors","PollAutoCuratedContentError","PollAutoCuratedInvalid","PollAutoCuratedResultsFetchError","PollAutoCuratedResultsTransformError","MonetizationAppErrors","PlacementManagerLoadError","ArrangementPositionLoadError","GetCMSContentError","GetSAMRTBResponseError","MediaNetEOABError","InvalidPromoModuleConfig","CookieSyncDownloadExternalScriptError","CookieSyncMissingExternalScriptUrl","CookieSyncTimeout","CookieSyncPartnerScriptError","CookieSyncPixelPartnerDownloadError","CMSOrBackfillNativeAdLoadError","MissingRequiredPropertyPlacementManagerConfig","NativeAdTargetScopeError","RiverVideoAdPartnerError","JsTrackerPartnerScriptLoadError","ViglinkError","MissingTopicId","TopicIdNotFound","GetSAMRTBResponseErrorNoAlert","DisplayAdsOathLoadError","DisplayAdsApnLoadError","DisplayAdsApnEmptyProvider","DisplayAdsAdsDetectionNotInit","DisplayAdsMoatLoadError","DisplayAdsNoAdObjects","DisplayAdsProviderIdEncode","TaboolaRiverAppErrors","TaboolaRiverFetchError","CoreLibAppErrors","DeprecatedCompositionLayoutUsed","InvalidColumnInGridConfig","ErrorLoadingBundle","GenericJSException","LocalStorageDoesntExist","SessionStorageDoesntExist","ReactRenderException","ResolverAppErrors","IndexedDbWriteFailed","IndexedDbReadFailed","CrsFetchFailed","ReceivedConfigFromCdnAsCrsFetchFailed","GetConfigException","IndexedDbBulkReadFailed","IndexedDbFailedToRemoveCachedConfig","IndexedDbFailedToClearAllCachedConfigs","RenderCachePurgedDueToChangesInConfig","FailedToPurgeRenderCache","RefreshConfigCacheFailed","IndexedDbInitFailed","DifferentCbid","PrgFlightLsWriteError","PrgFlightLsReadError","ResolverErrorConfigsDownloadedByCdn","CachedConfigsForDifferentFlight","BingCardsAppErrors","BingCardGetHotelAnswersError","BingCardGetHotelErrorFromService","BingCardGetAnswersError","BingCardInvalidEntityType","BingCardErrorOut","BingAnswersAppErrors","FailedToLoadData","NoCardsContentType","NoCardsRelated","BingShoppingLifestyleCardError","LifestyleShopCardServiceFetchError","LifestyleShopCardServiceFetchInvalidResponse","LifestyleShopCardServiceEmptyResponse","LifestyleShopCardServiceInvalidResponse","LifestyleShopCardCdnServiceFetchError","LifestyleShopCardCdnServiceFetchInvalidResponse","LifestyleShopCardCdnServiceInvalidResponse","LifestyleShopAutosuggestServiceFetchError","LifestyleShopAutosuggestServiceFetchInvalidResponse","LifestyleShopAutosuggestServiceEmptyResponse","LifestyleShopAutosuggestServiceInvalidResponse","LifestyleShopAutosuggestInvalidSuggestionUrl","BingMiniShoppingServiceClientSourceFile","BingMiniShoppingError","BingMiniShoppingServiceFetchError","BingMiniShoppingServiceEmptyResponse","BingMiniShoppingServiceInvalidResponse","BingMiniShoppingServiceInsufficientDealsItems","BingMiniShoppingServiceInsufficientActiveDealsItems","BingMiniShoppingServiceInsufficientTrendingItems","BingMiniShoppingServiceInsufficientTrendingCategories","BingShoppingMeStripeServiceFetchError","BingShoppingMeStripeServiceEmptyResponse","BingShoppingMeStripeServiceInvalidResponse","BingShoppingMeStripeServiceMissingRequiredFields","ShoppingCarouselEntitiesDataServiceFetchError","ShoppingCarouselEntitiesDataServiceEmptyResponse","ShoppingCarouselEntitiesDataServiceInvalidResponse","ShoppingCarouselEntitiesDataServiceInsufficientItems","ShoppingCarouselGenericError","ShoppingCarouselRenderError","ShoppingContentCardServiceFetchError","ShoppingContentCardServiceEmptyResponse","ShoppingContentServiceInvalidData","ShoppingContentServiceInsufficientActiveItems","ShoppingContentServiceMissingFields","OneServiceContentDataConnector","FailedToUpdateBypassValueConnectorNotInitialized","FailedToGetBypassValueConnectorNotInitialized","NotificationBellErrors","JsonParseError","NewsItemDataFetchError","MalformedNewsItemResponseError","ElectionResultMapConnectorErrors","ElectionResultMapInspectorErrors","EmptyResultSummaryError","ElectionResultMapErrors","FetchAndUpdateElectionDataError","ElectionDelegateCounterErrors","TopicByNameFetchFailed","RecommendedTopicsErrors","TopicsDataConnectorFailed","InvalidTopicClick","WebWorkerErrors","FileNotFound","RuntimeError","MessageTimeout","HandledError","AppError_InvalidQParams_35001","AppError_ArcResponseNotOk_35003","AppError_ArcResponseUnparsable_35004","AppError_MissingAppEnv_35005","AppError_UnknownIrisErrorFound_35006","AppError_TimeoutIrisErrorFound_35007","AppError_TemplateIrisErrorFound_35008","AppError_ClientErrorIrisErrorFound_35009","AppError_DSourceIrisErrorFound_35010","AppError_ActionResponseFailure_35013","AppError_UncaughtErrorDetected_35014","AppError_UnconvertableCreative_35015","AppError_InvalidResponseFormat_35016","AppError_TimeoutErrorDiscovered_35017","AppError_UnparsableSingleResponseJSON_35018","IrisDataConnectorErrors","SubscriberNotFound","CreativeCountNegativeOrZero","MissingIrisParameterForConditionalBanner","SubscriberNotFoundInIrisPlacementDictionary","FailedToReadNurturingAcceptedFlag","EdgeChromiumAPIsNotAvailable","AcquireAccessTokenFailed","RenderCacheErrors","JssStyleMismatchWarning","JssStyleCriticalMismatchError","PreloadReportingMessages","TtvrMissing","TfprMissing","TtvrSearchBoxMissing","TtfSearchBoxMissing","PushNotificationsLibErrors","FetchKeyError","SubscribeUnsubscribeError","ContentTruncationErrors","OverTruncationError","EmptyFeedWithFeedId","EmptySearchedFeedWithFeedId","EmptySearchedFeedWithFeedQuery","EmptyKidsModeFeed","FallingBackToSkipStrategy","FallingBackToFullHeightStrategy","SocialNoModuleName","SocialAPIRequestErrorUnknown","SocialAPIRequestErrorContents","SocialAPIRequestErrorComments","SocialAPIRequestErrorUsers","SocialExperienceRenderErrorComment","SocialExperienceRenderErrorProfilePage","SocialExperienceRenderErrorProfileCard","SocialExperienceRenderErrorProfileTabs","SocialExperienceRenderErrorSocialBar","SocialExperienceRenderErrorReactionBreakdown","SocialExperienceRenderErrorGuideline","SocialExperienceRenderErrorMultilineLogin","SocialExperienceRenderErrorNotificationTray","SocialExperienceRenderErrorOnboarding","SocialExperienceRenderErrorOnbardingThirdParty","SocialExperienceRenderErrorUnknownComponent","UnknownBulkLoadGraphActionType","AppEnvironment","_serviceUrl","_configServiceUrlBase","initializeAppEnvironment","ClientSettings","environmentConfigUrl","process","env","WEBPACK_DEV_SERVER","URLSearchParams","searchParam","contentServiceUrlBase","currentRequestTargetScope","currentMarket","environment","assetsHost","hostPage","appType","authCookieName","useOneServiceAuthEndpoints","accountInfoPromise","resolvedAccountInfo","buildVersion","clarityEnabled","rootTelemetryId","trackInfo","getUserMuid","userId","isDebug","showMnsCreatorDashboard","currentContentLinkHost","serviceUrlBase","feedServiceUrlBase","isFrePage","disableCachingConfigs","enableConfigService","EnableCMSPPEConfigs","isMultiConfigRetrievalEnabled","disableContentPreviewCache","sendFeedCallActivityIdInHeader","queryParamOverride","disableContentCacheIDBRead","configServiceBaseUrl","featureFlags","configRootUrl","cacheBustingIdentifier","countryCode","latitude","longitude","configServiceUrlBase","appEnvironment","environmentFromHeadData","tryReformatGuid","Locale","apps_locale","geo_country","geo_lat","geo_long","pcsInfo","setAccountInfoPromise","apptype","getAuthCookieName","disableActivityIdInHeader","Edge","Hub","cbid","pcsVersion","propertyBagPcsVersion","rootElement","locationOrigin","envQSOverwrite","prod","endsWith","defaultFeedBaseDomain","EdgeChromium","MicrosoftNews","feedBaseDomain","getHostPageFromUrl","Number","trackPageProd","trackPageTypeVal","sitePage","page_product","page_type","createContentLinkHost","setTargetScope","useMultiConfigsRetrieval","baseUrl","getConfigServiceBaseUrl","1","true","muid","muidCookie","relativePath","int","urlQuery","param","FirstParty","Views","Weather","Finance","Anon","MMX","Office","AppAnon","ResolvedAccountInfo","AccountInfoPromise","chrome","authPrivate","getPrimaryAccountInfo","startTime","Math","round","performance","now","accountInfo","endTime","ZHCN","guid","matches","match","Kids","Adult","browser","deviceFormFactor","domain","os","platform","Web","stringHasData","CurrentFlights","pageExperiments","addWpoFlights","FeatureFlags","wpoEnabled","wpoData","flightsCached","currentPageExperiments","concat","getAppEnvironment","RequestData","_innerWidth","innerHeight","canUseCssGrid","requestId","cookie","referer","_viewportWidth","viewportWidth","global","resetRequestData","overrideInnerWidthWithFixedViewportWidth","getRequestData","connectorStateKey","dataConnectorMergeInitAction","localStorage","storage","supported","defaultValue","parsedObj","index","logError","matchingKeys","ex","tryParseJson","jsonString","parse","tryParseInt","parseInt","isNaN","renderCacheObject","batchCSS","batchCss","styles","dataset","jss","innerHTML","scrapeDom","includeNewsFeed","root","rivers","getElementsByClassName","river","outerHTML","getStateFromRenderCache","renderCache","renderCacheKeys","renderCacheStoredKeys","renderCacheKeyOfNormalizedKeys","keyn","expn","frcn","jssn","cacheExpirationTimestamp","parsedCacheExpirationTimestamp","Date","renderCacheStorage","dom","batch_css","getRenderCache","state","initialState","reduxStoreStringifyReviver","getNormalizedLocationHref","configParamsList","normalizeKeyParamsList","normalizeUrlQsp","getNormalizeKeyParamsList","normalizedParams","setNormalizeKeyParamsList","toString","dataType","Map","Utility","isNotNullOrUndefined","isDefined","potentialKeyValuePair","isKey","isValue","isNonNullObject","isNotNull","isNullOrWhiteSpace","trim","toNumber","arrayHasData","constructor","Array","objectToString","firstRun","attribute","logger","aadTokenQsKey","aadTokenQsVal","TokenFetchSecondaryErrors","useEnterpriseCompliance","sharedStateConnector","SharedState","getCurrentState","useEnterpriseDomain","getAadData","clientId","scopeOrResource","friendlyName","allowInteraction","resolveAccountInfo","tokenAcquireParameters","account_id","account_type","client_id","scope_or_resource","totalMarkerName","startMarkerName","endMarkerName","pageTimings","startPerfMarker","endPerfMarker","totalPerfMarker","acquireAccessTokenWithUserInteraction","acquireAccessTokenSilently","acquireResult","is_success","status","success","authErrorObject","error_info","authPrivateApi","accountId","accountType","resource","tenantId","tenant_id","sendAppErrorEvent","secondary_error","kTokenFetchUserInteractionRequired","kInteractionRequired","mfaRequired","otherError","token","access_token","errorInfo","isSuccess","isValid","is_token_valid","_connectorMap","_globalConnectors","_allConnectors","_getDataConnectorPendingPromises","reduce","dataConnector","pendingPromise","resolveCallback","rejectCallback","actionPayload","newState","stateChanged","typeIsString","statePropertyKey","connectorState","experienceFullNamespace","dataConnectorName","initializeExperience","isGlobal","merge","connectorReducerResult","computeNextStateForConnector","reportStateChange","keys","fullNamespace","has","delete","connectorPreviousState","nextStateForConnector","subReduce","reducer","connectorStateChanged","previousState","reducedState","designSystemMap","WeakMap","designSystemIndexMap","createGenerateClassName","designSystem","callback","dsName","dsIndex","rulesMap","rule","sheet","enhancer","middlewares","__REDUX_DEVTOOLS_EXTENSION_COMPOSE__","trace","traceLimit","_rootReducer","needsHydrate","hasPreHydrateState","_store","onApplicationStart","connectedTopLevelElement","hostElement","updateJss","updateJssManagerInstance","hydrate","SSR","startMark","render","jssInstance","plugins","Size1ColumnWidth","Size2ColumnWidth","Size3ColumnWidth","Size4ColumnWidth","Size5ColumnWidth","GutterSize","MilestoneDataActionsImpl","updateAboveTheFoldVisuallyReady","updateBelowTheFoldTransitionStart","updateExperienceLoadDeferralState","updateExperienceCurrentState","updateExperiencePublicState","updateExperienceRenderDeferralState","updateInitTiming","updatePageComplete","updatePageRevealStart","updatePageRevealComplete","updateRenderTiming","updateVisuallyReadyTiming","updateDomCompleteTiming","updateMilestonePlugins","registerExperienceForPageReveal","MilestoneDataActions","createPerfTimeline","ctor","timelineName","instanceId","addPerfMarks","addPageTimings","tryGetPerfTimelineFuncRef","setTryGetPerfTimelineFunc","func","experienceName","_pageTimings","_secondaryPageTimings","getPageTimings","incrementCounter","counterName","existingCount","getCookie","RegExp","getMuidCookie","setRequireFunctionalCookie","expiryDays","path","secure","expiryDate","builder","date","setTime","toUTCString","Environment","getEnvironmentFromString","int1","intpr","intpef","PageType","AudienceModeType","ExperienceLoadingState","ColumnArrangement","minViewportWidthOverrides","ColumnArrangementDefinition","arrangement","contentSizePx","isFirstBreakpoint","widthOverride","contentBufferPx","columnArrangements","c1","c2","c3","c4","fiveColSupported","c5","columnArrangementMap","columnArrangementDefinition","getMediaQuery","minArragement","maxArrangement","queries","minWidthPx","minViewportWidthPx","maxArrangementDefinition","maxArrangementIndex","getMediaQueryFor","columnArrangement","getMediaQuerySelector","mediaQuery","getMediaQuerySelectorFor","AccessTokenStatus","oneServiceScope","oneServiceFriendlyName","Telemetry","dataConnectorToExperienceKeyMap","createStatePropertyKey","dataConnectorInjector","registerInjection","experienceSet","Set","add","appState","experienceStatePropertyKey","initialDataConnectorState","dataConnectorNamespace","newDataConnectorState","experienceKeys","experienceKey","experiencePreviousState","PerfMarker","endMarkSuffix","initialize","instance","singleMark","measureStartEnd","mark","getPromise","endMark","perfMarkers","perfEntries","getEntriesByType","markerName","perfMarkerDetail","PerfMarkerDetail","processPerfEntry","measure","perfMarker","duration","perfEntry","firstStartTime","requireAsync","moduleName","defaultModule","require","OneServiceUtility","getOneServiceParamsWithoutAuth","ocidSpecifier","addPageInfoToOcid","ActivityId","getOneServiceOCID","TrackInfo","CurrentMarket","runningExperiments","getOneServiceHeaders","headers","aadData","authenticationTicketType","signedInCookieNameHeader","userLocationHeader","serviceRequestOnComplete","serviceRequest","callbackMethod","getOneServiceNonDynamicParamsWithoutAuth","getOneServiceParamsWithAuth","AuthCookieName","toUpperCase","getOneServiceFeedCallHeaders","SendFeedCallActivityIdInHeader","getLocationParams","customizedLatitude","customizedLongitude","Latitude","Longitude","getBaseRequestData","method","getCommonParams","UserIsSignedIn","UserId","ConnectorNamespaces","props","handledProps","ariaLabel","fill","glyphType","height","managedClasses","onError","onClick","width","wrapperClassName","svgClassName","renderSvgWithWrapper","svgComponent","then","setState","ReactComponent","prevProps","LazyLoadedSvgComponent","attrProps","className","generateClassNames","icon_inline","role","icon","unhandledProps","style","title","wrapperCss","renderSvgComponent","Market","Accounts","CDCSelfCheck","ClinicalTrialBot","CoronaVirusIcon","DoubleTap","EmptyMruDark","EmptyMruLight","EmptyPinnedDark","EmptyPinnedLight","EmptySharedDark","EmptySharedLight","RiverLayout","StripeLayout","NewsArticle","NotificationFivePlusSign","NotificationRefreshArrow","PollResults","Video","WaterDrop","LiteLogger","isDebugEnabled","webpackRequire","tags","getMessage","nameRegEx","queryNameValueMatches","HostPage","host","pathnameSegments","pathname","topDomainName","originalUrl","categoryKey","verticalKey","hostName","topDomain","indexOffset","subcategoryKey","AuthCookieExistsCookieName","getWpoStorageCacheKey","targetScope","getWpoFlights","treatments","TelemetryAttrName","TelemetryContentViewType","MockLRUCache","cacheMap","maxAge","PageInvalidationReasons","isWebWorkerPresent","messages","logAppError","standbyMessages","getFromWebWorker","timeoutInMs","defaultResponse","fetched","endGetFromWebWorker","standbyMessageData","promiseTimeout","timeOutPromise","errorMessage","webWorkerPromise","webWorker","postMessage","race","sendToWebWorker","subscribeWebWorkerNotification","override","_isWebWorkerPresent","onmessage","pendingMessage","getTrack","trackingResolved","trackingObject","trackExtCompleted","trackEventBuffer","trackImpressionBuffer","trackAppErrorEventBuffer","trackingPromiseCalled","sendTrackingCall","element","destination","headline","trackEvent","sendPartialPageRequest","elem","visibilityCheck","mechanism","topLevelContainerType","trackPartialImpression","sendTrackAppErrorEvent","appError","trackAppErrorEvent","errId","errSource","errMsg","processPendingTrackingCall","eventObj","handleTelemetryCall","action","behavior","handlePartialPageImpressionCall","viewType","handleAppErrorEventCall","IntraArticleComponentPosition","IntraArticleComponentType","MediatorEventNames","ContentActionsUpdated","FeedFollowed","ForcePageReload","FollowedTopicsUpdated","MediatedCoachMark","TabNavigation","TabNavigateTo","TopicAction","Msn360","CardActionInit","CardActionPost","InterestsRenderComplete","RenderXFeed","ShowPivotById","ResumeInfopaneAutoRotate","SocialActionsUpdated","getMediator","resetCallbacks","registerResetCallback","SubnavTabId","stringifyError","PageUtility","isDhpPage","DHP","isNtpPage","NTP","CurrentRequestTargetScope","ActionHandler","actionMap","actionMaps","actionPayloadType","String","TelemetryType","Undefined","Header","Footer","TopNavBar","NavBar","DropDown","Section","Carousel","Module","SearchBox","InputBox","ActionButton","Interaction","Headline","Entity","Topic","Provider","NewStories","AutoSuggest","Tile","TrendingNews","AllCoverage","Report","MsccCookieComplianceBanner","CookieWallCookieComplianceBanner","TelemetryContentType","StructuredData","AppStore","CmsPromotions","MicrosoftWebStore","XboxStore","OfficeStore","PartnerLinks","SponsoredContent","Spotlight","ExternalLink","SearchPromo","Feed","Article","Gallery","Audio","Settings","DisplayAd","OfficeDocument","App","SearchResult","VideoAd","TelemetryActionType","Click","Hover","Submit","View","RightClick","TelemetryBehaviorType","Navigate","ContextMenu","Pin","Unpin","Rearrange","Remove","Add","Open","Follow","Unfollow","More","Close","Share","Like","Dislike","Unlike","Undislike","Mute","Unmute","Cancel","Launch","Install","Manage","Show","MuteCancel","Save","Hide","Unhide","Customize","Suspend","Clear","SignIn","SignOut","UndoSave","TurnOn","TurnOff","Forward","Response","prodAssets","cnProdAssets","ENV","segments","initializeHybridPublicPath","SubnavTabName","Interests","MyFeed","XFeed","loggingService","maxRetries","baseRetryDelayInMs","maxRetryDelayInMs","factor","minOffsetInMs","maxOffsetInMs","loggedExceptionManager","LoggedExceptionManager","logInvalidParams","defaultMaxRetries","defaultBaseRetryDelayInMs","maxAllowedRetryDelayInMs","defaultFactor","defaultMinOffsetInMs","defaultMaxOffsetInMs","infoCallback","minTimeout","maxTimeout","serviceCall","requestInfo","activity","tryRequest","maxAllowedRetries","fatal","currentRetry","timeoutServiceRequest","fractionDigit","offset","parseFloat","random","toFixed","half","plusOrMinus","delayWithOffset","min","pow","warnCallback","errorCallback","timeoutId","instrumentationService","exponentialBackoffRetry","sendRequest","activityName","getInstrumentationService","activityLoggingService","createActivity","getExponentialBackoffRetry","executeRequest","endActivity","activityService","ActivityLoggingService","addAppender","BrowserConsoleAppender","LogLevel","Activity","InstrumentationService","getLoggingService","CommonActions","renderExperience","ActionMap","dataConnectorMergeInit","ExperienceState","ChildExperiencesDeferRenderType","ExperiencesRevalidationReason","ValidatorSectionName","apptypeValidator","expValidatorMap","getAllValidators","expConfig","size","childExpValidatorMap","expMap","originalConfig","tempConfig","validatorName","childExpValidator","validator","validationArgs","expConfigMap","cloneDeep","filterConfig","riverGridChildren","childElems","children","childExp","configInfo","childExperienceConfigInfo","experienceType","baseExperienceConfig","childrenConfigInfo","dataConnectors","dataConnectorForCurrentScreenType","getOrdinalObjectForCurrentBreakpoint","screenWidth","screenTypeObjList","obj","ScreenWidth","Any","currentColumnArrangement","getMetadataByScreenWidth","OneColumn","TwoColumn","ThreeColumn","FourColumn","FiveColumn","connectorProps","getCompositionIdOverride","composition","compositionOverrides","compositionOverrideResolver","ExperienceCompositionTypes","horizontalStack","layout","page","grid","column","childType","ChildrenTypes","peregrineExperience","child","rows","row","columns","itemType","customExperience","customConfig","experience","sectionName","removeFromRiverGridChildren","KeyCounter","timelineCount","count","getCount","perfTimelineInstances","getInstanceKey","getInstanceKeyCore","configIndexHref","parentStore","requestContext","experienceConnector","experienceComponent","$experienceType","config","ExperienceIds","earlyLoadBundlePromises","loadExperience","fullConfig","getConfig","getChildrenDataConnectorConfigInfos","properties","childConfig","earlyLoadBundles","getChildrenExperienceConfigInfos","isDataConnector","linesRunUntilFailure","uniqueId","configResult","configPromise","instrumentPromise","loaderPromises","bundlePromise","newExperienceName","oldInstanceKey","rename","newInstanceKey","renamePerfTimeline","bundleModule","initMeasureEnd","updateExperienceLoadedMilestone","ExperienceConnector","ExperienceReducer","app","experienceNamespace","experienceConfigInfo","experienceParentNamespace","experienceStore","configHref","stack","configIndex","loadConnector","connectComponent","milestoneDataConnector","getActionSender","send","loaded","ConfiglessConnectors","BingImageData","OneServiceContent","TelemetryData","TopicData","PageClickTrackerData","OfficeSharedData","pivotContentV2","DataConnector","childMap","telemetryContext","telemetryTags","$experienceGroup","$connectedComponent","$componentInstance","$renderIfOffline","$isStale","$maxWaitToBatchRenderChildExperiences","$milestoneDataConnector","onExperienceMilestoneTimingUpdate","milestoneType","ExperienceMilestoneEventTypes","domComplete","updateTiming","initialized","rendered","visuallyReady","staleRevalidationComplete","updateExperienceState","onAppError","selectComponentState","namespaceArray","configNamespace","processConfig","setupForPageReveal","childComponentList","componentInstance","ownProps","stateProps","dispatchProps","mnsDashBoardProps","ShowMnsCreatorDashboard","isStale","componentToConnect","onLine","onAppErrorCallback","connectMeasureEnd","WrappedComponent","telemetryObject","onComponentConnect","Component","context","lastRenderEndMeasure","instrumentPerf","mapStateToProps","instrumentFunc","mapDispatchToProps","mergeProps","connectedComponent","pure","experienceInfoList","mergeStartPosition","additionalChildExperiences","ordinalBlockForCurrentColumn","mergeEndPos","childArrangementMetadata","childExpArrangement","positionProps","experienceArrangement","startPosition","insertAt","experienceInfo","initialProps","$connectorProps","telemetryContract","content","parentTelemetry","isEmpty","addOrUpdateChild","TelemetryObject","loadDataConnectors","injectedDataConnector","injectedDataConnectors","onLoadChildExperiences","newProps","loadChildrenExperiences","childConnectorProps","childExpsToLoadImmediately","reRenderCallback","readyExperienceToRender","promiseDependency","startProcessingChildExperience","loadDataConnector","childConnector","getChildExperienceConnector","addConnectorToChildMap","Failed","childExperienceType","childExperienceInstanceId","markStaleRevalidationComplete","expType","invalidationReason","revalidateExperienceStaleState","staleThreshold","revalidateExperienceStateCallback","pageRevealInfo","revalidationReason","Staleness","stalenessThreshold","willRevalidateStaleState","onPageReveal","experienceConfig","mockStalenessConfig","stalenessInfo","isStaleCheckRequired","registerForPageReveal","observePageReveal","eventType","experienceGroup","experienceInstance","loader","getConnectedExperience","getChildExperienceConnectorProps","getNewComponentInstance","removeCachedConfig","milestoneDependencyToLoadChildExp","shouldResolve","addTimeout","deferralType","CustomEventBasedDeferral","Unknown","resolveDependency","loadAndRenderExperience","childExpInfo","delayLoaded","milestoneDependencyToRenderChildExp","ReadyToRender","reRender","childExperiencesRenderType","batch","reRenderExperience","dependency","pending","timer","moneyCard","weatherCard","topSitesEdgeNext","backgroundImageEdgeNext","searchBoxEdgeNext","headerEdgeNext","ViewsStringResource","article","image","video","gallery","exitFullscreen","fullscreen","nextSlide","previousSlide","publishedSecondAgo","publishedSecondsAgo","publishedMinuteAgo","publishedMinutesAgo","publishedHourAgo","publishedHoursAgo","publishedDayAgo","publishedDaysAgo","gallerySlideError","sharingToolbarLoadFailure","invalidCMSIdErrorFormat","documentDataFetchErrorFormat","intraArticleComponentErrorFormat","gallerySlideCountFormat","gallerySlideCountFullScreenFormat","seeOnProviderSite","socialFeedNotSupported","articleReadMoreText","spec","qspPrefix","memo","objectFromSpecification","values","requestDataValue","clientValue","pv","cv","qsp","ver","qp","verParam","current","newValue","recurse","prefix","k","currentPrefix","sort","getURLSearchParams","SSRContract","locationHash","hash","locationHost","locationHostName","locationPathName","locationProtocol","protocol","CSS","supports","documentElement","lang","direction","requestData","loadQueryParams","verifyDataExists","dataName","getContextData","dataGetter","throwException","IndexedDb","idb","searchObj","IDBObjectStore","getAll","idbPromise","req","withIdbStore","storeCallback","isGetAllAllowed","returnArray","openCursor","onsuccess","cursor","continue","put","clear","idbVersion","idbStoreName","dbName","preInitializedIdbPromise","storeName","endOpen","openreq","open","onupgradeneeded","createObjectStore","operationName","db","endOperation","transaction","oncomplete","onabort","objectStore","FastBreakpointManager","callbackMap","refreshBreakpoints","defaultBreakpoint","breakpoints","indexToStandardConverter","currentBreakpoint","isArray","pop","breakpoint","update","managerCallback","subscribe","unsubscribe","_fastBreakpointManager","fastBreakpointManager","recreate","feedServiceUrl","getServiceUrl","initializationLogs","initializeServiceRequest","EnterpriseServiceUrlBase","ServiceUrlBase","getFeedServiceUrl","initializeFeedServiceRequest","FeedServiceUrlBase","getServiceUrlForSubpath","getFeedServiceUrlForSubpath","authEnabled","trackingExperiences","shouldTrackExperience","shouldTrack","contract","parent","isRoot","ordinal","ordinalCount","createObjectId","setOrdinal","internalContract","lineage","lineageOrdinal","getLineage","placement","parentId","fullId","objectIdMapper","lastId","resetOrdinal","metadataAttribute","metadataObject","getItemById","delimeter","includeRootElement","outputObj","savedChildObject","option","mapObjectId","attr","a","b","getChildren","overrideId","_","isParentOf","jssGeneratedClassesMap","jssCaptureCompleted","removeRenderCache","removeSubstringKeys","captureJssGeneratedClasses","renderCacheEnabled","serverCache","ServerCache","cache","reset","del","itemCount","_fullNamespace","selectState","_subspace","_perfTimeline","addSubReducerForConnector","_configHref","getState","globalConnectors","globalConnector","namespaceParts","connectorType","DeferralEventType","DynamicBundles","dynamicBundles","bundle","registerExperience","es6Import","hasExperienceRegistered","CustomDeferralEventTypes","ExperienceDeferralEventTypes","experienceDeferralDependencyMap","isExperienceDependencyResolved","experienceDependency","deferralEventType","dependents","currentState","getMilestoneDataConnector","MilestoneData","getDefaultExperienceInstance","milestones","perExperienceMilestones","perInstanceMilestones","getExperienceLoadDelegate","deferralEventReady","loadAfter","aboveTheFoldVisuallyReady","isAboveTheFoldVisuallyReady","belowTheFoldTransitionStart","isBelowTheFoldTransitionStarted","getDeferralLoadEventReadyState","shouldLoad","getDeferralEventMetadata","waitForAboveTheFoldVisuallyReadyAsync","registerObserver","requestPageRevealStartedAsync","IsPrerender","pageReveal","Boolean","isPageRevealStarted","requestPageRevealCompletedAsync","isPageRevealCompleted","pageRevealStartedObserver","getExperienceRenderDelegate","renderAfter","getDeferralRenderEventReadyState","shouldRender","deferralInfo","StandardEventBasedDeferral","createExperienceStateUpdate","createTimingUpdate","pageRevealExperienceInfo","getCurrentPerformanceTimeStamp","timing","navigationStart","hasExperiencePersistentDataUpdated","storedExperiences","timeStamp","trackExpWithPersistentDataUpdate","trackPageInvalidation","time","getPeregrineFlights","cleanedUpFlights","lowercaseItem","currentTargetScope","configMap","promiseMap","stalenessCheckTimestamp","localOverrideMap","initializeIndexedDb","memoize","_initializeIndexedDb","populateConfigMapFromIndexedDbAsync","_populateConfigMapFromIndexedDbAsync","peregrineFlightsKey","initializeCaching","cdnConfigBaseUrl","ConfigRootUrl","EnvironmentConfigUrl","ConfigServiceBaseUrl","resolverErrors","configTimings","useWebWorkerToCache","indexedDb","useIndexedDb","enableIndexedDbInMainResolver","DisableCachingConfigs","isCachingAllowed","useServerCache","peregrineFlights","useConfigService","scopeWithPeregrineFlights","configServiceParameters","IsMultiConfigRetrievalEnabled","CacheBustingIdentifier","getConfigRetrievalMaxDepth","_cbid","containsDevOnlyQueryParameters","generateKey","configs","mergeWith","customizer","configPaths","experienceRef","targetScopeMatched","overrideConfig","audienceModeMatched","browserTypeMatched","deviceTypeMatched","domainMatched","experimentMatched","marketMatched","osMatched","pageTypeMatched","platformMatched","browserType","version","isString","experimentId","lhs","rhs","localeCompare","sensitivity","targetLocale","currentLocale","stringsEqualCaseInsensitive","srcValue","objValue","overrideEnv","relativeUrl","typeVersion","_name","cacheKey","getCacheKey","startGetConfig","configFromMemory","addConfigTiming","existingPromise","processed","configEndMeasure","configSource","serializedConfig","configFromServerCache","cacheFetchDuration","isServerCacheConfigStale","storageTimestamp","networkReadPromise","getConfigFromNetwork","networkConfig","readPromises","configFromMemoryAfterRace","mergedConfigsMap","configServiceRelativeUrl","removeCmsPathFromRelativeUrl","crsResponse","downloadFile","rootConfigIndexId","crsMergedConfig","configIndexKey","addConfigToConfigMap","crsConfig","cdnConfig","downloadMergeConfig","areConfigsEqual","experienceIndex","resolveConfigIndex","configObjects","downloadExperienceConfig","mergeConfig","baseConfigUrl","hrefs","promiseArray","fetch","ok","crsVersion","statusText","json","EnableConfigService","crsMaxDepth","segment","wwResponse","refreshConfigResponse","purgeRenderCacheUponConfigChanges","configsEqual","liveCbId","liveCbid","writeCbidInLocalStorage","pcsCbid","highestCbid","clearConfigCache","clearObjects","getAllConfigTimingsOverride","allConfigsCacheDuration","allConfigsNetworkDuration","configTiming","networkFetchDuration","IsDebug","configFetchTimings","clientSettingsCbid","cachedCbid","cacheSource","prgFlights","startBulkConfig","cachedConfigs","_idbConfigReadPromise","_idbConfigLookup","populateConfigMapFromCachedConfigs","_idbConfigOpenPromise","unusableCount","cachedConfig","isConfigStale","cbidKey","resolver","getConfigTimings","getResolverErrors","refreshConfigCache","overrideCurrentRequestTargetScope","overrideCurrentRequestEnvironment","clearInternalState","getConfigServiceParameters","setConfigTimingsObject","getHighestCbid","PerfMarkersGroup","remainingMarkers","remainingSecondaryMarkers","remainingTtvrMarkers","remainingTtprMarkers","ttvrMarkers","resolveTtvrCallback","perfMarkerResolveCallback","secondaryPerfMarkerResolveCallback","resolveTtvsCallback","ttprMarkerPromise","resolveTtprCallback","primaryMarkers","secondaryMarkers","markTtf","markTimeNA","setMark","markTtvr","markTtvrRaf","requestAnimationFrame","markTtprRaf","startMarker","perfMarks","getEntriesByName","getSinglePerfMarkStartTimeByName","waitForTtprMarkers","setSecondaryPerfMarkerTime","existingMarker","getSecondaryMarkers","markerFullName","getTtvrMarkers","getMarkers","getMarkersWithType","markerPrefix","maxValue","PerfTracker","InitialCommonExperienceProps","customField","visuallyReadyTracker","initializedTracker","domCompleteTracker","isStaleRevalidated","startInitializeMilestone","startVisuallyReadyMilestone","startDomCompleteMilestone","incrementExpCount","endDomCompleteMilestone","prevState","snapshot","completeStaleRevalidation","endInitializeMilestone","shouldMarkTelemetryTtvr","aliasName","endVisuallyReadyMilestone","setStart","updateStartTiming","updateEndTiming","markTimeToRevalidateStaleState","shouldMarkPageReveal","tracker","getStart","getEnd","setEnd","renderCounterPrefix","ClarityEnabled","functionalonly_cookie_experience","UrlSearchParamsHelper","parseQueryString","charAt","keyValuePairs","ImageServiceConfig","cachedDevicePixelRatio","ImageFormat","ImageResizeMode","HighEndImageQuality","generateImageUrlFromId","generateImageUrlFromBaseUrl","focalRegion","backgroundColor","format","JPG","auxQsp","focusX","midPoint","x1","x2","focusY","y1","y2","enableDpiScaling","pixelRatio","ceil","quality","max","floor","SocialMediaProviderConfig","SocialMedia","SocialMediaTarget","apiUrl","attribution","FacebookEmbed","InstagramEmbed","TwitterEmbed","SocialMediaDefaultConfig","Email","color","Mail","label","_self","Facebook","_blank","Line","LinkedIn","Skype","Twitter","WhatsApp","VK","Vkcom","PrimeIntegrationConstants","Mediator","getActiveTabValue","activeTabValue","navigation","activeTab","tabNameToTabId","registerForTabChangeEvent","shouldCallCallbackImmediately","sendActiveTabToCallback","None","tab","_perfMarker","tabIdToTabName","sub","registerContentActionsUpdatedEvent","registerCardActionEnableEvent","initData","registerCardActionPostEvent","postData","registerForFollowButtonClickEvent","followButtonData","topicId","isFollowed","registerForInterestsRenderCompleteEvent","registerSocialActionsUpdatedEvent","publishEventForPrime","pub","renderUserActionErrorCoachmark","refElement","hideCoachMark","coachMarkId","TabsHelper","tabId","tabName","anchor","autoFlipX","autoFocus","enable","left","onDismiss","staticPosition","zIndex","keyDownHandler","keyCode","focus","tabEventHandler","popOverRef","contains","activeElement","tabbable","shiftKey","preventDefault","determinePosition","getBoundingClientRect","scrollY","scrollX","createRef","zIndexStyle","onKeyDown","tabIndex","ref","popOver","getPlacementStyle","popOverPlaceholder","createPortal","pageDirection","position","windowWidth","documentHeight","offsetHeight","displayOnLeft","right","displayOnRight","displayOnPrioritySide","displayOnNonPrioritySide","rtl","canFitPrioritySide","canFitNonPrioritySide","PopOverStyles","Flyout","outline","visibility","from","opacity","to","transform","ZIndex","menuItems","enabled","buttonLabel","positionOffset","telemetryTag","handleUnfocus","node","containerRef","buttonContainerContainsNode","menuRef","parentNode","menuPopoverContainsNode","closeMenu","buttonRef","menuOpened","addEventListener","removeEventListener","menuContainer","settingButton","settingButtonIcon","onSettingClick","renderPopOver","dropDownLocation","isNil","contextMenu","enableAutoFocus","renderContextMenu","contextMenuItem","contextMenuItem_contentRegion","contextMenuItem_image","itemProps","onInvoke","onMenuItemClick","onSelect","text","onSelectCallback","posOffset","offsetX","offsetY","y","border","background","padding","outlineWidth","display","margin","ButtonStyle","button__justified","socialMedia","contentUrl","contentTitle","emailBody","hideLabel","socialMediaItemConfigOverride","onClickNewWindow","shareUrl","newWindowOptions","newWindowTelemetryCall","openNewWindow","itemConfig","getSocialMediaShareUrl","targetRelatedAtributes","newWindow","attributes","appearance","justified","jssStyleSheet","iconContainer","iconImage","iconLabel","ShallowCompare","ShareDialogColors","setStyleByZIndex","overrides","dialog_modalOverlay","dialog_contentRegion","StringResource","dialogButtonClose","dialogTitle","copyButton","copiedButton","copyButtonAriaLabel","copiedButtonAriaLabel","Dialog","dialog","bottom","Above","overflow","baseDialogProps","closeButtonTelemetryTags","closeButtonTelemetryObject","copyButtonAttributes","copyButtonTelemetryObject","copyButtonTelemetryTags","copyLinkOcid","dialogStrings","onClose","renderOneColLayout","socialMediaConfigOverride","socialMediaItems","shareIconTelemetryObject","shareIconTelemetryTags","baseDialogStyleOverride","inputRef","onCopyLinkToClipboard","isLinkCopied","execCommand","setSocialMediaItemsConfig","coerceDialogProps","dialogContainer","header","_7","tag","h3","headerText","closeButton","closeIcon","renderSocialIconsList","renderCopyLink","buttonText","copyTelemetryTag","inputContainer","copyLinkInput","readOnly","copyLinkButton","socialMediaIcons","renderSocialIcon","iconListContainer","socialMediaItem","media","mediaKey","iconTelemetryTags","iconListItem","socialMediaItemsConfig","keyLower","visible","modal","contentHeight","contentWidth","fallbackStyles","backgroundStyle","semibold","float","TelemetryBase","sendSinglePageViewBeacon","ArticleCard","anchorRef","headlineTitle","provider","nextProps","articleCard","renderContent","articleCard_content","renderImage","articleCard_textWrapper","renderTitle","renderProvider","articleCard_imageWrapper","articleCard_image","articleCard_imageOverlay","articleCard_headline","articleCard_headlineText","articleCard_headlineMask","providerImage","articleCard_providerImage","articleCard_provider","articleCard_providerTitle","SharedDocumentType","SharingHelper","sharingInfo","appId","getAppId","getSharingUrlBase","sharingUrl","shortUrlPathFormat","documentType","documentId","AppKeys","Base36AppIdString","substr","articleUrl","currentBaseUrl","SharingProductionHosts","SharingBaseUrlDefault","overrideShareUrl","socialMediaItemConfig","appendQueryStringFormat","Format","refererUrl","options","finalOptions","toolbar","resizable","scrollbars","BreakpointIndexToPx","ToolbarBreakpoints","TelemetryConstants","PlaceHolderId","LikeDislikeActionKey","SelectPropKey","Status","ButtonType","ContentActionsToolbarActions","initializeToolbar","ContentStatuReady","documentDataReady","likeContent","unlikeContent","dislikeContent","undislikeContent","sharingToolbarError","ViewportUpdate","moreOptionsIconColors","likeDislikeIconBackroundColor","moreOptionsMenuDefaultOffsetPos","OptionItemLike","like","OptionItemDislike","dislike","Disliked","OptionItemUndoLike","undoliked","OptionItemUndoDislike","undodisliked","inspect","localizedStrings","isContentStatusRequired","connectorArgs","sharingToolbar","sharingButtons","contentStatus","sharingError","sharingShortUrl","documentData","articleTitle","articleImageUrl","providerName","providerLogoUrl","buttonItem","newButtonItem","buttonType","buttonData","emailBodyText","ShareDialog","shareDialogProps","shareDialogTitleText","shareDialogCopyButtonText","shareDialogCopyButtonAriaLabelText","shareDialogCopiedButtonText","shareDialogCopiedButtonAriaLabelText","dialogArticleCardProps","articleId","alt","shareDialogButtonAriaLabelText","LikeDislike","likeDislikeButtonAriaLabelText","MoreOptions","moreOptionsUnlikeText","moreOptionsUnlikeAriaLabelText","moreOptionsDislikeText","moreOptionsDislikeAriaLabelText","DisLike","moreOptionsUndislikeText","moreOptionsUndislikeAriaLabelText","moreOptionsLikeText","moreOptionsLikeAriaLabelText","moreOptionsButtonAriaLabelText","offsetPos","missingChildren","fetchImpl","contentActionsServiceEndpoint","contentPreviewApiEndpoint","targetId","GetContentStatusRequest","isLike","actionType","isDislike","contentPreviewData","GetContentPreviewData","TranslateContentPreviewDocumentData","PostContentActionRequest","DeleteContentActionRequest","requestParams","credentials","contentStatusData","pair","ContentServiceUrlBase","deleteQueryParam","deleteResponse","targetType","postResponse","articleDataResponse","articleImageId","providerLogoId","some","contentActionsToolbarConnectorArgs","inspectorArgs","contentActionsToolbarProps","inspectorResponse","likeDislikeCallbacks","BuildLikeDislikeCallbacks","InjectCallbacksToMoreOptionsMenu","onDislike","onLike","sharingToolbarTelemetryObject","button","buttonTelemetryName","mediaType","sendActionEvent","currentTarget","mediaTelemetryObject","userFacingText","copyLinkTelemetryName","closeDialogTelemetryName","mediaItem","mediaItemOverride","shareDialogTelemetryObject","shareDialogTelemetryName","articleTelemetryTags","shareArticleTelemetryName","InjectTelemetry","rootTelemetryTags","sharingToolbarTelemetryTags","contentId","isRSThree","CMS","actionServiceClient","generateTelemetryTags","getContentStatus","getDocumentData","initializeBreakpointTracker","GetPreferenceInitialState","GetDocumentData","shortUrlBuilder","moreOptionsButton","callbacks","socialToolbarTelemetryName","moreOptionsTelemetryTags","UndoLike","UndoDislike","ToolbarPosition","handleAction","breakpointIndex","isRSThreeDevice","getToolbarPosition","Breakpoint3_2","Breakpoint3_3","vertical","horizontal","SharingToolbarStyles","icon_none","icon_like","icon_dislike","iconListHorizontal","iconListVertical","shareDialog","highContrast","moreOptions","iconContainerDimension","contextMenuStyles","e11","Scale","coerceTitleProps","coerceProviderProps","articleCard_noImage","coercedProps","_6","coercedProviderNameProps","_8","h5","flex","onShareDialogOpen","shareDialogOpened","onShareDialogClose","managedClass","appendHighContrastStyle","shareDialogButtonRef","getPositioningClassName","renderSharingButtons","renderShareDialog","buttonId","listItem","renderSocialMediaIcon","renderShareDialogIcon","renderLikeDislikeIcon","renderMoreOptionsIcon","shareDialogItem","articleCardStylesheet","LikedText","LikeText","DislikeText","iconClassName","BaseExperience","firstRenderCompleted","contentActionsToolbar","componentDidUpdate","shouldFlip","flipToolbar","contentActionsToolbar_horizontal","contentActionsToolbar_vertical","currentHostId","hostElem","prevHostId","newHostId","prevHostElem","newHostElem","childNodes","defaultProps","RequestContext","start","setupContentActionsInitialState","cmsDocumentId","documentid","isrsthree","verticalkey","categorykey","connectContentActionsComponent","contentActionsToolbarConfig","contentActionsExperience","renderRootElement","contentActionsConfig","catch"],"mappings":"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uB,GAAK,uBAAuB,GAAK,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAAuB,IAAM,uBAA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3CC,EAAOD,QAAU,IAA0B,wB,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,uB,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,c,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,c,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,c,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,yB,gBCA3CC,EAAOD,QAAU,IAA0B,0B,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,yB,gBCA3CC,EAAOD,QAAU,IAA0B,W,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,c,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,yB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,yB,gBCA3CC,EAAOD,QAAU,IAA0B,wB,gBCA3CC,EAAOD,QAAU,IAA0B,wB,gBCA3CC,EAAOD,QAAU,IAA0B,yB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,+B,gBCA3CC,EAAOD,QAAU,IAA0B,gC,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,c,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,0B,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,wB,gBCA3CC,EAAOD,QAAU,IAA0B,8B,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,yB,gBCA3CC,EAAOD,QAAU,IAA0B,4B,gBCA3CC,EAAOD,QAAU,IAA0B,4B,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,yB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,c,gBCA3CC,EAAOD,QAAU,IAA0B,uB,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,c,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,uB,gBCA3CC,EAAOD,QAAU,IAA0B,4B,gBCA3CC,EAAOD,QAAU,IAA0B,yB,gBCA3CC,EAAOD,QAAU,IAA0B,yB,gBCA3CC,EAAOD,QAAU,IAA0B,8B,gBCA3CC,EAAOD,QAAU,IAA0B,2B,gBCA3CC,EAAOD,QAAU,IAA0B,W,gBCA3CC,EAAOD,QAAU,IAA0B,c,gBCA3CC,EAAOD,QAAU,IAA0B,c,gBCA3CC,EAAOD,QAAU,IAA0B,W,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,iB,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,2B,gBCA3CC,EAAOD,QAAU,IAA0B,wB,gBCA3CC,EAAOD,QAAU,IAA0B,wB,gBCA3CC,EAAOD,QAAU,IAA0B,6B,gBCA3CC,EAAOD,QAAU,IAA0B,0B,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,0B,gBCA3CC,EAAOD,QAAU,IAA0B,+B,gBCA3CC,EAAOD,QAAU,IAA0B,4B,gBCA3CC,EAAOD,QAAU,IAA0B,iC,gBCA3CC,EAAOD,QAAU,IAA0B,8B,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,c,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,c,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,2B,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,yB,gBCA3CC,EAAOD,QAAU,IAA0B,0B,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,2B,gBCA3CC,EAAOD,QAAU,IAA0B,wB,gBCA3CC,EAAOD,QAAU,IAA0B,wB,gBCA3CC,EAAOD,QAAU,IAA0B,6B,gBCA3CC,EAAOD,QAAU,IAA0B,0B,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,sB,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,kB,gBCA3CC,EAAOD,QAAU,IAA0B,Y,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,0B,gBCA3CC,EAAOD,QAAU,IAA0B,uB,gBCA3CC,EAAOD,QAAU,IAA0B,gB,gBCA3CC,EAAOD,QAAU,IAA0B,e,gBCA3CC,EAAOD,QAAU,IAA0B,oB,gBCA3CC,EAAOD,QAAU,IAA0B,qB,gBCA3CC,EAAOD,QAAU,IAA0B,mB,gBCA3CC,EAAOD,QAAU,IAA0B,a,gBCA3CC,EAAOD,Q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EAAYn/D,IAAIU,OAwC7B2gC,IAhCJ,SAAmB3gC,G,mDACf,aAAay+D,EAAY99B,IAAI3gC,OAgC7B6+D,IAxBJ,SAAmB7+D,G,mDACf,aAAay+D,EAAYI,IAAI7+D,OAwB7B8+D,UAjBJ,W,mDACI,aAAaL,EAAYK,iBAoBzBloC,EAAiB,WAAM,eAKvB8nC,EAAYz0B,WAAW,IAAI,O,+CC5F/B,IAAY2d,EAPZ,kCAOA,SAAYA,GACR,sBACA,wBACA,0CACA,gDACA,4CACA,oDACA,gCACA,0BACA,4BACA,kCACA,8BACA,wDACA,8CACA,sCACA,0BACA,oBACA,8BACA,0BACA,wBACA,oBACA,sBACA,8BACA,gDACA,wCACA,kCACA,oCACA,kCACA,gDACA,gDACA,0BACA,8BACA,0BACA,4BACA,2BACA,0BACA,gEACA,0BACA,8BACA,sBACA,kCACA,kDACA,oDACA,4CACA,wCACA,4CACA,0CACA,0DACA,0BACA,0CACA,sCACA,oCACA,8BACA,kDACA,sCACA,0BACA,4BACA,kCACA,0BACA,kCACA,8BACA,8BACA,wCACA,wCACA,0CACA,oDACA,wDACA,8CACA,sCACA,wCACA,4BACA,wCACA,kCACA,8CACA,gCACA,sBACA,kBACA,sBACA,wBACA,oCACA,0CACA,4BACA,kCACA,kCACA,8CACA,wBACA,wCACA,4CACA,sCACA,sCACA,kCACA,wBACA,sBACA,oBACA,gCACA,wCACA,sCACA,sBACA,oBACA,4CACA,wBACA,0BACA,kCACA,wBACA,sCACA,sBACA,4BACA,sCACA,oCACA,kBACA,oCACA,0CACA,8CACA,wBACA,oBACA,4CACA,4BACA,gCACA,8BACA,kCACA,0BACA,wBACA,4BACA,wBACA,oCACA,oCACA,4BACA,8CACA,oCACA,8CACA,wCACA,oEACA,wDACA,sCACA,wCACA,4CACA,wBACA,wCACA,gBACA,sCACA,oCACA,gCACA,wCACA,4CACA,wCACA,gDACA,wCACA,0CACA,8BACA,4CACA,gCACA,kDACA,8CACA,oCACA,4BACA,8CACA,4CACA,sCACA,4CACA,wC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","file":"content-actions-toolbar.27f3893916640c626e37.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t23: 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// script path function\n \tfunction jsonpScriptSrc(chunkId) {\n \t\treturn __webpack_require__.p + \"\" + ({\"96\":\"icon-assets-Accounts\",\"97\":\"icon-assets-AdChoices\",\"98\":\"icon-assets-AlertWhite\",\"99\":\"icon-assets-BingCardDefaultHotelImage\",\"100\":\"icon-assets-BingHotelSeePrice\",\"101\":\"icon-assets-BingLogo\",\"102\":\"icon-assets-BingRatingDarkLightStar\",\"103\":\"icon-assets-BingRatingDarkStar\",\"104\":\"icon-assets-BingRatingLightStar\",\"105\":\"icon-assets-BlowingHail\",\"106\":\"icon-assets-BlowingHailV2\",\"107\":\"icon-assets-BlowingHailWhite\",\"108\":\"icon-assets-BlowingSnow\",\"109\":\"icon-assets-BlowingSnowV2\",\"110\":\"icon-assets-BlowingSnowWhite\",\"111\":\"icon-assets-CDCLogo\",\"112\":\"icon-assets-Check\",\"113\":\"icon-assets-Chevron\",\"114\":\"icon-assets-ChevronDown\",\"115\":\"icon-assets-ChevronRight\",\"116\":\"icon-assets-ChevronWhite\",\"117\":\"icon-assets-CircleChevron\",\"118\":\"icon-assets-CircleClose\",\"119\":\"icon-assets-ClearNight\",\"120\":\"icon-assets-ClearNightV2\",\"121\":\"icon-assets-ClearNightWhite\",\"122\":\"icon-assets-ClinicalTrialBot\",\"123\":\"icon-assets-Close\",\"124\":\"icon-assets-CloseThin\",\"125\":\"icon-assets-Cloudy\",\"126\":\"icon-assets-CloudyV2\",\"127\":\"icon-assets-CloudyWhite\",\"128\":\"icon-assets-Comment\",\"129\":\"icon-assets-Copy\",\"130\":\"icon-assets-DarkModeHotel\",\"131\":\"icon-assets-DayTime\",\"132\":\"icon-assets-Delete\",\"133\":\"icon-assets-Discover\",\"134\":\"icon-assets-Dislike\",\"135\":\"icon-assets-DislikeText\",\"136\":\"icon-assets-Disliked\",\"137\":\"icon-assets-DislikedLight\",\"138\":\"icon-assets-DislikedText\",\"139\":\"icon-assets-Docx\",\"140\":\"icon-assets-DoubleTap\",\"141\":\"icon-assets-Download\",\"142\":\"icon-assets-DownloadNoFill\",\"143\":\"icon-assets-Edit\",\"144\":\"icon-assets-EditNoFill\",\"145\":\"icon-assets-Edited\",\"146\":\"icon-assets-EditedNoFill\",\"147\":\"icon-assets-Ellipses\",\"148\":\"icon-assets-EllipsesLight\",\"149\":\"icon-assets-EmptyDiscoverDark\",\"150\":\"icon-assets-EmptyDiscoverLight\",\"151\":\"icon-assets-EmptyMruDark\",\"152\":\"icon-assets-EmptyMruLight\",\"153\":\"icon-assets-EmptyPinnedDark\",\"154\":\"icon-assets-EmptyPinnedLight\",\"155\":\"icon-assets-EmptySharedDark\",\"156\":\"icon-assets-EmptySharedLight\",\"157\":\"icon-assets-Excel\",\"158\":\"icon-assets-Facebook\",\"159\":\"icon-assets-FacebookCircle\",\"160\":\"icon-assets-FacebookText\",\"161\":\"icon-assets-FacebookTextBlack\",\"162\":\"icon-assets-Fog\",\"163\":\"icon-assets-FogV2\",\"164\":\"icon-assets-FogWhite\",\"165\":\"icon-assets-Folder\",\"166\":\"icon-assets-FolderNoFill\",\"167\":\"icon-assets-FolderOpen\",\"168\":\"icon-assets-Form\",\"169\":\"icon-assets-Forward\",\"170\":\"icon-assets-FreezingRain\",\"171\":\"icon-assets-FreezingRainV2\",\"172\":\"icon-assets-FreezingRainWhite\",\"173\":\"icon-assets-GalleryFullscreen\",\"174\":\"icon-assets-GalleryMediaIcon\",\"175\":\"icon-assets-GeneralErrorDark\",\"176\":\"icon-assets-GeneralErrorLight\",\"177\":\"icon-assets-GenericFile\",\"178\":\"icon-assets-GridView\",\"179\":\"icon-assets-HailDay\",\"180\":\"icon-assets-HailDayV2\",\"181\":\"icon-assets-HailDayWhite\",\"182\":\"icon-assets-HailNight\",\"183\":\"icon-assets-HailNightV2\",\"184\":\"icon-assets-HailNightWhite\",\"185\":\"icon-assets-HazeSmoke\",\"186\":\"icon-assets-HazeSmokeV2\",\"187\":\"icon-assets-HazeSmokeWhite\",\"188\":\"icon-assets-HeavySnow\",\"189\":\"icon-assets-HeavySnowV2\",\"190\":\"icon-assets-HeavySnowWhite\",\"191\":\"icon-assets-Hide\",\"192\":\"icon-assets-HideStory\",\"193\":\"icon-assets-HideStoryV2\",\"194\":\"icon-assets-Hotel\",\"195\":\"icon-assets-Hurricane\",\"196\":\"icon-assets-Hurricane1\",\"197\":\"icon-assets-Hurricane2\",\"198\":\"icon-assets-Hurricane3\",\"199\":\"icon-assets-Hurricane4\",\"200\":\"icon-assets-Hurricane5\",\"201\":\"icon-assets-HurricaneFull\",\"202\":\"icon-assets-HurricaneTC\",\"203\":\"icon-assets-HurricaneTD\",\"204\":\"icon-assets-HurricaneTS\",\"205\":\"icon-assets-Information\",\"206\":\"icon-assets-InteractionRequiredDark\",\"207\":\"icon-assets-InteractionRequiredLight\",\"208\":\"icon-assets-Interested\",\"209\":\"icon-assets-Layout\",\"210\":\"icon-assets-LightRain\",\"211\":\"icon-assets-LightRainV2\",\"212\":\"icon-assets-LightRainWhite\",\"213\":\"icon-assets-LightSnow\",\"214\":\"icon-assets-LightSnowV2\",\"215\":\"icon-assets-LightSnowWhite\",\"216\":\"icon-assets-Like\",\"217\":\"icon-assets-LikeText\",\"218\":\"icon-assets-Liked\",\"219\":\"icon-assets-LikedText\",\"220\":\"icon-assets-Line\",\"221\":\"icon-assets-Link\",\"222\":\"icon-assets-LinkedIn\",\"223\":\"icon-assets-LinkedInBlack\",\"224\":\"icon-assets-LinkedInText\",\"225\":\"icon-assets-ListMenu\",\"226\":\"icon-assets-Locate\",\"227\":\"icon-assets-LocateWhite\",\"228\":\"icon-assets-LocationDetect\",\"229\":\"icon-assets-Mail\",\"230\":\"icon-assets-MailBlack\",\"231\":\"icon-assets-MailNoFill\",\"232\":\"icon-assets-MailRoundedCorners\",\"233\":\"icon-assets-ManagedBriefcase\",\"234\":\"icon-assets-ManagedBriefcaseNoFill\",\"235\":\"icon-assets-MapZoomIn\",\"236\":\"icon-assets-MapZoomOut\",\"237\":\"icon-assets-Message\",\"238\":\"icon-assets-MessageNoFill\",\"239\":\"icon-assets-Messages\",\"240\":\"icon-assets-MicrosoftLogo\",\"241\":\"icon-assets-MicrosoftNews\",\"242\":\"icon-assets-MicrosoftNews_FR\",\"243\":\"icon-assets-MicrosoftNews_ZH\",\"244\":\"icon-assets-ModerateRain\",\"245\":\"icon-assets-ModerateRainV2\",\"246\":\"icon-assets-ModerateRainWhite\",\"247\":\"icon-assets-More\",\"248\":\"icon-assets-Movie\",\"249\":\"icon-assets-MsnLogo\",\"250\":\"icon-assets-NewsArticle\",\"251\":\"icon-assets-NightTime\",\"252\":\"icon-assets-Notification-Five-Plus-Sign\",\"253\":\"icon-assets-Office\",\"254\":\"icon-assets-OfficeFormsLogo\",\"255\":\"icon-assets-OneDrive\",\"256\":\"icon-assets-OneNote\",\"257\":\"icon-assets-Onetoc\",\"258\":\"icon-assets-Open\",\"259\":\"icon-assets-OpenSquared\",\"260\":\"icon-assets-Outlook\",\"261\":\"icon-assets-PartlyCloudyDay\",\"262\":\"icon-assets-PartlyCloudyDayV2\",\"263\":\"icon-assets-PartlyCloudyDayWhite\",\"264\":\"icon-assets-PartlyCloudyNight\",\"265\":\"icon-assets-PartlyCloudyNightV2\",\"266\":\"icon-assets-PartlyCloudyNightWhite\",\"267\":\"icon-assets-Pdf\",\"268\":\"icon-assets-Pencil\",\"269\":\"icon-assets-People\",\"270\":\"icon-assets-Pin\",\"271\":\"icon-assets-PowerBI\",\"272\":\"icon-assets-PowerPoint\",\"273\":\"icon-assets-Pptx\",\"274\":\"icon-assets-PriceDrop\",\"275\":\"icon-assets-PriceDropBlue\",\"276\":\"icon-assets-Project\",\"277\":\"icon-assets-Radar\",\"278\":\"icon-assets-RainShowersDay\",\"279\":\"icon-assets-RainShowersDayV2\",\"280\":\"icon-assets-RainShowersDayWhite\",\"281\":\"icon-assets-RainShowersNight\",\"282\":\"icon-assets-RainShowersNightV2\",\"283\":\"icon-assets-RainShowersNightWhite\",\"284\":\"icon-assets-RainSnow\",\"285\":\"icon-assets-RainSnowShowersDay\",\"286\":\"icon-assets-RainSnowShowersDayWhite\",\"287\":\"icon-assets-RainSnowShowersNight\",\"288\":\"icon-assets-RainSnowShowersNightV2\",\"289\":\"icon-assets-RainSnowShowersNightWhite\",\"290\":\"icon-assets-RainSnowV2\",\"291\":\"icon-assets-RainSnowWhite\",\"292\":\"icon-assets-Refresh\",\"293\":\"icon-assets-Remove\",\"294\":\"icon-assets-Save\",\"295\":\"icon-assets-Saved\",\"296\":\"icon-assets-Search\",\"297\":\"icon-assets-SetHome\",\"298\":\"icon-assets-Share\",\"299\":\"icon-assets-ShareLight\",\"300\":\"icon-assets-ShareNoFill\",\"301\":\"icon-assets-ShareRoundedCorners\",\"302\":\"icon-assets-Sharepoint\",\"303\":\"icon-assets-Shopping\",\"304\":\"icon-assets-ShoppingDealsDark\",\"305\":\"icon-assets-ShoppingDealsLight\",\"306\":\"icon-assets-Skype\",\"307\":\"icon-assets-SkypeOffice\",\"308\":\"icon-assets-SnowShowersDay\",\"309\":\"icon-assets-SnowShowersDayV2\",\"310\":\"icon-assets-SnowShowersDayWhite\",\"311\":\"icon-assets-SnowShowersNight\",\"312\":\"icon-assets-SnowShowersNightV2\",\"313\":\"icon-assets-SnowShowersNightWhite\",\"314\":\"icon-assets-Star\",\"315\":\"icon-assets-StarFill\",\"316\":\"icon-assets-StarFollow\",\"317\":\"icon-assets-StarFollowBlue\",\"318\":\"icon-assets-Stars\",\"319\":\"icon-assets-SunnyDay\",\"320\":\"icon-assets-SunnyDayV2\",\"321\":\"icon-assets-SunnyDayWhite\",\"322\":\"icon-assets-Sway\",\"323\":\"icon-assets-SwayApp\",\"324\":\"icon-assets-Teams\",\"325\":\"icon-assets-ThumbnailView\",\"326\":\"icon-assets-Thunderstorms\",\"327\":\"icon-assets-ThunderstormsV2\",\"328\":\"icon-assets-ThunderstormsWhite\",\"329\":\"icon-assets-Trending\",\"330\":\"icon-assets-Twitter\",\"331\":\"icon-assets-TwitterBlack\",\"332\":\"icon-assets-TwitterNoFill\",\"333\":\"icon-assets-TwitterText\",\"334\":\"icon-assets-Unpin\",\"335\":\"icon-assets-VerticalSeparator\",\"336\":\"icon-assets-Video\",\"337\":\"icon-assets-VideoFallback\",\"338\":\"icon-assets-VideoMediaIcon\",\"339\":\"icon-assets-VideoPlay\",\"340\":\"icon-assets-Visio\",\"341\":\"icon-assets-Vkcom\",\"342\":\"icon-assets-Vsdx\",\"343\":\"icon-assets-WaterDrop\",\"344\":\"icon-assets-WaterDropL2\",\"345\":\"icon-assets-WeatherAlert\",\"346\":\"icon-assets-WeatherBarometer\",\"347\":\"icon-assets-WeatherCloud\",\"348\":\"icon-assets-WeatherDewpoint\",\"349\":\"icon-assets-WeatherExpand\",\"350\":\"icon-assets-WeatherIcon\",\"351\":\"icon-assets-WeatherMapPause\",\"352\":\"icon-assets-WeatherMapPlay\",\"353\":\"icon-assets-WeatherPrecipitation\",\"354\":\"icon-assets-WeatherSatellite\",\"355\":\"icon-assets-WeatherTemperature\",\"356\":\"icon-assets-WeatherVisiblity\",\"357\":\"icon-assets-WeatherWind\",\"358\":\"icon-assets-WeatherWindDir\",\"359\":\"icon-assets-WeeklyAdsDark\",\"360\":\"icon-assets-WeeklyAdsLight\",\"361\":\"icon-assets-WhatsApp\",\"362\":\"icon-assets-WhatsAppBlack\",\"363\":\"icon-assets-Windy\",\"364\":\"icon-assets-WindyV2\",\"365\":\"icon-assets-WindyWhite\",\"366\":\"icon-assets-Word\",\"367\":\"icon-assets-World\",\"368\":\"icon-assets-Xlsx\",\"369\":\"icon-assets-Yammer\",\"370\":\"icon-coronavirus-icon\",\"371\":\"icon-poll-results\"}[chunkId]||chunkId) + \".\" + {\"96\":\"9e93dd46b7fd7060c30c\",\"97\":\"d980e8d00c24297263bc\",\"98\":\"9e6d10633c91c453cbfb\",\"99\":\"5935df70c9d338f8bb42\",\"100\":\"dc58d0b4fd90a491f6b4\",\"101\":\"9318d5915ad038c0002b\",\"102\":\"65a45cdce4d0e4a76731\",\"103\":\"dbb0bdf67372153e0c12\",\"104\":\"0c1b0b0334c13020ac88\",\"105\":\"bdb74e85f7f2f529b8da\",\"106\":\"b2629128942185c7db2c\",\"107\":\"32d2f82adac118cd3909\",\"108\":\"e5cd8f0e989ea195c388\",\"109\":\"dcacb7f483045f954927\",\"110\":\"85acb54303671d00db30\",\"111\":\"57f7054057bb2051300a\",\"112\":\"f37de3f06b8333f14615\",\"113\":\"a7bc090a2cbe45384c36\",\"114\":\"eb3c99230b8dd53bfce0\",\"115\":\"a8695252330fd4389834\",\"116\":\"c096de714e579e4b85ab\",\"117\":\"e7c77da481966a8e23e9\",\"118\":\"cea6df127bab48eefd8b\",\"119\":\"8e8fe159ad6ad67385ae\",\"120\":\"60b9f14e47dacd8c52bc\",\"121\":\"a1d47bd0850df2effd45\",\"122\":\"cb8f2edbfcd997e19c7a\",\"123\":\"98344bec1faf01379431\",\"124\":\"a8a09efc8f9c1dbb00f9\",\"125\":\"34fca1e3f2b9ca1f9dc8\",\"126\":\"ce6889ec4232fbfe0aee\",\"127\":\"0f8144868cc1ee2dde1d\",\"128\":\"0b60c5f1b9861f5295c7\",\"129\":\"d18894ecbdc353e088aa\",\"130\":\"ab8afdf7d59a1dc9faee\",\"131\":\"63bfbb9ecb9589112fe4\",\"132\":\"3008992ed84c17b4ec2f\",\"133\":\"0fd9fe174d86a225a21a\",\"134\":\"559f5169fefac532cbd1\",\"135\":\"9a5a7781b9dc08363438\",\"136\":\"35c5ac0081c0ca64752b\",\"137\":\"3a3a1c7da4f72a5e1886\",\"138\":\"25b7986e3c53e3d91220\",\"139\":\"19bddb5b33452a76fcba\",\"140\":\"411733f05f0f83bbb147\",\"141\":\"790bde7961d53fbdebf4\",\"142\":\"56b974e6baca20f2e883\",\"143\":\"8d5a03c9d849336eaecf\",\"144\":\"6c7dc9f1cf98d1e6a799\",\"145\":\"d0759cd8e9da1732d7e4\",\"146\":\"e7cc18028d3391160fe3\",\"147\":\"92668da4c010383eb874\",\"148\":\"19f2a64aa83ab827e80e\",\"149\":\"3abdbd931dad22818111\",\"150\":\"702a789a3fa5da97b7ae\",\"151\":\"dbbae466087890897586\",\"152\":\"da7b28d796821ef57769\",\"153\":\"f99ad4bdb4b692c187dd\",\"154\":\"7d8e9b9fd88d3cc655c5\",\"155\":\"401d0b58396003f23a87\",\"156\":\"1347f80c67e4f2224f9d\",\"157\":\"babaad17e295097e821e\",\"158\":\"844ed8a0f64e4df7683e\",\"159\":\"02cdbb7eba7e5278efaa\",\"160\":\"b573da28083dce7c7b96\",\"161\":\"100786b2a89003e62b4a\",\"162\":\"88457902f8b90a5c5674\",\"163\":\"1f0794de693a0773c0f8\",\"164\":\"a1b3e4eff0894d135a8d\",\"165\":\"81f89fb12ce7364dc0ca\",\"166\":\"cb5dd3ab858f46c4ff78\",\"167\":\"91ae3d92650d5f94cb45\",\"168\":\"3fec68be0ed0f476c8c1\",\"169\":\"23f3aedae20ab6a51fb5\",\"170\":\"3727a22911f8198503a4\",\"171\":\"e73c25f9bc36641739d4\",\"172\":\"49abbedb4e3223f7469a\",\"173\":\"10546269dd271cca497e\",\"174\":\"e9908c4128fc3bd7c5bd\",\"175\":\"c30b67b93dcaee5db2b3\",\"176\":\"a5ad2eac6ad2099389b2\",\"177\":\"644da0c60428a887ece8\",\"178\":\"4653da8f9c45abb3d01f\",\"179\":\"a1b9357569c58d70743d\",\"180\":\"12a4a51c3580e5296edc\",\"181\":\"2fb839425a4da0fc9a08\",\"182\":\"ccd465bc3befb4639fb5\",\"183\":\"e00f68ac45a9691eefc1\",\"184\":\"e00fdff93f7849b515d3\",\"185\":\"5baef474f8194af75404\",\"186\":\"61d43c2e18ccdeeb0bf2\",\"187\":\"71ca73ff1bcc26bf9e3b\",\"188\":\"6ba28241ad134c595123\",\"189\":\"d0fe884c3fa1a5a3ef0b\",\"190\":\"75dbde35be5cde3c0dff\",\"191\":\"f3c5a99091e4da5276b7\",\"192\":\"f378d73d46fd7357154e\",\"193\":\"baa6e19f775aa170eeaa\",\"194\":\"d3d122f8a9a02bb75f18\",\"195\":\"5a8ddfc9efc8b94cbba8\",\"196\":\"7a38a2ea8d6ed9086398\",\"197\":\"dfee3329b008ba7fa71a\",\"198\":\"f39d52e912f6b50c6cde\",\"199\":\"5c74b6d763122ca85f81\",\"200\":\"15ee55caf6a4cbe05714\",\"201\":\"a0fcc4a798562c13f1ee\",\"202\":\"ba02ffe9dac8072e2781\",\"203\":\"4439056efb2ba6dd61f2\",\"204\":\"206d94f19dcbc77dab0a\",\"205\":\"d674af68f174396ea735\",\"206\":\"b460be6c7137f16eeec7\",\"207\":\"ca78e16e987300471814\",\"208\":\"24126d16b5e831c48bc4\",\"209\":\"8b874327123970d44484\",\"210\":\"53d992c0f6011a68c872\",\"211\":\"991f25a1e4c47096fd71\",\"212\":\"4e4d72480b465098d1b9\",\"213\":\"4ed6f1e96724176f8cde\",\"214\":\"3be791c0c9d5c2c7560e\",\"215\":\"711072c2f7e9d0cc64da\",\"216\":\"a936d12e19a07868aaa8\",\"217\":\"a2246acbb13ddaaeff7c\",\"218\":\"88effad4ffc4ff175b5d\",\"219\":\"9b235308faf3455e3ae3\",\"220\":\"ef87a4322209cd9ac4e0\",\"221\":\"7d9dc2879b64601e9730\",\"222\":\"ba264bb914e774e1dbb2\",\"223\":\"f1490cdcd54f82cd89cb\",\"224\":\"094e1aa9c9699a37159b\",\"225\":\"6373b1f724c6285caea1\",\"226\":\"766c20b65fcdbc538e5f\",\"227\":\"63cc0b74cab47fd88b23\",\"228\":\"67839851bc3ca647e536\",\"229\":\"531f76a75e4baf58ebb7\",\"230\":\"0cf362fb2ab677bcbc64\",\"231\":\"5e254b4e9f35455e09e9\",\"232\":\"75cf66f149b4145dd7a6\",\"233\":\"85152a365aac1f0747cd\",\"234\":\"e91ed636eb5f001af88a\",\"235\":\"df6ec7707d5639a25dd0\",\"236\":\"9a040ef1c21bde27aa66\",\"237\":\"8692b3386dbbb919e034\",\"238\":\"81dc16b6462455ee7a82\",\"239\":\"c904a84fdff69651dd1f\",\"240\":\"3d9f72175a5e14242738\",\"241\":\"b4ad6bc1e93ae0efdb31\",\"242\":\"476a7c504c65f463f3e1\",\"243\":\"4e1592e5f4bc282e99ef\",\"244\":\"f917f291c1b9cd8e75e2\",\"245\":\"84effd00a07a8109e456\",\"246\":\"887ac8d0ef3b3ae953c1\",\"247\":\"6b8744fe683560b0e2ec\",\"248\":\"9e0f6a4e60fa2675bbae\",\"249\":\"461f1d70bc525f1b661e\",\"250\":\"17f72fadfff3b701fbc1\",\"251\":\"172a6d8b5f22bce38b4f\",\"252\":\"f5ccac74f4e1747d419b\",\"253\":\"fcf58d2537b6f67e8e6a\",\"254\":\"2adece4239c6a3b21751\",\"255\":\"f91eadb57355132b2054\",\"256\":\"dfe5c49fe639341253c8\",\"257\":\"7a46c72b397018186ebe\",\"258\":\"0e8b2038efe3b1859f0c\",\"259\":\"71c7dfb1ebdd6021c80c\",\"260\":\"e87c84432c8586b34024\",\"261\":\"b2fc0aab1375f8a6eeb6\",\"262\":\"1d82526719b827c9b7ce\",\"263\":\"922e6aebcc50b9c16812\",\"264\":\"3429abf50943a8c8483b\",\"265\":\"8e88d473314ac10bcd38\",\"266\":\"170b85f6fdcdd26a57b1\",\"267\":\"9070a355ba9777c40d55\",\"268\":\"94b1228876a1090b29ad\",\"269\":\"916e91a26ce6f75132ed\",\"270\":\"75b2063787a847be775d\",\"271\":\"0104c0e3e339bdef49de\",\"272\":\"f13b8a4407439b0e4b98\",\"273\":\"d7d29dd9d76c47fa43b5\",\"274\":\"04f36bc514b43a74e3f8\",\"275\":\"a10834dedb806dda26f0\",\"276\":\"344f1cd7eca169767b96\",\"277\":\"71ba085644e1b6f7c925\",\"278\":\"4c0afb584e4bc7084f22\",\"279\":\"f1fe7c327678e1f8d924\",\"280\":\"1b9db1dab96247ac1227\",\"281\":\"1cd3f8b4c4de0246b7d1\",\"282\":\"aaefbb93e26cd09ddaf3\",\"283\":\"0fc97bdfd596f02c120a\",\"284\":\"31e5357bb4ddae64c749\",\"285\":\"0e3c49184c3d700c2422\",\"286\":\"9e753bf50345aeb59991\",\"287\":\"c03ca45501ab2f554ca5\",\"288\":\"aaac1ebd164046163708\",\"289\":\"6d4c306fce7135a596e4\",\"290\":\"8f5628e3fee5edf56a94\",\"291\":\"a186b6731c61af225327\",\"292\":\"045e7ec69bd7e4fc6acf\",\"293\":\"de2c05347e7b334c3bb5\",\"294\":\"32b0e5a4625fab2e6952\",\"295\":\"def6e70524c5663d52cb\",\"296\":\"45b4369398fcb85e46ad\",\"297\":\"e55d85f1a168239bc17e\",\"298\":\"add9a7f5e3e994e1d683\",\"299\":\"1a4e1f8afa825fe98b17\",\"300\":\"87f8b54a9e0a2d7f1b63\",\"301\":\"049a182782929608716a\",\"302\":\"5342b8bf03df92ac0954\",\"303\":\"66c6bb29bafe93a6a49c\",\"304\":\"ca9618b83ebead05a9a7\",\"305\":\"f6c4a8620deb5efc1823\",\"306\":\"ddb72a40f90d57ccd896\",\"307\":\"fdc47f7eef93cc302ab5\",\"308\":\"d23469ac288cb8c4844b\",\"309\":\"701b542c132ce37fd1c7\",\"310\":\"eef16f78f252905bf357\",\"311\":\"dcfa48cfb6d7165fbefb\",\"312\":\"75c9ac12ade8af0aa502\",\"313\":\"32044ddac1883dac8bd6\",\"314\":\"3ec1d123cc6e7a18508e\",\"315\":\"8a26960187c810c4992e\",\"316\":\"3e8d129fa73bfaba413a\",\"317\":\"74044b549670ac746054\",\"318\":\"8c2b08b8085bae9555b9\",\"319\":\"9db40d9c56a22869fa35\",\"320\":\"7e80322989ff350f6aa8\",\"321\":\"9206687f161bd1b71fd3\",\"322\":\"0779c21a610875ad6424\",\"323\":\"a20fa2a62fe8bc6f504c\",\"324\":\"007691b82b6a81d023f0\",\"325\":\"f0b5e499644cc2fc00c6\",\"326\":\"755d6182bff9a4d880db\",\"327\":\"e1fc06ea49ffa5b32bbf\",\"328\":\"2736138d1d42a98c72a0\",\"329\":\"abdac2428ebc44adeaf5\",\"330\":\"179019f3dbf78261330e\",\"331\":\"727675397c5f9c661671\",\"332\":\"5271025c6c446d03ac31\",\"333\":\"b50994cbe7be2ca7205a\",\"334\":\"49155df9d79aa9f19b74\",\"335\":\"9be6e9d2d239575b1b34\",\"336\":\"c213503e5fa22ac4e6ca\",\"337\":\"5330287914c513cb0427\",\"338\":\"2100d01a438305596487\",\"339\":\"bb6d765ac4c5c6d29789\",\"340\":\"a5d3fdf5a4b5f821c604\",\"341\":\"7f1db19a3fc3e7d03082\",\"342\":\"04dcb7e6fe9f4e7d16df\",\"343\":\"470075fe1da48cef2109\",\"344\":\"4214995246fb846621dc\",\"345\":\"7630414828399b95c19d\",\"346\":\"3ab4c604147d6e1e7dfa\",\"347\":\"9cb8cca412098500d7d0\",\"348\":\"cadf77305526fc813712\",\"349\":\"1b82e3b12e56c748e6f3\",\"350\":\"5bad58d80e8b6de868ea\",\"351\":\"f24e6eb2e96673b7499f\",\"352\":\"0153566788adb497fb02\",\"353\":\"af6df3bbbecea214859a\",\"354\":\"c1352c3a6db5e0bc0531\",\"355\":\"07ae1b24e88510235135\",\"356\":\"771b72909f78192560b8\",\"357\":\"d00b1e2ff46331c3e147\",\"358\":\"37e8d489cff03e15651e\",\"359\":\"39578906561ffada1acc\",\"360\":\"a483066099b3f9cfe4a0\",\"361\":\"bed44ac0607e7ae8d54d\",\"362\":\"0b9de6c9e257b01709e6\",\"363\":\"1c1ecacaf4f004b8b8cf\",\"364\":\"aad6940fb89628fe6290\",\"365\":\"f5f94856c3dfed624daa\",\"366\":\"66abf2d8f275595f4fc8\",\"367\":\"d072b3b8c103e2014910\",\"368\":\"9ea760e0994da94ad462\",\"369\":\"624469453dcd27f52912\",\"370\":\"0eb42016c827caf6765b\",\"371\":\"c653314364de63a3689e\"}[chunkId] + \".js\"\n \t}\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tvar promises = [];\n\n\n \t\t// JSONP chunk loading for javascript\n\n \t\tvar installedChunkData = installedChunks[chunkId];\n \t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n \t\t\t// a Promise means \"currently loading\".\n \t\t\tif(installedChunkData) {\n \t\t\t\tpromises.push(installedChunkData[2]);\n \t\t\t} else {\n \t\t\t\t// setup Promise in chunk cache\n \t\t\t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n \t\t\t\t});\n \t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n \t\t\t\t// start chunk loading\n \t\t\t\tvar script = document.createElement('script');\n \t\t\t\tvar onScriptComplete;\n\n \t\t\t\tscript.charset = 'utf-8';\n \t\t\t\tscript.timeout = 120;\n \t\t\t\tif (__webpack_require__.nc) {\n \t\t\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t\t\t}\n \t\t\t\tscript.src = jsonpScriptSrc(chunkId);\n\n \t\t\t\t// create error before stack unwound to get useful stacktrace later\n \t\t\t\tvar error = new Error();\n \t\t\t\tonScriptComplete = function (event) {\n \t\t\t\t\t// avoid mem leaks in IE.\n \t\t\t\t\tscript.onerror = script.onload = null;\n \t\t\t\t\tclearTimeout(timeout);\n \t\t\t\t\tvar chunk = installedChunks[chunkId];\n \t\t\t\t\tif(chunk !== 0) {\n \t\t\t\t\t\tif(chunk) {\n \t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n \t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n \t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n \t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n \t\t\t\t\t\t\terror.type = errorType;\n \t\t\t\t\t\t\terror.request = realSrc;\n \t\t\t\t\t\t\tchunk[1](error);\n \t\t\t\t\t\t}\n \t\t\t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t\t\t}\n \t\t\t\t};\n \t\t\t\tvar timeout = setTimeout(function(){\n \t\t\t\t\tonScriptComplete({ type: 'timeout', target: script });\n \t\t\t\t}, 120000);\n \t\t\t\tscript.onerror = script.onload = onScriptComplete;\n \t\t\t\tdocument.head.appendChild(script);\n \t\t\t}\n \t\t}\n \t\treturn Promise.all(promises);\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/bundles/v1/hybrid/20200917.353/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([1254,0]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * The app error object that contains the data of an app error\r\n */\r\nexport interface AppError {\r\n /** error id */\r\n id: number;\r\n\r\n /** source file */\r\n source: string;\r\n\r\n /** Message or data */\r\n message?: string;\r\n\r\n /** severity */\r\n severity: Severity;\r\n\r\n /** Property Bag */\r\n pb?: AppErrorPropertyBag;\r\n\r\n /** optional property: Bug meta data for auto bug creation from app error */\r\n bug?: any;\r\n}\r\n\r\n/**\r\n * The app error property bag that will be used for build number etc.\r\n */\r\nexport interface AppErrorPropertyBag {\r\n /** Build number */\r\n build?: string;\r\n\r\n /** Custom message */\r\n customMessage?: string;\r\n\r\n /** PCS build version */\r\n pcsVersion?: string;\r\n\r\n /** The error source. */\r\n source?: string;\r\n\r\n /** The line number of the error. */\r\n line?: number;\r\n\r\n /** The column number of the error. */\r\n column?: number;\r\n\r\n /** The stack trace for the error. */\r\n stack?: string;\r\n}\r\n\r\n/**\r\n * The interface that defines a generic app error tracker\r\n */\r\nexport interface AppErrorTracker {\r\n /**\r\n * Report an app error\r\n * @param {AppError} error - the app error to report\r\n */\r\n trackError(error: AppError): Promise;\r\n}\r\n\r\n/**\r\n * This will decide whether to create Alert for this app error or no alert. This can generate IcM ticket.\r\n * Alerts ones are tracked at http://aka.ms/AppErrors\r\n * NoAlerts will have separate tab just next to Errors aka Warnings. IcM ticket won't be generated when NoAlert is set.\r\n */\r\nexport enum Severity {\r\n /**\r\n * This is app error with default severity\r\n */\r\n Alert,\r\n\r\n /**\r\n * This is app warning\r\n */\r\n NoAlert,\r\n\r\n /**\r\n * This app error has high user impact\r\n */\r\n HighImpact,\r\n\r\n /**\r\n * This is fatal app error\r\n */\r\n Critical\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n// Split from DOMHelper to aid treeshaking\r\n// which currently adds class definition dependency (eg. RequestData)\r\n// even if they aren't used by code that only uses canUseDOM\r\n//\r\n// This being used in PCS inline scripts so only add to here\r\n// if critically important and do not have any other dependencies;\r\n// otherwise add to DOMHelpers\r\n\r\n/**\r\n * Checks if the DOM is available to access and use.\r\n * @returns {boolean} - true if DOM is available, or false if it is not. This is typically true for\r\n * client side rendering and false for server side rendering.\r\n */\r\nexport function canUseDOM(): boolean {\r\n return !!(typeof window !== \"undefined\" && window.document && window.document.createElement);\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * The aria-label html attribute\r\n * @type {string}\r\n */\r\nexport const ariaLabelAttribute = \"aria-label\";\r\n\r\n/**\r\n * The id attribute on the
element that is the root element for Peregrine Pages / Experiences.\r\n * There is only ever 1 root element on a page\r\n * @type {string}\r\n */\r\nexport const rootElementId = \"msnewsroot\";\r\n\r\n/**\r\n * Element names that are commonly used in Peregrine pages and experiences\r\n * @type {object}\r\n */\r\nexport const htmlElementIds: any = {\r\n html: \"html\",\r\n head: \"head\",\r\n body: \"body\"\r\n};\r\n\r\n/**\r\n * Constants used by application cache related scenarios\r\n */\r\nexport const applicationCacheConstants = {\r\n /**\r\n * Attribute name on html tag that is set when appcache is being used on the page\r\n */\r\n manifestAttributeName: \"manifest\",\r\n\r\n /**\r\n * Local storage key that holds the appcache info used to determine page refresh needs\r\n * for different page types.\r\n */\r\n pagesRefreshData: \"ac_prd\",\r\n\r\n /**\r\n * Legacy local storage key that holds the appcache stored head data entries.\r\n * TODO Task #28853629: Remove this after new code is in place for a while\r\n */\r\n legacyStoredHeadDataKey: \"ac_shd\",\r\n\r\n /**\r\n * Legacy local storage key that holds the appcache stored activity IDs.\r\n * TODO Task #28853629: Remove this after new code is in place for a while\r\n */\r\n legacyStoredLastUsedActivityIdKey: \"ac_sai\"\r\n\r\n};\r\n\r\n/**\r\n * The attributes that are part of markup elements that we care about\r\n */\r\nexport const clientSettings = \"data-client-settings\";\r\nexport const pagetypeSettings = \"data-pagetype\";\r\nexport const id = \"data-id\";\r\nexport const info = \"data-info\";\r\nexport const js = \"data-js\";\r\nexport const t = \"data-t\";\r\nexport const lang = \"lang\";\r\nexport const dir = \"dir\";\r\nexport const serviceUrl = \"data-service-url\";\r\nexport const telemetryId = \"data-telemetry-id\";\r\nexport const trackPageProduct = \"data-page-product\";\r\nexport const trackPageType = \"data-page-type\";\r\n\r\n/**\r\n * The number of characters that our Service Request Ids must have. This is currently defined by OneService\r\n * @type {number}\r\n */\r\nexport const numberOfCharactersNeededForUniqueRequestId = 32;\r\n\r\n/**\r\n * The minimum number of path segments that will be in the URL which hosts MS News Experience pages.\r\n * The first path segment should be the vertical key, e.g. spartan and the second path segment\r\n * should be the the category key, e.g. ntp\r\n * @type {number}\r\n */\r\nexport const minimumHostPagePathSegments = 2;\r\n\r\n/**\r\n * Default value we use for the name of the cookie that holds the ANID\r\n */\r\nexport const anonCookieName = \"APP_ANON\";\r\n\r\n/**\r\n * App Anon Cookie Exists Cookie Name. This cookie is a marker if APP_ANON exist or not.\r\n * This is necessary because APP_ANON is HTTP cookie and not accessible by JS.\r\n */\r\nexport const appAnonCookieExistsCookieName = \"aace\";\r\n\r\n/**\r\n * Child cookie name, used to signal if rpsUser is child account.\r\n */\r\nexport const childCookieName = \"child\";\r\n\r\n/**\r\n * Tracks user engagement for the Meet Now feature via the first day it was shown\r\n */\r\nexport const meetNowEngagementDayFirstShown = \"meetnow-day-first-shown\";\r\n\r\n/**\r\n * Tracks user engagment for the Meet Now feature via the number of clicks\r\n */\r\nexport const meetNowEngagementNumberOfClicks = \"meetnow-number-clicks\";\r\n\r\n/**\r\n * Tracks whether user engagement requirements for the Meet Now feature have been met\r\n */\r\nexport const meetNowengagementReached = \"meetnow-engagement-reached\";\r\n\r\n/**\r\n * Migration consent state cookie, indicates user has already granted or denied migration consent\r\n */\r\nexport const migrationConsentStateKey = \"migration-state\";\r\n\r\n/**\r\n * Id of MSCC cookie banner container element.\r\n */\r\nexport const msccCookieBannerElementId = \"consent-banner-container\";\r\n\r\n/**\r\n * Nurturing accepted state key is intended to be used in local storage, indicates user has opted in or out of Iris targeted content.\r\n */\r\nexport const nurturingAcceptedStateKey = \"nurturingAccepted\";\r\n\r\n/**\r\n * Recommended search key is intended to be used in local storage,\r\n * indicates user has opted in or out to show recommended search below search box\r\n */\r\nexport const recommendedSearchKey = \"recommended-search-enabled\";\r\n\r\n/**\r\n * Search history key is intended to be used in local storage, indicates user has opted in or out to show search history\r\n */\r\nexport const searchHistoryKey = \"search-history-enabled\";\r\n\r\n/**\r\n * Local storage key to indicated if no search history is expected based on auth logic\r\n * If it is expected then do not show search history toggle, otherwise show search history toggle in settings dialog\r\n */\r\nexport const noSearchHistoryExpectedKey = \"no-search-history-expected-auth\";\r\n\r\n/**\r\n * Headers used for one service requests\r\n */\r\nexport const oneServiceHeaders = {\r\n activityId: \"x-client-activityid\",\r\n authorization: \"Authorization\"\r\n};\r\n\r\n/**\r\n * used query string params in OneService requests\r\n */\r\nexport const oneServiceQueryStringKeys = {\r\n activityId: \"activityId\",\r\n apiKey: \"apikey\",\r\n complexInfoPaneEnabled: \"cipenabled\",\r\n contentType: \"contentType\",\r\n delta: \"delta\",\r\n disableTypeSerialization: \"DisableTypeSerialization\",\r\n infopaneCount: \"infopaneCount\",\r\n fdhead: \"fdhead\",\r\n feedLayoutRequestType: \"t\",\r\n filter: \"$filter\",\r\n ids: \"ids\",\r\n location: \"location\",\r\n market: \"market\",\r\n ocid: \"ocid\",\r\n parentContentId: \"parent-content-id\",\r\n parentNamespace: \"parent-ns\",\r\n parentTitle: \"parent-title\",\r\n queryQ: \"q\",\r\n query: \"query\",\r\n queryType: \"queryType\",\r\n qScope: \"qscope\",\r\n responseSchema: \"responseschema\",\r\n select: \"$select\",\r\n session: \"session\",\r\n signInCookieName: \"scn\",\r\n skip: \"$skip\",\r\n source: \"source\",\r\n timeOut: \"timeOut\",\r\n top: \"$top\",\r\n type: \"type\",\r\n user: \"user\",\r\n wrapOData: \"wrapodata\"\r\n};\r\n\r\n/**\r\n * Constants to use as role attribute value for elements\r\n */\r\nexport enum AriaRoles {\r\n /**\r\n * Presentation role is used to remove semantic meaning from an element and any of its related child elements.\r\n */\r\n Presentation = \"presentation\"\r\n}\r\n\r\n/**\r\n * Basic enum values for mobile device orientation\r\n */\r\nexport enum DeviceOrientation {\r\n Unknown = \"Unknown\",\r\n Portrait = \"Portrait\",\r\n Landscape = \"Landscape\"\r\n}\r\n\r\n/**\r\n * Enterprise compliant domain for One Service api\r\n */\r\nexport const EnterpriseOneServiceApi = \"https://ent-api.msn.com/\";\r\n\r\n/**\r\n * Common local storage keys\r\n */\r\nexport const CoreLocalStorageKeys = {\r\n /**\r\n * This key is used to store a dictionary of app versions per app type based on the current page version from the DOM.\r\n * Note that the version value will represent the current **loaded page** version and **not the new version** in scenarios\r\n * where the page is cached and require a new version to be loaded upon version detection (i.e., appcache, or service worker).\r\n * In these cached/refresh scenarios, we still want to store the version that the page was actually loaded from.\r\n */\r\n pageVersions: \"pageVersions\"\r\n};\r\n\r\n/**\r\n * The default APIKey for OneService requests\r\n */\r\nexport const defaultOneServiceApiKey = \"0QfOX3Vn51YCzitbLaRkTTBadtWpgTN8NZLW0C1SEM\";\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { getRequestData } from \"./requestData\";\r\nimport { canUseDOM } from \"./DOMHelpersCore\";\r\n\r\n/**\r\n * Checks if a given JS media query matches in an isomorphic manner\r\n * NOTE: Only supports min/max-width queries outside of the web client\r\n * @param query The media query\r\n */\r\nexport function canMatchMedia(query: string): boolean {\r\n if (canUseDOM()) {\r\n return window.matchMedia(query).matches;\r\n }\r\n\r\n const maxWidthValues = /max-width:\\s?(\\d+)/.exec(query);\r\n const minWidthValues = /min-width:\\s?(\\d+)/.exec(query);\r\n\r\n const minWidth = minWidthValues && minWidthValues.length ? minWidthValues[1] : 0;\r\n const maxWidth = maxWidthValues && maxWidthValues.length ? maxWidthValues[1] : Infinity;\r\n const innerWidth = getInnerWidth();\r\n\r\n return innerWidth >= minWidth && innerWidth <= maxWidth;\r\n}\r\n\r\n/**\r\n * Get window.location.href in an isomorphic manner.\r\n */\r\nexport function getLocationHref(): string {\r\n return canUseDOM() ? window.location.href : getRequestData().url.href;\r\n}\r\n\r\n/**\r\n * Get window.location.hostname in an isomorphic manner.\r\n */\r\nexport function getLocationHostname(): string {\r\n return canUseDOM() ? window.location.hostname : getRequestData().url.hostname;\r\n}\r\n\r\n/**\r\n * Get window.location.host in an isomorphic manner.\r\n */\r\nexport function getLocationHost(): string {\r\n return canUseDOM() ? window.location.host : getRequestData().url.host;\r\n}\r\n\r\n/**\r\n * Get window.location.origin in an isomorphic manner.\r\n */\r\nexport function getLocationOrigin(): string {\r\n return canUseDOM() ? window.location.origin : getRequestData().url.origin;\r\n}\r\n\r\n/**\r\n * Get window.location.search in an isomorphic manner.\r\n */\r\nexport function getLocationSearch(): string {\r\n return canUseDOM() ? window.location.search : getRequestData().url.search;\r\n}\r\n\r\n/**\r\n * Get window.location.pathname in an isomorphic manner.\r\n */\r\nexport function getLocationPathname(): string {\r\n return canUseDOM() ? window.location.pathname : getRequestData().url.pathname;\r\n}\r\n\r\n/**\r\n * Get window.location.protocol in an isomorphic manner.\r\n */\r\nexport function getLocationProtocol(): string {\r\n return canUseDOM() ? window.location.protocol : getRequestData().url.protocol;\r\n}\r\n\r\n/**\r\n * Get window.location.hash in an isomorphic manner.\r\n */\r\nexport function getLocationHash(): string {\r\n return canUseDOM() ? window.location.hash : getRequestData().url.hash;\r\n}\r\n\r\n/**\r\n * Get document.cookie in an isomorphic manner.\r\n */\r\nexport function getCookieString(): string {\r\n return canUseDOM() ? window.document.cookie : getRequestData().cookie;\r\n}\r\n\r\n/**\r\n * Get window.document.getElementById(elementId).\r\n */\r\nexport function getDocumentElementById(elementId: string): HTMLElement {\r\n if (!canUseDOM()) {\r\n throw new Error(\"getDocumentElementById is unsupported server side. This call should be wrapped in canUseDOM().\");\r\n }\r\n\r\n return window.document.getElementById(elementId);\r\n}\r\n\r\n/**\r\n * Get window.document.getDocumentElementsByTagName(elementId).\r\n */\r\nexport function getDocumentElementsByTagName(tagName: string): HTMLCollectionOf {\r\n if (!canUseDOM()) {\r\n throw new Error(\"getDocumentElementsByTagName is unsupported server side. This call should be wrapped in canUseDOM().\");\r\n }\r\n\r\n return window.document.getElementsByTagName(tagName);\r\n}\r\n\r\n/**\r\n * Get localStorage in an isomorphic manner.\r\n * Todo (http://osgvsowi/23753462), provide actual functionality for localStorage on the server side.\r\n */\r\nexport function getLocalStorage(): Storage {\r\n return canUseDOM() ? window.localStorage : null;\r\n}\r\n\r\n/**\r\n * Get indexedDB in an isomorphic manner.\r\n * Todo (http://osgvsowi/23753462), provide actual functionality for indexedDB on the server side.\r\n */\r\nexport function getIndexedDB(): IDBFactory {\r\n return canUseDOM() ? window.indexedDB : null;\r\n}\r\n\r\n/**\r\n * Get window.innerWidth in an isomorphic manner.\r\n * Todo (http://osgvsowi/23876778), remove the need for server to know about innerWidth by limiting layout options or use CSS based solution.\r\n */\r\nexport function getInnerWidth(): number {\r\n return canUseDOM() ? window.innerWidth : getRequestData().innerWidth;\r\n}\r\n\r\n/**\r\n * Get window.innerWidth in an isomorphic manner.\r\n * Todo (http://osgvsowi/23876778), remove the need for server to know about innerWidth by limiting layout options or use CSS based solution.\r\n */\r\nexport function getInnerHeight(): number {\r\n return canUseDOM() ? window.innerHeight : getRequestData().innerHeight;\r\n}\r\n\r\n/**\r\n * Get window.devicePixelRatio in an isomorphic manner.\r\n */\r\nexport function getDevicePixelRatio(): number {\r\n return canUseDOM() ? window.devicePixelRatio : getRequestData().devicePixelRatio;\r\n}\r\n\r\n/**\r\n * Get CSS Grid support in an isomorphic manner\r\n */\r\nexport function getCssGridSupport(): boolean {\r\n return !!(canUseDOM() ? (window.CSS && window.CSS.supports && CSS.supports(\"display\", \"grid\")) : getRequestData().canUseCssGrid);\r\n}\r\n\r\n/**\r\n * Get variable font support in an isomorphic manner\r\n * TODO: SSR currently does not support custom fonts.\r\n */\r\nexport function getVariableFontSupport(): boolean {\r\n if (!canUseDOM()) {\r\n throw new Error(\"SSR currently does not support custom fonts.\");\r\n }\r\n\r\n return !!(window.CSS && window.CSS.supports && CSS.supports(\"(font-variation-settings: normal)\"));\r\n}\r\n\r\n/**\r\n * Returns a script element using several default values.\r\n * Not supported server side.\r\n * @param src The absolute URL for the script src. Default is undefined, blank is okay.\r\n * @param id The id to assign the script element. default is \"\" so no id.\r\n * @param loadAsync Should the script load asynchronously. Default is true.\r\n * @returns {HTMLScriptElement} the script element. not using const so it can be overridden by caller.\r\n */\r\nexport function createScriptTag(src: string = undefined, id = undefined, loadAsync = true): HTMLScriptElement {\r\n if (!canUseDOM()) {\r\n throw new Error(\"createScriptTag is unsupported server side. This call should be wrapped in canUseDOM().\");\r\n }\r\n\r\n const scriptElement: HTMLScriptElement = document.createElement(\"script\");\r\n if (id) {\r\n scriptElement.id = id;\r\n }\r\n scriptElement.type = \"text/javascript\";\r\n if (src) {\r\n scriptElement.src = src;\r\n scriptElement.async = loadAsync;\r\n }\r\n // @ts-ignore\r\n if (window && window.NONCE_ID) {\r\n // @ts-ignore\r\n scriptElement.nonce = window.NONCE_ID;\r\n }\r\n\r\n return scriptElement;\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { canUseDOM, getDocumentElementsByTagName, getLocationSearch, getLocationHostname } from \"@msnews/isomorphic-util\";\r\nimport { applicationCacheConstants, clientSettings, dir, htmlElementIds, info, js, lang, pagetypeSettings, CoreLocalStorageKeys } from \"../constants\";\r\n\r\nimport { AudienceModeType } from \"@msnews/experiences-constants\";\r\nimport { DeviceFormFactorType } from \"cms-models-msn/configuration/types/DeviceFormFactorType\";\r\nimport { ILocale } from \"cms-models-msn/configuration/ILocale\";\r\nimport { IPcsBrowserScope } from \"../types/PcsBrowsersType\";\r\nimport { IPcsInformation } from \"../types/PcsInformation\";\r\nimport { IBundleInformation } from \"../types/BundleInformation\";\r\nimport { MarketProperties } from \"./MarketProperties\";\r\nimport { WebClientData } from \"./WebClientData\";\r\nimport { OperatingSystemType } from \"cms-models-msn/configuration/types/OperatingSystemType\";\r\nimport { UrlUtility } from \"../utilities/UrlUtility\";\r\nimport { localStorage } from \"../webstorage\";\r\nimport { tryParseJson } from \"../utilities/Parsing\";\r\nimport { KeyValueArray } from \"../utilities\";\r\nimport { logger } from \"@msnews/diagnostics\";\r\nimport { parseISO } from \"date-fns\";\r\n\r\n/**\r\n * Format used for activity ID stored in storage\r\n */\r\nexport type StoredActivityId = {\r\n /**\r\n * ID value\r\n */\r\n id: string;\r\n\r\n /**\r\n * Timestamp of when value was stored\r\n */\r\n ts: number;\r\n};\r\n\r\n/**\r\n * Map of page type to stored activity ID object.\r\n * TODO Task #28853629: Remove this after new code is in place for a while\r\n */\r\nexport type StoredActivityIdMap = { [pageType: string]: StoredActivityId };\r\n\r\n/**\r\n * Components for local storage keys for different pieces of data.\r\n */\r\nenum LocalStorageKey {\r\n /** Stored activity ID */\r\n StoredActivityId = \"sai\",\r\n\r\n /** Stored head data */\r\n StoredHeadData = \"shd\"\r\n}\r\n\r\n/**\r\n * The response from the HeadData API\r\n */\r\nexport interface HeadDataResponse {\r\n /** The client settings object. */\r\n clientSettings: IClientSettings;\r\n\r\n /** The info string, containing flights. */\r\n info: string;\r\n}\r\n\r\n/**\r\n * JSON data contract / interface for settings in the element that are part of the data-client-settings attribute.\r\n */\r\nexport interface IClientSettings {\r\n aid: string,\r\n apptype: string,\r\n apps_locale: string,\r\n audienceMode?: AudienceModeType,\r\n browser?: IPcsBrowserScope,\r\n configRootUrl?: string,\r\n deviceFormFactor?: DeviceFormFactorType,\r\n domain?: string,\r\n featureFlags?: any,\r\n contentId?: string,\r\n\r\n /** The schema://domain to be used for the main feed URL */\r\n feedBaseDomain?: string;\r\n\r\n categoryKey?: string;\r\n functionalonly_cookie_experience: boolean;\r\n functional_cookie_patterns: string;\r\n functional_cookies: string;\r\n geo_city?: string;\r\n geo_country?: string;\r\n geo_countryname?: string;\r\n geo_lat: string;\r\n geo_long: string;\r\n geo_subdivision?: string;\r\n geo_zip?: string;\r\n locale?: ILocale;\r\n market?: MarketProperties;\r\n os?: OperatingSystemType;\r\n pageGenTime?: string;\r\n pagetype?: string;\r\n\r\n /** Query params in the format \"?key=value&...\" as observed from the PCS origin server */\r\n queryparams?: string,\r\n /** Some explicit parameters need to be forwardable to downstream canvases, such as fdhead */\r\n forwardablequeryparams?: string,\r\n\r\n static_page?: string,\r\n verticalKey?: string,\r\n\r\n /** cache busting identifier sent by pcs */\r\n cbid?: string\r\n\r\n /** PCS information */\r\n pcsInfo?: IPcsInformation,\r\n\r\n /** Bundle information */\r\n bundleInfo?: IBundleInformation,\r\n}\r\n\r\nexport const EnterpiseFlightId = \"prg-enterpriseblended-t\";\r\nexport const OfficeDefaultPivotFlightId = \"prg-officedefault-t\";\r\n\r\n/** Type for storing app versions for different page types */\r\nexport type PageAppVersions = { [pageType: string]: string };\r\n\r\n/**\r\n * Class for getting the head data information.\r\n */\r\nclass HeadData {\r\n /**\r\n * The single instance of the HeadData class.\r\n * @type {HeadData}\r\n */\r\n private static _instance: HeadData;\r\n\r\n private anonCookieName: string;\r\n private locale: string;\r\n private marketDir: string;\r\n private currentFlights: string;\r\n private clientSettings: IClientSettings;\r\n private enableCMSPPEConfigs = false;\r\n private userIsSignedIn: boolean; // Always signed out on server side: https://dev.azure.com/microsoft/OS/_workitems/edit/25344027\r\n private isPreload: boolean;\r\n private isPrerender: boolean;\r\n private headElement: any;\r\n private htmlElement: any;\r\n private isAppcache: boolean;\r\n private isEnterprise: boolean;\r\n private isOfficeDefaultPivot: boolean;\r\n private isServiceWorkerCache: boolean;\r\n private ssoComplete: boolean;\r\n private aadState: boolean;\r\n private locationSearch: string;\r\n private lastKnownAppVersion: string;\r\n\r\n // TODO: Task 24890741: refactor this class to use the current singleton pattern with ES6 modules\r\n // This will also clean up these getters/setters\r\n public get Locale(): string { return this.locale; }\r\n\r\n public get MarketDir(): string { return this.marketDir; }\r\n public set MarketDir(value: string) { this.marketDir = value; }\r\n\r\n public get CurrentFlights(): string { return this.currentFlights || \"\"; }\r\n public set CurrentFlights(value: string) { this.currentFlights = value; }\r\n\r\n public get ClientSettings(): IClientSettings { return this.clientSettings; }\r\n public set ClientSettings(value: IClientSettings) { this.clientSettings = value; }\r\n\r\n public get EnableCMSPPEConfigs(): boolean { return this.enableCMSPPEConfigs; }\r\n\r\n public get UserIsSignedIn(): boolean { return this.userIsSignedIn; }\r\n public set UserIsSignedIn(value: boolean) { this.userIsSignedIn = value; }\r\n\r\n public get IsPreload(): boolean { return this.isPreload; }\r\n public set IsPreload(value: boolean) { this.isPreload = value; }\r\n\r\n public get IsPrerender(): boolean { return this.isPrerender; }\r\n public set IsPrerender(value: boolean) { this.isPrerender = value; }\r\n\r\n public get IsAppCache(): boolean { return this.isAppcache; }\r\n\r\n public get IsEnterprise(): boolean { return this.isEnterprise; }\r\n public set IsEnterprise(value: boolean) { this.isEnterprise = value; }\r\n\r\n public get IsOfficeDefaultPivot(): boolean { return this.isOfficeDefaultPivot; }\r\n public set IsOfficeDefaultPivot(value: boolean) { this.isOfficeDefaultPivot = value; }\r\n\r\n public get IsServiceWorkerCache(): boolean { return this.isServiceWorkerCache; }\r\n\r\n /**\r\n * The last known app version for the currently loaded page type.\r\n * To get the current page version, use clientSetings.bundleInfo.v value.\r\n */\r\n public get LastKnownAppVersion(): string { return this.lastKnownAppVersion; }\r\n\r\n // TODO: Dependencies that some client side code expects headData to specify but doesn't due to PCS\r\n public get AnonCookieName(): string { return this.anonCookieName; }\r\n public set AnonCookieName(value: string) { this.anonCookieName = value; }\r\n\r\n public get SsoComplete(): boolean { return this.ssoComplete; }\r\n\r\n public get AadState(): boolean { return this.aadState; }\r\n public set AadState(value: boolean) { this.aadState = value; }\r\n\r\n public set LocaleName(value: string) { this.locale = value; }\r\n\r\n /**\r\n * True if we need to generate a new RID for telemetry.\r\n * In normal scenarios the ActivityID and telemetry RID will match. But sometimes we are unable to refresh the head data\r\n * to get a new activity ID. In those cases we need to generate a fresh RID for telemetry, and the ActivityID and RID will\r\n * not match.\r\n */\r\n public newRidNeeded: boolean;\r\n\r\n /**\r\n * Initialize the head data instance, on server side provide the client info & client settings\r\n * @param {WebClientData} clientData Data object containing both client info and settings\r\n */\r\n private constructor(clientData?: WebClientData) {\r\n this.initializeHeadData(clientData);\r\n }\r\n\r\n /**\r\n * Returns singleton class instance.\r\n * @returns {HeadData}\r\n */\r\n public static getInstance(): HeadData { return HeadData._instance || (HeadData._instance = new HeadData()); }\r\n\r\n /**\r\n * Reset singleton class instance with passed in info and client settings. Used on server side to reset HeadData for each request.\r\n * @param {WebClientData} clientData Data object containing both client info and settings\r\n * @returns {HeadData}\r\n */\r\n public static resetInstance(clientData?: WebClientData): HeadData {\r\n HeadData._instance = new HeadData(clientData);\r\n headData = HeadData._instance;\r\n return HeadData._instance;\r\n }\r\n\r\n /**\r\n * Initializes head data. If WebClientData is provided use that, otherwise do client side initialization.\r\n * @param {WebClientData} clientData - Data object containing both client info and settings\r\n */\r\n public initializeHeadData(clientData?: WebClientData): void {\r\n if (clientData) {\r\n // Data is passed in only from Render Service under Node.JS environment since there is no DOM.\r\n this.initializeFromData(clientData);\r\n return;\r\n }\r\n\r\n this.newRidNeeded = undefined;\r\n this.lastUsedActivityIdBacking = undefined;\r\n this.locationSearch = getLocationSearch();\r\n this.htmlElement = canUseDOM() ? getDocumentElementsByTagName(htmlElementIds.html)[0] : null;\r\n this.headElement = canUseDOM() ? getDocumentElementsByTagName(htmlElementIds.head)[0] : null;\r\n\r\n if (!this.htmlElement || !this.headElement) {\r\n return;\r\n }\r\n\r\n // We always initialize from DOM first because\r\n // even if we are in an appcache/service worker case, we still need some data from the DOM\r\n // and we will fallback to DOM if there are no items found in storage\r\n this.initializeFromDom();\r\n\r\n // Attempt to override with local storage item when in appcache scenario\r\n // In service worker scenario, just update the storage activity id\r\n if (this.htmlElement.getAttribute(applicationCacheConstants.manifestAttributeName)) {\r\n this.isAppcache = true;\r\n } else if (window && window.navigator && window.navigator.serviceWorker && window.navigator.serviceWorker.controller) {\r\n this.isServiceWorkerCache = true;\r\n }\r\n\r\n if (this.isAppcache || this.isServiceWorkerCache) {\r\n // First apply head data from local storage. This might change the AID\r\n this.initializeFromStorage();\r\n\r\n // Now update last used activity ID based on the current activity ID\r\n this.initializeLastUsedActivityId();\r\n }\r\n\r\n // Below items are common for both scenarios\r\n const clientSettingsLocaleExists = this.clientSettings && this.clientSettings.locale && this.clientSettings.locale.language && this.clientSettings.locale.market;\r\n this.locale = clientSettingsLocaleExists &&\r\n (\r\n this.clientSettings.locale.language\r\n + \"-\"\r\n + (this.clientSettings.locale.script ? this.clientSettings.locale.script + \"-\" : \"\")\r\n + this.clientSettings.locale.market\r\n ).toLowerCase() || \"\";\r\n\r\n const marketDir = this.htmlElement.getAttribute(dir);\r\n this.marketDir = marketDir && marketDir.toLocaleLowerCase() || \"\";\r\n\r\n this.setQueryItemProvidedValues();\r\n\r\n // Note: This isn't currently being stamped by PCS\r\n const headDataJs = this.headElement.getAttribute(js);\r\n if (headDataJs) {\r\n const headJs = <{ anonckname: string, signedin: number }>tryParseJson(headDataJs);\r\n this.anonCookieName = headJs.anonckname;\r\n this.userIsSignedIn = headJs.signedin === 1;\r\n }\r\n\r\n // Checks if current request is background preload or prerender request\r\n if (UrlUtility.getQueryParameterByName(\"backgroundpreload\", this.locationSearch)) {\r\n this.isPreload = true;\r\n }\r\n\r\n // Checks if current request is prerender request\r\n if (UrlUtility.getQueryParameterByName(\"prerender\", this.locationSearch)\r\n && document.visibilityState === \"hidden\") {\r\n this.isPrerender = true;\r\n }\r\n\r\n // Determine if we are in Enterprise version or not\r\n this.setIsEnterprise();\r\n\r\n // Determine if Office is the default pivot\r\n this.setIsOfficeDefaultPivot();\r\n }\r\n\r\n private lastUsedActivityIdBacking: StoredActivityId;\r\n\r\n /**\r\n * Gets the last used activity ID, or null if there is none stored.\r\n */\r\n public get lastUsedActivityId(): StoredActivityId {\r\n if (this.lastUsedActivityIdBacking) {\r\n return this.lastUsedActivityIdBacking;\r\n }\r\n\r\n const storageKey: string = this.getStoredActivityIdKey();\r\n const storedActivityIdJson: string = localStorage.getItem(storageKey);\r\n if (storedActivityIdJson) {\r\n this.lastUsedActivityIdBacking = tryParseJson(storedActivityIdJson);\r\n } else {\r\n // Fall back to old local storage location.\r\n // TODO Task #28853629: Remove this after new code is in place for a while\r\n this.lastUsedActivityIdBacking = this.fetchAndUpgradeOldStorage(LocalStorageKey.StoredActivityId);\r\n }\r\n\r\n return this.lastUsedActivityIdBacking;\r\n }\r\n\r\n /**\r\n * Sets the last used activity ID. Pass in null to clear the stored data.\r\n */\r\n public set lastUsedActivityId(activityId: StoredActivityId) {\r\n const storageKey: string = this.getStoredActivityIdKey();\r\n if (activityId) {\r\n if (activityId.id && activityId.ts) {\r\n localStorage.setItem(storageKey, JSON.stringify(activityId));\r\n this.lastUsedActivityIdBacking = activityId;\r\n }\r\n } else {\r\n localStorage.removeItem(storageKey);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the stored head data, or null if none is stored.\r\n */\r\n public get storedHeadData(): HeadDataResponse {\r\n const storageKey: string = this.getStoredHeadDataKey();\r\n const storedHeadDataJson: string = localStorage.getItem(storageKey);\r\n if (storedHeadDataJson) {\r\n return tryParseJson(storedHeadDataJson);\r\n } else {\r\n // Fall back to old local storage location.\r\n // TODO Task #28853629: Remove this after new code is in place for a while\r\n return this.fetchAndUpgradeOldStorage(LocalStorageKey.StoredHeadData);\r\n }\r\n }\r\n\r\n /**\r\n * Sets the stored head data. Pass in null to clear the stored data.\r\n */\r\n public set storedHeadData(headDataResponse: HeadDataResponse) {\r\n const storageKey: string = this.getStoredHeadDataKey();\r\n\r\n if (headDataResponse) {\r\n localStorage.setItem(storageKey, JSON.stringify(headDataResponse));\r\n } else {\r\n localStorage.removeItem(storageKey);\r\n }\r\n }\r\n\r\n /**\r\n * Fetches an item from legacy local storage and upgrades entries.\r\n * @param localStorageKey The local storage key to use. shd or sai.\r\n * @returns The value being requested, or null if it doesn't exist.\r\n */\r\n private fetchAndUpgradeOldStorage(localStorageKey: LocalStorageKey): T {\r\n const legacyLocalStorageKey: string = \"ac_\" + localStorageKey;\r\n const responsesFromStorage = localStorage.getItem(legacyLocalStorageKey);\r\n const parsedResponseFromStorage = tryParseJson(responsesFromStorage);\r\n\r\n if (parsedResponseFromStorage) {\r\n // Break apart the old entry and save it under the new keys.\r\n for (const [pageType, value] of Object.entries(parsedResponseFromStorage)) {\r\n localStorage.setItem(`${localStorageKey}_${pageType}`, JSON.stringify(value));\r\n localStorage.removeItem(legacyLocalStorageKey);\r\n }\r\n\r\n const itemToReturn: T = parsedResponseFromStorage[this.clientSettings.pagetype];\r\n if (itemToReturn) {\r\n return itemToReturn;\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Initializes the client settings and info from client data passed in externally (render service query param)\r\n * @param {WebClientData} clientData Data object containing both client info and settings\r\n */\r\n private initializeFromData(clientData: WebClientData): void {\r\n this.clientSettings = tryParseJson(clientData.clientSettings);\r\n\r\n this.setFlights(clientData.clientInfo);\r\n\r\n this.setQueryItemProvidedValues();\r\n\r\n const clientSettingsLocaleExists = this.clientSettings && this.clientSettings.locale && this.clientSettings.locale.language && this.clientSettings.locale.market;\r\n this.locale = clientSettingsLocaleExists &&\r\n (\r\n this.clientSettings.locale.language\r\n + \"-\"\r\n + (this.clientSettings.locale.script ? this.clientSettings.locale.script + \"-\" : \"\")\r\n + this.clientSettings.locale.market\r\n ).toLowerCase() || \"\";\r\n this.marketDir = clientData.marketDir && clientData.marketDir.toLocaleLowerCase() || \"\";\r\n\r\n // Determine if we are in Enterprise version or not\r\n this.setIsEnterprise();\r\n\r\n // Determine if Office is the default pivot\r\n this.setIsOfficeDefaultPivot();\r\n }\r\n\r\n /**\r\n * Initializes the client settings and info from DOM element\r\n */\r\n private initializeFromDom(): void {\r\n\r\n this.setFlights(this.headElement.getAttribute(info));\r\n\r\n const dataClientSettings = this.headElement.getAttribute(clientSettings);\r\n if (!dataClientSettings) {\r\n return;\r\n }\r\n\r\n this.clientSettings = tryParseJson(dataClientSettings);\r\n if (!this.clientSettings) {\r\n return;\r\n }\r\n\r\n this.calculateForwardableParams();\r\n const { pagetype } = this.clientSettings;\r\n\r\n // If clientSettings.pagetype does not exist, try getting from data-pagetype.\r\n // For Peregrine full spa page: pagetype is part of data-client-settings. There is no data-pagetype.\r\n // For Prime/Hybrid, pagetype is outside of data-client-settings and it belongs to data-pagetype\r\n if (!pagetype) {\r\n const pageTypeFromSettings = this.headElement.getAttribute(pagetypeSettings);\r\n this.clientSettings.pagetype = pageTypeFromSettings == null ? undefined : pageTypeFromSettings;\r\n }\r\n\r\n // try to get the previously store page version from local storage for this page type,\r\n // and store back the current version\r\n if (pagetype) {\r\n try {\r\n const storedVersions = localStorage.getObject(CoreLocalStorageKeys.pageVersions) || {};\r\n this.lastKnownAppVersion = storedVersions[pagetype];\r\n\r\n // update the dictionary with the new value if different, and store it back to local storage\r\n const { bundleInfo: currentDomVersion } = this.clientSettings;\r\n if (currentDomVersion && this.lastKnownAppVersion !== currentDomVersion) {\r\n storedVersions[pagetype] = currentDomVersion.v;\r\n localStorage.setObject(CoreLocalStorageKeys.pageVersions, storedVersions);\r\n }\r\n } catch {\r\n logger.log(`${this.logPrefix()} couldn't complete localStorage related operation.`);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Initializes headData client settings and info from the value found in storage\r\n * and if none is found, falls back to using the DOM element\r\n */\r\n private initializeFromStorage(): void {\r\n const currentPageStoredHeadData = this.storedHeadData;\r\n\r\n if (currentPageStoredHeadData) {\r\n this.populateFromApiResponse(currentPageStoredHeadData);\r\n }\r\n }\r\n\r\n /**\r\n * Populates fields based on a HeadData API response.\r\n * @param response The response to populate from.\r\n */\r\n private populateFromApiResponse(response: HeadDataResponse) {\r\n if (!response) {\r\n return;\r\n }\r\n\r\n const responseClientSettings = response.clientSettings;\r\n const responseFlights = response.info;\r\n\r\n // The stored head data is corrupt, bail\r\n if (!responseClientSettings || !responseFlights) {\r\n return;\r\n }\r\n\r\n // If DOM page gen time is later than response page gen time, bail. We don't want to load stale head data from storage.\r\n if (this.clientSettings.pageGenTime >= responseClientSettings.pageGenTime) {\r\n // Purge obsolete stored head data.\r\n this.storedHeadData = null;\r\n return;\r\n }\r\n\r\n // Hold on to the current DOM queryparams as we will need to override\r\n // what we get from what is in storage\r\n const domQueryParams = this.clientSettings.queryparams;\r\n\r\n // save the current version if available in a temp variable so we can\r\n // restore it back after updating the clientSettings object with the one from\r\n // storage (which came from head data API, which does not contain the version info\r\n // by design, because version is tied with the static bundles, which should represent the currently\r\n // loaded page.\r\n const currentPageVersion = this.clientSettings && this.clientSettings.bundleInfo && this.clientSettings.bundleInfo.v;\r\n this.clientSettings = responseClientSettings;\r\n\r\n // restore the version after the object update\r\n this.clientSettings.bundleInfo = Object.assign(this.clientSettings.bundleInfo || {}, { v: currentPageVersion});\r\n\r\n // restore the queryParams base on what is found in DOM\r\n // as we want the DOM value to be what is used\r\n // and not what is found in storage for this field\r\n // We want these to stay true to what PCS generated for the page\r\n // and avoid desync when reading what comes from future headData API calls.\r\n this.clientSettings.queryparams = domQueryParams;\r\n this.calculateForwardableParams();\r\n\r\n this.setFlights(responseFlights);\r\n }\r\n\r\n /**\r\n * Initializes the queryparams from parameters\r\n */\r\n private calculateForwardableParams() {\r\n const params = this.clientSettings ? this.clientSettings.queryparams : \"\";\r\n if (!params) {\r\n return;\r\n }\r\n const forwardableParams = [\"fdhead\", \"item\"];\r\n const lowerCaseParams = params.toLocaleLowerCase();\r\n const availableParams = forwardableParams.map((key) => {\r\n const paramValue = UrlUtility.getQueryParameterByName(key, lowerCaseParams);\r\n if (!paramValue) {\r\n return null;\r\n }\r\n return `${key}=${encodeURIComponent(paramValue)}`;\r\n }).filter(x => x);\r\n this.clientSettings.forwardablequeryparams = availableParams.join(\"&\");\r\n }\r\n\r\n /**\r\n * Initializes the \"newRidNeeded\" value based on the page generation time and last used activity ID timestamp.\r\n * Updates the stored \"last used activity ID\"\r\n */\r\n private initializeLastUsedActivityId() {\r\n // Read the \"last used activity ID\"\r\n const lastUsedAid = this.lastUsedActivityId;\r\n\r\n // The activity ID that the page is currently planning on using. This may have been embedded or it may have been loaded up from stored head data.\r\n const currentAid = this.clientSettings.aid;\r\n const pageGenTimeDate: Date = parseISO(this.clientSettings.pageGenTime);\r\n const pageGenTimestamp: number = pageGenTimeDate.getTime();\r\n\r\n // Three conditions need to be met to generate a new RID\r\n // 1) The user has stored a previously used activity ID\r\n // 2) We have a valid page generation timestamp from PCS. PCS embeds pageGenTimestamp in the client settings to tell us\r\n // when it ran and generated the page. This will not be the case for localhost requests because they do not use PCS and instead\r\n // use a static App.html file. For localhost we do not need to generate a new RID.\r\n // 3) The current ActivityId matches the previously used one\r\n this.newRidNeeded = !!(lastUsedAid && pageGenTimestamp && lastUsedAid.id === currentAid);\r\n\r\n // If we have a proper timestamp and it's more recent than the last stored one\r\n if (pageGenTimestamp && (!lastUsedAid || pageGenTimestamp > lastUsedAid.ts)) {\r\n // Store the current activity ID as last used.\r\n this.lastUsedActivityId = { id: currentAid, ts: pageGenTimestamp };\r\n }\r\n }\r\n\r\n /**\r\n * Parses flights from provided string (if in proper format of f:{flights})\r\n * and sets it to the headData object\r\n */\r\n private setFlights(flightString: string): void {\r\n // The comma separated list of flights enabled in current request\r\n this.currentFlights = ((/f:\\s*([^;]+)/i.exec(flightString) || {})[1] || \"\").toLowerCase();\r\n }\r\n\r\n /**\r\n * Determines if we are in Enterprise version based on clientSettings and currentFlights\r\n */\r\n private setIsEnterprise(): void {\r\n // We know we are in the Enterpise version of the page when both the audience mode is set to Enterprise\r\n // and the correct flight id is set.\r\n this.IsEnterprise = this.clientSettings &&\r\n this.currentFlights &&\r\n this.currentFlights.includes(EnterpiseFlightId) &&\r\n this.clientSettings.audienceMode === AudienceModeType.Enterprise;\r\n }\r\n\r\n /**\r\n * Read query items to determine the headdata variable values.\r\n */\r\n private setQueryItemProvidedValues(): void {\r\n // This only finds multiples of item=key:value qsp. If keys are the same, first given will be used (similar to UrlSearchParamsHelper).\r\n const queryItems = UrlUtility.getParamsWithItems(getLocationSearch());\r\n const cmsItem = queryItems.find(item => item.key === \"cms\");\r\n this.enableCMSPPEConfigs = (cmsItem && cmsItem.value === \"ppe\");\r\n\r\n // Test override to add flights for scope purposes\r\n this.setCurrentFlightsTestOverride(queryItems);\r\n }\r\n\r\n /**\r\n * Overrides currentFlights when hostname is localhost. Used for testing.\r\n */\r\n private setCurrentFlightsTestOverride(queryItems: KeyValueArray): void {\r\n if (getLocationHostname().toLowerCase().includes(\"localhost\") && queryItems) {\r\n const flights = queryItems.find(item => item.key === \"flights\");\r\n if (flights) {\r\n this.currentFlights = flights.value;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Determines if Office is the default pivot based on flight id.\r\n */\r\n private setIsOfficeDefaultPivot(): void {\r\n // There is work scheduled to have \"sticky\" pivots stored in some form of local storage which will\r\n // replace this check. Until then, the only way to know if Office is the default pivot is to check\r\n // for this flight id\r\n this.IsOfficeDefaultPivot = this.currentFlights && this.currentFlights.includes(OfficeDefaultPivotFlightId);\r\n }\r\n\r\n /**\r\n * Gets the local storage key for the head data.\r\n */\r\n private getStoredHeadDataKey(): string {\r\n return \"shd_\" + this.clientSettings.pagetype;\r\n }\r\n\r\n /**\r\n * Gets the local storage key for the head data.\r\n */\r\n private getStoredActivityIdKey(): string {\r\n return \"sai_\" + this.clientSettings.pagetype;\r\n }\r\n\r\n /**\r\n * Prefix for headdata logs. Server side add the head and html elements.\r\n * @returns the prefix string for logger message.\r\n */\r\n private logPrefix(): string {\r\n // Request Id is only available on server side.\r\n return `HeadData:${(canUseDOM() ? \"\" : ` [Head:${this.headElement}] and [Html:${this.htmlElement}]`)}`;\r\n }\r\n}\r\n\r\nexport const getHeadData = HeadData.getInstance;\r\n\r\n// headData can be reinitialized through resetHeadData.\r\nexport let headData = HeadData.getInstance();\r\n\r\n/**\r\n * Export function to reset headData based on WebClientData\r\n */\r\nexport const resetHeadData = HeadData.resetInstance;","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { IActionPayload } from \"./IActionPayload\";\r\nimport { IDataConnector } from \"../connectors\";\r\nimport PageBase from \"../pages/PageBase\";\r\n\r\n/**\r\n * Helper function to create an action payload\r\n * @param connector The connector (if applicable) where the action will be dispatched\r\n * @param type The Action Type (name of the action)\r\n * @param args Arguments to be passed to the action\r\n * @param experienceInstanceId If defined, the id of an experience instance, that will be used by action receiver\r\n */\r\nexport function getActionPayload(connector: IDataConnector, type: string, args: any[], experienceInstanceId: string): IActionPayload {\r\n let stateKey: string = undefined;\r\n if (connector) {\r\n if (!connector.parentNamespace) {\r\n stateKey = connector.namespace;\r\n } else {\r\n stateKey = connector.parentNamespace + \".\" + connector.namespace;\r\n }\r\n }\r\n\r\n return {\r\n key: stateKey,\r\n experienceInstanceId: experienceInstanceId,\r\n type: type,\r\n params: args\r\n };\r\n}\r\n\r\n/**\r\n * Helper function to dispatch an action either to a connector's namespaced store, or to the root store for the entire app.\r\n * @param connector The connector (if applicable) where the action will be dispatched\r\n * @param payload The action payload\r\n */\r\nexport function dispatchAction(connector: IDataConnector, payload: IActionPayload): any {\r\n\r\n // Dispatch the action\r\n if (connector) {\r\n return connector.store.dispatch(payload);\r\n } else {\r\n return PageBase.getInstance().store.dispatch(payload);\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { dispatchAction, getActionPayload } from \"./ActionDispatchHelper\";\r\n\r\nimport { ActionDispatchCancellationToken } from \"./ActionDispatchCancellationToken\";\r\nimport { ConnectorConstants } from \"../constants/ConnectorConstants\";\r\nimport { IActionDispatchCancellationToken } from \"./IActionDispatchCancellationToken\";\r\nimport { IActionPayload } from \"./IActionPayload\";\r\nimport { Observer } from \"./ActionObserver\";\r\nimport { PerfTimeline } from \"@msnews/diagnostics\";\r\nimport { IDataConnector } from \"../connectors\";\r\n\r\n/**\r\n * Class that wraps the sending of a action to a connector (i.e. dispatch) with an explicit method, so that in the consuming code\r\n * it is obvious that the action is being \"sent\"\r\n * @class\r\n */\r\nexport abstract class ActionSenderBase {\r\n /**\r\n * Property which is a function that will send an action to the connector.\r\n */\r\n public get send(): TActionSignature {\r\n return (this.dispatchAction());\r\n }\r\n\r\n /**\r\n * Creates an instance of the `ActionSender` class.\r\n * @constructor\r\n * @param {string} type The action type.\r\n * @param {Observer[]} observers Array of registered action observers\r\n * @param {IDataConnector} connector Optional connector to send the action to\r\n * @param {IActionDispatchCancellationToken} cancellationToken Optional cancellation token, which can be used to cancel an in flight action\r\n */\r\n constructor(\r\n protected type: string,\r\n private observers: Observer[],\r\n protected connector?: IDataConnector,\r\n private cancellationToken?: IActionDispatchCancellationToken) { }\r\n\r\n /**\r\n * Method to get dispatcher and payload\r\n * @param args - the arguments being dispatched\r\n * @returns dispatch result metadata\r\n */\r\n protected abstract getDispatchResult(args: any[]): { payload: IActionPayload, result: any };\r\n\r\n /**\r\n * Gets the perf timeline object if applicable\r\n */\r\n protected abstract tryGetPerfTimeline(): PerfTimeline;\r\n\r\n /**\r\n * Method that returns an action sender function to send the action.\r\n * @method\r\n * @return {TActionSignature} return value is a function to send to action.\r\n */\r\n private dispatchAction(): TActionSignature {\r\n return function (...args: unknown[]): unknown {\r\n if (!ActionDispatchCancellationToken.isCancellationRequested(this.cancellationToken)) {\r\n\r\n const perfTimeline = this.tryGetPerfTimeline();\r\n const actionEndMeasure = perfTimeline && perfTimeline.startMeasure(\"action\", this.type).endMeasure;\r\n\r\n const { payload, result } = this.getDispatchResult(args);\r\n\r\n // Call any observers\r\n this.observers.forEach(o => {\r\n try {\r\n if (!o.filterConnector\r\n || this.connector === o.filterConnector) {\r\n\r\n // Call the observer\r\n o.observer(payload);\r\n }\r\n } catch (error) {\r\n console.log(`Error calling observer: ${JSON.stringify(o.observer)}, with error: ${error}`);\r\n }\r\n\r\n // If there is a dispatch connector, dispatch an action to it, forcing it to re-render\r\n if (o.dispatchConnector) {\r\n const renderActionPayload = getActionPayload(o.dispatchConnector, ConnectorConstants.renderAction, [], undefined);\r\n dispatchAction(o.dispatchConnector, renderActionPayload);\r\n }\r\n });\r\n\r\n if (actionEndMeasure) {\r\n actionEndMeasure();\r\n }\r\n\r\n // Return the dispatch result\r\n return result;\r\n } else {\r\n // Don't dispatch the action because it has been canceled\r\n return;\r\n }\r\n };\r\n }\r\n\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { IActionDispatchCancellationToken } from \"./IActionDispatchCancellationToken\";\r\n\r\n/**\r\n * Cancellation Token class.\r\n * @class\r\n */\r\nexport class ActionDispatchCancellationToken implements IActionDispatchCancellationToken {\r\n /** Backing variable for the isCancellationRequested property\r\n * @type {boolean}\r\n */\r\n private isCancelled: boolean;\r\n\r\n /**\r\n * Creates an instance of the `ActionDispatchCancellationToken` class.\r\n * @constructor\r\n */\r\n constructor() {\r\n this.isCancelled = false;\r\n }\r\n\r\n /**\r\n * Helper method to cater for a null or undefined token.\r\n * A null or undefined token means cancellation cannot be requested, so it is equivalent to false\r\n * @method\r\n * @param {IActionDispatchCancellationToken} cancellationToken Optional cancellation token to be checked for undefined, null or cancellation requested\r\n * @returns {boolean}\r\n */\r\n public static isCancellationRequested(cancellationToken?: IActionDispatchCancellationToken): boolean {\r\n return !(cancellationToken === undefined || cancellationToken === null || !cancellationToken.isCancellationRequested);\r\n }\r\n\r\n /** The cancel method.\r\n * @method\r\n */\r\n public cancel(): void {\r\n this.isCancelled = true;\r\n }\r\n\r\n /** getter for the isCancellationRequested property\r\n * @property\r\n * @returns {boolean} Whether cancellation has been requested or not.\r\n */\r\n public get isCancellationRequested(): boolean {\r\n return this.isCancelled;\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { dispatchAction, getActionPayload } from \"./ActionDispatchHelper\";\r\n\r\nimport { ActionSenderBase } from \"./ActionSenderBase\";\r\nimport { IActionDispatchCancellationToken } from \"./IActionDispatchCancellationToken\";\r\nimport { IActionPayload } from \"./IActionPayload\";\r\nimport { IDataConnector } from \"../connectors\";\r\nimport { Observer } from \"./ActionObserver\";\r\nimport { PerfTimeline } from \"@msnews/diagnostics\";\r\n\r\n/**\r\n * Class that wraps the sending of a action to a connector (i.e. dispatch) with an explicit method, so that in the consuming code\r\n * it is obvious that the action is being \"sent\"\r\n * @class\r\n */\r\nexport class ActionSender extends ActionSenderBase {\r\n\r\n /**\r\n * Creates an instance of the `ActionSender` class.\r\n * @constructor\r\n * @param {string} type The action type.\r\n * @param {IDataConnector} connector The connector instance to dispatch the action to.\r\n * @param {IActionDispatchCancellationToken} cancellationToken Optional cancellation token, which can be used to cancel an in flight action\r\n */\r\n constructor(\r\n type: string,\r\n observers: Observer[],\r\n connector: IDataConnector,\r\n cancellationToken?: IActionDispatchCancellationToken) {\r\n\r\n super(type, observers, connector, cancellationToken);\r\n }\r\n\r\n /**\r\n * Core dispatch implementation for {GlobalActionSender}\r\n * @param args - the arguments being dispatched\r\n * @returns dispatch result metadata\r\n */\r\n protected getDispatchResult(args: any[]): { payload: IActionPayload, result: any } {\r\n const payload = getActionPayload(this.connector, this.type, args, undefined);\r\n const result = dispatchAction(this.connector, payload);\r\n return { payload, result };\r\n }\r\n\r\n /**\r\n * Gets the perf timeline if applicable\r\n */\r\n protected tryGetPerfTimeline(): PerfTimeline {\r\n return this.connector.perfTimeline;\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { PerfTimeline, tryGetPerfTimeline } from \"@msnews/diagnostics\";\r\nimport { dispatchAction, getActionPayload } from \"./ActionDispatchHelper\";\r\n\r\nimport { ActionSenderBase } from \"./ActionSenderBase\";\r\nimport { IActionDispatchCancellationToken } from \"./IActionDispatchCancellationToken\";\r\nimport { IActionPayload } from \"./IActionPayload\";\r\nimport { Observer } from \"./ActionObserver\";\r\n\r\n/**\r\n * Class that wraps the sending of a action globally to all connectors\r\n * @export\r\n * @class\r\n */\r\nexport class GlobalActionSender extends ActionSenderBase {\r\n\r\n /**\r\n * Creates an instance of the `GlobalActionSender` class.\r\n * @constructor\r\n * @param {string} type The action type.\r\n * @param {string} experienceInstanceId Optional experienceInstanceId of the experience that is originating the action.\r\n * @param {IActionDispatchCancellationToken} cancellationToken Optional cancellation token, which can be used to cancel an in flight action.\r\n */\r\n constructor(\r\n type: string,\r\n observers: Observer[],\r\n private experienceInstanceId?: string,\r\n cancellationToken?: IActionDispatchCancellationToken) {\r\n\r\n super(type, observers, null, cancellationToken);\r\n }\r\n\r\n /**\r\n * Core dispatch implementation for {GlobalActionSender}\r\n * @param args - the arguments being dispatched\r\n * @returns dispatch result metadata\r\n */\r\n protected getDispatchResult(args: any[]): { payload: IActionPayload, result: any } {\r\n const payload = getActionPayload(undefined, this.type, args, this.experienceInstanceId);\r\n const result = dispatchAction(undefined, payload);\r\n return { payload, result };\r\n }\r\n\r\n /**\r\n * Gets the perf timeline if applicable\r\n */\r\n protected tryGetPerfTimeline(): PerfTimeline {\r\n return tryGetPerfTimeline(\"GlobalActionSender\", this.experienceInstanceId || \"unknown\");\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ActionObserver, Observer } from \".\";\r\n\r\nimport { ActionSender } from \"./ActionSender\";\r\nimport { GlobalActionSender } from \"./GlobalActionSender\";\r\nimport { IActionDispatchCancellationToken } from \"./IActionDispatchCancellationToken\";\r\nimport { IActionMap } from \"./IActionMap\";\r\nimport { IDataConnector } from \"../connectors/IDataConnector\";\r\nimport PageBase from \"../pages\";\r\n\r\n/**\r\n * Class that maps Action to its callback function type.\r\n * Provides the method to get action creator which returns callback function to send to action.\r\n * Callback function dispatches the action payload.\r\n * @class\r\n */\r\nexport class ActionMap implements IActionMap {\r\n\r\n /**\r\n * An array of registered action observers\r\n */\r\n private observers: Observer[] = [];\r\n\r\n /**\r\n * Creates an instance of the `ActionMap` class.\r\n * @constructor\r\n * @param {string} type The action type, which is part of the IActionMap contract.\r\n */\r\n constructor(public type: string) {\r\n }\r\n\r\n /**\r\n * Method that returns an action sender function that can be used to send/dispatch the action to a specific connector\r\n * @method\r\n * @param {IDataConnector | string} connector The connector instance to send the action to, or the connector namespace. If the param type\r\n * is string, then the connector instance will be looked up, and used if found.\r\n * @param {IActionDispatchCancellationToken} cancellationToken If passed in and cancellation has been requested, then nothing is dispatched.\r\n * @return {TActionSignature} return value is an object with a send method, which is used to send the action.\r\n */\r\n public getActionSender(connector: IDataConnector | string, cancellationToken?: IActionDispatchCancellationToken): ActionSender | undefined {\r\n let connectorInstance: IDataConnector = undefined;\r\n if (typeof (connector) === \"string\") {\r\n // Find the connector with the matching namespace\r\n connectorInstance = PageBase.getInstance().rootReducer.connector(connector);\r\n } else {\r\n connectorInstance = connector;\r\n }\r\n\r\n if (connectorInstance) {\r\n return new ActionSender(this.type, this.observers, connectorInstance, cancellationToken);\r\n }\r\n }\r\n\r\n /**\r\n * Method that returns an action sender function that can be used to send/dispatch the action globally to all connectors\r\n * @method\r\n * @param {string} experienceInstanceId An optional experienceInstanceId, that will get passed along in the action payload.\r\n * It can then be used by the receiving reducer to determine if the action should be handled.\r\n * @param {IActionDispatchCancellationToken} cancellationToken If passed in and cancellation has been requested, then nothing is dispatched.\r\n * @return {TActionSignature} return value is an object with a send method, which is used to send the action.\r\n */\r\n public getGlobalActionSender(experienceInstanceId?: string, cancellationToken?: IActionDispatchCancellationToken): GlobalActionSender {\r\n return new GlobalActionSender(this.type, this.observers, experienceInstanceId, cancellationToken);\r\n }\r\n\r\n /**\r\n * Method that registers a new observer for this action. The observer will be called after the action is dispatched\r\n * @method\r\n * @param {ActionObserver} observer The observer to be added to the list of observers that will be called when the action completes\r\n * @param {Object} connectors Option connectors associated to the observer that will be called by the observer\r\n */\r\n public registerObserver(observer: ActionObserver, connectors?: { dispatchConnector?: IDataConnector, filterConnector?: IDataConnector }): void {\r\n const { dispatchConnector, filterConnector } = (connectors || {});\r\n\r\n this.observers.push({ observer, dispatchConnector, filterConnector });\r\n }\r\n\r\n /**\r\n * Test method to help clear existing observers to reset the state in unit test scenarios.\r\n */\r\n public _clearObservers(): void {\r\n this.observers.length = 0;\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * locationHref of page\r\n */\r\nexport const locationHref = (typeof (window) !== \"undefined\" ? window.location.href : \"\");\r\n\r\n/**\r\n * Render-cache expiration time in ms\r\n * 86400000 = 24 hours in milliseconds\r\n */\r\nexport const defaultExpirationTimeMs = 86400000;\r\n\r\n/**\r\n * Render-cache force expiration time in ms\r\n * 129600000 = 36 hours in milliseconds\r\n */\r\nexport const defaultForceExpirationTimeMs = 129600000;\r\n\r\n/**\r\n * localStorage key prefix for render cache expiration timestamp\r\n * Stores the sliding window expiration\r\n */\r\nexport const expirationPrefix = \"timestamp_\";\r\n\r\n/**\r\n * Force timestamp prefix for render cache values\r\n * Stores the absolute window expiration\r\n */\r\nexport const forceTimestampPrefix = \"force_timestamp_\";\r\n\r\n/**\r\n * Jss map suffix for render cache values\r\n * Stores the jss class list map\r\n */\r\nexport const jssMapSuffix = \"_jssMap\";\r\n\r\n/**\r\n * Prefix for render cache keys\r\n * Stores the collection of all render cache keys\r\n */\r\nexport const keysPrefix = \"keys_\";\r\n\r\n/**\r\n * Prefix for render cache qsp to remove and normlize the url\r\n */\r\nexport const normalizedUrlConfigkey = \"rcqsp\";\r\n\r\n/**\r\n * localStorage key prefix for render cache object\r\n * Stores the render cache snapshot\r\n */\r\nexport const storagePrefix = \"lastKnown_\";\r\n\r\n/**\r\n * River Render Cache ClassName\r\n */\r\nexport const riverRcClassName = \"river-rc\";","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { KeyValueArray, KeyValuePair, Utility } from \"./Utility\";\r\nimport { findIndex, isArray, isEmpty, isString, trimEnd, trimStart } from \"lodash-es\";\r\n\r\nimport { StringMap } from \"../types\";\r\nimport { getLocationOrigin } from \"@msnews/isomorphic-util\";\r\n\r\nexport namespace UrlUtility {\r\n\r\n /**\r\n * Characters that, if present on a url, will make prime routing misbehave\r\n *\r\n * These are the characters we know cause problems:\r\n * - spaces\r\n * - slashes\r\n * - punctuation: !?.:\r\n * - ampersands\r\n *\r\n * As we don't know all the offending characters, we are just removing every character that is not alphanumeric\r\n */\r\n const primeForbiddenCharacters = /[^A-Za-z0-9]+/g;\r\n\r\n /**\r\n * Parse parameters from the given URL\r\n * @param {string} url - the URL to parse for parameters\r\n * @param {boolean} decodeComponents - flag to indicate whether the query param key and value should be URL decoded\r\n * @returns {KeyValueArray} - the parsed query key/value collection\r\n */\r\n export function getParamsFromUrl(url: string, decodeComponents = false): KeyValueArray {\r\n if (!isString(url)) {\r\n return null;\r\n }\r\n\r\n const queryString: string = (url || \"\").split(\"?\")[1];\r\n return getParams(queryString, decodeComponents);\r\n }\r\n\r\n /**\r\n * Decode the given URL encoded string that may contain plus signs\r\n * @param {string} val - The value to decode.\r\n * @returns {string} - the decoded value\r\n */\r\n function decodeURIComponentWithPlusSign(val: string): string {\r\n val = val.replace(/\\+/g, \" \");\r\n val = decodeURIComponent(val);\r\n return val;\r\n }\r\n\r\n /**\r\n * Encode uri components in a way that won't break prime routing system\r\n * @param uriComponent the uriComponent to be encoded\r\n */\r\n export function encodeURIComponentForPrime(uriComponent: string): string {\r\n return encodeURIComponent(uriComponent.replace(primeForbiddenCharacters, \"-\"));\r\n }\r\n\r\n /**\r\n * Parse parameters from the given query string\r\n * @param {string} queryString - the query string to parse for parameters\r\n * @param {boolean} decodeComponents - flag to indicate whether the query param key and value should be URL decoded\r\n * @returns {KeyValueArray} - the parsed query key/value collection\r\n */\r\n export function getParams(queryString: string, decodeComponents = false): KeyValueArray {\r\n const params: KeyValueArray = [];\r\n // Remove the leading ? if it is present\r\n if (queryString && queryString.startsWith(\"?\")) {\r\n queryString = queryString.substring(1);\r\n }\r\n\r\n if (queryString) {\r\n // remove hash part.\r\n queryString = queryString.split(\"#\")[0];\r\n const queryArray = queryString.split(\"&\");\r\n for (let ndx = 0; ndx < queryArray.length; ndx++) {\r\n const parts = queryArray[ndx].split(\"=\");\r\n let queryKey = parts[0];\r\n let queryValue = parts[1];\r\n\r\n if (decodeComponents) {\r\n queryKey = decodeURIComponentWithPlusSign(queryKey);\r\n if (queryValue) {\r\n queryValue = decodeURIComponentWithPlusSign(queryValue);\r\n }\r\n }\r\n\r\n // Don't allow for duplicate query string parameter keys. Take the last one\r\n const newParam: KeyValuePair = { key: queryKey, value: queryValue };\r\n const existingParam = findIndex(params, (entry) => entry.key === newParam.key);\r\n if (existingParam === -1) {\r\n params.push(newParam);\r\n } else {\r\n params[existingParam] = newParam;\r\n }\r\n }\r\n }\r\n return params;\r\n }\r\n\r\n /**\r\n * Parse specific parameters from the given query string, allowing for multiple item=key:value.\r\n * This function ONLY parses qsp item=[key]:[value]\r\n * Note: Use first given rule for duplicate key!\r\n * @param {string} queryString - the query string to parse for parameters\r\n * @returns {KeyValueArray} - the parsed query key/value collection\r\n */\r\n export function getParamsWithItems(queryString: string): KeyValueArray {\r\n const params: KeyValueArray = [];\r\n\r\n const inputKey = \"item\";\r\n\r\n if (queryString) {\r\n // Remove the leading ? if it is present\r\n if (queryString.startsWith(\"?\")) {\r\n queryString = queryString.substring(1);\r\n }\r\n\r\n // split on the hashes.\r\n queryString = queryString.split(\"#\")[0];\r\n const queryArray = queryString.split(\"&\");\r\n for (let ndx = 0; ndx < queryArray.length; ndx++) {\r\n const parts = queryArray[ndx].split(\"=\");\r\n let queryKey = parts[0];\r\n let queryValue = parts[1];\r\n\r\n // If the query key is inputKey (default: \"item\"), and the query values is key:value, then convert the\r\n // value into the actual key/value\r\n if (queryKey.toLowerCase() === inputKey) {\r\n const queryItems = queryValue.split(\":\");\r\n // Ignore value not in \"key:value\" format\r\n if (queryItems.length === 2) {\r\n queryKey = queryItems[0];\r\n queryValue = queryItems[1];\r\n\r\n // Don't allow for duplicate query string parameter keys. Use first given rule for duplicate key!\r\n const newParam: KeyValuePair = { key: queryKey, value: queryValue };\r\n const existingParam = params.findIndex((entry) => entry.key === newParam.key);\r\n if (existingParam === -1) {\r\n params.push(newParam);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return params;\r\n }\r\n\r\n /**\r\n * Cache URI to paramsObj mapping\r\n */\r\n const hrefParamsObj: any = {};\r\n\r\n /**\r\n * Utility method to extract query string param in url.\r\n *\r\n * @export\r\n * @param {string} name - query param name\r\n * @param {string} href - URL\r\n * @returns {string} - query param value\r\n */\r\n export function getQueryParameterByName(name: string, href: string): string {\r\n if (!hrefParamsObj[href]) {\r\n hrefParamsObj[href] = getParamsObj(href);\r\n }\r\n\r\n const paramsObj = hrefParamsObj[href];\r\n const value = paramsObj[name];\r\n return (value !== undefined)\r\n ? value\r\n : null;\r\n }\r\n\r\n /**\r\n * Check if given url string is a valid url.\r\n * Returns true when url string is a valid url, otherwise false.\r\n *\r\n * @export\r\n * @param url {string} - Url string value to check\r\n * @param validateScheme {boolean} - Should scheme validation be forced\r\n * @return {boolean}\r\n */\r\n export function isValidUrl(url: string, validateScheme: boolean): boolean {\r\n return (isString(url) &&\r\n (url.length > 0) &&\r\n (!validateScheme ||\r\n validateScheme && url.indexOf(\"http\") === 0));\r\n }\r\n\r\n /**\r\n * Converts a keyValueArray into a set of query string parameters\r\n *\r\n * @export\r\n * @param {any} - params to be converted\r\n * @return {string}\r\n */\r\n export function keyValueArrayToQueryString(params: KeyValueArray): string {\r\n // Validate we have a nonempty array\r\n if (!isArray(params) || isEmpty(params)) {\r\n return \"\";\r\n }\r\n\r\n // Filter for valid keyValue entries, and then map them into key==value strings\r\n // joined with an &\r\n const queryString: string = params.filter(kv =>\r\n Utility.isKeyValuePair(\r\n kv,\r\n (key) => typeof (key) === \"string\",\r\n (value) => typeof (value) === \"string\"))\r\n .map(kv => kv.key + \"=\" + kv.value)\r\n .join(\"&\");\r\n\r\n return queryString;\r\n }\r\n\r\n /**\r\n * Helper method to parse the given URLs query parameters to a lookup dictionary\r\n * @param url - the URL string with the query params to parse\r\n * @returns The {StringMap} containing the key/value pairs, or empty object.\r\n */\r\n function getParamsObj(url: string): StringMap {\r\n const paramsObj = {};\r\n const paramArray = getParamsFromUrl(url, true);\r\n if (paramArray && paramArray.length) {\r\n paramArray.forEach(keyValuePair =>\r\n paramsObj[keyValuePair.key] = keyValuePair.value);\r\n }\r\n return paramsObj;\r\n }\r\n\r\n /**\r\n * For the given `url`, it appends the `subPath` to it.\r\n * It takes propers care to forward slashes characters\r\n * at the end of `url` and at the start of `subPath` parameters\r\n * @param url a valid url\r\n * @param subPath the path which is appended to `url`\r\n * @returns an URL object which is the `url` appended by `subPath`\r\n */\r\n export function joinSubpathToURL(url: URL, subPath: string): URL {\r\n const href = url.href;\r\n const trimmedEndSlashFromHref = trimEnd(href, \"/\");\r\n const trimmedStartSlashFromSubpath = trimStart(subPath, \"/\");\r\n return new URL(`${trimmedEndSlashFromHref}/${trimmedStartSlashFromSubpath}`);\r\n }\r\n\r\n /**\r\n * Updates a search parameter in the given url to map to a new value\r\n * Does not modify the url if the given search param doesn't exist\r\n * @param url the url to update\r\n * @param key the name of the search param to be updated\r\n * @param value the new value for the given search param\r\n * @returns {URL} the updated URL\r\n */\r\n export function updateSearchParam(url: URL, key: string, value: string): URL {\r\n // Note that the searchParams data member may not be compatible with older browser versions\r\n // see https://caniuse.com/#search=searchparams\r\n if (url && url.searchParams && url.searchParams.get(key)) {\r\n url.searchParams.set(key, value);\r\n }\r\n\r\n return url;\r\n }\r\n\r\n /**\r\n * Appends a search parameter to the given url\r\n * @param url the url to modify\r\n * @param key the name of the search param to be appended\r\n * @param value the new value for the given search param\r\n * @returns {URL} the modified URL\r\n */\r\n export function appendSearchParam(url: URL, key: string, value: string, fallback?: boolean): URL {\r\n if (url) {\r\n if (url.searchParams || fallback) {\r\n url.searchParams.append(key, value);\r\n } else {\r\n // TODO Bug 22390312: [Peregrine] UrlUtility appendSearchParam needs more robust polyfill\r\n url = new URL(url.href + (url.search.indexOf(\"?\") >= 0 ? \"&\" : \"?\") + key + \"=\" + value);\r\n }\r\n }\r\n\r\n return url;\r\n }\r\n\r\n /**\r\n * Returns an absolute URL if a relative on is passed in, or returns the passed in URL if already absolute\r\n * @param partialUrl The relative or absolute URL\r\n * @returns {string} the absolute URL\r\n */\r\n export function getAbsoluteUrl(partialUrl: string): string {\r\n if (partialUrl.indexOf(\"://\") > 0 || partialUrl.indexOf(\"//\") === 0) {\r\n return partialUrl;\r\n } else {\r\n return getLocationOrigin() + partialUrl;\r\n }\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Enum for different app types\r\n * @enum\r\n */\r\nexport enum AppType {\r\n Edge = \"edge\",\r\n EdgeChromium = \"edgeChromium\",\r\n Finance = \"finance\",\r\n FirstParty = \"firstParty\",\r\n HomePage = \"homePage\",\r\n Hub = \"hub\",\r\n MicrosoftNews = \"microsoftNews\",\r\n MMX = \"mmx\",\r\n Office = \"office\",\r\n SuperApp = \"superApp\",\r\n Traffic = \"traffic\",\r\n Views = \"views\",\r\n Weather = \"weather\",\r\n Windows = \"windows\",\r\n WindowsShell = \"windowsShell\"\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { AppError, AppErrorPropertyBag, Severity } from \"./AppErrorTracker\";\r\n\r\n/**\r\n * This file contains the list of errors to log to the server for each feature.\r\n * We are centralizing errors here to make sure we do not have any dupes\\conflicts.\r\n * The idea is that each feature would have their own range of values.\r\n *\r\n * IMPORTANT: Please do not add strings to this file. Please map messages to send in your\r\n * code.\r\n */\r\n\r\n/**\r\n * All app errors are set to create IcM ticket by default unless specified in individual error code otherwise.\r\n */\r\nconst severity = Severity.Alert;\r\n\r\n// Webpack defines the BUILD_NUMBER of client code build number.\r\ndeclare let BUILD_NUMBER: string;\r\n\r\n/**\r\n * Get build number from web pack. If not present, return empty\r\n */\r\nconst pb: AppErrorPropertyBag = {\r\n build: typeof BUILD_NUMBER === \"undefined\"\r\n ? \"\"\r\n : BUILD_NUMBER\r\n};\r\n\r\nexport function updateAppErrorsPropertyBag(newPbInfo: Partial): void {\r\n Object.assign(pb, newPbInfo);\r\n}\r\n\r\nexport function getAppErrorsPropertyBag(): AppErrorPropertyBag {\r\n return pb;\r\n}\r\n\r\n/**\r\n * Helper to create an error for logging with message and customMessage properties without having\r\n * to go manually clone the error object, or property bag, etc.\r\n * @param baseError - The base error object to use as prototype for creating the error\r\n * @param message - The custom message to use for the error\r\n * @param customMessage - The custom message that may contain strings that do not aggregate well (i.e., unique / per request data)\r\n */\r\nexport function createError(baseError: AppError, message: string, customMessage?: string): AppError {\r\n return {\r\n ...baseError,\r\n message: message || baseError.message,\r\n pb: customMessage\r\n ? { ...baseError.pb, customMessage }\r\n : baseError.pb\r\n };\r\n}\r\n\r\n/**\r\n * Error during app initialization for Edge page experience.\r\n * Need to mimic the prime one since telemetry cooking logic looks for this\r\n */\r\nexport const EstablishSignedInState: AppError = {\r\n id: 1405,\r\n source: \"EstablishSignInStateHelpers.ts\",\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/** Represents a ServiceUI related error */\r\nexport const ServiceUiError: AppError = {\r\n id: 5100,\r\n source: \"ServiceUiComm.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\n/** Represents a Top Sites related error */\r\nexport const TopSitesError: AppError = {\r\n id: 8010,\r\n source: \"TopSites.tsx\",\r\n severity,\r\n pb\r\n};\r\n\r\n/** Represents a Top Sites error when there are zero rendered top sites */\r\nexport const ZeroTopSitesError: AppError = {\r\n id: 8011,\r\n source: \"TopSites.connector.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\n/** Curated sites list is empty */\r\nexport const CuratedSitesEmpty: AppError = {\r\n id: 8012,\r\n source: \"TopSites.connector.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\nconst TopSitesEdgeConnectorFileName = \"TopSitesEdge.connector.tsx\";\r\nconst TopSitesEdgeStorageFileName = \"TopSitesStorage.ts\";\r\n\r\nexport const TopSitesEdgeAppErrors = {\r\n ZeroTopSitesError: {\r\n id: 8013,\r\n source: TopSitesEdgeConnectorFileName,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n CuratedSitesEmpty: {\r\n id: 8014,\r\n source: TopSitesEdgeStorageFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n ComponentMountFailed: {\r\n id: 8015,\r\n source: TopSitesEdgeConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n ErrorFetchingRichTopSitesDataCollectionFromCms: {\r\n id: 8016,\r\n source: TopSitesEdgeStorageFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst TopSitesEdgeNextConnectorFileName = \"TopSitesEdgeNext.connector.tsx\";\r\n\r\nexport const TopSitesEdgeNextAppErrors = {\r\n\r\n /** The React component failed to mount */\r\n ComponentMountFailed: {\r\n id: 8020,\r\n source: TopSitesEdgeNextConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Represents a Top Sites error when there are zero rendered top sites */\r\n ZeroTopSitesError: {\r\n id: 8021,\r\n source: TopSitesEdgeNextConnectorFileName,\r\n severity: Severity.NoAlert,\r\n pb\r\n }\r\n};\r\n\r\nexport const TopSiteDialogAppErrors = {\r\n /** The React component failed to mount */\r\n TopSitesDialogFailedToMount: {\r\n id: 8025,\r\n source: \"TopSitesDialog.tsx\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst OneServiceCardProviderFileName = \"OneServiceCardProvider.ts\";\r\n\r\nexport const OneServiceCardProviderAppErrors = {\r\n EmptyMyFeed: {\r\n id: 8030,\r\n source: OneServiceCardProviderFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n OneServiceResponseWasNullOrErroneous: {\r\n id: 8031,\r\n source: OneServiceCardProviderFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n ErrorFetchingOneServiceResponse: {\r\n id: 8032,\r\n source: OneServiceCardProviderFileName,\r\n severity: Severity.HighImpact,\r\n pb\r\n },\r\n\r\n InvalidJsonInOneServiceResponse: {\r\n id: 8033,\r\n source: OneServiceCardProviderFileName,\r\n severity: Severity.HighImpact,\r\n pb\r\n },\r\n\r\n InvalidFeedListInOneServiceResponse: {\r\n id: 8034,\r\n source: OneServiceCardProviderFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n RiverConfigurationIssue: {\r\n id: 8035,\r\n source: OneServiceCardProviderFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load views river content based on current vertical/category. */\r\n QueryInterestContentFetchError: {\r\n id: 8036,\r\n source: OneServiceCardProviderFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n StaticContentLoaded: {\r\n id: 8037,\r\n source: OneServiceCardProviderFileName,\r\n severity: Severity.NoAlert,\r\n pb\r\n }\r\n};\r\n\r\nconst OneServiceDailyBriefApi = \"dailyBriefServiceClient.ts\";\r\n\r\nexport const DailyBriefServiceClientAppErrors = {\r\n OneServiceResponseWasNullOrErroneous: {\r\n id: 8038,\r\n source: OneServiceDailyBriefApi,\r\n severity,\r\n pb\r\n },\r\n\r\n OneServiceArticleListWasNullOrErroneous: {\r\n id: 8039,\r\n source: OneServiceDailyBriefApi,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst ContentPreviewSourceFile = \"ContentPreview.connector.ts\";\r\nconst ContentPreviewDataSourceFile = \"ContentPreviewData.ts\";\r\nconst ExternalContentMapperHelperFile = \"ExternalContentMapperHelper.ts\";\r\n\r\nexport const ContentPreviewAppErrors = {\r\n\r\n ErrorWhileFetchingContentPreviewContent: {\r\n id: 8041,\r\n source: ContentPreviewDataSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n InvalidResponseFromContentPreviewFetch: {\r\n id: 8042,\r\n source: ContentPreviewDataSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n InvalidResponseFromContentPreviewResponseJson: {\r\n id: 8043,\r\n source: ContentPreviewDataSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n ErrorWhileInitializingAsyncContentPreviewContent: {\r\n id: 8044,\r\n source: ContentPreviewSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n InvalidOrMissingContentId: {\r\n id: 8045,\r\n source: ContentPreviewDataSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n MissingDataForExternalContent: {\r\n id: 8046,\r\n source: ExternalContentMapperHelperFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n }\r\n};\r\n\r\nexport const MissingPartnerLink: AppError = {\r\n id: 8047,\r\n source: ContentPreviewDataSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst RiverSourceFile = \"River.connector.ts\";\r\n\r\nexport const RiverAppErrors = {\r\n UnknownMetadataReceivedFromRiverCardProvider: {\r\n id: 8051,\r\n source: RiverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n RiverContentProviderFetchException: {\r\n id: 8052,\r\n source: RiverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n SkipPositionedCardsFallbackStrategyFailed: {\r\n id: 8053,\r\n source: RiverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n InvalidConfig: {\r\n id: 8054,\r\n source: RiverSourceFile,\r\n severity: Severity.HighImpact,\r\n pb\r\n },\r\n\r\n MissingExperienceTypeMap: {\r\n id: 8055,\r\n source: RiverSourceFile,\r\n severity: Severity.HighImpact,\r\n pb\r\n },\r\n\r\n ChildLoadError: {\r\n id: 8056,\r\n source: RiverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n InitialDataLoadError: {\r\n id: 8057,\r\n source: RiverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Warning for when the ordinal children we get from config contains a duplicate instance id. */\r\n DuplicateInstanceIdWarning: {\r\n id: 8058,\r\n source: RiverSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n }\r\n};\r\n\r\nexport const FullHeightFallbackStrategyFailed: AppError = {\r\n id: 8059,\r\n source: RiverSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst UserInitiatedPageRefreshSourceFile = \"UserInitiatedPageRefresh.ts\";\r\nexport const UserInitiatedPageRefreshErrors = {\r\n Default: {\r\n id: 8060,\r\n source: UserInitiatedPageRefreshSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst PivotContentSourceFile = \"PivotContent.connector.ts\";\r\nexport const PivotContentErrors = {\r\n LoadFailure: {\r\n id: 8070,\r\n source: PivotContentSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst PivotContentV2SourceFile = \"PivotContentV2.connector.ts\";\r\nexport const PivotContentV2Errors = {\r\n LoadFailure: {\r\n id: 8071,\r\n source: PivotContentV2SourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst PivotsNavSourceFile = \"PivotsNav.connector.ts\";\r\nexport const PivotsNavErrors = {\r\n TopicDataConnectorUnavailable: {\r\n id: 8075,\r\n source: PivotsNavSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n NavigationDataConnectorUnavailable: {\r\n id: 8076,\r\n source: PivotsNavSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n DynamicPivotsHelperLoaderFailed: {\r\n id: 8077,\r\n source: PivotsNavSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n LayoutPreferenceDataConnectorUnavailable: {\r\n id: 8078,\r\n source: PivotsNavSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst PivotsNavV2SourceFile = \"PivotsNavV2.connector.ts\";\r\nexport const PivotsNavV2Errors = {\r\n PivotHoverLoadFailure: {\r\n id: 8079,\r\n source: PivotsNavV2SourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Smart list is empty */\r\nexport const SmartListEmpty: AppError = {\r\n id: 8080,\r\n source: \"SmartList.connector.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\n/** Represents BingWebSSO related App errors */\r\nconst BingWebSSOSourceFile = \"BingWebSSO.tsx\";\r\nexport const BingWebSSOAppErrors = {\r\n /** Failed to render bing websso iframe */\r\n BingWebSSORenderFailed: {\r\n id: 8090,\r\n source: BingWebSSOSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** User signed-in to MSA on page but bing SSO returned authentication failed response */\r\n BingWebSSOSignInFailed: {\r\n id: 8091,\r\n source: BingWebSSOSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Bing SSO process did not complete withing required time */\r\n BingWebSSOTimeout: {\r\n id: 8092,\r\n source: BingWebSSOSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst WeatherDataConnectorSourceFile = \"WeatherData.connector.ts\";\r\nconst WeatherCardConnectorSourceFile = \"WeatherCard.connector.ts\";\r\n/** Failed to fetch weather summary */\r\nexport const WeatherSummaryFetchError: AppError = {\r\n id: 8100,\r\n source: WeatherDataConnectorSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** No valid Location set from User */\r\nexport const WeatherLocationEmpty: AppError = {\r\n id: 8101,\r\n source: WeatherDataConnectorSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/** Not able to read from PDP */\r\nexport const WeatherPDPReadFailed: AppError = {\r\n id: 8102,\r\n source: WeatherDataConnectorSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/** Not able to write home location to PDP */\r\nexport const WeatherPDPHomeLocationWriteFailed: AppError = {\r\n id: 8103,\r\n source: WeatherDataConnectorSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Not able to write display Unit to PDP */\r\nexport const WeatherPDPDisplayUnitWriteFailed: AppError = {\r\n id: 8104,\r\n source: WeatherDataConnectorSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Not able to localize Location */\r\nexport const WeatherLocalizeLocationFailed: AppError = {\r\n id: 8105,\r\n source: WeatherDataConnectorSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\nexport const WeatherCardAppErrors = {\r\n /** Failed to fetch local news */\r\n WeatherLocalNewsFetchError: {\r\n id: 8106,\r\n source: WeatherCardConnectorSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /** Failed to fetch autosuggest for locations */\r\n WeatherAutoSuggestFetchError: {\r\n id: 8107,\r\n source: WeatherCardConnectorSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /** No valid Location set from User */\r\n WeatherLocationEmpty: {\r\n id: 8108,\r\n source: WeatherCardConnectorSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Failed to fetch autosuggest for locations */\r\nexport const WeatherAutoSuggestFetchError: AppError = {\r\n id: 8109,\r\n source: WeatherDataConnectorSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** for more error about Weather, use 295XX */\r\n\r\nconst SportsPdpServiceClientSourceFile = \"SportsPdpServiceClient.ts\";\r\nexport const SportsCardError = {\r\n /** Failed to fetch league sports pdp */\r\n SportsLeaguePdpFetchError: {\r\n id: 8110,\r\n source: SportsPdpServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to fetch league sports pdp */\r\n SportsLeaguePdpInvalidResponse: {\r\n id: 8111,\r\n source: SportsPdpServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to fetch players sports pdp */\r\n SportsPlayersPdpFetchError: {\r\n id: 8112,\r\n source: SportsPdpServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to fetch players sports pdp */\r\n SportsPlayersPdpInvalidResponse: {\r\n id: 8113,\r\n source: SportsPdpServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to fetch teams sports pdp */\r\n SportsTeamsPdpFetchError: {\r\n id: 8114,\r\n source: SportsPdpServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to fetch teams sports pdp */\r\n SportsTeamsPdpInvalidResponse: {\r\n id: 8115,\r\n source: SportsPdpServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get sports card config */\r\n SportsCardConfigFetchError: {\r\n id: 8116,\r\n source: \"SportsCardConfigReader.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get Team Data */\r\n SportsCardGetFavoriteTeamDataError: {\r\n id: 8117,\r\n source: \"SportsCard.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get Team Data */\r\n SportsCardGetPlayerBioError: {\r\n id: 8118,\r\n source: \"SportsCard.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n SportsCardGetLeaguesGamesArrayError: {\r\n id: 8119,\r\n source: \"SportsCard.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n SportsCardGetPdpDataFailure: {\r\n id: 8120,\r\n source: \"SportsCard.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n SportsCardGetLeagueSeasonYearDataFailure: {\r\n id: 8121,\r\n source: \"SportsCardServiceClient.ts\",\r\n severity,\r\n pb\r\n },\r\n SportsCardGetLocalizedTeamNameDataFailure: {\r\n id: 8122,\r\n source: \"SportsCardServiceClient.ts\",\r\n severity,\r\n pb\r\n },\r\n SportsCardGetTeamDataFailure: {\r\n id: 8123,\r\n source: \"SportsCardServiceClient.ts\",\r\n severity,\r\n pb\r\n },\r\n SportsCardGetLeagueDataFailure: {\r\n id: 8124,\r\n source: \"SportsCardServiceClient.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst MoneyCardConnectorFile = \"MoneyCard.connector.ts\";\r\nconst MoneyPdpServiceClientFile = \"MoneyPdpServiceClient.ts\";\r\nexport const MoneyCardError = {\r\n /** Failed to get quote summary for user */\r\n MoneyQuoteSummaryGetError: {\r\n id: 8130,\r\n source: MoneyCardConnectorFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get quote summaries */\r\n MoneyQuoteSummariesGetError: {\r\n id: 8131,\r\n source: MoneyCardConnectorFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get pdp data */\r\n MoneyPdpDataGetErrorFromService: {\r\n id: 8132,\r\n source: MoneyPdpServiceClientFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get pdp data because of invalid response */\r\n MoneyPdpInvalidResponseFromService: {\r\n id: 8133,\r\n source: MoneyPdpServiceClientFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get quote summary response for user from service client */\r\n MoneyQuoteSummaryGetErrorFromService: {\r\n id: 8134,\r\n source: MoneyPdpServiceClientFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get quote summary response for user from service client because of invalid response */\r\n MoneyQuoteSummaryInvalidResponseFromService: {\r\n id: 8135,\r\n source: MoneyPdpServiceClientFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst TrendingNewsConnectorFile = \"TrendingNews.connector.ts\";\r\nexport const TrendingNewsErrors = {\r\n /** Failed to fetch the trending news stories */\r\n DataFetchError: {\r\n id: 8140,\r\n source: TrendingNewsConnectorFile,\r\n severity,\r\n pb\r\n },\r\n /** Failed to fetch the backup data for trending news stories */\r\n BackupDataFetchError: {\r\n id: 8141,\r\n source: TrendingNewsConnectorFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst ComplexContentPreviewSourceFile = \"ComplexContentPreview.connector.ts\";\r\nexport const ComplexContentPreviewErrors = {\r\n InitError: {\r\n id: 8150,\r\n source: ComplexContentPreviewSourceFile,\r\n severity,\r\n pb\r\n },\r\n LoadError: {\r\n id: 8151,\r\n source: ComplexContentPreviewSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n ContentError: {\r\n id: 8152,\r\n source: ComplexContentPreviewSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const GridSectionAppErrors = {\r\n /** Unable to generate river section cards */\r\n GridSectionCardGenerationError: {\r\n id: 8160,\r\n source: \"GridSection.tsx\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst MmxEntryPointFileName = \"MMXPage.connector.ts\";\r\n\r\nexport const MmxEntryPointAppErrors = {\r\n /**\r\n * MMX river is not able to load Error Page.\r\n */\r\n MmxErrorPage: {\r\n id: 8170,\r\n source: MmxEntryPointFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Error fetching the APP_ANON cookie on MMX page load\r\n */\r\n ErrorFetchingAppAnonCookie: {\r\n id: 8171,\r\n source: \"page.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst irisImageHotspotsFile = \"ImageHotspots.manager.ts\";\r\nconst irisHotspotCtaFile = \"Hotspot.cta.ts\";\r\nexport const BackgroundImageAppErrors = {\r\n /** The Bing Image of the Day failed to load properly */\r\n BingIOTDFailedToLoad: {\r\n id: 8180,\r\n source: \"BingImageOfTheDayProvider.ts\",\r\n severity,\r\n pb\r\n },\r\n /** Error when Iris fails to return Hotspots Data to the client. */\r\n FailedHotspotsDataDelivery: {\r\n id: 8181,\r\n source: irisImageHotspotsFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /** Hotspots data that was returned failed to validate. */\r\n IncompleteHotspotsContract: {\r\n id: 8182,\r\n source: irisImageHotspotsFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /** Hotspots data found for the off page navigation failed inspection. */\r\n InvalidOffPageNavCTA: {\r\n id: 8183,\r\n source: irisHotspotCtaFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Hotspots cta type or metadata not defined */\r\nexport const CTATypeOrMetdataNotDefined: AppError = {\r\n id: 8184,\r\n source: irisHotspotCtaFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Event not defined */\r\nexport const EventNotDefined: AppError = {\r\n id: 8185,\r\n source: irisHotspotCtaFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Hotspot call to action state not defined */\r\nexport const HotspotCtaStateNotDefined: AppError = {\r\n id: 8186,\r\n source: irisHotspotCtaFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SettingsDialogAppErrors = {\r\n /** Failed to get the saved layout preferences */\r\n ReadPreferencesFailed: {\r\n id: 8190,\r\n source: \"SettingsDialogEdgeNext.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to fetch the ConfigData object from the client API */\r\n FetchNtpConfigDataFailed: {\r\n id: 8191,\r\n source: \"SettingsDialogEdgeNextBase.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n ChromiumClientEmbededsearchAPIError: {\r\n id: 8192,\r\n source: \"SettingsDialogEdgeNext.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst MsnSettingMenuConnectorFileName = \"MsnSettingMenuConnector.connector.ts\";\r\n\r\nexport const MsnSettingsMenuAppErrors = {\r\n /** Failed to get feedback dialog connector */\r\n FailedToGetFeedbackDialogConnector: {\r\n id: 8193,\r\n source: MsnSettingMenuConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** Failed to get feedback data connector */\r\n FailedToGetFeedbackDataConnector: {\r\n id: 8194,\r\n source: MsnSettingMenuConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** The Msn settings menu failed to load valid config settings */\r\n MsnSettingsMenuFailedToFetchConfig: {\r\n id: 8195,\r\n source: MsnSettingMenuConnectorFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const EdgePageSettingsAppErrors = {\r\n ServiceUiError: {\r\n id: 8196,\r\n source: \"EdgeSettingsProvider.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst ShowFeedConnectorFileName = \"ShowFeed.connector.ts\";\r\n\r\nexport const ShowFeedAppErrors = {\r\n ExpectedDataMissing: {\r\n id: 8198,\r\n source: ShowFeedConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n MissingPageSettings: {\r\n id: 8199,\r\n source: ShowFeedConnectorFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst InfopaneSourceFile = \"Infopane.connector.ts\";\r\nexport const InfopaneErrors = {\r\n InitializeError: {\r\n id: 8201,\r\n source: InfopaneSourceFile,\r\n severity,\r\n pb\r\n },\r\n InvalidConfig: {\r\n id: 8202,\r\n source: InfopaneSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const FeedbackLinkAppErrors = {\r\n /** The Feedback link failed to load valid config settings */\r\n FeedbackLinkFailedToFetchConfig: {\r\n id: 8210,\r\n source: \"FeedbackLink.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n /** Failed to get feedback dialog connector */\r\n FailedToGetFeedbackDialogConnector: {\r\n id: 8211,\r\n source: \"FeedbackLink.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n /** Failed to get feedback data connector */\r\n FailedToGetFeedbackDataConnector: {\r\n id: 8212,\r\n source: \"FeedbackLink.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst FeedbackServiceClientSourceFile = \"FeedbackServiceClient.ts\";\r\nexport const FeedbackDialogAppErrors = {\r\n /** Failed to get feedback data connector */\r\n FailedToGetFeedbackDataConnector: {\r\n id: 8213,\r\n source: \"FeedbackDialog.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n /** Request is not valid, it has no content, or the manifest is not formatted correctly */\r\n BadRequestReportingFeedback: {\r\n id: 8214,\r\n source: FeedbackServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n /** Exception thrown when reporting feedback to OCV */\r\n ExceptionReportingFeedback: {\r\n id: 8215,\r\n source: FeedbackServiceClientSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst OneFooterConnectorFileName = \"OneFooter.connector.ts\";\r\nexport const OneFooterErrors = {\r\n InvalidConfig: {\r\n id: 8220,\r\n source: OneFooterConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** Failed to get feedback data connector */\r\n FailedToGetFeedbackDataConnector: {\r\n id: 8221,\r\n source: OneFooterConnectorFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const PoweredByLegendAppErrors = {\r\n /** The PoweredBy legend failed to load expected config settings */\r\n PoweredByLegendInvalidConfig: {\r\n id: 8230,\r\n source: \"PoweredByLegend.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst EdgeHeaderConnectorFileName = \"EdgeHeader.connector.ts\";\r\n\r\nexport const EdgeHeaderAppErrors = {\r\n /** The BingImageData Connector was not loaded */\r\n BingImageDataConnectorNotLoaded: {\r\n id: 8240,\r\n source: EdgeHeaderConnectorFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst MicrosoftNewsPageConnectorFileName = \"MicrosoftNewsPage.connector.ts\";\r\n\r\nexport const MicrosoftNewsPageAppErrors = {\r\n /** The BingImageData Connector was not loaded */\r\n BingImageDataConnectorNotLoaded: {\r\n id: 8241,\r\n source: MicrosoftNewsPageConnectorFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst WindowsPageConnectorFileName = \"WindowsPage.connector.ts\";\r\n\r\nexport const WindowsPageAppErrors = {\r\n /** The BingImageData Connector was not loaded */\r\n BingImageDataConnectorNotLoaded: {\r\n id: 8242,\r\n source: WindowsPageConnectorFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst TabbedInfopaneSourceFile = \"TabbedInfopane.connector.ts\";\r\nexport const TabbedInfopaneErrors = {\r\n InitializeError: {\r\n id: 8250,\r\n source: TabbedInfopaneSourceFile,\r\n severity,\r\n pb\r\n },\r\n InvalidConfig: {\r\n id: 8251,\r\n source: TabbedInfopaneSourceFile,\r\n severity,\r\n pb\r\n },\r\n ChildLoadError: {\r\n id: 8252,\r\n source: TabbedInfopaneSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const MeControlAppErrors = {\r\n /** The SSO call failed to return valid SSO sign-in information. */\r\n SSOFailedError: {\r\n id: 8260,\r\n source: \"MeControl.tsx\",\r\n severity,\r\n pb\r\n },\r\n /** The Me Control failed to load */\r\n MeControlLoadFailedError: {\r\n id: 8261,\r\n source: \"MeControl.tsx\",\r\n severity: Severity.HighImpact,\r\n pb\r\n }\r\n};\r\n\r\nconst TabbedInfopaneTabPreviewSourceFile = \"TabbedInfopaneTabPreview.connector.ts\";\r\nexport const TabbedInfopaneTabPreviewErrors = {\r\n InitError: {\r\n id: 8270,\r\n source: TabbedInfopaneTabPreviewSourceFile,\r\n severity,\r\n pb\r\n },\r\n InvalidConfig: {\r\n id: 8271,\r\n source: TabbedInfopaneTabPreviewSourceFile,\r\n severity,\r\n pb\r\n },\r\n LoadError: {\r\n id: 8272,\r\n source: TabbedInfopaneTabPreviewSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const HeaderNavigationLogoAppErrors = {\r\n MegaMenuDataError: {\r\n id: 8280,\r\n source: \"HeaderNavigationLogoConnector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst pageClicksTrackerFileName = \"pageClicksTracker.ts\";\r\nexport const PageClickTrackerErrors = {\r\n InvalidResponse: {\r\n id: 8290,\r\n severity: Severity.NoAlert,\r\n source: pageClicksTrackerFileName,\r\n pb\r\n },\r\n FetchFailure: {\r\n id: 8291,\r\n severity: Severity.NoAlert,\r\n source: pageClicksTrackerFileName,\r\n pb\r\n }\r\n};\r\n\r\nconst TargetingSystemSourceFile = \"TargetingSystem.ts\";\r\nexport const TargetingSystemAppErrors = {\r\n GeneralError: {\r\n id: 8310,\r\n source: TargetingSystemSourceFile,\r\n severity,\r\n pb\r\n },\r\n TopLevelDataMissing: {\r\n id: 8311,\r\n source: TargetingSystemSourceFile,\r\n severity,\r\n pb\r\n },\r\n TrackingDataUPSMissing: {\r\n id: 8312,\r\n source: TargetingSystemSourceFile,\r\n severity,\r\n pb\r\n },\r\n AppEnvironmentValuesMissing: {\r\n id: 8313,\r\n source: TargetingSystemSourceFile,\r\n severity,\r\n pb\r\n },\r\n CallingOneServiceFailed: {\r\n id: 8314,\r\n source: TargetingSystemSourceFile,\r\n severity,\r\n pb\r\n },\r\n CallingUPSServiceFailed: {\r\n id: 8315,\r\n source: TargetingSystemSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst CoachmarkSourceFile = \"Coachmark.connector.ts\";\r\nconst CoachmarkTSX = \"Coachmark.tsx\";\r\nconst CoachmarkCTA = \"Coachmark.cta.ts\";\r\nexport const CoachmarkAppErrors = {\r\n GeneralError: {\r\n id: 8320,\r\n source: CoachmarkTSX,\r\n severity,\r\n pb\r\n },\r\n NotPlaceable: {\r\n id: 8321,\r\n source: CoachmarkTSX,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n NotFoundComponent: {\r\n id: 8322,\r\n source: CoachmarkTSX,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n CoachmarkDataConnectorUndefined: {\r\n id: 8323,\r\n source: CoachmarkSourceFile,\r\n severity,\r\n pb\r\n },\r\n InvalidCTAType: {\r\n id: 8324,\r\n source: CoachmarkCTA,\r\n severity,\r\n pb\r\n },\r\n CTATypeNotDefined: {\r\n id: 8325,\r\n source: CoachmarkCTA,\r\n severity,\r\n pb\r\n },\r\n ConfigDataUndefined: {\r\n id: 8326,\r\n source: CoachmarkSourceFile,\r\n severity,\r\n pb\r\n },\r\n FailedToFetchConfigData: {\r\n id: 8327,\r\n source: CoachmarkSourceFile,\r\n severity,\r\n pb\r\n },\r\n ExceptionFetchingConfigData: {\r\n id: 8328,\r\n source: CoachmarkSourceFile,\r\n severity,\r\n pb\r\n },\r\n EventNotDefined: {\r\n id: 8329,\r\n source: CoachmarkCTA,\r\n severity,\r\n pb\r\n },\r\n CoachmarkStateNotDefined: {\r\n id: 8330,\r\n source: CoachmarkCTA,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst CoachmarkDataConnectorSourceFile = \"CoachmarkData.connector.ts\";\r\nconst CoachmarkPayloadSourceFile = \"CoachmarkPayload.ts\";\r\nconst IrisHandlerSourceFile = \"IrisHandler.ts\";\r\nexport const CoachmarkDataAppErrors = {\r\n InvalidCoachmarkMessage: {\r\n id: 8331,\r\n source: CoachmarkPayloadSourceFile,\r\n severity,\r\n pb\r\n },\r\n IrisDataConnectorUndefined: {\r\n id: 8332,\r\n source: IrisHandlerSourceFile,\r\n severity,\r\n pb\r\n },\r\n ErrorFoundForSurface: {\r\n id: 8334,\r\n source: IrisHandlerSourceFile,\r\n severity,\r\n pb\r\n },\r\n TelemetryInfoUndefined: {\r\n id: 8335,\r\n source: CoachmarkDataConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n EventTypeUndefined: {\r\n id: 8336,\r\n source: CoachmarkDataConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n IrisActionUndefined: {\r\n id: 8337,\r\n source: CoachmarkDataConnectorSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst AppTraceFile = \"AppTrace\";\r\nexport const AppTraceErrors = {\r\n /** Error for when app trace upload fails */\r\n UploadError: {\r\n id: 8350,\r\n source: AppTraceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst ConditionalBannerPayloadSourceFile = \"ConditionalBannerPayload.ts\";\r\nconst ConditionalBannerIrisHandlerSourceFile = \"ConditionalBannerIrisHandler.ts\";\r\n\r\nexport const ConditionalBannerInvalidConditionalBannerMessage: AppError = {\r\n id: 8363,\r\n source: ConditionalBannerPayloadSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ConditionalBannerIrisDataConnectorUndefined: AppError = {\r\n id: 8364,\r\n source: ConditionalBannerIrisHandlerSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ConditionalBannerNoSurfaceFoundForCampaign: AppError = {\r\n id: 8365,\r\n source: ConditionalBannerIrisHandlerSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ConditionalBannerErrorFoundForSurface: AppError = {\r\n id: 8366,\r\n source: ConditionalBannerIrisHandlerSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ConditionalBannerTelemetryInfoUndefined: AppError = {\r\n id: 8367,\r\n source: ConditionalBannerIrisHandlerSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ConditionalBannerEventTypeUndefined: AppError = {\r\n id: 8368,\r\n source: ConditionalBannerIrisHandlerSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ConditionalBannerIrisActionUndefined: AppError = {\r\n id: 8369,\r\n source: ConditionalBannerIrisHandlerSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst SpotlightPreviewSourceFile = \"SpotlightPreview.connector.ts\";\r\n\r\nexport const SpotlightPreviewAppErrors = {\r\n ErrorWhileFetchingSpotlightPreviewCardInfo: {\r\n id: 8401,\r\n source: SpotlightPreviewSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n NoServiceContextMetadata: {\r\n id: 8402,\r\n source: SpotlightPreviewSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst SpotlightSourceFile = \"Spotlight.connector.ts\";\r\nexport const SpotlightErrors = {\r\n UnknownError: {\r\n id: 8500,\r\n source: SpotlightSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n ContentFetchError: {\r\n id: 8501,\r\n source: SpotlightSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n PartnerFetchFail: {\r\n id: 8502,\r\n source: \"PartnerService.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const CommentsErrors: { [key: string]: AppError } = {\r\n NoPost: {\r\n id: 8510,\r\n source: \"Comments.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const CardActionErrors = {\r\n /** Error catch in base CardAction experience container */\r\n CardActionBaseExperienceError: {\r\n id: 8600,\r\n source: \"CardAction.tsx\",\r\n severity,\r\n pb\r\n },\r\n /** Post action failed (Like/Dislike) */\r\n CardActionPostActionError: {\r\n id: 8601,\r\n source: \"CarActionServiceClient.tsx\",\r\n severity,\r\n pb\r\n },\r\n /** Delete action failed (Unlike/Undislike) */\r\n CardActionDeleteActionError: {\r\n id: 8602,\r\n source: \"CardActionServiceClient.tsx\",\r\n severity,\r\n pb\r\n },\r\n /** Get action failed (GetPublisherDetails) */\r\n CardActionGetActionError: {\r\n id: 8603,\r\n source: \"CardActionServiceClient.tsx\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst ContentRelatedSourceFile = \"ContentRelated.connector.ts\";\r\nexport const ContentRelatedErrors = {\r\n /**\r\n * Missing source Id error\r\n */\r\n MissingSourceIdError: {\r\n id: 8700,\r\n source: ContentRelatedSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Invalid sourceIdError\r\n */\r\n InvalidSourceIdError: {\r\n id: 8701,\r\n source: ContentRelatedSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Related contents feed fetch error\r\n */\r\n ContentRelatedFeedFetchError: {\r\n id: 8702,\r\n source: ContentRelatedSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst CookieConsentBannerHelper = \"MsccCookieConsentHelper.ts\";\r\nexport const CookieConsentBannerHelperErrors = {\r\n FailedToParseStaticsUrls: {\r\n id: 8810,\r\n source: CookieConsentBannerHelper,\r\n severity: Severity.HighImpact,\r\n pb\r\n },\r\n ScriptsNotFound: {\r\n id: 8811,\r\n source: CookieConsentBannerHelper,\r\n severity: Severity.HighImpact,\r\n pb\r\n },\r\n StyleSheetsNotFound: {\r\n id: 8812,\r\n source: CookieConsentBannerHelper,\r\n severity: Severity.HighImpact,\r\n pb\r\n },\r\n FailedToMountScript: {\r\n id: 8813,\r\n source: CookieConsentBannerHelper,\r\n severity: Severity.HighImpact,\r\n pb\r\n },\r\n FailedToMountStyleSheet: {\r\n id: 8814,\r\n source: CookieConsentBannerHelper,\r\n severity: Severity.HighImpact,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents IFrame related errors */\r\nconst IFrameSourceFile = \"IFrame.tsx\";\r\nexport const IFrameErrors = {\r\n /** Message recieved by event listener not from expected origin */\r\n IFrameUnallowedOriginMessage: {\r\n id: 8820,\r\n source: IFrameSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n }\r\n};\r\n\r\nexport const RightRailCarouselAppErrors = {\r\n NoChildrenExperienceFoundError: {\r\n id: 8830,\r\n source: \"RightRailCarousel.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst Cookies = \"Cookies.ts\";\r\nexport const CookieRelatedErrors = {\r\n SharedStateConnectorNull: {\r\n id: 8840,\r\n source: Cookies,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const BreakingNewsErrors = {\r\n /** Error fetching Breaking News content */\r\n ContentFetchError: {\r\n id: 8901,\r\n source: \"BreakingNews.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n /** Error fetching Blowout content */\r\n BlowoutDocumentFetchError: {\r\n id: 8902,\r\n source: \"BreakingNews.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const BlowoutErrors = {\r\n /** Error fetching Blowout content */\r\n ContentFetchError: {\r\n id: 8921,\r\n source: \"Blowout.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const OverlayErrors: { [name: string]: AppError } = {\r\n /** Error loading experience */\r\n LoadExperienceError: {\r\n id: 8941,\r\n source: \"Overlay.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const ViewsCommonAppErrors = {\r\n /** Invalid intra article component metadata passed. */\r\n InvalidIntraArticleDataError: {\r\n id: 9001,\r\n source: \"IntraArticleHelper.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to fetch from data api. */\r\n DataFetchError: {\r\n id: 9002,\r\n source: \"ViewsServiceClient.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Invalid content markup encountered. */\r\n InvalidDocumentContentError: {\r\n id: 9003,\r\n source: \"ViewsUtility.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load views paddle data from data api. */\r\n ViewsPaddleDataLoadError: {\r\n id: 9004,\r\n source: \"ViewsPaddle.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Error during app initialization for views page experience. */\r\n ViewsErrorPage: {\r\n id: 9005,\r\n source: \"page.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Error during mapping provider data for views content header experience */\r\n ProviderMapperError: {\r\n id: 9006,\r\n source: \"ViewContentHeader.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const LegacySharingToolbarAppErrors = {\r\n /** Failed to invoke legacy sharing toolbar. */\r\n LegacySharingToolbarInvokeError: {\r\n id: 9100,\r\n source: \"SharingHelper.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load sharing toolbar. */\r\n SharingToolbarLoadError: {\r\n id: 9101,\r\n source: \"LegacySharingToolbar.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Invalid source content id passed in. */\r\n InvalidContentIdError: {\r\n id: 9102,\r\n source: \"LegacySharingToolbar.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents ContentActionsToolbar experience related errors */\r\nconst ContentActionsToolbarConnectorSourceFile = \"ContentActionToolbar.connector.ts\";\r\nconst ContentActionsToolbarSourceFile = \"ContentActionToolbar.tsx\";\r\nconst ContentActionsToolbarServiceClientSourceFile = \"ContentActionToolbarServiceClient.tsx\";\r\nexport const ContentActionsToolbarAppErrors = {\r\n /** Failed to load sharing toolbar - 9120 */\r\n ContentActionsSharingToolbarLoadError: {\r\n id: 9120,\r\n source: ContentActionsToolbarConnectorSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /** Error fetching article data - 9121 */\r\n ContentActionsArticleDatafetchError: {\r\n id: 9121,\r\n source: ContentActionsToolbarConnectorSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /** Base Experience error - 9122 */\r\n ContentActionsBaseExperienceError: {\r\n id: 9122,\r\n source: ContentActionsToolbarSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /** Get content views action failed (getContentViewsRequest) - 9123 */\r\n ContentActionsGetDocumentDataError: {\r\n id: 9123,\r\n source: ContentActionsToolbarServiceClientSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /** Get content status action failed (getContentStatusRequest) - 9124 */\r\n ContentActionsGetContentStatusActionError: {\r\n id: 9124,\r\n source: ContentActionsToolbarServiceClientSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /** Delete action failed (Unlike/Undislike) - 9125 */\r\n ContentActionsDeleteActionError: {\r\n id: 9125,\r\n source: ContentActionsToolbarServiceClientSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /** Post action failed (Like/Dislike) - 9126 */\r\n ContentActionsPostActionError: {\r\n id: 9126,\r\n source: ContentActionsToolbarServiceClientSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /** Prime hybrid error loading the experience - 9127 */\r\n ContentActionsExperienceLoadError: {\r\n id: 9127,\r\n source: ContentActionsToolbarSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /** Missing vert/horiz placeholder to flip toolbar - 9128 */\r\n ContentActionsFlipToolbarError: {\r\n id: 9128,\r\n source: ContentActionsToolbarSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /** Failed fetching contentStatus - 9129 */\r\n ContentActionsContentStatusFetchError: {\r\n id: 9129,\r\n source: ContentActionsToolbarServiceClientSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /** Failed fetching contentPreview - 9130 */\r\n ContentActionsContentPreviewFetchError: {\r\n id: 9130,\r\n source: ContentActionsToolbarServiceClientSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n }\r\n};\r\n\r\nexport const ContentSharingToolbarAppErrors = {\r\n ContentSharingToolbarInitializationError: {\r\n id: 9150,\r\n source: \"ContentSharingToolbar.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const ContentProviderAppErrors = {\r\n /** Invalid source article/gallery id passed in. */\r\n InvalidSourceIdError: {\r\n id: 9200,\r\n source: \"ContentProvider.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to fetch provider details. */\r\n ProviderDetailsFetchError: {\r\n id: 9201,\r\n source: \"ContentProvider.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to fetch provider feed. */\r\n ProviderFeedFetchError: {\r\n id: 9202,\r\n source: \"ContentProvider.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Invalid layout template passed in. */\r\n InvalidLayoutTemplate: {\r\n id: 9203,\r\n source: \"ContentProvider.templates.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** ApplicationCache related messages */\r\nconst refreshHeadDataFile = \"Appcache/RefreshHeadDataAppCache.ts\";\r\nconst edgeAppCacheHelperFile = \"Appcache/EdgeApplicationCacheHelper.ts\";\r\n\r\nexport const ApplicationCacheMessages = {\r\n FailedToFetchHeadData: {\r\n id: 9310,\r\n source: refreshHeadDataFile,\r\n severity,\r\n pb\r\n },\r\n CatastrophicFailedToFetchHeadData: {\r\n id: 9311,\r\n source: refreshHeadDataFile,\r\n severity,\r\n pb\r\n },\r\n StaleActivityIdEncountered: {\r\n id: 9312,\r\n source: refreshHeadDataFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /**\r\n * The current DOM that is in AppCache doesn't match what should be getting served\r\n * to the user due to the existence of the ntps cookie that defines what the locale should be.\r\n * In this case, we must bypass AppCache to get the proper DOM from PCS.\r\n */\r\n LocaleMismatch: {\r\n id: 9313,\r\n source: edgeAppCacheHelperFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n /**\r\n * Our checks determining we need to bypass appcache for the user are failing\r\n * to detect that the appcache refresh has succeeded. We've tried, for the current page view, to\r\n * bypass without any success.\r\n */\r\n RapidAppcacheForcedRefreshes: {\r\n id: 9314,\r\n source: edgeAppCacheHelperFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n FailedToReadFromStorage: {\r\n id: 9315,\r\n source: refreshHeadDataFile,\r\n severity,\r\n pb\r\n },\r\n FailedToWriteToStorage: {\r\n id: 9316,\r\n source: refreshHeadDataFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst MsRewardsConnectorSourceFile = \"MsRewards.connector.ts\";\r\nexport const MsRewardsAppErrors = {\r\n RewardsDataConnectorUndefined: {\r\n id: 9400,\r\n source: MsRewardsConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n CategoryKeyOrAppTypeUndefined: {\r\n id: 9401,\r\n source: MsRewardsConnectorSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n FailedToFetchCoachmarkUXConfig: {\r\n id: 9402,\r\n source: MsRewardsConnectorSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n ConfigDataUndefined: {\r\n id: 9403,\r\n source: MsRewardsConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n FailedToFetchConfigData: {\r\n id: 9404,\r\n source: MsRewardsConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n ExceptionFetchingConfigData: {\r\n id: 9405,\r\n source: MsRewardsConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n ChromiumPageSettingsDataConnectorUndefined: {\r\n id: 9406,\r\n source: MsRewardsConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n PageSettingsStateUndefined: {\r\n id: 9407,\r\n source: MsRewardsConnectorSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst RewardsDataConnectorSourceFile = \"RewardsData.connector.ts\";\r\nconst RewardsPayloadSourceFile = \"RewardsPayload.ts\";\r\nconst RewardsServiceClientSourceFile = \"RewardsServiceClient.ts\";\r\nexport const RewardsDataAppErrors = {\r\n InvalidCreative: {\r\n id: 9420,\r\n source: RewardsPayloadSourceFile,\r\n severity,\r\n pb\r\n },\r\n IrisDataConnectorUndefined: {\r\n id: 9421,\r\n source: IrisHandlerSourceFile,\r\n severity,\r\n pb\r\n },\r\n ErrorFoundForSurface: {\r\n id: 9423,\r\n source: IrisHandlerSourceFile,\r\n severity,\r\n pb\r\n },\r\n CoachmarkDataConnectorUndefined: {\r\n id: 9424,\r\n source: RewardsDataConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n ErrorFetchingUserProfile: {\r\n id: 9425,\r\n source: RewardsServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n ExceptionFetchingUserProfile: {\r\n id: 9426,\r\n source: RewardsServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n ExceptionReportingRewardActivity: {\r\n id: 9427,\r\n source: RewardsServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n BadRequestReportingRewardActivity: {\r\n id: 9428,\r\n source: RewardsServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n OfferIdNotDefined: {\r\n id: 9429,\r\n source: RewardsDataConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n ActionNameNotDefined: {\r\n id: 9430,\r\n source: RewardsDataConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n InvalidParameters: {\r\n id: 9431,\r\n source: RewardsServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n UnknownErrorsReportingRewardActivity: {\r\n id: 9432,\r\n source: RewardsServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n UnknownErrorOccurred: {\r\n id: 9433,\r\n source: RewardsServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n MaxRetryReachedForUpdatingRewardsPoints: {\r\n id: 9434,\r\n source: RewardsDataConnectorSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst TrendingNewsCardConnectorFile = \"mobile-feed/trending-news/TrendingNews.connector.ts\";\r\n/** Failed to fetch the trending news card in mobile feed */\r\nexport const TrendingNewsDataFetchError: AppError = {\r\n id: 9501,\r\n source: TrendingNewsCardConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to parse JSON data for trending news in mobile feed */\r\nexport const TrendingNewsDataParseError: AppError = {\r\n id: 9502,\r\n source: TrendingNewsCardConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Received null or empty response for trending news in mobile feed */\r\nexport const TrendingNewsEmptyResponseDataError: AppError = {\r\n id: 9503,\r\n source: TrendingNewsCardConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst LocalNewsCardConnectorFile = \"LocalNews.connector.ts\";\r\n/** Failed to fetch the local news card in mobile feed*/\r\nexport const LocalNewsDataFetchError: AppError = {\r\n id: 9601,\r\n source: LocalNewsCardConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to parse JSON data for local news in mobile feed */\r\nexport const LocalNewsDataParseError: AppError = {\r\n id: 9602,\r\n source: LocalNewsCardConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Received null or empty response for local news in mobile feed */\r\nexport const LocalNewsEmptyResponseDataError: AppError = {\r\n id: 9603,\r\n source: LocalNewsCardConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst ViewsGallerySourceFile = \"ViewsGallery.connector.ts\";\r\nexport const ViewsGalleryAppErrors = {\r\n /** Invalid gallery id passed. */\r\n InvalidGalleryIdError: {\r\n id: 10001,\r\n source: ViewsGallerySourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load gallery data. */\r\n GalleryDataLoadError: {\r\n id: 10010,\r\n source: ViewsGallerySourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load images. */\r\n GalleryImagesLoadError: {\r\n id: 10020,\r\n source: ViewsGallerySourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst SlideShowConnectorFile = \"SlideShow.connector.ts\";\r\nconst SlideShowCarouselFile = \"SlideShowCarousel.tsx\";\r\nexport const SlideShowAppErrors = {\r\n /** Invalid slideshow id passed. */\r\n InvalidSlideShowIdError: {\r\n id: 10100,\r\n source: SlideShowConnectorFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load slideshow data. */\r\n SlideShowDataLoadError: {\r\n id: 10110,\r\n source: SlideShowConnectorFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load images. */\r\n SlideShowImagesLoadError: {\r\n id: 10120,\r\n source: SlideShowConnectorFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to ads refresh. */\r\n SlideShowAdsRefreshError: {\r\n id: 10130,\r\n source: SlideShowCarouselFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load image. */\r\n SlideShowImageLoadFailed: {\r\n id: 10135,\r\n source: SlideShowCarouselFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const VideoListAppErrors = {\r\n /** Failed to load the video list data. */\r\n VideoListDataLoadError: {\r\n id: 11001,\r\n source: \"VideoList.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst VideoContentSourceFile = \"VideoContent.connector.ts\";\r\nexport const VideoContentAppErrors = {\r\n /** Failed to load the video content data. */\r\n InvalidResponseFromVideoContentResponseJson: {\r\n id: 11101,\r\n source: VideoContentSourceFile,\r\n severity\r\n },\r\n /** Failed to fetch the video content data from server. */\r\n ErrorWhileFetchingContentPreviewContent: {\r\n id: 11102,\r\n source: VideoContentSourceFile,\r\n severity\r\n }\r\n};\r\n\r\nconst ViewsArticleSourceFile = \"ViewsArticle.connector.ts\";\r\nexport const ViewsArticleAppErrors = {\r\n /** Invalid article id passed. */\r\n InvalidArticleIdError: {\r\n id: 12001,\r\n source: ViewsArticleSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load article data. */\r\n ArticleDataLoadError: {\r\n id: 12002,\r\n source: ViewsArticleSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load intra-article component. */\r\n IntraArticleComponentLoadError: {\r\n id: 12003,\r\n source: ViewsArticleSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to invoke inline gallery experience. */\r\n InlineGalleryInvokeError: {\r\n id: 12004,\r\n source: ViewsArticleSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const InterestsSearchAppErrors = {\r\n /** Received non 200 from OneService */\r\n ErrorResponseFromOneService: {\r\n id: 13000,\r\n source: \"InterestsSearchServiceClient.ts\",\r\n severity,\r\n pb\r\n },\r\n /** Received a response from 200 but didn't have expected structure */\r\n ErrorResponseFromOneServiceIsInvalid: {\r\n id: 13001,\r\n source: \"InterestsSearchServiceClient.ts\",\r\n severity,\r\n pb\r\n },\r\n /**\r\n * When building the XFeed URL for one of the suggestion items,\r\n * we weren't able to build a valid URL\r\n */\r\n InvalidUrlFoundForElement: {\r\n id: 13002,\r\n source: \"InterestsSearch.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n /**\r\n * When building the XFeed URL for one of the suggestion items,\r\n * we weren't able to build a valid URL\r\n */\r\n SelectedItemNotFoundInSuggestions: {\r\n id: 13003,\r\n source: \"InterestsSearch.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n /**\r\n * When building the XFeed URL for one of the suggestion items,\r\n * we weren't able to build a valid URL\r\n */\r\n SelectedItemIsInvalid: {\r\n id: 13004,\r\n source: \"InterestsSearch.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst InterestsConnectorFileName = \"Interests.connector.ts\";\r\nconst TopicCacheFileName = \"TopicCache.ts\";\r\nconst XfeedConnectorFileName = \"Xfeed.connector.ts\";\r\nexport const InterestsAppErrors = {\r\n /** We could not retrieve the list of Topics from OneService */\r\n InterestsRetrieveTopicsError: {\r\n id: 13100,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** We could not retrieve the user's list of Followed Topics from OneService */\r\n InterestsRetrieveFollowedTopicsError: {\r\n id: 13101,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** We could not retrieve the user's list of Muted Publishers from OneService */\r\n InterestsRetrieveMutedPublishersError: {\r\n id: 13102,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** We could not UnMute a Muted Publisher */\r\n InterestsUnMutePublisherError: {\r\n id: 13103,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** We could not follow a new interests topic */\r\n InterestsFollowTopicError: {\r\n id: 13104,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** We could not unfollow an interests topic */\r\n InterestsUnfollowTopicError: {\r\n id: 13105,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** TopicState should not be undefined */\r\n InterestsTopicStateUndefined: {\r\n id: 13106,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** Topics should have rendered */\r\n InterestsShouldHaveRendered: {\r\n id: 13107,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** Could not retrieve a specific topic */\r\n InterestsRetrieveTopicError: {\r\n id: 13108,\r\n source: XfeedConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** We could not retrieve the user's list of Saved Stories from OneService */\r\n InterestsRetrieveSavedStoriesError: {\r\n id: 13109,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** Saved stories config is invalid */\r\n InterestsSavedStoriesInvalidConfigError: {\r\n id: 13110,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** We could not load saved stories children */\r\n InterestsSavedStoriesChildLoadError: {\r\n id: 13111,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** OneService response for saved stories had invalid json */\r\n InterestsSavedStoriesInvalidJsonError: {\r\n id: 13112,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** OneService response for saved stories had invalid list of response */\r\n InterestsSavedStoriesInvalidListError: {\r\n id: 13113,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** We could not retrieve the user's list of Recommended Topics from OneService */\r\n InterestsRetrieveRecommendedTopicsError: {\r\n id: 13114,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** Topic Data Connector is not defined */\r\n UndefinedTopicDataConnector: {\r\n id: 13115,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** We could not retrieve the user's list of Read Stories from OneService */\r\n InterestsRetrieveReadStoriesError: {\r\n id: 13116,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** Read stories config is invalid */\r\n InterestsReadStoriesInvalidConfigError: {\r\n id: 13117,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** We could not load Read stories children */\r\n InterestsReadStoriesChildLoadError: {\r\n id: 13118,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** OneService response for Read stories had invalid json */\r\n InterestsReadStoriesInvalidJsonError: {\r\n id: 13119,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** OneService response for Read stories had invalid list of response */\r\n InterestsReadStoriesInvalidListError: {\r\n id: 13120,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** OneService failed resetting user default set of interests */\r\n FailedRestoringDefaultTopicsError: {\r\n id: 13121,\r\n source: InterestsConnectorFileName,\r\n severity,\r\n pb\r\n },\r\n /** Failed opening topics IndexedDB connection */\r\n TopicsFailedIndexedDBConnection: {\r\n id: 13122,\r\n source: TopicCacheFileName,\r\n severity,\r\n pb\r\n },\r\n /** Failed getting topics indexedDB */\r\n TopicsFailedGettingIndexedDB: {\r\n id: 13123,\r\n source: TopicCacheFileName,\r\n severity,\r\n pb\r\n },\r\n /** Failed updating topics indexedDB */\r\n TopicsFailedUpdatingIndexedDB: {\r\n id: 13124,\r\n source: TopicCacheFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst ComponentConnector = \"ComponentConnector.ts\";\r\n\r\n/** {ComponentConnector} base app errors */\r\nexport const ComponentConnectorAppErrors = {\r\n\r\n /** Duplicate child experience instance found */\r\n DuplicateChildInstanceFound: {\r\n id: 14000,\r\n source: ComponentConnector,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load bundle */\r\n BundleLoadError: {\r\n id: 14001,\r\n source: ComponentConnector,\r\n severity,\r\n pb\r\n },\r\n\r\n /** ChildConfigInfoList is null */\r\n ChildConfigInfoListNull: {\r\n id: 14002,\r\n source: ComponentConnector,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Merge List start position must be greater than 0 */\r\n ListStartPositionInvalid: {\r\n id: 14003,\r\n source: ComponentConnector,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to delay load child bundle */\r\n ChildDelayLoadError: {\r\n id: 14004,\r\n source: ComponentConnector,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Milestone dependency failed to resolve and timeout triggered */\r\n ExperienceDependencyTimeout: {\r\n id: 14005,\r\n source: ComponentConnector,\r\n severity: Severity.NoAlert,\r\n pb\r\n }\r\n};\r\n\r\n/** Data connector loading failed */\r\nexport const LoadDataConnectorConfigFailed: AppError = {\r\n id: 14006,\r\n source: ComponentConnector,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Data connector loading failed */\r\nexport const LoadDataConnectorFailed: AppError = {\r\n id: 14007,\r\n source: ComponentConnector,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Attempted to load child with invalid experience */\r\nexport const ChildWithInvalidExperience: AppError = {\r\n id: 14008,\r\n source: ComponentConnector,\r\n severity,\r\n pb\r\n};\r\n\r\n/** App errors for {ExperienceLoader} */\r\nexport const ExperienceLoaderAppErrors = {\r\n /** Logged when neither the config type nor config HREF was provided to the loader */\r\n InsufficientLoadArgs: {\r\n id: 14100,\r\n source: \"ExperienceLoader.ts\",\r\n severity: Severity.HighImpact,\r\n pb\r\n }\r\n};\r\n\r\n/** Logged when ConnectComponent call in getConnectedExperience fails */\r\nexport const ConnectComponentFailureError: AppError = {\r\n id: 14101,\r\n source: \"ExperienceLoader.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\n/** Logged when loadComponent fails */\r\nexport const LoadComponentFailureError: AppError = {\r\n id: 14102,\r\n source: \"ExperienceLoader.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\n/** Represents SearchHistoryCommon related App errors */\r\nconst SearchHistoryCommonSourceFile = \"SearchHistoryCommon.tsx\";\r\nexport const SearchHistoryCommonAppErrors = {\r\n /** Failed to parse search history response */\r\n ResponseParsingFailed: {\r\n id: 15000,\r\n source: SearchHistoryCommonSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Search history service call failed */\r\n ServiceCallFailed: {\r\n id: 15001,\r\n source: SearchHistoryCommonSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to render search history */\r\n RenderFailed: {\r\n id: 15002,\r\n source: SearchHistoryCommonSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Search history api response not received within configured time */\r\n Timeout: {\r\n id: 15003,\r\n source: SearchHistoryCommonSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Search history api call unauthorized */\r\n Unauthorized: {\r\n id: 15004,\r\n source: SearchHistoryCommonSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Search history api call forbidden */\r\n Forbidden: {\r\n id: 15005,\r\n source: SearchHistoryCommonSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Search history api not able to find recent search associated with this request */\r\n NotFound: {\r\n id: 15006,\r\n source: SearchHistoryCommonSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Search history api response not received within configured time but wait for searchHistoryFetchPromise to be completed */\r\n TimeoutDetail: {\r\n id: 15007,\r\n source: SearchHistoryCommonSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents search history edgenext failed to render */\r\nexport const SearchHistoryEdgenextRenderFailed: AppError = {\r\n id: 15008,\r\n source: \"SearchHistoryEdgenext.tsx\",\r\n severity: Severity.HighImpact,\r\n pb\r\n};\r\n\r\nconst SearchHistoryEdgeNextSourceFile = \"SearchHistoryEdgenext.connector.ts\";\r\n/** Represents failed to retrieve account type */\r\nexport const FailedToRetrieveAccountType: AppError = {\r\n id: 15009,\r\n source: SearchHistoryEdgeNextSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/** Represents failed to retrieve account info */\r\nexport const FailedToRetrieveAccountInfo: AppError = {\r\n id: 15010,\r\n source: SearchHistoryEdgeNextSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/** Represents failed to get access token */\r\nexport const FailedToGetAccessToken: AppError = {\r\n id: 15011,\r\n source: SearchHistoryEdgeNextSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/** Represents a Search related error */\r\nexport const SearchError: AppError = {\r\n id: 15100,\r\n source: \"SearchBox.tsx\",\r\n severity: Severity.HighImpact,\r\n pb\r\n};\r\n\r\n/** Represents missing form code/parameters related App errors */\r\nexport const MissingFormCode: AppError = {\r\n id: 15101,\r\n source: \"SearchBoxCommon.connector.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\n/** Represents RecommendedSearch related App errors */\r\nconst RecommendedSearchSourceFile = \"RecommendedSearchDataService.ts\";\r\nexport const RecommendedSearchErrors = {\r\n /** Warning for failed to parse recommended search response */\r\n ResponseParsingFailed: {\r\n id: 15200,\r\n source: RecommendedSearchSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /** warning for recommended search service returned invalid Json response */\r\n InvalidJsonResponse: {\r\n id: 15201,\r\n source: RecommendedSearchSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /** Warning for recommended search service call failed */\r\n ServiceCallFailed: {\r\n id: 15202,\r\n source: RecommendedSearchSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /** Failed to render recommended searches */\r\n RenderFailed: {\r\n id: 15203,\r\n source: RecommendedSearchSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Warning for recommended search api response not received within configured time */\r\n Timeout: {\r\n id: 15204,\r\n source: RecommendedSearchSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /** recommended search back fill failed to fetch content from CMS */\r\n ContentFetchError: {\r\n id: 15205,\r\n source: RecommendedSearchSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents recommende search below search box rendered failed to render */\r\nexport const RecommendedSearchBelowSearchBoxRenderFailed: AppError = {\r\n id: 15211,\r\n source: \"RecommendedSearchBelowSearchBox.tsx\",\r\n severity: Severity.Critical,\r\n pb\r\n};\r\n\r\n/** Represents Trending Now related app errors */\r\nconst TrendingNowSourceFile = \"TrendingNow.connector.ts\";\r\nexport const TrendingNowErrors = {\r\n /** Failed to fetch Trending now content from CMS */\r\n ContentFetchError: {\r\n id: 15250,\r\n source: TrendingNowSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to fetch child experience config */\r\n FailedToFetchConfig: {\r\n id: 15251,\r\n source: TrendingNowSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load child experience */\r\n FailedToLoadChildExperience: {\r\n id: 15252,\r\n source: TrendingNowSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** OCID not set for canvas */\r\n OCIDNotSetWarning: {\r\n id: 15253,\r\n source: \"TrendingNowServiceClient.ts\",\r\n severity: Severity.NoAlert,\r\n pb\r\n }\r\n};\r\n\r\nconst RelatedSearchesCardConnectorFile = \"RelatedSearchesCard.connector.ts\";\r\nexport const RelatedSearchesNoSearchTerm: AppError = {\r\n id: 15260,\r\n source: RelatedSearchesCardConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const RelatedSearchesServiceCallError: AppError = {\r\n id: 15261,\r\n source: RelatedSearchesCardConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const RelatedSearchesResponseEmpty: AppError = {\r\n id: 15262,\r\n source: RelatedSearchesCardConnectorFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\nconst PollsCardConnectorSourceFile = \"PollsCard.connector.ts\";\r\nconst PollsCardSchemaTransformerFile = \"PollsCard.SchemaTransformer.ts\";\r\nexport const PollsCardAppErrors = {\r\n /**\r\n * Failed to fetch polls list\r\n */\r\n PollsListFetchError: {\r\n id: 18000,\r\n source: PollsCardConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Failed to fetch poll data\r\n */\r\n PollDataFetchError: {\r\n id: 18001,\r\n source: PollsCardConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * No data{questions} for poll\r\n */\r\n PollsCardInvalidPoll: {\r\n id: 18002,\r\n source: PollsCardConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Invalid Poll Quiz\r\n */\r\n PollsCardInvalidQuizPoll: {\r\n id: 18003,\r\n source: PollsCardConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * PollsVoteError\r\n */\r\n PollsCardVoteError: {\r\n id: 18004,\r\n source: PollsCardConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * PollsMapStateToPropsError\r\n */\r\n PollsCardMapStateToPropsError: {\r\n id: 18005,\r\n source: PollsCardConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * PollsUnknownError\r\n */\r\n PollsUnknownError: {\r\n id: 18006,\r\n source: PollsCardConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Poll Result Percentage Error\r\n */\r\n PollsResultPercentageError: {\r\n id: 18007,\r\n source: PollsCardConnectorSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const PollAutoCuratedErrors = {\r\n /**\r\n * Poll Auto curate content error\r\n */\r\n PollAutoCuratedContentError: {\r\n id: 18008,\r\n source: PollsCardConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Poll Auto curate content error\r\n */\r\n PollAutoCuratedInvalid: {\r\n id: 18009,\r\n source: PollsCardSchemaTransformerFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Poll Auto curate content error\r\n */\r\n PollAutoCuratedResultsFetchError: {\r\n id: 18010,\r\n source: PollsCardConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n PollAutoCuratedResultsTransformError: {\r\n id: 18011,\r\n source: PollsCardSchemaTransformerFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const EdgeNextAppErrors = {\r\n /**\r\n * Error during app initialization for EdgeNext page experience.\r\n */\r\n EdgeNextErrorPage: {\r\n id: 19000,\r\n source: \"page.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Error fetching the APP_ANON cookie on EdgeNext page load */\r\n ErrorFetchingAppAnonCookie: {\r\n id: 19001,\r\n source: \"page.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Tracking errors where we ended up showing the local ntp page on bundle syntax errors.\r\n */\r\n EdgeNextLocalNTPPageShownSyntaxErrors: {\r\n id: 19002,\r\n source: \"page.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Tracking errors where we ended up showing the local ntp page on bundle failures.\r\n */\r\n EdgeNextLocalNTPPageShownBundleFailureErrors: {\r\n id: 19003,\r\n source: \"page.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Tracking errors where we ended up showing the local ntp page on page exception.\r\n */\r\n EdgeNextLocalNTPPageShownPageExceptionError: {\r\n id: 19004,\r\n source: \"page.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Tracking errors where we ended up showing the local ntp page on page exception.\r\n */\r\n EdgeNextLocalNTPPageShownJSSMismatchExceptionError: {\r\n id: 19005,\r\n source: \"page.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Tracking errors where we ended up reloading the NTP page on jss mismatch exception.\r\n */\r\n EdgeNextPageReloadedPageExceptionError: {\r\n id: 19010,\r\n source: \"page.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Tracking errors where we ended up reloading the NTP page on jss mismatch exception.\r\n */\r\n EdgeNextPageReloadedJSSMismatchExceptionError: {\r\n id: 19011,\r\n source: \"PersistRenderCache.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst AdRefreshSourceFile = \"AdsRefresh.ts\";\r\nconst ApnWrapperSourceFile = \"AppnexusWrapper.ts\";\r\nconst DisplayAdsAdsDetectionSourceFile = \"AdsDetection.ts\";\r\nconst DisplayAdsConnectorSourceFile = \"DisplayAds.connector.ts\";\r\nconst DisplayAdsManagerConnectorSourceFile = \"DisplayAdsManager.connector.ts\";\r\nconst NativeAdConnectorSourceFile = \"NativeAd.connector.ts\";\r\nconst OathWrapperSourceFile = \"OathAdsWrapper.ts\";\r\nconst PlacementManagerConnectorSourceFile = \"PlacementManager.connector.ts\";\r\nconst PlacementManagerCookieSyncSourceFile = \"PlacementManagerCookieSync.ts\";\r\nconst PlacementManagerCMSServiceSourceFile = \"PlacementManagerCMSService.ts\";\r\nconst NativeAdClientConnectorSourceFile = \"NativeAdClient.connector.ts\";\r\nconst PartnerScriptLoaderFile = \"PartnerScriptLoader.ts\";\r\nconst NativeAdBeaconSourceFile = \"Beacon.ts\";\r\n\r\nexport const MonetizationAppErrors = {\r\n /** Failed to load Placement Manager. */\r\n PlacementManagerLoadError: {\r\n id: 20000,\r\n source: NativeAdConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load arrangement position on native ad experience. */\r\n ArrangementPositionLoadError: {\r\n id: 20001,\r\n source: NativeAdConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get CMS Content. */\r\n GetCMSContentError: {\r\n id: 20002,\r\n source: PlacementManagerCMSServiceSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get SAM RTB Response. */\r\n GetSAMRTBResponseError: {\r\n id: 20003,\r\n source: PlacementManagerConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load MediaNet End Of Article Block. */\r\n MediaNetEOABError: {\r\n id: 20005,\r\n source: \"medianetNativeAdOnArticle.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** Invalid promo module config */\r\n InvalidPromoModuleConfig: {\r\n id: 20006,\r\n source: NativeAdConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to download cookie sync external script. */\r\n CookieSyncDownloadExternalScriptError: {\r\n id: 20007,\r\n source: PlacementManagerCookieSyncSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Missing cookie sync external script. */\r\n CookieSyncMissingExternalScriptUrl: {\r\n id: 20008,\r\n source: PlacementManagerCookieSyncSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Cookie sync timeout. */\r\n CookieSyncTimeout: {\r\n id: 20009,\r\n source: PlacementManagerCookieSyncSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Cookie sync partner script error */\r\n CookieSyncPartnerScriptError: {\r\n id: 20010,\r\n source: PlacementManagerCookieSyncSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Cookie pixel sync partner download error */\r\n CookieSyncPixelPartnerDownloadError: {\r\n id: 20011,\r\n source: PlacementManagerCookieSyncSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load cms or backfill native ad. */\r\n CMSOrBackfillNativeAdLoadError: {\r\n id: 20012,\r\n source: NativeAdConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Missing required property on placement manager config */\r\n MissingRequiredPropertyPlacementManagerConfig: {\r\n id: 20014,\r\n source: PlacementManagerConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Missing page type target scope. */\r\n NativeAdTargetScopeError: {\r\n id: 20016,\r\n source: NativeAdConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** River video ad partner error. */\r\n RiverVideoAdPartnerError: {\r\n id: 20017,\r\n source: PartnerScriptLoaderFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** JsTracker ad partner script load error. */\r\n JsTrackerPartnerScriptLoadError: {\r\n id: 20018,\r\n source: NativeAdBeaconSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Viglink load error. */\r\n ViglinkError: {\r\n id: 20019,\r\n source: PartnerScriptLoaderFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Missing topic id for stripe native ad */\r\n MissingTopicId: {\r\n id: 20020,\r\n source: NativeAdConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Topic id not found for stripe native ad */\r\n TopicIdNotFound: {\r\n id: 20021,\r\n source: NativeAdConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get SAM RTB Response. This App error doesn't trigger alert */\r\n GetSAMRTBResponseErrorNoAlert: {\r\n id: 20022,\r\n source: PlacementManagerConnectorSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /** Failed to load Oath JS */\r\n DisplayAdsOathLoadError: {\r\n id: 20050,\r\n source: OathWrapperSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to load AppNexus JS */\r\n DisplayAdsApnLoadError: {\r\n id: 20051,\r\n source: ApnWrapperSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** AppNexus Provider was empty */\r\n DisplayAdsApnEmptyProvider: {\r\n id: 20052,\r\n source: ApnWrapperSourceFile,\r\n severity: Severity.Alert\r\n },\r\n\r\n /** Ads Detection no initialized properly Provider was empty */\r\n DisplayAdsAdsDetectionNotInit: {\r\n id: 20053,\r\n source: DisplayAdsAdsDetectionSourceFile,\r\n severity: Severity.Alert,\r\n pb\r\n },\r\n\r\n /** Failed to load Moat JS */\r\n DisplayAdsMoatLoadError: {\r\n id: 20054,\r\n source: DisplayAdsManagerConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Display ad objects were not available for refresh */\r\n DisplayAdsNoAdObjects: {\r\n id: 20055,\r\n source: AdRefreshSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** There was a problem in encoding CMS provider ID from base 62 to 32 */\r\n DisplayAdsProviderIdEncode: {\r\n id: 20056,\r\n source: DisplayAdsConnectorSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const TaboolaRiverAppErrors = {\r\n /** Failed to fetch taboola river data. */\r\n TaboolaRiverFetchError: {\r\n id: 20100,\r\n source: \"TaboolaRiver.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst NativeAdServiceFile = \"NativeAdService.ts\";\r\nconst CMSAdServiceFile = \"CMSAdService.ts\";\r\nexport const AdServiceAppErrors = {\r\n /** Failed to get valid Response from AdService library */\r\n GetNativeAdResponseError: {\r\n id: 20150,\r\n source: NativeAdServiceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Failed to get valid CMS Response from AdService library */\r\n GetCMSAdResponseError: {\r\n id: 20151,\r\n source: CMSAdServiceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst PCSPageHTMLFile = \"PCS-Page.cshtml\";\r\nexport const CoreLibAppErrors = {\r\n /** Deprecated composition layout config in use */\r\n DeprecatedCompositionLayoutUsed: {\r\n id: 20200,\r\n source: \"LayoutBase.inspector.ts\",\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /** Deprecated composition layout config in use */\r\n InvalidColumnInGridConfig: {\r\n id: 20201,\r\n source: \"GridBase.inspector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Error during loading of page bundles.\r\n */\r\n ErrorLoadingBundle: {\r\n id: 20202,\r\n source: PCSPageHTMLFile,\r\n severity: Severity.HighImpact,\r\n pb\r\n },\r\n\r\n /**\r\n * Generic JS exceptions.\r\n */\r\n GenericJSException: {\r\n id: 20203,\r\n source: PCSPageHTMLFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Missing localStorage exception\r\n */\r\n LocalStorageDoesntExist: {\r\n id: 20204,\r\n source: \"WebStorage.ts\",\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /**\r\n * Missing sessionStorage exception\r\n */\r\n SessionStorageDoesntExist: {\r\n id: 20205,\r\n source: \"WebStorage.ts\",\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /**\r\n * Exception thrown during rendering in React\r\n */\r\n ReactRenderException: {\r\n id: 20206,\r\n source: PCSPageHTMLFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents Authenticatedfetch related App errors */\r\nconst AuthenticatedFetchSourceFile = \"AuthenticatedFetch.ts\";\r\nexport const AuthenticatedFetchErrors = {\r\n ErrorCodeReceived: {\r\n id: 20302,\r\n source: AuthenticatedFetchSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n CallFailed: {\r\n id: 20303,\r\n source: AuthenticatedFetchSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst resolverSourceFile = \"resolver.ts\";\r\nexport const ResolverAppErrors = {\r\n /**\r\n * IndexedDb write failed in resolver.\r\n */\r\n IndexedDbWriteFailed: {\r\n id: 22010,\r\n source: resolverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * IndexedDb read failed in resolver.\r\n */\r\n IndexedDbReadFailed: {\r\n id: 22011,\r\n source: resolverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Config Service Resolver fetch failed.\r\n */\r\n CrsFetchFailed: {\r\n id: 22012,\r\n source: resolverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Config Service Resolver was enabled but we still went to Assets to getConfig and merge configs at client (classic resolver).\r\n */\r\n ReceivedConfigFromCdnAsCrsFetchFailed: {\r\n id: 22013,\r\n source: resolverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Exception In GetConfig function.\r\n */\r\n GetConfigException: {\r\n id: 22014,\r\n source: resolverSourceFile,\r\n severity: Severity.Critical,\r\n pb\r\n },\r\n\r\n /**\r\n * IndexedDb bulk read failed in resolver.\r\n */\r\n IndexedDbBulkReadFailed: {\r\n id: 22015,\r\n source: resolverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * IndexedDb failed to remove cached config\r\n */\r\n IndexedDbFailedToRemoveCachedConfig: {\r\n id: 22016,\r\n source: resolverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * IndexedDb failed to clear all configs\r\n */\r\n IndexedDbFailedToClearAllCachedConfigs: {\r\n id: 22017,\r\n source: resolverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Render cache is purged due to changes in config\r\n */\r\n RenderCachePurgedDueToChangesInConfig: {\r\n id: 22018,\r\n source: resolverSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /**\r\n * Render cache failed purge even though config changes were detected.\r\n */\r\n FailedToPurgeRenderCache: {\r\n id: 22019,\r\n source: resolverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Failed to refresh config cache\r\n */\r\n RefreshConfigCacheFailed: {\r\n id: 22020,\r\n source: resolverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Failed to initialize indexedDb\r\n */\r\n IndexedDbInitFailed: {\r\n id: 22021,\r\n source: resolverSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Different cache busting identifier\r\n */\r\n DifferentCbid: {\r\n id: 22022,\r\n source: resolverSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /**\r\n * Error writing prg flights to localStorage\r\n */\r\n PrgFlightLsWriteError: {\r\n id: 22023,\r\n source: resolverSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /**\r\n * Error reading prg flights to localStorage\r\n */\r\n PrgFlightLsReadError: {\r\n id: 22024,\r\n source: resolverSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n }\r\n};\r\n\r\n/**\r\n * Configs served from CDN after CRS fetch failed\r\n */\r\nexport const ResolverErrorConfigsDownloadedByCdn: AppError = {\r\n id: 22025,\r\n source: resolverSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/**\r\n * Cached configs are for different flight\r\n */\r\nexport const CachedConfigsForDifferentFlight: AppError = {\r\n id: 22026,\r\n source: resolverSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\nexport const HubAppErrors = {\r\n /**\r\n * Error during app initialization for hub page experience.\r\n */\r\n HubErrorPage: {\r\n id: 22100,\r\n source: \"page.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst EdgePageFileName = \"Edge/page.ts\";\r\n\r\n/** Edge App Type errors. */\r\nexport const EdgeAppErrors = {\r\n ErrorFetchingChildCookie: {\r\n id: 23000,\r\n source: EdgePageFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Error during app initialization for Edge page experience.\r\n */\r\n EdgeErrorPage: {\r\n id: 23001,\r\n source: EdgePageFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Error fetching the APP_ANON cookie on Edge page load\r\n */\r\n ErrorFetchingAppAnonCookie: {\r\n id: 23002,\r\n source: EdgePageFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Error during set flight instrumentation data\r\n */\r\n ErrorSetFlightInstrumentation: {\r\n id: 23003,\r\n source: EdgePageFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const BingCardsAppErrors = {\r\n BingCardGetHotelAnswersError: {\r\n id: 24001,\r\n source: \"BingCardsServiceClient.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n BingCardGetHotelErrorFromService: {\r\n id: 24002,\r\n source: \"BingCardsServiceClient.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n BingCardGetAnswersError: {\r\n id: 24003,\r\n source: \"BingCardsExperience.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n BingCardInvalidEntityType: {\r\n id: 24004,\r\n source: \"BingCardsExperience.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n BingCardErrorOut: {\r\n id: 24005,\r\n source: \"BingCardsExperience.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const BingAnswersAppErrors = {\r\n UnknownError: {\r\n id: 24101,\r\n source: \"BingAnswers.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n FailedToLoadData: {\r\n id: 24102,\r\n source: \"BingAnswers.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n NoCardsContentType: {\r\n id: 24103,\r\n source: \"BingAnswers.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n NoCardsRelated: {\r\n id: 24104,\r\n source: \"BingAnswers.connector.ts\",\r\n severity: Severity.NoAlert,\r\n pb\r\n }\r\n};\r\n\r\nconst BingShoppingShopCardServiceClientSourceFile =\r\n \"bing-shopping/ShopCardServiceClient.ts\";\r\n\r\nexport const BingShoppingShopCardError = {\r\n ShopCardServiceFetchError: {\r\n id: 24200,\r\n source: BingShoppingShopCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n ShopCardServiceFetchInvalidResponse: {\r\n id: 24201,\r\n source: BingShoppingShopCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n ShopCardServiceEmptyPersonalizedResponse: {\r\n id: 24202,\r\n source: BingShoppingShopCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n ShopCardServiceInvalidPersonalizedResponse: {\r\n id: 24203,\r\n source: BingShoppingShopCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n ShopCardServiceEmptyTrendingResponse: {\r\n id: 24204,\r\n source: BingShoppingShopCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n ShopCardServiceInvalidTrendingResponse: {\r\n id: 24205,\r\n source: BingShoppingShopCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst BingShoppingLifestyleCardServiceClientSourceFile =\r\n \"bing-shopping-lifestyle-card/BingShoppingLifestyleCardServiceClient.ts\";\r\n\r\nconst BingShoppingLifestyleCardCdnServiceClientSourceFile =\r\n \"bing-shopping-lifestyle-card/BingShoppingLifestyleCardCdnServiceClient.ts\";\r\n\r\nconst BingShoppingLifestyleAutosuggestServiceClientSourceFile =\r\n \"bing-shopping-lifestyle-card/BingShoppingLifestyleAutosuggestServiceClient.ts\";\r\n\r\nconst BingShoppingLifestyleConnectorSourceFile =\r\n \"bing-shopping-lifestyle-card/BingShoppingLifestyleCard.connector.ts\";\r\nexport const BingShoppingLifestyleCardError = {\r\n // Lifestyle Shopcard service Errors\r\n LifestyleShopCardServiceFetchError: {\r\n id: 24300,\r\n source: BingShoppingLifestyleCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n LifestyleShopCardServiceFetchInvalidResponse: {\r\n id: 24301,\r\n source: BingShoppingLifestyleCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n LifestyleShopCardServiceEmptyResponse: {\r\n id: 24302,\r\n source: BingShoppingLifestyleCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n LifestyleShopCardServiceInvalidResponse: {\r\n id: 24303,\r\n source: BingShoppingLifestyleCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n // Lifestyle Shopcard Cdn service Errors\r\n LifestyleShopCardCdnServiceFetchError: {\r\n id: 24304,\r\n source: BingShoppingLifestyleCardCdnServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n LifestyleShopCardCdnServiceFetchInvalidResponse: {\r\n id: 24305,\r\n source: BingShoppingLifestyleCardCdnServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n LifestyleShopCardCdnServiceInvalidResponse: {\r\n id: 24306,\r\n source: BingShoppingLifestyleCardCdnServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n // Lifestyle Autosuggest service Errors\r\n LifestyleShopAutosuggestServiceFetchError: {\r\n id: 24310,\r\n source: BingShoppingLifestyleAutosuggestServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n LifestyleShopAutosuggestServiceFetchInvalidResponse: {\r\n id: 24311,\r\n source: BingShoppingLifestyleAutosuggestServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n LifestyleShopAutosuggestServiceEmptyResponse: {\r\n id: 24312,\r\n source: BingShoppingLifestyleAutosuggestServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n LifestyleShopAutosuggestServiceInvalidResponse: {\r\n id: 24313,\r\n source: BingShoppingLifestyleAutosuggestServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n LifestyleShopAutosuggestInvalidSuggestionUrl: {\r\n id: 24314,\r\n source: BingShoppingLifestyleConnectorSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst ShoppingSmartListServiceClientSourceFile =\r\n \"shopping-smart-list/ShoppingSmartListServiceClient.ts\";\r\n\r\nconst ShoppingSmartListConnectorSourceFile =\r\n \"shopping-smart-list/ShoppingSmartList.connector.ts\";\r\n\r\nexport const ShoppingSmartListError = {\r\n ShoppingSmartListServiceEmptyResponse: {\r\n id: 24400,\r\n source: ShoppingSmartListServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n ShoppingSmartListServiceFetchError: {\r\n id: 24401,\r\n source: ShoppingSmartListServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n ShoppingSmartListServiceInvalidResponse: {\r\n id: 24402,\r\n source: ShoppingSmartListServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n ShoppingSmartListServiceMissingRequiredFields: {\r\n id: 24403,\r\n source: ShoppingSmartListServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n ShoppingSmartListChromiumApiConfigDataFetchFailure: {\r\n id: 24404,\r\n source: ShoppingSmartListConnectorSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst BingMiniShoppingServiceClientSourceFile =\r\n \"bing-mini-shopping/BingMiniShoppingServiceClient.ts\";\r\n\r\nexport const BingMiniShoppingError = {\r\n // Bing-MiniShopping service Errors\r\n BingMiniShoppingServiceFetchError: {\r\n id: 24500,\r\n source: BingMiniShoppingServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n BingMiniShoppingServiceEmptyResponse: {\r\n id: 24501,\r\n source: BingMiniShoppingServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n BingMiniShoppingServiceInvalidResponse: {\r\n id: 24502,\r\n source: BingMiniShoppingServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n BingMiniShoppingServiceInsufficientDealsItems: {\r\n id: 24503,\r\n source: BingMiniShoppingServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n BingMiniShoppingServiceInsufficientActiveDealsItems: {\r\n id: 24504,\r\n source: BingMiniShoppingServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n BingMiniShoppingServiceInsufficientTrendingItems: {\r\n id: 24505,\r\n source: BingMiniShoppingServiceClientSourceFile,\r\n severity,\r\n pb\r\n },\r\n BingMiniShoppingServiceInsufficientTrendingCategories: {\r\n id: 24506,\r\n source: BingMiniShoppingServiceClientSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst BingShoppingMeStripeServiceClientSourceFile =\r\n \"bing-shopping-mestripe/BingShoppingMeStripeServiceClient.ts\";\r\n\r\nexport const BingShoppingMeStripeServiceFetchError: AppError = {\r\n id: 24510,\r\n source: BingShoppingMeStripeServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const BingShoppingMeStripeServiceEmptyResponse: AppError = {\r\n id: 24511,\r\n source: BingShoppingMeStripeServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const BingShoppingMeStripeServiceInvalidResponse: AppError = {\r\n id: 24512,\r\n source: BingShoppingMeStripeServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const BingShoppingMeStripeServiceMissingRequiredFields: AppError = {\r\n id: 24513,\r\n source: BingShoppingMeStripeServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst ShoppingCarouselServiceClientSourceFile =\r\n \"shopping-carousel/ShoppingCarouselServiceClient.ts\";\r\n\r\nexport const ShoppingCarouselEntitiesDataServiceFetchError: AppError = {\r\n id: 24520,\r\n source: ShoppingCarouselServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ShoppingCarouselEntitiesDataServiceEmptyResponse: AppError = {\r\n id: 24521,\r\n source: ShoppingCarouselServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ShoppingCarouselEntitiesDataServiceInvalidResponse: AppError = {\r\n id: 24522,\r\n source: ShoppingCarouselServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ShoppingCarouselEntitiesDataServiceInsufficientItems: AppError = {\r\n id: 24523,\r\n source: ShoppingCarouselServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst ShoppingCarouselConnectorSourceFile =\r\n \"shopping-carousel/ShoppingCarousel.connector.ts\";\r\n\r\nexport const ShoppingCarouselGenericError: AppError = {\r\n id: 24524,\r\n source: ShoppingCarouselConnectorSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst ShoppingCarouselSourceFile =\r\n \"shopping-carousel/ShoppingCarousel.tsx\";\r\n\r\nexport const ShoppingCarouselRenderError: AppError = {\r\n id: 24525,\r\n source: ShoppingCarouselSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst ShoppingContentCardServiceClientSourceFile =\r\n \"ShoppingContentCard.serviceClient.ts\";\r\n\r\nexport const ShoppingContentCardServiceFetchError: AppError = {\r\n id: 24530,\r\n source: ShoppingContentCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ShoppingContentCardServiceEmptyResponse: AppError = {\r\n id: 24531,\r\n source: ShoppingContentCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ShoppingContentServiceInvalidData: AppError = {\r\n id: 24532,\r\n source: ShoppingContentCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ShoppingContentServiceInsufficientActiveItems: AppError = {\r\n id: 24533,\r\n source: ShoppingContentCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const ShoppingContentServiceMissingFields: AppError = {\r\n id: 24534,\r\n source: ShoppingContentCardServiceClientSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const PageSettingsDataConnectorAppErrors = {\r\n PageSettingsGetInitialState: {\r\n id: 26001,\r\n source: \"PageSettingsData.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst MicrosoftNewsEntryPointFileName = \"MicrosoftNews.connector.ts\";\r\nexport const MicrosoftNewsEntryPointAppErrors = {\r\n /**\r\n * Error during app initialization for MicrosoftNews page experience.\r\n */\r\n MicrosoftNewsErrorPage: {\r\n id: 27000,\r\n source: MicrosoftNewsEntryPointFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const NavigationDataConnectorAppErrors = {\r\n /**\r\n * Error while trying to fetch the Navigation Items\r\n */\r\n NavigationDataGetNavigationItems: {\r\n id: 28000,\r\n source: \"NavigationData.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n NavigationDataIndexedDbInitializationFailed: {\r\n id: 28001,\r\n source: \"NavigationData.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n NavigationDataIndexedDbWriteFailed: {\r\n id: 28002,\r\n source: \"NavigationData.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n NavigationDataIndexedDbBulkReadFailed: {\r\n id: 28003,\r\n source: \"NavigationData.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const CategoryDataConnectorAppErrors = {\r\n /**\r\n * Error while to get the category details\r\n */\r\n CategoryDataGetCategoryDetail: {\r\n id: 28100,\r\n source: \"CategoryData.connector.ts\",\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n CategoryDataIndexedDbInitializationFailed: {\r\n id: 28101,\r\n source: \"CategoryData.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n CategoryDataIndexedDbWriteFailed: {\r\n id: 28102,\r\n source: \"CategoryData.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n CategoryDataIndexedDbBulkReadFailed: {\r\n id: 28103,\r\n source: \"CategoryData.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/**\r\n * App reporting messages related to OneService Content Data Connector\r\n */\r\nexport const OneServiceContentDataConnector = {\r\n /**\r\n * Message sent when a feature tries to update\r\n * the cache bypass value but the connector was not initialized\r\n * for the page\r\n */\r\n FailedToUpdateBypassValueConnectorNotInitialized: {\r\n id: 28200,\r\n source: \"OneServiceContentHelper.ts\",\r\n severity,\r\n pb\r\n },\r\n /**\r\n * Message sent when a feature tries to update\r\n * the cache bypass value but the connector was not initialized\r\n * for the page\r\n */\r\n FailedToGetBypassValueConnectorNotInitialized: {\r\n id: 28201,\r\n source: \"OneServiceContentHelper.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/**\r\n * App reporting messages related to Stripe Experience\r\n */\r\nexport const StripeAppErrors = {\r\n InvalidConfig: {\r\n id: 28300,\r\n source: \"Stripe.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const NotificationBellErrors = {\r\n /** Failed to fetch the notification bell data content */\r\n DataFetchError: {\r\n id: 28400,\r\n source: \"NotificationBell.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n JsonParseError: {\r\n id: 28401,\r\n source: \"LocalStorageSettings.ts\",\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n NewsItemDataFetchError: {\r\n id: 28402,\r\n source: \"NotificationBellServiceClient.ts\",\r\n severity,\r\n pb\r\n },\r\n MalformedNewsItemResponseError: {\r\n id: 28403,\r\n source: \"NotificationBellServiceClient.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents Layout Preference Data Connector related App errors */\r\nconst LayoutPreferenceDataSourceFile = \"LayoutPreferenceData.connector.ts\";\r\nexport const LayoutPreferenceDataErrors = {\r\n /** Failed to retrieve Layout Preference Data */\r\n LayoutPreferenceDataGetFailed: {\r\n id: 28500,\r\n source: LayoutPreferenceDataSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/**\r\n * App reporting messages related to StripeView Experience\r\n */\r\nexport const StripeViewAppErrors = {\r\n InvalidConfig: {\r\n id: 28600,\r\n source: \"StripeView.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n ChildLoadError: {\r\n id: 28601,\r\n source: \"StripeView.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents Sentiment Line Chart Connector related app errors */\r\nconst SentimentLineChartSourceFile = \"SentimentLineChart.connector.ts\";\r\nexport const SentimentLineChartErrors = {\r\n ContentFetchError: {\r\n id: 28700,\r\n source: SentimentLineChartSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents Sentiment Result Card Connector related app errors */\r\nconst SentimentResultCardSourceFile = \"SentimentResultCard.connector.ts\";\r\nexport const SentimentResultCardErrors = {\r\n ContentFetchError: {\r\n id: 28710,\r\n source: SentimentResultCardSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents Sentiment Map Connector related app errors */\r\nconst SentimentMapSourceFile = \"SentimentMap.connector.ts\";\r\nexport const SentimentMapErrors = {\r\n ContentFetchError: {\r\n id: 28720,\r\n source: SentimentMapSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents Election Results Card Connector related app errors */\r\nconst ElectionResultsCardFile = \"ElectionResultsCard.connector.ts\";\r\nexport const ElectionResultsCardErrors = {\r\n ContentFetchError: {\r\n id: 28730,\r\n source: ElectionResultsCardFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents Sentiment Bar chart Connector related app errors */\r\nconst SentimentBarChartSourceFile = \"SentimentBarChart.connector.ts\";\r\nexport const SentimentBarChartErrors = {\r\n ContentFetchError: {\r\n id: 28740,\r\n source: SentimentBarChartSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Elction Result Map connector App errors */\r\nconst ElectionResultMapConnectorSourceFile = \"ElectionResultMap.connector.ts\";\r\nexport const ElectionResultMapConnectorErrors = {\r\n UnknownError: {\r\n id: 28750,\r\n source: ElectionResultMapConnectorSourceFile,\r\n severity\r\n },\r\n\r\n ContentFetchError: {\r\n id: 28751,\r\n source: ElectionResultMapConnectorSourceFile,\r\n severity\r\n }\r\n};\r\n\r\n/** Elction Result Map Inspector App errors */\r\nconst ElectionResultMapInspectorSourceFile = \"ElectionResultMap.inspector.ts\";\r\nexport const ElectionResultMapInspectorErrors = {\r\n EmptyResultSummaryError: {\r\n id: 28752,\r\n source: ElectionResultMapInspectorSourceFile,\r\n severity\r\n }\r\n};\r\n/** Elction Result Map App errors */\r\nconst ElectionResultMapSourceFile = \"ElectionResultMap.tsx\";\r\nexport const ElectionResultMapErrors = {\r\n FetchAndUpdateElectionDataError: {\r\n id: 28753,\r\n source: ElectionResultMapSourceFile,\r\n severity\r\n }\r\n};\r\n\r\n/** Election Editor's Note App errors */\r\nexport const ElectionEditorsNoteErrors = {\r\n\r\n ContentFetchError: {\r\n id: 28760,\r\n source: \"ElectionEditorsNote.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents Election Delegate Counter related app errors */\r\nexport const ElectionDelegateCounterErrors = {\r\n ContentFetchError: {\r\n id: 28770,\r\n source: \"ElectionDelegateCounter.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/**\r\n * Topics hub - failed to fetch topic by name\r\n */\r\nexport const TopicByNameFetchFailed: AppError = {\r\n id: 28790,\r\n source: \"TopicsHub.connector.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * App reporting messages related to Partner Widget Experience\r\n */\r\nexport const PartnerWidgetAppErrors = {\r\n /** default breakpoint settings missing */\r\n DefaultBreakpointSettingsMissing: {\r\n id: 28801,\r\n source: \"PartnerWidget.connector.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n /** non whitelisted source url */\r\n NonWhitelistedSourceUrl: {\r\n id: 28802,\r\n source: \"PartnerWidget.connector.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents RecommendedSearch related App errors */\r\nconst RecommendedTopicsSourceFile = \"RecommendedTopics.connector.ts\";\r\nexport const RecommendedTopicsErrors = {\r\n /** Failed to connect to the Topics Data Connector */\r\n TopicsDataConnectorFailed: {\r\n id: 28901,\r\n source: RecommendedTopicsSourceFile,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Topic Clicked was null */\r\n InvalidTopicClick: {\r\n id: 28902,\r\n source: RecommendedTopicsSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst webWorkerSource = \"Web worker\";\r\nconst webWorkerUtility = \"WebWorkerUtility.ts\";\r\nexport const WebWorkerErrors = {\r\n /** Web worker script load error (404 response) */\r\n FileNotFound: {\r\n id: 29000,\r\n source: webWorkerUtility,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Web worker runtime error, fired by web worker on unhandled exceptions */\r\n RuntimeError: {\r\n id: 29001,\r\n source: webWorkerSource,\r\n severity,\r\n pb\r\n },\r\n\r\n /** Web worker message timeout */\r\n MessageTimeout: {\r\n id: 29002,\r\n source: webWorkerUtility,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /** Web worker handled errors. These are the errors received as messages from web worker */\r\n HandledError: {\r\n id: 29003,\r\n source: webWorkerSource,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst PageTimingsSource = \"entry-point-shared-utils/src/PageTimings.ts\";\r\n/**\r\n * Indicates that for some reason the page never received all the perf markers it was waiting for\r\n * resulting in the timeout logic kicking in.\r\n */\r\nexport const WaitForAllPerfMarkersTimeoutInvoked: AppError = {\r\n id: 29100,\r\n source: PageTimingsSource,\r\n severity: Severity.Alert,\r\n pb\r\n};\r\n\r\n/**\r\n * Indicates that for some reason the page never received all the secondary perf markers\r\n * it was waiting for, resulting in the timeout logic kicking in.\r\n */\r\nexport const WaitForAllSecondaryPerfMarkersTimeoutInvoked: AppError = {\r\n id: 29101,\r\n source: PageTimingsSource,\r\n severity: Severity.Alert,\r\n pb\r\n};\r\n\r\nconst PageLoadTimeSource = \"entry-point-shared-utils/src/TrackPageLoadTime.ts\";\r\n/**\r\n * Indicates that for some reason the page load time is not able to be sent out.\r\n */\r\nexport const PageLoadTimeError: AppError = {\r\n id: 29102,\r\n source: PageLoadTimeSource,\r\n severity: Severity.Alert,\r\n pb\r\n};\r\n\r\nconst FirstPartyEntryPointFileName = \"FirstParty.connector.ts\";\r\nconst FirstPartyPageFileName = \"page.ts\";\r\nexport const FirstPartyEntryPointAppErrors = {\r\n /**\r\n * Error during app initialization for FirstParty page experience.\r\n */\r\n FirstPartyErrorPage: {\r\n id: 29200,\r\n source: FirstPartyEntryPointFileName,\r\n severity,\r\n pb\r\n },\r\n /** Error during initial SSO call, either the call failed of the user was not signed in */\r\n SSOFailedError: {\r\n id: 29250,\r\n source: FirstPartyPageFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst HomePageEntryPointFileName = \"HomePage.connector.ts\";\r\nconst HomePageFileName = \"page.ts\";\r\nexport const HomePageEntryPointAppErrors = {\r\n /**\r\n * Error during app initialization for Home page experience.\r\n */\r\n HomePageErrorPage: {\r\n id: 29300,\r\n source: HomePageEntryPointFileName,\r\n severity,\r\n pb\r\n },\r\n /** Error during initial SSO call, either the call failed of the user was not signed in */\r\n SSOFailedError: {\r\n id: 29301,\r\n source: HomePageFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst WindowsEntryPointFileName = \"Windows.connector.ts\";\r\nconst WindowsPageFileName = \"page.ts\";\r\n\r\nexport const WindowsEntryPointAppErrors = {\r\n /**\r\n * Error during app initialization for Windows page experience.\r\n */\r\n WindowsErrorPage: {\r\n id: 29400,\r\n source: WindowsEntryPointFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Tracking errors where we ended up showing the local ntp page on page exception.\r\n */\r\n WindowsPageShownPageExceptionError: {\r\n id: 29401,\r\n source: WindowsPageFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Tracking errors where we ended up reloading the NTP page on jss mismatch exception.\r\n */\r\n WindowsPageReloadedPageExceptionError: {\r\n id: 29402,\r\n source: WindowsPageFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Error fetching the APP_ANON cookie on Windows page load\r\n */\r\n ErrorFetchingAppAnonCookie: {\r\n id: 29403,\r\n source: WindowsPageFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst WeatherAppEntrySourceFile = \"Weather.connector.ts\";\r\nconst WeatherLocationSearchSourceFile = \"WeatherLocationSearch.connector.ts\";\r\nconst WeatherMapSourceFile = \"WeatherMap.connector.ts\";\r\n\r\n/** Error during 'weather' app initialization. */\r\nexport const WeatherEntryPointAppError: AppError = {\r\n id: 29500,\r\n source: WeatherAppEntrySourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Fetch no data when search for locations from msn api */\r\nexport const WeatherLocationSearchNullError: AppError = {\r\n id: 29501,\r\n source: WeatherDataConnectorSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Exception to fetch search for locations from msn api */\r\nexport const WeatherLocationSearchFetchError: AppError = {\r\n id: 29502,\r\n source: WeatherDataConnectorSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Warnings when the alert title is too long to display */\r\nexport const WeatherAlertTitleTooLongError: AppError = {\r\n id: 29503,\r\n source: WeatherCardConnectorSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Warnings when the alert title is too long to display */\r\nexport const WeatherLocationSearchInvalidSuggestionIdError: AppError = {\r\n id: 29504,\r\n source: WeatherLocationSearchSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Exception when fail to fetch hurricane data */\r\nexport const WeatherMapHurricaneApiError: AppError = {\r\n id: 29505,\r\n source: WeatherMapSourceFile,\r\n severity: Severity.HighImpact,\r\n pb\r\n};\r\n\r\n/** Exception when Hurricane schema broken */\r\nexport const WeatherMapHurricaneSchemaError: AppError = {\r\n id: 29506,\r\n source: WeatherMapSourceFile,\r\n severity: Severity.Alert,\r\n pb\r\n};\r\n\r\nconst WindowsShellPage = \"page.ts\";\r\n/**\r\n * Windows Shell Page level exception was thrown\r\n */\r\nexport const WindowsShellPageError: AppError = {\r\n\r\n id: 29600,\r\n source: WindowsShellPage,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Windows Shell Page Error fetching the APP_ANON cookie\r\n */\r\nexport const WindowsShellPageErrorFetchingAppAnonCookie: AppError = {\r\n id: 29601,\r\n source: WindowsShellPage,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Auth related app messages (errors|warnings) */\r\nexport const AuthenticationAppMessages = {\r\n AuthRefreshBlockedError: {\r\n id: 33000,\r\n source: \"\",\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n /**\r\n * Error fetching the APP_ANON cookie\r\n */\r\n ErrorFetchingAppAnonCookie: {\r\n id: 33001,\r\n source: \"\",\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Error during app initialization for migration consent\r\n */\r\n EstablishMigrationConsent: {\r\n id: 33010,\r\n source: \"EstablishMigrationConsent.ts\",\r\n severity,\r\n pb\r\n },\r\n\r\n MigrationConsentServiceClient: {\r\n id: 33011,\r\n source: \"MigrationConsentServiceClient.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Server side rendering error */\r\nexport const RenderServerError: AppError = {\r\n id: 34000,\r\n source: \"service-render-app.ts\",\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\nconst irisArcCallerFileName = \"Iris.arcCaller.ts\";\r\nconst irisArcParserFileName = \"Iris.arcParser.ts\";\r\nconst irisMasterFileName = \"Iris.master.ts\";\r\n\r\n/** Generic Unknown related to the Iris system. Investigate. */\r\nexport const AppError_IrisUnknown_35000: AppError = {\r\n id: 35000,\r\n source: \"Iris\",\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n/** The query parameters presented to the arc caller were found to be invalid. */\r\nexport const AppError_InvalidQParams_35001: AppError = {\r\n id: 35001,\r\n source: irisArcCallerFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_ArcCallFailed_35002: AppError = {\r\n id: 35002,\r\n source: irisArcCallerFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_ArcResponseNotOk_35003: AppError = {\r\n id: 35003,\r\n source: irisArcCallerFileName,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\nexport const AppError_ArcResponseUnparsable_35004: AppError = {\r\n id: 35004,\r\n source: irisArcCallerFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_MissingAppEnv_35005: AppError = {\r\n id: 35005,\r\n source: irisArcCallerFileName,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\nexport const AppError_UnknownIrisErrorFound_35006: AppError = {\r\n id: 35006,\r\n source: irisArcParserFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_TimeoutIrisErrorFound_35007: AppError = {\r\n id: 35007,\r\n source: irisArcParserFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_TemplateIrisErrorFound_35008: AppError = {\r\n id: 35008,\r\n source: irisArcParserFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_ClientErrorIrisErrorFound_35009: AppError = {\r\n id: 35009,\r\n source: irisArcParserFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_DSourceIrisErrorFound_35010: AppError = {\r\n id: 35010,\r\n source: irisArcParserFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_ActionCallFailure_35011: AppError = {\r\n id: 35011,\r\n source: irisArcCallerFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_ActionFetchFailure_35012: AppError = {\r\n id: 35012,\r\n source: irisArcCallerFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_ActionResponseFailure_35013: AppError = {\r\n id: 35013,\r\n source: irisArcCallerFileName,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\nexport const AppError_UncaughtErrorDetected_35014: AppError = {\r\n id: 35014,\r\n source: irisMasterFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_UnconvertableCreative_35015: AppError = {\r\n id: 35015,\r\n source: irisMasterFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_InvalidResponseFormat_35016: AppError = {\r\n id: 35016,\r\n source: irisMasterFileName,\r\n severity,\r\n pb\r\n};\r\nexport const AppError_TimeoutErrorDiscovered_35017: AppError = {\r\n id: 35017,\r\n source: irisMasterFileName,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\nexport const AppError_UnparsableSingleResponseJSON_35018: AppError = {\r\n id: 35018,\r\n source: irisMasterFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Represents Iris data connector related App errors */\r\nconst IrisDataConnectorSourceFile = \"IrisData.connector.ts\";\r\nconst SubscriberValidatorSourceFile = \"SubscriberValidator.ts\";\r\nconst IrisPersistentStorageUtilityFile = \"IrisPersistentStorageUtility.ts\";\r\n\r\nexport const IrisDataConnectorErrors = {\r\n SubscriberNotFound: {\r\n id: 35117,\r\n source: SubscriberValidatorSourceFile,\r\n severity,\r\n pb\r\n },\r\n CreativeCountNegativeOrZero: {\r\n id: 35118,\r\n source: IrisDataConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n MissingIrisParameterForConditionalBanner: {\r\n id: 35119,\r\n source: SubscriberValidatorSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n ErrorFoundForSurface: {\r\n id: 35120,\r\n source: IrisDataConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n SubscriberNotFoundInIrisPlacementDictionary: {\r\n id: 35121,\r\n source: IrisDataConnectorSourceFile,\r\n severity,\r\n pb\r\n },\r\n ConfigDataUndefined: {\r\n id: 35122,\r\n source: IrisPersistentStorageUtilityFile,\r\n severity,\r\n pb\r\n },\r\n FailedToFetchConfigData: {\r\n id: 35123,\r\n source: IrisPersistentStorageUtilityFile,\r\n severity,\r\n pb\r\n },\r\n ExceptionFetchingConfigData: {\r\n id: 35124,\r\n source: IrisPersistentStorageUtilityFile,\r\n severity,\r\n pb\r\n },\r\n FailedToReadNurturingAcceptedFlag: {\r\n id: 35125,\r\n source: IrisPersistentStorageUtilityFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents AccessTokens related App errors */\r\nconst AccessTokensSourceFile = \"AadAuthHelper.ts\";\r\nconst PivotContentErrorPlaceholderFile = \"AadErrorPlaceholder.tsx\";\r\nexport const EdgeChromiumAPIsNotAvailable: AppError = {\r\n id: 35200,\r\n source: AccessTokensSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const AcquireAccessTokenFailed: AppError = {\r\n id: 35201,\r\n source: AccessTokensSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\nexport const AcquireAccessTokenFailedForPivotContent: AppError = {\r\n id: 35202,\r\n source: PivotContentErrorPlaceholderFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/** Represents Render Cache errors*/\r\nconst PersistRenderCacheFile = \"PersistRenderCache.ts\";\r\nexport const RenderCacheErrors = {\r\n JssStyleMismatchWarning: {\r\n id: 35300,\r\n source: PersistRenderCacheFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n\r\n JssStyleCriticalMismatchError: {\r\n id: 35301,\r\n source: PersistRenderCacheFile,\r\n severity: Severity.Alert,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents OcvFeedbackData related App errors */\r\nconst OcvFeedbackDataSourceFile = \"OcvFeedbackData.ts\";\r\nexport const OcvFeedbackDataErrors = {\r\n UndefinedDataNotAvailable: {\r\n id: 35400,\r\n source: OcvFeedbackDataSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nexport const PivotHoverErrors = {\r\n /** Failed to fetch feed summary data for the Pivot Hover list. */\r\n FeedSummaryFetchError: {\r\n id: 35500,\r\n source: \"FeedSummaryFetcher.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst PreloadActionHelpers = \"PreloadActionHelpers.ts\";\r\nexport const PreloadReportingMessages = {\r\n TtvrMissing: {\r\n id: 35600,\r\n source: PreloadActionHelpers,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n TfprMissing: {\r\n id: 35601,\r\n source: PreloadActionHelpers,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n TtvrSearchBoxMissing: {\r\n id: 35602,\r\n source: PreloadActionHelpers,\r\n severity: Severity.NoAlert,\r\n pb\r\n },\r\n TtfSearchBoxMissing: {\r\n id: 35603,\r\n source: PreloadActionHelpers,\r\n severity: Severity.NoAlert,\r\n pb\r\n }\r\n};\r\n\r\nconst PrerenderPageTimingHelper = \"PrerenderPageTimingHelper.ts\";\r\nexport const PrerenderTtvrMissing: AppError = {\r\n id: 35604,\r\n source: PrerenderPageTimingHelper,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\nexport const PrerenderTtprMissing: AppError = {\r\n id: 35605,\r\n source: PreloadActionHelpers,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\nexport const PrerenderTtvrSearchBoxMissing: AppError = {\r\n id: 35606,\r\n source: PrerenderPageTimingHelper,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\nexport const PrerenderTtfSearchBoxMissing: AppError = {\r\n id: 35607,\r\n source: PrerenderPageTimingHelper,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/** Represents push notifications lib App errors */\r\nconst PushNotificationsLibFile = \"PushNotifications.ts\";\r\nexport const PushNotificationsLibErrors = {\r\n FetchKeyError: {\r\n id: 35700,\r\n source: PushNotificationsLibFile,\r\n severity,\r\n pb\r\n },\r\n SubscribeUnsubscribeError: {\r\n id: 35701,\r\n source: PushNotificationsLibFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Represents content truncation lib App errors */\r\nconst ContentTruncationSourceFile = \"ContentTruncation.ts\";\r\nexport const ContentTruncationErrors = {\r\n OverTruncationError: {\r\n id: 35800,\r\n source: ContentTruncationSourceFile,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\nconst SuperAppEntryPointFileName = \"SuperAppPage.connector.ts\";\r\n\r\nexport const SuperAppEntryPointAppErrors = {\r\n /**\r\n * Super app river is not able to load Error Page.\r\n */\r\n SuperAppErrorPage: {\r\n id: 35901,\r\n source: SuperAppEntryPointFileName,\r\n severity,\r\n pb\r\n },\r\n\r\n /**\r\n * Error fetching the APP_ANON cookie on super app page load\r\n */\r\n ErrorFetchingAppAnonCookie: {\r\n id: 35902,\r\n source: \"page.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/** Error fetching feed with location in Local News experience */\r\nconst LocalNewsFileName = \"LocalNews.connector.ts\";\r\nexport const LocalNewsInterestByLocationFetchFailed: AppError = {\r\n id: 36001,\r\n source: LocalNewsFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/** 361XX represent office related errors */\r\nconst GenerateShareUiFile = \"GenerateShareUi.tsx\";\r\nconst OfficeShareUiFile = \"OfficeShareUi.tsx\";\r\nconst OfficeFallbackHandlerFileName = \"OfficeFallbackHandler.ts\";\r\nconst OfficeDocumentsTableConnectorFile = \"OfficeDocumentsTable.connector.ts\";\r\nconst OfficeDocumentsTableMruUtilitiesFile = \"mru-plusplus.utility.ts\";\r\nconst OfficeSharePointSitesTableConnectorFile = \"SharePointSitesTable.connector.ts\";\r\nconst OfficeDocumentsTableDiscoverFile = \"DiscoverDocumentProvider.ts\";\r\n\r\nexport const OfficeFallbackHandlerAppErrors = {\r\n /**\r\n * Tracking errors where we ended up reloading the office content on jss mismatch exception.\r\n */\r\n OfficeContentReloadedJSSMismatchExceptionError: {\r\n id: 36101,\r\n source: OfficeFallbackHandlerFileName,\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/**\r\n * Error for failure to generate office share ui\r\n */\r\nexport const OfficeGenerateShareUiError: AppError = {\r\n id: 36105,\r\n source: GenerateShareUiFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/**\r\n * Error for failure inside office share ui\r\n */\r\nexport const OfficeShareUiError: AppError = {\r\n id: 36106,\r\n source: OfficeShareUiFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/**\r\n * Tracking errors when Office Documents Table type is not provided\r\n */\r\nexport const OfficeDocumentsTableInvalidTypeError: AppError = {\r\n id: 36110,\r\n source: OfficeDocumentsTableConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Tracking errors when Office Documents Table fails to fetch documents\r\n */\r\nexport const OfficeDocumentsTableDocumentFetchFailedError: AppError = {\r\n id: 36111,\r\n source: OfficeDocumentsTableConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Tracking errors when Office Documents Table fails to fetch documents\r\n */\r\nexport const OfficeDocumentsTableLinkFetchFailedError: AppError = {\r\n id: 36112,\r\n source: OfficeDocumentsTableConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Tracking errors when Office Documents Table fails to update document properties\r\n */\r\nexport const OfficeDocumentsTableUpdateDocumentPropertiesFailed: AppError = {\r\n id: 36113,\r\n source: OfficeDocumentsTableMruUtilitiesFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n* Tracking errors when Office Documents Table fails to fetch activity data\r\n*/\r\nexport const OfficeDocumentsTableFetchActivitiesFailed: AppError = {\r\n id: 36114,\r\n source: OfficeDocumentsTableDiscoverFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/**\r\n * Tracking errors when Office Share Point Table fails to fetch sites\r\n */\r\nexport const OfficeSharepointSitesTableFetchFailedError: AppError = {\r\n id: 36120,\r\n source: OfficeSharePointSitesTableConnectorFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Represents autos experiences App errors */\r\nconst AutosExperienceConnectorFile = \"AutosCard.connector.ts\";\r\nconst AutosExperienceServiceClientFile = \"AutosServiceClient.ts\";\r\n\r\n/**\r\n * Error while fetching research make models\r\n */\r\nexport const FetchResearchMakeModelDocumentError: AppError = {\r\n id: 36200,\r\n source: AutosExperienceServiceClientFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/**\r\n * Error while fetching Film Strip Document Error\r\n */\r\nexport const FetchFilmStripDocumentError: AppError = {\r\n id: 36201,\r\n source: AutosExperienceServiceClientFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/**\r\n * Error while fetching lead classified cms documents\r\n */\r\nexport const FetchClassifiedLeadCMSDocumentsError: AppError = {\r\n id: 36202,\r\n source: AutosExperienceServiceClientFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/**\r\n * Error while fetching lead classified make models\r\n */\r\nexport const FetchLeadClassifiedMakeModelDocumentError: AppError = {\r\n id: 36203,\r\n source: AutosExperienceServiceClientFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/**\r\n * Error for incorrect tab configuration\r\n */\r\nexport const TabsIncorrectConfiguration: AppError = {\r\n id: 36204,\r\n source: AutosExperienceConnectorFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/** Whole Page Optimization(WPO) App errors */\r\n\r\nconst WpoServiceFileName = \"WpoServiceClient.ts\";\r\n\r\n/**\r\n * WPO service call failure.\r\n */\r\nexport const WpoServiceCallFailure: AppError = {\r\n id: 36301,\r\n source: WpoServiceFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Error updating local storage with wpo service call response.\r\n */\r\nexport const WpoFailedToStoreToLocalStorage: AppError = {\r\n id: 36302,\r\n source: WpoServiceFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/** MarketSelector App errors */\r\nconst MarketSelectorFileName = \"marketSetting/index.ts\";\r\n\r\n/**\r\n * Error when load current market setting when initialize market selector\r\n */\r\nexport const MarketSelectorFailedToReadCurrentMarket: AppError = {\r\n id: 36401,\r\n source: MarketSelectorFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/** FlyoutCard App errors */\r\nconst FlyoutCardFileName = \"FlyoutCard.connector.ts\";\r\n\r\n/**\r\n * Error when fetching feed in FlyoutCard experience\r\n */\r\nexport const FlyoutCardFailedToLoadOneServiceData: AppError = {\r\n id: 36410,\r\n source: FlyoutCardFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Represents a Microsoft Logo related error */\r\nexport const MicrosoftLogoErrors: AppError = {\r\n id: 36420,\r\n source: \"MicrosoftLogo.tsx\",\r\n severity: Severity.HighImpact,\r\n pb\r\n};\r\n\r\n/**\r\n * Clarity Script App Errors\r\n */\r\nconst ClarityScriptLoaderFile = \"ScriptLoader.ts\";\r\n\r\n/**\r\n * Error loading clarity script.\r\n */\r\nexport const LoadScriptError: AppError = {\r\n id: 36500,\r\n source: ClarityScriptLoaderFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Error starting clarity script.\r\n */\r\nexport const ScriptStartError: AppError = {\r\n id: 36501,\r\n source: ClarityScriptLoaderFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** 366XX are River OneService App Errors */\r\nexport const EmptyFeedWithFeedId: AppError = {\r\n id: 36600,\r\n source: OneServiceCardProviderFileName,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const EmptySearchedFeedWithFeedId: AppError = {\r\n id: 36601,\r\n source: OneServiceCardProviderFileName,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const EmptySearchedFeedWithFeedQuery: AppError = {\r\n id: 36602,\r\n source: OneServiceCardProviderFileName,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const EmptyKidsModeFeed: AppError = {\r\n id: 36603,\r\n source: OneServiceCardProviderFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/** 367XX are River App Errors */\r\nexport const FallingBackToSkipStrategy: AppError = {\r\n id: 36700,\r\n source: RiverSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const FallingBackToFullHeightStrategy: AppError = {\r\n id: 36701,\r\n source: RiverSourceFile,\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/** Represents OutlookEmailPreview related App errors */\r\nconst OutlookEmailPreviewDataSourceFile = \"OutlookEmailPreviewDataHelper.ts\";\r\n\r\nexport const OutlookEmailPreviewEmailFetchError: AppError = {\r\n id: 36800,\r\n source: OutlookEmailPreviewDataSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const OutlookEmailPreviewUnreadEmailCountFetchError: AppError = {\r\n id: 36801,\r\n source: OutlookEmailPreviewDataSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst FinancePageFilename = \"Finance.connector.ts\";\r\nconst FinanceUserServiceImplFile = \"FinanceUserServiceImpl.ts\";\r\nconst FinanceServiceImplFile = \"FinanceServiceImpl.ts\";\r\nconst FinanceAutoSuggestServiceImplFile = \"AutoSuggestServiceImpl\";\r\n\r\n/**\r\n * Error when initializing Finance page experience.\r\n */\r\nexport const FinanceEntryPointAppErrors: AppError = {\r\n id: 36900,\r\n source: FinancePageFilename,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get autosuggest because of unsuccessful fetch */\r\nexport const FinanceAutoSuggestFetchError: AppError = {\r\n id: 36901,\r\n source: FinanceAutoSuggestServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get autosuggest because the http code is not 20x */\r\nexport const FinanceAutoSuggestStatusError: AppError = {\r\n id: 36902,\r\n source: FinanceAutoSuggestServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get autosuggest because the response body is not valid */\r\nexport const FinanceAutoSuggestInvalidResponseBody: AppError = {\r\n id: 36903,\r\n source: FinanceAutoSuggestServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get MostActiveQuotes because unsuccess fetch */\r\nexport const FinanceMostActiveQuotesFetchError: AppError = {\r\n id: 36904,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get MostActiveQuotes because the http code is not 20x */\r\nexport const FinanceMostActiveQuotesStatusError: AppError = {\r\n id: 36905,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get MostActiveQuotes because the response body is not valid */\r\nexport const FinanceMostActiveQuotesInvalidResponseBody: AppError = {\r\n id: 36906,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Exception when fetch watchlist */\r\nexport const FinanceWatchListFetchFailed: AppError = {\r\n id: 36907,\r\n source: FinanceUserServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get Chart because unsuccess fetch */\r\nexport const FinanceChartFetchError: AppError = {\r\n id: 36908,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get Chart because the http code is not 20x */\r\nexport const FinanceChartStatusError: AppError = {\r\n id: 36909,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get Chart because the response body is not valid */\r\nexport const FinanceChartInvalidResponseBody: AppError = {\r\n id: 36910,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get QuoteSummary because unsuccess fetch */\r\nexport const FinanceQuoteSummaryFetchError: AppError = {\r\n id: 36911,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get QuoteSummary because the http code is not 20x */\r\nexport const FinanceQuoteSummaryStatusError: AppError = {\r\n id: 36912,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get QuoteSummary because the response body is not valid */\r\nexport const FinanceQuoteSummaryInvalidResponseBody: AppError = {\r\n id: 36913,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get Exchange because unsuccess fetch */\r\nexport const FinanceExchangeFetchError: AppError = {\r\n id: 36914,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get Exchange because the http code is not 20x */\r\nexport const FinanceExchangeStatusError: AppError = {\r\n id: 36915,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get Exchange because the response body is not valid */\r\nexport const FinanceExchangeInvalidResponseBody: AppError = {\r\n id: 36916,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get indices because of unsuccessful fetch */\r\nexport const FinanceIndicesFetchError: AppError = {\r\n id: 36917,\r\n source: FinanceAutoSuggestServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get indices because the http code is not 20x */\r\nexport const FinanceIndicesStatusError: AppError = {\r\n id: 36918,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get indices because the response body is not valid */\r\nexport const FinanceIndicesInvalidResponseBody: AppError = {\r\n id: 36919,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get equities because of unsuccessful fetch */\r\nexport const FinanceEquitiesFetchError: AppError = {\r\n id: 36920,\r\n source: FinanceAutoSuggestServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get equities because the http code is not 20x */\r\nexport const FinanceEquitiesStatusError: AppError = {\r\n id: 36921,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get equities because the response body is not valid */\r\nexport const FinanceEquitiesInvalidResponseBody: AppError = {\r\n id: 36922,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get equity financials because of unsuccessful fetch */\r\nexport const FinanceEquityFinancialsFetchError: AppError = {\r\n id: 36923,\r\n source: FinanceAutoSuggestServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get equity financials because the http code is not 20x */\r\nexport const FinanceEquityFinancialsStatusError: AppError = {\r\n id: 36924,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/** Failed to get equity financials because the response body is not valid */\r\nexport const FinanceEquityFinancialsInvalidResponseBody: AppError = {\r\n id: 36925,\r\n source: FinanceServiceImplFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Error when initializing Social page experience.\r\n */\r\nconst SocialPreviewSourceFile = \"Social.connector.ts\";\r\n\r\nexport const SocialNoModuleName: AppError = {\r\n id: 37000,\r\n source: SocialPreviewSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Errors on Social experience http requests\r\n */\r\n\r\nconst SocialAPISourceFile = \"Social.api.ts\";\r\n\r\nexport const SocialAPIRequestErrorUnknown: AppError = {\r\n id: 37020,\r\n source: SocialAPISourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialAPIRequestErrorContents: AppError = {\r\n id: 37021,\r\n source: SocialAPISourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialAPIRequestErrorComments: AppError = {\r\n id: 37022,\r\n source: SocialAPISourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialAPIRequestErrorUsers: AppError = {\r\n id: 37023,\r\n source: SocialAPISourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Errors on Social experience component renders\r\n */\r\n\r\nconst SocialExperienceFile = \"Social.tsx\";\r\n\r\nexport const SocialExperienceRenderErrorComment: AppError = {\r\n id: 37050,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialExperienceRenderErrorProfilePage: AppError = {\r\n id: 37051,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialExperienceRenderErrorProfileCard: AppError = {\r\n id: 37052,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialExperienceRenderErrorProfileTabs: AppError = {\r\n id: 37053,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialExperienceRenderErrorSocialBar: AppError = {\r\n id: 37054,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialExperienceRenderErrorReactionBreakdown: AppError = {\r\n id: 37055,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialExperienceRenderErrorGuideline: AppError = {\r\n id: 37057,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\nexport const SocialExperienceRenderErrorMultilineLogin: AppError = {\r\n id: 37058,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialExperienceRenderErrorNotificationTray: AppError = {\r\n id: 37059,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialExperienceRenderErrorOnboarding: AppError = {\r\n id: 37060,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialExperienceRenderErrorOnbardingThirdParty: AppError = {\r\n id: 37061,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const SocialExperienceRenderErrorUnknownComponent: AppError = {\r\n id: 37062,\r\n source: SocialExperienceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst LocationSelectorConnectorFileName = \"LocationSelector.connector.ts\";\r\n/**\r\n * Suggestion Id is out of bounds or it doesn't exist;\r\n */\r\nexport const LocationSelectorInvalidSuggestionId: AppError = {\r\n id: 37100,\r\n source: LocationSelectorConnectorFileName,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const CommunityErrorPage: AppError = {\r\n id: 37200,\r\n source: \"app-types/community/src/page.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * PDP Service library errors - 3730X\r\n */\r\nexport const UnknownBulkLoadGraphActionType: AppError = {\r\n id: 37300,\r\n source: \"PdpServiceClient.ts\",\r\n severity: Severity.NoAlert,\r\n pb\r\n};\r\n\r\n/**\r\n * Head data refresh errors - 3731X\r\n */\r\nexport const HeadDataRefreshErrors = {\r\n /** Refresh of stale head data was needed for service worker. */\r\n RefreshRequiredOnServiceWorker: {\r\n id: 37310,\r\n source: \"RefreshHeadDataServiceWorker.ts\",\r\n severity,\r\n pb\r\n }\r\n};\r\n\r\n/**\r\n * Set of errors in story-snippet experience.\r\n */\r\nexport const StorySnippetInvalidStoryData: AppError = {\r\n id: 37450,\r\n source: \"StorySnippet.connector.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Erro when Story Snippet experience receives invalid data schema from related content cluster endpoint.\r\n */\r\nexport const StorySnippetInvalidRelatedContentClusterData: AppError = {\r\n id: 37451,\r\n source: \"StorySnippet.connector.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Errors related to MyBriefRiverCard\r\n */\r\nconst MyBriefRiverCardFileName = \"MyBriefRiverCard.connector.ts\";\r\nexport const MyBriefRiverCardMissingConfig: AppError = {\r\n id: 37500,\r\n source: MyBriefRiverCardFileName,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const MyBriefRiverCardEmptyOrNullResponse: AppError = {\r\n id: 37501,\r\n source: MyBriefRiverCardFileName,\r\n severity,\r\n pb\r\n};\r\n\r\nconst WindowsCardProviderFileName = \"WindowsCardProvider.ts\";\r\nexport const WindowsCardProviderResponseWasNullOrErroneous: AppError = {\r\n id: 37550,\r\n source: WindowsCardProviderFileName,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const WindowsCardProviderErrorFetchingData: AppError = {\r\n id: 37551,\r\n source: WindowsCardProviderFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Error related to Traffic experiences.\r\n */\r\nconst TrafficPageFileName = \"traffic/page.ts\";\r\nexport const TrafficEntryPointAppError: AppError = {\r\n id: 37600,\r\n source: TrafficPageFileName,\r\n severity,\r\n pb\r\n};\r\n\r\nconst TrafficCardConnectorFileName = \"traffic-card/TrafficCard.connector.ts\";\r\nexport const TrafficIncidentsError: AppError = {\r\n id: 37601,\r\n source: TrafficCardConnectorFileName,\r\n severity,\r\n pb\r\n};\r\n\r\nconst TrafficAutoSuggestClientFileName = \"traffic-card/AutoSuggest/DirectionsAutoSuggestClient.ts\";\r\nexport const TrafficAutoSuggestError: AppError = {\r\n id: 37602,\r\n source: TrafficAutoSuggestClientFileName,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const TrafficSettingsSaveError: AppError = {\r\n id: 37603,\r\n source: TrafficCardConnectorFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Represents GmailEmailPreview related App errors\r\n */\r\nconst GmailEmailPreviewDataSourceFile = \"GmailEmailPreview.connector.ts\";\r\nexport const GmailEmailPreviewGoogleAPIError: AppError = {\r\n id: 37700,\r\n source: GmailEmailPreviewDataSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const GmailEmailPreviewGmailAPIError: AppError = {\r\n id: 37701,\r\n source: GmailEmailPreviewDataSourceFile,\r\n severity,\r\n pb\r\n};\r\n\r\nconst LocalNewsViewCardConnectorFileName = \"LocalNewsViewCard.connector.ts\";\r\n/**\r\n * Data connector fails to be found or to get the cards from;\r\n */\r\nexport const LocalNewsViewCardDataConnectorAppError: AppError = {\r\n id: 37800,\r\n source: LocalNewsViewCardConnectorFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * LocationFeedData Errors\r\n */\r\nexport const LocationFeedDataConnectorAppError: AppError = {\r\n id: 37900,\r\n source: \"LocationFeed.connector.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Errors related to Admin Portal\r\n */\r\nconst AdminPortalConnectorFileName = \"AdminPortalData.connector.ts\";\r\nexport const AdminPortalSettingsFetchAppError: AppError = {\r\n id: 38000,\r\n source: AdminPortalConnectorFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Errors related to Desktop Feed\r\n */\r\nconst DesktopFeedConnectorFileName = \"DesktopFeed.connector.ts\";\r\nexport const DesktopFeedRiverContentFetchFailed: AppError = {\r\n id: 38010,\r\n source: DesktopFeedConnectorFileName,\r\n severity,\r\n pb\r\n};\r\n\r\nexport const DesktopFeedUnsupportedCardType: AppError = {\r\n id: 38011,\r\n source: DesktopFeedConnectorFileName,\r\n severity,\r\n pb\r\n};\r\n\r\n/**\r\n * Set of errors in video-card experience.\r\n */\r\nexport const VideoCardInvalidVideoData: AppError = {\r\n id: 38100,\r\n source: \"VideoCard.connector.ts\",\r\n severity,\r\n pb\r\n};\r\n\r\nconst NewsbarFeedConnectorFileName = \"NewsbarFeed.connector.ts\";\r\nexport const NewsbarFeedNativeAdServiceFetchFailed: AppError = {\r\n id: 38200,\r\n source: NewsbarFeedConnectorFileName,\r\n severity,\r\n pb\r\n};\r\nexport const NewsbarFeedNativeWindowsServiceFetchFailed: AppError = {\r\n id: 38201,\r\n source: NewsbarFeedConnectorFileName,\r\n severity,\r\n pb\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { AppErrorPropertyBag, getAppErrorsPropertyBag, getPageTimings, updateAppErrorsPropertyBag } from \"@msnews/diagnostics\";\r\nimport { AppType, AudienceModeType, AuthCookieName } from \"@msnews/experiences-constants\";\r\nimport { EnterpriseOneServiceApi, appAnonCookieExistsCookieName, childCookieName, rootElementId, serviceUrl, telemetryId, trackPageProduct, trackPageType } from \"../constants\";\r\nimport { Environment, getEnvironmentFromString } from \"./Environment\";\r\nimport { HostPage, IHostPage } from \"./HostPage\";\r\nimport { WpoModel, getWpoFlights, getWpoStorageCacheKey } from \"@msnews/wpo-common\";\r\nimport { canUseDOM, getDocumentElementById, getLocationHostname, getLocationHref, getLocationOrigin, getLocationSearch } from \"@msnews/isomorphic-util\";\r\nimport { getCookie, getMuidCookie } from \"../utilities/CookieUtility\";\r\n\r\nimport { AccountInfo } from \"./Enterprise\";\r\nimport { Market } from \"./Market\";\r\nimport { PageRequestTargetScope } from \"./PageRequestTargetScope\";\r\nimport { PlatformType } from \"cms-models-msn/configuration/types/PlatformType\";\r\nimport { UrlUtility } from \"../utilities/UrlUtility\";\r\nimport { Utility } from \"../utilities/Utility\";\r\nimport { headData } from \"./HeadData\";\r\nimport { isString } from \"lodash-es\";\r\nimport { localStorage } from \"../webstorage\";\r\n\r\n/**\r\n * chrome\r\n * The chrome API is not defined in Typescript\r\n */\r\ndeclare global {\r\n interface Window { chrome: any; }\r\n}\r\n\r\n/**\r\n * Page level experience tracking info\r\n */\r\nexport interface ITrackInfo {\r\n sitePage: {\r\n page_product: string,\r\n page_type: string\r\n }\r\n}\r\n\r\nexport class AppEnvironment {\r\n /**\r\n * The single instance of the AppEnvironment class.\r\n * @type {AppEnvironment}\r\n */\r\n private static _instance: AppEnvironment;\r\n\r\n /**\r\n * the activity id for the current page view\r\n */\r\n private activityId: string;\r\n\r\n /**\r\n * Base url for the content service, endpoints/queries are appended for specific content calls.\r\n * This is an akamai url for highly cacheable content.\r\n * Possible values are enumerated on ContentServiceConfig.ts\r\n *\r\n * @private\r\n * @type {string}\r\n * @memberof AppEnvironment\r\n */\r\n private contentServiceUrlBase: URL;\r\n\r\n private currentRequestTargetScope: PageRequestTargetScope;\r\n\r\n private currentMarket: Market;\r\n private hostPage: IHostPage;\r\n\r\n /** The hostname to use for content links. */\r\n private currentContentLinkHost: string;\r\n\r\n /**\r\n * Indicates that the page is running as an FRE page (i.e. the url contains fre=1)\r\n * Does not indicate that the FRE itself is currently displayed over the page.\r\n */\r\n private isFrePage: boolean;\r\n\r\n /**\r\n * Base for the service url, endpoints/queries are appended for specific service calls.\r\n * This is the OneService url used for personalized content.\r\n * Possible values are enumerated on OneServiceConfig.ts\r\n *\r\n * @private\r\n * @type {string}\r\n * @memberof AppEnvironment\r\n */\r\n private serviceUrlBase: URL;\r\n\r\n /**\r\n * Base URL for the feed service\r\n */\r\n private feedServiceUrlBase: URL;\r\n\r\n /**\r\n * The account info for the current page user wrapped in a promise\r\n */\r\n private accountInfoPromise: Promise;\r\n\r\n /**\r\n * The resolved account info. This is only set when the account info promise is resolved.\r\n */\r\n private resolvedAccountInfo: AccountInfo;\r\n\r\n private appType: string;\r\n private authCookieName: AuthCookieName;\r\n private buildVersion: string;\r\n\r\n private environmentConfigUrl: URL;\r\n\r\n private rootTelemetryId: number;\r\n private trackInfo: ITrackInfo;\r\n private userId: string;\r\n private countryCode: string;\r\n private latitude: string;\r\n private longitude: string;\r\n private environment: Environment;\r\n private assetsHost: string;\r\n private featureFlags: any;\r\n private disableCachingConfigs: boolean;\r\n private enableConfigService: boolean;\r\n private isMultiConfigRetrievalEnabled: boolean;\r\n private configServiceBaseUrl: URL;\r\n private disableContentPreviewCache: boolean;\r\n private disableContentCacheIDBRead: boolean;\r\n private sendFeedCallActivityIdInHeader: boolean;\r\n private useOneServiceAuthEndpoints: boolean;\r\n private clarityEnabled: boolean;\r\n\r\n /** True if query string has appropriate debug flag */\r\n private isDebug: boolean;\r\n\r\n /** True if query string has appropriate flag to show msnCreatorDashboard (msnDash=) */\r\n private showMnsCreatorDashboard: boolean;\r\n\r\n /** Config Root Url */\r\n private configRootUrl: URL;\r\n\r\n /** Cache busting identifier received from pcs */\r\n private cacheBustingIdentifier: string;\r\n\r\n /**\r\n * ActivityId value from initial server response, use telemetry's requestId instead for associating with current page client navigation\r\n */\r\n public get ActivityId(): string { return this.activityId; }\r\n public set ActivityId(value: string) {\r\n this.activityId = value;\r\n headData.ClientSettings = {\r\n ...headData.ClientSettings,\r\n aid: value\r\n };\r\n }\r\n\r\n /**\r\n * Getter for the base url for the content service, endpoints/queries are appended for specific content calls.\r\n * This is an akamai url for highly cacheable content.\r\n * Possible values are enumerated on ContentServiceConfig.ts\r\n *\r\n * @readonly\r\n * @type {URL}\r\n * @memberof AppEnvironment\r\n */\r\n public get EnvironmentConfigUrl(): URL {\r\n // If I mutate the same object, I will need to revert to the original state somewhere.\r\n // For safety reason, it is better to use a new Object\r\n const url = new URL(\"\", this.environmentConfigUrl);\r\n\r\n if (process.env.WEBPACK_DEV_SERVER || new URLSearchParams(getLocationSearch()).get(\"env\") === \"dev\") {\r\n url.searchParams.set(\"env.config\", \"dev\");\r\n }\r\n\r\n const searchParam = new URLSearchParams(getLocationSearch()).get(\"env.config\");\r\n if (searchParam) {\r\n url.searchParams.set(\"env.config\", searchParam);\r\n }\r\n\r\n return url;\r\n }\r\n\r\n /**\r\n * Getter for the base url for the content service, endpoints/queries are appended for specific content calls.\r\n * This is an akamai url for highly cacheable content.\r\n * Possible values are enumerated on ContentServiceConfig.ts\r\n *\r\n * @readonly\r\n * @type {URL}\r\n * @memberof AppEnvironment\r\n */\r\n public get ContentServiceUrlBase(): URL {\r\n // If I mutate the same object, I will need to revert to the original state somewhere.\r\n // For safety reason, it is better to use a new Object\r\n const url = new URL(\"\", this.contentServiceUrlBase);\r\n\r\n if (process.env.WEBPACK_DEV_SERVER || new URLSearchParams(getLocationSearch()).get(\"env\") === \"dev\") {\r\n url.searchParams.set(\"env.content\", \"dev\");\r\n }\r\n\r\n const searchParam = new URLSearchParams(getLocationSearch()).get(\"env.content\");\r\n if (searchParam) {\r\n url.searchParams.set(\"env.content\", searchParam);\r\n }\r\n\r\n return url;\r\n }\r\n\r\n public get CurrentRequestTargetScope(): PageRequestTargetScope { return this.currentRequestTargetScope; }\r\n public set CurrentRequestTargetScope(value: PageRequestTargetScope) { this.currentRequestTargetScope = value; }\r\n\r\n public get CurrentMarket(): Market { return this.currentMarket; }\r\n public set CurrentMarket(value: Market) { this.currentMarket = value; }\r\n\r\n public get Environment(): Environment { return this.environment; }\r\n public set Environment(value: Environment) { this.environment = value; }\r\n\r\n public get AssetsHost(): string { return this.assetsHost; }\r\n\r\n public get HostPage(): IHostPage { return this.hostPage; }\r\n public set HostPage(value: IHostPage) { this.hostPage = value; }\r\n\r\n public get AppType(): string { return this.appType; }\r\n\r\n public get AuthCookieName(): AuthCookieName { return this.authCookieName; }\r\n public set AuthCookieName(value: AuthCookieName) { this.authCookieName = value; }\r\n\r\n public get UseOneServiceAuthEndpoints(): boolean { return this.useOneServiceAuthEndpoints; }\r\n public set UseOneServiceAuthEndpoints(value: boolean) { this.useOneServiceAuthEndpoints = value; }\r\n\r\n public get AccountInfoPromise(): Promise { return this.accountInfoPromise; }\r\n public set AccountInfoPromise(value: Promise) { this.accountInfoPromise = value; }\r\n\r\n public get ResolvedAccountInfo(): AccountInfo { return this.resolvedAccountInfo; }\r\n public set ResolvedAccountInfo(value: AccountInfo) { this.resolvedAccountInfo = value; }\r\n\r\n public get BuildVersion(): string { return this.buildVersion; }\r\n\r\n public get ClarityEnabled(): boolean { return this.clarityEnabled; }\r\n public set ClarityEnabled(value: boolean) { this.clarityEnabled = value; }\r\n\r\n public get RootTelemetryId(): number { return this.rootTelemetryId; }\r\n public set RootTelemetryId(value: number) { this.rootTelemetryId = value; }\r\n\r\n public get TrackInfo(): ITrackInfo { return this.trackInfo; }\r\n public set TrackInfo(value: ITrackInfo) { this.trackInfo = value; }\r\n\r\n public get UserId(): string { return this.getUserMuid() || this.userId; }\r\n public set UserId(value: string) { this.userId = value; }\r\n\r\n /** True if query string has appropriate debug flag */\r\n public get IsDebug(): boolean { return this.isDebug; }\r\n\r\n /** True if query string has appropriate flag to show msnCreatorDashboard (msnDash=) */\r\n public get ShowMnsCreatorDashboard(): boolean { return this.showMnsCreatorDashboard; }\r\n\r\n /**\r\n * Gets the host to use when linking to content.\r\n */\r\n public get contentLinkHost(): string { return this.currentContentLinkHost; }\r\n\r\n /**\r\n * Getter for the base for the service url, endpoints/queries are appended for specific service calls.\r\n * This is the oneservice url used for personalized content.\r\n * Possible values are enumerated on OneServiceConfig.ts\r\n *\r\n * @type {URL}\r\n * @memberof AppEnvironment\r\n */\r\n public get ServiceUrlBase(): URL {\r\n const url = new URL(\"\", this.serviceUrlBase);\r\n\r\n if (process.env.WEBPACK_DEV_SERVER || new URLSearchParams(getLocationSearch()).get(\"env\") === \"dev\") {\r\n url.searchParams.set(\"env.service\", \"dev\");\r\n }\r\n\r\n const searchParam = new URLSearchParams(getLocationSearch()).get(\"env.service\");\r\n if (searchParam) {\r\n url.searchParams.set(\"env.service\", searchParam);\r\n }\r\n\r\n return url;\r\n }\r\n\r\n /**\r\n * Base URL for the feed service\r\n */\r\n public get FeedServiceUrlBase(): URL {\r\n if (!this.feedServiceUrlBase) {\r\n return null;\r\n }\r\n\r\n const url = new URL(\"\", this.feedServiceUrlBase);\r\n\r\n if (process.env.WEBPACK_DEV_SERVER || new URLSearchParams(getLocationSearch()).get(\"env\") === \"dev\") {\r\n url.searchParams.set(\"env.service\", \"dev\");\r\n }\r\n\r\n const searchParam = new URLSearchParams(getLocationSearch()).get(\"env.service\");\r\n if (searchParam) {\r\n url.searchParams.set(\"env.service\", searchParam);\r\n }\r\n\r\n return url;\r\n }\r\n\r\n /**\r\n * Base URL for the enterprise service\r\n */\r\n public get EnterpriseServiceUrlBase(): URL {\r\n const url = new URL(\"\", EnterpriseOneServiceApi);\r\n\r\n if (process.env.WEBPACK_DEV_SERVER || new URLSearchParams(getLocationSearch()).get(\"env\") === \"dev\") {\r\n url.searchParams.set(\"env.service\", \"dev\");\r\n }\r\n\r\n const searchParam = new URLSearchParams(getLocationSearch()).get(\"env.service\");\r\n if (searchParam) {\r\n url.searchParams.set(\"env.service\", searchParam);\r\n }\r\n\r\n return url;\r\n }\r\n\r\n public get IsFrePage(): boolean { return this.isFrePage; }\r\n\r\n /**\r\n * This is the switch to turn on/off indexed db operation used as a caching layer in config resolver (Resolver.ts)\r\n */\r\n public get DisableCachingConfigs(): boolean { return this.disableCachingConfigs; }\r\n\r\n /**\r\n * This is the switch to turn on/off config service operation in Resolver.ts\r\n */\r\n public get EnableConfigService(): boolean { return this.enableConfigService; }\r\n\r\n /**\r\n * This indicates whether we will use CMS PPE configs or not\r\n */\r\n public get EnableCMSPPEConfigs(): boolean { return headData && headData.EnableCMSPPEConfigs; }\r\n\r\n /**\r\n * Check whether multi config retrieval is supported.\r\n */\r\n public get IsMultiConfigRetrievalEnabled(): boolean { return this.isMultiConfigRetrievalEnabled; }\r\n\r\n /**\r\n * This is the switch to turn on/off content preview caching in core/cache/ContentPreview.ts\r\n */\r\n public get DisableContentPreviewCache(): boolean {\r\n return this.disableContentPreviewCache;\r\n }\r\n\r\n /**\r\n * Returns a flag indicating whether the one service feed fetch call should send activityID\r\n * in the request header or as a QSP in the URL (current behavior is via QSP).\r\n */\r\n public get SendFeedCallActivityIdInHeader(): boolean {\r\n return this.sendFeedCallActivityIdInHeader;\r\n }\r\n\r\n /**\r\n * This is the switch to turn off hydrating content preview cache from IndexedDB.\r\n * Default is false\r\n */\r\n public get DisableContentCacheIDBRead(): boolean {\r\n const queryParamOverride = UrlUtility.getQueryParameterByName(\"disableContentCacheIDBRead\", getLocationSearch());\r\n\r\n if (queryParamOverride) {\r\n return queryParamOverride === \"true\";\r\n }\r\n\r\n return this.disableContentCacheIDBRead;\r\n }\r\n\r\n /**\r\n * Get base url of Config Service.\r\n */\r\n public get ConfigServiceBaseUrl(): URL { return this.configServiceBaseUrl; }\r\n\r\n /**\r\n * This returns feature flags client settings stamped by PCS.\r\n */\r\n public get FeatureFlags(): any { return this.featureFlags; }\r\n\r\n /**\r\n * This returns config root url\r\n */\r\n public get ConfigRootUrl(): URL {\r\n if (!this.configRootUrl) {\r\n return null;\r\n }\r\n\r\n const url = new URL(\"\", this.configRootUrl);\r\n\r\n if (process.env.WEBPACK_DEV_SERVER || new URLSearchParams(getLocationSearch()).get(\"env\") === \"dev\") {\r\n url.searchParams.set(\"env.config\", \"dev\");\r\n }\r\n\r\n const searchParam = new URLSearchParams(getLocationSearch()).get(\"env.config\");\r\n if (searchParam) {\r\n url.searchParams.set(\"env.config\", searchParam);\r\n }\r\n\r\n return url;\r\n }\r\n\r\n /**\r\n * Returns cache busting identifier from PCS.\r\n */\r\n public get CacheBustingIdentifier(): string { return this.cacheBustingIdentifier; }\r\n\r\n /**\r\n * Returns the country code. For example \"br\"\r\n */\r\n public get CountryCode(): string { return this.countryCode; }\r\n public set CountryCode(value: string) { this.countryCode = value; }\r\n\r\n /// / FIXME: hyphen has a second 'h'\r\n /// / Bug 24228723: [Peregrine] ActivityIdLowerCaseNoHypens misspells \"Hyphen\"\r\n /**\r\n * Gets the Activity ID in lower case and without any hyphens. This helper method should be where parity with Prime is required.\r\n * Use telemetry's requestId instead for associating with current page client navigation\r\n */\r\n public get ActivityIdLowerCaseNoHypens(): string { return ((headData && headData.ClientSettings && headData.ClientSettings.aid) || \"\").toLowerCase(); }\r\n\r\n /**\r\n * Returns the latitude. For example \"42.361145\"\r\n */\r\n public get Latitude(): string { return this.latitude; }\r\n\r\n /**\r\n * Returns the longitude. For example \"-71.057083\"\r\n */\r\n public get Longitude(): string { return this.longitude; }\r\n\r\n /**\r\n * Initialize the AppEnvironment singleton instance.\r\n * @param _serviceUrl Optional URL to initialize the ServiceUrlBase.\r\n * @param _configServiceUrlBase ConfigServiceUrlBase provided during server side rendering this is the ServiceFabric ClusterRegionUrl.\r\n */\r\n private constructor(_serviceUrl: URL, _configServiceUrlBase: string) {\r\n this.initializeAppEnvironment(_serviceUrl, _configServiceUrlBase);\r\n }\r\n\r\n /**\r\n * Returns singleton class instance.\r\n * @returns {AppEnvironment}\r\n */\r\n public static getInstance(serviceUrl: URL = null, configServiceUrlBase: string = null): AppEnvironment {\r\n return AppEnvironment._instance || (AppEnvironment._instance = new AppEnvironment(serviceUrl, configServiceUrlBase));\r\n }\r\n\r\n /**\r\n * Reinitialize the singleton class instance.\r\n * @param serviceUrl OneService service url to initialize to.\r\n * @param configServiceUrlBase Config service url to initialize to.\r\n * @returns {AppEnvironment}\r\n */\r\n public static resetInstance(serviceUrl: URL = null, configServiceUrlBase: string = null): AppEnvironment {\r\n AppEnvironment._instance = new AppEnvironment(serviceUrl, configServiceUrlBase);\r\n appEnvironment = AppEnvironment._instance;\r\n return AppEnvironment._instance;\r\n }\r\n\r\n /**\r\n * Initializes App environment. This is normally only called by the constructor (singleton pattern)\r\n * It is made public so that it can be also called by test code.\r\n */\r\n public initializeAppEnvironment(_serviceUrl?: URL, configServiceUrlBase?: string): void {\r\n\r\n let environmentFromHeadData: Environment = null;\r\n const clientSettings = headData && headData.ClientSettings;\r\n\r\n if (clientSettings) {\r\n this.activityId = this.tryReformatGuid(clientSettings.aid);\r\n this.buildVersion = clientSettings.bundleInfo && clientSettings.bundleInfo.v || \"\";\r\n this.currentMarket = (headData.Locale || clientSettings.apps_locale) as Market;\r\n this.countryCode = clientSettings.geo_country;\r\n this.latitude = clientSettings.geo_lat;\r\n this.longitude = clientSettings.geo_long;\r\n this.configRootUrl = clientSettings.configRootUrl ? new URL(\"\", clientSettings.configRootUrl) : null;\r\n environmentFromHeadData = getEnvironmentFromString(clientSettings.pcsInfo && clientSettings.pcsInfo.env || \"prod\");\r\n\r\n this.setAccountInfoPromise();\r\n this.appType = clientSettings.apptype || \"\";\r\n this.authCookieName = this.getAuthCookieName();\r\n this.useOneServiceAuthEndpoints = false;\r\n\r\n this.featureFlags = clientSettings.featureFlags;\r\n\r\n this.disableCachingConfigs =\r\n this.featureFlags && this.featureFlags.disableCachingConfigs\r\n ? this.featureFlags.disableCachingConfigs === \"true\"\r\n : false;\r\n\r\n this.enableConfigService =\r\n this.featureFlags && this.featureFlags.enableConfigService\r\n ? this.featureFlags.enableConfigService === \"true\"\r\n : true;\r\n\r\n this.disableContentPreviewCache =\r\n this.featureFlags && this.featureFlags.disableContentPreviewCache\r\n ? this.featureFlags.disableContentPreviewCache === \"true\"\r\n : false;\r\n\r\n this.disableContentCacheIDBRead = this.featureFlags && this.featureFlags.disableContentCacheIDBRead\r\n ? this.featureFlags.disableContentCacheIDBRead === \"true\"\r\n : false;\r\n\r\n // Use feature flag as a switch to disable the feature (will need a PCS deployment)\r\n this.sendFeedCallActivityIdInHeader = this.featureFlags && this.featureFlags.disableActivityIdInHeader && this.featureFlags.disableActivityIdInHeader === \"true\"\r\n ? false\r\n : this.appType === AppType.Edge || this.appType === AppType.Hub;\r\n\r\n this.cacheBustingIdentifier = clientSettings.cbid;\r\n\r\n if (clientSettings.pcsInfo && !getAppErrorsPropertyBag().pcsVersion) {\r\n const propertyBagPcsVersion: AppErrorPropertyBag = {\r\n pcsVersion: clientSettings.pcsInfo.v\r\n };\r\n\r\n updateAppErrorsPropertyBag(propertyBagPcsVersion);\r\n }\r\n }\r\n\r\n const rootElement = canUseDOM() ? getDocumentElementById(rootElementId) : null;\r\n const locationHref = getLocationHref();\r\n const locationOrigin = getLocationOrigin();\r\n\r\n // env is read from\r\n // - query string param env, if present\r\n // - headData.ClientSettings.pcsInfo.env\r\n // - defaults to prod otherwise\r\n const envQSOverwrite = getEnvironmentFromString(UrlUtility.getQueryParameterByName(\"env\", locationHref));\r\n this.environment =\r\n envQSOverwrite\r\n || environmentFromHeadData\r\n || Environment.prod;\r\n\r\n // Find the host for the Akamai assets store.\r\n this.assetsHost = getLocationHostname().endsWith(\".cn\") ? \"assets.msn.cn\" : \"assets.msn.com\";\r\n\r\n this.serviceUrlBase = _serviceUrl || (rootElement && rootElement.getAttribute(serviceUrl) && new URL(\"\", rootElement.getAttribute(serviceUrl))) || new URL(\"\", `https://${this.assetsHost}/service/`);\r\n\r\n // Dependency (revert back when complete):\r\n // Deliverable 27138476: [PCS] China pages should point to assets via assets.msn.cn for all endpoints send from PCS.\r\n // This is also applied to WW Environment.\r\n // Only default to assets.msn.com if anaheim, msftnews or edge.\r\n // Should never be applied to MMX due to additional handshake overhead\r\n const defaultFeedBaseDomain = this.appType === AppType.EdgeChromium || this.appType === AppType.MicrosoftNews || this.appType === AppType.Edge ? `https://${this.assetsHost}` : locationOrigin;\r\n\r\n // If PCS sent the feed base domain, use it for the feed URL base\r\n // or else default to host page rooted URL.\r\n this.feedServiceUrlBase = new URL(\"./service/\", clientSettings && clientSettings.feedBaseDomain ? clientSettings.feedBaseDomain : defaultFeedBaseDomain);\r\n\r\n // Get the hostPage from the request url\r\n this.hostPage = HostPage.getHostPageFromUrl(locationHref);\r\n\r\n // Determine if the page is running as an FRE page\r\n this.isFrePage = (UrlUtility.getQueryParameterByName(\"fre\", locationHref) === \"1\");\r\n\r\n this.userId = this.getUserMuid();\r\n\r\n // Get attributes from the head (full page Peregrine experience) or from the spa \"root\" element (PrimeHybrid case)\r\n // TODO, determine where in the element attributes these values should be set\r\n this.rootTelemetryId = rootElement ? Number(rootElement.getAttribute(telemetryId)) : 0;\r\n const trackPageProd = rootElement && rootElement.getAttribute(trackPageProduct);\r\n const trackPageTypeVal = rootElement && rootElement.getAttribute(trackPageType);\r\n this.trackInfo = { sitePage: { page_product: trackPageProd, page_type: trackPageTypeVal } };\r\n\r\n this.contentServiceUrlBase = new URL(\"\", `https://${this.assetsHost}/content/`);\r\n\r\n this.currentContentLinkHost = this.createContentLinkHost();\r\n\r\n this.setTargetScope();\r\n\r\n this.isMultiConfigRetrievalEnabled = this.useMultiConfigsRetrieval();\r\n\r\n const baseUrl = this.getConfigServiceBaseUrl(this.isMultiConfigRetrievalEnabled, configServiceUrlBase);\r\n this.configServiceBaseUrl = baseUrl ? new URL(\"\", baseUrl) : null;\r\n\r\n this.environmentConfigUrl = new URL(\"\", `https://${this.assetsHost}/config/v1/`);\r\n\r\n this.isDebug = ((UrlUtility.getQueryParameterByName(\"debug\", locationHref) || \"\").toLowerCase() in { 1: 1, true: 1 })\r\n || (UrlUtility.getQueryParameterByName(\"item\", locationHref) || \"\").toLowerCase().indexOf(\"/debug\") > 0;\r\n\r\n this.showMnsCreatorDashboard = UrlUtility.getQueryParameterByName(\"mnsDash\", locationHref) != null;\r\n }\r\n\r\n /**\r\n * Get the UserMuid from the muid cookie\r\n */\r\n private getUserMuid(): string {\r\n let muid: string;\r\n const muidCookie: string = getMuidCookie();\r\n if (isString(muidCookie)) {\r\n muid = \"m-\" + muidCookie;\r\n }\r\n return muid;\r\n }\r\n\r\n /**\r\n * Get config service base url\r\n * @param isMultiConfigRetrievalEnabled if multiple config retrieval is supported.\r\n * @param configServiceUrlBase externally configured config service url (from SSR environment)\r\n * @returns {string} - config service base url.\r\n */\r\n private getConfigServiceBaseUrl(isMultiConfigRetrievalEnabled = true, configServiceUrlBase?: string): string {\r\n const relativePath = `/resolver/api/resolve/${isMultiConfigRetrievalEnabled ? \"v2/\" : \"\"}configindex/`;\r\n\r\n if (configServiceUrlBase) {\r\n // When doing server side rendering the ClusterRegionUrl env variable should be set, use this to avoid calls to CRS going outside of the cluster.\r\n return configServiceUrlBase + relativePath;\r\n } else if (process.env.WEBPACK_DEV_SERVER || this.environment === Environment.int) {\r\n // int and localhost to use int.msn.com for config service.\r\n return \"https://int.msn.com\" + relativePath;\r\n } else {\r\n return getLocationOrigin() ? getLocationOrigin() + relativePath : null;\r\n }\r\n }\r\n\r\n /**\r\n * Function checks if ConfigService should return multiple configs\r\n * @returns true if supported else false.\r\n */\r\n private useMultiConfigsRetrieval(): boolean {\r\n const urlQuery = getLocationSearch();\r\n if (urlQuery) {\r\n const param = UrlUtility.getQueryParameterByName(\"isMultiConfigRetrievalEnabled\", urlQuery);\r\n if (param) {\r\n return param.toLocaleLowerCase() === \"true\";\r\n }\r\n }\r\n\r\n // PCS flag to turn on/off multi config retrieval.\r\n if (this.featureFlags\r\n && this.featureFlags.isMultiConfigRetrievalEnabled) {\r\n return this.featureFlags.isMultiConfigRetrievalEnabled === \"true\";\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Get the auth cookie name based on the app type of the page\r\n * @returns {AuthCookieName} - the name of the auth cookie to use\r\n */\r\n private getAuthCookieName(): AuthCookieName {\r\n const clientSettings = headData && headData.ClientSettings;\r\n const appType: AppType = (clientSettings.apptype || \"\") as AppType;\r\n let authCookieName: AuthCookieName;\r\n switch (appType) {\r\n case AppType.FirstParty:\r\n case AppType.Hub:\r\n case AppType.MicrosoftNews:\r\n case AppType.Views:\r\n case AppType.Weather:\r\n case AppType.Finance:\r\n authCookieName = AuthCookieName.Anon;\r\n break;\r\n case AppType.Edge:\r\n case AppType.EdgeChromium:\r\n case AppType.MMX:\r\n case AppType.Office:\r\n default:\r\n authCookieName = AuthCookieName.AppAnon;\r\n }\r\n\r\n return authCookieName;\r\n }\r\n\r\n /**\r\n * Sets the AccountInfoPromise for the current user.\r\n * If unable to await, ResolvedAccountInfo is also set when the promise is resolved.\r\n */\r\n private setAccountInfoPromise(): void {\r\n this.ResolvedAccountInfo = null;\r\n this.AccountInfoPromise = new Promise((resolve) => {\r\n if (!canUseDOM() || !window.chrome || !window.chrome.authPrivate || !window.chrome.authPrivate.getPrimaryAccountInfo) {\r\n return resolve(null);\r\n }\r\n\r\n const markerName = \"Auth.GetPrimaryAccountInfo\";\r\n const startTime = Math.round(performance.now());\r\n\r\n window.chrome.authPrivate.getPrimaryAccountInfo((accountInfo) => {\r\n const endTime = Math.round(performance.now());\r\n const pageTimings = getPageTimings();\r\n pageTimings[markerName] = endTime - startTime;\r\n\r\n this.ResolvedAccountInfo = accountInfo;\r\n return resolve(accountInfo);\r\n });\r\n });\r\n\r\n // Start the promise asynchronously.\r\n this.AccountInfoPromise;\r\n }\r\n\r\n /**\r\n * Determines the content link host to use.\r\n * @returns The content link host.\r\n */\r\n private createContentLinkHost(): string {\r\n const topLevelDomain = this.currentMarket === Market.ZHCN ? \"cn\" : \"com\";\r\n return \"www.msn.\" + topLevelDomain;\r\n }\r\n\r\n /**\r\n * Reformats the given guid without dashes to a guid string with dashes.\r\n * @param {string} guid - The guid without dashes.\r\n * @returns {string} - The reformatted GUI with dashes.\r\n */\r\n private tryReformatGuid(guid: string): string {\r\n if (guid && guid.length === 32) {\r\n // use a regex to extract the specific substrings to reformat the guid\r\n const matches = guid.match(/(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})/i);\r\n if (matches) {\r\n // join all the captured groups from 1-5 to format the final guid string\r\n guid = matches.slice(1).join(\"-\");\r\n }\r\n }\r\n\r\n return guid;\r\n }\r\n\r\n /**\r\n * Sets target scope for current request.\r\n */\r\n private setTargetScope(): void {\r\n if (!headData || !headData.ClientSettings) {\r\n return;\r\n }\r\n\r\n // If user is signed in and \"child\" Cookie exists - set Kids audience mode, otherwise use PCS provided Audience mode.\r\n let audienceMode: AudienceModeType;\r\n if (getCookie(appAnonCookieExistsCookieName) && getCookie(childCookieName)) {\r\n audienceMode = AudienceModeType.Kids;\r\n } else {\r\n audienceMode = headData.ClientSettings.audienceMode || AudienceModeType.Adult;\r\n }\r\n\r\n const { browser, deviceFormFactor, domain, locale, os, pagetype } = headData.ClientSettings;\r\n\r\n this.currentRequestTargetScope = {\r\n audienceMode: audienceMode,\r\n browser: browser,\r\n deviceFormFactor: deviceFormFactor,\r\n domain: domain,\r\n locale: locale,\r\n os: os,\r\n platform: PlatformType.Web,\r\n pageType: pagetype\r\n };\r\n\r\n // if locale is not defined in client settings, try reading it from headData for backward compatibility\r\n if (!this.currentRequestTargetScope.locale && Utility.stringHasData(headData.Locale)) {\r\n const locale = headData.Locale.split(\"-\");\r\n if (locale.length > 1) {\r\n this.currentRequestTargetScope.locale = {\r\n language: locale[0],\r\n // Some spartan locale are in format \"ha-latn-ng\". Here the market is \"ng\" and language is \"ha\"\r\n market: locale[locale.length - 1]\r\n };\r\n }\r\n }\r\n\r\n if (Utility.stringHasData(headData.CurrentFlights)) {\r\n this.currentRequestTargetScope.pageExperiments = headData.CurrentFlights.split(\",\");\r\n }\r\n\r\n this.addWpoFlights();\r\n }\r\n\r\n /**\r\n * Adds WPO flights to the current request target scope pageExperiments.\r\n */\r\n private addWpoFlights(): void {\r\n\r\n if (!this.FeatureFlags || !this.FeatureFlags.wpoEnabled) {\r\n return;\r\n }\r\n\r\n const key: string = getWpoStorageCacheKey(this.appType, this.currentRequestTargetScope);\r\n const wpoData: WpoModel = localStorage.getObject(key);\r\n const flightsCached: string[] = getWpoFlights(wpoData);\r\n\r\n if (!flightsCached) {\r\n return;\r\n }\r\n\r\n const currentPageExperiments = this.currentRequestTargetScope.pageExperiments || [];\r\n this.currentRequestTargetScope.pageExperiments = currentPageExperiments.concat(flightsCached);\r\n }\r\n}\r\n\r\nexport const getAppEnvironment = AppEnvironment.getInstance;\r\n\r\n// appEnvironment can be reinitialized for server side rendering through resetAppEnvironment.\r\nexport let appEnvironment = AppEnvironment.getInstance();\r\n\r\nexport const resetAppEnvironment = AppEnvironment.resetInstance;","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Client side properties that Render Service sends to initialize RequestData.\r\n * These properties are typically passed via query param to the render service.\r\n * On the client side these are available and populated through the DOM.\r\n */\r\nexport interface RequestProps {\r\n\r\n /**\r\n * URL for the original client request.\r\n */\r\n href: string;\r\n\r\n /**\r\n * Width of client browser window.\r\n */\r\n innerWidth: number;\r\n\r\n /**\r\n * Height of client browser window.\r\n */\r\n innerHeight: number;\r\n\r\n /**\r\n * Device pixel ratio of client.\r\n */\r\n devicePixelRatio: number;\r\n\r\n /**\r\n * CSS Grid support of the client browser.\r\n */\r\n canUseCssGrid: boolean;\r\n\r\n /**\r\n * Request Id.\r\n */\r\n requestId: string;\r\n\r\n /**\r\n * The request cookie string\r\n */\r\n cookie: string;\r\n\r\n /**\r\n * The request referer string\r\n */\r\n referer: string;\r\n}\r\n\r\n/**\r\n * Singleton class to store client browser data sent through query param to Render Service.\r\n * This is only used under server environment.\r\n */\r\nclass RequestData {\r\n /**\r\n * The single instance of the RequestData class.\r\n * @type {RequestData}\r\n */\r\n private static _instance: RequestData = null;\r\n\r\n /**\r\n * URL object to be used to store original request url.\r\n */\r\n public readonly url: URL;\r\n\r\n /**\r\n * Inner height of browser from the original request.\r\n */\r\n public readonly innerHeight: number;\r\n\r\n /**\r\n * Device pixel ratio from the original request.\r\n */\r\n public readonly devicePixelRatio: number;\r\n\r\n /**\r\n * Boolean flag that represents if CSS Grid is supported by the browser from the original request.\r\n */\r\n public readonly canUseCssGrid: boolean;\r\n\r\n /**\r\n * Request Id.\r\n */\r\n public readonly requestId: string;\r\n\r\n /**\r\n * Request cookie string\r\n */\r\n public readonly cookie: string;\r\n\r\n /**\r\n * Request referer string\r\n */\r\n public readonly referer: string;\r\n\r\n /**\r\n * Inner width of browser from the original request.\r\n */\r\n private readonly _innerWidth: number;\r\n\r\n /**\r\n * The viewport width\r\n */\r\n private _viewportWidth: number;\r\n\r\n /**\r\n * Initialize the request data instance with passed in client properties\r\n */\r\n private constructor(data: RequestProps) {\r\n this.url = new URL(data.href);\r\n this._innerWidth = data.innerWidth;\r\n this.innerHeight = data.innerHeight;\r\n this.devicePixelRatio = data.devicePixelRatio;\r\n this.canUseCssGrid = data.canUseCssGrid;\r\n this.requestId = data.requestId;\r\n this.cookie = data.cookie;\r\n this.referer = data.referer;\r\n this._viewportWidth = null;\r\n }\r\n\r\n /**\r\n * Returns the inner width of browser from the original request.\r\n */\r\n public get innerWidth(): number {\r\n return this._viewportWidth || this._innerWidth;\r\n }\r\n\r\n /**\r\n * Sets the viewport width for the request, which will override the innerWidth property from the request\r\n */\r\n public static overrideInnerWidthWithFixedViewportWidth(viewportWidth: number): void {\r\n if (viewportWidth > 0) {\r\n RequestData._instance._viewportWidth = viewportWidth;\r\n }\r\n }\r\n\r\n /**\r\n * Returns singleton class instance.\r\n * @returns RequestData\r\n */\r\n public static getInstance(): RequestData {\r\n if (global[\"TEST_ENV\"] && !RequestData._instance) {\r\n resetRequestData({\r\n href: \"http://localhost:8080/\",\r\n innerWidth: 1024,\r\n innerHeight: 768,\r\n devicePixelRatio: 1,\r\n canUseCssGrid: false,\r\n requestId: \"0\",\r\n cookie: \"\",\r\n referer: \"\"\r\n });\r\n }\r\n\r\n if (!RequestData._instance) {\r\n // Throw error if the request data has not been set as this should never be the case.\r\n // This likely highlights that the request data was not initialized when handling a\r\n // request when server side rendering.\r\n throw new Error(\"Request data is not initialized yet through ResetInstance.\");\r\n }\r\n return RequestData._instance;\r\n }\r\n\r\n /**\r\n * Reset singleton class instance with passed in info and client settings\r\n * @returns RequestData\r\n */\r\n public static resetInstance(data: RequestProps): RequestData {\r\n RequestData._instance = new RequestData(data);\r\n return RequestData._instance;\r\n }\r\n}\r\n\r\n/**\r\n * Used to override the innerWidth value from the request data with a fixed viewport width\r\n */\r\nexport const overrideInnerWidthWithFixedViewportWidth = RequestData.overrideInnerWidthWithFixedViewportWidth;\r\n\r\n/**\r\n * Export function to reset the request data singleton.\r\n * This must be used to set the request data.\r\n */\r\nexport const resetRequestData = RequestData.resetInstance;\r\n\r\n/**\r\n * Export get instance function for testing\r\n */\r\nexport const getRequestData = () => (RequestData.getInstance());","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Constants that are used throughout the library\r\n */\r\nexport namespace ConnectorConstants {\r\n /**\r\n * The key within a state JSON document used to store a connectors individual state\r\n */\r\n export const connectorStateKey = \"_@STATE@_\";\r\n\r\n export const renderAction = \"@@connector-view/RENDER\";\r\n\r\n export const dataConnectorMergeInitAction = \"@@data-connector/MERGE-INIT\";\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { WebStorage } from \"./WebStorage\";\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\n\r\n/**\r\n * Local storage class for persistent storage\r\n */\r\nexport class LocalStorage extends WebStorage {\r\n constructor() {\r\n let storage: Storage = null;\r\n\r\n if (canUseDOM()) {\r\n try {\r\n storage = \"localStorage\" in window && window.localStorage;\r\n } catch (ex) {\r\n // Getting local storage failed. Can happen in Chrome when user has disabled cookies.\r\n }\r\n }\r\n\r\n super(storage);\r\n }\r\n}\r\n\r\n/**\r\n * Set the local storage instance. Useful when setting up mock storage instance.\r\n * @param _storage The local storage instance to change to.\r\n */\r\nexport function setLocalStorage(_storage: WebStorage): void {\r\n localStorage = _storage;\r\n}\r\n\r\nexport let localStorage: WebStorage = new LocalStorage();","// © Microsoft Corporation. All rights reserved.\r\n// Provides utility functions to get and set data from browser webStorage.\r\n\r\nimport { tryParseJson } from \"../utilities/Parsing\";\r\nimport { logger } from \"@msnews/diagnostics\";\r\n\r\n/**\r\n * Base class for localeStorage and sessionStorage abstractions\r\n */\r\nexport class WebStorage {\r\n\r\n /**\r\n * Check if the web storage is supported\r\n * @returns {boolean} true if supported\r\n */\r\n public get supported(): boolean {\r\n return !!this.storage;\r\n }\r\n\r\n /**\r\n * Local storage object for persistent storage\r\n * @param storage Storage used.\r\n */\r\n constructor(private readonly storage: Storage) {\r\n }\r\n\r\n /**\r\n * Get given key's value from web storage\r\n * @param {string} key - Key name\r\n * @returns {string} Key value\r\n */\r\n public getItem(key: string): string {\r\n if (this.supported) {\r\n return this.storage.getItem(key);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the value from local storage using the key.\r\n * @param {string} key - the storage key to store under\r\n * @param {T} defaultValue - the default value to return if parsing fails\r\n * @returns {T} The parsed JSON value\r\n */\r\n public getObject(key: string, defaultValue?: T): T {\r\n const value = this.getItem(key);\r\n if (value != null) {\r\n const parsedObj = tryParseJson(value);\r\n if (parsedObj != null) {\r\n return parsedObj;\r\n }\r\n }\r\n\r\n return defaultValue;\r\n }\r\n\r\n /**\r\n * Gets given index location key from web storage\r\n * @param {string} key - Key name\r\n * @returns {string} Key value\r\n */\r\n public key(index: number): string {\r\n if (this.supported && index >= 0) {\r\n return this.storage.key(index);\r\n }\r\n }\r\n\r\n /**\r\n * Sets the given value after stringifying as JSON\r\n * @param {string} key - the storage key to store under\r\n * @param {T} value - the value to serialize and store\r\n */\r\n public setObject(key: string, value: T): void {\r\n (value !== undefined)\r\n ? this.setItem(key, JSON.stringify(value))\r\n : this.removeItem(key);\r\n }\r\n\r\n /**\r\n * Removes the given key from storage and returns the existing value parsed\r\n * @param {string} key - the key to remove.\r\n */\r\n public removeObject(key: string): T {\r\n const value = this.removeItem(key);\r\n if (value != null) {\r\n return tryParseJson(value);\r\n }\r\n }\r\n\r\n /**\r\n * Set given key's value to local storage\r\n * @param {string} key - Key name\r\n * @param {string} value - Key value\r\n */\r\n public setItem(key: string, value: string): void {\r\n if (this.supported) {\r\n // Catch quota exceeded exception\r\n try {\r\n this.storage.setItem(key, value);\r\n } catch (e) {\r\n logger.logError(e);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Remove key item from local storage\r\n * @param {string} key - Key name\r\n * @returns {string} Key value\r\n */\r\n public removeItem(key: string): string {\r\n if (this.supported) {\r\n const value = this.getItem(key);\r\n this.storage.removeItem(key);\r\n return value;\r\n }\r\n }\r\n\r\n /**\r\n * Removes all keys containing the given substring in the storage key\r\n * @param {string} substring The substring to check\r\n */\r\n public removeSubstringKeys(substring: string): void {\r\n if (!this.supported || !substring) {\r\n return;\r\n }\r\n\r\n const matchingKeys = [];\r\n for (let index = 0; index < this.storage.length; index++) {\r\n const storageKey = this.key(index);\r\n if (storageKey && storageKey.includes(substring)) {\r\n matchingKeys.push(storageKey);\r\n }\r\n }\r\n\r\n for (let index = 0; index < matchingKeys.length; index++) {\r\n this.removeItem(matchingKeys[index]);\r\n }\r\n }\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Attempts to parse a given string to a JSON object\r\n * @param {string} jsonString - The string to parse.\r\n * @returns {any} - the parsed object if successful, or null otherwise.\r\n */\r\nexport function tryParseJson(jsonString: string): any {\r\n try {\r\n return JSON.parse(jsonString);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/** Attempts to parse the given value as a integer and if failed will return the defaultValue.\r\n * @param {string} value - The value to parse.\r\n * @param {number} defaultValue - The default value to return if parsing fails\r\n * @returns {number} the parsed value if it was a valid number or otherwise the default value if specified.\r\n */\r\nexport function tryParseInt(value: string, defaultValue: number): number {\r\n const n = parseInt(value);\r\n return isNaN(n) ? defaultValue : n;\r\n}\r\n","\r\n// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { RenderCache, RenderCacheKeys } from \"./RenderCache\";\r\nimport { riverRcClassName, locationHref, normalizedUrlConfigkey, keysPrefix } from \"./Constants\";\r\nimport { KeyValueArray } from \"@msnews/core\";\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\n\r\nlet renderCacheObject: RenderCache;\r\n\r\n/**\r\n * Function to get render cache if it's valid.\r\n * @returns Render cache object if it exists and is valid otherwise null.\r\n */\r\nexport function getRenderCache(): RenderCache {\r\n if (renderCacheObject) {\r\n return renderCacheObject;\r\n }\r\n\r\n if (!(window && window.localStorage)) {\r\n return null;\r\n }\r\n\r\n // get all normalized render cache keys from local storage\r\n let renderCacheKeys: RenderCacheKeys;\r\n const renderCacheStoredKeys = window.localStorage.getItem(renderCacheKeyOfNormalizedKeys);\r\n try {\r\n renderCacheKeys = renderCacheStoredKeys && JSON.parse(renderCacheStoredKeys);\r\n } catch (error) {\r\n return null; // keys not parsable.\r\n }\r\n\r\n if (!renderCacheKeys || !renderCacheKeys.keyn || !renderCacheKeys.expn || !renderCacheKeys.frcn || !renderCacheKeys.jssn) {\r\n return null;\r\n }\r\n\r\n const cacheExpirationTimestamp = window.localStorage.getItem(renderCacheKeys.expn);\r\n if (!cacheExpirationTimestamp) {\r\n return null; // Cache Expiration Timestamp not exist\r\n }\r\n\r\n const parsedCacheExpirationTimestamp = parseInt(cacheExpirationTimestamp);\r\n if (!parsedCacheExpirationTimestamp) {\r\n return null; // Cache Expiration Timestamp broken.\r\n }\r\n\r\n const currentTimestamp: number = new Date().getTime();\r\n if (currentTimestamp >= parsedCacheExpirationTimestamp) {\r\n return null; // cache expired.\r\n }\r\n\r\n const renderCacheStorage = window.localStorage.getItem(renderCacheKeys.keyn);\r\n if (!renderCacheStorage) {\r\n return null; // Cache object is missing.\r\n }\r\n\r\n try {\r\n renderCacheObject = JSON.parse(renderCacheStorage);\r\n } catch (error) {\r\n return null; // Cache object not parsable.\r\n }\r\n\r\n if (!renderCacheObject || !renderCacheObject.dom || !renderCacheObject.batch_css) {\r\n renderCacheObject = null; // Cache object is broken\r\n }\r\n\r\n return renderCacheObject;\r\n}\r\n\r\n/**\r\n * Batch All styles into one object.\r\n */\r\nexport function batchCSS(): string {\r\n let batchCss = \"\";\r\n\r\n // Enumerate and write out all of the JSS styles\r\n const styles = document.getElementsByTagName(\"style\");\r\n const length = styles.length;\r\n\r\n for (let i = 0; i < length; i++) {\r\n // Skip any styles that do not have a data-jss attribute to always pick newer styles added by jss\r\n if (styles[i].dataset.jss != null) {\r\n batchCss += styles[i].innerHTML;\r\n }\r\n }\r\n\r\n return batchCss;\r\n}\r\n\r\n/**\r\n * Scrapes Dom and remove River.\r\n */\r\nexport function scrapeDom(includeNewsFeed: boolean): string {\r\n const root = document.getElementById(\"root\");\r\n\r\n if (!root || !root.innerHTML) {\r\n return \"\";\r\n }\r\n\r\n /* Currently we don't have functionality to include experiences separately,\r\n because of that we do return whole dom if river included in render cache and exclude river otherwise */\r\n if (includeNewsFeed) {\r\n return root.innerHTML;\r\n }\r\n\r\n const rivers = document.getElementsByClassName(riverRcClassName);\r\n\r\n if (!rivers || !rivers.length) {\r\n return root.innerHTML;\r\n }\r\n\r\n const river = rivers[0] as HTMLElement;\r\n\r\n return root.innerHTML.replace(river.outerHTML, \"\");\r\n}\r\n\r\n/**\r\n * Gets the state object from render cache.\r\n * @returns The redux state object.\r\n */\r\nexport function getStateFromRenderCache(): any {\r\n // Check to see if this app instance was bootstrapped with a render-cache\r\n const renderCache = getRenderCache();\r\n\r\n if (!renderCache || !renderCache.state) {\r\n return null; // Render Cache missing or it does not include State.\r\n }\r\n\r\n let initialState;\r\n\r\n try {\r\n initialState = JSON.parse(renderCache.state, reduxStoreStringifyReviver);\r\n } catch (error) {\r\n // Cache state object is not parsable.\r\n }\r\n\r\n return initialState;\r\n}\r\n\r\n/**\r\n * Redux Store Stringify replacer HOF, generates store stringify.\r\n * @param storeExceptions list of store namespaces which will not be included in result.\r\n */\r\nexport function reduxStoreStringifyReplacer(key: string, value: any): any {\r\n const originalObject = this[key];\r\n if (originalObject instanceof Map) {\r\n return {\r\n dataType: \"Map\",\r\n value: [...originalObject]\r\n };\r\n } else {\r\n return value;\r\n }\r\n}\r\n\r\n/**\r\n * Function to normalize current URL\r\n * Example:\r\n * For normalizeKeyParamsList = [\"startpage\", \"prerender\"]\r\n * https://ntp.msn.com/edge/ntp?locale=en-us&startpage=1 is normalized to https://ntp.msn.com/edge/ntp?locale=en-us\r\n * https://ntp.msn.com/edge/ntp?startpage=1&locale=en-us is normalized to https://ntp.msn.com/edge/ntp?locale=en-us\r\n * https://ntp.msn.com/edge/ntp?locale=en-us&startpage=1&prerender=1 is normalized to https://ntp.msn.com/edge/ntp?locale=en-us\r\n * @returns normalized location href\r\n */\r\nexport function getNormalizedLocationHref(configParamsList?: [string]) {\r\n\r\n // get the url\r\n const normalizeKeyParamsList = configParamsList || getNormalizeKeyParamsList();\r\n\r\n if (!normalizeKeyParamsList || !normalizeKeyParamsList.length) {\r\n return locationHref;\r\n }\r\n\r\n const searchParams: URLSearchParams = new URLSearchParams(location.search);\r\n if (!searchParams) {\r\n return locationHref;\r\n }\r\n\r\n const normalizedParams: KeyValueArray = [];\r\n searchParams.forEach((value, key) => {\r\n if (!normalizeKeyParamsList.includes(key)) {\r\n normalizedParams.push({ key, value });\r\n }\r\n });\r\n\r\n // Filter for valid keyValue entries, and then map them into key==value strings\r\n // joined with an &\r\n const queryString = normalizedParams.map(kv => kv.key + \"=\" + kv.value).join(\"&\");\r\n const basePath = (locationHref || \"\").split(\"?\")[0];\r\n return basePath + (queryString ? \"?\" + queryString : \"\");\r\n}\r\n\r\n/**\r\n * set normalized param list to localStorage\r\n */\r\nexport function setNormalizeKeyParamsList(normalizeKeyParamsList: Array): void {\r\n if (normalizeKeyParamsList) {\r\n window.localStorage.setItem(normalizedUrlConfigkey, normalizeKeyParamsList.toString());\r\n }\r\n}\r\n\r\n/**\r\n * The key for storing all render cache normalized keys\r\n * Maintain a single entry for collection of all render cache keys\r\n * Example: for https://ntp.msn.com/edge/ntp?locale=en-us URL,\r\n * we have one key with all the following render cache keys values\r\n *\r\n * key: keys_https://ntp.msn.com/edge/ntp?locale=en-us&startpage=1\r\n * value: {\r\n * keyn: \"lastKnown_https://ntp.msn.com/edge/ntp?locale=en-us\", // render cache key\r\n * expn: \"timestamp_https://ntp.msn.com/edge/ntp?locale=en-us\", // expiration key\r\n * frcn: \"force_timestamp_https://ntp.msn.com/edge/ntp?locale=en-us\", // force timestamp key\r\n * jssn: \"lastKnown_https://ntp.msn.com/edge/ntp?locale=en-us_jssMap\" // jss map key\r\n * }\r\n */\r\nexport const renderCacheKeyOfNormalizedKeys = `${keysPrefix}${(typeof (window) !== \"undefined\" ? getNormalizedLocationHref() : \"\")}`;\r\n\r\n/**\r\n * Custom JSON.stringify reviver that will create Map objects from a string/JSON representation\r\n * @param key not used\r\n * @param value The value being converted from a string\r\n */\r\nfunction reduxStoreStringifyReviver(key: any, value: any): any {\r\n // If the value being restored is a object, check it it was a map\r\n if (typeof value === \"object\" && value !== null) {\r\n // If the object value being restored was a map, that was custom written, then revive it by creating a map\r\n if (value.dataType === \"Map\") {\r\n return new Map(value.value);\r\n }\r\n }\r\n\r\n // Return the original value being restored\r\n return value;\r\n}\r\n\r\n/**\r\n * get normalized param list from localStorage\r\n */\r\nfunction getNormalizeKeyParamsList(): Array {\r\n if (!canUseDOM()) {\r\n return null;\r\n }\r\n\r\n const normalizeUrlQsp = window.localStorage.getItem(normalizedUrlConfigkey);\r\n return normalizeUrlQsp ? normalizeUrlQsp.split(\",\") : null;\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { toNumber as _toNumber, isString } from \"lodash-es\";\r\n\r\nexport type KeyValuePair = { key: K, value: V };\r\nexport type KeyValueArray = KeyValuePair[];\r\n\r\nexport namespace Utility {\r\n /**\r\n * Check if given value is not null. Returns true when not null, otherwise false.\r\n *\r\n * @export\r\n * @param {any} value - Value to check for not null\r\n * @return {boolean}\r\n */\r\n export function isNotNullOrUndefined(value: any): boolean {\r\n return typeof value !== \"undefined\" && value !== null;\r\n }\r\n\r\n export interface IHashable {\r\n /**\r\n * This function will return the string representation of the complex object\r\n * @type {function}\r\n */\r\n toString(): string;\r\n }\r\n\r\n /**\r\n * Check if given value is defined. Returns true when defined, otherwise false.\r\n *\r\n * @export\r\n * @param {any} value - Value to check for defined\r\n * @return {boolean}\r\n */\r\n export function isDefined(value: any): boolean {\r\n return (typeof value !== \"undefined\");\r\n }\r\n\r\n /**\r\n * Check if a given value is a valid key value pair\r\n *\r\n * @export\r\n * @param potentialKeyValuePair\r\n * @return {boolean}\r\n */\r\n export function isKeyValuePair(potentialKeyValuePair: { key: K, value: V },\r\n isKey: (key: K) => boolean,\r\n isValue: (value: V) => boolean): boolean {\r\n return Utility.isNonNullObject(potentialKeyValuePair)\r\n && isKey(potentialKeyValuePair.key)\r\n && isValue(potentialKeyValuePair.value);\r\n }\r\n\r\n /**\r\n * Check if given value is a non null object. Returns true when value is non null , otherwise false.\r\n *\r\n * @export\r\n * @param {any} value - Value to check for non null\r\n * @return {boolean}\r\n */\r\n export function isNonNullObject(value: any): boolean {\r\n return value && typeof value === \"object\";\r\n }\r\n\r\n /**\r\n * Check if given value is not null. Returns true when not null, otherwise false.\r\n *\r\n * @export\r\n * @param {any} value - Value to check for not null\r\n * @return {boolean}\r\n */\r\n export function isNotNull(value: any): boolean {\r\n return value !== null;\r\n }\r\n\r\n /**\r\n * Check if given value is a a non-null or non-empty string. Returns true when it is, otherwise false.\r\n *\r\n * @export\r\n * @param {string} value - Value to check for string\r\n * @return {boolean}\r\n */\r\n export function isNullOrWhiteSpace(value: string): boolean {\r\n return !isString(value) || value.trim() === \"\";\r\n }\r\n\r\n /**\r\n * Converts string to number\r\n *\r\n * @export\r\n * @param {string} value - string to convert to a number\r\n * @param {number} defaultValue - number to return if there is an error\r\n * @return {number}\r\n */\r\n export function toNumber(value: string, defaultValue = -1): number {\r\n if (!value) {\r\n return defaultValue;\r\n }\r\n\r\n const result = _toNumber(value);\r\n if (!isNaN(result)) {\r\n return result;\r\n } else {\r\n return defaultValue;\r\n }\r\n }\r\n\r\n /**\r\n * Check if given value is an array with content in it.\r\n * Returns true when value is an array with content, otherwise false.\r\n *\r\n * @export\r\n * @param {any[]} value - Value to check for array with content\r\n * @return {boolean}\r\n */\r\n export function arrayHasData(value: any[]): boolean {\r\n if (isNotNullOrUndefined(value)) {\r\n return ((value.constructor === Array) && (value.length > 0));\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Check if given value is a string with content in it.\r\n * Returns true when value is a string with content, otherwise false.\r\n *\r\n * @export\r\n * @param {string} value - Value to check for string with content\r\n * @return {boolean}\r\n */\r\n export function stringHasData(value: string): boolean {\r\n return (isString(value) && (value.trim().length > 0));\r\n }\r\n\r\n /**\r\n * Convert object to string representation for it's values.\r\n * @param {object} object - The object to convert\r\n * @returns {string}\r\n */\r\n export function objectToString(object: object): string {\r\n let value = \"\";\r\n let firstRun = true;\r\n\r\n if (typeof object !== \"object\") {\r\n return value;\r\n }\r\n\r\n for (const attribute in object) {\r\n if (typeof object[attribute] === \"object\") {\r\n value += firstRun ? `${objectToString(object[attribute])}` : `-${objectToString(object[attribute])}`;\r\n } else {\r\n value += firstRun ? `${object[attribute]}` : `-${object[attribute]}`;\r\n }\r\n\r\n firstRun = false;\r\n }\r\n\r\n return value;\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { LiteLogger } from \"./LiteLogger\";\r\nimport { ILoggingService } from \"clientcore-infrastructure-analytics/ILoggingService\";\r\n\r\n/**\r\n * Interface for logger so different implementation of logger could be used.\r\n */\r\nexport interface Logger {\r\n\r\n /**\r\n * Returns the logging service\r\n * @returns {ILoggingService}\r\n */\r\n getLoggingService(): ILoggingService;\r\n\r\n /**\r\n * Checks whether we're running in debug mode.\r\n * @returns True when either debug=1 or debug=true is present as a query param, otherwise false.\r\n */\r\n isDebug(): boolean;\r\n\r\n /**\r\n * Override the isDebug setting. Useful when server side rendering.\r\n */\r\n setDebug(isDebug: boolean): void;\r\n\r\n /**\r\n * Set the tags to filter logs.\r\n * @param tags Tags to filter logs. If empty, do not filter.\r\n */\r\n setTags(tags: string[]): void;\r\n\r\n /**\r\n * Log console message.\r\n * Note that these are not output to the console unless you're in debug mode.\r\n * @param message - Message to log.\r\n * @param tags - Optional tags for specifying log type for filtering logs.\r\n */\r\n log(message: string, tags?: string[]): void;\r\n\r\n /**\r\n * Log error message.\r\n * @param message - Message to log\r\n */\r\n logError(message: string): void;\r\n\r\n /**\r\n * Lazy log console message. Use this when the message being constructed is complex or expensive so that it's only evaluated if needed.\r\n * Note that the callback is not invoked and the message is not output unless you're in debug mode.\r\n * @param getMessage - The function to call to get message to log\r\n */\r\n logCallback(getMessage: () => string): void;\r\n\r\n /**\r\n * Log the object to the console.\r\n * Note that these are not output to the console unless you're in debug mode.\r\n * @param message - Array of messages to log\r\n */\r\n logObjects(...message: any[]): void;\r\n}\r\n\r\n/**\r\n * Set the logger instance.\r\n * @param _logger The logger instance to change to.\r\n */\r\nexport function setLogger(_logger: Logger): void {\r\n logger = _logger;\r\n}\r\n\r\n/** Logger used by everyone. Default is LiteLogger. Please set up desired logger implementaiton with setLogger(). */\r\nexport let logger: Logger = new LiteLogger();","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { AadData, AccessTokenStatus, AccountInfo, getAppEnvironment } from \"@msnews/core\";\r\nimport { AcquireAccessTokenFailed, EdgeChromiumAPIsNotAvailable } from \"@msnews/diagnostics\";\r\n\r\nimport { ConnectorNamespaces } from \"@msnews/experiences-constants\";\r\nimport { ExperiencesSharedStateConnector } from \"@msnews/experiences-shared-state\";\r\nimport { PageBase } from \"@msnews/experiences-redux\";\r\nimport { Telemetry } from \"@msnews/telemetry-contracts\";\r\nimport { getPageTimings } from \"@msnews/diagnostics\";\r\n\r\n/**\r\n * chrome\r\n * The chrome API is not defined in Typescript\r\n */\r\ndeclare global {\r\n interface Window { chrome: any; }\r\n}\r\n\r\n/** The aadToken QS key */\r\nexport const aadTokenQsKey = \"stn\";\r\n\r\n/** The aadToken QS value */\r\nexport const aadTokenQsVal = \"aad\";\r\n\r\n// More information re: specific errors here:\r\n// https://microsoft.visualstudio.com/Edge/_git/chromium.src?path=%2Ftools%2Fmetrics%2Fhistograms%2Fedge_enums.xml&version=GBmaster&line=3770&lineEnd=3770&lineStartColumn=1&lineEndColumn=52&lineStyle=plain\r\nexport enum TokenFetchSecondaryErrors {\r\n /** Token fetch operation requires user interaction */\r\n \"kTokenFetchUserInteractionRequired\" = 13,\r\n /** Authentication is possible, but it requires direct user interaction */\r\n \"kInteractionRequired\" = 24\r\n}\r\n\r\n/**\r\n * Gets a value to indicate if we are in an enterprise scenario\r\n * eg. whether we should append the AAD Token as part of the call to oneservice endpoints\r\n * The default value is false, so we don't need to wait until the value is explicitly set\r\n */\r\nexport function useEnterpriseCompliance(): boolean {\r\n // Obtain the current value of useEnterpriseCompliance from the ExperiencesSharedState connector\r\n const sharedStateConnector: ExperiencesSharedStateConnector = PageBase.getInstance().rootReducer.connector(ConnectorNamespaces.SharedState) as ExperiencesSharedStateConnector;\r\n return sharedStateConnector ? sharedStateConnector.getCurrentState().useEnterpriseCompliance : false;\r\n}\r\n\r\n/**\r\n * Gets a value to indicate if we should use enterprise domain\r\n * eg. whether we should use the Falcon domain vs. consumer domain for oneservice requests\r\n * The default value is false, so we don't need to wait until the value is explicitly set\r\n */\r\nexport function useEnterpriseDomain(): boolean {\r\n // Obtain the current value of useEnterpriseDomain from the ExperiencesSharedState connector\r\n const sharedStateConnector: ExperiencesSharedStateConnector = PageBase.getInstance().rootReducer.connector(ConnectorNamespaces.SharedState) as ExperiencesSharedStateConnector;\r\n return sharedStateConnector ? sharedStateConnector.getCurrentState().useEnterpriseDomain : false;\r\n}\r\n\r\n/**\r\n * Checks if aad token is invalid for user\r\n */\r\nexport function isInvalidAadToken(aadData: AadData): boolean {\r\n return !aadData || !aadData.isSuccess || !aadData.isValid;\r\n}\r\n\r\n/**\r\n * Fetches aad data to be used to call an authenticated API.\r\n * @param clientId The client id of the AAD application requesting access\r\n * @param scopeOrResource The scope or resource to request access for\r\n * @param friendlyName Friendly name for scope\r\n * @param allowInteraction Attempt to fetch the access token using the allowInteraction version of the API instead of the silent version\r\n */\r\nexport async function getAadData(clientId: string, scopeOrResource: string, friendlyName: string, allowInteraction = false): Promise {\r\n const accountInfo = await resolveAccountInfo();\r\n\r\n if (!accountInfo) {\r\n Telemetry.sendAppErrorEvent({\r\n ...EdgeChromiumAPIsNotAvailable,\r\n message: \"Auth api not available\",\r\n pb: {\r\n ...EdgeChromiumAPIsNotAvailable.pb,\r\n customMessage: `Auth api not available for ${scopeOrResource}`\r\n }\r\n });\r\n\r\n return null;\r\n }\r\n\r\n return new Promise((resolve) => {\r\n const tokenAcquireParameters = {\r\n account_id: accountInfo.account_id,\r\n account_type: accountInfo.account_type,\r\n client_id: clientId,\r\n scope_or_resource: scopeOrResource\r\n };\r\n\r\n const totalMarkerName = `Auth.AcquireAccessToken.${friendlyName}`;\r\n const startMarkerName = `${totalMarkerName}.Start`;\r\n const endMarkerName = `${totalMarkerName}.End`;\r\n const pageTimings = getPageTimings();\r\n const startPerfMarker = pageTimings[startMarkerName];\r\n const endPerfMarker = pageTimings[endMarkerName];\r\n const totalPerfMarker = pageTimings[totalMarkerName];\r\n const startTime = Math.round(performance.now());\r\n if (!startPerfMarker && !allowInteraction) {\r\n pageTimings[startMarkerName] = startTime;\r\n }\r\n\r\n const tokenAccessApi = allowInteraction ? window.chrome.authPrivate.acquireAccessTokenWithUserInteraction : window.chrome.authPrivate.acquireAccessTokenSilently;\r\n\r\n tokenAccessApi(tokenAcquireParameters, (acquireResult) => {\r\n if (!endPerfMarker && !allowInteraction) {\r\n const endTime = Math.round(performance.now());\r\n pageTimings[endMarkerName] = acquireResult.is_success ? endTime : -1;\r\n if (!totalPerfMarker) {\r\n pageTimings[totalMarkerName] = acquireResult.is_success ? endTime - startTime : -1;\r\n }\r\n }\r\n\r\n let status = AccessTokenStatus.success;\r\n if (!acquireResult.is_success) {\r\n const authErrorObject = {\r\n ...acquireResult.error_info,\r\n authPrivateApi: allowInteraction ? \"acquireAccessTokenWithUserInteraction\" : \"acquireAccessTokenSilently\",\r\n accountId: tokenAcquireParameters.account_id,\r\n accountType: tokenAcquireParameters.account_type,\r\n clientId: tokenAcquireParameters.client_id,\r\n resource: scopeOrResource,\r\n tenantId: accountInfo.tenant_id\r\n };\r\n\r\n Telemetry.sendAppErrorEvent({\r\n ...AcquireAccessTokenFailed,\r\n message: \"Failed to get access token\",\r\n pb: {\r\n ...AcquireAccessTokenFailed.pb,\r\n customMessage: JSON.stringify(authErrorObject)\r\n }\r\n });\r\n\r\n status = acquireResult.error_info.secondary_error === TokenFetchSecondaryErrors.kTokenFetchUserInteractionRequired ||\r\n acquireResult.error_info.secondary_error === TokenFetchSecondaryErrors.kInteractionRequired ?\r\n AccessTokenStatus.mfaRequired : AccessTokenStatus.otherError;\r\n }\r\n\r\n resolve({\r\n token: acquireResult.access_token,\r\n errorInfo: acquireResult.error_info,\r\n isSuccess: acquireResult.is_success,\r\n isValid: acquireResult.is_token_valid,\r\n status\r\n });\r\n });\r\n });\r\n}\r\n\r\n/**\r\n * Resolve account info promise\r\n */\r\nexport async function resolveAccountInfo(): Promise {\r\n const appEnvironment = getAppEnvironment();\r\n\r\n if (!appEnvironment.AccountInfoPromise) {\r\n return null;\r\n }\r\n\r\n return await appEnvironment.AccountInfoPromise;\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { assign, get, merge, set } from \"lodash-es\";\r\n\r\nimport { ConnectorConstants } from \"../constants/ConnectorConstants\";\r\nimport { ConnectorNamespaces } from \"@msnews/experiences-constants\";\r\nimport { IActionPayload } from \"./IActionPayload\";\r\nimport { IDataConnector } from \"../connectors/IDataConnector\";\r\nimport { IReducer } from \"./IReducer\";\r\nimport { dataConnectorInjector } from \"./DataConnectorInjector\";\r\nimport { isNullOrUndefined } from \"util\";\r\n\r\n/** Resolve & Reject Function Signature */\r\ntype ResolveConnectorSignature = (connector: IDataConnector) => void;\r\ntype RejectConnectorSignature = (error: Error) => void;\r\n\r\n/**\r\n * Pending getDataConnector Promise\r\n */\r\ninterface PendingConnectorPromise {\r\n /** Promise */\r\n promise: Promise>;\r\n /** callback to resolve the promise */\r\n resolve: ResolveConnectorSignature;\r\n /** callback to reject the promise */\r\n reject: RejectConnectorSignature;\r\n}\r\n\r\n/** Result from running a reducer. */\r\ninterface ReducerResult {\r\n /** The new state calculated by the reducer */\r\n newState: any;\r\n\r\n /** True if the state changed. */\r\n stateChanged: boolean;\r\n}\r\n\r\n/**\r\n * A reducer that can dynamically add and remove individual sub-reducers\r\n * @class\r\n */\r\nexport class DynamicReducer {\r\n\r\n /**\r\n * A map of connectors, which maintain the sub-spaced state. Reducers and connectors are keyed by namespace\r\n */\r\n private readonly _connectorMap: {[key: string]: IDataConnector} = {};\r\n\r\n /**\r\n * The list of global connectors. Used for fast lookup instead of iterating through _connectorMap keys and toArray methods.\r\n */\r\n private readonly _globalConnectors: IDataConnector[] = [];\r\n\r\n /**\r\n * The list of all connectors. Used for fast lookup instead of iterating through _connectorMap keys and toArray methods.\r\n */\r\n private readonly _allConnectors: IDataConnector[] = [];\r\n\r\n /**\r\n * The list of all pending promises for the get data connector call. Used to resolve the promise when data connector is instantiated.\r\n */\r\n private readonly _getDataConnectorPendingPromises: Map = new Map();\r\n\r\n /**\r\n * Creates an instance of the `DynamicReducer` class.\r\n * @constructor\r\n * @param {string} type The action type.\r\n */\r\n constructor() {\r\n // bind the reduce method to this instance\r\n this.reduce = this.reduce.bind(this);\r\n }\r\n\r\n /**\r\n * Returns an array of connectors that have their reducers registered with this instance\r\n * @method\r\n * @returns {IDataConnector} A simple arry of all connectors\r\n */\r\n public connectors(): IDataConnector[] {\r\n return this._allConnectors;\r\n }\r\n\r\n /**\r\n * Returns an array of connectors that have their reducers registered with this instance\r\n * @method\r\n * @param {string} namespace The namespace of the connector to return, if it is in the map\r\n * @returns {IDataConnector | undefined} A simple arry of all connectors\r\n */\r\n public connector(namespace: string): IDataConnector | undefined {\r\n return (this._connectorMap[namespace]);\r\n }\r\n\r\n /**\r\n * Returns an array of connectors that have state that is global\r\n * @method\r\n * @returns {IDataConnector} A simple arry of connectors that have global state\r\n */\r\n public globalConnectors(): IDataConnector[] {\r\n return this._globalConnectors;\r\n }\r\n\r\n /**\r\n * Returns a promise which resolves immediately if the data connector is already present on the page,\r\n * otherwise resolves when the data connector is instantiated on the Page later in the lifecycle.\r\n * @method\r\n * @param namespace The namespace of data connector to return\r\n */\r\n public getDataConnector(namespace: ConnectorNamespaces): Promise> {\r\n // Check for data connector, if it is already present resolve immediately\r\n const dataConnector = this.connector(namespace);\r\n if (dataConnector) {\r\n return Promise.resolve(dataConnector);\r\n }\r\n\r\n // Check if we have an entry for the namespace in pending promise map, if present return the same promise\r\n const pendingPromise = this._getDataConnectorPendingPromises.get(namespace);\r\n if (pendingPromise) {\r\n return pendingPromise.promise;\r\n }\r\n\r\n // If the data connector is not on the page and has no entry in the pending promise map, create a new promise\r\n let resolveCallback: ResolveConnectorSignature;\r\n let rejectCallback: RejectConnectorSignature;\r\n const promise = new Promise>((resolve, reject) => {\r\n // Get the reference to the resolve & reject which can be called later when the data connector is instantiated on the Page\r\n resolveCallback = resolve;\r\n rejectCallback = reject;\r\n });\r\n\r\n // Add the promise to the pending promise map\r\n this._getDataConnectorPendingPromises.set(namespace, { promise: promise, resolve: resolveCallback, reject: rejectCallback });\r\n\r\n // Return the promise\r\n return promise;\r\n }\r\n\r\n /**\r\n * Produces the next state based on the given action. The state to be reduced is an aggregate of the reducers for all of the connectors\r\n * that have been added.\r\n * The overall state looks something like:\r\n * This will be the state for the redux-subspace for the connector. It is of the form:\r\n * {\r\n * FOO: {\r\n * _@STATE@_: {\r\n * \r\n * },\r\n * BAR: {\r\n * _@STATE@_: {\r\n * \r\n * },\r\n * },\r\n * }\r\n * }\r\n * @function\r\n * @param state {any} The previous state of the application. The application state, will contain one or more sub-states, which will be individually reduced\r\n * @param actionPayload {IActionPayload} The action detail to update the state with.\r\n * @returns {any} The next state for the application, containing the next state for each connector (a.k.a subspace)\r\n */\r\n public reduce(state: any, actionPayload: IActionPayload): any {\r\n // If the initial state is undefined, then create an empty object to start with\r\n if (isNullOrUndefined(state)) {\r\n state = {};\r\n }\r\n\r\n let newState = { ...state };\r\n let stateChanged = false;\r\n\r\n // See if we need to reduce for a specific connector. This is the common case.\r\n if (actionPayload !== undefined && actionPayload.key !== undefined) {\r\n // If this is a special action, used to force a re-render, then we need to set stateChanged to true, and create a clone of the existing scoped state\r\n const typeIsString: boolean = typeof actionPayload.type === \"string\";\r\n if (typeIsString && actionPayload.type.endsWith(ConnectorConstants.renderAction)) {\r\n const statePropertyKey = actionPayload.key + \".\" + ConnectorConstants.connectorStateKey;\r\n const connectorState = assign({}, get(state, statePropertyKey, undefined));\r\n set(newState, statePropertyKey, connectorState);\r\n stateChanged = true;\r\n } else if (typeIsString && actionPayload.type.endsWith(ConnectorConstants.dataConnectorMergeInitAction)) {\r\n const experienceFullNamespace: string = actionPayload.key;\r\n const dataConnectorName: ConnectorNamespaces = actionPayload.params[0];\r\n\r\n if (dataConnectorName) {\r\n dataConnectorInjector.initializeExperience(newState, experienceFullNamespace, dataConnectorName);\r\n stateChanged = true;\r\n }\r\n } else {\r\n // If the connector doing the reducing is global, then create a deep copy of state, so that all the connected\r\n // components think the state is new, and run their mappers. Connected components are subscribed to, and only see\r\n // changed in their subspace portion of the state tree. The redux connect implementation uses strict equal comparison,\r\n // meaning it consider the state change if it is a new object reference, even if all the properties are still the same\r\n if (this._connectorMap[actionPayload.key].isGlobal) {\r\n newState = merge({}, newState);\r\n }\r\n\r\n const connectorReducerResult = this.computeNextStateForConnector(newState, actionPayload.key, actionPayload);\r\n stateChanged = connectorReducerResult.stateChanged;\r\n\r\n if (stateChanged) {\r\n // Check to see if any experiences are including this data connector state. If so, update those too.\r\n dataConnectorInjector.reportStateChange(newState, actionPayload.key, connectorReducerResult.newState);\r\n }\r\n }\r\n } else {\r\n // Iterate over the full list of connectors calling each reducer. This is not the common case, and is typically done\r\n // for actions that come from Redux, during initialization\r\n Object.keys(this._connectorMap).forEach(key => {\r\n if (this.computeNextStateForConnector(newState, key, actionPayload).stateChanged) {\r\n stateChanged = true;\r\n }\r\n });\r\n }\r\n\r\n // Return the newState, as modified by the reducer(s) if it was changed, otherwise return the original state\r\n if (stateChanged) {\r\n return newState;\r\n } else {\r\n return state;\r\n }\r\n }\r\n\r\n /**\r\n * Adds a sub reducer for a connector to the sub-reducer collection.\r\n * @method\r\n * @param {IDataConnector} connector The connector to add.\r\n */\r\n public addSubReducerForConnector(connector: IDataConnector): void {\r\n if (!connector) {\r\n throw new Error(\"The parameter 'connector' cannot be null.\");\r\n }\r\n\r\n // Add the sub-reducer and connector into their maps, based on the connector's namespace\r\n const key = connector.fullNamespace;\r\n this._connectorMap[key] = connector;\r\n\r\n // update the all and global connector fast lookup lists\r\n this._allConnectors.push(connector);\r\n\r\n if (connector.isGlobal) {\r\n this._globalConnectors.push(connector);\r\n }\r\n\r\n // Check if there is a pending promise for the data connector\r\n // DO NOT CHANGE namespace to fullnamespace, data connectors are supposed to be queried using just the namespace by design.\r\n if (this._getDataConnectorPendingPromises.has(connector.namespace)) {\r\n // Get the resolve callback for the pending promise and resolve it\r\n const pendingPromise = this._getDataConnectorPendingPromises.get(connector.namespace);\r\n\r\n try {\r\n pendingPromise.resolve(connector);\r\n } catch (error) {\r\n pendingPromise.reject(error);\r\n }\r\n\r\n // Delete the entry from the pending promise map\r\n this._getDataConnectorPendingPromises.delete(connector.namespace);\r\n }\r\n\r\n connector.store.dispatch({ key: key, type: \"@@connector-view/INIT\" });\r\n }\r\n\r\n /**\r\n * Helper method to compute the next state for a given connector. This method will get the connector's actual state\r\n * from the state tree, call the reducer, and then state the state in the passed in object that is to receive the new state\r\n * @param {any} state The current subspace (or root) state object, which will be updated\r\n * @param {string} key The key to the connector in the connector map\r\n * @param {IActionPayload} actionPayload The action to apply\r\n * @returns Information on how the connector state was changed\r\n */\r\n private computeNextStateForConnector(state: any, key: string, actionPayload: IActionPayload): ReducerResult {\r\n // Get the connector, so that we can call the reducer\r\n const connector = this._connectorMap[key];\r\n\r\n // Setup the key and get the actual state property for the connector. lodash uses dotted notation\r\n // so the key will be something like: namespace._@STATE@_\r\n const statePropertyKey = key + \".\" + ConnectorConstants.connectorStateKey;\r\n const connectorPreviousState = get(state, statePropertyKey, undefined);\r\n\r\n // Call the reducer for the connector, and validate that we received a state object back.\r\n const nextStateForConnector = this.subReduce(connector.reducer, connectorPreviousState, actionPayload);\r\n if (typeof nextStateForConnector === \"undefined\") {\r\n throw new Error(\"Reducer for: \" + key + \" must not return undefined.\");\r\n }\r\n\r\n // If the state changed, then set the new connector state in the overall state object\r\n const connectorStateChanged: boolean = nextStateForConnector !== connectorPreviousState;\r\n if (connectorStateChanged) {\r\n set(state, statePropertyKey, nextStateForConnector);\r\n }\r\n\r\n return { newState: nextStateForConnector, stateChanged: connectorStateChanged };\r\n }\r\n\r\n /**\r\n * Calls the reducer that has been registered to handle the state associated with a specific subspace\r\n * @param {Reducer} reducer The reducer to call\r\n * @param {TSubReducerState} state The state object for the subreducer\r\n * @param {IActionPayload} actionPayload The action to apply\r\n */\r\n private subReduce(reducer: IReducer, previousState: TSubReducerState, actionPayload: IActionPayload): TSubReducerState {\r\n const reducedState: TSubReducerState = reducer.reduce(previousState, actionPayload);\r\n if (reducedState !== previousState) {\r\n return reducedState;\r\n } else {\r\n return previousState;\r\n }\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { captureJssGeneratedClasses } from \"@msnews/render-cache\";\r\nimport { registerResetCallback } from \"@msnews/core\";\r\n\r\n/**\r\n * Weak map which is used to store DesignSystem to GenerateClassName Callback.\r\n */\r\nlet designSystemMap = new WeakMap();\r\n\r\n/**\r\n * Map which will store number of DesignSystem appearances with same name.\r\n */\r\nlet designSystemIndexMap = new Map();\r\n\r\n/**\r\n * Register a callback to reset the designSystem globals.\r\n * The callback is registered once when the module is loaded and invoked once on the server side at the beginning of each request.\r\n */\r\nregisterResetCallback(() => {\r\n designSystemMap = new WeakMap();\r\n designSystemIndexMap = new Map();\r\n});\r\n\r\n/**\r\n * JSS callback function that defines the class name generation logic\r\n * The default jss manager class name generation logic increments counter based on order\r\n * of how the experiences are rendered. We cannot guarantee the order due to async nature\r\n * of experiences which potentially causes different class names on every reload/refresh.\r\n * Instead here with this callback, we start the counter from 1 per rule to ensure class\r\n * names stays consistent irrespective of when they are rendered.\r\n *\r\n * Design system is taken into account since a change in it can result in potential different\r\n * styling being needed even if that rule was already used in a previous design system.\r\n *\r\n * For example:\r\n * For TopSites, with this override the class name would be generated as \"topSites-DS-default1-1\"\r\n * (jss manager by default would have generated it something like \"topSites-0-1-305\")\r\n * If the design system were to be updated and the same rule would be passed then you would\r\n * get topsites-DS-default2-1.\r\n */\r\nexport function createGenerateClassName(designSystem: any): (rule: any, sheet: any) => string {\r\n if (!designSystem) {\r\n return;\r\n }\r\n\r\n let callback = designSystemMap.get(designSystem);\r\n\r\n if (!callback) {\r\n const dsName = designSystem.name || \"unknown\";\r\n const dsIndex = designSystemIndexMap.get(dsName) + 1 || 1;\r\n const rulesMap: any = {};\r\n callback = (rule: any, sheet: any) => {\r\n const key = rule.key;\r\n\r\n if (!rulesMap[key]) {\r\n rulesMap[key] = 1;\r\n } else {\r\n rulesMap[key]++;\r\n }\r\n\r\n const name = `DS-${dsName}${dsIndex}-${rulesMap[key]}`;\r\n captureJssGeneratedClasses(key, name);\r\n\r\n return `${key}-${name}`;\r\n };\r\n\r\n designSystemMap.set(designSystem, callback);\r\n designSystemIndexMap.set(dsName, dsIndex);\r\n }\r\n\r\n return callback;\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { Provider, connect } from \"react-redux\";\r\nimport { Store, StoreEnhancer, compose, createStore } from \"redux\";\r\nimport { getPageTimings, logger, perfMarker } from \"@msnews/diagnostics\";\r\n\r\nimport { DynamicReducer } from \"../reducers\";\r\nimport { IDataConnector } from \"../connectors/IDataConnector\";\r\nimport { JSSManager } from \"@microsoft/fast-jss-manager-react\";\r\nimport React from \"react\";\r\nimport ReactDom from \"react-dom\";\r\nimport { applyMiddleware } from \"redux-subspace\";\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\nimport { create } from \"jss\";\r\nimport { createGenerateClassName } from \"./PageHelper\";\r\nimport { getStateFromRenderCache } from \"@msnews/render-cache\";\r\nimport jssGlobal from \"jss-global\";\r\nimport jssNested from \"jss-nested\";\r\n\r\ndeclare global {\r\n interface Window {\r\n /**\r\n * Boolean flag to indicate if this is an SSR page or not\r\n */\r\n SSR: boolean;\r\n\r\n /**\r\n * Enable redux devtools extension debugging\r\n */\r\n __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: any;\r\n\r\n /**\r\n * Boolean flag to indicate if render cache hydration is happening\r\n */\r\n needsHydrate?: boolean;\r\n\r\n /**\r\n * Boolean flag to indicate if state is stored in render cache along with DOM\r\n */\r\n hasPreHydrateState?: boolean;\r\n }\r\n}\r\n\r\n/**\r\n * Page Base.\r\n * Each page or hybrid page/experience must have an instance of the PageBase, which contains the the store, and dynamic reducer\r\n * for the experience/app.\r\n * PageBase is setup as a singleton, so the proper usage in consumers is:\r\n * var pageBase = PageBase.getInstance();\r\n * @export\r\n * @class\r\n */\r\nclass PageBase {\r\n /**\r\n * The singleton instance of this class\r\n * @type: {PageBase}\r\n */\r\n private static _instance: PageBase;\r\n\r\n /**\r\n * The Dynamic reducer for this app/experience\r\n * @type: {DynamicReducer}\r\n */\r\n private _rootReducer: DynamicReducer;\r\n\r\n /**\r\n * The Redux store containing the top level application state. All component and data connectors will manage namespaced subspaces within\r\n * this store\r\n * @type {Store}\r\n */\r\n private _store: Store;\r\n\r\n /**\r\n * Constructor for PageBase class\r\n * @constructor\r\n * @param {any} initialState Optional initial redux state provided as part of SSR response during hydration\r\n */\r\n private constructor(initialState?: any) {\r\n /**\r\n * In debug build, add the option to turn on redux-devtools-extension debugging.\r\n * More info here https://github.com/zalmoxisus/redux-devtools-extension\r\n */\r\n let enhancer: StoreEnhancer;\r\n const middlewares: any = [];\r\n if (canUseDOM() && ((typeof logger !== \"undefined\") && logger ? logger.isDebug() : false)) {\r\n const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ trace: true, traceLimit: 25 }) || compose;\r\n enhancer = composeEnhancers(applyMiddleware(...middlewares)\r\n );\r\n } else {\r\n enhancer = applyMiddleware(...middlewares);\r\n }\r\n\r\n // Create the root reducer\r\n this._rootReducer = new DynamicReducer();\r\n\r\n // Check to see if this app instance was bootstrapped with a render-cache\r\n initialState = initialState || (canUseDOM() && window.needsHydrate && getStateFromRenderCache()) || {};\r\n if (canUseDOM()) {\r\n window.hasPreHydrateState = !!(initialState && Object.keys(initialState).length !== 0);\r\n }\r\n\r\n // create the store with a basic root reducer\r\n this._store = createStore(this.rootReducer.reduce, initialState, enhancer);\r\n\r\n }\r\n\r\n /**\r\n * Reset PageBase. Useful when handling multiple requests when server side rendering.\r\n */\r\n public static resetPageBaseInstance(initialState?: any): void {\r\n this._instance = new PageBase(initialState);\r\n }\r\n\r\n /**\r\n * Gets the Redux store for this app/experience\r\n * @method\r\n * @returns {Store} The overall state for the App, which contains sub-states for each connector\r\n */\r\n public get store(): Store {\r\n return this._store;\r\n }\r\n\r\n /**\r\n * Gets the root reducer for this app/experience\r\n * @returns {DynamicReducer} The reducer for the app/experience\r\n */\r\n public get rootReducer(): DynamicReducer {\r\n return this._rootReducer;\r\n }\r\n\r\n /**\r\n * Gets the singleton instance of this class for the app/experience\r\n * @returns {PageBase} The instance of PageBase for the page/hybrid experience\r\n */\r\n public static getInstance(initialState?: any): PageBase {\r\n return this._instance || (this._instance = new this(initialState));\r\n }\r\n\r\n /**\r\n * Starts the application by calling the onApplicationStart method for each connector that has been added to the app.\r\n * @function\r\n * @method\r\n */\r\n public start(): void {\r\n // Iterate over all of the connector's and call their OnApplicationStart method\r\n const allConnectors: IDataConnector[] = this.rootReducer.connectors();\r\n allConnectors.forEach(connector => connector.onApplicationStart());\r\n }\r\n\r\n /**\r\n * Creates and renders a root element, that is connected to the store.\r\n * The root element will created with the passed in connected element as a child.\r\n * @function\r\n * @param {React.ReactElement} connectedTopLevelElement The top level rendering element for the page/application.\r\n * @param {HTMLElement} hostElement The host element (usually a
) to contain the msnews-experiences-redux application\r\n * @param {Function} callback An optional callback to be fired after hydration is complete, used when hydrating server side rendered content.\r\n * @param {boolean} [updateJss=true] To bypass JSSManager instance update set this to false\r\n * @method\r\n */\r\n public renderRootElement(connectedTopLevelElement: React.ReactElement, hostElement: HTMLElement, callback?: Function, updateJss = true): void {\r\n // Update the base JSS manager instance\r\n if (updateJss) {\r\n this.updateJssManagerInstance();\r\n }\r\n\r\n // Create a ReactElement, that contains the Redux provider with the store, passing the incoming top level element in as a child, so that\r\n // the pageElement wraps the top level element with the redux store\r\n const rootElement = React.createElement(Provider, { store: this._store }, connectedTopLevelElement);\r\n\r\n // Capture Render cache state in page timings\r\n const pageTimings = getPageTimings();\r\n\r\n if (window.needsHydrate) {\r\n ReactDom.hydrate(rootElement, hostElement);\r\n pageTimings[\"isRenderCachePresent\"] = 1;\r\n window.needsHydrate = false;\r\n } else if (window.SSR) {\r\n pageTimings[\"isRenderCachePresent\"] = 0;\r\n perfMarker.startMark(\"SSR.Hydrate\");\r\n ReactDom.hydrate(rootElement, hostElement, callback);\r\n } else {\r\n pageTimings[\"isRenderCachePresent\"] = 0;\r\n ReactDom.render(rootElement, hostElement);\r\n }\r\n }\r\n\r\n /**\r\n * Updates the base JSSManager instance with the correct default plugins\r\n */\r\n public updateJssManagerInstance(): void {\r\n const jssInstance: ReturnType = create({\r\n plugins: [jssNested(), jssGlobal()]\r\n });\r\n\r\n JSSManager.createGenerateClassName = createGenerateClassName;\r\n JSSManager.jss = jssInstance;\r\n }\r\n}\r\n\r\nexport default PageBase;","// © Microsoft Corporation. All rights reserved.\r\n\r\nexport const Size1ColumnWidth = 300;\r\nexport let Size2ColumnWidth = 624;\r\nexport let Size3ColumnWidth = 948;\r\nexport let Size4ColumnWidth = 1272;\r\nexport let Size5ColumnWidth = 1596;\r\nexport let GutterSize = 24;\r\n\r\n/** Updates the current ColumnWidths based on changes in gutterSize */\r\nexport function updateColumnWidths(gutterSize: number): void {\r\n GutterSize = gutterSize;\r\n Size5ColumnWidth = (Size1ColumnWidth * 5) + (gutterSize * 4);\r\n Size4ColumnWidth = (Size1ColumnWidth * 4) + (gutterSize * 3);\r\n Size3ColumnWidth = (Size1ColumnWidth * 3) + (gutterSize * 2);\r\n Size2ColumnWidth = (Size1ColumnWidth * 2) + gutterSize;\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ExperienceMilestoneEventTypes, MilestonePlugin } from \"./data-model\";\r\n\r\nimport { ActionMap } from \"@msnews/experiences-redux\";\r\nimport { ExperienceDeferralInfo } from \"./data-model/ExperienceDeferralInfo\";\r\nimport { ExperienceLoadingState } from \"./data-model/ExperienceLoadingState\";\r\nimport { PageRevealRegistrationInterface } from \"./data-model/PageRevealRegistrationInterface\";\r\n\r\n/**\r\n * Base arguments for all experience milestone updates\r\n */\r\nexport interface UpdateArgsBase {\r\n /** Experience Type - Defines an experience */\r\n experienceType: string;\r\n\r\n /** Associated Experience Group */\r\n experienceGroup?: string;\r\n\r\n /** Defines an instance of the Experience */\r\n experienceInstance?: string;\r\n}\r\n\r\nexport interface UpdateExperiencePublicStateArgs extends UpdateArgsBase {\r\n /** Current Milestone eventType of the experience e.g loaded, staleRevalidationComplete etc */\r\n eventType: ExperienceMilestoneEventTypes;\r\n}\r\n\r\nexport interface UpdateExperienceCurrentStateArgs extends UpdateArgsBase {\r\n /** Current Milestone of the experience e.g initialized, loaded, deferred etc */\r\n currentState: ExperienceLoadingState;\r\n}\r\n\r\nexport interface UpdateExperienceDeferralArgs extends UpdateArgsBase {\r\n /** Tracks deferral information used by an experience to determine when it should load/render */\r\n deferralInfo: ExperienceDeferralInfo;\r\n}\r\n\r\nexport interface UpdateTimingArgs extends UpdateArgsBase {\r\n /** start time fo the milestone e.g. startTime of loaded milestone */\r\n startTime?: number;\r\n\r\n /** end time fo the milestone e.g. endTime of loaded milestone */\r\n endTime?: number;\r\n}\r\n\r\nexport type UpdateExperienceCurrentStateSignature = (info: Array) => void;\r\n\r\nexport type UpdateExperiencePublicStateSignature = (args: UpdateExperiencePublicStateArgs) => void;\r\n\r\nexport type UpdateExperienceDeferralSignature = (info: Array) => void;\r\n\r\nexport type UpdateTimingSignature = (args: UpdateTimingArgs) => void;\r\n\r\nexport type UpdatePluginSignature = (\r\n /** Plugins to add additional behaviors in page lifecycle events */\r\n plugins: MilestonePlugin[]\r\n) => void;\r\n\r\nexport type UpdatePageTimingSignature = (time?: number) => void;\r\n\r\nexport type UpdatePageRevealStartSignature = (time?: number, wasHidden?: boolean) => void;\r\n\r\nexport type UpdateBelowTheFoldTransitionSignature = (start?: boolean) => void;\r\n\r\ntype RegisterExperienceForPageRevealSignature = (experiencePageRevealInfo: PageRevealRegistrationInterface) => void;\r\n\r\n/**\r\n * Actions for the Milestone Data Connector\r\n * @class\r\n */\r\nexport class MilestoneDataActionsImpl {\r\n\r\n /** Action to trigger above the fold timing updates */\r\n public updateAboveTheFoldVisuallyReady: ActionMap\r\n = new ActionMap(\"updateAboveTheFoldVisuallyReady\");\r\n\r\n /** Action to trigger below the fold transition updates */\r\n public updateBelowTheFoldTransitionStart: ActionMap\r\n = new ActionMap(\"updateBelowTheFoldTransitionStart\");\r\n\r\n /** Action to trigger when deferring an experience load */\r\n public updateExperienceLoadDeferralState: ActionMap\r\n = new ActionMap(\"updateExperienceLoadDeferralState\");\r\n\r\n /** Action to trigger when updating current state of experience in load/render life-cycle */\r\n public updateExperienceCurrentState: ActionMap\r\n = new ActionMap(\"updateExperienceCurrentState\");\r\n\r\n /** Action to trigger when updating current state of experience through publicly exposed MilestoneExperienceEventTypes */\r\n public updateExperiencePublicState: ActionMap\r\n = new ActionMap(\"updateExperiencePublicState\");\r\n\r\n /** Action to trigger when deferring an experience render */\r\n public updateExperienceRenderDeferralState: ActionMap\r\n = new ActionMap(\"updateExperienceRenderDeferralState\");\r\n\r\n /** Action to trigger when experience load initiates */\r\n public updateInitTiming: ActionMap\r\n = new ActionMap(\"UpdateInitTiming\");\r\n\r\n /** Action to trigger page complete timing updates */\r\n public updatePageComplete: ActionMap\r\n = new ActionMap(\"updatePageCompleteTiming\");\r\n\r\n /** Action to trigger page complete timing updates */\r\n public updatePageRevealStart: ActionMap\r\n = new ActionMap(\"updatePageRevealStart\");\r\n\r\n /** Action to trigger page complete timing updates */\r\n public updatePageRevealComplete: ActionMap\r\n = new ActionMap(\"updatePageRevealComplete\");\r\n\r\n /** Action to trigger when experience instance completed render */\r\n public updateRenderTiming: ActionMap\r\n = new ActionMap(\"UpdateRenderTiming\");\r\n\r\n /** Action to trigger when experience instance is visually ready */\r\n public updateVisuallyReadyTiming: ActionMap\r\n = new ActionMap(\"UpdateVisuallyReadyTiming\");\r\n\r\n /** Action to trigger when experience instance is DOM complete */\r\n public updateDomCompleteTiming: ActionMap\r\n = new ActionMap(\"UpdateDomCompleteTiming\");\r\n\r\n /** Action to trigger when adding/updating milestone plugin */\r\n public updateMilestonePlugins: ActionMap\r\n = new ActionMap(\"updateMilestonePlugin\");\r\n\r\n /** Action to register experiences for Page Reveal */\r\n public registerExperienceForPageReveal: ActionMap\r\n = new ActionMap(\"registerExperienceForPageReveal\");\r\n\r\n /** Reset the static instance. Useful when server side rendering. */\r\n public resetInstance(): void {\r\n MilestoneDataActions = new MilestoneDataActionsImpl();\r\n }\r\n}\r\n\r\n/** The singleton instance */\r\nexport let MilestoneDataActions = new MilestoneDataActionsImpl();","// © Microsoft Corporation. All rights reserved.\r\n\r\n/** Type info of a single page measure in the window._pageMeasures object */\r\nexport type PageMeasure = {\r\n\r\n /** Name of the timeline */\r\n timelineName: string;\r\n\r\n /** Name of the metric */\r\n measureName: string;\r\n\r\n /** Flag that indicates whether this measure is an async measure */\r\n async?: boolean;\r\n\r\n /** The start time of the measure */\r\n from: number;\r\n\r\n /** The end time of the measure */\r\n to: number;\r\n};\r\n\r\n/**\r\n * Interface for PerfTimeline constructor\r\n *\r\n * Reason for constructor interface is to\r\n * prevent PerfTimeline implementation and dependencies\r\n * from added to inline script bundle (eg. Edge Legacy service-ui)\r\n * when perftimeline is disabled.\r\n*/\r\ninterface PerfTimelineConstructor {\r\n /**\r\n * New method to construct a {PerfTimeline} instance\r\n * @param timelineName - the name of the perf timeline. Note that if you don't know the name\r\n * of a perf timeline at construction time, it can later be renamed to a known name later via\r\n * the 'rename' method.\r\n * @param instanceId - this specific instance's ID. Used during a renaming operation to idenfity any previous isntance.\r\n * @param addPerfMarks - Flag to indicate whether to log perf marks with the native performance API.\r\n * @param addPageTimings - Flag to indicate whether to log the perf marks into the _pageTimings object.\r\n * @param async - Flag to mark this timeline as an async timeline, so by default all measures under\r\n * this timeline will show under a new process line.\r\n */\r\n new (timelineName: string,\r\n instanceId: string,\r\n addPerfMarks: boolean,\r\n addPageTimings: boolean,\r\n async?: boolean): PerfTimeline;\r\n}\r\n\r\n/**\r\n * Factory method to construct a {PerfTimeline} instance\r\n * @param timelineName - the name of the perf timeline. Note that if you don't know the name\r\n * of a perf timeline at construction time, it can later be renamed to a known name later via\r\n * the 'rename' method.\r\n * @param instanceId - this specific instance's ID. Used during a renaming operation to idenfity any previous isntance.\r\n * @param addPerfMarks - Flag to indicate whether to log perf marks with the native performance API.\r\n * @param addPageTimings - Flag to indicate whether to log the perf marks into the _pageTimings object.\r\n * @param async - Flag to mark this timeline as an async timeline, so by default all measures under\r\n * this timeline will show under a new process line.\r\n */\r\nexport function createPerfTimeline(\r\n ctor: PerfTimelineConstructor,\r\n timelineName: string,\r\n instanceId: string,\r\n addPerfMarks = false,\r\n addPageTimings = false,\r\n async?: boolean\r\n ): PerfTimeline {\r\n return new ctor(timelineName, instanceId, addPerfMarks, addPageTimings, async);\r\n}\r\n\r\n/** PerfTimeline interface for diagnostic utilities and its clients. */\r\nexport interface PerfTimeline {\r\n\r\n /**\r\n * the name of the perf timeline. Note that if you don't know the name\r\n * of a perf timeline at construction time, it can later be renamed to a known name later via\r\n * the 'rename' method.\r\n */\r\n readonly timelineName: string;\r\n\r\n /** this specific instance's ID. Used during a renaming operation to idenfity any previous isntance. */\r\n readonly instanceId: string;\r\n\r\n /** Renames this instances of the timeline to the new given name. */\r\n rename(timelineName: string): void;\r\n\r\n /** Marks the start of a timeline measurement. */\r\n startMeasure(coreMarkerName: string, dynamicMeasureName?: string, async?: boolean): {\r\n /** Method that should be used to mark the end the measure */\r\n endMeasure: (updatedDynamicMeasureName?: string) => void\r\n };\r\n\r\n /** Returns the list of page measures for this timeline object */\r\n getPageMeasures(): Array;\r\n\r\n /** Instruments the start/begin for the given function with a given binding context */\r\n instrumentFunc(funcName: string, func: TFunc, bindingContext?: Object): TFunc;\r\n\r\n /** Instruments the start/begin for the given async-style function */\r\n instrumentPromise(promiseName: string, getPromise: () => Promise , async?: boolean): Promise ;\r\n}\r\n\r\n/** Main factory function interface for perf timeline. */\r\nexport interface TryGetPerfTimelineFunc {\r\n /**\r\n * Gets or creates a perf timeline object for the given experience instance\r\n * @param experienceName - the name of the experience for which to create the timeline\r\n * @param instanceId - the ID that will uniquely identify this timeline across multiple instances.\r\n * @param async - Optional flag to indicate the default tracing mode for this timeline.\r\n * Specifying true will render the measures under its own process id in the app trace.\r\n * Useful if the timeline will contain many async operations that frequently overlap with each other.\r\n * Note that this value can be overriden when taking an individual measure as well.\r\n */\r\n (experienceName: string, instanceId: string, async?: boolean): PerfTimeline;\r\n}\r\n\r\n/** Internal function reference for the perf timeline factory method */\r\nlet tryGetPerfTimelineFuncRef: TryGetPerfTimelineFunc = null;\r\n\r\n/** Set the function to use to get PerfTimeline. This is used by initializeExperienceDiagnotics. */\r\nexport function setTryGetPerfTimelineFunc(func: TryGetPerfTimelineFunc): void {\r\n tryGetPerfTimelineFuncRef = func;\r\n}\r\n\r\n/**\r\n * Gets or creates a perf timeline object for the given experience instance\r\n * @param experienceName - the name of the experience for which to create the timeline\r\n * @param instanceId - the ID that will uniquely identify this timeline across multiple instances.\r\n * @param async - Optional flag to indicate the default tracing mode for this timeline.\r\n * Specifying true will render the measures under its own process id in the app trace.\r\n * Useful if the timeline will contain many async operations that frequently overlap with each other.\r\n * Note that this value can be overriden when taking an individual measure as well.\r\n */\r\nexport const tryGetPerfTimeline: TryGetPerfTimelineFunc = (experienceName: string, instanceId: string, async?: boolean): PerfTimeline => {\r\n if (tryGetPerfTimelineFuncRef) {\r\n return tryGetPerfTimelineFuncRef(experienceName, instanceId, async);\r\n } else {\r\n return null;\r\n }\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\n\r\nconst pageTimings = canUseDOM() ? (window._pageTimings || (window._pageTimings = {})) : {};\r\nconst secondaryPageTimings = canUseDOM() ? (window._secondaryPageTimings || (window._secondaryPageTimings = {})) : {};\r\n\r\n/**\r\n * Gets current window._pageTimings object\r\n */\r\nexport function getPageTimings(): object {\r\n return pageTimings;\r\n}\r\n\r\n/**\r\n * Gets current window._secondaryPageTimings object\r\n */\r\nexport function getSecondaryPageTimings(): object {\r\n return secondaryPageTimings;\r\n}\r\n\r\n/**\r\n * Creates or updates a new counter under the page timings\r\n * @param counterName - the name of the counter to increment.\r\n */\r\nexport function incrementCounter(counterName: string): void {\r\n if (counterName && pageTimings) {\r\n const existingCount = pageTimings[counterName] || (pageTimings[counterName] = 0);\r\n pageTimings[counterName] = existingCount + 1;\r\n }\r\n}\r\n\r\n/**\r\n * Reset pageTimings object\r\n */\r\nexport function resetPageTimings(): void {\r\n Object.keys(pageTimings).forEach(key => delete pageTimings[key]);\r\n Object.keys(secondaryPageTimings).forEach(key => delete secondaryPageTimings[key]);\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\n\r\n/**\r\n * Returns the cookie content given a name\r\n *\r\n * @param name {string} - cookie name\r\n * @returns the value of the cookie or `null`, if the key is not found.\r\n */\r\nexport function getCookie(name: string): string {\r\n if (canUseDOM() && document && document.cookie) {\r\n const re = new RegExp(\"\\\\b\" + name + \"\\\\s*=\\\\s*([^;]*)\", \"i\");\r\n const match = re.exec(document.cookie);\r\n return (match && match.length > 1 ? match[1] : null);\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Helper function that retrieves the MUID from the document.cookie\r\n * or uses the saved value if the cookie was retrieved for the current page instance\r\n */\r\nexport function getMuidCookie(): string {\r\n return getCookie(\"MUID\");\r\n}\r\n\r\n/**\r\n * Helper function used to set a cookie\r\n * NOTE: THIS BYPASSES ANY GDPR CHECK AND HENCE ONLY REQUIRED FUNCTIONAL COOKIES SHOULD BE SET USING THIS\r\n * IF YOU DO NOT KNOW IF YOUR COOKIE IS ONE THEN PLEASE USE Cookies.ts setCookie THAT MAKES USE OF GDPR LOGIC CHECKS\r\n * When expiryDays is equal to -1 it will unset the cookie\r\n * * @param {string} name Cookie name\r\n * * @param {string} value Cookie value\r\n * * @param {number} expiryDays Cookie expiry days\r\n * * @param {string} domain Cookie domain\r\n * * @param {string} path Cookie path\r\n * * @param {boolean} secure Is it a https only cookie\r\n */\r\nexport function setRequireFunctionalCookie(name: string, value: string, expiryDays?: number, domain?: string, path?: string, secure?: boolean): void {\r\n let expiryDate;\r\n const builder = [name, \"=\", value];\r\n if (-1 === expiryDays) {\r\n // Expires date format is supposed to be in GMT.\r\n expiryDate = \"Fri, 31 Dec 1999 23:59:59 GMT\";\r\n } else if (expiryDays) {\r\n const date = new Date();\r\n date.setTime(date.getTime() + (expiryDays * 86400000)); // 86400000 == 24*60*60*1000 (ms/day)\r\n expiryDate = date.toUTCString();\r\n }\r\n\r\n if (expiryDate) { builder.push(\";expires=\", expiryDate); }\r\n if (domain) { builder.push(\";domain=\", domain); }\r\n if (path) { builder.push(\";path=\", path); }\r\n if (secure) { builder.push(\";secure\"); }\r\n\r\n if (canUseDOM() && document) {\r\n document.cookie = builder.join(\"\");\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nexport enum Environment {\r\n prod = \"prod\",\r\n int1 = \"int1\",\r\n int = \"int\",\r\n intpr = \"intPR\",\r\n intpef = \"intPef\"\r\n}\r\n\r\n/**\r\n * Parses from string to Environment enum.\r\n * Defaults to null\r\n *\r\n * @export\r\n * @param {(string | null | undefined)} environment - string being parsed\r\n * @returns {(Environment | null)} - the parsed Environment enum, or null.\r\n */\r\nexport function getEnvironmentFromString(environment: string | null | undefined): Environment | null {\r\n switch (environment) {\r\n case Environment.prod:\r\n return Environment.prod;\r\n case Environment.int1:\r\n return Environment.int1;\r\n case Environment.int:\r\n case Environment.intpr:\r\n case Environment.intpef:\r\n return Environment.int;\r\n default:\r\n return null;\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Enum for different page types\r\n * @enum\r\n */\r\nexport enum PageType {\r\n Article = \"article\",\r\n ArticleFullScreen = \"articlefullscreen\",\r\n DHP = \"dhp\",\r\n Gallery = \"gallery\",\r\n GalleryFullScreen = \"galleryfullscreen\",\r\n Launcher = \"launcher\",\r\n MMX = \"mmx\",\r\n Newsbar = \"newsbar\",\r\n NTP = \"ntp\",\r\n Story = \"story\",\r\n Video = \"video\",\r\n Windows = \"windowshp\",\r\n WindowsShell = \"shellhp\"\r\n}\r\n\r\n/** The AudienceMode enum */\r\nexport enum AudienceModeType {\r\n Adult = \"adult\",\r\n Enterprise = \"enterprise\",\r\n Kids = \"kids\"\r\n}","// © Microsoft Corporation. All rights reserved.\r\n/**\r\n * Defines valid loading states for an experience\r\n * The state has been defined as it happens. Please do not update the ordering or the numeric value of states.\r\n * If the numeric value of the state is updated this will break internal logic.\r\n */\r\nexport enum ExperienceLoadingState {\r\n\r\n /**\r\n * The experience has not been started yet\r\n */\r\n notStarted = 1,\r\n\r\n /**\r\n * The experience loading has been deferred\r\n */\r\n loadDeferred = 2,\r\n\r\n /**\r\n * The experience is coming out of loadDeferred state and is now resolved to be loaded.\r\n */\r\n resolvedForLoad = 3,\r\n\r\n /**\r\n * The experience has been loaded (i.e. the bundle has been downloaded and parsed, and the connector created)\r\n */\r\n loaded = 4,\r\n\r\n /**\r\n * The experience initialized milestone has been reached\r\n */\r\n initialized = 5,\r\n\r\n /**\r\n * The experience render has been deferred\r\n */\r\n renderDeferred = 6,\r\n\r\n /**\r\n * The experience is coming out of renderDeferred state and is now resolved to be rendered.\r\n */\r\n resolvedForRender = 7,\r\n\r\n /**\r\n * The experience rendered milestone has been reached (render function has been completed)\r\n */\r\n rendered = 8,\r\n\r\n /**\r\n * The experience DOM complete milestone has been reached\r\n */\r\n domComplete = 10,\r\n\r\n /**\r\n * The initial render of the experience has completed. All initial DOM elements have been created, and the browser has completed all render\r\n * task (applying styles, animations, etc)\r\n */\r\n visuallyReady = 11,\r\n\r\n /**\r\n * The experience encountered an error during loading\r\n */\r\n error = 12,\r\n\r\n /**\r\n * The experience has completed the revalidation of stale state.\r\n */\r\n staleRevalidationComplete = 13\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport PageBase from \"./PageBase\";\r\n\r\nexport default PageBase;\r\nexport * from \"./PageBase\";\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { Size1ColumnWidth, Size2ColumnWidth, Size3ColumnWidth, Size4ColumnWidth, Size5ColumnWidth } from \"./ColumnWidths\";\r\n\r\nimport { PageUtility } from \"@msnews/core\";\r\nimport { findIndex } from \"lodash-es\";\r\nimport { toPx } from \"@microsoft/fast-jss-utilities\";\r\n\r\n/**\r\n * Describes possible arrangements of columns. For example c3 represents 3 columns.\r\n *\r\n * Each arrangement is valid for a particular range of window widths. For example, for window widths from 996px to 1319px,\r\n * we will use the c3 arrangement, or 3 columns.\r\n *\r\n * Currently each arrangement describes a column count, but in the future, there may be separate 3-column \"large\"\r\n * and 3-column \"small\" arrangements, like on msn.com.\r\n */\r\nexport enum ColumnArrangement {\r\n c1 = \"c1\",\r\n c2 = \"c2\",\r\n c3 = \"c3\",\r\n c4 = \"c4\",\r\n c5 = \"c5\"\r\n}\r\n\r\nlet minViewportWidthOverrides: Map;\r\n\r\n/**\r\n * Override the min viewport widths for the given column arrangements.\r\n * @param overrides The overrides to use for the column arrangements.\r\n */\r\nexport function overrideMinViewportWidths(overrides: Map): void {\r\n minViewportWidthOverrides = overrides;\r\n}\r\n\r\n/**\r\n * Defines the properties of a particular column arrangement.\r\n */\r\nexport class ColumnArrangementDefinition {\r\n /**\r\n * Creates a column arrangement definition.\r\n * @param arrangement The column arrangement being defined.\r\n * @param contentSizePx The size of the content in pixels for this arrangement.\r\n * @param isFirstBreakpoint True if this is the first breakpoint.\r\n */\r\n constructor(public arrangement: ColumnArrangement, public contentSizePx: number, private isFirstBreakpoint?: boolean) { }\r\n\r\n /**\r\n * Gets the minimum required window width to trigger this column arrangement.\r\n */\r\n public get minViewportWidthPx(): number {\r\n if (this.isFirstBreakpoint) {\r\n return 0;\r\n }\r\n\r\n if (minViewportWidthOverrides) {\r\n const widthOverride = minViewportWidthOverrides.get(this.arrangement);\r\n if (widthOverride) {\r\n return widthOverride;\r\n }\r\n }\r\n\r\n return this.contentSizePx + contentBufferPx;\r\n }\r\n}\r\n\r\n/**\r\n * The list of possible column arrangement definitions. Use this to determine what window sizes are\r\n * appropriate for each column arrangement.\r\n */\r\nexport const columnArrangements: ColumnArrangementDefinition[] = [\r\n new ColumnArrangementDefinition(ColumnArrangement.c1, Size1ColumnWidth, true),\r\n new ColumnArrangementDefinition(ColumnArrangement.c2, Size2ColumnWidth),\r\n new ColumnArrangementDefinition(ColumnArrangement.c3, Size3ColumnWidth),\r\n new ColumnArrangementDefinition(ColumnArrangement.c4, Size4ColumnWidth)];\r\n\r\n// add five column arrangement when supported\r\nif (PageUtility.fiveColSupported()) {\r\n columnArrangements.push(new ColumnArrangementDefinition(ColumnArrangement.c5, Size5ColumnWidth));\r\n}\r\n\r\n/**\r\n * A map of column arrangements to definitions.\r\n */\r\nconst columnArrangementMap: { [columnArrangement in ColumnArrangement]?: ColumnArrangementDefinition } = {};\r\nfor (const columnArrangementDefinition of columnArrangements) {\r\n columnArrangementMap[columnArrangementDefinition.arrangement] = columnArrangementDefinition;\r\n}\r\n\r\n/**\r\n * The number of pixels to add on top of the content width in order to get the window width required to show it.\r\n * This buffer guarantees space between the content and the edge of the window, and also space for the scrollbar,\r\n * which is also counted when determining breakpoints.\r\n */\r\nconst contentBufferPx = 32;\r\n\r\n/**\r\n * Gets the content width for the given column arrangement.\r\n * @param columnArrangement The column arrangement to look up.\r\n * @returns The width in pixels of the content.\r\n */\r\nexport function contentWidthPxForColumnArrangement(columnArrangement: ColumnArrangement): number {\r\n return columnArrangementMap[columnArrangement].contentSizePx;\r\n}\r\n\r\n/**\r\n * Gets the minimum window width for the given column arrangement.\r\n * @param columnArrangement The column arrangement to look up.\r\n * @returns The minimum width for the window to show this column arrangement.\r\n */\r\nexport function minWindowWidthPxForColumnArrangement(columnArrangement: ColumnArrangement): number {\r\n return columnArrangementMap[columnArrangement].minViewportWidthPx;\r\n}\r\n\r\n/**\r\n * Gets the maximum window width for the given column arrangement.\r\n * @param columnArrangement The column arrangement to look up.\r\n * @returns The maximum width for the window to show this column arrangement. NaN if there is no maximum.\r\n */\r\nexport function maxWindowWidthPxForColumnArrangement(columnArrangement: ColumnArrangement): number {\r\n const arrangementIndex = findIndex(columnArrangements, a => a.arrangement === columnArrangement);\r\n\r\n if (arrangementIndex < columnArrangements.length - 1) {\r\n return columnArrangements[arrangementIndex + 1].minViewportWidthPx - 1;\r\n }\r\n\r\n return NaN;\r\n}\r\n\r\n/**\r\n * Helper to efficiently get the media query string to be used for given min/max column arrangements\r\n * It can be used in conjuction with `window.matchMedia` to target specific page widths, and it is also\r\n * used internally to generate the equivalent css selectors in `getMediaQuerySelector`\r\n * @param minArragement The min column arrangement to use for the @media query (inclusive)\r\n * @param maxArrangement The max column arrangement to use for the @media query (inclusive)\r\n * @returns the @media query for the specified min/max.\r\n */\r\nexport function getMediaQuery(minArragement: ColumnArrangement | null, maxArrangement: ColumnArrangement | null): string {\r\n const queries = [];\r\n\r\n if (minArragement) {\r\n const minArrangementDefinition = columnArrangementMap[minArragement];\r\n const minWidthPx = minArrangementDefinition.minViewportWidthPx;\r\n\r\n if (minWidthPx > 0) {\r\n queries.push(`(min-width: ${toPx(minWidthPx)})`);\r\n }\r\n }\r\n\r\n if (maxArrangement) {\r\n const maxArrangementDefinition = columnArrangementMap[maxArrangement];\r\n const maxArrangementIndex = columnArrangements.indexOf(maxArrangementDefinition);\r\n\r\n if (maxArrangementIndex < columnArrangements.length - 1) {\r\n queries.push(`(max-width: ${toPx(columnArrangements[maxArrangementIndex + 1].minViewportWidthPx - 1)})`);\r\n }\r\n }\r\n\r\n return queries.join(\" and \");\r\n}\r\n\r\n/**\r\n * Helper to efficiently get the media query string to be used for the given column arrangement\r\n * It can be used in conjuction with `window.matchMedia` to target specific page widths, and it is also\r\n * used internally to generate the equivalent css selectors in `getMediaQuerySelector`\r\n * @param columnArrangement The column arrangement to target\r\n * @returns The media query to target that column arrangement\r\n */\r\nexport function getMediaQueryFor(columnArrangement: ColumnArrangement): string {\r\n return getMediaQuery(columnArrangement, columnArrangement);\r\n}\r\n\r\n/**\r\n * Helper to efficiently get the CSS selector to be used for apply styles for given min/max arrangements\r\n * @param minArragement The min column arrangement to use for the media query (inclusive)\r\n * @param maxArrangement The max column arrangement to use for the media query (inclusive)\r\n * @returns the css media query selector for the specified min/max.\r\n */\r\nexport function getMediaQuerySelector(minArragement: ColumnArrangement | null, maxArrangement: ColumnArrangement | null): string {\r\n const mediaQuery = getMediaQuery(minArragement, maxArrangement);\r\n return mediaQuery ? \"@media \" + mediaQuery : \"\";\r\n}\r\n\r\n/**\r\n * Helper to efficiently get the CSS selector to be used for apply styles for the given column arrangement.\r\n * @param columnArrangement The column arrangement to target\r\n * @returns the css media query selector for the specified column arrangement.\r\n */\r\nexport function getMediaQuerySelectorFor(columnArrangement: ColumnArrangement): string {\r\n return getMediaQuerySelector(columnArrangement, columnArrangement);\r\n}\r\n\r\n/**\r\n * Callback type for subscribing to BreakpointManager breakpoint changed events.\r\n */\r\nexport type BreakpointManagerCallback = (columnArrangement: ColumnArrangement) => void;\r\n\r\n/**\r\n * Breakpoint manager common interface.\r\n */\r\nexport interface BreakpointManager {\r\n /**\r\n * Gets the current column arrangement.\r\n */\r\n currentColumnArrangement: ColumnArrangement;\r\n\r\n /**\r\n * Subscribes for changes\r\n * @param callback The method to call when the column arrangement changes.\r\n */\r\n subscribe(callback: BreakpointManagerCallback): void;\r\n\r\n /**\r\n * Unsubscribe from changes\r\n * @param callback The callback to unregister.\r\n */\r\n unsubscribe(callback: BreakpointManagerCallback): void;\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Aad data formatted from browser response\r\n */\r\nexport type AadData = {\r\n /**\r\n * Access token\r\n */\r\n token: string;\r\n\r\n /**\r\n * Any error info\r\n */\r\n errorInfo: AadErrorInfo;\r\n\r\n /**\r\n * Flag to indicate if call was successful\r\n */\r\n isSuccess: boolean;\r\n\r\n /**\r\n * Flag to indicate if token is valid\r\n */\r\n isValid: boolean;\r\n\r\n /**\r\n * Status for the authentication\r\n */\r\n status: AccessTokenStatus;\r\n};\r\n\r\n/**\r\n * Error info from aad request\r\n */\r\nexport type AadErrorInfo = {\r\n /**\r\n * Error string\r\n */\r\n error_string?: string;\r\n\r\n /**\r\n * Platform error code\r\n */\r\n platform_error_code?: number;\r\n\r\n /**\r\n * Primary error code\r\n */\r\n primary_error?: number;\r\n\r\n /**\r\n * Secondary error code\r\n */\r\n secondary_error?: number;\r\n};\r\n\r\n/**\r\n * Account info\r\n */\r\nexport type AccountInfo = {\r\n /**\r\n * Account id\r\n */\r\n account_id?: string;\r\n\r\n /**\r\n * Account type\r\n */\r\n account_type?: string;\r\n\r\n /**\r\n * Tenant id\r\n */\r\n tenant_id?: string;\r\n\r\n /**\r\n * First name\r\n */\r\n first_name?: string;\r\n\r\n /**\r\n * Last name\r\n */\r\n last_name?: string;\r\n};\r\n\r\nexport enum AccessTokenStatus {\r\n success,\r\n mfaRequired,\r\n otherError\r\n}\r\n\r\n/**\r\n * The client id of our application\r\n */\r\nexport const clientId = \"d7b530a4-7680-4c23-a8bf-c52c121d2e87\";\r\n\r\n/**\r\n * The scope/resource id for enterprise One Service\r\n */\r\nexport const oneServiceScope = \"https://enterprisenews.microsoft.com\";\r\n\r\n/**\r\n * The friendly name for the scope/resource for Enterprise One Service to be used\r\n * in logging.\r\n */\r\nexport const oneServiceFriendlyName = \"OneService\";","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { TelemetryLibraryBase } from \"../telemetry-interfaces\";\r\n\r\n/**\r\n * Static global variables used to reference to Telemetry library implementation.\r\n * @var TelemetryLibraryBase\r\n */\r\nexport let Telemetry: TelemetryLibraryBase = null;\r\n\r\n/**\r\n * Initialize Telemetry\r\n * @param telemetry TelemetryLibraryBase implementation\r\n */\r\nexport function initTelemetry(telemetry: TelemetryLibraryBase): void {\r\n Telemetry = telemetry;\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { get, set } from \"lodash-es\";\r\n\r\nimport { ConnectorConstants } from \"../constants/ConnectorConstants\";\r\nimport { ConnectorNamespaces } from \"@msnews/experiences-constants\";\r\n\r\n/**\r\n * Maps the data connector name to the set of experience keys it is injected into.\r\n * The values include the \"._@STATE@_\" portion needed to pull experience state out of the app state object.\r\n */\r\nconst dataConnectorToExperienceKeyMap: Map> = new Map>();\r\n\r\n/**\r\n * Register a data connector to inject into an experience.\r\n * @param experienceFullNamespace The full namespace of the experience to inject into.\r\n * @param dataConnectorName The name for the data connector to inject.\r\n */\r\nfunction registerInjection(\r\n experienceFullNamespace: string,\r\n dataConnectorName: ConnectorNamespaces): void {\r\n let experienceSet: Set = dataConnectorToExperienceKeyMap.get(dataConnectorName);\r\n if (!experienceSet) {\r\n experienceSet = new Set();\r\n dataConnectorToExperienceKeyMap.set(dataConnectorName, experienceSet);\r\n }\r\n\r\n experienceSet.add(createStatePropertyKey(experienceFullNamespace));\r\n}\r\n\r\n/**\r\n * Initializes the shared data connector state for the given experience.\r\n * @param appState The global app state to modify.\r\n * @param experienceFullNamespace The full namespace of the experience to host the data connector state.\r\n * @param dataConnectorName The name of the data connector to use.\r\n */\r\nfunction initializeExperience(\r\n appState: any,\r\n experienceFullNamespace: string,\r\n dataConnectorName: ConnectorNamespaces): void {\r\n\r\n // Setup the key and get the actual state property for the connector. lodash uses dotted notation\r\n // so the key will be something like: namespace._@STATE@_\r\n const experienceStatePropertyKey = createStatePropertyKey(experienceFullNamespace);\r\n const connectorPreviousState = get(appState, experienceStatePropertyKey, undefined);\r\n\r\n // Find the initial data connector state\r\n const initialDataConnectorState = get(appState, createStatePropertyKey(dataConnectorName), undefined);\r\n\r\n // Create the new experience connector state\r\n const nextStateForConnector = { ...connectorPreviousState, [dataConnectorName]: initialDataConnectorState };\r\n set(appState, experienceStatePropertyKey, nextStateForConnector);\r\n}\r\n\r\n/**\r\n * Updates the data connector state on all experiences that include it.\r\n * @param appState The global app state object.\r\n * @param dataConnectorNamespace The namespace of the data connector that's been updated.\r\n * @param newDataConnectorState The new data connector state object.\r\n */\r\nfunction reportStateChange(\r\n appState: any,\r\n dataConnectorNamespace: string,\r\n newDataConnectorState: any): void {\r\n\r\n const experienceKeys: Set = dataConnectorToExperienceKeyMap.get(dataConnectorNamespace);\r\n if (experienceKeys) {\r\n for (const experienceKey of experienceKeys) {\r\n const experiencePreviousState: any = get(appState, experienceKey, undefined);\r\n\r\n if (experiencePreviousState) {\r\n set(appState, experienceKey, { ...experiencePreviousState, [dataConnectorNamespace]: newDataConnectorState });\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Creates the lodash property key to get or set the experience or data connector state.\r\n * @param fullNamespace The full namespace of the experience or data connector.\r\n */\r\nfunction createStatePropertyKey(fullNamespace: string): string {\r\n return fullNamespace + \".\" + ConnectorConstants.connectorStateKey;\r\n}\r\n\r\n/** Methods to support injecting data connector state into experiences */\r\nexport const dataConnectorInjector = {\r\n registerInjection,\r\n initializeExperience,\r\n reportStateChange\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { logger } from \"../logging\";\r\n\r\n/** Perf marker start suffix */\r\nconst StartMarkSuffix = \"-start\";\r\n\r\n/**\r\n * PerfMarker facilitates adding and measuring performance markers.\r\n */\r\nclass PerfMarker {\r\n /** The single instance of the PerfMarker class. */\r\n private static instance: PerfMarker;\r\n\r\n /** The performance object. */\r\n private performance: Performance;\r\n\r\n /** Perf marker end suffix */\r\n private readonly endMarkSuffix: string = \"-end\";\r\n\r\n /**\r\n * The constructor.\r\n */\r\n private constructor() {\r\n if (typeof window !== \"undefined\") {\r\n this.initialize(window.performance);\r\n }\r\n }\r\n\r\n /**\r\n * Returns singleton class instance.\r\n * @returns The class instance\r\n */\r\n public static getInstance(): PerfMarker {\r\n if (!PerfMarker.instance) {\r\n PerfMarker.instance = new PerfMarker();\r\n }\r\n\r\n return PerfMarker.instance;\r\n }\r\n\r\n /**\r\n * Initialize the member variables.\r\n * @param performance - The performance object instance.\r\n */\r\n public initialize(performance: Performance): void {\r\n this.performance = performance;\r\n }\r\n\r\n /**\r\n * Adds given perf marker to browser.\r\n * @param name - Perf marker to start\r\n */\r\n public startMark(name: string): void {\r\n this.singleMark(name + StartMarkSuffix);\r\n }\r\n\r\n /**\r\n * Adds given perf marker to browser.\r\n * @param name - Perf marker to end\r\n */\r\n public endMark(name: string): void {\r\n this.singleMark(name + this.endMarkSuffix);\r\n this.measureStartEnd(name);\r\n }\r\n\r\n /**\r\n * Adds a single performance marker via the performance API.\r\n * @param name - the name of the perf marker\r\n */\r\n public singleMark(name: string): void {\r\n const performance = this.performance;\r\n if (performance && performance.mark) {\r\n performance.mark(name);\r\n }\r\n }\r\n\r\n /**\r\n * Utility method to add start/end marker around a promise.\r\n * @param name - The name of perf marker\r\n * @param getPromise - The callback\r\n * @returns The promise\r\n */\r\n public async measurePromise(name: string, getPromise: () => Promise): Promise {\r\n this.startMark(name);\r\n const result = await getPromise();\r\n this.endMark(name);\r\n return result;\r\n }\r\n\r\n /**\r\n * Telemetry call this method to collect existing perf markers that each Experience has added.\r\n * @param experienceName - Perf marker name in case of custom marker / Experience name\r\n * @returns {IPerfMarkers}\r\n */\r\n public measurePerfMarker(experienceName: string): IPerfMarkers {\r\n\r\n if (!this.performance) {\r\n return;\r\n }\r\n\r\n const perfMarkers: { [id: string]: PerfMarkerDetail; } = {};\r\n\r\n // Get all perf markers from browser.\r\n const perfEntries = this.performance.getEntriesByType(\"mark\");\r\n if (!perfEntries) {\r\n return perfMarkers;\r\n }\r\n\r\n // Iterate through perfEntries received from browser.\r\n for (let i = 0; i < perfEntries.length; i++) {\r\n\r\n // if marker name in perfEntries object is null\r\n let markerName: string = perfEntries[i].name;\r\n if (!markerName || perfEntries[i].startTime == null) {\r\n continue;\r\n }\r\n\r\n // Remove start and end suffix.\r\n markerName = markerName.replace(/-(end|start)$/i, \"\");\r\n\r\n // if marker name retrieved from browser is not for this experience then continue with next marker.\r\n if (!markerName.startsWith(experienceName)) {\r\n continue;\r\n }\r\n\r\n const perfMarkerDetail = perfMarkers[markerName] || new PerfMarkerDetail(markerName);\r\n perfMarkerDetail.processPerfEntry(perfEntries[i]);\r\n if (perfMarkerDetail.isValid) {\r\n perfMarkers[markerName] = perfMarkerDetail;\r\n }\r\n }\r\n\r\n return perfMarkers;\r\n }\r\n\r\n /**\r\n * Measures the given marker name's start/end markers.\r\n * @param name - The name of the marker whose -start and -end to measure\r\n */\r\n private measureStartEnd(name: string): void {\r\n const performance = this.performance;\r\n if (performance && performance.measure) {\r\n try {\r\n performance.measure(\r\n name,\r\n name + StartMarkSuffix,\r\n name + this.endMarkSuffix\r\n );\r\n } catch (ex) {\r\n // An exception will be thrown if either start/end marker didn't exist.\r\n // We swallo this exception and log an error so that actual code's execution\r\n // would not be effected due to performance measurement code.\r\n logger.logError(`Error while attempting to measure start/end of '${name}'. Error: ${ex}`);\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport const perfMarker = PerfMarker.getInstance();\r\n\r\n/**\r\n * Interface defining attributes of each per marker.\r\n */\r\nexport interface IPerfMarkers {\r\n [key: string]: PerfMarkerDetail;\r\n}\r\n\r\n/**\r\n * Interface defining perf markers.\r\n */\r\nclass PerfMarkerDetail {\r\n /** marker name */\r\n public readonly markerName: string;\r\n /** first start time */\r\n public firstStartTime: number;\r\n /** start time */\r\n public startTime: number;\r\n /** duration */\r\n public duration = 0;\r\n\r\n /**\r\n * Sets marker name.\r\n */\r\n constructor(markerName: string) {\r\n this.markerName = markerName;\r\n }\r\n\r\n /**\r\n * Check if given marker is valid. If marker has a start time then it is a valid marker.\r\n * @returns True if valid else false.\r\n */\r\n get isValid(): boolean {\r\n return this.startTime != null;\r\n }\r\n\r\n /**\r\n * Sum up start and end marker duraiton per marker name.\r\n */\r\n public processPerfEntry(perfEntry: PerformanceEntry): void {\r\n\r\n // If given mark is a start mark\r\n if (perfEntry.name.endsWith(StartMarkSuffix)) {\r\n\r\n // If this is a start mark and firstStartTime is undefined then assign value of startTime now.\r\n if (!this.firstStartTime) {\r\n this.firstStartTime = perfEntry.startTime;\r\n }\r\n\r\n // Change start time to start time of current mark.\r\n this.startTime = perfEntry.startTime;\r\n\r\n } else if (this.startTime != null) {\r\n // This is is not a start mark. Assuming this is end mark, check start time of this mark is set earlier. if set properly then proceed.\r\n // else likely a candiddate to skip \"if\" part.\r\n\r\n // This is a end mark. Add earlier duration plus current start time minus this start time.\r\n this.duration += perfEntry.startTime - this.startTime;\r\n\r\n // reset start time so we can recalculate the next start/end pair correctly\r\n this.startTime = null;\r\n }\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Helper to promisify the Prime 'require' AMD helper to resolve a single module with no dependencies.\r\n * @param moduleName {string} - the name of the module to resolve\r\n * @param defaultModule {TModule} - the default module implementation if require is not available.\r\n * @returns {Promise{TModule}} a promise that will resolve the module when it's available.\r\n * @description Note that this version only resolves a single module with no dependencies.\r\n */\r\nexport async function requireAsync(moduleName: string, defaultModule?: TModule): Promise {\r\n return new Promise((resolve: (module: TModule) => void, reject) => {\r\n\r\n if (typeof window.require === \"function\") {\r\n window.require([moduleName], resolve);\r\n } else if (defaultModule) {\r\n console.error(`require was not available. Returning default implementation for ${moduleName}`);\r\n resolve(defaultModule);\r\n } else {\r\n reject(\"require is not available\");\r\n }\r\n });\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n ITrackInfo,\r\n KeyValueArray,\r\n KeyValuePair,\r\n Utility,\r\n clientId,\r\n getAppEnvironment,\r\n getHeadData,\r\n oneServiceHeaders,\r\n oneServiceQueryStringKeys,\r\n oneServiceFriendlyName,\r\n oneServiceScope\r\n} from \"@msnews/core\";\r\nimport { aadTokenQsKey, aadTokenQsVal, getAadData, useEnterpriseCompliance } from \"@msnews/auth\";\r\n\r\nimport { isString } from \"lodash-es\";\r\n\r\n/**\r\n * A namespace that provides OneService utility functionality\r\n */\r\nexport namespace OneServiceUtility {\r\n\r\n /**\r\n * Authentication ticket type - Header value required by back-end service\r\n * Specifies what type of authentication to do\r\n */\r\n export const authenticationTicketType = \"10\";\r\n\r\n /**\r\n * Header name that holds which ANON cookie to use\r\n */\r\n export const signedInCookieNameHeader = \"signedInCookieName\";\r\n\r\n /**\r\n * Header name that holds the user-location value.\r\n */\r\n export const userLocationHeader = \"user-location\";\r\n\r\n /**\r\n * The api-key we'll be sending to OneService.\r\n */\r\n export const apiKey = \"0QfOX3Vn51YCzitbLaRkTTBadtWpgTN8NZLW0C1SEM\";\r\n\r\n /**\r\n * Executes a callback on completing of a service request\r\n *\r\n * @param {() => Promise} serviceRequest - The service request\r\n * @param {() => void} callbackMethod - The callback method\r\n * @return {Promise} - A promise of the service response\r\n */\r\n export async function serviceRequestOnComplete(serviceRequest: () => Promise, callbackMethod: () => void): Promise {\r\n try {\r\n const result = await serviceRequest();\r\n callbackMethod();\r\n\r\n return result;\r\n } catch (error) {\r\n callbackMethod();\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Gets common parameters used in service requests to OneService, when there is no personalization involved\r\n * @param {string} userId - The user id for the request\r\n * @param {string} ocidSpecifier - The OCID\r\n * @param {string} addPageInfoToOcid - If true, page_product and page_type are added to the ocid. Defaults to true\r\n * @returns {KeyValueArray}\r\n */\r\n export function getOneServiceParamsWithoutAuth(userId: string = null, ocidSpecifier: string, addPageInfoToOcid = true): KeyValueArray {\r\n const appEnvironment = getAppEnvironment();\r\n const params = [\r\n {\r\n key: oneServiceQueryStringKeys.apiKey,\r\n value: apiKey\r\n },\r\n {\r\n // TODO Bug 22266910: clarify use of activityId vs rid in this spot\r\n key: oneServiceQueryStringKeys.activityId,\r\n value: appEnvironment.ActivityId\r\n },\r\n {\r\n key: oneServiceQueryStringKeys.ocid,\r\n value: addPageInfoToOcid ? getOneServiceOCID(appEnvironment.TrackInfo, ocidSpecifier) : ocidSpecifier\r\n },\r\n {\r\n key: oneServiceQueryStringKeys.market,\r\n value: appEnvironment.CurrentMarket\r\n }\r\n ];\r\n\r\n // 21527208 - remove this after upgrading experiences to use shared lib.\r\n if (userId) {\r\n params.push({\r\n key: oneServiceQueryStringKeys.user,\r\n value: userId\r\n });\r\n }\r\n\r\n const runningExperiments = getHeadData().CurrentFlights;\r\n if (runningExperiments) {\r\n params.push({\r\n key: oneServiceQueryStringKeys.fdhead,\r\n value: runningExperiments\r\n });\r\n }\r\n\r\n if (useEnterpriseCompliance()) {\r\n params.push({\r\n key: aadTokenQsKey,\r\n value: aadTokenQsVal\r\n });\r\n }\r\n\r\n return params;\r\n }\r\n\r\n /**\r\n * Returns the params which are static in nature and don't change.\r\n * @param ocidSpecifier - The OCID\r\n * @param addPageInfoToOcid - If true, page_product and page_type are added to the ocid. Defaults to true\r\n */\r\n export function getOneServiceNonDynamicParamsWithoutAuth(ocidSpecifier: string, addPageInfoToOcid = true): KeyValueArray {\r\n const appEnvironment = getAppEnvironment();\r\n const params = [\r\n {\r\n key: oneServiceQueryStringKeys.apiKey,\r\n value: apiKey\r\n },\r\n {\r\n key: oneServiceQueryStringKeys.ocid,\r\n value: addPageInfoToOcid ? getOneServiceOCID(appEnvironment.TrackInfo, ocidSpecifier) : ocidSpecifier\r\n },\r\n {\r\n key: oneServiceQueryStringKeys.market,\r\n value: appEnvironment.CurrentMarket\r\n }\r\n ];\r\n\r\n if (useEnterpriseCompliance()) {\r\n params.push({\r\n key: aadTokenQsKey,\r\n value: aadTokenQsVal\r\n });\r\n }\r\n\r\n return params;\r\n }\r\n\r\n /**\r\n * Gets common parameters used in service requests to OneService,\r\n * plus authentication params in the form of the sign in cookie name\r\n * Note: This should only be called if the user is known to be signed in, else use getOneServiceParamsWithoutAuth\r\n *\r\n * @export\r\n * @param {string} userId - The user id for the request\r\n * @param {string} ocidSpecifier - The OCID\r\n * @param {string} addPageInfoToOcid - If true, page_product and page_type are added to the ocid. Defaults to true\r\n * @returns {KeyValueArray}\r\n */\r\n export function getOneServiceParamsWithAuth(userId: string = null, ocidSpecifier: string, addPageInfoToOcid = true): KeyValueArray {\r\n const appEnvironment = getAppEnvironment();\r\n const authCookieName: string = appEnvironment.AuthCookieName as string;\r\n const params = [...getOneServiceParamsWithoutAuth(userId, ocidSpecifier, addPageInfoToOcid)];\r\n if (authCookieName) {\r\n params.push({\r\n key: oneServiceQueryStringKeys.signInCookieName, // sign-in cookie name\r\n value: authCookieName.toUpperCase()\r\n });\r\n }\r\n\r\n return params;\r\n }\r\n\r\n /**\r\n * Gets common headers used in service requests to OneService\r\n *\r\n * @export\r\n * @returns {Promise}\r\n */\r\n export async function getOneServiceHeaders(): Promise {\r\n const headers = {};\r\n\r\n if (useEnterpriseCompliance()) {\r\n const aadData = await getAadData(clientId, oneServiceScope, oneServiceFriendlyName);\r\n if (aadData && aadData.token) {\r\n headers[oneServiceHeaders.authorization] = `Bearer ${aadData.token}`;\r\n }\r\n }\r\n\r\n return headers;\r\n }\r\n\r\n /**\r\n * Gets headers specifically used in service requests to OneService /feed endpoint\r\n * @export\r\n * @returns {Promise}\r\n */\r\n export async function getOneServiceFeedCallHeaders(): Promise {\r\n const headers = await getOneServiceHeaders();\r\n const appEnvironment = getAppEnvironment();\r\n const activityId = appEnvironment.ActivityId;\r\n\r\n if (appEnvironment.SendFeedCallActivityIdInHeader && activityId) {\r\n headers[oneServiceHeaders.activityId] = activityId;\r\n }\r\n\r\n return headers;\r\n }\r\n\r\n /**\r\n * Gets the location query string parameters based on lat/long from paramaters or AppEnvironment.\r\n * @param customizedLatitude The customized latitude\r\n * @param customizedLongitude The customized Longitude\r\n * @returns The key value pair of location query string parameters.\r\n */\r\n export function getLocationParams(customizedLatitude?: string, customizedLongitude?: string): KeyValuePair {\r\n const appEnvironment = getAppEnvironment();\r\n const latitude = customizedLatitude || appEnvironment.Latitude;\r\n const longitude = customizedLongitude || appEnvironment.Longitude;\r\n\r\n if (latitude && longitude) {\r\n return { key: oneServiceQueryStringKeys.location, value: `${latitude}|${longitude}` };\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Returns the OCID generated from the telemetry TrackInfo if it is valid, otherwise returns the ocid specifier\r\n * @param trackInfo The track info\r\n * @param ocidSpecifier The OCID\r\n * @returns The OCID to use.\r\n */\r\n export function getOneServiceOCID(trackInfo: ITrackInfo, ocidSpecifier: string): string {\r\n if (Utility.isNonNullObject(trackInfo) &&\r\n Utility.isNonNullObject(trackInfo.sitePage) &&\r\n isString(trackInfo.sitePage.page_product) &&\r\n isString(trackInfo.sitePage.page_type)) {\r\n return trackInfo.sitePage.page_product + \"-\" + trackInfo.sitePage.page_type + (ocidSpecifier ? \"-\" + ocidSpecifier : \"\");\r\n } else {\r\n return ocidSpecifier;\r\n }\r\n }\r\n\r\n /**\r\n * Sets up base request data for One Service calls\r\n * @param method\r\n * @returns - RequestInit\r\n */\r\n export async function getBaseRequestData(method): Promise {\r\n const requestObj: RequestInit = {\r\n headers: await OneServiceUtility.getOneServiceHeaders(),\r\n method\r\n };\r\n\r\n return requestObj;\r\n }\r\n\r\n /**\r\n * Populates the request init and return commonParams\r\n * @param ocid -- the ocid for this request\r\n * @returns {KeyValueArray} - parameters as a key/value array\r\n */\r\n export function getCommonParams(ocid: string): KeyValueArray {\r\n if (getHeadData().UserIsSignedIn) {\r\n return this.getOneServiceParamsWithAuth(getAppEnvironment().UserId, ocid);\r\n }\r\n\r\n return this.getOneServiceParamsWithoutAuth(getAppEnvironment().UserId, ocid);\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * An enumeration of global / fixed connector namespaces\r\n * Only name spaces that are constant (i.e. not instanced) for the entire SPA lifetime should be listed here\r\n * NOTE: Keep this list alphabetical\r\n * NOTE: Left/Right side need to match\r\n */\r\nexport enum ConnectorNamespaces {\r\n AdminPortalData = \"AdminPortalData\",\r\n AdService = \"AdService\",\r\n AdsManager = \"AdsManager\",\r\n BingImageData = \"BingImageData\",\r\n CategoryData = \"CategoryData\",\r\n ChromiumPageSettings = \"ChromiumPageSettings\",\r\n CoachmarkData = \"CoachmarkData\",\r\n DailyBriefServiceClient = \"DailyBriefServiceClient\",\r\n DisplayAdsManager = \"DisplayAdsManager\",\r\n ExperienceTrackerCommunityData = \"ExperienceTrackerCommunityData\",\r\n ExperienceTrackerData = \"ExperienceTrackerData\",\r\n ExperienceTrackerEdgeData = \"ExperienceTrackerEdgeData\",\r\n ExperienceTrackerEdgeNextData = \"ExperienceTrackerEdgeNextData\",\r\n ExperienceTrackerFinanceData = \"ExperienceTrackerFinanceData\",\r\n ExperienceTrackerFirstPartyData = \"ExperienceTrackerFirstPartyData\",\r\n ExperienceTrackerHomePageData = \"ExperienceTrackerHomePageData\",\r\n ExperienceTrackerHubData = \"ExperienceTrackerHubData\",\r\n ExperienceTrackerMicrosoftNewsData = \"ExperienceTrackerMicrosoftNewsData\",\r\n ExperienceTrackerOfficeData = \"ExperienceTrackerOfficeData\",\r\n ExperienceTrackerTrafficData = \"ExperienceTrackerTrafficData\",\r\n ExperienceTrackerViewsData = \"ExperienceTrackerViewsData\",\r\n ExperienceTrackerWeatherData = \"ExperienceTrackerWeatherData\",\r\n ExperienceTrackerWeatherDataConnector = \"ExperienceTrackerWeatherDataConnector\",\r\n ExperienceTrackerWindowsData = \"ExperienceTrackerWindowsData\",\r\n ExperienceTrackerWindowsShellData = \"ExperienceTrackerWindowsShellData\",\r\n FeedbackData = \"FeedbackData\",\r\n HubPageSettings = \"HubPageSettings\",\r\n IrisData = \"IrisData\",\r\n LayoutPreferenceData = \"LayoutPreferenceData\",\r\n LocationFeed = \"LocationFeed\",\r\n MarketSelector = \"MarketSelector\",\r\n MilestoneData = \"MilestoneData\",\r\n MsccCookieBannerData = \"MsccCookieBannerData\",\r\n MsNewsPageSettings = \"MsNewsPageSettings\",\r\n NavigationData = \"NavigationData\",\r\n OfficeSharedData = \"OfficeSharedData\",\r\n OneServiceContent = \"OneServiceContent\",\r\n PageClickTrackerData = \"PageClickTrackerData\",\r\n PageLayout = \"PageLayout\",\r\n PageSettingsData = \"PageSettingsData\",\r\n PlacementManager = \"PlacementManager\",\r\n PoweredByData = \"PoweredByData\",\r\n Preload = \"Preload\",\r\n RewardsData = \"RewardsData\",\r\n SharedState = \"SharedState\",\r\n Telemetry = \"Telemetry\",\r\n SmartListSharedData = \"SmartListSharedData\",\r\n TelemetryData = \"TelemetryData\",\r\n TelemetryDataEdgeChromium = \"TelemetryDataEdgeChromium\",\r\n TelemetryEdgeChromium = \"TelemetryEdgeChromium\",\r\n TopicData = \"TopicData\",\r\n VerticalPropertyData = \"VerticalPropertyData\",\r\n VideoDataManager = \"VideoDataManager\",\r\n WeatherData = \"WeatherData\",\r\n FinanceData = \"FinanceData\",\r\n WindowsShellData = \"WindowsShellData\"\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { IconHandledProps, IconProps, IconUnhandledProps } from \"./Icon.props\";\r\nimport React, { CSSProperties } from \"react\";\r\n\r\nimport Foundation from \"@microsoft/fast-components-foundation-react\";\r\nimport { Glyph } from \".\";\r\nimport { HandledPropsKeys } from \"@msnews/core\";\r\n\r\n/**\r\n * Icon state\r\n */\r\ninterface IconState {\r\n /**\r\n * Svg component that we are lazy loading. Normally, we would use React.lazy and React.suspense, but those are not recommended for\r\n * production with Preact. Using them will cause CardActions to break.\r\n */\r\n svgComponent?: React.ComponentType>;\r\n}\r\n\r\n/**\r\n * Icon component\r\n * @class - Icon\r\n * @classdesc - The Icon component. Renders the image with respective glyph icon\r\n * @default\r\n */\r\nexport class Icon extends Foundation {\r\n /**\r\n * Component HandledProps enumeration. Anything not enumerated here will be included in the experience root HTML tag via unhandledProps()\r\n */\r\n protected handledProps: HandledPropsKeys = {\r\n ariaLabel: undefined,\r\n fill: undefined,\r\n glyphType: undefined,\r\n height: undefined,\r\n managedClasses: undefined,\r\n onError: undefined,\r\n onClick: undefined,\r\n width: undefined,\r\n wrapperClassName: undefined,\r\n svgClassName: undefined,\r\n renderSvgWithWrapper: undefined\r\n };\r\n\r\n constructor(props: IconProps) {\r\n super(props);\r\n this.state = {\r\n svgComponent: null\r\n };\r\n }\r\n\r\n /**\r\n * If glyphType is a promise, lazy load the component with the promise. Once loaded, update state with the new\r\n * component.\r\n * @method\r\n */\r\n public componentDidMount() {\r\n const { glyphType } = this.props;\r\n\r\n if (typeof glyphType === \"function\") {\r\n glyphType().then((m) => {\r\n this.setState({ svgComponent: m.ReactComponent });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * If glyphType is a promise and has changed, lazy load the new component with the promise. Once loaded, update\r\n * state with the new component.\r\n * @method\r\n * @param {IconProps} prevProps - props before update\r\n */\r\n public componentDidUpdate(prevProps: IconProps) {\r\n const { glyphType } = this.props;\r\n\r\n if (typeof glyphType === \"function\" && glyphType !== prevProps.glyphType) {\r\n glyphType().then((m) => {\r\n this.setState({ svgComponent: m.ReactComponent });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Updating state before render. If there is no glyphType, we can set this.state.svgComponent to null. This avoids\r\n * an extra render if we tried to use setState in componentDidUpdate to set this.state.svgComponent to null.\r\n * @method\r\n * @param {IconProps} props - props to be used in the upcoming render\r\n * @param {IconState} state - state to be used in the upcoming render\r\n * @returns {IconState} - updated state to be used in the next render\r\n */\r\n public static getDerivedStateFromProps(props: IconProps, state: IconState): IconState {\r\n const { glyphType } = props;\r\n\r\n if (glyphType) {\r\n return state;\r\n }\r\n\r\n return {\r\n svgComponent: null\r\n };\r\n }\r\n\r\n /**\r\n * Render our lazy loaded svg component\r\n * @method\r\n * @param {React.ComponentType} LazyLoadedSvgComponent - the lazy loaded svg component we're going to render\r\n * @returns {JSX.Element} A JSX element with a span wrapping our lazy loaded svg component\r\n */\r\n private renderSvgComponent(LazyLoadedSvgComponent: React.ComponentType): JSX.Element {\r\n const { height, width, fill, managedClasses, svgClassName } = this.props;\r\n const attrProps: React.SVGAttributes = {};\r\n\r\n if (width) {\r\n attrProps.width = width;\r\n }\r\n\r\n if (height) {\r\n attrProps.height = height;\r\n }\r\n\r\n return ();\r\n }\r\n\r\n /**\r\n * Component renderer\r\n * @public\r\n * @method\r\n * @returns {JSX.Element} the image component containing a glyph icon\r\n */\r\n public render(): JSX.Element {\r\n const { ariaLabel, height, managedClasses, glyphType, width, wrapperClassName, renderSvgWithWrapper, onClick } = this.props;\r\n if (!glyphType) {\r\n return (null);\r\n }\r\n const role = ariaLabel ? \"img\" : \"presentation\";\r\n\r\n if (typeof glyphType === \"string\") {\r\n // when glyphType is string, use img tag\r\n let icon = glyphType as string;\r\n if (Glyph[icon]) {\r\n icon = Glyph[icon];\r\n }\r\n return ();\r\n }\r\n\r\n let wrapperCss: CSSProperties = {};\r\n if (width) {\r\n wrapperCss.width = width;\r\n }\r\n if (height) {\r\n wrapperCss.height = height;\r\n }\r\n\r\n if (!wrapperCss.width && !wrapperCss.height) {\r\n wrapperCss = undefined;\r\n }\r\n\r\n if (renderSvgWithWrapper === false) {\r\n return this.state.svgComponent ? this.renderSvgComponent(this.state.svgComponent) : null;\r\n }\r\n\r\n return (\r\n \r\n {this.state.svgComponent ? this.renderSvgComponent(this.state.svgComponent) : ()}\r\n \r\n );\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ComponentStyles } from \"@microsoft/fast-jss-manager\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\n\r\n/** CSS class names to apply to various {CardAction} components */\r\nexport interface IconCssClasses {\r\n /** CSS class for the image icon */\r\n icon?: string,\r\n /** CSS class for the inline icon */\r\n icon_inline?: string\r\n}\r\n\r\n/**\r\n * The main JSS stylesheet for {CardAction}\r\n */\r\nexport const IconStyles: ComponentStyles = {\r\n icon: {\r\n \"max-height\": \"100%\",\r\n \"max-width\": \"100%\"\r\n },\r\n icon_inline: {\r\n \"&&\": {\r\n width: \"auto\",\r\n height: \"auto\"\r\n }\r\n }\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { IconHandledProps as BaseHandledProps, IconProps as BaseIconProps, IconManagedClasses, IconUnhandledProps } from \"./Icon.props\";\r\nimport { Glyph, GlyphInline, GlyphType } from \"./Icon.props\";\r\nimport manageJss, { ManagedJSSProps } from \"@microsoft/fast-jss-manager-react\";\r\n\r\nimport { Icon as BaseIcon } from \"./Icon\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { IconCssClasses as IconClassNameContract } from \"./Icon.styles\";\r\nimport { IconStyles } from \"./Icon.styles\";\r\nimport { Subtract } from \"utility-types\";\r\n\r\nconst Icon = manageJss(IconStyles)(BaseIcon);\r\ntype Icon = InstanceType;\r\ntype IconHandledProps = Subtract;\r\ntype IconProps = ManagedJSSProps;\r\n\r\nexport {\r\n Icon,\r\n IconProps,\r\n IconClassNameContract,\r\n IconHandledProps,\r\n IconUnhandledProps,\r\n GlyphType,\r\n Glyph,\r\n GlyphInline\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nexport enum Market {\r\n BR = \"pt-br\",\r\n ENCA = \"en-ca\",\r\n FRCA = \"fr-ca\",\r\n FRFR = \"fr-fr\",\r\n IN = \"en-in\",\r\n ENUS = \"en-us\",\r\n ZHCN = \"zh-cn\"\r\n}","// © Microsoft Corporation. All rights reserved.\r\n/// \r\n\r\n/**\r\n * List of SVG icon types available by its key\r\n */\r\nexport const Accounts = () => import(/* webpackChunkName: \"icon-assets-Accounts\" */\"@svgr/webpack?-svgo!../../icons/Accounts.svg\");\r\nexport const AdChoices = () => import(/* webpackChunkName: \"icon-assets-AdChoices\" */\"@svgr/webpack?-svgo!../../icons/AdChoices.svg\");\r\nexport const AlertWhite = () => import(/* webpackChunkName: \"icon-assets-AlertWhite\" */\"@svgr/webpack?-svgo!../../icons/AlertWhite.svg\");\r\nexport const BingCardDefaultHotelImage = () => import(/* webpackChunkName: \"icon-assets-BingCardDefaultHotelImage\" */\"@svgr/webpack?-svgo!../../icons/BingCardDefaultHotelImage.svg\");\r\nexport const BingHotelSeePrice = () => import(/* webpackChunkName: \"icon-assets-BingHotelSeePrice\" */\"@svgr/webpack?-svgo!../../icons/BingHotelSeePrice.svg\");\r\nexport const BingLogo = () => import(/* webpackChunkName: \"icon-assets-BingLogo\" */\"@svgr/webpack?-svgo!../../icons/BingLogo.svg\");\r\nexport const BingRatingDarkStar = () => import(/* webpackChunkName: \"icon-assets-BingRatingDarkStar\" */\"@svgr/webpack?-svgo!../../icons/BingRatingDarkStar.svg\");\r\nexport const BingRatingLightStar = () => import(/* webpackChunkName: \"icon-assets-BingRatingLightStar\" */\"@svgr/webpack?-svgo!../../icons/BingRatingLightStar.svg\");\r\nexport const BingRatingDarkLightStar = () => import(/* webpackChunkName: \"icon-assets-BingRatingDarkLightStar\" */\"@svgr/webpack?-svgo!../../icons/BingRatingDarkLightStar.svg\");\r\nexport const BlowingHail = () => import(/* webpackChunkName: \"icon-assets-BlowingHail\" */\"@svgr/webpack?-svgo!../../icons/BlowingHail.svg\");\r\nexport const BlowingHailWhite = () => import(/* webpackChunkName: \"icon-assets-BlowingHailWhite\" */\"@svgr/webpack?-svgo!../../icons/BlowingHailWhite.svg\");\r\nexport const BlowingHailV2 = () => import(/* webpackChunkName: \"icon-assets-BlowingHailV2\" */\"@svgr/webpack?-svgo!../../icons/BlowingHailV2.svg\");\r\nexport const BlowingSnow = () => import(/* webpackChunkName: \"icon-assets-BlowingSnow\" */\"@svgr/webpack?-svgo!../../icons/BlowingSnow.svg\");\r\nexport const BlowingSnowWhite = () => import(/* webpackChunkName: \"icon-assets-BlowingSnowWhite\" */\"@svgr/webpack?-svgo!../../icons/BlowingSnowWhite.svg\");\r\nexport const BlowingSnowV2 = () => import(/* webpackChunkName: \"icon-assets-BlowingSnowV2\" */\"@svgr/webpack?-svgo!../../icons/BlowingSnowV2.svg\");\r\nexport const CDCSelfCheck = () => import(/* webpackChunkName: \"icon-assets-CDCLogo\" */\"@svgr/webpack?-svgo!../../icons/CDCSelfCheck.svg\");\r\nexport const Check = () => import(/* webpackChunkName: \"icon-assets-Check\" */\"@svgr/webpack?-svgo!../../icons/Check.svg\");\r\nexport const Chevron = () => import(/* webpackChunkName: \"icon-assets-Chevron\" */\"@svgr/webpack?-svgo!../../icons/Chevron.svg\");\r\nexport const ChevronDown = () => import(/* webpackChunkName: \"icon-assets-ChevronDown\" */\"@svgr/webpack?-svgo!../../icons/ChevronDown.svg\");\r\nexport const ChevronRight = () => import(/* webpackChunkName: \"icon-assets-ChevronRight\" */ \"@svgr/webpack?-svgo!../../icons/ChevronRight.svg\");\r\nexport const ChevronWhite = () => import(/* webpackChunkName: \"icon-assets-ChevronWhite\" */\"@svgr/webpack?-svgo!../../icons/ChevronWhite.svg\");\r\nexport const CircleClose = () => import(/* webpackChunkName: \"icon-assets-CircleClose\" */\"@svgr/webpack?-svgo!../../icons/CircleClose.svg\");\r\nexport const CircleChevron = () => import(/* webpackChunkName: \"icon-assets-CircleChevron\" */\"@svgr/webpack?-svgo!../../icons/CircleChevron.svg\");\r\nexport const ClearNight = () => import(/* webpackChunkName: \"icon-assets-ClearNight\" */\"@svgr/webpack?-svgo!../../icons/ClearNight.svg\");\r\nexport const ClearNightWhite = () => import(/* webpackChunkName: \"icon-assets-ClearNightWhite\" */\"@svgr/webpack?-svgo!../../icons/ClearNightWhite.svg\");\r\nexport const ClearNightV2 = () => import(/* webpackChunkName: \"icon-assets-ClearNightV2\" */\"@svgr/webpack?-svgo!../../icons/ClearNightV2.svg\");\r\nexport const ClinicalTrialBot = () => import(/* webpackChunkName: \"icon-assets-ClinicalTrialBot\" */\"@svgr/webpack?-svgo!../../icons/ClinicalTrialBot.svg\");\r\nexport const Close = () => import(/* webpackChunkName: \"icon-assets-Close\" */\"@svgr/webpack?-svgo!../../icons/Close.svg\");\r\nexport const CloseThin = () => import(/* webpackChunkName: \"icon-assets-CloseThin\" */\"@svgr/webpack?-svgo!../../icons/CloseThin.svg\");\r\nexport const Cloudy = () => import(/* webpackChunkName: \"icon-assets-Cloudy\" */\"@svgr/webpack?-svgo!../../icons/Cloudy.svg\");\r\nexport const CloudyWhite = () => import(/* webpackChunkName: \"icon-assets-CloudyWhite\" */\"@svgr/webpack?-svgo!../../icons/CloudyWhite.svg\");\r\nexport const CloudyV2 = () => import(/* webpackChunkName: \"icon-assets-CloudyV2\" */\"@svgr/webpack?-svgo!../../icons/CloudyV2.svg\");\r\nexport const Comment = () => import(/* webpackChunkName: \"icon-assets-Comment\" */\"@svgr/webpack?-svgo!../../icons/Comment.svg\");\r\nexport const Copy = () => import(/* webpackChunkName: \"icon-assets-Copy\" */\"@svgr/webpack?-svgo!../../icons/Copy.svg\");\r\nexport const CoronaVirusIcon = () => import(/* webpackChunkName: \"icon-coronavirus-icon\" */\"@svgr/webpack?-svgo!../../icons/CoronavirusIcon.svg\");\r\nexport const DarkModeHotel = () => import(/* webpackChunkName: \"icon-assets-DarkModeHotel\" */\"@svgr/webpack?-svgo!../../icons/DarkModeHotel.svg\");\r\nexport const DayTime = () => import(/* webpackChunkName: \"icon-assets-DayTime\" */\"@svgr/webpack?-svgo!../../icons/DayTime.svg\");\r\nexport const Delete = () => import(/* webpackChunkName: \"icon-assets-Delete\" */\"@svgr/webpack?-svgo!../../icons/Delete.svg\");\r\nexport const Discover = () => import(/* webpackChunkName: \"icon-assets-Discover\" */\"@svgr/webpack?-svgo!../../icons/Discover.svg\");\r\nexport const Dislike = () => import(/* webpackChunkName: \"icon-assets-Dislike\" */\"@svgr/webpack?-svgo!../../icons/Dislike.svg\");\r\nexport const DislikeText = () => import(/* webpackChunkName: \"icon-assets-DislikeText\" */\"@svgr/webpack?-svgo!../../icons/DislikeText.svg\");\r\nexport const Disliked = () => import(/* webpackChunkName: \"icon-assets-Disliked\" */\"@svgr/webpack?-svgo!../../icons/Disliked.svg\");\r\nexport const DislikedText = () => import(/* webpackChunkName: \"icon-assets-DislikedText\" */\"@svgr/webpack?-svgo!../../icons/DislikedText.svg\");\r\nexport const DislikedLight = () => import(/* webpackChunkName: \"icon-assets-DislikedLight\" */\"@svgr/webpack?-svgo!../../icons/DislikedLight.svg\");\r\nexport const Docx = () => import(/* webpackChunkName: \"icon-assets-Docx\" */\"@svgr/webpack?-svgo!../../icons/Docx.svg\");\r\nexport const DoubleTap = () => import(/* webpackChunkName: \"icon-assets-DoubleTap\" */\"@svgr/webpack?-svgo!../../icons/DoubleTap.svg\");\r\nexport const Download = () => import(/* webpackChunkName: \"icon-assets-Download\" */\"@svgr/webpack?-svgo!../../icons/Download.svg\");\r\nexport const DownloadNoFill = () => import(/* webpackChunkName: \"icon-assets-DownloadNoFill\" */\"@svgr/webpack?-svgo!../../icons/DownloadNoFill.svg\");\r\nexport const Edit = () => import(/* webpackChunkName: \"icon-assets-Edit\" */\"@svgr/webpack?-svgo!../../icons/Edit.svg\");\r\nexport const EditNoFill = () => import(/* webpackChunkName: \"icon-assets-EditNoFill\" */\"@svgr/webpack?-svgo!../../icons/EditNoFill.svg\");\r\nexport const Edited = () => import(/* webpackChunkName: \"icon-assets-Edited\" */\"@svgr/webpack?-svgo!../../icons/Edited.svg\");\r\nexport const EditedNoFill = () => import(/* webpackChunkName: \"icon-assets-EditedNoFill\" */\"@svgr/webpack?-svgo!../../icons/EditedNoFill.svg\");\r\nexport const Ellipses = () => import(/* webpackChunkName: \"icon-assets-Ellipses\" */\"@svgr/webpack?-svgo!../../icons/Ellipses.svg\");\r\nexport const EllipsesLight = () => import(/* webpackChunkName: \"icon-assets-EllipsesLight\" */\"@svgr/webpack?-svgo!../../icons/EllipsesLight.svg\");\r\nexport const EmptyDiscoverDark = () => import(/* webpackChunkName: \"icon-assets-EmptyDiscoverDark\" */\"@svgr/webpack?-svgo!../../icons/EmptyDiscoverDark.svg\");\r\nexport const EmptyDiscoverLight = () => import(/* webpackChunkName: \"icon-assets-EmptyDiscoverLight\" */\"@svgr/webpack?-svgo!../../icons/EmptyDiscoverLight.svg\");\r\nexport const EmptyMruDark = () => import(/* webpackChunkName: \"icon-assets-EmptyMruDark\" */\"@svgr/webpack?-svgo!../../icons/EmptyMruDark.svg\");\r\nexport const EmptyMruLight = () => import(/* webpackChunkName: \"icon-assets-EmptyMruLight\" */\"@svgr/webpack?-svgo!../../icons/EmptyMruLight.svg\");\r\nexport const EmptyPinnedDark = () => import(/* webpackChunkName: \"icon-assets-EmptyPinnedDark\" */\"@svgr/webpack?-svgo!../../icons/EmptyPinnedDark.svg\");\r\nexport const EmptyPinnedLight = () => import(/* webpackChunkName: \"icon-assets-EmptyPinnedLight\" */\"@svgr/webpack?-svgo!../../icons/EmptyPinnedLight.svg\");\r\nexport const EmptySharedDark = () => import(/* webpackChunkName: \"icon-assets-EmptySharedDark\" */\"@svgr/webpack?-svgo!../../icons/EmptySharedDark.svg\");\r\nexport const EmptySharedLight = () => import(/* webpackChunkName: \"icon-assets-EmptySharedLight\" */\"@svgr/webpack?-svgo!../../icons/EmptySharedLight.svg\");\r\nexport const Excel = () => import(/* webpackChunkName: \"icon-assets-Excel\" */\"@svgr/webpack?-svgo!../../icons/Excel.svg\");\r\nexport const Facebook = () => import(/* webpackChunkName: \"icon-assets-Facebook\" */\"@svgr/webpack?-svgo!../../icons/Facebook.svg\");\r\nexport const FacebookCircle = () => import(/* webpackChunkName: \"icon-assets-FacebookCircle\" */\"@svgr/webpack?-svgo!../../icons/FacebookCircle.svg\");\r\nexport const FacebookText = () => import(/* webpackChunkName: \"icon-assets-FacebookText\" */\"@svgr/webpack?-svgo!../../icons/FacebookText.svg\");\r\nexport const FacebookTextBlack = () => import(/* webpackChunkName: \"icon-assets-FacebookTextBlack\" */\"@svgr/webpack?-svgo!../../icons/FacebookTextBlack.svg\");\r\nexport const Fog = () => import(/* webpackChunkName: \"icon-assets-Fog\" */\"@svgr/webpack?-svgo!../../icons/Fog.svg\");\r\nexport const FogWhite = () => import(/* webpackChunkName: \"icon-assets-FogWhite\" */\"@svgr/webpack?-svgo!../../icons/FogWhite.svg\");\r\nexport const FogV2 = () => import(/* webpackChunkName: \"icon-assets-FogV2\" */\"@svgr/webpack?-svgo!../../icons/FogV2.svg\");\r\nexport const Form = () => import(/* webpackChunkName: \"icon-assets-Form\" */\"@svgr/webpack?-svgo!../../icons/Form.svg\");\r\nexport const Folder = () => import(/* webpackChunkName: \"icon-assets-Folder\" */\"@svgr/webpack?-svgo!../../icons/Folder.svg\");\r\nexport const FolderNoFill = () => import(/* webpackChunkName: \"icon-assets-FolderNoFill\" */\"@svgr/webpack?-svgo!../../icons/FolderNoFill.svg\");\r\nexport const FolderOpen = () => import(/* webpackChunkName: \"icon-assets-FolderOpen\" */\"@svgr/webpack?-svgo!../../icons/FolderOpen.svg\");\r\nexport const Forward = () => import(/* webpackChunkName: \"icon-assets-Forward\" */\"@svgr/webpack?-svgo!../../icons/Forward.svg\");\r\nexport const FreezingRain = () => import(/* webpackChunkName: \"icon-assets-FreezingRain\" */\"@svgr/webpack?-svgo!../../icons/FreezingRain.svg\");\r\nexport const FreezingRainWhite = () => import(/* webpackChunkName: \"icon-assets-FreezingRainWhite\" */\"@svgr/webpack?-svgo!../../icons/FreezingRainWhite.svg\");\r\nexport const FreezingRainV2 = () => import(/* webpackChunkName: \"icon-assets-FreezingRainV2\" */\"@svgr/webpack?-svgo!../../icons/FreezingRainV2.svg\");\r\nexport const GalleryFullscreen = () => import(/* webpackChunkName: \"icon-assets-GalleryFullscreen\" */\"@svgr/webpack?-svgo!../../icons/GalleryFullscreen.svg\");\r\nexport const GalleryMediaIcon = () => import(/* webpackChunkName: \"icon-assets-GalleryMediaIcon\" */\"@svgr/webpack?-svgo!../../icons/GalleryMediaIcon.svg\");\r\nexport const GeneralErrorDark = () => import(/* webpackChunkName: \"icon-assets-GeneralErrorDark\" */\"@svgr/webpack?-svgo!../../icons/GeneralErrorDark.svg\");\r\nexport const GeneralErrorLight = () => import(/* webpackChunkName: \"icon-assets-GeneralErrorLight\" */\"@svgr/webpack?-svgo!../../icons/GeneralErrorLight.svg\");\r\nexport const GenericFile = () => import(/* webpackChunkName: \"icon-assets-GenericFile\" */\"@svgr/webpack?-svgo!../../icons/GenericFile.svg\");\r\nexport const GridView = () => import(/* webpackChunkName: \"icon-assets-GridView\" */\"@svgr/webpack?-svgo!../../icons/GridView.svg\");\r\nexport const HailDay = () => import(/* webpackChunkName: \"icon-assets-HailDay\" */\"@svgr/webpack?-svgo!../../icons/HailDay.svg\");\r\nexport const HailDayWhite = () => import(/* webpackChunkName: \"icon-assets-HailDayWhite\" */\"@svgr/webpack?-svgo!../../icons/HailDayWhite.svg\");\r\nexport const HailDayV2 = () => import(/* webpackChunkName: \"icon-assets-HailDayV2\" */\"@svgr/webpack?-svgo!../../icons/HailDayV2.svg\");\r\nexport const HailNight = () => import(/* webpackChunkName: \"icon-assets-HailNight\" */\"@svgr/webpack?-svgo!../../icons/HailNight.svg\");\r\nexport const HailNightWhite = () => import(/* webpackChunkName: \"icon-assets-HailNightWhite\" */\"@svgr/webpack?-svgo!../../icons/HailNightWhite.svg\");\r\nexport const HailNightV2 = () => import(/* webpackChunkName: \"icon-assets-HailNightV2\" */\"@svgr/webpack?-svgo!../../icons/HailNightV2.svg\");\r\nexport const HazeSmoke = () => import(/* webpackChunkName: \"icon-assets-HazeSmoke\" */\"@svgr/webpack?-svgo!../../icons/HazeSmoke.svg\");\r\nexport const HazeSmokeWhite = () => import(/* webpackChunkName: \"icon-assets-HazeSmokeWhite\" */\"@svgr/webpack?-svgo!../../icons/HazeSmokeWhite.svg\");\r\nexport const HazeSmokeV2 = () => import(/* webpackChunkName: \"icon-assets-HazeSmokeV2\" */\"@svgr/webpack?-svgo!../../icons/HazeSmokeV2.svg\");\r\nexport const HeavySnow = () => import(/* webpackChunkName: \"icon-assets-HeavySnow\" */\"@svgr/webpack?-svgo!../../icons/HeavySnow.svg\");\r\nexport const HeavySnowWhite = () => import(/* webpackChunkName: \"icon-assets-HeavySnowWhite\" */\"@svgr/webpack?-svgo!../../icons/HeavySnowWhite.svg\");\r\nexport const HeavySnowV2 = () => import(/* webpackChunkName: \"icon-assets-HeavySnowV2\" */\"@svgr/webpack?-svgo!../../icons/HeavySnowV2.svg\");\r\nexport const Hide = () => import(/* webpackChunkName: \"icon-assets-Hide\" */\"@svgr/webpack?-svgo!../../icons/Hide.svg\");\r\nexport const HideStory = () => import(/* webpackChunkName: \"icon-assets-HideStory\" */\"@svgr/webpack?-svgo!../../icons/HideStory.svg\");\r\nexport const HideStoryV2 = () => import(/* webpackChunkName: \"icon-assets-HideStoryV2\" */\"@svgr/webpack?-svgo!../../icons/HideStoryV2.svg\");\r\nexport const Hotel = () => import(/* webpackChunkName: \"icon-assets-Hotel\" */\"@svgr/webpack?-svgo!../../icons/Hotel.svg\");\r\nexport const HurricaneFull = () => import(/* webpackChunkName: \"icon-assets-HurricaneFull\" */\"@svgr/webpack?-svgo!../../icons/HurricaneFull.svg\");\r\nexport const Hurricane = () => import(/* webpackChunkName: \"icon-assets-Hurricane\" */\"@svgr/webpack?-svgo!../../icons/Hurricane.svg\");\r\nexport const Hurricane1 = () => import(/* webpackChunkName: \"icon-assets-Hurricane1\" */\"@svgr/webpack?-svgo!../../icons/Hurricane1.svg\");\r\nexport const Hurricane2 = () => import(/* webpackChunkName: \"icon-assets-Hurricane2\" */\"@svgr/webpack?-svgo!../../icons/Hurricane2.svg\");\r\nexport const Hurricane3 = () => import(/* webpackChunkName: \"icon-assets-Hurricane3\" */\"@svgr/webpack?-svgo!../../icons/Hurricane3.svg\");\r\nexport const Hurricane4 = () => import(/* webpackChunkName: \"icon-assets-Hurricane4\" */\"@svgr/webpack?-svgo!../../icons/Hurricane4.svg\");\r\nexport const Hurricane5 = () => import(/* webpackChunkName: \"icon-assets-Hurricane5\" */\"@svgr/webpack?-svgo!../../icons/Hurricane5.svg\");\r\nexport const HurricaneTC = () => import(/* webpackChunkName: \"icon-assets-HurricaneTC\" */\"@svgr/webpack?-svgo!../../icons/HurricaneTC.svg\");\r\nexport const HurricaneTD = () => import(/* webpackChunkName: \"icon-assets-HurricaneTD\" */\"@svgr/webpack?-svgo!../../icons/HurricaneTD.svg\");\r\nexport const HurricaneTS = () => import(/* webpackChunkName: \"icon-assets-HurricaneTS\" */\"@svgr/webpack?-svgo!../../icons/HurricaneTS.svg\");\r\nexport const Information = () => import(/* webpackChunkName: \"icon-assets-Information\" */\"@svgr/webpack?-svgo!../../icons/Information.svg\");\r\nexport const InteractionRequiredDark = () => import(/* webpackChunkName: \"icon-assets-InteractionRequiredDark\" */\"@svgr/webpack?-svgo!../../icons/InteractionRequiredDark.svg\");\r\nexport const InteractionRequiredLight = () => import(/* webpackChunkName: \"icon-assets-InteractionRequiredLight\" */\"@svgr/webpack?-svgo!../../icons/InteractionRequiredLight.svg\");\r\nexport const Interested = () => import(/* webpackChunkName: \"icon-assets-Interested\" */\"@svgr/webpack?-svgo!../../icons/Interested.svg\");\r\nexport const RiverLayout = () => import(/* webpackChunkName: \"icon-assets-Layout\" */\"@svgr/webpack?-svgo!../../icons/RiverLayout.svg\");\r\nexport const StripeLayout = () => import(/* webpackChunkName: \"icon-assets-Layout\" */\"@svgr/webpack?-svgo!../../icons/StripeLayout.svg\");\r\nexport const ListMenu = () => import(/* webpackChunkName: \"icon-assets-ListMenu\" */\"@svgr/webpack?-svgo!../../icons/ListMenu.svg\");\r\nexport const LightRain = () => import(/* webpackChunkName: \"icon-assets-LightRain\" */\"@svgr/webpack?-svgo!../../icons/LightRain.svg\");\r\nexport const LightRainWhite = () => import(/* webpackChunkName: \"icon-assets-LightRainWhite\" */\"@svgr/webpack?-svgo!../../icons/LightRainWhite.svg\");\r\nexport const LightRainV2 = () => import(/* webpackChunkName: \"icon-assets-LightRainV2\" */\"@svgr/webpack?-svgo!../../icons/LightRainV2.svg\");\r\nexport const LightSnow = () => import(/* webpackChunkName: \"icon-assets-LightSnow\" */\"@svgr/webpack?-svgo!../../icons/LightSnow.svg\");\r\nexport const LightSnowWhite = () => import(/* webpackChunkName: \"icon-assets-LightSnowWhite\" */\"@svgr/webpack?-svgo!../../icons/LightSnowWhite.svg\");\r\nexport const LightSnowV2 = () => import(/* webpackChunkName: \"icon-assets-LightSnowV2\" */\"@svgr/webpack?-svgo!../../icons/LightSnowV2.svg\");\r\nexport const Like = () => import(/* webpackChunkName: \"icon-assets-Like\" */\"@svgr/webpack?-svgo!../../icons/Like.svg\");\r\nexport const LikeText = () => import(/* webpackChunkName: \"icon-assets-LikeText\" */\"@svgr/webpack?-svgo!../../icons/LikeText.svg\");\r\nexport const Liked = () => import(/* webpackChunkName: \"icon-assets-Liked\" */\"@svgr/webpack?-svgo!../../icons/Liked.svg\");\r\nexport const LikedText = () => import(/* webpackChunkName: \"icon-assets-LikedText\" */\"@svgr/webpack?-svgo!../../icons/LikedText.svg\");\r\nexport const Line = () => import(/* webpackChunkName: \"icon-assets-Line\" */\"@svgr/webpack?-svgo!../../icons/Line.svg\");\r\nexport const Link = () => import(/* webpackChunkName: \"icon-assets-Link\" */\"@svgr/webpack?-svgo!../../icons/Link.svg\");\r\nexport const LinkedIn = () => import(/* webpackChunkName: \"icon-assets-LinkedIn\" */\"@svgr/webpack?-svgo!../../icons/LinkedIn.svg\");\r\nexport const LinkedInBlack = () => import(/* webpackChunkName: \"icon-assets-LinkedInBlack\" */\"@svgr/webpack?-svgo!../../icons/LinkedInBlack.svg\");\r\nexport const LinkedInText = () => import(/* webpackChunkName: \"icon-assets-LinkedInText\" */\"@svgr/webpack?-svgo!../../icons/LinkedInText.svg\");\r\nexport const Locate = () => import(/* webpackChunkName: \"icon-assets-Locate\" */\"@svgr/webpack?-svgo!../../icons/Locate.svg\");\r\nexport const LocateWhite = () => import(/* webpackChunkName: \"icon-assets-LocateWhite\" */\"@svgr/webpack?-svgo!../../icons/LocateWhite.svg\");\r\nexport const LocationDetect = () => import(/* webpackChunkName: \"icon-assets-LocationDetect\" */\"@svgr/webpack?-svgo!../../icons/LocationDetect.svg\");\r\nexport const Mail = () => import(/* webpackChunkName: \"icon-assets-Mail\" */\"@svgr/webpack?-svgo!../../icons/Mail.svg\");\r\nexport const MailBlack = () => import(/* webpackChunkName: \"icon-assets-MailBlack\" */\"@svgr/webpack?-svgo!../../icons/MailBlack.svg\");\r\nexport const MailNoFill = () => import(/* webpackChunkName: \"icon-assets-MailNoFill\" */\"@svgr/webpack?-svgo!../../icons/MailNoFill.svg\");\r\nexport const MailRoundedCorners = () => import(/* webpackChunkName: \"icon-assets-MailRoundedCorners\" */\"@svgr/webpack?-svgo!../../icons/MailRoundedCorners.svg\");\r\nexport const ManagedBriefcase = () => import(/* webpackChunkName: \"icon-assets-ManagedBriefcase\" */\"@svgr/webpack?-svgo!../../icons/ManagedBriefcase.svg\");\r\nexport const ManagedBriefcaseNoFill = () => import(/* webpackChunkName: \"icon-assets-ManagedBriefcaseNoFill\" */\"@svgr/webpack?-svgo!../../icons/ManagedBriefcaseNoFill.svg\");\r\nexport const MapZoomIn = () => import(/* webpackChunkName: \"icon-assets-MapZoomIn\" */\"@svgr/webpack?-svgo!../../icons/MapZoomIn.svg\");\r\nexport const MapZoomOut = () => import(/* webpackChunkName: \"icon-assets-MapZoomOut\" */\"@svgr/webpack?-svgo!../../icons/MapZoomOut.svg\");\r\nexport const Message = () => import(/* webpackChunkName: \"icon-assets-Message\" */\"@svgr/webpack?-svgo!../../icons/Message.svg\");\r\nexport const MessageNoFill = () => import(/* webpackChunkName: \"icon-assets-MessageNoFill\" */\"@svgr/webpack?-svgo!../../icons/MessageNoFill.svg\");\r\nexport const Messages = () => import(/* webpackChunkName: \"icon-assets-Messages\" */\"@svgr/webpack?-svgo!../../icons/Messages.svg\");\r\nexport const MsnLogo = () => import(/* webpackChunkName: \"icon-assets-MsnLogo\" */\"@svgr/webpack?-svgo!../../icons/MsnLogo.svg\");\r\nexport const MicrosoftLogo = () => import(/* webpackChunkName: \"icon-assets-MicrosoftLogo\" */\"@svgr/webpack?-svgo!../../icons/MicrosoftLogo.svg\");\r\nexport const MicrosoftNews = () => import(/* webpackChunkName: \"icon-assets-MicrosoftNews\" */\"@svgr/webpack?-svgo!../../icons/MicrosoftNews.svg\");\r\nexport const MicrosoftNewsFull = () => import(/* webpackChunkName: \"icon-assets-MicrosoftNews\" */\"@svgr/webpack?-svgo!../../icons/MicrosoftNewsFull.svg\");\r\nexport const MicrosoftNewsFull_FR = () => import(/* webpackChunkName: \"icon-assets-MicrosoftNews_FR\" */\"@svgr/webpack?-svgo!../../icons/MicrosoftNewsFull_FR.svg\");\r\nexport const MicrosoftNewsFull_ZH = () => import(/* webpackChunkName: \"icon-assets-MicrosoftNews_ZH\" */\"@svgr/webpack?-svgo!../../icons/MicrosoftNewsFull_ZH.svg\");\r\nexport const ModerateRain = () => import(/* webpackChunkName: \"icon-assets-ModerateRain\" */\"@svgr/webpack?-svgo!../../icons/ModerateRain.svg\");\r\nexport const ModerateRainWhite = () => import(/* webpackChunkName: \"icon-assets-ModerateRainWhite\" */\"@svgr/webpack?-svgo!../../icons/ModerateRainWhite.svg\");\r\nexport const ModerateRainV2 = () => import(/* webpackChunkName: \"icon-assets-ModerateRainV2\" */\"@svgr/webpack?-svgo!../../icons/ModerateRainV2.svg\");\r\nexport const More = () => import(/* webpackChunkName: \"icon-assets-More\" */\"@svgr/webpack?-svgo!../../icons/More.svg\");\r\nexport const Movie = () => import(/* webpackChunkName: \"icon-assets-Movie\" */\"@svgr/webpack?-svgo!../../icons/Movie.svg\");\r\nexport const NewsArticle = () => import(/* webpackChunkName: \"icon-assets-NewsArticle\" */\"@svgr/webpack?-svgo!../../icons/NewsArticle.svg\");\r\nexport const NightTime = () => import(/* webpackChunkName: \"icon-assets-NightTime\" */\"@svgr/webpack?-svgo!../../icons/NightTime.svg\");\r\nexport const NotificationFivePlusSign = () => import(/* webpackChunkName: \"icon-assets-Notification-Five-Plus-Sign\" */\"@svgr/webpack?-svgo!../../icons/NotificationFivePlusSign.svg\");\r\nexport const NotificationRefreshArrow = () => import(/* webpackChunkName: \"icon-assets-Notification-Five-Plus-Sign\" */\"@svgr/webpack?-svgo!../../icons/NotificationRefreshArrow.svg\");\r\nexport const Office = () => import(/* webpackChunkName: \"icon-assets-Office\" */\"@svgr/webpack?-svgo!../../icons/Office.svg\");\r\nexport const OfficeFormsLogo = () => import(/* webpackChunkName: \"icon-assets-OfficeFormsLogo\" */\"@svgr/webpack?-svgo!../../icons/OfficeFormsLogo.svg\");\r\nexport const OneDrive = () => import(/* webpackChunkName: \"icon-assets-OneDrive\" */\"@svgr/webpack?-svgo!../../icons/OneDrive.svg\");\r\nexport const OneNote = () => import(/* webpackChunkName: \"icon-assets-OneNote\" */\"@svgr/webpack?-svgo!../../icons/OneNote.svg\");\r\nexport const Onetoc = () => import(/* webpackChunkName: \"icon-assets-Onetoc\" */\"@svgr/webpack?-svgo!../../icons/Onetoc.svg\");\r\nexport const Open = () => import(/* webpackChunkName: \"icon-assets-Open\" */\"@svgr/webpack?-svgo!../../icons/Open.svg\");\r\nexport const OpenSquared = () => import(/* webpackChunkName: \"icon-assets-OpenSquared\" */\"@svgr/webpack?-svgo!../../icons/OpenSquared.svg\");\r\nexport const Outlook = () => import(/* webpackChunkName: \"icon-assets-Outlook\" */\"@svgr/webpack?-svgo!../../icons/Outlook.svg\");\r\nexport const PartlyCloudyDay = () => import(/* webpackChunkName: \"icon-assets-PartlyCloudyDay\" */\"@svgr/webpack?-svgo!../../icons/PartlyCloudyDay.svg\");\r\nexport const PartlyCloudyDayWhite = () => import(/* webpackChunkName: \"icon-assets-PartlyCloudyDayWhite\" */\"@svgr/webpack?-svgo!../../icons/PartlyCloudyDayWhite.svg\");\r\nexport const PartlyCloudyDayV2 = () => import(/* webpackChunkName: \"icon-assets-PartlyCloudyDayV2\" */\"@svgr/webpack?-svgo!../../icons/PartlyCloudyDayV2.svg\");\r\nexport const PartlyCloudyNight = () => import(/* webpackChunkName: \"icon-assets-PartlyCloudyNight\" */\"@svgr/webpack?-svgo!../../icons/PartlyCloudyNight.svg\");\r\nexport const PartlyCloudyNightWhite = () => import(/* webpackChunkName: \"icon-assets-PartlyCloudyNightWhite\" */\"@svgr/webpack?-svgo!../../icons/PartlyCloudyNightWhite.svg\");\r\nexport const PartlyCloudyNightV2 = () => import(/* webpackChunkName: \"icon-assets-PartlyCloudyNightV2\" */\"@svgr/webpack?-svgo!../../icons/PartlyCloudyNightV2.svg\");\r\nexport const Pdf = () => import(/* webpackChunkName: \"icon-assets-Pdf\" */\"@svgr/webpack?-svgo!../../icons/Pdf.svg\");\r\nexport const People = () => import(/* webpackChunkName: \"icon-assets-People\" */\"@svgr/webpack?-svgo!../../icons/People.svg\");\r\nexport const Pencil = () => import(/* webpackChunkName: \"icon-assets-Pencil\" */\"@svgr/webpack?-svgo!../../icons/Pencil.svg\");\r\nexport const Pin = () => import(/* webpackChunkName: \"icon-assets-Pin\" */\"@svgr/webpack?-svgo!../../icons/Pin.svg\");\r\nexport const PowerBI = () => import(/* webpackChunkName: \"icon-assets-PowerBI\" */\"@svgr/webpack?-svgo!../../icons/PowerBI.svg\");\r\nexport const PowerPoint = () => import(/* webpackChunkName: \"icon-assets-PowerPoint\" */\"@svgr/webpack?-svgo!../../icons/PowerPoint.svg\");\r\nexport const PollResults = () => import(/* webpackChunkName: \"icon-poll-results\" */\"@svgr/webpack?-svgo!../../icons/PollResults.svg\");\r\nexport const Pptx = () => import(/* webpackChunkName: \"icon-assets-Pptx\" */\"@svgr/webpack?-svgo!../../icons/Pptx.svg\");\r\nexport const PriceDrop = () => import(/* webpackChunkName: \"icon-assets-PriceDrop\" */\"@svgr/webpack?-svgo!../../icons/PriceDrop.svg\");\r\nexport const PriceDropBlue = () => import(/* webpackChunkName: \"icon-assets-PriceDropBlue\" */\"@svgr/webpack?-svgo!../../icons/PriceDropBlue.svg\");\r\nexport const Project = () => import(/* webpackChunkName: \"icon-assets-Project\" */\"@svgr/webpack?-svgo!../../icons/Project.svg\");\r\nexport const Radar = () => import(/* webpackChunkName: \"icon-assets-Radar\" */\"@svgr/webpack?-svgo!../../icons/Radar.svg\");\r\nexport const RainShowersDay = () => import(/* webpackChunkName: \"icon-assets-RainShowersDay\" */\"@svgr/webpack?-svgo!../../icons/RainShowersDay.svg\");\r\nexport const RainShowersDayWhite = () => import(/* webpackChunkName: \"icon-assets-RainShowersDayWhite\" */\"@svgr/webpack?-svgo!../../icons/RainShowersDayWhite.svg\");\r\nexport const RainShowersDayV2 = () => import(/* webpackChunkName: \"icon-assets-RainShowersDayV2\" */\"@svgr/webpack?-svgo!../../icons/RainShowersDayV2.svg\");\r\nexport const RainShowersNight = () => import(/* webpackChunkName: \"icon-assets-RainShowersNight\" */\"@svgr/webpack?-svgo!../../icons/RainShowersNight.svg\");\r\nexport const RainShowersNightWhite = () => import(/* webpackChunkName: \"icon-assets-RainShowersNightWhite\" */\"@svgr/webpack?-svgo!../../icons/RainShowersNightWhite.svg\");\r\nexport const RainShowersNightV2 = () => import(/* webpackChunkName: \"icon-assets-RainShowersNightV2\" */\"@svgr/webpack?-svgo!../../icons/RainShowersNightV2.svg\");\r\nexport const RainSnow = () => import(/* webpackChunkName: \"icon-assets-RainSnow\" */\"@svgr/webpack?-svgo!../../icons/RainSnow.svg\");\r\nexport const RainSnowWhite = () => import(/* webpackChunkName: \"icon-assets-RainSnowWhite\" */\"@svgr/webpack?-svgo!../../icons/RainSnowWhite.svg\");\r\nexport const RainSnowV2 = () => import(/* webpackChunkName: \"icon-assets-RainSnowV2\" */\"@svgr/webpack?-svgo!../../icons/RainSnowV2.svg\");\r\nexport const RainSnowShowersDay = () => import(/* webpackChunkName: \"icon-assets-RainSnowShowersDay\" */\"@svgr/webpack?-svgo!../../icons/RainSnowShowersDay.svg\");\r\nexport const RainSnowShowersDayWhite = () => import(/* webpackChunkName: \"icon-assets-RainSnowShowersDayWhite\" */\"@svgr/webpack?-svgo!../../icons/RainSnowShowersDayWhite.svg\");\r\nexport const RainSnowShowersNight = () => import(/* webpackChunkName: \"icon-assets-RainSnowShowersNight\" */\"@svgr/webpack?-svgo!../../icons/RainSnowShowersNight.svg\");\r\nexport const RainSnowShowersNightWhite = () => import(/* webpackChunkName: \"icon-assets-RainSnowShowersNightWhite\" */\"@svgr/webpack?-svgo!../../icons/RainSnowShowersNightWhite.svg\");\r\nexport const RainSnowShowersNightV2 = () => import(/* webpackChunkName: \"icon-assets-RainSnowShowersNightV2\" */\"@svgr/webpack?-svgo!../../icons/RainSnowShowersNightV2.svg\");\r\nexport const Refresh = () => import(/* webpackChunkName: \"icon-assets-Refresh\" */\"@svgr/webpack?-svgo!../../icons/Refresh.svg\");\r\nexport const Remove = () => import(/* webpackChunkName: \"icon-assets-Remove\" */\"@svgr/webpack?-svgo!../../icons/Remove.svg\");\r\nexport const VideoMediaIcon = () => import(/* webpackChunkName: \"icon-assets-VideoMediaIcon\" */\"@svgr/webpack?-svgo!../../icons/VideoMediaIcon.svg\");\r\nexport const VideoPlay = () => import(/* webpackChunkName: \"icon-assets-VideoPlay\" */\"@svgr/webpack?-svgo!../../icons/VideoPlay.svg\");\r\nexport const Save = () => import(/* webpackChunkName: \"icon-assets-Save\" */\"@svgr/webpack?-svgo!../../icons/Save.svg\");\r\nexport const Saved = () => import(/* webpackChunkName: \"icon-assets-Saved\" */\"@svgr/webpack?-svgo!../../icons/Saved.svg\");\r\nexport const SetHome = () => import(/* webpackChunkName: \"icon-assets-SetHome\" */\"@svgr/webpack?-svgo!../../icons/SetHome.svg\");\r\nexport const Search = () => import(/* webpackChunkName: \"icon-assets-Search\" */\"@svgr/webpack?-svgo!../../icons/Search.svg\");\r\nexport const Share = () => import(/* webpackChunkName: \"icon-assets-Share\" */\"@svgr/webpack?-svgo!../../icons/Share.svg\");\r\nexport const ShareLight = () => import(/* webpackChunkName: \"icon-assets-ShareLight\" */\"@svgr/webpack?-svgo!../../icons/ShareLight.svg\");\r\nexport const ShareNoFill = () => import(/* webpackChunkName: \"icon-assets-ShareNoFill\" */\"@svgr/webpack?-svgo!../../icons/ShareNoFill.svg\");\r\nexport const ShareRoundedCorners = () => import(/* webpackChunkName: \"icon-assets-ShareRoundedCorners\" */\"@svgr/webpack?-svgo!../../icons/ShareRoundedCorners.svg\");\r\nexport const Sharepoint = () => import(/* webpackChunkName: \"icon-assets-Sharepoint\" */\"@svgr/webpack?-svgo!../../icons/Sharepoint.svg\");\r\nexport const Shopping = () => import(/* webpackChunkName: \"icon-assets-Shopping\" */\"@svgr/webpack?-svgo!../../icons/Shopping.svg\");\r\nexport const ShoppingDealsDark = () => import(/* webpackChunkName: \"icon-assets-ShoppingDealsDark\" */\"@svgr/webpack?-svgo!../../icons/ShoppingDealsDark.svg\");\r\nexport const ShoppingDealsLight = () => import(/* webpackChunkName: \"icon-assets-ShoppingDealsLight\" */\"@svgr/webpack?-svgo!../../icons/ShoppingDealsLight.svg\");\r\nexport const Skype = () => import(/* webpackChunkName: \"icon-assets-Skype\" */\"@svgr/webpack?-svgo!../../icons/Skype.svg\");\r\nexport const SkypeOffice = () => import(/* webpackChunkName: \"icon-assets-SkypeOffice\" */\"@svgr/webpack?-svgo!../../icons/SkypeOffice.svg\");\r\nexport const SnowShowersDay = () => import(/* webpackChunkName: \"icon-assets-SnowShowersDay\" */\"@svgr/webpack?-svgo!../../icons/SnowShowersDay.svg\");\r\nexport const SnowShowersDayWhite = () => import(/* webpackChunkName: \"icon-assets-SnowShowersDayWhite\" */\"@svgr/webpack?-svgo!../../icons/SnowShowersDayWhite.svg\");\r\nexport const SnowShowersDayV2 = () => import(/* webpackChunkName: \"icon-assets-SnowShowersDayV2\" */\"@svgr/webpack?-svgo!../../icons/SnowShowersDayV2.svg\");\r\nexport const SnowShowersNight = () => import(/* webpackChunkName: \"icon-assets-SnowShowersNight\" */\"@svgr/webpack?-svgo!../../icons/SnowShowersNight.svg\");\r\nexport const SnowShowersNightWhite = () => import(/* webpackChunkName: \"icon-assets-SnowShowersNightWhite\" */\"@svgr/webpack?-svgo!../../icons/SnowShowersNightWhite.svg\");\r\nexport const SnowShowersNightV2 = () => import(/* webpackChunkName: \"icon-assets-SnowShowersNightV2\" */\"@svgr/webpack?-svgo!../../icons/SnowShowersNightV2.svg\");\r\nexport const Star = () => import(/* webpackChunkName: \"icon-assets-Star\" */\"@svgr/webpack?-svgo!../../icons/Star.svg\");\r\nexport const StarFill = () => import(/* webpackChunkName: \"icon-assets-StarFill\" */\"@svgr/webpack?-svgo!../../icons/StarFill.svg\");\r\nexport const StarFollow = () => import(/* webpackChunkName: \"icon-assets-StarFollow\" */\"@svgr/webpack?-svgo!../../icons/StarFollow.svg\");\r\nexport const StarFollowBlue = () => import(/* webpackChunkName: \"icon-assets-StarFollowBlue\" */\"@svgr/webpack?-svgo!../../icons/StarFollowBlue.svg\");\r\nexport const Stars = () => import(/* webpackChunkName: \"icon-assets-Stars\" */\"@svgr/webpack?-svgo!../../icons/Stars.svg\");\r\nexport const SunnyDay = () => import(/* webpackChunkName: \"icon-assets-SunnyDay\" */\"@svgr/webpack?-svgo!../../icons/SunnyDay.svg\");\r\nexport const SunnyDayWhite = () => import(/* webpackChunkName: \"icon-assets-SunnyDayWhite\" */\"@svgr/webpack?-svgo!../../icons/SunnyDayWhite.svg\");\r\nexport const SunnyDayV2 = () => import(/* webpackChunkName: \"icon-assets-SunnyDayV2\" */\"@svgr/webpack?-svgo!../../icons/SunnyDayV2.svg\");\r\nexport const Sway = () => import(/* webpackChunkName: \"icon-assets-Sway\" */\"@svgr/webpack?-svgo!../../icons/Sway.svg\");\r\nexport const SwayApp = () => import(/* webpackChunkName: \"icon-assets-SwayApp\" */\"@svgr/webpack?-svgo!../../icons/SwayApp.svg\");\r\nexport const Teams = () => import(/* webpackChunkName: \"icon-assets-Teams\" */\"@svgr/webpack?-svgo!../../icons/Teams.svg\");\r\nexport const ThumbnailView = () => import(/* webpackChunkName: \"icon-assets-ThumbnailView\" */\"@svgr/webpack?-svgo!../../icons/ThumbnailView.svg\");\r\nexport const Thunderstorms = () => import(/* webpackChunkName: \"icon-assets-Thunderstorms\" */\"@svgr/webpack?-svgo!../../icons/Thunderstorms.svg\");\r\nexport const ThunderstormsWhite = () => import(/* webpackChunkName: \"icon-assets-ThunderstormsWhite\" */\"@svgr/webpack?-svgo!../../icons/ThunderstormsWhite.svg\");\r\nexport const ThunderstormsV2 = () => import(/* webpackChunkName: \"icon-assets-ThunderstormsV2\" */\"@svgr/webpack?-svgo!../../icons/ThunderstormsV2.svg\");\r\nexport const Trending = () => import(/* webpackChunkName: \"icon-assets-Trending\" */\"@svgr/webpack?-svgo!../../icons/Trending.svg\");\r\nexport const Twitter = () => import(/* webpackChunkName: \"icon-assets-Twitter\" */\"@svgr/webpack?-svgo!../../icons/Twitter.svg\");\r\nexport const TwitterBlack = () => import(/* webpackChunkName: \"icon-assets-TwitterBlack\" */\"@svgr/webpack?-svgo!../../icons/TwitterBlack.svg\");\r\nexport const TwitterNoFill = () => import(/* webpackChunkName: \"icon-assets-TwitterNoFill\" */\"@svgr/webpack?-svgo!../../icons/TwitterNoFill.svg\");\r\nexport const TwitterText = () => import(/* webpackChunkName: \"icon-assets-TwitterText\" */\"@svgr/webpack?-svgo!../../icons/TwitterText.svg\");\r\nexport const Unpin = () => import(/* webpackChunkName: \"icon-assets-Unpin\" */\"@svgr/webpack?-svgo!../../icons/Unpin.svg\");\r\nexport const VerticalSeparator = () => import(/* webpackChunkName: \"icon-assets-VerticalSeparator\" */\"@svgr/webpack?-svgo!../../icons/VerticalSeparator.svg\");\r\nexport const Video = () => import(/* webpackChunkName: \"icon-assets-Video\" */\"@svgr/webpack?-svgo!../../icons/Video.svg\");\r\nexport const VideoFallback = () => import(/* webpackChunkName: \"icon-assets-VideoFallback\" */\"@svgr/webpack?-svgo!../../icons/VideoFallback.svg\");\r\nexport const Visio = () => import(/* webpackChunkName: \"icon-assets-Visio\" */\"@svgr/webpack?-svgo!../../icons/Visio.svg\");\r\nexport const Vkcom = () => import(/* webpackChunkName: \"icon-assets-Vkcom\" */\"@svgr/webpack?-svgo!../../icons/Vkcom.svg\");\r\nexport const Vsdx = () => import(/* webpackChunkName: \"icon-assets-Vsdx\" */\"@svgr/webpack?-svgo!../../icons/Vsdx.svg\");\r\nexport const WaterDrop = () => import(/* webpackChunkName: \"icon-assets-WaterDrop\" */\"@svgr/webpack?-svgo!../../icons/WaterDrop.svg\");\r\nexport const WaterDropL2 = () => import(/* webpackChunkName: \"icon-assets-WaterDropL2\" */\"@svgr/webpack?-svgo!../../icons/WaterDropL2.svg\");\r\nexport const WeatherAlert = () => import(/* webpackChunkName: \"icon-assets-WeatherAlert\" */\"@svgr/webpack?-svgo!../../icons/WeatherAlert.svg\");\r\nexport const WeatherBarometer = () => import(/* webpackChunkName: \"icon-assets-WeatherBarometer\" */\"@svgr/webpack?-svgo!../../icons/WeatherBarometer.svg\");\r\nexport const WeatherCloud = () => import(/* webpackChunkName: \"icon-assets-WeatherCloud\" */\"@svgr/webpack?-svgo!../../icons/WeatherCloud.svg\");\r\nexport const WeatherDewpoint = () => import(/* webpackChunkName: \"icon-assets-WeatherDewpoint\" */\"@svgr/webpack?-svgo!../../icons/WeatherDewpoint.svg\");\r\nexport const WeatherExpand = () => import(/* webpackChunkName: \"icon-assets-WeatherExpand\" */\"@svgr/webpack?-svgo!../../icons/WeatherExpand.svg\");\r\nexport const WeatherIcon = () => import(/* webpackChunkName: \"icon-assets-WeatherIcon\" */\"@svgr/webpack?-svgo!../../icons/WeatherIcon.svg\");\r\nexport const WeatherMapPause = () => import(/* webpackChunkName: \"icon-assets-WeatherMapPause\" */\"@svgr/webpack?-svgo!../../icons/WeatherMapPause.svg\");\r\nexport const WeatherMapPlay = () => import(/* webpackChunkName: \"icon-assets-WeatherMapPlay\" */\"@svgr/webpack?-svgo!../../icons/WeatherMapPlay.svg\");\r\nexport const WeatherPrecipitation = () => import(/* webpackChunkName: \"icon-assets-WeatherPrecipitation\" */\"@svgr/webpack?-svgo!../../icons/WeatherPrecipitation.svg\");\r\nexport const WeatherSatellite = () => import(/* webpackChunkName: \"icon-assets-WeatherSatellite\" */\"@svgr/webpack?-svgo!../../icons/WeatherSatellite.svg\");\r\nexport const WeatherTemperature = () => import(/* webpackChunkName: \"icon-assets-WeatherTemperature\" */\"@svgr/webpack?-svgo!../../icons/WeatherTemperature.svg\");\r\nexport const WeatherVisiblity = () => import(/* webpackChunkName: \"icon-assets-WeatherVisiblity\" */\"@svgr/webpack?-svgo!../../icons/WeatherVisiblity.svg\");\r\nexport const WeatherWind = () => import(/* webpackChunkName: \"icon-assets-WeatherWind\" */\"@svgr/webpack?-svgo!../../icons/WeatherWind.svg\");\r\nexport const WeatherWindDir = () => import(/* webpackChunkName: \"icon-assets-WeatherWindDir\" */\"@svgr/webpack?-svgo!../../icons/WeatherWindDir.svg\");\r\nexport const WeeklyAdsDark = () => import(/* webpackChunkName: \"icon-assets-WeeklyAdsDark\" */\"@svgr/webpack?-svgo!../../icons/WeeklyAdsDark.svg\");\r\nexport const WeeklyAdsLight = () => import(/* webpackChunkName: \"icon-assets-WeeklyAdsLight\" */\"@svgr/webpack?-svgo!../../icons/WeeklyAdsLight.svg\");\r\nexport const WhatsApp = () => import(/* webpackChunkName: \"icon-assets-WhatsApp\" */\"@svgr/webpack?-svgo!../../icons/WhatsApp.svg\");\r\nexport const WhatsAppBlack = () => import(/* webpackChunkName: \"icon-assets-WhatsAppBlack\" */\"@svgr/webpack?-svgo!../../icons/WhatsAppBlack.svg\");\r\nexport const Windy = () => import(/* webpackChunkName: \"icon-assets-Windy\" */\"@svgr/webpack?-svgo!../../icons/Windy.svg\");\r\nexport const WindyWhite = () => import(/* webpackChunkName: \"icon-assets-WindyWhite\" */\"@svgr/webpack?-svgo!../../icons/WindyWhite.svg\");\r\nexport const WindyV2 = () => import(/* webpackChunkName: \"icon-assets-WindyV2\" */\"@svgr/webpack?-svgo!../../icons/WindyV2.svg\");\r\nexport const Word = () => import(/* webpackChunkName: \"icon-assets-Word\" */\"@svgr/webpack?-svgo!../../icons/Word.svg\");\r\nexport const World = () => import(/* webpackChunkName: \"icon-assets-World\" */\"@svgr/webpack?-svgo!../../icons/World.svg\");\r\nexport const Xlsx = () => import(/* webpackChunkName: \"icon-assets-Xlsx\" */\"@svgr/webpack?-svgo!../../icons/Xlsx.svg\");\r\nexport const Yammer = () => import(/* webpackChunkName: \"icon-assets-Yammer\" */\"@svgr/webpack?-svgo!../../icons/Yammer.svg\");\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ILoggingService } from \"clientcore-infrastructure-analytics/ILoggingService\";\r\nimport { Logger, logger } from \"./Logger\";\r\nimport { getQueryParameterByName } from \"./Util\";\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\n\r\ndeclare global {\r\n interface Window {\r\n webpackRequire: any;\r\n }\r\n}\r\n\r\ndeclare let __webpack_require__: any;\r\n\r\n/**\r\n * Logger that simply logs to console with minimum dependencies.\r\n * Used for bootstrap/inline script where we don't need any logging nor its dependencies.\r\n */\r\nexport class LiteLogger implements Logger {\r\n\r\n /** Backing field for the isDebug function */\r\n private isDebugEnabled: boolean;\r\n\r\n /**\r\n * The constructor\r\n */\r\n public constructor() {\r\n if (canUseDOM()) {\r\n this.isDebugEnabled = ((getQueryParameterByName(window.location.href, \"debug\") || \"\").toLowerCase() in { 1: 1, true: 1 });\r\n\r\n // On debug mode, make webpack_require available as global function\r\n // so any code in packages could be triggered from console. Handy for debugging.\r\n if (this.isDebugEnabled && !global[\"TEST_ENV\"]) {\r\n window.webpackRequire = __webpack_require__;\r\n }\r\n } else {\r\n this.isDebugEnabled = false; // isDebugEnabled should be set explictly using the setDebug method\r\n }\r\n }\r\n\r\n /**\r\n * Returns the logging service\r\n * @returns {ILoggingService}\r\n */\r\n public getLoggingService(): ILoggingService {\r\n return null;\r\n }\r\n\r\n /**\r\n * Checks whether we're running in debug mode.\r\n * @returns True when either debug=1 or debug=true is present as a query param, otherwise false.\r\n */\r\n public isDebug(): boolean {\r\n return this.isDebugEnabled;\r\n }\r\n\r\n /**\r\n * Override the isDebug setting. Useful when server side rendering.\r\n */\r\n public setDebug(isDebug: boolean): void {\r\n this.isDebugEnabled = isDebug;\r\n }\r\n\r\n /**\r\n * Set the tags to filter logs.\r\n * @param tags Tags to filter logs. If empty, do not filter.\r\n */\r\n public setTags(tags: string[]): void {\r\n // Not supported in console logger at the moment\r\n }\r\n\r\n /**\r\n * Log console message.\r\n * Note that these are not output to the console unless you're in debug mode.\r\n * @param message - Message to log.\r\n * @param tags - Optional tags for specifying log type for filtering logs.\r\n */\r\n public log(message: string, tags?: string[]): void {\r\n if (this.isDebug()) {\r\n console.info(message);\r\n }\r\n }\r\n\r\n /**\r\n * Log error message.\r\n * @param message - Message to log\r\n */\r\n public logError(message: string): void {\r\n console.error(message);\r\n }\r\n\r\n /**\r\n * Lazy log console message. Use this when the message being constructed is complex or expensive so that it's only evaluated if needed.\r\n * Note that the callback is not invoked and the message is not output unless you're in debug mode.\r\n * @param getMessage - The function to call to get message to log\r\n */\r\n public logCallback(getMessage: () => string): void {\r\n if (this.isDebug()) {\r\n console.info(getMessage());\r\n }\r\n }\r\n\r\n /**\r\n * Log the object to the console.\r\n * Note that these are not output to the console unless you're in debug mode.\r\n * @param message - Array of messages to log\r\n */\r\n public logObjects(...message: any[]): void {\r\n if (this.isDebug()) {\r\n console.log(...message);\r\n }\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Utility method to extract query string param in url.\r\n * @param name - Query param name\r\n * @returns Query param value\r\n */\r\nexport function getQueryParameterByName(locationHref: string, name: string): string {\r\n\r\n const nameRegEx = name.replace(/[[\\]]/g, \"\\\\$&\");\r\n const regex: any = new RegExp(\"[?&]\" + nameRegEx + \"(=([^&#]*)|&|#|$)\");\r\n\r\n const queryNameValueMatches: any = regex.exec(locationHref);\r\n if (!queryNameValueMatches) {\r\n return null;\r\n }\r\n\r\n // the second group would contain the value of the param\r\n const queryValue = queryNameValueMatches[2];\r\n\r\n return decodeURIComponent(queryValue.replace(/\\+/g, \" \")) || \"\";\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { minimumHostPagePathSegments } from \"../constants\";\r\n\r\n/**\r\n * The HostPage interface uses words defined by the Prime project for us to locate in what hostpage\r\n * the Feeds project is running.\r\n */\r\nexport interface IHostPage {\r\n originalUrl: string; // ex: https://www.msn.com/spartan/ntp/interests/my?fdhead=gizmodemo\r\n verticalKey: string, // ex: spartan or compass\r\n categoryKey: string, // ex: dhp or ntp\r\n hostName: string, // ex: www.msn.com\r\n topDomain: string, // ex: msn.com or msn.cn\r\n subcategoryKey?: string // ex: interests or discover\r\n}\r\n\r\nexport namespace HostPage {\r\n /**\r\n * This function extracts the hostPage information from the passed in href. This is based on the\r\n * Prime pathname convention of \"/vertical/category/subcategory\". If the passed href does not have at least the\r\n * category, then null is returned instead as this is considered an invalid URL.\r\n * @param {string} href - The URL, which will be used to extract the hostPage\r\n * @returns {IHostPage | null}\r\n */\r\n export function getHostPageFromUrl(href: string): IHostPage | null {\r\n const url = new URL(href);\r\n\r\n const host = url.hostname;\r\n const pathnameSegments = url.pathname.split(\"/\");\r\n\r\n // for cookie stamping that needs the msn.com or msn.cn path isntead of using the full host value\r\n const topDomainName = (host.match(/[^.]+\\.[^.\\d]+$/) || {})[0] || \"\";\r\n\r\n /**\r\n * The + 1 in the following statement is take into account the empty string \"segment\"\r\n * that would be to the left of the first backslash in a valid path like \"/spartan/ntp\"\r\n */\r\n if (pathnameSegments.length <= minimumHostPagePathSegments) {\r\n return {\r\n originalUrl: href,\r\n categoryKey: null,\r\n verticalKey: null,\r\n hostName: host,\r\n topDomain: topDomainName\r\n }; // When the user url doesn't have atleast two pathsegments the vertical and category keys are null\r\n }\r\n\r\n /**\r\n * Consider path segments that have market in it e.g.\r\n * /en-us/news/other/title/ar-cmsId\r\n * /en-us/video/animals\r\n * /en-us/sports/nfl/scores\r\n */\r\n const isMarketPresent = pathnameSegments[1].length === 5 && pathnameSegments[1].split(\"-\").length === 2;\r\n const indexOffset = isMarketPresent ? 1 : 0;\r\n\r\n const hostPage: IHostPage = {\r\n originalUrl: href,\r\n categoryKey: pathnameSegments[2 + indexOffset],\r\n verticalKey: pathnameSegments[1 + indexOffset],\r\n hostName: host,\r\n topDomain: topDomainName\r\n };\r\n\r\n if (pathnameSegments.length >= minimumHostPagePathSegments) {\r\n hostPage.subcategoryKey = pathnameSegments[3 + indexOffset];\r\n }\r\n return hostPage;\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Enum for different auth cookie names\r\n * @enum\r\n */\r\nexport enum AuthCookieName {\r\n Anon = \"ANON\",\r\n AppAnon = \"APP_ANON\",\r\n Unknown = \"\"\r\n}\r\n\r\n/**\r\n * List of http-readable cookies that indicate the presence of an auth cookie\r\n */\r\nexport enum AuthCookieExistsCookieName {\r\n AnonCookieExists = \"ace\",\r\n AppAnonCookieExists = \"aace\"\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { WpoModel } from \".\";\r\nimport { ITargetScope } from \"cms-models-msn/configuration/ITargetScope\";\r\n\r\n/**\r\n * Get storage cache key used to store WPO service response.\r\n * @param {string} appType - The appType value.\r\n * @param {ITargetScope} targetScope - The current page request target scope.\r\n * @returns string - Cache key string.\r\n */\r\nexport function getWpoStorageCacheKey(appType: string, targetScope: ITargetScope): string {\r\n const { audienceMode = \"\", locale = {}, pageType = \"\" } = targetScope || {};\r\n const { language, market } = locale;\r\n\r\n return `wpo_data_ ${audienceMode}_${language}_${market}_${pageType}_${appType}`;\r\n}\r\n\r\n/**\r\n * Extracts the WPO flight ids from the WPOModel object.\r\n * @param {WpoModel} wpoData - The WPOModel object.\r\n * @returns string[] - Array of WPO recommended flight ids\r\n */\r\nexport function getWpoFlights(wpoData: WpoModel): string[] | null {\r\n if (!wpoData || !wpoData.treatments) {\r\n return null;\r\n }\r\n\r\n return wpoData.treatments.map(item => item.id);\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/** Telemetry attribute name */\r\nexport const TelemetryAttrName = \"data-t\";\r\n/**\r\n * Telemetry event type\r\n * @interface TelemetryEventType\r\n */\r\nexport type TelemetryEventType = \"UserAction\" | \"PageView\" | \"ContentView\" | \"AppError\" | \"LoadTime\" | \"Unload\" | \"Feedback\" | \"AdImpression\" | \"AdFeedback\" | \"VideoPlay\" | \"VideoAdPlay\" | \"ServerLog\" | \"AppPerfTrace\";\r\n\r\n/**\r\n * Telemetry content view type\r\n * @interface TelemetryContentViewType\r\n */\r\nexport enum TelemetryContentViewType {\r\n Load = \"load\",\r\n Partial = \"partial\",\r\n Scroll = \"scroll\",\r\n Tap = \"tap\",\r\n Resize = \"resize\",\r\n Swipe = \"swipe\",\r\n View = \"view\",\r\n Auto = \"auto\"\r\n}\r\n\r\nexport const telemetryPageViewNotificationEvent = \"TelemetryPageViewNotificationEvent\";","// © Microsoft Corporation. All rights reserved.\r\n\r\n/// \r\n\r\n/**\r\n * Used to mock the LRU cache in unit test environments.\r\n * Partial is used to highlight this class is a subset of LRUCache and only\r\n * implements the functions we currently use out of this API. If more functions are\r\n * utilized they will need to be implmented here in this class.\r\n */\r\nexport class MockLRUCache implements Partial> {\r\n /** cache */\r\n private cacheMap: Map = new Map();\r\n\r\n /** Check if cache key exists */\r\n public async has(key: string): Promise {\r\n return !!this.cacheMap[key];\r\n }\r\n /** Get cached value by key */\r\n public async get(key: string): Promise {\r\n return this.cacheMap[key];\r\n }\r\n /** Set cached value by key */\r\n public async set(key: string, value: any, maxAge?: number): Promise {\r\n this.cacheMap[key] = value;\r\n return true;\r\n }\r\n /** Delete cached key-value pair */\r\n public async del(key: string): Promise {\r\n delete this.cacheMap[key];\r\n }\r\n /** Get count of total items cached */\r\n public async itemCount(): Promise {\r\n return Object.keys(this.cacheMap).length;\r\n }\r\n /** Reset entire cache */\r\n public async reset(): Promise {\r\n this.cacheMap = new Map();\r\n }\r\n}","\r\n// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Defines the different reasons why the hidden page should be reloaded on reveal\r\n */\r\nexport enum PageInvalidationReasons {\r\n MuidChange = 1,\r\n MarketChange = 2,\r\n InterestsChange = 3\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { AppError, WebWorkerErrors, logger, stringifyError, tryGetPerfTimeline } from \"@msnews/diagnostics\";\r\n\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\n\r\ndeclare global {\r\n /** Adding webWorker to Window */\r\n interface Window {\r\n /** Global flag indicating if web worker is present */\r\n _isWebWorkerPresent: boolean;\r\n\r\n /** Web worker instance */\r\n webWorker?: Worker;\r\n\r\n /** Web worker runtime errors */\r\n webWorkerErrors?: any[];\r\n }\r\n}\r\n\r\n/** Web worker request interface. */\r\nexport interface WebWorkerRequest {\r\n /** The message id. */\r\n id: string;\r\n\r\n /** The type of message. */\r\n type?: string;\r\n\r\n /** The additional message payload */\r\n payload?: any;\r\n}\r\n\r\n/** Web worker response interface. */\r\nexport interface WebWorkerResponse {\r\n /** The message id. */\r\n id: string;\r\n\r\n /** The item fetched status. */\r\n fetched: boolean;\r\n\r\n /** The item payload. */\r\n payload: any;\r\n}\r\n\r\n/**\r\n * Reports web worker presence.\r\n *\r\n * **NOTE**: Make sure to update the **_window._isWebWorkerPresent_** flag as well\r\n * while updating this, since the diagnostics lib doesn't have access to the core lib.\r\n */\r\nexport let isWebWorkerPresent: boolean;\r\n\r\n/** Web-worker message-map entry */\r\nexport interface WebWorkerMessageMapEntry {\r\n /** The message type (default is \"data\") */\r\n type: string;\r\n\r\n /** The callback, if any, that receives the data payload for the message */\r\n callback: (data: any) => void;\r\n}\r\n\r\n/** The message map from message id to the WebWorkerMessageMapEntry */\r\nconst messages = new Map();\r\n\r\nlet logAppError: (data: AppError) => void;\r\n\r\n/** The perf timeline for the web-worker interface */\r\nconst perfTimeline = tryGetPerfTimeline(\"WebWorkerUtility\", \"WebWorkerUtility\", true);\r\n\r\n/** Map to save messages that were sent from web worker but were not requested by main thread */\r\nconst standbyMessages = new Map();\r\n\r\n/**\r\n * Initialize isWebWorkerPresent. And this function also serve as test hook.\r\n * @param override - The test override\r\n */\r\nexport function init(override?: boolean): void {\r\n isWebWorkerPresent = false;\r\n if (canUseDOM()) {\r\n isWebWorkerPresent = (typeof override !== \"undefined\" ? override : !!window.webWorker);\r\n window._isWebWorkerPresent = isWebWorkerPresent;\r\n }\r\n\r\n if (!isWebWorkerPresent) {\r\n return;\r\n }\r\n\r\n window.webWorker.onmessage = (event: MessageEvent) => {\r\n const { data: response } = event;\r\n const pendingMessage = messages.get(response.id);\r\n\r\n if (!pendingMessage) {\r\n // TODO: Update inline script to save the messages that were received prior to initialization\r\n standbyMessages.set(response.id, response);\r\n return;\r\n }\r\n\r\n if (pendingMessage.type === \"data\") {\r\n messages.delete(response.id);\r\n }\r\n\r\n const callback = pendingMessage.callback;\r\n if (callback) {\r\n callback(response);\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * This function utility is converting web worker's postMessage communication into an async function.\r\n * It's sends given request to web worker, returns a promise, and promise is resolved when response is received from web worker.\r\n * @param request - The message to send\r\n * @param timeoutInMs(optional) - Timeout in milliseconds after which the promise will resolve with the default(failed) web worker response\r\n * @returns A promise to return WebWorkerResponse\r\n */\r\nexport function getFromWebWorker(request: WebWorkerRequest, timeoutInMs?: number): Promise {\r\n const defaultResponse = {\r\n id: (request && request.id) || \"\",\r\n fetched: false,\r\n payload: null\r\n };\r\n\r\n if (!isWebWorkerPresent || !request || !request.id) {\r\n return Promise.resolve(defaultResponse);\r\n }\r\n\r\n const endGetFromWebWorker = perfTimeline && perfTimeline.startMeasure(request.id).endMeasure;\r\n\r\n // Check if web worker already sent the message with data and return it.\r\n const standbyMessageData = standbyMessages.get(request.id);\r\n\r\n if (standbyMessageData) {\r\n // Delete the message to avoid returning the same data for future requests\r\n standbyMessages.delete(request.id);\r\n\r\n if (endGetFromWebWorker) {\r\n endGetFromWebWorker(\"standbymessage\");\r\n }\r\n\r\n return Promise.resolve(standbyMessageData);\r\n }\r\n\r\n let promiseTimeout;\r\n let timeOutPromise;\r\n\r\n // If timeout is provided, create a promise that will resolve after the timeout expires\r\n if (timeoutInMs) {\r\n timeOutPromise = new Promise(resolve => {\r\n promiseTimeout = setTimeout(\r\n () => {\r\n // Request timed out, we need not process the response if it's returned later, remove from messages map\r\n messages.delete(request.id);\r\n\r\n const errorMessage = `Web worker request timed out after ${timeoutInMs}ms for request id: [${request.id}]`;\r\n\r\n if (logAppError) {\r\n logAppError({\r\n ...WebWorkerErrors.MessageTimeout,\r\n message: \"Web worker request timed out\",\r\n pb: {\r\n ...WebWorkerErrors.MessageTimeout.pb,\r\n customMessage: errorMessage\r\n }\r\n });\r\n } else {\r\n logger.logError(errorMessage);\r\n }\r\n\r\n if (endGetFromWebWorker) {\r\n endGetFromWebWorker(\"timeout\");\r\n }\r\n\r\n resolve(defaultResponse);\r\n },\r\n timeoutInMs);\r\n });\r\n }\r\n\r\n const webWorkerPromise: Promise = new Promise(\r\n resolve => {\r\n const onMessage = (response: WebWorkerResponse) => {\r\n // We got a response from web worker, clear the promise timeout if it exists.\r\n if (promiseTimeout) {\r\n clearTimeout(promiseTimeout);\r\n }\r\n\r\n if (endGetFromWebWorker) {\r\n endGetFromWebWorker();\r\n }\r\n\r\n resolve(response);\r\n };\r\n\r\n messages.set(request.id, {\r\n type: request.type || \"data\",\r\n callback: onMessage\r\n });\r\n }\r\n );\r\n\r\n window.webWorker.postMessage({\r\n id: request.id,\r\n type: request.type || \"data\",\r\n payload: request.payload\r\n });\r\n\r\n return timeoutInMs\r\n ? Promise.race([webWorkerPromise, timeOutPromise])\r\n : webWorkerPromise;\r\n}\r\n\r\n/**\r\n * Sends given request to the web worker.\r\n * @param request - The message to send\r\n */\r\nexport function sendToWebWorker(request: WebWorkerRequest): void {\r\n if (!isWebWorkerPresent || !request || !request.id) {\r\n return;\r\n }\r\n\r\n window.webWorker.postMessage({\r\n id: request.id,\r\n type: request.type || \"command\",\r\n payload: request.payload || null\r\n });\r\n}\r\n\r\n/**\r\n * Subscribes to web worker notification\r\n * @param request subscription request\r\n * @param callback the callback to execute when notification is received\r\n */\r\nexport function subscribeWebWorkerNotification(request: WebWorkerRequest, callback: (payload: any) => void): void {\r\n if (!isWebWorkerPresent || !request || request.type !== \"subscription\" || !callback) {\r\n return;\r\n }\r\n\r\n messages.set(request.id, { type: \"subscription\", callback });\r\n window.webWorker.postMessage(request);\r\n}\r\n\r\n/**\r\n * Sets the AppError logging function and adds event listener for web worker errors.\r\n * @param handler - Error tracker function\r\n */\r\nexport function trackWebWorkerErrors(trackAppErrorEvent: (data: AppError) => void): void {\r\n if (!isWebWorkerPresent || !trackAppErrorEvent || typeof trackAppErrorEvent !== \"function\") {\r\n return;\r\n }\r\n\r\n logAppError = function (data: AppError): void {\r\n try {\r\n trackAppErrorEvent(data);\r\n } catch (ex) {\r\n logger.logError(`Failed to log web worker AppError. Error: ${stringifyError(ex)}`);\r\n }\r\n };\r\n\r\n // callback for unhandled runtime exceptions\r\n window.webWorker.onerror = onWebWorkerRuntimeError;\r\n\r\n // Callback for handled errors(logger.error) in web worker\r\n const onWorkerErrorMessage = (response: WebWorkerResponse) => {\r\n if (response.payload && typeof response.payload === \"object\") {\r\n const wwAppError = response.payload as AppError;\r\n\r\n // Since web worker is not aware of build number, give build number from other app error.\r\n wwAppError.pb = {\r\n ...wwAppError.pb,\r\n build: WebWorkerErrors.HandledError.pb.build\r\n };\r\n\r\n logAppError(wwAppError);\r\n } else {\r\n logAppError({\r\n ...WebWorkerErrors.HandledError,\r\n message: \"Web worker error\",\r\n pb: {\r\n ...WebWorkerErrors.HandledError.pb,\r\n customMessage: JSON.stringify(response.payload || \"\")\r\n }\r\n });\r\n }\r\n };\r\n\r\n subscribeWebWorkerNotification({ id: \"WebWorkerError\", type: \"subscription\" }, onWorkerErrorMessage);\r\n\r\n // Read and log web worker errors that were reported before the main thread initialized.\r\n if (window.webWorkerErrors && Array.isArray(window.webWorkerErrors)) {\r\n window.webWorkerErrors.forEach(error => {\r\n onWebWorkerRuntimeError(error);\r\n });\r\n\r\n delete window.webWorkerErrors;\r\n }\r\n}\r\n\r\n/**\r\n * Handler for web worker error events\r\n * @param event web worker ErrorEvent\r\n */\r\nfunction onWebWorkerRuntimeError(event: ErrorEvent): void {\r\n // If ErrorEvent does not contain the filename, only possible reason could be that the web worker script 404ed.\r\n if (!event.filename) {\r\n isWebWorkerPresent = false;\r\n window._isWebWorkerPresent = isWebWorkerPresent;\r\n window.webWorker.terminate();\r\n\r\n logAppError({\r\n ...WebWorkerErrors.FileNotFound,\r\n message: \"Web worker script not found\",\r\n pb: {\r\n ...WebWorkerErrors.FileNotFound.pb,\r\n customMessage: JSON.stringify(getErrorDetails(event))\r\n }\r\n });\r\n\r\n return;\r\n }\r\n\r\n logAppError({\r\n ...WebWorkerErrors.RuntimeError,\r\n message: \"Web worker runtime error\",\r\n pb: {\r\n ...WebWorkerErrors.RuntimeError.pb,\r\n customMessage: JSON.stringify(getErrorDetails(event))\r\n }\r\n });\r\n}\r\n\r\n/** Extracts properties from error event. Direct JSON.stringify removes all properties except `isTrusted` */\r\nfunction getErrorDetails(error: ErrorEvent): any {\r\n return JSON.stringify({\r\n filename: error.filename,\r\n message: error.message,\r\n lineno: error.lineno\r\n });\r\n}\r\n\r\ninit();\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { requireAsync } from \"./RequireAsync\";\r\n\r\n/**\r\n * Integration function to retrieve the prime track object.\r\n *\r\n * @export\r\n * @return {Promise} - Resolves if the track object could be loaded, rejects otherwise.\r\n */\r\nexport const getTrack: IGetTrack = () => {\r\n return requireAsync(\"track\");\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { AppError } from \"@msnews/diagnostics\";\r\nimport { getTrack } from \"./PrimeTrack\";\r\nimport { getTrackExtCompleteCanary } from \"./PrimeTrackExtensionComplete\";\r\nimport { getTrackInfo } from \"./PrimeTrackInfo\";\r\n\r\ntype trackingEventCall = {event: Event, element: HTMLElement, destination: string, headline: string};\r\ntype trackPartialImpression = {elem?: HTMLElement, visibilityCheck?: boolean, mechanism?: TrackMechanism, topLevelContainerType?: string};\r\n\r\nlet trackingResolved = false;\r\nlet trackingObject: PrimeGlobal.ITrack = null;\r\nlet trackExtCompleted: any = null;\r\nlet trackEventBuffer: trackingEventCall[] = [];\r\nlet trackImpressionBuffer: trackPartialImpression[] = [];\r\nlet trackAppErrorEventBuffer: AppError[] = [];\r\nlet trackingPromiseCalled = false;\r\n\r\n// Following code is to decouple Prime dependency from initial state of experience. Once tracking is ported to Peregrine, it would not be needed.\r\n/**\r\n * Send the tracking call\r\n * @param {Event} event event object\r\n * @param {HTMLElement} element form code\r\n * @param {string} destination text\r\n * @param {string} headline text\r\n * @void\r\n */\r\nfunction sendTrackingCall(event: Event, element: HTMLElement, destination: string, headline: string): void {\r\n trackingObject.trackEvent(event, element, destination, headline);\r\n}\r\n\r\n/**\r\n * Makes the partial page request\r\n * @param {HTMLElement} elem object\r\n * @param {boolean} visibilityCheck\r\n * @param {TrackMechanism} mechanism\r\n * @param {string} topLevelContainerType\r\n * @void\r\n */\r\nfunction sendPartialPageRequest(elem?: HTMLElement, visibilityCheck?: boolean, mechanism?: TrackMechanism, topLevelContainerType?: string): void {\r\n trackingObject.trackPartialImpression(elem, visibilityCheck, mechanism, topLevelContainerType);\r\n}\r\n\r\n/**\r\n * Converts the AppError object to the Prime AppError type and make the trackAppErrorEvent call\r\n * @param appError - App error object\r\n */\r\nfunction sendTrackAppErrorEvent(appError: AppError): void {\r\n trackingObject.trackAppErrorEvent({ errId: appError.id, errSource: appError.source, errMsg: appError.message });\r\n}\r\n\r\n/**\r\n * Processes the pending tracking and page impresssion calls for statics.\r\n * Dependencies: getTrack(), getTrackExtCompleteCanary()\r\n * @void\r\n */\r\nfunction processPendingTrackingCall(): void {\r\n Promise.all([getTrack(), getTrackExtCompleteCanary()])\r\n .then(modules => {\r\n [trackingObject, trackExtCompleted] = modules;\r\n\r\n // at this point we will process any pending requests and resolve tracking\r\n trackingResolved = true;\r\n if (trackEventBuffer.length > 0) {\r\n trackEventBuffer.forEach(eventObj => {\r\n try {\r\n sendTrackingCall(eventObj.event, eventObj.element, eventObj.destination, eventObj.headline);\r\n } catch {\r\n // This catch block is meant to continue to next element in the loop.\r\n // We may remove this in future once Error Boundaries are added.\r\n }\r\n });\r\n\r\n // empty it again after processing\r\n trackEventBuffer = [];\r\n }\r\n\r\n if (trackImpressionBuffer.length > 0) {\r\n trackImpressionBuffer.forEach(eventObj => {\r\n sendPartialPageRequest(eventObj.elem, eventObj.visibilityCheck, eventObj.mechanism, eventObj.topLevelContainerType);\r\n });\r\n\r\n // empty it again after processing\r\n trackImpressionBuffer = [];\r\n }\r\n\r\n if (trackAppErrorEventBuffer.length > 0) {\r\n trackAppErrorEventBuffer.forEach(appError => {\r\n sendTrackAppErrorEvent(appError);\r\n });\r\n\r\n // empty it again after processing\r\n trackAppErrorEventBuffer = [];\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Callback function to pass to experience. It maintains an internal array to hold track calls until dependencies resolved.\r\n * @param {HTMLElement} element form code\r\n * @param {string} action (Type of action. Necessary to make it compatible with 1DS Telemetry SDK)\r\n * @param {number} behavior (Type of beavior. Necessary to make it compatible with 1DS Telemetry SDK)\r\n * @param {Event} event event object\r\n * @param {string} destination text\r\n * @param {string} headline text\r\n * @void\r\n */\r\nexport function handleTelemetryCall(element: HTMLElement, action?: string, behavior?: number, event?: Event, destination?: string, headline?: string): void {\r\n if (trackingResolved) {\r\n sendTrackingCall(event, element, destination, headline);\r\n } else {\r\n trackEventBuffer.push({ event: event, element: element, destination: destination, headline: headline });\r\n\r\n if (!trackingPromiseCalled) {\r\n trackingPromiseCalled = true;\r\n\r\n // only want to call this once\r\n processPendingTrackingCall();\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Makes the partial page request\r\n * @param {HTMLElement} elem object\r\n * @param {} viewType (Necessary to make it compatible with 1DS Telemetry SDK)\r\n * @param {boolean} visibilityCheck\r\n * @param {TrackMechanism} mechanism\r\n * @param {string} topLevelContainerType\r\n * @void\r\n */\r\nexport function handlePartialPageImpressionCall(elem?: HTMLElement, viewType?, visibilityCheck?: boolean, mechanism?: TrackMechanism, topLevelContainerType?: string): void {\r\n if (trackingResolved) {\r\n sendPartialPageRequest(elem, visibilityCheck, mechanism, topLevelContainerType);\r\n } else {\r\n trackImpressionBuffer.push({ elem: elem, visibilityCheck: visibilityCheck, mechanism: mechanism, topLevelContainerType: topLevelContainerType });\r\n\r\n if (!trackingPromiseCalled) {\r\n trackingPromiseCalled = true;\r\n\r\n // only want to call this once\r\n processPendingTrackingCall();\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Handler to log app errors\r\n * @param appError - App error object\r\n * @void\r\n */\r\nexport function handleAppErrorEventCall(appError: AppError): void {\r\n if (trackingResolved) {\r\n sendTrackAppErrorEvent(appError);\r\n } else {\r\n trackAppErrorEventBuffer.push({ ...appError });\r\n if (!trackingPromiseCalled) {\r\n trackingPromiseCalled = true;\r\n\r\n // only want to call this once\r\n processPendingTrackingCall();\r\n }\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { requireAsync } from \"./RequireAsync\";\r\n\r\n/**\r\n * Integration function to wait on track extension complete canary.\r\n *\r\n * @export\r\n * @return {Promise} - Resolves if track extension canary is define, rejects otherwise.\r\n */\r\nexport const getTrackExtCompleteCanary: IGetTrackExtComplete = () => {\r\n return requireAsync(\"c.trackExtComplete\");\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { HeadingProps } from \"@microsoft/fast-components-react-msft\";\r\n\r\n/**\r\n * An enum for intra article component position values\r\n *\r\n * @export\r\n * @enum IntraArticleComponentPosition\r\n */\r\nexport enum IntraArticleComponentPosition {\r\n Normal = \"normal\",\r\n Wide = \"wide\"\r\n}\r\n\r\n/**\r\n * An enum for views article component types\r\n *\r\n * @export\r\n * @enum IntraArticleComponentType\r\n */\r\nexport enum IntraArticleComponentType {\r\n ArticleReader = \"articlereader\",\r\n InlineImage = \"inlineimage\",\r\n InlineSlideshow = \"inlineslideshow\",\r\n InlineVideo = \"inlinevideo\",\r\n FacebookEmbed = \"facebookembed\",\r\n TwitterEmbed = \"twitterembed\",\r\n InstagramEmbed = \"instagramembed\",\r\n GiphyEmbed = \"giphyembed\",\r\n GraphiqEmbed = \"graphiqembed\",\r\n PinterestEmbed = \"pinterestembed\",\r\n TextParagraph = \"textparagraph\",\r\n Unknown = \"unknown\"\r\n}\r\n\r\n/**\r\n * An interface for SocialEmbedData contract\r\n *\r\n * @export\r\n * @interface SocialEmbedData\r\n */\r\nexport interface SocialEmbedData {\r\n /**\r\n * Social feed attribution\r\n * @type {string}\r\n */\r\n attribution?: string;\r\n\r\n /**\r\n * Url to fetch social feed from provider\r\n * @type {string}\r\n */\r\n feedHref: string;\r\n\r\n /**\r\n * Embed identifier\r\n * @type {string}\r\n */\r\n id: string;\r\n\r\n /**\r\n * Title for the social feed\r\n * @type {string}\r\n */\r\n title?: string;\r\n\r\n /**\r\n * Social embed type\r\n * @type {IntraArticleComponentType}\r\n */\r\n type: IntraArticleComponentType;\r\n}\r\n\r\n/**\r\n * An interface for IntraArticleComponent contract\r\n *\r\n * @export\r\n * @interface IntraArticleComponent\r\n */\r\nexport interface IntraArticleComponent {\r\n /**\r\n * CMS document id\r\n * @type {string}\r\n */\r\n cmsDocumentId?: string;\r\n\r\n /**\r\n * Additional component data\r\n * @type {unknown}\r\n */\r\n data?: unknown;\r\n\r\n /**\r\n * Message to show if error encountered while loading component\r\n * @type {HeadingProps}\r\n */\r\n loadError?: HeadingProps;\r\n\r\n /**\r\n * Ingested component markup\r\n * @type {string}\r\n */\r\n marker: string;\r\n\r\n /**\r\n * Position index in ingested article body markup\r\n * @type {number}\r\n */\r\n startIndex: number;\r\n\r\n /**\r\n * Expected component positioning inside article body\r\n * @type {IntraArticleComponentPosition}\r\n */\r\n position?: IntraArticleComponentPosition;\r\n\r\n /**\r\n * Type of component\r\n * @type {IntraArticleComponentType}\r\n */\r\n type: IntraArticleComponentType;\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Mediator events\r\n * @export\r\n * @type {object}\r\n */\r\nexport const MediatorEventNames = {\r\n // Event fired when content actions attributes are updated (eg: new video is loaded)\r\n ContentActionsUpdated: \"contentActionsUpdated\",\r\n // Event fired when a feed is successfully followed\r\n FeedFollowed: \"feedFollowed\",\r\n // Event fired when a feed is successfully followed/un-followed to let pre-load\r\n // framework know it needs to refresh the page\r\n ForcePageReload: \"forcePageReload\",\r\n // Event fired when a feed is successfully followed/un-followed\r\n FollowedTopicsUpdated: \"followedTopicsUpdated\",\r\n // Event to fire to show a specific mediated coach mark\r\n MediatedCoachMark: \"mediated_coach_mark\",\r\n // Event fired by Prime when the tab is being changed\r\n TabNavigation: \"tab_navigation\",\r\n // Event that tells Prime feedsNav module to navigate to the specified URL\r\n TabNavigateTo: \"tab_navigate_to\",\r\n // Event fired when a topic is followed/unfollowed so SPA can re-act\r\n TopicAction: \"topic_action\",\r\n // Event fired when a 360 experience is launched\r\n Msn360: \"msn360\",\r\n // Event to fire to show card action menu\r\n CardActionInit: \"cardActionInit\",\r\n // Event to fire to post card action menu\r\n CardActionPost: \"cardActionPostEvent\",\r\n // Event to fire when interests render complete\r\n InterestsRenderComplete: \"interestsRenderCompleteEvent\",\r\n // Event to fire when an Xfeed needs to load\r\n RenderXFeed: \"show_xfeed_content\",\r\n // Event to fire when a pivot needs to load by id\r\n ShowPivotById: \"show_pivot_by_id\",\r\n // Event that tells Prime infopane module to resume the auto-rotation\r\n ResumeInfopaneAutoRotate: \"resumeInfopaneAutoRotate\",\r\n // Event fired when social actions attributes are updated (eg: new video is loaded)\r\n SocialActionsUpdated: \"socialActionsUpdated\"\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { requireAsync } from \"./RequireAsync\";\r\n\r\n/**\r\n * Integration function to retrieve the prime mediator object.\r\n *\r\n * @export\r\n * @return {Promise} - Resolves with the mediator if it could be loaded, rejects otherwise.\r\n */\r\nexport const getMediator: IGetMediator = () => {\r\n return requireAsync(\"mediator\");\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * A callback to reset singleton data. Used for server side rendering.\r\n */\r\nexport type ResetCallback = () => void;\r\n\r\n/**\r\n * Global array of callbacks that are used for resetting singleton data.\r\n */\r\nconst resetCallbacks: ResetCallback[] = [];\r\n\r\n/**\r\n * Adds a callback to the global array of reset callbacks.\r\n * This should only be used to reset singleton data.\r\n * @param callback The function that resets the singleton data.\r\n */\r\nexport function registerResetCallback(callback: ResetCallback): void {\r\n resetCallbacks.push(callback);\r\n}\r\n\r\n/**\r\n * Calls all of the reset functions in resetCallbacks.\r\n * This gets called once on the server side at the beginning of each request.\r\n */\r\nexport function invokeResetCallbacks(): void {\r\n for (const resetCallback of resetCallbacks) {\r\n resetCallback();\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n// TODO: This should be considered for moving it to the Interests experience wrapper, once that\r\n// code arrives, since this is specific to that experience\r\n\r\n/**\r\n * Subnav TabId Enum object\r\n * @export\r\n * @type {enum}\r\n */\r\nexport enum SubnavTabId {\r\n None = 0,\r\n MyFeed = 1,\r\n XFeed = 2,\r\n Interests = 3\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Converts the given error object to its string representation based on\r\n * the type of the input object.\r\n * @param error - the error object to convert to a string.\r\n * @returns {string} - The string representation of the error.\r\n */\r\nexport function stringifyError(error: string | object | Error): string {\r\n if (error instanceof Error) {\r\n return error.toString();\r\n } else if (typeof error === \"string\") {\r\n return error;\r\n } else {\r\n return JSON.stringify(error);\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { AppType, PageType } from \"@msnews/experiences-constants\";\r\n\r\nimport { appEnvironment } from \"../app\";\r\nimport { headData } from \"../app/HeadData\";\r\n\r\n/**\r\n * Base class for page utility functions\r\n */\r\nexport namespace PageUtility {\r\n\r\n /**\r\n * Returns true if the current page is the DHP\r\n */\r\n export function isDhpPage(): boolean {\r\n return headData.ClientSettings.pagetype === PageType.DHP;\r\n }\r\n\r\n /**\r\n * Returns true if the current page is the NTP\r\n */\r\n export function isNtpPage(): boolean {\r\n return headData.ClientSettings.pagetype === PageType.NTP;\r\n }\r\n\r\n /**\r\n * Returns true if five column is supported or not\r\n */\r\n export function fiveColSupported(): boolean {\r\n // restrict the flight to Anaheim apptype\r\n if (appEnvironment.AppType !== AppType.EdgeChromium) {\r\n return false;\r\n }\r\n\r\n const pageExperiments = appEnvironment && appEnvironment.CurrentRequestTargetScope && appEnvironment.CurrentRequestTargetScope.pageExperiments;\r\n if (pageExperiments && pageExperiments.length\r\n && (pageExperiments.indexOf(\"prg-fivecol\") > -1\r\n || pageExperiments.indexOf(\"prg-staging\") > -1\r\n || pageExperiments.indexOf(\"prg-stripecol5\") > -1)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { endsWith as _endsWith, some as _some } from \"lodash-es\";\r\n\r\nimport { IActionMap } from \"./IActionMap\";\r\nimport { IActionPayload } from \"./IActionPayload\";\r\nimport { String as StringOperations } from \"typescript-string-operations\";\r\n\r\n/**\r\n * Class Contains helpers to use inside of a reducer, that is managed by and called from DynamicReducer\r\n * These helpers provide the ability to use a strongly typed callback that matches the parameters of an Action.\r\n * redux-subspace will automatically prepend a namespace to actions so that they are targeted to their specific subspace.\r\n * DynamicReducer already handles ensuring actions reach the correct reducer, so the redux-subspace namespace can be ignored\r\n * @class\r\n */\r\nexport class ActionHandler {\r\n\r\n /**\r\n * local function that either uses the built-in String.prototype.endsWith function, or uses the lodash-es function to polyFill;\r\n * the built-in function is significantly faster than the lodash-es function or other options, so we want to use it when we can;\r\n * the lodash-es function, based on splice, is faster than String.prototype.indexOf, but using RegEx might be faster...\r\n */\r\n private static endsWith: Function = String.prototype.endsWith\r\n ? function (search: string, target: string): boolean { return search.endsWith(target); }\r\n : _endsWith;\r\n\r\n /**\r\n * Method to handle specific actions.\r\n * @method\r\n * @param actionPayload {IActionPayload} The action details.\r\n * @param actionMap {IActionMap} The actionMap which maps Action to its callback function type.\r\n * @param callback {TActionSignature} function of type TActionSignature.\r\n * @return { boolean } true if the action type matched, false otherwise.\r\n */\r\n public static handleAction(\r\n actionPayload: IActionPayload,\r\n actionMap: IActionMap,\r\n callback: TActionSignature): boolean {\r\n\r\n // actionPayload.type may have a redux-subspace namespace prepended, so check to see if the ending action is what we want\r\n // namespaces are separated from the action type by a \"/\";\r\n // we use that to differentiate where the payload type ends with the mapped type as part of the name, but is not the same action\r\n // e.g. \"Action\" in the action map and \"NameSpace/AnotherAction\" in the payload, both end in \"Action\" but do not match\r\n // we prepend to *both* to cover the case where they are already equal (that is, no namespace is present)\r\n\r\n if (ActionHandler.endsWith(actionPayload.type + \"\", actionMap.type)) {\r\n callback.apply(callback, actionPayload.params);\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Method to handle multiple actions with same signature.\r\n * @method\r\n * @param actionPayload {IActionPayload} The action details.\r\n * @param actionMap {IActionMap[]} The collection of actionMaps which maps Action to its callback function type.\r\n * @param callback {TActionSignature} function of type TActionSignature.\r\n * @return { boolean } true if the action type matched, false otherwise.\r\n */\r\n public static handleActions(\r\n actionPayload: IActionPayload,\r\n actionMaps: IActionMap[],\r\n callback: TActionSignature): boolean {\r\n\r\n const actionPayloadType = actionPayload.type + \"\";\r\n const actionsMatched = _some(actionMaps, (actionMap) => ActionHandler.endsWith(actionPayloadType, actionMap.type));\r\n\r\n if (actionsMatched) {\r\n callback.apply(callback, actionPayload.params);\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Method to handle specific actions and check typescript type safely.\r\n * It throws error if actionMap.type does not equal the actionPayload.type.\r\n * @method\r\n * @param actionPayload {IActionPayload} The action details.\r\n * @param actionMap {IActionMap} The actionMap which maps Action to its callback function type.\r\n * @param callback {TActionSignature} function of type TActionSignature.\r\n * @return { boolean } true if the action type matched, false otherwise.\r\n */\r\n public static safeHandleAction(\r\n actionPayload: IActionPayload,\r\n actionMap: IActionMap,\r\n callback: TActionSignature): any {\r\n\r\n if (!ActionHandler.endsWith(actionPayload.type + \"\", actionMap.type)) {\r\n throw \"The action payload does not match the action type.\";\r\n }\r\n\r\n callback.apply(callback, actionPayload.params);\r\n return true;\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * This file defines the datatypes used in telemetry beacons.\r\n */\r\n\r\n/**\r\n * Telemetry Page Type\r\n * @enum TelemetryTelemetryPageTypeProduct\r\n */\r\nexport const TelemetryPageType = {\r\n Unspecified: \"unspecified\",\r\n DHP: \"dhp\",\r\n NTP: \"ntp\",\r\n HomePage: \"hp\",\r\n VerticalHomePage: \"verthp\",\r\n Article: \"article\",\r\n Gallery: \"gallery\",\r\n Video: \"video\",\r\n Spotlight: \"spotlight\"\r\n};\r\n\r\n/**\r\n * Telemetry Object Type. (Deprecating. Please use TelemetryContentType and TelemetryBehaviorType instead)\r\n * @enum TelemetryObjectType\r\n */\r\nexport const TelemetryType = {\r\n Undefined: 0,\r\n Header: 1,\r\n Footer: 2,\r\n TopNavBar: 3,\r\n NavBar: 4,\r\n DropDown: 5,\r\n Section: 6,\r\n Carousel: 7,\r\n Module: 8,\r\n SearchBox: 9,\r\n InputBox: 10,\r\n ActionButton: 11,\r\n Interaction: 12,\r\n Headline: 13,\r\n Entity: 15,\r\n Topic: 29,\r\n Provider: 30,\r\n NewStories: 46,\r\n AutoSuggest: 47,\r\n Tile: 49,\r\n TrendingNews: 50,\r\n AllCoverage: 51,\r\n Report: 52,\r\n MsccCookieComplianceBanner: 54,\r\n CookieWallCookieComplianceBanner: 57\r\n};\r\n\r\n/**\r\n * Telemetry Content Type used to describe content type that is assocated with an object\r\n * @enum TelemetryContentType\r\n */\r\nexport const TelemetryContentType = {\r\n Undefined: 0,\r\n StructuredData: 1,\r\n AppStore: 2,\r\n CmsPromotions: 3,\r\n MicrosoftWebStore: 4,\r\n XboxStore: 5,\r\n OfficeStore: 6,\r\n PartnerLinks: 7,\r\n SponsoredContent: 8,\r\n Spotlight: 9,\r\n ExternalLink: 10,\r\n SearchPromo: 11,\r\n Feed: 12,\r\n Article: 13,\r\n Gallery: 14,\r\n Video: 15,\r\n Audio: 16,\r\n Settings: 17,\r\n DisplayAd: 18,\r\n OfficeDocument: 19,\r\n App: 20,\r\n SearchResult: 21,\r\n VideoAd: 22\r\n};\r\n\r\n/**\r\n * Telemetry Action Type\r\n * @enum TelemetryActionType\r\n */\r\nexport const TelemetryActionType = {\r\n Click: \"click\",\r\n Hover: \"mouseenter\",\r\n Submit: \"submit\",\r\n View: \"view\",\r\n RightClick: \"rightclick\"\r\n};\r\n\r\n/**\r\n * Telemetry Behavior Type\r\n * @enum TelemetryBehaviorType\r\n */\r\nexport const TelemetryBehaviorType = {\r\n Undefined: 0,\r\n Navigate: 1,\r\n ContextMenu: 2,\r\n Pin: 3,\r\n Unpin: 4,\r\n Rearrange: 5,\r\n Remove: 6,\r\n Add: 7,\r\n Open: 8,\r\n View: 9,\r\n Follow: 10,\r\n Unfollow: 11,\r\n More: 12,\r\n Close: 13,\r\n Share: 14,\r\n Like: 15,\r\n Dislike: 16,\r\n Unlike: 17,\r\n Undislike: 18,\r\n Mute: 19,\r\n Unmute: 20,\r\n Cancel: 21,\r\n Launch: 22,\r\n Install: 23,\r\n Manage: 24,\r\n Show: 25,\r\n MuteCancel: 26,\r\n Save: 27,\r\n Hide: 28,\r\n Unhide: 29,\r\n Customize: 30,\r\n Suspend: 31,\r\n Clear: 32,\r\n SignIn: 33,\r\n SignOut: 34,\r\n UndoSave: 35,\r\n TurnOn: 36,\r\n TurnOff: 37,\r\n Forward: 38,\r\n Response: 39,\r\n Report: 40\r\n};\r\n\r\n/**\r\n * Telemetry Content Source Type\r\n * @enum TelemetryContentSourceType\r\n */\r\nexport const TelemetryContentSourceType = {\r\n Editor: 0,\r\n PersonalizationAlgo: 1,\r\n Bing: 2,\r\n Taboola: 3,\r\n Outbrain: 4,\r\n AutoCuration: 5,\r\n User: 6,\r\n AppNexus: 7,\r\n OtherSponconProvider: 8\r\n};\r\n\r\n/**\r\n * Telemetry Page Configuration\r\n * @enum TelemetryPageConfiguration\r\n */\r\nexport const TelemetryPageConfiguration = {\r\n Empty: 0,\r\n SearchBox: 1,\r\n TopSites: 2,\r\n Suggested: 4,\r\n ContentFeed: 8,\r\n WinFRE: 16,\r\n BingImage: 32,\r\n ContentBelowTheFold: 64,\r\n CustomModeOption: 128,\r\n GreetingEnabled: 256,\r\n HeadingsOnly: 512,\r\n StripeLayout: 1024\r\n};\r\n\r\n/**\r\n * Telemetry Page Product\r\n * @enum TelemetryPageProduct\r\n */\r\nexport const TelemetryPageProduct = {\r\n Emmx: \"emmx\",\r\n Prime: \"prime\",\r\n Spartan: \"spartan\",\r\n ChromeExt: \"chromeext\",\r\n IEExt: \"ieext\",\r\n Anaheim: \"anaheim\",\r\n Amp: \"amp\"\r\n};\r\n\r\n/**\r\n * Log type.\r\n * @type LogType\r\n */\r\nexport type LogType = \"information\" | \"error\" | \"warning\";\r\n\r\n/**\r\n * ANID cookie name.\r\n * @type ANONCookieName\r\n */\r\nexport type ANONCookieName = \"anon\" | \"app_anon\";","module.exports = __webpack_public_path__ + \"AdChoices.svg\";","module.exports = __webpack_public_path__ + \"AlertWhite.svg\";","module.exports = __webpack_public_path__ + \"BingCardDefaultHotelImage.svg\";","module.exports = __webpack_public_path__ + \"BingHotelSeePrice.svg\";","module.exports = __webpack_public_path__ + \"BingLogo.svg\";","module.exports = __webpack_public_path__ + \"BingRatingDarkLightStar.svg\";","module.exports = __webpack_public_path__ + \"BingRatingDarkStar.svg\";","module.exports = __webpack_public_path__ + \"BingRatingLightStar.svg\";","module.exports = __webpack_public_path__ + \"BlowingHail.svg\";","module.exports = __webpack_public_path__ + \"BlowingHailWhite.svg\";","module.exports = __webpack_public_path__ + \"BlowingHailV2.svg\";","module.exports = __webpack_public_path__ + \"BlowingSnow.svg\";","module.exports = __webpack_public_path__ + \"BlowingSnowWhite.svg\";","module.exports = __webpack_public_path__ + \"BlowingSnowV2.svg\";","module.exports = __webpack_public_path__ + \"Check.svg\";","module.exports = __webpack_public_path__ + \"Chevron.svg\";","module.exports = __webpack_public_path__ + \"ChevronDown.svg\";","module.exports = __webpack_public_path__ + \"ChevronRight.svg\";","module.exports = __webpack_public_path__ + \"ChevronWhite.svg\";","module.exports = __webpack_public_path__ + \"CircleChevron.svg\";","module.exports = __webpack_public_path__ + \"CircleClose.svg\";","module.exports = __webpack_public_path__ + \"ClearNight.svg\";","module.exports = __webpack_public_path__ + \"ClearNightWhite.svg\";","module.exports = __webpack_public_path__ + \"ClearNightV2.svg\";","module.exports = __webpack_public_path__ + \"Close.svg\";","module.exports = __webpack_public_path__ + \"CloseThin.svg\";","module.exports = __webpack_public_path__ + \"Cloudy.svg\";","module.exports = __webpack_public_path__ + \"CloudyWhite.svg\";","module.exports = __webpack_public_path__ + \"CloudyV2.svg\";","module.exports = __webpack_public_path__ + \"Comment.svg\";","module.exports = __webpack_public_path__ + \"Copy.svg\";","module.exports = __webpack_public_path__ + \"DarkModeHotel.svg\";","module.exports = __webpack_public_path__ + \"DayTime.svg\";","module.exports = __webpack_public_path__ + \"Delete.svg\";","module.exports = __webpack_public_path__ + \"Discover.svg\";","module.exports = __webpack_public_path__ + \"Dislike.svg\";","module.exports = __webpack_public_path__ + \"DislikeText.svg\";","module.exports = __webpack_public_path__ + \"Disliked.svg\";","module.exports = __webpack_public_path__ + \"DislikedLight.svg\";","module.exports = __webpack_public_path__ + \"DislikedText.svg\";","module.exports = __webpack_public_path__ + \"Docx.svg\";","module.exports = __webpack_public_path__ + \"Download.svg\";","module.exports = __webpack_public_path__ + \"DownloadNoFill.svg\";","module.exports = __webpack_public_path__ + \"Edit.svg\";","module.exports = __webpack_public_path__ + \"EditNoFill.svg\";","module.exports = __webpack_public_path__ + \"Edited.svg\";","module.exports = __webpack_public_path__ + \"EditedNoFill.svg\";","module.exports = __webpack_public_path__ + \"Ellipses.svg\";","module.exports = __webpack_public_path__ + \"EllipsesLight.svg\";","module.exports = __webpack_public_path__ + \"EmptyDiscoverDark.svg\";","module.exports = __webpack_public_path__ + \"EmptyDiscoverLight.svg\";","module.exports = __webpack_public_path__ + \"Excel.svg\";","module.exports = __webpack_public_path__ + \"Facebook.svg\";","module.exports = __webpack_public_path__ + \"FacebookCircle.svg\";","module.exports = __webpack_public_path__ + \"FacebookText.svg\";","module.exports = __webpack_public_path__ + \"FacebookTextBlack.svg\";","module.exports = __webpack_public_path__ + \"Fog.svg\";","module.exports = __webpack_public_path__ + \"FogWhite.svg\";","module.exports = __webpack_public_path__ + \"FogV2.svg\";","module.exports = __webpack_public_path__ + \"Folder.svg\";","module.exports = __webpack_public_path__ + \"FolderNoFill.svg\";","module.exports = __webpack_public_path__ + \"FolderOpen.svg\";","module.exports = __webpack_public_path__ + \"Form.svg\";","module.exports = __webpack_public_path__ + \"Forward.svg\";","module.exports = __webpack_public_path__ + \"FreezingRain.svg\";","module.exports = __webpack_public_path__ + \"FreezingRainWhite.svg\";","module.exports = __webpack_public_path__ + \"FreezingRainV2.svg\";","module.exports = __webpack_public_path__ + \"GalleryFullscreen.svg\";","module.exports = __webpack_public_path__ + \"GalleryMediaIcon.svg\";","module.exports = __webpack_public_path__ + \"GeneralErrorDark.svg\";","module.exports = __webpack_public_path__ + \"GeneralErrorLight.svg\";","module.exports = __webpack_public_path__ + \"GenericFile.svg\";","module.exports = __webpack_public_path__ + \"GridView.svg\";","module.exports = __webpack_public_path__ + \"HailDay.svg\";","module.exports = __webpack_public_path__ + \"HailDayWhite.svg\";","module.exports = __webpack_public_path__ + \"HailDayV2.svg\";","module.exports = __webpack_public_path__ + \"HailNight.svg\";","module.exports = __webpack_public_path__ + \"HailNightWhite.svg\";","module.exports = __webpack_public_path__ + \"HailNightV2.svg\";","module.exports = __webpack_public_path__ + \"HazeSmoke.svg\";","module.exports = __webpack_public_path__ + \"HazeSmokeWhite.svg\";","module.exports = __webpack_public_path__ + \"HazeSmokeV2.svg\";","module.exports = __webpack_public_path__ + \"HeavySnow.svg\";","module.exports = __webpack_public_path__ + \"HeavySnowWhite.svg\";","module.exports = __webpack_public_path__ + \"HeavySnowV2.svg\";","module.exports = __webpack_public_path__ + \"Hide.svg\";","module.exports = __webpack_public_path__ + \"HideStory.svg\";","module.exports = __webpack_public_path__ + \"HideStoryV2.svg\";","module.exports = __webpack_public_path__ + \"Hotel.svg\";","module.exports = __webpack_public_path__ + \"HurricaneFull.svg\";","module.exports = __webpack_public_path__ + \"Hurricane.svg\";","module.exports = __webpack_public_path__ + \"Hurricane1.svg\";","module.exports = __webpack_public_path__ + \"Hurricane2.svg\";","module.exports = __webpack_public_path__ + \"Hurricane3.svg\";","module.exports = __webpack_public_path__ + \"Hurricane4.svg\";","module.exports = __webpack_public_path__ + \"Hurricane5.svg\";","module.exports = __webpack_public_path__ + \"HurricaneTC.svg\";","module.exports = __webpack_public_path__ + \"HurricaneTD.svg\";","module.exports = __webpack_public_path__ + \"HurricaneTS.svg\";","module.exports = __webpack_public_path__ + \"Information.svg\";","module.exports = __webpack_public_path__ + \"InteractionRequiredDark.svg\";","module.exports = __webpack_public_path__ + \"InteractionRequiredLight.svg\";","module.exports = __webpack_public_path__ + \"Interested.svg\";","module.exports = __webpack_public_path__ + \"ListMenu.svg\";","module.exports = __webpack_public_path__ + \"LightRain.svg\";","module.exports = __webpack_public_path__ + \"LightRainWhite.svg\";","module.exports = __webpack_public_path__ + \"LightRainV2.svg\";","module.exports = __webpack_public_path__ + \"LightSnow.svg\";","module.exports = __webpack_public_path__ + \"LightSnowWhite.svg\";","module.exports = __webpack_public_path__ + \"LightSnowV2.svg\";","module.exports = __webpack_public_path__ + \"Like.svg\";","module.exports = __webpack_public_path__ + \"LikeText.svg\";","module.exports = __webpack_public_path__ + \"Liked.svg\";","module.exports = __webpack_public_path__ + \"LikedText.svg\";","module.exports = __webpack_public_path__ + \"Line.svg\";","module.exports = __webpack_public_path__ + \"Link.svg\";","module.exports = __webpack_public_path__ + \"LinkedIn.svg\";","module.exports = __webpack_public_path__ + \"LinkedInBlack.svg\";","module.exports = __webpack_public_path__ + \"LinkedInText.svg\";","module.exports = __webpack_public_path__ + \"LocaleLanguage.svg\";","module.exports = __webpack_public_path__ + \"Locate.svg\";","module.exports = __webpack_public_path__ + \"LocateWhite.svg\";","module.exports = __webpack_public_path__ + \"LocationDetect.svg\";","module.exports = __webpack_public_path__ + \"Mail.svg\";","module.exports = __webpack_public_path__ + \"MailBlack.svg\";","module.exports = __webpack_public_path__ + \"MailRoundedCorners.svg\";","module.exports = __webpack_public_path__ + \"MailNoFill.svg\";","module.exports = __webpack_public_path__ + \"ManagedBriefcase.svg\";","module.exports = __webpack_public_path__ + \"ManagedBriefcaseNoFill.svg\";","module.exports = __webpack_public_path__ + \"MapZoomIn.svg\";","module.exports = __webpack_public_path__ + \"MapZoomOut.svg\";","module.exports = __webpack_public_path__ + \"Message.svg\";","module.exports = __webpack_public_path__ + \"MessageNoFill.svg\";","module.exports = __webpack_public_path__ + \"Messages.svg\";","module.exports = __webpack_public_path__ + \"MicrosoftLogo.svg\";","module.exports = __webpack_public_path__ + \"MicrosoftNews.svg\";","module.exports = __webpack_public_path__ + \"MicrosoftNewsFull.svg\";","module.exports = __webpack_public_path__ + \"MicrosoftNewsFull_FR.svg\";","module.exports = __webpack_public_path__ + \"MicrosoftNewsFull_ZH.svg\";","module.exports = __webpack_public_path__ + \"ModerateRain.svg\";","module.exports = __webpack_public_path__ + \"ModerateRainWhite.svg\";","module.exports = __webpack_public_path__ + \"ModerateRainV2.svg\";","module.exports = __webpack_public_path__ + \"More.svg\";","module.exports = __webpack_public_path__ + \"Movie.svg\";","module.exports = __webpack_public_path__ + \"MsnLogo.svg\";","module.exports = __webpack_public_path__ + \"NightTime.svg\";","module.exports = __webpack_public_path__ + \"Office.svg\";","module.exports = __webpack_public_path__ + \"OfficeFormsLogo.svg\";","module.exports = __webpack_public_path__ + \"OneDrive.svg\";","module.exports = __webpack_public_path__ + \"OneNote.svg\";","module.exports = __webpack_public_path__ + \"Onetoc.svg\";","module.exports = __webpack_public_path__ + \"Open.svg\";","module.exports = __webpack_public_path__ + \"OpenSquared.svg\";","module.exports = __webpack_public_path__ + \"Outlook.svg\";","module.exports = __webpack_public_path__ + \"PartlyCloudyDay.svg\";","module.exports = __webpack_public_path__ + \"PartlyCloudyDayWhite.svg\";","module.exports = __webpack_public_path__ + \"PartlyCloudyDayV2.svg\";","module.exports = __webpack_public_path__ + \"PartlyCloudyNight.svg\";","module.exports = __webpack_public_path__ + \"PartlyCloudyNightWhite.svg\";","module.exports = __webpack_public_path__ + \"PartlyCloudyNightV2.svg\";","module.exports = __webpack_public_path__ + \"Pdf.svg\";","module.exports = __webpack_public_path__ + \"People.svg\";","module.exports = __webpack_public_path__ + \"Pencil.svg\";","module.exports = __webpack_public_path__ + \"Pin.svg\";","module.exports = __webpack_public_path__ + \"PowerBI.svg\";","module.exports = __webpack_public_path__ + \"PowerPoint.svg\";","module.exports = __webpack_public_path__ + \"Pptx.svg\";","module.exports = __webpack_public_path__ + \"PriceDrop.svg\";","module.exports = __webpack_public_path__ + \"PriceDropBlue.svg\";","module.exports = __webpack_public_path__ + \"Project.svg\";","module.exports = __webpack_public_path__ + \"Radar.svg\";","module.exports = __webpack_public_path__ + \"RainShowersDay.svg\";","module.exports = __webpack_public_path__ + \"RainShowersDayWhite.svg\";","module.exports = __webpack_public_path__ + \"RainShowersDayV2.svg\";","module.exports = __webpack_public_path__ + \"RainShowersNight.svg\";","module.exports = __webpack_public_path__ + \"RainShowersNightWhite.svg\";","module.exports = __webpack_public_path__ + \"RainShowersNightV2.svg\";","module.exports = __webpack_public_path__ + \"RainSnow.svg\";","module.exports = __webpack_public_path__ + \"RainSnowV2.svg\";","module.exports = __webpack_public_path__ + \"RainSnowShowersDay.svg\";","module.exports = __webpack_public_path__ + \"RainSnowShowersDayWhite.svg\";","module.exports = __webpack_public_path__ + \"RainSnowShowersNight.svg\";","module.exports = __webpack_public_path__ + \"RainSnowShowersNightWhite.svg\";","module.exports = __webpack_public_path__ + \"RainSnowShowersNightV2.svg\";","module.exports = __webpack_public_path__ + \"RainSnowWhite.svg\";","module.exports = __webpack_public_path__ + \"Refresh.svg\";","module.exports = __webpack_public_path__ + \"Remove.svg\";","module.exports = __webpack_public_path__ + \"Save.svg\";","module.exports = __webpack_public_path__ + \"Saved.svg\";","module.exports = __webpack_public_path__ + \"SetHome.svg\";","module.exports = __webpack_public_path__ + \"Search.svg\";","module.exports = __webpack_public_path__ + \"Share.svg\";","module.exports = __webpack_public_path__ + \"ShareRoundedCorners.svg\";","module.exports = __webpack_public_path__ + \"ShareLight.svg\";","module.exports = __webpack_public_path__ + \"ShareNoFill.svg\";","module.exports = __webpack_public_path__ + \"Sharepoint.svg\";","module.exports = __webpack_public_path__ + \"Shopping.svg\";","module.exports = __webpack_public_path__ + \"ShoppingDealsDark.svg\";","module.exports = __webpack_public_path__ + \"ShoppingDealsLight.svg\";","module.exports = __webpack_public_path__ + \"Skype.svg\";","module.exports = __webpack_public_path__ + \"SkypeOffice.svg\";","module.exports = __webpack_public_path__ + \"SnowShowersDay.svg\";","module.exports = __webpack_public_path__ + \"SnowShowersDayWhite.svg\";","module.exports = __webpack_public_path__ + \"SnowShowersDayV2.svg\";","module.exports = __webpack_public_path__ + \"SnowShowersNight.svg\";","module.exports = __webpack_public_path__ + \"SnowShowersNightWhite.svg\";","module.exports = __webpack_public_path__ + \"SnowShowersNightV2.svg\";","module.exports = __webpack_public_path__ + \"Star.svg\";","module.exports = __webpack_public_path__ + \"StarFill.svg\";","module.exports = __webpack_public_path__ + \"StarFollow.svg\";","module.exports = __webpack_public_path__ + \"StarFollowBlue.svg\";","module.exports = __webpack_public_path__ + \"Stars.svg\";","module.exports = __webpack_public_path__ + \"SunnyDay.svg\";","module.exports = __webpack_public_path__ + \"SunnyDayWhite.svg\";","module.exports = __webpack_public_path__ + \"SunnyDayV2.svg\";","module.exports = __webpack_public_path__ + \"Sway.svg\";","module.exports = __webpack_public_path__ + \"SwayApp.svg\";","module.exports = __webpack_public_path__ + \"Teams.svg\";","module.exports = __webpack_public_path__ + \"ThumbnailView.svg\";","module.exports = __webpack_public_path__ + \"Thunderstorms.svg\";","module.exports = __webpack_public_path__ + \"ThunderstormsWhite.svg\";","module.exports = __webpack_public_path__ + \"ThunderstormsV2.svg\";","module.exports = __webpack_public_path__ + \"Trending.svg\";","module.exports = __webpack_public_path__ + \"Twitter.svg\";","module.exports = __webpack_public_path__ + \"TwitterBlack.svg\";","module.exports = __webpack_public_path__ + \"TwitterNoFill.svg\";","module.exports = __webpack_public_path__ + \"TwitterText.svg\";","module.exports = __webpack_public_path__ + \"Unpin.svg\";","module.exports = __webpack_public_path__ + \"Upload.svg\";","module.exports = __webpack_public_path__ + \"VerticalSeparator.svg\";","module.exports = __webpack_public_path__ + \"VideoMediaIcon.svg\";","module.exports = __webpack_public_path__ + \"VideoPlay.svg\";","module.exports = __webpack_public_path__ + \"VideoFallback.svg\";","module.exports = __webpack_public_path__ + \"Visio.svg\";","module.exports = __webpack_public_path__ + \"Vkcom.svg\";","module.exports = __webpack_public_path__ + \"Vsdx.svg\";","module.exports = __webpack_public_path__ + \"WaterDropL2.svg\";","module.exports = __webpack_public_path__ + \"WeatherAlert.svg\";","module.exports = __webpack_public_path__ + \"WeatherBarometer.svg\";","module.exports = __webpack_public_path__ + \"WeatherCloud.svg\";","module.exports = __webpack_public_path__ + \"WeatherDewpoint.svg\";","module.exports = __webpack_public_path__ + \"WeatherWarning.svg\";","module.exports = __webpack_public_path__ + \"WeatherWatch.svg\";","module.exports = __webpack_public_path__ + \"WeatherAdvisory.svg\";","module.exports = __webpack_public_path__ + \"WeatherExpand.svg\";","module.exports = __webpack_public_path__ + \"WeatherIcon.svg\";","module.exports = __webpack_public_path__ + \"WeatherMapPause.svg\";","module.exports = __webpack_public_path__ + \"WeatherMapPlay.svg\";","module.exports = __webpack_public_path__ + \"WeatherPrecipitation.svg\";","module.exports = __webpack_public_path__ + \"WeatherSatellite.svg\";","module.exports = __webpack_public_path__ + \"WeatherTemperature.svg\";","module.exports = __webpack_public_path__ + \"WeatherVisiblity.svg\";","module.exports = __webpack_public_path__ + \"WeatherWind.svg\";","module.exports = __webpack_public_path__ + \"WeatherWindDir.svg\";","module.exports = __webpack_public_path__ + \"WeeklyAdsDark.svg\";","module.exports = __webpack_public_path__ + \"WeeklyAdsLight.svg\";","module.exports = __webpack_public_path__ + \"WhatsApp.svg\";","module.exports = __webpack_public_path__ + \"WhatsAppBlack.svg\";","module.exports = __webpack_public_path__ + \"Windy.svg\";","module.exports = __webpack_public_path__ + \"WindyWhite.svg\";","module.exports = __webpack_public_path__ + \"WindyV2.svg\";","module.exports = __webpack_public_path__ + \"Word.svg\";","module.exports = __webpack_public_path__ + \"World.svg\";","module.exports = __webpack_public_path__ + \"Xlsx.svg\";","module.exports = __webpack_public_path__ + \"Yammer.svg\";","// © Microsoft Corporation. All rights reserved.\r\n\r\n// See https://webpack.js.org/guides/public-path/#on-the-fly for the details of __webpack_public_path__\r\n\r\nimport { UrlSearchParamsHelper, UrlUtility } from \"../utilities\";\r\n\r\nimport { headData } from \"../app/HeadData\";\r\n\r\ndeclare let __webpack_public_path__: string;\r\nconst prodAssets = \"//assets.msn.com\";\r\nconst cnProdAssets = \"//assets.msn.cn\";\r\n\r\nconst ENV = {\r\n \"microsoftnews.msn.com\": prodAssets,\r\n \"microsoftnews-int1.msn.com\": prodAssets,\r\n \"microsoftnews.msn.cn\": cnProdAssets,\r\n \"microsoftnews-int1.msn.cn\": cnProdAssets,\r\n \"microsoftnews-dev.msn.com\": prodAssets,\r\n \"ntp.msn.com\": prodAssets,\r\n \"ntp.msn.cn\": cnProdAssets,\r\n \"owa.msn.com\": prodAssets,\r\n \"www.msn.com\": prodAssets,\r\n \"www.msn.cn\": cnProdAssets,\r\n \"int1.msn.com\": prodAssets,\r\n \"int1.msn.cn\": cnProdAssets,\r\n \"int.msn.com\": prodAssets,\r\n \"int.msn.cn\": cnProdAssets,\r\n \"pagecomposition.msn.com\": prodAssets,\r\n \"pagecomposition-int.msn.com\": prodAssets,\r\n \"superapp.msn.cn\": cnProdAssets,\r\n \"superapp.msn.com\": prodAssets,\r\n \"superapp-int1.msn.cn\": cnProdAssets,\r\n \"superapp-int1.msn.com\": prodAssets,\r\n \"windows.msn.com\": prodAssets,\r\n \"windows.msn.cn\": cnProdAssets,\r\n \"windows-int1.msn.com\": prodAssets,\r\n \"windows-int1.msn.cn\": cnProdAssets,\r\n \"localhost:6000\": prodAssets // for pcs local dev box\r\n};\r\n\r\nexport const initializePublicPath = () => {\r\n if (ENV[window.location.host]) {\r\n // Combine query string params from HeadData with current query string param\r\n // to figure out what is the supported qsp is.\r\n // This is to solve qsp rewritten to PCS but client side have no qsp in address.\r\n const headDataQsp = headData.ClientSettings && headData.ClientSettings.queryparams;\r\n const searchParamStringLocation = (window.location.search || \"\").substring(1);\r\n const searchParamStringHeadData = (headDataQsp || \"\").substring(1);\r\n\r\n // Current query string param from client side has higher priority\r\n let combinedString = \"?\" + searchParamStringHeadData ? searchParamStringLocation + \"&\" + searchParamStringHeadData : searchParamStringLocation;\r\n combinedString = decodeURIComponent(combinedString);\r\n\r\n // For duplicate qsp keys, UrlSearchParamsHelper assumes first given, and other duplicates are ignored.\r\n const search = new UrlSearchParamsHelper(combinedString);\r\n const bundlesValue = search.get(\"bundles\");\r\n\r\n // Item qsp supports multiple items. First value of the same key will be used.\r\n // Example, spalinkValue is rolling when qsp is item=test&item=spalink:rolling&item=spalink:123.45\r\n const itemParams = UrlUtility.getParamsWithItems(combinedString);\r\n const spalinkItem = itemParams.find(item => item.key === \"spalink\");\r\n const spalinkValue = spalinkItem && spalinkItem.value;\r\n const isRolling = spalinkValue === \"rolling\";\r\n\r\n if (spalinkItem && !isRolling) {\r\n __webpack_public_path__ = ENV[window.location.host] + __webpack_public_path__;\r\n } else {\r\n // default case without spalink override\r\n // in order to have the lazy chunk pointing to latest with a stable path, the build number will be overridden on runtime\r\n // PATHNAME: /bundles/v1/mmx/20190221.2/\r\n // PATHNAME.split(\"/\"): [\"\", \"bundles\", \"v1\", \"mmx\", \"20190221.2\", \"\"]\r\n const segments = __webpack_public_path__.split(\"/\");\r\n if (isRolling) {\r\n segments[4] = \"rolling\";\r\n } else if (bundlesValue) {\r\n segments[4] = bundlesValue;\r\n } else {\r\n segments[4] = \"latest\";\r\n }\r\n __webpack_public_path__ = ENV[window.location.host] + segments.join(\"/\");\r\n }\r\n }\r\n};\r\n\r\nexport const initializeHybridPublicPath = () => {\r\n const search = decodeURIComponent(window.location.search);\r\n if (search.indexOf(\"item=spa_env:localdev\") > -1) {\r\n // Use active prime instance SPA directory for localdev\r\n __webpack_public_path__ = `//${window.location.host}/spa/`;\r\n return;\r\n }\r\n\r\n const host = ENV[window.location.host] || prodAssets;\r\n const isOverriden = search.indexOf(\"item=spalink:\") > -1;\r\n if (isOverriden) {\r\n __webpack_public_path__ = host + __webpack_public_path__;\r\n } else {\r\n // default case without spalink override\r\n // in order to have the lazy chunk pointing to latest with a stable path, the build number will be overridden on runtime\r\n // PATHNAME: /bundles/v1/mmx/20190221.2/\r\n // PATHNAME.split(\"/\"): [\"\", \"bundles\", \"v1\", \"mmx\", \"20190221.2\", \"\"]\r\n const segments = __webpack_public_path__.split(\"/\");\r\n segments[4] = \"latest\";\r\n __webpack_public_path__ = host + segments.join(\"/\");\r\n }\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { initializeHybridPublicPath } from \"@msnews/core\";\r\n\r\ninitializeHybridPublicPath();","// © Microsoft Corporation. All rights reserved.\r\n\r\n// TODO: This should be considered for moving it to the Interests experience wrapper, once that\r\n// code arrives, since this is specific to that experience\r\n\r\n/**\r\n * Tab Names\r\n * @export\r\n * @type {object}\r\n */\r\nexport const SubnavTabName = {\r\n Interests: \"cinterests\",\r\n MyFeed: \"newsfeed\",\r\n XFeed: \"xfeed\"\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { IActivityLogItem } from \"clientcore-infrastructure-analytics/models/IActivityLogItem\";\r\nimport { ILoggingService } from \"clientcore-infrastructure-analytics/ILoggingService\";\r\nimport { LoggedExceptionManager } from \"clientcore-infrastructure-analytics/LoggedExceptionManager\";\r\n\r\n/**\r\n * ExponentialBackoffRetry implements retry logic for transient errors.\r\n * When encountering transient errors, the request is tried again and each retry is delayed exponentially using following calculation:\r\n * Math.min(this.baseRetryDelay * Math.pow(this.factor, retry), this.maxRetryDelay).\r\n * The request is retried until maximum retry count is reached or the request completes successfully or fails with a non-transient error.\r\n * Each delay is offset by a random number between a minimum and maximum offset range, so that in the cases of when there is a failure\r\n * where many clients fail at once (e.g. network outage) there is not a huge amount of requests at the same time to the server.\r\n * @class\r\n */\r\nexport class ExponentialBackoffRetry {\r\n\r\n /**\r\n * Default base delay between each retries.\r\n * @type {number}\r\n */\r\n private static defaultBaseRetryDelayInMs = 100;\r\n\r\n /**\r\n * Default exponential factor to use to increase each retry delay.\r\n * @type {number}\r\n */\r\n private static defaultFactor = 2;\r\n\r\n /**\r\n * Default maximum offset for each delay.\r\n * @type {number}\r\n */\r\n private static defaultMaxOffsetInMs = 25;\r\n\r\n /**\r\n * Default number of retries.\r\n * @type {number}\r\n */\r\n private static defaultMaxRetries = 5;\r\n\r\n /**\r\n * Default minimum offset for each delay.\r\n * @type {number}\r\n */\r\n private static defaultMinOffsetInMs = 1;\r\n\r\n /**\r\n * Maximum allowed number of retries.\r\n * @type {number}\r\n */\r\n private static maxAllowedRetries = 10;\r\n\r\n /**\r\n * Maximum allowed time in milliseconds to delay each retry.\r\n * @type {number}\r\n */\r\n private static maxAllowedRetryDelayInMs = 2000;\r\n\r\n /**\r\n * Base delay value in milliseconds to delay each retry.\r\n * Default value is 100.\r\n * @type {number}\r\n */\r\n private baseRetryDelayInMs: number;\r\n\r\n /**\r\n * The exponential factor to use for delaying each subsequent retry.\r\n * Default value is 2.\r\n * @type {number}\r\n */\r\n private factor: number;\r\n\r\n /**\r\n * The logging service\r\n * @type {ILoggingService}\r\n */\r\n private loggingService: ILoggingService;\r\n\r\n /**\r\n * Maximum delay offet in milliseconds.\r\n * Default value is 25.\r\n * @type {number}\r\n */\r\n private maxOffsetInMs: number;\r\n\r\n /**\r\n * Maximum number of retries.\r\n * Default is 5.\r\n * @type {number}\r\n */\r\n private maxRetries: number;\r\n\r\n /**\r\n * Maximum delay in milliseconds between each retry.\r\n * Default value is 2000.\r\n * @type {number}\r\n */\r\n private maxRetryDelayInMs: number;\r\n\r\n /**\r\n * Minimum delay offet in milliseconds.\r\n * Default value is 1.\r\n * @type {number}\r\n */\r\n private minOffsetInMs: number;\r\n\r\n /**\r\n * Initializes a new instance of the 'ExponentialBackoffRetry' class.\r\n *\r\n * @constructor\r\n * @param loggingService {ILoggingService}\r\n * @param maxRetries? {number} The maximum number of times to retry the operation. Default is 5 and maximum value allowed is 10.\r\n * @param baseRetryDelayInMs? {number} The base delay in milliseconds for each retry. Default is 100.\r\n * @param maxRetryDelayInMs? {number} The maximum number of milliseconds between two retries. Default and maximum allowed is 2000.\r\n * @param factor? {number} The exponential factor to use. Default is 2.\r\n * @param minOffsetInMs? {number} The minimum delay in milliseconds offset to use. Default is 1.\r\n * @param maxOffsetInMs? {number} The maximum delay in milliseconds offset to use. Default is 25.\r\n */\r\n constructor(\r\n loggingService: ILoggingService,\r\n maxRetries?: number,\r\n baseRetryDelayInMs?: number,\r\n maxRetryDelayInMs?: number,\r\n factor?: number,\r\n minOffsetInMs?: number,\r\n maxOffsetInMs?: number) {\r\n if (!loggingService) {\r\n throw new Error(\"loggingService is required for ExponentialBackoffRetry.\");\r\n }\r\n\r\n const loggedExceptionManager = new LoggedExceptionManager(loggingService);\r\n\r\n this.logInvalidParams(\r\n loggedExceptionManager,\r\n maxRetries,\r\n baseRetryDelayInMs,\r\n maxRetryDelayInMs,\r\n factor,\r\n maxOffsetInMs\r\n );\r\n\r\n this.loggingService = loggingService;\r\n this.maxRetries = maxRetries || ExponentialBackoffRetry.defaultMaxRetries;\r\n this.baseRetryDelayInMs = baseRetryDelayInMs || ExponentialBackoffRetry.defaultBaseRetryDelayInMs;\r\n this.maxRetryDelayInMs = maxRetryDelayInMs || ExponentialBackoffRetry.maxAllowedRetryDelayInMs;\r\n this.factor = factor || ExponentialBackoffRetry.defaultFactor;\r\n this.minOffsetInMs = minOffsetInMs || ExponentialBackoffRetry.defaultMinOffsetInMs;\r\n this.maxOffsetInMs = maxOffsetInMs || ExponentialBackoffRetry.defaultMaxOffsetInMs;\r\n\r\n this.loggingService.infoCallback(() => \"ExponentialBackoffRetry has been configured.\", null, { maxRetries, minTimeout: baseRetryDelayInMs, maxTimeout: maxRetryDelayInMs, factor });\r\n }\r\n\r\n /**\r\n * Execute given request and retry it as configured.\r\n * @param serviceCall {() => Promise}\r\n */\r\n public async executeRequest(serviceCall: () => Promise, requestInfo?: any, activity?: IActivityLogItem): Promise {\r\n return new Promise(async(resolve, reject) => {\r\n await this.tryRequest(serviceCall, resolve, reject, 0 /* currentRetry is 0 based */, requestInfo, activity);\r\n });\r\n }\r\n\r\n /**\r\n * Log valid params to the class constructor.\r\n *\r\n * @constructor\r\n * @param loggedExceptionManager {LoggedExceptionManager}\r\n * @param maxRetries? {number} The maximum number of times to retry the operation. Default is 5 and maximum value allowed is 10.\r\n * @param baseRetryDelayInMs? {number} The base delay in milliseconds for each retry. Default is 100.\r\n * @param maxRetryDelayInMs? {number} The maximum number of milliseconds between two retries. Default and maximum allowed is 2000.\r\n * @param factor? {number} The exponential factor to use. Default is 2.\r\n */\r\n private logInvalidParams(\r\n loggedExceptionManager: LoggedExceptionManager,\r\n maxRetries?: number,\r\n baseRetryDelayInMs?: number,\r\n maxRetryDelayInMs?: number,\r\n factor?: number,\r\n maxOffsetInMs?: number): void {\r\n if (maxRetries && (maxRetries < 1 || maxRetries > ExponentialBackoffRetry.maxAllowedRetries)) {\r\n loggedExceptionManager.fatal(`maxRetries should be at least 1 and less than ${ExponentialBackoffRetry.maxAllowedRetries}.`);\r\n }\r\n\r\n if (baseRetryDelayInMs && baseRetryDelayInMs < ExponentialBackoffRetry.defaultBaseRetryDelayInMs) {\r\n loggedExceptionManager.fatal(\"baseRetryDelay has to be a positive value greater than or equal to 100.\");\r\n }\r\n\r\n if (baseRetryDelayInMs && maxOffsetInMs && baseRetryDelayInMs <= maxOffsetInMs) {\r\n loggedExceptionManager.fatal(\"baseRetryDelay must not be smaller than the maximum delay offset.\");\r\n }\r\n\r\n if (maxRetryDelayInMs && (maxRetryDelayInMs <= 0 || maxRetryDelayInMs > ExponentialBackoffRetry.maxAllowedRetryDelayInMs)) {\r\n loggedExceptionManager.fatal(`maxRetryDelay has to be a positive value less than ${ExponentialBackoffRetry.maxAllowedRetryDelayInMs}.`);\r\n }\r\n\r\n if (factor && factor <= 0) {\r\n loggedExceptionManager.fatal(\"factor has to be a positive value.\");\r\n }\r\n }\r\n\r\n /**\r\n * Try the request if it fails with a transient error.\r\n * @param serviceCall {() => Promise} The request to execute and retry.\r\n * @param currentRetry {number} current retry count, 0 based.\r\n * @param requestInfo? {TRequestInfo} Additional request info to include in logging.\r\n * @param activity? {IActivityLogItem} Optional activity to associate logged messages with.\r\n * @returns {Promise}\r\n */\r\n private async tryRequest(\r\n serviceCall: () => Promise,\r\n resolve: (result?: any) => void,\r\n reject: (error: any) => void,\r\n currentRetry: number,\r\n requestInfo?: any,\r\n activity?: IActivityLogItem): Promise {\r\n try {\r\n const timeoutInMs = 10000; // Default timeout is 10 sec\r\n const response = await this.timeoutServiceRequest(timeoutInMs, serviceCall());\r\n resolve(response);\r\n } catch (error) {\r\n // Check if the error is transient and retry if we didn't exceed the retry count.\r\n if (currentRetry < this.maxRetries) {\r\n // Offset for delay, in the instance where there is some sort of outage and all clients retry at the same interval. In this case it will stagger the retries.\r\n const fractionDigit = 3;\r\n const offset = parseFloat((Math.random() * (this.minOffsetInMs - this.maxOffsetInMs) + this.maxOffsetInMs).toFixed(fractionDigit));\r\n // Weather to add or subtract the random element.\r\n const half = 0.5;\r\n const plusOrMinus = Math.random() < half ? -1 : 1;\r\n // Delay the retry based on the factor and the current retry count. Do not exceed maximum delay allowed.\r\n const delay = Math.min(this.baseRetryDelayInMs * Math.pow(this.factor, currentRetry), this.maxRetryDelayInMs);\r\n // Offset the delay either positively or negatively by the offset.\r\n const delayWithOffset = delay + (offset * plusOrMinus);\r\n this.loggingService.warnCallback(() => `Retrying the request in ${delayWithOffset} milliseconds.`, activity, { error, currentRetry: currentRetry + 1, requestInfo });\r\n setTimeout(() => this.tryRequest(serviceCall, resolve, reject, currentRetry + 1, requestInfo, activity), delayWithOffset);\r\n } else {\r\n // Give up retrying.\r\n this.loggingService.errorCallback(\r\n () => (currentRetry < this.maxRetries) ? `ExponentialBackoffRetry has exceeded maximum retries ${this.maxRetries}` : \"Request has failed.\",\r\n activity,\r\n { error, currentRetry, requestInfo });\r\n reject(error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Timeout functionality for service call;\r\n * This is not a connection timeout but rather a response timeout\r\n *\r\n * @param {number} timeoutInMs - The timeout in ms\r\n * @param {Promise} promise - The promise for service call\r\n * @return {Promise} - A promise of the service response\r\n */\r\n private async timeoutServiceRequest(timeoutInMs: number, promise: Promise): Promise {\r\n return new Promise(async (resolve, reject) => {\r\n const timeoutId = setTimeout(() => reject(new Error(\"Service Request Timed out!\")), timeoutInMs);\r\n\r\n try {\r\n const response = await promise;\r\n resolve(response);\r\n clearTimeout(timeoutId);\r\n } catch (error) {\r\n reject(error);\r\n clearTimeout(timeoutId);\r\n }\r\n });\r\n }\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ActivityLoggingService } from \"clientcore-infrastructure-analytics/ActivityLoggingService\";\r\nimport { BrowserConsoleAppender } from \"clientcore-infrastructure-analytics/appenders/BrowserConsoleAppender\";\r\nimport { ExponentialBackoffRetry } from \"@msnews/core\";\r\nimport { IInstrumentationService } from \"clientcore-infrastructure-analytics/IInstrumentationService\";\r\nimport { InstrumentationService } from \"clientcore-infrastructure-analytics/InstrumentationService\";\r\nimport { LogLevel } from \"clientcore-infrastructure-analytics/models/LogLevel\";\r\nimport { OneServiceUtility } from \"./OneServiceUtility\";\r\nimport { logger } from \"@msnews/diagnostics\";\r\n\r\n/**\r\n * Instrumentation service\r\n *\r\n * @type {IInstrumentationService}\r\n */\r\nlet instrumentationService: IInstrumentationService;\r\n\r\n/**\r\n * Retry manager\r\n *\r\n * @type {ExponentialBackoffRetry}\r\n */\r\nlet exponentialBackoffRetry: ExponentialBackoffRetry;\r\n\r\n/**\r\n * Number of times to retry requests\r\n */\r\nconst retryCount = 3;\r\n\r\n/**\r\n * Sends a request\r\n *\r\n * @returns {Promise} - A promise to fulfill the request\r\n */\r\nexport async function sendRequest(request: () => Promise, activityName: string): Promise {\r\n const activity = getInstrumentationService().activityLoggingService.createActivity(activityName);\r\n\r\n return await OneServiceUtility.serviceRequestOnComplete(\r\n () => getExponentialBackoffRetry().executeRequest(request, null, activity),\r\n () => getInstrumentationService().activityLoggingService.endActivity(activity));\r\n}\r\n\r\n/**\r\n * Get exponential backoff retry instance\r\n */\r\nfunction getExponentialBackoffRetry(): ExponentialBackoffRetry {\r\n if (exponentialBackoffRetry) {\r\n return exponentialBackoffRetry;\r\n }\r\n\r\n exponentialBackoffRetry = new ExponentialBackoffRetry(getInstrumentationService().loggingService, retryCount);\r\n\r\n return exponentialBackoffRetry;\r\n}\r\n\r\n/**\r\n * Get instrumentation service instance\r\n */\r\nfunction getInstrumentationService(): IInstrumentationService {\r\n if (instrumentationService) {\r\n return instrumentationService;\r\n }\r\n\r\n const activityService = ActivityLoggingService.getInstance(\"ExperienceActivityLogger\");\r\n // Todo: use a different appender to log into mds tables\r\n if (logger.isDebug()) {\r\n activityService.addAppender(new BrowserConsoleAppender(LogLevel.Activity));\r\n }\r\n\r\n instrumentationService = new InstrumentationService(logger.getLoggingService(), activityService);\r\n\r\n return instrumentationService;\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ActionMap } from \"../reducers\";\r\nimport { ConnectorConstants } from \"../constants/ConnectorConstants\";\r\nimport { ConnectorNamespaces } from \"@msnews/experiences-constants\";\r\n\r\n/**\r\n * Action signature to trigger an experience to render\r\n */\r\ntype RenderExperienceSignature = () => void;\r\n\r\n/**\r\n * Action signature to initialize data connector state merge.\r\n */\r\ntype DataConnectorMergeInitSignature = (dataConnectorName: ConnectorNamespaces) => void;\r\n\r\n/**\r\n * Actions that are common to all experiences\r\n * @class\r\n */\r\nexport class CommonActions {\r\n /**\r\n * Definition for an action that can be dispatched to any experience causing it to render\r\n */\r\n public static renderExperience: ActionMap = new ActionMap(ConnectorConstants.renderAction);\r\n\r\n /**\r\n * Definition for an action that initializes shared data connector state on an experience.\r\n */\r\n public static dataConnectorMergeInit: ActionMap = new ActionMap(ConnectorConstants.dataConnectorMergeInitAction);\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nexport enum ExperienceState {\r\n /**\r\n * State when experience has not started its lifecycle events\r\n */\r\n NotStarted = 0,\r\n\r\n /**\r\n * This state is when experience is waiting to load its bundles\r\n */\r\n WaitingToLoad = 1,\r\n\r\n /**\r\n * Bundles loaded for experience and connector has been initialized\r\n */\r\n LoadedWaitingToRender = 2,\r\n\r\n /**\r\n * All milestone dependencies have been resolved for this experience and its ready to render\r\n */\r\n ReadyToRender = 3,\r\n\r\n /**\r\n * Experience failed to load\r\n */\r\n Failed = 4,\r\n\r\n /**\r\n * Experience state is not known, probably when timeout happened before dependency is resolved or dependency is on some UI event.\r\n */\r\n Unknown = 5\r\n}","\r\n// © Microsoft Corporation. All rights reserved.\r\n\r\nexport enum ChildExperiencesDeferRenderType {\r\n /**\r\n * Wait for all child experinces milestone load dependecies to be resolved, once all child experiences are loaded and available\r\n * triggers parent re-render. Best from perfomance standpoint as it does a single re-render of parent\r\n */\r\n batch = \"batch\",\r\n\r\n /**\r\n * Render every child experince as soon as its available after milestone load dependecies has been resolved, This is less performant as it triggers\r\n * parent re-render multiple times for each delay loaded child experience\r\n */\r\n renderWhenAvailable = \"renderWhenAvailable\"\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Use this interface to register experiences for page reveal\r\n */\r\nexport interface PageRevealRegistrationInterface {\r\n\r\n /**\r\n * identifier\r\n */\r\n readonly experienceType: string;\r\n\r\n /**\r\n * page reveal info for the experience\r\n */\r\n readonly pageRevealInfo: PageRevealExperienceInfo;\r\n}\r\n\r\n/**\r\n * Page reveal experience information\r\n */\r\nexport interface PageRevealExperienceInfo {\r\n\r\n /**\r\n * experience revalidation reason\r\n */\r\n readonly revalidationReason: ExperiencesRevalidationReason;\r\n\r\n /**\r\n * Staleness threshold in mins\r\n */\r\n readonly stalenessThreshold: number;\r\n\r\n /**\r\n * Provide hook into willRevalidateStaleState event.\r\n * This handler will execute when page reveal starts and registered experience(s) are found to be stale.\r\n */\r\n readonly willRevalidateStaleState?: (isStale: boolean) => Promise | void | boolean;\r\n}\r\n\r\n/**\r\n * Defines the different reasons why the prerendered experience should be reloaded\r\n */\r\nexport enum ExperiencesRevalidationReason {\r\n Staleness = 1,\r\n PersistentDataUpdate = 2\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ChildExperienceConfigInfo } from \"./ChildExperienceConfigInfo\";\r\n\r\n/**\r\n * Specifies validator for child experience\r\n * @export\r\n * @interface\r\n */\r\nexport interface ChildExperienceValidator {\r\n /**\r\n * section name from where child element should be removed\r\n */\r\n sectionName: ValidatorSectionName;\r\n\r\n /**\r\n * ChildExperienceConfigInfo object to be removed\r\n */\r\n childExperienceConfigInfo: ChildExperienceConfigInfo;\r\n\r\n /**\r\n * Optional validation arguments\r\n */\r\n validationArgs?: ValidationArgs;\r\n}\r\n\r\n/**\r\n * section name from where child element should be removed. We can add more support in this list as additionalChildExperiences\r\n * or childExperienceMap. The current design and approach support that.\r\n */\r\nexport enum ValidatorSectionName {\r\n /**\r\n * Section name for River Grid children, positioned by row/column syntax\r\n */\r\n riverGridChildren = \"riverGridChildren\"\r\n}\r\n\r\n/**\r\n * Validation arguments to determine experience enable / disable\r\n * @export\r\n * @interface\r\n */\r\nexport interface ValidationArgs {\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n BaseExperienceConfig,\r\n ChildExperienceConfigInfo,\r\n ChildExperienceValidator,\r\n ChildInfo,\r\n ChildrenTypes,\r\n CustomCompositionConfig,\r\n ExperienceCompositionTypes,\r\n GridCompositionConfig,\r\n HorizontalStackConfig,\r\n LayoutConfig,\r\n PeregrineChildInfo,\r\n ScreenTypeMetadata,\r\n ScreenWidth,\r\n ValidationArgs,\r\n ValidatorSectionName,\r\n VerticalStackConfig\r\n} from \"@msnews/core\";\r\nimport {\r\n ColumnArrangement,\r\n ExperienceInitialProps,\r\n fastBreakpointManager\r\n} from \"@msnews/experiences-base\";\r\n\r\nimport { AppValidator } from \"./AppValidator\";\r\nimport { cloneDeep } from \"lodash-es\";\r\nimport { isFunction } from \"util\";\r\n\r\n/**\r\n * Config Processor class to filter config\r\n * @class\r\n */\r\nexport class ConfigProcessor {\r\n /**\r\n * experience validator map to be provided by app type. Each entry has a validator name and a validator function associated\r\n * with that.\r\n */\r\n static expValidatorMap: Map boolean> = new Map();\r\n\r\n /**\r\n * config map that keeps track of original configs which are modified by ConfigProcessor.\r\n * This is required for partial page refresh scenarios where original config is required for refernce like ReAdding previously removed SD cards\r\n */\r\n static expConfigMap: Map> = new Map();\r\n\r\n /**\r\n * Registers apptype validators\r\n * @method\r\n * @param {AppValidator} apptypeValidator Validator for a specific app type\r\n * @returns {void}\r\n */\r\n public static registerAppValidator(apptypeValidator: AppValidator): void {\r\n this.expValidatorMap = apptypeValidator.getAllValidators();\r\n }\r\n\r\n /**\r\n * process config based on registered validators for current app-type and removes child experience from\r\n * section defined in CMS condig\r\n * @method\r\n * @param {BaseExperienceConfig} expConfig Experience config object\r\n * @returns {BaseExperienceConfig} returns filtered experience config\r\n */\r\n public static processConfig(expConfig: BaseExperienceConfig, namespace: string): BaseExperienceConfig {\r\n if (!this.expValidatorMap || this.expValidatorMap.size < 1 || !expConfig || !expConfig.childExpValidatorMap) {\r\n return expConfig;\r\n }\r\n\r\n const expMap: { [instanceId: string]: ChildExperienceValidator } = expConfig.childExpValidatorMap;\r\n let originalConfig: BaseExperienceConfig = null;\r\n let tempConfig: BaseExperienceConfig = null;\r\n\r\n for (const validatorName in expMap) {\r\n const childExpValidator = expMap[validatorName];\r\n if (this.expValidatorMap.has(validatorName)) {\r\n const validator = this.expValidatorMap.get(validatorName);\r\n const removeChildExp = validator(childExpValidator.validationArgs);\r\n\r\n if (removeChildExp) {\r\n if (tempConfig === null) {\r\n // always use saved config if exists\r\n tempConfig = this.expConfigMap.get(namespace) || expConfig;\r\n }\r\n\r\n // keep a copy of original config\r\n if (originalConfig === null) {\r\n originalConfig = cloneDeep(tempConfig);\r\n }\r\n\r\n expConfig = this.filterConfig(childExpValidator, tempConfig);\r\n }\r\n }\r\n }\r\n\r\n if (originalConfig) {\r\n this.expConfigMap.set(namespace, originalConfig);\r\n } else if (tempConfig === null && this.expConfigMap.has(namespace)) {\r\n // if tempConfig is null, none of the validators returned true.\r\n // restore expConfig with originalConfig for this case\r\n expConfig = this.expConfigMap.get(namespace);\r\n }\r\n\r\n return expConfig;\r\n }\r\n\r\n /**\r\n * remove child experience based on the response from registerd validator and config.\r\n * @method\r\n * @param {ChildExperienceValidator} childExpValidator Experience config object\r\n * @param {BaseExperienceConfig} expConfig Experience config object\r\n * @returns {BaseExperienceConfig} returns filtered experience config\r\n */\r\n private static removeFromRiverGridChildren(childExpValidator: ChildExperienceValidator, expConfig: any): BaseExperienceConfig {\r\n // TODO: River config is in experiences and we should not take dependency of experiences in this project.\r\n // We should move RiverConfig to core config project or expConfig has to be of type any\r\n const riverGridChildren = expConfig.riverGridChildren;\r\n if (riverGridChildren) {\r\n riverGridChildren.forEach(element => {\r\n const childElems = element.children;\r\n if (childElems) {\r\n element.children = childElems.filter((childExp) => {\r\n const configInfo = childExp.childExperienceConfigInfo;\r\n return !configInfo || !childExpValidator.childExperienceConfigInfo\r\n || childExpValidator.childExperienceConfigInfo.instanceId !== configInfo.instanceId\r\n || childExpValidator.childExperienceConfigInfo.experienceType !== configInfo.experienceType;\r\n });\r\n }\r\n });\r\n }\r\n\r\n return expConfig;\r\n }\r\n\r\n /**\r\n * Given a experience config, get a list of child experience configs for child data connectors\r\n * @method\r\n * @param {BaseExperienceConfig} baseExperienceConfig experience config to find child data connectors configs\r\n * @returns {ChildExperienceConfigInfo[]} - child data connectors configs\r\n */\r\n public static getChildrenDataConnectorConfigInfos(baseExperienceConfig: BaseExperienceConfig): ChildExperienceConfigInfo[] {\r\n const childrenConfigInfo: ChildExperienceConfigInfo[] = [];\r\n\r\n if (baseExperienceConfig && baseExperienceConfig.dataConnectors && baseExperienceConfig.dataConnectors.length > 0) {\r\n const dataConnectorForCurrentScreenType = ConfigProcessor.getOrdinalObjectForCurrentBreakpoint(baseExperienceConfig.dataConnectors);\r\n\r\n if (dataConnectorForCurrentScreenType && dataConnectorForCurrentScreenType.children && dataConnectorForCurrentScreenType.children.length > 0) {\r\n dataConnectorForCurrentScreenType.children.forEach(connector => {\r\n childrenConfigInfo.push(connector);\r\n });\r\n }\r\n }\r\n\r\n return childrenConfigInfo;\r\n }\r\n\r\n /**\r\n * Helper function to match screenWidth and return the correct ScreenTypeMetadata object\r\n * @method\r\n * @param {ScreenWidth} screenWidth - screenWidth to match\r\n * @param {ScreenTypeMetadata[]} screenTypeObjList - Array of ScreenTypeMetadata objects\r\n * @returns {ScreenTypeMetadata} returns the matching ScreenTypeMetadata object for given screenWidth.\r\n */\r\n public static getMetadataByScreenWidth(screenWidth: ScreenWidth, screenTypeObjList: ScreenTypeMetadata[]): ScreenTypeMetadata {\r\n const result =\r\n screenTypeObjList.find(obj =>\r\n obj.screenWidth === screenWidth\r\n )\r\n || screenTypeObjList.find(obj =>\r\n obj.screenWidth === ScreenWidth.Any\r\n );\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * This method returns the ScreenTypeMetadata for current breakpoint.\r\n * @method\r\n * @param {ScreenTypeMetadata[]} screenTypeObjList Array of ScreenTypeMetadata objects\r\n * @returns {ScreenTypeMetadata} returns the matching ScreenTypeMetadata object for current breakpoint.\r\n */\r\n public static getOrdinalObjectForCurrentBreakpoint(screenTypeObjList: ScreenTypeMetadata[]): ScreenTypeMetadata {\r\n switch (fastBreakpointManager().currentColumnArrangement) {\r\n case ColumnArrangement.c1: {\r\n return ConfigProcessor.getMetadataByScreenWidth(ScreenWidth.OneColumn, screenTypeObjList);\r\n }\r\n case ColumnArrangement.c2: {\r\n return ConfigProcessor.getMetadataByScreenWidth(ScreenWidth.TwoColumn, screenTypeObjList);\r\n }\r\n case ColumnArrangement.c3: {\r\n return ConfigProcessor.getMetadataByScreenWidth(ScreenWidth.ThreeColumn, screenTypeObjList);\r\n }\r\n case ColumnArrangement.c4: {\r\n return ConfigProcessor.getMetadataByScreenWidth(ScreenWidth.FourColumn, screenTypeObjList);\r\n }\r\n case ColumnArrangement.c5: {\r\n return ConfigProcessor.getMetadataByScreenWidth(ScreenWidth.FiveColumn, screenTypeObjList);\r\n }\r\n default: {\r\n return ConfigProcessor.getMetadataByScreenWidth(ScreenWidth.Any, screenTypeObjList);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Composition resolver. It will return the composition value based on any possible overrides.\r\n * @method\r\n * @param {BaseExperienceConfig} baseExperienceConfig Array of ScreenTypeMetadata objects\r\n * @param {ExperienceInitialProps} connectorProps initial props for connector\r\n * @returns { GridCompositionConfig | LayoutConfig | HorizontalStackConfig | VerticalStackConfig | CustomCompositionConfig } returns composition from config or given override\r\n */\r\n public static compositionOverrideResolver(baseExperienceConfig: BaseExperienceConfig, connectorProps?: ExperienceInitialProps): GridCompositionConfig | LayoutConfig | HorizontalStackConfig | VerticalStackConfig | CustomCompositionConfig {\r\n const { getCompositionIdOverride } = connectorProps || {};\r\n const { composition, compositionOverrides } = baseExperienceConfig;\r\n return compositionOverrides && isFunction(getCompositionIdOverride) && compositionOverrides[getCompositionIdOverride()] || composition;\r\n }\r\n\r\n /**\r\n * Give an experience config, get a list of child experience configs.\r\n * @method\r\n * @param {BaseExperienceConfig} baseExperienceConfig experience config to find child data connectors configs\r\n * @param {ExperienceInitialProps} connectorProps connector props for given experience\r\n * @returns {ChildExperienceConfigInfo[]} - child data connectors configs\r\n */\r\n public static getChildrenExperienceConfigInfos(baseExperienceConfig: BaseExperienceConfig, connectorProps?: ExperienceInitialProps): ChildExperienceConfigInfo[] {\r\n const childrenConfigInfo: ChildExperienceConfigInfo[] = [];\r\n\r\n // Determine if there are any children in the composition portion of the config document.\r\n if (baseExperienceConfig && baseExperienceConfig.composition) {\r\n\r\n const composition = ConfigProcessor.compositionOverrideResolver(baseExperienceConfig, connectorProps);\r\n\r\n switch (composition.type) {\r\n case ExperienceCompositionTypes.horizontalStack:\r\n case ExperienceCompositionTypes.layout: {\r\n\r\n // Iterate over the composition config to find the children\r\n const layoutConfig = composition as LayoutConfig;\r\n\r\n // Iterate over the composition config to find the children\r\n layoutConfig.page.children.forEach(grid => {\r\n\r\n // If the grid does not contain children, then there are no child experiences\r\n if (grid.children === undefined) {\r\n return;\r\n }\r\n\r\n // Iterate over the grid children (each one is a column) and see if there is a child experience\r\n grid.children.forEach((column) => {\r\n\r\n // If the columnProps does not contain children, then there are no child experiences\r\n if (!column.children) {\r\n return;\r\n }\r\n\r\n // If the column.children is a legacy ColumnChildInfo, or of type PeregrineExperience, then\r\n // add the child to the list\r\n const { childType } = column.children as ChildInfo;\r\n if (!childType) {\r\n childrenConfigInfo.push(column.children as ChildExperienceConfigInfo);\r\n } else if (childType === ChildrenTypes.peregrineExperience) {\r\n childrenConfigInfo.push((column.children as PeregrineChildInfo).child);\r\n }\r\n });\r\n });\r\n break;\r\n }\r\n\r\n case ExperienceCompositionTypes.grid: {\r\n\r\n // Iterate over the grid composition config to find the peregrine child experiences to load\r\n const gridRows = (composition as GridCompositionConfig).grid.rows;\r\n gridRows.forEach(row => {\r\n\r\n // If the row does not contain columns, then there are no child experiences\r\n if (row.columns === undefined) {\r\n return;\r\n }\r\n\r\n // Iterate over the grid columns and see if there are any items\r\n row.columns.forEach((column) => {\r\n // If the column.item is a PeregrineExperience, then add the child to the list of children experiences to load\r\n const { itemType } = column.item;\r\n if (itemType && itemType === ChildrenTypes.peregrineExperience) {\r\n childrenConfigInfo.push(column.item.child as ChildExperienceConfigInfo);\r\n }\r\n });\r\n });\r\n break;\r\n }\r\n\r\n case ExperienceCompositionTypes.customExperience: {\r\n const customConfig = composition as CustomCompositionConfig;\r\n childrenConfigInfo.push(customConfig.experience);\r\n\r\n break;\r\n }\r\n\r\n // No children to load, if we do not know what type of composition this experience has\r\n default:\r\n }\r\n }\r\n\r\n return childrenConfigInfo;\r\n }\r\n\r\n /**\r\n * Verify if the section provided in CMS schema is supported for removal of child experiences.\r\n * Currently only riverGridChildren is supported. Support will be extended to other sections.\r\n * @method\r\n * @param {ChildExperienceValidator} childExpValidator Experience config object\r\n * @param {BaseExperienceConfig} expConfig Experience config object\r\n * @returns {BaseExperienceConfig} returns filtered experience config\r\n */\r\n private static filterConfig(childExpValidator: ChildExperienceValidator, expConfig: BaseExperienceConfig): BaseExperienceConfig {\r\n if (childExpValidator && typeof childExpValidator.sectionName === \"string\" && childExpValidator.sectionName.toLowerCase() === ValidatorSectionName.riverGridChildren.toLowerCase()) {\r\n return this.removeFromRiverGridChildren(childExpValidator, expConfig);\r\n }\r\n\r\n return expConfig;\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { PageMeasure, PerfTimeline } from \"./PerfTimeline\";\r\n\r\nimport { getPageTimings } from \"./PageTimings\";\r\nimport { logger } from \"../logging\";\r\n\r\nconst pageTimings = getPageTimings();\r\n\r\n/**\r\n * Utility class to keep track of how many times a key has appeared in order to\r\n * get a uniquely qualified name back to be used in a dictionary.\r\n */\r\nclass KeyCounter {\r\n\r\n /** Lookup of counts for the given key */\r\n private timelineCount: { [name: string]: number } = {};\r\n\r\n /** Gets the qualified key name */\r\n public qualifyKey(timelineName: string): string {\r\n\r\n // get the previous count\r\n const count = this.getCount(timelineName);\r\n\r\n // if we've called it previously append the count as suffix\r\n // to identify it uniquely.\r\n if (count <= 1) {\r\n return timelineName;\r\n }\r\n\r\n return timelineName + count;\r\n }\r\n\r\n /** Resets the counter state to initial values */\r\n public reset(): void {\r\n this.timelineCount = {};\r\n }\r\n\r\n /** Gets the key's appearence count */\r\n private getCount(timelineName: string): number {\r\n\r\n // get the previous count\r\n const count = this.timelineCount[timelineName] || 0;\r\n\r\n // update the new count\r\n return this.timelineCount[timelineName] = count + 1;\r\n }\r\n}\r\n\r\n/**\r\n * Unique key qualifier for distinctly identifying instances of perf timelines\r\n * across multiple instances of the same or different experience types.\r\n * For example, ContentPreview, ContentPreview2, ContentPreview3, etc.\r\n */\r\nconst timelineKeyCount = new KeyCounter();\r\n\r\n/** Suffix for start markers */\r\nconst startSuffix = \"-start\";\r\n\r\n/** Suffix for end markers */\r\nconst endSuffix = \"-end\";\r\n\r\n/**\r\n * This class can be used to aggregate a list of perf markers and their transitions.\r\n */\r\nexport class PerfTimelineImpl implements PerfTimeline {\r\n\r\n /**\r\n * Unique key qualifier for metric names that appear multiple times.\r\n * For example, render, render2, render3, etc.\r\n */\r\n private readonly markerCount: KeyCounter = new KeyCounter();\r\n\r\n /**\r\n * List of in-memory logged markers for this perf-timeline object\r\n */\r\n private readonly measures: Array> = [];\r\n\r\n /**\r\n * Constructor of a {PerfTimeline} instance\r\n * @param timelineName - the name of the perf timeline. Note that if you don't know the name\r\n * of a perf timeline at construction time, it can later be renamed to a known name later via\r\n * the 'rename' method.\r\n * @param instanceId - this specific instance's ID. Used during a renaming operation to idenfity any previous isntance.\r\n * @param addPerfMarks - Flag to indicate whether to log perf marks with the native performance API.\r\n * @param addPageTimings - Flag to indicate whether to log the perf marks into the _pageTimings object.\r\n * @param async - Flag to mark this timeline as an async timeline, so by default all measures under\r\n * this timeline will show under a new process line.\r\n */\r\n public constructor(\r\n public timelineName: string,\r\n public readonly instanceId: string,\r\n private readonly addPerfMarks: boolean,\r\n private readonly addPageTimings: boolean,\r\n private readonly async?: boolean\r\n ) {\r\n this.timelineName = timelineKeyCount.qualifyKey(timelineName);\r\n }\r\n\r\n /**\r\n * Renames this instances of the timeline to the new given name.\r\n * This is useful when the timeline name is not known until after some asynchronous operation is completed,\r\n * but the measuring operation required to be started before the name was known.\r\n * @param timelineName - the new name of the timeline.\r\n */\r\n public rename(timelineName: string): void {\r\n\r\n if (this.timelineName === timelineName) {\r\n return;\r\n }\r\n\r\n if (this.addPageTimings) {\r\n // if we're adding page timings, then make sure we delete the measures under the old name and add the new ones\r\n this.measures.forEach(measure => {\r\n const oldMeasureName = this.qualifyMeasureName(measure.measureName);\r\n delete pageTimings[oldMeasureName + startSuffix];\r\n delete pageTimings[oldMeasureName];\r\n });\r\n }\r\n\r\n this.timelineName = timelineName;\r\n\r\n if (this.addPageTimings) {\r\n // add back the page timings under the new timeline name\r\n this.measures.forEach(measure => {\r\n const newMeasureName = this.qualifyMeasureName(measure.measureName);\r\n pageTimings[newMeasureName + startSuffix] = measure.from;\r\n pageTimings[newMeasureName] = measure.to - measure.from;\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Marks the start of a timeline measurement.\r\n * @param coreMarkerName - the name of the core marker. This value is usually invariant\r\n * from instance to instance (i.e., init, config, render)\r\n * @param dynamicMeasureName - the optional additional identifying name to give for the measure.\r\n * This value can be used to identify dynamic values across instances. For example the\r\n * HREF of the config. This can also later be updated to a new name when calling the 'endMeasure'\r\n * method.\r\n * @param async - flag to indicate whether this is an async measure or not.\r\n * @returns An object with the following properties:\r\n * - endMeasure - method that should be used to mark the end the measure.\r\n */\r\n public startMeasure(coreMarkerName: string, dynamicMeasureName?: string, async?: boolean): { endMeasure: (updatedDynamicMeasureName?: string) => void } {\r\n\r\n const startTime = performance.now();\r\n\r\n const timelineNameAtStart = this.timelineName;\r\n let measureNameCore = this.formatMeasureName(coreMarkerName, dynamicMeasureName);\r\n let measureName = this.qualifyMeasureName(measureNameCore);\r\n\r\n const startMarkerName = measureName + startSuffix;\r\n this.singleMark(startMarkerName);\r\n\r\n if (this.addPageTimings) {\r\n pageTimings[startMarkerName] = startTime;\r\n }\r\n\r\n return {\r\n /**\r\n * Ends the given measure we started\r\n */\r\n endMeasure: (updatedDynamicMeasureName?: string) => {\r\n\r\n const endTime = performance.now();\r\n\r\n // flag to indicate whether we need to re-qualify the measure name based on frequency. Note that we only\r\n // set this to true if the timeline name has changed since start, or we have a new dynamic name at the end.\r\n const requalifyMeasureName = updatedDynamicMeasureName\r\n || (timelineNameAtStart !== this.timelineName);\r\n\r\n if (requalifyMeasureName) {\r\n // if by the time we're ending the measure, we have a new dynamic name for the measurement, use that as the final measure name.\r\n measureNameCore = this.formatMeasureName(coreMarkerName, updatedDynamicMeasureName);\r\n measureName = this.qualifyMeasureName(measureNameCore);\r\n }\r\n\r\n const endMarkerName = measureName + endSuffix;\r\n\r\n this.singleMark(endMarkerName);\r\n this.measure(measureName, startMarkerName, endMarkerName);\r\n\r\n // Note we only save the partial metric without the timeline name, so we can use the final timeline name\r\n // if any rename operations happen while initial measurements have started without the final timeline name\r\n this.measures.push({\r\n measureName: measureNameCore,\r\n async: (async != null) ? async : this.async,\r\n from: startTime,\r\n to: endTime\r\n });\r\n\r\n if (this.addPageTimings) {\r\n pageTimings[measureName] = endTime - startTime;\r\n }\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Returns the list of page measures for this timeline object\r\n * @returns {Array} containing the fully qualified list of metric names for this perf timeline.\r\n */\r\n public getPageMeasures(): Array {\r\n return this.measures.map(measure => ({\r\n ...measure,\r\n timelineName: this.timelineName\r\n }));\r\n }\r\n\r\n /**\r\n * Instruments the start/begin for the given function with a given binding context\r\n * @param funcName - the identifying name of the function\r\n * @param func - the function instance to measure\r\n * @param bindingContext - the optional context from which to invoke the function\r\n * @returns the instrumented function that will track the start/end of the given function.\r\n */\r\n public instrumentFunc(funcName: string, func: TFunc, bindingContext?: Object): TFunc {\r\n\r\n const _this = this;\r\n\r\n const wrapper = function (...args: unknown[]): unknown {\r\n const endMeasure = _this.startMeasure(funcName).endMeasure;\r\n try {\r\n return func.apply(bindingContext, args);\r\n } finally {\r\n endMeasure();\r\n }\r\n };\r\n\r\n return wrapper as any as TFunc;\r\n }\r\n\r\n /**\r\n * Instruments the start/begin for the given async-style function\r\n * @param promiseName - the identifying name of the promise\r\n * @param getPromise - the promise getter that returns the promise to measure. This is needed\r\n * so that the start measurement can occur before the promise starts executing.\r\n * @param async - flag to indicate whether to measure this promise as an async timeline\r\n * or a synchronous one. Please note that if you specify this as true, and other measurements\r\n * in the timeline are synchronous, the async measurements will appear as a separate timeline\r\n * and will not be next to the synchronous one. If unsure, leave undefined.\r\n * @returns the wrapped promise that tracks the start/end of the promise execution.\r\n */\r\n public async instrumentPromise(promiseName: string, getPromise: () => Promise, async?: boolean): Promise {\r\n\r\n const endMeasure = this.startMeasure(promiseName, null, async).endMeasure;\r\n try {\r\n return await getPromise();\r\n } finally {\r\n endMeasure();\r\n }\r\n }\r\n\r\n /**\r\n * Prefixes the given measure name with the current timeline name\r\n * @param measureName - the measure name to qualify\r\n * @returns the timeline name prefixed measure name.\r\n */\r\n private qualifyMeasureName(measureName: string): string {\r\n return `${this.timelineName}-${measureName}`;\r\n }\r\n\r\n /**\r\n * Returns the formatted measure name with it's constiuent parts\r\n * @param coreMeasureName - the core marker name\r\n * @param dynamicMeasureName - optional dynamic measure name\r\n * @returns the formatted marker name\r\n */\r\n private formatMeasureName(coreMeasureName: string, dynamicMeasureName?: string): string {\r\n const dynamicMeasureSuffix = dynamicMeasureName ? (\"-\" + dynamicMeasureName) : \"\";\r\n return this.markerCount.qualifyKey(`${coreMeasureName}${dynamicMeasureSuffix}`);\r\n }\r\n\r\n /**\r\n * Helper to add a single mark with the performance API\r\n * @param markerName - the name of the marker to add.\r\n */\r\n private singleMark(markerName: string): void {\r\n if (this.addPerfMarks) {\r\n performance.mark(markerName);\r\n }\r\n }\r\n\r\n /**\r\n * Helper to calculate a performance measurement against the performance API\r\n * @param measureName - the name of the measure\r\n * @param startMarker - the name of the start marker\r\n * @param endMarker - the name of the end marker\r\n */\r\n private measure(measureName: string, startMarker: string, endMarker: string): void {\r\n if (this.addPerfMarks) {\r\n try {\r\n // this can throw if start/end markers were not available for some reason\r\n performance.measure(measureName, startMarker, endMarker);\r\n } catch (ex) {\r\n logger.logError(ex);\r\n }\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Test export for resetting the timeline name counter\r\n */\r\nexport function _resetTimelineKeyCounter(): void {\r\n timelineKeyCount.reset();\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { PageMeasure, PerfTimeline, createPerfTimeline, setTryGetPerfTimelineFunc, TryGetPerfTimelineFunc } from \"./PerfTimeline\";\r\nimport { AppPerfTraceConfig, tryParseAppTraceConfig } from \"./AppPerfTraceConfig\";\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\n\r\nimport { PerfTimelineImpl } from \"./PerfTimelineImpl\";\r\nimport { getAppPerfTrace } from \"./AppPerfTrace\";\r\nimport { logger } from \"../logging\";\r\n\r\nlet configOverrides: AppPerfTraceConfig;\r\n\r\n/**\r\n * The configuration for app trace switches. This will be updated with the\r\n * config in the CMS and any properties from URL overrides.\r\n */\r\nconst config: AppPerfTraceConfig = {};\r\n\r\n/**\r\n * Dictionary containing the unique {PerfTimeline} object instances across the app.\r\n * When related measurements on the same perf timeline is required across unrelated parts\r\n * of the code, this will guarantee you're tracking those measurements under the same\r\n * perf timeline using a combination of the experience name and instance id.\r\n */\r\nlet perfTimelineInstances: { [instanceId: string]: PerfTimeline };\r\n\r\n/**\r\n * Initializes experience perf diagnostic specific state.\r\n * @param locationHref - the value of window.location.href from which to parse options.\r\n * @param tryGetPerfTimelineFunc - the injected dependency for perf timeline factory method.\r\n */\r\nexport function initExperienceDiagnostics(locationHref: string, tryGetPerfTimelineFunc: TryGetPerfTimelineFunc): void {\r\n perfTimelineInstances = {};\r\n\r\n if (canUseDOM()) {\r\n // Note that we're setting the _getAppPerfTrace function here so that it doesn't get tree shaken out\r\n // since it's not actually referenced from any PROD code anywhere. However since the tryGetPerfTimeline function\r\n // is referenced, having this code run here makes it work.\r\n //\r\n // TODO: This creates a circular dependency which is fine for actual functionality as ES modules know\r\n // how to deal with it. However this can cause issues when debugging UTs sometimes.\r\n (window)._getAppPerfTrace = getAppPerfTrace;\r\n }\r\n\r\n // Use the actual function to get perf timeline when initExperienceDiagnostics is called.\r\n setTryGetPerfTimelineFunc(tryGetPerfTimelineFunc);\r\n\r\n setAppPerfTraceConfigOverrides(locationHref);\r\n}\r\n\r\n/**\r\n * Returns the app trace config.\r\n */\r\nexport function getAppPerfTraceConfig(): AppPerfTraceConfig {\r\n return config;\r\n}\r\n\r\n/**\r\n * Helper to set the app trace config dynamically. Useful when the app trace config\r\n * has been loaded via a configuration (such as entry point config), and we want to use\r\n * that as the default/base config instead. Note that we still apply higher precedence\r\n * to the location parsed config since we want to make sure to use those if specified.\r\n * @param baseConfig the base configuration to apply.\r\n */\r\nexport function setAppPerfTraceBaseConfig(baseConfig: Partial): void {\r\n if (!baseConfig) {\r\n return;\r\n }\r\n\r\n // Use the config from URL last, so we have highest precedence on QSPs\r\n Object.assign(config, baseConfig, configOverrides);\r\n\r\n // forcefully disable for some options we never want enabled in upload scenario\r\n if (config.uploadTrace) {\r\n\r\n // don't bloat page timings with app trace related timings\r\n config.addPageTimings = false;\r\n\r\n // don't emit performance marks that show up on F12\r\n config.addPerformanceMarks = false;\r\n\r\n // if sample rate has not been set, set to 0, or does not pass\r\n // the random value test, we need to:\r\n // 1. disable app trace collection completely\r\n // 2. disable upload flag, so that when we try to get the app trace for upload\r\n // it will simply return an empty trace, and prevent the upload.\r\n //\r\n if (!config.sampleRate\r\n || Math.random() > config.sampleRate) {\r\n\r\n config.enablePerfTimeline = false;\r\n config.uploadTrace = false;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Initializes experience perf diagnostic specific state\r\n * Note: this method should not be called explicitly (other than from UTs.)\r\n * It is already called by default at the beginning of module initialization.\r\n * @param locationHref - the value of window.location.href from which to parse options\r\n */\r\nfunction setAppPerfTraceConfigOverrides(locationHref: string): void {\r\n Object.assign(config, configOverrides = tryParseAppTraceConfig(locationHref));\r\n}\r\n\r\n/**\r\n * Gets or creates a perf timeline object for the given experience instance if perf measurements are enabled\r\n * for the given experience.\r\n * @param experienceName - the name of the experience for which to create the timeline.\r\n * @param instanceId - the ID that will uniquely identify this timeline across multiple instances.\r\n */\r\nexport const tryGetPerfTimelineImpl: TryGetPerfTimelineFunc = (experienceName: string, instanceId: string, async?: boolean): PerfTimeline => {\r\n return shouldTrackPerfTimeline(experienceName)\r\n ? getPerfTimeline(experienceName, instanceId, async)\r\n : undefined;\r\n};\r\n\r\n/**\r\n * Gets or creates a perf timeline object for the given experience instance. This should only be used in special\r\n * circumstances where we may not know in advance whether perf timeline should be enabled for an experience, but\r\n * still want to start the measurements as not to miss anything in case collection is enabled at a later time.\r\n * This is usually used in entry point to collect intialization measurements before the config is loaded with\r\n * more parameters for app perf trace collection in order to upload trace logs in production.\r\n * @param experienceName - the name of the experience for which to get the perf timeline.\r\n * @param instanceId - the instance specific ID that will uniquely identify this instance from other instances.\r\n */\r\nexport function getPerfTimeline(experienceName: string, instanceId: string, async?: boolean): PerfTimeline {\r\n const instanceKey = getInstanceKeyCore(experienceName, instanceId);\r\n\r\n const perfTimeline = perfTimelineInstances[instanceKey];\r\n if (perfTimeline) {\r\n return perfTimeline;\r\n }\r\n\r\n return perfTimelineInstances[instanceKey] = createPerfTimeline(\r\n PerfTimelineImpl,\r\n experienceName,\r\n instanceId,\r\n config.addPerformanceMarks,\r\n config.addPageTimings,\r\n async\r\n );\r\n}\r\n\r\n/**\r\n * Renames the given perf timeline object and moves the lookup dictionary reference under the new key\r\n * @param perfTimeline - the perf timeline to rename\r\n * @param newExperienceName - the new name for the perf timeline\r\n */\r\nexport function renamePerfTimeline(perfTimeline: PerfTimeline, newExperienceName: string): void {\r\n\r\n const oldInstanceKey = getInstanceKey(perfTimeline);\r\n\r\n if (perfTimelineInstances[oldInstanceKey] !== perfTimeline) {\r\n logger.logError(`Attempted to rename a perf timeline object with mismatching instance key ${oldInstanceKey}`);\r\n return;\r\n }\r\n\r\n // rename the perf timeline to the new name\r\n perfTimeline.rename(newExperienceName);\r\n\r\n // delete the old reference\r\n delete perfTimelineInstances[oldInstanceKey];\r\n\r\n // ...and add the new instance under the new key\r\n const newInstanceKey = getInstanceKey(perfTimeline);\r\n perfTimelineInstances[newInstanceKey] = perfTimeline;\r\n}\r\n\r\n/**\r\n * Returns the list of page measures from all the perf timeline objects being tracked\r\n */\r\nexport function getExperienceMeasures(): Array {\r\n const pageMeasures: Array = [];\r\n Object.keys(perfTimelineInstances).forEach(instanceKey =>\r\n pageMeasures.push(...perfTimelineInstances[instanceKey].getPageMeasures())\r\n );\r\n return pageMeasures;\r\n}\r\n\r\n/**\r\n * Helper to check whether we should track perf timeline for the given experience\r\n * @param experienceName - the name of the experience to check\r\n * @returns {boolean} indicating whether the given experience should be tracked for perf\r\n */\r\nfunction shouldTrackPerfTimeline(experienceName: string): boolean {\r\n if (!config.enablePerfTimeline) {\r\n return false;\r\n }\r\n\r\n // if inclusion list is present, it will supercede the exclusion list,\r\n // so return true early if a match is found here.\r\n const { experiencesForPerf } = config;\r\n if (experiencesForPerf && experiencesForPerf[experienceName]) {\r\n return true;\r\n }\r\n\r\n // check for exclusion list\r\n const { experiencesExcludedForPerf } = config;\r\n if (experiencesExcludedForPerf && experiencesExcludedForPerf[experienceName]) {\r\n return false;\r\n }\r\n\r\n // otherwise the final fallback will be the track all flag.\r\n return config.trackAllExp;\r\n}\r\n\r\n/**\r\n * Gets the instance key to store the experience timeline\r\n * @param perfTimeline - the timeline object from which to get the instance key.\r\n * @returns the cache key that represents the location to which to store the perf timeline.\r\n */\r\nfunction getInstanceKey(perfTimeline: PerfTimeline): string {\r\n const { timelineName, instanceId } = perfTimeline;\r\n return getInstanceKeyCore(timelineName, instanceId);\r\n}\r\n\r\n/**\r\n * Gets the instance key to store the experience timeline\r\n * @param experienceName - the name of the experience\r\n * @param instanceId - the instance ID for the perf timeline.\r\n * @returns the cache key that represents the location to which to store the perf timeline.\r\n */\r\nfunction getInstanceKeyCore(experienceName: string, instanceId: string): string {\r\n return `${experienceName}-${instanceId || \"0\"}`;\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n BaseExperienceConfig,\r\n DynamicBundles,\r\n ExperienceConfigWrapper,\r\n resolver\r\n} from \"@msnews/core\";\r\nimport { ChildExperienceConfigInfo, IRequestContext } from \"@msnews/core\";\r\nimport { ConnectComponentFailureError, ExperienceLoaderAppErrors, LoadComponentFailureError, renamePerfTimeline, tryGetPerfTimeline } from \"@msnews/diagnostics\";\r\nimport { ExperienceLoadingState, MilestoneDataActions, createExperienceStateUpdate, getExperienceLoadDelegate, getMilestoneDataConnector } from \"@msnews/milestone-data\";\r\n\r\nimport { ConfigProcessor } from \"@msnews/config-validator\";\r\nimport { ExperienceIds } from \"@msnews/experiences-constants\";\r\nimport { IComponentConnector } from \"../\";\r\nimport { PageBase } from \"@msnews/experiences-redux\";\r\nimport React from \"react\";\r\nimport { Store } from \"react-redux\";\r\nimport { Telemetry } from \"@msnews/telemetry-contracts\";\r\nimport { uniqueId } from \"lodash-es\";\r\n\r\n/**\r\n * An experience loader class that encapsulates the dynamic loading of an experience.\r\n * Give an experience config href, this class will determine the bundle to be loaded, load the bundle, and then enable the caller to get\r\n * the connected render component for the experience.\r\n * The loading/initialization of the experience connector and the connecting are separate methods, so that the caller can control when each is done\r\n */\r\nexport class ExperienceLoader {\r\n /**\r\n * The connector for this instance of the experience loader. It is undefined until after loadConnector is called\r\n */\r\n private experienceConnector: IComponentConnector = undefined;\r\n\r\n /**\r\n * The experience rendering Component for this instance of the experience loader. It is undefined until after loadConnector is called\r\n */\r\n private experienceComponent: any = undefined;\r\n\r\n /**\r\n * The experience Type of the experience being loaded. It is undefined until after loadConnector is called\r\n */\r\n private $experienceType: string = undefined;\r\n\r\n /**\r\n * Gets the experience Type for this instance of the experience loader. It is undefined until after loadConnector is called\r\n */\r\n public get experienceType(): string { return this.$experienceType; }\r\n\r\n /**\r\n * Gets the current Connector for this experience loader instance\r\n */\r\n public get connector(): IComponentConnector { return this.experienceConnector; }\r\n\r\n /**\r\n * When we want to load bundles preemptively with earlyLoadBundles, we'll store their promises here. Mapping from experienceType\r\n * string to the promise for loading its bundle.\r\n */\r\n public static earlyLoadBundlePromises: Map> = new Map>();\r\n\r\n /**\r\n * Creates an experience loader.\r\n * @param {string} configIndexHref The config index href for the config to load (ex: cms/api/amp/experienceConfigIndex/BBTjjqH ).\r\n * @param {string} [instanceId] The instanceId of the experience\r\n * @param {string} [parentNamespace] The namespace of the parent experience, if it is known\r\n * @param {Store} [parentStore] The parent experience redux store\r\n * @param {string} [type] The experienceType of the experience being loaded. If provided, this type will be used to load the bundle\r\n */\r\n public constructor(\r\n private configIndexHref: string,\r\n private instanceId?: string | undefined,\r\n private parentNamespace?: string | undefined,\r\n private parentStore?: Store | undefined,\r\n private requestContext?: IRequestContext | undefined,\r\n experienceType?: string | undefined) {\r\n\r\n this.$experienceType = experienceType;\r\n }\r\n /**\r\n * Given a child config, recursively find bundles that we can load immediately. If we find a bundle to load immediately, we'll\r\n * create a promise and store it in earlyLoadBundlePromises. The loadConnector method should check the earlyLoadBundlePromises\r\n * before creating new promises to a load bundle.\r\n * @param config child config of an experience config\r\n */\r\n public static async earlyLoadBundles(config: ChildExperienceConfigInfo) {\r\n if (config\r\n && config.experienceType\r\n && !getExperienceLoadDelegate(config.experienceType)) {\r\n // Do not early load experiences with delegates. They should have specific events triggering loading.\r\n\r\n if (config.experienceType === ExperienceIds.river) {\r\n // We should not traverse to the River when early loading bundles because it may have children disabled.\r\n return;\r\n }\r\n\r\n if (!ExperienceLoader.earlyLoadBundlePromises.has(config.experienceType)) {\r\n ExperienceLoader.earlyLoadBundlePromises.set(config.experienceType, DynamicBundles.loadExperience(config.experienceType));\r\n }\r\n\r\n const fullConfig = await resolver.getConfig(config.href);\r\n\r\n ConfigProcessor.getChildrenDataConnectorConfigInfos(fullConfig.properties).forEach(async (childConfig) => {\r\n ExperienceLoader.earlyLoadBundles(childConfig);\r\n });\r\n\r\n ConfigProcessor.getChildrenExperienceConfigInfos(fullConfig.properties).forEach(async (childConfig) => {\r\n ExperienceLoader.earlyLoadBundles(childConfig);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Dynamically loads and experience bundle, and creates the experience connector\r\n */\r\n public async loadConnector(isDataConnector = false): Promise {\r\n let linesRunUntilFailure = \"start;\";\r\n try {\r\n // Log an app error, if we didn't get either a configIndexHref NOR an experienceType\r\n if (!this.configIndexHref && !this.$experienceType) {\r\n // Log an app error if the loader failed to load for whatever reason\r\n Telemetry.sendAppErrorEvent({\r\n ...ExperienceLoaderAppErrors.InsufficientLoadArgs,\r\n message: \"Failed loading experience bundle due to missing config href and experienceType\",\r\n pb: {\r\n ...ExperienceLoaderAppErrors.InsufficientLoadArgs.pb,\r\n customMessage: `Details: \" ${JSON.stringify({ instanceId: this.instanceId, parentNamespace: this.parentNamespace })}`\r\n }\r\n\r\n });\r\n throw new Error(\"Cannot load a connector bundle without either the experienceType, or configIndexHref\");\r\n }\r\n linesRunUntilFailure += \"nullCheck;\";\r\n\r\n const perfTimeline = tryGetPerfTimeline(this.$experienceType || uniqueId(), this.instanceId);\r\n\r\n linesRunUntilFailure += \"perfTimeline;\";\r\n\r\n // the loaded config result\r\n let configResult: ExperienceConfigWrapper;\r\n\r\n // Get a promise for the resolved config of the experience that is being initialized. If not configIndexHref is supplied,\r\n // then assume the experience has no config, so just create a resolved promise the returns an empty config\r\n let configPromise: any;\r\n if (this.configIndexHref) {\r\n if (perfTimeline) {\r\n configPromise = perfTimeline.instrumentPromise(\"config\", () => resolver.getConfig(this.configIndexHref));\r\n } else {\r\n configPromise = resolver.getConfig(this.configIndexHref);\r\n }\r\n } else {\r\n configPromise = Promise.resolve({ experienceType: this.$experienceType, properties: {} });\r\n }\r\n\r\n linesRunUntilFailure += \"configPromise;\";\r\n\r\n // The async promises for loading the config and loading the bundles\r\n const loaderPromises: Promise[] = [configPromise];\r\n\r\n // If we don't know the experienceType, then we need to wait for the config to load and get it from the child config\r\n if (!this.$experienceType) {\r\n configResult = await configPromise;\r\n this.$experienceType = configResult.experienceType;\r\n\r\n linesRunUntilFailure += \"awaitConfigPromise;\";\r\n // if we didn't have $experienceType at construction time, then we would've used uniqueId() to create this\r\n // temporary timeline. Now that we have the proper type, rename the timeline to the known value.\r\n if (perfTimeline) {\r\n renamePerfTimeline(perfTimeline, this.$experienceType);\r\n linesRunUntilFailure += \"renamePerfTimeline;\";\r\n }\r\n }\r\n\r\n let bundlePromise: Promise;\r\n\r\n if (!ExperienceLoader.earlyLoadBundlePromises.has(this.$experienceType)) {\r\n // Get a promise for loading in the experience bundle\r\n bundlePromise = perfTimeline\r\n ? perfTimeline.instrumentPromise(\"scripts\", () => DynamicBundles.loadExperience(this.$experienceType))\r\n : DynamicBundles.loadExperience(this.$experienceType);\r\n\r\n loaderPromises.push(bundlePromise);\r\n linesRunUntilFailure += \"loadExperienceBundle;\";\r\n }\r\n\r\n // Wait for all of the promises to complete. This will either be both the config and bundle promises,\r\n // or the bundle promise with the pre-resolved config promise to the empty config object.\r\n await Promise.all(loaderPromises);\r\n linesRunUntilFailure += \"waitForLoaderPromises;\";\r\n\r\n // If we don't have the config result yet, get it from the completed promises.\r\n if (!configResult) {\r\n configResult = await configPromise;\r\n linesRunUntilFailure += \"awaitConfigPromise;\";\r\n }\r\n\r\n // Get the bundle from the completed promises\r\n const bundleModule = ExperienceLoader.earlyLoadBundlePromises.has(this.$experienceType)\r\n ? await ExperienceLoader.earlyLoadBundlePromises.get(this.$experienceType)\r\n : await bundlePromise;\r\n linesRunUntilFailure += \"getBundleModule;\";\r\n\r\n const initMeasureEnd = perfTimeline && perfTimeline.startMeasure(\"init\").endMeasure;\r\n\r\n // update experience current state to loaded\r\n this.updateExperienceLoadedMilestone(this.$experienceType);\r\n linesRunUntilFailure += \"updateExperienceLoadedMilestone;\";\r\n\r\n // Extract config object from result\r\n const config = configResult.properties;\r\n\r\n // Get the Connector/Reducer/Component via naming convention\r\n const ExperienceConnector = bundleModule[this.$experienceType + \"Connector\"];\r\n const ExperienceReducer = bundleModule[this.$experienceType + \"Reducer\"];\r\n\r\n // Store the experience rendering component as a class member, for use later when it is connected\r\n this.experienceComponent = bundleModule[this.$experienceType];\r\n\r\n // Create the experience connector. The namespace is a combination of the experienceType and its instance ID (in case there are multiple of them on a page)\r\n const app = PageBase.getInstance();\r\n const experienceNamespace = getExperienceNamespace({ experienceType: this.$experienceType, instanceId: this.instanceId, href: this.configIndexHref });\r\n linesRunUntilFailure += \"getExperienceNamespace;\";\r\n\r\n const experienceParentNamespace = this.parentNamespace ? this.parentNamespace : \"\";\r\n const experienceStore = this.parentStore ? this.parentStore : app.store;\r\n\r\n // Data connectors are singletons, and so their registered namespace is only their experienceType. This allows\r\n // data connectors to be found by using the constants in the ExperienceIds enum\r\n this.experienceConnector = new ExperienceConnector(\r\n isDataConnector ? this.$experienceType : experienceNamespace,\r\n experienceParentNamespace,\r\n app.rootReducer,\r\n new ExperienceReducer(config),\r\n experienceStore,\r\n config,\r\n this.requestContext\r\n );\r\n linesRunUntilFailure += \"newExperienceConnector;\";\r\n\r\n // Set the experience config index href property on the connector.\r\n this.experienceConnector.configHref = this.configIndexHref;\r\n\r\n if (initMeasureEnd) {\r\n initMeasureEnd();\r\n }\r\n } catch (error) {\r\n Telemetry.sendAppErrorEvent({\r\n ...LoadComponentFailureError,\r\n message: \"loadComponent failed\",\r\n pb: {\r\n ...LoadComponentFailureError.pb,\r\n customMessage: `Details: \" ${JSON.stringify({\r\n error: (error instanceof Error) ? { message: error.message, stack: error.stack } : error,\r\n instanceId: this.instanceId,\r\n parentNamespace: this.parentNamespace,\r\n configIndex: this.configIndexHref,\r\n linesRunUntilFailure\r\n })}`\r\n }\r\n });\r\n\r\n throw new Error(\"ExperienceLoader loadComponent failed\");\r\n }\r\n }\r\n\r\n /**\r\n * Creates and returns the connected rendering component for the experience\r\n * @param connectorProps Any initial props that should be passed to the connector in its onComponentConnect() method\r\n * @returns The Connected component for the experience\r\n */\r\n public async getConnectedExperience(connectorProps?: any): Promise {\r\n // If the connector has not been loaded yet, then load it first\r\n if (!this.experienceConnector) {\r\n await this.loadConnector();\r\n }\r\n\r\n // Return a promise that will resolve to the connected component, ready to render.\r\n try {\r\n return this.experienceConnector.connectComponent(this.experienceComponent, connectorProps);\r\n } catch (error) {\r\n Telemetry.sendAppErrorEvent({\r\n ...ConnectComponentFailureError,\r\n message: \"connectComponent failed\",\r\n pb: {\r\n ...ConnectComponentFailureError.pb,\r\n customMessage: `Details: \" ${JSON.stringify({\r\n error,\r\n connectorProps,\r\n instanceId: this.instanceId,\r\n parentNamespace: this.parentNamespace,\r\n configIndex: this.configIndexHref\r\n })}`\r\n }\r\n });\r\n\r\n throw new Error(\"ExperienceLoader connectComponent failed\");\r\n }\r\n }\r\n\r\n /**\r\n * update loaded milestone for the experience\r\n * @param experienceType - Experience Type to update\r\n */\r\n private updateExperienceLoadedMilestone(experienceType: string): void {\r\n const milestoneDataConnector = getMilestoneDataConnector();\r\n if (milestoneDataConnector) {\r\n MilestoneDataActions.updateExperienceCurrentState.getActionSender(milestoneDataConnector)\r\n .send([createExperienceStateUpdate(experienceType, ExperienceLoadingState.loaded, null, null)]);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Creates a namespace based on the passed in experience config info\r\n * @param experienceConfigInfo\r\n */\r\nexport function getExperienceNamespace(experienceConfigInfo: ChildExperienceConfigInfo): string {\r\n return `${experienceConfigInfo.experienceType}_${experienceConfigInfo.href}_${experienceConfigInfo.instanceId}`;\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n ActionMap,\r\n CommonActions,\r\n DataConnector,\r\n DynamicReducer,\r\n IActionPayload,\r\n IReducer,\r\n PageBase,\r\n dataConnectorInjector\r\n} from \"@msnews/experiences-redux\";\r\nimport {\r\n AppError,\r\n ExperienceInitialPositionProps,\r\n ExperienceInitialProps\r\n} from \"@msnews/experiences-base\";\r\nimport {\r\n BaseExperienceConfig,\r\n ChildArrangementMetadata,\r\n ChildExperienceConfigInfo,\r\n ChildExperiencesDeferRenderType,\r\n ExperienceState,\r\n IRequestContext,\r\n appEnvironment,\r\n resolver\r\n} from \"@msnews/core\";\r\nimport { ChildWithInvalidExperience, ComponentConnectorAppErrors, LoadDataConnectorConfigFailed, LoadDataConnectorFailed, createError, logger, markTtprRaf, stringifyError } from \"@msnews/diagnostics\";\r\nimport { ConnectorNamespaces, ExperienceIds } from \"@msnews/experiences-constants\";\r\nimport { DeferralEventType, ExperienceMilestoneEventTypes, ExperiencesRevalidationReason, MilestoneDataActions, MilestoneDataConnector, UpdateExperiencePublicStateSignature, UpdateTimingSignature, createTimingUpdate, getExperienceLoadDelegate, getExperienceRenderDelegate, pageRevealStartedObserver, registerExperienceForPageReveal, requestPageRevealStartedAsync, shouldTrackExperience, requestPageRevealCompletedAsync } from \"@msnews/milestone-data\";\r\nimport { Dispatch, Store } from \"redux\";\r\nimport { ObjectTelemetryContract, Telemetry, TelemetryContext, TelemetryObjectBase, TelemetryTags, TelemetryType } from \"@msnews/telemetry-contracts\";\r\nimport { PageInvalidationReasons, hasExperiencePersistentDataUpdated, trackExpWithPersistentDataUpdate, trackPageInvalidation } from \"@msnews/page-lifecycle-helpers\";\r\nimport { TelemetryObject, trackComponent } from \"@msnews/telemetry-core\";\r\nimport { canUseDOM, getLocationSearch } from \"@msnews/isomorphic-util\";\r\n\r\nimport { ConfigProcessor } from \"@msnews/config-validator\";\r\nimport { ExperienceLoadInfo } from \"./ExperienceLoadInfo\";\r\nimport { ExperienceLoader } from \"..\";\r\nimport { IComponentConnector } from \"./IComponentConnector\";\r\nimport React from \"react\";\r\nimport { connect } from \"react-redux\";\r\nimport { getMilestoneDataConnector } from \"@msnews/milestone-data\";\r\nimport { instrumentPerf } from \"./ExperiencePerfTimeline\";\r\nimport { isEmpty } from \"lodash-es\";\r\nimport { isFunction } from \"util\";\r\nimport { networkErrorString } from \"./ComponentConnector.constants\";\r\nimport { subspaced } from \"react-redux-subspace\";\r\n\r\nexport type mapToPropsSignature = (state: TState, ownProps?: TProps) => TProps;\r\nexport type mapStateToPropsReturnType = TProps | mapToPropsSignature;\r\nexport type mapDispatchToPropsReturnType = TProps | mapToPropsSignature;\r\n\r\n/**\r\n * Map for making config-less data connectors faster to load\r\n *\r\n * HACK: HACK: HACK: This is a temporary hack until we can update CMS configs to remove\r\n * the HREF requirement for config-less connectors, so that we can opt out\r\n * of loading configs without having this special check. Need to do in phases\r\n * so that we're not breaking PROD users with old scripts.\r\n */\r\nexport const ConfiglessConnectors = {\r\n [ConnectorNamespaces.BingImageData]: true,\r\n [ConnectorNamespaces.OneServiceContent]: true,\r\n [ConnectorNamespaces.TelemetryData]: true,\r\n [ConnectorNamespaces.TopicData]: true,\r\n [ConnectorNamespaces.PageClickTrackerData]: true,\r\n [ConnectorNamespaces.OfficeSharedData]: true,\r\n [ExperienceIds.pivotContentV2]: true\r\n};\r\n\r\n/**\r\n * Base class for a component connector. Every connected component in an app has a connector that inherits from this class\r\n * @class\r\n */\r\nexport abstract class ComponentConnector\r\n extends DataConnector\r\n implements IComponentConnector {\r\n\r\n /**\r\n * A map of child connectors. The key to the map is a concatenation: ExperienceType_ExperienceInstanceId.\r\n * The ExperienceType is the the same as the ExperienceId in the @msnews/experiences-constants ExperienceIds enum (i.e. River)\r\n * The ExperienceInstanceId is set in config, as part of the parent experience config. Which children get created and rendered\r\n * by a parent experience will be specific to that experience, so it will be up to the parent experience to determine the\r\n * instanceId of the children to be rendered by looking in its config object.\r\n * @type Map>\r\n */\r\n protected childMap?: Map> = new Map();\r\n\r\n /**\r\n * Telemetry object of the component. It is automatically populated by this class when experience calls onComponentConnect().\r\n */\r\n protected telemetryObject: TelemetryObjectBase;\r\n\r\n /**\r\n * All telemetry objects of all subcomponent\r\n * It constitutes an object that provides access to each of the telemetry object children of a provided telemetryObject\r\n * attribute that is passed to its contructor. Particularly useful when there are many telemetry object children that need to be accessed\r\n * anywhere in the experience, for example, to update their contracts or to render them within a particular DOM element.\r\n * A great example of how it could be used can be found in the Feedback dialog experience:\r\n * FeedbackDialog.telemetry.ts: https://microsoft.visualstudio.com/ICE/_git/msnews-experiences/pullrequest/4063110?_a=files&path=%2Fexperiences%2Ffeedback-dialog%2Fsrc%2FFeedbackDialog.telemetry.ts\r\n * Feedbackdialog.tsx: https://microsoft.visualstudio.com/ICE/_git/msnews-experiences/pullrequest/4063110?_a=files&path=%2Fexperiences%2Ffeedback-dialog%2Fsrc%2FFeedbackDialog.tsx\r\n */\r\n protected telemetryContext: TelemetryContext = undefined;\r\n\r\n /**\r\n * The telemetry tags to pass along as unhandled props for rendering\r\n */\r\n protected telemetryTags: TelemetryTags = null;\r\n\r\n /**\r\n * The group the experience belongs to, if applicable. This property is to be set as needed in the specific experience connectors\r\n */\r\n protected $experienceGroup: string = undefined;\r\n\r\n /**\r\n * The connected rendering component for the experience connector\r\n */\r\n private $connectedComponent: React.ComponentClass = undefined;\r\n\r\n /**\r\n * The connected rendering component ReactElement instance for the experience connector\r\n */\r\n private $componentInstance: React.ReactElement = undefined;\r\n\r\n /**\r\n * The connector props used to connect this connector to an experience\r\n */\r\n private $connectorProps: ExperienceInitialProps;\r\n\r\n /**\r\n * flag indicating if we should render when offline. Default is false\r\n */\r\n private $renderIfOffline = false;\r\n\r\n /**\r\n * flag indicating if experience is liable to be stale\r\n */\r\n private $isStale = false;\r\n\r\n /**\r\n * The experience type\r\n */\r\n private $experienceType: string = undefined;\r\n\r\n /**\r\n * failsafe timeout(ms) to render child experiences based on milestone batch load strategy\r\n */\r\n private $maxWaitToBatchRenderChildExperiences = 4000;\r\n\r\n /**\r\n * The milestone data connector (if it exists)\r\n */\r\n private $milestoneDataConnector: MilestoneDataConnector = undefined;\r\n\r\n /**\r\n * Gets the connected component for this experience\r\n */\r\n public get connectedComponent(): React.ComponentClass { return this.$connectedComponent; }\r\n\r\n /**\r\n * Gets the component instance for this experience. This is used for rendering the experience\r\n */\r\n public get componentInstance(): React.ReactElement { return this.$componentInstance; }\r\n\r\n /**\r\n * Sets the component instance for this experience\r\n */\r\n public set componentInstance(value: React.ReactElement) { this.$componentInstance = value; }\r\n\r\n /**\r\n * Gets the experience type for this experience.\r\n */\r\n public get experienceType(): string { return this.$experienceType; }\r\n\r\n /**\r\n * Sets the renderIfOffline flag\r\n */\r\n public set renderIfOffline(value: boolean) { this.$renderIfOffline = value; }\r\n\r\n /**\r\n * Gets the staleLiable flag\r\n */\r\n public get isStale(): boolean { return this.$isStale; }\r\n\r\n /**\r\n * Gets the staleLiable flag\r\n */\r\n public set isStale(value: boolean) { this.$isStale = value; }\r\n\r\n /**\r\n * Get a map of the child experience component instances, which is appropriate for passing into the\r\n * inspector function as part of mapStateToProps\r\n */\r\n public get childComponentInstanceList(): { [instanceId: string]: React.ReactElement; } {\r\n const childComponentList: { [instanceId: string]: React.ReactElement; } = {};\r\n this.childMap.forEach((connector, key) => {\r\n childComponentList[key] = connector.componentInstance;\r\n });\r\n return childComponentList;\r\n }\r\n\r\n /**\r\n * Construct a new Component connector\r\n * @constructor\r\n * @param { string } namespace The redux subspace namespace for the connector\r\n * @param { string } parentNamespace The redux subspace namespace for the parent connector, if it exists\r\n * @param { DynamicReducer } rootReducer The root reducer for the Application\r\n * @param { IReducer } reducer The reducer for this connector instance\r\n * @param { Store} parentStore The parent store (or redux subspace) that this connector will be a subspace within\r\n * @param { TConfig } config Optional param containing the config for the connector\r\n * @param { IRequestContext } requestContext Optional injected request context\r\n */\r\n public constructor(\r\n namespace: string,\r\n parentNamespace: string,\r\n rootReducer: DynamicReducer,\r\n reducer: IReducer,\r\n parentStore: Store,\r\n config?: TConfig,\r\n requestContext?: IRequestContext\r\n ) {\r\n super(namespace, parentNamespace, rootReducer, reducer, parentStore, config, requestContext);\r\n this.selectComponentState = this.selectComponentState.bind(this);\r\n\r\n // To get the experience type, split the namespace at the first \"_\" and use the first substring\r\n // as the type. The convention for namespace is: ExperienceType_configHref_InstanceId. If there is no instanceId, then then namespace is just: ExperienceType\r\n const namespaceArray = namespace.split(\"_\");\r\n this.$experienceType = namespaceArray[0];\r\n // configNamespace includes experienceType + index path\r\n const configNamespace = (namespaceArray.length > 1) ? this.$experienceType + namespaceArray[1] : this.$experienceType;\r\n\r\n this.config = ConfigProcessor.processConfig(this.config, configNamespace) as TConfig;\r\n\r\n // update if experience is staleable\r\n this.setupForPageReveal();\r\n }\r\n\r\n /**\r\n * Redux mapper used to map the current state to props the component use to render itself.\r\n * @method\r\n * @param {TState} state The current state of the component.\r\n * @param {any} ownProps The set of properties that is passed in from where the component is created.\r\n * This parameter should be not nil only when the component is supposed to have part of its properties coming from a parent component.\r\n * It can be omitted when the entire set of props is derived from the state.\r\n * @returns {mapStateToPropsReturnType} It can either return the set of mapped props as an object of type TProps derived from a state\r\n * object of type TState or a function that will be used to map the state to the props.\r\n */\r\n public abstract mapStateToProps(state: TState, ownProps?: any): mapStateToPropsReturnType;\r\n\r\n /**\r\n * Inject into props redux action creators.\r\n * @method\r\n * @param {Dispatch} dispatch The redux dispatch function.\r\n * @param {any} ownProps The set of properties that is passed from where the component is created.\r\n * This parameter should be not nil only when the component is supposed to have part of its properties coming from a parent component.\r\n * It can be omitted when the entire set of props is derived from the state.\r\n * @returns {TProps} An enriched set of props.\r\n */\r\n public mapDispatchToProps(dispatch: Dispatch, ownProps?: any): mapDispatchToPropsReturnType {\r\n return {} as TProps;\r\n }\r\n\r\n /**\r\n * Overrides the default redux mergeProps function that will add a callback function for reporting experience milestone timing\r\n * @method\r\n * @param {TState} stateProps The set of properties from mapStateToProps.\r\n * @param {TProps} dispatchProps The set of properties from mapDispatchToProps.\r\n * @param {any} ownProps The set of properties that is passed from where the component is created.\r\n * @returns {TProps} The merged set of props.\r\n */\r\n public mergeProps(stateProps: TProps, dispatchProps: TProps, ownProps: any): TProps {\r\n // WARNING WARNING WARNING. Some render engines, like preact will take dependencies on some props that may be set to undefined, so the\r\n // merge must preserve properties that are undefined in the source (i.e stateProps) in the result.\r\n // Specific to preact depends on the constructor property being explicity set to undefined. When an element is created by preact\r\n // the constructor property is set to undefined, and that must be preserved by this merge function.\r\n // Avoid using lodash merge, as it does not preserve the undefined properties\r\n\r\n // If we are in Mns Creator Dashboard mode, then set props for the config href, and experience type. These will get rendered\r\n // on each experience as unhandled props\r\n let mnsDashBoardProps = {};\r\n if (appEnvironment.ShowMnsCreatorDashboard) {\r\n mnsDashBoardProps = {\r\n \"data-config-href\": this.configHref,\r\n \"data-experience-type\": this.experienceType\r\n };\r\n }\r\n\r\n // The onExperienceMilestoneTimingUpdate and isStale prop is set here, so that it is injected into the resulting properties for all experiences.\r\n return {\r\n onExperienceMilestoneTimingUpdate: this.onExperienceMilestoneTimingUpdate,\r\n isStale: this.isStale,\r\n ...mnsDashBoardProps,\r\n ...ownProps,\r\n ...stateProps,\r\n ...dispatchProps,\r\n ...(this.requestContext && { requestContext: this.requestContext } || {})\r\n };\r\n }\r\n\r\n /**\r\n * Connects the passed in component to the redux store/state of the connector\r\n * @method\r\n * @param {React.ComponentType} componentToConnect The react element to connect.\r\n * @param {any} connectorProps Optional connector props to pass to the onComponentConnect call.\r\n * @returns {React.ComponentClass} The Redux connected component.\r\n */\r\n public async connectComponent(componentToConnect: React.ComponentType, connectorProps?: ExperienceInitialProps): Promise> {\r\n\r\n // If we are not online, and we should not render offline, then just return undefined. This will prevent the experience from ever\r\n // rendering\r\n if (canUseDOM() && !navigator.onLine && !this.$renderIfOffline) {\r\n if (connectorProps && connectorProps.onAppErrorCallback) {\r\n connectorProps.onAppErrorCallback(\r\n {\r\n id: 404,\r\n message: networkErrorString,\r\n source: \"ComponentConnector.ts\",\r\n severity: 0\r\n }\r\n );\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n const connectMeasureEnd = this.perfTimeline && this.perfTimeline.startMeasure(\"connect\").endMeasure;\r\n\r\n // Call the onComponentConnect method. This is done first, so that the connector can see the initialProps before mapStateToProps is called\r\n // onComponentConnect is async, so we need to wait for it to complete first\r\n await this.onComponentConnect(connectorProps);\r\n\r\n if (this.telemetryObject) {\r\n componentToConnect = trackComponent(componentToConnect, this.telemetryObject);\r\n }\r\n\r\n // if this experience should be instrumented for perf, do so and get the perf HOC\r\n if (this.perfTimeline) {\r\n componentToConnect = instrumentPerf(componentToConnect, this.perfTimeline);\r\n this.mapStateToProps = this.perfTimeline.instrumentFunc(\"mapStateToProps\", this.mapStateToProps, this);\r\n this.mapDispatchToProps = this.perfTimeline.instrumentFunc(\"mapDispatchToProps\", this.mapDispatchToProps, this);\r\n this.mergeProps = this.perfTimeline.instrumentFunc(\"mergeProps\", this.mergeProps, this);\r\n }\r\n\r\n // Connect the component to redux (will cause mapStateToProps to be called)\r\n const connectedComponent: React.ComponentClass = connect(\r\n this.mapStateToProps.bind(this),\r\n this.mapDispatchToProps.bind(this),\r\n this.mergeProps.bind(this),\r\n { pure: true }\r\n )(componentToConnect);\r\n\r\n // Wrap the redux connected component in a Subspace Provider, and set that as the connectedComponent for this connector\r\n this.$connectedComponent = subspaced(this.selectComponentState, this.namespace)(connectedComponent);\r\n\r\n if (connectMeasureEnd) {\r\n connectMeasureEnd();\r\n }\r\n\r\n return this.$connectedComponent;\r\n }\r\n\r\n /**\r\n * This method reads the experience config and adds any ordinal(index) based child experiences specified in the config to the input\r\n * ChildExperienceConfigInfo array at the specified ordinal position defined in config.\r\n * @method\r\n * @param {ExperienceLoadInfo[]} ExperienceLoadInfoList Array of ChildExperienceConfigInfo objects\r\n * @param {number} mergeStartPosition MergeStartPosition represents the start position for the merge. If your experience only need to call this once,\r\n * it should be 1. For deep river kind of scenario, you would need to pass the updated merge start position. StartPosition = lastEndPosition + 1\r\n * @returns {ExperienceLoadInfo[]}\r\n */\r\n public mergeOrdinalChildExperiences(\r\n experienceInfoList: ExperienceLoadInfo[],\r\n mergeStartPosition: number,\r\n callback?: (experienceInfo: ExperienceLoadInfo) => void\r\n ): ExperienceLoadInfo[] {\r\n\r\n if (!experienceInfoList) {\r\n return null;\r\n }\r\n\r\n if (mergeStartPosition < 1) {\r\n Telemetry.sendAppErrorEvent({\r\n ...ComponentConnectorAppErrors.ListStartPositionInvalid,\r\n message: \"listStartFrom must be greater than 0.\"\r\n });\r\n\r\n return experienceInfoList;\r\n }\r\n\r\n const config = this.config as BaseExperienceConfig;\r\n\r\n if (!config.additionalChildExperiences || config.additionalChildExperiences.length === 0) {\r\n return experienceInfoList;\r\n }\r\n\r\n const ordinalBlockForCurrentColumn = ConfigProcessor.getOrdinalObjectForCurrentBreakpoint(config.additionalChildExperiences);\r\n let mergeEndPos = mergeStartPosition + experienceInfoList.length;\r\n\r\n // Following code loops through the ChildArrangementMetadata array and inserts an additional child experience if startPosition provided in config is greater than mergeStartPosition\r\n // and less than mergeEndPos which is mergeStartPosition + length of the input childConfigInfoList\r\n ordinalBlockForCurrentColumn.children.forEach((childArrangementMetadata) => {\r\n const childExpArrangement = childArrangementMetadata.arrangement;\r\n\r\n // TS requires to define this explicitly and then assign it in line 234.\r\n const positionProps: ExperienceInitialPositionProps = { experienceArrangement: childExpArrangement };\r\n\r\n if (childExpArrangement && childExpArrangement.startPosition >= mergeStartPosition && childExpArrangement.startPosition <= mergeEndPos) {\r\n const insertAt = childExpArrangement.startPosition - mergeStartPosition;\r\n const experienceInfo: ExperienceLoadInfo = {\r\n configInfo: childArrangementMetadata.childExperienceConfigInfo,\r\n initialProps: positionProps\r\n };\r\n\r\n experienceInfoList.splice(insertAt, 0, experienceInfo);\r\n mergeEndPos++;\r\n\r\n if (typeof callback === \"function\") {\r\n callback(experienceInfo);\r\n }\r\n }\r\n });\r\n\r\n return experienceInfoList;\r\n }\r\n\r\n /**\r\n * This method is called when a component is connected to the connectors' store.\r\n * This method can be overridden and used by connectors to perform one time initialization functions\r\n * @method\r\n * @param {any} connectorProps Optional initial props passed into the onComponentConnect call.\r\n * @returns {void}\r\n */\r\n public async onComponentConnect(connectorProps?: ExperienceInitialProps): Promise {\r\n\r\n // save the last connected connector props\r\n this.$connectorProps = connectorProps;\r\n\r\n if (connectorProps) {\r\n const telemetryContract = {\r\n type: TelemetryType.Module,\r\n name: this.$experienceType,\r\n content: {}\r\n } as ObjectTelemetryContract;\r\n\r\n // Setup telemetry props for this experience.\r\n if (!this.telemetryObject) {\r\n if (connectorProps.parentTelemetry && !isEmpty(connectorProps.parentTelemetry)) {\r\n this.telemetryObject = connectorProps.parentTelemetry.addOrUpdateChild(telemetryContract, this.telemetryObject);\r\n } else {\r\n this.telemetryObject = new TelemetryObject(telemetryContract);\r\n }\r\n }\r\n\r\n // generate the telemetry tags to pass along for rendering\r\n this.telemetryTags = this.telemetryObject.render();\r\n\r\n // Override the onAppError function if passed one.\r\n if (isFunction(connectorProps.onAppErrorCallback)) {\r\n this.onAppError = connectorProps.onAppErrorCallback;\r\n }\r\n }\r\n\r\n // load data connectors\r\n // Experiences relying on looking up data connectors need await here. Data Connectors should not have any blocking calls\r\n // in the constructor.\r\n await this.loadDataConnectors();\r\n\r\n for (const injectedDataConnector of this.injectedDataConnectors) {\r\n // Setup the initial state\r\n CommonActions.dataConnectorMergeInit.getActionSender(this).send(injectedDataConnector);\r\n\r\n // Register the merge so we get updates\r\n dataConnectorInjector.registerInjection(this.fullNamespace, injectedDataConnector);\r\n }\r\n\r\n // load up child experiences\r\n await this.onLoadChildExperiences();\r\n }\r\n\r\n /**\r\n * Gets a new instance of a ReactElement for the connected Component for this connector, that can be used to render\r\n * the experience.\r\n * This method will replace any existing ReactElement instance that has been previously created.\r\n * @param ownProps optional props to be passed into the connected components' mapStateToProps method\r\n */\r\n public getNewComponentInstance(ownProps?: TProps): React.ReactElement {\r\n // If there is a connected component for this connector, then create an instance of it.\r\n if (this.$connectedComponent) {\r\n const newProps = { ...ownProps, key: this.namespace };\r\n this.$componentInstance = React.createElement(this.$connectedComponent, newProps);\r\n }\r\n\r\n return this.$componentInstance;\r\n }\r\n\r\n /**\r\n * Report a milestone timing event\r\n * @param milestoneType The type of milestone timing is being reported for\r\n * @param startTime The start time (if defined)\r\n * @param endTime The end time (if defined)\r\n */\r\n protected onExperienceMilestoneTimingUpdate = (\r\n milestoneType: ExperienceMilestoneEventTypes,\r\n startTime?: number,\r\n endTime?: number\r\n ) => {\r\n\r\n if (!shouldTrackExperience(this.experienceType)) {\r\n return;\r\n }\r\n\r\n // Do a onetime check to get the Milestone Data Connector instance\r\n if (this.$milestoneDataConnector === undefined) {\r\n this.$milestoneDataConnector = getMilestoneDataConnector() || null;\r\n }\r\n\r\n // Skip the Milestone update if we don't have a Milestone Data connector\r\n if (!this.$milestoneDataConnector) {\r\n return;\r\n }\r\n\r\n switch (milestoneType) {\r\n case ExperienceMilestoneEventTypes.domComplete:\r\n this.updateTiming(MilestoneDataActions.updateDomCompleteTiming, startTime, endTime);\r\n break;\r\n\r\n case ExperienceMilestoneEventTypes.initialized:\r\n this.updateTiming(MilestoneDataActions.updateInitTiming, startTime, endTime);\r\n break;\r\n\r\n case ExperienceMilestoneEventTypes.rendered:\r\n this.updateTiming(MilestoneDataActions.updateRenderTiming, startTime, endTime);\r\n break;\r\n\r\n case ExperienceMilestoneEventTypes.visuallyReady:\r\n this.updateTiming(MilestoneDataActions.updateVisuallyReadyTiming, startTime, endTime);\r\n break;\r\n\r\n case ExperienceMilestoneEventTypes.staleRevalidationComplete:\r\n this.updateExperienceState(MilestoneDataActions.updateExperiencePublicState, ExperienceMilestoneEventTypes.staleRevalidationComplete);\r\n break;\r\n\r\n default:\r\n // do nothing for the default cause, since there is no default timing that can be updated\r\n logger.log(`Milestone timing update was attempted for an unknown milestone type: ${milestoneType}`);\r\n break;\r\n }\r\n };\r\n\r\n /**\r\n * This method reads the experience config and returns child experiences placed using index based position.\r\n * @method\r\n * @returns {ExperienceLoadInfo[]}\r\n */\r\n protected getOrdinalChildExperiences(): ExperienceLoadInfo[] {\r\n const config = this.config as BaseExperienceConfig;\r\n\r\n if (!config.additionalChildExperiences || config.additionalChildExperiences.length === 0) {\r\n return null;\r\n }\r\n\r\n const result: ExperienceLoadInfo[] = [];\r\n const ordinalBlockForCurrentColumn = ConfigProcessor.getOrdinalObjectForCurrentBreakpoint(config.additionalChildExperiences);\r\n\r\n ordinalBlockForCurrentColumn.children.forEach((childArrangementMetadata) => {\r\n const childExpArrangement = childArrangementMetadata.arrangement;\r\n\r\n // TS requires to define this explicitly and then assign it in line 234.\r\n const positionProps: ExperienceInitialPositionProps = { experienceArrangement: childExpArrangement };\r\n result.push({\r\n configInfo: childArrangementMetadata.childExperienceConfigInfo,\r\n initialProps: positionProps\r\n });\r\n });\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Loads all the children experiences defined under the configuration in parallel.\r\n * @returns {Promise{void}[]} - an array of promises that loads all the children experiences.\r\n */\r\n protected async onLoadChildExperiences(): Promise {\r\n // Load all the children.\r\n // TODO: passing in the parent's connector props to children verbatim seems wrong.\r\n // However experiences such as spotlight seems to be loading it using this method by\r\n // passing child specific initial props from all the way from the top level page experience,\r\n // so need to resolve that before removing the this.$connectorProps parameter.\r\n await this.loadChildrenExperiences(ConfigProcessor.getChildrenExperienceConfigInfos(this.config, this.$connectorProps), this.$connectorProps);\r\n }\r\n\r\n /**\r\n * Load a list of child experiences\r\n * @param children - The list (array) of child experiences to be loaded\r\n * @param childConnectorProps - The connector props to pass to each child experience as it is loaded\r\n * @returns {Promise{void}} - the async operation that denotes loading of all the children.\r\n */\r\n protected async loadChildrenExperiences(children: ChildExperienceConfigInfo[], childConnectorProps?: ExperienceInitialProps): Promise {\r\n if (!children || children.length === 0) {\r\n return;\r\n }\r\n\r\n const childExpsToLoadImmediately = [];\r\n\r\n const reRenderCallback = () => {\r\n this.readyExperienceToRender(children);\r\n };\r\n\r\n for (const child of children) {\r\n const promiseDependency = this.startProcessingChildExperience(child, reRenderCallback, childConnectorProps);\r\n childExpsToLoadImmediately.push(promiseDependency);\r\n }\r\n\r\n // NOTE: In order to make sure that the fail-fast behavior of Promise.all doesn't kick in, we're wrapping the individual promises\r\n // with a catch block and ensuring that they always resolve (never reject/throw error). If we don't do this, then\r\n // even if one child promise gets rejected early, then the parent experience might fail to load the remaining children.\r\n await Promise.all(childExpsToLoadImmediately);\r\n }\r\n\r\n /**\r\n * Gets the list of data connectors to inject into this experience.\r\n */\r\n protected get injectedDataConnectors(): ConnectorNamespaces[] {\r\n return [];\r\n }\r\n\r\n /**\r\n * Load a list of data connectors provided in the experience config\r\n * @returns {Promise{void}} - the async operation that denotes loading of all the children.\r\n */\r\n protected async loadDataConnectors(): Promise {\r\n await Promise.all(\r\n ConfigProcessor.getChildrenDataConnectorConfigInfos(this.config).map(connector =>\r\n this.loadDataConnector(connector)));\r\n }\r\n\r\n /**\r\n * Loads a single child experience with the given connector initial props.\r\n * @param configInfo - the child experience config info\r\n * @param childConnectorProps - optional initial props to pass to connector.\r\n * @returns {Promise{void}} - the async operation that denotes loading of the child.\r\n */\r\n protected async loadChildExperience(\r\n configInfo: ChildExperienceConfigInfo,\r\n childConnectorProps?: ExperienceInitialProps\r\n ): Promise {\r\n // If the experience is delay loaded, load it through the same flow as composition ones so that MilestoneData deferred loading logic is intact.\r\n const milestoneDependencyToLoadChildExp = getExperienceLoadDelegate(configInfo.experienceType);\r\n if (milestoneDependencyToLoadChildExp) {\r\n await this.loadChildrenExperiences([configInfo], childConnectorProps);\r\n return;\r\n }\r\n\r\n const childConnector = await this.getChildExperienceConnector(configInfo, childConnectorProps);\r\n if (!childConnector) {\r\n configInfo.state = ExperienceState.Failed;\r\n return;\r\n }\r\n\r\n this.addConnectorToChildMap(configInfo, childConnector);\r\n }\r\n\r\n /**\r\n * Provides the connector props to be passed into the onComponentConnect method for any children that are created for this\r\n * experience connector\r\n * @param childExperienceType The experience Type of the child experience being loaded\r\n * @param childExperienceInstanceId The experienceInstance Id of the child experience being loaded\r\n */\r\n protected getChildExperienceConnectorProps(childExperienceType: string, childExperienceInstanceId: string): ExperienceInitialProps {\r\n return (\r\n {\r\n parentTelemetry: this.telemetryObject,\r\n context: this.$connectorProps && this.$connectorProps.context,\r\n onAppErrorCallback: this.onAppError,\r\n requestContext: this.requestContext\r\n });\r\n }\r\n\r\n /**\r\n * function to call an action to reRender experience\r\n */\r\n protected reRenderExperience(): void {\r\n CommonActions.renderExperience.getActionSender(this).send();\r\n }\r\n\r\n /**\r\n * function to re-initialize experience state, re-fetch data if stale.\r\n */\r\n protected reInitExperienceState(): void {\r\n CommonActions.renderExperience.getActionSender(this).send();\r\n }\r\n\r\n /**\r\n * The optional function for Experiences to call use when an error occurs.\r\n * Defined as empty function so clients don't need to check it.\r\n * Passed to child experiences. Used mainly outside of Peregrine. e.g. Office page.\r\n * NOTE: we need to default to track.trackAppErrorEvent for PH components.\r\n */\r\n protected onAppError: ((error: AppError) => void) = (err) => Telemetry.sendAppErrorEvent(err);\r\n\r\n /**\r\n * The optional function to re-initialize experience state, re-fetch data if stale and fire page reveal TTVR.\r\n * Derived connectors need to override and implement experience specific revalidation logic.\r\n */\r\n protected async revalidateExperienceStaleState(isStale: boolean): Promise {\r\n this.isStale = isStale;\r\n\r\n // if the experience is not stale, mark stale revalidation complete\r\n if (!isStale) {\r\n markTtprRaf(this.experienceType);\r\n this.markStaleRevalidationComplete();\r\n }\r\n }\r\n\r\n /**\r\n * track experience changes for pageReveal\r\n * @param expType - experience type to be revalidated\r\n */\r\n protected trackExperienceChangesForPageReveal(expType?: string): void {\r\n // track changes in persistent store to be used on pageReveal\r\n trackExpWithPersistentDataUpdate(expType ? expType : this.experienceType);\r\n }\r\n\r\n /**\r\n * track experience changes for pageReveal\r\n * @param invalidationReason - page invalidation reason\r\n */\r\n protected trackPageInvalidationOnReveal(invalidationReason: PageInvalidationReasons): void {\r\n // track changes in persistent store for page invalidation on pageReveal\r\n trackPageInvalidation(invalidationReason);\r\n }\r\n\r\n /**\r\n * Default implementation of onPageReveal.\r\n * Derived connectors should override this method for specific implementation.\r\n */\r\n protected onPageReveal(): void {\r\n this.revalidateExperienceStaleState(true);\r\n }\r\n\r\n /**\r\n * Base implementation for page visible, resolves when page moves from hidden to visible.\r\n * This is currently used for Prerender PageReveal scenario.\r\n * In future this can be extended for page lifecycle api events.\r\n */\r\n protected async requestPageVisibleAsync(): Promise {\r\n return await requestPageRevealStartedAsync();\r\n }\r\n\r\n /**\r\n * Base implementation for page visible complete, resolves when page is ready to be revealed\r\n * This is currently used for Prerender PageReveal scenario.\r\n * In future this can be extended for page lifecycle api events.\r\n */\r\n protected async requestPageVisibleCompleteAsync(): Promise {\r\n return await requestPageRevealCompletedAsync();\r\n }\r\n\r\n /**\r\n * Base implementation for page visible, resolves when page mov* In future this can be extended for page lifecycle api events.\r\n */\r\n protected markStaleRevalidationComplete(): void {\r\n this.updateExperienceState(MilestoneDataActions.updateExperiencePublicState, ExperienceMilestoneEventTypes.staleRevalidationComplete);\r\n this.$isStale = false;\r\n }\r\n\r\n /**\r\n * register experience for pageReveal event\r\n * @param staleThreshold - defines experience staleness threshold.\r\n */\r\n private registerForPageReveal(staleThreshold: number): void {\r\n const revalidateExperienceStateCallback = this.revalidateExperienceStaleState.bind(this);\r\n\r\n // register with milestone to for page reveal and attach revalidateExperienceStaleState to update experience.\r\n registerExperienceForPageReveal(\r\n {\r\n experienceType: this.$experienceType,\r\n pageRevealInfo:\r\n {\r\n revalidationReason: ExperiencesRevalidationReason.Staleness,\r\n stalenessThreshold: staleThreshold,\r\n willRevalidateStaleState: revalidateExperienceStateCallback\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * observer page reveal and update connector start if required.\r\n */\r\n private observePageReveal(): void {\r\n pageRevealStartedObserver().then(() => {\r\n // add code to check if we need to call\r\n if (hasExperiencePersistentDataUpdated(this.experienceType)) {\r\n this.onPageReveal();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Initial setup for page reveal\r\n */\r\n private setupForPageReveal() {\r\n const experienceConfig = this.config as BaseExperienceConfig;\r\n // mock config for staleness if url override is provided\r\n this.mockStalenessConfig(experienceConfig);\r\n\r\n if (experienceConfig && experienceConfig.stalenessInfo\r\n && experienceConfig.stalenessInfo.isStaleCheckRequired) {\r\n this.registerForPageReveal(experienceConfig.stalenessInfo.staleThreshold);\r\n\r\n // observe page reveal and update connector state if required.\r\n this.observePageReveal();\r\n }\r\n }\r\n\r\n /**\r\n * Common helper to send a milestone timing update for a specific action.\r\n */\r\n private updateTiming(actionMap: ActionMap, startTime?: number, endTime?: number): void {\r\n actionMap.getActionSender(this.$milestoneDataConnector)\r\n .send(createTimingUpdate(this.$experienceType, this.$experienceGroup, this.namespace, startTime, endTime));\r\n }\r\n\r\n /**\r\n * Common helper to send a milestone public state update for a specific action.\r\n */\r\n private updateExperienceState(actionMap: ActionMap, eventType: ExperienceMilestoneEventTypes): void {\r\n if (this.$milestoneDataConnector === undefined) {\r\n this.$milestoneDataConnector = getMilestoneDataConnector() || null;\r\n }\r\n\r\n actionMap.getActionSender(this.$milestoneDataConnector)\r\n .send({\r\n experienceType: this.$experienceType,\r\n experienceGroup: this.$experienceGroup,\r\n experienceInstance: this.namespace,\r\n eventType});\r\n }\r\n\r\n /**\r\n * Initializes connector and connected component for a given child experience.\r\n * @param configInfo - the child experience config info\r\n * @param childConnectorProps - optional initial props to pass to connector.\r\n * @returns {Promise>} - the async operation that returns the connector for child experience.\r\n */\r\n private async getChildExperienceConnector(\r\n configInfo: ChildExperienceConfigInfo,\r\n childConnectorProps?: ExperienceInitialProps): Promise> {\r\n\r\n try {\r\n // Get an experience loader instance for the child experience\r\n const { instanceId, href, experienceType } = configInfo;\r\n const loader = new ExperienceLoader(href, instanceId, this.fullNamespace, this.store, this.requestContext, experienceType);\r\n\r\n // Get the connector for the child experience, and add it to the child connector map\r\n await loader.loadConnector();\r\n const { connector: childConnector } = loader;\r\n\r\n // Get the connected component for the child experience.\r\n await loader.getConnectedExperience({\r\n // add any override props\r\n ...(childConnectorProps || {}),\r\n // get core connector props\r\n ...this.getChildExperienceConnectorProps(experienceType, instanceId)\r\n });\r\n\r\n // Get the initial component instance for the child. The experience connector can get a new instance if it needs to do special\r\n // processing (i.e. passing in OwnProps)\r\n childConnector.getNewComponentInstance();\r\n\r\n return childConnector;\r\n } catch (error) {\r\n // Remove this config from cache.\r\n resolver.removeCachedConfig(configInfo.href);\r\n\r\n // Log an app error if the loader failed to load for whatever reason\r\n /// NOTE: DO NOT throw Error or reject promise here, or else the parent might not load the remaining child experiences.\r\n Telemetry.sendAppErrorEvent({\r\n ...ComponentConnectorAppErrors.BundleLoadError,\r\n message: `Failed to load experience ${configInfo && configInfo.experienceType || \"\"}`,\r\n pb: {\r\n ...ComponentConnectorAppErrors.BundleLoadError.pb,\r\n customMessage: `${JSON.stringify(configInfo)}, with error: ${error}`\r\n }\r\n });\r\n\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Load a single data connector\r\n * @param configInfo - data connector config info object\r\n * @returns {Promise{void}} - the async operation that denotes loading of all the children.\r\n */\r\n private async loadDataConnector(configInfo: ChildExperienceConfigInfo): Promise {\r\n\r\n // Get an experience loader instance for the child experience\r\n if (!configInfo || !configInfo.href) {\r\n\r\n // Log an app error if the loader failed to load for whatever reason\r\n Telemetry.sendAppErrorEvent({\r\n ...LoadDataConnectorConfigFailed,\r\n message: \"configInfo or Href is null while loading data connector\",\r\n pb: {\r\n ...LoadDataConnectorConfigFailed.pb,\r\n customMessage: JSON.stringify(configInfo)\r\n }\r\n });\r\n\r\n return;\r\n }\r\n\r\n const { experienceType } = configInfo;\r\n\r\n try {\r\n const loader = new ExperienceLoader(\r\n // if it's a config-less experience type, do not pass in the HREF to prevent loading the config.\r\n // TODO: after deployment, we need to update configs of config-less connectors so that we don't need\r\n // a special check like this, and instead the empty HREF can be directly set in the config.\r\n // Need to do this in a phased approach so that we don't break PROD users with old scripts.\r\n experienceType && ConfiglessConnectors[experienceType]\r\n ? \"\"\r\n : configInfo.href,\r\n \"\",\r\n \"\",\r\n PageBase.getInstance().store,\r\n this.requestContext,\r\n experienceType\r\n );\r\n\r\n // Get the connector for the child experience, and add it to the child connector map\r\n await loader.loadConnector(true);\r\n } catch (error) {\r\n // Log an app error if the loader failed to load for whatever reason\r\n /// NOTE: DO NOT throw Error or reject promise here, or else the parent might not load the remaining child experiences.\r\n Telemetry.sendAppErrorEvent({\r\n ...LoadDataConnectorFailed,\r\n message: `Data connector loading failed for ${configInfo && configInfo.experienceType || \"\"}`,\r\n pb: {\r\n ...LoadDataConnectorFailed.pb,\r\n customMessage: `${JSON.stringify(configInfo)}, with error: ${error}`\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Select and return the proper inner state for the component. The base DataConnector manages the wrapping of the state\r\n * and so it's getCurrentState() method is used to get the inner state (TState) for the connected component\r\n * NOTE: The signature of this component requires a state parameter, so that it can be passed into the subspaced()\r\n * method that is used to connect the component to state\r\n * @param state For this implementation, this parameter is ignored, since the actual state is managed by the base DataConnector\r\n */\r\n private selectComponentState(state: TParentState): TState {\r\n return (this.getCurrentState());\r\n }\r\n\r\n /**\r\n * Start lifecycle of a child experience\r\n * @param configInfo - the child experience config info\r\n * @param reRenderCallback - Render callback to call when dependencies are resolved\r\n * @param childConnectorProps - child experience connector props\r\n * @returns {Promise{void}} - the async operation that denotes loading of the child.\r\n */\r\n private async startProcessingChildExperience(\r\n configInfo: ChildExperienceConfigInfo,\r\n reRenderCallback: () => void,\r\n childConnectorProps?: ExperienceInitialProps\r\n ): Promise {\r\n\r\n const milestoneDependencyToLoadChildExp = getExperienceLoadDelegate(configInfo.experienceType);\r\n\r\n if (milestoneDependencyToLoadChildExp && milestoneDependencyToLoadChildExp.shouldResolve) {\r\n // Don't load delayed children on server side to avoid HTML mismatches\r\n if (canUseDOM()) {\r\n let addTimeout = true;\r\n\r\n if (milestoneDependencyToLoadChildExp.deferralType === DeferralEventType.CustomEventBasedDeferral) {\r\n addTimeout = false;\r\n configInfo.state = ExperienceState.Unknown;\r\n }\r\n\r\n this.resolveDependency(\r\n configInfo,\r\n milestoneDependencyToLoadChildExp.shouldResolve,\r\n () => this.loadAndRenderExperience(configInfo, reRenderCallback, true, childConnectorProps),\r\n addTimeout\r\n );\r\n }\r\n } else {\r\n await this.loadAndRenderExperience(configInfo, reRenderCallback, false, childConnectorProps);\r\n }\r\n }\r\n\r\n /**\r\n * load and render experience\r\n * @param childExpInfo - the child experience config info\r\n * @param reRenderCallback - Render callback to call when dependencies are resolved\r\n * @param delayLoaded - whether this experience is delay loaded or not\r\n * @param childConnectorProps - child experience connector props\r\n * @returns {Promise{void}} - the async operation that denotes loading of the child.\r\n */\r\n private async loadAndRenderExperience(\r\n childExpInfo: ChildExperienceConfigInfo,\r\n reRenderCallback: () => void,\r\n delayLoaded: boolean,\r\n childConnectorProps?: ExperienceInitialProps): Promise {\r\n // Get an experience loader instance for the child experience\r\n if (!childExpInfo\r\n || (!childExpInfo.href && !ConfiglessConnectors[childExpInfo.experienceType])\r\n || !childExpInfo.instanceId) {\r\n\r\n // Log an app error if the loader failed to load for whatever reason\r\n Telemetry.sendAppErrorEvent({\r\n ...ChildWithInvalidExperience,\r\n message: `Attempted to load child with invalid experience ${childExpInfo && childExpInfo.experienceType || \"\"}`,\r\n pb: {\r\n ...ChildWithInvalidExperience.pb,\r\n customMessage: JSON.stringify(childExpInfo)\r\n }\r\n });\r\n\r\n return;\r\n }\r\n\r\n try {\r\n const connector = await this.getChildExperienceConnector(childExpInfo, childConnectorProps);\r\n\r\n if (!connector) {\r\n childExpInfo.state = ExperienceState.Failed;\r\n return;\r\n }\r\n\r\n const milestoneDependencyToRenderChildExp = getExperienceRenderDelegate(childExpInfo.experienceType);\r\n\r\n if (milestoneDependencyToRenderChildExp && milestoneDependencyToRenderChildExp.shouldResolve) {\r\n this.resolveDependency(\r\n childExpInfo,\r\n milestoneDependencyToRenderChildExp.shouldResolve, () => {\r\n childExpInfo.state = ExperienceState.ReadyToRender;\r\n this.addConnectorToChildMap(childExpInfo, connector);\r\n reRenderCallback();\r\n },\r\n true\r\n );\r\n } else {\r\n childExpInfo.state = ExperienceState.ReadyToRender;\r\n this.addConnectorToChildMap(childExpInfo, connector);\r\n if (delayLoaded) {\r\n reRenderCallback();\r\n }\r\n }\r\n } catch (error) {\r\n childExpInfo.state = ExperienceState.Failed;\r\n\r\n // Log an app error if the loader failed to delayload\r\n Telemetry.sendAppErrorEvent(\r\n createError(\r\n ComponentConnectorAppErrors.ChildDelayLoadError,\r\n `Attempted to delay load child ${childExpInfo.experienceType} and failed as associated deferral promise returned an error`,\r\n stringifyError(error)\r\n )\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * add connector to child map\r\n * @param configInfo - the child experience config info\r\n * @param childConnector - child experience connector\r\n */\r\n private addConnectorToChildMap(configInfo: ChildExperienceConfigInfo, childConnector: IComponentConnector): void {\r\n // If the experience loaded, and we got the connected component, then add it to the child map,\r\n // as long as we have not seen this child before\r\n if (!this.childMap.has(configInfo.instanceId)) {\r\n this.childMap.set(configInfo.instanceId, childConnector);\r\n } else {\r\n // Log an app error\r\n Telemetry.sendAppErrorEvent({\r\n ...ComponentConnectorAppErrors.DuplicateChildInstanceFound,\r\n message: `Duplicate child instance found: ${childConnector.namespace}`,\r\n pb: {\r\n ...ComponentConnectorAppErrors.DuplicateChildInstanceFound.pb,\r\n customMessage: `href: ${location && location.href}, parentNamespace: ${this.fullNamespace}`\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Check if delay loaded experiences are ready to be rendered\r\n * @param children - the child experience config info array\r\n */\r\n private readyExperienceToRender(children: ChildExperienceConfigInfo[]): void {\r\n const config = this.config as BaseExperienceConfig;\r\n let reRender = true;\r\n\r\n if (!config.childExperiencesRenderType || config.childExperiencesRenderType === ChildExperiencesDeferRenderType.batch) {\r\n for (const child of children) {\r\n if (child.state !== ExperienceState.ReadyToRender && child.state !== ExperienceState.Failed && child.state !== ExperienceState.Unknown) {\r\n reRender = false;\r\n }\r\n }\r\n }\r\n\r\n if (reRender) {\r\n this.reRenderExperience();\r\n }\r\n }\r\n\r\n /**\r\n * Resolves promise dependency with applicable timeout strategy\r\n * @param dependency - Delegate Promise to resolve dependency\r\n * @param callback - callback function to call when dependency is resolved\r\n */\r\n private resolveDependency(\r\n configInfo: ChildExperienceConfigInfo,\r\n dependency: () => Promise,\r\n callback: () => void,\r\n addTimeout: boolean\r\n ): void {\r\n\r\n let pending = true;\r\n let timer: NodeJS.Timer = null;\r\n\r\n if (addTimeout) {\r\n timer = setTimeout(\r\n () => {\r\n if (pending) {\r\n pending = false;\r\n callback();\r\n }\r\n },\r\n this.$maxWaitToBatchRenderChildExperiences\r\n );\r\n }\r\n\r\n dependency().then(() => {\r\n if (addTimeout) {\r\n clearTimeout(timer);\r\n }\r\n\r\n if (pending) {\r\n pending = false;\r\n callback();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * mock experience config through url override\r\n * @param experienceConfig - experience config\r\n */\r\n private mockStalenessConfig(experienceConfig: BaseExperienceConfig) {\r\n\r\n const searchParams = new URLSearchParams(getLocationSearch());\r\n const enableMockStalenessConfig = searchParams.get(\"debugstalerevalidation\");\r\n\r\n if (enableMockStalenessConfig) {\r\n if (this.experienceType === ExperienceIds.moneyCard) {\r\n experienceConfig.stalenessInfo = { isStaleCheckRequired: true, staleThreshold: 3 };\r\n }\r\n if (this.experienceType === ExperienceIds.weatherCard) {\r\n experienceConfig.stalenessInfo = { isStaleCheckRequired: true, staleThreshold: 2 };\r\n }\r\n if (this.experienceType === ExperienceIds.river) {\r\n experienceConfig.stalenessInfo = { isStaleCheckRequired: true, staleThreshold: 1 };\r\n }\r\n if (this.experienceType === ExperienceIds.topSitesEdgeNext) {\r\n experienceConfig.stalenessInfo = { isStaleCheckRequired: true };\r\n }\r\n if (this.experienceType === ExperienceIds.backgroundImageEdgeNext) {\r\n experienceConfig.stalenessInfo = { isStaleCheckRequired: true };\r\n }\r\n if (this.experienceType === ExperienceIds.searchBoxEdgeNext) {\r\n experienceConfig.stalenessInfo = { isStaleCheckRequired: true };\r\n }\r\n if (this.experienceType === ExperienceIds.headerEdgeNext) {\r\n experienceConfig.stalenessInfo = { isStaleCheckRequired: true };\r\n }\r\n }\r\n }\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Network err string\r\n */\r\nexport const networkErrorString = \"No network\";\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { Telemetry, TelemetryAttrName, TelemetryObjectBase } from \"@msnews/telemetry-contracts\";\r\n\r\nimport React from \"react\";\r\n\r\n/**\r\n * Returns an HOC for tracking telemetry of a React.Component.\r\n * @param WrappedComponent - the component to track telemetry.\r\n * @param telemetryObject - the telemetry object of the component.\r\n */\r\nexport function trackComponent(\r\n WrappedComponent: React.ComponentType,\r\n telemetryObject: TelemetryObjectBase\r\n): React.ComponentClass {\r\n\r\n return class ComponentTracker extends React.Component {\r\n /** Telemetry object for the component. */\r\n private telemetryObject: TelemetryObjectBase;\r\n\r\n constructor(props: TProps, context?: any) {\r\n super(props, context);\r\n this.telemetryObject = telemetryObject;\r\n }\r\n\r\n /** React render lifecycle handler */\r\n public render(): JSX.Element {\r\n return ;\r\n }\r\n };\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { PerfTimeline } from \"@msnews/diagnostics\";\r\nimport React from \"react\";\r\n\r\n/**\r\n * Returns an HOC for tracking perf timeline of a React.Component\r\n * @param WrappedComponent - the component to instrument perf for\r\n * @param perfTimeline - the {PerfTimeline} object to use for tracking perf.\r\n * This is normally created in the parent context when instantating the component\r\n * and passed down to the HOC.\r\n */\r\nexport function instrumentPerf(\r\n WrappedComponent: React.ComponentType,\r\n perfTimeline: PerfTimeline\r\n): React.ComponentClass {\r\n\r\n return class ComponentPerfTimeline extends React.Component {\r\n\r\n /**\r\n * The last render action's endMeasure method to be used to mark the end of the render\r\n * cycle when mount or update happens next\r\n */\r\n private lastRenderEndMeasure: () => void;\r\n\r\n /** React render lifecycle handler */\r\n public render(): JSX.Element {\r\n this.lastRenderEndMeasure = perfTimeline.startMeasure(\"render\").endMeasure;\r\n return ;\r\n }\r\n\r\n /** React componentDidMount lifecycle handler */\r\n public componentDidMount(): void {\r\n this.lastRenderEndMeasure();\r\n }\r\n\r\n /** React componentDidUpdate lifecycle handler */\r\n public componentDidUpdate(): void {\r\n this.lastRenderEndMeasure();\r\n }\r\n };\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Set of resource string used by article reader components\r\n */\r\nconst ViewsStringResource = {\r\n article: \"article\",\r\n image: \"image\",\r\n video: \"video\",\r\n gallery: \"gallery\",\r\n exitFullscreen: \"Exit Full Screen\",\r\n fullscreen: \"Full Screen\",\r\n nextSlide: \"Next Slide\",\r\n previousSlide: \"Previous Slide\",\r\n publishedSecondAgo: \"second ago\",\r\n publishedSecondsAgo: \"seconds ago\",\r\n publishedMinuteAgo: \"minute ago\",\r\n publishedMinutesAgo: \"minutes ago\",\r\n publishedHourAgo: \"hr ago\",\r\n publishedHoursAgo: \"hrs ago\",\r\n publishedDayAgo: \"day ago\",\r\n publishedDaysAgo: \"days ago\",\r\n gallerySlideError: \"Something went wrong while loading this slide.\",\r\n sharingToolbarLoadFailure: \"Failed to render sharing toolbar.\",\r\n invalidCMSIdErrorFormat: \"Invalid {0} document. Please try a different one.\",\r\n documentDataFetchErrorFormat: \"Whoops! This {0} doesn’t exist or can’t be found. Please try a different one.\",\r\n intraArticleComponentErrorFormat: \"This {0} doesn’t exist or can’t be found.\",\r\n gallerySlideCountFormat: \"{0}/{1} SLIDES\",\r\n gallerySlideCountFullScreenFormat: \"{0} of {1}\",\r\n seeOnProviderSite: \"See on {0}\",\r\n socialFeedNotSupported: \"Social media feed type not supported.\",\r\n articleReadMoreText: \"show more\"\r\n};\r\n\r\nexport { ViewsStringResource };","// © Microsoft Corporation. All rights reserved.\r\n/**\r\n * Default query param prefix used if none specified\r\n */\r\nexport const DefaultQueryParamPrefix = \"rd\";\r\n/**\r\n * Generates a plain JavaScript object with the client values.\r\n * @param values The values to convert.\r\n */\r\nfunction objectFromSpecification(values) {\r\n const requestDataValue = values;\r\n if (requestDataValue.clientValue !== undefined) {\r\n // If it's a IRequestDataValueSpecification, return the actual getter\r\n return requestDataValue.clientValue;\r\n }\r\n // Otherwise recurse for each key until we find a plain value type\r\n return Object\r\n .keys(values)\r\n .reduce((pv, cv) => (Object.assign(Object.assign({}, pv), { [cv]: objectFromSpecification(values[cv]) })), {});\r\n}\r\n/**\r\n * Allows you to pass data about a request between client and server.\r\n * This interface can be used isomorphically.\r\n *\r\n * The \"spec\" contains \"getters\" to receive the data when called client side.\r\n * To operate server-side you must first serialize the client-side data and pass it via\r\n * query string parameters to the server. You then \"load\" the query string parameters using\r\n * \"loadQueryParams\". Once loaded you can request the data server-side with the same\r\n * interface as the client.\r\n *\r\n * NOTE: The use of URLSearchParams makes this not IE11 compatible without polyfill.\r\n *\r\n * @example\r\n * interface IRequestContext extends IRequestDataObject {\r\n * window: {\r\n * innerWidth: IRequestDataValue\r\n * }\r\n * }\r\n *\r\n * // On client and server\r\n * const rd = new RequestData(\r\n * {\r\n * window: {\r\n * innerWidth: {\r\n * clientValue: window.innerWidth\r\n * }\r\n * }\r\n * });\r\n *\r\n * // Client-side\r\n * const innerWidth = rd.data.window.innerWidth();\r\n *\r\n * const serialized = rd.getSerializedData();\r\n * // Make-call to server\r\n * fetch(`https://assets.msn.com/render?${serialized}`);\r\n *\r\n * // Server-side (in default module)\r\n * requestData.loadQueryParams(req.query)\r\n * const innerWidth = rd.data.window.innerWidth();\r\n */\r\nexport class RequestData {\r\n /**\r\n * @param spec Spec contains serialization metadata as well as client and server value getters\r\n * @param qspPrefix Prefix to append to serialized query string parameters\r\n */\r\n constructor(spec, qspPrefix) {\r\n this.spec = spec;\r\n this.qspPrefix = qspPrefix || DefaultQueryParamPrefix;\r\n }\r\n get verParam() {\r\n return `${this.qspPrefix}.ver`;\r\n }\r\n /**\r\n * Will return memoized values in the same structure as IRequestDataSpecification,\r\n * or the data loaded into\r\n */\r\n get data() {\r\n if (this.memo === undefined) {\r\n // Assume we're client-side if we haven't memoized query string params\r\n this.memo = objectFromSpecification(this.spec.spec);\r\n }\r\n return this.memo;\r\n }\r\n /**\r\n * Loads all query string parameters prefixed with qspPrefix into request data.\r\n * @param qsp The query string params to parse. It is safe to pass in the entire query--not just data prefixed by qspPrefix.\r\n */\r\n loadQueryParams(qsp) {\r\n if (this.memo !== undefined) {\r\n throw \"overwriting existing query string parameters.\";\r\n }\r\n const ver = qsp.get([this.qspPrefix, \"ver\"].join(\".\"));\r\n if (ver !== this.spec.ver) {\r\n throw `unmatched spec version: expected \"${this.spec.ver}\" but got ${ver}.`;\r\n }\r\n this.memo = {};\r\n // Load each query string parameter one at a time\r\n qsp.forEach((value, qp) => {\r\n if (!qp.startsWith(this.qspPrefix)) {\r\n // We don't belong in this set (we don't have the right prefix)--ignore.\r\n return;\r\n }\r\n if (qp === this.verParam) {\r\n // Skip version\r\n return;\r\n }\r\n // Split key by dots and remove prefix\r\n const split = qp.split(\".\").slice(1);\r\n let current = this.memo;\r\n split.forEach((key, i) => {\r\n let newValue = {}; // assume object unless last in list\r\n if (i === split.length - 1) {\r\n try {\r\n newValue = () => JSON.parse(value);\r\n }\r\n catch (ex) {\r\n // Reset memo to undefined and re-throw\r\n this.memo = undefined;\r\n throw ex;\r\n }\r\n }\r\n if (!Object.prototype.hasOwnProperty.call(current, key)) {\r\n current[key] = newValue;\r\n }\r\n if (typeof newValue === \"object\") {\r\n // Already exists--don't overwrite\r\n current = current[key];\r\n return;\r\n }\r\n });\r\n });\r\n }\r\n /**\r\n * Gets the stored values serialized as strings\r\n */\r\n getURLSearchParams() {\r\n const params = new URLSearchParams();\r\n /**\r\n * recurse traverses the data object to build dotted prefixes.\r\n * e.g.\r\n * { a: { b: { c: 5 } } } becomes a.b.c=5\r\n */\r\n const recurse = (obj, prefix) => {\r\n Object.keys(obj).forEach(k => {\r\n const current = obj[k];\r\n const currentPrefix = [...prefix, k];\r\n if (typeof current === \"object\") {\r\n recurse(current, currentPrefix);\r\n return;\r\n }\r\n // This will put explicit quotes (%22) around strings in the query, which is intentional\r\n // so JSON.parse is able to determine the correct type for the value.\r\n params.append(currentPrefix.join(\".\"), JSON.stringify(current()));\r\n });\r\n };\r\n recurse(this.data, [this.qspPrefix]);\r\n params.sort();\r\n // Version is always at the end\r\n params.append(this.verParam, this.spec.ver);\r\n return params;\r\n }\r\n /**\r\n * Sort the search params and serialize them to string.\r\n */\r\n getSerializedData() {\r\n return this.getURLSearchParams().toString();\r\n }\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * The param-name prefix used when serializing params onto the query string.\r\n */\r\nexport const SSRRequestDataPrefix = \"rd\";\r\n\r\n/**\r\n * Defines the \"interop\" contract between client and server-side renderer.\r\n * All of these values will be serialized into request parameters to be passed\r\n * on the HTTP request to the SSR server.\r\n */\r\nexport const SSRContract = {\r\n ver: \"0.1.0\",\r\n spec: {\r\n // IWindow\r\n innerWidth: {\r\n clientValue: () => window.innerWidth\r\n },\r\n innerHeight: {\r\n clientValue: () => window.innerHeight\r\n },\r\n locationHash: {\r\n clientValue: () => window.location.hash\r\n },\r\n locationHref: {\r\n clientValue: () => window.location.href\r\n },\r\n locationHost: {\r\n clientValue: () => window.location.host\r\n },\r\n locationHostName: {\r\n clientValue: () => window.location.hostname\r\n },\r\n locationOrigin: {\r\n clientValue: () => window.location.origin\r\n },\r\n locationPathName: {\r\n clientValue: () => window.location.pathname\r\n },\r\n locationProtocol: {\r\n clientValue: () => window.location.protocol\r\n },\r\n locationSearch: {\r\n clientValue: () => window.location.search\r\n },\r\n // IBrowser\r\n canUseCssGrid: {\r\n clientValue: () => ((window.CSS && window.CSS.supports && CSS.supports(\"display\", \"grid\")) || false)\r\n },\r\n // IDevice\r\n devicePixelRatio: {\r\n clientValue: () => window.devicePixelRatio\r\n },\r\n // ILocale\r\n language: {\r\n clientValue: () => document.documentElement.lang\r\n },\r\n direction: {\r\n clientValue: () => document.documentElement.dir\r\n }\r\n }\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { AppEnvironment, appEnvironment } from \"..\";\r\nimport { IRequestContext, IRequestData } from \"./IRequestContext\";\r\nimport { IRequestDataInteropValue, IRequestDataSpecification, RequestData } from \"@msnews/ssr-server\";\r\nimport { SSRContract, SSRRequestDataPrefix } from \"@msnews/isomorphic-util\";\r\n\r\n/**\r\n * Defines the parameters used to create a request contract.\r\n * Destructured from an object due to the combinations of parameters that are valid.\r\n */\r\nexport interface IRequestContextContract {\r\n /**\r\n * URL Search params that contain request data (client-side values sent to the server).\r\n * Only required when called server-side\r\n */\r\n params?: URLSearchParams;\r\n\r\n /**\r\n * The prefix to use to pull query params related to request data.\r\n */\r\n qspPrefix?: string;\r\n\r\n /**\r\n * The specification defining what request data should be passed between client and server.\r\n */\r\n spec?: IRequestDataSpecification;\r\n}\r\n\r\n/**\r\n * Used to propagate client-only data (like window.innerWidth) and singletons (like AppEnvironment)\r\n * in a non-global way to assist in making all libs/components/experiences isomorphic.\r\n */\r\nexport class RequestContext implements IRequestContext {\r\n private requestData: RequestData;\r\n\r\n /**\r\n * Create a new request context.\r\n *\r\n * If spec or qspPrefix is not provided it will use the defaults specified in \"@msnews/isomorphic-util\"\r\n *\r\n * @param IRequestContextContract parameters used to initialize the request context\r\n */\r\n constructor({ params, qspPrefix, spec }: IRequestContextContract = {}) {\r\n this.requestData = new RequestData(spec || SSRContract, qspPrefix || SSRRequestDataPrefix);\r\n if (params) {\r\n this.requestData.loadQueryParams(params);\r\n }\r\n }\r\n\r\n /**\r\n * The request ID is used to distinguish requests server-side.\r\n * This method passes through the app environment ActivityId\r\n */\r\n public get requestId(): string {\r\n return this.app.ActivityId;\r\n }\r\n\r\n /**\r\n * The current app environment.\r\n */\r\n public get app(): AppEnvironment {\r\n // TODO: Remove global reference and add to the constructor parameters.\r\n // The constructor should create a new app environment or accept an optional override.\r\n return appEnvironment;\r\n }\r\n\r\n /**\r\n * The current request data. i.e. client-side data that is passed\r\n * between client and server.\r\n */\r\n public get data(): IRequestData {\r\n return this.requestData.data;\r\n }\r\n}\r\n\r\n/**\r\n * Verifies the input data is defined, and throws an error if it is not.\r\n * @param dataName - The name of the requestContext value that we are verifying.\r\n * @param data - The value being checked.\r\n */\r\nexport function verifyDataExists(dataName: string, data: IRequestDataInteropValue): void {\r\n if (data === undefined) {\r\n throw new Error(\"Expected \" + dataName + \" to return value. Possible invalid RequestContext spec used.\");\r\n }\r\n}\r\n\r\n/**\r\n * Get clientValue from data getter.\r\n * @param dataGetter the data getter to get client-side value from spec\r\n * @param dataName the data name\r\n * @param throwException If true, throws an exception\r\n */\r\nexport function getContextData(dataGetter: any, dataName: string, throwException = true) {\r\n if ((typeof(dataGetter) === \"function\")) {\r\n const value = dataGetter();\r\n if (value) {\r\n return value;\r\n }\r\n }\r\n if (throwException) {\r\n throw new Error(\"Expected \" + dataName + \" to return value. Possible invalid RequestContext spec used or the spec doesn't contain this data.\");\r\n }\r\n return undefined;\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { PerfTimeline, logger, tryGetPerfTimeline } from \"@msnews/diagnostics\";\r\nimport { getIndexedDB, getLocationSearch } from \"@msnews/isomorphic-util\";\r\n\r\nimport { UrlUtility } from \"./UrlUtility\";\r\n\r\n/**\r\n * Provides utility functions to get and set data from IndexedDB.\r\n * If dbName is not provied, this class creates a db with name MicrosoftNews.\r\n * If storeName is not provied, this class creates a table/store with name Default.\r\n * Recommended to create a new table for your feature to separate and iterate through entries quickly.\r\n * IndexedDB utility does not require stringify and json parsing so more efficient! Just store your object as value.\r\n */\r\nexport class IndexedDb {\r\n\r\n /** IndexedDb object */\r\n private idb: IDBFactory = getIndexedDB();\r\n\r\n /** IndexedDb store name */\r\n /** DO NOT PUT DOT IN THE STORE NAME. */\r\n private storeName: string;\r\n\r\n /** IndexedDb promise. Sets when IndexedDB is initialized. */\r\n private idbPromise: Promise;\r\n\r\n /** The perf timeline for this IDB instance */\r\n private perfTimeline: PerfTimeline;\r\n\r\n /**\r\n * Returns if IndexedDb is supported.\r\n * @returns true if supported else false.\r\n */\r\n public get supported(): boolean {\r\n if (!this.idb) {\r\n logger.log(\"window.indexedDB is not supported.\");\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Function looks at query string param and check if IndexedDb operation is allowed or not. By default it is allowed.\r\n * @returns true if supported else false.\r\n */\r\n public get isCachingAllowed(): boolean {\r\n const searchObj = getLocationSearch();\r\n if (searchObj) {\r\n const param = UrlUtility.getQueryParameterByName(\"enableIndexedDbOperation\", searchObj);\r\n if (param) {\r\n return param.toLocaleLowerCase() === \"true\";\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Function looks at query string param and check if IndexedDb operation is allowed or not. By default it is allowed.\r\n * @returns true if supported else false.\r\n */\r\n public get isGetAllAllowed(): boolean {\r\n const searchObj = getLocationSearch();\r\n if (searchObj) {\r\n const param = UrlUtility.getQueryParameterByName(\"allowGetAllOverCursor\", searchObj);\r\n if (param) {\r\n return param.toLocaleLowerCase() === \"true\";\r\n }\r\n }\r\n\r\n if (IDBObjectStore.prototype && IDBObjectStore.prototype.getAll) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * This should be used for unit testing only.\r\n * @public\r\n * @param {IDBFactory} idb - IndexedDB object to override.\r\n */\r\n public _setIndexedDb(idb: IDBFactory): void {\r\n this.idb = idb;\r\n }\r\n\r\n /**\r\n * This should be used for unit testing only.\r\n * @public\r\n * @return {Promise} existing promise.\r\n */\r\n public _getIdbPromise(): Promise {\r\n return this.idbPromise;\r\n }\r\n\r\n /**\r\n * Returns object from IndexedDB\r\n * @public\r\n * @param {IDBValidKey} key - IndexedDB key. Typically it can be string or any supported type.\r\n * @returns Promise\r\n */\r\n public async getObject(key: IDBValidKey): Promise {\r\n let req: IDBRequest;\r\n\r\n await this.withIdbStore(\"readonly\", \"getObject\", storeCallback => {\r\n req = storeCallback.get(key);\r\n });\r\n return req.result;\r\n }\r\n\r\n /**\r\n * Return all objects from IndexedDB using getAll implementation.\r\n * @public\r\n * @returns Promise\r\n */\r\n public async getAll(): Promise {\r\n let req: IDBRequest;\r\n await this.withIdbStore(\"readonly\", \"getAll\", storeCallback => {\r\n req = storeCallback.getAll();\r\n });\r\n return req.result;\r\n }\r\n\r\n /**\r\n * Returns all objects from IndexedDB.\r\n * if getAll is supported, call it else fallback to Cursor implementation that exists on wide range of devices.\r\n * @public\r\n * @returns Promise\r\n */\r\n public async getAllObjects(): Promise {\r\n if (this.isGetAllAllowed) {\r\n return this.getAll();\r\n }\r\n\r\n const returnArray: Type[] = [];\r\n await this.withIdbStore(\"readonly\", \"getAllObjects\", storeCallback => {\r\n storeCallback.openCursor().onsuccess = function (event: any): void {\r\n const cursor = event.target && event.target.result ? event.target.result : undefined;\r\n if (cursor && cursor.value) {\r\n returnArray.push(cursor.value);\r\n cursor.continue();\r\n }\r\n };\r\n });\r\n return returnArray;\r\n }\r\n\r\n /**\r\n * Sets object into IndexedDB\r\n * @public\r\n * @param {IDBValidKey} key - IndexedDB key. Typically it can be string or any supported type.\r\n * @param {any} value - Any typed value you want to insert into IndexedDB.\r\n */\r\n public async setObject(key: IDBValidKey, value: any): Promise {\r\n return await this.withIdbStore(\"readwrite\", \"setObject\", storeCallback => {\r\n storeCallback.put(value, key);\r\n });\r\n }\r\n\r\n /**\r\n * Removes object from IndexedDB\r\n * @public\r\n * @param {IDBValidKey} key - IndexedDB key. Typically it can be string or any supported type.\r\n */\r\n public async removeObject(key: IDBValidKey): Promise {\r\n return await this.withIdbStore(\"readwrite\", \"removeObject\", storeCallback => {\r\n storeCallback.delete(key);\r\n });\r\n }\r\n\r\n /**\r\n * Removes all objects from IndexedDB\r\n * @public\r\n */\r\n public async clearObjects(): Promise {\r\n return await this.withIdbStore(\"readwrite\", \"clearObjects\", storeCallback => {\r\n storeCallback.clear();\r\n });\r\n }\r\n\r\n /**\r\n * Initialize IndexedDb.\r\n * @param idbStoreName {string} - IndexedDB store name\r\n * @param dbName {string} - Database name\r\n * @param preInitializedIdbPromise {Promise} - Optional pre-initialized promise that is fetching the {IDBDatabase} object.\r\n * Used to optimize/prime the IDB connection cost so it can be started as early as possible in the page without incurring additional cost\r\n * later when lot more things are happening on the page.\r\n */\r\n public async initializeIndexedDb(\r\n idbVersion = 1,\r\n idbStoreName = \"Default\",\r\n dbName = \"MicrosoftNews\",\r\n preInitializedIdbPromise: Promise = null\r\n ): Promise {\r\n\r\n this.storeName = idbStoreName;\r\n this.perfTimeline = tryGetPerfTimeline(`IndexedDB-${idbStoreName}`, idbStoreName);\r\n\r\n this.idbPromise = preInitializedIdbPromise || new Promise((resolve, reject) => {\r\n\r\n const endOpen = this.perfTimeline && this.perfTimeline.startMeasure(\"open\").endMeasure;\r\n const openreq = this.idb.open(dbName, idbVersion);\r\n\r\n openreq.onerror = () => {\r\n if (endOpen) { endOpen(\"error\"); }\r\n reject(openreq.error);\r\n };\r\n\r\n openreq.onsuccess = () => {\r\n if (endOpen) { endOpen(); }\r\n resolve(openreq.result);\r\n };\r\n\r\n openreq.onupgradeneeded = () => {\r\n openreq.result.createObjectStore(idbStoreName);\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Private function to set transaction.\r\n * @param type - IDB read/write mode\r\n * @param operationName - readable name to use in the app trace logging\r\n * @param callback - the callback to invoke with the IDB objectStore.\r\n * @returns {Promise} async operation that ends when the IDB transaction is complete.\r\n */\r\n private async withIdbStore(\r\n type: IDBTransactionMode,\r\n operationName: string,\r\n callback: ((store: IDBObjectStore) => void)\r\n ): Promise {\r\n\r\n return this.idbPromise.then(db => new Promise((resolve, reject) => {\r\n const endOperation = this.perfTimeline && this.perfTimeline.startMeasure(operationName).endMeasure;\r\n const transaction = db.transaction(this.storeName, type);\r\n\r\n transaction.oncomplete = () => {\r\n if (endOperation) { endOperation(); }\r\n resolve();\r\n };\r\n\r\n transaction.onabort = transaction.onerror = () =>\r\n reject(transaction.error);\r\n\r\n callback(transaction.objectStore(this.storeName));\r\n }));\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { BreakpointManager, BreakpointManagerCallback, ColumnArrangement, columnArrangements } from \"./BreakpointManager\";\r\nimport { BreakpointTracker, BreakpointTrackerCallback, defaultBreakpoints, identifyBreakpoint } from \"@microsoft/fast-layouts-react\";\r\n\r\nimport { Breakpoint } from \"@microsoft/fast-layouts-react\";\r\nimport { pull as _pull } from \"lodash-es\";\r\n\r\n/**\r\n * This class establishes a standard breakpoint scheme that can be used by all experiences\r\n * to achieve a unified breakpoint strategy. The implementation is a glorified wrapper around\r\n * the FAST BreakpointTracker that standardizes on a set of specific number of column arrangements\r\n * that will then be exposed to clients via the {ColumnArrangement} enum.\r\n */\r\nexport class FastBreakpointManager implements BreakpointManager {\r\n\r\n /**\r\n * Map of BreakpointManager callbacks to Breakpoint Tracker callback.\r\n * Required to quickly get Breakpoint callback on unsubscribe.\r\n */\r\n private callbackMap: Map = new Map();\r\n\r\n /**\r\n * Gets the {ColumnArrangement} enum that maps to the current viewport width.\r\n */\r\n public get currentColumnArrangement(): ColumnArrangement {\r\n return this.indexToStandardConverter(BreakpointTracker.currentBreakpoint());\r\n }\r\n\r\n /**\r\n * The constructor\r\n */\r\n public constructor(width?: number) {\r\n this.refreshBreakpoints();\r\n\r\n BreakpointTracker.defaultBreakpoint = identifyBreakpoint(width, BreakpointTracker.breakpoints);\r\n }\r\n\r\n /**\r\n * Refreshes breakpoints from current column arrangements.\r\n */\r\n public refreshBreakpoints(): void {\r\n const breakpoints: number[] = [0];\r\n for (let i = 1; i < columnArrangements.length; i++) {\r\n breakpoints.push(columnArrangements[i].minViewportWidthPx);\r\n }\r\n\r\n this.breakpoints = breakpoints;\r\n }\r\n\r\n /** breakpoint values */\r\n public set breakpoints(breakpoints: number[]) {\r\n BreakpointTracker.breakpoints = breakpoints;\r\n\r\n // TODO: Remove this when https://github.com/microsoft/fast-dna/issues/2602 is solved\r\n if (defaultBreakpoints && Array.isArray(defaultBreakpoints)) {\r\n const count = defaultBreakpoints.length;\r\n for (let i = 0; i < count; i++) {\r\n defaultBreakpoints.pop();\r\n }\r\n breakpoints.forEach(breakpoint => defaultBreakpoints.push(breakpoint));\r\n }\r\n\r\n // TODO: Remove after Fix of BreakpointTracker which update current breakpoint on setting breakpoint list.\r\n BreakpointTracker.update();\r\n }\r\n\r\n public get breakpoints(): number[] {\r\n return BreakpointTracker.breakpoints;\r\n }\r\n\r\n /**\r\n * Add a subscription to the breakpoint tracker changed notification list\r\n * @param callback - the callback to invoke when the breakpoint changes\r\n */\r\n public subscribe(callback: BreakpointManagerCallback): void {\r\n\r\n // Create callback with breakpoint value conversion.\r\n const managerCallback = (breakpoint: Breakpoint) => {\r\n callback(this.indexToStandardConverter(breakpoint));\r\n };\r\n\r\n this.callbackMap.set(callback, managerCallback);\r\n\r\n BreakpointTracker.subscribe(managerCallback);\r\n }\r\n\r\n /**\r\n * Removes an existing subscription from the breakpoint tracker notification list\r\n * @param callback - the callback to remove from the notification list\r\n */\r\n public unsubscribe(callback: BreakpointManagerCallback): void {\r\n BreakpointTracker.unsubscribe(this.callbackMap.get(callback));\r\n this.callbackMap.delete(callback);\r\n }\r\n\r\n /**\r\n * Converts an index-based breakpoint to a column arrangement.\r\n * @param breakpoint The breakpoint index to convert.\r\n * @returns The corresponding column arrangement.\r\n */\r\n private indexToStandardConverter(breakpoint: Breakpoint): ColumnArrangement {\r\n return columnArrangements[breakpoint].arrangement;\r\n }\r\n}\r\n\r\nlet _fastBreakpointManager: FastBreakpointManager;\r\n\r\n/**\r\n * Default instance of fastBreakpointManager\r\n * @param width\r\n * @param recreate\r\n */\r\nexport const fastBreakpointManager = (width?: number, recreate?: boolean) => {\r\n if (!_fastBreakpointManager || recreate) {\r\n _fastBreakpointManager = new FastBreakpointManager(width);\r\n }\r\n\r\n return _fastBreakpointManager;\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { getAppEnvironment, getHeadData } from \"@msnews/core\";\r\nimport { useEnterpriseCompliance, useEnterpriseDomain } from \"@msnews/auth\";\r\n\r\nimport { logger } from \"@msnews/diagnostics\";\r\n\r\n/**\r\n * The service URL to use\r\n */\r\nlet serviceUrl: URL;\r\n\r\n/**\r\n * The feed service URL to use\r\n */\r\nlet feedServiceUrl: URL;\r\n\r\n/**\r\n * Initialize AppServiceManager with serviceUrl\r\n *\r\n * @param url {string} - The service url\r\n */\r\nexport function initializeServiceRequest(url: URL): void {\r\n serviceUrl = new URL(\"\", url);\r\n initializationLogs(serviceUrl);\r\n}\r\n\r\n/**\r\n * Initialize AppServiceManager with feedServiceUrl\r\n *\r\n * @param url {string} - The feed service url\r\n */\r\nexport function initializeFeedServiceRequest(url: URL): void {\r\n feedServiceUrl = new URL(\"\", url);\r\n initializationLogs(feedServiceUrl);\r\n}\r\n\r\n/**\r\n * Returns service url\r\n * @returns an URL pointing to Service Request base URL\r\n */\r\nexport function getServiceUrl(): URL {\r\n const appEnvironment = getAppEnvironment();\r\n\r\n if (!serviceUrl) {\r\n // Use enterprise request if in enterprise compliant scenario\r\n const isEnterpriseDomain = useEnterpriseCompliance() && useEnterpriseDomain();\r\n const url = isEnterpriseDomain ? appEnvironment.EnterpriseServiceUrlBase : appEnvironment.ServiceUrlBase;\r\n\r\n initializeServiceRequest(url);\r\n }\r\n\r\n return serviceUrl;\r\n}\r\n\r\n/**\r\n * Returns feed service url\r\n * @returns an URL pointing to Feed Service Request base URL\r\n */\r\nexport function getFeedServiceUrl(): URL {\r\n const appEnvironment = getAppEnvironment();\r\n\r\n if (!feedServiceUrl) {\r\n // Use enterprise request if in enterprise compliant scenario\r\n const isEnterpriseDomain = useEnterpriseCompliance() && useEnterpriseDomain();\r\n const url = isEnterpriseDomain ? appEnvironment.EnterpriseServiceUrlBase : appEnvironment.FeedServiceUrlBase;\r\n\r\n initializeFeedServiceRequest(url);\r\n }\r\n\r\n return feedServiceUrl;\r\n}\r\n\r\n/**\r\n * Appends `subPath` to Service Request URL.\r\n * It is an abstraction for the client so it won't have to\r\n * know the url format\r\n * @param subPath the path to append to Service Request URL\r\n * @returns an URL pointing to Service Request base URL appended by `subPath`\r\n */\r\nexport function getServiceUrlForSubpath(subPath: string): URL {\r\n return new URL(subPath + getServiceUrl().search, getServiceUrl());\r\n}\r\n\r\n/**\r\n * Appends `subPath` to Feed Service Request URL.\r\n * It is an abstraction for the client so it won't have to\r\n * know the url format\r\n * @param subPath the path to append to Feed Service Request URL\r\n * @returns an URL pointing to Feed Service Request base URL appended by `subPath`\r\n */\r\nexport function getFeedServiceUrlForSubpath(subPath: string): URL {\r\n return new URL(subPath + getFeedServiceUrl().search, getFeedServiceUrl());\r\n}\r\n\r\n/**\r\n * Add initial logs based on url and environment\r\n * @param url the url that is being used to initialize\r\n */\r\nfunction initializationLogs(url: URL): void {\r\n let authEnabled = false;\r\n if (!process.env.WEBPACK_DEV_SERVER && url.searchParams.get(\"env.service\") !== \"dev\" && getHeadData().UserIsSignedIn) {\r\n authEnabled = true;\r\n }\r\n\r\n logger.log(\"u-si: \" + getAppEnvironment().UserId);\r\n logger.log(\"a-si: \" + authEnabled);\r\n logger.log(\"ss-si: \" + getHeadData().UserIsSignedIn);\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { registerResetCallback } from \"@msnews/core\";\r\n\r\n/**\r\n * Experiences being tracked for milestone data updates. This normally includes all experience\r\n * types being tracked under various trackers such as DOM, Visual Readiness & Deferral trackers.\r\n * It is used to prevent firing of certain general milestone events from base classes so that\r\n * we're not wasting CPU cycles processing unnecessary redux actions.\r\n */\r\nlet trackingExperiences: { [experienceType: string]: boolean } = {};\r\n\r\n/**\r\n * Helper to check whether we're tracking milestone events for the given experience and the event type\r\n */\r\nexport function shouldTrackExperience(experienceType: string, shouldTrack?: boolean): boolean {\r\n return shouldTrack != null\r\n ? trackingExperiences[experienceType] = shouldTrack\r\n : trackingExperiences[experienceType];\r\n}\r\n\r\n/**\r\n * Register a callback to reset the trackingExperiences.\r\n * The callback is registered once when the module is loaded and invoked once on the server side at the beginning of each request.\r\n */\r\nregisterResetCallback(() => {\r\n trackingExperiences = {};\r\n});\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { CombinedObjectTelemetryContract, ObjectTelemetryContractInternal } from \"../types/TelemetryInternalContract\";\r\nimport { DeepPartial, ObjectTelemetryContract, TelemetryAttrName, TelemetryObjectBase, TrackingOptions } from \"@msnews/telemetry-contracts\";\r\nimport { merge, values } from \"lodash-es\";\r\n\r\nimport { TelemetryMetadataAttribute } from \"./TelemetryMetadataAttribute\";\r\n\r\n/**\r\n * Object metadata class which combination of external contract and internal data\r\n * @class TelemetryObject\r\n */\r\nexport class TelemetryObject implements TelemetryObjectBase {\r\n /**\r\n * Root object.\r\n */\r\n private static root: TelemetryObject = new TelemetryObject(\r\n { name: \"root\" },\r\n null,\r\n true\r\n );\r\n\r\n /**\r\n * Default values\r\n */\r\n private static defaultValue: DeepPartial = {};\r\n\r\n /**\r\n * Mapping between object id and object itself.\r\n */\r\n private static objectIdMapper: { [key: string]: TelemetryObject } = {};\r\n\r\n /**\r\n * Last id.\r\n */\r\n private static lastId = 0;\r\n\r\n /**\r\n * Flag for identifying whether object already is captured or not.\r\n */\r\n public isCaptured?: boolean;\r\n\r\n /**\r\n * Flag for identifying whether object is visible or not.\r\n */\r\n public isVisible?: boolean;\r\n\r\n /**\r\n * Id of current object.\r\n */\r\n public id: number;\r\n\r\n /**\r\n * Full id.\r\n */\r\n public fullId: string;\r\n\r\n /**\r\n * Reference to parent object.\r\n */\r\n public readonly parent: TelemetryObject;\r\n\r\n /**\r\n * External object contract.\r\n */\r\n public contract: ObjectTelemetryContract;\r\n\r\n /**\r\n * Ordinal of the object.\r\n */\r\n private ordinal: number;\r\n\r\n /**\r\n * Last ordinal of its children.\r\n */\r\n private ordinalCount: number;\r\n\r\n /**\r\n * Contract getter.\r\n * @returns Combined contract between internal and external.\r\n */\r\n public get combinedContract(): CombinedObjectTelemetryContract {\r\n return merge({}, TelemetryObject.defaultValue, this.contract, this.internalContract);\r\n }\r\n\r\n /**\r\n * Internal contract getter.\r\n * @returns Internal contract.\r\n */\r\n private get internalContract(): ObjectTelemetryContractInternal {\r\n const { lineage, lineageOrdinal } = TelemetryObject.getLineage(this);\r\n const contract = {\r\n placement: {\r\n id: this.id,\r\n lineage: lineage,\r\n lineageOrdinal: lineageOrdinal\r\n }\r\n } as ObjectTelemetryContractInternal;\r\n\r\n if (this.parent && this.parent.id && this.parent.id !== 0) {\r\n contract.placement.parentId = this.parent.id;\r\n contract.placement.ordinal = this.ordinal;\r\n }\r\n\r\n return contract;\r\n }\r\n\r\n constructor(contract: ObjectTelemetryContract, parent?: TelemetryObject, isRoot?: boolean) {\r\n this.contract = contract;\r\n this.ordinal = 0;\r\n this.ordinalCount = 0;\r\n\r\n if (!isRoot) {\r\n if (parent) {\r\n this.parent = parent;\r\n } else {\r\n this.parent = TelemetryObject.root;\r\n }\r\n\r\n this.id = this.createObjectId();\r\n this.setOrdinal();\r\n }\r\n }\r\n\r\n /**\r\n * Get root object\r\n * @returns Telemetry root object.\r\n */\r\n public static getRoot(): TelemetryObject {\r\n return TelemetryObject.root;\r\n }\r\n\r\n /**\r\n * Get telemetry object by id.\r\n * @param fullId full id.\r\n * @returns Telemetry object.\r\n */\r\n public static getItemById(fullId: string): TelemetryObject {\r\n return this.objectIdMapper[fullId];\r\n }\r\n\r\n /**\r\n * Get all telemetry objects.\r\n * @returns Telemetry objects.\r\n */\r\n public static getItems(): TelemetryObject[] {\r\n return values(this.objectIdMapper);\r\n }\r\n\r\n /**\r\n * Reset id to be back to 0.\r\n */\r\n public static resetIdTracker(): void {\r\n this.objectIdMapper = {};\r\n this.lastId = 0;\r\n TelemetryObject.root.resetOrdinal();\r\n }\r\n\r\n /**\r\n * Get telemetry object from an element.\r\n * @param element The element.\r\n * @returns Telemetry object.\r\n */\r\n public static getObject(element: Element): TelemetryObject {\r\n const metadataAttribute = element && element.getAttribute && element.getAttribute(TelemetryAttrName);\r\n const metadataObject = metadataAttribute && JSON.parse(metadataAttribute) as TelemetryMetadataAttribute;\r\n\r\n return metadataObject && TelemetryObject.getItemById(metadataObject.i);\r\n }\r\n\r\n /**\r\n * Get lineage and lineageOrdinal strings.\r\n * Lineage is concatenation of telemetry object's name of the current object up to the root. It basically tells the placement of the object in the page.\r\n * Lineage ordinal is concatenation of ordinal. It tells which position of each object up to root in the hierachy is.\r\n * Lineage can be duplicated since object name can be the same in some cases e.g. slideshow. Lineage ordinal is used to distinguish that.\r\n * @params obj Target telemetry object.\r\n * @returns Lineage and lineageOrdinal strings.\r\n */\r\n public static getLineage(obj: TelemetryObject, delimeter = \">\", includeRootElement = false): any {\r\n if (obj.parent && obj.parent !== TelemetryObject.root) {\r\n let { lineage, lineageOrdinal } = this.getLineage(obj.parent, delimeter, includeRootElement);\r\n lineage += delimeter + obj.contract.name;\r\n const newLineageOrdinal = (lineageOrdinal ? lineageOrdinal + delimeter : \"\") + obj.ordinal;\r\n return { lineage, lineageOrdinal: newLineageOrdinal };\r\n } else if (obj.parent && obj.parent === TelemetryObject.root && includeRootElement) {\r\n const outputObj: any = { lineage: obj.contract.name };\r\n outputObj.lineageOrdinal = \"\" + obj.ordinal;\r\n return outputObj;\r\n } else {\r\n return { lineage: obj.contract.name };\r\n }\r\n }\r\n\r\n /**\r\n * Add a new telemetry object as a child.\r\n * @param contract Object telemetry contract.\r\n * @returns New telemetry object.\r\n */\r\n public addChild(contract: ObjectTelemetryContract): TelemetryObject {\r\n const telemetryObject = new TelemetryObject(contract, this);\r\n return telemetryObject;\r\n }\r\n\r\n /**\r\n * Add or update a child telemetry object.\r\n * @param contract Object telemetry contract.\r\n * @param savedChildObject Existing child telemetry object (if exist).\r\n * @returns New telemetry object.\r\n */\r\n public addOrUpdateChild(contract: ObjectTelemetryContract, savedChildObject?: TelemetryObject): TelemetryObject {\r\n // Check both childObject and id in case current object already get soft deleted.\r\n if (savedChildObject && this.id) {\r\n savedChildObject.contract = contract;\r\n return savedChildObject;\r\n } else {\r\n return new TelemetryObject(contract, this);\r\n }\r\n }\r\n\r\n /**\r\n * Render telemetry attribute.\r\n * @param option Tracking options.\r\n * @returns Telemetry attribute.\r\n */\r\n public render(option?: TrackingOptions): any {\r\n this.mapObjectId();\r\n const attr: { [key: string]: any } = {};\r\n attr.i = this.fullId;\r\n\r\n const action = (option && option.action) || this.contract.action;\r\n if (action !== undefined && action !== null) {\r\n attr.a = action;\r\n }\r\n\r\n const behavior = (option && option.behavior) || this.contract.behavior;\r\n if (behavior !== undefined && behavior !== null) {\r\n attr.b = behavior;\r\n }\r\n\r\n return { [TelemetryAttrName]: JSON.stringify(attr) };\r\n }\r\n\r\n /**\r\n * Reset ordinal.\r\n */\r\n public resetOrdinal(): void {\r\n this.ordinalCount = 0;\r\n }\r\n\r\n /**\r\n * Set ordinal.\r\n */\r\n public setOrdinal(): void {\r\n if (this.ordinal === 0) {\r\n this.parent.ordinalCount++;\r\n this.ordinal = this.parent.ordinalCount;\r\n this.ordinalCount = 0;\r\n }\r\n }\r\n\r\n /**\r\n * Soft delete. Remove all references to the current object to allow gabage colletor to clear it out.\r\n */\r\n public delete(): void {\r\n const children = this.getChildren();\r\n for (let i = 0; i < children.length; i++) {\r\n const child = children[i];\r\n child.delete();\r\n }\r\n\r\n // Remove reference to this object to allow gabage collector to collect.\r\n delete TelemetryObject.objectIdMapper[this.fullId];\r\n // Reset ordinal of all children under the same parent because order will change after the object get deleted.\r\n this.parent.resetOrdinal();\r\n }\r\n\r\n /**\r\n * Create object id.\r\n * @param Object id.\r\n */\r\n private createObjectId(): number {\r\n const id = ++TelemetryObject.lastId;\r\n\r\n return id;\r\n }\r\n\r\n /**\r\n * Map between object and fullId\r\n */\r\n private mapObjectId(): void {\r\n if (this.contract && this.contract.overrideId) {\r\n this.fullId = this.contract.overrideId;\r\n } else if (this.fullId) {\r\n return;\r\n } else {\r\n const { _, lineageOrdinal } = TelemetryObject.getLineage(this, \"|\", true);\r\n this.fullId = lineageOrdinal;\r\n }\r\n\r\n TelemetryObject.objectIdMapper[this.fullId] = this;\r\n }\r\n\r\n /**\r\n * Check whether this is parent of the target object.\r\n * @param obj Target object.\r\n * @returns true if this is the parent. Otherwise, false.\r\n */\r\n private isParentOf(obj: TelemetryObject): boolean {\r\n return obj.parent === this;\r\n }\r\n\r\n /**\r\n * Get all the children.\r\n */\r\n private getChildren(): TelemetryObject[] {\r\n const children = [];\r\n if (TelemetryObject.objectIdMapper) {\r\n Object.keys(TelemetryObject.objectIdMapper).forEach((key) => {\r\n const obj = TelemetryObject.objectIdMapper[key];\r\n if (this.isParentOf(obj)) {\r\n children.push(obj);\r\n }\r\n });\r\n }\r\n\r\n return children;\r\n }\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { IsForceTimestampExpired, RenderCacheConfig, getRenderCacheKeys } from \".\";\r\nimport { RenderCache, RenderCacheKeys } from \"./RenderCache\";\r\nimport { RenderCacheErrors, logger } from \"@msnews/diagnostics\";\r\nimport { appEnvironment, localStorage } from \"@msnews/core\";\r\nimport { batchCSS, scrapeDom, renderCacheKeyOfNormalizedKeys } from \"./Helper\";\r\nimport { defaultExpirationTimeMs, expirationPrefix, forceTimestampPrefix, jssMapSuffix, keysPrefix, storagePrefix } from \"./Constants\";\r\n\r\nimport { Telemetry } from \"@msnews/telemetry-contracts\";\r\nimport { userInteractionHappened } from \"./UserInteractionWatcher\";\r\n\r\nconst jssGeneratedClassesMap: { [instanceId: string]: Array } = {};\r\nlet jssCaptureCompleted = false;\r\n\r\n/**\r\n * Persist the complete render state (DOM and Styles) necessary to restore the rendered Peregrine SPA page, without needing to\r\n * first load all of the Peregrine experience bundles.\r\n * This is the equivalent of using Server Side Rendering to generate the initial DOM, though in this case the initial DOM elements and styles\r\n * are persisted and loaded locally on the client.\r\n * @param config Render cache configuration.\r\n * @param stateJson The state to persist in JSON form.\r\n * @param markers List of performance markers, which will be fired upon cache restore.\r\n * @param invokeFallback Canvas specific fallback function to be executed on jss exception.\r\n */\r\nexport function persistRenderCache(config: RenderCacheConfig, stateJson?: string, markers?: string[], invokeFallback?: (message: string) => void): void {\r\n jssCaptureCompleted = true;\r\n\r\n if (!config || !localStorage.supported || !window.renderCacheEnabled) {\r\n return;\r\n }\r\n\r\n // Get normalized render cache keys\r\n const renderCacheKeys: RenderCacheKeys = getRenderCacheKeys(config && config.normalizeKeyParamsList);\r\n\r\n // Check if we need to refresh cache by force. Used as Failsafe if user stuck in broken render cache loop.\r\n if (IsForceTimestampExpired(config && config.forceExpirationTime)) {\r\n removeRenderCache();\r\n logger.log(\"[RC Info] Force timestamp expired: removing render cache\");\r\n return;\r\n }\r\n\r\n // Found an issue with User interaction check. Its inconsistent and as we are not deleting RC on this,\r\n // users may get stuck in this state.\r\n if (userInteractionHappened()) {\r\n return;\r\n }\r\n\r\n // When critical jss mismatch is detected - do not persist and based on config decide to purge and fallback\r\n if (criticalJssMismatchDetected(config, invokeFallback)) {\r\n return;\r\n }\r\n\r\n let { includeNewsFeed, expirationTime, newsFeedExpirationTime } = config;\r\n\r\n // Persist build version recorded for the page being render cached\r\n const buildVersion = appEnvironment.BuildVersion || \"\";\r\n\r\n // Form Cache Object\r\n const renderCacheStorageObj: RenderCache = {\r\n dom: scrapeDom(includeNewsFeed),\r\n batch_css: batchCSS(),\r\n build_version: buildVersion,\r\n markers,\r\n state: stateJson\r\n };\r\n\r\n expirationTime = (includeNewsFeed ? newsFeedExpirationTime : expirationTime)\r\n || defaultExpirationTimeMs;\r\n\r\n // Try to persist Render Cache and Timestamp\r\n const expiresOn: number = new Date().getTime() + expirationTime;\r\n\r\n localStorage.setObject(renderCacheKeys.expn, expiresOn);\r\n localStorage.setObject(renderCacheKeys.keyn, renderCacheStorageObj);\r\n}\r\n\r\n/**\r\n * Deletes render cache local storage for all domains\r\n */\r\nexport function removeRenderCache(): void {\r\n if (!localStorage.supported) {\r\n return;\r\n }\r\n\r\n // The render cache Urls are currently not normalized, so we have different render\r\n // cache saved for DHP and NTP page. But, some of the properties (example: market)\r\n // is shared between those pages. To ensure a purge on render cache on one page,\r\n // does purge the other render cache as well, and avoid breaking the page layout,\r\n // we remove all render cache keys on removeRenderCache\r\n localStorage.removeSubstringKeys(storagePrefix);\r\n localStorage.removeSubstringKeys(expirationPrefix);\r\n localStorage.removeSubstringKeys(forceTimestampPrefix);\r\n localStorage.removeSubstringKeys(keysPrefix);\r\n localStorage.removeSubstringKeys(jssMapSuffix);\r\n}\r\n\r\n/**\r\n * Deletes render cache local storage only for current href\r\n */\r\nexport function removeCurrentRenderCache(): void {\r\n if (!localStorage.supported) {\r\n return;\r\n }\r\n\r\n const renderCacheKeys: RenderCacheKeys = getRenderCacheKeys();\r\n localStorage.removeObject(renderCacheKeys.keyn);\r\n localStorage.removeObject(renderCacheKeys.frcn);\r\n localStorage.removeObject(renderCacheKeys.expn);\r\n localStorage.removeObject(renderCacheKeys.jssn);\r\n localStorage.removeObject(renderCacheKeyOfNormalizedKeys);\r\n}\r\n\r\n/**\r\n * Capture class names generated by JSS and maintain inside a dictionary.\r\n * @param key key for class name\r\n * @param val JSS val for class name\r\n */\r\nexport function captureJssGeneratedClasses(key: string, val: string): void {\r\n if (jssCaptureCompleted || !(window && window.renderCacheEnabled)) {\r\n return;\r\n }\r\n\r\n if (jssGeneratedClassesMap[key]) {\r\n jssGeneratedClassesMap[key].push(val);\r\n } else {\r\n jssGeneratedClassesMap[key] = [val];\r\n }\r\n}\r\n\r\n/**\r\n * Compares stored JSS Map with current JSS Map and log corresponding app errors\r\n * @param config Render cache configuration.\r\n * @param invokeFallback Canvas specific fallback function to be executed on jss exception.\r\n * @returns boolean - returns true when there is critical jss mismatch, otherwise false\r\n */\r\nexport function criticalJssMismatchDetected(config: RenderCacheConfig, invokeFallback?: (message: string) => void): boolean {\r\n // if we haven't captured any generated classes log an app error and return\r\n if (Object.keys(jssGeneratedClassesMap).length === 0) {\r\n logJssMismatchAppError(RenderCacheErrors.JssStyleMismatchWarning, \"Generated classes map is empty. \");\r\n return false;\r\n }\r\n\r\n const { isJssIdentical, isCriticalJssIdentical, jssWarningMessage, jssErrorMessage } = compareJssMap(config);\r\n\r\n // in case of non critical JSS mismatch we just log an app warning\r\n if (!isJssIdentical) {\r\n logJssMismatchAppError(RenderCacheErrors.JssStyleMismatchWarning, jssWarningMessage);\r\n } else {\r\n // in case there are no mismatches - write back the newly generated class map back to localstorage\r\n Object.keys(jssGeneratedClassesMap).length && localStorage.setObject(getRenderCacheKeys().jssn, jssGeneratedClassesMap);\r\n logger.log(\"[RC Info] No style mismatch found\");\r\n }\r\n\r\n // in case of critical JSS mismatch, log an app error and based on config\r\n // decide to purge and invoke canvas specific fallback\r\n if (!isCriticalJssIdentical) {\r\n logJssMismatchAppError(RenderCacheErrors.JssStyleCriticalMismatchError, jssErrorMessage);\r\n\r\n if (config && config.enablePurgeOnJssMismatch) {\r\n removeRenderCache();\r\n\r\n if (config && config.enableFallbackOnJssMismatch && invokeFallback && typeof invokeFallback === \"function\") {\r\n invokeFallback(jssErrorMessage);\r\n }\r\n }\r\n }\r\n\r\n return !isCriticalJssIdentical;\r\n}\r\n\r\n/**\r\n * Compares stored JSS Map with current JSS Map and identifies if those are critical vs non critical error message with corresponding error message\r\n * @param config Render cache configuration.\r\n * @returns object - returns mismatch and error information\r\n */\r\nfunction compareJssMap(config: RenderCacheConfig): { isJssIdentical: boolean, isCriticalJssIdentical: boolean, jssWarningMessage: string, jssErrorMessage: string } {\r\n let jssErrorMessage = \"\";\r\n let jssWarningMessage = \"\";\r\n let isCriticalJssIdentical = true;\r\n let isJssIdentical = true;\r\n\r\n const jssCriticalClassListMap: { [className: string]: boolean } = getJssCriticalClassListMap(config && config.jssCriticalClassList || []);\r\n\r\n const storedMap = localStorage.getObject(getRenderCacheKeys().jssn);\r\n if (storedMap && typeof storedMap === \"object\" && Object.keys(storedMap).length) {\r\n // this for loop compares every item in stored Map of Css class names to the current page instance map\r\n for (const key in storedMap) {\r\n const storedClasses = storedMap[key];\r\n\r\n // if stored class isn't correctly set, log a non critical app app warning and return\r\n if (!Array.isArray(storedClasses)) {\r\n return { isJssIdentical: false, isCriticalJssIdentical: true, jssWarningMessage: `Stored classes expected to be an array, but received something else. stored val: ${storedClasses}. `, jssErrorMessage: \"\" };\r\n }\r\n\r\n /*\r\n We only care about extra classes being present in the stored classes. If the current page\r\n instance has new class names not present in the stored map, we do not consider this a mismatch\r\n since the render cache snapshot won't be broken due to this scenario. Also if there are no\r\n classes corresponding to a key in the current map, detect that as a mismatch as well.\r\n\r\n --- Scenario 1: (detect as a mismatch) ---\r\n storedClasses : k1: { [c1, c2, c3] }\r\n currentClasses: k1: { [c1, c2] }\r\n\r\n --- Scenario 2: (do not detect as a mismatch) ---\r\n storedClasses : k1: { [c1, c2] }\r\n currentClasses: k1: { [c1, c2, c3] }\r\n\r\n --- Scenario 3: (detect as a mismatch) ---\r\n storedClasses : k1: { [c1, c2] }\r\n currentClasses: k2: { [c3, c4, c5] }\r\n */\r\n const currentClasses = jssGeneratedClassesMap[key];\r\n if (currentClasses) {\r\n if (storedClasses.some(className => currentClasses.indexOf(className) === -1)) {\r\n const errorMessage = `JSSError: val mismatch for key: ${key}, val stored: ${storedClasses}, new val: ${currentClasses}. `;\r\n if (jssCriticalClassListMap[key]) {\r\n jssErrorMessage += errorMessage;\r\n isCriticalJssIdentical = false;\r\n }\r\n\r\n jssWarningMessage += errorMessage;\r\n isJssIdentical = false;\r\n }\r\n } else {\r\n const errorMessage = `JSSError: val mismatch for key: ${key}, val stored: ${storedClasses}, new val: '' (empty). `;\r\n if (jssCriticalClassListMap[key]) {\r\n jssErrorMessage += errorMessage;\r\n isCriticalJssIdentical = false;\r\n }\r\n\r\n jssWarningMessage += errorMessage;\r\n isJssIdentical = false;\r\n }\r\n }\r\n }\r\n\r\n return {\r\n isJssIdentical: isJssIdentical,\r\n isCriticalJssIdentical: isCriticalJssIdentical,\r\n jssWarningMessage: jssWarningMessage,\r\n jssErrorMessage: jssErrorMessage\r\n };\r\n}\r\n\r\n/**\r\n * Helper function to log render cache jss mismatch app errors\r\n * @param errorParams The error params.\r\n * @param customMessage The custom message to be logged.\r\n */\r\nfunction logJssMismatchAppError(errorParams: any, customMessage: string): void {\r\n Telemetry.sendAppErrorEvent({\r\n ...errorParams,\r\n message: \"RC JSS mismatch issue\",\r\n pb: {\r\n ...errorParams.pb,\r\n customMessage: customMessage\r\n }\r\n });\r\n}\r\n\r\n/**\r\n * Helper function to generate critical class list map\r\n * @param jssCriticalClassList The critical class list array\r\n * @returns jssCriticalClassListMap The map of critical class list\r\n */\r\nfunction getJssCriticalClassListMap(jssCriticalClassList: [string?]) {\r\n const jssCriticalClassListMap: { [className: string]: boolean } = {};\r\n jssCriticalClassList.forEach((key) => {\r\n jssCriticalClassListMap[key] = true;\r\n jssCriticalClassListMap[key + \" - jssStyleSheet\"] = true;\r\n });\r\n\r\n return jssCriticalClassListMap;\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/// \r\n\r\nimport { MockLRUCache } from \"./ServerCacheMock\";\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\n\r\n/**\r\n * Clustered cache.\r\n * @type {LRUCache}\r\n */\r\nlet serverCache: LRUCache;\r\n\r\n/**\r\n * Initializes the serverCache with the LRUCache instance provided by the Render Service.\r\n * For testing it is initialized with a mock instance.\r\n * This needs to be called once on the server side.\r\n * @param cache\r\n */\r\nfunction initialize(cache: LRUCache): void {\r\n serverCache = cache;\r\n}\r\n\r\n/**\r\n * Reset the serverCache, clearing all data from the cache.\r\n * Currently only used for unit tests.\r\n * @returns {ServerCache}\r\n */\r\nasync function reset(): Promise {\r\n await serverCache.reset();\r\n}\r\n\r\n/**\r\n * Set cache. Update the \"recently used\"-ness of the key.\r\n * @param key Cache key to set.\r\n * @param value Cache value to set.\r\n * @param maxAge Optional maximum age in milliseconds.\r\n */\r\nasync function set(key: string, value: any, maxAge?: number): Promise {\r\n await serverCache.set(key, value, maxAge);\r\n}\r\n\r\n/**\r\n * Get cache. Update the \"recently used\"-ness of the key.\r\n * @param key Cache key to get.\r\n * @returns Cached object. If not found, return undefined.\r\n */\r\nasync function get(key: string): Promise {\r\n return await serverCache.get(key);\r\n}\r\n\r\n/**\r\n * Check if a key is in the cache, without updating the recent-ness or deleting it for being stale.\r\n * @param key Cache key to check.\r\n * @returns True if key exists.\r\n */\r\nasync function has(key: string): Promise {\r\n return await serverCache.has(key);\r\n}\r\n\r\n/**\r\n * Removes a value from the cache.\r\n * @param key Cache key to delete.\r\n * @returns Promise for completing the task\r\n */\r\nasync function del(key: string): Promise {\r\n return await serverCache.del(key);\r\n}\r\n\r\n/**\r\n * Return total quantity of objects currently in cache. Note, that stale (see options) items are returned as part of this item count.\r\n * @returns Total quantity of objects currently in cache.\r\n */\r\nasync function itemCount(): Promise {\r\n return await serverCache.itemCount();\r\n}\r\n\r\n/**\r\n * ServerCache is server side only data cache.\r\n * More detailed docs are in the following links\r\n * https://github.com/isaacs/node-lru-cache#readme\r\n * https://github.com/doublesharp/lru-cache-for-clusters-as-promised\r\n */\r\nexport const ServerCache = (!canUseDOM()) ? {\r\n initialize,\r\n reset,\r\n set,\r\n get,\r\n has,\r\n del,\r\n itemCount\r\n} : null;\r\n\r\n// Initialize ServerCache using mock cache for tests, we do it here so it works for relative imports\r\nif (global[\"TEST_ENV\"] && !canUseDOM()) {\r\n // MockLRUCache implements only a subset of LRUCache; it implements only the functions currently being used.\r\n // This was simply to avoid exhaustively reimplementing the whole API.\r\n // If more functions are utilized from the API a mock implmenting will need provided for in the MockServerCache class.\r\n // @ts-ignore\r\n ServerCache.initialize(new MockLRUCache());\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * An enumeration of all experiences ID.\r\n * By convention the experience ID ***MUST*** match exactly (including case) the class name for the experience.\r\n * NOTE: Keep this list alphabetical\r\n */\r\nexport enum ExperienceIds {\r\n animator = \"Animator\",\r\n autosCard = \"AutosCard\",\r\n backgroundGradient = \"BackgroundGradient\",\r\n backgroundImageCommon = \"BackgroundImageCommon\",\r\n backgroundImageEdge = \"BackgroundImageEdge\",\r\n backgroundImageEdgeNext = \"BackgroundImageEdgeNext\",\r\n bannerManager = \"BannerManager\",\r\n baseHeader = \"BaseHeader\",\r\n bingAnswers = \"BingAnswers\",\r\n bingCards = \"BingCardsExperience\",\r\n bingShopping = \"BingShopping\",\r\n bingShoppingLifestyleCard = \"BingShoppingLifestyleCard\",\r\n bingShoppingMeStripe = \"BingShoppingMeStripe\",\r\n bingMiniShopping = \"BingMiniShopping\",\r\n bingWebSSO = \"BingWebSSO\",\r\n blowout = \"Blowout\",\r\n breakingNews = \"BreakingNews\",\r\n cardAction = \"CardAction\",\r\n coachmark = \"Coachmark\",\r\n clarity = \"Clarity\",\r\n comments = \"Comments\",\r\n commonHeader = \"CommonHeader\",\r\n complexContentPreview = \"ComplexContentPreview\",\r\n conditionalBanner = \"ConditionalBanner\",\r\n contentPreview = \"ContentPreview\",\r\n contentProvider = \"ContentProvider\",\r\n contentRelated = \"ContentRelated\",\r\n contentActionsToolbar = \"ContentActionsToolbar\",\r\n contentSharingToolbar = \"ContentSharingToolbar\",\r\n cookieWall = \"CookieWall\",\r\n covidChatBot = \"CovidChatBot\",\r\n dailyBrief = \"DailyBrief\",\r\n desktopFeed = \"DesktopFeed\",\r\n directions = \"TrafficCard\",\r\n displayAds = \"DisplayAds\",\r\n displayAdsWithContentFallback = \"DisplayAdsWithContentFallback\",\r\n edgeHeader = \"EdgeHeader\",\r\n edgeNextPage = \"EdgeNextPage\",\r\n edgePage = \"EdgePage\",\r\n edgePageSettings = \"PageSettings\",\r\n editorsChoicePromoCard = \"EditorsChoicePromoCard\",\r\n electionDelegateCounter = \"ElectionDelegateCounter\",\r\n electionEditorsNote = \"ElectionEditorsNote\",\r\n electionResultMap = \"ElectionResultMap\",\r\n electionResultsCard = \"ElectionResultsCard\",\r\n electionVisualizer = \"ElectionVisualizer\",\r\n enterpriseComplianceBanner = \"EnterpriseComplianceBanner\",\r\n entryPoint = \"EntryPoint\",\r\n entryPointEdgeNext = \"EntryPointEdgeNext\",\r\n entryPointOffice = \"EntryPointOffice\",\r\n eventHubHeroNav = \"EventHubHeroNav\",\r\n eventHubPage = \"EventHubPage\",\r\n externalContentPreview = \"ExternalContentPreview\",\r\n externalNativeAd = \"ExternalNativeAd\",\r\n feedToggle = \"FeedToggle\",\r\n financePage = \"FinancePage\",\r\n firstPartyPage = \"FirstPartyPage\",\r\n flyoutCard = \"FlyoutCard\",\r\n feedbackDialog = \"FeedbackDialog\",\r\n feedbackLink = \"FeedbackLink\",\r\n feedEdgeNext = \"FeedEdgeNext\",\r\n financeCardCommon = \"FinanceCardCommon\",\r\n financeMarketCard = \"FinanceMarketCard\",\r\n financeIndicesCard = \"FinanceIndicesCard\",\r\n financeMarketMoversCard = \"FinanceMarketMoversCard\",\r\n financeRecentlyViewedCard = \"FinanceRecentlyViewedCard\",\r\n financeWatchlistCard = \"FinanceWatchlistCard\",\r\n financeSearchBox = \"FinanceSearchBox\",\r\n freMarketSelector = \"FreMarketSelector\",\r\n glanceCards = \"GlanceCards\",\r\n gmailEmailPreview = \"GmailEmailPreview\",\r\n headerEdgeNext = \"HeaderEdgeNext\",\r\n headerNavigationLogo = \"HeaderNavigationLogo\",\r\n hiddenContent = \"HiddenContent\",\r\n homePage = \"HomePage\",\r\n iframe = \"IFrame\",\r\n infopane = \"Infopane\",\r\n interests = \"Interests\",\r\n interestsSearch = \"InterestsSearch\",\r\n interestsV1Wrapper = \"InterestsV1Wrapper\",\r\n interestsV2 = \"InterestsV2\",\r\n languageToggle = \"LanguageToggle\",\r\n layoutSwitcher = \"LayoutSwitcher\",\r\n legacySharingToolbar = \"LegacySharingToolbar\",\r\n localNews = \"LocalNews\",\r\n localNewsViewCard = \"LocalNewsViewCard\",\r\n locationContentCard = \"LocationContentCard\",\r\n locationSelector = \"LocationSelector\",\r\n marketAggregator = \"MarketAggregator\",\r\n marketSelector = \"MarketSelector\",\r\n meControl = \"MeControl\",\r\n meStripe = \"MeStripe\",\r\n meetNow = \"MeetNow\",\r\n microsoftLogo = \"MicrosoftLogo\",\r\n microsoftNewsPage = \"MicrosoftNewsPage\",\r\n migrationConsent = \"MigrationConsent\",\r\n miniApps = \"MiniApps\",\r\n mmxPage = \"MMXPage\",\r\n mnsCreatorDashboard = \"MnsCreatorDashboard\",\r\n moneyCard = \"MoneyCard\",\r\n mobileFeed = \"MobileFeed\",\r\n msnSettingMenu = \"MsnSettingMenu\",\r\n msRewards = \"MsRewards\",\r\n myBriefRiverCard = \"MyBriefRiverCard\",\r\n nativeAd = \"NativeAd\",\r\n newsbarFeed = \"NewsbarFeed\",\r\n notificationBell = \"NotificationBell\",\r\n ocvFeedbackData = \"OcvFeedbackData\",\r\n office = \"Office\",\r\n officeContainer = \"OfficeContainer\",\r\n officeDocumentCard = \"OfficeDocumentCard\",\r\n officeDocumentsTable = \"OfficeDocumentsTable\",\r\n oneFooter = \"OneFooter\",\r\n overlay = \"Overlay\",\r\n outlookEmailPreview = \"OutlookEmailPreview\",\r\n pageRefresh = \"PageRefresh\",\r\n partnerWidget = \"PartnerWidget\",\r\n pivotContent = \"PivotContent\",\r\n pivotContentV2 = \"PivotContentV2\",\r\n pivotHover = \"PivotHover\",\r\n pivotsNav = \"PivotsNav\",\r\n pivotsNavV2 = \"PivotsNavV2\",\r\n pollsCard = \"PollsCard\",\r\n poweredByLegend = \"PoweredbyLegend\",\r\n proactiveCanvas = \"ProactiveCanvas\",\r\n promoBanner = \"PromoBanner\",\r\n publishersManagement = \"PublishersManagement\",\r\n recommendedCard = \"RecommendedCard\",\r\n recommendedDocuments = \"RecommendedDocuments\",\r\n recommendedSearch = \"RecommendedSearch\",\r\n recommendedSearchBelowSearchBox = \"RecommendedSearchBelowSearchBox\",\r\n recommendedSearchCarousel = \"RecommendedSearchCarousel\",\r\n recommendedSites = \"RecommendedSites\",\r\n recommendedTopics = \"RecommendedTopics\",\r\n relatedSearchesCard = \"RelatedSearchesCard\",\r\n rightRail = \"RightRail\",\r\n rightRailCarousel = \"RightRailCarousel\",\r\n river = \"River\",\r\n riverPlaceholder = \"RiverPlaceholder\",\r\n searchBoxCommon = \"SearchBoxCommon\",\r\n searchBoxEdge = \"SearchBoxEdge\",\r\n searchBoxEdgeNext = \"SearchBoxEdgeNext\",\r\n searchHistoryCommon = \"SearchHistoryCommon\",\r\n searchHistoryEdge = \"SearchHistoryEdge\",\r\n searchHistoryEdgenext = \"SearchHistoryEdgenext\",\r\n sentimentBarChart = \"SentimentBarChart\",\r\n sentimentLineChart = \"SentimentLineChart\",\r\n sentimentMap = \"SentimentMap\",\r\n sentimentResultCard = \"SentimentResultCard\",\r\n serviceWaffle = \"ServiceWaffle\",\r\n settingsDialogEdgeNext = \"SettingsDialogEdgeNext\",\r\n settingsDialogMsNews = \"SettingsDialogMsNews\",\r\n sharedLinksCard = \"SharedLinksCard\",\r\n sharedState = \"SharedState\",\r\n sharePointSitesTable= \"SharePointSitesTable\",\r\n shopContentCarousel = \"ShopContentCarousel\",\r\n shoppingCarousel = \"ShoppingCarousel\",\r\n shoppingContentCard = \"ShoppingContentCard\",\r\n shoppingSmartList = \"ShoppingSmartList\",\r\n showFeed = \"ShowFeed\",\r\n showFeedPill = \"ShowFeedPill\",\r\n simpleBanner = \"SimpleBanner\",\r\n slideShow = \"SlideShow\",\r\n smartList = \"SmartList\",\r\n social = \"Social\",\r\n sportsCard = \"SportsCard\",\r\n spotlight = \"Spotlight\",\r\n spotlightPreview = \"SpotlightPreview\",\r\n starterKit = \"StarterKit\",\r\n storyPage = \"StoryPage\",\r\n storySnippet = \"StorySnippet\",\r\n stripe = \"Stripe\",\r\n stripeView = \"StripeView\",\r\n superAppPage = \"SuperAppHomepage\",\r\n superappHeaderData = \"SuperappHeaderData\",\r\n tabbedInfopane = \"TabbedInfopane\",\r\n tabbedInfopaneTabPreview = \"TabbedInfopaneTabPreview\",\r\n taboolaRiver = \"TaboolaRiver\",\r\n tasksCard = \"TasksCard\",\r\n topicsHub = \"TopicsHub\",\r\n topSites = \"TopSites\",\r\n topSitesCommon = \"TopSitesCommon\",\r\n topSitesEdge = \"TopSitesEdge\",\r\n topSitesEdgeNext = \"TopSitesEdgeNext\",\r\n trafficCard = \"TrafficCard\",\r\n trafficMap = \"TrafficMap\",\r\n trafficPage = \"TrafficPage\",\r\n trendingNews = \"TrendingNews\",\r\n trendingNow = \"TrendingNow\",\r\n userInitiatedPageRefresh = \"UserInitiatedPageRefresh\",\r\n userProfileDisplay = \"UserProfileDisplay\",\r\n videoCard = \"VideoCard\",\r\n videoContent = \"VideoContent\",\r\n videoList = \"VideoList\",\r\n viewsArticle = \"ViewsArticle\",\r\n viewsContentHeader = \"ViewsContentHeader\",\r\n viewsGallery = \"ViewsGallery\",\r\n viewsPaddles = \"ViewsPaddles\",\r\n watchlistCard = \"WatchlistCard\",\r\n weatherCard = \"WeatherCard\",\r\n weatherData = \"WeatherData\",\r\n weatherLocationSearch = \"WeatherLocationSearch\",\r\n weatherMap = \"WeatherMap\",\r\n weatherOverview = \"WeatherOverview\",\r\n weatherPage = \"WeatherPage\",\r\n weatherTodayCard = \"WeatherTodayCard\",\r\n weatherTodayMini = \"WeatherTodayMini\",\r\n welcomeGreeting = \"WelcomeGreeting\",\r\n windowsPage = \"WindowsPage\",\r\n xfeed = \"Xfeed\"\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { DynamicReducer, IReducer } from \"../reducers\";\r\nimport { PerfTimeline, tryGetPerfTimeline } from \"@msnews/diagnostics\";\r\nimport { Subspace, subspace } from \"redux-subspace\";\r\nimport { merge as _merge, set as _set } from \"lodash-es\";\r\n\r\nimport { ConnectorConstants } from \"../constants/ConnectorConstants\";\r\nimport { IDataConnector } from \"./IDataConnector\";\r\nimport { IRequestContext } from \"@msnews/core\";\r\nimport { Store } from \"redux\";\r\n\r\n/**\r\n * Base class for data connectors.\r\n * A Data connector is a the base for all connectors in a msnews-experiences-redux application. The data connector has\r\n * the methods and properties that manage a state object, which can either be a sub-state within the app, or the full\r\n * application state tree\r\n * @class\r\n */\r\nexport class DataConnector implements IDataConnector {\r\n /**\r\n * The Redux subspace store for this connector\r\n * @type {Subspace}\r\n */\r\n protected _subspace: Subspace;\r\n\r\n /**\r\n * The full namespace, including all of the ancestors, in dotted notation:\r\n * i.e.: parent.child.grandchild\r\n */\r\n private _fullNamespace: string;\r\n\r\n /**\r\n * The perf timeline object for this connector\r\n */\r\n private _perfTimeline: PerfTimeline;\r\n\r\n /**\r\n * The config href for the connector\r\n */\r\n private _configHref: string;\r\n\r\n /**\r\n * Gets the Redux store for this data connector instance, which is a subspace within the parent state\r\n * @property\r\n * @returns {Store} The state subspace for this connector, which looks like a Redux Store\r\n */\r\n public get store(): Store {\r\n return this._subspace;\r\n }\r\n\r\n /**\r\n * Gets the full namespace for this connector\r\n * @property\r\n * @returns {string} The connector's full namespace\r\n */\r\n public get fullNamespace(): string {\r\n return this._fullNamespace;\r\n }\r\n\r\n /**\r\n * The perf timeline object for this connector\r\n */\r\n public get perfTimeline(): PerfTimeline {\r\n return this._perfTimeline;\r\n }\r\n\r\n /**\r\n * Get the config href for the connector\r\n */\r\n public get configHref(): string {\r\n return this._configHref;\r\n }\r\n /**\r\n * Set the config href for the connector\r\n */\r\n public set configHref(href: string) {\r\n this._configHref = href;\r\n }\r\n\r\n /**\r\n * Construct a new Data connector\r\n * @constructor\r\n * @param { string } namespace The redux subspace namespace for the connector\r\n * @param { string } parentNamespace The redux subspace namespace for the parent connector, if it exists\r\n * @param { DynamicReducer } rootReducer The root reducer for the Application\r\n * @param { IReducer } reducer The reducer for this connector instance\r\n * @param { Store} parentStore The parent store (or redux subspace) that this connector will be a subspace within\r\n * @param { TConfig } config Optional param containing the config for the connector\r\n * @param { boolean } isGlobal Optional param to set if the connector should be global or not. Defaults to false\r\n */\r\n public constructor(\r\n public readonly namespace: string,\r\n public readonly parentNamespace: string,\r\n public readonly rootReducer: DynamicReducer,\r\n public readonly reducer: IReducer,\r\n parentStore: Store,\r\n public config?: TConfig,\r\n public requestContext?: IRequestContext,\r\n public readonly isGlobal: boolean = false) {\r\n // Setup the full namespace. This namespace will be used as the parentNamespace to any connectors created as children of this\r\n // connector. It is the \"dotted\" concatenation of the parentNamespace + namespace, which represents the key into the state tree for the child connectors\r\n this._fullNamespace = (typeof parentNamespace !== \"undefined\" && parentNamespace !== \"\") ? parentNamespace + \".\" + namespace : namespace;\r\n\r\n // setup the sub-spaced store with a state selector that is bound to this connector's instance, and returns the inner state object (TState) for this connector\r\n this.selectState = this.selectState.bind(this);\r\n this._subspace = subspace(this.selectState, this.namespace)(parentStore);\r\n\r\n // try to create a perf timeline for this connector\r\n this._perfTimeline = this.tryGetPerfTimeline(namespace);\r\n\r\n rootReducer.addSubReducerForConnector(this);\r\n }\r\n\r\n /**\r\n * Gets the current state of the connector. The connector's state (TState) is the sub-portion of the returned state object with the postfix \"State\"\r\n * This is because the overall subspace state for the connector will contain the children states as well\r\n * @method\r\n * @returns {TState} The current state of the component.\r\n */\r\n public getCurrentState(): TState {\r\n // Get the subspace state for this connector. It will be something like:\r\n // { _@STATE@_ : { TState }}, where the subspace selector will already have been used to get the namespaced substate\r\n const wrappedState: TState = this.store.getState();\r\n\r\n // Get the currentState, that will be returned. By default it wil be just the state for this controller\r\n const connectorState = wrappedState[ConnectorConstants.connectorStateKey];\r\n\r\n // If the connector's state is not global, then check to see if there are any global connectors it needs to be merged with\r\n // If the connector is global, then its state is just returned, otherwise we would have an infinte loop merging a global connectors's\r\n // state with itself.\r\n if (!this.isGlobal) {\r\n // Get the list of global connectors\r\n const globalConnectors = this.rootReducer.globalConnectors();\r\n\r\n // See if there are any global connectors that need to be merged in.\r\n if (globalConnectors.length !== 0) {\r\n // For each global connector, merge it's state into the final result, using the global connector's namespace\r\n // So the resulting state will be:\r\n // { globalConnectorNamespace: { state }, TSTATE }}\r\n globalConnectors.forEach(globalConnector => {\r\n _set(connectorState, globalConnector.namespace, globalConnector.getCurrentState());\r\n });\r\n }\r\n }\r\n return connectorState;\r\n }\r\n\r\n /**\r\n * The method is called as the application is starting up, components are created.\r\n * The method can be used by connectors to perform one time initialization functions\r\n * This method needs to be overridden if your connector has specific startup needs\r\n * @method\r\n * @returns void\r\n */\r\n public onApplicationStart(): void { /** no-op */ }\r\n\r\n /**\r\n * The subspace selector that gets the portion of the state tree that is for this connector\r\n * @param state The parent state object that contains the subspace\r\n */\r\n private selectState(state: TParentState): TState {\r\n return (state[this.namespace]);\r\n }\r\n\r\n /**\r\n * Attempts to create the {PerfTimeline} object for this connector\r\n */\r\n private tryGetPerfTimeline(namespace: string): PerfTimeline {\r\n\r\n const namespaceParts = namespace.split(\"_\");\r\n const [connectorType] = namespaceParts;\r\n\r\n // there may not be any instance id -- in which case this would simply be the connector type.\r\n const instanceId = namespaceParts[namespaceParts.length - 1];\r\n\r\n // get the perf timeline object if applicable to the current experience\r\n return tryGetPerfTimeline(connectorType, instanceId);\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * The \"DeferralHandlerSignature\" is a callback signature is called used when an experience is deferred on the callback to be resolved.\r\n * This callback should return a Promise that resolves with a boolean.\r\n */\r\nexport type DeferralHandlerSignature = () => Promise;\r\n\r\n/**\r\n * Deferral type of an experience\r\n */\r\nexport enum DeferralEventType {\r\n /**\r\n * Standard Deferral Event Type based on page/experience lifecycle based events like AboveTheFoldReady or other experience available\r\n */\r\n StandardEventBasedDeferral = 0,\r\n\r\n /**\r\n * Custom Deferral Event Type based like belowTheFoldTransitionStart which hoooked to work with UI events like intersectionObserver.\r\n */\r\n CustomEventBasedDeferral = 1\r\n}\r\n\r\n/**\r\n * Type to resolve deferral info to calling code\r\n */\r\nexport interface ExperienceDeferralMetadata {\r\n /**\r\n * Deferral type of an experience\r\n */\r\n deferralType: DeferralEventType;\r\n\r\n /**\r\n * A callback that resolves with a bool to specify when the experience is ready to load/render\r\n */\r\n shouldResolve: DeferralHandlerSignature\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Defines valid milestone event types\r\n */\r\nexport enum ExperienceMilestoneEventTypes {\r\n /**\r\n * Fired when all the initial DOM elements for the experience have been added (i.e. onComponentDidMount)\r\n * The DOM may not be completely rendered by the browser when then milestone is reached\r\n */\r\n domComplete,\r\n\r\n /**\r\n * Fired if the experience hits an unrecoverable error\r\n */\r\n error,\r\n\r\n /**\r\n * Fired when the experience is initialized\r\n */\r\n initialized,\r\n\r\n /**\r\n * Fired when the experience is initially rendered. This is after the browser has processed all of the DOM elements that were\r\n * added in the experience render function.\r\n */\r\n rendered,\r\n\r\n /**\r\n * Fired when the experience's stale state revalidation completes.\r\n */\r\n staleRevalidationComplete,\r\n\r\n /**\r\n * Fired when the experience is visually ready, which is a business metric and defined in the MSNews Performance Metrics documentation.\r\n */\r\n visuallyReady\r\n}\r\n","\r\n// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Enum to describe screen width(column types)\r\n */\r\nexport enum ScreenWidth {\r\n OneColumn = \"OneColumn\",\r\n TwoColumn = \"TwoColumn\",\r\n ThreeColumn = \"ThreeColumn\",\r\n FourColumn = \"FourColumn\",\r\n FiveColumn = \"FiveColumn\",\r\n Any = \"Any\"\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nexport enum ExperienceCompositionTypes {\r\n grid = \"grid\",\r\n horizontalStack = \"horizontalStack\",\r\n layout = \"layout\",\r\n verticalStack = \"verticalStack\",\r\n customExperience = \"customExperience\"\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * An enumeration of possible children types that can be rendered into a layout column\r\n */\r\nexport enum ChildrenTypes {\r\n /**\r\n * A Fast DNA ActionTrigger component\r\n */\r\n actionTrigger = \"ActionTrigger\",\r\n /**\r\n * A Fast DNA Button component\r\n */\r\n button = \"Button\",\r\n\r\n /**\r\n * A Fast DNA Heading component\r\n */\r\n heading = \"Heading\",\r\n\r\n /**\r\n * A Peregrine Experience\r\n */\r\n peregrineExperience = \"PeregrineExperience\",\r\n\r\n /**\r\n * A Fast DNA Typography component\r\n */\r\n typography = \"Typography\"\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nexport namespace DynamicBundles {\r\n const dynamicBundles: { [experienceName: string]: () => Promise } = {};\r\n\r\n /**\r\n * lazy load the experience\r\n *\r\n * @param experienceName - the experience name\r\n * @return {Promise} - the experience wrapped by the promise\r\n */\r\n export const loadExperience = async (experienceName: string) => {\r\n const bundle = dynamicBundles[experienceName];\r\n if (!bundle) {\r\n throw new Error(`Attempted to load unknown dynamic bundle \"${experienceName}\". Make sure it's a registered dynamic experience bundle.`);\r\n }\r\n return bundle();\r\n };\r\n\r\n /**\r\n * register the experience for lazy loading\r\n *\r\n * @param experienceName - the experience name\r\n * @param es6Import - the import(\"@msnews/your/experience/path\")\r\n */\r\n export const registerExperience = (experienceName: string, es6Import: () => Promise) => {\r\n dynamicBundles[experienceName] = es6Import;\r\n };\r\n\r\n /**\r\n * check if an experience is registered\r\n * @param experienceName - the experience name\r\n * @return {boolean} - return true if experience is already registered, otherwise false\r\n */\r\n export const hasExperienceRegistered = (experienceName: string): boolean => {\r\n return !!dynamicBundles[experienceName];\r\n };\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ExperienceLoadingState } from \"./ExperienceLoadingState\";\r\n\r\n/**\r\n * Defines custom deferral event types which is not part of page/experience lifecycle event types\r\n */\r\nexport enum CustomDeferralEventTypes {\r\n\r\n /**\r\n * The page level milestone when experiences outside the viewport are transitioning into viewport\r\n */\r\n belowTheFoldTransitionStart\r\n}\r\n\r\n/**\r\n * Defines valid deferral events used during milestone tracking\r\n * The event types should be mapped with loading types so that they have the exact same numeric value.\r\n */\r\nexport enum ExperienceDeferralEventTypes {\r\n\r\n /**\r\n * The loaded milestone of dependent experience\r\n */\r\n loaded = ExperienceLoadingState.loaded,\r\n\r\n /**\r\n * The rendered milestone of dependent experience\r\n */\r\n rendered = ExperienceLoadingState.rendered,\r\n\r\n /**\r\n * The domComplete milestone of dependent experience\r\n */\r\n domComplete = ExperienceLoadingState.domComplete,\r\n\r\n /**\r\n * The visuallyReady milestone of dependent experience\r\n */\r\n visuallyReady = ExperienceLoadingState.visuallyReady,\r\n\r\n /**\r\n * The page level milestone when experiences in viewport are visuallyReady\r\n */\r\n aboveTheFoldVisuallyReady,\r\n\r\n /**\r\n * The page level milestone when experiences outside the viewport are transitioning into viewport\r\n */\r\n belowTheFoldTransitionStart = CustomDeferralEventTypes.belowTheFoldTransitionStart\r\n}\r\n\r\n/**\r\n * Helper to lookup the equivalent deferrel event type given the experience loadings state\r\n */\r\nexport const ExperienceLoadingStateToDeferralEventType = new Map([\r\n [ExperienceLoadingState.loaded, ExperienceDeferralEventTypes.loaded],\r\n [ExperienceLoadingState.rendered, ExperienceDeferralEventTypes.rendered],\r\n [ExperienceLoadingState.domComplete, ExperienceDeferralEventTypes.domComplete],\r\n [ExperienceLoadingState.visuallyReady, ExperienceDeferralEventTypes.visuallyReady]\r\n]);","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ExperienceDeferralEventTypes, ExperienceLoadingState } from \"../data-model\";\r\n\r\nimport { registerResetCallback } from \"@msnews/core\";\r\n\r\n/**\r\n * Identifies a referenced experience and its dependents\r\n */\r\nexport interface ExperienceDependents {\r\n /**\r\n * Determines the state of deferral identifier experience.\r\n */\r\n currentState: ExperienceLoadingState;\r\n\r\n /**\r\n * The dependent set of experiences and its associated state mapped to a deferred event type.\r\n * An experience moves from deferred to resolvedForLoad or resolvedForRender state when deferral identifier experienceType/Group currentState matches deferred state.\r\n */\r\n referencedDependentsDeferralMap: Map>\r\n}\r\n\r\n// Keeps track of Experience Identifier to its referenced dependents mapping for loadAfter/renderAfter scenario\r\n// Experience Identifier, acts as a reference to resolve its dependents.\r\n// The key (experienceIdentifier) should be either experienceType or experienceGroup\r\nexport let experienceDeferralDependencyMap: Map = new Map();\r\n\r\n/**\r\n * Register a callback to reset the experienceDeferralDependencyMap.\r\n * The callback is registered once when the module is loaded and invoked once on the server side at the beginning of each request.\r\n */\r\nregisterResetCallback(() => {\r\n experienceDeferralDependencyMap = new Map();\r\n});\r\n\r\n/**\r\n * Checks if experience's dependency is resolved\r\n * @returns true if dependent experience has been resolved.\r\n * @param experienceDependency - dependent experience\r\n * @param deferralEventType - deferral EventType\r\n */\r\nexport function isExperienceDependencyResolved(experienceDependency: string, deferralEventType: ExperienceDeferralEventTypes): boolean {\r\n\r\n const dependents = experienceDeferralDependencyMap.get(experienceDependency);\r\n return !dependents\r\n || dependents.currentState >= deferralEventType;\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { CustomDeferralEventTypes, DeferralEventType, ExperienceDeferralEventTypes, ExperienceDeferralInfo, ExperienceDeferralMetadata, ExperienceLoadingState, ExperienceMilestoneEventTypes } from \"./data-model\";\r\nimport { IActionPayload, PageBase } from \"@msnews/experiences-redux\";\r\nimport { MilestoneDataActions, UpdateExperienceCurrentStateArgs, UpdateExperienceDeferralArgs, UpdateTimingArgs } from \"./MilestoneData.actions\";\r\nimport { defaultInstanceKeyName, defaultTimeValue } from \"./MilestoneData.constants\";\r\n\r\nimport { ConnectorNamespaces } from \"@msnews/experiences-constants\";\r\nimport { ExperienceInstanceMilestoneModel } from \"./data-model/ExperienceInstanceMilestoneModel\";\r\nimport { MilestoneDataConnector } from \"./MilestoneData.connector\";\r\nimport { MilestonePluginEvents } from \"./data-model/MilestonePluginEvents\";\r\nimport { PageRevealRegistrationInterface } from \"./data-model/PageRevealRegistrationInterface\";\r\nimport { headData } from \"@msnews/core\";\r\nimport { isExperienceDependencyResolved } from \"./data-management/ExperienceDeferralDependencyTrackerState\";\r\nimport { pluginUtils } from \"./utils/MilestonePluginUtils\";\r\n\r\n/**\r\n * Helper method to get the milestone data connector instance.\r\n * @returns Milestone data connector promise.\r\n */\r\nexport function getMilestoneDataConnector(): MilestoneDataConnector {\r\n return PageBase.getInstance().rootReducer.connector(\r\n ConnectorNamespaces.MilestoneData\r\n ) as MilestoneDataConnector;\r\n}\r\n\r\n/**\r\n * Helper method to get default instance of an experience.\r\n * @returns Experience Milestone instance data.\r\n */\r\nexport function getDefaultExperienceInstance(\r\n experienceType: string\r\n): ExperienceInstanceMilestoneModel {\r\n const connector = getMilestoneDataConnector();\r\n\r\n if (!connector) {\r\n return;\r\n }\r\n\r\n const milestones = connector.getCurrentState().perExperienceMilestones;\r\n const experience = milestones && milestones.get(experienceType);\r\n let instance: ExperienceInstanceMilestoneModel;\r\n\r\n if (experience) {\r\n instance = experience.perInstanceMilestones.get(defaultInstanceKeyName);\r\n }\r\n\r\n return instance;\r\n}\r\n\r\n/**\r\n * returns promise based experience load delegate, which resolves when experience dependent event is fired.\r\n * @returns A callback promise which resolves to boolean when associated experience is ready to be loaded\r\n * If null is returned experience is not deferred and should be loaded/rendered right away.\r\n */\r\nexport function getExperienceLoadDelegate(\r\n experienceType: string\r\n): ExperienceDeferralMetadata {\r\n\r\n const instance: ExperienceInstanceMilestoneModel = getDefaultExperienceInstance(experienceType);\r\n\r\n // return null if dependent deferral event has already been fired\r\n if (!instance || getDeferralLoadEventReadyState(instance)) {\r\n return null;\r\n }\r\n\r\n if (instance.shouldLoad && instance.loadAfter) {\r\n\r\n const deferralEventType = getDeferralEventMetadata(instance.loadAfter);\r\n return { deferralType: deferralEventType, shouldResolve: instance.shouldLoad };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * returns a promise that is resolved when\r\n * Milestone data connector was not initialized\r\n * Milestone data connector has already fired the above the fold visual ready action\r\n * Milestone data connector hasn't fired above the fold visual ready action so an observer is\r\n * set on the action to resolve the promise when that callback is invoked\r\n */\r\nexport function waitForAboveTheFoldVisuallyReadyAsync(): Promise {\r\n const milestoneDataConnector = getMilestoneDataConnector();\r\n\r\n if (!milestoneDataConnector) {\r\n return Promise.resolve();\r\n }\r\n\r\n if (isAboveTheFoldVisuallyReady()) {\r\n return Promise.resolve();\r\n }\r\n\r\n return new Promise(resolve => {\r\n MilestoneDataActions.updateAboveTheFoldVisuallyReady.registerObserver(((actionPayload: IActionPayload) => {\r\n resolve();\r\n }));\r\n });\r\n}\r\n\r\n/**\r\n * returns a promise that is resolved when\r\n * Milestone data connector was not initialized\r\n * Milestone data connector has already fired the page reveal started action\r\n * Milestone data connector hasn't fired page reveal started action so an observer is\r\n * set on the action to resolve the promise when that callback is invoked\r\n */\r\nexport function requestPageRevealStartedAsync(): Promise {\r\n const milestoneDataConnector = getMilestoneDataConnector();\r\n\r\n if (!headData.IsPrerender || !milestoneDataConnector) {\r\n return Promise.resolve();\r\n }\r\n\r\n if (isPageRevealStarted()) {\r\n return Promise.resolve();\r\n }\r\n\r\n return new Promise(resolve => {\r\n MilestoneDataActions.updatePageRevealStart.registerObserver(((actionPayload: IActionPayload) => {\r\n resolve();\r\n }));\r\n });\r\n}\r\n\r\n/**\r\n * returns a promise that is resolved when\r\n * Milestone data connector was not initialized\r\n * Milestone data connector has already fired the page reveal completed action\r\n * Milestone data connector hasn't fired page reveal completed action so an observer is\r\n * set on the action to resolve the promise when that callback is invoked\r\n */\r\nexport function requestPageRevealCompletedAsync(): Promise {\r\n const milestoneDataConnector = getMilestoneDataConnector();\r\n\r\n if (!headData.IsPrerender || !milestoneDataConnector) {\r\n return Promise.resolve();\r\n }\r\n\r\n if (isPageRevealCompleted()) {\r\n return Promise.resolve();\r\n }\r\n\r\n return new Promise(resolve => {\r\n MilestoneDataActions.updatePageRevealComplete.registerObserver(((actionPayload: IActionPayload) => {\r\n resolve();\r\n }));\r\n });\r\n}\r\n\r\n/**\r\n * returns a promise that is resolved when\r\n * Milestone data connector was not initialized\r\n * Milestone data connector hasn't fired page reveal started action so an observer is\r\n * set on the action to resolve the promise when that callback is invoked\r\n */\r\nexport function pageRevealStartedObserver(): Promise {\r\n const milestoneDataConnector = getMilestoneDataConnector();\r\n\r\n if (!milestoneDataConnector) {\r\n return Promise.resolve();\r\n }\r\n\r\n return new Promise(resolve => {\r\n MilestoneDataActions.updatePageRevealStart.registerObserver(((actionPayload: IActionPayload) => {\r\n resolve();\r\n }));\r\n });\r\n}\r\n\r\n/**\r\n * returns promise based experience render delegate, which resolves when experience dependent event is fired.\r\n * @returns A callback promise which resolves to boolean when associated experience is ready to be rendered.\r\n * If null is returned experience is not deferred and should be loaded/rendered right away.\r\n */\r\nexport function getExperienceRenderDelegate(\r\n experienceType: string\r\n): ExperienceDeferralMetadata {\r\n\r\n const instance: ExperienceInstanceMilestoneModel = getDefaultExperienceInstance(experienceType);\r\n\r\n // return null if dependent deferral event has already been fired\r\n if (!instance || getDeferralRenderEventReadyState(instance)) {\r\n return null;\r\n }\r\n\r\n if (instance.shouldRender && instance.renderAfter) {\r\n\r\n const deferralEventType = getDeferralEventMetadata(instance.renderAfter);\r\n return { deferralType: deferralEventType, shouldResolve: instance.shouldRender };\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/**\r\n * Execute milestone event hooks\r\n */\r\nexport async function executeMilestoneEventPlugins(eventType: MilestonePluginEvents): Promise {\r\n\r\n const connector = getMilestoneDataConnector();\r\n\r\n if (!connector) {\r\n return;\r\n }\r\n\r\n const plugins = connector.getCurrentState().plugins;\r\n\r\n if (!plugins || plugins.length === 0) {\r\n return;\r\n }\r\n\r\n const filteredPlugins = pluginUtils.filter(plugins, eventType);\r\n\r\n for (const plugin of filteredPlugins) {\r\n if (plugin[eventType] !== undefined) {\r\n await plugin[eventType].call(plugin);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Return dependent deferral event ready state\r\n * @param instance - Experience instance\r\n */\r\nfunction getDeferralLoadEventReadyState(instance: ExperienceInstanceMilestoneModel): boolean {\r\n\r\n let deferralEventReady: boolean;\r\n\r\n switch (instance.loadAfter.eventType) {\r\n case ExperienceDeferralEventTypes.aboveTheFoldVisuallyReady:\r\n deferralEventReady = isAboveTheFoldVisuallyReady();\r\n break;\r\n\r\n case ExperienceDeferralEventTypes.belowTheFoldTransitionStart:\r\n deferralEventReady = isBelowTheFoldTransitionStarted();\r\n break;\r\n\r\n default:\r\n deferralEventReady = isExperienceDependencyResolved(instance.loadAfter.experienceType, instance.loadAfter.eventType);\r\n }\r\n\r\n return deferralEventReady;\r\n}\r\n\r\n/**\r\n * Return dependent deferral event ready state\r\n * @param instance - Experience instance\r\n */\r\nfunction getDeferralRenderEventReadyState(instance: ExperienceInstanceMilestoneModel): boolean {\r\n\r\n let deferralEventReady: boolean;\r\n\r\n switch (instance.renderAfter.eventType) {\r\n case ExperienceDeferralEventTypes.aboveTheFoldVisuallyReady:\r\n deferralEventReady = isAboveTheFoldVisuallyReady();\r\n break;\r\n\r\n case ExperienceDeferralEventTypes.belowTheFoldTransitionStart:\r\n deferralEventReady = isBelowTheFoldTransitionStarted();\r\n break;\r\n\r\n default:\r\n deferralEventReady = isExperienceDependencyResolved(instance.loadAfter.experienceType, instance.renderAfter.eventType);\r\n }\r\n\r\n return deferralEventReady;\r\n}\r\n\r\n/**\r\n * Returns true if above the fold is ready\r\n */\r\nfunction isAboveTheFoldVisuallyReady(): boolean {\r\n const connector = getMilestoneDataConnector();\r\n\r\n if (!connector) {\r\n return false;\r\n }\r\n\r\n const { aboveTheFoldVisuallyReady } = connector.getCurrentState();\r\n return Boolean(\r\n aboveTheFoldVisuallyReady\r\n && aboveTheFoldVisuallyReady.endTime !== defaultTimeValue\r\n );\r\n}\r\n\r\n/**\r\n * Returns true if page reveal has started\r\n */\r\nfunction isPageRevealStarted(): boolean {\r\n const connector = getMilestoneDataConnector();\r\n\r\n if (!connector) {\r\n return false;\r\n }\r\n\r\n const { pageReveal } = connector.getCurrentState();\r\n return Boolean(\r\n pageReveal\r\n && pageReveal.startTime!== defaultTimeValue\r\n );\r\n}\r\n\r\n/**\r\n * Returns true if page reveal has completed\r\n */\r\nfunction isPageRevealCompleted(): boolean {\r\n const connector = getMilestoneDataConnector();\r\n\r\n if (!connector) {\r\n return false;\r\n }\r\n\r\n const { pageReveal } = connector.getCurrentState();\r\n return Boolean(\r\n pageReveal\r\n && pageReveal.endTime!== defaultTimeValue\r\n );\r\n}\r\n\r\n/**\r\n * Returns true if below the fold transition has started\r\n */\r\nfunction isBelowTheFoldTransitionStarted(): boolean {\r\n const connector = getMilestoneDataConnector();\r\n\r\n if (!connector) {\r\n return false;\r\n }\r\n\r\n return connector.getCurrentState().belowTheFoldTransitionStart;\r\n}\r\n\r\n/**\r\n * Update deferral event metadata\r\n * @param deferralInfo - Tracks deferral information used by an experience to determine when it should load/render\r\n * @returns - DeferralEventType, this can be either standard or custom depending upon what type of deferral has been used for experience deferral\r\n */\r\nfunction getDeferralEventMetadata(deferralInfo: ExperienceDeferralInfo): DeferralEventType {\r\n return deferralInfo.eventType in CustomDeferralEventTypes\r\n ? DeferralEventType.CustomEventBasedDeferral\r\n : DeferralEventType.StandardEventBasedDeferral;\r\n}\r\n\r\n/**\r\n * Helper to create deferral info\r\n * @param deferralInfo - Tracks deferral information used by an experience to determine when it should load/render\r\n * @param experienceType - Experience Type - Defines an experience\r\n * @param experienceGroup - Associated Experience Group\r\n * @param experienceInstance - Defines an instance of the Experience\r\n */\r\nexport function createDeferralInfo(\r\n deferralInfo: ExperienceDeferralInfo,\r\n experienceType: string,\r\n experienceGroup?: string,\r\n experienceInstance?: string\r\n): UpdateExperienceDeferralArgs {\r\n\r\n return {\r\n deferralInfo,\r\n experienceType,\r\n experienceGroup,\r\n experienceInstance\r\n };\r\n}\r\n\r\n/**\r\n * Helper to create experience state update arguments.\r\n * @param experienceType - Experience Type - Defines an experience\r\n * @param currentState - Current Milestone of the experience e.g initialized, loaded, deferred etc\r\n * @param experienceGroup - Associated Experience Group\r\n * @param experienceInstance - Defines an instance of the Experience\r\n */\r\nexport function createExperienceStateUpdate(\r\n experienceType: string,\r\n currentState: ExperienceLoadingState,\r\n experienceGroup?: string,\r\n experienceInstance?: string\r\n): UpdateExperienceCurrentStateArgs {\r\n\r\n return {\r\n experienceType,\r\n currentState,\r\n experienceGroup,\r\n experienceInstance\r\n };\r\n}\r\n\r\n/**\r\n * Creates a timing update arguments\r\n * @param experienceType - Experience Type - Defines an experience\r\n * @param experienceGroup - Associated Experience Group\r\n * @param experienceInstance - Defines an instance of the Experience\r\n * @param startTime - start time fo the milestone e.g. startTime of loaded milestone\r\n * @param endTime - end time fo the milestone e.g. endTime of loaded milestone\r\n */\r\nexport function createTimingUpdate(\r\n experienceType: string,\r\n experienceGroup?: string,\r\n experienceInstance?: string,\r\n startTime?: number,\r\n endTime?: number\r\n): UpdateTimingArgs {\r\n\r\n return {\r\n experienceType,\r\n experienceGroup,\r\n experienceInstance,\r\n startTime,\r\n endTime\r\n };\r\n}\r\n\r\n/**\r\n * helper method to register experience for page reveal\r\n * @param pageRevealExperienceInfo - page reveal registration data for experience\r\n */\r\nexport function registerExperienceForPageReveal(pageRevealExperienceInfo: PageRevealRegistrationInterface): void {\r\n const connector = getMilestoneDataConnector();\r\n if (!connector || !pageRevealExperienceInfo) {\r\n return;\r\n }\r\n\r\n MilestoneDataActions.registerExperienceForPageReveal.getActionSender(connector).send(pageRevealExperienceInfo);\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Default key value for looking up experience instances\r\n */\r\nexport const defaultInstanceKeyName = \"default\";\r\n\r\n/**\r\n * Default time value for start/end time\r\n */\r\nexport const defaultTimeValue = -1;\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { getMuidCookie, headData, localStorage } from \"@msnews/core\";\r\nimport { prerenderedPageAge, prerenderedPageReload } from \"./PageLifecycleConstants\";\r\n\r\nimport { PageInvalidationReasons } from \"./PageInvalidationReasons\";\r\nimport { Telemetry } from \"@msnews/telemetry-contracts\";\r\nimport { forceReloadFlagName } from \"./PageLifecycleConstants\";\r\nimport { logger } from \"@msnews/diagnostics\";\r\nimport { refreshPage } from \"@msnews/experiences-base\";\r\n\r\nlet muidAtLoad;\r\nlet invalidationReason: PageInvalidationReasons;\r\n/** The HTML element which is being used as the overlay element */\r\nlet overlayElement;\r\nlet overlayTimeout;\r\n\r\n/**\r\n * Init Prerender\r\n */\r\nexport function initPrerender() {\r\n muidAtLoad = getMuidCookie() || \"\";\r\n overlayElement = document.createElement(\"div\");\r\n}\r\n\r\n/**\r\n * return true if prerendered page is visible else false0\r\n */\r\nexport function isPrerenderVisible(): boolean {\r\n if (headData.IsPrerender && document.visibilityState === \"visible\") {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Process pageReveal state\r\n * This method should be hooked just before pageReveal is started.\r\n * !!!IMPORTANT!!! - Hook this up with milestone pageRevealStartWillFire plugin event.\r\n */\r\nexport function processPageRevealedState(): boolean {\r\n if (document.visibilityState !== \"visible\") {\r\n return false;\r\n }\r\n\r\n // remove overlay with timeout\r\n removeOverlayWithTimeout();\r\n\r\n if (shouldReloadPrerenderPage()) {\r\n preparePageForReload(getCurrentPerformanceTimeStamp());\r\n } else {\r\n firePageRevealTelemetry(getCurrentPerformanceTimeStamp());\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * current performance timestamp\r\n */\r\nexport function getCurrentPerformanceTimeStamp(): number {\r\n return Math.round(performance.timing.navigationStart + performance.now());\r\n}\r\n\r\n/**\r\n * Add the overlay which mocks the background. This is needed when a preloaded page on reveal is forced reloaded (stale content, settings change).\r\n * For preload, we add an overlay over the content, that we show until we know the content is fresh.\r\n * If the content is not fresh, we will reload to ensure freshness. The purpose of the overlay is to prevent flickering\r\n * (showing the old content, then the new) when the revealed data is old.\r\n */\r\n export function addPrerenderOverlay(): void {\r\n if (!headData.IsPrerender) {\r\n return;\r\n }\r\n\r\n if (!overlayElement) {\r\n return;\r\n }\r\n\r\n const body = document.body;\r\n const style = overlayElement.style;\r\n\r\n style.background = \"inherit\";\r\n style.position = \"fixed\";\r\n style.bottom = style.left = style.right = style.top = \"0\";\r\n style.zIndex = \"2147483647\";\r\n\r\n if (body) {\r\n body.appendChild(overlayElement);\r\n logger.logObjects(\"pageRevealDelegate:addOverlay: Added overlay\");\r\n } else {\r\n logger.logObjects(\"pageRevealDelegate:addOverlay: Document body is not available, failed to add overlay.\");\r\n }\r\n}\r\n\r\n/**\r\n * Remove the overlay\r\n */\r\nexport function removePrerenderOverlay(): void {\r\n try {\r\n // clear overlayTimeout if its set.\r\n overlayTimeout && clearTimeout(overlayTimeout);\r\n\r\n // Remove it safely if it is present in the DOM\r\n document.body.removeChild(overlayElement);\r\n logger.logObjects(\"pageRevealDelegate:removeOverlay: Removed overlay\");\r\n } catch (e) {\r\n // Suppress the error\r\n }\r\n\r\n overlayElement = null;\r\n}\r\n\r\n/**\r\n * prepare page for reload\r\n * @param pageRevealTimeStamp - pageReveal start timestamp\r\n */\r\nfunction preparePageForReload(pageRevealTimeStamp: DOMHighResTimeStamp): void {\r\n // save telemetry in persistent storage to be used after page is reloaded.\r\n savePrerenderedPageReloadTracking(pageRevealTimeStamp);\r\n\r\n // By specifying the new URL, the helper will use location.replace() method which\r\n // replaces the current resource with the one at the provided URL.\r\n // After using replace() the current page will not be saved in session History,\r\n // meaning the user won't be able to use the back button to navigate to it.\r\n refreshPage({ newUrl: getReloadUrl() });\r\n}\r\n\r\n/**\r\n * should reload hidden page on reveal\r\n */\r\nfunction shouldReloadPrerenderPage(): boolean {\r\n if (!headData.IsPrerender) {\r\n return false;\r\n }\r\n\r\n const flag = localStorage.getItem(forceReloadFlagName);\r\n\r\n if (flag) {\r\n\r\n // remove after reading\r\n localStorage.removeItem(forceReloadFlagName);\r\n\r\n let flagData;\r\n\r\n try {\r\n flagData = JSON.parse(flag);\r\n logger.logObjects(\"pageRevealDelegate:isForceReloadRequested, time: \" + (new Date(flagData.time)).toTimeString());\r\n } catch (e) {\r\n logger.logObjects(\"pageRevealDelegate:isForceReloadRequested: JSON parsing failed for fpr data\");\r\n }\r\n\r\n if (flagData) {\r\n // We should only reload the page if reload request was made after this page navigation started.\r\n // if the request was made before the page navigation, preloaded page must already have the latest settings.\r\n // Therefore no need to reload at reveal.\r\n\r\n const time = flagData.time;\r\n invalidationReason = flagData.data;\r\n\r\n if (!isNaN(time) && (time > performance.timing.navigationStart)) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n return hasMuidChanged();\r\n}\r\n\r\n/**\r\n * Has muid changed\r\n */\r\nfunction hasMuidChanged(): boolean {\r\n const muid = getMuidCookie() || \"\";\r\n\r\n if (muidAtLoad !== muid) {\r\n invalidationReason = PageInvalidationReasons.MuidChange;\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * Fire Telemetry for prerendered tab reload.\r\n */\r\nfunction trackPrerenderedPageReloadTelemetry(): void {\r\n if (!headData.IsPrerender && document.visibilityState === \"visible\") {\r\n const prerenderedPageReloadData = localStorage.getItem(prerenderedPageReload);\r\n const prerenderedPageAgeData = localStorage.getItem(prerenderedPageAge);\r\n\r\n if (prerenderedPageReloadData) {\r\n Telemetry.addOrUpdateCustomProperty(prerenderedPageReload, prerenderedPageReloadData);\r\n localStorage.removeItem(prerenderedPageReload);\r\n }\r\n\r\n if (prerenderedPageAgeData) {\r\n Telemetry.addOrUpdateCustomProperty(prerenderedPageAge, prerenderedPageAgeData);\r\n localStorage.removeItem(prerenderedPageAge);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Save Telemetry for prerendered tab reload.\r\n */\r\nfunction savePrerenderedPageReloadTracking(pageRevealTimeStamp: DOMHighResTimeStamp): void {\r\n if (headData.IsPrerender && invalidationReason) {\r\n localStorage.setItem(prerenderedPageReload, invalidationReason + \"\");\r\n localStorage.setItem(prerenderedPageAge, (pageRevealTimeStamp - performance.timing.navigationStart).toString());\r\n }\r\n}\r\n\r\n/**\r\n * Fire Telemetry for prerendered tab.\r\n */\r\nfunction trackPrerenderedPageTelemetry(pageRevealTimeStamp: DOMHighResTimeStamp): void {\r\n if (isPrerenderVisible()) {\r\n // There was a race condition within trackInfo which would undo the tmpl\r\n // This race condition is fixed by taking dependency on c.trackExtComplete\r\n Telemetry.addOrUpdateTmplProperty(\"isbackgroundpreload\", \"1\");\r\n Telemetry.addOrUpdateTmplProperty(\"isprerender\", \"1\");\r\n Telemetry.addOrUpdateCustomProperty(prerenderedPageAge, (pageRevealTimeStamp - performance.timing.navigationStart).toString());\r\n }\r\n}\r\n\r\n/**\r\n * Returns modified current URL with removed prerender query string.\r\n */\r\nfunction getReloadUrl(): string {\r\n // background prerender query string is added by browser whenever the page is rendered in the background.\r\n // Since we are going to reload the page, we need to remove this query string to make sure the MSN servers\r\n // do not think of this request as a prerendered page.\r\n const url = location.href;\r\n\r\n return url ? url.replace(/[?&]prerender(=\\d)?/, \"\") : \"\";\r\n}\r\n\r\n/**\r\n * fire pageReveal telemetry\r\n * @param pageRevealTimeStamp - pageReveal start timestamp\r\n */\r\nfunction firePageRevealTelemetry(pageRevealTimeStamp: DOMHighResTimeStamp): void {\r\n trackPrerenderedPageTelemetry(pageRevealTimeStamp);\r\n trackPrerenderedPageReloadTelemetry();\r\n}\r\n\r\n/**\r\n * fail safe measure to remove overlay after timeout.\r\n */\r\nfunction removeOverlayWithTimeout(): void {\r\n // fail safe measure to remove overlay after timeout.\r\n overlayTimeout = setTimeout(() => {\r\n removePrerenderOverlay();\r\n }, 1000);\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { expPersistentDataChangeTrackerKey, forceReloadFlagName } from \"./PageLifecycleConstants\";\r\nimport { headData, localStorage } from \"@msnews/core\";\r\n\r\nimport { PageInvalidationReasons } from \"./PageInvalidationReasons\";\r\nimport { getCurrentPerformanceTimeStamp } from \"./PrerenderActionHelpers\";\r\n\r\n/** Type for storing experiences with persistent data updates */\r\nexport type ExpWithPersistentDataUpdate = { [expType: string]: number };\r\n\r\n/**\r\n * return true if prerendered page is visible else false\r\n * @param expType - experience identifier\r\n */\r\nexport function hasExperiencePersistentDataUpdated(expType: string): boolean {\r\n if (headData.IsPrerender && document.visibilityState === \"visible\") {\r\n const storedExperiences = localStorage.getObject(expPersistentDataChangeTrackerKey) || {};\r\n\r\n const timeStamp = storedExperiences[expType];\r\n if (!isNaN(timeStamp)) {\r\n delete storedExperiences[expType];\r\n localStorage.setObject(expPersistentDataChangeTrackerKey, storedExperiences);\r\n\r\n if (timeStamp > performance.timing.navigationStart) {\r\n return true;\r\n }\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * update local storage to track experiences with updated persistent data/settings\r\n * @param expType - experience identifier\r\n */\r\nexport function trackExpWithPersistentDataUpdate(expType: string): void {\r\n const storedExperiences = localStorage.getObject(expPersistentDataChangeTrackerKey) || {};\r\n const timeStamp = storedExperiences[expType];\r\n\r\n if (isNaN(timeStamp)) {\r\n storedExperiences[expType] = getCurrentPerformanceTimeStamp();\r\n localStorage.setObject(expPersistentDataChangeTrackerKey, storedExperiences);\r\n }\r\n}\r\n\r\n/**\r\n * Track page invalidation, marks page to be reloaded on reveal.\r\n * @param expType - experience identifier\r\n */\r\nexport function trackPageInvalidation(invalidationReason: PageInvalidationReasons): void {\r\n // Write to local storage, current timestamp and invalidation requested reason\r\n localStorage.setItem(forceReloadFlagName, JSON.stringify({ time: getCurrentPerformanceTimeStamp(), data: invalidationReason }));\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Local storage key to save prerendered page reload telemetry data\r\n */\r\nexport const expPersistentDataChangeTrackerKey = \"epdu\";\r\n\r\n/**\r\n * Local storage key to save prerendered page reload telemetry data\r\n */\r\nexport const prerenderedPageReload = \"ppreload\";\r\n\r\n/**\r\n * Local storage key to track of the page's age (used for telemetry)\r\n */\r\nexport const prerenderedPageAge = \"ppage\";\r\n\r\n/**\r\n * The key for storing \"timeTakenFromVisibleToReload\" value in local storage.\r\n * This value will be used to calculate the totalTimeTaken between when the current page became visible\r\n * and next page(same page reloaded by prerender code)'s TTAFMax event.\r\n */\r\nexport const timeTakenFromVisibleToReloadKey = \"timeTakenFromVisibleToReload\";\r\n\r\n/**\r\n * Visibility change event\r\n */\r\nexport const visibilityChangeEventName = \"visibilitychange\";\r\n\r\n/**\r\n * Force reload flag name\r\n */\r\nexport const forceReloadFlagName = \"fpr\";\r\n\r\n/**\r\n * Time To Page Reveal when page's primary content is already rendered.\r\n * This is for when the page was revealed after the page had finished loading in the background\r\n */\r\nexport const timeToPageRevealMarker = \"TTPR\";\r\n\r\n/**\r\n * Time To Functional SearchBox\r\n */\r\nexport const timeToFunctionalSearchBoxMarker = \"TTF.SearchBox\";\r\n\r\n/**\r\n * Time To Visually Ready Marker\r\n */\r\nexport const timeToVisuallyReadyMarker = \"TTVR\";\r\n\r\n/**\r\n * Time To Visually Ready Marker SearchBox\r\n */\r\nexport const timeToVisuallyReadySearchBoxMarker = \"TTVR.SearchBox\";\r\n\r\n/**\r\n * Time To Visually Ready Marker when the page was loaded in the background\r\n */\r\nexport const ttvrBackgroundExecution = \"TTVR.BackgroundExecution\";\r\n\r\n/**\r\n * PageTiming entry added when the page is background preloaded\r\n */\r\nexport const backgroundPreloadKey = \"backgroundpreload\";\r\n\r\n/**\r\n * PageTiming entry added when the page is prerendered\r\n */\r\nexport const prerenderKey = \"prerender\";\r\n\r\n/**\r\n * Time To Page Visible\r\n */\r\nexport const timeToPageVisible = \"TTPV\";","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Prefix that all flights for peregrine will use\r\n */\r\nconst peregrineFlightPrefix = \"prg-\";\r\n\r\n/**\r\n * Goes through the array of flights that is given and will filter out any flight that doesn't start with\r\n * prg-. It then sorts them and returns a new string[].\r\n * @param flights Array of flights that we will filter through and return only the peregrine\r\n * @returns specific flights\r\n */\r\nexport function getPeregrineFlights(flights: string[]): string[] {\r\n if (!flights || flights.length === 0) {\r\n return flights;\r\n }\r\n\r\n const cleanedUpFlights = [];\r\n flights.forEach((item) => {\r\n const lowercaseItem = item.toLocaleLowerCase().trim();\r\n // Including specific 1s- prefix to bypass flightID regards OneService's bing.news backfill. Will fill bug to track/remove this.\r\n if (lowercaseItem.startsWith(peregrineFlightPrefix) || lowercaseItem.startsWith(\"1s-\")) {\r\n cleanedUpFlights.push(lowercaseItem);\r\n }\r\n });\r\n\r\n return cleanedUpFlights.sort();\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { AppError, PerfTimeline, ResolverAppErrors, logger, tryGetPerfTimeline, ResolverErrorConfigsDownloadedByCdn, CachedConfigsForDifferentFlight } from \"@msnews/diagnostics\";\r\nimport { Environment, PageRequestTargetScope, appEnvironment } from \"../app\";\r\nimport { ExperienceConfigWrapper, ExperienceConfigs } from \"./configs/\";\r\nimport { IndexedDb, ServerCache, UrlUtility, Utility, getFromWebWorker, isWebWorkerPresent, sendToWebWorker } from \"../utilities\";\r\nimport { localStorage } from \"../webstorage\";\r\nimport { canUseDOM, getLocationHref, getLocationSearch, getRequestData } from \"@msnews/isomorphic-util\";\r\nimport { isArray, isEmpty, isString, memoize, mergeWith } from \"lodash-es\";\r\n\r\nimport { IExperienceConfig } from \"cms-models-msn/configuration/IExperienceConfig\";\r\nimport { IExperienceConfigIndex } from \"cms-models-msn/configuration/IExperienceConfigIndex\";\r\nimport { IExperienceConfigLink } from \"cms-models-msn/configuration/IExperienceConfigLink\";\r\nimport { getPeregrineFlights } from \"@msnews/experimentation-helpers\";\r\n\r\n/**\r\n * Type definition for cached configs in the indexed DB\r\n */\r\ntype CachedConfigsType = Map;\r\n\r\n/**\r\n * Constants for TTLs\r\n */\r\nconst SERVER_CACHE_TTL: number = 60 * 60 * 24 * 1000; // one day in milliseconds\r\nconst SERVER_CACHE_CONFIG_STALENESS_TIMEOUT: number = 5 * 60 * 1000; // 5 minutes in milliseconds\r\n\r\n/**\r\n * Resolver Class\r\n */\r\nclass Resolver {\r\n\r\n /**\r\n * The single instance of the Resolver class.\r\n * @type {Resolver}\r\n */\r\n private static _instance: Resolver = null;\r\n\r\n /**\r\n * Target scope of the current page request\r\n * @type {PageRequestTargetScope}\r\n */\r\n private currentTargetScope: PageRequestTargetScope = appEnvironment.CurrentRequestTargetScope;\r\n\r\n /**\r\n * Dictionary to maintain all resolved config for internal state management\r\n * @type {Map}\r\n */\r\n private configMap: CachedConfigsType = new Map();\r\n\r\n /** set fallback env to prod to avoid any live site issues */\r\n private env: Environment = appEnvironment.Environment || Environment.prod;\r\n\r\n /**\r\n * Config base url used during cms config resolution.\r\n * @type {string}\r\n */\r\n private cdnConfigBaseUrl: URL;\r\n\r\n /**\r\n * Config base url for Config Service\r\n * @type {string}\r\n */\r\n private configServiceBaseUrl: URL;\r\n\r\n /**\r\n * Dictionary to maintain all promise objects which are not resolved/rejected. Once promise object is resolved/rejected,\r\n * it gets deleted from this dictionary and put in the configMap.\r\n * @type {Map>}\r\n */\r\n private promiseMap: Map> = new Map();\r\n\r\n /** Resolver app errors */\r\n private resolverErrors: AppError[];\r\n\r\n /** Object of IndexedDb wrapper class */\r\n private indexedDb: IndexedDb;\r\n\r\n /**\r\n * Check if IndexedDb operation is allowed or not.\r\n * @type {boolean}: true if indexedDB should be used else false.\r\n */\r\n private useIndexedDb: boolean;\r\n\r\n /**\r\n * Check if ServerCache can be used or not.\r\n * @type {boolean}\r\n */\r\n private useServerCache: boolean;\r\n\r\n /** Current Timestamp for config staleness check. */\r\n private stalenessCheckTimestamp: number = new Date().getTime();\r\n\r\n /**\r\n * Check if ConfigService operation is allowed or not.\r\n * @type {boolean}\r\n */\r\n private enableConfigService: boolean;\r\n\r\n /**\r\n * Get config service parameters from currentTargetScope\r\n * @type {string}\r\n */\r\n private configServiceParameters: string;\r\n\r\n /**\r\n * Storage key for indexedDb\r\n * @type {string}\r\n */\r\n private storageKey: string;\r\n\r\n /** Config timings object storing fetch duration of network or cache to retrieve config. */\r\n private configTimings: ConfigFetchTiming[];\r\n\r\n /**\r\n * Check if web worker exists\r\n * @type {boolean}\r\n */\r\n private useWebWorkerToCache: boolean;\r\n\r\n /** The perf timeline for the resolver */\r\n private perfTimeline: PerfTimeline = tryGetPerfTimeline(\"Resolver\", \"Resolver\", true);\r\n\r\n /**\r\n * Check if config service shold return more than 1 config\r\n * @type {boolean}\r\n */\r\n private isMultiConfigRetrievalEnabled = false;\r\n\r\n /** Maps config index HREF to local override for config. */\r\n private localOverrideMap: { [configIndexHref: string]: ExperienceConfigWrapper } = {};\r\n\r\n /** Initialize indexedDb for configs. */\r\n private initializeIndexedDb = memoize(this._initializeIndexedDb);\r\n\r\n /** Initialize configs from IDB. */\r\n private populateConfigMapFromIndexedDbAsync = memoize(this._populateConfigMapFromIndexedDbAsync);\r\n\r\n /** Peregrine only lower cased flights in alphabetical order */\r\n private peregrineFlights: string;\r\n\r\n /** Peregrine flights local storage key */\r\n private peregrineFlightsKey = \"prgflights\";\r\n\r\n /**\r\n * Constructor to initialize private variables.\r\n */\r\n public constructor() {\r\n this.initializeCaching();\r\n }\r\n\r\n /**\r\n * Initialize caching layer of resolver.\r\n *\r\n * WARNING!!! Do NOT add async/await in this function. It must remain a pure synchronous function in order\r\n * to initialize the indexedDB cache as quickly as possible before entry point beats to us due to multi-level\r\n * promise waiting hierarchies.\r\n *\r\n * @param idb object of indexedDb class. Unit tests set this value. It will be null in other cases.\r\n * @param cbid optional cache busting identifier. Unit tests set this value. It will be null in other cases.\r\n * @\r\n */\r\n public initializeCaching(idb?: IndexedDb, cbid?: string): void {\r\n /**\r\n * In most cases configRootUrl will be sent by PCS so appEnvironment will have it.\r\n * In case it is not sent, we fall back to environmentConfig so config will be always served.\r\n */\r\n this.cdnConfigBaseUrl = appEnvironment.ConfigRootUrl || appEnvironment.EnvironmentConfigUrl;\r\n\r\n // Get ConfigServiceBaseUrl from appEnvironment\r\n this.configServiceBaseUrl = appEnvironment.ConfigServiceBaseUrl;\r\n\r\n this.resolverErrors = [];\r\n this.configTimings = [];\r\n\r\n this.useWebWorkerToCache = isWebWorkerPresent;\r\n\r\n this.perfTimeline = tryGetPerfTimeline(\"Resolver\", \"Resolver\");\r\n\r\n this.indexedDb = idb ? idb : new IndexedDb();\r\n\r\n const enableCMSPPEConfigs = appEnvironment.EnableCMSPPEConfigs;\r\n\r\n // Check if IndexedDb is supported\r\n this.useIndexedDb =\r\n // Debug scenario: Check if indexedDB is allowed to be read in main thread. By default true.\r\n this.enableIndexedDbInMainResolver()\r\n // PCS flag to turn on/off IndexedDb caching of configs.\r\n && !appEnvironment.DisableCachingConfigs\r\n // Debug scenario: to turn off indexedDB in all threads.\r\n && this.indexedDb.isCachingAllowed\r\n // Check if there exists IndexedDB in browser\r\n && this.indexedDb.supported\r\n // Use case is simple config tests, we do not want to cache\r\n // Also not caching in server-side in this scenario\r\n && !enableCMSPPEConfigs;\r\n\r\n // Check if server cache could be used or not\r\n this.useServerCache = ServerCache !== null\r\n // PCS flag to turn on/off IndexedDb caching of configs.\r\n && !appEnvironment.DisableCachingConfigs\r\n // Use case is simple config tests, we do not want to cache\r\n // Also not caching in server-side in this scenario\r\n && !enableCMSPPEConfigs;\r\n\r\n // Read peregrine specific flights\r\n const pageExperiments = this.currentTargetScope && getPeregrineFlights(this.currentTargetScope.pageExperiments);\r\n if (pageExperiments && pageExperiments.length > 0) {\r\n this.peregrineFlights = pageExperiments.join(\",\");\r\n }\r\n\r\n // Check whether to use Config Resolver Service (CRS).\r\n this.enableConfigService = this.useConfigService();\r\n if (this.enableConfigService) {\r\n\r\n const scopeWithPeregrineFlights = {\r\n ...this.currentTargetScope,\r\n pageExperiments\r\n };\r\n\r\n // Query string parameter from target scope.\r\n this.configServiceParameters = \"?targetScope=\" + JSON.stringify(scopeWithPeregrineFlights);\r\n\r\n // Send PCS apptype to CRS so we can build CRS Jarvis dashboards per apptype.\r\n this.configServiceParameters += `&apptype=${appEnvironment.AppType}`;\r\n\r\n const { IsMultiConfigRetrievalEnabled, CacheBustingIdentifier } = appEnvironment;\r\n\r\n // Check if CRS should fetch multiple configs and its depth.\r\n this.isMultiConfigRetrievalEnabled = IsMultiConfigRetrievalEnabled;\r\n if (this.isMultiConfigRetrievalEnabled) {\r\n this.configServiceParameters += `&maxDepth=${this.getConfigRetrievalMaxDepth()}`;\r\n }\r\n\r\n // If cbid is provided, typically in unit testing context, use it.\r\n // If window has _cbid then use it else use the value from PCS, to send to CRS for busting disk, AFD and Origin cache.\r\n const cacheBustingIdentifier = cbid || window._cbid || CacheBustingIdentifier;\r\n if (cacheBustingIdentifier) {\r\n this.configServiceParameters += `&cbid=${cacheBustingIdentifier}`;\r\n }\r\n\r\n // If url has dev only query string params, inform CRS so it can exclude from availability and will help debugging on Jarvis.\r\n if (this.containsDevOnlyQueryParameters()) {\r\n this.configServiceParameters += \"&item=dev:true\";\r\n }\r\n\r\n if (enableCMSPPEConfigs) {\r\n this.configServiceParameters += \"&item=cms:ppe\";\r\n }\r\n }\r\n\r\n // Get storage key based on target scope.\r\n this.storageKey = this.generateKey();\r\n\r\n // if pre-initialized config map doesn't exist or does not contain the storageKey entry we want,\r\n // then proceed to asynchronously initialize the configMap from indexedDb\r\n // NOTE: we only start the async read, and don't await for this to finish\r\n this.populateConfigMapFromIndexedDbAsync();\r\n }\r\n\r\n /**\r\n * Merges config objects.\r\n * @private\r\n * @param {ExperienceConfigWrapper[]} configs - an array of config documents\r\n * @param {string} experienceType - experienceType\r\n * @return ExperienceConfig - returns merged config based on a set of rules\r\n */\r\n public mergeConfig(configs: IExperienceConfig[]): IExperienceConfig {\r\n if (!configs || configs.length < 1) {\r\n return null;\r\n }\r\n\r\n const result: IExperienceConfig = configs[0];\r\n\r\n // skip the 0th item as it is assigned to result above, only merge properties section\r\n for (let count = 1; count < configs.length; count++) {\r\n result.properties = mergeWith(result.properties, configs[count].properties, this.customizer);\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * matches targeting scope and returns the config urls for the same.\r\n * @private\r\n * @param {IExperienceConfigIndex} configIndex - an array of config documents\r\n * @return string[] - returns urls for configurations for which the scope matched\r\n */\r\n public resolveConfigIndex(configIndex: IExperienceConfigIndex): string[] {\r\n if (!configIndex) {\r\n return null;\r\n }\r\n\r\n const configPaths: string[] = [];\r\n configIndex.configs.forEach(experienceRef => {\r\n if (this.targetScopeMatched(experienceRef)) {\r\n configPaths.push(experienceRef.href);\r\n }\r\n });\r\n\r\n // if override config is provided, then we add that to the end of list\r\n // so props provided in override config will add/update existing properties.\r\n // This is similar to CMS override settings but scoped to experience level.\r\n if (configIndex.overrideConfig && Utility.stringHasData(configIndex.overrideConfig.href)) {\r\n configPaths.push(configIndex.overrideConfig.href);\r\n }\r\n\r\n return configPaths;\r\n }\r\n\r\n /**\r\n * basic version of target scope that only checks market currently.\r\n * @private\r\n * @param {IExperienceConfigReference} experienceRef - experience config reference that has targetscope as child property\r\n * @return boolean - true if current target scope matches with config target scope, otherwise false\r\n */\r\n public targetScopeMatched(experienceRef: IExperienceConfigLink): boolean {\r\n const targetScope = experienceRef.targetScope;\r\n\r\n // if target scope is undefined for a config entry, we treat that as default config and apply it\r\n if (!targetScope) {\r\n return true;\r\n }\r\n\r\n return (this.audienceModeMatched(targetScope)\r\n && this.browserTypeMatched(targetScope)\r\n && this.deviceTypeMatched(targetScope)\r\n && this.domainMatched(targetScope)\r\n && this.experimentMatched(targetScope)\r\n && this.marketMatched(targetScope)\r\n && this.osMatched(targetScope)\r\n && this.pageTypeMatched(targetScope)\r\n && this.platformMatched(targetScope));\r\n }\r\n\r\n /**\r\n * function to check if current audienceMode type matches target audienceMode type\r\n * @private\r\n * @param {PageRequestTargetScope} targetScope - experience config reference that has targetscope as child property\r\n * @return boolean - true if current target scope audienceMode matches with config target scope audienceMode, otherwise false\r\n */\r\n public audienceModeMatched(targetScope: PageRequestTargetScope): boolean {\r\n return !targetScope.audienceMode || this.currentTargetScope.audienceMode === targetScope.audienceMode;\r\n }\r\n\r\n /**\r\n * function to check if current browser type matches target browser type\r\n * @private\r\n * @param {PageRequestTargetScope} targetScope - experience config reference that has targetscope as child property\r\n * @return boolean - true if current target scope browser type matches with config target scope browser type, otherwise false\r\n */\r\n public browserTypeMatched(targetScope: PageRequestTargetScope): boolean {\r\n if (!targetScope.browser || !targetScope.browser.browserType) {\r\n return true;\r\n }\r\n\r\n if (this.currentTargetScope.browser && this.currentTargetScope.browser.browserType === targetScope.browser.browserType &&\r\n (!targetScope.browser.version || this.currentTargetScope.browser.version === targetScope.browser.version)) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * function to check if current device type matches target device type\r\n * @private\r\n * @param {PageRequestTargetScope} targetScope - experience config reference that has targetscope as child property\r\n * @return boolean - true if current target scope device type matches with config target scope device type, otherwise false\r\n */\r\n public deviceTypeMatched(targetScope: PageRequestTargetScope): boolean {\r\n return !targetScope.deviceFormFactor || this.currentTargetScope.deviceFormFactor === targetScope.deviceFormFactor;\r\n }\r\n\r\n /**\r\n * Check if current domain matches target domain\r\n * @param targetScope - experience config reference that has targetscope as child property\r\n * @return Whether the current target scope domain matches with config target scope domain\r\n */\r\n public domainMatched(targetScope: PageRequestTargetScope): boolean {\r\n return !targetScope.domain || this.currentTargetScope.domain === targetScope.domain;\r\n }\r\n\r\n /**\r\n * function to check if current experiment id matches with the requested scope experiment id.\r\n * @private\r\n * @param {PageRequestTargetScope} targetScope - experience config reference that has targetscope as child property\r\n * @return boolean - true if current target scope experiment matches with config target scope experiment, otherwise false\r\n */\r\n public experimentMatched(targetScope: PageRequestTargetScope): boolean {\r\n this.currentTargetScope.pageExperiments = this.currentTargetScope.pageExperiments || [];\r\n\r\n if (!isString(targetScope.experimentId) || isEmpty(targetScope.experimentId)\r\n || this.currentTargetScope.pageExperiments.indexOf(targetScope.experimentId) >= 0) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Compare the strings case insensitive.\r\n * @private\r\n * @param {string} lhs The string to compare.\r\n * @param {string} rhs The string to compare against.\r\n * @return {number} - true if the strings equal case insensitive.\r\n */\r\n public stringsEqualCaseInsensitive(lhs: string, rhs: string): boolean {\r\n return (lhs || \"\").localeCompare(rhs || \"\", undefined, { sensitivity: \"accent\" }) === 0;\r\n }\r\n\r\n /**\r\n * function to check if current market scope match with target scope market.\r\n * @private\r\n * @param {PageRequestTargetScope} targetScope - experience config reference that has targetscope as child property\r\n * @return boolean - true if current target scope market matches with config target scope market, otherwise false\r\n */\r\n public marketMatched(targetScope: PageRequestTargetScope): boolean {\r\n // if locale is not part of target scope, we assume it is applicable for all locale.\r\n // Separated out this if condition to have clarity about this behavior.\r\n if (!targetScope.locale) {\r\n return true;\r\n }\r\n\r\n const targetLocale = targetScope.locale;\r\n const currentLocale = this.currentTargetScope.locale;\r\n\r\n if ((!targetLocale.language || this.stringsEqualCaseInsensitive(targetLocale.language, currentLocale.language)) &&\r\n (!targetLocale.market || this.stringsEqualCaseInsensitive(targetLocale.market, currentLocale.market)) &&\r\n (!targetLocale.script || this.stringsEqualCaseInsensitive(targetLocale.script, currentLocale.script))) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * function to check if current operating system type matches target operating system type\r\n * @private\r\n * @param {PageRequestTargetScope} targetScope - experience config reference that has targetscope as child property\r\n * @return boolean - true if current target scope operating system type matches with config target scope operating system type, otherwise false\r\n */\r\n public osMatched(targetScope: PageRequestTargetScope): boolean {\r\n return !targetScope.os || this.currentTargetScope.os === targetScope.os;\r\n }\r\n\r\n /**\r\n * function to check if current pagetype matches target scope\r\n * @private\r\n * @param {PageRequestTargetScope} targetScope - experience config reference that has targetscope as child property\r\n * @return boolean - true if current target scope pagetype matches with config target scope pagetype, otherwise false\r\n */\r\n public pageTypeMatched(targetScope: PageRequestTargetScope): boolean {\r\n return !targetScope.pageType || this.currentTargetScope.pageType === targetScope.pageType;\r\n }\r\n\r\n /**\r\n * function to check if current scope platform type matches target scope platform type\r\n * @private\r\n * @param {PageRequestTargetScope} targetScope - experience config reference that has targetscope as child property\r\n * @return boolean - true if current target scope platform matches with config target scope platform, otherwise false\r\n */\r\n public platformMatched(targetScope: PageRequestTargetScope): boolean {\r\n return !targetScope.platform || this.currentTargetScope.platform === targetScope.platform;\r\n }\r\n\r\n /**\r\n * Customizer for merge. We are explcitly overriding the array from taget to source. No array elements from source are preserved.\r\n * @private\r\n * @param {any} srcValue - source object to merge. Can be of type any\r\n * @param {any} objValue - target object to merge. Can be of type any\r\n * @return target Object when the type is array. Otherwise uses default behavior of merge.\r\n */\r\n public customizer(srcValue: any, objValue: any): any {\r\n if (isArray(srcValue)) {\r\n return objValue;\r\n }\r\n }\r\n\r\n /**\r\n * Function to clear internal state map for Unit testing.\r\n * @public\r\n * @void\r\n */\r\n public clearInternalState(): void {\r\n this.configMap.clear();\r\n this.initializeIndexedDb.cache.clear();\r\n this.populateConfigMapFromIndexedDbAsync.cache.clear();\r\n }\r\n\r\n /**\r\n * Function to override current request target scope. Should be used only when running outside the\r\n * context of client side rendering. Example tooling.\r\n * This function should not be called by any client rendering experience running inside the Page Context.\r\n * @public\r\n * @param {PageRequestTargetScope} targetScope - Target scope to override current Request target scope\r\n * @void\r\n */\r\n public overrideCurrentRequestTargetScope(targetScope: PageRequestTargetScope): void {\r\n this.currentTargetScope = targetScope;\r\n }\r\n\r\n /**\r\n * Function to override current request environment. Should be used only when not running outside the\r\n * context of client side rendering. Example tooling\r\n * @public\r\n * @param {Environment} overrideEnv - environment enum to override\r\n * @void\r\n */\r\n public overrideCurrentRequestEnvironment(overrideEnv: Environment): void {\r\n // fallback as prod\r\n this.env = overrideEnv || Environment.prod;\r\n }\r\n\r\n /**\r\n * Overrides a config entry. Use for local testing only. Does not work on PROD environment.\r\n * @param relativeUrl The config index URL to override\r\n * @param experienceType The experience type\r\n * @param config The config to use\r\n */\r\n public overrideConfig(relativeUrl: string, experienceType: string, config: any): void {\r\n if (this.env !== Environment.prod) {\r\n this.localOverrideMap[relativeUrl] = {\r\n experienceType: experienceType,\r\n properties: config,\r\n typeVersion: \"1.0.0\",\r\n _name: \"index\"\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Returns the resolved merged Experience config when passed Experience Config Index.\r\n * This function downloads the config index, filter based on target scope, download the configs and\r\n * merge the configs\r\n * @public\r\n * @param {string} relativeUrl - Expeience Index document relative url\r\n * @return Promise\r\n */\r\n public async getConfig(relativeUrl: string): Promise {\r\n\r\n const cacheKey = this.getCacheKey(relativeUrl);\r\n\r\n if (!this.currentTargetScope || !relativeUrl || !isString(relativeUrl) || isEmpty(relativeUrl)) {\r\n throw new Error(\"getConfig: Invalid target scope or relativeUrl\");\r\n }\r\n\r\n // If there is a local override for testing, use it.\r\n if (this.localOverrideMap[relativeUrl]) {\r\n return this.localOverrideMap[relativeUrl];\r\n }\r\n\r\n const startGetConfig = performance.now();\r\n\r\n // if it exists in memory, return it immediately\r\n const configFromMemory = this.configMap.get(cacheKey);\r\n if (configFromMemory) {\r\n this.addConfigTiming(configFromMemory.experienceType, startGetConfig, \"cache\");\r\n return configFromMemory;\r\n }\r\n\r\n // if promiseMap has the item, we already have an active promise which is not yet resolved/rejected. Return this promise\r\n const existingPromise = this.promiseMap.get(cacheKey);\r\n if (existingPromise) {\r\n return existingPromise;\r\n }\r\n\r\n let processed = false;\r\n const configEndMeasure = this.perfTimeline && this.perfTimeline.startMeasure(\"config\", relativeUrl).endMeasure;\r\n let experienceType: string;\r\n let configSource: string;\r\n\r\n const configPromise = new Promise(async (resolve, reject) => {\r\n\r\n try {\r\n // Fetch merged config from server cache if available\r\n if (this.useServerCache) {\r\n const cachedOnServer: boolean = await ServerCache.has(cacheKey);\r\n if (cachedOnServer) {\r\n // Retrieve and deserialize the stringified config stored in ServerCache\r\n const serializedConfig: string = await ServerCache.get(cacheKey);\r\n const configFromServerCache = JSON.parse(serializedConfig) as ExperienceConfigWrapper;\r\n if (configFromServerCache) {\r\n this.configTimings.push({\r\n experienceType: configFromServerCache.experienceType,\r\n cacheFetchDuration: performance.now() - startGetConfig\r\n });\r\n processed = true;\r\n this.promiseMap.delete(cacheKey);\r\n resolve(configFromServerCache);\r\n\r\n // Invalidate config in server cache if this is already stale (5 minutes)\r\n //\r\n // Might prefer to actively refresh in a separate worker instead on server hot path.\r\n //\r\n // TODO Tracking Work Item: Investigate refresh config in server cache\r\n // https://dev.azure.com/microsoft/OS/_workitems/edit/24737222\r\n if (this.isServerCacheConfigStale(configFromServerCache.storageTimestamp)) {\r\n ServerCache.del(cacheKey);\r\n }\r\n\r\n logger.log(`${this.logPrefix()} ${configFromServerCache.experienceType} config fetched from server cache.`);\r\n return;\r\n }\r\n }\r\n\r\n // Not found on server cache so getting config from network\r\n const networkReadPromise = this.getConfigFromNetwork(relativeUrl);\r\n\r\n // Await on the network promise to get the merged config.\r\n const networkConfigsMap = await networkReadPromise;\r\n const networkConfig = networkConfigsMap.get(cacheKey);\r\n experienceType = networkConfig.experienceType;\r\n this.addConfigTiming(experienceType, startGetConfig, configSource = \"network\");\r\n resolve(networkConfig);\r\n\r\n } else {\r\n // this will contain both the IDB cache read promise, in case we haven't yet read from\r\n // IDB yet, as well as the network read promise, which we will race until one finishes.\r\n const readPromises: Array> = [\r\n\r\n // it's possible that the IDB read is still going on, so see if we can get results from\r\n // cache after racing with it. Note that we never want to 'hard await' on the IDB read\r\n // as it's possible the IDB read may have errored out / stalled, etc. So we're using this\r\n // result only as a secondary fallback. Primary is still the network.\r\n this.populateConfigMapFromIndexedDbAsync()\r\n ];\r\n\r\n const networkReadPromise = this.getConfigFromNetwork(relativeUrl);\r\n readPromises.push(networkReadPromise as Promise);\r\n\r\n // start the race between network and IDB cache read\r\n await Promise.race(readPromises);\r\n\r\n // after the race check in-memory again (in case the IDB read finished populated the\r\n // in-memory map early)\r\n const configFromMemoryAfterRace = this.configMap.get(cacheKey);\r\n if (configFromMemoryAfterRace) {\r\n experienceType = configFromMemoryAfterRace.experienceType;\r\n this.addConfigTiming(experienceType, startGetConfig, configSource = \"cache\");\r\n resolve(configFromMemoryAfterRace);\r\n return;\r\n }\r\n\r\n // Await on the network promise to get the merged config.\r\n const networkConfigsMap = await networkReadPromise;\r\n const networkConfig = networkConfigsMap.get(cacheKey);\r\n experienceType = networkConfig.experienceType;\r\n this.addConfigTiming(experienceType, startGetConfig, configSource = \"network\");\r\n resolve(networkConfig);\r\n\r\n }\r\n } catch (error) {\r\n this.resolverErrors.push({\r\n ...ResolverAppErrors.GetConfigException,\r\n message: `Exception in getConfig for ${relativeUrl}`,\r\n pb: {\r\n ...ResolverAppErrors.GetConfigException.pb,\r\n customMessage: error\r\n }\r\n });\r\n\r\n // If we don't explicitly catch the error, then the promise never gets rejected which might cause issues during experience load time.\r\n reject(error);\r\n } finally {\r\n\r\n processed = true;\r\n this.promiseMap.delete(cacheKey);\r\n\r\n // only measure the network operations (otherwise there are too many overlapping measures to make sense)\r\n if (configEndMeasure) {\r\n configEndMeasure(`${experienceType}-${relativeUrl}-${configSource}`);\r\n }\r\n }\r\n });\r\n\r\n // if caller is using await then this request has been processed and we should not add it to promiseMap.\r\n // if caller is trying to download multiple configs in parallel, then processed should be false.\r\n if (!processed) {\r\n this.promiseMap.set(cacheKey, configPromise);\r\n }\r\n\r\n return configPromise;\r\n }\r\n /**\r\n * Returns the resolved merged Experience config when passed Experience Config Index.\r\n * This function downloads the config index, filter based on target scope, download the configs and\r\n * merge the configs\r\n * @private\r\n * @param {string} relativeUrl - Expeience Index document relative url.\r\n * @return Promise> map of config(s) resolved by service/cdn.\r\n */\r\n public async getConfigFromNetwork(relativeUrl: string): Promise> {\r\n\r\n const cacheKey = this.getCacheKey(relativeUrl);\r\n\r\n const mergedConfigsMap = new Map();\r\n\r\n if (this.enableConfigService) {\r\n const configServiceRelativeUrl = this.removeCmsPathFromRelativeUrl(relativeUrl) + this.configServiceParameters;\r\n try {\r\n // Get merged config from config service with multi config support.\r\n if (this.isMultiConfigRetrievalEnabled) {\r\n const crsResponse = await this.downloadFile(new URL(`${configServiceRelativeUrl}${this.configServiceBaseUrl.search}`, this.configServiceBaseUrl));\r\n if (crsResponse && crsResponse.rootConfigIndexId && crsResponse.configs) {\r\n const configs = Object.keys(crsResponse.configs).map(e => crsResponse.configs[e]);\r\n for (const crsMergedConfig of configs) {\r\n if (crsMergedConfig && crsMergedConfig.configIndexHref) {\r\n const configIndexKey = crsMergedConfig.configIndexHref;\r\n // Save config to in-memory cache\r\n await this.addConfigToConfigMap(configIndexKey, crsMergedConfig);\r\n mergedConfigsMap.set(this.getCacheKey(configIndexKey), crsMergedConfig);\r\n logger.log(`${this.logPrefix()} ${configIndexKey} config for ${crsMergedConfig.experienceType} fetched from network using CRS url with multi config support.`);\r\n }\r\n }\r\n\r\n return mergedConfigsMap;\r\n }\r\n }\r\n\r\n // Get single merged config from config service\r\n const crsConfig = await this.downloadFile(new URL(`${configServiceRelativeUrl}${this.configServiceBaseUrl.search}`, this.configServiceBaseUrl));\r\n\r\n // Save config to in-memory cache\r\n await this.addConfigToConfigMap(relativeUrl, crsConfig);\r\n mergedConfigsMap.set(cacheKey, crsConfig);\r\n logger.log(`${this.logPrefix()} ${cacheKey} config for ${crsConfig.experienceType} fetched from network using CRS url.`);\r\n return mergedConfigsMap;\r\n\r\n } catch (error) {\r\n this.resolverErrors.push({\r\n ...ResolverAppErrors.CrsFetchFailed,\r\n message: `CRS fetch failed for ${relativeUrl}.`,\r\n pb: {\r\n ...ResolverAppErrors.CrsFetchFailed.pb,\r\n customMessage: `CRS relative Url: ${configServiceRelativeUrl} Error: ${error}`\r\n }\r\n });\r\n }\r\n }\r\n\r\n // Get config from CDN when config service is not enabled or it returned null or invalid response.\r\n if (mergedConfigsMap && !mergedConfigsMap.has(cacheKey)) {\r\n const cdnConfig = await this.downloadMergeConfig(relativeUrl);\r\n if (cdnConfig) {\r\n\r\n // Save config to in-memory cache\r\n await this.addConfigToConfigMap(relativeUrl, cdnConfig);\r\n\r\n mergedConfigsMap.set(cacheKey, cdnConfig);\r\n\r\n // Dev scenario: if config service is not enabled and we got configs from CDN, do not log app error.\r\n if (this.enableConfigService) {\r\n this.resolverErrors.push({\r\n ...ResolverErrorConfigsDownloadedByCdn,\r\n message: \"Configs served from CDN after CRS fetch failed\",\r\n pb: {\r\n ...ResolverErrorConfigsDownloadedByCdn.pb,\r\n customMessage: `Relative Url: ${relativeUrl} CRS Params: ${ this.configServiceParameters}`\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n return mergedConfigsMap;\r\n }\r\n\r\n /**\r\n * Set configMap object with appropriate values.\r\n * @private\r\n * @param configIndexHref example: cms/api/amp/experienceConfigIndex/AfCDeG\r\n * @param config object of ExperienceConfigWrapper\r\n */\r\n public async addConfigToConfigMap(configIndexHref: string, config: ExperienceConfigWrapper): Promise {\r\n config.storageTimestamp = this.stalenessCheckTimestamp;\r\n config.configIndexHref = configIndexHref;\r\n\r\n const cacheKey = this.getCacheKey(configIndexHref);\r\n\r\n // No need to cache on configMap on server side since it will be another layer of memcache to worry about.\r\n if (this.useServerCache) {\r\n // Save config to server cache so other processes could reuse the cache.\r\n // ServerCache only accepts string to avoid serialization issues.\r\n // TTL is 1 day for now.\r\n const serializedConfig = JSON.stringify(config);\r\n await ServerCache.set(cacheKey, serializedConfig, SERVER_CACHE_TTL);\r\n } else {\r\n // Set configMap for future reference.\r\n this.configMap.set(cacheKey, config);\r\n }\r\n }\r\n\r\n /**\r\n * Clear render cache when applicable.\r\n * @private\r\n * @param areConfigsEqual: response from web worker. This is typically true or false in this case.\r\n */\r\n public purgeRenderCacheUponConfigChanges(areConfigsEqual: boolean): void {\r\n if (areConfigsEqual) {\r\n return;\r\n }\r\n\r\n try {\r\n localStorage.removeSubstringKeys(\"lastKnown_\");\r\n localStorage.removeSubstringKeys(\"timestamp_\");\r\n localStorage.removeSubstringKeys(\"keys_\");\r\n } catch (e) {\r\n // Send alert to monitoring system that render cache is not being purged, when it is supposed to.\r\n this.resolverErrors.push({\r\n ...ResolverAppErrors.FailedToPurgeRenderCache,\r\n message: \"Failed to purge render cache when cached config and network config is not same.\",\r\n pb: {\r\n ...ResolverAppErrors.FailedToPurgeRenderCache.pb,\r\n customMessage: e\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Get the config over the network, merge and return.\r\n * @private\r\n * @param {string} relativeUrl - Expeience Index document relative url.\r\n * @return Promise\r\n */\r\n public async downloadMergeConfig(relativeUrl: string): Promise {\r\n const experienceIndex = await this.downloadFile(new URL(`${relativeUrl}${this.cdnConfigBaseUrl.search}`, this.cdnConfigBaseUrl));\r\n const configPaths = this.resolveConfigIndex(experienceIndex);\r\n const configObjects = await this.downloadExperienceConfig(this.cdnConfigBaseUrl, configPaths);\r\n const config: ExperienceConfigWrapper = this.mergeConfig(configObjects) as ExperienceConfigWrapper;\r\n config.experienceType = experienceIndex.experienceType;\r\n\r\n return config;\r\n }\r\n\r\n /**\r\n * Given an array of config urls, this function downloads them in parallel and returns a promise.\r\n * @private\r\n * @param {string} baseConfigUrl - base config url depends on implementation\r\n * @param {string[]} hrefs - Array of configuration relative urls\r\n * @return Promise\r\n */\r\n public async downloadExperienceConfig(baseConfigUrl: URL, hrefs: string[]): Promise {\r\n const promiseArray = [];\r\n hrefs.forEach(href => {\r\n promiseArray.push(this.downloadFile(new URL(`${href}${baseConfigUrl.search}`, baseConfigUrl)));\r\n });\r\n\r\n return await Promise.all(promiseArray);\r\n }\r\n\r\n /**\r\n * downloads file from CMS given the relative url\r\n * @private\r\n * @param {string} relativeUrl - relative url of the document\r\n * @return Promise returns generic Type object wrapped in Promise\r\n */\r\n public async downloadFile(url: URL): Promise {\r\n // Use node-fetch to be compatible with SSR\r\n return fetch(url.toString())\r\n .then(response => {\r\n if (!response.ok) {\r\n const crsVersion = response.headers.get(\"X-Crs-BuildVersion\") || \"[Not a CRS Call]\";\r\n throw new Error(`Status: ${response.status}, Status Text: ${response.statusText}, Url: ${url} and CRS Version: ${crsVersion}`);\r\n }\r\n\r\n return response.json();\r\n }, error => {\r\n throw new Error(error);\r\n });\r\n }\r\n\r\n /**\r\n * This function generates a key that is used to write/read configurations to/from storage.\r\n * example key: \"kids|ja|jp|testPage|mmx\"\r\n * @private\r\n * @return string\r\n */\r\n public generateKey(): string {\r\n\r\n // Client side resolver will use reduced set of keys for perf and retrival logic. This logic has to match WebWorkerResolver.generateKey\r\n if (canUseDOM()) {\r\n\r\n const { audienceMode = \"\", locale = {}, pageType = \"\" } = this.currentTargetScope || {};\r\n const { language, market } = locale;\r\n\r\n const keys = [audienceMode, language, market, pageType, appEnvironment.AppType || \"\"];\r\n return keys.map(key => key || \"\").join(\"|\").toLowerCase();\r\n\r\n // Server side resolver needs to generate full set of target scopes since multiple pages/users will share the same cache for longer duration\r\n } else {\r\n let { audienceMode = \"\",\r\n browser = null,\r\n deviceFormFactor = \"\",\r\n experimentId = \"\",\r\n locale = {},\r\n os = {},\r\n pageType = \"\",\r\n platform = \"\",\r\n pageExperiments = null } = this.currentTargetScope || {};\r\n const { language, market } = locale;\r\n const { browserType = \"\", version = \"\" } = browser || {};\r\n\r\n // Filter out non-peregrine flights so they are not part of cache key.\r\n pageExperiments = getPeregrineFlights(pageExperiments);\r\n\r\n const keys = [audienceMode, browserType, version, deviceFormFactor, language, market, os, experimentId, pageType, platform, pageExperiments ? pageExperiments.join() : \"\", appEnvironment.AppType || \"\"];\r\n return keys.map(key => key || \"\").join(\"|\").toLowerCase();\r\n }\r\n }\r\n\r\n /**\r\n * Function checks if ConfigService is enabled.\r\n * @returns true if supported else false.\r\n */\r\n public useConfigService(): boolean {\r\n const urlQuery = getLocationSearch();\r\n if (urlQuery) {\r\n const param = UrlUtility.getQueryParameterByName(\"enableConfigService\", urlQuery);\r\n if (param) {\r\n return param.toLocaleLowerCase() === \"true\";\r\n }\r\n }\r\n\r\n // PCS flag to turn on/off ConfigService.\r\n // When EnableConfigService = false, it gets configs from CDN and merge at client side.\r\n return appEnvironment.EnableConfigService;\r\n }\r\n\r\n /**\r\n * Function that returns maxDepth if exists in query string else default value.\r\n * This is the max depth of the config tree.\r\n * @returns Depth of config in tree.\r\n */\r\n public getConfigRetrievalMaxDepth(): string {\r\n const param = UrlUtility.getQueryParameterByName(\"maxDepth\", getLocationHref());\r\n if (param) {\r\n return param;\r\n }\r\n\r\n // PCS flag for maxDepth\r\n if (appEnvironment.FeatureFlags\r\n && appEnvironment.FeatureFlags.crsMaxDepth) {\r\n return appEnvironment.FeatureFlags.crsMaxDepth;\r\n }\r\n\r\n // Config service to use this default to parse depth of config tree.\r\n return \"10\";\r\n }\r\n\r\n /**\r\n * Function checks if url has any dev only query string param\r\n * @returns true if exist else false.\r\n */\r\n public containsDevOnlyQueryParameters(): boolean {\r\n const urlQuery = getLocationSearch();\r\n const item = UrlUtility.getQueryParameterByName(\"item\", urlQuery);\r\n if (item && item.length > 0) {\r\n return true;\r\n }\r\n\r\n const segment = UrlUtility.getQueryParameterByName(\"pcsonly\", urlQuery);\r\n if (segment && segment.length > 0) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Returns resolver errors if any.\r\n * @returns resolverErrors\r\n */\r\n public getResolverErrors(): AppError[] {\r\n return this.resolverErrors;\r\n }\r\n\r\n /**\r\n * Refresh configs in indexedDb. Next time users visits the page within 3 days, we will get configs from indexedDB first\r\n * After TTVR we will background refresh them in web worker through this function.\r\n * If it more than 3 days, we won't use indexedDb response in main thread, After TTVR, we will background refresh.\r\n * This is required to have latest configs in indexedDb\r\n */\r\n public async refreshConfigCache(): Promise {\r\n // If web worker is not enabled, do not refresh.\r\n if (!this.useWebWorkerToCache) {\r\n return;\r\n }\r\n\r\n try {\r\n // Send post message to web worker to refresh indexedDB.\r\n const wwResponse = await getFromWebWorker({ id: \"refreshconfigs\" });\r\n if (wwResponse\r\n && wwResponse.fetched\r\n && wwResponse.payload !== undefined\r\n && wwResponse.payload !== null) {\r\n\r\n // Receive payload as post message response containing whether configs are changed and live cache busting identifier.\r\n const refreshConfigResponse = wwResponse.payload;\r\n\r\n // Check if cached config and network config properties have any changes.\r\n this.purgeRenderCacheUponConfigChanges(refreshConfigResponse.configsEqual);\r\n\r\n // For Flight specific config resolution, we want to use cached configs only if flights match.\r\n try {\r\n localStorage.setItem(this.peregrineFlightsKey, this.peregrineFlights);\r\n } catch (e) {\r\n this.resolverErrors.push({\r\n ...ResolverAppErrors.PrgFlightLsWriteError,\r\n message: \"Error writing prg flights to localStorage\",\r\n pb: {\r\n ...ResolverAppErrors.PrgFlightLsWriteError.pb,\r\n customMessage: e\r\n }\r\n });\r\n }\r\n\r\n // Web worker queried CRS endpoint and got value latest liveCbId.\r\n // Write CBID into local storage.\r\n if (refreshConfigResponse.liveCbId) {\r\n const liveCbid = refreshConfigResponse.liveCbId.toString();\r\n this.writeCbidInLocalStorage(liveCbid);\r\n\r\n const pcsCbid = appEnvironment.CacheBustingIdentifier || \"\";\r\n const highestCbid = window._cbid || \"\";\r\n if (liveCbid !== pcsCbid\r\n || liveCbid !== highestCbid) {\r\n this.resolverErrors.push({\r\n ...ResolverAppErrors.DifferentCbid,\r\n message: \"Different Cbid detected than configured.\",\r\n pb: {\r\n ...ResolverAppErrors.DifferentCbid.pb,\r\n customMessage: `PcsCbid = ${pcsCbid}. HighestCbid = ${highestCbid}. LiveCbid = ${liveCbid}.`\r\n }\r\n });\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n this.resolverErrors.push({\r\n ...ResolverAppErrors.RefreshConfigCacheFailed,\r\n message: \"refreshConfigCache error\",\r\n pb: {\r\n ...ResolverAppErrors.RefreshConfigCacheFailed.pb,\r\n customMessage: e\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Function checks whether to enable or disable indexedDb in main using query string override.\r\n * @returns true if supported else false.\r\n */\r\n public enableIndexedDbInMainResolver(): boolean {\r\n const urlQuery = getLocationSearch();\r\n if (urlQuery) {\r\n const param = UrlUtility.getQueryParameterByName(\"enableIndexedDbInMainResolver\", urlQuery);\r\n if (param) {\r\n return param.toLocaleLowerCase() === \"true\";\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Function to check config is stale.\r\n * @returns true if stale else false.\r\n */\r\n public isConfigStale(storageTimestamp: number): boolean {\r\n if (!storageTimestamp) {\r\n return true;\r\n }\r\n\r\n // 259200000 = 3 days in milliseconds\r\n if ((this.stalenessCheckTimestamp - storageTimestamp) > 259200000) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Function to check config on server cache is stale\r\n * @returns true if stale else false.\r\n */\r\n public isServerCacheConfigStale(storageTimestamp: number): boolean {\r\n if (!storageTimestamp) {\r\n return true;\r\n }\r\n\r\n // 300000 = 5 minutes in milliseconds\r\n if ((this.stalenessCheckTimestamp - storageTimestamp) > SERVER_CACHE_CONFIG_STALENESS_TIMEOUT) {\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Removes relative path from url and returns Config Index Href.\r\n * Input Example: cms/api/amp/experienceConfigIndex/ABCD\r\n * @returns string. Example: ABCD\r\n */\r\n public removeCmsPathFromRelativeUrl(relativeUrl: string): string {\r\n return relativeUrl.replace(\"cms/api/amp/experienceConfigIndex/\", \"\");\r\n }\r\n\r\n /**\r\n * Removes cached config from IndexedDB.\r\n */\r\n public removeCachedConfig(relativeUrl: string): void {\r\n // check if web worker and indexedDb use is allowed.\r\n if (this.useWebWorkerToCache && this.useIndexedDb) {\r\n // Send post message to web worker.\r\n sendToWebWorker({ id: \"clearconfigcache\", payload: relativeUrl });\r\n } else {\r\n // If web worker is not allowed, remove all configs from indexedDb as they are all stored as a single row.\r\n this.clearConfigCache();\r\n }\r\n }\r\n\r\n /**\r\n * This helper function is used to clear cached configs\r\n * @returns Promise\r\n */\r\n public async clearConfigCache(): Promise {\r\n if (this.useIndexedDb) {\r\n try {\r\n await this.initializeIndexedDb();\r\n\r\n try {\r\n await this.indexedDb.clearObjects();\r\n logger.log(`${this.logPrefix()} Cleared all configs from indexedDb.`);\r\n } catch {\r\n logger.logError(`${this.logPrefix()} Failed to clear all configs from indexedDb`);\r\n }\r\n } catch {\r\n logger.logError(`${this.logPrefix()} Failed to initialize indexedDb`);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * For testing purpose to access what has been set for configServiceParameters\r\n */\r\n public getConfigServiceParameters(): string {\r\n return this.configServiceParameters;\r\n }\r\n\r\n /**\r\n * Adds an entry into the config timings for the given type and relative start time\r\n */\r\n public addConfigTiming(experienceType: string, startTime: number, type: \"network\" | \"cache\"): void {\r\n this.configTimings.push({\r\n experienceType,\r\n [type + \"FetchDuration\"]: performance.now() - startTime\r\n });\r\n }\r\n\r\n /**\r\n * Helper function to get Config Timings\r\n * @param pageTimings _pageTimings object\r\n */\r\n public getConfigTimings(pageTimings: any = {}, getAllConfigTimingsOverride = false): void {\r\n if (!this.configTimings) {\r\n return;\r\n }\r\n\r\n let allConfigsCacheDuration = 0;\r\n let allConfigsNetworkDuration = 0;\r\n for (const configTiming of this.configTimings) {\r\n // Instrument networkFetchDuration and cacheFetchDuration\r\n const experienceType = configTiming.experienceType.toLowerCase();\r\n const cacheFetchDuration = configTiming.cacheFetchDuration;\r\n const networkFetchDuration = configTiming.networkFetchDuration;\r\n\r\n if (experienceType === \"entrypoint\"\r\n || experienceType === \"river\"\r\n || experienceType === \"contentpreview\"\r\n // when appropriate debug flag is set, output all config timings.\r\n || appEnvironment.IsDebug\r\n || getAllConfigTimingsOverride) {\r\n\r\n // Instrumenting networkFetchDuration to check effectiveness of get Config over the network for FRE.\r\n if (networkFetchDuration !== undefined) {\r\n pageTimings[\"ConfigFetch.\" + experienceType] = Math.round(networkFetchDuration);\r\n }\r\n\r\n // Instrumenting cacheFetchDuration to check effectiveness of storing merged config since it will be always used in non FRE.\r\n if (cacheFetchDuration !== undefined) {\r\n pageTimings[\"ConfigCache.\" + experienceType] = Math.round(cacheFetchDuration);\r\n }\r\n }\r\n\r\n if (cacheFetchDuration !== undefined) {\r\n allConfigsCacheDuration += cacheFetchDuration;\r\n }\r\n\r\n if (networkFetchDuration !== undefined) {\r\n allConfigsNetworkDuration += networkFetchDuration;\r\n }\r\n }\r\n\r\n if (allConfigsCacheDuration) {\r\n pageTimings[\"ConfigCache.All\"] = Math.round(allConfigsCacheDuration);\r\n }\r\n\r\n if (allConfigsNetworkDuration) {\r\n pageTimings[\"ConfigFetch.All\"] = Math.round(allConfigsNetworkDuration);\r\n }\r\n }\r\n\r\n /**\r\n * UNIT TEST PURPOSE: Function to set configTimings\r\n * @param ConfigFetchTiming[]\r\n */\r\n public setConfigTimingsObject(configFetchTimings: ConfigFetchTiming[]): void {\r\n this.configTimings = configFetchTimings;\r\n }\r\n\r\n /**\r\n * Get the cache key based on confix index url and the target scope generated suffix.\r\n * @param relativeUrl The config url\r\n * @returns The unique cache key for the merged config + target scope combination.\r\n */\r\n public getCacheKey(relativeUrl: string): string {\r\n return relativeUrl === null ? null : this.removeCmsPathFromRelativeUrl(relativeUrl) + \"_\" + this.storageKey;\r\n }\r\n\r\n /**\r\n * Read CBID in client settings and also look up same in local storage. Use the highest number as CBID.\r\n * @param clientSettingsCbid - cbid from client settings\r\n * @param appType - appType passed by PCS in client settings\r\n * @returns Highest cbid from client settings and local storage\r\n */\r\n public getHighestCbid(clientSettingsCbid, appType?): void {\r\n try {\r\n const pcsCbid = parseInt(clientSettingsCbid);\r\n const cachedCbid = parseInt(JSON.parse(localStorage.getItem(`cbid_${appType || \"\"}`)));\r\n let cbid;\r\n\r\n if (pcsCbid\r\n && !isNaN(pcsCbid)\r\n && cachedCbid\r\n && !isNaN(cachedCbid)) {\r\n cbid = pcsCbid > cachedCbid ? pcsCbid : cachedCbid;\r\n }\r\n\r\n cbid = cbid || pcsCbid || cachedCbid;\r\n if (cbid) {\r\n return (window._cbid = cbid.toString());\r\n }\r\n\r\n return undefined;\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Get cached Configs from IndexedDb and populate configMap based on target scope key.\r\n */\r\n private async _populateConfigMapFromIndexedDbAsync(): Promise {\r\n\r\n let cacheSource: string;\r\n\r\n try {\r\n // Check if indexedDb is present, if not return.\r\n // Check if web worker is present, if not, indexedDb will not be refreshed since refreshConfigCache uses post message to web worker.\r\n // so you may get stale configs within 3 days of time range so this check is essential as well.\r\n // Check if we've previously attempted to read from IDB, and if don't do it again.\r\n if (!this.useIndexedDb || !this.useWebWorkerToCache) {\r\n return;\r\n }\r\n\r\n // For Flight specific config resolution, we want to use cached configs only if flights match.\r\n try {\r\n const prgFlights = localStorage.getItem(this.peregrineFlightsKey);\r\n if (prgFlights\r\n && this.peregrineFlights\r\n && prgFlights !== this.peregrineFlights) {\r\n\r\n // Reverse flight: if cached configs are for different flight, throw app error.\r\n if (this.peregrineFlights.indexOf(\"prg-lsconfigs\") >= 0) {\r\n this.resolverErrors.push({\r\n ...CachedConfigsForDifferentFlight,\r\n message: \"Cached configs are for different flight\"\r\n });\r\n }\r\n\r\n // DO NOT USE CACHED CONFIGS SINCE FLIGHTS ARE NOT SAME\r\n // SO CONFIG RESOLUTION MAY LEAD TO INCONSISTENT BEHAVIOR\r\n return;\r\n }\r\n } catch (e) {\r\n this.resolverErrors.push({\r\n ...ResolverAppErrors.PrgFlightLsReadError,\r\n message: \"Error reading prg flights from localStorage\",\r\n pb: {\r\n ...ResolverAppErrors.PrgFlightLsReadError.pb,\r\n customMessage: e\r\n }\r\n });\r\n }\r\n\r\n const startBulkConfig = performance.now();\r\n\r\n this.configMap.clear();\r\n let cachedConfigs: CachedConfigsType;\r\n\r\n // Optionally pre-initialized IDB config read promise at the top page level\r\n const { _idbConfigReadPromise, _idbConfigLookup } = window;\r\n\r\n // Check if we have a top page-level initialized IDB read config lookup populated\r\n // with the specific entry we need, and if so use it. Otherwise proceed to load from indexDB\r\n cachedConfigs = (_idbConfigLookup || {})[this.storageKey] as CachedConfigsType;\r\n if (cachedConfigs) {\r\n\r\n cacheSource = \"pre-initialized config cache\";\r\n\r\n } else if (_idbConfigReadPromise) {\r\n // see if we have the pre-initialized config read promise from IDB, and if so\r\n // await on that instead of starting our own duplicate IDB init/read.\r\n\r\n cacheSource = \"pre-initialized IndexedDb read\";\r\n await _idbConfigReadPromise;\r\n cachedConfigs = (window._idbConfigLookup || {})[this.storageKey] as CachedConfigsType;\r\n\r\n } else {\r\n\r\n // start our own IDB read.\r\n cacheSource = \"IndexedDb bulk read\";\r\n await this.initializeIndexedDb();\r\n cachedConfigs = await this.indexedDb.getObject(this.storageKey);\r\n }\r\n\r\n if (!cachedConfigs || cachedConfigs.size === 0) {\r\n logger.log(`${this.logPrefix()} Bulk read of configs from ${cacheSource} didn't find any configs.`);\r\n return;\r\n }\r\n\r\n this.populateConfigMapFromCachedConfigs(cachedConfigs, cacheSource);\r\n this.addConfigTiming(\"IdbInitAndReadAll\", startBulkConfig, \"cache\");\r\n\r\n } catch (e) {\r\n this.resolverErrors.push({\r\n ...ResolverAppErrors.IndexedDbBulkReadFailed,\r\n message: \"IndexedDb bulk read failed\",\r\n pb: {\r\n ...ResolverAppErrors.IndexedDbBulkReadFailed.pb,\r\n customMessage: `IndexedDb bulk read from ${cacheSource} failed. Error: ${e}`\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Initialize indexedDb for configs. Instead of using this directly, please use the memoized\r\n * initializeIndexedDb function instead to avoid re-entrancy of the same async operation.\r\n */\r\n private async _initializeIndexedDb(): Promise {\r\n if (!this.useIndexedDb) {\r\n return;\r\n }\r\n\r\n try {\r\n // IMPORTANT!! The wwConfigs name must be in sync with the PCS script that initializes the IDB and WebWorkerResolver\r\n const { _idbConfigOpenPromise } = window;\r\n await this.indexedDb.initializeIndexedDb(1, \"Configurations_12\", \"wwConfigs\", _idbConfigOpenPromise);\r\n logger.log(`${this.logPrefix()} IndexedDb initialized in main thread.`);\r\n } catch (e) {\r\n this.resolverErrors.push({\r\n ...ResolverAppErrors.IndexedDbInitFailed,\r\n message: \"IndexedDb initialization failed\",\r\n pb: {\r\n ...ResolverAppErrors.IndexedDbInitFailed.pb,\r\n customMessage: e\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Populates the in-memory map object with the configs from cache\r\n */\r\n private populateConfigMapFromCachedConfigs(cachedConfigs: CachedConfigsType, cacheSource: string): void {\r\n\r\n // targetScopeKey is inserted into IndexedDb along with configIndexHref.\r\n // Although there can be more than type of keys being formed since DHP and NTP will have different ones due to pageType in targetScope.\r\n let unusableCount = 0;\r\n\r\n cachedConfigs.forEach(cachedConfig => {\r\n if (!cachedConfig.configIndexHref\r\n || this.isConfigStale(cachedConfig.storageTimestamp)) {\r\n\r\n unusableCount++;\r\n } else {\r\n const cacheKey = this.getCacheKey(cachedConfig.configIndexHref);\r\n\r\n this.configMap.set(cacheKey, cachedConfig);\r\n }\r\n });\r\n\r\n logger.log(`${this.logPrefix()} Found ${cachedConfigs.size - unusableCount} valid configs out of ${cachedConfigs.size} from ${cacheSource}`);\r\n }\r\n\r\n /**\r\n * Prefix for config resolver logs. Server side add the request id.\r\n * @returns the prefix string for logger message.\r\n */\r\n private logPrefix(): string {\r\n // Request Id is only available on server side.\r\n return `Config Resolver:${(canUseDOM() ? \"\" : ` [Request:${getRequestData().requestId}]`)}`;\r\n }\r\n\r\n /**\r\n * Write given CBID in local storage\r\n * @param cbid Cache busting identifier\r\n */\r\n private writeCbidInLocalStorage(cbid: string): void {\r\n const cbidKey = `cbid_${appEnvironment.AppType || \"\"}`;\r\n try {\r\n localStorage.setItem(cbidKey, cbid);\r\n } catch (e) {\r\n throw `Error writing cbid: ${cbid} to local storage with key ${cbidKey}. Error: ${e}`;\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Config Timings type to determine how much time each experience took to getConfig\r\n */\r\ninterface ConfigFetchTiming {\r\n /**\r\n * Experience Type\r\n */\r\n experienceType: string,\r\n\r\n /**\r\n * Time took to get configs over the network and merge them.\r\n */\r\n networkFetchDuration?: number,\r\n\r\n /**\r\n * Time took to get merged configs from cache.\r\n */\r\n cacheFetchDuration?: number\r\n}\r\n\r\n/**\r\n * Typed object containing boolean flag that tells if configs are equal and live cbid. This type comes are response from web worker to refresh config message.\r\n */\r\ninterface RefreshConfigsResponse {\r\n /**\r\n * True if configs are equal\r\n */\r\n configsEqual?: boolean;\r\n\r\n /**\r\n * CBID (cache busting identifier) from live document\r\n */\r\n liveCbId?: number;\r\n}\r\n\r\n/** Resolver Singleton */\r\nlet _instance: Resolver = new Resolver();\r\n\r\n/** Reinitialize the singleton class instance. */\r\nexport function resetInstance(): void {\r\n _instance = new Resolver();\r\n}\r\n\r\nexport const resolver = {\r\n getConfig: (relativeUrl: string) => { return _instance.getConfig(relativeUrl); },\r\n mergeConfig: (configs: IExperienceConfig[]) => { return _instance.mergeConfig(configs); },\r\n resolveConfigIndex: (configIndex: IExperienceConfigIndex) => { return _instance.resolveConfigIndex(configIndex); },\r\n targetScopeMatched: (experienceRef: IExperienceConfigLink) => { return _instance.targetScopeMatched(experienceRef); },\r\n getConfigTimings: (pageTimings: any = {}, getAllConfigTimingsOverride = false) => { return _instance.getConfigTimings(pageTimings, getAllConfigTimingsOverride); },\r\n getResolverErrors: () => { return _instance.getResolverErrors(); },\r\n refreshConfigCache: () => { return _instance.refreshConfigCache(); },\r\n removeCachedConfig: (relativeUrl: string) => { return _instance.removeCachedConfig(relativeUrl); },\r\n clearConfigCache: () => { return _instance.clearConfigCache(); },\r\n getInstance: () => { return _instance; },\r\n\r\n // these are test specific exports\r\n overrideConfig: (relativeUrl: string, experienceType: string, config: any) => { return _instance.overrideConfig(relativeUrl, experienceType, config); },\r\n overrideCurrentRequestTargetScope: (targetScope: PageRequestTargetScope) => { return _instance.overrideCurrentRequestTargetScope(targetScope); },\r\n overrideCurrentRequestEnvironment: (overrideEnv: Environment) => { return _instance.overrideCurrentRequestEnvironment(overrideEnv); },\r\n generateKey: () => { return _instance.generateKey(); },\r\n clearInternalState: () => { return _instance.clearInternalState(); },\r\n initializeCaching: (idb?: IndexedDb, cbid?: string) => { return _instance.initializeCaching(idb, cbid); },\r\n getConfigServiceParameters: () => { return _instance.getConfigServiceParameters(); },\r\n setConfigTimingsObject: (configFetchTimings: ConfigFetchTiming[]) => { return _instance.setConfigTimingsObject(configFetchTimings); },\r\n getHighestCbid: (clientSettingsCbid: string, appType?: string) => { return _instance.getHighestCbid(clientSettingsCbid, appType); }\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { pageRevealStartMarker, timeToFunctional, timeToVideoStart, timeToVisuallyReady } from \"./PerfMarkerConstants\";\r\n\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\nimport { isNullOrUndefined } from \"util\";\r\nimport { perfMarker } from \"./PerfMarker\";\r\n\r\n/** Collection of marker names grouped by marker type */\r\nexport interface MarkerNames {\r\n /** Array of timeToFunctional names */\r\n TTF?: string[];\r\n\r\n /** Array of timeToVisualReady names */\r\n TTVR?: string[];\r\n\r\n /** Array of timeToPageReveal names */\r\n TTPR?: string[];\r\n}\r\n\r\n/** Enum for PerfMarkersGroup */\r\nexport enum PerfMarkersGroup {\r\n Primary = \"primary\",\r\n Secondary = \"secondary\"\r\n}\r\n\r\nlet remainingMarkers: Set;\r\nlet remainingSecondaryMarkers: Set;\r\nlet remainingTtvrMarkers: Set;\r\nlet remainingTtprMarkers: Set;\r\nlet ttvrMarkers: Set;\r\n\r\nlet ttvrPromise: Promise<[string, number][]>;\r\nlet resolveTtvrCallback: (markers: [string, number][]) => void;\r\n\r\nlet perfMarkerPromise: Promise<[string, number][]>;\r\nlet perfMarkerResolveCallback: (markers: [string, number][]) => void;\r\nlet secondaryPerfMarkerPromise: Promise<[string, number][]>;\r\nlet secondaryPerfMarkerResolveCallback: (markers: [string, number][]) => void;\r\n\r\nlet ttvsMarkerPromise: Promise<[string, number][]>;\r\nlet resolveTtvsCallback: (ttvs: [string, number][]) => void;\r\n\r\nlet ttprMarkerPromise: Promise<[string, number][]>;\r\nlet resolveTtprCallback: (ttpr: [string, number][]) => void;\r\n\r\n/** The markers map. Key is the experience name, e.g. \"River\". Value is the number of milliseconds it took to reach that marker. */\r\nlet primaryMarkers: Map = new Map();\r\n\r\n/** The secondary markers map. Key is the experience name, e.g. \"TTS.NativeAd\". Value is the number of milliseconds it took to reach that marker. */\r\nlet secondaryMarkers: Map = new Map();\r\n\r\nconst ttfPrefix = \"TTF.\";\r\nconst ttvrPrefix = \"TTVR.\";\r\nconst ttvsPrefix = \"TTVS.\";\r\nconst ttprPrefix = \"TTPR.\";\r\n\r\nlet isSetMarkersCalled = false;\r\n\r\n/**\r\n * Saves the Time To Functional timestamp for the given marker and also marks the performance timeline.\r\n * If the same marker is added again, it overrides with the original marker.\r\n * @param name - The marker name\r\n * @param markTimeNA - To set -1 mark time for the TTF to resolve the dependency.\r\n * @param time - The elapsed time since window.performance.timing.navigationStart\r\n */\r\nexport function markTtf(name = \"\", markTimeNA = false, time?: number): void {\r\n if (canUseDOM()) {\r\n time = time || window.performance.now();\r\n return setMark(ttfPrefix, name, markTimeNA, time);\r\n }\r\n}\r\n\r\n/**\r\n * Saves the Time To Visually Ready timestamp for the given marker and also marks the performance timeline.\r\n * If the same marker is added again, it overrides with the original marker.\r\n * @param name - The marker name\r\n * @param markTimeNA - To set -1 mark time for the TTVR to resolve the dependency.\r\n * @param time - The elapsed time since window.performance.timing.navigationStart\r\n */\r\nexport function markTtvr(name = \"\", markTimeNA = false, time?: number): void {\r\n if (canUseDOM()) {\r\n time = time || window.performance.now();\r\n return setMark(ttvrPrefix, name, markTimeNA, time);\r\n }\r\n}\r\n\r\n/**\r\n * Helper that wraps the markTtvr call inside a request animation frame and setTimeout\r\n * with the idea that this will allow the experience time to render before setting the mark\r\n * @param name The marker name\r\n * @param markTimeNA To set -1 mark time for the TTVR to resolve the dependency\r\n * @param time - The elapsed time since window.performance.timing.navigationStart\r\n */\r\nexport function markTtvrRaf(name = \"\", markTimeNA = false, time?: number): void {\r\n if (canUseDOM()) {\r\n time = time || window.performance.now();\r\n window.requestAnimationFrame(() => {\r\n setTimeout(() => {\r\n markTtvr(name, markTimeNA, time);\r\n }, 0);\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * Saves the Time To Page Reveal timestamp for the given marker.\r\n * The call is inside a request animation frame and setTimeout,\r\n * with the idea that this will allow the experience time to render before setting the mark.\r\n * @param name The marker name\r\n */\r\nexport function markTtprRaf(name = \"\"): void {\r\n window.requestAnimationFrame(() => {\r\n setTimeout(() => {\r\n const startMarker = getSinglePerfMarkStartTimeByName(pageRevealStartMarker);\r\n const time = startMarker === -1\r\n ? -1\r\n : performance.now() - startMarker;\r\n\r\n setMark(ttprPrefix, name, false, time);\r\n }, 0);\r\n });\r\n\r\n if (!ttprMarkerPromise) {\r\n // add the promise\r\n waitForTtprMarkers();\r\n }\r\n}\r\n\r\n/**\r\n * Saves the Time to Video Start timestamp for the given marker and also marks the performance timeline.\r\n * If the same marker is added again, it overrides with the original marker.\r\n * @param name - The marker name\r\n * @param markTimeNA - To set -1 mark time for the TTVR to resolve the dependency.\r\n * @param time - The elapsed time since window.performance.timing.navigationStart\r\n */\r\nexport function markTtvs(name = \"\", markTimeNA = false, time?: number): void {\r\n if (canUseDOM()) {\r\n time = time || window.performance.now();\r\n return setMark(ttvsPrefix, name, markTimeNA, time);\r\n }\r\n}\r\n\r\n/**\r\n * Saves the time stamp for a given secondary perf marker.\r\n * @param markerName - The marker name\r\n * @param time - Time in milliseconds\r\n */\r\nexport function setSecondaryPerfMarkerTime(markerName: string, time?: number) {\r\n // return if the marker already exists.\r\n if (secondaryMarkers.get(markerName)) {\r\n return;\r\n }\r\n\r\n const existingMarker = performance.getEntriesByName && performance.getEntriesByName(markerName);\r\n const isMarkerSet = Boolean(existingMarker && existingMarker.length);\r\n\r\n if (!isMarkerSet) {\r\n perfMarker.singleMark(markerName);\r\n\r\n if (isNullOrUndefined(time)) {\r\n secondaryMarkers.set(markerName, -1);\r\n } else {\r\n secondaryMarkers.set(markerName, Math.round(time));\r\n }\r\n } else {\r\n secondaryMarkers.set(markerName, Math.round(existingMarker[0].startTime));\r\n }\r\n\r\n // Notify any callers waiting for reports\r\n if (remainingSecondaryMarkers && remainingSecondaryMarkers.delete(markerName) && remainingSecondaryMarkers.size === 0 && secondaryPerfMarkerResolveCallback) {\r\n secondaryPerfMarkerResolveCallback(getSecondaryMarkers());\r\n }\r\n}\r\n\r\n/**\r\n * Saves the timestamp for the given marker and also marks the performance timeline.\r\n * If the same marker is added again, it overrides with the original marker.\r\n * @param name - The marker name\r\n * @param markTimeNA - To set -1 mark time for the ttvr to resolve the dependency.\r\n * @param time - The elapsed time since window.performance.timing.navigationStart\r\n */\r\nfunction setMark(prefix: string, name: string, markTimeNA: boolean, time: number): void {\r\n if (!(name && name.length)) {\r\n return;\r\n }\r\n\r\n if (!(prefix && prefix.length)) {\r\n return;\r\n }\r\n\r\n const markerFullName = prefix + name;\r\n\r\n // To check if the marker exists then return.\r\n if (primaryMarkers.get(markerFullName)) {\r\n return;\r\n }\r\n\r\n const existingMarker = performance.getEntriesByName && performance.getEntriesByName(markerFullName);\r\n const isMarkerSet = Boolean(existingMarker && existingMarker.length);\r\n\r\n if (!isMarkerSet) {\r\n perfMarker.singleMark(markerFullName);\r\n\r\n if (markTimeNA) {\r\n primaryMarkers.set(markerFullName, -1);\r\n } else {\r\n primaryMarkers.set(markerFullName, Math.round(time));\r\n }\r\n } else {\r\n primaryMarkers.set(markerFullName, Math.round(existingMarker[0].startTime));\r\n }\r\n\r\n // Notify any callers waiting for TTVR reports\r\n if (remainingTtvrMarkers && remainingTtvrMarkers.delete(markerFullName) && remainingTtvrMarkers.size === 0 && resolveTtvrCallback) {\r\n resolveTtvrCallback(getTtvrMarkers());\r\n }\r\n\r\n // Notify any callers waiting for reports\r\n if (remainingMarkers && remainingMarkers.delete(markerFullName) && remainingMarkers.size === 0 && perfMarkerResolveCallback) {\r\n perfMarkerResolveCallback(getMarkers());\r\n }\r\n\r\n // Resolve TTVS if this is ttvs. TTVS only need one time to mark instead of multiple markers.\r\n if (prefix === ttvsPrefix && resolveTtvsCallback) {\r\n resolveTtvsCallback(getTtvsMarkers());\r\n }\r\n\r\n // Notify any callers waiting for TTPR reports\r\n if (prefix === ttprPrefix\r\n && remainingTtprMarkers\r\n && remainingTtprMarkers.delete(markerFullName)\r\n && remainingTtprMarkers.size === 0 && resolveTtprCallback) {\r\n resolveTtprCallback(getMarkers());\r\n }\r\n}\r\n\r\n/**\r\n * Sets the collection of primary perf markers to use for waitForAllPerfMarkers, waitForTtvr .\r\n * @param markerNames The collection of primary TTF and TTVR perf markers.\r\n */\r\nexport function setMarkers(markerNames: MarkerNames): void {\r\n remainingMarkers = getRemainingMarkers(markerNames);\r\n remainingTtvrMarkers = getRemainingMarkers(markerNames, \"TTVR\");\r\n remainingTtprMarkers = getRemainingMarkers(markerNames, \"TTPR\");\r\n ttvrMarkers = new Set(flattenMarkerNames(markerNames, \"TTVR\"));\r\n\r\n if (resolveTtvrCallback && remainingTtvrMarkers.size === 0) {\r\n perfMarkerResolveCallback(getTtvrMarkers());\r\n }\r\n\r\n if (perfMarkerResolveCallback && remainingMarkers.size === 0) {\r\n perfMarkerResolveCallback(getMarkers());\r\n }\r\n\r\n isSetMarkersCalled = true;\r\n}\r\n\r\n/**\r\n * Sets the collection of secondary perf markers to use for waitForAllSecondaryPerfMarkers. Should be called only once.\r\n * @param markerNames The collection of secondary perf markers that are required.\r\n */\r\nexport function setRequiredSecondaryMarkers(markerNames: string[]): void {\r\n // Return if remainingSecondaryMarkers is already set. This means setRequiredSecondaryMarkers was already called.\r\n if (remainingSecondaryMarkers) {\r\n return;\r\n }\r\n\r\n remainingSecondaryMarkers = new Set();\r\n\r\n markerNames.forEach(markerName => {\r\n if (!secondaryMarkers.get(markerName)) {\r\n remainingSecondaryMarkers.add(markerName);\r\n }\r\n });\r\n\r\n // If there are no required secondary perf markers, immediately resolve the promise\r\n if (remainingSecondaryMarkers.size === 0 && secondaryPerfMarkerResolveCallback) {\r\n secondaryPerfMarkerResolveCallback(getSecondaryMarkers());\r\n }\r\n}\r\n\r\n/**\r\n * Determines whether setMarkers has been called.\r\n */\r\nexport function setMarkersCalled(): boolean {\r\n return isSetMarkersCalled;\r\n}\r\n\r\n/**\r\n * Adds marker to the remainingTtvrMarkers\r\n * Here for the case where the marker cannot be added in experience tracker\r\n * Example: Stripe layout - since we don't know if user has that layout selected\r\n * until later (in layoutPreferenceData connector)\r\n *\r\n * @export\r\n * @param {string} markerName\r\n * @returns {void}\r\n */\r\nexport function addTtvrMarker(markerName: string): void {\r\n if (!markerName || !isSetMarkersCalled || !remainingMarkers || !remainingTtvrMarkers) {\r\n return;\r\n }\r\n\r\n remainingMarkers.add(markerName);\r\n remainingTtvrMarkers.add(markerName);\r\n}\r\n\r\n/**\r\n * Waits for the all perf markers supplied to setMarkers() to be logged.\r\n * @returns A promise with all of the TTF and TTVR perf markers, including the overall page marker\r\n */\r\nexport function waitForAllPerfMarkers(): Promise<[string, number][]> {\r\n return waitForPerfMarkers();\r\n}\r\n\r\n/**\r\n * Waits for the all perf markers supplied to setMarkers() to be logged.\r\n * @returns A promise with all of the TTF and TTVR perf markers, including the overall page marker\r\n */\r\nexport function waitForAllSecondaryPerfMarkers(): Promise<[string, number][]> {\r\n\r\n // If we have a promise, return it. It may already be completed.\r\n if (secondaryPerfMarkerPromise) {\r\n return secondaryPerfMarkerPromise;\r\n }\r\n\r\n if (!remainingSecondaryMarkers || remainingSecondaryMarkers.size === 0) {\r\n return Promise.resolve(getSecondaryMarkers());\r\n }\r\n\r\n // If the markers are not yet declared or are incomplete, set up a promise to resolve when they are all done.\r\n secondaryPerfMarkerPromise = new Promise<[string, number][]>(resolve => {\r\n secondaryPerfMarkerResolveCallback = resolve;\r\n });\r\n\r\n return secondaryPerfMarkerPromise;\r\n}\r\n\r\n/**\r\n * Waits for the TTVR markers supplied to setMarkers() to be logged.\r\n * @returns A promise with the TTVR perf markers, including the overall page TTVR marker\r\n */\r\nexport function waitForTtvr(): Promise<[string, number][]> {\r\n // If we have a promise, return it. It may already be completed.\r\n if (ttvrPromise) {\r\n return ttvrPromise;\r\n }\r\n\r\n if (remainingTtvrMarkers && remainingTtvrMarkers.size === 0) {\r\n return Promise.resolve(getTtvrMarkers());\r\n }\r\n\r\n // If the markers are not yet declared or are incomplete, set up a promise to resolve when they are all done.\r\n ttvrPromise = new Promise<[string, number][]>(resolve => {\r\n resolveTtvrCallback = resolve;\r\n });\r\n\r\n return ttvrPromise;\r\n}\r\n\r\n/**\r\n * Waits for the perf markers supplied to setMarkers() to be logged.\r\n * @returns A promise with all of the TTF and TTVR perf markers, including the overall page marker\r\n */\r\nfunction waitForPerfMarkers(): Promise<[string, number][]> {\r\n // If we have a promise, return it. It may already be completed.\r\n if (perfMarkerPromise) {\r\n return perfMarkerPromise;\r\n }\r\n\r\n if (remainingMarkers && remainingMarkers.size === 0) {\r\n return Promise.resolve(getMarkers());\r\n }\r\n\r\n // If the markers are not yet declared or are incomplete, set up a promise to resolve when they are all done.\r\n perfMarkerPromise = new Promise<[string, number][]>(resolve => {\r\n perfMarkerResolveCallback = resolve;\r\n });\r\n\r\n return perfMarkerPromise;\r\n}\r\n\r\n/**\r\n * Wait for the ttvs marker to be logged\r\n * @returns A promise with TTVS perf time in ms\r\n */\r\nexport function waitForTtvsMarker(): Promise<[string, number][]> {\r\n if (ttvsMarkerPromise) {\r\n return ttvsMarkerPromise;\r\n }\r\n\r\n ttvsMarkerPromise = new Promise<[string, number][]>(resolve => {\r\n resolveTtvsCallback = resolve;\r\n });\r\n\r\n return ttvsMarkerPromise;\r\n}\r\n\r\n/**\r\n * Wait for the ttpr marker to be logged\r\n * @returns A promise with TTPR perf time in ms\r\n */\r\nexport function waitForTtprMarkers(): Promise<[string, number][]> {\r\n if (ttprMarkerPromise) {\r\n return ttprMarkerPromise;\r\n }\r\n\r\n ttprMarkerPromise = new Promise<[string, number][]>(resolve => {\r\n resolveTtprCallback = resolve;\r\n });\r\n\r\n return ttprMarkerPromise;\r\n}\r\n\r\n/**\r\n * Returns TTVR of given entry if exists in markers array\r\n * @param entryName the entry name for the marker eg. \"TTVR.xx\" or just \"TTVR\"\r\n * @returns the TTVR value for that entry name OR undefined if entry does not exist\r\n */\r\nexport function getTtvrOfEntry(entryName: string): number {\r\n const ttvrMarkers = getTtvrMarkers();\r\n const marker = ttvrMarkers.find((mark) => mark[0] === entryName) || [];\r\n\r\n return marker[1];\r\n}\r\n\r\n/**\r\n * Returns array of markers, including the page-level marker. For example:\r\n * Note: didn't add TTVS in getMarkers because TTVS only applies to specific page type and special cases.\r\n * It could be fired way after in the page cycle.\r\n * [[\"TTVR.Search\", 100], [\"TTVR.TopSites\", 100.123], [\"TTVR.River\", 100.504], [\"TTVR\", 100.504]]\r\n * @returns The array of markers\r\n */\r\nexport function getMarkers(): [string, number][] {\r\n const ttvrResults = getTtvrMarkers();\r\n const ttfResults = getTtfMarkers();\r\n const result: [string, number][] = [...ttvrResults, ...ttfResults];\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Returns array of secondary markers. E.g.:\r\n * [[\"TTS.NativeAd\", 3300], [\"TTS.SearchHistory\", 2100]]\r\n * @returns The array of secondary markers\r\n */\r\nexport function getSecondaryMarkers(): [string, number][] {\r\n const result: [string, number][] = [];\r\n\r\n secondaryMarkers.forEach((value: number, key: string) => {\r\n result.push([key, value]);\r\n });\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Returns array of markers that are yet to be completed.\r\n * @returns The array of incomplete markers\r\n */\r\nexport function getIncompleteMarkers(perfMarkersGroup: PerfMarkersGroup): string[] {\r\n return perfMarkersGroup === PerfMarkersGroup.Primary\r\n ? Array.from(remainingMarkers || [])\r\n : Array.from(remainingSecondaryMarkers || []);\r\n}\r\n\r\n/**\r\n * Returns markers yet to be set\r\n * @param markerNames The names of the markers to check. e.g. { TTVR: [\"River\", \"TopSites\"], TTF: [\"SearchBox\"] }\r\n * @param markerType The type of markers to return \"TTVR\", \"TTF\", or if undefined all\r\n * @returns The set of markers that have not yet been set.\r\n */\r\nfunction getRemainingMarkers(markerNames: MarkerNames, markerType?: string): Set {\r\n const result: Set = new Set();\r\n for (const markerName of flattenMarkerNames(markerNames, markerType)) {\r\n if (!primaryMarkers.get(markerName)) {\r\n result.add(markerName);\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n* Returns TTPR of given entry if exists in markers array\r\n* @param expType - key for experience\r\n* @returns the TTVR value for that entry name OR undefined if entry does not exist\r\n*/\r\nexport function getExperienceTtpr(expType: string): number {\r\n const ttprMarkers = getTtprMarkers();\r\n const marker = ttprMarkers.find((mark) => mark[0].includes(expType)) || [];\r\n\r\n return marker[1];\r\n}\r\n\r\n/**\r\n* Returns array of TTPR markers, time to page reveal. For example:\r\n* [[\"TTPR.SearchBoxEdgeNext\", 120], [\"BackgroundImageEdgeNext\", 120]]\r\n* @returns The array of markers\r\n*/\r\nexport function getTtprMarkers(): [string, number][] {\r\n return getMarkersWithType(ttprPrefix);\r\n}\r\n\r\n/**\r\n * Returns array of TTF markers, including the page-level marker. For example:\r\n * [[\"TTF.Search\", 100], [\"TTF\", 100]]\r\n * @returns The array of markers\r\n */\r\nfunction getTtfMarkers(): [string, number][] {\r\n return getMarkersWithType(ttfPrefix);\r\n}\r\n\r\n/**\r\n * Returns array of TTVR markers, including the page-level marker. For example:\r\n * [[\"TTVR.Search\", 100], [\"TTVR.TopSites\", 100.123], [\"TTVR.River\", 100.504], [\"TTVR\", 100.504]]\r\n * @returns The array of markers\r\n */\r\nfunction getTtvrMarkers(): [string, number][] {\r\n return getMarkersWithType(ttvrPrefix, timeToVisuallyReady);\r\n}\r\n\r\n/**\r\n * Returns array of TTVS markers, including the page-level marker. For example:\r\n * [[\"TTVS.VideoContent\", 1200], [\"TTVS\", 1200]]\r\n * @returns The array of markers\r\n */\r\nfunction getTtvsMarkers(): [string, number][] {\r\n return getMarkersWithType(ttvsPrefix, timeToVideoStart);\r\n}\r\n\r\n/**\r\n * Returns array of a provided markers based on markerName, optionally including the page-level marker.\r\n * @param markerPrefix the marker prefix for the markers\r\n * @param markerName the optional page-level markerName\r\n * @returns The array of markers\r\n */\r\nfunction getMarkersWithType(markerPrefix: string, markerName?: string) {\r\n const result: [string, number][] = [];\r\n let maxValue = 0;\r\n primaryMarkers.forEach((value: number, key: string) => {\r\n if (key.startsWith(markerPrefix)) {\r\n result.push([key, value]);\r\n\r\n // Only include value in max TTVR when added to ttvrMarkers in setMarkers()\r\n if (value > maxValue && (!key.startsWith(\"TTVR\") || ttvrMarkers.has(key))) {\r\n maxValue = value;\r\n }\r\n }\r\n });\r\n\r\n // Add the max, overall marker at the end\r\n if (markerName) {\r\n result.push([markerName, maxValue]);\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Put marker names into a expanded/flattened array [ \"TTVR.River\", \"TTVR.TopSites\", \"TTF.SearchBox\" ]\r\n * @param markerNames The names of the markers to check. e.g. { TTVR: [ \"River\", \"TopSites\" ], TTF: [ \"SearchBox\" ] }\r\n * @param markerType The type of markers to return \"TTVR\", \"TTF\", or if undefined all\r\n */\r\nfunction flattenMarkerNames(markerNames: MarkerNames, markerType: string): string[] {\r\n let ttvr: string[] = [];\r\n let ttpr: string[] = [];\r\n let ttf: string[] = [];\r\n\r\n if (markerNames && markerNames.TTVR && (!markerType || markerType === \"TTVR\")) {\r\n ttvr = markerNames.TTVR.map((n) => { return ttvrPrefix + n; });\r\n }\r\n\r\n if (markerNames && markerNames.TTF && (!markerType || markerType === \"TTF\")) {\r\n ttf = markerNames.TTF.map((n) => { return ttfPrefix + n; });\r\n }\r\n\r\n if (markerNames && markerNames.TTPR && markerType === \"TTPR\") {\r\n ttpr = markerNames.TTPR.map((n) => { return ttprPrefix + n; });\r\n }\r\n\r\n return [...ttvr, ...ttf, ...ttpr];\r\n}\r\n\r\n/**\r\n * helper method to get performance mark name.\r\n * @param markerName - performance mark name\r\n */\r\nfunction getSinglePerfMarkStartTimeByName(markerName: string): number {\r\n const perfMarks = window.performance.getEntriesByName(markerName);\r\n if (perfMarks && perfMarks[0] && perfMarks[0].startTime) {\r\n return perfMarks[0].startTime;\r\n }\r\n\r\n return -1;\r\n}\r\n\r\n/**\r\n * Reset the markers object singleton for test environments\r\n */\r\nexport function resetMarkersForTest(): void {\r\n primaryMarkers = new Map();\r\n secondaryMarkers = new Map();\r\n isSetMarkersCalled = false;\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Time To Functional\r\n */\r\nexport const timeToFunctional = \"TTF\";\r\n\r\n/**\r\n * Time To Page Visible\r\n */\r\nexport const timeToPageVisible = \"TTPV\";\r\n\r\n/**\r\n * Time To Visually Ready\r\n */\r\nexport const timeToVisuallyReady = \"TTVR\";\r\n\r\n/**\r\n * Time To Video Start\r\n */\r\nexport const timeToVideoStart = \"TTVS\";\r\n\r\n/**\r\n * pageTiming cacheKey for html cached state\r\n */\r\nexport const htmlCachedKey = \"htmlCached\";\r\n\r\n/**\r\n * Page reveal start performance marker\r\n */\r\nexport const pageRevealStartMarker = \"pageRevealStart\";\r\n\r\n/**\r\n * Page reveal complete performance marker\r\n */\r\nexport const pageRevealCompleteMarker = \"pageRevealComplete\";\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * class defining perf trackers.\r\n */\r\nexport class PerfTracker {\r\n\r\n /** The perf tracker end time. */\r\n private endTime = -1;\r\n\r\n /** The perf tracker start time. */\r\n private startTime = -1;\r\n\r\n /**\r\n * Get perf tracker time duration\r\n */\r\n public getDuration(): number {\r\n let result = -1;\r\n if (this.startTime !== -1 && this.endTime !== -1) {\r\n result = this.endTime - this.startTime;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * get perf tracker end time\r\n */\r\n public getEnd(): number {\r\n return this.endTime;\r\n }\r\n\r\n /**\r\n * get perf tracker start time\r\n */\r\n public getStart(): number {\r\n return this.startTime;\r\n }\r\n\r\n /**\r\n * set perf tracker end time\r\n */\r\n public setEnd(): void {\r\n this.endTime = performance.now();\r\n }\r\n\r\n /**\r\n * set perf tracker start time\r\n */\r\n public setStart(): void {\r\n this.startTime = performance.now();\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport Foundation, { FoundationProps } from \"@microsoft/fast-components-foundation-react\";\r\nimport { IRequestContext, appEnvironment, headData } from \"@msnews/core\";\r\nimport { PerfTracker, getPageTimings, incrementCounter, logger, markTtf, markTtprRaf, markTtvr, markTtvrRaf } from \"@msnews/diagnostics\";\r\n\r\nimport { ExperienceMilestoneEventTypes } from \"@msnews/milestone-data\";\r\nimport { MnsCreatorDashboardAttributes } from \"./MnsCreatorDashboard.attributes\";\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\n\r\ndeclare global {\r\n interface Window {\r\n /**\r\n * Boolean flag to indicate if render cache hydration is happening\r\n */\r\n needsHydrate?: boolean;\r\n }\r\n}\r\n\r\n/** Type definition for the onExperienceMilestoneTimingUpdate callback */\r\nexport type ExperienceMilestoneTimingUpdate = (milestoneType: ExperienceMilestoneEventTypes,\r\n startTime?: number,\r\n endTime?: number) => void;\r\n\r\nconst pageTimings = getPageTimings();\r\n\r\n/** Type definition for the onExperienceMilestoneTimingUpdate callback */\r\nexport type ExperienceStaleRevalidationUpdate = (milestoneType: ExperienceMilestoneEventTypes) => void;\r\n\r\n/**\r\n * Internal interface used for detecting render counter related static properties\r\n * in Experience components. We use this to cast the object's constructor to see\r\n * if the custom render counter prefix is available to use to emit custom page timings.\r\n * Note that this interface is not meant to be explicitly extended, since we're trying to\r\n * to leverage static properties from the Experience component classes and interfaces are\r\n * not supported on static properties. This purely serves as a type definition so we can\r\n * access the static `renderCounterPrefix` property without typescript complaining about it.\r\n */\r\ninterface ExperienceStaticConstructor {\r\n /**\r\n * Optional custom render count marker prefix to use to log an additional count metric\r\n * in addition to the default render counters. Useful when you want to count a group of\r\n * similar experiences under a custom render counter group. Currently used by content\r\n * experiences to log the total number of content card renders before TTVR. This value\r\n * is used as an prefix value to form the final marker name. For example, a value of\r\n * \"XYZ\" would end up logging \"XYZExpRenderCount\" in addition to the default \"ExpRenderCount\"\r\n */\r\n renderCounterPrefix: string;\r\n}\r\n\r\n/**\r\n * Common props for all experiences\r\n */\r\nexport interface CommonExperienceProps {\r\n /** The experience name. */\r\n experienceName?: string;\r\n\r\n /** Custom Field per experience when sending beacon to Cosmos. */\r\n customField?: string;\r\n\r\n /** Request specific context */\r\n requestContext?: IRequestContext;\r\n\r\n /**\r\n * Handler function for Experience Milestone timing updates\r\n */\r\n onExperienceMilestoneTimingUpdate?: ExperienceMilestoneTimingUpdate;\r\n\r\n /**\r\n * boolean to indicate if experience is stale\r\n */\r\n isStale?: boolean;\r\n}\r\n\r\n/**\r\n * Helper to spread the default values for common experience props to all handled props fields.\r\n */\r\nexport const InitialCommonExperienceProps = {\r\n experienceName: undefined,\r\n customField: undefined,\r\n requestContext: undefined,\r\n onExperienceMilestoneTimingUpdate: undefined,\r\n isStale: undefined\r\n};\r\n\r\n/**\r\n * TODO: This class may need to be sampled collecting and sending Perf timings if the traffic goes beyond a certain reach.\r\n * Assessment will be performed later after analyzing the data.\r\n */\r\nexport class BaseExperience extends Foundation {\r\n /** Perf marker for tracking Visually Reading timing */\r\n protected visuallyReadyTracker: PerfTracker = new PerfTracker();\r\n\r\n protected componentRef: any;\r\n\r\n /** Perf marker for tracking Initialization timing */\r\n protected initializedTracker: PerfTracker = new PerfTracker();\r\n\r\n /** Perf marker for tracking DomComplete timing */\r\n protected domCompleteTracker: PerfTracker = new PerfTracker();\r\n\r\n /** boolean to indicate if stale state has been revalidated */\r\n private isStaleRevalidated = false;\r\n\r\n /**\r\n * The constructor.\r\n * @param props - The props\r\n * @param context - The context\r\n */\r\n constructor(props: H & U & CommonExperienceProps & FoundationProps, context?: any) {\r\n super(props);\r\n\r\n this.startInitializeMilestone();\r\n this.startVisuallyReadyMilestone();\r\n this.startDomCompleteMilestone();\r\n\r\n // This tracks the # of experiences that got instantiated on the page before TTVR marker happens.\r\n this.incrementExpCount(\"\");\r\n }\r\n\r\n /**\r\n * Default react hook.\r\n */\r\n public componentDidMount(): void {\r\n // End the domComplete milestone\r\n this.endDomCompleteMilestone();\r\n }\r\n\r\n /**\r\n * Default react hook.\r\n *\r\n * note: don't delete it, as it has different arity than the original react hook, and some components call it\r\n * with arity=0\r\n *\r\n * @param prevProps - previous component props\r\n * @param prevState - previous component state\r\n * @param snapshot - \"snapshot\" returned by getSnapshotBeforeUpdate() in React life cycle\r\n */\r\n public componentDidUpdate(\r\n prevProps: Readonly = undefined,\r\n prevState: Readonly = undefined,\r\n snapshot: any = undefined\r\n ): void {\r\n\r\n // End the domComplete milestone\r\n this.endDomCompleteMilestone();\r\n\r\n // complete stale revalidation\r\n this.completeStaleRevalidation();\r\n }\r\n\r\n /**\r\n * Default render function\r\n *\r\n * note: don't delete it, even if empty, as a bunch of code calls super.render()\r\n */\r\n public render(): any {\r\n logger.log(`Rendering ${(this.props as CommonExperienceProps).experienceName}. needsHydrate: ${canUseDOM() && window.needsHydrate}`);\r\n\r\n // End the initialized milestone, and start the domComplete milestone\r\n this.endInitializeMilestone();\r\n this.startDomCompleteMilestone();\r\n\r\n // This tracks the # of times all experiences on the page render before TTVR marker happens.\r\n this.incrementExpCount(\"Render\");\r\n }\r\n\r\n /**\r\n * Marks the Time To Visually Ready and optionally mark perf ttvr for telemetry.\r\n * @param shouldMarkTelemetryTtvr - Flag to opt out from from telemetry ttvr marker\r\n * @param time - Optional ttvr marker value, default value is current time\r\n * @param aliasName - Optional alias for TTVR marker name, default is no alias\r\n */\r\n public markTimeToVisuallyReady(shouldMarkTelemetryTtvr: boolean, time?: number, aliasName?: string): void {\r\n if (shouldMarkTelemetryTtvr) {\r\n if (time == undefined) {\r\n time = window.performance.now();\r\n }\r\n markTtvr(this.props.experienceName, false, time);\r\n if (aliasName) {\r\n markTtvr(aliasName, false, time);\r\n }\r\n }\r\n\r\n this.endVisuallyReadyMilestone();\r\n }\r\n\r\n /**\r\n * Mark perf ttf for telemetry.\r\n * @param aliasName - Optional alias for TTF marker name\r\n */\r\n public markTimeToFunctional(aliasName?: string): void {\r\n const t = window.performance.now();\r\n markTtf(this.props.experienceName, false, t);\r\n if (aliasName) {\r\n markTtf(aliasName, false, t);\r\n }\r\n }\r\n\r\n /**\r\n * Generate attributes for the mnsDashboard\r\n */\r\n protected mnsDashAttributes(): MnsCreatorDashboardAttributes {\r\n if (appEnvironment.ShowMnsCreatorDashboard) {\r\n const msnCreatorDashAttributes = {\r\n \"data-config-href\": this.props[\"data-config-href\"],\r\n \"data-experience-type\": this.props[\"data-experience-type\"]\r\n };\r\n return msnCreatorDashAttributes;\r\n } else {\r\n return null;\r\n }\r\n }\r\n\r\n /** Start the initialized perf timer, and mark the Initialized milestone start time */\r\n protected startInitializeMilestone(): void {\r\n this.initializedTracker.setStart();\r\n this.updateStartTiming(this.initializedTracker, ExperienceMilestoneEventTypes.initialized);\r\n }\r\n\r\n /** End the initialized perf timer, and mark the Initialized milestone end time */\r\n protected endInitializeMilestone(): void {\r\n this.updateEndTiming(this.initializedTracker, ExperienceMilestoneEventTypes.initialized);\r\n }\r\n\r\n /** Start the Visually Reader perf timer, and mark the VisuallyReady milestone start time */\r\n protected startVisuallyReadyMilestone(): void {\r\n this.updateStartTiming(this.visuallyReadyTracker, ExperienceMilestoneEventTypes.visuallyReady);\r\n }\r\n\r\n /** Complete Stale Revalidation */\r\n protected completeStaleRevalidation(): void {\r\n const { isStale } = this.props;\r\n if (isStale && !this.isStaleRevalidated) {\r\n this.isStaleRevalidated = true;\r\n this.markTimeToRevalidateStaleState();\r\n\r\n const { onExperienceMilestoneTimingUpdate } = this.props;\r\n if (onExperienceMilestoneTimingUpdate) {\r\n onExperienceMilestoneTimingUpdate(ExperienceMilestoneEventTypes.staleRevalidationComplete);\r\n }\r\n }\r\n }\r\n\r\n /** End the Visually Reader perf timer, and mark the VisuallyReady milestone end time */\r\n protected endVisuallyReadyMilestone(): void {\r\n this.updateEndTiming(this.visuallyReadyTracker, ExperienceMilestoneEventTypes.visuallyReady);\r\n }\r\n\r\n /** Start the DomComplete perf timer, and mark the DomComplete milestone start time */\r\n protected startDomCompleteMilestone(): void {\r\n this.updateStartTiming(this.domCompleteTracker, ExperienceMilestoneEventTypes.domComplete);\r\n }\r\n\r\n /** End the DomComplete perf timer, and mark the DomComplete milestone end time */\r\n protected endDomCompleteMilestone(): void {\r\n this.updateEndTiming(this.domCompleteTracker, ExperienceMilestoneEventTypes.domComplete);\r\n }\r\n\r\n /**\r\n * Mark perf pageReveal ttvr\r\n * @param aliasName - Optional alias for TTF marker name\r\n */\r\n private markTimeToRevalidateStaleState(shouldMarkPageReveal = true): void {\r\n if (shouldMarkPageReveal) {\r\n markTtprRaf(this.props.experienceName);\r\n }\r\n }\r\n\r\n /**\r\n * Helper to update the start timing for a given tracker & event type\r\n * @param tracker - the {PerfTracker} to update the start time\r\n * @param eventType - the milestone event type\r\n */\r\n private updateStartTiming(tracker: PerfTracker, eventType: ExperienceMilestoneEventTypes): void {\r\n\r\n tracker.setStart();\r\n\r\n const { onExperienceMilestoneTimingUpdate } = this.props;\r\n if (onExperienceMilestoneTimingUpdate) {\r\n onExperienceMilestoneTimingUpdate(eventType, tracker.getStart());\r\n }\r\n }\r\n\r\n /**\r\n * Helper to update end timing for a given tracker & event type\r\n * @param tracker - the {PerfTracker} to update the start time\r\n * @param eventType - the milestone event type\r\n */\r\n private updateEndTiming(tracker: PerfTracker, eventType: ExperienceMilestoneEventTypes): void {\r\n\r\n if (tracker.getEnd() !== -1) {\r\n return;\r\n }\r\n\r\n tracker.setEnd();\r\n\r\n const { onExperienceMilestoneTimingUpdate } = this.props;\r\n if (onExperienceMilestoneTimingUpdate) {\r\n onExperienceMilestoneTimingUpdate(eventType, undefined, tracker.getEnd());\r\n }\r\n }\r\n\r\n /**\r\n * Helper to increment render counter statistics on the _pageTimings object for a given marker name\r\n * Note that if the `renderCounterPrefix` static property is present on the Experience's component class,\r\n * this method will update the render counters for that custom counter name as well.\r\n * @param markerPrefix - the prefix of the marker to increment.\r\n */\r\n protected incrementExpCount(markerPrefix: string): void {\r\n\r\n // prevent counting in post-TTVR scenarios\r\n if (!pageTimings || pageTimings[\"TTVR\"]) {\r\n return;\r\n }\r\n\r\n incrementCounter(`Exp.${markerPrefix}Count`);\r\n\r\n const renderCounterPrefix = (this.constructor as unknown as ExperienceStaticConstructor).renderCounterPrefix;\r\n if (renderCounterPrefix) {\r\n incrementCounter(`Exp.${renderCounterPrefix}${markerPrefix}Count`);\r\n }\r\n }\r\n\r\n /**\r\n * Helper to add masking props for clarity.microsoft.com analytics tool\r\n * for elements containing personally identifiable info\r\n */\r\n protected clarityProps(): Object {\r\n\r\n // only add clarity mask props if clarity script is enabled and user is not signed in and there is no cookie wall banner\r\n if (appEnvironment.ClarityEnabled && !headData.UserIsSignedIn && !headData.ClientSettings.functionalonly_cookie_experience) {\r\n return {\r\n \"data-clarity-mask\": true\r\n };\r\n }\r\n return {};\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n// IF YOU UPDATE THIS FILE PLEASE UPDATE THE ONE IN WebWorker\r\n// DUE TO TREE SHAKING ISSUES WHEN IN DEBUG WE CAN'T USE COMMON CODE\r\n// WITHOUT CAUSING ISSUES IN WebWorker\r\n\r\n/** Helper class to work on URL search params */\r\nexport class UrlSearchParamsHelper {\r\n /** Object that contains all the query strings */\r\n private searchParams: { [index: string]: string } = Object.create(null);\r\n\r\n constructor(search?: string) {\r\n this.parseQueryString(search);\r\n }\r\n\r\n /**\r\n * Sets the query string value\r\n * @param name query string name\r\n * @param value query string value\r\n */\r\n public set(name: string, value: string): UrlSearchParamsHelper {\r\n if (value !== undefined && value !== null) {\r\n this.searchParams[name] = value;\r\n }\r\n\r\n return this;\r\n }\r\n\r\n /**\r\n * Gets the query string value\r\n * @param name query string name\r\n */\r\n public get(name: string): string {\r\n return this.searchParams[name];\r\n }\r\n\r\n /**\r\n * Deletes the query string value\r\n * @param name query string name\r\n */\r\n public delete(name: string): void {\r\n delete this.searchParams[name];\r\n }\r\n\r\n /**\r\n * Returns the query parameters as a string\r\n */\r\n public toString(): string {\r\n const keys = Object.keys(this.searchParams);\r\n\r\n if (!keys.length) {\r\n return \"\";\r\n }\r\n\r\n return keys.sort().map((key: string) => {\r\n return `${key}=${this.searchParams[key]}`;\r\n }).join(\"&\");\r\n }\r\n\r\n /** Parses the query string and adds the values to searchParams */\r\n private parseQueryString(queryString?: string): void {\r\n if (!queryString) {\r\n return;\r\n }\r\n\r\n if (queryString.charAt(0) === \"?\") {\r\n queryString = queryString.substring(1);\r\n }\r\n\r\n queryString.split(\"&\").forEach((keyValuePairs) => {\r\n const query = keyValuePairs.split(\"=\");\r\n\r\n const name = query[0];\r\n\r\n if (!this.get(name)) {\r\n this.searchParams[name] = query[1];\r\n }\r\n });\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * The base URL for loading CMS images via CDN. Follows the format: //[host]/tenant/amp/entityid/.\r\n * The content ID and image service parameters can be appended to the end to form the final URL.\r\n */\r\nexport const ImageServiceConfig = {\r\n prod: \"//img-s-msn-com.akamaized.net/tenant/amp/entityid/\"\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ImageServiceConfig } from \"../services/ImageServiceConfig\";\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\nimport { isInteger } from \"lodash-es\";\r\n\r\n/** The cached device pixel ratio. This might not match window.devicePixelRatio as it could be bucketed into a standard size to promote easier caching. */\r\nlet cachedDevicePixelRatio: number;\r\n\r\n/**\r\n * Specifies the focal region for the image.\r\n */\r\nexport interface ImageFocalRegion {\r\n /** The x coordinate of the left side of the focal region. */\r\n x1: number;\r\n\r\n /** The y coordinate of the top of the focal region. */\r\n y1: number;\r\n\r\n /** The x coordinate of the right side of the focal region. */\r\n x2: number;\r\n\r\n /** The y coordinate of the bottom of the focal region. */\r\n y2: number;\r\n}\r\n\r\n/** image format used for generating image url */\r\nexport enum ImageFormat {\r\n JPG = \"jpg\",\r\n PNG = \"png\"\r\n}\r\n\r\n/**\r\n * Contains sizing information needed to generate an image URL.\r\n */\r\nexport interface ImageUrlGenerationInfo {\r\n /** The width of the image that should be generated, in device independent pixels. */\r\n width?: number;\r\n\r\n /** The height of the image that should be generated, in device independent pixels. */\r\n height?: number;\r\n\r\n /** the format of the image. E.g. jpg or png */\r\n format?: ImageFormat;\r\n\r\n /** The focal region for the image. */\r\n focalRegion?: ImageFocalRegion;\r\n\r\n /** True to enable DPI scaling and get better looking images when the screen DPI/zoom level lets us. */\r\n enableDpiScaling: boolean;\r\n\r\n /** The image resize mode. */\r\n mode?: ImageResizeMode;\r\n\r\n /** The image quality. */\r\n quality?: number;\r\n\r\n /** The background color to use when letterboxing. */\r\n backgroundColor?: string;\r\n}\r\n\r\n/**\r\n * Image resize mode enum\r\n */\r\nexport enum ImageResizeMode {\r\n /**\r\n * Default value but the Image Resizer actually replaces it by the scale option (2)\r\n */\r\n None = 0,\r\n\r\n /**\r\n * Maintains aspect ratio as letter box\r\n */\r\n Letterbox = 1,\r\n\r\n /**\r\n * Maintains aspect ratio\r\n */\r\n Scale = 2,\r\n\r\n /**\r\n * Stretches image to fit height and width\r\n */\r\n Stretch = 3,\r\n\r\n /**\r\n * Crops image to fit height and width\r\n */\r\n Crop = 4,\r\n\r\n /**\r\n * Crops the image using focal points\r\n */\r\n FocalCrop = 5,\r\n\r\n /**\r\n * Crop the image using a face auto-detection technique.\r\n */\r\n FacialCrop = 6\r\n}\r\n\r\n/**\r\n * Match the image quality of Bing for content images.\r\n */\r\nexport const HighEndImageQuality = 90;\r\n\r\n/**\r\n * Generates an image URL from an ID and sizing info.\r\n * @param id The ID of the image. e.g. \"BB113a2G\"\r\n * @param info Sizing information to generate the URL.\r\n * @returns The image URL.\r\n */\r\nexport function generateImageUrlFromId(id: string, info: ImageUrlGenerationInfo): string {\r\n return generateImageUrlFromBaseUrl(ImageServiceConfig.prod + id, info);\r\n}\r\n\r\n/**\r\n * Generates an image URL from a base URL.\r\n * NOTE: Url must match what is generated in WW.\r\n * @param baseUrl The base URL for the image, with no query string. e.g. \"https://img-s-msn-com.akamaized.net/tenant/amp/entityid/BB12hxvq.img\"\r\n * @param info Sizing information to generate the URL.\r\n * @returns The image URL.\r\n */\r\nexport function generateImageUrlFromBaseUrl(baseUrl: string, info: ImageUrlGenerationInfo): string {\r\n const { focalRegion, backgroundColor } = info;\r\n\r\n // Passing width or height 0 to image resizer will cause it to ignore that dimension and size on the other one\r\n let { width = 0, height = 0, format = ImageFormat.JPG } = info;\r\n\r\n let auxQsp = \"\";\r\n if (focalRegion) {\r\n const focusX = midPoint(focalRegion.x1, focalRegion.x2);\r\n const focusY = midPoint(focalRegion.y1, focalRegion.y2);\r\n\r\n if (focusX != null && focusY != null) {\r\n auxQsp += `&x=${focusX}&y=${focusY}`;\r\n }\r\n }\r\n\r\n if (backgroundColor) {\r\n auxQsp += `&b=${backgroundColor}`;\r\n }\r\n\r\n // m=6 is facial crop. If a focal crop area is provided, we will add the x and y parameters, which will override the facial crop and do a manual focal crop.\r\n const mode: number = info.mode == null ? 6 : info.mode;\r\n\r\n // Image resizer has a bug where upscaling is not enabled by default, so we need to force it with the query param.\r\n if (mode === 6) {\r\n // NOTE: WW appends this separately NOT as part of auxQsp.\r\n auxQsp += \"&u=t\";\r\n }\r\n\r\n if (info.enableDpiScaling) {\r\n // If we have info about the device pixel ratio, convert these device independent pixels into physical pixels.\r\n const pixelRatio: number = getDevicePixelRatio();\r\n if (pixelRatio) {\r\n width = Math.round(width * pixelRatio);\r\n height = Math.round(height * pixelRatio);\r\n }\r\n }\r\n\r\n const quality: number = info.quality || 60;\r\n\r\n // Image resizer documentation: https://microsoft.sharepoint.com/teams/publishing_infrastructure/_layouts/15/Doc.aspx?sourcedoc={5a9c9f56-4762-47a6-8cd3-c0146bc9bf9a}&action=view&wd=target%28Develop.one%7C3340d642-e2bf-4bdd-9b63-42c479572962%2FImage%20Resizer%20Parameters%7Cdeb5ddfd-d569-45e1-8c21-ed41cecd8f91%2F%29\r\n return `${baseUrl}?w=${width}&h=${height}&q=${quality}&m=${mode}&f=${format}${auxQsp}`;\r\n}\r\n\r\n/**\r\n * Gets the device pixel ratio to use for generating image URLs.\r\n * @returns The device pixel ratio.\r\n */\r\nfunction getDevicePixelRatio(): number {\r\n if (cachedDevicePixelRatio) {\r\n return cachedDevicePixelRatio;\r\n }\r\n\r\n if (!canUseDOM() || !window.devicePixelRatio || window.devicePixelRatio < 1) {\r\n return null;\r\n }\r\n\r\n cachedDevicePixelRatio = window.devicePixelRatio;\r\n\r\n // Special case the x.25 / x.5 / x.75 values, they are always OK\r\n if (!isInteger(cachedDevicePixelRatio * 4)) {\r\n // If not special cased, round up to nearest tenth.\r\n cachedDevicePixelRatio = Math.ceil(cachedDevicePixelRatio * 10) / 10;\r\n }\r\n\r\n // Cap at 3x\r\n if (cachedDevicePixelRatio > 3) {\r\n cachedDevicePixelRatio = 3;\r\n }\r\n\r\n return cachedDevicePixelRatio;\r\n}\r\n\r\n/**\r\n * Returns the midpoint between two min/max coordinate points.\r\n * @param min - the min coordinate\r\n * @param max - the max coordinate\r\n * @returns the midpoint between min and max.\r\n */\r\nfunction midPoint(min: number, max: number): number {\r\n if (min != null && max != null) {\r\n return Math.floor((min + max) / 2);\r\n }\r\n}\r\n\r\n/**\r\n * Create ImageUrlGenerationInfo with height and width params based on the desired width and width/height ratios. If the base image size does\r\n * not match any ratios wihout stretching the image, use the given fallback width and ratio.\r\n * @param baseImageSize - height and width of the base image\r\n * @param desiredDisplayWidth - width we would like the image to span if it can match one of the given primaryImageRatios\r\n * @param desiredImageRatios - list of width/height ratios. We will try to match one of these ratios otherwise we'll use fallbackImageRatio\r\n * @param fallbackDisplayWidth - if a ratio in primaryImageRatios cannot be matched, we'll use this value for the images width\r\n * @param fallbackImageRatio - if a ratio primaryImageRatios cannot be matched, we'll use this value for the images width/height ratio\r\n * @returns a ImageUrlGenerationInfo with height and width set along with enableDpiScaling set to true and mode set to FacialCrop\r\n */\r\nexport function createUrlInfoGivenDesiredWidthAndRatio(\r\n baseImageHeight: number,\r\n baseImageWidth: number,\r\n desiredDisplayWidth: number,\r\n desiredImageRatios: number[],\r\n fallbackDesiredWidth: number,\r\n fallbackImageRatio: number,\r\n focalRegion?: ImageFocalRegion): ImageUrlGenerationInfo {\r\n const urlInfo = {\r\n enableDpiScaling: true,\r\n mode: focalRegion ? ImageResizeMode.FocalCrop : ImageResizeMode.FacialCrop,\r\n height: 0,\r\n width: 0,\r\n focalRegion: focalRegion\r\n };\r\n\r\n let minRatioDiff;\r\n\r\n if (desiredDisplayWidth <= baseImageWidth) {\r\n // we don't want to lose image quality to fit the desired displayWidth.\r\n const baseImageRatio = baseImageWidth/baseImageHeight;\r\n\r\n for (let i = 0; i < desiredImageRatios.length; i++) {\r\n const ratioDiff = Math.abs(baseImageRatio - desiredImageRatios[i]);\r\n\r\n if (ratioDiff < 0.2) {\r\n const newHeight = Math.floor(desiredDisplayWidth/desiredImageRatios[i]);\r\n\r\n if (newHeight <= baseImageHeight\r\n && (minRatioDiff === undefined || ratioDiff < minRatioDiff)) {\r\n // Make sure we're not losing image quality to meet the required height based on the disired displayWidth\r\n // Also, if we match multiple ratios with the 0.2 error, make sure to match the ratio closest to the base dimenions\r\n urlInfo.height = newHeight;\r\n urlInfo.width = desiredDisplayWidth;\r\n minRatioDiff = ratioDiff;\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (urlInfo.height > 0) {\r\n return urlInfo;\r\n } else {\r\n urlInfo.height = Math.floor(fallbackDesiredWidth/fallbackImageRatio);\r\n urlInfo.width = fallbackDesiredWidth;\r\n return urlInfo;\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { Glyph, GlyphType } from \"@msnews/icon\";\r\n\r\nimport { IntraArticleComponentType } from \"./\";\r\nimport { KeyValueArray } from \"@msnews/core\";\r\n\r\n/**\r\n * Social media provider details interface\r\n */\r\ninterface SocialMediaProvider {\r\n apiUrl: string;\r\n attribution: string;\r\n name: string;\r\n}\r\n\r\n/**\r\n * Dictionary of social media provider configuration.\r\n */\r\nconst SocialMediaProviderConfig: KeyValueArray = [];\r\nSocialMediaProviderConfig[IntraArticleComponentType.Unknown] = { apiUrl: \"\", attribution: \"\", name: \"\" };\r\nSocialMediaProviderConfig[IntraArticleComponentType.FacebookEmbed] = { apiUrl: \"//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v3.5&appid=689384617806917\", attribution: \"Facebook Inc.\", name: \"Facebook\" };\r\nSocialMediaProviderConfig[IntraArticleComponentType.InstagramEmbed] = { apiUrl: \"//instagram.com/embed.js\", attribution: \"Instagram Inc.\", name: \"Instagram\" };\r\nSocialMediaProviderConfig[IntraArticleComponentType.TwitterEmbed] = { apiUrl: \"//platform.twitter.com/widgets.js\", attribution: \"Twitter Inc.\", name: \"Twitter\" };\r\n\r\n/**\r\n * Enumerates the available sharing option keys\r\n * @export\r\n */\r\nenum SocialMedia {\r\n Email = \"email\",\r\n Facebook = \"facebook\",\r\n Line = \"line\",\r\n LinkedIn = \"linkedin\",\r\n Skype = \"skype\",\r\n Twitter = \"twitter\",\r\n VK = \"vk\",\r\n WhatsApp = \"whatsapp\"\r\n}\r\n\r\n/**\r\n * Possible target attribute to open social media linked pages\r\n */\r\nenum SocialMediaTarget {\r\n _blank = \"_blank\",\r\n _self = \"_self\",\r\n _parent = \"_parent\",\r\n _top = \"_top\",\r\n newWindow = \"newWindow\"\r\n}\r\n\r\n/**\r\n * A map of social media items and its config attributes\r\n * @export\r\n * @type {[key in SocialMedia]: SocialMediaItemConfigAttributes}\r\n */\r\ntype SocialMediaConfig = {[key in SocialMedia]: SocialMediaItemConfigAttributes};\r\n\r\n/**\r\n * The default configuration values for social media. Those can be overriden per experience\r\n * @export\r\n * @type {SocialMediaConfig}\r\n */\r\nconst SocialMediaDefaultConfig: SocialMediaConfig = {\r\n [SocialMedia.Email]: {\r\n ariaLabel: \"share via email\",\r\n backgroundColor: \"#0078D7\",\r\n color: \"white\",\r\n icon: Glyph.Mail,\r\n label: \"Mail\",\r\n target: SocialMediaTarget._self,\r\n url: \"mailto:?subject={title}&body={body}\"\r\n },\r\n [SocialMedia.Facebook]: {\r\n ariaLabel: \"share on facebook\",\r\n backgroundColor: \"#4267B2\",\r\n color: \"white\",\r\n icon: Glyph.Facebook,\r\n label: \"Facebook\",\r\n target: SocialMediaTarget._blank,\r\n url: \"https://www.facebook.com/sharer.php?u={url}&t={title}\"\r\n },\r\n [SocialMedia.Line]: {\r\n ariaLabel: \"share on line\",\r\n backgroundColor: \"#00C300\",\r\n color: \"white\",\r\n icon: Glyph.Line,\r\n label: \"Line\",\r\n target: SocialMediaTarget._blank,\r\n url: \"https://social-plugins.line.me/lineit/share?url={url}\"\r\n },\r\n [SocialMedia.LinkedIn]: {\r\n ariaLabel: \"share on linkedin\",\r\n backgroundColor: \"#0083BE\",\r\n color: \"white\",\r\n icon: Glyph.LinkedIn,\r\n label: \"LinkedIn\",\r\n target: SocialMediaTarget._blank,\r\n url: \"https://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}&source={refererUrl}\"\r\n },\r\n [SocialMedia.Skype]: {\r\n ariaLabel: \"share on skype\",\r\n backgroundColor: \"#33BFFC\",\r\n color: \"white\",\r\n icon: Glyph.Skype,\r\n label: \"Skype\",\r\n target: SocialMediaTarget._blank,\r\n url: \"https://web.skype.com/share?url={url}&flow_id={flowid}&source=msn\"\r\n },\r\n [SocialMedia.Twitter]: {\r\n ariaLabel: \"share on twitter\",\r\n backgroundColor: \"#20A2F2\",\r\n color: \"white\",\r\n icon: Glyph.Twitter,\r\n label: \"Twitter\",\r\n target: SocialMediaTarget._blank,\r\n url: \"https://twitter.com/share?url={url}&text={title}&original_referer={refererUrl}\"\r\n },\r\n [SocialMedia.WhatsApp]: {\r\n ariaLabel: \"share on whatsapp\",\r\n backgroundColor: \"#25D366\",\r\n color: \"white\",\r\n icon: Glyph.WhatsApp,\r\n label: \"WhatsApp\",\r\n target: SocialMediaTarget._blank,\r\n url: \"https://web.whatsapp.com/send?text={url}\"\r\n },\r\n [SocialMedia.VK]: {\r\n ariaLabel: \"share on vk.com\",\r\n backgroundColor: \"#4680C2\",\r\n color: \"white\",\r\n icon: Glyph.Vkcom,\r\n label: \"VK\",\r\n target: SocialMediaTarget._blank,\r\n url: \"http://vk.com/share.php?url={url}\"\r\n }\r\n};\r\n\r\n/**\r\n * The config attributed type for a given social media\r\n * @export\r\n */\r\ntype SocialMediaItemConfigAttributes = {\r\n /** Arial labe text */\r\n ariaLabel?: string,\r\n /** Attributes to be spread in the anchor tag element */\r\n attributes?: React.HTMLAttributes,\r\n /** Background color of the icon div */\r\n backgroundColor?: string,\r\n /** Foreground color of the icon div */\r\n color?: string,\r\n /** Fill colour for when using svg icons */\r\n fill?: string,\r\n /** Icon glyph to override default value */\r\n icon?: GlyphType,\r\n /** Label text to override default value */\r\n label?: string,\r\n /** To be used in js window.open features param if target = newWindow */\r\n newWindowOptions?: any,\r\n /** telemetry click event should be handled by the caller using this callback */\r\n newWindowTelemetryCall?: (event: any) => void,\r\n /** ocid to be appended in the shared link */\r\n ocid?: string,\r\n /** target to be placed in anchor tag. newWindow has a customized js method that can make use of newWindowOptions attribute */\r\n target?: SocialMediaTarget,\r\n /** Share url to be hard overriden */\r\n url?: string\r\n};\r\n\r\nexport {\r\n SocialMedia,\r\n SocialMediaProvider,\r\n SocialMediaProviderConfig,\r\n SocialMediaConfig,\r\n SocialMediaDefaultConfig,\r\n SocialMediaItemConfigAttributes,\r\n SocialMediaTarget\r\n };\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Constants used for Prime Integration\r\n */\r\nexport const PrimeIntegrationConstants = {\r\n\r\n /**\r\n * Default value we use for the name of the cookie that holds the ANID\r\n */\r\n AnonCookieName: \"APP_ANON\",\r\n\r\n /** The ID of the coachmark to show for when a user performed follow/unfollow action fails */\r\n userActionErrorCoachMarkId: \"cm-spafeedsapp-user-action-error\"\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { MediatorEventNames } from \"./MediatorEventNames\";\r\nimport { PrimeIntegrationConstants } from \"./Constants\";\r\nimport { SubnavTabId } from \"./SubnavTabId\";\r\nimport { TabsHelper } from \"./SubnavTabHelper\";\r\nimport { getMediator } from \"mediator-integration\";\r\nimport { logger } from \"@msnews/diagnostics\";\r\n\r\nexport namespace Mediator {\r\n /**\r\n * API to listen for tab change event from Prime\r\n *\r\n * @export\r\n * @param callback {(tabId: number) => void} - A callback method to handle the event\r\n * @param shouldCallTabChangeEventImmediately {Boolean} - if we should immediately call the callback in order to capture any changes between initialization and registration.\r\n * @return Promise\r\n */\r\n export async function registerForTabChangeEvent(callback: (tabId: number) => void, shouldCallCallbackImmediately = false): Promise {\r\n try {\r\n const mediator = await getMediator();\r\n\r\n function sendActiveTabToCallback(data: PrimeGlobal.INavigateEventData): void {\r\n let activeTab: SubnavTabId = getActiveTabValue();\r\n\r\n // This is only used if the caller of the mediator event neglected to set window.navigation and if the caller decides to use \"tab\" instead of \"tabId\"\r\n if (activeTab === SubnavTabId.None && data && data.tab) {\r\n activeTab = data.tab;\r\n }\r\n\r\n if (window._perfMarker) {\r\n window._perfMarker(\"TimeToTabClick_\" + TabsHelper.tabIdToTabName(activeTab), true);\r\n }\r\n\r\n callback(activeTab);\r\n }\r\n\r\n mediator.sub(MediatorEventNames.TabNavigation, sendActiveTabToCallback);\r\n if (shouldCallCallbackImmediately) {\r\n sendActiveTabToCallback(null);\r\n }\r\n } catch {\r\n logger.logError(\"Couldn't load the mediator object.\");\r\n }\r\n }\r\n\r\n /**\r\n * API to listen for content actions updates from Prime\r\n *\r\n * @export\r\n * @param callback {()) => void} - A callback method to handle the event\r\n * @return Promise\r\n */\r\n export async function registerContentActionsUpdatedEvent(callback: () => void): Promise {\r\n try {\r\n const mediator = await getMediator();\r\n mediator.sub(MediatorEventNames.ContentActionsUpdated, callback);\r\n } catch {\r\n logger.logError(\"Couldn't load the mediator object.\");\r\n }\r\n }\r\n\r\n /**\r\n * API to listen for card action enable event from Prime\r\n *\r\n * @export\r\n * @param callback {(initData PrimeGlobal.ICardActionInitEventData)) => void} - A callback method to handle the event\r\n * @return Promise\r\n */\r\n export async function registerCardActionEnableEvent(callback: (initData: PrimeGlobal.ICardActionInitEventData) => void): Promise {\r\n try {\r\n const mediator = await getMediator();\r\n mediator.sub(MediatorEventNames.CardActionInit, (initData: PrimeGlobal.ICardActionInitEventData): void => {\r\n callback(initData);\r\n });\r\n } catch {\r\n logger.logError(\"Couldn't load the mediator object.\");\r\n }\r\n }\r\n\r\n /**\r\n * API to listen for card action post event from Prime\r\n *\r\n * @export\r\n * @param callback {(initData PrimeGlobal.ICardActionPostEventData)) => void} - A callback method to handle the event\r\n * @return Promise\r\n */\r\n export async function registerCardActionPostEvent(callback: (postData: PrimeGlobal.ICardActionPostEventData) => void): Promise {\r\n try {\r\n const mediator = await getMediator();\r\n mediator.sub(MediatorEventNames.CardActionPost, (postData: PrimeGlobal.ICardActionPostEventData): void => {\r\n callback(postData);\r\n });\r\n } catch {\r\n logger.logError(\"Couldn't load the mediator object.\");\r\n }\r\n }\r\n\r\n /**\r\n * API to listen for follow button click event from Prime\r\n *\r\n * @export\r\n * @param callback {(topicId: string, isFollowed: boolean) => void} - A callback method to handle the event\r\n * @return Promise\r\n */\r\n export async function registerForFollowButtonClickEvent(callback: (topicId: string, isFollowed: boolean) => void): Promise {\r\n try {\r\n const mediator = await getMediator();\r\n mediator.sub(MediatorEventNames.TopicAction, function (followButtonData: PrimeGlobal.IFollowButtonClickData): void {\r\n if (followButtonData && followButtonData.topicId) {\r\n callback(followButtonData.topicId, followButtonData.isFollowed);\r\n }\r\n });\r\n } catch {\r\n logger.logError(\"Couldn't load the mediator object.\");\r\n }\r\n }\r\n\r\n /**\r\n * API to listen for Interests render complete event.\r\n *\r\n * @export\r\n * @return Promise\r\n */\r\n export async function registerForInterestsRenderCompleteEvent(callback: () => void): Promise {\r\n try {\r\n const mediator = await getMediator();\r\n mediator.sub(MediatorEventNames.InterestsRenderComplete, function (): void {\r\n callback();\r\n });\r\n } catch {\r\n logger.logError(\"Couldn't load the mediator object.\");\r\n }\r\n }\r\n\r\n /**\r\n * API to listen for social actions updates from Prime\r\n *\r\n * @export\r\n * @param callback {()) => void} - A callback method to handle the event\r\n * @return Promise\r\n */\r\n export async function registerSocialActionsUpdatedEvent(callback: () => void): Promise {\r\n try {\r\n const mediator = await getMediator();\r\n mediator.sub(MediatorEventNames.SocialActionsUpdated, callback);\r\n } catch {\r\n logger.logError(\"Couldn't load the mediator object.\");\r\n }\r\n }\r\n\r\n /**\r\n * Returns the active tab\r\n * @public\r\n * @return {SubnavTabId}\r\n */\r\n export function getActiveTabValue(): SubnavTabId {\r\n let activeTabValue = \"\";\r\n\r\n if (window.navigation && typeof window.navigation.activeTab === \"string\") {\r\n activeTabValue = window.navigation.activeTab.toLowerCase();\r\n }\r\n\r\n return TabsHelper.tabNameToTabId(activeTabValue);\r\n }\r\n\r\n /**\r\n * API to publish the event to Prime.\r\n *\r\n * @export\r\n * @param event - the mediator event name string\r\n * @param data - the event data\r\n * @return Promise\r\n */\r\n export async function publishEventForPrime(event: string, data?: any): Promise {\r\n try {\r\n const mediator = await getMediator();\r\n mediator.pub(event, data);\r\n } catch {\r\n logger.logError(\"Couldn't load the mediator object in publishEventForPrime.\");\r\n }\r\n }\r\n\r\n /**\r\n * Publishes a message to trigger rendering of a mediated coach mark from Prime page\r\n * @param refElement {Element} - the reference element next to which the coachmark should be rendered. This is optional for Overlay type of coachmarks\r\n * @param hideCoachMark {boolean} - flag to indicate whether to hide the coachmark. Default value of false indicates that the coachmark should be shown.\r\n * @returns Promise{void} - The promise that will return after the action has been completed.\r\n */\r\n export async function renderUserActionErrorCoachmark(\r\n args: { refElement?: Element, hideCoachMark?: boolean } = {}): Promise {\r\n\r\n args = {\r\n refElement: undefined,\r\n hideCoachMark: false,\r\n ...args\r\n };\r\n\r\n const mediator = await getMediator();\r\n mediator.pub(\r\n MediatorEventNames.MediatedCoachMark,\r\n {\r\n coachMarkId: PrimeIntegrationConstants.userActionErrorCoachMarkId,\r\n refElement: args.refElement,\r\n hideCoachMark: args.hideCoachMark\r\n });\r\n }\r\n}","\r\n// © Microsoft Corporation. All rights reserved.\r\n\r\n// TODO: This should be considered for moving it to the Interests experience wrapper, once that\r\n// code arrives, since this is specific to that experience\r\n\r\nimport { SubnavTabId } from \"./SubnavTabId\";\r\nimport { SubnavTabName } from \"./SubnavTabName\";\r\n\r\nexport namespace TabsHelper {\r\n /**\r\n * Converts from the tab enum to the tab names\r\n *\r\n * @export\r\n * @param {SubnavTabId} tabId - The tabId being converted\r\n * @return The tab name\r\n */\r\n export function tabIdToTabName(tabId: SubnavTabId): string {\r\n switch (tabId) {\r\n case SubnavTabId.Interests:\r\n return SubnavTabName.Interests;\r\n\r\n case SubnavTabId.MyFeed:\r\n return SubnavTabName.MyFeed;\r\n\r\n case SubnavTabId.XFeed:\r\n return SubnavTabName.XFeed;\r\n\r\n default:\r\n return \"\";\r\n }\r\n }\r\n\r\n /**\r\n * Converts from the tab name to the tab enum\r\n *\r\n * @export\r\n * @param {string} tabName - The tabName being converted\r\n * @return The tabId\r\n */\r\n export function tabNameToTabId(tabName: string): SubnavTabId {\r\n switch (tabName) {\r\n\r\n case SubnavTabName.MyFeed:\r\n return SubnavTabId.MyFeed;\r\n\r\n case SubnavTabName.XFeed:\r\n return SubnavTabId.XFeed;\r\n\r\n case SubnavTabName.Interests:\r\n return SubnavTabId.Interests;\r\n\r\n default:\r\n return SubnavTabId.None;\r\n }\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { PopOverHandledProps, PopOverProps, PopOverUnhandledProps } from \"./PopOver.props\";\r\nimport { keyCodeEscape, keyCodeTab } from \"@microsoft/fast-web-utilities\";\r\n\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { DesignSystemConsumer } from \"@microsoft/fast-jss-manager-react\";\r\nimport { Direction } from \"@microsoft/fast-web-utilities\";\r\nimport Foundation from \"@microsoft/fast-components-foundation-react\";\r\nimport { HandledPropsKeys } from \"@msnews/core\";\r\nimport React from \"react\";\r\nimport ReactDOM from \"react-dom\";\r\nimport Tabbable from \"tabbable\";\r\n\r\ninterface PositionStyles {\r\n /** Top offset, in px */\r\n top: number;\r\n\r\n /** Left offset, in px */\r\n left?: number;\r\n\r\n /** Right offset, in px */\r\n right?: number;\r\n}\r\n\r\n/**\r\n * PopOver component\r\n * @class - PopOver\r\n * @classdesc - The PopOver component. Renders a popover menu on a new portal. Position to be defined by top/left props\r\n * @default\r\n */\r\nclass PopOver extends Foundation {\r\n /**\r\n * The Pop Over handled prop contract\r\n * Describes the object that enumerates all handled props for a component. This\r\n * object includes all props that can in some way consumed or manipulated by component\r\n * code.\r\n * @protected\r\n * @type { HandledPropsKeys }\r\n */\r\n protected handledProps: HandledPropsKeys = {\r\n anchor: undefined,\r\n autoFlipX: undefined,\r\n autoFocus: undefined,\r\n children: undefined,\r\n enable: undefined,\r\n left: undefined,\r\n managedClasses: undefined,\r\n offset: undefined,\r\n onDismiss: undefined,\r\n staticPosition: undefined,\r\n top: undefined,\r\n zIndex: undefined,\r\n requestContext: undefined\r\n };\r\n\r\n /** Reference for the PopOver div element */\r\n private popOverRef: React.RefObject;\r\n\r\n constructor(props: PopOverProps) {\r\n super(props);\r\n this.popOverRef = React.createRef();\r\n this.state = {\r\n width: 0,\r\n height: 0\r\n };\r\n }\r\n\r\n /**\r\n * Component did mount\r\n */\r\n public componentDidMount(): void {\r\n if (this.popOverRef && this.popOverRef.current) {\r\n const { width, height } = this.popOverRef.current.getBoundingClientRect();\r\n this.setState({ width, height });\r\n } else if (!this.props.enable && this.state.width && this.state.height) {\r\n this.setState({width: 0, height: 0});\r\n }\r\n }\r\n\r\n /**\r\n * Component has updated\r\n */\r\n public componentDidUpdate(): void {\r\n if (this.popOverRef && this.popOverRef.current) {\r\n // Autofocus on popover unless already focused on a descendant of the popover\r\n if (this.props.autoFocus && (!document.activeElement || !this.popOverRef.current.contains(document.activeElement))) {\r\n this.popOverRef.current.focus();\r\n }\r\n const { width, height } = this.popOverRef.current.getBoundingClientRect();\r\n if (width !== this.state.width || height !== this.state.height) {\r\n this.setState({ width, height });\r\n }\r\n } else if (!this.props.enable && this.state.width && this.state.height) {\r\n this.setState({width: 0, height: 0});\r\n }\r\n }\r\n\r\n /**\r\n * Component renderer\r\n * @public\r\n * @method\r\n * @returns {JSX.Element} the popover component rendered in a new portal\r\n */\r\n public render(): JSX.Element {\r\n const { enable, managedClasses, staticPosition, zIndex } = this.props;\r\n if (!enable) {\r\n return null;\r\n }\r\n let result = (null);\r\n const zIndexStyle = zIndex != undefined ? {zIndex} : {};\r\n if (!this.popOverRef || !this.popOverRef.current) {\r\n result = (\r\n \r\n {this.props.children}\r\n
\r\n );\r\n } else {\r\n result = (\r\n \r\n {({ direction }: DesignSystem) => (\r\n \r\n {this.props.children}\r\n
\r\n )}\r\n \r\n );\r\n }\r\n\r\n return staticPosition ? result : ReactDOM.createPortal(result, document.body);\r\n }\r\n\r\n /** Event handler for escape and tab */\r\n private keyDownHandler = (e: React.KeyboardEvent) => {\r\n const { onDismiss = () => null, anchor } = this.props;\r\n if (e.keyCode === keyCodeEscape) {\r\n if (anchor) {\r\n anchor.focus();\r\n }\r\n onDismiss(e);\r\n } else {\r\n this.tabEventHandler(e, onDismiss, anchor);\r\n }\r\n };\r\n\r\n /**\r\n * Event handler for tab event\r\n */\r\n private tabEventHandler = (\r\n e: React.KeyboardEvent,\r\n onDismiss: (e: React.SyntheticEvent) => void,\r\n anchor?: HTMLElement) => {\r\n if (e.keyCode === keyCodeTab\r\n && anchor\r\n && this.popOverRef.current.contains(document.activeElement)) {\r\n const tabbable: HTMLElement[] = Tabbable(this.popOverRef.current);\r\n if (e.shiftKey && e.target === tabbable[0]) {\r\n // focus on anchor if shift+tab is pressed on the first tabbable element\r\n anchor.focus();\r\n onDismiss(e);\r\n e.preventDefault();\r\n } else if (!e.shiftKey && e.target === tabbable[tabbable.length - 1]) {\r\n // focus on the next tabbable from anchor if tab is pressed on the last tabbable element\r\n anchor.focus();\r\n onDismiss(e);\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * calculate the placement style for popover\r\n */\r\n private getPlacementStyle(pageDirection: Direction): PositionStyles {\r\n let { left, top, offset, anchor } = this.props;\r\n const { autoFlipX } = this.props;\r\n if (anchor && left === undefined && top === undefined) {\r\n const position = this.determinePosition();\r\n left = position.left;\r\n top = position.top;\r\n offset = position.offset;\r\n }\r\n const { width, height } = this.state;\r\n const windowWidth = window.innerWidth;\r\n const documentHeight = window.document && window.document.documentElement && window.document.documentElement.offsetHeight;\r\n\r\n if (documentHeight && top + height > documentHeight) {\r\n top = documentHeight - height - offset;\r\n }\r\n // Styles for displaying on left of origin\r\n const displayOnLeft: PositionStyles = {\r\n top,\r\n right: windowWidth - left\r\n };\r\n\r\n // Styles for displaying on right of origin\r\n const displayOnRight: PositionStyles = {\r\n top,\r\n left: left + offset\r\n };\r\n\r\n // Prioritise displaying on right for LTR, on left for RTL\r\n const [displayOnPrioritySide, displayOnNonPrioritySide] =\r\n pageDirection === Direction.rtl ? [displayOnLeft, displayOnRight] : [displayOnRight, displayOnLeft];\r\n\r\n // Determine which directions have enough space to display full width\r\n const canFitPrioritySide = (displayOnPrioritySide.left || displayOnPrioritySide.right) + width < windowWidth;\r\n const canFitNonPrioritySide = (displayOnNonPrioritySide.left || displayOnNonPrioritySide.right) + width < windowWidth;\r\n\r\n // Return non-priority if auto-flip is enabled, and only the priority direction doesn't have space\r\n return autoFlipX && !canFitPrioritySide && canFitNonPrioritySide ? displayOnNonPrioritySide : displayOnPrioritySide;\r\n }\r\n\r\n /**\r\n * determine position based on anchor position\r\n */\r\n private determinePosition = (): {top: number, left: number, offset: number} => {\r\n const { anchor } = this.props;\r\n if (anchor) {\r\n const { top, left, width } = anchor.getBoundingClientRect();\r\n return { top: top + window.scrollY, left: left + window.scrollX, offset: width };\r\n }\r\n return { top: window.scrollY, left: window.scrollX, offset: 0 };\r\n };\r\n}\r\n\r\nexport default PopOver;\r\nexport * from \"./PopOver.props\";\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ComponentStyles } from \"@microsoft/fast-jss-manager\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { PopOverClassNameContract } from \"./PopOver.classnames\";\r\nimport { ZIndex } from \"@msnews/core\";\r\n\r\n/**\r\n * The main JSS stylesheet for the popover component\r\n */\r\nexport const PopOverStyles: ComponentStyles = {\r\n popOver: {\r\n \"animation-duration\": \"0.367s\",\r\n \"animation-fill-mode\": \"both\",\r\n \"animation-name\": \"fadeIn, slideIn\",\r\n \"animation-timing-function\": \"cubic-bezier(0.1, 0.9, 0.2, 1)\",\r\n position: \"absolute\",\r\n \"z-index\": `${ZIndex.Flyout}`,\r\n \"&:focus\": {\r\n outline: \"none\"\r\n }\r\n },\r\n popOverPlaceholder: {\r\n left: \"50%\",\r\n top: \"50%\",\r\n position: \"absolute\",\r\n visibility: \"hidden\"\r\n },\r\n \"@keyframes fadeIn\": {\r\n from: { opacity: 0 },\r\n to: { opacity: 1 }\r\n },\r\n \"@keyframes slideIn\": {\r\n from: { transform: \"translate3d(0px, -10px, 0px)\" },\r\n to: { transform: \"translate3d(0px, 0px, 0px)\" }\r\n }\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport BasePopOver, {\r\n PopOverHandledProps as BasePopOverHandledProps,\r\n PopOverProps as BasePopOverProps,\r\n PopOverManagedClasses,\r\n PopOverUnhandledProps\r\n} from \"./PopOver\";\r\nimport manageJss, { ManagedJSSProps } from \"@microsoft/fast-jss-manager-react\";\r\n\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { PopOverClassNameContract } from \"./PopOver.classnames\";\r\nimport { PopOverStyles } from \"./PopOver.styles\";\r\nimport { Subtract } from \"utility-types\";\r\n\r\n/*\r\n * The type returned by manageJss type is very complicated so we'll let the\r\n * compiler infer the type instead of re-declaring just for the package export\r\n */\r\nconst PopOver = manageJss(PopOverStyles)(BasePopOver);\r\ntype PopOver = InstanceType;\r\n\r\n// Create a valid JSS managed interface that doesn't require managed classes which are provided by the manageJSS HOC\r\ntype PopOverHandledProps = Subtract;\r\n\r\n// Create type for manageJSS HOC styled instance we are exporting\r\ntype PopOverProps = ManagedJSSProps<\r\n BasePopOverProps,\r\n PopOverClassNameContract,\r\n DesignSystem\r\n>;\r\n\r\n// Export everything a user might need from this index file\r\nexport {\r\n PopOver,\r\n PopOverProps,\r\n PopOverClassNameContract,\r\n PopOverHandledProps,\r\n PopOverUnhandledProps\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Enum to set standardized z-index values.\r\n *\r\n * // EXAMPLE:\r\n * myClass: {\r\n * \"z-index\": ZIndex.Above.toString()\r\n * }\r\n *\r\n * Use these constants to specify z-index values in the root stacking context. If you have created another stacking context,\r\n * these values will have no meaning.\r\n *\r\n * Adequate room is left in each block for additional levels to be added if needed.\r\n *\r\n * OTHER GUIDANCE:\r\n * Easily increment within a block by adding an integer like the below example.\r\n * Consider a scenario where you need to increase something just above the navigation level:\r\n *\r\n * myClass: {\r\n * \"z-index\": `${ZIndex.Nav + 1}`\r\n * }\r\n *\r\n * You may also find it useful to increment by other values in the case where you are within a given stacking context.\r\n *\r\n * Recommended reading: https://philipwalton.com/articles/what-no-one-told-you-about-z-index/\r\n *\r\n * Note: If you have a reason to use a value above CookieWall, Make sure it is not causing a compliance violation.\r\n */\r\nexport enum ZIndex {\r\n /** Use for cookie wall (Compliance). */\r\n CookieWall = 1100,\r\n\r\n /** A modal dialog that needs a button press to be dismissed. */\r\n Dialog = 900,\r\n\r\n /** Any kind of easily-dismissed flyout */\r\n Flyout = 700,\r\n\r\n /** An overlay that darkens the page to display a flyout or dialog. */\r\n Overlay = 600,\r\n\r\n /** Navigation pivots. */\r\n Nav = 500,\r\n\r\n /** Items that need to appear over the page content, like a fixed header. */\r\n Over = 300,\r\n\r\n /** Items in the main page content that need to float above the rest, like floating buttons on top of a content card. */\r\n Above = 100,\r\n\r\n /** Default browser element z-index (baseline). */\r\n Default = 0,\r\n\r\n /** Use for elements that need to live below the normal flow of the document. */\r\n Below = -1,\r\n\r\n /** Reserved for lowest elements in the stack. */\r\n Buried = -2\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { CardContextMenuHandledProps, CardContextMenuProps, CardContextMenuUnHandledProps } from \"./CardContextMenu.props\";\r\nimport { ContextMenu, ContextMenuItem } from \"@microsoft/fast-components-react-msft\";\r\n\r\nimport Foundation from \"@microsoft/fast-components-foundation-react\";\r\nimport { HandledPropsKeys } from \"@msnews/core\";\r\nimport { Icon } from \"@msnews/icon\";\r\nimport { More } from \"@edge-web-ui/news-icons\";\r\nimport { PopOver } from \"@msnews/pop-over\";\r\nimport React from \"react\";\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\nimport { isNil } from \"lodash-es\";\r\nimport { keyCodeEscape } from \"@microsoft/fast-web-utilities\";\r\n\r\ninterface CardContextMenuState {\r\n menuOpened: boolean,\r\n dropDownLocation?: {\r\n top?: number,\r\n left?: number,\r\n offset?: number\r\n }\r\n}\r\n\r\n/**\r\n * The component to render the context menu\r\n */\r\nclass CardContextMenu extends Foundation {\r\n /**\r\n * handled props for card context menu\r\n * @protected\r\n * @type { HandledPropsKeys}\r\n */\r\n protected handledProps: HandledPropsKeys = {\r\n managedClasses: undefined,\r\n menuItems: undefined,\r\n enabled: undefined,\r\n buttonLabel: undefined,\r\n positionOffset: undefined,\r\n telemetryTag: undefined,\r\n zIndex: undefined,\r\n requestContext: undefined\r\n };\r\n\r\n /**\r\n * Reference to Container to set/unset focus\r\n * @private\r\n * @type { React.RefObject}\r\n */\r\n private containerRef: React.RefObject;\r\n\r\n /**\r\n * Reference to menu to set/unset focus\r\n * @private\r\n * @type { React.RefObject}\r\n */\r\n private menuRef: React.RefObject;\r\n\r\n /**\r\n * Reference to anchor button\r\n * @private\r\n * @type { React.RefObject}\r\n */\r\n private readonly buttonRef: React.RefObject;\r\n\r\n /**\r\n * Constructor Function for the CardContextMenu\r\n */\r\n public constructor(props: CardContextMenuHandledProps) {\r\n super(props);\r\n this.state = {\r\n menuOpened: false\r\n };\r\n this.containerRef = React.createRef();\r\n this.menuRef = React.createRef();\r\n this.buttonRef = React.createRef();\r\n }\r\n\r\n /**\r\n * Component did update lifecycle event\r\n * @method\r\n */\r\n public componentDidUpdate(): void {\r\n if (this.state.menuOpened) {\r\n this.menuRef.current.focus();\r\n if (canUseDOM()) {\r\n document.addEventListener(\"click\", this.handleUnfocus, false);\r\n document.addEventListener(\"keydown\", this.handleUnfocus, false);\r\n }\r\n } else if (canUseDOM()) {\r\n document.removeEventListener(\"click\", this.handleUnfocus, false);\r\n document.removeEventListener(\"keydown\", this.handleUnfocus, false);\r\n }\r\n }\r\n\r\n /**\r\n * Renders the component\r\n * @method\r\n * @returns {JSX.Element} The Card Context Menu JSX Element\r\n */\r\n public render(): JSX.Element {\r\n const { enabled, managedClasses, menuItems = [], telemetryTag } = this.props;\r\n if (!enabled || !menuItems.length) {\r\n return (null);\r\n }\r\n\r\n const { menuContainer, settingButton, settingButtonIcon } = managedClasses;\r\n\r\n return (\r\n
\r\n this.onSettingClick(e)}\r\n aria-label={this.props.buttonLabel}\r\n ref={this.buttonRef}\r\n {...telemetryTag}\r\n >\r\n \r\n \r\n {this.renderPopOver()}\r\n
\r\n );\r\n }\r\n\r\n /**\r\n * Renders the pop over menu\r\n * @method\r\n * @returns {JSX.Element} The pop over menu JSX Element\r\n */\r\n private renderPopOver(): JSX.Element {\r\n const { menuOpened, dropDownLocation } = this.state;\r\n const enabled = menuOpened && dropDownLocation && !isNil(dropDownLocation.left) && !isNil(dropDownLocation.top);\r\n\r\n return (\r\n \r\n
\r\n \r\n {this.renderContextMenu()}\r\n \r\n
\r\n
\r\n );\r\n }\r\n\r\n /**\r\n * Renders the context menu items\r\n * @method\r\n * @returns {JSX.Element} The pcontext menu items JSX Element\r\n */\r\n private renderContextMenu(): JSX.Element[] {\r\n const { menuItems } = this.props;\r\n const { contextMenuItem, contextMenuItem_contentRegion, contextMenuItem_image } = this.props.managedClasses;\r\n return menuItems.map(itemProps => (\r\n | React.KeyboardEvent): void => {\r\n e.preventDefault();\r\n this.onMenuItemClick(e, itemProps.onSelect);\r\n }}>\r\n
\r\n {itemProps.icon && (\r\n )}\r\n {itemProps.text}\r\n
\r\n \r\n ));\r\n }\r\n\r\n /**\r\n * Handles unfocusing the Context Menu or Esc key down\r\n * @method\r\n */\r\n private handleUnfocus = (e: Event) => {\r\n const buttonContainerContainsNode = (node: Node) => !this.containerRef.current || this.containerRef.current.contains(node);\r\n // Can't put ref on the PopOver react element, so we attach to a ref div and check its immediate parent\r\n // Must check parent because focus goes to PopOver, which is outside menuRef (otherwise menu closes when you try tab to it)\r\n const menuPopoverContainsNode = (node: Node) => !this.menuRef.current || this.menuRef.current.parentNode.contains(node);\r\n\r\n if (e.target && !buttonContainerContainsNode(e.target as Node) && !menuPopoverContainsNode(e.target as Node)) {\r\n this.closeMenu();\r\n } else if (e.type === \"keydown\") {\r\n const keyEvent = e as KeyboardEvent;\r\n if (keyEvent.keyCode === keyCodeEscape) {\r\n e.preventDefault();\r\n this.closeMenu();\r\n this.buttonRef.current.focus();\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * Handles closing the menu\r\n * @method\r\n */\r\n private closeMenu = (): void => {\r\n this.setState({ menuOpened: false });\r\n };\r\n\r\n /**\r\n * Handles the click on the menuitems\r\n * @method\r\n */\r\n private onMenuItemClick(event: any, onSelectCallback: (e) => void): void {\r\n if (onSelectCallback) {\r\n onSelectCallback(event);\r\n }\r\n this.closeMenu();\r\n }\r\n\r\n /**\r\n * Handles the click on the settings button to show the context menu\r\n * @method\r\n */\r\n private onSettingClick(e: any): void {\r\n const posOffset = this.props.positionOffset;\r\n const offsetX = posOffset ? posOffset.x : 0;\r\n const offsetY = posOffset ? posOffset.y : 0;\r\n\r\n let dropDownLocation = {};\r\n if (e.target) {\r\n const { top, left, width } = e.target.getBoundingClientRect();\r\n dropDownLocation = { top: top + offsetY + window.scrollY, left: left + offsetX + window.scrollX, offset: width };\r\n }\r\n this.setState({ menuOpened: !this.state.menuOpened, dropDownLocation });\r\n }\r\n}\r\n\r\nexport { CardContextMenu as CardContextMenu };\r\nexport * from \"./CardContextMenu.props\";","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { applyLocalizedProperty, toPx } from \"@microsoft/fast-jss-utilities\";\r\nimport {\r\n highContrastSelected,\r\n neutralFillActive,\r\n neutralFillHover,\r\n neutralFillRest,\r\n neutralOutlineActive,\r\n neutralOutlineHover,\r\n neutralOutlineRest\r\n}\r\n from \"@microsoft/fast-components-styles-msft\";\r\n\r\nimport { CardContextMenuClassNameContract } from \"./CardContextMenu.classnames\";\r\nimport { ComponentStyles } from \"@microsoft/fast-jss-manager\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\n\r\nexport const CardContextMenuStyles: ComponentStyles = (config: DesignSystem) => {\r\n return {\r\n settingButton: {\r\n height: \"100%\",\r\n width: \"100%\",\r\n border: \"none\",\r\n background: \"none\",\r\n cursor: \"pointer\",\r\n outline: \"none\",\r\n padding: \"0\",\r\n\r\n \"&:focus\": {\r\n border: `${toPx(config.outlineWidth)} dotted`,\r\n \"border-color\": neutralOutlineActive\r\n }\r\n },\r\n settingButtonIcon: {\r\n fill: neutralOutlineHover,\r\n height: \"24px\",\r\n width: \"24px\"\r\n },\r\n contextMenuItem: {\r\n display: \"flex\",\r\n cursor: \"pointer\",\r\n border: `${toPx(config.outlineWidth)} solid transparent`, // Reserve space for hover border\r\n height: \"30px\",\r\n margin: \"0\",\r\n padding: \"0px 12px 0px\",\r\n \"user-select\": \"none\",\r\n \"&:focus, &:hover\": {\r\n background: neutralFillHover,\r\n \"border-color\": neutralOutlineHover,\r\n ...highContrastSelected\r\n },\r\n \"&:active\": {\r\n background: neutralFillActive\r\n }\r\n },\r\n contextMenuItem_contentRegion: {\r\n display: \"flex\",\r\n \"align-items\": \"center\"\r\n },\r\n contextMenuItem_image: {\r\n [applyLocalizedProperty(\"margin-right\", \"margin-left\", config.direction)]: \"8px\"\r\n },\r\n contextMenu: {\r\n \"box-shadow\": \"none\",\r\n padding: \"0\",\r\n width: \"145px\",\r\n background: neutralFillRest,\r\n border: `${toPx(config.outlineWidth)} solid`,\r\n \"border-color\": neutralOutlineRest\r\n }\r\n };\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n CardContextMenu as BaseCardContextMenu,\r\n CardContextMenuHandledProps as BaseCardContextMenuHandledProps,\r\n CardContextMenuProps as BaseCardContextMenuProps,\r\n CardContextMenuUnHandledProps,\r\n CardContextMenusCssClassesManagedClasses\r\n} from \"./CardContextMenu\";\r\nimport manageJss, { ManagedJSSProps } from \"@microsoft/fast-jss-manager-react\";\r\n\r\nimport { CardContextMenuClassNameContract } from \"./CardContextMenu.classnames\";\r\nimport { CardContextMenuItem } from \"./CardContextMenu.props\";\r\nimport { CardContextMenuStyles } from \"./CardContextMenu.style\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { Subtract } from \"utility-types\";\r\n\r\n/*\r\n * The type returned by manageJss type is very complicated so we'll let the\r\n * compiler infer the type instead of re-declaring just for the package export\r\n */\r\nconst CardContextMenu = manageJss(CardContextMenuStyles)(BaseCardContextMenu);\r\ntype CardContextMenu = InstanceType;\r\n\r\ntype CardContextMenuHandledProps = Subtract;\r\ntype CardContextMenuProps = ManagedJSSProps<\r\n BaseCardContextMenuProps,\r\n CardContextMenuClassNameContract,\r\n DesignSystem\r\n>;\r\n\r\nexport {\r\n CardContextMenu,\r\n CardContextMenuClassNameContract,\r\n CardContextMenuHandledProps,\r\n CardContextMenuProps,\r\n CardContextMenuUnHandledProps,\r\n CardContextMenuItem\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n DesignSystem,\r\n applyTypeRampConfig,\r\n highContrastSelector,\r\n neutralForegroundRest\r\n} from \"@microsoft/fast-components-styles-msft\";\r\n\r\nimport { ButtonClassNameContract } from \"@microsoft/fast-components-class-name-contracts-msft\";\r\nimport { ComponentStyles } from \"@microsoft/fast-jss-manager\";\r\nimport { SocialMediaIconClassNameContract } from \"./SocialMediaIcon.classnames\";\r\nimport { toPx } from \"@microsoft/fast-jss-utilities\";\r\n\r\n/** Value for border radius on icons */\r\nconst borderRadiusIcons = 2;\r\n\r\n/** icon height */\r\nconst iconHeight = 40;\r\n\r\n/** icon width */\r\nconst iconWidth = 40;\r\n\r\n/** label width */\r\nconst labelWidth = 60;\r\n\r\n/**\r\n * The JSS stylesheet for the social media icon\r\n * @type {ComponentStyles}\r\n * @param {DesignSystem} config - The design system configuration interface\r\n */\r\nexport const SocialMediaIconStyles: ComponentStyles = (config: DesignSystem) => {\r\n return {\r\n iconContainer: {\r\n \"border-radius\": toPx(borderRadiusIcons),\r\n height: toPx(iconHeight),\r\n width: toPx(iconWidth),\r\n \"line-height\": toPx(iconHeight),\r\n margin: \"0 auto\",\r\n position: \"relative\",\r\n \"&:hover\": {\r\n cursor: \"pointer\"\r\n }\r\n },\r\n iconLabel: {\r\n \"&&\": {\r\n ...applyTypeRampConfig(\"t8\"),\r\n \"line-height\": \"20px\",\r\n \"text-align\": \"center\",\r\n \"margin-top\": \"4px\",\r\n padding: \"3px 0\",\r\n width: toPx(labelWidth),\r\n \"&:hover\": {\r\n cursor: \"pointer\"\r\n },\r\n [highContrastSelector]: {\r\n background: \"ButtonFace\",\r\n color: \"LinkText\"\r\n }\r\n }\r\n }\r\n };\r\n};\r\n\r\n/** style to override button existing style */\r\nexport const ButtonStyle: Partial> = (config: DesignSystem) => {\r\n return {\r\n button__justified: {\r\n \"&&\": {\r\n \"background-color\": \"transparent\",\r\n \"text-decoration\": \"none\",\r\n height: \"inherit\",\r\n \"min-width\": \"unset\",\r\n width: \"fit-content\",\r\n \"&:focus\": {\r\n outline: `1px solid ${neutralForegroundRest(config)}`\r\n },\r\n \"& span\": {\r\n width: \"inherit\"\r\n }\r\n }\r\n }\r\n };\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { Button, ButtonAppearance, Label } from \"@microsoft/fast-components-react-msft\";\r\nimport { HandledPropsKeys, getContextData } from \"@msnews/core\";\r\nimport {\r\n SharingHelper,\r\n SocialMediaDefaultConfig,\r\n SocialMediaItemConfigAttributes,\r\n SocialMediaTarget\r\n} from \"@msnews/views-helpers\";\r\nimport {\r\n SocialMediaIconHandledProps,\r\n SocialMediaIconProps,\r\n SocialMediaIconUnHandledProps\r\n} from \"./SocialMediaIcon.props\";\r\n\r\nimport { ButtonStyle } from \"./SocialMediaIcon.styles\";\r\nimport Foundation from \"@microsoft/fast-components-foundation-react\";\r\nimport { Icon } from \"@msnews/icon\";\r\nimport React from \"react\";\r\nimport { merge } from \"lodash-es\";\r\n\r\n/**\r\n * Social medial icon component\r\n * @class - The Social Media Icon class\r\n * @classdesc - Renders the visual Social Media Icon used to share links without major social media solutions.\r\n * @export\r\n * @default\r\n */\r\nexport class SocialMediaIcon extends Foundation {\r\n /**\r\n * Social media icon handled props contract\r\n * @protected\r\n * @type { HandledPropsKeys }\r\n */\r\n protected handledProps: HandledPropsKeys = {\r\n managedClasses: undefined,\r\n socialMedia: undefined,\r\n contentUrl: undefined,\r\n contentTitle: undefined,\r\n emailBody: undefined,\r\n hideLabel: undefined,\r\n socialMediaItemConfigOverride: undefined,\r\n requestContext: undefined\r\n };\r\n\r\n /**\r\n * Render social media icon\r\n *\r\n * @public\r\n * @return {JSX.Element}\r\n */\r\n public render(): JSX.Element {\r\n const { managedClasses, contentUrl, contentTitle, emailBody, hideLabel, socialMedia, socialMediaItemConfigOverride, requestContext } = this.props;\r\n const itemConfig = merge({}, SocialMediaDefaultConfig[socialMedia], socialMediaItemConfigOverride);\r\n if (!itemConfig) {\r\n return null;\r\n }\r\n\r\n const locationHref = getContextData(requestContext.data.locationHref, \"locationHref\");\r\n const shareUrl = SharingHelper.getSocialMediaShareUrl(locationHref, socialMedia, contentUrl, contentTitle, emailBody, itemConfig.ocid, itemConfig.url);\r\n if (!shareUrl) {\r\n return null;\r\n }\r\n\r\n const target = itemConfig.target.toString();\r\n const targetRelatedAtributes = target === SocialMediaTarget.newWindow ?\r\n { onClick: (event: any) => this.onClickNewWindow(event, shareUrl, itemConfig.newWindowOptions, itemConfig.newWindowTelemetryCall), role: \"button\", \"data-customhandled\": true } :\r\n { href: shareUrl, target: target };\r\n\r\n return (\r\n \r\n );\r\n }\r\n\r\n /**\r\n * Handles custom on click when targeting new windows\r\n * @public\r\n * @return {JSX.Element}\r\n */\r\n private onClickNewWindow = (event: any, shareUrl: string, newWindowOptions: any, newWindowTelemetryCall: (event: any) => void): void => {\r\n SharingHelper.openNewWindow(event, shareUrl, newWindowOptions);\r\n if (newWindowTelemetryCall) {\r\n newWindowTelemetryCall(event);\r\n }\r\n };\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n SocialMediaIconHandledProps as BaseComponentHandledProps,\r\n SocialMediaIconProps as BaseComponentProps,\r\n SocialMediaIconManagedClasses,\r\n SocialMediaIconUnHandledProps\r\n} from \"./SocialMediaIcon.props\";\r\nimport manageJss, { ManagedJSSProps } from \"@microsoft/fast-jss-manager-react\";\r\n\r\nimport { SocialMediaIcon as BaseComponent } from \"./SocialMediaIcon\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { SocialMediaIconClassNameContract } from \"./SocialMediaIcon.classnames\";\r\nimport { SocialMediaIconStyles } from \"./SocialMediaIcon.styles\";\r\nimport { Subtract } from \"utility-types\";\r\n\r\n/*\r\n * The type returned by manageJss type is very complicated so we'll let the\r\n * compiler infer the type instead of re-declaring just for the package export\r\n */\r\nconst SocialMediaIcon = manageJss(SocialMediaIconStyles)(BaseComponent);\r\ntype SocialMediaIcon = InstanceType;\r\n\r\n// Create a valid JSS managed interface that doesn't require managed classes which are provided by the manageJSS HOC\r\ntype SocialMediaIconHandledProps = Subtract;\r\n\r\n// Create type for manageJSS HOC styled instance we are exporting\r\ntype SocialMediaIconProps = ManagedJSSProps;\r\n\r\n// Export everything a user might need from this index file\r\nexport {\r\n SocialMediaIcon,\r\n SocialMediaIconProps,\r\n SocialMediaIconClassNameContract,\r\n SocialMediaIconHandledProps,\r\n SocialMediaIconUnHandledProps\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Shallow compare of two objects.\r\n * Compares reference and primitive values of both object's key-value pairs\r\n *\r\n * @param a\r\n * @param b\r\n * @returns {bool} result of comparison.\r\n */\r\nexport function ShallowCompare(a: Object, b: Object): boolean {\r\n for (const key in a) {\r\n if (!(key in b) || a[key] !== b[key]) {\r\n return false;\r\n }\r\n }\r\n\r\n for (const key in b) {\r\n if (!(key in a) || a[key] !== b[key]) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { CSSRules, ComponentStyleSheet, ComponentStyles } from \"@microsoft/fast-jss-manager\";\r\nimport {\r\n DesignSystem,\r\n DesignSystemDefaults,\r\n applyAcrylicMaterial,\r\n applyTypeRampConfig,\r\n fontWeight,\r\n highContrastSelector,\r\n neutralForegroundRest\r\n} from \"@microsoft/fast-components-styles-msft\";\r\nimport { applyLocalizedProperty, toPx } from \"@microsoft/fast-jss-utilities\";\r\nimport { get, memoize } from \"lodash-es\";\r\n\r\nimport { DialogClassNameContract } from \"@microsoft/fast-components-react-base\";\r\nimport { ShareDialogClassNameContract } from \"./ShareDialog.classnames\";\r\nimport { ZIndex } from \"@msnews/core\";\r\nimport { canUseDOM } from \"@msnews/isomorphic-util\";\r\n\r\n/** Default values for border radius */\r\nconst borderRadiusCopyLink = 2;\r\nconst borderRadiusDialog = 4;\r\n\r\nconst dialogContainerWidth = 322;\r\n\r\n/**\r\n * Default color values for the share dialog\r\n */\r\nconst ShareDialogColors = {\r\n dividerLine: \"rgba(0,0,0, 0.05)\",\r\n inputText: \"rgba(0, 1, 0, 0.6)\",\r\n inputBorder: \"rgba(0, 0, 0, 0.2)\",\r\n copyLinkButtonBackground: \"#0078D4\",\r\n copyLinkButtonBackgroundActive: \"#1B64B0\",\r\n copyLinkButtonText: \"#FFF\",\r\n dialogOverlayBackground: \"rgba(0, 0, 0, 0.4)\"\r\n};\r\n\r\n/**\r\n * The JSS stylesheet for the base dialog\r\n * @type {ComponentStyles}\r\n * @param {DesignSystem} config - The design system configuration interface\r\n */\r\nexport const baseDialogStyles: ComponentStyles = (config: DesignSystem) => {\r\n const backgroundColor: string = get(config, \"backgroundColor\", DesignSystemDefaults.backgroundColor);\r\n\r\n return {\r\n dialog: {\r\n display: \"none\",\r\n '&[aria-hidden=\"false\"]': {\r\n display: \"block\"\r\n }\r\n },\r\n dialog_modalOverlay: {\r\n position: \"fixed\",\r\n background: ShareDialogColors.dialogOverlayBackground,\r\n top: \"0\",\r\n left: \"0\",\r\n right: \"0\",\r\n bottom: \"0\",\r\n \"z-index\": `${ZIndex.Above}`\r\n },\r\n dialog_contentRegion: {\r\n position: \"fixed\",\r\n left: \"50%\",\r\n top: \"50%\",\r\n transform: \"translate(-50%, -50%)\",\r\n \"max-height\": \"100vh\",\r\n \"max-width\": \"100vw\",\r\n overflow: \"auto\",\r\n \"border-radius\": toPx(borderRadiusDialog),\r\n \"box-shadow\": \"none\",\r\n \"z-index\": `${ZIndex.Above + 1}`,\r\n ...applyAcrylicMaterial(backgroundColor, 0.7, 0.7, true)\r\n }\r\n };\r\n};\r\n\r\n /**\r\n * Gets the override style for base dialog based on ZIndex\r\n * @private\r\n * @method\r\n * @return {>} the result style to be passed to base dialog\r\n */\r\nexport const setStyleByZIndex = memoize((overrides: ComponentStyleSheet = {}, zIndex: number = null) => {\r\n return zIndex == null ? overrides : {\r\n ...overrides,\r\n dialog_modalOverlay: {\r\n ...overrides.dialog_modalOverlay,\r\n \"z-index\": zIndex.toString()\r\n },\r\n dialog_contentRegion: {\r\n ...overrides.dialog_contentRegion,\r\n \"z-index\": (zIndex + 1).toString()\r\n }\r\n };\r\n});\r\n\r\n/**\r\n * The JSS stylesheet for the share dialog\r\n * @type {ComponentStyles}\r\n * @param {DesignSystem} config - The design system configuration interface\r\n */\r\nexport const ShareDialogStyles: ComponentStyles = (config: DesignSystem) => {\r\n const iconWidth = 40;\r\n const headerLineHeight = 24;\r\n const backdropFilterStyles: CSSRules = {\r\n background: \"none\"\r\n };\r\n const fallbackStyles: CSSRules = {\r\n background: get(config, \"backgroundColor\", DesignSystemDefaults.backgroundColor)\r\n };\r\n const backdropFilterSupport: boolean = canUseDOM() && (\"backdrop-filter\" in document.documentElement.style || \"-webkit-backdrop-filter\" in document.documentElement.style);\r\n const backgroundStyle: CSSRules = backdropFilterSupport ? backdropFilterStyles : fallbackStyles;\r\n return {\r\n closeButton: {\r\n background: \"transparent !important\",\r\n border: \"none\",\r\n height: `${headerLineHeight}px !important`,\r\n padding: \"0\",\r\n position: \"absolute\",\r\n \"min-width\": toPx(headerLineHeight),\r\n [applyLocalizedProperty(\"right\", \"left\", config.direction)]: \"4px\",\r\n \"&:hover, &:focus, &:active\": {\r\n cursor: \"pointer\",\r\n outline: \"auto\"\r\n },\r\n [highContrastSelector]: {\r\n background: \"ButtonFace !important\",\r\n \"& svg\": {\r\n fill: \"ButtonText\"\r\n },\r\n \"&:hover, &:focus, &:active\": {\r\n background: \"Highlight !important\",\r\n \"& svg\": {\r\n fill: \"HighlightText\"\r\n }\r\n }\r\n }\r\n },\r\n closeIcon: {\r\n fill: neutralForegroundRest\r\n },\r\n copyLinkButton: {},\r\n copyLinkInput: {},\r\n dialogContainer: {\r\n ...backgroundStyle,\r\n \"border-radius\": toPx(borderRadiusDialog),\r\n padding: \"0 12px\",\r\n width: toPx(dialogContainerWidth),\r\n \"box-sizing\": \"content-box\",\r\n \"text-align\": \"center\",\r\n \"& $inputContainer\": {\r\n \"& $copyLinkInput\": {\r\n [applyLocalizedProperty(\"border-top-left-radius\", \"border-top-right-radius\", config.direction)]: toPx(borderRadiusCopyLink),\r\n [applyLocalizedProperty(\"border-bottom-left-radius\", \"border-bottom-right-radius\", config.direction)]: toPx(borderRadiusCopyLink)\r\n }\r\n },\r\n [highContrastSelector]: {\r\n border: \"1px solid Highlight\"\r\n }\r\n },\r\n header: {\r\n \"border-bottom\": `${config.outlineWidth}px solid ${ShareDialogColors.dividerLine}`,\r\n display: \"flex\",\r\n \"line-height\": toPx(headerLineHeight),\r\n padding: \"12px 0\",\r\n \"text-align\": \"center\"\r\n },\r\n headerText: {\r\n ...applyTypeRampConfig(\"t7\"),\r\n \"font-weight\": `${fontWeight.semibold}`,\r\n margin: \"0\",\r\n width: \"100%\"\r\n },\r\n iconListContainer: {\r\n display: \"inline-block\",\r\n \"list-style\": \"none\",\r\n \"text-align\": \"center\",\r\n \"margin-top\": \"36px\",\r\n padding: \"0\",\r\n width: \"inherit\"\r\n },\r\n iconListItem: {\r\n float: applyLocalizedProperty(\"left\", \"right\", config.direction),\r\n width: \"25%\",\r\n \"&:nth-child(n+5)\": {\r\n \"margin-top\": \"24px\"\r\n },\r\n \"&:nth-child(4n+1)\": {\r\n clear: \"both\"\r\n }\r\n },\r\n inputContainer: {\r\n \"box-sizing\": \"content-box\",\r\n \"padding-top\": \"24px\",\r\n \"padding-bottom\": \"32px\",\r\n \"text-align\": \"center\",\r\n \"& $copyLinkInput\": {\r\n border: `2px solid ${ShareDialogColors.inputBorder}`,\r\n \"box-sizing\": \"content-box\",\r\n color: ShareDialogColors.inputText,\r\n ...applyTypeRampConfig(\"t8\"),\r\n padding: \"1px 0 1px 5px\",\r\n height: \"28px\",\r\n width: \"191px\"\r\n },\r\n \"& $copyLinkButton\": {\r\n background: ShareDialogColors.copyLinkButtonBackground,\r\n [applyLocalizedProperty(\"border-top-right-radius\", \"border-top-left-radius\", config.direction)]: toPx(borderRadiusCopyLink),\r\n [applyLocalizedProperty(\"border-bottom-right-radius\", \"border-bottom-left-radius\", config.direction)]: toPx(borderRadiusCopyLink),\r\n border: \"none\",\r\n color: ShareDialogColors.copyLinkButtonText,\r\n ...applyTypeRampConfig(\"t8\"),\r\n height: \"32px\",\r\n \"vertical-align\": \"middle\",\r\n width: \"89px\",\r\n \"&:hover\": {\r\n cursor: \"pointer\"\r\n },\r\n \"&:active\": {\r\n background: ShareDialogColors.copyLinkButtonBackgroundActive\r\n },\r\n [highContrastSelector]: {\r\n background: \"ButtonFace\",\r\n color: \"ButtonText\",\r\n \"&:hover, &:focus, &:active\": {\r\n background: \"Highlight\",\r\n color: \"HighlightText\"\r\n }\r\n }\r\n }\r\n }\r\n };\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\n/** String resource to be used in the Card Action components */\r\nexport const StringResource = {\r\n dialogStrings: {\r\n dialogButtonClose: \"close dialog\",\r\n dialogTitle: \"Share\",\r\n copyButton: \"Copy\",\r\n copiedButton: \"Link Copied\",\r\n copyButtonAriaLabel: \"copy link to clipboard\",\r\n copiedButtonAriaLabel: \"link copied to clipboard\"\r\n }\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n AccentButton,\r\n Heading,\r\n HeadingSize,\r\n HeadingTag,\r\n StealthButton\r\n} from \"@microsoft/fast-components-react-msft\";\r\nimport {\r\n DialogProps,\r\n Dialog as MSFTBaseDialog\r\n} from \"@microsoft/fast-components-react-base\";\r\nimport { GlyphInline, Icon } from \"@msnews/icon\" ;\r\nimport { ShareDialogHandledProps, ShareDialogProps, ShareDialogStrings } from \"./ShareDialog.props\";\r\nimport {\r\n SocialMedia,\r\n SocialMediaConfig,\r\n SocialMediaDefaultConfig\r\n} from \"@msnews/views-helpers\";\r\nimport { baseDialogStyles, setStyleByZIndex } from \"./ShareDialog.styles\";\r\n\r\nimport Foundation from \"@microsoft/fast-components-foundation-react\";\r\nimport { HandledPropsKeys } from \"@msnews/core\";\r\nimport React from \"react\";\r\nimport { SocialMediaIcon } from \"@msnews/social-media-icon\";\r\nimport { StringResource } from \"./StringResource\";\r\nimport { TelemetryTags } from \"@msnews/telemetry-contracts\";\r\nimport { logger } from \"@msnews/diagnostics\";\r\nimport manageJss from \"@microsoft/fast-jss-manager-react\";\r\n\r\n/** Base MSFT dialog with overriden style */\r\nconst Dialog = manageJss(baseDialogStyles)(MSFTBaseDialog);\r\n\r\n/** Duration the button should present the \"link copied\" text after a user click */\r\nconst linkCopiedDisplayDuration = 1600;\r\n\r\n/**\r\n * Share dialog state interface\r\n * @export\r\n * @interface ShareDialogState\r\n */\r\nexport interface ShareDialogState {\r\n isLinkCopied: boolean\r\n}\r\n/**\r\n * ShareDialog Component\r\n * @class - ShareDialog\r\n * @classdesc - The ShareDialog component. Renders the dialog that provides social media sharing options\r\n * @default\r\n */\r\nexport class ShareDialog extends Foundation {\r\n /**\r\n * Component HandledProps enumeration. Anything not enumerated here will be included in the experience root HTML tag via unhandledProps()\r\n */\r\n protected handledProps: HandledPropsKeys = {\r\n baseDialogProps: undefined,\r\n closeButtonTelemetryTags: undefined,\r\n closeButtonTelemetryObject: undefined,\r\n contentTitle: undefined,\r\n contentUrl: undefined,\r\n emailBody: undefined,\r\n copyButtonAttributes: undefined,\r\n copyButtonTelemetryObject: undefined,\r\n copyButtonTelemetryTags: undefined,\r\n copyLinkOcid: undefined,\r\n dialogStrings: undefined,\r\n enabled: undefined,\r\n managedClasses: undefined,\r\n onClose: undefined,\r\n renderOneColLayout: undefined,\r\n socialMediaConfigOverride: undefined,\r\n socialMediaItems: undefined,\r\n shareIconTelemetryObject: undefined,\r\n shareIconTelemetryTags: undefined,\r\n baseDialogStyleOverride: undefined,\r\n zIndex: undefined,\r\n requestContext: undefined\r\n };\r\n\r\n /**\r\n * Stores the strings to be used in the dialog. Merged default strings with passed from props\r\n * @type {ShareDialogStrings}\r\n */\r\n private dialogStrings: ShareDialogStrings;\r\n\r\n /**\r\n * Social media items config that stores merged values from default and props\r\n * @type {SocialMediaConfig}\r\n */\r\n private socialMediaItemsConfig: SocialMediaConfig;\r\n\r\n /**\r\n * Ref to input field with shared url\r\n * @type {React.RefObject}\r\n */\r\n private readonly inputRef: React.RefObject = React.createRef();\r\n\r\n /**\r\n * Constructs a ShareDialog component\r\n * @constructor\r\n * @param { ShareDialogProps } props props contract\r\n */\r\n constructor(props: ShareDialogProps) {\r\n super(props);\r\n this.state = {\r\n isLinkCopied: false\r\n };\r\n\r\n // Merges some values from props with default values\r\n this.dialogStrings = { ...StringResource.dialogStrings, ...props.dialogStrings };\r\n\r\n this.setSocialMediaItemsConfig();\r\n }\r\n\r\n /**\r\n * Component renderer\r\n * @public\r\n * @method\r\n * @returns {JSX.Element} the ShareDialog component\r\n */\r\n public render(): JSX.Element {\r\n const { managedClasses, enabled, contentUrl, baseDialogProps, onClose, children, closeButtonTelemetryTags, baseDialogStyleOverride, zIndex } = this.props;\r\n if (!enabled || !contentUrl) {\r\n return null;\r\n }\r\n\r\n return (\r\n \r\n
\r\n
\r\n \r\n {this.dialogStrings.dialogTitle}\r\n \r\n \r\n \r\n \r\n
\r\n {children}\r\n {this.renderSocialIconsList()}\r\n {this.renderCopyLink()}\r\n
\r\n \r\n );\r\n }\r\n\r\n /**\r\n * Renders the copy link input and button part of the share dialog\r\n * @private\r\n * @method\r\n * @returns {JSX.Element} the content part of the ShareDialog component\r\n */\r\n private renderCopyLink(): JSX.Element {\r\n const { managedClasses, copyLinkOcid, contentUrl, copyButtonAttributes, copyButtonTelemetryObject, copyButtonTelemetryTags } = this.props;\r\n\r\n const url = copyLinkOcid ? `${contentUrl}?ocid=${copyLinkOcid}` : contentUrl;\r\n const buttonText = this.state.isLinkCopied ? this.dialogStrings.copiedButton : this.dialogStrings.copyButton;\r\n const ariaLabel = this.state.isLinkCopied ? this.dialogStrings.copiedButtonAriaLabel : this.dialogStrings.copyButtonAriaLabel;\r\n\r\n const copyTelemetryTag = copyButtonTelemetryTags || copyButtonTelemetryObject.render();\r\n\r\n return (\r\n
\r\n \r\n \r\n {buttonText}\r\n \r\n
\r\n );\r\n }\r\n\r\n /**\r\n * Copy share url to clipboard and set timer to update the copy link button text\r\n * @private\r\n * @method\r\n */\r\n private onCopyLinkToClipboard = () => {\r\n if (!this.state.isLinkCopied) {\r\n this.setState({ isLinkCopied: true });\r\n this.inputRef.current.select();\r\n document.execCommand(\"copy\");\r\n setTimeout(() => {\r\n /* istanbul ignore next */\r\n this.setState({ isLinkCopied: false });\r\n },\r\n linkCopiedDisplayDuration\r\n );\r\n }\r\n };\r\n\r\n /**\r\n * Renders the social items list part of the share dialog\r\n * @private\r\n * @method\r\n * @returns {JSX.Element} the social media list element of the ShareDialog component\r\n */\r\n private renderSocialIconsList(): JSX.Element {\r\n const { managedClasses, socialMediaItems } = this.props;\r\n if (!socialMediaItems || !socialMediaItems.length) {\r\n return null;\r\n }\r\n\r\n const socialMediaIcons = socialMediaItems.map((item) => {\r\n return this.renderSocialIcon(item);\r\n });\r\n\r\n return (\r\n
    \r\n {socialMediaIcons}\r\n
\r\n );\r\n }\r\n\r\n /**\r\n * Renders each individual social media icon of the social media list\r\n * @private\r\n * @method\r\n * @param { string } socialMediaItem The social media item as string\r\n * @returns {JSX.Element} the icon part of the social media list\r\n */\r\n private renderSocialIcon(socialMediaItem: string): JSX.Element {\r\n const { managedClasses, shareIconTelemetryObject, shareIconTelemetryTags, contentTitle, contentUrl, emailBody, requestContext } = this.props;\r\n const media: SocialMedia = SocialMedia[Object.keys(SocialMedia).find(key => SocialMedia[key] === socialMediaItem.toLowerCase())];\r\n if (!media) {\r\n logger.logError(`ShareDialog: renderSocialIcon: Invalid param: socialMediaItem = ${socialMediaItem}`);\r\n return null;\r\n }\r\n const mediaKey = media.toString();\r\n\r\n const iconTelemetryTags: TelemetryTags = (shareIconTelemetryTags && shareIconTelemetryTags[mediaKey]) ||\r\n (shareIconTelemetryObject && shareIconTelemetryObject[mediaKey].render());\r\n\r\n return (\r\n
  • \r\n \r\n
  • \r\n );\r\n }\r\n\r\n /**\r\n * Sets configuration specs for social media items based on default and override props values\r\n * @method\r\n */\r\n private setSocialMediaItemsConfig(): void {\r\n this.socialMediaItemsConfig = { ...SocialMediaDefaultConfig };\r\n\r\n // merge default config with override props\r\n if (this.props.socialMediaConfigOverride) {\r\n Object.keys(this.props.socialMediaConfigOverride).forEach((key) => {\r\n const keyLower = key.toLowerCase();\r\n this.socialMediaItemsConfig[keyLower] = { ...this.socialMediaItemsConfig[keyLower], ...this.props.socialMediaConfigOverride[key] };\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Gets the final props to apply to the dialog component\r\n * @private\r\n * @method\r\n * @param {DialogProps} props - the default dialog props\r\n * @returns {DialogProps} the resulting props to be passed to base dialog\r\n */\r\n private coerceDialogProps(props: DialogProps): DialogProps {\r\n return {\r\n visible: this.props.enabled,\r\n modal: true,\r\n contentHeight: \"auto\",\r\n contentWidth: this.props.renderOneColLayout ? \"100%\" : \"346px\",\r\n ...props\r\n };\r\n }\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n ShareDialogHandledProps as BaseShareDialogHandledProps,\r\n ShareDialogProps as BaseShareDialogProps,\r\n ShareDialogManagedClasses,\r\n ShareDialogStrings,\r\n ShareDialogUnhandledProps\r\n} from \"./ShareDialog.props\";\r\nimport manageJss, { ManagedJSSProps } from \"@microsoft/fast-jss-manager-react\";\r\n\r\nimport { ShareDialog as BaseShareDialog } from \"./ShareDialog\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { ShareDialogClassNameContract } from \"./ShareDialog.classnames\";\r\nimport { ShareDialogStyles } from \"./ShareDialog.styles\";\r\nimport { Subtract } from \"utility-types\";\r\n\r\n/* The type returned by manageJss type is very complicated so we'll let the\r\n* compiler infer the type instead of re-declaring just for the package export\r\n*/\r\nconst ShareDialog = manageJss(ShareDialogStyles)(BaseShareDialog);\r\ntype ShareDialog = InstanceType;\r\n\r\n// Create a valid JSS managed interface that doesn't require managed classes which are provided by the manageJSS HOC\r\ntype ShareDialogHandledProps = Subtract;\r\n\r\n// Create type for manageJSS HOC styled instance we are exporting\r\ntype ShareDialogProps = ManagedJSSProps<\r\n BaseShareDialogProps,\r\n ShareDialogClassNameContract,\r\n DesignSystem\r\n>;\r\n\r\n// Export everything a user might need from this index file\r\nexport {\r\n ShareDialog,\r\n ShareDialogProps,\r\n ShareDialogHandledProps,\r\n ShareDialogUnhandledProps,\r\n ShareDialogManagedClasses,\r\n ShareDialogClassNameContract,\r\n ShareDialogStrings\r\n};\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { AppError } from \"@msnews/diagnostics\";\r\n\r\n/**\r\n * This is a global tracking object which is used to avoid\r\n * the need to have hard dependencies to a telemetry package.\r\n * Think of this as an interface which is overrided at runtime\r\n * by each app-type.\r\n */\r\n\r\ninterface TelemetryBase {\r\n trackAppErrorEvent(error: AppError): void;\r\n sendSinglePageViewBeacon(beaconId: string): void;\r\n trackPartialImpression(element?: any, viewType?: any, visibilityCheck?: boolean, mechanism?: string, topLevelContainerType?: string): void;\r\n trackEvent(element: HTMLElement,\r\n action?: string,\r\n behavior?: number,\r\n event?: any,\r\n destination?: any,\r\n headline?: string,\r\n module?: string,\r\n index?: string,\r\n campaign?: string,\r\n contentAction?: number): void;\r\n}\r\n\r\nexport const TelemetryBase: TelemetryBase = {\r\n trackAppErrorEvent: (): void => undefined,\r\n sendSinglePageViewBeacon: (): void => undefined,\r\n trackPartialImpression: (): void => undefined,\r\n trackEvent: (): void => undefined\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ArticleCardHandledProps, ArticleCardProps, ArticleCardUnhandledProps } from \"./ArticleCard.props\";\r\nimport { HandledPropsKeys, ShallowCompare } from \"@msnews/core\";\r\nimport { Heading, Image, Typography } from \"@microsoft/fast-components-react-msft\";\r\n\r\nimport Foundation from \"@microsoft/fast-components-foundation-react\";\r\nimport React from \"react\";\r\n\r\n/**\r\n * Article card state interface\r\n */\r\nexport interface ArticleCardState {}\r\n\r\n/**\r\n * Article card component\r\n * @class - Article card\r\n * @classdesc - Article card component base; provides semantic structure of a basic article card.\r\n * @export\r\n * @default\r\n */\r\nclass ArticleCard extends Foundation {\r\n /**\r\n * Article card handled props contract\r\n * @protected\r\n * @type { HandledPropsKeys}\r\n */\r\n protected handledProps: HandledPropsKeys = {\r\n anchorRef: undefined,\r\n headlineTitle: undefined,\r\n href: undefined,\r\n image: undefined,\r\n managedClasses: undefined,\r\n provider: undefined\r\n };\r\n\r\n /**\r\n * Construct a new article card\r\n * @constructor\r\n * @param { ArticleCardHandledProps } props the props contract for ArticleCard\r\n */\r\n constructor(props: ArticleCardHandledProps) {\r\n super(props);\r\n }\r\n\r\n /**\r\n * Performs a shallow comparison on the props\r\n * @param nextProps Incoming props\r\n * @param nextState Incoming state. Ignored as component is stateless\r\n */\r\n public shouldComponentUpdate(nextProps: ArticleCardProps): boolean {\r\n return !ShallowCompare(this.props, nextProps);\r\n }\r\n\r\n /**\r\n * Renders the component\r\n * @method\r\n * @returns {JSX.Element} the ArticleCard JSX element\r\n */\r\n public render(): JSX.Element {\r\n return (\r\n \r\n {this.renderContent()}\r\n {this.props.children}\r\n \r\n );\r\n }\r\n\r\n /**\r\n * Renders the content component of the article\r\n * @method\r\n * @returns {JSX.Element} the content of an article\r\n */\r\n private renderContent(): JSX.Element {\r\n let content: JSX.Element;\r\n const { href, managedClasses } = this.props;\r\n\r\n if (href) {\r\n content = (\r\n \r\n {this.renderImage()}\r\n
    \r\n {this.renderTitle()}\r\n {this.renderProvider()}\r\n
    \r\n \r\n );\r\n } else {\r\n content = (\r\n
    \r\n {this.renderImage()}\r\n
    \r\n {this.renderTitle()}\r\n {this.renderProvider()}\r\n
    \r\n
    \r\n );\r\n }\r\n\r\n return content;\r\n }\r\n\r\n /**\r\n * Renders the card image component of the article\r\n * @method\r\n * @returns {JSX.Element} the image component of an article\r\n */\r\n private renderImage(): JSX.Element {\r\n if (!this.props.image) {\r\n return;\r\n }\r\n\r\n const { articleCard_imageWrapper, articleCard_image, articleCard_imageOverlay } = this.props.managedClasses;\r\n\r\n return (\r\n
    \r\n \r\n
    \r\n
    \r\n );\r\n }\r\n\r\n /**\r\n * Renders the headline title component of the article\r\n * @method\r\n * @returns {JSX.Element} the headline title component of an article\r\n */\r\n private renderTitle(): JSX.Element {\r\n const { articleCard_headline, articleCard_headlineText, articleCard_headlineMask } = this.props.managedClasses;\r\n\r\n return (\r\n
    \r\n \r\n
    \r\n
    \r\n );\r\n }\r\n\r\n /**\r\n * Renders the article provider component of an article\r\n * @method\r\n * @returns {JSX.Element} the article provider component if it exists\r\n */\r\n private renderProvider(): JSX.Element {\r\n if (!this.props.provider) {\r\n return;\r\n }\r\n\r\n let providerImage: JSX.Element;\r\n if (this.props.provider.image && this.props.provider.image.src) {\r\n providerImage = (\r\n \r\n );\r\n }\r\n\r\n return (\r\n
    \r\n {providerImage}\r\n \r\n
    \r\n );\r\n }\r\n}\r\n\r\nexport default ArticleCard;\r\nexport * from \"./ArticleCard.props\";","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { SocialMedia, SocialMediaDefaultConfig } from \"./SocialMediaConfig\";\r\nimport { indexOf, uniqueId } from \"lodash-es\";\r\n\r\nimport { String } from \"typescript-string-operations\";\r\nimport { format } from \"@microsoft/fast-web-utilities\";\r\nimport { getAppEnvironment } from \"@msnews/core\";\r\nimport { getLocationOrigin } from \"@msnews/isomorphic-util\";\r\nimport { logger } from \"@msnews/diagnostics\";\r\n\r\n/**\r\n * Document type being shared\r\n */\r\nexport enum SharedDocumentType {\r\n CMS = \"0\",\r\n SD = \"5\"\r\n}\r\n\r\n/**\r\n * Sharing details interface to build sharing items\r\n * @interface\r\n */\r\nexport interface SharingInfo {\r\n /**\r\n * CMS document id\r\n * @type {string}\r\n */\r\n documentId: string;\r\n\r\n /**\r\n * Document type\r\n * @type {SharedDocumentType}\r\n */\r\n documentType: SharedDocumentType;\r\n\r\n /**\r\n * Sharing url for the content\r\n * @type {string}\r\n */\r\n sharingUrl?: string;\r\n}\r\n\r\n/**\r\n * Helper for building sharing details\r\n * @class\r\n */\r\nexport class SharingHelper {\r\n /**\r\n * Base production url used in the sharing link\r\n */\r\n private static readonly SharingBaseUrlDefault: string = \"http://a.msn.com/\";\r\n\r\n /**\r\n * Path format used to build the sharing url\r\n */\r\n private static readonly shortUrlPathFormat: string = \"{0}{1}/{2}/{3}\";\r\n\r\n /**\r\n * List the available options that should be mapped to prod url\r\n */\r\n private static readonly SharingProductionHosts: string = \"bing.com|www.bing.com|preview.msn.com|www.msn.com\";\r\n\r\n /**\r\n * String used to map the AppId number to single char identifier required in the sharing url\r\n */\r\n private static readonly Base36AppIdString: string = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\r\n\r\n /**\r\n * Path format used to append querystring to the sharing url\r\n */\r\n private static readonly appendQueryStringFormat: string = \"{0}?ocid={1}\";\r\n\r\n /**\r\n * List of available vertical keys to be mapped.\r\n * The order matter here as the AppId to be used is based on the array index of the key\r\n */\r\n private static readonly AppKeys: string[] = [\"finance\",\r\n \"news\",\r\n \"sports\",\r\n \"travel\",\r\n \"weather\",\r\n \"health\",\r\n \"foodanddrink\",\r\n \"entertainment\",\r\n \"autos\",\r\n \"video\",\r\n \"tv\",\r\n \"music\",\r\n \"movies\",\r\n \"games\",\r\n \"lifestyle\",\r\n \"kids\",\r\n \"sample\",\r\n \"asia\",\r\n \"africa\",\r\n \"australasia\",\r\n \"europe\",\r\n \"latinamerica\",\r\n \"middleeast\",\r\n \"northamerica\"];\r\n\r\n /**\r\n * Builds the short url that links to the article to be shared\r\n * @param sharingInfo The sharing data based on SharingInfo interface\r\n * @param locale The locale\r\n * @returns String with the short url to be shared\r\n */\r\n public static shortUrlBuilder(sharingInfo: SharingInfo, locale: string): string {\r\n const appId = this.getAppId();\r\n if (!appId) {\r\n return null;\r\n }\r\n\r\n const baseUrl = this.getSharingUrlBase(sharingInfo.sharingUrl);\r\n\r\n return baseUrl + format(this.shortUrlPathFormat, sharingInfo.documentType, appId, locale, sharingInfo.documentId);\r\n }\r\n\r\n /**\r\n * Gets the base36 AppId that is mapped from the vertical key identifier\r\n * @returns The mapped AppId\r\n */\r\n public static getAppId(): string {\r\n const { HostPage } = getAppEnvironment();\r\n const verticalKey: string = ((HostPage && HostPage.verticalKey) || \"news\").toLowerCase();\r\n let appId = indexOf(this.AppKeys, verticalKey);\r\n if (appId === -1 || appId >= this.Base36AppIdString.length) {\r\n appId = 1;\r\n }\r\n const base36Id = this.Base36AppIdString.substr(appId, 1);\r\n return base36Id;\r\n }\r\n\r\n /**\r\n * Gets the base url to be used in the shared link\r\n * @param articleUrl The full article url\r\n * @returns The base url to be used in the shared link\r\n */\r\n public static getSharingUrlBase(articleUrl: string): string {\r\n const url = new URL(articleUrl, getLocationOrigin());\r\n\r\n const host = url.host;\r\n const currentBaseUrl = url.origin + \"/\";\r\n\r\n const splitUrls = this.SharingProductionHosts.split(\"|\");\r\n\r\n const baseUrl = splitUrls.indexOf(host) > -1 ? this.SharingBaseUrlDefault : currentBaseUrl;\r\n\r\n return baseUrl;\r\n }\r\n\r\n /**\r\n * Strips off query string params\r\n * @param url Input url\r\n * @returns The plain url\r\n */\r\n public static getUrlWithoutQueryParams(url: string): string {\r\n if (url && url.length > 0) {\r\n return url.split(\"?\")[0];\r\n }\r\n\r\n return null;\r\n }\r\n\r\n /**\r\n * Retrieves the URL for sharing with Social Media.\r\n * @param locationHref current window.location.href from requestContext\r\n * @param medias social media to be included\r\n * @param contentUrl The url of the content to be shared\r\n * @param contentTitle The title of the content\r\n * @param emailBody The body text to be used in the email\r\n * @param ocid The ocid to be included in the shared link\r\n * @returns The share url\r\n */\r\n public static getSocialMediaShareUrl(locationHref: string, media: string, contentUrl: string, contentTitle: string, emailBody?: string, ocid?: string, overrideShareUrl?: string): string {\r\n if (!locationHref || !media || !contentUrl || !contentTitle) {\r\n logger.logError(`SharingHelper: getSocialMediaShareUrl: Parameter missing: locationHref=${locationHref}, media=${media}, contentUrl=${contentUrl}, contentTitle=${contentTitle}`);\r\n return;\r\n }\r\n\r\n const socialMediaItemConfig = SocialMediaDefaultConfig[media];\r\n if (!socialMediaItemConfig) {\r\n logger.logError(`SharingHelper: getSocialMediaShareUrl: Cannot find media type: ${socialMediaItemConfig}`);\r\n return \"\";\r\n }\r\n\r\n let shareUrl = overrideShareUrl || socialMediaItemConfig.url;\r\n if (media === SocialMedia.Skype) {\r\n shareUrl = shareUrl.replace(\"{flowid}\", uniqueId());\r\n }\r\n\r\n if (ocid) {\r\n contentUrl = format(this.appendQueryStringFormat, contentUrl, ocid);\r\n }\r\n\r\n if (media === SocialMedia.Email && emailBody) {\r\n emailBody = format(emailBody, contentTitle, contentUrl);\r\n }\r\n\r\n shareUrl = String.Format(shareUrl, {\r\n url: encodeURIComponent(contentUrl),\r\n title: encodeURIComponent(contentTitle),\r\n body: emailBody ? encodeURIComponent(emailBody): \"\",\r\n refererUrl: locationHref\r\n });\r\n\r\n return shareUrl;\r\n }\r\n\r\n /**\r\n * Opens the social media sharing page in a new window\r\n * @param event Mouse event\r\n * @param shareUrl The complete url to be shared\r\n * @param options The features optional parameter in window.open\r\n */\r\n public static openNewWindow = (event: React.MouseEvent, shareUrl: string, options?: any): void => {\r\n const defaultOptions = { toolbar: 0, status: 0, resizable: 1, scrollbars: 1 };\r\n const finalOptions = Object.entries({ ...defaultOptions, ...options })\r\n .map(entry => entry.join(\"=\"))\r\n .join(\",\");\r\n\r\n window.open(shareUrl, null, finalOptions);\r\n };\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\n/**\r\n * Default name for the content action toolbar experience\r\n */\r\nexport const experienceDefaultName = \"ContentActionsToolbar\";\r\n\r\n/**\r\n * Windows sizes to trigger breakpoint tracker\r\n */\r\nexport const BreakpointIndexToPx = [0, 1152, 1263];\r\n\r\n/**\r\n * The breakpoint indexes to be maped by breakpoint tracker\r\n */\r\nexport enum ToolbarBreakpoints {\r\n Breakpoint3_1 = 0,\r\n Breakpoint3_2 = 1,\r\n Breakpoint3_3 = 2\r\n}\r\n\r\n/**\r\n * Constant names for telemetry data\r\n */\r\nexport enum TelemetryConstants {\r\n socialToolbarTelemetryName = \"socialtoolbar\",\r\n closeDialogTelemetryName = \"Close\",\r\n copyLinkTelemetryName = \"CopyLink\",\r\n shareArticleTelemetryName = \"ShareArticle\",\r\n shareDialogTelemetryName = \"ShareDialog\"\r\n}\r\n\r\n/**\r\n * Spa placeholders Ids\r\n */\r\nexport enum PlaceHolderId {\r\n vertical = \"content-actions-toolbar-vert\",\r\n horizontal = \"content-actions-toolbar-horiz\"\r\n}\r\n\r\n/**\r\n * Action keys for like/dislike\r\n */\r\nexport enum LikeDislikeActionKey {\r\n like = \"like\",\r\n dislike = \"dislike\",\r\n undoliked = \"undoliked\",\r\n undodisliked = \"undodisliked\"\r\n}\r\n\r\n/**\r\n * action keys available in content action\r\n */\r\nexport enum SelectPropKey {\r\n onLike = \"onLike\",\r\n onDislike = \"onDislike\",\r\n onOpenOptions = \"onOpenOptions\",\r\n onShareDialogOpen = \"onShareDialogOpen\"\r\n}\r\n\r\n/**\r\n * Content Status\r\n */\r\nexport enum Status {\r\n None = \"none\",\r\n Like = \"like\",\r\n DisLike = \"dislike\"\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { SocialMedia, SocialMediaTarget } from \"@msnews/views-helpers\";\r\n\r\nimport { CardContextMenuItem } from \"@msnews/card-context-menu\";\r\nimport { DialogArticleCardProps } from \"../dialog-article-card\";\r\nimport { GlyphType } from \"@msnews/icon\";\r\nimport { IRequestContext } from \"@msnews/core\";\r\nimport { ManagedClasses } from \"@microsoft/fast-components-class-name-contracts-msft\";\r\nimport { ShareDialogProps } from \"@msnews/share-dialog\";\r\nimport { SharingToolbarClassNames } from \"./\";\r\nimport { Status } from \"../../ContentActionsToolbar.constants\";\r\nimport { TelemetryTags } from \"@msnews/telemetry-contracts\";\r\nimport { ToolbarPosition } from \"../..\";\r\n\r\n/**\r\n * Enumeration of available button type options\r\n * @type {enum}\r\n */\r\nexport enum ButtonType {\r\n SocialMedia = \"SocialMedia\",\r\n ShareDialog = \"ShareDialog\",\r\n LikeDislike = \"LikeDislike\",\r\n MoreOptions = \"MoreOptions\"\r\n}\r\n\r\n/**\r\n * Coordinate position type\r\n */\r\nexport type CoordinatePos = {\r\n /**\r\n * A horizontal coordinate position\r\n * @type {number}\r\n */\r\n x: number;\r\n\r\n /**\r\n * A vertical coordinate position\r\n * @type {number}\r\n */\r\n y: number;\r\n};\r\n\r\n/**\r\n * The social media type button\r\n */\r\nexport type SocialMediaType = {\r\n /**\r\n * Optional HTML anchor attributes\r\n * @type {React.HTMLAttributes}\r\n */\r\n attributes?: React.HTMLAttributes;\r\n\r\n /**\r\n * The social media enum type\r\n * @type {SocialMedia}\r\n */\r\n mediaType: SocialMedia;\r\n\r\n /**\r\n * The shared content url\r\n * @type {string}\r\n */\r\n contentUrl: string;\r\n\r\n /**\r\n * The shared content title\r\n * @type {string}\r\n */\r\n contentTitle: string;\r\n\r\n /**\r\n * The localized email body text\r\n * @type {string}\r\n */\r\n emailBody?: string;\r\n\r\n /**\r\n * The icon to be used instead of default one\r\n * @type {GlyphType}\r\n */\r\n icon?: GlyphType;\r\n\r\n /**\r\n * The ocid value to be used\r\n * @type {string}\r\n */\r\n ocid?: string;\r\n\r\n /**\r\n * The social media anchor target attribute option to be used\r\n * @type {SocialMediaTarget}\r\n */\r\n target?: SocialMediaTarget;\r\n\r\n /**\r\n * The telemetry callback to triggered when new window is used as the anchor target\r\n * @type {(event: any) => void}\r\n */\r\n newWindowTelemetryCall?: (event: any) => void;\r\n};\r\n\r\n/**\r\n * The share dialog type button\r\n */\r\nexport type ShareDialogType = {\r\n /**\r\n * Optional HTML button attributes\r\n * @type {React.HTMLAttributes}\r\n */\r\n attributes?: React.HTMLAttributes;\r\n\r\n /**\r\n * The share dialog component props\r\n * @type {ShareDialogProps}\r\n */\r\n shareDialogProps: ShareDialogProps;\r\n\r\n /**\r\n * The dialog article card component props\r\n * @type {DialogArticleCardProps}\r\n */\r\n dialogArticleCardProps: DialogArticleCardProps;\r\n\r\n /**\r\n * The telemetry tags\r\n * @type {TelemetryTags}\r\n */\r\n articleTelemetryTags?: TelemetryTags;\r\n\r\n /**\r\n * Callback to be triggered at user click\r\n * @type {(event: any) => void}\r\n */\r\n onSelect?: (event: any) => void;\r\n};\r\n\r\n/**\r\n * The like/dislike type button\r\n */\r\nexport type LikeDislikeType = {\r\n /**\r\n * Optional HTML button attributes\r\n * @type {React.HTMLAttributes}\r\n */\r\n attributes?: React.HTMLAttributes;\r\n\r\n /**\r\n * Current status (like/dislike/none) of the content\r\n * @type {Status}\r\n */\r\n status: Status;\r\n\r\n /**\r\n * Callback to be triggered at user click\r\n * @type {(event: any) => void}\r\n */\r\n onSelect?: (event: any) => void;\r\n};\r\n\r\n/**\r\n * The more options type button\r\n */\r\nexport type MoreOptionsType = {\r\n /**\r\n * Optional HTML div attributes\r\n * @type {React.HTMLAttributes}\r\n */\r\n attributes?: React.HTMLAttributes;\r\n\r\n /**\r\n * Current status (like/dislike/none) of the content\r\n * @type {Status}\r\n */\r\n status: Status;\r\n\r\n /**\r\n * The array of items to be displayed in the menu\r\n * @type {CardContextMenuItem[]}\r\n */\r\n menuItems: CardContextMenuItem[];\r\n\r\n /**\r\n * The offset position of the menu to open in relation to its button\r\n * Default to (0,0)\r\n * @type {CoordinatePos}\r\n */\r\n offsetPos?: CoordinatePos;\r\n\r\n /**\r\n * The override zIndex to be used by the menu\r\n * @type {number}\r\n */\r\n zIndex?: number;\r\n};\r\n\r\n/**\r\n * The button item common type\r\n */\r\nexport type ButtonItemType = {\r\n /**\r\n * The content actions toolbar button type\r\n * @type {ButtonType}\r\n */\r\n buttonType: ButtonType;\r\n\r\n /**\r\n * The content actions toolbar button data type\r\n * @type {ButtonDataType}\r\n */\r\n buttonData?: ButtonDataType;\r\n\r\n /**\r\n * The telemetry tags\r\n * @type {TelemetryTags}\r\n */\r\n telemetryTags?: TelemetryTags;\r\n};\r\n\r\nexport type ButtonDataType = Partial;\r\n\r\n/**\r\n * An interface to represent the SharingToolbar jss managed classes.\r\n *\r\n * @export\r\n * @interface SharingToolbarManagedClasses\r\n */\r\nexport type SharingToolbarManagedClasses = ManagedClasses;\r\n\r\n/**\r\n * An interface to represent the SharingToolbar handled props.\r\n *\r\n * @export\r\n * @interface SharingToolbarHandledProps\r\n */\r\nexport interface SharingToolbarHandledProps extends SharingToolbarManagedClasses {\r\n\r\n /**\r\n * The toolbar position (vertical/horizontal)\r\n * @type {ToolbarPosition}\r\n */\r\n position: ToolbarPosition;\r\n\r\n /**\r\n * The sharing buttons configuration array\r\n * @type {ButtonItemType[]}\r\n */\r\n sharingButtons: ButtonItemType[];\r\n\r\n /**\r\n * Request specific context\r\n */\r\n requestContext: IRequestContext;\r\n}\r\n\r\n/**\r\n * An interface to represent the SharingToolbar unhandled props.\r\n * @export\r\n * @interface SharingToolbarUnHandledProps\r\n */\r\nexport type SharingToolbarUnHandledProps = React.HTMLAttributes;\r\n\r\n/**\r\n * The SharingToolbar props type\r\n */\r\nexport type SharingToolbarProps = SharingToolbarHandledProps & SharingToolbarUnHandledProps;","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ActionMap } from \"@msnews/experiences-redux\";\r\nimport { DocumentData } from \"./ContentActionsToolbar.state\";\r\nimport { Status } from \"./ContentActionsToolbar.constants\";\r\nimport { ToolbarPosition } from \"./ContentActionsToolbar.props\";\r\n\r\ntype InitializeToolbar = (breakpointIndex: number, isRSThreeDevice: boolean, documentId: string, staticPosition: ToolbarPosition) => void;\r\ntype ContentStatuReady = (status: Status) => void;\r\ntype DocumentDataReady = (documentData: DocumentData) => void;\r\ntype LikeContent = () => void;\r\ntype UnlikeContent = () => void;\r\ntype DislikeContent = () => void;\r\ntype UndislikeContent = () => void;\r\ntype ViewportUpdate = (breakpointIndex: number, isRSThreeDevice: boolean) => void;\r\ntype SharingToolbarError = (error: Error) => void;\r\n\r\n/**\r\n * Class containing actions that apply to the ContentActionsToolbar connector\r\n * @class\r\n */\r\nexport class ContentActionsToolbarActions {\r\n public static initializeToolbar: ActionMap = new ActionMap(\"InitializeToolbar\");\r\n public static ContentStatuReady: ActionMap = new ActionMap(\"ContentStatuReady\");\r\n public static documentDataReady: ActionMap = new ActionMap(\"DocumentDataReady\");\r\n public static likeContent: ActionMap = new ActionMap(\"LikeContent\");\r\n public static unlikeContent: ActionMap = new ActionMap(\"UnlikeContent\");\r\n public static dislikeContent: ActionMap = new ActionMap(\"DislikeContent\");\r\n public static undislikeContent: ActionMap = new ActionMap(\"UndislikeContent\");\r\n public static sharingToolbarError: ActionMap = new ActionMap(\"SharingToolbarError\");\r\n public static ViewportUpdate: ActionMap = new ActionMap(\"ViewportUpdate\");\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { CardContextMenuItem } from \"@msnews/card-context-menu\";\r\nimport { CoordinatePos } from \"./SharingToolbar.props\";\r\nimport { Glyph } from \"@msnews/icon\";\r\nimport { LikeDislikeActionKey } from \"../../ContentActionsToolbar.constants\";\r\n\r\n/**\r\n * Default color for the icon container\r\n */\r\nexport const iconContainerDefaultColor = \"#EEE\";\r\n\r\n/**\r\n * Colors for the more options icon\r\n */\r\nexport const moreOptionsIconColors = {\r\n background: iconContainerDefaultColor,\r\n foreground: \"#666\"\r\n};\r\n\r\n/**\r\n * Background colors for the like dislike icon\r\n */\r\nexport const likeDislikeIconBackroundColor = {\r\n none: iconContainerDefaultColor,\r\n like: \"#FF4343\",\r\n dislike: \"#666\"\r\n};\r\n\r\n/**\r\n * Default offset position to display the more options context menu\r\n */\r\nexport const moreOptionsMenuDefaultOffsetPos: CoordinatePos = {\r\n x: 0,\r\n y: -80\r\n};\r\n\r\n/**\r\n * Menu items to render the like option\r\n */\r\nexport const OptionItemLike: CardContextMenuItem = {\r\n key: LikeDislikeActionKey.like,\r\n text: null,\r\n onSelect: null,\r\n icon: Glyph.Like,\r\n telemetryTag: null\r\n};\r\n\r\n/**\r\n * Menu items to render the dislike option\r\n */\r\nexport const OptionItemDislike: CardContextMenuItem = {\r\n key: LikeDislikeActionKey.dislike,\r\n text: null,\r\n onSelect: null,\r\n icon: Glyph.Disliked,\r\n telemetryTag: null\r\n};\r\n\r\n/**\r\n * Menu items to render the undo like option\r\n */\r\nexport const OptionItemUndoLike: CardContextMenuItem = {\r\n key: LikeDislikeActionKey.undoliked,\r\n text: null,\r\n onSelect: null,\r\n icon: Glyph.Like,\r\n telemetryTag: null\r\n};\r\n\r\n/**\r\n * Menu items to render the undo dislike option\r\n */\r\nexport const OptionItemUndoDislike: CardContextMenuItem = {\r\n key: LikeDislikeActionKey.undodisliked,\r\n text: null,\r\n onSelect: null,\r\n icon: Glyph.Dislike,\r\n telemetryTag: null\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ContentActionsToolbarConfig, ContentActionsToolbarProps, ContentActionsToolbarState, Status } from \".\";\r\nimport { IRequestContext, InspectorArgs, InspectorResponse } from \"@msnews/core\";\r\nimport { OptionItemDislike, OptionItemLike, OptionItemUndoDislike, OptionItemUndoLike } from \"./components/sharing-toolbar/SharingToolbar.constants\";\r\n\r\nimport { ButtonType } from \"./components/sharing-toolbar/SharingToolbar\";\r\nimport { CardContextMenuItem } from \"@msnews/card-context-menu\";\r\nimport { SocialMediaTarget } from \"@msnews/views-helpers\";\r\nimport { cloneDeep } from \"lodash-es\";\r\n\r\n/**\r\n * Type for ContentActionsToolbar connectorArgs\r\n *\r\n * @export\r\n * @type {ContentActionsToolbarConnectorArgs}\r\n */\r\nexport type ContentActionsToolbarConnectorArgs = {\r\n /** Flag to indicate if there's a need to wait for content status endpoint response */\r\n isContentStatusRequired: boolean;\r\n requestContext: IRequestContext;\r\n};\r\n\r\nexport type ContentActionsToolbarInspectorArgs = InspectorArgs;\r\n\r\nexport namespace ContentActionsToolbarInspector {\r\n export function inspect(args: ContentActionsToolbarInspectorArgs): InspectorResponse {\r\n const { config, state, config: { localizedStrings } } = args;\r\n const { isContentStatusRequired, requestContext } = args.connectorArgs as ContentActionsToolbarConnectorArgs;\r\n\r\n const newProps: ContentActionsToolbarProps = {\r\n staticPosition: state.staticPosition,\r\n position: state.position,\r\n sharingToolbar: {\r\n position: state.position,\r\n sharingButtons: [],\r\n requestContext\r\n },\r\n contentStatus: args.state.status,\r\n sharingError: args.state.sharingError\r\n };\r\n\r\n const sharingShortUrl = state.documentData ? state.documentData.sharingShortUrl : undefined;\r\n const articleTitle = state.documentData ? state.documentData.articleTitle : undefined;\r\n const articleImageUrl = state.documentData ? state.documentData.articleImageUrl : undefined;\r\n const providerName = state.documentData ? state.documentData.providerName : undefined;\r\n const providerLogoUrl = state.documentData ? state.documentData.providerLogoUrl : undefined;\r\n\r\n if ((!isContentStatusRequired || state.status) && state.documentData) {\r\n newProps.sharingToolbar.sharingButtons = config.sharingButtons.map(buttonItem => {\r\n let newButtonItem = cloneDeep(buttonItem);\r\n switch (buttonItem.buttonType) {\r\n case ButtonType.SocialMedia:\r\n if (newButtonItem.buttonData) {\r\n newButtonItem.buttonData.contentUrl = sharingShortUrl;\r\n newButtonItem.buttonData.contentTitle = articleTitle;\r\n newButtonItem.buttonData.emailBody = localizedStrings.emailBodyText;\r\n newButtonItem.buttonData.target = buttonItem.buttonData.target ? SocialMediaTarget[buttonItem.buttonData.target] : undefined;\r\n } else {\r\n newButtonItem = undefined;\r\n }\r\n break;\r\n case ButtonType.ShareDialog:\r\n if (newButtonItem.buttonData && newButtonItem.buttonData.shareDialogProps && newButtonItem.buttonData.shareDialogProps.socialMediaItems) {\r\n const { shareDialogProps } = newButtonItem.buttonData;\r\n shareDialogProps.enabled = true;\r\n shareDialogProps.contentUrl = sharingShortUrl;\r\n shareDialogProps.contentTitle = articleTitle;\r\n shareDialogProps.emailBody = localizedStrings.emailBodyText;\r\n shareDialogProps.dialogStrings = {\r\n dialogTitle: localizedStrings.shareDialogTitleText,\r\n copyButton: localizedStrings.shareDialogCopyButtonText,\r\n copyButtonAriaLabel: localizedStrings.shareDialogCopyButtonAriaLabelText,\r\n copiedButton: localizedStrings.shareDialogCopiedButtonText,\r\n copiedButtonAriaLabel: localizedStrings.shareDialogCopiedButtonAriaLabelText\r\n };\r\n\r\n newButtonItem.buttonData.dialogArticleCardProps = {\r\n articleId: state.documentId,\r\n headlineTitle: {\r\n tag: undefined,\r\n children: articleTitle\r\n },\r\n href: sharingShortUrl,\r\n image: {\r\n alt: articleTitle,\r\n src: articleImageUrl\r\n },\r\n provider: {\r\n name: {\r\n title: providerName,\r\n children: providerName\r\n },\r\n image: {\r\n src: providerLogoUrl,\r\n alt: providerName\r\n }\r\n }\r\n };\r\n\r\n newButtonItem.buttonData.attributes = {\r\n \"aria-label\": localizedStrings.shareDialogButtonAriaLabelText,\r\n \"aria-hidden\": false,\r\n title: localizedStrings.shareDialogButtonAriaLabelText\r\n };\r\n } else {\r\n newButtonItem = undefined;\r\n }\r\n break;\r\n case ButtonType.LikeDislike:\r\n newButtonItem.buttonData = {\r\n attributes: {\r\n \"aria-label\": localizedStrings.likeDislikeButtonAriaLabelText,\r\n \"aria-hidden\": false,\r\n title: localizedStrings.likeDislikeButtonAriaLabelText\r\n },\r\n status: state.status\r\n };\r\n break;\r\n case ButtonType.MoreOptions: {\r\n const menuItems: CardContextMenuItem[] = [];\r\n if (state.status === Status.Like) {\r\n OptionItemUndoLike.text = localizedStrings.moreOptionsUnlikeText;\r\n OptionItemUndoLike.attr = {\r\n \"aria-label\": localizedStrings.moreOptionsUnlikeAriaLabelText,\r\n \"aria-hidden\": false,\r\n title: localizedStrings.moreOptionsUnlikeAriaLabelText\r\n };\r\n menuItems.push(OptionItemUndoLike);\r\n\r\n OptionItemDislike.text = localizedStrings.moreOptionsDislikeText;\r\n OptionItemDislike.attr = {\r\n \"aria-label\": localizedStrings.moreOptionsDislikeAriaLabelText,\r\n \"aria-hidden\": false,\r\n title: localizedStrings.moreOptionsDislikeAriaLabelText\r\n };\r\n menuItems.push(OptionItemDislike);\r\n } else if (state.status === Status.DisLike) {\r\n OptionItemUndoDislike.text = localizedStrings.moreOptionsUndislikeText;\r\n OptionItemUndoDislike.attr = {\r\n \"aria-label\": localizedStrings.moreOptionsUndislikeAriaLabelText,\r\n \"aria-hidden\": false,\r\n title: localizedStrings.moreOptionsUndislikeAriaLabelText\r\n };\r\n menuItems.push(OptionItemUndoDislike);\r\n\r\n OptionItemLike.text = localizedStrings.moreOptionsLikeText;\r\n OptionItemLike.attr = {\r\n \"aria-label\": localizedStrings.moreOptionsLikeAriaLabelText,\r\n \"aria-hidden\": false,\r\n title: localizedStrings.moreOptionsLikeAriaLabelText\r\n };\r\n menuItems.push(OptionItemLike);\r\n } else {\r\n OptionItemDislike.text = localizedStrings.moreOptionsDislikeText;\r\n OptionItemDislike.attr = {\r\n \"aria-label\": localizedStrings.moreOptionsDislikeAriaLabelText,\r\n \"aria-hidden\": false,\r\n title: localizedStrings.moreOptionsDislikeAriaLabelText\r\n };\r\n menuItems.push(OptionItemDislike);\r\n }\r\n newButtonItem.buttonData = {\r\n attributes: {\r\n \"aria-label\": localizedStrings.moreOptionsButtonAriaLabelText,\r\n \"aria-hidden\": false,\r\n title: localizedStrings.moreOptionsButtonAriaLabelText\r\n },\r\n menuItems: menuItems,\r\n status: state.status,\r\n offsetPos: buttonItem.buttonData ? buttonItem.buttonData.offsetPos : undefined,\r\n zIndex: buttonItem.buttonData ? buttonItem.buttonData.zIndex : undefined\r\n };\r\n break;\r\n }\r\n default:\r\n break;\r\n }\r\n return newButtonItem;\r\n }).filter(value => value);\r\n }\r\n\r\n return {\r\n props: newProps,\r\n missingChildren: []\r\n };\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n KeyValuePair,\r\n appEnvironment,\r\n headData,\r\n oneServiceQueryStringKeys\r\n} from \"@msnews/core\";\r\nimport { OneServiceUtility, getServiceUrlForSubpath, sendRequest } from \"@msnews/oneservice\";\r\n\r\nimport { ContentActionsToolbarAppErrors } from \"@msnews/diagnostics\";\r\nimport { DocumentData } from \"../ContentActionsToolbar.state\";\r\nimport { Status } from \"../ContentActionsToolbar.constants\";\r\nimport { Telemetry } from \"@msnews/telemetry-contracts\";\r\nimport { get } from \"lodash-es\";\r\n\r\n/**\r\n * Class to fetch data for the content actions toolbar experience\r\n * @class ContentActionsToolbarServiceClient\r\n */\r\nexport class ContentActionsToolbarServiceClient {\r\n /**\r\n * The actions service end point\r\n */\r\n private contentActionsServiceEndpoint = \"Graph/Actions\";\r\n\r\n /**\r\n * The content preview endpoint\r\n */\r\n private contentPreviewApiEndpoint = \"view/v1/Preview\";\r\n\r\n /**\r\n * The template url for article images\r\n */\r\n private articleImageUrl = \"https://img-s-msn-com.akamaized.net/tenant/amp/entityid/${imageId}.img?h=100&w=100&m=6&q=60&u=t&o=t&l=f&f=png\";\r\n\r\n /**\r\n * The template url for provider logo images\r\n */\r\n private providerLogoUrl = \"https://img-s-msn-com.akamaized.net/tenant/amp/entityid/${logoId}.img?h=16&w=16&m=6&q=60&u=t&o=t&l=f&f=png\";\r\n\r\n /**\r\n * the ocid for request\r\n */\r\n private ocid = \"feeds\";\r\n\r\n /**\r\n * Initializes a new instance of the `ContentActionsToolbarServiceClient` class.\r\n * @constructor\r\n * @public\r\n * @param {any} fetchImpl - The fetch implementation\r\n */\r\n public constructor(private fetchImpl: any) {\r\n }\r\n\r\n /**\r\n * Get content preference initial state\r\n * @param {string} targetId target id\r\n */\r\n public async GetPreferenceInitialState(targetId: string): Promise {\r\n let initialState: Status = undefined;\r\n try {\r\n const response = await this.GetContentStatusRequest(targetId);\r\n const isLike = response && response[\"value\"] && response[\"value\"].find(obj => obj.actionType === \"Like\");\r\n const isDislike = response && response[\"value\"] && response[\"value\"].find(obj => obj.actionType === \"Dislike\");\r\n if (isLike) {\r\n initialState = Status.Like;\r\n } else if (isDislike) {\r\n initialState = Status.DisLike;\r\n } else {\r\n initialState = Status.None;\r\n }\r\n } catch (error) {\r\n Telemetry.sendAppErrorEvent({\r\n ...ContentActionsToolbarAppErrors.ContentActionsGetContentStatusActionError,\r\n message: \"Failed obtaining content status\",\r\n pb: {\r\n ...ContentActionsToolbarAppErrors.ContentActionsGetContentStatusActionError.pb,\r\n customMessage: `Error: ${error}`\r\n }\r\n });\r\n }\r\n return initialState;\r\n }\r\n\r\n /**\r\n * Get required document data\r\n * @param {string} targetId target id\r\n */\r\n public async GetDocumentData(targetId: string): Promise {\r\n let documentData: DocumentData = undefined;\r\n try {\r\n const contentPreviewData = await this.GetContentPreviewData(targetId);\r\n documentData = this.TranslateContentPreviewDocumentData(contentPreviewData);\r\n if (!documentData) {\r\n throw new Error(`Failed to map content preview data to DocumentData. TargetId: ${targetId}`);\r\n }\r\n } catch (error) {\r\n Telemetry.sendAppErrorEvent({\r\n ...ContentActionsToolbarAppErrors.ContentActionsGetDocumentDataError,\r\n message: \"Failed obtaining document data\",\r\n pb: {\r\n ...ContentActionsToolbarAppErrors.ContentActionsGetDocumentDataError.pb,\r\n customMessage: `Error: ${error}`\r\n }\r\n });\r\n }\r\n return documentData;\r\n }\r\n\r\n /**\r\n * The dislike target service call\r\n * @param targetId target id to be disliked\r\n */\r\n public async Dislike(targetId: string): Promise {\r\n return this.PostContentActionRequest(targetId, \"Dislike\");\r\n }\r\n\r\n /**\r\n * The undislike target service call\r\n * @param targetId target id to be undislike\r\n */\r\n public async Undislike(targetId: string): Promise {\r\n return this.DeleteContentActionRequest(targetId, \"Dislike\");\r\n }\r\n\r\n /**\r\n * The like target service call\r\n * @param targetId target id to be like\r\n */\r\n public async Like(targetId: string): Promise {\r\n return this.PostContentActionRequest(targetId, \"Like\");\r\n }\r\n\r\n /**\r\n * The like target service call\r\n * @param targetId target id to be like\r\n */\r\n public async Unlike(targetId: string): Promise {\r\n return this.DeleteContentActionRequest(targetId, \"Like\");\r\n }\r\n\r\n /**\r\n * Set request to service to get the metadata about content status\r\n * @param targetId target id\r\n */\r\n private async GetContentStatusRequest(targetId: string): Promise {\r\n const requestParams = await OneServiceUtility.getBaseRequestData(\"GET\");\r\n requestParams.credentials = headData.UserIsSignedIn ? \"include\" : undefined;\r\n\r\n const serviceUrl = getServiceUrlForSubpath(this.contentActionsServiceEndpoint);\r\n const commonParams = OneServiceUtility.getCommonParams(this.ocid);\r\n [\r\n ...commonParams,\r\n {\r\n key: \"$filter\",\r\n value: `targetId eq '${targetId}'`\r\n }\r\n ].forEach(pair => pair.value && serviceUrl.searchParams.set(pair.key, pair.value));\r\n\r\n let contentStatusData: any;\r\n try {\r\n contentStatusData = await (sendRequest(\r\n async () => {\r\n const response: Response = await this.fetchImpl(serviceUrl.href, requestParams);\r\n if (response.status >= 400) {\r\n throw new Error(response.statusText);\r\n }\r\n return response.json();\r\n },\r\n \"getContentAction\"\r\n ));\r\n } catch (error) {\r\n Telemetry.sendAppErrorEvent({\r\n ...ContentActionsToolbarAppErrors.ContentActionsContentStatusFetchError,\r\n message: \"Failed to fetch from content status data endpoint\",\r\n pb: {\r\n ...ContentActionsToolbarAppErrors.ContentActionsContentStatusFetchError.pb,\r\n customMessage: `Service URL: ${serviceUrl}, error: ${error}`\r\n }\r\n });\r\n }\r\n\r\n return contentStatusData;\r\n }\r\n\r\n /**\r\n * Gets article content data from ContentPreview endpoint\r\n * @param articleId the article id\r\n * @returns Primise The article details data\r\n */\r\n private async GetContentPreviewData(articleId: string): Promise {\r\n const requestParams = await OneServiceUtility.getBaseRequestData(\"GET\");\r\n requestParams.credentials = headData.UserIsSignedIn ? \"include\" : undefined;\r\n\r\n // Build the url\r\n const serviceUrl = new URL(`${this.contentPreviewApiEndpoint}/${articleId}${appEnvironment.ContentServiceUrlBase.search}`, appEnvironment.ContentServiceUrlBase);\r\n\r\n let contentPreviewData: any;\r\n try {\r\n contentPreviewData = await (sendRequest(\r\n async () => {\r\n const response: Response = await this.fetchImpl(serviceUrl.href, requestParams);\r\n if (response.status >= 400) {\r\n throw new Error(response.statusText);\r\n }\r\n return response.json();\r\n },\r\n \"getContentAction\"\r\n ));\r\n } catch (error) {\r\n Telemetry.sendAppErrorEvent({\r\n ...ContentActionsToolbarAppErrors.ContentActionsContentPreviewFetchError,\r\n message: \"Failed to fetch from content views data endpoint\",\r\n pb: {\r\n ...ContentActionsToolbarAppErrors.ContentActionsContentPreviewFetchError.pb,\r\n customMessage: `Service URL: ${serviceUrl}, error: ${error}`\r\n }\r\n });\r\n }\r\n\r\n return contentPreviewData;\r\n }\r\n\r\n /**\r\n * Delete an action from target\r\n * @param targetId target to be deleted\r\n * @param actionType type of the action\r\n */\r\n private async DeleteContentActionRequest(targetId: string, actionType: string): Promise {\r\n const requestParams = await OneServiceUtility.getBaseRequestData(\"DELETE\");\r\n requestParams.credentials = headData.UserIsSignedIn ? \"include\" : undefined;\r\n\r\n const deleteQueryParam: KeyValuePair = {\r\n key: oneServiceQueryStringKeys.filter,\r\n value: `actionType eq '${actionType}' and targetId eq '${targetId}'`\r\n };\r\n\r\n const serviceUrl = getServiceUrlForSubpath(this.contentActionsServiceEndpoint);\r\n const commonParams = OneServiceUtility.getCommonParams(this.ocid);\r\n [\r\n deleteQueryParam,\r\n ...commonParams\r\n ].forEach((pair) => pair.value && serviceUrl.searchParams.set(pair.key, pair.value));\r\n\r\n let deleteResponse: Response;\r\n try {\r\n deleteResponse = await (sendRequest(\r\n async () => {\r\n const response: Response = await this.fetchImpl(serviceUrl.href, requestParams);\r\n if (response.status >= 400) {\r\n throw new Error(response.statusText);\r\n }\r\n return response;\r\n },\r\n `deleteContentAction${actionType}`\r\n ));\r\n } catch (error) {\r\n Telemetry.sendAppErrorEvent({\r\n ...ContentActionsToolbarAppErrors.ContentActionsDeleteActionError,\r\n message: \"Error while calling delete action for content actions toolbar\",\r\n pb: {\r\n ...ContentActionsToolbarAppErrors.ContentActionsDeleteActionError.pb,\r\n customMessage: `URL: ${serviceUrl.href}, error: ${error}`\r\n }\r\n });\r\n }\r\n\r\n return deleteResponse;\r\n }\r\n\r\n /**\r\n * create an action from target\r\n * @param targetId target to be created\r\n * @param actionType type of the action\r\n */\r\n private async PostContentActionRequest(targetId: string, actionType: string, targetType?: string): Promise {\r\n const requestParams: RequestInit = {\r\n method: \"POST\",\r\n body: JSON.stringify({\r\n actionType,\r\n targetId,\r\n targetType\r\n }),\r\n credentials: headData.UserIsSignedIn ? \"include\" : undefined,\r\n headers: await OneServiceUtility.getOneServiceHeaders()\r\n };\r\n\r\n const serviceUrl = getServiceUrlForSubpath(this.contentActionsServiceEndpoint);\r\n const commonParams = OneServiceUtility.getCommonParams(this.ocid);\r\n commonParams.forEach((pair) => {\r\n pair.value && serviceUrl.searchParams.set(pair.key, pair.value);\r\n });\r\n\r\n let postResponse: Response;\r\n try {\r\n postResponse = await (sendRequest(\r\n async () => {\r\n const response: Response = await this.fetchImpl(serviceUrl.href, requestParams);\r\n if (response.status >= 400) {\r\n throw new Error(response.statusText);\r\n }\r\n return response;\r\n },\r\n `getContentAction${actionType}`\r\n ));\r\n } catch (error) {\r\n Telemetry.sendAppErrorEvent({\r\n ...ContentActionsToolbarAppErrors.ContentActionsPostActionError,\r\n message: \"Error while posting action for content actions toolbar\",\r\n pb: {\r\n ...ContentActionsToolbarAppErrors.ContentActionsPostActionError.pb,\r\n customMessage: `URL: ${serviceUrl.href}, error: ${error}`\r\n }\r\n });\r\n }\r\n\r\n return postResponse;\r\n }\r\n\r\n /**\r\n * Schema Translator for content preview data\r\n * @param {any} articleDataResponse response data from content preview api\r\n * @returns {DocumentData} translated document data\r\n */\r\n private TranslateContentPreviewDocumentData(articleDataResponse: any): DocumentData {\r\n const articleImageId = get(articleDataResponse, \"images[0].id\", undefined);\r\n const providerLogoId = get(articleDataResponse, \"provider.logo.id\", undefined);\r\n\r\n return {\r\n articleTitle: get(articleDataResponse, \"title\", undefined),\r\n articleImageUrl: articleImageId ? this.articleImageUrl.replace(\"${imageId}\", articleImageId) : undefined,\r\n providerName: get(articleDataResponse, \"provider.name\", undefined),\r\n providerLogoUrl: providerLogoId ? this.providerLogoUrl.replace(\"${logoId}\", providerLogoId) : undefined\r\n };\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { BreakpointIndexToPx, LikeDislikeActionKey, Status, TelemetryConstants } from \"./ContentActionsToolbar.constants\";\r\nimport { BreakpointTracker, identifyBreakpoint } from \"@microsoft/fast-layouts-react\";\r\nimport { ButtonItemType, ButtonType } from \"./components/sharing-toolbar/SharingToolbar\";\r\nimport { ContentActionsToolbarActions, ContentActionsToolbarConfig, ContentActionsToolbarProps, ContentActionsToolbarState } from \".\";\r\nimport { ContentActionsToolbarConnectorArgs, ContentActionsToolbarInspector, ContentActionsToolbarInspectorArgs } from \"./ContentActionsToolbar.inspector\";\r\nimport { DynamicReducer, IReducer } from \"@msnews/experiences-redux\";\r\nimport { IRequestContext, InspectorResponse, getAppEnvironment } from \"@msnews/core\";\r\nimport { OptionItemDislike, OptionItemLike, OptionItemUndoDislike, OptionItemUndoLike } from \"./components/sharing-toolbar/SharingToolbar.constants\";\r\nimport { SharedDocumentType, SharingHelper, ViewsStringResource } from \"@msnews/views-helpers\";\r\nimport { Telemetry, TelemetryActionType, TelemetryBehaviorType, TelemetryObjectBase, TelemetryTags, TelemetryType } from \"@msnews/telemetry-contracts\";\r\n\r\nimport { ComponentConnector } from \"@msnews/experiences-connector\";\r\nimport { ContentActionsToolbarAppErrors } from \"@msnews/diagnostics\";\r\nimport { ContentActionsToolbarServiceClient } from \"./services\";\r\nimport { ContentActionsToolbarTelemetryHelper } from \"./ContentActionsToolbar.telemetry\";\r\nimport { ExperienceInitialProps } from \"@msnews/experiences-base\";\r\nimport { Store } from \"redux\";\r\nimport { getInnerWidth } from \"@msnews/isomorphic-util\";\r\n\r\n/**\r\n * An interface to represent the more options menu callbacks\r\n * @interface MoreOptionsCallbacks\r\n */\r\ninterface MoreOptionsCallbacks {\r\n /** On like event handler */\r\n onLike: (event: any) => void;\r\n\r\n /** On dislike evewnt hander */\r\n onDislike: (event: any) => void;\r\n}\r\n\r\n/**\r\n * The connector for the ContentActionsToolbar Experience\r\n * @class\r\n */\r\nexport class ContentActionsToolbarConnector extends ComponentConnector {\r\n\r\n /**\r\n * Telemetry related props for the experience.\r\n * @type {TelemetryObject}\r\n */\r\n private sharingToolbarTelemetryObject: TelemetryObjectBase;\r\n\r\n /**\r\n * Telemetry related tags for the experience.\r\n * @type {TelemetryObject}\r\n */\r\n private sharingToolbarTelemetryTags: TelemetryTags;\r\n\r\n /**\r\n * An instance of the content action service client\r\n * @type {ContentActionsToolbarServiceClient}\r\n */\r\n private actionServiceClient: ContentActionsToolbarServiceClient;\r\n\r\n /**\r\n * Flag to indicate LikeDislike button is present, so content status needs to be obtained\r\n * @type {boolean}\r\n */\r\n private isContentStatusRequired: boolean;\r\n\r\n /**\r\n * Telemetry related tags for the more option button.\r\n */\r\n private moreOptionsTelemetryTags: {\r\n Like: TelemetryTags,\r\n Dislike: TelemetryTags,\r\n UndoLike: TelemetryTags,\r\n UndoDislike: TelemetryTags\r\n };\r\n\r\n /**\r\n * Initializes the ContentActionsToolbar connector\r\n * @param {string} namespace Redux subspace name for the connector\r\n * @param {string} parentNamespace Redux subspace name for the parent connector\r\n * @param {DynamicReducer} rootReducer Application root reducer\r\n * @param {IReducer} reducer The connector reducer\r\n * @param {Store} store The store or redux subspace that the connector will be connected to\r\n * @param {ContentActionsToolbarConfig} config The configuration properties from config index\r\n * @param {IRequestContext} requestContext The request specific context\r\n */\r\n public constructor(namespace: string,\r\n parentNamespace: string,\r\n rootReducer: DynamicReducer,\r\n reducer: IReducer,\r\n store: Store,\r\n config: ContentActionsToolbarConfig,\r\n requestContext: IRequestContext) {\r\n super(namespace, parentNamespace, rootReducer, reducer, store, config, requestContext);\r\n\r\n this.isContentStatusRequired = config.sharingButtons.some(t => t.buttonType == ButtonType.LikeDislike);\r\n }\r\n\r\n /**\r\n * State mapper\r\n * @param state The current state for the connector\r\n */\r\n public mapStateToProps(state: ContentActionsToolbarState): ContentActionsToolbarProps {\r\n const contentActionsToolbarConnectorArgs: ContentActionsToolbarConnectorArgs = {\r\n isContentStatusRequired: this.isContentStatusRequired,\r\n requestContext: this.requestContext\r\n };\r\n\r\n const inspectorArgs: ContentActionsToolbarInspectorArgs = {\r\n config: this.config,\r\n children: {},\r\n state: state,\r\n connectorArgs: contentActionsToolbarConnectorArgs\r\n };\r\n\r\n let contentActionsToolbarProps: ContentActionsToolbarProps = {};\r\n\r\n if (state.documentId && state.documentData && (!this.isContentStatusRequired || state.status)) {\r\n const inspectorResponse: InspectorResponse = ContentActionsToolbarInspector.inspect(inspectorArgs);\r\n\r\n let likeDislikeCallbacks: MoreOptionsCallbacks;\r\n if (inspectorResponse.props.sharingToolbar && inspectorResponse.props.sharingToolbar.sharingButtons && inspectorResponse.props.sharingToolbar.sharingButtons.length > 0) {\r\n const sharingButtons = inspectorResponse.props.sharingToolbar.sharingButtons;\r\n\r\n let status: Status;\r\n if (this.isContentStatusRequired) {\r\n status = inspectorResponse.props.contentStatus;\r\n likeDislikeCallbacks = this.BuildLikeDislikeCallbacks(status, state.documentId);\r\n this.InjectCallbacksToMoreOptionsMenu(sharingButtons.find(m => m.buttonType === ButtonType.MoreOptions), status, likeDislikeCallbacks);\r\n\r\n // Set likeDislike button callback based on content status\r\n sharingButtons.find(m => m.buttonType === ButtonType.LikeDislike).buttonData\r\n .onSelect = (event: any) => status === Status.DisLike ? likeDislikeCallbacks.onDislike(event) : likeDislikeCallbacks.onLike(event);\r\n }\r\n\r\n ContentActionsToolbarTelemetryHelper.InjectTelemetry(sharingButtons, status, this.sharingToolbarTelemetryObject);\r\n }\r\n\r\n contentActionsToolbarProps = {\r\n ...inspectorResponse.props,\r\n rootTelemetryTags: this.sharingToolbarTelemetryTags,\r\n ...this.telemetryTags,\r\n ...likeDislikeCallbacks\r\n };\r\n }\r\n\r\n return contentActionsToolbarProps;\r\n }\r\n\r\n /**\r\n * Perform one time initialization of the connector, including getting initial state from config\r\n * @param {ExperienceInitialProps} connectorProps Application initial props\r\n */\r\n public async onComponentConnect(initialProps?: ExperienceInitialProps): Promise {\r\n await ComponentConnector.prototype.onComponentConnect.call(this, initialProps);\r\n\r\n const { contentId, context: { staticPosition, isRSThree = false, documentType = SharedDocumentType.CMS } } = initialProps;\r\n if (!contentId) {\r\n ContentActionsToolbarActions.sharingToolbarError.getActionSender(this).send(new Error(ViewsStringResource.sharingToolbarLoadFailure));\r\n this.onAppError({\r\n ...ContentActionsToolbarAppErrors.ContentActionsSharingToolbarLoadError,\r\n message: `Error while initializing content actions toolbar. Requried initial props is not available: InitialProps = ${initialProps}`\r\n });\r\n return;\r\n }\r\n\r\n this.actionServiceClient = new ContentActionsToolbarServiceClient(window.fetch.bind(window));\r\n\r\n this.generateTelemetryTags();\r\n\r\n if (this.isContentStatusRequired) {\r\n this.getContentStatus(contentId);\r\n }\r\n this.getDocumentData(contentId, documentType);\r\n\r\n const currentBreakpoint = this.initializeBreakpointTracker(isRSThree);\r\n ContentActionsToolbarActions.initializeToolbar.getActionSender(this).send(currentBreakpoint, isRSThree, contentId, staticPosition);\r\n }\r\n\r\n /**\r\n * Initialize and subscribe Breakpoint tracker to detect change in toolbar position\r\n */\r\n private initializeBreakpointTracker(isRSThree: boolean): number {\r\n BreakpointTracker.defaultBreakpoint = identifyBreakpoint(getInnerWidth());\r\n BreakpointTracker.breakpoints = BreakpointIndexToPx;\r\n BreakpointTracker.update();\r\n BreakpointTracker.subscribe(breakpoint => {\r\n ContentActionsToolbarActions.ViewportUpdate.getActionSender(this).send(breakpoint, isRSThree);\r\n });\r\n\r\n return BreakpointTracker.currentBreakpoint();\r\n }\r\n\r\n /**\r\n * Fetches the current status (like/dislike/none) of the document\r\n * @param {ExperienceInitialProps} documentId The document Id\r\n */\r\n private async getContentStatus(documentId: string): Promise {\r\n const contentStatus = await this.actionServiceClient.GetPreferenceInitialState(documentId);\r\n if (!contentStatus) {\r\n ContentActionsToolbarActions.sharingToolbarError.getActionSender(this).send(new Error(ViewsStringResource.sharingToolbarLoadFailure));\r\n this.onAppError({\r\n ...ContentActionsToolbarAppErrors.ContentActionsSharingToolbarLoadError,\r\n message: \"Error while retrieving content status data from API\"\r\n });\r\n return;\r\n }\r\n ContentActionsToolbarActions.ContentStatuReady.getActionSender(this).send(contentStatus);\r\n }\r\n\r\n /**\r\n * Fetches the required document data for the experience\r\n * @param {ExperienceInitialProps} documentId The document Id\r\n */\r\n private async getDocumentData(documentId: string, documentType: SharedDocumentType): Promise {\r\n const documentData = await this.actionServiceClient.GetDocumentData(documentId);\r\n if (!documentData) {\r\n ContentActionsToolbarActions.sharingToolbarError.getActionSender(this).send(new Error(ViewsStringResource.sharingToolbarLoadFailure));\r\n this.onAppError({\r\n ...ContentActionsToolbarAppErrors.ContentActionsSharingToolbarLoadError,\r\n message: \"Error while retrieving content status data from API\"\r\n });\r\n return;\r\n }\r\n\r\n documentData.sharingShortUrl = SharingHelper.shortUrlBuilder({ documentId, documentType }, getAppEnvironment().CurrentMarket);\r\n ContentActionsToolbarActions.documentDataReady.getActionSender(this).send(documentData);\r\n }\r\n\r\n /**\r\n * Builds the like and dislike callbacks\r\n * @param {Status} The content status\r\n * @param {DocumentId} The document id\r\n * @returns {MoreOptionsCallbacks} The MoreOptionsCallbacks interface implementation\r\n */\r\n private BuildLikeDislikeCallbacks(status: Status, documentId: string): MoreOptionsCallbacks {\r\n return {\r\n onLike: (event: Event) => {\r\n if (status !== Status.Like) {\r\n this.actionServiceClient.Like(documentId);\r\n Telemetry.sendActionEvent(event.currentTarget as HTMLElement, TelemetryActionType.Click, TelemetryBehaviorType.Like);\r\n ContentActionsToolbarActions.likeContent.getActionSender(this).send();\r\n } else {\r\n this.actionServiceClient.Unlike(documentId);\r\n Telemetry.sendActionEvent(event.currentTarget as HTMLElement, TelemetryActionType.Click, TelemetryBehaviorType.Unlike);\r\n ContentActionsToolbarActions.unlikeContent.getActionSender(this).send();\r\n }\r\n return;\r\n },\r\n onDislike: (event: Event) => {\r\n if (status !== Status.DisLike) {\r\n this.actionServiceClient.Dislike(documentId);\r\n Telemetry.sendActionEvent(event.currentTarget as HTMLElement, TelemetryActionType.Click, TelemetryBehaviorType.Dislike);\r\n ContentActionsToolbarActions.dislikeContent.getActionSender(this).send();\r\n } else {\r\n this.actionServiceClient.Undislike(documentId);\r\n Telemetry.sendActionEvent(event.currentTarget as HTMLElement, TelemetryActionType.Click, TelemetryBehaviorType.Undislike);\r\n ContentActionsToolbarActions.undislikeContent.getActionSender(this).send();\r\n }\r\n return;\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Injects callbacks to more options menu buttons\r\n * @param {ButtonItemType} moreOptionsButton The more option button\r\n * @param {Status} status The current content status\r\n * @param {MoreOptionsCallbacks} The more options menu callbacks interface\r\n */\r\n private InjectCallbacksToMoreOptionsMenu(moreOptionsButton: ButtonItemType, status: Status, callbacks: MoreOptionsCallbacks): void {\r\n if (!moreOptionsButton || !moreOptionsButton.buttonData || !moreOptionsButton.buttonData.menuItems) {\r\n return;\r\n }\r\n const { menuItems } = moreOptionsButton.buttonData;\r\n\r\n if (status === Status.Like) {\r\n menuItems.find(e => e.key === LikeDislikeActionKey.undoliked).onSelect = (event: any) => callbacks.onLike(event);\r\n menuItems.find(e => e.key === LikeDislikeActionKey.dislike).onSelect = (event: any) => callbacks.onDislike(event);\r\n } else if (status === Status.DisLike) {\r\n menuItems.find(e => e.key === LikeDislikeActionKey.undodisliked).onSelect = (event: any) => callbacks.onDislike(event);\r\n menuItems.find(e => e.key === LikeDislikeActionKey.like).onSelect = (event: any) => callbacks.onLike(event);\r\n } else {\r\n menuItems.find(e => e.key === LikeDislikeActionKey.dislike).onSelect = (event: any) => callbacks.onDislike(event);\r\n }\r\n }\r\n\r\n /**\r\n * Sets base telemetry data for Content Actions Toolbar\r\n */\r\n private generateTelemetryTags(): void {\r\n this.sharingToolbarTelemetryObject = this.telemetryObject.addOrUpdateChild({ name: TelemetryConstants.socialToolbarTelemetryName, type: TelemetryType.Module });\r\n this.sharingToolbarTelemetryTags = this.sharingToolbarTelemetryObject.render();\r\n this.moreOptionsTelemetryTags = {\r\n Like: this.sharingToolbarTelemetryObject.addOrUpdateChild({ name: OptionItemLike.key.toUpperCase(), behavior: TelemetryBehaviorType.Like }).render(),\r\n Dislike: this.sharingToolbarTelemetryObject.addOrUpdateChild({ name: OptionItemDislike.key.toUpperCase(), behavior: TelemetryBehaviorType.Dislike }).render(),\r\n UndoLike: this.sharingToolbarTelemetryObject.addOrUpdateChild({ name: OptionItemUndoLike.key.toUpperCase(), behavior: TelemetryBehaviorType.Unlike }).render(),\r\n UndoDislike: this.sharingToolbarTelemetryObject.addOrUpdateChild({ name: OptionItemUndoDislike.key.toUpperCase(), behavior: TelemetryBehaviorType.Undislike }).render()\r\n };\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ButtonItemType, ButtonType } from \"./components/sharing-toolbar/SharingToolbar\";\r\nimport { LikeDislikeActionKey, TelemetryConstants } from \"./ContentActionsToolbar.constants\";\r\nimport { OptionItemDislike, OptionItemLike, OptionItemUndoDislike, OptionItemUndoLike } from \"./components/sharing-toolbar/SharingToolbar.constants\";\r\nimport { SocialMediaItemConfigAttributes, SocialMediaTarget, ViewsUtility } from \"@msnews/views-helpers\";\r\nimport { Telemetry, TelemetryActionType, TelemetryBehaviorType, TelemetryObjectBase, TelemetryType } from \"@msnews/telemetry-contracts\";\r\n\r\nimport { Status } from \".\";\r\n\r\n/**\r\n * Helper class to implement telemetry for content actions toolbar\r\n * @export\r\n * @class\r\n */\r\nexport class ContentActionsToolbarTelemetryHelper {\r\n\r\n /**\r\n * Injects telemetry data into sharing buttons array\r\n * @param {ButtonItemType[]} sharingButtons The sharing buttons array\r\n * @param {Status} status The current content status\r\n * @param {TelemetryObjectBase} sharingToolbarTelemetryObject The sharing toolbar telemetry props\r\n * @param {TrackTelemetryEventSignature} handleTelemetryCall Dispatches click telemetry events\r\n */\r\n public static InjectTelemetry(sharingButtons: ButtonItemType[], status: Status, sharingToolbarTelemetryObject: TelemetryObjectBase): void {\r\n sharingButtons.map(button => {\r\n let buttonTelemetryName: string;\r\n switch (button.buttonType) {\r\n case ButtonType.SocialMedia:\r\n buttonTelemetryName = button.buttonData.mediaType.toUpperCase();\r\n button.buttonData.newWindowTelemetryCall = (event: any) => {\r\n Telemetry.sendActionEvent(event.currentTarget as HTMLElement, TelemetryActionType.Click, TelemetryBehaviorType.Navigate);\r\n return;\r\n };\r\n break;\r\n case ButtonType.ShareDialog:\r\n if (button.buttonData.shareDialogProps && button.buttonData.shareDialogProps.socialMediaItems) {\r\n buttonTelemetryName = button.buttonType.toUpperCase();\r\n const { shareDialogProps } = button.buttonData;\r\n button.buttonData.onSelect = (event: any) => {\r\n Telemetry.sendActionEvent(event.currentTarget as HTMLElement, TelemetryActionType.Click, TelemetryBehaviorType.Share);\r\n return;\r\n };\r\n if (button.buttonData.target === SocialMediaTarget.newWindow) {\r\n button.buttonData.newWindowTelemetryCall = (event: any) => {\r\n Telemetry.sendActionEvent(event.currentTarget as HTMLElement, TelemetryActionType.Click, TelemetryBehaviorType.Navigate);\r\n return;\r\n };\r\n }\r\n\r\n const mediaTelemetryObject: { [s: string]: TelemetryObjectBase } = shareDialogProps.socialMediaItems.reduce(\r\n (result, value) => {\r\n if (value) {\r\n result[value.toLowerCase()] = sharingToolbarTelemetryObject.addOrUpdateChild({ name: value.toUpperCase(), behavior: TelemetryBehaviorType.Share }, result[value.toLowerCase()]);\r\n result[value.toLowerCase()].userFacingText = `tmx-stb-sd-${value.toLowerCase()}`;\r\n }\r\n return result;\r\n },\r\n {}\r\n );\r\n shareDialogProps.copyButtonTelemetryObject = sharingToolbarTelemetryObject.addOrUpdateChild({ name: TelemetryConstants.copyLinkTelemetryName, behavior: TelemetryBehaviorType.Share }, shareDialogProps.copyButtonTelemetryObject);\r\n shareDialogProps.closeButtonTelemetryObject = sharingToolbarTelemetryObject.addOrUpdateChild({ name: TelemetryConstants.closeDialogTelemetryName, behavior: TelemetryBehaviorType.Close }, shareDialogProps.closeButtonTelemetryObject);\r\n shareDialogProps.closeButtonTelemetryTags = shareDialogProps.closeButtonTelemetryObject.render();\r\n shareDialogProps.shareIconTelemetryObject = mediaTelemetryObject;\r\n shareDialogProps.socialMediaConfigOverride = shareDialogProps.socialMediaItems.reduce((result, mediaItem) => {\r\n let mediaItemOverride: SocialMediaItemConfigAttributes = {};\r\n if (shareDialogProps.socialMediaConfigOverride && shareDialogProps.socialMediaConfigOverride[mediaItem]) {\r\n mediaItemOverride = {...shareDialogProps.socialMediaConfigOverride[mediaItem]};\r\n }\r\n mediaItemOverride.newWindowTelemetryCall = event => Telemetry.sendActionEvent(event.currentTarget as HTMLElement, TelemetryActionType.Click, TelemetryBehaviorType.Share);\r\n result[mediaItem] = mediaItemOverride;\r\n return result;\r\n }, {}\r\n );\r\n const shareDialogTelemetryObject = sharingToolbarTelemetryObject.addOrUpdateChild({ name: TelemetryConstants.shareDialogTelemetryName, type: TelemetryType.Interaction }, sharingToolbarTelemetryObject);\r\n button.buttonData.shareDialogProps = {\r\n ...shareDialogProps,\r\n ...shareDialogTelemetryObject.render()\r\n\r\n };\r\n button.buttonData.articleTelemetryTags = sharingToolbarTelemetryObject.addOrUpdateChild({ name: TelemetryConstants.shareArticleTelemetryName, behavior: TelemetryBehaviorType.Share }, sharingToolbarTelemetryObject).render();\r\n\r\n }\r\n break;\r\n case ButtonType.LikeDislike:\r\n if (status === Status.Like) {\r\n buttonTelemetryName = OptionItemUndoLike.key.toUpperCase();\r\n } else if (status === Status.DisLike) {\r\n buttonTelemetryName = OptionItemUndoDislike.key.toUpperCase();\r\n } else {\r\n buttonTelemetryName = OptionItemLike.key.toUpperCase();\r\n }\r\n break;\r\n case ButtonType.MoreOptions: {\r\n buttonTelemetryName = button.buttonType.toUpperCase();\r\n const menuItems = button.buttonData.menuItems;\r\n\r\n if (status === Status.Like) {\r\n menuItems.find(e => e.key === LikeDislikeActionKey.undoliked).telemetryTag = sharingToolbarTelemetryObject.addOrUpdateChild(\r\n { name: OptionItemUndoLike.key.toUpperCase(), behavior: TelemetryBehaviorType.Unlike }).render();\r\n menuItems.find(e => e.key === LikeDislikeActionKey.dislike).telemetryTag = sharingToolbarTelemetryObject.addOrUpdateChild(\r\n { name: OptionItemDislike.key.toUpperCase(), behavior: TelemetryBehaviorType.Dislike }).render();\r\n } else if (status === Status.DisLike) {\r\n menuItems.find(e => e.key === LikeDislikeActionKey.undodisliked).telemetryTag = sharingToolbarTelemetryObject.addOrUpdateChild(\r\n { name: OptionItemUndoDislike.key.toUpperCase(), behavior: TelemetryBehaviorType.Undislike }).render();\r\n menuItems.find(e => e.key === LikeDislikeActionKey.like).telemetryTag = sharingToolbarTelemetryObject.addOrUpdateChild(\r\n { name: OptionItemLike.key.toUpperCase(), behavior: TelemetryBehaviorType.Like }).render();\r\n } else {\r\n menuItems.find(e => e.key === LikeDislikeActionKey.dislike).telemetryTag = sharingToolbarTelemetryObject.addOrUpdateChild(\r\n { name: OptionItemDislike.key.toUpperCase(), behavior: TelemetryBehaviorType.Dislike }).render();\r\n }\r\n break;\r\n }\r\n default:\r\n break;\r\n }\r\n button.telemetryTags = sharingToolbarTelemetryObject.addOrUpdateChild({ name: buttonTelemetryName, behavior: TelemetryBehaviorType.Share }, sharingToolbarTelemetryObject).render();\r\n if (button.telemetryTags) {\r\n // Keeping same telemetry headline data as found today in Prime for AB testing\r\n button.telemetryTags[\"data-hl\"] = `tmx-stb-${buttonTelemetryName.toLowerCase()}`;\r\n }\r\n });\r\n }\r\n\r\n}\r\n","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { AppError } from \"@msnews/diagnostics\";\r\nimport { CommonExperienceProps } from \"@msnews/experiences-base\";\r\nimport { ContentActionsToolbarClassNames } from \".\";\r\nimport { ManagedClasses } from \"@microsoft/fast-components-class-name-contracts-msft\";\r\nimport { SharingToolbarProps } from \"./components/sharing-toolbar\";\r\nimport { Status } from \"./ContentActionsToolbar.constants\";\r\nimport { TelemetryTags } from \"@msnews/telemetry-contracts\";\r\n\r\n/**\r\n * Toolbar positioning options\r\n */\r\nexport enum ToolbarPosition {\r\n horizontal = \"horizontal\",\r\n vertical = \"vertical\"\r\n}\r\n\r\n/**\r\n * An interface to represent the ContentActionsToolbar jss managed classes.\r\n * @export\r\n * @interface ContentActionsToolbarManagedClasses\r\n */\r\nexport type ContentActionsToolbarManagedClasses = ManagedClasses;\r\n\r\n/**\r\n * An interface to represent the ContentActionsToolbar handled props.\r\n * @export\r\n * @interface ContentActionsToolbarHandledProps\r\n */\r\nexport interface ContentActionsToolbarHandledProps extends CommonExperienceProps, ContentActionsToolbarManagedClasses {\r\n /**\r\n * Defines the toolbar position in case of single static position. Undefined otherwise.\r\n */\r\n staticPosition?: ToolbarPosition;\r\n\r\n /**\r\n * Position to render toolbar in\r\n * @type {ToolbarPosition}\r\n */\r\n position?: ToolbarPosition;\r\n\r\n /**\r\n * Sharing toolbar props\r\n * @type {SharingToolbarProps}\r\n */\r\n sharingToolbar?: SharingToolbarProps;\r\n\r\n /**\r\n * Content Status\r\n * @type {Status}\r\n */\r\n contentStatus?: Status;\r\n\r\n /**\r\n * Sharing toolbar error\r\n * @type {Error}\r\n */\r\n sharingError?: Error;\r\n\r\n /**\r\n * Root element telemetry tags\r\n * @type {TelemetryTags}\r\n */\r\n rootTelemetryTags?: TelemetryTags;\r\n}\r\n\r\n/**\r\n * An interface to represent the ContentActionsToolbar unhandled props.\r\n * @export\r\n * @interface ContentActionsToolbarUnhandledProps\r\n */\r\nexport type ContentActionsToolbarUnhandledProps = React.HTMLAttributes;\r\n\r\n/**\r\n * The ContentActionsToolbar props type\r\n */\r\nexport type ContentActionsToolbarProps = ContentActionsToolbarHandledProps & ContentActionsToolbarUnhandledProps;\r\n\r\n/**\r\n * App Error Event Tracking Callback Signature\r\n */\r\nexport type TrackAppErrorEventSignature = (error: AppError) => void;\r\n\r\n/**\r\n * Click event tracking callback signature\r\n */\r\nexport type TrackTelemetryEventSignature = (event: Object, element: HTMLElement, destination: string, headline: string) => void;","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ActionHandler, IActionPayload, IReducer } from \"@msnews/experiences-redux\";\r\nimport { ContentActionsToolbarActions, ContentActionsToolbarState, ToolbarPosition } from \".\";\r\nimport { Status, ToolbarBreakpoints } from \"./ContentActionsToolbar.constants\";\r\n\r\nimport { DocumentData } from \"./ContentActionsToolbar.state\";\r\n\r\n/**\r\n * Experience initial state.\r\n */\r\nconst initialState: ContentActionsToolbarState = {\r\n documentData: undefined,\r\n documentId: undefined,\r\n position: undefined,\r\n sharingError: undefined,\r\n staticPosition: undefined,\r\n status: undefined\r\n};\r\n\r\n/**\r\n * The reducer for the ContentActionsToolbar connector, and the ContentActionsToolbarState\r\n * @export\r\n * @class\r\n */\r\nexport class ContentActionsToolbarReducer implements IReducer {\r\n /**\r\n * Update the state for the connector, based on the action being applied\r\n * @param state The previous state\r\n * @param actionPayload The action being applied\r\n */\r\n public reduce(state: ContentActionsToolbarState, actionPayload: IActionPayload): ContentActionsToolbarState {\r\n // Return the initial state for this experience, including the config.\r\n if (!state) {\r\n return initialState;\r\n }\r\n\r\n // Return the passed in state, if there is no action specified\r\n if (!actionPayload) {\r\n return state;\r\n }\r\n\r\n let newState: ContentActionsToolbarState;\r\n\r\n // handle actions\r\n ActionHandler.handleAction(actionPayload, ContentActionsToolbarActions.initializeToolbar, (breakpointIndex: number,\r\n isRSThreeDevice: boolean,\r\n documentId: string,\r\n staticPosition: ToolbarPosition) => {\r\n newState = initialState;\r\n newState.position = this.getToolbarPosition(staticPosition, isRSThreeDevice, breakpointIndex);\r\n newState.documentId = documentId;\r\n newState.staticPosition = staticPosition;\r\n });\r\n\r\n ActionHandler.handleAction(actionPayload, ContentActionsToolbarActions.ContentStatuReady, (status: Status) => {\r\n newState = {\r\n ...state,\r\n status\r\n };\r\n });\r\n\r\n ActionHandler.handleAction(actionPayload, ContentActionsToolbarActions.documentDataReady, (documentData: DocumentData) => {\r\n newState = {\r\n ...state,\r\n documentData\r\n };\r\n });\r\n\r\n ActionHandler.handleAction(actionPayload, ContentActionsToolbarActions.likeContent, () => {\r\n newState = {\r\n ...state,\r\n status: Status.Like\r\n };\r\n });\r\n\r\n ActionHandler.handleAction(actionPayload, ContentActionsToolbarActions.unlikeContent, () => {\r\n newState = {\r\n ...state,\r\n status: Status.None\r\n };\r\n });\r\n\r\n ActionHandler.handleAction(actionPayload, ContentActionsToolbarActions.dislikeContent, () => {\r\n newState = {\r\n ...state,\r\n status: Status.DisLike\r\n };\r\n });\r\n\r\n ActionHandler.handleAction(actionPayload, ContentActionsToolbarActions.undislikeContent, () => {\r\n newState = {\r\n ...state,\r\n status: Status.None\r\n };\r\n });\r\n\r\n ActionHandler.handleAction(actionPayload, ContentActionsToolbarActions.ViewportUpdate, (breakpointIndex: number, isRSThreeDevice: boolean) => {\r\n newState = {\r\n ...state,\r\n position: this.getToolbarPosition(state.staticPosition, isRSThreeDevice, breakpointIndex)\r\n };\r\n });\r\n\r\n ActionHandler.handleAction(actionPayload, ContentActionsToolbarActions.sharingToolbarError, (error: Error) => {\r\n newState = {\r\n ...state,\r\n sharingError: error\r\n };\r\n });\r\n\r\n return newState || state;\r\n }\r\n\r\n /**\r\n * Calculates current toolbar position\r\n * @param staticPosition Defines orientation for static position if single position. Undefined otherwise.\r\n * @param isRSThreeDevice Indicates if device is RSThree\r\n * @param breakpointIndex Current breakpoint index.\r\n * @returns Toolbar current position\r\n */\r\n private getToolbarPosition(staticPosition: ToolbarPosition, isRSThreeDevice: boolean, breakpointIndex: number): ToolbarPosition {\r\n if (staticPosition) {\r\n return staticPosition;\r\n } else {\r\n const currentBreakpointIndex = isRSThreeDevice ? ToolbarBreakpoints.Breakpoint3_2 : ToolbarBreakpoints.Breakpoint3_3;\r\n return breakpointIndex >= currentBreakpointIndex ? ToolbarPosition.vertical : ToolbarPosition.horizontal;\r\n }\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n DesignSystem,\r\n ElevationMultiplier,\r\n applyElevation,\r\n highContrastSelector,\r\n neutralFillActive,\r\n neutralFillHover,\r\n neutralForegroundRest,\r\n neutralLayerCard\r\n} from \"@microsoft/fast-components-styles-msft\";\r\nimport { applyLocalizedProperty, toPx } from \"@microsoft/fast-jss-utilities\";\r\nimport { iconContainerDefaultColor, likeDislikeIconBackroundColor, moreOptionsIconColors } from \"./SharingToolbar.constants\";\r\n\r\nimport { CardContextMenuClassNameContract } from \"@msnews/card-context-menu\";\r\nimport { ComponentStyles } from \"@microsoft/fast-jss-manager\";\r\nimport { SharingToolbarClassNames } from \"./\";\r\n\r\n// reduce listItem dimension to 32, remove margin for iconListHorizontal (3px) and add list icon margin (in between) dinamically hor/vert\r\nconst iconListItemDimension = 32;\r\nconst iconContainerDimension = 32;\r\nconst iconImageDimension = 18;\r\nconst iconPadding = 10;\r\n\r\n/**\r\n * The SharingToolbar styles\r\n * @type {ComponentStyles}\r\n */\r\nexport const SharingToolbarStyles: ComponentStyles = (config: DesignSystem) => {\r\n return {\r\n icon_none: {},\r\n icon_like: {},\r\n icon_dislike: {},\r\n iconListHorizontal: {\r\n \"list-style\": \"none\",\r\n padding: \"0\",\r\n margin: \"0\",\r\n \"text-align\": \"center\",\r\n \"& $iconListItem\": {\r\n [applyLocalizedProperty(\"margin-right\", \"margin-left\", config.direction)]: toPx(iconPadding)\r\n }\r\n },\r\n iconListVertical: {\r\n float: \"left\",\r\n height: \"auto\",\r\n width: toPx(iconListItemDimension),\r\n position: \"absolute\",\r\n \"& $iconListItem\": {\r\n \"margin-bottom\": toPx(iconPadding)\r\n }\r\n },\r\n iconListItem: {\r\n \"align-items\": \"center\",\r\n display: \"inline-flex\",\r\n height: toPx(iconListItemDimension),\r\n \"justify-content\": \"center\",\r\n width: toPx(iconListItemDimension),\r\n \"&:hover\": {\r\n cursor: \"pointer\"\r\n }\r\n },\r\n shareDialog: {\r\n \"background-color\": \"#f00\"\r\n },\r\n iconContainer: {\r\n cursor: \"pointer\",\r\n border: \"unset\",\r\n padding: \"unset\",\r\n \"background-color\": iconContainerDefaultColor,\r\n \"border-radius\": \"50%\",\r\n color: neutralForegroundRest,\r\n height: toPx(iconContainerDimension),\r\n \"justify-content\": \"center\",\r\n position: \"relative\",\r\n width: toPx(iconContainerDimension),\r\n \"$icon_none &\": {\r\n \"background-color\": likeDislikeIconBackroundColor.none\r\n },\r\n \"$icon_like &\": {\r\n \"background-color\": likeDislikeIconBackroundColor.like\r\n },\r\n \"$icon_dislike &\": {\r\n \"background-color\": likeDislikeIconBackroundColor.dislike\r\n },\r\n \"& img\": {\r\n \"vertical-align\": \"unset\"\r\n }\r\n },\r\n highContrast: {\r\n [highContrastSelector]: {\r\n background: \"Highlight\",\r\n border: \"1px solid Highlight\",\r\n \"border-radius\": \"50%\",\r\n \"& svg\": {\r\n fill: \"Highlight\"\r\n }\r\n }\r\n },\r\n iconImage: {\r\n bottom: \"0\",\r\n left: \"0\",\r\n margin: \"7px\",\r\n right: \"0\",\r\n top: \"0\",\r\n height: toPx(iconImageDimension),\r\n width: toPx(iconImageDimension)\r\n },\r\n moreOptions: {\r\n height: toPx(iconContainerDimension),\r\n width: toPx(iconContainerDimension),\r\n [highContrastSelector]: {\r\n width: toPx(iconContainerDimension - 2),\r\n height: toPx(iconContainerDimension - 2)\r\n }\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * The context menu styles\r\n * @type {ComponentStyles}\r\n */\r\nexport const contextMenuStyles: Partial> = {\r\n menuContainer: {\r\n \"background-color\": moreOptionsIconColors.background,\r\n \"border-radius\": \"50%\",\r\n height: toPx(iconContainerDimension),\r\n width: toPx(iconContainerDimension),\r\n [highContrastSelector]: {\r\n width: toPx(iconContainerDimension - 2),\r\n height: toPx(iconContainerDimension - 2)\r\n }\r\n },\r\n settingButton: {\r\n background: \"none\",\r\n border: \"0\",\r\n cursor: \"pointer\",\r\n display: \"flex\",\r\n padding: \"0\",\r\n height: toPx(iconContainerDimension),\r\n margin: \"0\",\r\n width: toPx(iconContainerDimension),\r\n \"& svg\": {\r\n color: moreOptionsIconColors.foreground,\r\n display: \"flex\",\r\n margin: \"auto\",\r\n height: \"inherit\",\r\n width: toPx(iconImageDimension),\r\n \"& path\": {\r\n fill: \"currentColor\"\r\n }\r\n }\r\n },\r\n contextMenu: {\r\n ...applyElevation(ElevationMultiplier.e11),\r\n \"background-color\": neutralLayerCard,\r\n border: \"none\",\r\n display: \"grid\",\r\n padding: \"8px 0\",\r\n margin: \"0 14px\",\r\n width: \"240px\"\r\n },\r\n contextMenuItem: {\r\n background: neutralLayerCard,\r\n \"box-sizing\": \"border-box\",\r\n border: \"none\",\r\n display: \"inline-block\",\r\n padding: \"6px 16px\",\r\n width: \"auto\",\r\n \"&:hover, &:focus\": {\r\n background: neutralFillHover(neutralLayerCard),\r\n border: \"none\"\r\n },\r\n \"&:active\": {\r\n background: neutralFillActive(neutralLayerCard)\r\n }\r\n },\r\n contextMenuItem_contentRegion: {\r\n color: neutralForegroundRest(neutralLayerCard),\r\n \"grid-column-start\": \"1\"\r\n }\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport * as React from \"react\";\r\n\r\nimport { ArticleCard, ArticleProviderProps } from \"@msnews/article-card\";\r\nimport {\r\n DialogArticleCardHandledProps,\r\n DialogArticleCardManagedClasses,\r\n DialogArticleCardUnhandledProps\r\n} from \"./DialogArticleCard.props\";\r\nimport { HandledPropsKeys, ImageResizeMode, generateImageUrlFromBaseUrl } from \"@msnews/core\";\r\nimport { HeadingProps, HeadingSize, HeadingTag } from \"@microsoft/fast-components-react-msft\";\r\nimport { TypographyProps, TypographySize, TypographyTag } from \"@microsoft/fast-components-react-base\";\r\n\r\nimport Foundation from \"@microsoft/fast-components-foundation-react\";\r\n\r\n/**\r\n * Dialog article card\r\n * @class - Dialog Article Card\r\n * @classdesc - An dialog article Card composed from the base article card.\r\n */\r\nexport class DialogArticleCard extends Foundation {\r\n /**\r\n * Handled props contract\r\n * @protected\r\n * @type { HandledPropsKeys }\r\n */\r\n protected handledProps: HandledPropsKeys = {\r\n anchorRef: undefined,\r\n articleId: undefined,\r\n headlineTitle: undefined,\r\n href: undefined,\r\n image: undefined,\r\n managedClasses: undefined,\r\n provider: undefined\r\n };\r\n\r\n /**\r\n * Constructs an DialogArticleCard component\r\n * @constructor\r\n * @param { DialogArticleCardHandledProps & DialogArticleCardManagedClasses } props props contract\r\n */\r\n constructor(props: DialogArticleCardHandledProps & DialogArticleCardManagedClasses) {\r\n super(props);\r\n }\r\n\r\n /**\r\n * Component rendered\r\n * @method\r\n * @returns {JSX.Element} the DialogArticleCard component\r\n */\r\n public render(): JSX.Element {\r\n const { href, image, managedClasses } = this.props;\r\n\r\n if (image && image.src) {\r\n image.src = generateImageUrlFromBaseUrl(\r\n image.src,\r\n {\r\n width: 100,\r\n height: 100,\r\n enableDpiScaling: false,\r\n mode: ImageResizeMode.Scale\r\n });\r\n }\r\n\r\n const articleCard = (\r\n \r\n );\r\n\r\n if (image) {\r\n return (\r\n articleCard\r\n );\r\n } else {\r\n return (\r\n
    \r\n {articleCard}\r\n
    \r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Coerces the title props to enforce visual level\r\n * @method\r\n * @returns {HeadingProps} the headline title props\r\n */\r\n private coerceTitleProps(): any {\r\n const coercedProps: Partial = {\r\n size: HeadingSize._6,\r\n tag: HeadingTag.h3\r\n };\r\n\r\n return { ...this.props.headlineTitle, ...coercedProps };\r\n }\r\n\r\n /**\r\n * Coerces the provider props to enforce visual level of the name\r\n * @method\r\n * @returns {ArticleProviderProps} the provider props\r\n */\r\n private coerceProviderProps(): ArticleProviderProps {\r\n const { provider } = this.props;\r\n if (!provider) {\r\n return;\r\n }\r\n\r\n const coercedProviderNameProps: Partial = {\r\n size: TypographySize._8,\r\n tag: TypographyTag.h5\r\n };\r\n\r\n const coercedProps: Partial = {\r\n name: { ...provider.name, ...coercedProviderNameProps }\r\n };\r\n\r\n const coerceProviderProps = { ...provider, ...coercedProps };\r\n if (!coerceProviderProps.image || !coerceProviderProps.image.src) {\r\n coerceProviderProps.image = undefined;\r\n }\r\n\r\n return coerceProviderProps;\r\n }\r\n}\r\n\r\nexport * from \"./DialogArticleCard.props\";","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { applyFontWeightNormal, applyFontWeightSemiBold, applyTypeRampConfig, getLineHeight, neutralFillStealthRest, neutralForegroundHover } from \"@microsoft/fast-components-styles-msft\";\r\nimport { applyLocalizedProperty, applyMaxLines, toPx } from \"@microsoft/fast-jss-utilities\";\r\n\r\nimport { ComponentStyles } from \"@microsoft/fast-jss-manager\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { DialogArticleCardClassNameContract } from \"./DialogArticleCard.classnames\";\r\n\r\nconst ArticleCardImageBorderRadius = 2;\r\nconst RelatedCardHeight = 100;\r\nconst RelatedCardImageSize = 100;\r\nconst HeadlineTextMargin = 16;\r\n\r\nconst borderColor = \"rgba(0,0,0, 0.05)\";\r\nconst DialogArticleCardTypeRamp = \"t7\";\r\n\r\n/**\r\n * The DialogArticleCard styles\r\n * @type {ComponentStyles}\r\n */\r\nexport const DialogArticleCardStyles: ComponentStyles = (config: DesignSystem) => {\r\n return {\r\n articleCard: {\r\n background: \"none\",\r\n \"border-bottom\": `1px solid ${borderColor}`,\r\n cursor: \"pointer\",\r\n display: \"flex\",\r\n padding: \"15px 0\",\r\n position: \"relative\"\r\n },\r\n articleCard_content: {\r\n display: \"flex\",\r\n flex: \"1\",\r\n \"text-decoration\": \"none\",\r\n \"&:hover\": {\r\n \"& $articleCard_headline\": {\r\n color: neutralForegroundHover(neutralFillStealthRest),\r\n \"text-decoration\": \"underline\"\r\n },\r\n \"& $articleCard_imageOverlay\": {\r\n opacity: 0.1\r\n }\r\n }\r\n },\r\n articleCard_imageWrapper: {\r\n position: \"relative\",\r\n \"& $articleCard_image\": {\r\n height: toPx(RelatedCardImageSize)\r\n }\r\n },\r\n articleCard_image: {\r\n \"border-radius\": toPx(ArticleCardImageBorderRadius),\r\n \"object-fit\": \"cover\",\r\n width: toPx(RelatedCardImageSize)\r\n },\r\n articleCard_imageOverlay: {\r\n height: \"100%\",\r\n opacity: \"0\",\r\n position: \"absolute\",\r\n top: \"0\",\r\n width: \"100%\"\r\n },\r\n articleCard_textWrapper: {\r\n \"box-sizing\": \"border-box\",\r\n display: \"flex\",\r\n flex: \"1\",\r\n height: toPx(RelatedCardHeight),\r\n padding: applyLocalizedProperty(`0 0 0 ${toPx(HeadlineTextMargin)}`, `0 ${toPx(HeadlineTextMargin)} 0 0`, config.direction)\r\n },\r\n articleCard_headline: {\r\n \"text-align\": applyLocalizedProperty(\"left\", \"right\", config.direction),\r\n \"& $articleCard_headlineText\": {\r\n ...applyFontWeightSemiBold(),\r\n ...applyMaxLines(3, getLineHeight(DialogArticleCardTypeRamp)),\r\n ...applyTypeRampConfig(DialogArticleCardTypeRamp)\r\n }\r\n },\r\n articleCard_headlineText: {\r\n \"padding-top\": \"3px\"\r\n },\r\n articleCard_headlineMask: {},\r\n articleCard_provider: {\r\n bottom: \"23px\",\r\n display: \"inline-flex\",\r\n position: \"absolute\",\r\n \"& $articleCard_providerImage\": {\r\n height: \"16px\"\r\n },\r\n \"& $articleCard_providerTitle\": {\r\n \"line-height\": \"16px\"\r\n }\r\n },\r\n articleCard_providerImage: {\r\n display: \"inline-block\",\r\n [applyLocalizedProperty(\"padding-right\", \"padding-left\", config.direction)]: \"8px\"\r\n },\r\n articleCard_providerTitle: {\r\n display: \"inline-block\",\r\n \"vertical-align\": \"top\",\r\n ...applyFontWeightNormal()\r\n },\r\n articleCard_noImage: {\r\n \"& $articleCard_textWrapper\": {\r\n height: \"auto\",\r\n \"text-align\": applyLocalizedProperty(\"left\", \"right\", config.direction)\r\n },\r\n \"& $articleCard_provider\": {\r\n \"margin-top\": \"15px\",\r\n position: \"static\"\r\n },\r\n \"& $articleCard_headlineText\": {\r\n \"padding-top\": \"0\"\r\n }\r\n }\r\n };\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n DialogArticleCard as BaseDialogArticleCard,\r\n DialogArticleCardHandledProps as BaseDialogArticleCardHandledProps,\r\n DialogArticleCardProps as BaseDialogArticleCardProps,\r\n DialogArticleCardManagedClasses,\r\n DialogArticleCardUnhandledProps\r\n} from \"./DialogArticleCard\";\r\nimport manageJss, { ManagedJSSProps } from \"@microsoft/fast-jss-manager-react\";\r\n\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { DialogArticleCardClassNameContract } from \"./DialogArticleCard.classnames\";\r\nimport { DialogArticleCardStyles } from \"./DialogArticleCard.styles\";\r\nimport { Subtract } from \"utility-types\";\r\n\r\n/*\r\n * The type returned by manageJss type is very complicated so we'll let the\r\n * compiler infer the type instead of re-declaring just for the package export\r\n */\r\nconst DialogArticleCard = manageJss(DialogArticleCardStyles)(BaseDialogArticleCard);\r\ntype DialogArticleCard = InstanceType;\r\n\r\n// Create a valid JSS managed interface that doesn't require managed classes which are provided by the manageJSS HOC\r\ntype DialogArticleCardHandledProps = Subtract;\r\n\r\n// Create type for manageJSS HOC styled instance we are exporting\r\ntype DialogArticleCardProps = ManagedJSSProps<\r\n BaseDialogArticleCardProps,\r\n DialogArticleCardClassNameContract,\r\n DesignSystem\r\n>;\r\n\r\nexport {\r\n DialogArticleCard,\r\n DialogArticleCardProps,\r\n DialogArticleCardHandledProps,\r\n DialogArticleCardUnhandledProps,\r\n DialogArticleCardManagedClasses,\r\n DialogArticleCardClassNameContract\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport * as ReactDOM from \"react-dom\";\r\n\r\nimport {\r\n ButtonItemType,\r\n ButtonType,\r\n SharingToolbarHandledProps,\r\n SharingToolbarProps,\r\n SharingToolbarUnHandledProps\r\n} from \"./SharingToolbar.props\";\r\nimport { Glyph, Icon } from \"@msnews/icon\";\r\nimport { SharingToolbarStyles, contextMenuStyles } from \"./SharingToolbar.styles\";\r\nimport { get, merge } from \"lodash-es\";\r\n\r\nimport { CardContextMenu } from \"@msnews/card-context-menu\";\r\nimport { ComponentStyles } from \"@microsoft/fast-jss-manager\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { DialogArticleCard } from \"../dialog-article-card\";\r\nimport { DialogClassNameContract } from \"@microsoft/fast-components-react-base\";\r\nimport Foundation from \"@microsoft/fast-components-foundation-react\";\r\nimport { HandledPropsKeys } from \"@msnews/core\";\r\nimport React from \"react\";\r\nimport { Share } from \"@edge-web-ui/news-icons\";\r\nimport { ShareDialog } from \"@msnews/share-dialog\";\r\nimport { SharingToolbarClassNames } from \".\";\r\nimport { SocialMediaIcon } from \"@msnews/social-media-icon\";\r\nimport { Status } from \"../../ContentActionsToolbar.constants\";\r\nimport { ToolbarPosition } from \"../../ContentActionsToolbar.props\";\r\nimport { moreOptionsMenuDefaultOffsetPos } from \"./SharingToolbar.constants\";\r\n\r\n/**\r\n * The local state interface of the component\r\n */\r\nexport interface SharingToolbarState {\r\n /** Flag to determine if share dialog should be displayed */\r\n shareDialogOpened: boolean\r\n}\r\n\r\n/**\r\n * Social media sharing toolbar component\r\n * @class - SharingToolbar\r\n * @classdesc - Sharing toolbar component class\r\n */\r\nexport class SharingToolbar extends Foundation {\r\n /**\r\n * Describes the object that enumerates all handled props for a component.\r\n * @protected\r\n * @type { HandledPropsKeys }\r\n */\r\n protected handledProps: HandledPropsKeys = {\r\n managedClasses: undefined,\r\n position: undefined,\r\n sharingButtons: undefined,\r\n requestContext: undefined\r\n };\r\n\r\n /**\r\n * Stylesheet to apply to article card\r\n * @type {Partial>}\r\n */\r\n private articleCardStylesheet: Partial>;\r\n\r\n /**\r\n * Reference to share dialog button\r\n * @private\r\n * @type { React.RefObject}\r\n */\r\n private readonly shareDialogButtonRef: React.RefObject;\r\n\r\n /**\r\n * Constructs a SharingToolbar component\r\n * @constructor\r\n * @param { SharingToolbarProps } props props contract\r\n */\r\n constructor(props: SharingToolbarProps) {\r\n super(props);\r\n this.state = {\r\n shareDialogOpened: false\r\n };\r\n\r\n this.shareDialogButtonRef = React.createRef();\r\n }\r\n\r\n /** @inheritdoc */\r\n public componentDidUpdate(_: SharingToolbarProps, prevState: SharingToolbarState): void {\r\n if (prevState.shareDialogOpened && !this.state.shareDialogOpened && this.shareDialogButtonRef.current) {\r\n this.shareDialogButtonRef.current.focus();\r\n }\r\n }\r\n\r\n /**\r\n * Render sharing toolbar component\r\n * @public\r\n * @return {JSX.Element}\r\n */\r\n public render(): JSX.Element {\r\n return (\r\n
    \r\n
      \r\n {this.renderSharingButtons()}\r\n
    \r\n {this.renderShareDialog()}\r\n
    \r\n );\r\n }\r\n\r\n /**\r\n * Get the classname based on positioning of the toolbar\r\n */\r\n private getPositioningClassName(): string {\r\n const positionClass: string = this.props.position === ToolbarPosition.horizontal ?\r\n this.managedClass(\"iconListHorizontal\") :\r\n this.managedClass(\"iconListVertical\");\r\n\r\n return positionClass;\r\n }\r\n\r\n /**\r\n * Render the toolbar sharing buttons\r\n * @private\r\n * @return {JSX.Element} The sharing buttons element\r\n */\r\n private renderSharingButtons(): JSX.Element[] {\r\n if (!this.props.sharingButtons) {\r\n return ([]);\r\n }\r\n\r\n return this.props.sharingButtons.map(buttonItem => {\r\n if (!buttonItem.buttonData) {\r\n return null;\r\n }\r\n\r\n const buttonId: string = buttonItem.buttonType === ButtonType.SocialMedia ? buttonItem.buttonData.mediaType.toString() : buttonItem.buttonType.toString();\r\n let listItem: JSX.Element;\r\n\r\n switch (buttonItem.buttonType) {\r\n case ButtonType.SocialMedia:\r\n listItem = this.renderSocialMediaIcon(buttonItem);\r\n break;\r\n case ButtonType.ShareDialog:\r\n listItem = this.renderShareDialogIcon(buttonItem);\r\n break;\r\n case ButtonType.LikeDislike:\r\n listItem = this.renderLikeDislikeIcon(buttonItem);\r\n break;\r\n case ButtonType.MoreOptions:\r\n listItem = this.renderMoreOptionsIcon(buttonItem);\r\n break;\r\n default:\r\n return (null);\r\n }\r\n\r\n return (\r\n
  • \r\n {listItem}\r\n
  • \r\n );\r\n });\r\n }\r\n\r\n /**\r\n * Renders the share dialog\r\n * @private\r\n * @return {JSX.Element} The share dialog element\r\n */\r\n private renderShareDialog(): JSX.Element {\r\n const shareDialogItem = this.props.sharingButtons.find(x => x.buttonType === ButtonType.ShareDialog);\r\n if (!shareDialogItem || !shareDialogItem.buttonData) {\r\n return null;\r\n }\r\n\r\n const { shareDialogProps, dialogArticleCardProps, articleTelemetryTags } = shareDialogItem.buttonData;\r\n if (!this.state.shareDialogOpened || !shareDialogProps || !dialogArticleCardProps) {\r\n return null;\r\n }\r\n\r\n const shareDialog = (\r\n \r\n \r\n \r\n );\r\n\r\n return ReactDOM.createPortal(\r\n shareDialog,\r\n document.body\r\n );\r\n }\r\n\r\n /**\r\n * Renders the social media icon element\r\n * @private\r\n * @param {ButtonItemType} buttonItem The button item data\r\n * @return {JSX.Element} The share dialog element\r\n */\r\n private renderSocialMediaIcon(buttonItem: ButtonItemType): JSX.Element {\r\n const { attributes, mediaType, contentUrl, contentTitle, emailBody, icon, ocid, target, newWindowTelemetryCall } = buttonItem.buttonData;\r\n if (!mediaType || !contentUrl || !contentTitle) {\r\n return null;\r\n }\r\n\r\n return (\r\n \r\n );\r\n }\r\n\r\n /**\r\n * Renders the share dialog icon element\r\n * @private\r\n * @param {ButtonItemType} buttonItem The button item data\r\n * @return {JSX.Element} The share dialog icon element\r\n */\r\n private renderShareDialogIcon(buttonItem: ButtonItemType): JSX.Element {\r\n const { attributes, shareDialogProps, dialogArticleCardProps, onSelect } = buttonItem.buttonData;\r\n if (!shareDialogProps || !dialogArticleCardProps || !shareDialogProps.enabled || !shareDialogProps.contentTitle || !shareDialogProps.contentUrl) {\r\n return null;\r\n }\r\n\r\n return (\r\n this.onShareDialogOpen(event, onSelect)}\r\n ref={this.shareDialogButtonRef}\r\n {...attributes}\r\n {...buttonItem.telemetryTags}\r\n >\r\n \r\n \r\n);\r\n }\r\n\r\n /**\r\n * Renders the like/dislike icon element\r\n * @private\r\n * @param {ButtonItemType} buttonItem The button item data\r\n * @return {JSX.Element} The like/dislike icon element\r\n */\r\n private renderLikeDislikeIcon(buttonItem: ButtonItemType): JSX.Element {\r\n if (!buttonItem.buttonData.status) {\r\n return;\r\n }\r\n const { attributes, status, onSelect } = buttonItem.buttonData;\r\n\r\n let glyphType: any ;\r\n if (status !== Status.DisLike) {\r\n if (status === Status.Like) {\r\n glyphType = Glyph.LikedText;\r\n } else {\r\n glyphType = Glyph.LikeText;\r\n }\r\n } else {\r\n glyphType = Glyph.DislikeText;\r\n }\r\n\r\n const iconClassName = this.managedClass(\"icon_\" + status.toString() as keyof SharingToolbarClassNames);\r\n return (\r\n
    \r\n \r\n \r\n \r\n
    \r\n );\r\n }\r\n\r\n /**\r\n * Renders the more options icon element\r\n * @private\r\n * @param {ButtonItemType} buttonItem The button item data\r\n * @return {JSX.Element} The more options icon element\r\n */\r\n private renderMoreOptionsIcon(buttonItem: ButtonItemType): JSX.Element {\r\n if (!buttonItem.buttonData || !buttonItem.buttonData.status || !buttonItem.buttonData.menuItems) {\r\n return;\r\n }\r\n const { attributes, menuItems, offsetPos, zIndex } = buttonItem.buttonData;\r\n\r\n const positionOffset = this.props.position === ToolbarPosition.vertical\r\n ? { ...moreOptionsMenuDefaultOffsetPos, ...offsetPos }\r\n : undefined;\r\n\r\n return (\r\n \r\n \r\n
    \r\n );\r\n }\r\n\r\n /**\r\n * Enables and open the share dialog\r\n * @private\r\n * @param {any} event Event\r\n * @param {(e: any) => void)} onSelect Telemetry callback\r\n */\r\n private onShareDialogOpen = (event: any, onSelect: (e: any) => void): void => {\r\n this.setState({ shareDialogOpened: true });\r\n if (onSelect) {\r\n onSelect(event);\r\n }\r\n };\r\n\r\n /**\r\n * Disables and close the share dialog\r\n * @private\r\n */\r\n private onShareDialogClose = (): void => {\r\n this.setState({ shareDialogOpened: false });\r\n };\r\n\r\n /**\r\n * Utility function to simplify getting class name from managedClasses.\r\n * @param className - The class to get from managedClasses\r\n * @returns The managed class name\r\n */\r\n private managedClass = (className: keyof SharingToolbarClassNames): string => {\r\n return get(this.props.managedClasses, className);\r\n };\r\n\r\n /**\r\n * Utility function to obtain the highContrast styles for non social media content actions buttons\r\n * @returns The high contrast styles to append\r\n */\r\n private appendHighContrastStyle = (): string => {\r\n return this.managedClass(\"highContrast\") ? \" \" + this.managedClass(\"highContrast\") : \"\";\r\n };\r\n}\r\n\r\nexport * from \"./SharingToolbar.props\";","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n SharingToolbarHandledProps as BaseComponentHandledProps,\r\n SharingToolbarProps as BaseComponentProps,\r\n ButtonItemType,\r\n ButtonType,\r\n SharingToolbarManagedClasses,\r\n SharingToolbarUnHandledProps\r\n} from \"./SharingToolbar.props\";\r\nimport manageJss, { ManagedJSSProps } from \"@microsoft/fast-jss-manager-react\";\r\n\r\nimport { SharingToolbar as BaseComponent } from \"./SharingToolbar\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { SharingToolbarClassNames } from \"./SharingToolbar.classnames\";\r\nimport { SharingToolbarStyles } from \"./SharingToolbar.styles\";\r\nimport { Subtract } from \"utility-types\";\r\n\r\n/*\r\n * The type returned by manageJss type is very complicated so we'll let the\r\n * compiler infer the type instead of re-declaring just for the package export\r\n */\r\nconst SharingToolbar = manageJss(SharingToolbarStyles)(BaseComponent);\r\ntype SharingToolbar = InstanceType;\r\n\r\n// Create a valid JSS managed interface that doesn't require managed classes which are provided by the manageJSS HOC\r\ntype SharingToolbarHandledProps = Subtract;\r\n\r\n// Create type for manageJSS HOC styled instance we are exporting\r\ntype SharingToolbarProps = ManagedJSSProps;\r\n\r\n// Export everything a user might need from this index file\r\nexport {\r\n ButtonType,\r\n ButtonItemType,\r\n SharingToolbar,\r\n SharingToolbarProps,\r\n SharingToolbarClassNames,\r\n SharingToolbarHandledProps,\r\n SharingToolbarUnHandledProps\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { BaseExperience, InitialCommonExperienceProps } from \"@msnews/experiences-base\";\r\nimport {\r\n ContentActionsToolbarHandledProps,\r\n ContentActionsToolbarUnhandledProps\r\n} from \"./ContentActionsToolbar.props\";\r\nimport { ContentActionsToolbarProps, ToolbarPosition } from \".\";\r\nimport { PlaceHolderId, experienceDefaultName } from \"./ContentActionsToolbar.constants\";\r\n\r\nimport { ContentActionsToolbarAppErrors } from \"@msnews/diagnostics\";\r\nimport { HandledPropsKeys } from \"@msnews/core\";\r\nimport React from \"react\";\r\nimport { SharingToolbar } from \"./components/sharing-toolbar\";\r\nimport { Telemetry } from \"@msnews/telemetry-contracts\";\r\nimport { classNames } from \"@microsoft/fast-web-utilities\";\r\nimport { markTtvr } from \"@msnews/diagnostics\";\r\n\r\n/**\r\n * Content Action toolbar base experience class\r\n * @class - ContentActionsToolbar\r\n * @classdesc - ContentActionsToolbar\r\n */\r\nexport class ContentActionsToolbar extends BaseExperience {\r\n /**\r\n * The ContentActionsToolbar default prop contract\r\n * Describes any default values for any component handled props\r\n * @public\r\n * @type { Partial }\r\n */\r\n public static defaultProps: Partial = {\r\n experienceName: experienceDefaultName\r\n };\r\n\r\n /**\r\n * The content action toolbar handled prop contract\r\n * Describes the object that enumerates all handled props for a component. This\r\n * object includes all props that can in some way consumed or manipulated by component\r\n * code.\r\n * @protected\r\n * @type { HandledPropsKeys }\r\n */\r\n protected handledProps: HandledPropsKeys = {\r\n ...InitialCommonExperienceProps,\r\n contentStatus: undefined,\r\n managedClasses: undefined,\r\n position: undefined,\r\n rootTelemetryTags: undefined,\r\n sharingError: undefined,\r\n sharingToolbar: undefined,\r\n staticPosition: undefined\r\n };\r\n\r\n /**\r\n * Flag to confirm first render is completed\r\n * @type {boolean}\r\n */\r\n private firstRenderCompleted = false;\r\n\r\n /**\r\n * Constructs a ContentActionsToolbar component\r\n * @constructor\r\n * @param { ContentActionsToolbarProps } props props contract\r\n */\r\n constructor(props: ContentActionsToolbarProps) {\r\n super(props);\r\n }\r\n\r\n /**\r\n * Render App component.\r\n *\r\n * @public\r\n * @return {JSX.Element}\r\n */\r\n public render(): JSX.Element {\r\n super.render();\r\n\r\n if (this.props.position && this.props.sharingToolbar && this.props.sharingToolbar.sharingButtons && !this.props.sharingError) {\r\n return (\r\n
    \r\n \r\n
    \r\n );\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Trigger after component update\r\n */\r\n public componentDidUpdate(prevProps: ContentActionsToolbarHandledProps): void {\r\n super.componentDidUpdate(prevProps);\r\n\r\n if (!prevProps.staticPosition && this.shouldFlip()) {\r\n this.flipToolbar();\r\n }\r\n\r\n if (!this.firstRenderCompleted) {\r\n markTtvr(this.props.experienceName);\r\n this.firstRenderCompleted = true;\r\n }\r\n }\r\n\r\n /**\r\n * A handler that gets invoked for unhandled errors.\r\n * @param error error object.\r\n */\r\n public componentDidCatch(error: Error): void {\r\n const appError = { ...ContentActionsToolbarAppErrors.ContentActionsBaseExperienceError, message: `${error.message}\\n${error.stack}` };\r\n Telemetry.sendAppErrorEvent(appError);\r\n }\r\n\r\n /**\r\n * Get the classname based on positioning of the toolbar\r\n */\r\n private getPositioningClassName(): string {\r\n const managedClasses = this.props.managedClasses;\r\n const positionClass: string = this.props.position === ToolbarPosition.horizontal ?\r\n managedClasses.contentActionsToolbar_horizontal :\r\n managedClasses.contentActionsToolbar_vertical;\r\n\r\n return positionClass;\r\n }\r\n\r\n /**\r\n * Check if toolbar needs to flip from one position to another\r\n * @method\r\n * @returns {boolean} True if toolbar should flip. False otherwise.\r\n */\r\n private shouldFlip(): boolean {\r\n const { position } = this.props;\r\n\r\n const currentHostId = position === ToolbarPosition.vertical ? PlaceHolderId.vertical : PlaceHolderId.horizontal;\r\n const hostElem = document.getElementById(currentHostId);\r\n if (!hostElem) {\r\n Telemetry.sendAppErrorEvent({\r\n ...ContentActionsToolbarAppErrors.ContentActionsFlipToolbarError,\r\n message: \"Missing toolbar placeholder while checking shouldFlip\",\r\n pb: {\r\n ...ContentActionsToolbarAppErrors.ContentActionsFlipToolbarError.pb,\r\n customMessage: `CurrentHostId: ${currentHostId}`\r\n }\r\n });\r\n return false;\r\n }\r\n return hostElem.getElementsByTagName(\"ul\").length === 0;\r\n }\r\n\r\n /**\r\n * Move toolbar from one placeholder to another, depending on the toolbar position\r\n * @method\r\n */\r\n private flipToolbar(): void {\r\n const { position } = this.props;\r\n const prevHostId = position === ToolbarPosition.vertical ? PlaceHolderId.horizontal : PlaceHolderId.vertical;\r\n const newHostId = position === ToolbarPosition.vertical ? PlaceHolderId.vertical : PlaceHolderId.horizontal;\r\n\r\n const prevHostElem = document.getElementById(prevHostId);\r\n const newHostElem = document.getElementById(newHostId);\r\n\r\n if (!prevHostElem || !newHostElem) {\r\n return null;\r\n }\r\n\r\n while (prevHostElem.childNodes.length > 0) {\r\n newHostElem.appendChild(prevHostElem.childNodes[0]);\r\n }\r\n }\r\n}","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport { ComponentStyles } from \"@microsoft/fast-jss-manager\";\r\nimport { ContentActionsToolbarClassNames } from \".\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { toPx } from \"@microsoft/fast-jss-utilities\";\r\n\r\nconst toolbarMinDim = 40;\r\nconst iconHeight = 32;\r\n\r\n/**\r\n * The ContentActionsToolbar styles\r\n * @type {ComponentStyles}\r\n */\r\nexport const ContentActionsToolbarStyles: ComponentStyles = (config: DesignSystem) => {\r\n return {\r\n contentActionsToolbar: {\r\n \"background-color\": \"none\"\r\n },\r\n contentActionsToolbar_vertical: {\r\n width: toPx(toolbarMinDim)\r\n },\r\n contentActionsToolbar_horizontal: {\r\n width: \"auto\"\r\n }\r\n };\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport {\r\n ContentActionsToolbarHandledProps as BaseExperienceHandledProps,\r\n ContentActionsToolbarProps as BaseExperienceProps,\r\n ContentActionsToolbarManagedClasses,\r\n ContentActionsToolbarUnhandledProps,\r\n ToolbarPosition\r\n} from \"./ContentActionsToolbar.props\";\r\nimport {\r\n ContentActionsToolbarConfigSchema,\r\n ContentActionsToolbarMockConfig,\r\n ContentActionsToolbarMockState\r\n} from \"./experience-info\";\r\nimport { ContentActionsToolbarConnectorArgs, ContentActionsToolbarInspector } from \"./ContentActionsToolbar.inspector\";\r\nimport { PlaceHolderId, Status } from \"./ContentActionsToolbar.constants\";\r\nimport manageJss, { ManagedJSSProps } from \"@microsoft/fast-jss-manager-react\";\r\n\r\nimport {\r\n ContentActionsToolbar as BaseExperience\r\n} from \"./ContentActionsToolbar\";\r\nimport { ComponentClass } from \"react-redux\";\r\nimport { ContentActionsToolbarActions } from \"./ContentActionsToolbar.actions\";\r\nimport { ContentActionsToolbarClassNames } from \"./ContentActionsToolbar.classnames\";\r\nimport { ContentActionsToolbarConfig } from \"./ContentActionsToolbar.config\";\r\nimport { ContentActionsToolbarConnector } from \"./ContentActionsToolbar.connector\";\r\nimport { ContentActionsToolbarReducer } from \"./ContentActionsToolbar.reducer\";\r\nimport { ContentActionsToolbarState } from \"./ContentActionsToolbar.state\";\r\nimport { ContentActionsToolbarStyles } from \"./ContentActionsToolbar.styles\";\r\nimport { DesignSystem } from \"@microsoft/fast-components-styles-msft\";\r\nimport { ExperienceInfo } from \"@msnews/core\";\r\nimport { Subtract } from \"utility-types\";\r\n\r\n/*\r\n * The type returned by manageJss type is very complicated so we'll let the\r\n * compiler infer the type instead of re-declaring just for the package export\r\n */\r\nconst ContentActionsToolbar = manageJss(ContentActionsToolbarStyles)(BaseExperience);\r\ntype ContentActionsToolbar = InstanceType;\r\n\r\n// Create a valid JSS managed interface that doesn't require managed classes which are provided by the manageJSS HOC\r\ntype ContentActionsToolbarHandledProps = Subtract;\r\n\r\n// Create type for manageJSS HOC styled instance we are exporting\r\ntype ContentActionsToolbarProps = ManagedJSSProps;\r\n\r\nconst ToolingInfo: ExperienceInfo<\r\n ContentActionsToolbarConfig,\r\n ContentActionsToolbarState,\r\n ContentActionsToolbarProps,\r\n ContentActionsToolbarConnectorArgs\r\n> = {\r\n reactComponent: ContentActionsToolbar,\r\n experienceConfigSchema: ContentActionsToolbarConfigSchema,\r\n mockState: ContentActionsToolbarMockState,\r\n mockConfig: ContentActionsToolbarMockConfig,\r\n inspector: ContentActionsToolbarInspector.inspect\r\n};\r\n\r\n// type for ContentActionsToolbar experience to be invoked by other experiences\r\ntype ContentActionsToolbarExp = ComponentClass;\r\n\r\n// Export everything a user might need from this index file\r\nexport {\r\n ContentActionsToolbar,\r\n ContentActionsToolbarActions,\r\n ContentActionsToolbarConfig,\r\n ContentActionsToolbarConnector,\r\n ContentActionsToolbarExp,\r\n ContentActionsToolbarProps,\r\n ContentActionsToolbarReducer,\r\n ContentActionsToolbarState,\r\n ContentActionsToolbarClassNames,\r\n ContentActionsToolbarHandledProps,\r\n ContentActionsToolbarUnhandledProps,\r\n PlaceHolderId,\r\n Status,\r\n ToolbarPosition,\r\n ToolingInfo\r\n};","// © Microsoft Corporation. All rights reserved.\r\n\r\nimport \"../publicPath\";\r\n\r\nimport {\r\n ContentActionsToolbar,\r\n ContentActionsToolbarConfig,\r\n ContentActionsToolbarConnector,\r\n ContentActionsToolbarReducer,\r\n PlaceHolderId\r\n} from \"@msnews/content-actions-toolbar\";\r\nimport { ExperienceConfigWrapper, IRequestContext, RequestContext, TelemetryBase, appEnvironment, resolver } from \"@msnews/core\";\r\nimport { handleAppErrorEventCall, handlePartialPageImpressionCall, handleTelemetryCall } from \"../integration/PrimeTelemetry\";\r\n\r\nimport { ContentActionsToolbarAppErrors } from \"@msnews/diagnostics\";\r\nimport { DesignSystemDefaults } from \"@microsoft/fast-components-styles-msft\";\r\nimport { DesignSystemProvider } from \"@microsoft/fast-jss-manager-react\";\r\nimport { ExperienceInitialProps } from \"@msnews/experiences-base\";\r\nimport { Mediator } from \"../integration/Mediator\";\r\nimport { PageBase } from \"@msnews/experiences-redux\";\r\nimport React from \"react\";\r\nimport { SharedDocumentType } from \"@msnews/views-helpers\";\r\nimport { ToolbarPosition } from \"@msnews/content-actions-toolbar\";\r\nimport { isNullOrUndefined } from \"util\";\r\n\r\n// export default function bootstrapPrimeHybrid(): void {\r\n// Get an instance of the PageBase for this app, and start the app\r\nconst app = PageBase.getInstance();\r\n\r\nconst requestContext = new RequestContext();\r\n\r\n// Mock documentId to be used when running hybrid locally for testing purposes\r\nconst mockDocumentId = \"BBKJJOS\";\r\n\r\n// Map base telemetry to prime library for hybrid\r\nTelemetryBase.trackAppErrorEvent = handleAppErrorEventCall;\r\nTelemetryBase.trackPartialImpression = handlePartialPageImpressionCall;\r\nTelemetryBase.trackEvent = handleTelemetryCall;\r\n\r\n// Start the App\r\napp.start();\r\n\r\nlet hostElement: HTMLElement;\r\n\r\nconst initialProps: ExperienceInitialProps = {\r\n contentId: mockDocumentId,\r\n parentTelemetry: {},\r\n context: {\r\n handleTelemetryCall: handleTelemetryCall\r\n }\r\n};\r\n\r\n/**\r\n * Otains document data properties from Prime placeholder and sets up the initial props and appEnv variables\r\n */\r\nfunction setupContentActionsInitialState(): void {\r\n // For Content Actions the placeholder can be in vertical in one prime region or horizontal in another prime region (depending on pagetype and column size)\r\n hostElement = document.getElementById(PlaceHolderId.vertical) || document.getElementById(PlaceHolderId.horizontal) || document.getElementById(\"content-actions-toolbar\");\r\n\r\n const dataset = hostElement.dataset || {};\r\n const cmsDocumentId: string = dataset.documentid || mockDocumentId;\r\n const isRSThree: string = dataset.isrsthree || \"false\";\r\n\r\n // Check for the existence of second position and sets staticsPosition accordingly\r\n let staticPosition: ToolbarPosition;\r\n if (hostElement.id === PlaceHolderId.vertical) {\r\n staticPosition = document.getElementById(PlaceHolderId.horizontal) ? undefined : ToolbarPosition.vertical;\r\n } else {\r\n staticPosition = document.getElementById(PlaceHolderId.vertical) ? undefined : ToolbarPosition.horizontal;\r\n }\r\n\r\n // Set initital props\r\n initialProps.contentId = cmsDocumentId;\r\n initialProps.context.staticPosition = staticPosition;\r\n initialProps.context.isRSThree = (isRSThree.toLowerCase() === \"true\");\r\n initialProps.context.documentType = SharedDocumentType.CMS;\r\n\r\n // Update app environment\r\n appEnvironment.HostPage = {\r\n originalUrl: location.href,\r\n hostName: location.hostname,\r\n verticalKey: dataset.verticalkey || \"news\",\r\n categoryKey: dataset.categorykey || \"other\",\r\n topDomain: appEnvironment.HostPage.topDomain\r\n };\r\n}\r\n\r\n/**\r\n * Connected the component to the Redux store passing initial props data\r\n * @param {any} experienceConfig\r\n * @returns The Redux connected component\r\n */\r\nfunction connectContentActionsComponent(contentActionsToolbarConfig: ContentActionsToolbarConfig, requestContext: IRequestContext): Promise> {\r\n const contentActionsToolbarConnector = new ContentActionsToolbarConnector(\"ContentActionsToolbar\",\r\n \"\",\r\n app.rootReducer,\r\n new ContentActionsToolbarReducer(),\r\n app.store,\r\n contentActionsToolbarConfig,\r\n requestContext);\r\n return contentActionsToolbarConnector.connectComponent(ContentActionsToolbar, initialProps);\r\n}\r\n\r\n/**\r\n * Render the experience on hostElement placeholder\r\n * @param contentActionsExperience\r\n */\r\nfunction renderExperience(contentActionsExperience: any): void {\r\n app.renderRootElement(\r\n React.createElement(\r\n DesignSystemProvider,\r\n { designSystem: DesignSystemDefaults },\r\n React.createElement(contentActionsExperience)\r\n ),\r\n hostElement\r\n );\r\n}\r\n\r\nlet contentActionsConfig: ContentActionsToolbarConfig;\r\nconst configFilePath = \"cms/api/amp/experienceConfigIndex/BBWebZe\";\r\nresolver.getConfig(configFilePath)\r\n .then((experienceConfig: ExperienceConfigWrapper) => {\r\n if (!experienceConfig) {\r\n throw Error(`Failed to load config file. Path: ${configFilePath}`);\r\n }\r\n contentActionsConfig = experienceConfig.properties;\r\n setupContentActionsInitialState();\r\n return connectContentActionsComponent(contentActionsConfig, requestContext);\r\n }).then(renderExperience)\r\n .catch(error => {\r\n handleAppErrorEventCall({\r\n ...ContentActionsToolbarAppErrors.ContentActionsExperienceLoadError,\r\n message: \"Error in hybrid loading Content Actions experience\",\r\n pb: {\r\n ...ContentActionsToolbarAppErrors.ContentActionsExperienceLoadError.pb,\r\n customMessage: `Url: ${location.href} Config: ${contentActionsConfig} Error: ${error}`\r\n }\r\n });\r\n return;\r\n }\r\n );\r\n\r\n// Listen to update events from Prime (Necessary as video page auto updates current displayed video)\r\nMediator.registerContentActionsUpdatedEvent(async () => {\r\n setupContentActionsInitialState();\r\n connectContentActionsComponent(contentActionsConfig, requestContext)\r\n .then(renderExperience);\r\n});"],"sourceRoot":""}