{"version":3,"file":"main-9acf4d28-bundle.js?1738747637004","mappings":"UAAIA,ECCAC,EADAC,ECAAC,EACAC,E,mBCDJ,IAAIC,EAAM,CACT,yCAA0C,CACzC,MACA,KACA,KACA,KACA,KACA,MAED,8CAA+C,CAC9C,MACA,KACA,KACA,KACA,KACA,KAED,sCAAuC,CACtC,MACA,KACA,KACA,KACA,KAED,2CAA4C,CAC3C,MACA,KACA,KACA,MAED,uCAAwC,CACvC,MACA,KACA,KACA,KAED,2CAA4C,CAC3C,MACA,KACA,KACA,KACA,KACA,MAED,0CAA2C,CAC1C,MACA,KACA,KACA,KACA,KACA,MAED,yCAA0C,CACzC,MACA,KACA,KACA,KACA,KACA,MAED,sCAAuC,CACtC,MACA,KACA,KACA,KACA,KACA,MAED,yCAA0C,CACzC,MACA,KACA,KACA,KACA,KACA,MAED,uCAAwC,CACvC,MACA,KACA,KACA,MAED,8CAA+C,CAC9C,MACA,KACA,KACA,MAED,+CAAgD,CAC/C,MACA,KACA,KACA,KACA,KACA,MAED,qCAAsC,CACrC,MACA,KACA,KACA,MAED,qCAAsC,CACrC,MACA,KACA,KACA,KACA,MAED,sCAAuC,CACtC,MACA,KACA,KACA,KACA,KAED,qCAAsC,CACrC,MACA,KACA,KACA,KACA,MAED,wCAAyC,CACxC,MACA,KACA,KACA,MAED,qCAAsC,CACrC,MACA,KACA,KACA,KACA,MAED,sCAAuC,CACtC,MACA,KACA,KACA,KACA,MAED,4CAA6C,CAC5C,MACA,KACA,KACA,KACA,MAED,6CAA8C,CAC7C,MACA,KACA,KACA,KACA,MAED,wCAAyC,CACxC,MACA,KACA,KACA,KACA,MAED,yCAA0C,CACzC,MACA,KACA,KACA,MAED,0CAA2C,CAC1C,MACA,KACA,KACA,KACA,MAED,yCAA0C,CACzC,MACA,KACA,KACA,OAGF,SAASC,EAAoBC,GAC5B,IAAIC,EAAoBC,EAAEJ,EAAKE,GAC9B,OAAOG,QAAQC,UAAUC,MAAK,KAC7B,IAAIC,EAAI,IAAIC,MAAM,uBAAyBP,EAAM,KAEjD,MADAM,EAAEE,KAAO,mBACHF,CAAC,IAIT,IAAI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","sources":["webpack://klubble.app.client/webpack/runtime/chunk loaded","webpack://klubble.app.client/webpack/runtime/create fake namespace object","webpack://klubble.app.client/webpack/runtime/load script","webpack://klubble.app.client/./player/puzzles/ lazy ^\\.\\/.*\\/js\\/components\\/AppComponent$ chunkName: appcomponent-[request] namespace object","webpack://klubble.app.client/./pages/calendar/components/CalendarCongratulationsComponent.tsx","webpack://klubble.app.client/./pages/calendar/components/CalendarSuggestionsComponent.tsx","webpack://klubble.app.client/./pages/calendar/components/CalendarHeaderComponent.tsx","webpack://klubble.app.client/./pages/calendar/containers/CalendarHeaderContainer.tsx","webpack://klubble.app.client/./pages/calendar/components/CalendarDayComponent.tsx","webpack://klubble.app.client/./pages/calendar/components/CalendarComponent.tsx","webpack://klubble.app.client/./pages/common/SeoComponent.tsx","webpack://klubble.app.client/./pages/common/components/AnimatedBackgroundSquircle.tsx","webpack://klubble.app.client/./pages/common/components/AvatarComponent.tsx","webpack://klubble.app.client/./pages/common/components/BrandIconComponent.tsx","webpack://klubble.app.client/./pages/common/components/FeedbackCardComponent.tsx","webpack://klubble.app.client/./pages/common/components/navigation/NavigationMenuItemComponent.tsx","webpack://klubble.app.client/./pages/common/components/navigation/NavigationMenuComponent.tsx","webpack://klubble.app.client/./pages/common/components/navigation/AccountMenuComponent.tsx","webpack://klubble.app.client/./pages/common/components/HeaderComponent.tsx","webpack://klubble.app.client/./pages/common/components/HeaderTitleBarComponent.tsx","webpack://klubble.app.client/./pages/common/components/NavigationMobileComponent.tsx","webpack://klubble.app.client/./pages/common/containers/NavigationMobileContainer.tsx","webpack://klubble.app.client/./pages/common/components/FooterComponent.tsx","webpack://klubble.app.client/./pages/common/components/LayoutComponent.tsx","webpack://klubble.app.client/./pages/common/components/LogoComponent.tsx","webpack://klubble.app.client/./pages/common/components/LogoSubTitleComponent.tsx","webpack://klubble.app.client/./pages/common/components/NotificationsBellComponent.tsx","webpack://klubble.app.client/./pages/common/components/PublicRouteComponent.tsx","webpack://klubble.app.client/./pages/common/components/RecentPuzzlesBackgroundComponent.tsx","webpack://klubble.app.client/./pages/common/components/RecentPuzzlesComponent.tsx","webpack://klubble.app.client/./pages/common/components/StartGameByGuidComponent.tsx","webpack://klubble.app.client/./pages/common/components/StartQRHostGameComponent.tsx","webpack://klubble.app.client/./pages/common/components/TabNav.tsx","webpack://klubble.app.client/./pages/common/components/breadcrumbs/BreadcrumbsComponent.tsx","webpack://klubble.app.client/./pages/common/components/icons/CheckmarkComponent.tsx","webpack://klubble.app.client/./pages/common/components/buttons/DayButtonComponent.tsx","webpack://klubble.app.client/./pages/common/components/buttons/ButtonGroupDaysComponent.tsx","webpack://klubble.app.client/./pages/common/components/buttons/PlayButtonComponent.tsx","webpack://klubble.app.client/./pages/common/components/buttons/RoundedButtonComponent.tsx","webpack://klubble.app.client/./pages/common/components/buttons/SliderButtonComponent.tsx","webpack://klubble.app.client/./pages/common/components/buttons/ViewButtonComponent.tsx","webpack://klubble.app.client/./pages/common/components/cards/CardComponent.tsx","webpack://klubble.app.client/./pages/common/components/carouselbar/CarouselBarArrowComponent.tsx","webpack://klubble.app.client/./pages/common/components/context_providers/TranslationContextComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/endscreen/UspSliderComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/endscreen/DrawerContentJoinNowComponent.tsx","webpack://klubble.app.client/./pages/common/components/expression/ExpressionIcon.tsx","webpack://klubble.app.client/./pages/common/components/form/PasswordStrengthComponent.tsx","webpack://klubble.app.client/./pages/common/components/form/InputComponent.tsx","webpack://klubble.app.client/./pages/common/components/form/SelectComponent.tsx","webpack://klubble.app.client/./pages/common/components/form/SubmitButtonComponent.tsx","webpack://klubble.app.client/./pages/common/components/game_cards/GameCardCalendarComponent.tsx","webpack://klubble.app.client/./pages/common/components/game_cards/GameCardComponent.tsx","webpack://klubble.app.client/./pages/common/components/game_cards/GameCardRowComponent.tsx","webpack://klubble.app.client/./pages/common/components/game_cards/GameCardRowPuzzlePacksComponent.tsx","webpack://klubble.app.client/./pages/common/components/navigation/NavigationPagesTabsComponent.tsx","webpack://klubble.app.client/./pages/common/components/page_header/HeroBackgroundMobileComponent.tsx","webpack://klubble.app.client/./pages/common/components/page_header/PageHeaderBackgroundDesktopComponent.tsx","webpack://klubble.app.client/./pages/common/components/page_header/PageHeaderBackgroundMobileComponent.tsx","webpack://klubble.app.client/./pages/common/components/page_header/PageHeaderComponent.tsx","webpack://klubble.app.client/./pages/common/components/puzzle_icon/PuzzleIcon.tsx","webpack://klubble.app.client/./pages/common/components/puzzle_packs/PuzzlePackCardComponent.tsx","webpack://klubble.app.client/./pages/common/components/puzzle_packs/PuzzlePackCardContinueComponent.tsx","webpack://klubble.app.client/./pages/common/components/puzzle_packs/PuzzlePackIcons.tsx","webpack://klubble.app.client/./pages/common/components/pwa/PWAEventsProvider.tsx","webpack://klubble.app.client/./pages/common/components/react_markdown/CustomListItemComponent.tsx","webpack://klubble.app.client/./pages/common/components/resources/CommonApiResourcesComponent.tsx","webpack://klubble.app.client/./pages/common/components/theme/ThemeContext.ts","webpack://klubble.app.client/./pages/common/components/theme/ThemeProviderComponent.tsx","webpack://klubble.app.client/./themes/denksportTheme.ts","webpack://klubble.app.client/./themes/tankesportTheme.ts","webpack://klubble.app.client/./themes/sportCerebralTheme.ts","webpack://klubble.app.client/./pages/common/components/toasts/ToastComponent.tsx","webpack://klubble.app.client/./pages/common/components/toggles/HeartToggleComponent.tsx","webpack://klubble.app.client/./pages/common/components/toggles/ToggleComponent.tsx","webpack://klubble.app.client/./pages/common/components/tracking/DataLayerTrackingComponent.tsx","webpack://klubble.app.client/./pages/common/components/utility/ManagePersistencyStorageSpaceComponent.tsx","webpack://klubble.app.client/./pages/common/components/utility/ScrollTopComponent.tsx","webpack://klubble.app.client/./player/js/components/drawers/DrawerContentSmartHintWordsearchComponent.tsx","webpack://klubble.app.client/./player/js/containers/drawers/DrawerContentSmartHintWordsearchContainer.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentFeatureInDevelopmentComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentTermsAndConditionsComponent.tsx","webpack://klubble.app.client/./pages/common/components/form/TextButtonComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentAddToHomeScreenInfoComponent.tsx","webpack://klubble.app.client/./pages/common/components/form/RadioInputComponent.tsx","webpack://klubble.app.client/./pages/common/containers/drawer/content/DrawerContentSortingContainer.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentSortingComponent.tsx","webpack://klubble.app.client/./player/js/utilities/getCellValueOrSolution.ts","webpack://klubble.app.client/./player/js/containers/GuessBarContainer.tsx","webpack://klubble.app.client/./player/js/components/GuessBarComponent.tsx","webpack://klubble.app.client/./player/js/components/SmartHintsComponent.tsx","webpack://klubble.app.client/./player/js/containers/SmartHintsContainer.tsx","webpack://klubble.app.client/./player/js/components/drawers/DrawerContentDictionaryComponent.tsx","webpack://klubble.app.client/./player/js/components/drawers/DrawerContentSmartHintLogicComponent.tsx","webpack://klubble.app.client/./player/js/containers/drawers/DrawerContentSmartHintLogicContainer.tsx","webpack://klubble.app.client/./pages/common/components/drawer/account/DrawerContentCancelSubscriptionComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentCannotStartPuzzleComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/express/DrawerContentExpressItemComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/express/DrawerContentExpressComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentGameInstructionsComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentGenericConfirmComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentGenericErrorComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/share/SharePuzzleComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/share/DrawerContentGiftPuzzleComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentHideOnscreenKeyboard.tsx","webpack://klubble.app.client/./pages/common/components/drawer/share/DrawerContentInvitePuzzleComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentLevelComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/notifications/DrawerContentNotificationItemIconComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/notifications/DrawerContentNotificationItemComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/notifications/DrawerContentNotificationsComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentPlayerListComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentPuzzleFinishedWithoutContribution.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentSetPlayerNameComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentShowOnscreenKeyboard.tsx","webpack://klubble.app.client/./pages/payment_input/usp/SubscriptionUSPsComponent.tsx","webpack://klubble.app.client/./pages/payment_input/choose_subscription/ChooseSubscriptionComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/account/DrawerContentSubscribeComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/account/DrawerContentNeedToRegisterComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/account/DrawerContentUpgradeSubscriptionComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/account/DrawerContentUpgradeSubscriptionPremiumOnlyComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/endscreen/DrawerContentViewPuzzleComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/share/DrawerContentShareResultComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/personal-details/DrawerContentReportBugComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/puzzle-packs/DrawerContentPuzzlePackInfo.tsx","webpack://klubble.app.client/./pages/common/components/puzzle_packs/PuzzlePackPuzzlePiece.tsx","webpack://klubble.app.client/./pages/common/components/puzzle_packs/PuzzlePackStartComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/puzzle-packs/DrawerContentPuzzlePackContent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/headers/DefaultDrawerHeaderComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/headers/DrawerHeaderSubscribeComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/content/DrawerContentPuzzlePackTypeLevelComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/onboard/DrawerContentBackgroundComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/onboard/DrawerContentOnboardStepUsernameComponent.tsx","webpack://klubble.app.client/./pages/common/components/utility/OverflowContentSwitcherComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/onboard/DrawerContentOnboardStepSuccessComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/onboard/DrawerContentOnboardStepChooseOptInComponent.tsx","webpack://klubble.app.client/./pages/common/components/drawer/onboard/DrawerContentOnboardComponent.tsx","webpack://klubble.app.client/./pages/common/components/ConfettiComponent.tsx","webpack://klubble.app.client/./pages/common/components/DrawerComponent.tsx","webpack://klubble.app.client/./pages/common/containers/DrawerContainer.tsx","webpack://klubble.app.client/./pages/common/containers/HeartPuzzlePackTypeToggleContainer.tsx","webpack://klubble.app.client/./pages/common/containers/HeartToggleContainer.tsx","webpack://klubble.app.client/./pages/common/components/overlays/OverlayComponent.tsx","webpack://klubble.app.client/./pages/common/containers/OverlayContainer.tsx","webpack://klubble.app.client/./pages/common/components/PrivateRouteComponent.tsx","webpack://klubble.app.client/./pages/common/containers/PrivateRouteContainer.tsx","webpack://klubble.app.client/./pages/common/components/UIManagerComponent.tsx","webpack://klubble.app.client/./pages/common/containers/UIManagerContainer.tsx","webpack://klubble.app.client/./pages/common/containers/UserDataContainer.tsx","webpack://klubble.app.client/./pages/common/components/UserDataComponent.tsx","webpack://klubble.app.client/./pages/common/components/toasts/ToastsComponent.tsx","webpack://klubble.app.client/./pages/common/containers/toasts/ToastsContainer.tsx","webpack://klubble.app.client/./pages/common/loading/LoadingComponent.tsx","webpack://klubble.app.client/./pages/common/pages/ErrorExceptionComponent.tsx","webpack://klubble.app.client/./pages/common/pages/ErrorPageComponent.tsx","webpack://klubble.app.client/./pages/common/pages/ErrorPageNotFoundComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseNoScoreComponent.tsx","webpack://klubble.app.client/./pages/common/components/CounterComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseCirclesComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/containers/DailyDoseCirclesContainer.tsx","webpack://klubble.app.client/./pages/daily_dose/components/constants/DailyDosePeriod.ts","webpack://klubble.app.client/./utilities/date.ts","webpack://klubble.app.client/./pages/daily_dose/utilities/dailyDoseActivities.ts","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseDateComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseGameTypeSummaryNoScore.tsx","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseGameTypeSummaryComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/containers/DailyDoseTodayItemsContainer.tsx","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseTodayItemsComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseTodayComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/containers/DailyDoseTodayContainer.tsx","webpack://klubble.app.client/./pages/daily_dose/containers/DailyDoseActivityBarContainer.tsx","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseActivityBarComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/utilities/hooks.ts","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseActivityExtremeComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseActivityHeaderComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseActivityLabelComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseActivityComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/containers/DailyDoseContainer.tsx","webpack://klubble.app.client/./pages/daily_dose/components/DailyDoseComponent.tsx","webpack://klubble.app.client/./pages/daily_dose/utilities/dailyDoseComposer.ts","webpack://klubble.app.client/./pages/home/components/HomeFeaturedCardComponent.tsx","webpack://klubble.app.client/./pages/home/components/HomeFeaturedComponent.tsx","webpack://klubble.app.client/./pages/home/components/HomeFavoritesComponent.tsx","webpack://klubble.app.client/./pages/home/components/HomeMinisComponent.tsx","webpack://klubble.app.client/./pages/home/containers/HomeHeroPuzzleSliderContainer.tsx","webpack://klubble.app.client/./pages/home/components/HomeHeroPuzzleSliderComponent.tsx","webpack://klubble.app.client/./pages/common/components/page_header/HeroBackgroundDesktopComponent.tsx","webpack://klubble.app.client/./pages/home/components/HomeHeroComponent.tsx","webpack://klubble.app.client/./pages/home/components/HomeSuggestionsComponent.tsx","webpack://klubble.app.client/./pages/home/components/HomePuzzlePacksBackgroundComponent.tsx","webpack://klubble.app.client/./pages/home/components/HomePuzzlePacksComponent.tsx","webpack://klubble.app.client/./pages/home/components/HomeContinuePlayingComponent.tsx","webpack://klubble.app.client/./pages/home/HomeComponent.tsx","webpack://klubble.app.client/./pages/home/containers/HomeContainer.tsx","webpack://klubble.app.client/./pages/landing/components/LandingPrintSubscriberComponent.tsx","webpack://klubble.app.client/./pages/landing/components/LandingComponent.tsx","webpack://klubble.app.client/./pages/landing/components/LandingHeaderComponent.tsx","webpack://klubble.app.client/./pages/landing/components/LandingRegularComponent.tsx","webpack://klubble.app.client/./pages/landing/components/LandingSSOLoginComponent.tsx","webpack://klubble.app.client/./utilities/getCookies.ts","webpack://klubble.app.client/./pages/login/components/LoginComponent.tsx","webpack://klubble.app.client/./pages/onboarding/components/OnboardingHeaderComponent.tsx","webpack://klubble.app.client/./pages/common/components/game_cards/GameCardAddFavoriteComponent.tsx","webpack://klubble.app.client/./pages/common/components/game_cards/GameCardDifficultyComponent.tsx","webpack://klubble.app.client/./pages/onboarding/components/OnboardingPuzzlesBackgroundComponent.tsx","webpack://klubble.app.client/./pages/onboarding/hooks/useRevertPuzzleSettings.ts","webpack://klubble.app.client/./pages/onboarding/components/OnboardingPuzzlesComponent.tsx","webpack://klubble.app.client/./pages/onboarding/hooks/useSetSelectedPuzzleLevel.ts","webpack://klubble.app.client/./pages/payment_complete/PaymentCompletePageComponent.tsx","webpack://klubble.app.client/./pages/payment_complete/PaymentPageErrorComponent.tsx","webpack://klubble.app.client/./pages/payment_complete/PaymentPagePendingComponent.tsx","webpack://klubble.app.client/./pages/payment_complete/PaymentConfettiComponent.tsx","webpack://klubble.app.client/./pages/payment_complete/PaymentPageSuccessComponent.tsx","webpack://klubble.app.client/./pages/payment_input/product_cards/PaymentSubscriptionCardComponent.tsx","webpack://klubble.app.client/./pages/payment_complete/PaymentRedirectComponent.tsx","webpack://klubble.app.client/./pages/payment_input/PaymentStepHeaderComponent.tsx","webpack://klubble.app.client/./pages/payment_input/PaymentStepAdyenComponent.tsx","webpack://klubble.app.client/./pages/payment_input/PaymentStepSubscriptionComponent.tsx","webpack://klubble.app.client/./pages/payment_input/PaymentStepPersonalInfoComponent.tsx","webpack://klubble.app.client/./pages/payment_input/PaymentStepsComponent.tsx","webpack://klubble.app.client/./pages/payment_input/choose_subscription/PaymentPeriodComponent.tsx","webpack://klubble.app.client/./pages/payment_input/choose_subscription/ChoosePaymentPeriodComponent.tsx","webpack://klubble.app.client/./pages/payment_input/product_cards/PaymentPuzzlePackCardComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/EndscreenCheckmarkComponent.tsx","webpack://klubble.app.client/./utilities/brainpointsUtilities.ts","webpack://klubble.app.client/./pages/endscreen/hooks/useBrainpointBadges.ts","webpack://klubble.app.client/./pages/common/components/toggles/ExpandToggleComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/brainpoints/EndscreenBrainpointsComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/brainpoints/EndscreenBrainpointsOneComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/brainpoints/EndscreenBrainpointsTwoComponent.tsx","webpack://klubble.app.client/./pages/common/components/bars/NextQRPuzzleProgressBarComponent.tsx","webpack://klubble.app.client/./utilities/getImageUrls.ts","webpack://klubble.app.client/./player/js/components/modals/game_status/endgame_modal/CelebrationGifComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/celebration/EndscreenCelebrationToastsComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/celebration/EndscreenCelebrationComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/cards/EndscreenTopBarComponent.tsx","webpack://klubble.app.client/./pages/common/components/buttons/OverviewButtonComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/cards/EndscreenConfettiComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/cards/buttons/EndscreenGiftPuzzleButtonComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/cards/buttons/EndscreenShareResultButtonComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/cards/buttons/EndscreenViewPuzzleButtonComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/cards/EndscreenHeaderComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/cards/EndscreenDailyDoseComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/cards/EndscreenContributionComponent.tsx","webpack://klubble.app.client/./pages/endscreen/components/EndscreenComponent.tsx","webpack://klubble.app.client/./pages/endscreen/containers/EndscreenContainer.tsx","webpack://klubble.app.client/./pages/player/components/PlayerEndscreenAnimationComponent.tsx","webpack://klubble.app.client/./pages/player/components/PlayerComponent.tsx","webpack://klubble.app.client/./pages/common/components/SectionBackgroundComponent.tsx","webpack://klubble.app.client/./pages/puzzle_packs/components/PuzzlePackTypeHeaderComponent.tsx","webpack://klubble.app.client/./pages/puzzle_packs/components/TryOutPuzzleTypeCardComponent.tsx","webpack://klubble.app.client/./pages/puzzle_packs/components/PuzzlePackTypeComponent.tsx","webpack://klubble.app.client/./pages/puzzle_packs/hooks/useShowPuzzlePackContents.ts","webpack://klubble.app.client/./pages/puzzle_packs/containers/PuzzlePackTypeFilter1Container.tsx","webpack://klubble.app.client/./pages/puzzle_packs/containers/PuzzlePackTypeFilter2Container.tsx","webpack://klubble.app.client/./pages/common/components/puzzle_packs/PuzzlePackTypeCardComponent.tsx","webpack://klubble.app.client/./pages/puzzle_packs/components/PuzzlePackTypesDisplayComponent.tsx","webpack://klubble.app.client/./pages/puzzle_packs/components/PuzzlePackTypesComponent.tsx","webpack://klubble.app.client/./pages/puzzle_packs/hooks/usePuzzlePackAuthentication.ts","webpack://klubble.app.client/./pages/puzzle_packs/hooks/usePuzzlePacks.ts","webpack://klubble.app.client/./pages/puzzles/components/PuzzleFilter1Component.tsx","webpack://klubble.app.client/./pages/puzzles/components/PuzzleFilter2Component.tsx","webpack://klubble.app.client/./pages/puzzles/components/syncFilterAndSortingWithUrl.ts","webpack://klubble.app.client/./pages/puzzles/components/PuzzleSortComponent.tsx","webpack://klubble.app.client/./pages/puzzles/containers/PuzzleSortContainer.tsx","webpack://klubble.app.client/./pages/puzzles/containers/PuzzleFilter1Container.tsx","webpack://klubble.app.client/./pages/puzzles/containers/PuzzleFilter2Container.tsx","webpack://klubble.app.client/./pages/puzzles/components/PuzzleDisplayComponent.tsx","webpack://klubble.app.client/./pages/puzzles/containers/PuzzleDisplayContainer.tsx","webpack://klubble.app.client/./pages/puzzles/containers/PuzzlesContainer.tsx","webpack://klubble.app.client/./pages/puzzles/components/PuzzlesComponent.tsx","webpack://klubble.app.client/./pages/stats/StatsTotalsItemComponent.tsx","webpack://klubble.app.client/./pages/stats/StatsTotalsComponent.tsx","webpack://klubble.app.client/./pages/stats/StatsPieChartGraphComponent.tsx","webpack://klubble.app.client/./pages/stats/StatsSizesComponent.tsx","webpack://klubble.app.client/./pages/stats/StatsTypesComponent.tsx","webpack://klubble.app.client/./pages/stats/NoStatsComponent.tsx","webpack://klubble.app.client/./pages/stats/StatsComponent.tsx","webpack://klubble.app.client/./player/puzzles/wordsearch/js/actions/clueActions.ts","webpack://klubble.app.client/./player/js/actions/actionServices/cellActionServices.ts","webpack://klubble.app.client/./player/js/components/PlayerComponent.tsx","webpack://klubble.app.client/./utilities/tryPreloadAssets.tsx","webpack://klubble.app.client/./player/js/utilities/getPuzzleSpecificShareDetails.ts","webpack://klubble.app.client/./player/js/components/clue-bar/ClueBarSeeImageComponent.tsx","webpack://klubble.app.client/./player/js/components/gameroom/PlayerAvatarComponent.tsx","webpack://klubble.app.client/./player/js/components/header/PuzzleInviteButtonComponent.tsx","webpack://klubble.app.client/./player/js/components/modals/RotateScreenComponent.tsx","webpack://klubble.app.client/./player/js/gameroom/actions/gameroomActions.ts","webpack://klubble.app.client/./player/js/gameroom/gameroomConnection.ts","webpack://klubble.app.client/./player/js/store/utilities/error.ts","webpack://klubble.app.client/./player/js/store/utilities/persistency.ts","webpack://klubble.app.client/./reducers/notificationsReducer.ts","webpack://klubble.app.client/./reducers/settingsReducer.ts","webpack://klubble.app.client/./reducers/puzzleDataReducer.ts","webpack://klubble.app.client/./reducers/puzzleFilterReducer.ts","webpack://klubble.app.client/./reducers/userReducer.ts","webpack://klubble.app.client/./store/index.ts","webpack://klubble.app.client/./reducers/configReducer.ts","webpack://klubble.app.client/./utilities/error.ts","webpack://klubble.app.client/./utilities/form.ts","webpack://klubble.app.client/./utilities/formatLabel.tsx","webpack://klubble.app.client/./utilities/getActiveSubscription.ts","webpack://klubble.app.client/./utilities/getDisplayModeApp.tsx","webpack://klubble.app.client/./utilities/getParamsFromQueryString.tsx","webpack://klubble.app.client/./utilities/getPuzzlePackTypeColor.ts","webpack://klubble.app.client/./utilities/player.ts","webpack://klubble.app.client/./utilities/replaceAll.tsx","webpack://klubble.app.client/./utilities/useTwikeySanitizer.ts","webpack://klubble.app.client/./utilities/userInput.ts","webpack://klubble.app.client/webpack/bootstrap","webpack://klubble.app.client/webpack/runtime/amd options","webpack://klubble.app.client/webpack/runtime/compat get default export","webpack://klubble.app.client/webpack/runtime/define property getters","webpack://klubble.app.client/webpack/runtime/ensure chunk","webpack://klubble.app.client/webpack/runtime/get javascript chunk filename","webpack://klubble.app.client/webpack/runtime/get mini-css chunk filename","webpack://klubble.app.client/webpack/runtime/global","webpack://klubble.app.client/webpack/runtime/hasOwnProperty shorthand","webpack://klubble.app.client/webpack/runtime/make namespace object","webpack://klubble.app.client/webpack/runtime/node module decorator","webpack://klubble.app.client/webpack/runtime/publicPath","webpack://klubble.app.client/webpack/runtime/css loading","webpack://klubble.app.client/webpack/runtime/jsonp chunk loading","webpack://klubble.app.client/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","var getProto = Object.getPrototypeOf ? (obj) => (Object.getPrototypeOf(obj)) : (obj) => (obj.__proto__);\nvar leafPrototypes;\n// create a fake namespace object\n// mode & 1: value is a module id, require it\n// mode & 2: merge all properties of value into the ns\n// mode & 4: return value when already ns object\n// mode & 16: return value when it's Promise-like\n// mode & 8|1: behave like require\n__webpack_require__.t = function(value, mode) {\n\tif(mode & 1) value = this(value);\n\tif(mode & 8) return value;\n\tif(typeof value === 'object' && value) {\n\t\tif((mode & 4) && value.__esModule) return value;\n\t\tif((mode & 16) && typeof value.then === 'function') return value;\n\t}\n\tvar ns = Object.create(null);\n\t__webpack_require__.r(ns);\n\tvar def = {};\n\tleafPrototypes = leafPrototypes || [null, getProto({}), getProto([]), getProto(getProto)];\n\tfor(var current = mode & 2 && value; typeof current == 'object' && !~leafPrototypes.indexOf(current); current = getProto(current)) {\n\t\tObject.getOwnPropertyNames(current).forEach((key) => (def[key] = () => (value[key])));\n\t}\n\tdef['default'] = () => (value);\n\t__webpack_require__.d(ns, def);\n\treturn ns;\n};","var inProgress = {};\nvar dataWebpackPrefix = \"klubble.app.client:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = (url, done, key, chunkId) => {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\n\t\tscript.charset = 'utf-8';\n\t\tscript.timeout = 120;\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = (prev, event) => {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach((fn) => (fn(event)));\n\t\tif(prev) return prev(event);\n\t}\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","var map = {\n\t\"./arrowword/js/components/AppComponent\": [\n\t\t67028,\n\t\t4952,\n\t\t8472,\n\t\t2067,\n\t\t1240,\n\t\t8704\n\t],\n\t\"./arrowword_plus/js/components/AppComponent\": [\n\t\t39016,\n\t\t4952,\n\t\t8472,\n\t\t2067,\n\t\t1240,\n\t\t836\n\t],\n\t\"./binero/js/components/AppComponent\": [\n\t\t79360,\n\t\t4952,\n\t\t8472,\n\t\t1576,\n\t\t272\n\t],\n\t\"./blockpuzzle/js/components/AppComponent\": [\n\t\t34012,\n\t\t4952,\n\t\t8472,\n\t\t9172\n\t],\n\t\"./camping/js/components/AppComponent\": [\n\t\t17040,\n\t\t4952,\n\t\t8472,\n\t\t5000\n\t],\n\t\"./codebreaker/js/components/AppComponent\": [\n\t\t44438,\n\t\t4952,\n\t\t6120,\n\t\t8472,\n\t\t2067,\n\t\t2080\n\t],\n\t\"./continuous/js/components/AppComponent\": [\n\t\t52566,\n\t\t4952,\n\t\t8472,\n\t\t2067,\n\t\t1240,\n\t\t7972\n\t],\n\t\"./crossword/js/components/AppComponent\": [\n\t\t58812,\n\t\t4952,\n\t\t8472,\n\t\t2067,\n\t\t1240,\n\t\t8196\n\t],\n\t\"./crypto/js/components/AppComponent\": [\n\t\t29100,\n\t\t4952,\n\t\t8472,\n\t\t2067,\n\t\t1240,\n\t\t3238\n\t],\n\t\"./filippine/js/components/AppComponent\": [\n\t\t56328,\n\t\t4952,\n\t\t8472,\n\t\t2067,\n\t\t1240,\n\t\t8292\n\t],\n\t\"./fitword/js/components/AppComponent\": [\n\t\t49804,\n\t\t4952,\n\t\t8472,\n\t\t5764\n\t],\n\t\"./fleetcommander/js/components/AppComponent\": [\n\t\t74952,\n\t\t4952,\n\t\t8472,\n\t\t2496\n\t],\n\t\"./frenchcrossword/js/components/AppComponent\": [\n\t\t73592,\n\t\t4952,\n\t\t8472,\n\t\t2067,\n\t\t1240,\n\t\t4366\n\t],\n\t\"./hashi/js/components/AppComponent\": [\n\t\t20972,\n\t\t4952,\n\t\t8472,\n\t\t8520\n\t],\n\t\"./ikura/js/components/AppComponent\": [\n\t\t39940,\n\t\t4952,\n\t\t8472,\n\t\t1576,\n\t\t7840\n\t],\n\t\"./kakuro/js/components/AppComponent\": [\n\t\t69128,\n\t\t4952,\n\t\t8472,\n\t\t1576,\n\t\t824\n\t],\n\t\"./kdoku/js/components/AppComponent\": [\n\t\t85488,\n\t\t4952,\n\t\t8472,\n\t\t1576,\n\t\t4120\n\t],\n\t\"./nonogram/js/components/AppComponent\": [\n\t\t53304,\n\t\t4952,\n\t\t8472,\n\t\t8544\n\t],\n\t\"./rebus/js/components/AppComponent\": [\n\t\t96760,\n\t\t4952,\n\t\t8472,\n\t\t2067,\n\t\t6584\n\t],\n\t\"./sudoku/js/components/AppComponent\": [\n\t\t47404,\n\t\t4952,\n\t\t8472,\n\t\t1576,\n\t\t6244\n\t],\n\t\"./sudoku_chaos/js/components/AppComponent\": [\n\t\t74628,\n\t\t4952,\n\t\t8472,\n\t\t1576,\n\t\t5728\n\t],\n\t\"./sudoku_killer/js/components/AppComponent\": [\n\t\t74580,\n\t\t4952,\n\t\t8472,\n\t\t1576,\n\t\t6680\n\t],\n\t\"./tectonic/js/components/AppComponent\": [\n\t\t86680,\n\t\t4952,\n\t\t8472,\n\t\t1576,\n\t\t2672\n\t],\n\t\"./wordguess/js/components/AppComponent\": [\n\t\t62420,\n\t\t4952,\n\t\t8472,\n\t\t1024\n\t],\n\t\"./wordsearch/js/components/AppComponent\": [\n\t\t61312,\n\t\t4952,\n\t\t8782,\n\t\t8472,\n\t\t5584\n\t],\n\t\"./wordwheel/js/components/AppComponent\": [\n\t\t73640,\n\t\t4952,\n\t\t8472,\n\t\t4020\n\t]\n};\nfunction webpackAsyncContext(req) {\n\tif(!__webpack_require__.o(map, req)) {\n\t\treturn Promise.resolve().then(() => {\n\t\t\tvar e = new Error(\"Cannot find module '\" + req + \"'\");\n\t\t\te.code = 'MODULE_NOT_FOUND';\n\t\t\tthrow e;\n\t\t});\n\t}\n\n\tvar ids = map[req], id = ids[0];\n\treturn Promise.all(ids.slice(1).map(__webpack_require__.e)).then(() => {\n\t\treturn __webpack_require__(id);\n\t});\n}\nwebpackAsyncContext.keys = () => (Object.keys(map));\nwebpackAsyncContext.id = 84752;\nmodule.exports = webpackAsyncContext;","import React, { useContext } from 'react'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\n\nconst CalendarCongratulationsComponent = () => {\n const { getTranslation } = useContext(TranslationContext)\n\n return (\n
\n
\n

\n {getTranslation(translationGroups.calendarPage, 'congratulations-title')}\n

\n
\n {getTranslation(translationGroups.calendarPage, 'congratulations-text')}\n
\n
\n
\n
\n
\n )\n}\n\nexport default CalendarCongratulationsComponent\n","import React, { useContext } from 'react'\nimport { PuzzleType } from 'client/types/PuzzleType'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport RecentPuzzlesBackgroundComponent from 'client/pages/common/components/RecentPuzzlesBackgroundComponent'\nimport GameCardRowComponent from '../../common/components/game_cards/GameCardRowComponent'\n\ninterface Props {\n puzzleTypes: PuzzleType[],\n}\nconst CalendarSuggestionsComponent = ({ puzzleTypes }: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n\n /* Puzzle types should have a suggestion property */\n const filterSuggestions = (puzzle) => puzzle\n\n return (\n
\n \n
\n \n
\n
\n )\n}\n\nexport default CalendarSuggestionsComponent\n","import React, { useContext, useMemo } from 'react'\nimport { useHistory } from 'react-router'\nimport IconInfo from 'assets/icons/icon_info.svg'\nimport IconChevronBack from 'assets/icons/icon_chevron_back.svg'\nimport IconChevronDown from 'assets/icons/icon_chevron_down.svg'\nimport HeartToggleContainer from 'pages/common/containers/HeartToggleContainer'\nimport { type PuzzleType } from 'client/types/PuzzleType'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport usePuzzleSelectedLevel from 'client/hooks/usePuzzleSelectedLevel'\nimport formatLabel from 'client/utilities/formatLabel'\nimport { PageHeaderBackgroundMobileComponent } from 'client/pages/common/components/page_header/PageHeaderBackgroundMobileComponent'\nimport { PageHeaderBackgroundDesktopComponent } from 'client/pages/common/components/page_header/PageHeaderBackgroundDesktopComponent'\n\ntype Props = {\n puzzleType: PuzzleType,\n setDrawer: (puzzleTypeId: number) => void,\n showInstructions: () => void,\n}\n\nconst CalendarHeaderComponent = ({\n puzzleType,\n setDrawer,\n showInstructions,\n}: Props) => {\n const translation = useContext(TranslationContext)\n const history = useHistory<{ from: string }>()\n const {\n puzzleTypeId,\n nameLangKey,\n // tags = [],\n format,\n } = puzzleType\n const selectedLevel = usePuzzleSelectedLevel(puzzleTypeId)\n\n /*\n * Go back to a path defined in history.location.state\n * It get its value by adding a pathname as second argument of history.push('location', 'state pathname')\n */\n const goBack = () => {\n const { from } = (history?.location?.state) || {}\n if (from === 'puzzles') {\n history.push('/puzzles')\n return\n }\n history.push('/')\n }\n\n const title = useMemo(() => {\n const text = translation.getRawTranslation(translationGroups.puzzle, nameLangKey)\n return formatLabel(text, '®', 'calendar-header__title--superscript')\n }, [nameLangKey, translation])\n\n const subtitle = useMemo(() => {\n return [\n translation.getTranslation(translationGroups.puzzleTags, format),\n // to be decided if we want to show tags here!!\n // ...tags.map((tag) => translation.getTranslation(translationGroups.puzzleTags, tag)),\n ].join(' • ')\n }, [format, translation])\n\n const { isFavorite } = puzzleType\n\n return (\n
\n
\n \n \n
\n
\n
\n \n \n
\n {translation.getTranslation(translationGroups.calendarPage, isFavorite ? 'favorite-active' : 'favorite')}\n
\n \n \n
\n

\n {title}\n

\n

\n {subtitle}\n

\n \n
\n
\n )\n}\n\nexport default CalendarHeaderComponent\n","import { connect } from 'react-redux'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport CalendarHeaderComponent from '../components/CalendarHeaderComponent'\n\nconst mapDispatchToProps = (dispatch: any) => ({\n setDrawer: (puzzleTypeId: number) => {\n dispatch(uiActions.setDrawer({\n drawer: drawerTypes.PUZZLE_CALENDAR_LEVEL,\n drawerData: { puzzleTypeId },\n forceModal: true,\n }))\n },\n showInstructions: () => {\n dispatch(uiActions.setDrawer({ drawer: drawerTypes.GAME_INSTRUCTIONS }))\n },\n})\n\nexport default connect(null, mapDispatchToProps)(CalendarHeaderComponent)\n","import React, { useContext, useEffect, useMemo } from 'react'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { useDateFormatters } from 'client/hooks/useDateFormatters'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { useHistory } from 'react-router'\nimport { useDispatch } from 'react-redux'\nimport useConfig from 'client/hooks/useConfig'\nimport { showSubscribeDrawer } from 'client/actions/uiActions'\nimport { getPlayerPageQueryString } from 'client/utilities/player'\nimport { CalendarDay } from 'client/interfaces/IPuzzleCalendar'\nimport { PuzzleType } from 'client/types/PuzzleType'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport IconEye from 'assets/icons/icon_eye.svg'\nimport IconPlay from 'assets/icons/icon_play.svg'\nimport IconPause from 'assets/icons/icon_pause.svg'\nimport IconLock from 'assets/icons/icon_lock.svg'\nimport { isMobile } from 'common_packages/assets/js/utilities/devices'\n\ntype Props = {\n puzzleType: PuzzleType\n day: CalendarDay\n isActive?: boolean\n}\n\ntype Status = 'start' | 'paused' | 'finished' | 'locked'\n\nconst CalendarDayComponent = ({\n puzzleType, day, isActive,\n}: Props) => {\n const history = useHistory()\n const dispatch = useDispatch()\n const config = useConfig()\n const { formatDate } = useDateFormatters()\n const { getTranslation } = useContext(TranslationContext)\n const { hasSubscription } = useAbilities()\n const { nameLangKey: gameType, puzzleTypeId } = puzzleType ?? {}\n const {\n externalPuzzleId, klubblePuzzleId, isPlayed, playAllowed, isStarted,\n } = day as CalendarDay\n\n useEffect(\n // if the user lands directly on /calendar/{puzzleTypeId} and doesn't have a subscription, navigate to home and show the subscribe drawer\n () => {\n if (!hasSubscription) {\n dispatch(showSubscribeDrawer())\n history.push('/')\n }\n },\n [hasSubscription, history, dispatch],\n )\n\n const handleClickCard = () => {\n if (!isPlayed && !playAllowed) {\n dispatch(uiActions.setDrawer({\n drawer: drawerTypes.UPGRADE_SUBSCRIPTION,\n forceModal: true,\n modalAutoGrow: true,\n hideHeader: true,\n }))\n } else {\n const queryString = getPlayerPageQueryString(gameType, externalPuzzleId, config.entity?.puzzlesClientId, klubblePuzzleId, puzzleTypeId)\n history.push(`/player${queryString}`)\n }\n }\n\n const status = useMemo(() => {\n if (isPlayed) {\n return 'finished'\n }\n if (isStarted) {\n return 'paused'\n }\n if (!playAllowed) {\n return 'locked'\n }\n return 'start'\n }, [isPlayed, isStarted, playAllowed])\n\n const activeTitle = useMemo(() => {\n if (day.dayDelta === 0) {\n return getTranslation(translationGroups.calendarPage, 'today')\n }\n return formatDate(new Date(day.dayDate), { day: 'numeric', month: 'long' })\n }, [day, getTranslation, formatDate])\n\n const icons:{ [key in Status]: JSX.Element } = {\n start: ,\n paused: ,\n finished: ,\n locked: ,\n }\n\n const buttonLabelKeys: { [key in Status]: string } = {\n start: 'start',\n paused: 'continue',\n finished: 'view',\n locked: 'upgrade',\n }\n\n const bodyText = isActive ? activeTitle : String(day.dayNum)\n const headerText = day.dayDate ? formatDate(new Date(day.dayDate), isActive && day.dayDelta === 0 ? { day: 'numeric', month: 'long' } : { month: isMobile ? 'short' : 'long' }) : ''\n\n const cardClassName = [\n 'calendar-day',\n ...(isActive ? ['calendar-day--active'] : []),\n ...(status ? [`calendar-day--${status}`] : []),\n ].join(' ')\n\n return (\n
\n
{headerText}
\n
\n {bodyText}\n \n
\n
\n )\n}\n\nexport default CalendarDayComponent\n","import React, {\n useContext,\n useEffect, useMemo, useState,\n} from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { useHistory, useParams } from 'react-router'\nimport useAbilities from 'client/hooks/useAbilities'\nimport usePuzzleType from 'client/hooks/usePuzzleType'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport CalendarCongratulationsComponent from 'pages/calendar/components/CalendarCongratulationsComponent'\nimport Breadcrumbs from 'client/pages/common/components/breadcrumbs/BreadcrumbsComponent'\nimport usePuzzleSelectedLevel from 'client/hooks/usePuzzleSelectedLevel'\nimport { setUser } from 'client/actions/userActions'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { games } from 'common_packages/assets/js/types/gameDataTypes'\nimport { CalendarDay } from 'client/interfaces/IPuzzleCalendar'\nimport { getPuzzleCalendar } from 'client/actions/puzzleDataActions'\nimport { StoreState } from 'client/store'\nimport { PuzzleDataState } from 'client/reducers/puzzleDataReducer'\nimport useConfig from 'client/hooks/useConfig'\nimport breakpoints from 'common_packages/assets/js/constants/breakpoints'\nimport useWindowDimensions from 'common_packages/assets/js/hooks/useWindowDimensions'\nimport CalendarSuggestionsComponent from './CalendarSuggestionsComponent'\nimport PuzzleCalendarHeaderContainer from '../containers/CalendarHeaderContainer'\nimport CalendarDayComponent from './CalendarDayComponent'\n\nexport const WEEKLY_PUZZLE_DAYS = 4\nexport const DAILY_PUZZLE_DAYS = 31\nconst COLUMNS_SM = 4\nconst COLUMNS_MD = 6\nconst COLUMNS_LG = 8\n\nconst CalendarComponent = () => {\n const { puzzleTypes, currentPuzzleCalendar } = useSelector((state) => state.puzzleData)\n const config = useConfig()\n const [activeDayIndex, setActiveDayIndex] = useState(0)\n const [anyPuzzlesLeftToPlay, setAnyPuzzlesLeftToPlay] = useState(true)\n const params = useParams<{id: string}>()\n const puzzleTypeId = parseInt(params.id, 10)\n const dispatch = useDispatch()\n const history = useHistory()\n const { getTranslation } = useContext(TranslationContext)\n const currentPuzzleType = usePuzzleType(puzzleTypeId)\n const tryNowUrl = currentPuzzleType?.tryNowUrl\n const isPremiumOnlyPuzzle = currentPuzzleType?.isPremiumOnly ?? false\n const { width } = useWindowDimensions()\n\n // This exception is hardcoded, which is not ideal, but since it's not sure if will continue to have this puzzleType as a daily puzzle it would be too much work to set up a proper (database/backend) solution\n const isWeekPuzzle = currentPuzzleType?.puzzleType === games.ARROWWORD_PLUS && config.entity.name === 'klubble_nl'\n const [isLoading, setIsLoading] = useState(true)\n\n const suggestedPuzzleTypes = useMemo(() => {\n if (currentPuzzleType?.puzzleTypeTryAlsos) {\n const suggestions = currentPuzzleType.puzzleTypeTryAlsos.map((pTypeTryAlso) => puzzleTypes.find((pType) => pType.puzzleTypeId === pTypeTryAlso.puzzleTypeId))\n if (suggestions.length > 0) {\n return suggestions\n }\n }\n return puzzleTypes\n }, [currentPuzzleType, puzzleTypes])\n\n const puzzleType = usePuzzleType(puzzleTypeId)\n const selectedLevel = usePuzzleSelectedLevel(puzzleTypeId)\n\n useEffect(() => {\n const loadCalendar = async () => {\n setIsLoading(true)\n await getPuzzleCalendar(puzzleTypeId)(dispatch)\n setIsLoading(false)\n }\n\n loadCalendar()\n }, [puzzleTypeId, selectedLevel, dispatch])\n\n useEffect(() => {\n // Fetch user data to check for changed settings\n dispatch(setUser())\n }, [dispatch])\n\n // If light user and puzzle is premium only, dont allow playing\n const { canPlayPremiumOnlyPuzzles } = useAbilities()\n useEffect(() => {\n if (isPremiumOnlyPuzzle && !canPlayPremiumOnlyPuzzles) {\n const backToHome = () => {\n history.push('/')\n }\n dispatch(uiActions.setDrawer({\n drawer: drawerTypes.UPGRADE_SUBSCRIPTION_PREMIUM_ONLY,\n drawerData: { tryNowUrl },\n onClose: backToHome,\n forceModal: true,\n modalAutoGrow: true,\n hideHeader: true,\n }))\n }\n }, [canPlayPremiumOnlyPuzzles, dispatch, history, isPremiumOnlyPuzzle, tryNowUrl])\n\n const emptyCalendar: CalendarDay[] = new Array(isWeekPuzzle ? WEEKLY_PUZZLE_DAYS : DAILY_PUZZLE_DAYS).fill({\n hasPuzzle: true, dayDate: null, dayNum: 'null', dayDelta: null, isPlayed: null, isStarted: null, klubblePuzzleId: null, externalPuzzleId: null, nextAchievement: null, level: null, playAllowed: null,\n }).map((day, index) => ({ ...day, dayDelta: index * -1 }))\n const levelCalendar: CalendarDay[] = useMemo(() => currentPuzzleCalendar.daysPerLevel?.[selectedLevel], [currentPuzzleCalendar.daysPerLevel, selectedLevel])\n const calendarDays = isLoading || !levelCalendar?.length ? emptyCalendar : levelCalendar\n\n useEffect(() => {\n if (!isLoading) {\n const firstNonPlayedDay = levelCalendar?.findIndex((puzzle) => !puzzle.isPlayed && puzzle.hasPuzzle)\n\n if (firstNonPlayedDay > -1) {\n setActiveDayIndex(firstNonPlayedDay)\n setAnyPuzzlesLeftToPlay(true)\n } else {\n setActiveDayIndex(levelCalendar?.findIndex((puzzle) => puzzle.hasPuzzle))\n setAnyPuzzlesLeftToPlay(false)\n }\n }\n }, [levelCalendar, puzzleTypeId, isLoading])\n\n // Calculate the number of columns for the calendar grid, based on the active day index.\n // If the activeDay is the last item on a row for a given breakpoint, then the large item will not fit, and jumps to the next row.\n // To prevent this from happening, we increase the number of columns so that there will not be a gap at the end of the row.\n const gridColumns = useMemo(() => {\n const activeDayNumber = activeDayIndex + 1\n if (width >= breakpoints.LARGE) {\n return activeDayNumber % COLUMNS_LG ? COLUMNS_LG : COLUMNS_LG + 1\n }\n if (width >= breakpoints.MEDIUM) {\n return activeDayNumber % COLUMNS_MD ? COLUMNS_MD : COLUMNS_MD + 1\n }\n // On mobile, we have 4 columns. If the active day is the 12th or 24th day, we need to go to 5 columns to prevent a gap.\n // In case of 4th, 8th, 16th, 20th, 28th we use 3 columns. All other days 4 columns.\n const offSet = activeDayNumber === 12 || activeDayNumber === 24 ? 1 : -1\n return activeDayNumber % COLUMNS_SM ? COLUMNS_SM : COLUMNS_SM + offSet\n }, [activeDayIndex, width])\n\n if (!currentPuzzleType) {\n return null\n }\n\n return (\n <>\n \n \n
\n

{getTranslation(translationGroups.calendarPage, `header-title${isWeekPuzzle ? '-week-puzzle' : ''}`)}

\n {anyPuzzlesLeftToPlay ? (\n getTranslation(translationGroups.calendarPage, `header-sub-title${isWeekPuzzle ? '-week-puzzle' : ''}`)\n ) : (\n \n )}\n
\n {calendarDays\n .filter((day) => day.hasPuzzle)\n .slice(0, DAILY_PUZZLE_DAYS)\n .map((day) => )}\n
\n
\n \n \n )\n}\n\nexport default CalendarComponent\n","import React, { useContext } from 'react'\nimport { Helmet, type HelmetProps } from 'react-helmet'\nimport useConfig from 'client/hooks/useConfig'\nimport { ThemeContext } from './components/theme/ThemeContext'\n\ntype Props = {\n description?: string\n meta?: HelmetProps['meta']\n title: string\n}\n\nconst SEO = ({\n description = '',\n meta = [],\n title,\n}: Props) => {\n const { theme } = useContext(ThemeContext)\n const { entity } = useConfig()\n\n if (!theme) {\n return null\n }\n\n const { entityBrandName } = theme\n const pageTitle = title == null || title === entityBrandName ? entityBrandName : `${entityBrandName} - ${title}`\n const pageDescription = description || title\n\n return (\n \n )\n}\n\nexport default SEO\n","import React, { useContext } from 'react'\nimport { useTransform, useViewportScroll, motion } from 'framer-motion'\nimport { isMobile } from 'react-device-detect'\nimport { ThemeContext } from './theme/ThemeContext'\n\ntype Props = {\n size?: number,\n borderOnly?: boolean,\n color?: string,\n opacity?: number,\n top?: number,\n left?: number,\n border?: number,\n borderRadius?: number,\n gravity?: number,\n rotateFrom?: number,\n rotateTo?: number\n}\n\nconst AnimatedBackgroundSquircle = ({\n size = 300,\n borderOnly,\n color = null,\n opacity = 1,\n top = 0,\n left = 0,\n border = 4,\n borderRadius = 10,\n gravity = 1,\n rotateFrom = 45,\n rotateTo = 45,\n}: Props) => {\n const { scrollYProgress } = useViewportScroll()\n const rotate = useTransform(scrollYProgress, [0, 1], [`${rotateFrom}deg`, `${rotateTo}deg`])\n const y = useTransform(scrollYProgress, [0, 1], [`${200 * gravity + top}px`, `${-200 * gravity + top}px`])\n const scale = useTransform(scrollYProgress, [0.5, 0.7], [1 - (gravity * 0.2), 1])\n const { theme } = useContext(ThemeContext)\n\n return (\n \n )\n}\n\nexport default AnimatedBackgroundSquircle\n","import React from 'react'\n\ntype Props = {\n src?: string\n username?: string\n className?: string\n}\n\nconst AvatarComponent = ({ src, username, className }:Props) => {\n return (\n
\n {src.length\n ? (\"\")\n : (\n
\n {Array.from(username ?? '')[0]?.toUpperCase()}\n
\n )}\n
\n )\n}\n\nAvatarComponent.defaultProps = {\n src: '',\n username: '',\n className: '',\n}\nexport default AvatarComponent\n","import React, { useContext } from 'react'\nimport { ThemeContext } from './theme/ThemeContext'\n\ntype Props = {\n className?: string\n}\n\nconst BrandIconComponent = ({ className }: Props) => {\n const { theme } = useContext(ThemeContext)\n if (!theme) {\n return null\n }\n return (\n
\n \"icon\"\n
\n )\n}\n\nexport default BrandIconComponent\n","import React, { useContext } from 'react'\nimport IconThumbsDown from '../../../assets/icons/icon_thumbs_down.svg'\nimport IconThumbsUp from '../../../assets/icons/icon_thumbs_up.svg'\nimport CardComponent from './cards/CardComponent'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\n\nconst FeedbackCardComponent = () => {\n const translation = useContext(TranslationContext)\n\n return (\n \n

\n {translation.getTranslation(translationGroups.endscreenPage, 'feedback-title')}\n

\n
\n {translation.getTranslation(translationGroups.endscreenPage, 'feedback-subtitle')}\n
\n\n
\n \n \n
\n\n
\n )\n}\n\nexport default FeedbackCardComponent\n","import React, { PropsWithChildren } from 'react'\nimport { Link } from 'react-router-dom'\n\ninterface Props {\n icon?: string\n link?: string\n\n onClick?: () => void;\n}\n\nconst NavigationMenuItemComponent = (props: PropsWithChildren): JSX.Element => {\n const { link, onClick, children } = props\n\n return (\n
  • \n { link ? {children} : {children} }\n
  • \n )\n}\n\nexport default NavigationMenuItemComponent\n","import React, { ComponentProps } from 'react'\n\nconst NavigationMenuComponent = (props: ComponentProps<'ul'>) => {\n const { children, ...otherProps } = props\n\n return (\n
      \n {children}\n
    \n )\n}\n\nexport default NavigationMenuComponent\n","import React, { ComponentProps, useContext, useState } from 'react'\nimport { Link } from 'react-router-dom'\nimport { useHistory } from 'react-router'\nimport IconLogoutComponent from 'assets/icons/account/logout.svg'\nimport { accountPages } from 'client/pages/account/pages'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport * as auth from '../../../../api/authentication'\nimport NavigationMenuItemComponent from './NavigationMenuItemComponent'\nimport NavigationMenuComponent from './NavigationMenuComponent'\n\ninterface Props extends ComponentProps<'li'> {\n to?: string\n}\n\nconst AccountMenuComponent = (props: Props) => {\n const { children, to, ...otherProps } = props\n const [open, setOpen] = useState(false)\n const { getTranslation } = useContext(TranslationContext)\n\n const { push } = useHistory()\n\n const doLogout = (): void => {\n auth.logout()\n // when SSO is enabled the SSO provider handles this redirect\n if (process.env.KLUBBLE_LOGIN_SSO_ENABLED !== 'true') {\n push('/login')\n }\n }\n\n return (\n setOpen(true)}\n onTouchStart={() => setOpen(true)}\n onMouseLeave={() => setOpen(false)}\n >\n { to ? {children} : (\n
    \n {children}\n
    \n )}\n {open && (\n setOpen(false)}>\n {accountPages.map((page) => (\n \n \n {getTranslation(translationGroups.navigation, page.key)}\n \n ))}\n \n \n
    {getTranslation(translationGroups.navigation, 'logout')}
    \n
    \n
    \n )}\n \n )\n}\n\nexport default AccountMenuComponent\n","import React, { useContext } from 'react'\nimport { Link } from 'react-router-dom'\nimport useAbilities from 'client/hooks/useAbilities'\nimport useConfig from 'client/hooks/useConfig'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport useWindowPosition from 'client/hooks/useWindowPosition'\nimport LogoComponent from './LogoComponent'\nimport AccountMenuComponent from './navigation/AccountMenuComponent'\nimport NotificationsBellComponent from './NotificationsBellComponent'\n\ntype Props = {\n showMenu?: boolean\n}\n\ntype NavigationLink = '/puzzles' | '/daily_dose' | '/account' | '/puzzle-packs'\ntype NavigationItem = {\n text: string\n link: NavigationLink\n testId: string\n cmp?: React.FC<{ to: string, className: string }>\n}\n\nconst HeaderComponent = ({ showMenu = true }: Props) => {\n const scrollPosition = useWindowPosition()\n const { getTranslation } = useContext(TranslationContext)\n const { entity } = useConfig()\n const { canSeeMenu, isAnonymous } = useAbilities()\n\n const navigation: NavigationItem[] = [\n {\n text: getTranslation(translationGroups.navigation, 'puzzles'),\n link: '/puzzles',\n testId: 'puzzles',\n },\n {\n text: getTranslation(translationGroups.navigation, 'puzzle-packs'),\n link: '/puzzle-packs',\n testId: 'puzzle-packs',\n },\n {\n text: getTranslation(translationGroups.navigation, 'daily-dose'),\n link: '/daily_dose',\n testId: 'daily-dose',\n },\n {\n text: getTranslation(translationGroups.navigation, 'account'),\n link: '/account',\n testId: 'account',\n cmp: AccountMenuComponent,\n },\n ]\n\n const getClassName = (item: NavigationLink) => {\n if (\n window.location.pathname.includes(item)\n || (window.location.pathname.includes('/calendar') && item === '/puzzles')\n || (window.location.pathname.includes('/stats') && item === '/daily_dose')\n ) {\n return 'header__navigation-item header__navigation-item--active'\n }\n return 'header__navigation-item'\n }\n\n return (\n
    0 ? ' header--with-shadow' : ''}`}>\n
    \n \n {canSeeMenu && showMenu && (\n \n )}\n
    \n
    \n )\n}\n\nexport default HeaderComponent\n","import React, { PropsWithChildren } from 'react'\nimport { Link, useHistory, useLocation } from 'react-router-dom'\nimport IconChevronBack from 'assets/icons/icon_chevron_back.svg'\nimport IconAccount from 'assets/icons/icon_account.svg'\nimport useAbilities from 'client/hooks/useAbilities'\nimport BrandIconcomponent from './BrandIconComponent'\n\ntype Props = {\n title?: string\n showBackButton?: boolean\n showAccountButton?: boolean\n}\n\nconst HeaderTitleBarComponent = ({\n title = '',\n children,\n showBackButton = false,\n showAccountButton = false,\n}: PropsWithChildren) => {\n const history = useHistory()\n const { pathname } = useLocation()\n const { canSeeAccount } = useAbilities()\n\n const onClickBackHandler = () => {\n const pathParts = pathname?.split('/')\n pathParts.pop()\n history.push(pathParts.join('/'))\n }\n\n return (\n
    \n
    \n {showBackButton ? (\n \n ) : (\n \n {\n pathname === '/'\n ? ()\n : ()\n }\n \n )}\n
    \n

    {title}

    \n
    \n {children}\n {showAccountButton && canSeeAccount && (\n \n \n \n )}\n
    \n
    \n )\n}\n\nexport default HeaderTitleBarComponent\n","import React, { useContext } from 'react'\nimport { useLocation } from 'react-router'\nimport { useHistory } from 'react-router-dom'\nimport IconHomeComponent from 'assets/icons/icon_home.svg'\nimport IconPuzzleComponent from 'assets/icons/icon_puzzle.svg'\nimport IconDailyDoseComponent from 'assets/icons/icon_daily_dose.svg'\nimport IconPuzzlePacksComponent from 'assets/icons/icon_puzzle_packs.svg'\nimport { isIOS } from 'react-device-detect'\nimport useAbilities from 'client/hooks/useAbilities'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\n\ninterface Props {\n showNav: boolean\n}\n\nconst NavigationMobileComponent = ({ showNav }: Props): JSX.Element => {\n const translation = useContext(TranslationContext)\n const history = useHistory()\n const location = useLocation()\n const navigationBaseClassName = 'navigation-mobile'\n let navigationClassName = navigationBaseClassName\n const { canSeeMenu } = useAbilities()\n\n /* assuming iOS devices with a height larger than 750px do NOT have a physical home button and therefore show the home-bar we add the home-bar modifier */\n navigationClassName += isIOS && window.screen.height >= 750 ? ` ${navigationBaseClassName}--home-bar` : ''\n\n const items: Array<{ key: 'home' | 'puzzles' | 'daily-dose' | 'account' | 'puzzle-packs', icon: React.ElementType, title: string, pathname: string, active?: boolean }> = [\n {\n key: 'home',\n icon: IconHomeComponent,\n pathname: '/',\n title: translation.getTranslation(translationGroups.navigation, 'klubble'),\n },\n {\n key: 'puzzles',\n icon: IconPuzzleComponent,\n pathname: '/puzzles',\n title: translation.getTranslation(translationGroups.navigation, 'daily-puzzles'),\n },\n {\n key: 'puzzle-packs',\n icon: IconPuzzlePacksComponent,\n pathname: '/puzzle-packs',\n title: translation.getTranslation(translationGroups.navigation, 'puzzle-packs'),\n },\n {\n key: 'daily-dose',\n icon: IconDailyDoseComponent,\n pathname: '/daily_dose',\n title: translation.getTranslation(translationGroups.navigation, 'daily-dose'),\n },\n ]\n\n const renderItems = () => items.map((item) => {\n let classNameIcon = 'navigation-mobile__item-icon'\n let classNameTitle = 'navigation-mobile__item-title'\n if (\n (item.key === 'home' && location.pathname === '/') // home mapping\n || (item.key !== 'home' && location.pathname.includes(item.pathname)) // 1:1 mapping from location.pathname to item.pathname\n || (item.key === 'daily-dose' && location.pathname.includes('/stats')) // additional mapping for daily-dose\n || (item.key === 'puzzles' && location.pathname.includes('/calendar')) // additional mapping for puzzles\n ) {\n classNameIcon += ` ${classNameIcon}--active`\n classNameTitle += ` ${classNameTitle}--active`\n }\n\n const handleClick = (evt: React.MouseEvent) => {\n // prevent navigation to the current page, to keep the current page state including url search params, but do scroll to top\n if (item.pathname === window.location.pathname) {\n evt.preventDefault()\n window.scrollTo(0, 0)\n } else {\n history.push(item.pathname)\n }\n }\n\n return (\n \n \n \n {item.title}\n \n
    \n )\n })\n\n return (showNav && canSeeMenu) ? (\n
    \n {renderItems()}\n
    \n ) : null\n}\n\nexport default NavigationMobileComponent\n","import { connect } from 'react-redux'\nimport NavigationMobileComponent from '../components/NavigationMobileComponent'\n\nconst mapStateToProps = (state: any) => ({\n showNav: state.ui.showNav,\n})\n\nexport default connect(mapStateToProps, null)(NavigationMobileComponent)\n","import React, { useContext } from 'react'\nimport { Link } from 'react-router-dom'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport useAbilities from 'client/hooks/useAbilities'\nimport LogoComponent from './LogoComponent'\nimport LogoSubTitleComponent from './LogoSubTitleComponent'\n\n// visible in desktop only\nconst FooterComponent = (): JSX.Element => {\n const year = new Date().getFullYear()\n const { canSeePrivateFooterLinks } = useAbilities()\n const { getTranslation } = useContext(TranslationContext)\n\n return (\n \n )\n}\n\nexport default FooterComponent\n","import React, { type PropsWithChildren } from 'react'\nimport { useSelector } from 'react-redux'\nimport { isMobile } from 'common_packages/assets/js/utilities/devices'\nimport { type StoreState } from 'klubble/app/client/store'\nimport { type UIState } from 'common_packages/assets/js/reducers/uiReducer'\nimport NavigationMobileContainer from '../containers/NavigationMobileContainer'\nimport HeaderComponent from './HeaderComponent'\nimport FooterComponent from './FooterComponent'\n\ntype Props = PropsWithChildren<{\n page: string,\n hideMobileNavigation?: boolean\n hideDesktopNavigation?: boolean\n hideFooter?: boolean\n}>\n\nconst LayoutComponent = (props: Props) => {\n const { hideFooter } = props\n const { showNav, showEndscreen } = useSelector((state) => state.ui)\n const contentClass = [\n 'layout-content',\n ...(hideFooter ? [] : ['layout-content--with-footer']),\n ...(isMobile ? ['layout-content--is-mobile'] : []),\n ...(showEndscreen ? ['layout-content--show-endscreen'] : []),\n ].join(' ')\n\n return (\n
    \n {(!props.hideDesktopNavigation || (showNav && showEndscreen)) && }\n
    \n {props.children}\n
    \n {!props.hideMobileNavigation && }\n {!props.hideFooter && }\n
    \n )\n}\nexport default LayoutComponent\n","import React, { useContext } from 'react'\nimport { Link } from 'react-router-dom'\nimport { ThemeContext } from './theme/ThemeContext'\n\ntype Props = {\n className: string\n navigateTo: string\n darkBg?: boolean\n}\n\nconst LogoComponent = ({ className, navigateTo, darkBg = false }: Props) => {\n const { theme } = useContext(ThemeContext)\n if (!theme) {\n return null\n }\n const url = darkBg ? theme.logoInvertedPath : theme.logoPath\n\n if (navigateTo.startsWith('http')) {\n return (\n \n \"logo\"\n \n )\n }\n return (\n \n \"logo\"\n \n )\n}\n\nexport default LogoComponent\n","import React, { useContext } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { ThemeContext } from 'client/pages/common/components/theme/ThemeContext'\n\ntype Props = {\n className: string\n}\n\nconst LogoSubTitleComponent = ({ className }: Props) => {\n const { theme } = useContext(ThemeContext)\n const { getRawTranslation } = useContext(TranslationContext)\n\n if (!theme.showLogoSubTitle) {\n return null\n }\n\n return (\n
    \n {getRawTranslation(translationGroups.common, 'tagline')}\n
    \n )\n}\n\nexport default LogoSubTitleComponent\n","import React, { useEffect, useMemo } from 'react'\nimport {\n useDispatch, useSelector,\n} from 'react-redux'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { NotificationsState } from 'client/reducers/notificationsReducer'\nimport { StoreState } from 'client/store'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport IconBell from 'assets/icons/icon_bell.svg'\nimport { UIState } from 'common_packages/assets/js/reducers/uiReducer'\n\nconst NotificationsBellComponent = () => {\n const dispatch = useDispatch()\n const notifications = useSelector((state) => state.notifications)\n const drawer = useSelector((state) => state.ui)\n\n // for now a const, this should come from the backend after MVP\n const unreadMessagesCount = useMemo(() => {\n if (process.env.SHOW_NOTIFICATIONS !== 'true') {\n return 0\n }\n return parseInt(localStorage.getItem('notificationCount') ?? '1', 10) // remove once notifications are properly implemented\n // return notifications.length // .filter((n) => !!n.unread) //enable once notifications are properly implemented\n }, [drawer]) // needs to refresh after drawer is opened remove once notifications are properly implemented\n\n const handleOpenNotifications = () => {\n dispatch(uiActions.setDrawer({ drawer: drawerTypes.ADD_TO_HOMESCREEN_INFO, size: 'large', hideHeader: true }))\n\n // dispatch(uiActions.setDrawer({ drawer: drawerTypes.NOTIFICATIONS })) //enable once notifications are properly implemented\n }\n\n useEffect(() => {\n // PWA app badge\n navigator.setAppBadge?.(unreadMessagesCount).catch(() => {\n // not supported\n })\n }, [unreadMessagesCount])\n\n return (\n \n )\n}\n\nexport default NotificationsBellComponent\n","import React, { useContext, useEffect, useRef } from 'react'\nimport {\n Route, RouteProps, useHistory, useLocation,\n} from 'react-router-dom'\nimport SEO from 'pages/common/SeoComponent'\nimport { Helmet } from 'react-helmet'\nimport { isIOS } from 'react-device-detect'\nimport { ThemeColor } from 'client/types/Theme'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { useSelector } from 'react-redux'\nimport { type StoreState } from 'client/store'\nimport { type UserData } from 'client/reducers/userReducer'\nimport { getParamsFromQueryString } from 'client/utilities/getParamsFromQueryString'\nimport { setItemSafely } from 'common_packages/assets/js/utilities/persistencyStorage'\nimport { useLogin } from 'client/hooks/useLogin'\nimport { ThemeContext } from './theme/ThemeContext'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\nimport { replaceAll } from '../../../utilities/replaceAll'\n\ntype Props = RouteProps & {\n skipSEO?: boolean // set this on pages where the backend sets the and other SEO attributes in <head>\n themeColor?: ThemeColor // optional theme color override used on iOS for coloring the top bar, defaults to white for public routes\n}\n\ntype LocationState = {\n puzzlePackId?: number\n afterRegistrationPath?: string\n}\n\nconst PublicRouteComponent = ({\n children, skipSEO, themeColor, ...routeProps\n}: Props) => {\n const translation = useContext(TranslationContext)\n\n const { theme } = useContext(ThemeContext)\n\n const history = useHistory()\n const abilities = useAbilities()\n const login = useLogin()\n const loginCalled = useRef(false)\n const location = useLocation() as { state: LocationState, pathname: string }\n const { puzzlePackId, afterRegistrationPath } = location.state ?? {}\n const { paymentPeriodId, pack } = getParamsFromQueryString()\n const isAnonRegisterForPuzzlePack = pack?.toLowerCase() === 'true'\n const user = useSelector<StoreState, UserData>((state: StoreState) => state.user?.data)\n\n useEffect(() => {\n if (location.pathname === '/register' && !abilities.isAnonymous) {\n if (user === null) {\n // Not logged in as an anon user, attempt to do so now\n if (loginCalled.current === false) {\n loginCalled.current = true\n login()\n }\n } else if (afterRegistrationPath) {\n history.replace({\n pathname: afterRegistrationPath,\n state: { puzzlePackId },\n })\n } else {\n // Already registered, there is no reason to be here\n history.replace('/')\n }\n }\n }, [abilities.isAnonymous, puzzlePackId, paymentPeriodId, afterRegistrationPath, login, history, user, location.pathname])\n\n useEffect(() => {\n if (location.pathname === '/register') {\n // the external provider should handle the signup flow\n if (isAnonRegisterForPuzzlePack) {\n setItemSafely('puzzle-pack-id', puzzlePackId)\n window.location.replace(`${process.env.KLUBBLE_API_BASE_PATH}/account/signup?redirect_uri=${window.location.origin}${afterRegistrationPath}&redirect_after_login=true`)\n } else {\n window.location.replace(`${process.env.KLUBBLE_API_BASE_PATH}/account/signup`)\n }\n }\n }, [isAnonRegisterForPuzzlePack, puzzlePackId, afterRegistrationPath, location.pathname])\n\n if (isIOS) {\n document.querySelector('meta[name=theme-color]').setAttribute('content', themeColor ? theme.cssVariables[themeColor] : 'white')\n }\n\n function getTitle(path) {\n // Set the page title to the pathname\n if (path.includes('puzzle-packs')) {\n return translation.getTranslation(translationGroups.pageTitle, 'puzzle-packs')\n }\n return translation.getTranslation(translationGroups.pageTitle, replaceAll(path, '/', '-')?.substring(1))\n }\n\n if (skipSEO) {\n return (\n <Route {...routeProps}>\n <Helmet\n meta={[{\n property: 'robots',\n content: 'noindex',\n }]}\n />\n {children}\n </Route>\n )\n }\n\n return (\n <Route {...routeProps}>\n <SEO\n title={getTitle(location.pathname)}\n />\n {children}\n </Route>\n )\n}\n\nexport default PublicRouteComponent\n","import React, { useContext } from 'react'\nimport AnimatedBackgroundSquircle from 'client/pages/common/components/AnimatedBackgroundSquircle'\nimport { isMobile } from 'react-device-detect'\nimport { ThemeContext } from 'client/pages/common/components/theme/ThemeContext'\n\nconst RecentPuzzlesBackgroundComponent = () => {\n const { theme } = useContext(ThemeContext)\n\n return (\n <>\n {isMobile\n ? (\n <>\n <AnimatedBackgroundSquircle size={200} borderOnly border={5} borderRadius={5} top={-30} left={-50} color=\"var(--tertiary-color)\" gravity={0} />\n <AnimatedBackgroundSquircle size={40} top={-80} left={-20} color=\"var(--tertiary-color)\" gravity={0} borderRadius={20} />\n </>\n ) : (\n <AnimatedBackgroundSquircle size={300} borderOnly top={-60} left={900} color=\"var(--tertiary-color)\" gravity={0} borderRadius={8} border={10} />\n )}\n <div className=\"recently-played__bg-clipped\">\n <AnimatedBackgroundSquircle size={110} top={180} left={-100} opacity={0.65} color=\"#FFFFFF\" gravity={0.4} borderRadius={25} />\n\n <AnimatedBackgroundSquircle size={185} top={350} left={1055} borderOnly opacity={0.7} color=\"#FFFFFF\" gravity={0.1} borderRadius={10} border={6} />\n <AnimatedBackgroundSquircle size={175} top={540} left={1050} opacity={0.55} color=\"#FFFFFF\" gravity={0.3} borderRadius={15} />\n <svg xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <clipPath id=\"clip-path\" clipPathUnits=\"objectBoundingBox\">\n <path\n transform=\"scale(0.001078748651564, 0.001742160278746)\"\n d={theme.sectionDividerDefinition}\n />\n </clipPath>\n </defs>\n </svg>\n </div>\n </>\n )\n}\n\nexport default RecentPuzzlesBackgroundComponent\n","import React, { useContext } from 'react'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { ContinuePlayingPuzzleType } from 'client/types/ContinuePlayingPuzzleType'\nimport GameCardCalendarComponent from './game_cards/GameCardCalendarComponent'\nimport PuzzlePackCardContinueComponent from './puzzle_packs/PuzzlePackCardContinueComponent'\n\ntype Props = {\n puzzleTypes: ContinuePlayingPuzzleType[]\n fromLocation?: string\n stacked?: boolean\n size?: number\n}\n\nconst RecentPuzzlesComponent = ({\n puzzleTypes,\n fromLocation,\n size = 3,\n stacked,\n}: Props) => {\n const translation = useContext(TranslationContext)\n const abilities = useAbilities()\n\n if (!puzzleTypes?.length || !abilities.canSeeRecentPuzzles) {\n return null\n }\n\n return (\n <div className=\"recently-played\">\n <h2 className=\"section-header\">\n {translation.getTranslation(translationGroups.homePage, 'recently-played')}\n </h2>\n <p className=\"recently-played__intro\">{translation.getTranslation(translationGroups.homePage, 'recently-played-intro')}</p>\n <div className=\"recently-played__items\">\n {\n puzzleTypes.slice(0, size).map((cpPuzzle: ContinuePlayingPuzzleType) => {\n if (cpPuzzle.puzzlePackId) {\n return <PuzzlePackCardContinueComponent key={cpPuzzle.puzzlePackId} puzzlePackId={cpPuzzle.puzzlePackId} isStackedOnMobileView={!stacked} isStacked={stacked} />\n }\n return <GameCardCalendarComponent key={cpPuzzle.puzzleTypeId} puzzleTypeId={cpPuzzle.puzzleTypeId} recentDays={cpPuzzle.recentDays} fromLocation={fromLocation} stacked={stacked} isEntirelyClickable />\n })\n }\n </div>\n </div>\n )\n}\n\nexport default RecentPuzzlesComponent\n","import React, {\n useEffect, useContext, useState, useRef,\n} from 'react'\nimport { useHistory, useLocation, useParams } from 'react-router-dom'\nimport { useSelector, useDispatch } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport { UserData } from 'client/reducers/userReducer'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { getParamsFromQueryString } from 'client/utilities/getParamsFromQueryString'\nimport { ApiResult, klubbleAPI } from 'client/api/common'\nimport LandingRegularComponent from 'client/pages/landing/components/LandingRegularComponent'\nimport { closeDrawer, setDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { useLogin } from 'client/hooks/useLogin'\nimport useConfig from 'client/hooks/useConfig'\nimport SEO from '../SeoComponent'\n\ntype Props = {\n gameMode: 'JOIN_GAME' | 'JOIN_QR_GAME' | 'PLAY_GIFT_GAME' | 'PLAY_FREE_GAME' | 'PLAY_SHARE_RESULT_GAME'\n}\n\ntype JoinResponse = ApiResult<{\n externalPuzzleId: number,\n klubblePuzzleId: number,\n puzzleTypeNameKey: string,\n puzzleTypeId: string,\n isMultiPlayerQR: boolean,\n puzzlePackId: number,\n puzzlePackTypeId: number,\n puzzlePackTypeName: string,\n}>\n\nconst StartGameByGuidComponent = ({ gameMode }: Props) => {\n const [error, setError] = useState('')\n const history = useHistory()\n const dispatch = useDispatch()\n const { pathname } = useLocation()\n const translation = useContext(TranslationContext)\n const { getTranslation, translationsSet } = translation\n const userData = useSelector<StoreState, UserData>((state) => state.user?.data)\n const config = useConfig()\n const login = useLogin()\n const loginCalled = useRef(false)\n\n const abilities = useAbilities()\n const queryParams = useParams<{guid: string}>()\n\n const hasUserData = !!userData\n const firstName = userData?.firstName || userData?.userName\n\n useEffect(() => {\n const loginAnonymously = () => {\n login()\n }\n\n const enterGame = async () => {\n // For both gameModes 'PLAY_GIFT_GAME' and 'PLAY_FREE_GAME' we use the endpoint 'playgiftgame'\n const endPoint = (gameMode === 'JOIN_GAME' || gameMode === 'JOIN_QR_GAME') ? 'joinusinglink' : 'playgiftgame'\n\n try {\n const params = JSON.stringify({\n shareLinkShortUrl: queryParams.guid,\n shareLink: 'shareLink',\n })\n const { data: response } = await klubbleAPI.post<JoinResponse>(`Puzzle/${endPoint}`, params, {\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n\n if (!response.success) {\n if (response.message === 'too-many-players'\n || response.message === 'already-played-that-game'\n || response.message === 'already-playing-game-not-allowed-for-sharelink'\n || response.message === 'invite-no-longer-valid'\n || response.message === 'invite-not-found'\n || response.message === 'invite-no-longer-valid-game-completed') {\n const translationKey = response.data?.isMultiPlayerQR && response.message === 'too-many-players'\n ? `mpqr-${response.message}`\n : response.message\n dispatch(setDrawer({\n drawer: drawerTypes.GENERIC_ERROR,\n forceModal: true,\n drawerData: {\n content: getTranslation(translationGroups.startGame, translationKey),\n buttonText: getTranslation(translationGroups.startGame, 'ok-button'),\n },\n }))\n if (abilities.isAnonymous) {\n return history.replace('/landing')\n }\n return history.replace('/')\n }\n\n // in all other cases landing page will be displayed with error message\n setError('could-not-load-puzzle')\n } else {\n const {\n externalPuzzleId, klubblePuzzleId, puzzleTypeNameKey, puzzleTypeId, puzzlePackId, puzzlePackTypeName,\n } = response.data\n\n const isPuzzlePack = !!puzzlePackId\n\n const playerParams = {\n ...getParamsFromQueryString(),\n gametype: puzzleTypeNameKey,\n puzzleid: externalPuzzleId,\n customerid: isPuzzlePack ? 'klubblepacks' : config.entity?.puzzlesClientId,\n ...(isPuzzlePack && { portalid: config.entity?.puzzlesClientId }),\n klubblePuzzleId,\n puzzleTypeId,\n ...(puzzlePackId && { puzzlePackId }),\n ...(puzzlePackTypeName && { puzzlePackType: puzzlePackTypeName.toLowerCase() }),\n }\n\n if (gameMode === 'JOIN_GAME') {\n playerParams.multiplayer = true\n } else if (gameMode === 'JOIN_QR_GAME') {\n playerParams.mpqr = true\n } else if (gameMode === 'PLAY_GIFT_GAME') {\n playerParams.gift = true\n } else if (gameMode === 'PLAY_FREE_GAME') {\n playerParams.free = true\n } else if (gameMode === 'PLAY_SHARE_RESULT_GAME') {\n playerParams.gift = true\n playerParams.shareresult = true\n }\n history.replace(`/player?${new URLSearchParams(playerParams).toString()}`)\n }\n } catch (err) {\n setError('could-not-load-puzzle')\n }\n }\n\n if (!hasUserData) {\n if (loginCalled.current === false) {\n loginCalled.current = true\n loginAnonymously()\n }\n } else if (firstName || gameMode === 'PLAY_GIFT_GAME' || gameMode === 'PLAY_FREE_GAME' || gameMode === 'PLAY_SHARE_RESULT_GAME') {\n // firstName is set from the SET_FIRST_NAME drawer\n dispatch(closeDrawer())\n // Wait until we have translations, in case we have to show error\n if (translationsSet) { enterGame() }\n }\n }, [abilities.hasSubscription, abilities.isAnonymous, dispatch, login, gameMode, translation, getTranslation, translationsSet, history, queryParams.guid, hasUserData, firstName, config.entity?.puzzlesClientId])\n\n useEffect(() => {\n if (hasUserData) {\n if (!firstName && (gameMode === 'JOIN_GAME' || gameMode === 'JOIN_QR_GAME')) {\n // Joining as anonymous, please set your name before we can continue\n dispatch(setDrawer({\n drawer: drawerTypes.SET_FIRST_NAME,\n hideClose: true,\n hideHeader: true,\n }))\n }\n }\n }, [dispatch, gameMode, hasUserData, firstName])\n\n if (error) {\n return (\n <>\n <SEO\n title={getTranslation(translationGroups.pageTitle, 'landing-page')}\n />\n <LandingRegularComponent message={error} />\n </>\n )\n }\n\n return null\n}\n\nexport default StartGameByGuidComponent\n","import { useEffect, useContext } from 'react'\nimport { useHistory, useParams } from 'react-router-dom'\nimport { StoreState } from 'klubble/app/client/store'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { setDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport { useDispatch, useSelector } from 'react-redux'\nimport getQRGameForLocation from 'client/api/getQRGameForLocation'\nimport { loginQRHost } from 'client/api/authentication'\nimport { GameType } from 'common_packages/assets/js/types/gameDataTypes'\nimport useAbilities from 'client/hooks/useAbilities'\nimport * as auth from 'client/api/authentication'\nimport { UserData } from 'client/reducers/userReducer'\nimport useConfig from 'client/hooks/useConfig'\nimport { persistPrefix } from 'common_packages/assets/js/store/utilities/persistency'\nimport { getPersistKey } from 'client/player/js/store/utilities/persistency'\nimport { removePersistKey } from 'common_packages/assets/js/utilities/persistencyStorage'\n\nconst StartQRHostGameComponent = () => {\n const dispatch = useDispatch()\n const history = useHistory()\n const { getTranslation, translationsSet } = useContext(TranslationContext)\n const queryParams = useParams<{locationGuid: string}>()\n // the language of the QRHOST user determines (partly) which persisted puzzle to remove\n const { id: userId, language } = useSelector<StoreState, UserData>((state) => state.user?.data) ?? {}\n const config = useConfig()\n const { isQRHost } = useAbilities()\n\n useEffect(() => {\n const enterGame = async () => {\n try {\n if (!isQRHost) {\n auth.logout(true)\n loginQRHost(queryParams.locationGuid)\n } else if (userId) {\n const { playerParams, shareLink } = await getQRGameForLocation(queryParams.locationGuid, config.entity?.puzzlesClientId)\n const {\n gametype, puzzleid, klubblePuzzleId,\n } = playerParams\n\n // remove localstorage for this puzzle\n const key = `${persistPrefix + getPersistKey(gametype.toUpperCase() as GameType, puzzleid.toString(), language, +klubblePuzzleId, userId)}`\n removePersistKey(key)\n\n // passing along qrLocationGuid to the player, so it can be used later to refresh and see if we need to display another puzzle for this location.\n // passing along qrShareLink to the player, so it can be used to display it as a QR code in the player\n history.replace(`/player?${new URLSearchParams({\n ...playerParams,\n qrLocationGuid: queryParams.locationGuid,\n qrShareLink: shareLink,\n }).toString()}`)\n }\n } catch (err) {\n dispatch(setDrawer({\n drawer: drawerTypes.GENERIC_ERROR,\n forceModal: true,\n drawerData: {\n content: getTranslation(translationGroups.startGame, 'qr-game-could-not-be-started'),\n buttonText: getTranslation(translationGroups.startGame, 'ok-button'),\n },\n }))\n }\n }\n if (translationsSet) {\n enterGame()\n }\n }, [getTranslation, translationsSet, history, queryParams.locationGuid, language, userId, isQRHost, dispatch, config.entity?.puzzlesClientId])\n\n return null\n}\n\nexport default StartQRHostGameComponent\n","import React, { ComponentProps } from 'react'\n\ntype Props = {\n active: string\n buttons: Array<{key:string, text:string}>\n onClickHandler: (key: string) => void\n}\n\nconst TabNav = ({\n active, buttons, onClickHandler, ...restProps\n}:Props & ComponentProps<'div'>) => {\n const classNames = ['tab-nav', restProps.className]\n const renderButtons = () => buttons.map(({ key, text }) => {\n const buttonClassName = 'tab-nav__button'\n\n return (\n <button\n type=\"button\"\n className={`${buttonClassName} ${key === active ? `${buttonClassName}--active` : ''}`}\n key={key}\n onClick={() => onClickHandler(key)}\n >\n {text}\n </button>\n )\n })\n\n return (\n <div {...restProps} className={classNames.join(' ')}>\n {renderButtons()}\n </div>\n )\n}\n\nexport default TabNav\n","import { PuzzleType } from 'client/types/PuzzleType'\nimport React, { useCallback, useContext, useMemo } from 'react'\nimport { useSelector } from 'react-redux'\nimport { store as klubbleStore, type StoreState } from 'client/store'\nimport useBreadcrumbs, { BreadcrumbData } from 'use-react-router-breadcrumbs'\nimport getParameterByName from 'common_packages/assets/js/utilities/getParameterByName'\nimport IconChevronNext from 'assets/icons/icon_chevron_next.svg'\nimport { Link } from 'react-router-dom'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport { isMobile } from 'common_packages/assets/js/utilities/devices'\nimport transformGameNameForTranslation from 'common_packages/assets/js/utilities/gameNameTransformer'\nimport { GameType } from 'common_packages/assets/js/types/gameDataTypes'\n\nconst SITEMAP = {\n '/puzzles': { langKey: 'puzzles' },\n '/calendar': { langKey: 'puzzles', link: '/puzzles' },\n '/daily_dose': { langKey: 'daily-dose' },\n '/account': { langKey: 'account' },\n '/puzzle-packs': { langKey: 'puzzle-packs' },\n '/stats': { langKey: 'stats' },\n '/account/badges': { langKey: 'badges' },\n '/account/friends': { langKey: 'friends' },\n '/account/information': { langKey: 'information' },\n '/account/information/terms-and-conditions': { langKey: 'terms-and-conditions' },\n '/account/information/about': { langKey: 'about' },\n '/account/information/privacy': { langKey: 'privacy' },\n '/account/faq': { langKey: 'faq' },\n '/account/game-settings': { langKey: 'game-settings' },\n '/account/notification-settings': { langKey: 'notification-settings' },\n '/account/personal-details': { langKey: 'personal-details' },\n '/account/account-details': { langKey: 'account-details' },\n '/account/account-details/subscription': { langKey: 'subscription' },\n '/account/account-details/payment': { langKey: 'payment' },\n '/account/account-details/invoices': { langKey: 'invoices' },\n '/account/account-details/invoices/invoice': { langKey: 'invoice' },\n}\n\ntype Props = {\n onlyDesktop?: boolean // dont display on mobile devices (or desktop in forcemode mobile)\n}\n\nconst BreadcrumbsComponent = ({ onlyDesktop }: Props) => {\n const breadcrumbs = useBreadcrumbs()\n const puzzleTypes = useSelector<StoreState, PuzzleType[]>((state) => state.puzzleData?.puzzleTypes)\n const translation = useContext(TranslationContext)\n\n const renderBreadcrumb = useCallback((bc: BreadcrumbData, showLink: boolean) => {\n if (bc.key.startsWith('/puzzle-packs/')) {\n const puzzlePackType = bc.key.substring('/puzzle-packs/'.length)\n return (\n <span className=\"breadcrumb\">\n {translation.getTranslation(translationGroups.breadcrumbs, `puzzle-packs-${transformGameNameForTranslation(puzzlePackType as GameType)}`)}\n </span>\n )\n }\n if (bc.key.startsWith('/calendar/')) {\n const puzzleTypeId = parseInt(bc.key.substring('/calendar/'.length), 10)\n const puzzleType = puzzleTypes?.find((pt) => pt.puzzleTypeId === puzzleTypeId)\n return (\n <span className=\"breadcrumb\">\n {translation.getTranslation(translationGroups.breadcrumbs, `calendar-${puzzleType?.nameLangKey}`)}\n </span>\n )\n }\n if (bc.key.startsWith('/player')) {\n const puzzleType = getParameterByName('gametype')\n const puzzlePackType = getParameterByName('puzzlePackType')\n const puzzlePackId = getParameterByName('puzzlePackId')\n const isPuzzlePackPuzzle = !!puzzlePackType\n\n return (\n <>\n <span className=\"breadcrumb\">\n {isPuzzlePackPuzzle ? (\n <Link to=\"/puzzle-packs\">\n {translation.getTranslation(translationGroups.breadcrumbs, 'puzzle-packs')}\n </Link>\n ) : (\n <Link to=\"/puzzles\">\n {translation.getTranslation(translationGroups.breadcrumbs, 'puzzles')}\n </Link>\n )}\n </span>\n <IconChevronNext className=\"chevron\" />\n <span className=\"breadcrumb\">\n {isPuzzlePackPuzzle ? (\n <Link to={`/puzzle-packs/${puzzlePackType}`}>\n {translation.getTranslation(translationGroups.breadcrumbs, `puzzle-packs-${transformGameNameForTranslation(puzzlePackType as GameType)}`)}\n </Link>\n ) : (\n <Link to={`/calendar/${getParameterByName('puzzleTypeId')}`}>\n {translation.getTranslation(translationGroups.breadcrumbs, `calendar-${puzzleType}`)}\n </Link>\n )}\n </span>\n <IconChevronNext className=\"chevron\" />\n <span className=\"breadcrumb\">\n {isPuzzlePackPuzzle ? (\n <>\n {\n klubbleStore?.getState()?.puzzleData?.puzzlePacks?.find((p) => p.id === Number(puzzlePackId))?.displayName\n || translation.getTranslation(translationGroups.breadcrumbs, 'try-puzzle')\n }\n </>\n ) : (\n <>\n {translation.getTranslation(translationGroups.breadcrumbs, `puzzle-${puzzleType}`)}\n </>\n )}\n </span>\n </>\n )\n }\n\n return (\n <span>\n {showLink ? (\n <Link to={SITEMAP[bc.key]?.link ?? bc.key}>\n {translation.getTranslation(translationGroups.breadcrumbs, SITEMAP[bc.key]?.langKey)}\n </Link>\n ) : translation.getTranslation(translationGroups.breadcrumbs, SITEMAP[bc.key]?.langKey)}\n </span>\n )\n }, [puzzleTypes, translation])\n\n const content = useMemo(() => {\n return breadcrumbs.slice(1).map((bc, index) => (\n <React.Fragment key={bc.key}>\n { renderBreadcrumb(bc, (index < breadcrumbs.length - 2)) }\n { (index < breadcrumbs.length - 2) && <IconChevronNext className=\"chevron\" /> }\n </React.Fragment>\n ))\n }, [breadcrumbs, renderBreadcrumb])\n\n if (onlyDesktop && isMobile) return null\n\n return (\n <div className=\"container breadcrumbs\">\n {content}\n </div>\n )\n}\n\nexport default BreadcrumbsComponent\n","import React from 'react';\n\ntype Props = {\n className?: string,\n}\n\nconst CheckmarkComponent = ({ className }: Props) => (\n <svg className={className} width=\"25px\" height=\"25px\" viewBox=\"0 0 25 25\">\n <path fill=\"white\" d=\"M8.91435551,17.8717657 L3.28793845,12.2453486 C2.90628947,11.8636996 2.90066857,11.2249138 3.29119286,10.8343895 C3.68443982,10.4411425 4.31342509,10.4424081 4.70215202,10.8311351 L9.70540643,15.8343895 L19.2407133,6.29908264 C19.6408982,5.89889772 20.2695358,5.90342506 20.6600601,6.29394935 C21.0533071,6.68719631 21.0482861,7.31993687 20.6549268,7.7132962 L10.4127403,17.9554827 C10.0125554,18.3556677 9.38391773,18.3511403 8.99339344,17.960616 C8.96496774,17.9321903 8.93862301,17.9025132 8.91435551,17.8717657 Z\" id=\"path-1_icon_check_mark\" />\n\n </svg>\n)\n\nexport default CheckmarkComponent\n","import React, { ReactElement } from 'react'\nimport IconPause from 'assets/icons/icon_pause.svg'\nimport { Button } from '../../../../enums/Button'\nimport CheckmarkComponent from '../icons/CheckmarkComponent'\n\ntype Props = {\n buttonEnum: Button,\n buttonText?: string | ReactElement,\n onClick?: () => void\n}\n\nconst DayButtonComponent = ({ buttonEnum, buttonText, onClick }: Props) => {\n let className = 'day-button'\n let innerButtonElement = buttonText\n\n if (buttonEnum === Button.active) {\n className += ' day-button--active'\n } else if (buttonEnum === Button.played) {\n className += ' day-button--played'\n innerButtonElement = <CheckmarkComponent className=\"day-button__checkmark\" />\n } else if (buttonEnum === Button.playing) {\n innerButtonElement = <IconPause className=\"day-button__playing-icon\" />\n } else if (buttonEnum === Button.spelled) {\n className += ' day-button--spelled'\n }\n\n return (\n <div\n className={className}\n onClick={onClick}\n >\n {innerButtonElement}\n </div>\n )\n}\n\nexport default DayButtonComponent\n","import React from 'react'\nimport { Day } from 'client/types/Day'\nimport DayButtonComponent from './DayButtonComponent'\nimport { Button } from '../../../../enums/Button'\n\ntype Props = {\n recentDays?: Day[]\n onClick: () => void\n}\n\nconst reduceDuplicateDays = (acc: Day[], value: Day) => {\n if (!acc.some((s) => s.klubblePuzzleId === value.klubblePuzzleId)) {\n acc.push(value)\n }\n return acc\n}\n\nconst ButtonGroupDaysComponent = ({ recentDays = [], onClick }: Props) => (\n <div className=\"button-group-days\">\n <div className=\"day-button-line\" />\n <div className=\"day-button-line day-button-line--dotted\" />\n {recentDays.reduce<Day[]>(reduceDuplicateDays, []).map((day) => (\n <DayButtonComponent onClick={onClick} key={day.dayDate} buttonEnum={getButtonEnum(day)} buttonText={`${day.dayNum}`} />\n ))}\n </div>\n)\n\nconst getButtonEnum = (day: Day): Button => {\n if (day.isPlayed) {\n return Button.played\n } if (day.isStarted) {\n return Button.playing\n }\n return Button.default\n}\n\nexport default ButtonGroupDaysComponent\n","import React, { useContext, useMemo } from 'react'\nimport IconPlay from 'assets/icons/icon_play.svg'\nimport IconInfo from 'assets/icons/icon_info.svg'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\n\ntype Props = {\n nextPuzzleUrl?: string\n onClick?: () => void,\n text?: string,\n className?: string,\n active?: boolean,\n paused?: boolean,\n locked?: boolean,\n}\n\nconst PlayButtonComponent = ({\n nextPuzzleUrl,\n onClick,\n text = '',\n active = true,\n paused = false,\n locked = false,\n className: propsClassName = '',\n}: Props) => {\n const translation = useContext(TranslationContext)\n\n const className = [\n 'play-button',\n propsClassName,\n ...(!active ? ['play-button--disabled'] : []),\n ...(paused ? ['play-button--paused'] : []),\n ].join(' ')\n\n const inside = useMemo(() => {\n return (\n <>\n <span className=\"play-button-label\">{text || translation.getTranslation(translationGroups.common, 'play')}</span>\n {locked ? (\n <IconInfo className=\"info-button-icon\" />\n ) : (\n <IconPlay className=\"play-button-icon\" />\n )}\n </>\n )\n }, [locked, text, translation])\n\n if (!active || !nextPuzzleUrl) {\n return (\n <button\n type=\"button\"\n className={className}\n onClick={active ? onClick : undefined}\n data-test-id=\"button-start-puzzle\"\n >\n {inside}\n </button>\n )\n }\n\n // we use a `a` html element instead of react-router-dom's <Link> because we need to reload the page\n // even if just the query string changes\n return (\n <a\n href={nextPuzzleUrl}\n className={className}\n data-test-id=\"button-start-puzzle\"\n onClick={active ? onClick : undefined}\n >\n {inside}\n </a>\n )\n}\n\nexport default PlayButtonComponent\n","import React, {\n ComponentProps,\n ElementType,\n ReactNode,\n forwardRef,\n} from 'react'\n\ntype Props = {\n text?: ReactNode\n iconBefore?: ElementType\n iconAfter?: ElementType\n inverted?: boolean\n buttonType?: 'primary' | 'secondary'\n onClickHandler?: () => void,\n} & ComponentProps<'button'>\n\nconst RoundedButtonComponent = forwardRef<HTMLButtonElement, Props>(({\n disabled = false,\n className: customClassName,\n text = '',\n iconBefore: IconBefore,\n iconAfter: IconAfter,\n inverted = false,\n buttonType,\n onClickHandler,\n ...restProps\n}, ref) => {\n const className = [\n ...(customClassName ? [customClassName] : []),\n 'rounded-button',\n ...(disabled ? ['rounded-button--disabled'] : []),\n ...(inverted ? ['rounded-button--inverted'] : []),\n ...(buttonType ? [`rounded-button--type-${buttonType}`] : []),\n ].join(' ')\n\n return (\n <button\n {...restProps}\n type=\"button\"\n className={className}\n disabled={disabled}\n onClick={onClickHandler}\n ref={ref}\n >\n {IconBefore && <IconBefore className=\"rounded-button__icon--before\" />}\n {text}\n {IconAfter && <IconAfter className=\"rounded-button__icon--after\" />}\n </button>\n )\n})\n\nexport default RoundedButtonComponent\n","import React from 'react'\n\ntype Props = {\n currentSlide?: number,\n slideCount?: number,\n children:any\n }\n\nexport const SliderButton = ({\n currentSlide, slideCount, children, ...arrowProps\n}:Props) => (\n React.cloneElement(children, { ...arrowProps })\n);\n\nSliderButton.defaultProps = {\n currentSlide: null,\n slideCount: null,\n}\n\nexport default SliderButton\n","import React, { ReactNode } from 'react'\n\ntype Props = {\n children: ReactNode\n url?: string\n onClick?: () => void\n}\n\nconst ViewButtonComponent = ({ children, onClick, url }: Props) => (\n <a className=\"view-button\" type=\"button\" onClick={onClick} href={url}>\n {children}\n </a>\n)\n\nexport default ViewButtonComponent\n","import React, { ReactNode } from 'react'\n\ntype Props = {\n children: ReactNode,\n className?: string\n}\n\n/*\n* This component adds rounded corners to a component\n* Additional classnames can be added to the default card\n* */\nconst CardComponent = ({ children, className }: Props) => (\n <div className={`card ${className}`}>\n {children}\n </div>\n)\n\nCardComponent.defaultProps = {\n className: '',\n}\n\nexport default CardComponent\n","import React from 'react'\nimport IconChevronNext from 'assets/icons/icon_chevron_next.svg'\nimport ButtonComponent from 'common_packages/assets/js/components/ButtonComponent'\n\nconst CarouselBarArrowComponent = ({\n onClickHandler, disabled = false, arrowDirection, ...args\n}) => (\n <ButtonComponent\n type=\"button\"\n disabled={disabled}\n className={`carousel-bar__nav carousel-bar__nav-${arrowDirection}`}\n data-test-id={`carousel-bar-nav-${arrowDirection}`}\n onClick={() => onClickHandler({ ...args })}\n >\n <IconChevronNext />\n </ButtonComponent>\n)\n\nexport default CarouselBarArrowComponent\n","import React, {\n PropsWithChildren, useCallback, useEffect, useMemo, useState,\n} from 'react'\nimport useConfig from 'client/hooks/useConfig'\nimport TranslationContext, { type TranslationContextProps } from 'client/contexts/TranslationContext'\nimport * as translationAPI from 'client/api/translation'\nimport { API_URL } from 'client/api/common'\n\n// Prevent missing key error being printed to console more than once per key\nconst reportedKeys = []\n\nconst TranslationContextComponent = ({ children }: PropsWithChildren<unknown>) => {\n const [translations, setTranslations] = useState({})\n const { entity } = useConfig()\n\n const translationsSet = Object.keys(translations).length > 0\n let language = entity?.language\n if (entity && !entity.language) {\n language = 'en'\n }\n\n useEffect(() => {\n const abortController = new AbortController()\n\n const fetchTranslations = async () => {\n const res = await translationAPI.getAll(language, abortController)\n setTranslations(res)\n }\n if (language && !translationsSet) {\n fetchTranslations()\n }\n return () => {\n abortController.abort()\n }\n }, [language, translationsSet])\n\n const convertToJSX = (translation) => translation?.split('\\n').reduce((acc, item) => (\n acc === null ? item : (\n <>\n {acc}\n <br />\n {item}\n </>\n )\n ), null)\n\n const getTranslation = useCallback((group: string, name: string | number, data: { [key: string]: string | number } = null, shouldConvertToJSX = true) => {\n if (!group || !name?.toString()) return ''\n\n const key = `${group}_${name}`.toLowerCase()\n let translation = translations[key]\n\n if (data && translation) {\n const pattern = new RegExp(`{(${Object.keys(data).join('|')})}`, 'g')\n // Replace occurrences of properties with their values in the string\n translation = translation.replace(pattern, (match, p1) => data[p1] ?? match)\n }\n\n if (shouldConvertToJSX) {\n translation = convertToJSX(translation)\n }\n\n /**\n * Check translation against undefined instead of !translation to\n * allow empty string as translation. convertToJSX returns undefined\n * when translations[key] is nullish.\n * */\n if (translation === undefined && Object.keys(translations).length > 0) {\n translation = key\n\n if (process.env.KLUBBLE_REPORT_MISSING_TRANSLATIONS === 'true') {\n if (!reportedKeys.includes(key)) {\n reportedKeys.push(key)\n const token = JSON.parse(localStorage.getItem('authToken'))?.jwtToken\n // eslint-disable-next-line no-console\n console.log(`Translation ${key} not found. Click to create it: ${API_URL}languagetext/addText?langkey=${key}&lang=${language}&token=${token}`)\n }\n }\n }\n\n return translation || ''\n }, [translations, language])\n\n const getRawTranslation = useCallback((group: string, name: string | number, data: { [key: string]: string | number } = null) => {\n return getTranslation(group, name, data, false)\n }, [getTranslation])\n\n const translationContextProps: TranslationContextProps = useMemo(() => {\n return {\n translationsSet,\n getTranslation,\n getRawTranslation,\n }\n }, [translationsSet, getTranslation, getRawTranslation])\n\n return (\n <TranslationContext.Provider\n value={translationContextProps}\n >\n {children}\n </TranslationContext.Provider>\n )\n}\n\nexport default TranslationContextComponent\n","import React, {\n useState, useEffect, useContext, useCallback,\n} from 'react'\nimport Slider from 'react-slick'\nimport IconArrowPrev from 'assets/icons/icon_chevron_back.svg'\nimport IconArrowNext from 'assets/icons/icon_chevron_next.svg'\nimport SliderButton from 'pages/common/components/buttons/SliderButtonComponent'\nimport { ApiResult, klubbleAPI } from 'client/api/common'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\n\ntype USP = {\n id: number\n sortOrder: number\n titleKey: string,\n descriptionKey: string,\n imageUrl: string\n}\nconst UspSliderComponent = () => {\n const [currentSlide, setCurrentSlide] = useState(0)\n const [usps, setUsps] = useState(null)\n const translation = useContext(TranslationContext)\n const throwError = useAsyncError()\n\n useEffect(() => {\n const abortController = new AbortController()\n\n const fetchUsps = async ():Promise<void> => {\n klubbleAPI.get<ApiResult<USP[]>>('uniqueSellingPoints', { signal: abortController?.signal })\n .then((res) => setUsps(res.data))\n .catch((e) => {\n throwError(e, 'Error loading USPs')\n })\n }\n\n fetchUsps()\n\n return () => {\n abortController.abort()\n }\n }, [throwError])\n\n useEffect(() => {\n /* In some edgecases currentSlide can be -1 (I saw it happening while switching between different accounts),\n * then we set it to 0\n */\n if (currentSlide < 0) {\n setCurrentSlide(0)\n }\n }, [currentSlide])\n\n const customPaging = useCallback((i: number) => {\n let sliderPillClassName = 'slider-pill'\n if (currentSlide === i) {\n sliderPillClassName += ` ${sliderPillClassName}--active`\n }\n\n return (\n <div\n className={sliderPillClassName}\n />\n )\n }, [currentSlide])\n\n const settings = {\n dots: true,\n infinite: true,\n speed: 500,\n autoplay: true,\n autoplaySpeed: 6000,\n pauseHover: true,\n centerMode: true,\n marginBlockStart: 1,\n marginBlockEnd: 1,\n slidesToScroll: 1,\n centerPadding: 0,\n nextArrow: <SliderButton><IconArrowNext /></SliderButton>,\n prevArrow: <SliderButton><IconArrowPrev /></SliderButton>,\n beforeChange: (prev, next) => {\n setCurrentSlide(next)\n },\n customPaging,\n\n }\n return (\n <div className=\"usp-slider\">\n <Slider {...settings}>\n {usps?.sort((a, b) => a.sortOrder - b.sortOrder).map(({\n id, titleKey, descriptionKey, imageUrl,\n }) => {\n const title = translation.getTranslation(translationGroups.usp, titleKey)\n return (\n <div key={id}>\n <h1 className=\"usp-slider__title\">{title}</h1>\n <div className=\"usp-slider__image-container\">\n <img className=\"usp-slider__image\" src={imageUrl} alt={title} />\n </div>\n <div className=\"usp-slider__description\">\n {translation.getTranslation(translationGroups.usp, descriptionKey)}\n </div>\n </div>\n )\n })}\n </Slider>\n </div>\n )\n}\n\nexport default UspSliderComponent\n","import React, { useContext } from 'react'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useDispatch } from 'react-redux'\nimport { closeDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport { useHistory } from 'react-router-dom'\nimport useConfig from 'client/hooks/useConfig'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\nimport UspSliderComponent from './UspSliderComponent'\n\ninterface Props {\n inviterName?: string\n}\n\n// Presents the guest user with some motivation to become a paying Klubble member\nconst DrawerContentJoinNowComponent = ({ inviterName }: Props) => {\n const { getRawTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n const history = useHistory()\n const { lightTrialSuffix, lightTrialDaysText } = useConfig()\n\n const handleGoToRegistration = () => {\n dispatch(closeDrawer())\n history.push('/register')\n }\n\n return (\n <div className=\"drawer-join-now drawer__inner-content\">\n <div className=\"drawer-join-now__content\">\n <h3 className=\"drawer-join-now__title\">\n {getRawTranslation(translationGroups.drawer, inviterName ? 'join-now-inviter-title' : 'join-now-title').replace('{playerName}', inviterName)}\n </h3>\n <UspSliderComponent />\n <div className=\"drawer-join-now__footer\">\n <RoundedButtonComponent\n onClickHandler={handleGoToRegistration}\n text={getRawTranslation(translationGroups.drawer, `join-now-continue${lightTrialSuffix}`).replace(/{days}/g, lightTrialDaysText)}\n />\n <div className=\"drawer-join-now__sub-text\">{getRawTranslation(translationGroups.drawer, `join-now-subtext${lightTrialSuffix}`).replace(/{days}/g, lightTrialDaysText)}</div>\n </div>\n </div>\n </div>\n )\n}\n\nexport default DrawerContentJoinNowComponent\n","import React, { ComponentProps } from 'react'\nimport IconYeah from 'assets/icons/expression/yeah.svg'\nimport IconEureka from 'assets/icons/expression/eureka.svg'\nimport IconWelldone from 'assets/icons/expression/welldone.svg'\nimport IconLoveit from 'assets/icons/expression/loveit.svg'\nimport IconHmm from 'assets/icons/expression/hmm.svg'\nimport IconStuck from 'assets/icons/expression/stuck.svg'\nimport IconHaha from 'assets/icons/expression/haha.svg'\nimport { Expression } from '../drawer/express/DrawerContentExpressComponent'\n\nconst expressions: {[key in Expression]: { icon: React.FC<React.SVGProps<SVGSVGElement>> }} = {\n yeah: {\n icon: IconYeah,\n },\n eureka: {\n icon: IconEureka,\n },\n welldone: {\n icon: IconWelldone,\n },\n loveit: {\n icon: IconLoveit,\n },\n hmm: {\n icon: IconHmm,\n },\n stuck: {\n icon: IconStuck,\n },\n haha: {\n icon: IconHaha,\n },\n}\n\ntype Props = ComponentProps<'svg'> & {\n expression: Expression\n}\n\nconst ExpressionIcon = ({ expression, ...rest }: Props) => {\n const Icon = expressions[expression].icon\n return <Icon {...rest} />\n}\n\nexport default ExpressionIcon\n","import React, { useContext } from 'react'\nimport TranslationContext from '../../../../contexts/TranslationContext'\nimport translationGroups from '../../../../constants/translationGroups'\n\nconst PasswordStrengthComponent = () => {\n const translation = useContext(TranslationContext)\n\n return (\n <div className=\"password-strength\">{ translation.getTranslation(translationGroups.form, 'password-strength-description') }</div>\n )\n}\n\nexport default PasswordStrengthComponent\n","import React, {\n useState, useEffect, ReactNode, ComponentProps,\n} from 'react'\nimport IconEye from 'assets/icons/icon_eye.svg'\nimport IconRadioOff from 'assets/icons/icon_radio_off.svg'\nimport IconRadioOn from 'assets/icons/icon_radio_on.svg'\nimport {\n FieldPath,\n FieldPathValue,\n Path,\n UseFormReturn,\n} from 'react-hook-form'\nimport { Modify } from 'common_packages/assets/js/utilities/typescript'\nimport PasswordStrengthComponent from './PasswordStrengthComponent'\n\ntype Props<TFormType> = Modify<ComponentProps<'input'>, {\n name: Path<TFormType>\n type?: 'text' | 'password' | 'checkbox' | 'radio' | 'textarea' | 'file' | 'email'\n form: UseFormReturn<TFormType>\n label: ReactNode\n /* an additional label. it's recommended to add the class `form__field-secondary-label` to this element */\n secondaryLabel?: ReactNode\n customError?: boolean\n showValidatorError?: boolean\n validatePassword?: boolean\n radioValue?: string // only applicable when `type === radio`\n rows?: number // only applicable when 'type === textarea'\n}>\n\nconst BASE_CLASS_NAME = 'form__field'\n\nconst InputComponent = <TFormType extends {[key: string]: string | boolean | number | File}> ({\n name,\n form,\n label,\n secondaryLabel,\n type = 'text',\n customError = false,\n showValidatorError = false,\n validatePassword = true,\n radioValue,\n rows,\n children,\n className,\n ...props\n}: Props<TFormType>) => {\n const {\n register,\n watch,\n setValue,\n formState,\n } = form\n\n const { isSubmitting } = formState\n const [passwordVisible, setPasswordVisible] = useState(false)\n const value = watch(name) || ''\n\n const [labelClassName, setLabelClassName] = useState(value !== '' ? `${BASE_CLASS_NAME}--has-value` : '')\n const error = formState.errors[name]\n\n const inputClassName = [\n BASE_CLASS_NAME,\n `${BASE_CLASS_NAME}--${type}`,\n className,\n ...((!!error || customError) ? [`${BASE_CLASS_NAME}--error`] : []),\n ]\n const togglePasswordVisiblity = () => {\n setPasswordVisible(!passwordVisible)\n }\n\n useEffect(() => {\n setLabelClassName(value !== '' && type !== 'checkbox' && type !== 'radio' ? `${BASE_CLASS_NAME}--has-value` : '')\n }, [type, value])\n\n useEffect(() => {\n // check if first character is a whitespace\n if (typeof value === 'string' && /^\\s/.test(value)) {\n const newValue = value.trimStart()\n setValue(name, newValue as FieldPathValue<TFormType, FieldPath<TFormType>>)\n }\n }, [name, value, setValue])\n\n // see: https://codedaily.io/tutorials/69/Animated-Input-Label-with-Chrome-Autofill-Detection-in-React\n const handleAutoFill = (e) => {\n if (e.animationName === 'onAutoFillStart') {\n setLabelClassName(`${BASE_CLASS_NAME}--has-value`)\n }\n }\n\n const handleScrollTextarea = (e) => {\n const elem = e.target\n if (elem.scrollTop > 0) {\n elem.classList?.add('label--hide')\n } else {\n elem.classList?.remove('label--hide')\n }\n }\n\n const renderLabel = () => {\n if (showValidatorError && error) {\n const { message = '' } = error\n const split = (message as string).split('{name}')\n if (split.length !== 2) return message\n\n return (\n <span>\n {split[0]}\n {label}\n {split[1]}\n </span>\n )\n }\n return label\n }\n\n return (\n <>\n <div className={inputClassName.join(' ')}>\n {type === 'textarea' ? (\n <textarea\n {...register(name)}\n rows={rows}\n disabled={props.disabled || isSubmitting}\n name={name}\n id={name}\n onAnimationStart={handleAutoFill}\n onScroll={handleScrollTextarea}\n data-test-id={`input-${name}`}\n />\n ) : (\n <input\n {...register(name)}\n {...props}\n type={passwordVisible && type === 'password' ? 'text' : type}\n autoCapitalize={type === 'password' ? 'none' : 'sentences'}\n disabled={props.disabled || isSubmitting}\n name={name}\n id={name}\n onAnimationStart={handleAutoFill}\n value={radioValue}\n defaultChecked={radioValue === value}\n data-test-id={`input-${name}`}\n />\n )}\n <label htmlFor={name} className={labelClassName}>\n {renderLabel()}\n </label>\n {secondaryLabel}\n {type === 'password' && !props.disabled && !props.readOnly && (\n <IconEye\n className={`${BASE_CLASS_NAME}-password-eye${\n passwordVisible ? '' : ` ${BASE_CLASS_NAME}-password-eye--hidden`\n }`}\n onClick={togglePasswordVisiblity}\n />\n )}\n {type === 'radio' && (\n <>\n <IconRadioOff className=\"checkmark-off\" />\n <IconRadioOn className=\"checkmark-on\" />\n </>\n )}\n {children}\n {' '}\n </div>\n {type === 'password' && validatePassword && typeof value === 'string' && <PasswordStrengthComponent />}\n </>\n )\n}\n\nexport default InputComponent\n","import React, { ReactNode, useContext } from 'react'\nimport { UseFormReturn, Path, useFormState } from 'react-hook-form'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport IconChevronDown from '../../../../assets/icons/icon_chevron_down.svg'\n\ntype OptionObject = { val: string, displayVal: string }\n\ntype Props<TFormType> = {\n name: Path<TFormType>\n form: UseFormReturn<TFormType>\n label: ReactNode\n options: Array<string | OptionObject>\n disabled?: boolean\n customError?: boolean\n style?: any\n noEmptyOption?: boolean\n translateItem?: (name: string, item: string) => string\n}\n\nconst hasDisplayValue = (input: string | OptionObject): input is OptionObject => !!(input as OptionObject).displayVal\nconst hasValue = (input: string | number | boolean) => {\n if (typeof input === 'string') {\n return !!input?.length\n }\n return input !== undefined\n}\n\nconst SelectComponent = <TFormType extends {[key: string]: string | boolean | number}>({\n name,\n form,\n label,\n disabled = false,\n customError = false,\n options,\n style,\n noEmptyOption,\n translateItem,\n}: Props<TFormType>) => {\n const {\n register,\n watch,\n control,\n } = form\n const formState = useFormState({ control })\n const { errors, isSubmitting } = formState\n\n const { getTranslation } = useContext(TranslationContext)\n const value = watch(name) || ''\n\n const baseClassName = 'form__field'\n let className = `${baseClassName} ${baseClassName}--select`\n if (errors[name] || customError) {\n className += ` ${baseClassName}--error`\n }\n const labelClassName = hasValue(value) ? `${baseClassName}--has-value` : ''\n\n return (\n <div className={className} style={style}>\n <select\n disabled={disabled || isSubmitting}\n name={name}\n id={name}\n {...register(name)}\n >\n { !noEmptyOption && <option key=\"-1\" value=\"\" /> }\n {options.map((item) => (hasDisplayValue(item) ? (\n <option key={item.val} value={item.val}>\n {item.displayVal}\n </option>\n ) : (\n <option key={item} value={item}>\n {translateItem?.(name, item) ?? getTranslation(translationGroups.form, `${name}-option-${item}`)}\n </option>\n )))}\n </select>\n <IconChevronDown className={`${baseClassName}-select-icon`} />\n <label htmlFor={name} className={labelClassName}>\n {label}\n </label>\n </div>\n )\n}\n\nexport default SelectComponent\n","import React from 'react'\nimport { useFormState, UseFormReturn } from 'react-hook-form'\n\ntype Props<TFormType> = {\n label: string\n form: UseFormReturn<TFormType>\n successMessage?: string\n disableWhileNotDirty?:boolean\n}\n\nconst SubmitButtonComponent = <TFormType extends {[key: string]: string | boolean | number | File}>({\n label, form, successMessage, disableWhileNotDirty,\n}: Props<TFormType>) => {\n const {\n control,\n } = form\n const formState = useFormState({ control })\n const {\n isDirty,\n isSubmitting,\n isSubmitted,\n isValid,\n } = formState // https://github.com/react-hook-form/react-hook-form/discussions/6925\n let submitLabel = label\n let className = 'form__submit rounded-button rounded-button--type-secondary'\n\n if (successMessage && isSubmitted && !isDirty && isValid) {\n submitLabel = successMessage\n className += ' form__submit--success'\n }\n\n const disabled = (disableWhileNotDirty && !isDirty) || isSubmitting\n\n return (\n <input\n className={className}\n type=\"submit\"\n disabled={disabled}\n data-test-id=\"input-submit\"\n value={submitLabel}\n />\n )\n}\n\nexport default SubmitButtonComponent\n","import React, { useContext, useCallback } from 'react'\nimport IconEye from 'assets/icons/icon_eye.svg'\nimport ViewButtonComponent from 'client/pages/common/components/buttons/ViewButtonComponent'\nimport { useHistory } from 'react-router'\nimport { type Day } from 'client/types/Day'\nimport PillComponent from 'common_packages/assets/js/components/ui/pill/PillComponent'\nimport usePuzzleType from 'client/hooks/usePuzzleType'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { useDispatch } from 'react-redux'\nimport { showSubscribeDrawer } from 'client/actions/uiActions'\nimport PlayButtonComponent from '../buttons/PlayButtonComponent'\nimport ButtonGroupDaysComponent from '../buttons/ButtonGroupDaysComponent'\nimport PuzzleIcon from '../puzzle_icon/PuzzleIcon'\n\ntype Props = {\n puzzleTypeId: number\n recentDays: Day[]\n fromLocation?: string\n stacked?: boolean\n isEntirelyClickable?: boolean\n}\n\nconst GameCardCalendarComponent = ({\n puzzleTypeId,\n recentDays = [],\n fromLocation,\n stacked,\n isEntirelyClickable,\n}: Props) => {\n const translation = useContext(TranslationContext)\n\n const allPlayed = recentDays.every((day) => day.isPlayed)\n const history = useHistory()\n const puzzleType = usePuzzleType(puzzleTypeId)\n const canPlay = useAbilities().canPlayDailyPuzzles\n const dispatch = useDispatch()\n\n const handleClick = useCallback(() => {\n if (!canPlay) {\n dispatch(showSubscribeDrawer())\n return\n }\n\n if (fromLocation) {\n history.replace(`/calendar/${puzzleTypeId}`, { from: fromLocation })\n } else {\n history.push(`/calendar/${puzzleTypeId}`)\n }\n }, [canPlay, dispatch, fromLocation, history, puzzleTypeId])\n\n if (!puzzleType) return null\n\n const className = [\n 'game-card-calendar',\n ...(stacked ? ['game-card-calendar--stacked'] : []),\n ...(isEntirelyClickable ? ['game-card-calendar--entirely-clickable'] : []),\n ].join(' ')\n\n return (\n <div role=\"button\" className={className} onClick={isEntirelyClickable ? handleClick : undefined}>\n <PuzzleIcon\n puzzleTypeId={puzzleType.puzzleTypeId}\n nameLangKey={puzzleType.nameLangKey}\n isPremiumOnly={puzzleType.isPremiumOnly}\n className=\"game-card-calendar__puzzle-icon\"\n />\n <div className=\"game-card-calendar__days\">\n <div>\n <span className=\"game-card-calendar__title\">\n {translation.getTranslation(translationGroups.puzzle, puzzleType.nameLangKey)}\n </span>\n {puzzleType.isPremiumOnly && (\n <PillComponent type=\"info\" className=\"game-card-calendar__pill\">\n { translation.getTranslation(translationGroups.common, 'subscription-type-premium')}\n </PillComponent>\n )}\n </div>\n <span className=\"game-card-calendar__subtitle\">\n {translation.getTranslation(translationGroups.puzzleTags, puzzleType.format)}\n </span>\n <div className=\"game-card-calendar__buttons\">\n <ButtonGroupDaysComponent\n onClick={handleClick}\n recentDays={recentDays}\n />\n { !allPlayed\n ? (\n <PlayButtonComponent onClick={handleClick} />\n )\n : (\n <ViewButtonComponent onClick={handleClick}>\n {translation.getTranslation(translationGroups.common, 'button-view-calendar')}\n <IconEye />\n </ViewButtonComponent>\n )}\n </div>\n </div>\n </div>\n )\n}\n\nexport default GameCardCalendarComponent\n","import React, { type PropsWithChildren, type ReactNode, useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { Link } from 'react-router-dom'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { showSubscribeDrawer } from 'client/actions/uiActions'\nimport useAbilities from 'client/hooks/useAbilities'\nimport PuzzleIcon from '../puzzle_icon/PuzzleIcon'\n\ntype Props = {\n puzzleTypeId?: number\n nameLangKey: string\n subtitle?: ReactNode\n isNew?: boolean\n isPremiumOnly?: boolean\n isStacked?: boolean\n isStackedOnMobileView?: boolean\n showFavoriteToggle?: boolean\n disableLink?: boolean\n from?: string\n}\n\n/*\n* The gamecard component with an optional icon or new button\n* */\nconst GameCardComponent = ({\n puzzleTypeId,\n nameLangKey,\n subtitle,\n isNew = false,\n isPremiumOnly = false,\n isStacked = false,\n isStackedOnMobileView = false,\n showFavoriteToggle = false,\n disableLink = false,\n from = '',\n children,\n}: PropsWithChildren<Props>) => {\n const translation = useContext(TranslationContext)\n\n const gameCardClassName = [\n 'game-card',\n ...(isStackedOnMobileView ? ['game-card--stacked-on-mobile-view'] : []),\n ...(isNew || isPremiumOnly ? ['game-card--with-pill'] : []),\n ...(isStacked && !isStackedOnMobileView ? ['game-card--stacked'] : []),\n ].join(' ')\n\n const canPlay = useAbilities().canPlayDailyPuzzles\n const dispatch = useDispatch()\n\n const handleClick = () => {\n dispatch(showSubscribeDrawer())\n }\n\n const gameCardSubtitle = subtitle\n\n const innerGameCard = () => (\n <>\n <div className=\"game-card__image\">\n <PuzzleIcon\n puzzleTypeId={puzzleTypeId}\n nameLangKey={nameLangKey}\n isNew={isNew}\n isPremiumOnly={isPremiumOnly}\n showFavoriteToggle={showFavoriteToggle}\n className=\"game-card__puzzle-icon\"\n />\n </div>\n <div className=\"game-card__body\">\n <h3 className=\"game-card__title\">{translation.getTranslation(translationGroups.puzzle, nameLangKey)}</h3>\n <span className=\"game-card__subtitle\">{gameCardSubtitle}</span>\n {children}\n </div>\n </>\n )\n\n if (disableLink) {\n return <span className={gameCardClassName}>{innerGameCard()}</span>\n }\n\n if (!canPlay) {\n return (\n <span\n className={gameCardClassName}\n onClick={handleClick}\n role=\"button\"\n >\n {innerGameCard()}\n </span>\n )\n }\n\n return (\n <Link\n to={{ pathname: `/calendar/${puzzleTypeId}/?gameType=${nameLangKey}`, state: { from } }}\n className={gameCardClassName}\n data-test-id={`game-card-${nameLangKey}`}\n >\n {innerGameCard()}\n </Link>\n )\n}\n\nexport default GameCardComponent\n","import React, { useContext } from 'react'\nimport { type PuzzleType } from 'client/types/PuzzleType'\nimport GameCardComponent from 'pages/common/components/game_cards/GameCardComponent'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\n\ntype Props = {\n puzzleTypes: PuzzleType[]\n rowFilter?: (type: PuzzleType) => boolean | number\n rowTitle: React.ReactNode\n moreItem?: React.ReactNode\n}\n\nconst GameCardRowComponent = ({\n puzzleTypes,\n rowFilter,\n rowTitle,\n moreItem,\n}: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n\n return (\n <div className=\"game-card-row\">\n <h2 className=\"game-card-row__section-header section-header\">\n {rowTitle}\n </h2>\n <div className=\"game-card-row-cards\">\n {puzzleTypes\n .filter(rowFilter)\n .map((puzzle) => {\n const subtitle = getTranslation(translationGroups.puzzleTags, puzzle.format)\n return (\n <GameCardComponent\n key={puzzle.puzzleTypeId}\n puzzleTypeId={puzzle.puzzleTypeId}\n nameLangKey={puzzle.nameLangKey}\n subtitle={subtitle}\n isNew={puzzle.isNew}\n isPremiumOnly={puzzle.isPremiumOnly}\n showFavoriteToggle\n />\n )\n })}\n </div>\n {moreItem}\n </div>\n )\n}\n\nexport default GameCardRowComponent\n","import React, {\n type PropsWithChildren,\n useContext,\n useMemo,\n useState,\n} from 'react'\nimport { type PuzzlePack } from 'client/types/PuzzlePack'\nimport IconChevronDown from 'assets/icons/icon_chevron_down.svg'\nimport ProgressBarComponent from 'common_packages/assets/js/components/ui/progress-bar/ProgressBarComponent'\nimport { usePuzzleTypeImageUrls } from 'client/hooks/usePuzzleTypeImageUrls'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport PuzzlePackCardComponent from '../puzzle_packs/PuzzlePackCardComponent'\n\ntype Props = PropsWithChildren<{\n puzzlePacks: PuzzlePack[],\n showPerRow?: number,\n showProgress?: boolean,\n}>\n\nconst GameCardRowPuzzlePacksComponent = ({\n puzzlePacks,\n showPerRow = 0,\n showProgress = false,\n children,\n}: Props) => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const [rowsShown, setRowsShown] = useState(1)\n const { getIconUrl } = usePuzzleTypeImageUrls()\n\n const puzzlePacksToRender = useMemo(() => {\n if (showPerRow > 0) {\n return puzzlePacks.slice(0, rowsShown * showPerRow)\n }\n return puzzlePacks\n }, [puzzlePacks, showPerRow, rowsShown])\n\n return (\n <div className=\"game-card-row\">\n <h2 className=\"game-card-row__section-header section-header\">\n {children}\n </h2>\n <div className=\"game-card-row-cards\">\n {puzzlePacksToRender.map((puzzlePack) => {\n const puzzlePackCardSubtitle = getTranslation(translationGroups.puzzle, puzzlePack.largestFormat)\n const iconUrlIds = [0, puzzlePack.puzzleTypes.length > 1 ? 1 : 0, puzzlePack.puzzleTypes.length > 2 ? 1 : 0]\n return (\n <PuzzlePackCardComponent\n puzzlePack={puzzlePack}\n key={puzzlePack.id}\n iconUrls={iconUrlIds.map((id) => getIconUrl(puzzlePack.puzzleTypes[id]))}\n >\n <div className=\"game-card__content-size\">\n {getRawTranslation(translationGroups.puzzlePack, 'content-size', { size: puzzlePack.size })}\n </div>\n <span className=\"game-card__subtitle\">\n {puzzlePackCardSubtitle}\n <br />\n {getTranslation(translationGroups.difficulty, puzzlePack.levels[0].toLowerCase())}\n </span>\n {showProgress && (<ProgressBarComponent percentage={puzzlePack.percentageProgress} />)}\n </PuzzlePackCardComponent>\n )\n })}\n </div>\n {(puzzlePacksToRender.length < puzzlePacks.length) && (\n <button type=\"button\" className=\"game-card-row__show-more\" onClick={() => setRowsShown(rowsShown + 1)}>\n {getTranslation(translationGroups.puzzlePackTypePage, 'show-more')}\n <IconChevronDown />\n </button>\n )}\n </div>\n )\n}\n\nexport default GameCardRowPuzzlePacksComponent\n","import React, { useContext } from 'react'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport TabNav from '../TabNav'\n\ntype Props = {\n pages: string[]\n}\n\nconst NavigationPagesTabsComponent = ({ pages }: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const history = useHistory()\n const location = useLocation()\n const activePage = location.pathname.split('/')[1]\n\n const onClickHandler = (page: string) => {\n history.push(`/${page}`)\n }\n\n return (\n <div className=\"navigation-pages-tabs\">\n <TabNav\n active={activePage}\n buttons={pages.map((key) => ({ key, text: getTranslation(translationGroups.pageTitle, key) }))}\n onClickHandler={onClickHandler}\n />\n </div>\n )\n}\n\nexport default NavigationPagesTabsComponent\n","import React from 'react'\n\nexport const HeroBackgroundMobileComponent = () => (\n <>\n <svg className=\"page-header__background-svg--mobile\" width=\"800\" height=\"470\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style={{ position: 'absolute', top: 0, left: 0 }}>\n <rect width=\"50\" height=\"50\" rx=\"5\" transform=\"matrix(1 1 -1 1 80 60)\" fill=\"var(--header-squircle-4-color)\" />\n <rect width=\"50\" height=\"50\" rx=\"5\" transform=\"matrix(1 1 -1 1 -20 100)\" fill=\"var(--header-squircle-2-color)\" />\n <rect width=\"60\" height=\"60\" rx=\"6\" transform=\"matrix(1 1 -1 1 30 130)\" stroke=\"white\" strokeOpacity=\"0.6\" strokeWidth=\"1.5\" opacity=\"0.5\" />\n </svg>\n <svg className=\"page-header__background-svg--mobile\" width=\"800\" height=\"470\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style={{ position: 'absolute', top: 0, right: 0 }}>\n <g style={{ mixBlendMode: 'multiply' }}>\n <rect width=\"400\" height=\"400\" rx=\"10\" transform=\"matrix(1 1 -1 1 1070 -260)\" fill=\"var(--header-squircle-1-color)\" />\n </g>\n <g style={{ mixBlendMode: 'multiply' }}>\n <rect width=\"400\" height=\"400\" rx=\"10\" transform=\"matrix(1 1 -1 1 1110 -260)\" fill=\"var(--header-squircle-3-color)\" />\n </g>\n </svg>\n </>\n)\n","import React from 'react'\n\nexport const PageHeaderBackgroundDesktopComponent = () => (\n <>\n <svg\n className=\"page-header__background-svg--desktop\"\n width=\"100%\"\n height=\"470\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{\n position: 'absolute', top: 0, left: 'calc(50% - 500px)', overflow: 'unset',\n }}\n >\n <rect width=\"120\" height=\"120\" rx=\"12\" transform=\"matrix(1 1 -1 1 190 -90)\" fill=\"var(--header-squircle-4-color)\" />\n <g style={{ mixBlendMode: 'multiply' }}>\n <rect width=\"120\" height=\"120\" rx=\"15\" transform=\"matrix(1 1 -1 1 -20 10)\" fill=\"var(--header-squircle-1-color)\" />\n </g>\n <rect width=\"140\" height=\"140\" rx=\"12\" transform=\"matrix(1 1 -1 1 100 100)\" stroke=\"white\" strokeOpacity=\"0.6\" strokeWidth=\"2\" opacity=\"0.5\" />\n </svg>\n <svg className=\"page-header__background-svg--desktop\" width=\"100%\" height=\"470\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style={{ position: 'absolute', top: 0, left: 'calc(50% - 150px)' }}>\n <g style={{ mixBlendMode: 'multiply' }}>\n <rect width=\"600\" height=\"600\" rx=\"30\" transform=\"matrix(1 1 -1 1 950 -500)\" fill=\"var(--header-squircle-2-color)\" />\n </g>\n <g style={{ mixBlendMode: 'multiply' }}>\n <rect width=\"600\" height=\"600\" rx=\"30\" transform=\"matrix(1 1 -1 1 1100 -500)\" fill=\"var(--header-squircle-3-color)\" />\n </g>\n </svg>\n </>\n)\n","import React from 'react'\n\nexport const PageHeaderBackgroundMobileComponent = () => (\n <>\n <svg className=\"page-header__background-svg--mobile\" width=\"800\" height=\"470\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style={{ position: 'absolute', top: 0, left: 0 }}>\n <rect width=\"50\" height=\"50\" rx=\"5\" transform=\"matrix(1 1 -1 1 100 -40)\" fill=\"var(--header-squircle-4-color)\" />\n <g style={{ mixBlendMode: 'multiply' }}>\n <rect width=\"50\" height=\"50\" rx=\"10\" transform=\"matrix(1 1 -1 1 0 -20)\" fill=\"var(--header-squircle-2-color)\" />\n </g>\n <rect width=\"60\" height=\"60\" rx=\"6\" transform=\"matrix(1 1 -1 1 50 30)\" stroke=\"white\" strokeOpacity=\"0.6\" strokeWidth=\"1.5\" opacity=\"0.5\" />\n </svg>\n <svg className=\"page-header__background-svg--mobile\" width=\"800\" height=\"470\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style={{ position: 'absolute', top: 0, right: 0 }}>\n <g style={{ mixBlendMode: 'multiply' }}>\n <rect width=\"400\" height=\"400\" rx=\"15\" transform=\"matrix(1 1 -1 1 1080 -380)\" fill=\"var(--header-squircle-1-color)\" />\n </g>\n <g style={{ mixBlendMode: 'multiply' }}>\n <rect width=\"400\" height=\"400\" rx=\"15\" transform=\"matrix(1 1 -1 1 1120 -380)\" fill=\"var(--header-squircle-3-color)\" />\n </g>\n </svg>\n </>\n)\n","import { PageHeaderBackgroundDesktopComponent } from 'client/pages/common/components/page_header/PageHeaderBackgroundDesktopComponent'\nimport { PageHeaderBackgroundMobileComponent } from 'client/pages/common/components/page_header/PageHeaderBackgroundMobileComponent'\nimport React, { useContext } from 'react'\nimport TranslationContext from '../../../../contexts/TranslationContext'\n\ntype Props = {\n children: any,\n translationGroup: string,\n}\n\nconst PageHeaderComponent = ({\n children, translationGroup,\n}: Props) => {\n const translation = useContext(TranslationContext)\n\n return (\n <div className=\"page-header\">\n <PageHeaderBackgroundMobileComponent />\n <PageHeaderBackgroundDesktopComponent />\n <h1 className=\"page-header__title\">\n {translation.getTranslation(translationGroup, 'header-title')}\n </h1>\n <h3 className=\"page-header__sub-title\">\n {translation.getTranslation(translationGroup, 'header-sub-title')}\n </h3>\n {children}\n </div>\n )\n}\n\nexport default PageHeaderComponent\n","import React, { useContext } from 'react'\nimport HeartToggleContainer from 'pages/common/containers/HeartToggleContainer'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport PillComponent from 'common_packages/assets/js/components/ui/pill/PillComponent'\nimport { usePuzzleTypeImageUrls } from 'client/hooks/usePuzzleTypeImageUrls'\n\ntype Props = {\n puzzleTypeId?: number\n nameLangKey: string\n className: string\n isNew?: boolean\n isPremiumOnly?: boolean\n showFavoriteToggle?: boolean\n}\n\nconst GameCardPuzzleIcon = ({\n puzzleTypeId,\n nameLangKey,\n isNew = false,\n isPremiumOnly = false,\n showFavoriteToggle = false,\n className = '',\n}: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const { getIconUrl } = usePuzzleTypeImageUrls()\n\n return (\n <div className={`puzzle-icon ${className}`}>\n {showFavoriteToggle && puzzleTypeId && <HeartToggleContainer puzzleTypeId={puzzleTypeId} />}\n <img className=\"puzzle-icon__image\" src={getIconUrl(nameLangKey)} alt=\"\" />\n {isPremiumOnly && (\n <PillComponent type=\"info\" className=\"puzzle-icon__pill puzzle-icon__pill--premium\">\n {getTranslation(translationGroups.common, 'subscription-type-premium')}\n </PillComponent>\n )}\n {(isNew && !isPremiumOnly) && (\n <PillComponent type=\"new\" className=\"puzzle-icon__pill puzzle-icon__pill--new\">\n {getTranslation(translationGroups.common, 'new')}\n </PillComponent>\n )}\n </div>\n )\n}\n\nexport default GameCardPuzzleIcon\n","import React, {\n PropsWithChildren, useCallback, useContext,\n} from 'react'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { useDispatch } from 'react-redux'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { PuzzlePack } from 'client/types/PuzzlePack'\nimport { useCurrencyFormatters } from 'client/hooks/useCurrencyFormatters'\nimport IconEye from 'assets/icons/icon_eye.svg'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { useHistory } from 'react-router'\nimport { usePuzzlePacks } from 'client/pages/puzzle_packs/hooks/usePuzzlePacks'\nimport { getPuzzlePackTypeColor } from 'client/utilities/getPuzzlePackTypeColor'\nimport PuzzlePackIcons from './PuzzlePackIcons'\nimport RoundedButtonComponent from '../buttons/RoundedButtonComponent'\nimport PlayButtonComponent from '../buttons/PlayButtonComponent'\nimport ViewButtonComponent from '../buttons/ViewButtonComponent'\n\ntype Props = {\n puzzlePack: PuzzlePack\n iconUrls: string[]\n isStacked?: boolean\n isStackedOnMobileView?: boolean\n}\n\n/*\n* The puzzlePackCard component with an optional icon or new button\n* */\nconst PuzzlePackCardComponent = ({\n puzzlePack,\n iconUrls,\n isStacked = false,\n isStackedOnMobileView = false,\n children,\n}: PropsWithChildren<Props>) => {\n const dispatch = useDispatch()\n const translation = useContext(TranslationContext)\n const { formatCurrency } = useCurrencyFormatters()\n const { isAnonymous } = useAbilities()\n const { showPuzzlePackContents, getPuzzlePackTypeById } = usePuzzlePacks()\n const history = useHistory()\n const {\n id: puzzlePackId, displayName: name, puzzlePackTypeId, description, size, isPurchased, isNew, isFree, isCompleted,\n } = puzzlePack\n const price = formatCurrency(puzzlePack.price)\n const puzzlePackType = getPuzzlePackTypeById(puzzlePackTypeId)\n\n const handleBuy = useCallback(() => {\n dispatch(uiActions.setDrawer({\n drawer: drawerTypes.PUZZLE_PACK_INFO,\n drawerData: {\n puzzlePackId,\n name,\n description,\n size,\n },\n forceModal: true,\n modalAutoGrow: true,\n bleedToEdge: true,\n className: 'drawer--colored-header',\n }))\n }, [puzzlePackId, name, description, size, dispatch])\n\n const handleClickCard = useCallback(() => {\n if (isPurchased || (isFree && !isAnonymous)) {\n return showPuzzlePackContents(puzzlePackId)\n }\n if (isFree && isAnonymous) {\n // Anonymous user wants to play a free puzzlepack, so let's first make him sign up.\n return history.push({\n pathname: '/register',\n search: '?pack=true',\n state: { puzzlePackId, afterRegistrationPath: `/puzzle-packs/${puzzlePackType?.name.toLowerCase()}` },\n })\n }\n // in all other cases, pack is not free and not purchased, so he can buy the pack\n return handleBuy()\n }, [isPurchased, isFree, showPuzzlePackContents, history, handleBuy, isAnonymous, puzzlePackId, puzzlePackType])\n\n if (!puzzlePackType) {\n return null\n }\n\n const cardClassName = [\n `game-card puzzle-pack-card puzzle-pack-card--${getPuzzlePackTypeColor(puzzlePackType.name)}`,\n ...(isNew ? ['game-card--with-pill'] : []),\n ...(isStackedOnMobileView ? ['game-card--stacked-on-mobile-view'] : []),\n ...(isStacked && !isStackedOnMobileView ? ['game-card--stacked'] : []),\n ].join(' ')\n\n const renderButton = () => {\n if (isCompleted) {\n return (\n <ViewButtonComponent>\n <span className=\"view-button-label\">{translation.getTranslation(translationGroups.puzzlePack, 'button-view-completed')}</span>\n <IconEye />\n </ViewButtonComponent>\n )\n }\n if (isPurchased) {\n return (\n <PlayButtonComponent />\n )\n }\n if (isFree) {\n return (\n <PlayButtonComponent />\n )\n }\n return (\n <RoundedButtonComponent\n className=\"puzzle-pack-card__buy-button buy-button\"\n text={price}\n onClickHandler={handleBuy}\n />\n )\n }\n\n return (\n <div role=\"button\" className={cardClassName} onClick={handleClickCard}>\n <div className=\"game-card__image\">\n <PuzzlePackIcons\n className=\"game-card__puzzle-icon\"\n iconUrls={iconUrls}\n isNew={isNew}\n />\n </div>\n <div className=\"game-card__body\">\n <h3 className=\"game-card__title\" title={name}>{name}</h3>\n {children}\n {renderButton()}\n </div>\n </div>\n )\n}\n\nexport default PuzzlePackCardComponent\n","import React, {\n type PropsWithChildren,\n useContext,\n} from 'react'\nimport PuzzlePackCardComponent from 'client/pages/common/components/puzzle_packs/PuzzlePackCardComponent'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport ProgressBarComponent from 'common_packages/assets/js/components/ui/progress-bar/ProgressBarComponent'\nimport { usePuzzlePacks } from 'client/pages/puzzle_packs/hooks/usePuzzlePacks'\nimport { usePuzzleTypeImageUrls } from 'client/hooks/usePuzzleTypeImageUrls'\n\ntype Props = {\n puzzlePackId: number\n isStacked?: boolean\n isStackedOnMobileView?: boolean\n}\n\n/*\n* The puzzlePackCard component with an optional icon or new button\n* */\nconst PuzzlePackCardContinueComponent = ({\n puzzlePackId,\n isStacked = false,\n isStackedOnMobileView = false,\n}: PropsWithChildren<Props>) => {\n const { getTranslation } = useContext(TranslationContext)\n const { getIconUrl } = usePuzzleTypeImageUrls()\n const { getPuzzlePackById } = usePuzzlePacks()\n const puzzlePack = getPuzzlePackById(puzzlePackId)\n\n if (!puzzlePack) {\n return null\n }\n\n const iconUrlIds = [0, puzzlePack.puzzleTypes.length > 1 ? 1 : 0, puzzlePack.puzzleTypes.length > 2 ? 1 : 0]\n\n return (\n <PuzzlePackCardComponent\n puzzlePack={puzzlePack}\n key={puzzlePack.id}\n iconUrls={iconUrlIds.map((id) => getIconUrl(puzzlePack.puzzleTypes[id]))}\n isStacked={isStacked}\n isStackedOnMobileView={isStackedOnMobileView}\n >\n <span className=\"game-card__subtitle\">\n {`${getTranslation(translationGroups.puzzle, puzzlePack.largestFormat)} • ${getTranslation(translationGroups.difficulty, puzzlePack.levels[0])}`}\n </span>\n <ProgressBarComponent percentage={puzzlePack.percentageProgress} />\n </PuzzlePackCardComponent>\n )\n}\n\nexport default PuzzlePackCardContinueComponent\n","import React, { useContext } from 'react'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport PillComponent from 'common_packages/assets/js/components/ui/pill/PillComponent'\nimport HeartPuzzlePackTypeToggleContainer from '../../containers/HeartPuzzlePackTypeToggleContainer'\n\ntype Props = {\n iconUrls: string[]\n className: string\n puzzlePackTypeId?: number\n isNew?: boolean\n isPremiumOnly?: boolean\n showFavoriteToggle?: boolean\n}\n\nconst PuzzlePackIcons = ({\n iconUrls,\n className,\n puzzlePackTypeId,\n isNew = false,\n isPremiumOnly = false,\n showFavoriteToggle = false,\n}: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n\n return (\n <>\n <div className={`puzzle-icon ${className}`}>\n {showFavoriteToggle && <HeartPuzzlePackTypeToggleContainer puzzlePackTypeId={puzzlePackTypeId} />}\n <div className=\"puzzle-pack__icons-container\">\n {\n // eslint-disable-next-line react/no-array-index-key\n iconUrls.map((iconUrl, index) => <img className=\"puzzle-pack-icon__image\" src={iconUrl} key={`${iconUrl}${index}`} alt=\"\" />)\n }\n </div>\n </div>\n {isPremiumOnly && (\n <PillComponent type=\"info\" className=\"puzzle-icon__pill puzzle-icon__pill--premium\">\n { getTranslation(translationGroups.common, 'subscription-type-premium')}\n </PillComponent>\n )}\n {(isNew && !isPremiumOnly) && (\n <PillComponent type=\"new\" className=\"puzzle-icon__pill puzzle-icon__pill--new\">\n {getTranslation(translationGroups.common, 'new')}\n </PillComponent>\n )}\n </>\n )\n}\n\nexport default PuzzlePackIcons\n","import * as React from 'react'\nimport { type ReactNode, useEffect, useState } from 'react'\nimport { getDisplayModeApp } from 'client/utilities/getDisplayModeApp'\nimport AppDisplayModes from 'client/constants/appDisplayModes'\nimport PWAInstallContext from 'client/contexts/PWAInstallContext'\n\ntype Props = {\n children: ReactNode\n}\n\n/**\n * Store the 'install PWA' prompt in a context var such that we can\n * call it at a later point in time */\nconst PWAEventsProvider = ({ children }: Props) => {\n const [value, setDeferredPrompt] = useState<BeforeInstallPromptEvent>()\n\n useEffect(() => {\n const displayMode = getDisplayModeApp()\n\n if (displayMode === AppDisplayModes.browserTab) {\n // inform Google Tag Manager we're in 'web' mode\n window.dataLayer.push({\n event: 'session_start',\n source: 'web',\n })\n } else {\n // inform Google Tag Manager we're in 'standalone' mode\n window.dataLayer.push({\n event: 'session_start',\n source: 'standalone',\n })\n }\n }, [])\n\n useEffect(() => {\n const handleBeforeInstallPrompt = (e: BeforeInstallPromptEvent) => {\n // Prevent the mini-infobar from appearing on mobile\n e.preventDefault()\n setDeferredPrompt(e)\n }\n window.addEventListener('beforeinstallprompt', handleBeforeInstallPrompt)\n\n return () => {\n window.removeEventListener('beforeinstallprompt', handleBeforeInstallPrompt)\n }\n }, [setDeferredPrompt])\n\n return (\n <PWAInstallContext.Provider value={value}>\n {children}\n </PWAInstallContext.Provider>\n )\n}\n\nexport default PWAEventsProvider\n","import React, { ComponentProps } from 'react'\n\ntype Props = ComponentProps<'li'>\n\n// Adds ● before each list item for ReactMarkdown\nexport const CustomListItemComponent = (props: Props) => (\n <li>\n <span className=\"list-bullet-point\">●</span>\n <div>{props.children}</div>\n </li>\n)\n","import { useEffect } from 'react'\nimport { StoreState } from 'klubble/app/client/store'\nimport { getCurrentToken, setToken } from 'client/api/authentication'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { UserState } from 'client/reducers/userReducer'\nimport { getFeaturedPuzzleTypes, getPuzzleTypes } from 'client/actions/puzzleDataActions'\nimport { fetchConfig } from 'client/actions/configActions'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\n\n/*\n* CommonApiResourcesComponent pulls some shared resources from the backend\n* that are used on several pages like puzzleTypes\n* * */\nconst CommonApiResourcesComponent = () => {\n const { roles, data } = useSelector<StoreState, UserState>((state) => state.user) || {}\n const isAuthenticated = data !== null\n const dispatch = useDispatch()\n const throwError = useAsyncError()\n\n useEffect(() => {\n if (isAuthenticated) {\n const token = getCurrentToken()\n if (!roles.length && token) {\n setToken(token)\n }\n }\n }, [isAuthenticated, roles])\n\n useEffect(() => {\n const abortController = new AbortController()\n\n if (isAuthenticated) {\n Promise.all([\n dispatch(getPuzzleTypes()),\n dispatch(getFeaturedPuzzleTypes()),\n ]).catch((e) => {\n throwError(e)\n })\n }\n\n dispatch(fetchConfig(abortController))\n return () => {\n abortController.abort()\n }\n }, [isAuthenticated, dispatch, throwError])\n\n return null\n}\n\nexport default CommonApiResourcesComponent\n","import { createContext } from 'react'\nimport { type Theme } from 'client/types/Theme'\n\nexport type ThemeContextProps = {\n theme: Theme\n}\n\nexport const ThemeContext = createContext<ThemeContextProps>({\n theme: null,\n})\n","import React, {\n PropsWithChildren,\n useEffect,\n useMemo,\n useState,\n} from 'react'\n\nimport { denksportTheme } from 'client/themes/denksportTheme'\nimport { tankesportTheme } from 'client/themes/tankesportTheme'\nimport { sportCerebralTheme } from 'client/themes/sportCerebralTheme'\nimport { Theme, ThemeEntityName } from 'client/types/Theme'\nimport useConfig from 'client/hooks/useConfig'\nimport { ThemeContext } from './ThemeContext'\n\nexport const themes: { [key in ThemeEntityName]: Theme } = {\n klubble_nl: denksportTheme,\n klubble_se: tankesportTheme,\n klubble_fr: sportCerebralTheme,\n}\n\nconst ThemeProviderComponent = ({ children }: PropsWithChildren<unknown>) => {\n const config = useConfig()\n const [theme, setTheme] = useState<Theme>()\n const [activeThemeEntity, setActiveThemeEntity] = useState<ThemeEntityName>()\n\n /**\n * Set the theme for the activeThemeEntity\n */\n useEffect(() => {\n if (!activeThemeEntity) return\n const themeSettings = themes[activeThemeEntity]\n const { cssVariables } = themeSettings\n Object.keys(cssVariables).forEach((variable) => {\n document.documentElement.style.setProperty(variable, cssVariables[variable])\n })\n setTheme(themeSettings)\n }, [activeThemeEntity])\n\n /**\n * Set activeThemeEntity as config?.entity?.name changes\n */\n useEffect(() => {\n setActiveThemeEntity(config?.entity?.name)\n }, [config?.entity?.name])\n\n /**\n * Listen for shortcut keys to switch theme, in case KLUBBLE_THEME_SWITCHER_ENABLED is true\n */\n useEffect(() => {\n const handleSwitchTheme = (event) => {\n const { key, ctrlKey, metaKey } = event\n const themesArr = Object.keys(themes) as ThemeEntityName[]\n\n if (key > 0 && key <= themesArr.length && (ctrlKey || metaKey)) {\n const entityName = themesArr[Number(key) - 1]\n setActiveThemeEntity(entityName)\n }\n }\n\n if (process.env.KLUBBLE_THEME_SWITCHER_ENABLED === 'true') {\n window.addEventListener('keydown', handleSwitchTheme)\n }\n\n return () => {\n window.removeEventListener('keydown', handleSwitchTheme)\n }\n }, [])\n\n const memoizedValue = useMemo(() => ({ theme }), [theme])\n\n return (\n <ThemeContext.Provider\n value={memoizedValue}\n >\n {theme && children}\n </ThemeContext.Provider>\n )\n}\n\nexport default ThemeProviderComponent\n","import { Theme } from 'client/types/Theme'\n\nexport const denksportTheme: Theme = {\n cssVariables: {\n '--primary-color': '#E00916',\n '--primary-color-gradient-start': '#E40916',\n '--primary-color-gradient-end': '#B10000',\n '--primary-font-color': '#FFFFFF',\n '--secondary-color': '#3576C3',\n '--secondary-color-light': 'rgb(var(--secondary-color-light-rgb-values))',\n '--secondary-color-light-rgb-values': '111, 159, 216',\n '--secondary-color-lighter': '#EAF1F9',\n '--secondary-color-gradient-start': '#458ADA',\n '--secondary-color-gradient-end': '#2563AC',\n '--tertiary-color': '#F0F4F9',\n '--new-label-color': '#4A90E2',\n '--new-label-color-featured': '#E00916',\n '--primary-button-color': '#E00916',\n '--secondary-button-color': '#4A90E2',\n '--primary-button-hover-color': '#B00713',\n '--secondary-button-hover-color': '#2377D7',\n '--play-button-icon-color': '#FFFFFF',\n '--pause-icon-color': '#000000',\n '--primary-calendar-color': '#E00916',\n '--player-1-selection-color': '#4A90E2',\n '--player-2-selection-color': '#EA4F53',\n '--player-3-selection-color': '#3CA264',\n '--player-4-selection-color': '#A677C0',\n '--player-5-selection-color': '#D2C45B',\n '--player-6-selection-color': '#EF7D17',\n '--player-7-selection-color': '#F3A1C2',\n '--player-1-secondary-selection-color': '#D2E3F8',\n '--player-2-secondary-selection-color': '#EFB1B2',\n '--player-3-secondary-selection-color': '#A9D2B9',\n '--player-4-secondary-selection-color': '#D4C1DE',\n '--player-5-secondary-selection-color': '#EDE7BD',\n '--player-6-secondary-selection-color': '#F1CFAF',\n '--player-7-secondary-selection-color': '#F2D2DF',\n '--header-squircle-1-color': 'rgba(226, 0, 26, .35)',\n '--header-squircle-2-color': 'rgba(226, 0, 26, .5)',\n '--header-squircle-3-color': 'rgba(226, 0, 26, .65)',\n '--header-squircle-4-color': 'rgba(255, 255, 255, 0.18)',\n '--header-text-shadow': '1px 1px rgba(0, 0, 0, 0.2)',\n '--header-icon-color': '#FFFFFF',\n '--font-header': '\"Wavehaus\", sans-serif',\n '--font-header-color': '#FFFFFF',\n '--font-sub-title': '\"Work Sans\", sans-serif',\n '--font-body': '\"Work Sans\", sans-serif',\n '--font-weight-header-bold': 550,\n '--font-weight-body-bold': 600,\n '--font-weight-section-header': 600,\n '--border-radius-game-card': '.5rem',\n '--border-radius-button': '.5rem',\n '--bullet-y-offset': '0px',\n '--logo-height': '2.85rem',\n '--logo-transform': 'translateY(0px)',\n '--loading-square-color1': '#ffaeae',\n '--loading-square-color2': '#a6d3b9',\n '--loading-square-color3': '#c2c2e2',\n '--loading-square-color4': '#7fcce6',\n },\n entityBrandName: 'Denksport PLAY',\n helpHomescreenPath: '/entity/klubble_nl/images/help/homescreen-intro-{platform}.png',\n sectionDividerDefinition: 'M 1472 55 L 0 55 V 797.603 H 1472 V 0 Z',\n logoPath: '/entity/klubble_nl/images/logos/logo.svg',\n logoInvertedPath: '/entity/klubble_nl/images/logos/logo-inverted.svg',\n iconPath: '/entity/klubble_nl/images/logos/icon.svg',\n}\n","import { Theme } from 'client/types/Theme'\n\nexport const tankesportTheme: Theme = {\n cssVariables: {\n '--primary-color': '#E00916',\n '--primary-color-gradient-start': '#E40916',\n '--primary-color-gradient-end': '#B10000',\n '--primary-font-color': '#FFFFFF',\n '--secondary-color': '#3576C3',\n '--secondary-color-light': 'rgb(var(--secondary-color-light-rgb-values))',\n '--secondary-color-light-rgb-values': '111, 159, 216',\n '--secondary-color-lighter': '#EAF1F9',\n '--secondary-color-gradient-start': '#458ADA',\n '--secondary-color-gradient-end': '#2563AC',\n '--tertiary-color': '#F0F4F9',\n '--new-label-color': '#933765',\n '--new-label-color-featured': '#933765',\n '--primary-button-color': '#E00916',\n '--secondary-button-color': '#4A90E2',\n '--primary-button-hover-color': '#B00713',\n '--secondary-button-hover-color': '#2377D7',\n '--play-button-icon-color': '#FFFFFF',\n '--pause-icon-color': '#000000',\n '--primary-calendar-color': '#E00916',\n '--player-1-selection-color': '#4A90E2',\n '--player-2-selection-color': '#EA4F53',\n '--player-3-selection-color': '#3CA264',\n '--player-4-selection-color': '#A677C0',\n '--player-5-selection-color': '#D2C45B',\n '--player-6-selection-color': '#EF7D17',\n '--player-7-selection-color': '#F3A1C2',\n '--player-1-secondary-selection-color': '#D2E3F8',\n '--player-2-secondary-selection-color': '#EFB1B2',\n '--player-3-secondary-selection-color': '#A9D2B9',\n '--player-4-secondary-selection-color': '#D4C1DE',\n '--player-5-secondary-selection-color': '#EDE7BD',\n '--player-6-secondary-selection-color': '#F1CFAF',\n '--player-7-secondary-selection-color': '#F2D2DF',\n '--header-squircle-1-color': 'rgba(226, 0, 26, .35)',\n '--header-squircle-2-color': 'rgba(226, 0, 26, .5)',\n '--header-squircle-3-color': 'rgba(226, 0, 26, .65)',\n '--header-squircle-4-color': 'rgba(255, 255, 255, 0.18)',\n '--header-text-shadow': '1px 1px rgba(0, 0, 0, 0.2)',\n '--header-icon-color': '#FFFFFF',\n '--font-header': '\"Roboto\", sans-serif',\n '--font-header-color': '#FFFFFF',\n '--font-sub-title': '\"Pavanam\", sans-serif',\n '--font-body': '\"Maison Neue\", sans-serif',\n '--font-weight-header-bold': 700,\n '--font-weight-body-bold': 700,\n '--font-weight-section-header': 600,\n '--border-radius-game-card': '.5rem',\n '--border-radius-button': '.5rem',\n '--bullet-y-offset': '-1px',\n '--logo-height': '2.75rem',\n '--logo-transform': 'translateY(2px)',\n '--loading-square-color1': '#ffaeae',\n '--loading-square-color2': '#a6d3b9',\n '--loading-square-color3': '#c2c2e2',\n '--loading-square-color4': '#7fcce6',\n },\n entityBrandName: 'Tankesport Play',\n helpHomescreenPath: '/entity/klubble_se/images/help/homescreen-intro-{platform}.png',\n sectionDividerDefinition: 'M-0.643311 66.737C-0.643311 66.737 143.436 96.9677 472.762 33.9331C802.087 -29.1014 946.167 17.2101 946.167 17.2101V573.589H-0.643311V66.737Z',\n logoPath: '/entity/klubble_se/images/logos/logo.svg',\n logoInvertedPath: '/entity/klubble_se/images/logos/logo-inverted.svg',\n iconPath: '/entity/klubble_se/images/logos/icon.svg',\n}\n","import { Theme } from 'client/types/Theme'\n\nexport const sportCerebralTheme: Theme = {\n cssVariables: {\n '--primary-color': '#FBD918',\n '--primary-color-gradient-start': '#FCCA18',\n '--primary-color-gradient-end': '#FBEC19',\n '--primary-font-color': '#053F83',\n '--secondary-color': '#044287',\n '--secondary-color-light': 'rgb(var(--secondary-color-light-rgb-values))',\n '--secondary-color-light-rgb-values': '111, 159, 216',\n '--secondary-color-lighter': '#DBECFE',\n '--secondary-color-gradient-start': '#024B96',\n '--secondary-color-gradient-end': '#0A2F68',\n '--tertiary-color': '#F0F4F9',\n '--new-label-color': '#EC7A00',\n '--new-label-color-featured': '#EC7A00',\n '--primary-button-color': '#EC7A00',\n '--secondary-button-color': '#014B96',\n '--primary-button-hover-color': '#B85F00',\n '--secondary-button-hover-color': '#013365',\n '--play-button-icon-color': '#FFFFFF',\n '--pause-icon-color': '#000000',\n '--primary-calendar-color': '#EC7A00',\n '--player-1-selection-color': '#4A90E2',\n '--player-2-selection-color': '#EF7D17',\n '--player-3-selection-color': '#3CA264',\n '--player-4-selection-color': '#A677C0',\n '--player-5-selection-color': '#D2C45B',\n '--player-6-selection-color': '#EA4F53',\n '--player-7-selection-color': '#F3A1C2',\n '--player-1-secondary-selection-color': '#D2E3F8',\n '--player-2-secondary-selection-color': '#F1CFAF',\n '--player-3-secondary-selection-color': '#A9D2B9',\n '--player-4-secondary-selection-color': '#D4C1DE',\n '--player-5-secondary-selection-color': '#EDE7BD',\n '--player-6-secondary-selection-color': '#EFB1B2',\n '--player-7-secondary-selection-color': '#F2D2DF',\n '--header-squircle-1-color': 'rgba(248, 213, 45, .20)',\n '--header-squircle-2-color': 'rgba(248, 213, 45, .25)',\n '--header-squircle-3-color': 'rgba(248, 213, 45, .25)',\n '--header-squircle-4-color': 'rgba(255, 255, 255, 0.20)',\n '--header-text-shadow': 'none',\n '--header-icon-color': '#000000',\n '--font-header': '\"Cabin\", sans-serif',\n '--font-header-color': '#000000',\n '--font-sub-title': '\"Pavanam\", sans-serif',\n '--font-body': '\"Pavanam\", sans-serif',\n '--font-weight-header-bold': 700,\n '--font-weight-body-bold': 700,\n '--font-weight-section-header': 600,\n '--border-radius-game-card': '.5rem',\n '--border-radius-button': '.5rem',\n '--bullet-y-offset': '-1px',\n '--logo-height': '2.75rem',\n '--logo-transform': 'translateY(0px)',\n '--loading-square-color1': '#ffaeae',\n '--loading-square-color2': '#a6d3b9',\n '--loading-square-color3': '#c2c2e2',\n '--loading-square-color4': '#7fcce6',\n },\n entityBrandName: 'Sport Cérébral® Jeux',\n helpHomescreenPath: '/entity/klubble_fr/images/help/homescreen-intro-{platform}.png',\n sectionDividerDefinition: 'M-22 102L1450 0V890H-22V102Z',\n logoPath: '/entity/klubble_fr/images/logos/logo.svg',\n logoInvertedPath: '/entity/klubble_fr/images/logos/logo-inverted.svg',\n iconPath: '/entity/klubble_fr/images/logos/icon.svg',\n}\n","import { Toast } from 'common_packages/assets/js/types/Toast'\nimport React, { useEffect } from 'react'\n\ntype Props = Toast & {\n IconComponent: React.ElementType\n textRight?: string\n zIndex?: number\n remove?: (id: number) => void\n}\n\nconst ToastComponent = ({\n IconComponent,\n message,\n id,\n type,\n disableAutoClose,\n duration = 3000,\n textRight,\n zIndex = 0,\n remove,\n}: Props) => {\n useEffect(() => {\n let removeTimeout\n if (id && remove && !disableAutoClose) {\n removeTimeout = setTimeout(() => remove(id), duration)\n }\n return () => {\n clearTimeout(removeTimeout)\n }\n }, [id, remove, disableAutoClose, duration])\n let className = 'toast list-item'\n\n if (type) {\n className += ` toast--${type}`\n }\n return (\n <div style={{ zIndex }} className={className}>\n <div className=\"list-item__icon\">\n <IconComponent className=\"toast-icon\" />\n </div>\n <span className=\"list-item__description\">{message}</span>\n <span className=\"list-item__right\">{textRight}</span>\n </div>\n )\n}\n\nexport default ToastComponent\n","import React, {\n type PropsWithChildren,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport IconHeartFull from 'assets/icons/icon_heart_full.svg'\nimport IconHeartEmpty from 'assets/icons/icon_heart_empty.svg'\n\ntype Props = PropsWithChildren<{\n isFavorite: boolean\n toggleIsFavorite: () => void\n isStacked?: boolean\n className?: string\n}>\n\nconst HeartToggleComponent = ({\n className,\n toggleIsFavorite,\n isFavorite,\n children,\n isStacked = false,\n}: Props) => {\n const [justFavorited, setJustFavorited] = useState(false)\n const isMounted = useRef(false)\n\n const handleToggle = (evt) => {\n evt.preventDefault()\n evt.stopPropagation()\n\n toggleIsFavorite()\n }\n\n useEffect(() => {\n if (isMounted.current) {\n setJustFavorited(isFavorite) // show pop in animation\n }\n }, [isFavorite])\n\n useEffect(() => {\n isMounted.current = true\n return () => {\n isMounted.current = false\n }\n }, [])\n\n const toggleClassName = [\n 'heart-toggle',\n ...(isFavorite ? ['heart-toggle--full'] : []),\n ...(isStacked ? ['heart-toggle--stacked'] : []),\n ...(justFavorited ? ['heart-toggle--pop-in'] : []),\n className ?? '',\n ].join(' ')\n\n const Icon = isFavorite ? IconHeartFull : IconHeartEmpty\n\n return (\n <button\n type=\"button\"\n onClick={handleToggle}\n className={toggleClassName}\n >\n <Icon className=\"heart-toggle__icon\" />\n {children}\n </button>\n )\n}\nexport default HeartToggleComponent\n","import * as React from 'react'\n\ntype Props = {\n name: string\n value?: boolean\n handleToggle: (value: boolean) => void\n}\n\nconst ToggleComponent = ({\n name,\n value,\n handleToggle,\n}: Props) => (\n <div className=\"toggle\">\n <input className=\"toggler\" type=\"checkbox\" id={name} checked={!!value} onChange={(e) => handleToggle(e.target.checked)} />\n { /* eslint-disable jsx-a11y/label-has-associated-control */}\n <label htmlFor={name} />\n </div>\n)\n\nexport default ToggleComponent\n","import {\n useEffect, useMemo, useRef,\n} from 'react'\nimport useActiveSubscription from 'client/hooks/useActiveSubscription'\nimport { Role } from 'client/enums/Role'\nimport { useSelector } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport { UserData } from 'client/reducers/userReducer'\nimport useAbilities from 'client/hooks/useAbilities'\n\nconst DataLayerTrackingComponent = () => {\n const subscription = useActiveSubscription()\n const userData = useSelector<StoreState, UserData>((state) => state.user?.data)\n const { isPuzzlePackOwner } = useAbilities()\n const hasUserData = !!userData\n const eventSent = useRef(null)\n const numberOfPayments = useMemo(() => {\n return userData?.numberOfPayments ?? 'unknown'\n }, [userData?.numberOfPayments])\n\n useEffect(() => {\n let eventObj\n if (subscription) {\n eventObj = {\n event: 'account_status',\n subscriptionType: subscription.subscriptionTypeName,\n isTrial: subscription.isInTrialPeriod,\n isPuzzlePackOwner,\n numberOfPayments,\n }\n } else if (hasUserData) {\n eventObj = {\n event: 'account_status',\n subscriptionType: Role.free,\n isPuzzlePackOwner,\n }\n }\n if (!eventSent.current || (eventObj && Object.entries(eventObj).toString() !== Object.entries(eventSent.current).toString())) {\n window.dataLayer.push(eventObj)\n eventSent.current = eventObj\n }\n }, [subscription, hasUserData, numberOfPayments, isPuzzlePackOwner])\n\n return null\n}\n\nexport default DataLayerTrackingComponent\n","import { useEffect } from 'react'\nimport { managePersistencyStorageSpace } from 'common_packages/assets/js/utilities/persistency_storage/managePersistencyStorageSpace'\nimport { klubbleApp } from 'common_packages/assets/js/utilities/persistency_storage/localStorageKeys'\nimport { isUsingIndexedDb } from 'common_packages/assets/js/utilities/persistency_storage/setupStorage'\nimport * as Sentry from '@sentry/browser'\nimport { persistPrefix } from 'common_packages/assets/js/store/utilities/persistency'\n\nconst ManagePersistencyStorageSpaceComponent = () => {\n useEffect(() => {\n // remove old versions of persisted Klubble app, if any\n Object.keys(window.localStorage)\n .filter((key) => key.includes(`${persistPrefix}${klubbleApp}`) && !key.includes(process.env.KLUBBLE_VERSION))\n .forEach((key) => {\n localStorage.removeItem(key)\n })\n if (isUsingIndexedDb && navigator.storage && navigator.storage.estimate) {\n navigator.storage.estimate().then(({ usage, quota }) => {\n const percentageWarning = 80\n const percentageUsed = (usage / quota) * 100\n if (percentageUsed > percentageWarning) {\n const mbConverter = 1024 * 1024\n Sentry.captureMessage(`Over ${percentageWarning}% used of indexedDB quota`, { extra: { quota: `${quota / mbConverter}mb`, usage: `${usage / mbConverter}mb` } })\n }\n })\n }\n managePersistencyStorageSpace()\n }, [])\n\n return null\n}\n\nexport default ManagePersistencyStorageSpaceComponent\n","import { useEffect, useCallback } from 'react'\nimport { useHistory } from 'react-router-dom'\nimport { isIOS15OrAboveSafari } from 'common_packages/assets/js/utilities/devices'\n\n/*\n * To make sure we always see the top of the new page on route change (instead of the scroll y position of the previous page)\n * we scroll to the top. To prevent a minimized address bar on iOS 15.4+ to maximize again due to scrolling to the top, we scroll to y = 1\n */\nconst ScrollTopComponent = () => {\n const history = useHistory()\n\n const scroll = useCallback(() => { window.scrollTo({ top: isIOS15OrAboveSafari ? 1 : 0, left: 0 }) }, [])\n\n useEffect(() => {\n const unsetHistoryListen = history.listen(() => {\n scroll()\n })\n\n return unsetHistoryListen\n }, [history, scroll])\n\n return null\n}\n\nexport default ScrollTopComponent\n","import React, { useContext, useEffect } from 'react'\nimport { useSelector } from 'react-redux'\nimport applePencilHelper from 'common_packages/assets/js/utilities/applePencilHelper'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { determineSmartHintClueIndex } from 'wordsearch/resources/assets/js/utilities/smartHint'\nimport { WordsearchStoreState } from 'wordsearch/resources/assets/js/reducers'\nimport { SolvedClue } from 'wordsearch/resources/assets/js/reducers/cluesReducer'\n\ntype Props = {\n onActivateSmartHint: (clueIndex: number) => void,\n onGameInstructionsClick: () => void\n}\n\nconst DrawerContentSmartHintWordsearchComponent = ({ onActivateSmartHint, onGameInstructionsClick }: Props) => {\n const translation = useContext(TranslationContext)\n const clueCells = useSelector<WordsearchStoreState, number[][]>((state) => state.clues.clueCells)\n const solvedClues = useSelector<WordsearchStoreState, SolvedClue[]>((state) => state.clues.solvedClues)\n\n useEffect(() => {\n const clueIndex = determineSmartHintClueIndex(clueCells, solvedClues)\n onActivateSmartHint(clueIndex)\n }, [clueCells, onActivateSmartHint, solvedClues])\n\n return (\n <div className=\"smart-hint-wordsearch drawer__inner-content\" data-test-id=\"smart-hint-wordsearch\">\n {translation.getTranslation(translationGroups.drawer, 'smart-hint-wordsearch-look-at-this')}\n {' '}\n { /* eslint-disable jsx-a11y/anchor-is-valid */\n /* eslint-disable jsx-a11y/no-static-element-interactions */}\n <a\n className=\"link\"\n onClick={onGameInstructionsClick}\n onTouchStart={applePencilHelper.handleTouchStart}\n onTouchMove={applePencilHelper.handleTouchMove}\n onTouchEnd={(e) => applePencilHelper.handleTouchEnd(e, onGameInstructionsClick)}\n >\n {translation.getTranslation(translationGroups.drawer, 'smart-hint-wordsearch-game-instructions-link')}\n </a>\n </div>\n )\n}\n\nexport default DrawerContentSmartHintWordsearchComponent\n","import { connect } from 'react-redux'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { type TDispatch } from 'common_packages/assets/js/types/TDispatch'\nimport { activateSmartHint } from 'wordsearch/resources/assets/js/actions/smartHintActions'\nimport { type WordsearchAction } from 'wordsearch/resources/assets/js/actions/types'\nimport DrawerContentSmartHintWordsearchComponent from '../../components/drawers/DrawerContentSmartHintWordsearchComponent'\n\nconst mapDispatchToProps = (dispatch: TDispatch<WordsearchAction>) => ({\n onActivateSmartHint: (clueIndex: number) => {\n dispatch(activateSmartHint(clueIndex))\n },\n onGameInstructionsClick: async () => {\n await dispatch(uiActions.closeDrawer())\n await dispatch(uiActions.setDrawer({ drawer: drawerTypes.GAME_INSTRUCTIONS }))\n },\n})\n\nexport default connect(null, mapDispatchToProps)(DrawerContentSmartHintWordsearchComponent)\n","import React from 'react'\n\nconst DrawerContentFeatureInDevelopmentComponent = () => {\n return (\n <div className=\"drawer__feature-in-development drawer__inner-content\">\n Hier zijn we nog aan het bouwen! Kom later terug om te zien hoe het is geworden.\n </div>\n )\n}\n\nexport default DrawerContentFeatureInDevelopmentComponent\n","import React, { useContext } from 'react'\nimport TranslationContext from '../../../../../contexts/TranslationContext'\nimport translationGroups from '../../../../../constants/translationGroups'\n\nconst DrawerContentTermsAndConditionsComponent = () => {\n const translation = useContext(TranslationContext)\n\n return (\n <div className=\"drawer__inner-content\">\n {translation.getTranslation(translationGroups.common, 'terms-and-conditions')}\n </div>\n )\n}\n\nexport default DrawerContentTermsAndConditionsComponent\n","import React, { type ComponentProps } from 'react'\n\nconst TextButtonComponent = ({ children, className = '', ...props }: ComponentProps<'div'>) => {\n return (\n <div\n {...props}\n className={`form__text-button ${className}`}\n >\n {children}\n </div>\n )\n}\n\nexport default TextButtonComponent\n","import React, {\n useContext, useState, useEffect, useMemo, useRef,\n} from 'react'\nimport { useDispatch } from 'react-redux'\nimport { isAndroid, isTablet, isMobile } from 'react-device-detect'\nimport raw from 'rehype-raw'\nimport sanitize from 'rehype-sanitize'\nimport ReactMarkdown from 'react-markdown'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport RoundedButtonComponent from 'client/pages/common/components/buttons/RoundedButtonComponent'\nimport TextButtonComponent from 'client/pages/common/components/form/TextButtonComponent'\nimport { ThemeContext } from 'client/pages/common/components/theme/ThemeContext'\n\ntype Props = {\n skipIntro?: boolean\n}\n\nconst DrawerContentAddToHomeScreenInfoComponent = ({ skipIntro = false }: Props) => {\n const translation = useContext(TranslationContext)\n const dispatch = useDispatch()\n const okButtonRef = useRef<HTMLButtonElement>()\n\n const [onIntro, setOnIntro] = useState(!skipIntro)\n const { theme } = useContext(ThemeContext)\n\n const handleOk = () => {\n setOnIntro(false)\n }\n\n const handleCancel = () => {\n dispatch(uiActions.closeDrawer())\n }\n\n useEffect(() => {\n // remove once notifications are properly implemented\n localStorage.setItem('notificationCount', '0')\n }, [])\n\n useEffect(() => {\n if (onIntro && okButtonRef.current) {\n okButtonRef.current.focus()\n }\n }, [onIntro])\n\n const instructionText = useMemo(() => {\n let osType = 'desktop'\n if (isMobile) {\n if (isAndroid) {\n osType = 'android'\n } else {\n osType = 'ios'\n if (isTablet) {\n osType += '-tablet'\n }\n }\n }\n return translation.getRawTranslation(translationGroups.addHomescreenInfo, `text-${osType}`)\n }, [translation])\n\n const introImageSrc = theme.helpHomescreenPath.replace('{platform}', isMobile ? 'mobile' : 'desktop')\n\n if (onIntro) {\n return (\n <div className=\"drawer__inner-content drawer__content--centered drawer__add-to-homescreen-info\">\n <h1 className=\"drawer__add-to-homescreen-info__header\">{translation.getTranslation(translationGroups.addHomescreenInfo, `header-${isMobile ? 'mobile' : 'desktop'}`)}</h1>\n <div className=\"drawer__add-to-homescreen-info__top\">\n <img alt=\"intro\" src={introImageSrc} className=\"drawer__add-to-homescreen-info__top__image\" />\n </div>\n <div className=\"drawer__add-to-homescreen-info__bottom\">\n {translation.getTranslation(translationGroups.drawer, `add-to-homescreen-info-intro${isMobile ? '-mobile' : '-desktop'}`)}\n <RoundedButtonComponent\n ref={okButtonRef}\n text={translation.getTranslation(translationGroups.drawer, 'add-to-homescreen-info-button-start')}\n onClickHandler={handleOk}\n />\n <TextButtonComponent onClick={handleCancel}>\n {translation.getTranslation(translationGroups.drawer, 'add-to-homescreen-info-button-cancel')}\n </TextButtonComponent>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"drawer__inner-content drawer__add-to-homescreen-info\">\n <h1 className=\"drawer__add-to-homescreen-info__header\">\n {translation.getTranslation(translationGroups.addHomescreenInfo, `header-${isMobile ? 'mobile' : 'desktop'}`)}\n </h1>\n <div className=\"drawer__add-to-homescreen-info__instructions\">\n <ReactMarkdown rehypePlugins={[raw, sanitize]}>{instructionText}</ReactMarkdown>\n </div>\n </div>\n )\n}\n\nexport default DrawerContentAddToHomeScreenInfoComponent\n","import React from 'react'\nimport IconRadioOff from 'assets/icons/icon_radio_off.svg'\nimport IconRadioOn from 'assets/icons/icon_radio_on.svg'\nimport { useId } from 'common_packages/assets/js/hooks/useId'\n\ntype Props = {\n checked: boolean,\n value: string,\n label: string,\n onClickHandler: (value: string) => void\n}\n\nconst RadioInputComponent = ({\n checked, value, onClickHandler, label,\n}: Props) => {\n const id = useId()\n return (\n <div className=\"klubble-form-group-radio\" onClick={(e) => { e.preventDefault(); onClickHandler(value) }} role=\"button\">\n <label className=\"klubble-form-group-radio__label\" role=\"form\" htmlFor={id}>\n <input\n className=\"klubble-form-group-radio__input\"\n type=\"radio\"\n value={value}\n id={id}\n defaultChecked={checked}\n />\n <IconRadioOff className=\"klubble-form-group-radio__checkmark-off\" />\n <IconRadioOn className=\"klubble-form-group-radio__checkmark-on\" />\n {label}\n </label>\n </div>\n )\n}\nexport default RadioInputComponent\n","import { connect } from 'react-redux'\nimport { closeDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport { StoreState } from 'client/store'\nimport { TDispatch } from 'common_packages/assets/js/types/TDispatch'\nimport { PuzzleFilterAction } from 'client/actions/types'\nimport { puzzleSortingEnum } from '../../../../../enums/puzzleData'\nimport { setPuzzleSorting } from '../../../../../actions/puzzleDataActions'\nimport DrawerContentSortingComponent from '../../../components/drawer/content/DrawerContentSortingComponent'\n\nconst mapStateToProps = (state: StoreState) => ({\n puzzleSorting: state.puzzleData.puzzleSorting,\n})\n\nconst mapDispatchToProps = (dispatch: TDispatch<PuzzleFilterAction>) => ({\n setPuzzleSorting: (puzzleSortType: puzzleSortingEnum) => {\n const searchParams = new URLSearchParams(window.location.search)\n searchParams.set('sort', puzzleSortType)\n window.history.pushState({}, '', `${window.location.pathname}?${searchParams.toString()}`)\n dispatch(setPuzzleSorting(puzzleSortType))\n dispatch(closeDrawer())\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(DrawerContentSortingComponent)\n","import React, { useContext } from 'react'\nimport { puzzleSortingEnum } from '../../../../../enums/puzzleData'\nimport RadioInputComponent from '../../form/RadioInputComponent'\nimport TranslationContext from '../../../../../contexts/TranslationContext'\nimport translationGroups from '../../../../../constants/translationGroups'\n\ntype Props = {\n setPuzzleSorting: (value: puzzleSortingEnum) => void,\n puzzleSorting: puzzleSortingEnum\n}\n\nconst DrawerContentSortingComponent = ({ setPuzzleSorting, puzzleSorting }: Props) => {\n const translation = useContext(TranslationContext)\n\n const onClickHandler = (value) => {\n setPuzzleSorting(value)\n }\n\n return (\n <div onClick={(e) => e.stopPropagation()}>\n <RadioInputComponent\n checked={puzzleSorting === puzzleSortingEnum.alphabetical}\n value={puzzleSortingEnum.alphabetical}\n label={translation.getTranslation(translationGroups.puzzlePage, 'sort-alphabetically')}\n onClickHandler={onClickHandler}\n />\n <RadioInputComponent\n checked={puzzleSorting === puzzleSortingEnum.popularity}\n value={puzzleSortingEnum.popularity}\n label={translation.getTranslation(translationGroups.puzzlePage, 'sort-popularity')}\n onClickHandler={onClickHandler}\n />\n </div>\n )\n}\n\nexport default DrawerContentSortingComponent\n","import cellStatuses from 'common_packages/assets/js/constants/statuses';\n\nexport function getCellValueOrSolution(cell) {\n let value\n if (cell?.value) {\n value = cell.value\n } else if (cell?.solution && cell?.status === cellStatuses.INITIAL) {\n value = cell?.solution\n }\n return value\n}\n","import React from 'react'\nimport { connect } from 'react-redux'\nimport { getSelectedClueCells } from 'common_crossword_packages/assets/js/actions/selectionUtilities'\nimport { getCellValueOrSolution } from 'klubble_player/js/utilities/getCellValueOrSolution'\nimport { getSelectedClue } from 'common_crossword_packages/assets/js/selectors/selectionSelectors'\nimport { KEY_SEE_IMAGE } from 'common_crossword_packages/assets/js/constants/translation'\nimport GuessBarComponent from '../components/GuessBarComponent'\nimport ClueBarSeeImageComponent from '../components/clue-bar/ClueBarSeeImageComponent'\n\nconst mapStateToProps = (state) => {\n const { cells, selection, clues } = state\n\n const guessCells = getSelectedClueCells(state)\n const guess = guessCells.map((guessCell) => (getCellValueOrSolution(cells.cellData[guessCell])?.toUpperCase()))\n\n const selectedClue = getSelectedClue(selection, clues, cells)\n const clue = selectedClue === KEY_SEE_IMAGE ? <ClueBarSeeImageComponent /> : selectedClue\n\n return {\n guess,\n clue,\n }\n}\n\nexport default connect(mapStateToProps)(GuessBarComponent)\n","import React from 'react'\n\ntype Props = {\n guess: string[],\n clue: string,\n}\n\nconst GuessBarComponent = ({\n guess,\n clue,\n}: Props): JSX.Element => (\n <>\n <div className={`guess-bar${guess.length > 7 ? ' guess-bar--small' : ''}`}>\n <div className=\"guess-bar__container\">\n {guess.map((letter, index) => (\n <div className=\"guess-bar__cell\" key={String(index) + letter}>\n <div className=\"guess-bar__letter\">{letter}</div>\n </div>\n ))}\n </div>\n </div>\n <p className=\"guess-bar__clue\">{clue}</p>\n </>\n)\n\nexport default GuessBarComponent\n","import React, { useContext, useEffect, useState } from 'react'\nimport { useSelector } from 'react-redux'\nimport applePencilHelper from 'common_packages/assets/js/utilities/applePencilHelper'\nimport { languageUsesIJ } from 'common_packages/assets/js/utilities/languageUsesIJ'\nimport { CommonPuzzleStoreState } from 'common_packages/assets/js/store/types'\nimport { CommonSettingsStoreState } from 'common_packages/assets/js/reducers/settingsReducer'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { klubbleAPI } from 'client/api/common'\n\ntype Props = {\n pattern: string,\n onHintClick: (word: string[]) => () => void\n}\n\n/* The maximum amount of results that we want to display. We call gethints endpoint with MAX_AMOUNT.\nIf the gethints endpoint returns more than MAX_AMOUNT, we display a 'too many hints found' message.\nRegardless of how high we set the amount in the api call the backend will currently return a maximum of 100 */\nconst MAX_AMOUNT = 100\n\nconst SmartHintsComponent = ({ pattern, onHintClick }: Props) => {\n const { language } = useSelector<CommonPuzzleStoreState, CommonSettingsStoreState>((state) => state.settings)\n const [hints, setHints] = useState([])\n const [error, setError] = useState<string>()\n const translation = useContext(TranslationContext)\n const throwError = useAsyncError()\n\n useEffect(() => {\n const abortController = new AbortController()\n\n async function getHints() {\n try {\n const res = await klubbleAPI.get(`puzzle/gethints?pattern=${pattern}&amount=${MAX_AMOUNT}`, {\n signal: abortController?.signal,\n })\n\n const hintsFound = res.data\n if (hintsFound.length === 0) {\n setError(translation.getTranslation(translationGroups.dictionary, 'no-hints-found'))\n } else if (hintsFound.length >= MAX_AMOUNT) {\n setError(translation.getTranslation(translationGroups.dictionary, 'too-many-hints-found'))\n } else {\n setHints(hintsFound.sort())\n }\n } catch (e) {\n throwError(e, 'Error getting hints')\n }\n }\n\n if (!pattern) {\n setError(translation.getTranslation(translationGroups.dictionary, 'no-clue-selected'))\n } else {\n getHints()\n }\n return () => {\n abortController.abort()\n }\n }, [pattern, throwError, translation])\n\n if (error) {\n return (\n <div className=\"smart-hints smart-hints__error\" data-test-id=\"smart-hint-error\">\n <div>\n {error}\n </div>\n </div>\n )\n }\n return (\n <ul className=\"smart-hints\" data-test-id=\"smart-hint-dictionary\">\n {hints.map((singleHint) => {\n // convert hint to array of letters and replace Ÿ to IJ if language uses the IJ letter (Ÿ is how we receive a IJ from the API)\n const letters = singleHint.split('').map((letter) => (languageUsesIJ(language) && letter === 'Ÿ' ? 'IJ' : letter))\n\n // combine letters to a string to display in the list\n const hint = letters.join('')\n\n return (\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions\n <li\n key={hint}\n onClick={onHintClick(letters)}\n onTouchStart={applePencilHelper.handleTouchStart}\n onTouchMove={applePencilHelper.handleTouchMove}\n onTouchEnd={(e) => applePencilHelper.handleTouchEnd(e, onHintClick(letters))}\n className=\"smart-hints__hint\"\n >\n {hint}\n </li>\n )\n })}\n </ul>\n )\n}\n\nexport default SmartHintsComponent\n","import { connect } from 'react-redux'\nimport { closeDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport { getSelectedClueCells } from 'common_crossword_packages/assets/js/actions/selectionUtilities'\nimport { getCellValueOrSolution } from 'klubble_player/js/utilities/getCellValueOrSolution'\nimport { executeCellAction } from 'client/player/js/actions/actionServices/cellActionServices'\nimport SmartHintsComponent from '../components/SmartHintsComponent'\n\nconst mapStateToProps = (state) => {\n const clueCells = getSelectedClueCells(state)\n const pattern = clueCells.map((guessCell) => getCellValueOrSolution(state.cells.cellData[guessCell])?.replace('IJ', 'Ÿ') || '*').join('')\n return {\n pattern,\n }\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n onHintClick: (word) => () => {\n dispatch(executeCellAction('guessWord', word))\n dispatch(closeDrawer())\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(SmartHintsComponent)\n","import * as React from 'react'\nimport GuessBarContainer from 'klubble_player/js/containers/GuessBarContainer'\nimport SmartHintsContainer from 'klubble_player/js/containers/SmartHintsContainer'\n\nconst DrawerContentDictionaryComponent = () => (\n <div className=\"dictionary\" data-test-id=\"modal-smart-hint\">\n <div data-test-id=\"smart-hint-clues\">\n <GuessBarContainer />\n </div>\n <SmartHintsContainer />\n </div>\n)\n\nexport default DrawerContentDictionaryComponent\n","import React, { useContext, useEffect, useState } from 'react'\nimport applePencilHelper from 'common_packages/assets/js/utilities/applePencilHelper'\nimport TranslationContext from '../../../../contexts/TranslationContext'\nimport translationGroups from '../../../../constants/translationGroups'\n\ntype Props = {\n hintCellIndex?: number,\n hintCellEmpty?: boolean,\n selectCell: (number) => void,\n onGameInstructionsClick: () => void\n}\n\nconst DrawerContentSmartHintLogicComponent = ({\n hintCellIndex,\n hintCellEmpty,\n selectCell,\n onGameInstructionsClick,\n}: Props) => {\n const [bodyText, setBodyText] = useState('')\n const translation = useContext(TranslationContext)\n\n useEffect(() => {\n if (hintCellIndex !== null) {\n selectCell(hintCellIndex)\n setBodyText(`look-at-this-${hintCellEmpty ? 'empty' : 'error'}`)\n } else {\n setBodyText('not-found')\n }\n }, [hintCellIndex, hintCellEmpty, selectCell, setBodyText])\n\n return (\n <div className=\"smart-hint-logic drawer__inner-content\" data-test-id=\"modal-smart-hint\">\n {translation.getTranslation(translationGroups.drawer, `smart-hint-logic-${bodyText}`)}\n {' '}\n <a\n className=\"link\"\n onClick={onGameInstructionsClick}\n onTouchStart={applePencilHelper.handleTouchStart}\n onTouchMove={applePencilHelper.handleTouchMove}\n onTouchEnd={(e) => applePencilHelper.handleTouchEnd(e, onGameInstructionsClick)}\n >\n {translation.getTranslation(translationGroups.drawer, 'smart-hint-logic-game-instructions-link')}\n </a>\n </div>\n )\n}\n\nexport default DrawerContentSmartHintLogicComponent\n","import { connect } from 'react-redux'\nimport { selectCell } from 'common_sudoku_packages/assets/js/actions/selectionActions'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { type TDispatch } from 'common_packages/assets/js/types/TDispatch'\nimport { type AnyAction } from '@reduxjs/toolkit'\nimport DrawerContentSmartHintLogicComponent from '../../components/drawers/DrawerContentSmartHintLogicComponent'\n\nconst mapStateToProps = (props) => {\n const {\n columns, cellData, solutionPathData,\n } = props.cells\n // first, fix errors\n const firstFoundMistake = cellData.findIndex(({ solution, value }) => value !== '' && value !== solution)\n if (firstFoundMistake > -1) {\n return { hintCellIndex: firstFoundMistake, hintCellEmpty: false }\n }\n\n let solutionPathDataForGameType = [...solutionPathData]\n // If a gameTypes cellData contains notes, remove the solution paths with a RemoveCandidate action\n if (cellData.some((cell) => cell.notes)) {\n solutionPathDataForGameType = solutionPathDataForGameType\n .filter((solutionPath) => solutionPath.action !== 'RemoveCandidate')\n }\n // if no errors found, give hint based on solution path\n for (let i = 0; i < solutionPathDataForGameType.length; i += 1) {\n const solution = solutionPathDataForGameType[i]\n const index = solution.x + solution.y * columns\n\n if (cellData[index].value === '') {\n return { hintCellIndex: index, hintCellEmpty: true }\n }\n }\n\n return { hintCellIndex: null, hintCellEmpty: null }\n}\n\nconst mapDispatchToProps = (dispatch: TDispatch<AnyAction>) => ({\n selectCell: (selectedCellIndex) => {\n dispatch(selectCell({ selectedCellIndex }))\n },\n onGameInstructionsClick: async () => {\n await dispatch(uiActions.closeDrawer())\n await dispatch(uiActions.setDrawer({ drawer: drawerTypes.GAME_INSTRUCTIONS, drawerData: { drawerUseHighlightAnimation: false } }))\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(DrawerContentSmartHintLogicComponent)\n","import React, { useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { klubbleAPI } from 'client/api/common'\nimport { refreshToken } from 'client/api/authentication'\nimport { addToast, closeDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport { toastTypes } from 'common_packages/assets/js/types/toastTypes'\nimport useActiveSubscription from 'client/hooks/useActiveSubscription'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\nconst DrawerContentCancelSubscriptionComponent = () => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n const subscription = useActiveSubscription()\n\n const handleOk = async () => {\n try {\n // Send request to backend\n const { data: response } = await klubbleAPI.post('Auth/cancelpremiumsubscription', null, {\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n if (response.success) {\n // Fetch new subscription data\n refreshToken()\n\n dispatch(closeDrawer())\n dispatch(addToast({\n message: getRawTranslation(translationGroups.accountPage, 'cancelsubscription-successful'),\n type: toastTypes.SUCCESS,\n }))\n } else {\n dispatch(addToast({\n message: getRawTranslation(translationGroups.accountPage, `error-cancelsubscription-${response.message}`),\n type: toastTypes.ERROR,\n }))\n }\n } catch {\n dispatch(addToast({\n message: getTranslation(translationGroups.accountPage, 'error-cancelsubscription'),\n type: toastTypes.ERROR,\n }))\n }\n }\n\n const handleCancel = () => {\n dispatch(closeDrawer())\n }\n\n return (\n <div className=\"drawer__inner-content drawer__content--centered\">\n <h1>\n {getTranslation(translationGroups.drawer, 'cancel-subscription-title')}\n </h1>\n <p>\n {getTranslation(translationGroups.drawer, `cancel-subscription-question-${subscription?.subscriptionTypeName}`)}\n </p>\n <RoundedButtonComponent\n text={getTranslation(translationGroups.drawer, 'cancel-subscription-button-ok')}\n onClickHandler={handleOk}\n className=\"rounded-button--type-danger\"\n />\n <RoundedButtonComponent\n text={getTranslation(translationGroups.drawer, 'cancel-subscription-button-cancel')}\n onClickHandler={handleCancel}\n className=\"rounded-button--type-light\"\n />\n </div>\n )\n}\n\nexport default DrawerContentCancelSubscriptionComponent\n","import React, { useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { useHistory } from 'react-router'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\nconst DrawerContentCannotStartPuzzleComponent = () => {\n const { getTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n const history = useHistory()\n\n const handleOk = async () => {\n await dispatch(uiActions.closeDrawer())\n history.push('/')\n }\n\n return (\n <div className=\"drawer__inner-content drawer__content--centered\">\n <h1>\n {getTranslation(translationGroups.drawer, 'cannot-start-puzzle-title')}\n </h1>\n <p>\n {getTranslation(translationGroups.drawer, 'cannot-start-puzzle-body')}\n </p>\n <RoundedButtonComponent\n onClickHandler={handleOk}\n text={getTranslation(translationGroups.drawer, 'cannot-start-puzzle-ok')}\n />\n </div>\n )\n}\n\nexport default DrawerContentCannotStartPuzzleComponent\n","import React, { useContext } from 'react'\n\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { useDispatch } from 'react-redux'\nimport gameroomConnection from 'client/player/js/gameroom/gameroomConnection'\nimport { Expression } from './DrawerContentExpressComponent'\nimport ExpressionIcon from '../../expression/ExpressionIcon'\n\ninterface Props {\n expression: Expression\n}\n\nconst DrawerContentExpressItemComponent = ({ expression }: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n\n const handleClick = () => {\n gameroomConnection.sendExpression(expression)\n dispatch(uiActions.closeDrawer())\n }\n\n return (\n <li className=\"drawer__express-item\" onClick={handleClick}>\n <ExpressionIcon expression={expression} className=\"drawer__express-item__icon\" />\n <div className=\"drawer__express-item__text\">\n {getTranslation(translationGroups.expression, expression)}\n </div>\n </li>\n )\n}\n\nexport default DrawerContentExpressItemComponent\n","import React from 'react'\nimport DrawerContentExpressItemComponent from './DrawerContentExpressItemComponent'\n\nexport type Expression = 'yeah' | 'eureka' | 'welldone' | 'loveit' | 'hmm' | 'stuck' | 'haha'\n\nconst DrawerContentExpressComponent = () => (\n <div className=\"drawer__inner-content drawer__express\">\n <ul className=\"drawer__express-list\">\n <DrawerContentExpressItemComponent expression=\"yeah\" />\n <DrawerContentExpressItemComponent expression=\"eureka\" />\n <DrawerContentExpressItemComponent expression=\"welldone\" />\n <DrawerContentExpressItemComponent expression=\"loveit\" />\n <DrawerContentExpressItemComponent expression=\"hmm\" />\n <DrawerContentExpressItemComponent expression=\"stuck\" />\n <DrawerContentExpressItemComponent expression=\"haha\" />\n </ul>\n </div>\n)\n\nexport default DrawerContentExpressComponent\n","import React, { useContext, useMemo } from 'react'\nimport raw from 'rehype-raw'\nimport sanitize from 'rehype-sanitize'\nimport ReactMarkdown from 'react-markdown'\nimport { StoreState } from 'client/store'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useSelector } from 'react-redux'\nimport { CommonPuzzleStoreState } from 'common_packages/assets/js/store/types'\nimport { GameType } from 'common_packages/assets/js/types/gameDataTypes'\n\ntype Props = {\n drawerUseHighlightAnimation?: boolean\n}\n\nconst DrawerContentGameInstructionsComponent = ({ drawerUseHighlightAnimation }: Props) => {\n const translation = useContext(TranslationContext)\n\n const currentPuzzleCalendarNameLangKey = useSelector<StoreState, string | undefined>((store) => store.puzzleData?.currentPuzzleCalendar?.nameLangKey)\n const gameType = useSelector<CommonPuzzleStoreState, GameType>((store) => store.settings?.gameType)\n\n /* Important: Depending from where this gets called, we use the state from pages' redux, if not available we try state from player's redux */\n const puzzleType = useMemo(() => currentPuzzleCalendarNameLangKey ?? convertGameType(gameType), [currentPuzzleCalendarNameLangKey, gameType])\n\n const className = [\n 'drawer__inner-content',\n 'drawer__game-info',\n ...(drawerUseHighlightAnimation ? ['use-highlight-animation'] : []),\n ].join(' ')\n\n return (\n <div className={className} data-test-id=\"info-modal-text\">\n <ReactMarkdown rehypePlugins={[raw, sanitize]}>{translation.getRawTranslation(translationGroups.puzzleInstructions, puzzleType)}</ReactMarkdown>\n </div>\n )\n}\n\nexport default DrawerContentGameInstructionsComponent\n\nconst convertGameType = (gameType: GameType) => ((gameType ?? '').replace(/_/g, '-').toLowerCase())\n","import React, { useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\n// these props can be passed to `drawerData` in `setDrawer` action\nexport type Props = {\n translationKeyPart: string\n handleOk: () => void\n handleCancel?: () => void\n}\n\nconst DrawerContentGenericConfirmComponent = ({\n translationKeyPart,\n handleOk,\n handleCancel,\n}: Props) => {\n const translation = useContext(TranslationContext)\n const dispatch = useDispatch()\n\n return (\n <div className=\"drawer__inner-content drawer__content--centered\">\n <h1>\n {translation.getTranslation(translationGroups.assist, `confirm-${translationKeyPart}-title`)}\n </h1>\n <p>\n {translation.getTranslation(translationGroups.assist, `confirm-${translationKeyPart}-question`)}\n </p>\n <RoundedButtonComponent\n className=\"rounded-button--type-danger\"\n text={translation.getTranslation(translationGroups.drawer, `confirm-${translationKeyPart}-button-ok`)}\n onClickHandler={handleOk}\n data-test-id=\"button-confirm-yes\"\n />\n <RoundedButtonComponent\n className=\"rounded-button--type-light\"\n text={translation.getTranslation(translationGroups.drawer, `confirm-${translationKeyPart}-button-cancel`)}\n onClickHandler={() => { if (handleCancel) { handleCancel() } else { dispatch(uiActions.closeDrawer()) } }}\n />\n </div>\n )\n}\n\nexport default DrawerContentGenericConfirmComponent\n","import React, { ReactNode, useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { useHistory } from 'react-router'\nimport { closeDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\n// these props can be passed to `drawerData` in `setDrawer` action\nexport type Props = {\n content?: ReactNode\n contentTranslationKey?: string\n buttonText?: string\n onButtonClick?: () => void\n hideButton?: boolean\n returnUrl?: string\n}\n\n// A generic 'error message' drawer with a button home\nconst DrawerContentGenericErrorComponent = ({\n content,\n contentTranslationKey,\n buttonText,\n hideButton,\n onButtonClick,\n returnUrl = '/',\n}: Props) => {\n const dispatch = useDispatch()\n const history = useHistory()\n const { getTranslation } = useContext(TranslationContext)\n\n const handleCancel = () => {\n dispatch(closeDrawer())\n history.push(returnUrl)\n }\n\n return (\n <div className=\"drawer__generic-error drawer__inner-content\">\n {content ?? getTranslation(translationGroups.drawer, contentTranslationKey)}\n {!hideButton\n && (\n <RoundedButtonComponent\n onClickHandler={onButtonClick ?? handleCancel}\n text={buttonText ?? getTranslation(translationGroups.drawer, 'back-home')}\n inverted\n />\n ) }\n </div>\n )\n}\n\nexport default DrawerContentGenericErrorComponent\n","/* eslint-disable jsx-a11y/control-has-associated-label */\nimport React, { useContext, useRef, useState } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport IconCopy from 'assets/icons/icon_copy.svg'\nimport IconWhatsApp from 'assets/icons/platforms/icon_whatsapp.svg'\nimport IconTelegram from 'assets/icons/platforms/icon_telegram.svg'\nimport IconX from 'assets/icons/platforms/icon_x.svg'\nimport IconLink from 'assets/icons/icon_link.svg'\nimport IconMail from 'assets/icons/platforms/icon_mail.svg'\nimport IconMessenger from 'assets/icons/platforms/icon_facebook_messenger.svg'\nimport { isMobile } from 'common_packages/assets/js/utilities/devices'\nimport { addToast } from 'common_packages/assets/js/actions/uiActions'\nimport { toastTypes } from 'common_packages/assets/js/types/toastTypes'\n\ntype Props = {\n emailSubject: string\n text: string\n shareLink: string\n}\n\nenum CopyTextType {\n None,\n Link,\n Text\n}\n\n// used both for inviting another player to multiplayer\n// and gifting a puzzle to somemone\nconst SharePuzzleComponent = ({\n text, emailSubject, shareLink,\n}: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const [copied, setCopied] = useState<CopyTextType>(CopyTextType.None)\n const timeout = useRef<NodeJS.Timeout>()\n const dispatch = useDispatch()\n\n const encodedText = encodeURIComponent(text)\n\n const handleCopy = (toCopyText: string, copyTextType: CopyTextType) => {\n navigator.clipboard.writeText(toCopyText).then(() => {\n if (copied !== copyTextType) {\n clearTimeout(timeout.current)\n setCopied(copyTextType)\n timeout.current = setTimeout(() => {\n setCopied(CopyTextType.None)\n }, 3000)\n dispatch(addToast({\n message: copyTextType === CopyTextType.Text ? getTranslation(translationGroups.sharePuzzle, 'text-copied') : getTranslation(translationGroups.invite, 'link-copied'),\n type: toastTypes.SUCCESS,\n }))\n }\n })\n }\n\n return (\n <div className=\"drawer-share-puzzle\">\n <div className=\"drawer-share-puzzle__text\">{text}</div>\n <div>{getTranslation(translationGroups.sharePuzzle, 'share-via')}</div>\n <ul className=\"drawer-share-puzzle__platform-list\">\n <li className=\"drawer-share-puzzle__platform-item drawer-share-puzzle__platform-item--whatsapp\">\n <a href={`https://api.whatsapp.com/send?text=${encodedText}`} target=\"_blank\" rel=\"noopener noreferrer\">\n <IconWhatsApp className=\"drawer-share-puzzle__platform-item-icon\" />\n </a>\n </li>\n {isMobile && (\n <li className=\"drawer-share-puzzle__platform-item drawer-share-puzzle__platform-item--telegram\">\n <a href={`https://t.me/share/url?text=${encodedText}`} target=\"_blank\" rel=\"noopener noreferrer\">\n <IconTelegram className=\"drawer-share-puzzle__platform-item-icon\" />\n </a>\n </li>\n )}\n {isMobile && (\n <li className=\"drawer-share-puzzle__platform-item drawer-share-puzzle__platform-item--messenger\">\n <a href={`fb-messenger://share?link=${encodedText}`} target=\"_blank\" rel=\"noopener noreferrer\">\n <IconMessenger className=\"drawer-share-puzzle__platform-item-icon\" />\n </a>\n </li>\n )}\n <li className=\"drawer-share-puzzle__platform-item drawer-share-puzzle__platform-item--x\">\n <a href={`https://x.com/messages/compose?text=${encodedText}`} target=\"_blank\" rel=\"noopener noreferrer\">\n <IconX className=\"drawer-share-puzzle__platform-item-icon\" />\n </a>\n </li>\n <li className=\"drawer-share-puzzle__platform-item drawer-share-puzzle__platform-item--mail\">\n <a href={`mailto:?subject=${emailSubject}&body=${encodedText}`} target=\"_blank\" rel=\"noopener noreferrer\" className=\"rounded-button rounded-button--inverted\">\n <IconMail className=\"drawer-share-puzzle__platform-item-icon\" />\n </a>\n </li>\n </ul>\n <div>{getTranslation(translationGroups.sharePuzzle, 'or-copy')}</div>\n <ul className=\"drawer-share-puzzle__copy-list\">\n <li className=\"drawer-share-puzzle__copy-item drawer-share-puzzle__copy-item--copy-text\">\n <button onClick={() => handleCopy(text, CopyTextType.Text)} className=\"rounded-button rounded-button--inverted\" type=\"button\">\n <IconCopy className=\"drawer-share-puzzle__copy-item-icon\" />\n <span className=\"drawer-share-puzzle__copy-item-text\">\n {getTranslation(translationGroups.sharePuzzle, 'full-text')}\n </span>\n </button>\n </li>\n <li className=\"drawer-share-puzzle__copy-item drawer-share-puzzle__copy-item--copy-link\">\n <button onClick={() => handleCopy(shareLink, CopyTextType.Link)} className=\"rounded-button rounded-button--inverted\" type=\"button\">\n <IconLink className=\"drawer-share-puzzle__copy-item-icon\" />\n <span className=\"drawer-share-puzzle__copy-item-text\">\n {getTranslation(translationGroups.sharePuzzle, 'link-only')}\n </span>\n </button>\n </li>\n </ul>\n </div>\n )\n}\n\nexport default SharePuzzleComponent\n","import React, { useContext } from 'react'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport SharePuzzleComponent from './SharePuzzleComponent'\n\ntype Props = {\n shareLink: string\n}\n\n// This modal is shown when user wants to invite a friend to play the puzzle she just finished\n// when on desktop or the native `navigator.share` api is not available\nconst DrawerContentGiftPuzzleComponent = ({ shareLink }: Props) => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n\n return (\n <div className=\"drawer__inner-content drawer-gift-puzzle\">\n <SharePuzzleComponent\n shareLink={shareLink}\n emailSubject={getTranslation(translationGroups.invite, 'gift-puzzle-email-subject')}\n text={getRawTranslation(translationGroups.invite, 'gift-puzzle-share-text').replace(/{link}/g, shareLink)}\n />\n </div>\n )\n}\n\nexport default DrawerContentGiftPuzzleComponent\n","import React, { useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\nconst DrawerContentHideOnscreenKeyboard = () => {\n const translation = useContext(TranslationContext)\n const dispatch = useDispatch()\n\n const handleOk = async () => {\n await dispatch(uiActions.closeDrawer())\n /* Remove window.localStorage.forceModeUserChoice, because the user has indicated not wanting to force the ui mode */\n window.localStorage.removeItem('forceModeUserChoice')\n /* Use timeout here to make sure the closeDrawer action is processed in the localStorage with redux-persist.\n After that it's safe to reload (and make the backup of the localstorage)\n For this, 1ms would be enough, but set it to 100 to give the ui some time to close the drawer visually */\n\n setTimeout(() => window.location.reload(), 100)\n }\n\n const handleCancel = () => {\n dispatch(uiActions.closeDrawer())\n }\n\n return (\n <div className=\"drawer__inner-content drawer__content--centered\">\n <h1>\n {translation.getTranslation(translationGroups.drawer, 'hide-keyboard-title')}\n </h1>\n <p>\n {translation.getTranslation(translationGroups.drawer, 'hide-keyboard-body')}\n </p>\n <RoundedButtonComponent\n onClickHandler={handleOk}\n text={translation.getTranslation(translationGroups.drawer, 'confirm-hide-keyboard')}\n className=\"rounded-button--type-success\"\n />\n <RoundedButtonComponent\n onClickHandler={handleCancel}\n text={translation.getTranslation(translationGroups.drawer, 'cancel-hide-keyboard')}\n className=\"rounded-button--type-light\"\n />\n </div>\n )\n}\n\nexport default DrawerContentHideOnscreenKeyboard\n","import React, { useContext, useEffect } from 'react'\nimport { StoreState } from 'client/store'\nimport * as timerActions from 'common_packages/assets/js/actions/timerActions'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { DrawerType } from 'common_packages/assets/js/types/drawerTypes'\nimport SharePuzzleComponent from './SharePuzzleComponent'\n\ntype Props = {\n shareLink: string\n}\n\n// This modal is shown when user wants to invite a friend to a MP puzzle\n// when on desktop or the native `navigator.share` api is not available\nconst DrawerContentInvitePuzzleComponent = ({ shareLink }: Props) => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n const drawer = useSelector<StoreState, DrawerType>((store) => store.ui.drawer)\n\n useEffect(() => {\n if (!drawer) {\n // if drawer is closed, resume timer\n dispatch(timerActions.resumeTimer())\n }\n }, [dispatch, drawer])\n\n return (\n <div className=\"drawer__inner-content drawer-invite-puzzle\">\n <SharePuzzleComponent\n shareLink={shareLink}\n emailSubject={getTranslation(translationGroups.invite, 'mp-puzzle-email-subject')}\n text={getRawTranslation(translationGroups.invite, 'click-here-to-join').replace(/{link}/g, shareLink)}\n />\n </div>\n )\n}\n\nexport default DrawerContentInvitePuzzleComponent\n","import { useDispatch, useSelector } from 'react-redux'\nimport React, { useContext, useEffect, useRef } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport raw from 'rehype-raw'\nimport sanitize from 'rehype-sanitize'\nimport usePuzzleType from 'client/hooks/usePuzzleType'\nimport usePuzzleSelectedLevel from 'client/hooks/usePuzzleSelectedLevel'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { closeDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport * as puzzleDataActions from 'client/actions/puzzleDataActions'\nimport { Level, levels as difficultyLevels } from 'client/interfaces/IPuzzleCalendar'\nimport { StoreState } from 'client/store'\nimport { FeaturedPuzzleType } from 'client/types/FeaturedPuzzleType'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport RadioInputComponent from '../../form/RadioInputComponent'\n\nexport type Props = {\n puzzleTypeId: number,\n miniPuzzleTypeId?: number\n}\n\nconst DrawerContentLevelComponent = ({ puzzleTypeId, miniPuzzleTypeId }: Props) => {\n const { getRawTranslation, getTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n const puzzleType = usePuzzleType(puzzleTypeId)\n const miniPuzzleType = usePuzzleType(miniPuzzleTypeId)\n const selectedLevel = usePuzzleSelectedLevel(puzzleTypeId)\n const featuredPuzzleTypes = useSelector<StoreState, FeaturedPuzzleType[]>((state) => state.puzzleData.featuredPuzzleTypes)\n const previousSelectedLevel = useRef(selectedLevel)\n const throwError = useAsyncError()\n\n useEffect(() => {\n const previousSelectedLevelCurrent = previousSelectedLevel.current\n return () => {\n try {\n const featuredPuzzleTypeChanged = featuredPuzzleTypes.some((fPT) => [puzzleTypeId, miniPuzzleTypeId].includes(fPT.puzzleTypeId))\n if (selectedLevel !== previousSelectedLevelCurrent && featuredPuzzleTypeChanged) {\n // changed the level of a puzzle type shown in the featured cards\n // on the homepage so fetch these again\n dispatch(puzzleDataActions.getFeaturedPuzzleTypes())\n }\n } catch (e) {\n throwError(e, 'Error getting featured puzzles')\n }\n }\n }, [dispatch, featuredPuzzleTypes, miniPuzzleTypeId, puzzleTypeId, selectedLevel, throwError])\n\n if (!puzzleType) {\n return null\n }\n const { levels } = puzzleType\n\n const onClickHandler = (value: Level) => {\n dispatch(puzzleDataActions.savePuzzleSettings({ puzzleTypeId, selectedLevel: value }))\n\n if (miniPuzzleTypeId) {\n let closestMiniPuzzleLevel = miniPuzzleType.levels[0]\n miniPuzzleType.levels.forEach((level) => {\n if (difficultyLevels.indexOf(level) <= difficultyLevels.indexOf(value)) {\n closestMiniPuzzleLevel = level\n }\n })\n dispatch(puzzleDataActions.savePuzzleSettings({ puzzleTypeId: miniPuzzleTypeId, selectedLevel: closestMiniPuzzleLevel }))\n }\n dispatch(closeDrawer())\n }\n\n if (levels?.length < 2) {\n return (\n <div className=\"drawer__content-level\">\n <div className=\"drawer__content-level__no-other-levels\">\n {/* Support for soft hyphens */ }\n <ReactMarkdown rehypePlugins={[raw, sanitize]}>{getRawTranslation(translationGroups.difficulty, 'no-other-levels')}</ReactMarkdown>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"drawer__content-level\">\n {levels?.map((level) => (\n <RadioInputComponent\n key={level}\n checked={level === selectedLevel}\n value={level}\n label={getTranslation(translationGroups.difficulty, level)}\n onClickHandler={onClickHandler}\n />\n ))}\n </div>\n )\n}\n\nexport default DrawerContentLevelComponent\n","import React, { useMemo } from 'react'\n\nimport { NotificationIconType } from 'client/reducers/notificationsReducer'\nimport IconPuzzle from 'client/assets/icons/icon_puzzle.svg'\n\ninterface Props {\n icon: NotificationIconType\n}\n\nconst DrawerContentNotificationItemIconComponent = ({ icon = 'puzzle' }: Props): JSX.Element => {\n const content = useMemo(() => {\n switch (icon) {\n case 'klubble':\n case 'smile':\n return <></> // This was a old Klubble icon, it was removed as of changing to Denksport PLAY\n case 'puzzle':\n default:\n return <IconPuzzle />\n }\n }, [icon])\n\n return (\n <div className={`drawer__notifications-item-icon-${icon} drawer__notifications-item-icon`}>\n {content}\n </div>\n )\n}\n\nexport default DrawerContentNotificationItemIconComponent\n","import React, { useEffect } from 'react'\n\nimport { NotificationState } from 'client/reducers/notificationsReducer'\nimport { StoreState } from 'client/store'\nimport { useSelector } from 'react-redux'\nimport { format, register } from 'timeago.js'\nimport nl from 'timeago.js/lib/lang/nl'\nimport DrawerContentNotificationItemIconComponent from './DrawerContentNotificationItemIconComponent'\n\ninterface Props {\n content: NotificationState\n}\n\nconst DrawerContentNotificationItemComponent = ({ content }: Props): JSX.Element => {\n const language = useSelector<StoreState, string>((state) => state.user.data.language)\n\n useEffect(() => {\n // eslint-disable-next-line global-require, import/no-dynamic-require, @typescript-eslint/no-var-requires\n // const nl = require(`timeago.js/lib/lang/${language}`)\n register(language, nl)\n }, [language])\n\n return (\n <li className={`drawer__notifications-item${content.unread ? ' drawer__notifications-item-unread' : ''}`}>\n <div className=\"drawer__notifications-item-left\">\n <img src=\"https://placeimg.com/56/56/people\" className=\"drawer__notifications-item-image\" alt={content.author} />\n <DrawerContentNotificationItemIconComponent icon={content.icon} />\n </div>\n <div className=\"drawer__notifications-item-right\">\n <div className=\"drawer__notifications-item-content\">\n <span className=\"drawer__notifications-item-author\">\n {content.author}\n </span>\n {' '}\n {content.langKey}\n </div>\n <div className=\"drawer__notifications-item-date\">\n { format(content.date, language)}\n <span className=\"drawer__notifications-item-unread-indicator\" />\n </div>\n </div>\n </li>\n )\n}\n\nexport default DrawerContentNotificationItemComponent\n","import React, { useContext } from 'react'\n\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useSelector } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport { NotificationsState } from 'client/reducers/notificationsReducer'\nimport RoundedButtonComponent from 'client/pages/common/components/buttons/RoundedButtonComponent'\nimport DrawerContentNotificationItemComponent from './DrawerContentNotificationItemComponent'\n\nconst DrawerContentNotificationsComponent = () => {\n const { getTranslation } = useContext(TranslationContext)\n\n const notifications = useSelector<StoreState, NotificationsState>((state) => state.notifications)\n\n return (\n <div className=\"drawer__inner-content drawer__notifications\">\n <ul className=\"drawer__notifications-list\">\n {notifications.map((n) => <DrawerContentNotificationItemComponent key={n.date?.toString()} content={n} />)}\n </ul>\n <RoundedButtonComponent\n inverted\n text={getTranslation(translationGroups.common, 'clear-notifications')}\n />\n </div>\n )\n}\n\nexport default DrawerContentNotificationsComponent\n","import React, { useMemo } from 'react'\nimport { Player } from 'client/types/Player'\nimport PlayerAvatarComponent from 'client/player/js/components/gameroom/PlayerAvatarComponent'\nimport PuzzleInviteButtonComponent from 'client/player/js/components/header/PuzzleInviteButtonComponent'\nimport { gameStatus } from 'common_packages/assets/js/types/gameStatusTypes'\nimport { useSelector } from 'react-redux'\nimport { store } from 'client/store'\nimport { CommonKlubblePuzzleStoreState } from 'client/player/js/types/store'\n\ninterface Props {\n players: Player[]\n}\n\nconst DrawerContentPlayerListComponent = ({ players }: Props) => {\n const playerCount = useSelector<CommonKlubblePuzzleStoreState, number>((state) => state.gameroom.players?.length)\n const puzzleType = useSelector<CommonKlubblePuzzleStoreState, string>((state) => state.settings.gameType)\n const status = useSelector<CommonKlubblePuzzleStoreState>((puzzleStore) => puzzleStore.gameStatus.status)\n const isPlaying = status === gameStatus.IS_PLAYING\n\n const canInviteMore = useMemo(() => {\n const { puzzleTypes } = store.getState().puzzleData\n const puzzleTypeDefinition = puzzleTypes.find((pT) => pT.puzzleType === puzzleType)\n return puzzleTypeDefinition?.maxPlayers > playerCount ?? false\n }, [playerCount, puzzleType])\n\n return (\n <div className=\"drawer__inner-content drawer__player-list\">\n <ul className=\"drawer__player-list-players\">\n {players.map((p) => (\n <li className=\"drawer__player-list-players-item\" key={p.playerNumber}>\n <div className=\"drawer__player-list-players-item-avatar\">\n <PlayerAvatarComponent player={p} />\n </div>\n <div className=\"drawer__player-list-players-item-name\">\n {p.displayName}\n </div>\n </li>\n ))}\n </ul>\n { canInviteMore && isPlaying && (\n <div className=\"drawer__player-list-invite\">\n <PuzzleInviteButtonComponent className=\"drawer__player-list-invite-button\" />\n </div>\n )}\n </div>\n )\n}\n\nexport default DrawerContentPlayerListComponent\n","import React, { useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { useHistory } from 'react-router'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\nconst DrawerContentPuzzleFinishedWithoutContribution = () => {\n const { getTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n const history = useHistory()\n\n const handleOk = async () => {\n await dispatch(uiActions.closeDrawer())\n history.push('/')\n }\n\n return (\n <div className=\"drawer__inner-content drawer__content--centered\" id=\"puzzle-finished-without-contribution\">\n <h1>\n {getTranslation(translationGroups.drawer, 'puzzle-finished-without-contribution-title')}\n </h1>\n <p>\n {getTranslation(translationGroups.drawer, 'puzzle-finished-without-contribution-body')}\n </p>\n <RoundedButtonComponent\n onClickHandler={handleOk}\n text={getTranslation(translationGroups.drawer, 'puzzle-finished-without-contribution-ok')}\n />\n </div>\n )\n}\n\nexport default DrawerContentPuzzleFinishedWithoutContribution\n","import React, { useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { saveFirstName } from 'client/actions/userActions'\nimport * as yup from 'yup'\nimport { SubmitHandler, useForm } from 'react-hook-form'\nimport { yupResolver } from '@hookform/resolvers/yup'\nimport { alphanumeric, MAX_USERNAME_LENGTH } from 'client/utilities/userInput'\nimport InputComponent from '../../form/InputComponent'\nimport SubmitButtonComponent from '../../form/SubmitButtonComponent'\n\nexport type Inputs = {\n name: string\n}\n\nconst DrawerContentSetPlayerNameComponent = () => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n\n const handleOk: SubmitHandler<Inputs> = async (data) => {\n dispatch(saveFirstName(data.name))\n dispatch(uiActions.closeDrawer())\n }\n\n const schema = yup.object({}).shape({\n name: yup.string()\n .trim(getTranslation(translationGroups.error, 'required-field-generic'))\n .required(getTranslation(translationGroups.error, 'required-field-generic'))\n .matches(alphanumeric, {\n message: getTranslation(translationGroups.error, 'invalid-input-special-chars'),\n })\n .max(MAX_USERNAME_LENGTH, getRawTranslation(translationGroups.form, 'error-max-chars-used').replace('{charsLimit}', MAX_USERNAME_LENGTH.toString())),\n })\n const form = useForm<Inputs>({\n resolver: yupResolver(schema),\n })\n\n const {\n handleSubmit,\n } = form\n\n return (\n <div className=\"drawer__inner-content drawer__set-player-name\">\n <form onSubmit={handleSubmit(handleOk)}>\n <h1>\n {getTranslation(translationGroups.drawer, 'set-player-name-initial-title')}\n </h1>\n <p>\n {getTranslation(translationGroups.drawer, 'set-player-name-initial-instruction')}\n </p>\n <InputComponent\n name=\"name\"\n label=\"\"\n type=\"text\"\n showValidatorError\n form={form}\n />\n <SubmitButtonComponent\n form={form}\n label={getTranslation(translationGroups.drawer, 'set-player-name-initial-ok')}\n />\n </form>\n </div>\n )\n}\n\nexport default DrawerContentSetPlayerNameComponent\n","import React, { useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport forceModes from 'common_packages/assets/js/constants/forceModes'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\nconst DrawerContentShowOnscreenKeyboard = () => {\n const translation = useContext(TranslationContext)\n const dispatch = useDispatch()\n\n const handleOk = async () => {\n await dispatch(uiActions.closeDrawer())\n /* Set forceModeUserChoice and reload, so that getIdentifiers will be able to read forceModeUserChoice from localstorage.\n This will lead to getIdentifiers().forcemode to be 'mobile', causing the player to display in mobile mode.\n Also, window.localStorage.forceModeUserChoice is read by other parts of the code to determine whether or not to show\n a button giving the user the chance to exit from forcemode */\n window.localStorage.forceModeUserChoice = forceModes.mobile\n /* Use timeout here to make sure the closeDrawer action is processed in the localStorage with redux-persist.\n After that it's safe to reload (and make the backup of the localstorage)\n For this, 1ms would be enough, but set it to 100 to give the ui some time to close the drawer visually */\n setTimeout(() => window.location.reload(), 100)\n }\n\n const handleCancel = () => {\n dispatch(uiActions.closeDrawer())\n }\n\n return (\n <div className=\"drawer__inner-content drawer__content--centered\">\n <h1>\n {translation.getTranslation(translationGroups.drawer, 'show-keyboard-title')}\n </h1>\n <p>\n {translation.getTranslation(translationGroups.drawer, 'show-keyboard-body')}\n </p>\n <RoundedButtonComponent\n onClickHandler={handleOk}\n text={translation.getTranslation(translationGroups.drawer, 'confirm-show-keyboard')}\n className=\"rounded-button--type-success\"\n />\n <RoundedButtonComponent\n onClickHandler={handleCancel}\n text={translation.getTranslation(translationGroups.drawer, 'cancel-show-keyboard')}\n className=\"rounded-button--type-light\"\n />\n </div>\n )\n}\n\nexport default DrawerContentShowOnscreenKeyboard\n","import React, {\n useContext, useMemo,\n} from 'react'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport useConfig from 'client/hooks/useConfig'\nimport { SubscriptionType } from 'client/enums/SubscriptionType'\nimport { useSelector } from 'react-redux'\nimport { type StoreState } from 'client/store'\nimport { type UserData } from 'client/reducers/userReducer'\n\ntype Props = {\n subscriptionType: SubscriptionType // is this even needed?\n className?: string\n}\n\nconst PaymentSubscriptionUSPsComponent = ({ subscriptionType, className: propsClassName }: Props) => {\n const { getRawTranslation } = useContext(TranslationContext)\n const { lightTrialDaysText, extendedTrialDaysText } = useConfig()\n const freeDays = subscriptionType === SubscriptionType.extendedTrial ? extendedTrialDaysText : lightTrialDaysText\n\n // show texts about the discount you receive due to having print subscription\n const { hasRunningPrint } = useSelector<StoreState, UserData>((state) => state.user?.data) ?? {}\n\n const translationKey = useMemo(() => {\n return [\n 'subscription-type-usp',\n subscriptionType.toLowerCase(),\n ...(hasRunningPrint ? ['print-discount'] : []),\n ].join('-')\n }, [hasRunningPrint, subscriptionType])\n\n const listItems = useMemo(() => {\n const list = getRawTranslation(translationGroups.common, translationKey)\n .replace(/{days}/g, freeDays)\n .split('\\n') ?? []\n\n return list.map((item) => (\n <li className=\"info-list__element\" key={item}>\n <span className=\"info-list__divider\">•</span>\n {item}\n </li>\n ))\n }, [getRawTranslation, translationKey, freeDays])\n\n const className = [\n 'subscription-usps',\n 'info-list',\n propsClassName,\n ].join(' ')\n\n return (\n <ul className={className}>\n {listItems}\n </ul>\n )\n}\n\nexport default PaymentSubscriptionUSPsComponent\n","import React from 'react'\nimport { SubscriptionType } from 'client/enums/SubscriptionType'\nimport { PaymentPeriod } from '../PaymentStepsComponent'\nimport PaymentSubscriptionUSPsComponent from '../usp/SubscriptionUSPsComponent'\nimport ChoosePaymentPeriodComponent from './ChoosePaymentPeriodComponent'\n\ntype Props = {\n selectedPaymentPeriodId: PaymentPeriod\n onPaymentPeriodIdChange: (paymentPeriodId: PaymentPeriod) => void\n canStartTrial: boolean\n onNext?: () => void\n className?: string\n}\n\nconst ChooseSubscriptionComponent = ({\n selectedPaymentPeriodId,\n onPaymentPeriodIdChange,\n canStartTrial,\n onNext,\n className,\n}: Props) => (\n <div className={`choose-subscription ${className ?? ''}`}>\n <div className=\"choose-subscription__usps-container\">\n <PaymentSubscriptionUSPsComponent\n subscriptionType={SubscriptionType.premium}\n className=\"choose-subscription__usps\"\n />\n </div>\n <ChoosePaymentPeriodComponent\n selectedPaymentPeriodId={selectedPaymentPeriodId}\n canStartTrial={canStartTrial}\n onPaymentPeriodIdChange={onPaymentPeriodIdChange}\n onNext={onNext}\n />\n </div>\n)\n\nexport default ChooseSubscriptionComponent\n","import React, { useState, useContext } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useHistory } from 'react-router'\nimport { PaymentPeriod } from 'client/pages/payment_input/PaymentStepsComponent'\nimport { StoreState } from 'client/store'\nimport ChooseSubscriptionComponent from 'client/pages/payment_input/choose_subscription/ChooseSubscriptionComponent'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\nconst DrawerContentSubscribeComponent = () => {\n const dispatch = useDispatch()\n const history = useHistory()\n const { getTranslation } = useContext(TranslationContext)\n\n const [paymentPeriodId, setPaymentPeriodId] = useState<PaymentPeriod>(1)\n const canStartTrial = useSelector<StoreState, boolean>((state) => state.user?.data?.canStartTrial)\n\n const handlePaymentPeriodIdChange = (id: PaymentPeriod) => {\n setPaymentPeriodId(id)\n }\n\n const gotoPaymentFlow = () => {\n dispatch(uiActions.closeDrawer())\n history.push({\n pathname: '/subscribe',\n state: { paymentPeriodId },\n })\n }\n\n const gotoSelectPlan = () => {\n dispatch(uiActions.closeDrawer())\n history.push('/subscribe')\n }\n\n return (\n <div className=\"drawer-subscribe drawer__inner-content\">\n <ChooseSubscriptionComponent\n selectedPaymentPeriodId={paymentPeriodId}\n canStartTrial={canStartTrial}\n onPaymentPeriodIdChange={handlePaymentPeriodIdChange}\n onNext={gotoPaymentFlow}\n className=\"drawer-subscribe__choose-subscription\"\n />\n <RoundedButtonComponent\n className=\"drawer-subscribe__select-plan-button\"\n buttonType=\"secondary\"\n text={getTranslation(translationGroups.onboarding, 'select-plan')}\n onClickHandler={gotoSelectPlan}\n />\n </div>\n )\n}\n\nexport default DrawerContentSubscribeComponent\n","import React, { useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { useHistory } from 'react-router'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\nconst DrawerContentNeedToRegisterComponent = () => {\n const translation = useContext(TranslationContext)\n const dispatch = useDispatch()\n const history = useHistory()\n\n const handleOk = async () => {\n dispatch(uiActions.closeDrawer())\n history.push({\n pathname: '/register',\n search: '?pack=true',\n state: { afterRegistrationPath: '/puzzle-packs' },\n })\n }\n\n const handleCancel = () => {\n dispatch(uiActions.closeDrawer())\n }\n\n return (\n <div className=\"drawer__inner-content\">\n <h1>\n {translation.getTranslation(translationGroups.drawer, 'need-to-register-title')}\n </h1>\n <p>\n {translation.getTranslation(translationGroups.drawer, 'need-to-register-body')}\n </p>\n <RoundedButtonComponent\n text={translation.getTranslation(translationGroups.drawer, 'need-to-register-button-ok')}\n onClickHandler={handleOk}\n />\n <RoundedButtonComponent\n text={translation.getTranslation(translationGroups.drawer, 'need-to-register-button-cancel')}\n onClickHandler={handleCancel}\n className=\"rounded-button--type-light\"\n />\n </div>\n )\n}\n\nexport default DrawerContentNeedToRegisterComponent\n","import React, { useContext, useMemo } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { useHistory } from 'react-router'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { StoreState } from 'client/store'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\nconst DrawerContentUpgradeSubscriptionComponent = () => {\n const translation = useContext(TranslationContext)\n const dispatch = useDispatch()\n const blockPlayer = useSelector<StoreState, boolean>((store) => store.ui.drawerData?.blockPlayer)\n const history = useHistory()\n\n const listItems = useMemo(() => {\n const list = translation.getRawTranslation(translationGroups.drawer, 'upgrade-subscription-usp-list').split('\\n') ?? []\n return list.map((item) => (\n <li className=\"info-list__element\" key={item}>\n <span className=\"info-list__divider\">•</span>\n {item}\n </li>\n ))\n }, [translation])\n\n const handleOk = async () => {\n history.push({\n pathname: '/upgrade',\n })\n }\n\n const handleCancel = () => {\n if (blockPlayer) {\n /* if user does not have permission to play a puzzle, but still lands on the player url,\n this drawer is shown with extra drawerData: blockPlayer = true,\n in which case we redirect to home on cancel\n */\n history.push('/')\n }\n dispatch(uiActions.closeDrawer())\n }\n\n return (\n <div className=\"drawer__inner-content\">\n <h1>\n {translation.getTranslation(translationGroups.drawer, 'upgrade-subscription-title')}\n </h1>\n <p>\n {translation.getTranslation(translationGroups.drawer, `upgrade-subscription-intro${blockPlayer ? '-puzzle-no-longer-playable' : ''}`)}\n </p>\n <ul className=\"info-list\">\n {listItems}\n </ul>\n <RoundedButtonComponent\n text={translation.getTranslation(translationGroups.drawer, 'upgrade-subscription-button-ok')}\n onClickHandler={handleOk}\n />\n <RoundedButtonComponent\n text={translation.getTranslation(translationGroups.drawer, 'upgrade-subscription-button-cancel')}\n onClickHandler={handleCancel}\n className=\"rounded-button--type-light\"\n />\n </div>\n )\n}\n\nexport default DrawerContentUpgradeSubscriptionComponent\n","import React, { useContext, useMemo } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { useHistory } from 'react-router'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { StoreState } from 'client/store'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\nconst DrawerContentUpgradeSubscriptionPremiumOnlyComponent = () => {\n const translation = useContext(TranslationContext)\n const dispatch = useDispatch()\n const history = useHistory()\n const tryNowUrl = useSelector<StoreState, string>((store) => store.ui.drawerData?.tryNowUrl)\n\n const listItems = useMemo(() => {\n const list = translation.getRawTranslation(translationGroups.drawer, 'upgrade-subscription-usp-list').split('\\n') ?? []\n return list.map((item) => (\n <li className=\"info-list__element\" key={item}>\n <span className=\"info-list__divider\">•</span>\n {item}\n </li>\n ))\n }, [translation])\n\n const handleOk = async () => {\n history.push({\n pathname: '/upgrade',\n })\n }\n\n const handleTry = () => {\n dispatch(uiActions.closeDrawer())\n history.push(`/pgg/${tryNowUrl}`)\n }\n\n return (\n <div className=\"drawer__inner-content\">\n <h1>\n {translation.getTranslation(translationGroups.drawer, 'upgrade-subscription-title')}\n </h1>\n <p>\n {translation.getTranslation(translationGroups.drawer, 'upgrade-subscription-premium-only-intro')}\n </p>\n <ul className=\"info-list\">\n {listItems}\n </ul>\n <RoundedButtonComponent\n text={translation.getTranslation(translationGroups.drawer, 'upgrade-subscription-button-ok')}\n onClickHandler={handleOk}\n />\n <RoundedButtonComponent\n text={translation.getTranslation(translationGroups.drawer, 'upgrade-subscription-premium-only-button-try')}\n onClickHandler={handleTry}\n className=\"rounded-button--type-warning\"\n />\n </div>\n )\n}\n\nexport default DrawerContentUpgradeSubscriptionPremiumOnlyComponent\n","import React from 'react'\nimport PlayerComponent from 'client/player/js/components/PlayerComponent'\n\nconst DrawerContentViewPuzzleComponent = () => {\n return (\n <div className=\"drawer__view-puzzle\">\n <PlayerComponent isInViewPuzzleMode />\n </div>\n )\n}\nexport default DrawerContentViewPuzzleComponent\n","import React, { useContext } from 'react'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport useShareDialog from 'client/hooks/useShareDialog'\nimport SharePuzzleComponent from './SharePuzzleComponent'\n\ntype Props = {\n shareLink: string\n}\n\n// This modal is shown when user wants to share (the result of) a finished puzzle\n// when on desktop or the native `navigator.share` api is not available\nconst DrawerContentShareResultComponent = ({ shareLink }: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const { shareResultText } = useShareDialog()\n\n return (\n <div className=\"drawer__inner-content drawer-share-result\">\n <SharePuzzleComponent\n shareLink={shareLink}\n emailSubject={getTranslation(translationGroups.shareResult, 'email-subject')}\n text={shareResultText.replace(/{link}/g, shareLink)}\n />\n </div>\n )\n}\n\nexport default DrawerContentShareResultComponent\n","import React, {\n FormEvent, useContext, useMemo, useState,\n} from 'react'\nimport { useDispatch } from 'react-redux'\nimport * as yup from 'yup'\nimport { yupResolver } from '@hookform/resolvers/yup'\nimport { ApiFormResult, klubbleAPI } from 'client/api/common'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport InputComponent from 'client/pages/common/components/form/InputComponent'\nimport { SubmitHandler, useForm } from 'react-hook-form'\nimport { processValidationErrors } from 'client/utilities/form'\nimport { toastTypes } from 'common_packages/assets/js/types/toastTypes'\nimport { getDisplayModeApp } from 'client/utilities/getDisplayModeApp'\nimport AppDisplayModes from 'client/constants/appDisplayModes'\nimport { deviceType } from 'react-device-detect'\nimport { getLastCreatedStorages } from 'common_packages/assets/js/utilities/persistencyStorage'\nimport { MAX_REPORT_BUG_MESSAGE, MAX_FILE_SIZE_MB, SUPPORTED_UPLOAD_FORMATS } from 'client/utilities/userInput'\nimport SubmitButtonComponent from '../../form/SubmitButtonComponent'\n\ntype Inputs = {\n message: string\n attachment: File\n consent: boolean\n}\n\ntype DeviceInfo = {\n message: string\n consent: string\n deviceType: string\n standalone: string\n attachment: Blob\n indexedDbBytesUsage: string\n localStorageBytesUsed: string\n klubbleVersion: string\n}\n\nconst DrawerContentReportBugComponent = () => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n const [fileToUpload, setFileToUpload] = useState<Blob>(null)\n\n const schema = yup.object().shape({\n message: yup\n .string()\n .required(getTranslation(translationGroups.error, 'required-field'))\n .max(MAX_REPORT_BUG_MESSAGE, getRawTranslation(translationGroups.form, 'error-max-chars-used').replace('{charsLimit}', MAX_REPORT_BUG_MESSAGE.toString())),\n consent: yup\n .boolean()\n .oneOf([true], getTranslation(translationGroups.error, 'terms-must-be-agreed')),\n }, [])\n\n const form = useForm<Inputs>({\n resolver: yupResolver(schema),\n defaultValues: getDefaults(),\n })\n\n const {\n handleSubmit, setValue, setError, clearErrors,\n } = form\n\n const handleChangeattachment = (e: FormEvent<HTMLInputElement>) => {\n const file = e.currentTarget.files?.[0]\n if (!file) {\n // chrome clears the input on cancel\n setFileToUpload(null)\n return\n }\n\n const fileSizeMb = file.size / 1024 / 1024\n let fileUploadErrorMessage: string\n if (fileSizeMb > MAX_FILE_SIZE_MB) {\n fileUploadErrorMessage = getTranslation(translationGroups.form, 'report-bug-file-too-big').replace(/{maxFileSizeMb}/g, MAX_FILE_SIZE_MB.toString())\n }\n if (SUPPORTED_UPLOAD_FORMATS.indexOf(file.type.toLowerCase()) < 0) {\n fileUploadErrorMessage = getTranslation(translationGroups.form, 'report-bug-file-type-unsupported')\n }\n if (fileUploadErrorMessage) {\n setError('attachment', { type: 'custom', message: fileUploadErrorMessage })\n setValue('attachment', null)\n setFileToUpload(null)\n dispatch(uiActions.addToast({\n message: fileUploadErrorMessage,\n type: toastTypes.ERROR,\n }))\n } else {\n setFileToUpload(file)\n clearErrors('attachment')\n }\n }\n\n const clearFileButton = useMemo(() => {\n if (fileToUpload) {\n const handleClearFile = () => {\n setValue('attachment', null)\n setFileToUpload(null)\n }\n\n return (\n <div\n className=\"form__field-secondary-label drawer-reportbug__clear-file\"\n onClick={handleClearFile}\n role=\"button\"\n >\n {getTranslation(translationGroups.form, 'clear-file')}\n </div>\n )\n }\n return null\n }, [fileToUpload, getTranslation, setValue])\n\n const onValid: SubmitHandler<Inputs> = async (data: Inputs) => {\n try {\n const formData = new FormData()\n const storages = JSON.parse(getLastCreatedStorages()) || []\n formData.append('attachment', fileToUpload)\n formData.append('message', data.message)\n formData.append('standalone', JSON.stringify(getDisplayModeApp() !== AppDisplayModes.browserTab))\n formData.append('consent', JSON.stringify(data.consent))\n formData.append('deviceType', deviceType)\n formData.append('lastCreatedStoragesSize', storages.length)\n formData.append('localStorageBytesUsage', JSON.stringify(new Blob(Object.values(localStorage))?.size))\n let indexedDbBytesUsage = 'unknown'\n if (navigator.storage && navigator.storage.estimate) {\n const { usage, quota } = await navigator.storage.estimate()\n indexedDbBytesUsage = `${usage}/${quota}`\n }\n formData.append('indexedDbBytesUsage', indexedDbBytesUsage)\n formData.append('klubbleVersion', process.env.KLUBBLE_VERSION)\n const res = await klubbleAPI.post<ApiFormResult<boolean, DeviceInfo>>('Auth/deviceinfo', formData, {\n headers: {\n 'Content-Type': 'multipart/form-data',\n },\n })\n if (res.data.success) {\n dispatch(uiActions.closeDrawer())\n dispatch(uiActions.addToast({\n message: getTranslation(translationGroups.form, 'report-bug-success'),\n type: toastTypes.SUCCESS,\n }))\n } else {\n processValidationErrors<Inputs>(res.data, setError, getRawTranslation)\n }\n } catch {\n dispatch(uiActions.addToast({\n message: getTranslation(translationGroups.form, 'report-bug-error'),\n type: toastTypes.ERROR,\n }))\n // eslint-disable-next-line no-console\n console.error('error report bug')\n }\n }\n\n return (\n <div className=\"drawer__inner-content drawer-reportbug\">\n <form onSubmit={handleSubmit(onValid)} autoComplete=\"off\">\n <InputComponent<Inputs>\n name=\"message\"\n label={getTranslation(translationGroups.form, 'bug-message')}\n type=\"textarea\"\n className=\"drawer-reportbug__message\"\n showValidatorError\n form={form}\n />\n <InputComponent<Inputs>\n name=\"attachment\"\n label={getTranslation(translationGroups.form, 'bug-attachment').replace(/{maxFileSizeMb}/g, MAX_FILE_SIZE_MB.toString())}\n secondaryLabel={clearFileButton}\n type=\"file\"\n accept={SUPPORTED_UPLOAD_FORMATS.toString()}\n showValidatorError\n form={form}\n onChange={handleChangeattachment}\n onFocus={() => clearErrors('attachment')}\n onBlur={() => clearErrors('attachment')}\n />\n <InputComponent<Inputs>\n name=\"consent\"\n label={getTranslation(translationGroups.form, 'bug-consent')}\n type=\"checkbox\"\n form={form}\n />\n <SubmitButtonComponent<Inputs>\n label={getTranslation(translationGroups.accountPage, 'submit-bug')}\n form={form}\n />\n </form>\n </div>\n )\n}\n\nexport default DrawerContentReportBugComponent\n\nconst getDefaults = (): Partial<Inputs> => ({\n message: '',\n consent: false,\n})\n","import React, { useContext } from 'react'\nimport raw from 'rehype-raw'\nimport sanitize from 'rehype-sanitize'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useDispatch } from 'react-redux'\nimport useAbilities from 'client/hooks/useAbilities'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport ReactMarkdown from 'react-markdown'\nimport { useHistory } from 'react-router'\nimport { CustomListItemComponent } from 'client/pages/common/components/react_markdown/CustomListItemComponent'\nimport RoundedButtonComponent from '../../buttons/RoundedButtonComponent'\n\nexport type Props = {\n puzzlePackId: number,\n name: string,\n size: number,\n description: string,\n}\n\nconst DrawerContentPuzzlePackInfo = ({\n puzzlePackId, name, size, description,\n}: Props) => {\n const { getRawTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n const history = useHistory()\n const { isAnonymous } = useAbilities()\n\n const handleBuy = async () => {\n dispatch(uiActions.closeDrawer())\n if (isAnonymous) {\n // Anonymous user wants to buy a puzzlepack, so let's first make him sign up.\n history.push({\n pathname: '/register',\n search: '?pack=true',\n state: { puzzlePackId, afterRegistrationPath: '/buy-pack' },\n })\n } else {\n history.push({\n pathname: '/buy-pack',\n state: { puzzlePackId },\n })\n }\n }\n\n const subText = getRawTranslation(translationGroups.puzzlePack, 'info-subtext')\n\n return (\n <div className=\"drawer__puzzle-pack-info drawer__inner-content\" data-test-id=\"puzzle-pack-info-modal-text\">\n <div className=\"drawer__puzzle-pack-info__scroll-container\">\n <h1>\n {getRawTranslation(translationGroups.puzzlePack, 'info-title', {\n name,\n size,\n })}\n </h1>\n <div className=\"puzzle-pack-info__content\">\n <ReactMarkdown rehypePlugins={[raw, sanitize]} components={{ li: CustomListItemComponent }}>{description}</ReactMarkdown>\n </div>\n </div>\n <div className=\"drawer__puzzle-pack-info__fixed-container\">\n <RoundedButtonComponent\n className=\"puzzle-pack-info__buy-button buy-button\"\n onClickHandler={handleBuy}\n text={getRawTranslation(translationGroups.puzzlePack, 'buy')}\n />\n {subText && (\n <div className=\"puzzle-pack-info__subtext\">\n {subText}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport default DrawerContentPuzzlePackInfo\n","import React from 'react'\nimport { PuzzlePackPuzzle } from 'client/types/PuzzlePackPuzzle'\nimport IconCheckmark from 'assets/icons/icon_checkmark.svg'\nimport IconPause from 'assets/icons/icon_pause.svg'\nimport IconPuzzlePiece from 'client/assets/icons/icon_puzzle_piece.svg'\n\ntype Props = {\n puzzle: PuzzlePackPuzzle\n index: number\n activePuzzleIndex: number\n onClick?: () => void\n style?: { transform: string }\n}\n\nconst PuzzlePackPuzzlePiece = ({\n puzzle, index, activePuzzleIndex, onClick, style,\n}: Props) => {\n const baseClass = 'puzzle-pack-puzzle-piece'\n const className = [\n baseClass,\n ...(puzzle.isStarted && !puzzle.isPlayed ? [`${baseClass}--playing`] : []),\n ...(puzzle.isPlayed ? [`${baseClass}--played`] : []),\n ...(index === activePuzzleIndex ? [`${baseClass}--active`] : []),\n ].join(' ')\n\n const renderLabel = () => {\n if (puzzle.isPlayed) {\n return (<span className=\"puzzle-pack-puzzle-piece__played-icon\"><IconCheckmark /></span>)\n }\n if (puzzle.isStarted) {\n return (<span className=\"puzzle-pack-puzzle-piece__playing-icon\"><IconPause /></span>)\n }\n return (<span className=\"puzzle-pack-puzzle-piece__puzzle-number\">{index + 1}</span>)\n }\n\n return (\n <div key={puzzle.klubblePuzzleId} className={className} style={style}>\n <div className={`puzzle-pack-puzzle-piece__icon${index % 2 ? ' puzzle-pack-puzzle-piece__icon--rotated' : ''}`}>\n <IconPuzzlePiece onClick={onClick} />\n </div>\n {renderLabel()}\n </div>\n )\n}\n\nexport default PuzzlePackPuzzlePiece\n","import React, { useCallback, useContext, useMemo } from 'react'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useDispatch } from 'react-redux'\nimport { useHistory } from 'react-router'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport IconEye from 'assets/icons/icon_eye.svg'\nimport { PuzzlePackPuzzle } from 'client/types/PuzzlePackPuzzle'\nimport { usePuzzlePacks } from 'client/pages/puzzle_packs/hooks/usePuzzlePacks'\nimport useConfig from 'client/hooks/useConfig'\nimport { getPuzzlePackPlayerPageQueryString } from 'client/utilities/player'\nimport PlayButtonComponent from '../buttons/PlayButtonComponent'\nimport ViewButtonComponent from '../buttons/ViewButtonComponent'\nimport PuzzlePackPuzzlePiece from './PuzzlePackPuzzlePiece'\n\nexport type Props = {\n activePuzzleIndex: number,\n activePuzzle: PuzzlePackPuzzle,\n puzzlePackId: number,\n puzzlePackTypeId: number\n}\n\nconst PuzzlePackStartComponent = ({\n activePuzzleIndex, activePuzzle, puzzlePackId, puzzlePackTypeId,\n}: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const { getPuzzlePackTypeById } = usePuzzlePacks()\n const puzzlePackType = getPuzzlePackTypeById(puzzlePackTypeId)\n\n const dispatch = useDispatch()\n const config = useConfig()\n\n const puzzleUrl = useMemo(() => {\n if (!activePuzzle) {\n return undefined\n }\n const {\n nameLangKey,\n externalPuzzleId,\n klubblePuzzleId,\n puzzleTypeId,\n } = activePuzzle\n const portalid = config.entity?.puzzlesClientId\n const queryString = getPuzzlePackPlayerPageQueryString(nameLangKey, externalPuzzleId, portalid, klubblePuzzleId, puzzleTypeId, puzzlePackId, puzzlePackType)\n return `/player${queryString}`\n }, [activePuzzle, config.entity?.puzzlesClientId, puzzlePackId, puzzlePackType])\n\n const closeDrawer = () => {\n dispatch(uiActions.closeDrawer())\n }\n\n const translationKey = useMemo(() => {\n if (activePuzzle) {\n if (activePuzzle.isStarted && !activePuzzle.isPlayed) {\n return 'continue'\n }\n if (!activePuzzle.isStarted) {\n return 'start'\n }\n return 'view'\n }\n return null\n }, [activePuzzle])\n\n if (!activePuzzle) {\n return null\n }\n\n return (\n <div className=\"puzzle-pack-start\">\n <div className=\"puzzle-pack-start__selected-puzzle\">\n <PuzzlePackPuzzlePiece puzzle={activePuzzle} index={activePuzzleIndex} activePuzzleIndex={activePuzzleIndex} />\n </div>\n <div className=\"puzzle-pack-start__description\">\n <span className=\"puzzle-pack-start__title\">\n {getTranslation(translationGroups.puzzle, activePuzzle.nameLangKey)}\n </span>\n <span className=\"puzzle-pack-start__subtitle\">\n {getTranslation(translationGroups.puzzlePack, `start-sub-text-${translationKey}`)}\n </span>\n </div>\n {activePuzzle.isPlayed ? (\n <ViewButtonComponent onClick={closeDrawer} url={puzzleUrl}>\n <span>{getTranslation(translationGroups.puzzlePack, translationKey)}</span>\n <IconEye />\n </ViewButtonComponent>\n ) : (\n <PlayButtonComponent\n nextPuzzleUrl={puzzleUrl}\n onClick={closeDrawer}\n text={getTranslation(translationGroups.puzzlePack, translationKey)}\n />\n )}\n </div>\n )\n}\n\nexport default PuzzlePackStartComponent\n","import React, { useContext, useEffect, useState } from 'react'\nimport { type ApiResult, klubbleAPI } from 'client/api/common'\nimport { type PuzzlePack } from 'client/types/PuzzlePack'\nimport { type PuzzlePackPuzzle } from 'client/types/PuzzlePackPuzzle'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { type Level } from 'client/interfaces/IPuzzleCalendar'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport PuzzlePackStartComponent from '../../puzzle_packs/PuzzlePackStartComponent'\nimport PuzzlePackPuzzlePiece from '../../puzzle_packs/PuzzlePackPuzzlePiece'\n\nexport type Props = {\n puzzlePackId: number,\n}\n\nconst DrawerContentPuzzlePackContent = ({ puzzlePackId }: Props) => {\n const [activePuzzle, setActivePuzzle] = useState<PuzzlePackPuzzle>()\n const [puzzlePack, setPuzzlePack] = useState<PuzzlePack>()\n const { getTranslation } = useContext(TranslationContext)\n const throwError = useAsyncError()\n\n useEffect(() => {\n if (!activePuzzle) {\n let initialPuzzle = puzzlePack?.puzzles?.find((puzzle) => puzzle.isPlayed === false && puzzle.isStarted)\n if (!initialPuzzle) {\n initialPuzzle = puzzlePack?.puzzles?.find((puzzle) => puzzle.isPlayed === false) || puzzlePack?.puzzles?.[0]\n }\n setActivePuzzle(initialPuzzle)\n }\n }, [puzzlePack, activePuzzle])\n\n useEffect(() => {\n const abortController = new AbortController()\n\n async function fetchPuzzlePackContent() {\n try {\n const res = await klubbleAPI.get<ApiResult<PuzzlePack>>(`Puzzle/packs/${puzzlePackId}`, {\n signal: abortController?.signal,\n })\n if (res?.status === 200) {\n setPuzzlePack(res.data.data)\n } else {\n throw new Error(`${res.config.url} did not return succesfully`)\n }\n } catch (e) {\n throwError(e, 'Error fetching puzzle pack content')\n }\n }\n\n fetchPuzzlePackContent()\n\n return () => {\n abortController.abort()\n }\n }, [puzzlePackId, throwError])\n\n if (!puzzlePack) {\n return null\n }\n const {\n displayName,\n puzzles,\n formats,\n levels,\n puzzlePackTypeId,\n } = puzzlePack\n const activePuzzleIndex = puzzles?.indexOf(activePuzzle)\n\n return (\n <div className=\"drawer__puzzle-pack-content drawer__inner-content\" data-test-id=\"puzzle-pack-content-modal-text\">\n <div className=\"drawer__puzzle-pack-content__scroll-container\">\n <h1>{displayName}</h1>\n <div className=\"drawer__puzzle-pack-content__subtitle\">\n {formats?.map((format: string) => `${getTranslation(translationGroups.puzzleTags, format)} `).join(' / ')}\n <span>{` ${String.fromCharCode(9679)} `}</span>\n {levels.map((level: Level) => getTranslation(translationGroups.difficulty, level.toLocaleLowerCase())).join(' / ')}\n </div>\n\n <div className=\"puzzle-pack-content__puzzles\">\n {puzzles?.map((puzzle, index) => {\n const x = index % 5 * -7.5\n const y = Math.floor(index / 5) * -7\n const style = {\n transform: `scale(1.4) translate(${x}%, ${y}%)`,\n }\n return (\n <PuzzlePackPuzzlePiece\n puzzle={puzzle}\n key={`${x}${y}`}\n index={index}\n activePuzzleIndex={activePuzzleIndex}\n style={style}\n onClick={() => { setActivePuzzle(puzzle) }}\n />\n )\n })}\n </div>\n </div>\n <PuzzlePackStartComponent activePuzzleIndex={activePuzzleIndex} activePuzzle={activePuzzle} puzzlePackId={puzzlePackId} puzzlePackTypeId={puzzlePackTypeId} />\n </div>\n )\n}\n\nexport default DrawerContentPuzzlePackContent\n","import React, { type PropsWithChildren, type ReactNode, useContext } from 'react'\nimport IconCloseComponent from 'assets/icons/icon_close.svg'\nimport ButtonComponent from 'common_packages/assets/js/components/ButtonComponent'\nimport { type DrawerType } from 'common_packages/assets/js/types/drawerTypes'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\n\ntype Props = PropsWithChildren<{\n hideHeader?: boolean\n hideClose?: boolean\n drawer?: DrawerType\n className?: string\n onClose?: () => void\n}>\n\n// Will render children if provided, if not, will use translation of `drawer`\nconst DefaultDrawerHeaderComponent = ({\n drawer,\n hideHeader,\n hideClose,\n children,\n className: propsClassName,\n onClose,\n}: Props) => {\n const { getRawTranslation } = useContext(TranslationContext)\n\n const content: ReactNode = (() => {\n if (hideHeader) return null\n if (!children && drawer) return getRawTranslation(translationGroups.drawer, drawer.replace(/_/g, '-'))\n return children\n })()\n\n const className = [\n 'drawer__header',\n propsClassName,\n ].join(' ')\n\n return (\n <div className={className} data-test-id=\"drawer-header\">\n {content}\n {!hideClose && (\n <ButtonComponent className=\"drawer__close\" data-test-id=\"button-drawer-close\" onClick={onClose}>\n <IconCloseComponent className=\"drawer__close-icon\" />\n </ButtonComponent>\n )}\n </div>\n )\n}\n\nexport default DefaultDrawerHeaderComponent\n","import React, { useContext, useMemo } from 'react'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useSelector } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport { Subscription } from 'client/reducers/userReducer'\nimport { SubscriptionType } from 'client/enums/SubscriptionType'\nimport useConfig from 'client/hooks/useConfig'\nimport DefaultDrawerHeaderComponent from './DefaultDrawerHeaderComponent'\n\ntype Props = {\n onClose: () => void\n}\n\nconst DrawerHeaderSubscribeComponent = ({\n onClose,\n}: Props) => {\n const { getRawTranslation } = useContext(TranslationContext)\n const subscriptions = useSelector<StoreState, Subscription[]>((state) => state.user?.data?.subscriptions)\n const canStartTrial = useSelector<StoreState, boolean>((state) => state.user?.data?.canStartTrial)\n const {\n isLightTrialEnabled,\n lightTrialSuffix,\n lightTrialDaysText,\n extendedTrialDaysText,\n } = useConfig()\n\n const previousSubscriptionType = useMemo(() => {\n if (subscriptions?.find((s) => s.subscriptionTypeName === SubscriptionType.premium && s.paidUntilDate)) {\n return { suffix: SubscriptionType.premium.toLowerCase() }\n }\n if (subscriptions?.find((s) => s.subscriptionTypeName === SubscriptionType.light && s.paidUntilDate)) {\n return { suffix: SubscriptionType.light.toLowerCase() }\n }\n if (subscriptions?.find((s) => s.subscriptionTypeName === SubscriptionType.lightTrial && s.paidUntilDate)) {\n return { suffix: SubscriptionType.lightTrial.toLowerCase(), days: lightTrialDaysText }\n }\n if (subscriptions?.find((s) => s.subscriptionTypeName === SubscriptionType.extendedTrial && s.paidUntilDate)) {\n return { suffix: SubscriptionType.lightTrial.toLowerCase(), days: extendedTrialDaysText }\n }\n return { suffix: 'none' }\n }, [extendedTrialDaysText, lightTrialDaysText, subscriptions])\n\n const subtitleText = useMemo(() => {\n if (canStartTrial && isLightTrialEnabled) {\n return getRawTranslation(translationGroups.onboarding, `subscribe-modal-header-body-prev-${previousSubscriptionType.suffix}${lightTrialSuffix}`)\n .replace(/{days}/g, lightTrialDaysText)\n }\n return getRawTranslation(translationGroups.onboarding, `subscribe-modal-header-body-prev-${previousSubscriptionType.suffix}`)\n .replace(/{days}/g, `${previousSubscriptionType.days ?? ''}`)\n }, [canStartTrial, getRawTranslation, isLightTrialEnabled, lightTrialDaysText, lightTrialSuffix, previousSubscriptionType.days, previousSubscriptionType.suffix])\n\n return (\n <DefaultDrawerHeaderComponent onClose={onClose} className=\"drawer-header-subscribe\">\n <div>\n <h1>\n {getRawTranslation(translationGroups.onboarding, `subscribe-modal-header-prev-${previousSubscriptionType.suffix}`)\n .replace(/{days}/g, `${previousSubscriptionType.days ?? ''}`)}\n </h1>\n {subtitleText}\n </div>\n </DefaultDrawerHeaderComponent>\n )\n}\n\nexport default DrawerHeaderSubscribeComponent\n","import { useDispatch } from 'react-redux'\nimport React, { useContext } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport raw from 'rehype-raw'\nimport sanitize from 'rehype-sanitize'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { closeDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport { Level } from 'client/interfaces/IPuzzleCalendar'\nimport { usePuzzlePacks } from 'client/pages/puzzle_packs/hooks/usePuzzlePacks'\nimport * as puzzleDataActions from 'client/actions/puzzleDataActions'\nimport RadioInputComponent from '../../form/RadioInputComponent'\n\nexport type Props = {\n id: number,\n}\n\nconst DrawerContentPuzzlePackTypeLevelComponent = ({ id }: Props) => {\n const { getRawTranslation, getTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n const { getAvailableLevelsWithinPuzzlePackType, getSelectedLevelForPuzzlePackType } = usePuzzlePacks()\n const availableLevels = getAvailableLevelsWithinPuzzlePackType(id)\n const selectedLevel = getSelectedLevelForPuzzlePackType(id)\n\n const onClickHandler = (value: Level) => {\n dispatch(puzzleDataActions.setSelectedLevelPuzzlePackType({ puzzlePackTypeId: id, selectedLevel: value }))\n dispatch(closeDrawer())\n }\n\n if (availableLevels.length < 2) {\n return (\n <div className=\"drawer__content-level\">\n <div className=\"drawer__content-level__no-other-levels\">\n {/* Support for soft hyphens */ }\n <ReactMarkdown rehypePlugins={[raw, sanitize]}>{getRawTranslation(translationGroups.difficulty, 'no-other-levels')}</ReactMarkdown>\n </div>\n </div>\n )\n }\n\n return (\n <div className=\"drawer__content-level\">\n {availableLevels?.map((level) => (\n <RadioInputComponent\n key={level}\n checked={level === selectedLevel}\n value={level}\n label={getTranslation(translationGroups.difficulty, level)}\n onClickHandler={onClickHandler}\n />\n ))}\n </div>\n )\n}\n\nexport default DrawerContentPuzzlePackTypeLevelComponent\n","import * as React from 'react'\nimport FilledTopRight1SquircleMobile from 'client/assets/images/squircles/filled-336x336px.svg'\nimport FilledTopRight2SquircleMobile from 'client/assets/images/squircles/filled-202x202px.svg'\nimport OutlineBottomRightSquircleMobile from 'client/assets/images/squircles/outline-113x113px.svg'\nimport LightBottomLeftSquircleMobile from 'client/assets/images/squircles/light-353x353px.svg'\nimport FilledBottomRightSquircleMobile from 'client/assets/images/squircles/filled-40x40px.svg'\nimport FilledTopRight1SquircleDesktop from 'client/assets/images/squircles/filled-550x550px.svg'\nimport FilledTopRight2SquircleDesktop from 'client/assets/images/squircles/filled-186x186px.svg'\nimport OutlineBottomRightSquircleDesktop from 'client/assets/images/squircles/outline-143x143px.svg'\nimport LightBottomLeftSquircleDesktop from 'client/assets/images/squircles/light-610x610px.svg'\nimport LightBottomRightSquircleDesktop from 'client/assets/images/squircles/light-198x198px.svg'\nimport OutlineBottomLeftSquircleDesktop from 'client/assets/images/squircles/outline-122x122px.svg'\nimport FilledBottomLeftSquircleDesktop from 'client/assets/images/squircles/filled-99x99px.svg'\n\nconst DrawerContentBackgroundComponent = () => {\n return (\n <div className=\"drawer-content-background\">\n <div className=\"drawer-content-background__mobile\">\n <FilledTopRight1SquircleMobile className=\"drawer-content-background__squircle-1\" />\n <FilledTopRight2SquircleMobile className=\"drawer-content-background__squircle-2\" />\n <OutlineBottomRightSquircleMobile className=\"drawer-content-background__squircle-3\" />\n <LightBottomLeftSquircleMobile className=\"drawer-content-background__squircle-4\" />\n <FilledBottomRightSquircleMobile className=\"drawer-content-background__squircle-5\" />\n </div>\n <div className=\"drawer-content-background__desktop\">\n <FilledTopRight1SquircleDesktop className=\"drawer-content-background__squircle-1\" />\n <FilledTopRight2SquircleDesktop className=\"drawer-content-background__squircle-2\" />\n <LightBottomLeftSquircleDesktop className=\"drawer-content-background__squircle-3\" />\n <LightBottomRightSquircleDesktop className=\"drawer-content-background__squircle-4\" />\n <OutlineBottomRightSquircleDesktop className=\"drawer-content-background__squircle-5\" />\n <OutlineBottomLeftSquircleDesktop className=\"drawer-content-background__squircle-6\" />\n <FilledBottomLeftSquircleDesktop className=\"drawer-content-background__squircle-7\" />\n </div>\n </div>\n )\n}\n\nexport default DrawerContentBackgroundComponent\n","import * as React from 'react'\nimport { useContext } from 'react'\nimport * as yup from 'yup'\nimport { useHistory } from 'react-router'\nimport { yupResolver } from '@hookform/resolvers/yup'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { type ApiFormResult, klubbleAPI } from 'client/api/common'\nimport { type SubmitErrorHandler, type SubmitHandler, useForm } from 'react-hook-form'\nimport useCheckUsernameAvailable from 'client/hooks/useCheckUsernameAvailable'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { MAX_USERNAME_LENGTH } from 'client/utilities/userInput'\nimport { processValidationErrors } from 'client/utilities/form'\nimport { toastTypes } from 'common_packages/assets/js/types/toastTypes'\nimport { addToast } from 'common_packages/assets/js/actions/uiActions'\nimport { setUser } from 'client/actions/userActions'\nimport { type StoreState } from 'client/store'\nimport { type UserData } from 'client/reducers/userReducer'\nimport * as auth from 'client/api/authentication'\nimport InputComponent from 'client/pages/common/components/form/InputComponent'\nimport SubmitButtonComponent from 'client/pages/common/components/form/SubmitButtonComponent'\nimport TextButtonComponent from 'client/pages/common/components/form/TextButtonComponent'\n\ntype Inputs = {\n username: string\n}\n\nconst DrawerContentOnboardStepUsernameComponent = () => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const { push } = useHistory()\n\n const schema = yup.object().shape({\n username: yup.string()\n .required(getRawTranslation(translationGroups.error, 'required-field'))\n .max(MAX_USERNAME_LENGTH, getRawTranslation(translationGroups.form, 'error-max-chars-used').replace('{charsLimit}', MAX_USERNAME_LENGTH.toString())),\n })\n const form = useForm<Inputs>({\n resolver: yupResolver(schema),\n })\n\n const storedValues = useSelector<StoreState, UserData>((state) => state.user?.data)\n const dispatch = useDispatch()\n const { handleSubmit, watch, setError } = form\n const { username: usernameEntered } = watch()\n const usernameAvailable = useCheckUsernameAvailable({ username: usernameEntered })\n\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n const onInvalid: SubmitErrorHandler<Inputs> = async () => {\n }\n\n const onValid: SubmitHandler<Inputs> = async (data: Inputs) => {\n if (!usernameAvailable) {\n return\n }\n\n const payload = {\n userName: data.username,\n }\n\n const { data: response } = await klubbleAPI.post<ApiFormResult<boolean, Inputs>>('Auth/completeuser', JSON.stringify(payload), {\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n if (response.success === true) {\n dispatch(setUser({ ...storedValues, ...payload }))\n } else {\n processValidationErrors<Inputs>(response, setError, getRawTranslation)\n dispatch(addToast({\n message: getRawTranslation(translationGroups.form, response.message),\n type: toastTypes.ERROR,\n }))\n }\n }\n\n const handleLogout = (): void => {\n auth.logout()\n // when SSO is enabled the SSO provider handles this redirect\n if (process.env.KLUBBLE_LOGIN_SSO_ENABLED !== 'true') {\n push('/login')\n }\n }\n\n return (\n <div className=\"drawer__onboard-step drawer__onboard-step-username\">\n <div className=\"drawer__onboard-title-container\">\n <h1 className=\"drawer__onboard-title\">\n {getTranslation(translationGroups.onboarding, 'input-username-title')}\n </h1>\n </div>\n <div>\n <h2 className=\"drawer__onboard-subtitle\">\n {getTranslation(translationGroups.onboarding, 'input-username-subtitle')}\n </h2>\n <div className=\"drawer__onboard-instructions\">\n {getTranslation(translationGroups.onboarding, 'input-username-instructions')}\n </div>\n </div>\n <form onSubmit={handleSubmit(onValid, onInvalid)} className=\"drawer__onboard-form\">\n <InputComponent\n name=\"username\"\n label={getTranslation(\n translationGroups.onboarding,\n `username${!usernameAvailable ? '-unavailable' : ''}`,\n )}\n customError={!usernameAvailable}\n type=\"text\"\n showValidatorError\n form={form}\n />\n <div className=\"drawer__onboard-submit-wrapper\">\n <SubmitButtonComponent\n label={getTranslation(translationGroups.onboarding, 'input-username-next-button')}\n form={form}\n disableWhileNotDirty\n />\n <TextButtonComponent onClick={handleLogout}>\n {getTranslation(translationGroups.onboarding, 'logout-button')}\n </TextButtonComponent>\n </div>\n </form>\n </div>\n )\n}\n\nexport default DrawerContentOnboardStepUsernameComponent\n","import * as React from 'react'\nimport {\n type PropsWithChildren,\n type ReactNode,\n useLayoutEffect,\n useRef,\n useState,\n} from 'react'\n\nexport type Props = PropsWithChildren<{\n fallback: ReactNode\n}>\n\n/**\n * This component will attempt to render it's `children`, unless they are overflowing their\n * parent, in which case the `fallback` is rendered. For this to work at all the parent\n * obviously needs to have at least one dimension (width or height) set\n */\nconst OverflowContentSwitcherComponent = ({ fallback, children }: Props) => {\n const childrenRef = useRef<HTMLDivElement>()\n const [renderFallback, setRenderFallback] = useState<boolean | null>(null)\n\n useLayoutEffect(() => {\n setRenderFallback(hasOverflow(childrenRef.current.parentNode))\n }, [])\n\n if (renderFallback) {\n return <>{fallback}</>\n }\n\n return (\n <div ref={childrenRef} className={renderFallback === null ? 'ocs--hidden' : null}>\n {children}\n </div>\n )\n}\n\nexport default OverflowContentSwitcherComponent\n\nconst hasOverflow = (el) => el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth\n","import * as React from 'react'\nimport { useContext } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { Link } from 'react-router-dom'\nimport { type StoreState } from 'client/store'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { type UserData } from 'client/reducers/userReducer'\nimport { closeDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport RoundedButtonComponent from 'client/pages/common/components/buttons/RoundedButtonComponent'\nimport OverflowContentSwitcherComponent from 'client/pages/common/components/utility/OverflowContentSwitcherComponent'\nimport { refreshToken } from 'client/api/authentication'\nimport TextButtonComponent from 'client/pages/common/components/form/TextButtonComponent'\n\nconst DrawerContentOnboardStepSuccessComponent = () => {\n const { getTranslation } = useContext(TranslationContext)\n const { userName } = useSelector<StoreState, UserData>((state) => state.user?.data)\n const dispatch = useDispatch()\n\n const handleClose = () => {\n refreshToken()\n dispatch(closeDrawer())\n }\n\n return (\n <div className=\"drawer__onboard-step drawer__onboard-step-success\">\n <div className=\"drawer__onboard-title-container\">\n <h1 className=\"drawer__onboard-title\">\n <OverflowContentSwitcherComponent fallback={getTranslation(translationGroups.onboarding, 'success-title-noname')}>\n {getTranslation(translationGroups.onboarding, 'success-title', { userName })}\n </OverflowContentSwitcherComponent>\n </h1>\n </div>\n <div>\n <h2 className=\"drawer__onboard-subtitle\">\n {getTranslation(translationGroups.onboarding, 'success-subtitle')}\n </h2>\n <div className=\"drawer__onboard-instructions\">\n {getTranslation(translationGroups.onboarding, 'success-message')}\n </div>\n </div>\n <div className=\"drawer__onboard-form\">\n <Link to={{ pathname: '/onboarding', state: 'onboarding' }}>\n <RoundedButtonComponent\n text={getTranslation(translationGroups.onboarding, 'to-onboarding-puzzles-button')}\n buttonType=\"secondary\"\n onClickHandler={handleClose}\n />\n </Link>\n <TextButtonComponent onClick={handleClose}>\n {getTranslation(translationGroups.onboarding, 'skip-customization-button')}\n </TextButtonComponent>\n </div>\n </div>\n )\n}\n\nexport default DrawerContentOnboardStepSuccessComponent\n","import * as React from 'react'\nimport { useContext } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { type StoreState } from 'client/store'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { setOptInStatusses } from 'client/actions/userActions'\nimport RoundedButtonComponent from 'client/pages/common/components/buttons/RoundedButtonComponent'\nimport TextButtonComponent from 'client/pages/common/components/form/TextButtonComponent'\n\ntype Props = {\n onChooseOptIn: () => void\n}\n\nconst DrawerContentOnboardStepChooseOptInComponent = ({ onChooseOptIn }: Props) => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n\n const handleAgree = async () => {\n dispatch(setOptInStatusses(true, true, getRawTranslation(translationGroups.accountPage, 'notifications-newsletter-accept-terms')))\n onChooseOptIn()\n }\n\n const handleDecline = () => {\n onChooseOptIn()\n }\n\n return (\n <div className=\"drawer__onboard-step drawer__onboard-step-choose-opt-in\">\n <div className=\"drawer__onboard-title-container\">\n <h1 className=\"drawer__onboard-title\">\n {getTranslation(translationGroups.onboarding, 'choose-opt-in-title')}\n </h1>\n </div>\n <div>\n <h2 className=\"drawer__onboard-subtitle\">\n {getTranslation(translationGroups.onboarding, 'choose-opt-in-subtitle')}\n </h2>\n <div className=\"drawer__onboard-instructions\">\n {getTranslation(translationGroups.onboarding, 'choose-opt-in-instructions')}\n </div>\n </div>\n <div className=\"drawer__onboard-form\">\n <div className=\"drawer__onboard-submit-wrapper\">\n\n <RoundedButtonComponent\n text={getTranslation(translationGroups.onboarding, 'opt-in-ok-button')}\n buttonType=\"secondary\"\n onClickHandler={handleAgree}\n />\n <TextButtonComponent onClick={handleDecline}>\n {getTranslation(translationGroups.onboarding, 'skip-opt-in-button')}\n </TextButtonComponent>\n </div>\n </div>\n </div>\n )\n}\n\nexport default DrawerContentOnboardStepChooseOptInComponent\n","import * as React from 'react'\nimport { useContext, useMemo, useState } from 'react'\nimport { useSelector } from 'react-redux'\nimport { type StoreState } from 'client/store'\nimport { type UserState } from 'client/reducers/userReducer'\nimport useConfig from 'client/hooks/useConfig'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport OnboardingHeaderComponent from 'client/pages/onboarding/components/OnboardingHeaderComponent'\nimport ChevronBackImage from 'common_packages/assets/images/misc/chevron_left.svg'\nimport DrawerContentBackgroundComponent from './DrawerContentBackgroundComponent'\nimport DrawerContentOnboardStepUsernameComponent from './DrawerContentOnboardStepUsernameComponent'\nimport DrawerContentOnboardStepSuccessComponent from './DrawerContentOnboardStepSuccessComponent'\nimport DrawerContentOnboardStepChooseOptInComponent from './DrawerContentOnboardStepChooseOptInComponent'\n\ntype Props = {\n setShowConfetti: (value: boolean) => void\n}\n\nconst DrawerContentOnboardComponent = ({ setShowConfetti }:Props) => {\n const { entity } = useConfig()\n const { getTranslation } = useContext(TranslationContext)\n const { data } = useSelector<StoreState, UserState>((state) => state.user)\n const [completedOptInStep, completeOptInStep] = useState(false)\n\n const step = useMemo(() => {\n if (data.userName == null) {\n return 0\n }\n if (!completedOptInStep) {\n return 1\n }\n setShowConfetti(true)\n return 2\n }, [data.userName, completedOptInStep, setShowConfetti])\n const handleChooseOptIn = () => {\n completeOptInStep(true)\n }\n\n return (\n <div className=\"drawer__onboard\">\n <DrawerContentBackgroundComponent />\n <OnboardingHeaderComponent className=\"drawer__onboard-header\">\n { step === 0 && (\n <a className=\"drawer__onboard-back\" href={entity.platformUrl}>\n <ChevronBackImage className=\"profile-page__back-icon\" />\n <div className=\"drawer__onboard-back-label\">\n {getTranslation(translationGroups.onboarding, 'back')}\n </div>\n </a>\n )}\n </OnboardingHeaderComponent>\n { step === 0 && <DrawerContentOnboardStepUsernameComponent />}\n { step === 1 && <DrawerContentOnboardStepChooseOptInComponent onChooseOptIn={handleChooseOptIn} />}\n { step === 2 && <DrawerContentOnboardStepSuccessComponent />}\n </div>\n )\n}\n\nexport default DrawerContentOnboardComponent\n","import React, { useContext, useEffect, useState } from 'react'\nimport Realistic from 'react-canvas-confetti/dist/presets/realistic'\nimport { TCanvasConfettiAnimationOptions, TConductorInstance, TDecorateOptionsFn } from 'react-canvas-confetti/dist/types'\nimport { ThemeContext } from './theme/ThemeContext'\n\nconst ConfettiComponent = () => {\n const [confettiController, setConfettiController] = useState<TConductorInstance | null>(null)\n const { theme } = useContext(ThemeContext)\n\n const onInitConfetti = ({ conductor }: { conductor: TConductorInstance }) => {\n setConfettiController(conductor)\n }\n const decorateOptions: TDecorateOptionsFn = (defaultOptions: TCanvasConfettiAnimationOptions) => {\n return {\n ...defaultOptions,\n colors: [theme.cssVariables['--primary-color'], theme.cssVariables['--secondary-color'], theme.cssVariables['--tertiary-color']],\n scalar: 1.25,\n decay: 0.92,\n particleCount: 40,\n gravity: 1.5,\n spread: 100,\n ticks: 1000,\n }\n }\n\n useEffect(() => {\n if (confettiController) {\n confettiController.shoot()\n }\n }, [confettiController])\n\n return (\n <div className=\"confetti\">\n <Realistic onInit={onInitConfetti} decorateOptions={decorateOptions} />\n </div>\n )\n}\n\nexport default ConfettiComponent\n","import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { disableBodyScroll, clearAllBodyScrollLocks } from 'body-scroll-lock-upgrade'\nimport { isIOS } from 'react-device-detect'\nimport ResizeObserver from 'resize-observer-polyfill'\nimport { drawerTypes, DrawerType } from 'common_packages/assets/js/types/drawerTypes'\nimport { customVerticalScroll } from 'common_packages/assets/js/utilities/customScroll'\nimport { type Player } from 'client/types/Player'\nimport DrawerContentSmartHintWordsearchContainer from 'client/player/js/containers/drawers/DrawerContentSmartHintWordsearchContainer'\nimport { type DrawerSize } from 'common_packages/assets/js/types/drawerSize'\nimport { fullscreenArea } from 'common_packages/assets/js/config/idAttributes'\nimport RotateScreenComponent from 'client/player/js/components/modals/RotateScreenComponent'\nimport useWindowDimensions from 'common_packages/assets/js/hooks/useWindowDimensions'\nimport DrawerContentFeatureInDevelopmentComponent from './drawer/content/DrawerContentFeatureInDevelopmentComponent'\nimport DrawerContentTermsAndConditionsComponent from './drawer/content/DrawerContentTermsAndConditionsComponent'\nimport DrawerContentAddToHomeScreenInfoComponent from './drawer/content/DrawerContentAddToHomeScreenInfoComponent'\nimport DrawerContentSortingContainer from '../containers/drawer/content/DrawerContentSortingContainer'\nimport DrawerContentDictionaryComponent from '../../../player/js/components/drawers/DrawerContentDictionaryComponent'\nimport DrawerContentSmartHintLogicContainer from '../../../player/js/containers/drawers/DrawerContentSmartHintLogicContainer'\nimport DrawerContentCancelSubscriptionComponent from './drawer/account/DrawerContentCancelSubscriptionComponent'\nimport DrawerContentCannotStartPuzzleComponent from './drawer/content/DrawerContentCannotStartPuzzleComponent'\nimport DrawerContentExpressComponent from './drawer/express/DrawerContentExpressComponent'\nimport DrawerContentGameInstructionsComponent from './drawer/content/DrawerContentGameInstructionsComponent'\nimport DrawerContentGenericConfirmComponent, { type Props as GenericConfirmDrawerData } from './drawer/content/DrawerContentGenericConfirmComponent'\nimport DrawerContentGenericErrorComponent, { type Props as GenericErrorDrawerData } from './drawer/content/DrawerContentGenericErrorComponent'\nimport DrawerContentGiftPuzzleComponent from './drawer/share/DrawerContentGiftPuzzleComponent'\nimport DrawerContentHideOnscreenKeyboard from './drawer/content/DrawerContentHideOnscreenKeyboard'\nimport DrawerContentInvitePuzzleComponent from './drawer/share/DrawerContentInvitePuzzleComponent'\nimport DrawerContentJoinNowComponent from './drawer/endscreen/DrawerContentJoinNowComponent'\nimport DrawerContentLevelComponent, { Props as LevelDrawerData } from './drawer/content/DrawerContentLevelComponent'\nimport DrawerContentNotificationsComponent from './drawer/notifications/DrawerContentNotificationsComponent'\nimport DrawerContentPlayerListComponent from './drawer/content/DrawerContentPlayerListComponent'\nimport DrawerContentPuzzleFinishedWithoutContribution from './drawer/content/DrawerContentPuzzleFinishedWithoutContribution'\nimport DrawerContentSetPlayerNameComponent from './drawer/content/DrawerContentSetPlayerNameComponent'\nimport DrawerContentShowOnscreenKeyboard from './drawer/content/DrawerContentShowOnscreenKeyboard'\nimport DrawerContentSubscribeComponent from './drawer/account/DrawerContentSubscribeComponent'\nimport DrawerContentNeedToRegisterComponent from './drawer/account/DrawerContentNeedToRegisterComponent'\nimport DrawerContentUpgradeSubscriptionComponent from './drawer/account/DrawerContentUpgradeSubscriptionComponent'\nimport DrawerContentUpgradeSubscriptionPremiumOnlyComponent from './drawer/account/DrawerContentUpgradeSubscriptionPremiumOnlyComponent'\nimport DrawerContentViewPuzzleComponent from './drawer/endscreen/DrawerContentViewPuzzleComponent'\nimport DrawerContentShareResultComponent from './drawer/share/DrawerContentShareResultComponent'\nimport DrawerContentReportBugComponent from './drawer/personal-details/DrawerContentReportBugComponent'\nimport DrawerContentPuzzlePackInfo, { type Props as PuzzlePackInfoDrawerData } from './drawer/puzzle-packs/DrawerContentPuzzlePackInfo'\nimport DrawerContentPuzzlePackContent, { type Props as PuzzlePackContentDrawerData } from './drawer/puzzle-packs/DrawerContentPuzzlePackContent'\nimport DefaultDrawerHeaderComponent from './drawer/headers/DefaultDrawerHeaderComponent'\nimport DrawerHeaderSubscribeComponent from './drawer/headers/DrawerHeaderSubscribeComponent'\nimport DrawerContentPuzzlePackTypeLevelComponent, { type Props as PuzzlePackTypeLevelDrawerData } from './drawer/content/DrawerContentPuzzlePackTypeLevelComponent'\nimport DrawerContentOnboardComponent from './drawer/onboard/DrawerContentOnboardComponent'\nimport ConfettiComponent from './ConfettiComponent'\n\nexport type Props = {\n drawer: DrawerType\n drawerData: unknown\n forceModal?: boolean // ForceModal means the drawer is shown as a modal popup, even in mobile.\n fullscreenOnMobile?: boolean // when on mobile, the drawer is shown fullscreen\n modalAutoGrow?: boolean // If set, will cause no scrolling inside modal if content does not fit. Instead, modal will be larger than viewport and user scrolls the page to see rest of content.\n hideHeader?: boolean // Optionally hide the header.\n hideClose?: boolean // Optionally hide the close button. Also prevent clicking on the background to close.\n size?: DrawerSize\n bleedToEdge?: boolean\n className?: string // Optionally className that can be used for styling.\n onClose?: () => void\n}\n\nexport type DispatchProps = {\n close: () => void\n pauseTimer: () => void\n resumeTimer: () => void\n}\n\nconst ANIMATE_OUT_DURATION = 200\n\ntype State = 'hidden' | 'animate-in' | 'animate-out'\n\nconst SHOULD_ANIMATE = process.env.PLAYWRIGHT_ENV !== 'true'\nconst AUTO_GROW_MARGIN = 16 // 1 rem vertical margin\n\nconst DrawerComponent = ({\n close,\n pauseTimer,\n resumeTimer,\n drawer = null,\n drawerData = null,\n forceModal = false,\n fullscreenOnMobile = false,\n modalAutoGrow = false,\n hideHeader = false,\n hideClose = false,\n bleedToEdge = false,\n className: extraClassName = '',\n size,\n onClose, // extra onClose event\n}: Props & DispatchProps) => {\n const { height: windowHeight } = useWindowDimensions()\n\n const [state, setState] = useState<State>('hidden')\n\n // When animating out, `drawer` and `drawerData` are already `null`.\n // However, we need to remember which drawer was last shown to show the animation\n const previousDrawer = useRef(drawer)\n const currentDrawer = drawer ?? previousDrawer.current ?? null\n const previousDrawerData = useRef(drawerData)\n const currentDrawerData = useMemo(() => (drawerData ?? previousDrawerData.current ?? {}), [drawerData])\n const [showConfetti, setShowConfetti] = useState(false)\n\n const drawerRef = useRef<HTMLDivElement>(null)\n const drawerContent = useRef<HTMLDivElement>()\n\n useEffect(() => {\n if (drawer === drawerTypes.GAME_INSTRUCTIONS) {\n pauseTimer()\n }\n return () => {\n if (drawer === drawerTypes.GAME_INSTRUCTIONS) {\n resumeTimer()\n }\n }\n }, [drawer, pauseTimer, resumeTimer])\n\n useEffect(() => {\n const inFullscreen = !!document.getElementById(fullscreenArea)\n let shouldClearLock = false\n // We prevent scrolling behind the drawer. However it causes problems with fullscreen\n // in iOS, so when in fullscreen, don't lock the body\n if (drawer && drawerContent.current) {\n if ((!inFullscreen || !isIOS) && !modalAutoGrow) {\n disableBodyScroll(drawerRef.current, {\n allowTouchMove: (el: HTMLElement) => el.tagName === 'TEXTAREA',\n })\n shouldClearLock = true\n }\n }\n\n return () => {\n if (shouldClearLock) {\n clearAllBodyScrollLocks()\n }\n }\n }, [drawer, modalAutoGrow])\n\n useEffect(() => {\n // When `autoGrow` is set on a drawer, user can scroll it if needed. However if the page content underneath it\n // is larger than the modal, we don't want to allow scrolling past the modal. So we restrict the height\n // of the page content whilst the drawer is open\n let shouldClearPreventOverscroll = false\n const previousScrollY = window.scrollY\n const pageContentEl = document.querySelector('.page-content') as HTMLElement\n\n const drawerCurrent = drawerRef.current\n\n const drawerObserver = new ResizeObserver(([entry]) => {\n if (!pageContentEl) {\n return\n }\n const modalHeight = entry.contentRect.height + AUTO_GROW_MARGIN * 2\n\n const pageContentHeight = Math.max(modalHeight, window.innerHeight)\n pageContentEl.style.height = `${pageContentHeight}px`\n pageContentEl.style.overflow = 'hidden'\n shouldClearPreventOverscroll = true\n if (forceModal) {\n if (modalHeight > windowHeight) {\n drawerRef.current?.classList.add('drawer--position-absolute')\n } else {\n drawerRef.current?.classList.remove('drawer--position-absolute')\n }\n }\n })\n\n if (currentDrawer && drawerCurrent && modalAutoGrow) {\n if (drawerContent.current.getBoundingClientRect().height > document.body.getBoundingClientRect().height) {\n window.scrollTo(0, 0)\n }\n drawerObserver.observe(drawerCurrent)\n }\n\n return () => {\n if (drawerCurrent) {\n drawerObserver.unobserve(drawerCurrent)\n }\n\n if (pageContentEl && shouldClearPreventOverscroll) {\n pageContentEl.style.height = 'auto'\n pageContentEl.style.overflow = 'auto'\n\n window.requestAnimationFrame(() => {\n window.scrollTo(0, previousScrollY)\n })\n }\n }\n }, [currentDrawer, forceModal, modalAutoGrow, state, windowHeight])\n\n useEffect(() => {\n let addScrollbarBack = false // Prevents scrolling while endscreen animation is running.\n if (drawer && !modalAutoGrow) {\n const scrollbarWidth = `${window.innerWidth - document.body.clientWidth}px`\n document.body.style.overflowY = 'hidden'\n document.body.style.overflowX = 'hidden'\n document.body.style.paddingRight = scrollbarWidth\n document.body.style.height = '100%'\n document.body.style.width = '100%'\n document.body.style.touchAction = 'none'\n addScrollbarBack = true\n }\n\n return () => {\n if (addScrollbarBack) {\n document.body.style.overflowY = 'scroll'\n document.body.style.overflowX = 'visible'\n document.body.style.paddingRight = '0'\n document.body.style.height = 'inherit'\n document.body.style.width = 'auto'\n document.body.style.touchAction = 'initial'\n }\n }\n }, [drawer, modalAutoGrow])\n\n const handleClose = useCallback(() => {\n onClose?.()\n close?.()\n }, [close, onClose])\n\n const header = useMemo(() => {\n if (hideHeader && hideClose) {\n return null\n }\n switch (currentDrawer) {\n case drawerTypes.SUBSCRIBE: {\n return (\n <DrawerHeaderSubscribeComponent\n onClose={handleClose}\n />\n )\n }\n default: {\n return (\n <DefaultDrawerHeaderComponent\n hideHeader={hideHeader}\n hideClose={hideClose}\n drawer={currentDrawer}\n onClose={handleClose}\n />\n )\n }\n }\n }, [currentDrawer, handleClose, hideClose, hideHeader])\n\n const content = useMemo(() => {\n switch (currentDrawer) {\n case drawerTypes.ADD_TO_HOMESCREEN_INFO: { return <DrawerContentAddToHomeScreenInfoComponent skipIntro={(currentDrawerData as { skipIntro?: boolean })?.skipIntro} /> }\n case drawerTypes.CANCEL_SUBSCRIPTION: { return <DrawerContentCancelSubscriptionComponent /> }\n case drawerTypes.CANNOT_START_PUZZLE: { return <DrawerContentCannotStartPuzzleComponent /> }\n case drawerTypes.EXPRESS: { return <DrawerContentExpressComponent /> }\n case drawerTypes.FEATURE_IN_DEVELOPMENT: { return <DrawerContentFeatureInDevelopmentComponent /> }\n case drawerTypes.GAME_INSTRUCTIONS: { return <DrawerContentGameInstructionsComponent {...(currentDrawerData as { drawerUseHighlightAnimation: boolean })} /> }\n case drawerTypes.GENERIC_CONFIRM: { return <DrawerContentGenericConfirmComponent {...(currentDrawerData as GenericConfirmDrawerData)} /> }\n case drawerTypes.GENERIC_ERROR: { return <DrawerContentGenericErrorComponent {...(currentDrawerData as GenericErrorDrawerData)} /> }\n case drawerTypes.GIFT_PUZZLE: { return <DrawerContentGiftPuzzleComponent shareLink={currentDrawerData as string} /> }\n case drawerTypes.INVITE_PUZZLE: { return <DrawerContentInvitePuzzleComponent shareLink={currentDrawerData as string} /> }\n case drawerTypes.JOIN_NOW: { return <DrawerContentJoinNowComponent {...(currentDrawerData as { inviterName?: string})} /> }\n case drawerTypes.NEED_TO_REGISTER: { return <DrawerContentNeedToRegisterComponent /> }\n case drawerTypes.NOTIFICATIONS: { return <DrawerContentNotificationsComponent /> }\n case drawerTypes.ONBOARD_MODAL: { return <DrawerContentOnboardComponent setShowConfetti={setShowConfetti} /> }\n case drawerTypes.ONSCREEN_KEYBOARD_HIDE: { return <DrawerContentHideOnscreenKeyboard /> }\n case drawerTypes.ONSCREEN_KEYBOARD_SHOW: { return <DrawerContentShowOnscreenKeyboard /> }\n case drawerTypes.PLAYER_LIST: { return <DrawerContentPlayerListComponent players={currentDrawerData as Player[]} /> }\n case drawerTypes.PUZZLE_CALENDAR_LEVEL: { return <DrawerContentLevelComponent {...(currentDrawerData as LevelDrawerData)} /> }\n case drawerTypes.PUZZLE_FINISHED_WITHOUT_CONTRIBUTION: { return <DrawerContentPuzzleFinishedWithoutContribution /> }\n case drawerTypes.PUZZLE_ONBOARDING_LEVEL: { return <DrawerContentLevelComponent {...(currentDrawerData as LevelDrawerData)} /> }\n case drawerTypes.PUZZLE_PACK_CONTENT: { return <DrawerContentPuzzlePackContent {...(currentDrawerData as PuzzlePackContentDrawerData)} /> }\n case drawerTypes.PUZZLE_PACK_INFO: { return <DrawerContentPuzzlePackInfo {...(currentDrawerData as PuzzlePackInfoDrawerData)} /> }\n case drawerTypes.PUZZLE_PACK_TYPE_LEVEL: { return <DrawerContentPuzzlePackTypeLevelComponent {...(currentDrawerData as PuzzlePackTypeLevelDrawerData)} /> }\n case drawerTypes.PUZZLES_SORTING: { return <DrawerContentSortingContainer /> }\n case drawerTypes.REPORT_BUG: { return <DrawerContentReportBugComponent /> }\n case drawerTypes.SET_FIRST_NAME: { return <DrawerContentSetPlayerNameComponent /> }\n case drawerTypes.SHARE_RESULT: { return <DrawerContentShareResultComponent shareLink={currentDrawerData as string} /> }\n case drawerTypes.SMART_HINT_LOGIC: { return <DrawerContentSmartHintLogicContainer /> }\n case drawerTypes.SMART_HINT_WORDSEARCH: { return <DrawerContentSmartHintWordsearchContainer /> }\n case drawerTypes.SMART_HINTS_DICTIONARY: { return <DrawerContentDictionaryComponent /> }\n case drawerTypes.SUBSCRIBE: { return <DrawerContentSubscribeComponent /> }\n case drawerTypes.TERMS_AND_CONDITIONS: { return <DrawerContentTermsAndConditionsComponent /> }\n case drawerTypes.UPGRADE_SUBSCRIPTION_PREMIUM_ONLY: { return <DrawerContentUpgradeSubscriptionPremiumOnlyComponent /> }\n case drawerTypes.UPGRADE_SUBSCRIPTION: { return <DrawerContentUpgradeSubscriptionComponent /> }\n case drawerTypes.VIEW_PUZZLE: { return <DrawerContentViewPuzzleComponent /> }\n default:\n return null\n }\n }, [currentDrawer, currentDrawerData])\n\n useEffect(() => {\n // instead of unmounting directly, when drawer becomes null\n // set state to 'animate-out' for 0.2secs to allow for the animation\n let timeout: ReturnType<typeof setTimeout>\n if (drawer === null) {\n if (!SHOULD_ANIMATE || previousDrawer.current === null) {\n setState('hidden')\n previousDrawer.current = null\n previousDrawerData.current = null\n setShowConfetti(false)\n } else {\n setState('animate-out')\n timeout = setTimeout(() => {\n setState('hidden')\n previousDrawer.current = null\n previousDrawerData.current = null\n }, ANIMATE_OUT_DURATION)\n }\n } else {\n setState('animate-in')\n previousDrawer.current = drawer\n previousDrawerData.current = drawerData\n }\n return () => {\n clearTimeout(timeout)\n setShowConfetti(false)\n }\n }, [drawer, drawerData])\n\n const className = useMemo(() => ([\n 'drawer',\n ...(SHOULD_ANIMATE && state === 'animate-in' ? ['drawer--animating-in'] : []),\n ...(SHOULD_ANIMATE && state === 'animate-out' ? ['drawer--animating-out'] : []),\n ...(size ? [`drawer--size-${size}`] : []),\n ...(forceModal ? ['drawer--force-modal'] : []),\n ...(fullscreenOnMobile ? ['drawer--fullscreen-on-mobile'] : []),\n ...(forceModal && modalAutoGrow ? ['modal-no-max-height'] : []),\n ...(currentDrawer === drawerTypes.SMART_HINT_LOGIC || currentDrawer === drawerTypes.SMART_HINT_WORDSEARCH ? ['drawer--box-shadow'] : []),\n ...(currentDrawer === drawerTypes.VIEW_PUZZLE ? ['drawer--view-puzzle'] : []),\n ...(hideHeader ? ['drawer--header-hidden'] : []),\n ...(hideClose ? ['drawer--close-hidden'] : []),\n ...(bleedToEdge ? ['drawer--bleed-to-edge'] : []),\n ...(extraClassName ? [extraClassName] : []),\n ].join(' ')), [\n bleedToEdge,\n currentDrawer,\n extraClassName,\n forceModal,\n fullscreenOnMobile,\n hideClose,\n hideHeader,\n modalAutoGrow,\n size,\n state,\n ])\n\n if (state === 'hidden') {\n return null\n }\n\n return (\n <>\n <RotateScreenComponent />\n <div\n className={className}\n ref={drawerRef}\n >\n {header}\n <div\n className=\"drawer__content\"\n ref={drawerContent}\n onTouchStart={customVerticalScroll.handleTouchStart}\n onTouchMove={(e) => customVerticalScroll.handleTouchMove(e, drawerContent)}\n onTouchEnd={() => customVerticalScroll.handleTouchEnd(drawerContent)}\n >\n {content}\n </div>\n </div>\n {showConfetti && <ConfettiComponent />}\n </>\n )\n}\nexport default DrawerComponent\n","import { connect } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport * as timerActions from 'common_packages/assets/js/actions/timerActions'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { DrawerType } from 'common_packages/assets/js/types/drawerTypes'\nimport DrawerComponent, { DispatchProps, Props } from '../components/DrawerComponent'\n\nconst mapStateToProps = (state: StoreState): Props => {\n /* close will be a call to the ui reducer */\n const {\n drawer,\n drawerData,\n drawerForceModal,\n drawerFullscreenOnMobile,\n drawerModalAutoGrow,\n drawerHideHeader,\n drawerHideClose,\n drawerBleedToEdge,\n drawerClassName,\n drawerSize,\n drawerOnClose,\n } = state.ui\n\n return {\n drawer: drawer as DrawerType,\n drawerData,\n forceModal: drawerForceModal,\n fullscreenOnMobile: drawerFullscreenOnMobile,\n modalAutoGrow: drawerModalAutoGrow,\n hideHeader: drawerHideHeader,\n hideClose: drawerHideClose,\n bleedToEdge: drawerBleedToEdge,\n className: drawerClassName,\n size: drawerSize,\n onClose: drawerOnClose,\n }\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n pauseTimer: () => {\n dispatch(timerActions.pauseTimer())\n },\n resumeTimer: () => {\n dispatch(timerActions.resumeTimer())\n },\n close: () => {\n dispatch(uiActions.closeDrawer())\n },\n})\n\nexport default connect<Props, DispatchProps, unknown, StoreState>(mapStateToProps, mapDispatchToProps)(DrawerComponent)\n","import React, { type PropsWithChildren } from 'react'\nimport HeartToggleComponent from 'pages/common/components/toggles/HeartToggleComponent'\nimport usePuzzlePackTypeFavorite from 'client/hooks/usePuzzlePackTypeFavorite'\n\ntype Props = PropsWithChildren<{\n puzzlePackTypeId: number\n isStacked?: boolean,\n className?: string,\n}>\n\nconst HeartPuzzlePackTypeToggleContainer = ({ puzzlePackTypeId, ...rest }: Props) => {\n const { isFavorite, toggleIsFavorite } = usePuzzlePackTypeFavorite(puzzlePackTypeId)\n return (\n <HeartToggleComponent\n {...rest}\n isFavorite={isFavorite}\n toggleIsFavorite={toggleIsFavorite}\n />\n )\n}\n\nexport default HeartPuzzlePackTypeToggleContainer\n","import React, { ReactNode } from 'react'\nimport HeartToggleComponent from 'pages/common/components/toggles/HeartToggleComponent'\nimport usePuzzleTypeFavorite from 'client/hooks/usePuzzleTypeFavorite'\n\ntype Props = {\n puzzleTypeId: number\n miniPuzzleTypeId?: number\n isStacked?: boolean,\n className?: string,\n children?: ReactNode\n}\n\nconst HeartToggleContainer = ({\n puzzleTypeId, miniPuzzleTypeId, children, ...rest\n}: Props) => {\n const { isFavorite, toggleIsFavorite } = usePuzzleTypeFavorite(puzzleTypeId, miniPuzzleTypeId)\n return (\n <HeartToggleComponent\n {...rest}\n isFavorite={isFavorite}\n toggleIsFavorite={toggleIsFavorite}\n >\n {children}\n </HeartToggleComponent>\n )\n}\n\nexport default HeartToggleContainer\n","import React, { useEffect, useState } from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { useSelector } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport { UIState } from 'common_packages/assets/js/reducers/uiReducer'\nimport { browserVersion, isMobileSafari } from 'react-device-detect'\nimport { isIOS15OrAboveSafari } from 'common_packages/assets/js/utilities/devices'\nimport { getDisplayModeApp } from 'client/utilities/getDisplayModeApp'\nimport AppDisplayModes from 'client/constants/appDisplayModes'\n\nconst durationOpen = process.env.PLAYWRIGHT_ENV === 'true' ? 0 : 0.5\nconst durationClose = process.env.PLAYWRIGHT_ENV === 'true' ? 0 : 0.3\n\nconst overlayVariants = {\n open: {\n opacity: 1,\n transition: { duration: durationOpen },\n },\n closed: {\n opacity: 0,\n transition: { duration: durationClose },\n },\n}\nconst transparentVariants = {\n open: {\n opacity: 0,\n transition: { duration: 0 },\n },\n closed: {\n opacity: 0,\n transition: { duration: 0 },\n },\n}\n\ninterface Props {\n show: boolean\n drawerHideClose: boolean\n transparentOverlay: boolean\n onClose?: () => void\n}\n\nconst OverlayComponent = ({\n onClose,\n show,\n drawerHideClose,\n transparentOverlay,\n}: Props) => {\n const [clickable, setClickable] = useState(false)\n const displayMode = getDisplayModeApp()\n const drawerOnClose = useSelector<StoreState, UIState['drawerOnClose']>((store) => store.ui.drawerOnClose)\n\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout>\n\n // Delay the clickable state to prevent the overlay from being closed while in open animation.\n // Fixes the issue where the overlay is immediately closed when the drawer is opened on iOS standalone.\n if (show) {\n timer = setTimeout(() => {\n setClickable(true)\n }, 200)\n } else {\n setClickable(false)\n }\n\n return () => clearTimeout(timer)\n }, [show])\n\n const handleClick = () => {\n // Only prevent closing the overlay immediately for iOS standalone mode.\n if (clickable || !(isIOS15OrAboveSafari && displayMode === AppDisplayModes.standaloneIOS)) {\n if (!drawerHideClose) {\n onClose?.()\n }\n\n // additional onClose can be set through redux\n drawerOnClose?.()\n }\n }\n\n const className = [\n 'overlay',\n ...(isMobileSafari && browserVersion) === '16' ? ['overlay--safari16'] : [],\n ].join(' ')\n\n return (\n <AnimatePresence>\n {show && (\n <motion.div\n onClick={handleClick}\n className={className}\n key=\"overlay\"\n initial=\"closed\"\n animate=\"open\"\n exit=\"closed\"\n variants={transparentOverlay ? transparentVariants : overlayVariants}\n />\n )}\n\n </AnimatePresence>\n )\n}\n\nexport default OverlayComponent\n","import { connect } from 'react-redux'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions';\nimport OverlayComponent from '../components/overlays/OverlayComponent'\n\nconst mapStateToProps = (state) => {\n const { drawer, drawerHideClose, transparentOverlay } = state.ui\n return {\n show: drawer,\n drawerHideClose,\n transparentOverlay,\n }\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n onClose: () => {\n dispatch(uiActions.closeDrawer())\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(OverlayComponent)\n","import React, { useContext, useEffect } from 'react'\nimport { useSelector, useDispatch } from 'react-redux'\nimport { isIOS } from 'react-device-detect'\nimport {\n Route, RouteProps, useHistory, useLocation,\n} from 'react-router-dom'\nimport SEO from 'pages/common/SeoComponent'\nimport { type PuzzleType } from 'client/types/PuzzleType'\nimport { type StoreState } from 'client/store'\nimport { replaceAll } from 'client/utilities/replaceAll'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { getParamsFromQueryString } from 'client/utilities/getParamsFromQueryString'\nimport { type UserState } from 'client/reducers/userReducer'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { type DrawerType, drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { closeDrawer, setDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport LandingComponent from 'client/pages/landing/components/LandingComponent'\nimport { type ApiResult, klubbleAPI } from 'client/api/common'\nimport { logout, refreshToken } from 'client/api/authentication'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport { type ThemeColor } from 'client/types/Theme'\nimport { SubscriptionType } from 'client/enums/SubscriptionType'\nimport getParameterByName from 'common_packages/assets/js/utilities/getParameterByName'\nimport { IAuthToken } from 'client/interfaces/IAuthToken'\nimport { toastTypes } from 'common_packages/assets/js/types/toastTypes'\nimport { ThemeContext } from './theme/ThemeContext'\n\ntype Props = RouteProps & {\n isAuthenticated: boolean\n puzzleTypes?: Array<PuzzleType>\n anonymousAllowed?: boolean\n ignoreCanStartTrial?: boolean\n skipSubscriptionCheck?: boolean\n showLandingWhenUnAuthenticatedOrAnon?: boolean\n themeColor?: ThemeColor // optional theme color override used on iOS for coloring the top bar, defaults to primary color\n}\n\nconst PrivateRouteComponent = ({\n children,\n isAuthenticated,\n puzzleTypes,\n anonymousAllowed,\n skipSubscriptionCheck,\n showLandingWhenUnAuthenticatedOrAnon,\n themeColor = '--primary-color',\n ...rest\n}: Props) => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const abilities = useAbilities()\n const { roles, data } = useSelector<StoreState, UserState>((state) => state.user)\n const drawer = useSelector<StoreState, DrawerType>((store) => store.ui.drawer)\n const history = useHistory()\n const location = useLocation()\n const dispatch = useDispatch()\n const throwError = useAsyncError()\n\n const { theme } = useContext(ThemeContext)\n\n const renderLandingPage = () => (\n <>\n <SEO\n title={getTranslation(translationGroups.pageTitle, 'landing-page')}\n />\n <LandingComponent />\n </>\n )\n\n /**\n * Set the page title to the pathname\n */\n const getTitle = (path: string) => {\n /**\n * On the calendar pages, find the corresponding puzzleType name + - calender\n */\n\n if (path.includes('calendar')) {\n const puzzleTypeId = Number((path.split('/')[2]))\n const nameLangKey = puzzleTypes?.find((type) => type.puzzleTypeId === Number(puzzleTypeId))?.nameLangKey\n return `${getTranslation(translationGroups.puzzle, nameLangKey)} - ${getTranslation(translationGroups.pageTitle, 'calendar')}`\n }\n if (path.includes('player')) {\n const { gametype } = getParamsFromQueryString()\n return `${getTranslation(translationGroups.puzzle, gametype)} - ${getTranslation(translationGroups.pageTitle, 'player')}`\n }\n if (path === '/' || path === 'print-subscriber') {\n return theme.entityBrandName\n }\n return getTranslation(translationGroups.pageTitle, replaceAll(path, '/', '-')?.substring(1))\n }\n\n const shouldCheckPendingMandates = !abilities.isQRHost && !abilities.isAnonymous && !abilities.hasSubscription && !skipSubscriptionCheck && data?.emailConfirmed && roles?.length > 0\n const onboardingInProgress = drawer === drawerTypes.ONBOARD_MODAL || location.pathname.includes('/onboarding')\n const shouldShowTrialPresent = data && data.subscriptions?.find((e) => e.subscriptionTypeName === SubscriptionType.lightTrial && e.userNotified === false) && data.userName != null && !onboardingInProgress\n\n useEffect(() => {\n const acceptLightTrialPresent = async () => {\n try {\n const { data: response } = await klubbleAPI.post<ApiResult<IAuthToken>>(`Auth/accept-present?subscriptionType=${SubscriptionType.lightTrial}`)\n if (response.success) {\n dispatch(uiActions.addToast({\n message: getRawTranslation(translationGroups.onboarding, 'welcome-gift-toast'),\n type: toastTypes.SUCCESS,\n duration: 5000,\n customIcon: 'gift',\n }))\n refreshToken()\n } else {\n dispatch(uiActions.addToast({\n message: getRawTranslation(translationGroups.startLightTrial, response.message),\n type: toastTypes.ERROR,\n duration: 5000,\n }))\n }\n } catch {\n dispatch(uiActions.addToast({\n message: getRawTranslation(translationGroups.api, 'something-went-wrong'),\n type: toastTypes.ERROR,\n duration: 5000,\n }))\n }\n }\n\n if (shouldShowTrialPresent) {\n acceptLightTrialPresent()\n }\n if (shouldCheckPendingMandates) {\n // User is registered, email is confirmed but has no running plan, known to our backend.\n // Check with Twikey if this pending mandate is already signed, but not yet validated.\n klubbleAPI.post<ApiResult<boolean>>('/Auth/hassignedpendingmandates')\n .then((response) => {\n const hasSignedPendingMandates = response?.data?.data\n if (hasSignedPendingMandates) {\n // user has a mandate that the server just approved\n history.push('/payment-result?status=ok')\n }\n }).catch((e) => {\n throwError(e, 'Error loading hassignedpendingmandates')\n })\n }\n }, [dispatch, history, shouldCheckPendingMandates, shouldShowTrialPresent, throwError, getRawTranslation])\n useEffect(() => {\n if (abilities.hasLightSubscriptionOnly && !skipSubscriptionCheck) {\n // User has LIGHT subscription, possibly user upgraded to PREMIUM, but did not reach the success page, so backend is not aware.\n // Check with Twikey if this pending mandate is already signed, but not yet validated.\n\n klubbleAPI.post<ApiResult<boolean>>('/Auth/hassignedpendingmandates')\n .then((response) => {\n const hasSignedPendingMandates = response?.data?.data\n if (hasSignedPendingMandates) {\n // user has a mandate that the server just approved\n history.push('/payment-result?status=ok')\n }\n }).catch((e) => {\n throwError(e, 'Error loading hassignedpendingmandates')\n })\n }\n }, [history, abilities.hasLightSubscriptionOnly, skipSubscriptionCheck, throwError])\n\n const isFreeOrGiftOrMP = getParameterByName('free') === 'true' || getParameterByName('gift') === 'true' || getParameterByName('multiplayer') === 'true'\n const shouldShowOnboard = abilities.isIdentified && data?.userName == null && !isFreeOrGiftOrMP && !['/buy-pack', '/redirect', '/player', '/payment-success'].includes(location.pathname)\n\n useEffect(() => {\n if (shouldShowOnboard) {\n dispatch(setDrawer({\n drawer: drawerTypes.ONBOARD_MODAL,\n forceModal: true,\n fullscreenOnMobile: true,\n hideHeader: true,\n hideClose: true,\n className: 'drawer--onboard',\n }))\n }\n }, [shouldShowOnboard, dispatch])\n\n // QRHost can only see player\n if (abilities.isQRHost && !location.pathname.includes('player')) {\n dispatch(setDrawer({\n drawer: drawerTypes.GENERIC_ERROR,\n forceModal: true,\n drawerData: {\n content: getTranslation(translationGroups.qrGame, 'this-user-can-only-host-qr-games'),\n buttonText: getTranslation(translationGroups.qrGame, 'login-as-another-user'),\n onButtonClick: () => {\n dispatch(closeDrawer())\n logout()\n // when SSO is enabled the SSO provider handles this redirect\n if (process.env.KLUBBLE_LOGIN_SSO_ENABLED !== 'true') {\n history.push('/login')\n }\n },\n },\n }))\n return null\n }\n\n // User is unAuthenticated and therefore not allowed here.\n // Note: anonymous users are authenticated; they have a user id but no other user data.\n\n if (!isAuthenticated) {\n if (showLandingWhenUnAuthenticatedOrAnon) {\n return renderLandingPage()\n }\n history.push({\n pathname: '/login',\n state: { from: location },\n })\n return null\n }\n\n // User is anonymous and not explicitly allowed here by optional anonymousAllowed prop\n if (abilities.isAnonymous && !anonymousAllowed) {\n if (showLandingWhenUnAuthenticatedOrAnon) {\n return renderLandingPage()\n }\n history.push('/register')\n return null\n }\n\n if (isIOS) {\n document.querySelector('meta[name=theme-color]').setAttribute('content', location.pathname === '/' ? '#FFFFFF' : theme.cssVariables[themeColor])\n }\n\n // In all other cases, when not has been returned null before, render the wrapped children\n return (\n <Route {...rest}>\n <SEO\n title={getTitle(location.pathname)}\n />\n {children}\n </Route>\n )\n}\n\nexport default PrivateRouteComponent\n","import { StoreState } from 'client/store'\nimport { connect } from 'react-redux'\nimport PrivateRouteComponent from '../components/PrivateRouteComponent'\n\nconst mapStateToProps = (state: StoreState) => {\n const { data } = state.user\n return {\n isAuthenticated: data !== null,\n puzzleTypes: state.puzzleData?.puzzleTypes,\n }\n}\n\nexport default connect(mapStateToProps)(PrivateRouteComponent)\n","import { useEffect } from 'react'\nimport { useHistory } from 'react-router-dom'\n\n/*\n * This component sets the theme based on the entity name in the config.\n * Also, this component listens to the history and changes UI visibility based on changes.\n * Right now it only hides the endscreen and shows the nav bar on every page, since that could be turned off from the\n * endscreen.\n * */\nconst UIManagerComponent = ({\n showNav,\n setShowEndscreen,\n setShowNav,\n}): JSX.Element => {\n const history = useHistory()\n\n useEffect(() => {\n const unsubscribe = history.listen((l) => {\n setShowEndscreen(false)\n if (!showNav) {\n setShowNav(true)\n }\n })\n\n return unsubscribe\n }, [history, showNav, setShowNav, setShowEndscreen])\n\n return null\n}\n\nexport default UIManagerComponent\n","import { connect } from 'react-redux'\nimport { setShowEndscreen, setShowNav } from 'common_packages/assets/js/actions/uiActions'\nimport UIManagerComponent from '../components/UIManagerComponent'\n\nconst mapStateToProps = (state) => ({\n showNav: state.ui.showNav,\n})\n\nconst mapDispatchToProps = (dispatch: any) => ({\n setShowNav: (show) => {\n dispatch(setShowNav(show))\n },\n setShowEndscreen: (show) => {\n dispatch(setShowEndscreen(show))\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(UIManagerComponent)\n","import { connect } from 'react-redux'\nimport UserDataComponent from '../components/UserDataComponent'\nimport { setUser } from '../../../actions/userActions'\n\nconst mapStateToProps = (state) => ({\n hasUserData: !!state.user?.data,\n})\n\nconst mapDispatchToProps = (dispatch) => ({\n setUser: () => dispatch(setUser()),\n})\nexport default connect(mapStateToProps, mapDispatchToProps)(UserDataComponent)\n","import React, { PropsWithChildren, useEffect, useRef } from 'react'\nimport { useLocation } from 'react-router-dom'\nimport { useBroadcastChannel } from 'client/hooks/useBroadcastChannel'\nimport useConfig from 'client/hooks/useConfig'\nimport { IAuthToken } from 'client/interfaces/IAuthToken'\nimport useAbilities from 'client/hooks/useAbilities'\nimport {\n getCurrentToken,\n setToken,\n logout,\n checkHasActiveSSOSession,\n} from '../../../api/authentication'\n\ntype Props = PropsWithChildren<{\n hasUserData: boolean\n setUser: () => void\n}>\n\nconst SSO_SESSION_CHECK_INTERVAL_MS = 10 * 1000\n\nconst UserDataComponent = ({ hasUserData, setUser, children }: Props) => {\n const updateChannel = useBroadcastChannel('update-user-details')\n const { pathname } = useLocation()\n const lastSSOCheckTimeStamp = useRef(0)\n const config = useConfig()\n const { isIdentified, isAnonymous, isQRHost } = useAbilities()\n\n useEffect(() => {\n const msSinceLastCheck = Date.now() - lastSSOCheckTimeStamp.current\n const IsSSOSessionCheckAllowed = process.env.KLUBBLE_LOGIN_SSO_ENABLED === 'true'\n && msSinceLastCheck >= SSO_SESSION_CHECK_INTERVAL_MS\n && pathname !== '/logoutSSO'\n && hasUserData\n && isIdentified && !isQRHost && !isAnonymous\n\n if (IsSSOSessionCheckAllowed) {\n lastSSOCheckTimeStamp.current = Date.now()\n checkHasActiveSSOSession(config.entity.sso)\n .then((sessionIsActive) => {\n if (sessionIsActive === false) {\n // active local session but no session at SSO provider, so logout() and prompt with SSO login screen\n logout()\n }\n })\n }\n }, [config, hasUserData, pathname])\n\n useEffect(() => {\n if (pathname !== '/logoutSSO' && !hasUserData && getCurrentToken()) {\n setUser()\n }\n }, [setUser, hasUserData, pathname])\n\n useEffect(() => {\n updateChannel.onmessage = (e: MessageEvent<{ token?: IAuthToken }>) => {\n if (e.data.token) {\n setToken(e.data.token)\n }\n setUser()\n }\n }, [setUser, updateChannel])\n\n return (pathname !== '/logoutSSO' && !hasUserData && getCurrentToken()) ? null : (\n <>\n {' '}\n {children}\n {' '}\n </>\n )\n}\nexport default UserDataComponent\n","import React from 'react'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { toastTypes } from 'common_packages/assets/js/types/toastTypes'\nimport { Toast } from 'common_packages/assets/js/types/Toast'\nimport IconCheckmarkComponent from 'assets/icons/icon_check_bold.svg'\nimport IconClearComponnent from 'assets/icons/icon_clear.svg'\nimport IconInfoComponnent from 'assets/icons/icon_info.svg'\nimport IconGiftComponent from 'assets/icons/icon_gift.svg'\n\nimport ToastComponent from './ToastComponent'\n\ntype Props = {\n toasts: Array<Toast>\n remove: (id: number) => void\n}\n\nconst toastIcons = {\n [toastTypes.SUCCESS]: IconCheckmarkComponent,\n [toastTypes.INFO]: IconInfoComponnent,\n [toastTypes.ERROR]: IconClearComponnent,\n gift: IconGiftComponent,\n}\n\nexport type ToastIconType = keyof typeof toastIcons;\n\nconst variants = {\n enter: { y: -50, height: 0, opacity: 0 },\n open: { y: 0, height: 'calc(100%)', opacity: 1 },\n close: { y: -50, height: 0, opacity: 0 },\n}\n\nconst ToastsComponent = ({\n toasts, remove,\n}: Props) => (\n <div className=\"toasts container\">\n <AnimatePresence>\n {toasts?.map(({\n id, message, type, disableAutoClose, duration, customIcon,\n }) => (\n <motion.div\n key={id}\n variants={variants}\n initial=\"enter\"\n animate=\"open\"\n exit=\"close\"\n >\n <ToastComponent\n IconComponent={toastIcons[customIcon || type]}\n id={id}\n message={message}\n type={type}\n disableAutoClose={disableAutoClose}\n duration={duration}\n remove={remove}\n />\n </motion.div>\n ))}\n </AnimatePresence>\n </div>\n)\n\nexport default ToastsComponent\n","import { connect } from 'react-redux'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport ToastsComponent from '../../components/toasts/ToastsComponent'\n\nconst mapStateToProps = (state) => {\n /* close will be a call to the ui reducer */\n const { toasts } = state.ui\n\n return {\n toasts,\n }\n}\n\nconst mapDispatchToProps = (dispatch) => ({\n remove: (id: number) => {\n dispatch(uiActions.removeToast(id))\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(ToastsComponent)\n","import React from 'react'\n\nconst LoadingComponent = () => (\n <div className=\"loading\">\n <div className=\"loading__square\" />\n </div>\n)\n\nexport default LoadingComponent\n","import translationGroups from 'client/constants/translationGroups'\nimport React, { useContext } from 'react'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport useConfig from 'client/hooks/useConfig'\nimport SEO from '../SeoComponent'\nimport HeaderComponent from '../components/HeaderComponent'\nimport RoundedButtonComponent from '../components/buttons/RoundedButtonComponent'\nimport ErrorPageComponent from './ErrorPageComponent'\n\ntype Props = {\n error: Error | string\n resetError(): void\n}\n\n// ErrorComponent is used when an unexpected runtime exception occurs\nconst ErrorComponent = ({ resetError, error }: Props) => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const config = useConfig()\n\n // We provide hard-coded fallbacks for the translations in case the texts have failed loading too\n const textTitle = getRawTranslation(translationGroups.error, 'runtime-exception-title') || ':('\n const textDescription = getTranslation(translationGroups.error, 'runtime-exception-message') || 'An error occurred'\n const textButton = getRawTranslation(translationGroups.error, 'go-back') || 'Ok'\n const backUrl = config.entity?.publicUrl ?? '/'\n const message = error instanceof Error ? error.message : error\n const messageWithLinebreaks = message.split('\\n').reduce((acc, item) => (\n acc === null ? item : (\n <>\n {acc}\n <br />\n {item}\n </>\n )\n ), (<> </>))\n\n const handleBack = () => {\n resetError()\n window.location.href = backUrl\n }\n\n return (\n <div className=\"page-error-exception\">\n <SEO\n title={textTitle}\n description={textDescription}\n />\n <HeaderComponent showMenu={false} />\n <ErrorPageComponent\n title={textTitle}\n message={textDescription}\n >\n <div className=\"page-error-exception__error-description\">{messageWithLinebreaks}</div>\n\n <RoundedButtonComponent\n className=\"page-error-exception__button-back\"\n text={textButton}\n onClickHandler={handleBack}\n />\n </ErrorPageComponent>\n </div>\n )\n}\n\nexport default ErrorComponent\n","import React, { PropsWithChildren } from 'react'\nimport ErrorIcon from 'assets/images/misc/error.svg'\n\ntype Props = {\n title?: string\n message?: string\n}\n\nconst ErrorPageComponent = ({ title, message, children }: PropsWithChildren<Props>) => (\n <div className=\"page-error container\">\n <div className=\"page-error__icon-container\">\n <ErrorIcon />\n </div>\n <h1 className=\"page-error__title\">{title}</h1>\n <div className=\"page-error__message\">\n {message}\n {children}\n </div>\n </div>\n)\n\nexport default ErrorPageComponent\n","import React, { useContext } from 'react'\nimport { useHistory } from 'react-router'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport ErrorPageComponent from './ErrorPageComponent'\nimport SEO from '../SeoComponent'\nimport HeaderComponent from '../components/HeaderComponent'\nimport RoundedButtonComponent from '../components/buttons/RoundedButtonComponent'\n\nconst ErrorPageNotFoundComponent = () => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const history = useHistory()\n const handleBack = () => {\n history.push('/')\n }\n\n return (\n <div className=\"page-error-404\">\n <SEO\n title={getRawTranslation(translationGroups.error, 'page-not-found-title')}\n description={getRawTranslation(translationGroups.error, 'page-not-found-message')}\n />\n <HeaderComponent showMenu={false} />\n <ErrorPageComponent\n title={getTranslation(translationGroups.error, 'page-not-found-title')}\n message={getTranslation(translationGroups.error, 'page-not-found-message')}\n >\n <RoundedButtonComponent\n className=\"page-error-404__button-back\"\n text={getTranslation(translationGroups.error, 'go-back')}\n onClickHandler={handleBack}\n />\n </ErrorPageComponent>\n </div>\n )\n}\n\nexport default ErrorPageNotFoundComponent\n","import React, { useContext } from 'react'\nimport { useHistory } from 'react-router-dom'\nimport RoundedButtonComponent from 'pages/common/components/buttons/RoundedButtonComponent'\nimport CardComponent from '../../common/components/cards/CardComponent'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\n\nconst DailyDoseNoScoreCardComponent = () => {\n const translation = useContext(TranslationContext)\n const { push } = useHistory()\n return (\n <CardComponent className=\"daily-dose-no-score-card info-card\">\n <h2 className=\"info-card__title\">{translation.getTranslation(translationGroups.dailyDosePage, 'no-score-header')}</h2>\n <div className=\"info-card__body\">{translation.getTranslation(translationGroups.dailyDosePage, 'no-score-body')}</div>\n <div className=\"info-card__buttons\">\n <RoundedButtonComponent text={translation.getTranslation(translationGroups.dailyDosePage, 'no-score-play-puzzle-packs')} onClickHandler={() => { push('/puzzle-packs') }} />\n <RoundedButtonComponent text={translation.getTranslation(translationGroups.dailyDosePage, 'no-score-play-puzzles')} onClickHandler={() => { push('/puzzles') }} />\n </div>\n </CardComponent>\n )\n}\n\nexport default DailyDoseNoScoreCardComponent\n","import { animate } from 'framer-motion'\nimport React, { useEffect, useRef } from 'react'\n\ntype Props = {\n from: number,\n to: number,\n duration?: number,\n}\n\nconst CounterComponent = ({ from, to, duration = 1 }: Props): JSX.Element => {\n const nodeRef = useRef<HTMLParagraphElement>()\n\n useEffect(() => {\n const node = nodeRef.current\n\n /* We need to set the amount of frames within this animation to ensure a good rendering on multiple devices, especially on ios. */\n let prevVal = 0\n // duration in seconds times frames per second\n const frames = duration * 60\n const interval = (to - from) / frames\n const controls = animate(from, to, {\n duration,\n onUpdate(value) {\n if ((value > (prevVal + interval)) || value === to) {\n node.textContent = value.toFixed(0)\n prevVal = value\n }\n },\n })\n\n return () => controls.stop()\n }, [duration, from, to])\n\n return <p className=\"counter\" ref={nodeRef}>{to}</p>\n}\n\nexport default CounterComponent\n","import React from 'react'\nimport { motion } from 'framer-motion'\nimport { DailyDosesWithTotal } from 'client/types/DailyDose'\nimport CounterComponent from 'client/pages/common/components/CounterComponent'\n\nconst durationAnimationsToday = 1.4\n\ntype Props = {\n doses: DailyDosesWithTotal[],\n numPointsDay: number,\n animateOffset?: number,\n delay?: number,\n}\n\n/*\n* 1 for circles, get for one day, the doses with percentage required\n* 2 then use the same for dailydose today\n* */\nconst DailyDoseCirclesComponent = ({\n doses,\n numPointsDay,\n animateOffset,\n delay,\n}: Props): JSX.Element => {\n const lastThreeDoses = [...doses]\n .filter((dose) => dose.percentageOfRequired > 0)\n .reverse()\n .slice(0, 3)\n\n // get from outside in the first dose which is 100 percent\n const firstCompletedDoseIndex = lastThreeDoses.findIndex((dose) => dose.percentageOfRequired === 100)\n\n const getFirstStrokeDashArrayItem = (index: number): number => {\n // (numPointsDay - animateOffset)\n let strokeDashArrayFrom = 1\n if (animateOffset > 0) {\n if (index > firstCompletedDoseIndex) {\n strokeDashArrayFrom = 100\n } else if (index === firstCompletedDoseIndex) {\n const lastCirclePoints = numPointsDay - doses[firstCompletedDoseIndex].pointsRequired\n const completedDoseOffset = animateOffset - lastCirclePoints\n strokeDashArrayFrom = 100 - Math.abs(completedDoseOffset / numPointsDay * 100)\n }\n }\n return strokeDashArrayFrom\n }\n\n return (\n <div className=\"daily-dose-circles\">\n <svg viewBox=\"0 0 36 36\" className=\"daily-dose-circle\">\n <>\n <path\n className=\"daily-dose-circle__path daily-dose-circle__path--base\"\n strokeDasharray={100}\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n {/* Sort reversed dailydoses so they wont mutate. Only show the last 3 with a percentageOfRequired > 0 */}\n {lastThreeDoses\n .map((item, index) => {\n const scale = 1 - index * 0.2\n const strokeWidth = 2 * (1 / scale)\n const duration = index === 0 ? durationAnimationsToday / (10 / 9) : durationAnimationsToday\n return (\n <motion.path\n key={item.cssPostFix}\n strokeWidth={strokeWidth}\n initial={{\n scale,\n }}\n animate={{\n strokeDasharray: [`${getFirstStrokeDashArrayItem(index)}px, 100px`, `${item.percentageOfRequiredCircle}px, 100px`],\n transition: { duration, ease: 'linear', delay },\n\n }}\n className={`daily-dose-circle__path daily-dose-circle__path--${item.cssPostFix}`}\n d=\"M18 2.0845\n a 15.9155 15.9155 0 0 1 0 31.831\n a 15.9155 15.9155 0 0 1 0 -31.831\"\n />\n )\n })}\n\n </>\n </svg>\n <CounterComponent from={0} to={numPointsDay} duration={durationAnimationsToday} />\n </div>\n )\n}\nDailyDoseCirclesComponent.defaultProps = {\n animateOffset: 0,\n delay: 0,\n}\n\nexport default DailyDoseCirclesComponent\n","import { StoreState } from 'client/store'\nimport { connect } from 'react-redux'\nimport DailyDoseCirclesComponent from '../components/DailyDoseCirclesComponent'\nimport { getComposedDailyDoses } from '../utilities/dailyDoseComposer'\n\nconst mapStateToProps = (state: StoreState) => ({\n doses: getComposedDailyDoses(state.puzzleData.dailyDoseTypes, state.puzzleData?.dailyDoses?.[state.puzzleData?.dailyDoses.length - 1]),\n numPointsDay: state.puzzleData?.dailyDoses?.[state.puzzleData?.dailyDoses.length - 1]?.numPoints,\n})\n\nexport default connect(mapStateToProps, null)(DailyDoseCirclesComponent)\n","import { type DailyDosePeriod } from 'client/types/DailyDosePeriod'\n\nexport const DailyDosePeriodConstants = Object.freeze({\n fourWeeks: 28 as DailyDosePeriod,\n twoWeeks: 14 as DailyDosePeriod,\n week: 7 as DailyDosePeriod,\n})\n","export const datesEqual = (date1: Date, date2: Date) => date1.getFullYear() === date2.getFullYear()\n && date1.getMonth() === date2.getMonth()\n && date1.getDate() === date2.getDate()\n\nexport const getMonday = (today: Date) => {\n const day = today.getDay()\n const diff = today.getDate() - day + (day === 0 ? -6 : 1)\n return new Date(today.setDate(diff))\n}\n\nexport function getWeek(date: Date) {\n date.setHours(0, 0, 0, 0)\n /* Thursday in current week decides the year. */\n date.setDate(date.getDate() + 3 - ((date.getDay() + 6) % 7))\n /* January 4 is always in week 1. */\n const week1 = new Date(date.getFullYear(), 0, 4)\n /* Adjust to Thursday in week 1 and count number of weeks from date to week1. */\n return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + ((week1.getDay() + 6) % 7)) / 7)\n}\n","import { getWeek } from 'client/utilities/date'\nimport { DailyDose, DailyDoseType } from '../../../types/DailyDose'\n\nexport function getDailyDoseDaysWithinPeriod(dailyDoseDays, periodOffset, period): DailyDose[] {\n if (!dailyDoseDays?.length) {\n return []\n }\n const { from, to } = getTimespanInDays(dailyDoseDays, periodOffset, period)\n\n const dailyDoseDaysPeriod = dailyDoseDays?.slice(from, to)\n let emptyDayFills = []\n\n /* For visual reasons, fill the empty days */\n if (dailyDoseDaysPeriod?.length < period) {\n emptyDayFills = Array.from({ length: period - dailyDoseDaysPeriod.length }).map(() => ({\n composedTypes: [],\n date: null,\n numPoints: null,\n percentageOfRequired: null,\n }))\n }\n\n const filledDays = [...emptyDayFills, ...dailyDoseDaysPeriod]\n return filledDays\n}\n\n/*\n * For the DailyDosePeriod.fourweek view add the remaining days of the last week\n *\n * This method adds empty days for the current week for use in the four week filtered components: activities, summary, labels\n * @param dailyDoseDays\n */\nexport function getDailyDoseDaysFourWeeks(dailyDoseDays: (DailyDose & DailyDoseType)[]): (DailyDose & DailyDoseType)[] {\n const days = dailyDoseDays.map((day) => ({\n ...day,\n weekNumber: getWeek(new Date(day.date)),\n }))\n return days\n}\n\nexport const generateEmptyDaysForCurrentWeek = (lastDay: DailyDose): DailyDose[] => {\n const lastDate = lastDay?.date\n const daysToAdd = 7 - new Date(lastDate).getDay()\n\n const result: DailyDose[] = []\n for (let i = 0; i < daysToAdd; i += 1) {\n const date = addDays(lastDate, i + 1)\n const weekNumber = getWeek(new Date(date))\n result.push({\n date,\n weekNumber,\n numPoints: 0,\n puzzelTypes: [],\n })\n }\n return result\n}\n\n/*\n * This methods gets the indexes from the slice start\n * and end of the dailyDoseDays.\n * */\nexport function getTimespanInDays(doses, offset, period): { from: number, to: number } {\n let from = doses?.length + period * (offset - 1)\n const to = doses?.length + offset * period\n\n /* Make sure the first selected day is equal or bigger then 0 */\n if (from < 0) {\n from = 0\n }\n return {\n from,\n to,\n }\n}\n\nexport const addDays = (date: string, days: number) => {\n const result = new Date(date)\n result.setDate(result.getDate() + days)\n return result.toISOString()\n}\n","import React, { useContext, useMemo } from 'react'\nimport { generateEmptyDaysForCurrentWeek, getDailyDoseDaysFourWeeks, getTimespanInDays } from 'pages/daily_dose/utilities/dailyDoseActivities'\nimport { useSelector } from 'react-redux'\nimport { DailyDosePeriodConstants } from 'pages/daily_dose/components/constants/DailyDosePeriod'\nimport { StoreState } from 'klubble/app/client/store'\nimport { DailyDose } from 'klubble/app/client/types/DailyDose'\nimport { getWeek } from 'client/utilities/date'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\nimport { DailyDosePeriod } from '../../../types/DailyDosePeriod'\n\ntype Props = {\n period: DailyDosePeriod\n periodOffset: number,\n showSelectedDay?: boolean\n showWeekRange?: boolean,\n}\n\nconst DailyDoseDateComponent = ({\n period,\n periodOffset,\n showSelectedDay = false,\n showWeekRange = false,\n}: Props) => {\n const translation = useContext(TranslationContext)\n let dailyDoseDays = useSelector<StoreState, DailyDose[]>((state) => state.puzzleData.dailyDoses)\n let dailyDoseSelectedDate = useSelector<StoreState, string>((state) => state.puzzleData.dailyDoseSelectedDate)\n\n if (period === DailyDosePeriodConstants.fourWeeks) {\n dailyDoseDays = [\n ...getDailyDoseDaysFourWeeks(dailyDoseDays),\n ...generateEmptyDaysForCurrentWeek(dailyDoseDays[dailyDoseDays.length - 1]),\n ]\n }\n\n if (!dailyDoseSelectedDate) {\n dailyDoseSelectedDate = [...dailyDoseDays]?.reverse().find((day) => day.date)?.date\n }\n\n const headerTitle = useMemo(() => {\n if (showSelectedDay) {\n const currentDate = new Date(Date.parse(dailyDoseSelectedDate))\n\n if (Number.isNaN(currentDate.getTime())) {\n return ''\n }\n\n // Show just one day\n const day = translation.getRawTranslation(translationGroups.weekDays, currentDate.getDay())\n const month = translation.getRawTranslation(translationGroups.months, currentDate.getMonth())\n const date = currentDate.getDate()\n\n return `${day}, ${date} ${month}`\n }\n\n const { from, to } = getTimespanInDays(dailyDoseDays, periodOffset, period)\n let fromDate: Date\n let toDate: Date\n\n /*\n If showWeekRange equals true give the first and last day of\n the current selected week. This only happens in the fourweek view\n */\n if (showWeekRange) {\n const selectedWeekNumber = getWeek(new Date(dailyDoseSelectedDate))\n const selectedYear = dailyDoseSelectedDate.substring(0, 4)\n const selectedWeekDays = dailyDoseDays.filter((day) => day.weekNumber === selectedWeekNumber && day.date.substring(0, 4) === selectedYear)\n\n fromDate = new Date(selectedWeekDays[0].date)\n toDate = new Date(selectedWeekDays[selectedWeekDays.length - 1].date)\n } else {\n /* Otherwise, show the first and last date of the selected timespan (for the activity header for example) */\n fromDate = new Date(dailyDoseDays[from]?.date)\n toDate = new Date(dailyDoseDays[to - 1]?.date)\n }\n\n if (Number.isNaN(fromDate.getTime()) || Number.isNaN(toDate.getTime())) {\n return ''\n }\n\n // Show a range (from - to)\n const rangeFromDate = fromDate?.getDate()\n const rangeFromMonth = translation.getRawTranslation(translationGroups.months, fromDate?.getMonth())\n const rangeToDate = toDate?.getDate()\n const rangeToMonth = translation.getRawTranslation(translationGroups.months, toDate?.getMonth())\n\n return ` ${rangeFromMonth} ${rangeFromDate} - ${rangeToMonth} ${rangeToDate} `\n }, [dailyDoseDays, dailyDoseSelectedDate, period, periodOffset, showSelectedDay, showWeekRange, translation])\n\n if (!dailyDoseSelectedDate) {\n return null\n }\n\n return (\n <>\n {headerTitle}\n </>\n )\n}\n\nexport default DailyDoseDateComponent\n","import React, { useContext, useMemo } from 'react'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { DailyDosePeriod } from 'client/types/DailyDosePeriod'\nimport { datesEqual, getMonday } from 'client/utilities/date'\n\ntype Props = {\n period: DailyDosePeriod\n selectedDate: string\n}\n\nconst DailyDoseGameTypeSummaryNoScore = ({ selectedDate, period }: Props) => {\n const translation = useContext(TranslationContext)\n const suffix = useMemo(() => {\n const date = new Date(selectedDate);\n const today = new Date();\n if (period === 14 || period === 7) {\n if (datesEqual(date, today)) {\n return 'today'\n }\n return 'previous-day'\n }\n if (period === 28) {\n const monday = getMonday(today)\n if (datesEqual(date, monday)) {\n return 'current-week'\n }\n return 'previous-week'\n }\n return ''\n }, [period, selectedDate])\n return (\n <div className=\"daily-dose-gametype-summary__no-score\">\n {translation.getTranslation(translationGroups.dailyDosePage, `empty-score-${suffix}`)}\n </div>\n )\n}\n\nexport default DailyDoseGameTypeSummaryNoScore\n","import React, { useContext, useEffect, useState } from 'react'\nimport { useSelector } from 'react-redux'\nimport { type StoreState } from 'klubble/app/client/store'\nimport { DailyDosePeriodConstants } from 'pages/daily_dose/components/constants/DailyDosePeriod'\nimport DailyDoseDateComponent from 'pages/daily_dose/components/DailyDoseDateComponent'\nimport GameCardComponent from 'pages/common/components/game_cards/GameCardComponent'\nimport { type ApiResult, klubbleAPI } from 'client/api/common'\nimport { type PuzzleFormat } from 'client/constants/puzzleFormat'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { type DailyDosePeriod } from 'client/types/DailyDosePeriod'\nimport { type DailyDose } from 'client/types/DailyDose'\nimport DailyDoseGameTypeSummaryNoScore from './DailyDoseGameTypeSummaryNoScore'\n\ntype Props = {\n periodOffset: number\n period: DailyDosePeriod\n}\n\ntype DailyDoseGameType = { type: string, points: number, format: PuzzleFormat }\n\nconst DailyDoseGameTypeSummaryComponent = ({\n period,\n periodOffset,\n}: Props) => {\n const translation = useContext(TranslationContext)\n const dailyDoseSelectedDate = useSelector<StoreState, string>((state) => state.puzzleData.dailyDoseSelectedDate)\n const [isLoading, setIsLoading] = useState(false)\n // Get dailyDoseDays and dailyDoseTypes from redux state\n const dailyDoseDays = useSelector<StoreState, DailyDose[]>((state) => state.puzzleData.dailyDoses)\n const [dailyDoseGameTypeSummary, setDailyDoseGameTypeSummary] = useState<DailyDoseGameType[]>([])\n\n useEffect(() => {\n const abortController = new AbortController()\n\n const getDailyDoseSummaryGameTypes = async (timespan: 'day' | 'week'):Promise<DailyDoseGameType[]> => {\n if (!dailyDoseSelectedDate) {\n return []\n }\n\n try {\n setIsLoading(true)\n const { data: response } = await klubbleAPI.get<ApiResult<DailyDoseGameType[]>>(`Puzzle/dailydoses${timespan}?date=${dailyDoseSelectedDate}`, { signal: abortController?.signal })\n return response?.data ?? []\n } catch {\n return []\n } finally {\n setIsLoading(false)\n }\n }\n\n if (period === DailyDosePeriodConstants.week || period === DailyDosePeriodConstants.twoWeeks) {\n getDailyDoseSummaryGameTypes('day').then((dailyDoseGameTypes) => setDailyDoseGameTypeSummary(dailyDoseGameTypes))\n } else if (period === DailyDosePeriodConstants.fourWeeks) {\n getDailyDoseSummaryGameTypes('week').then((dailyDoseGameTypes) => {\n const groupedGameTypes = dailyDoseGameTypes.reduce((result, item) => {\n const gameTypeFound = result.find((el) => el.type === item.type)\n if (gameTypeFound) {\n gameTypeFound.points += item.points\n } else {\n result.push(item)\n }\n return result\n }, [])\n setDailyDoseGameTypeSummary(groupedGameTypes)\n })\n }\n return () => {\n abortController.abort()\n }\n }, [dailyDoseSelectedDate, dailyDoseDays, period])\n\n const totalPoints = dailyDoseGameTypeSummary.reduce(\n (accumulator, type) => accumulator + type.points,\n 0,\n )\n const className = `daily-dose-gametype-summary${isLoading ? ' daily-dose-gametype-summary--loading' : ''}`\n\n return (\n <div className={className}>\n <h2 className=\"section-header\">\n <DailyDoseDateComponent\n period={period}\n periodOffset={periodOffset}\n showWeekRange={period === DailyDosePeriodConstants.fourWeeks}\n showSelectedDay={period === DailyDosePeriodConstants.week || period === DailyDosePeriodConstants.twoWeeks}\n />\n </h2>\n\n <div className=\"daily-dose-gametype-summary__card card\">\n <div className=\"daily-dose-gametype-summary__list\">\n {dailyDoseGameTypeSummary.map((puzzle, index) => (\n <GameCardComponent\n key={`${puzzle.type + index}`}\n nameLangKey={puzzle.type}\n isStacked\n disableLink\n subtitle={translation.getTranslation(translationGroups.puzzle, puzzle.format)}\n >\n <div className=\"game-card__right\">{puzzle.points}</div>\n </GameCardComponent>\n ))}\n {dailyDoseGameTypeSummary.length === 0 && (\n <DailyDoseGameTypeSummaryNoScore period={period} selectedDate={dailyDoseSelectedDate} />\n )}\n </div>\n <div className=\"list-item\">\n <div className=\"list-item__icon\">\n {translation.getTranslation(translationGroups.dailyDosePage, 'total')}\n </div>\n <div className=\"list-item__right\">{totalPoints}</div>\n </div>\n </div>\n </div>\n )\n}\n\nexport default DailyDoseGameTypeSummaryComponent\n","import { StoreState } from 'client/store';\nimport { connect } from 'react-redux'\nimport DailyDoseTodayItemsComponent from '../components/DailyDoseTodayItemsComponent'\nimport { getComposedDailyDoses } from '../utilities/dailyDoseComposer';\n\nconst mapStateToProps = (state: StoreState) => ({\n doses: getComposedDailyDoses(state.puzzleData.dailyDoseTypes, state.puzzleData?.dailyDoses?.[state.puzzleData?.dailyDoses.length - 1]),\n})\n\nexport default connect(mapStateToProps, null)(DailyDoseTodayItemsComponent)\n","import React, { useContext } from 'react'\nimport IconCheckmark from 'client/assets/icons/icon_checkmark.svg'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { DailyDosesWithTotal } from 'client/types/DailyDose'\n\ninterface Props {\n doses: DailyDosesWithTotal[]\n}\n\nconst DailyDoseTodayItemsComponent = ({ doses }: Props) => {\n const translation = useContext(TranslationContext)\n\n return (\n <div className=\"daily-dose-today-items\">\n {doses.map((dose, _index) => (\n <div className=\"list-item\" key={`${dose.nameLangKey}`}>\n <div className={`list-item__icon list-item__icon--${dose.cssPostFix}`}>\n {dose.percentageOfRequired === 100 && <IconCheckmark />}\n </div>\n <span className=\"list-item__description\">\n {translation.getTranslation(translationGroups.dailyDosePage, `dose-${dose.nameLangKey.toLowerCase()}`)}\n </span>\n <span className=\"list-item__right\">\n {dose.pointsRequired}\n {' '}\n {translation.getTranslation(translationGroups.dailyDosePage, 'points')}\n </span>\n </div>\n ))}\n </div>\n )\n}\n\nexport default DailyDoseTodayItemsComponent\n","import React, { useContext } from 'react'\n\nimport CardComponent from '../../common/components/cards/CardComponent'\nimport DailyDoseNoScoreComponent from './DailyDoseNoScoreComponent'\nimport DailyDoseCirclesContainer from '../containers/DailyDoseCirclesContainer'\nimport DailyDoseTodayItemsContainer from '../containers/DailyDoseTodayItemsContainer'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\n\ntype Props = {\n numPointsDay: number,\n animateOffset?: number,\n delay?: number\n}\n\nconst DailyDoseTodayComponent = ({ numPointsDay, animateOffset, delay }:Props) => {\n const translation = useContext(TranslationContext)\n\n return (\n <div className=\"daily-dose-today\">\n <h2 className=\"section-header\">{translation.getTranslation(translationGroups.dailyDosePage, 'today')}</h2>\n {numPointsDay === 0\n && (\n <DailyDoseNoScoreComponent />\n )}\n <CardComponent>\n <DailyDoseCirclesContainer animateOffset={animateOffset} delay={delay} />\n <DailyDoseTodayItemsContainer />\n </CardComponent>\n </div>\n )\n}\n\nDailyDoseTodayComponent.defaultProps = {\n animateOffset: 0,\n delay: 0,\n}\n\nexport default DailyDoseTodayComponent\n","import { connect } from 'react-redux'\nimport DailyDoseTodayComponent from '../components/DailyDoseTodayComponent'\n\nconst mapStateToProps = (state) => ({\n numPointsDay: state.puzzleData?.dailyDoses?.[state.puzzleData?.dailyDoses.length - 1]?.numPoints,\n})\n\nexport default connect(mapStateToProps, null)(DailyDoseTodayComponent)\n","import { connect } from 'react-redux'\nimport DailyDoseActivityBarComponent from 'pages/daily_dose/components/DailyDoseActivityBarComponent'\nimport { DailyDoseEnum } from 'client/enums/DailyDoseEnum'\nimport { setDailyDoseSelectedDate } from '../../../actions/puzzleDataActions'\n\nconst mapStateToProps = (state) => ({\n dailyDoseSelectedDate: state.puzzleData.dailyDoseSelectedDate,\n dailyDoseRequiredCirclePoints: state.puzzleData.dailyDoseTypes.find((dailyDoseType) => dailyDoseType.nameLangKey === DailyDoseEnum.DAILY_DOSE)?.pointsRequired,\n})\n\nconst mapDispatchToProp = (dispatch) => ({\n onClick: (date) => {\n dispatch(setDailyDoseSelectedDate(date))\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProp)(DailyDoseActivityBarComponent)\n","import React from 'react'\nimport { motion } from 'framer-motion'\nimport { DailyDosePeriod } from '../../../types/DailyDosePeriod'\nimport { DailyDose } from '../../../types/DailyDose'\nimport IconCheckmark from '../../../assets/icons/icon_checkmark.svg'\nimport { DailyDosePeriodConstants } from './constants/DailyDosePeriod'\nimport { DailyDosePositionConfig, MAX_SCORE } from './DailyDoseActivityComponent'\n\ntype Props = {\n dailyDose: DailyDose,\n cssPostFix?: string,\n index: number,\n period: DailyDosePeriod,\n transitionDelay: number,\n positionConfig: DailyDosePositionConfig,\n maxDailyDose: number,\n dailyDoseRequiredCirclePoints: number,\n onClick: (date: string) => void,\n onMouseOver: () => void\n onMouseOut: () => void\n}\n\nconst DailyDoseActivityBarComponent = ({\n dailyDose,\n cssPostFix,\n index,\n period,\n transitionDelay,\n positionConfig,\n maxDailyDose,\n dailyDoseRequiredCirclePoints,\n onClick,\n onMouseOver,\n onMouseOut,\n}: Props) => {\n let classNameLine = 'daily-dose-activity__bar-line'\n let classNameCircle = 'daily-dose-activity__bar-circle'\n\n if (cssPostFix) {\n classNameLine += ` ${classNameLine}--${cssPostFix}`\n classNameCircle += ` ${classNameCircle}--${cssPostFix}`\n }\n\n let lineWidth = 1.6\n if (period === DailyDosePeriodConstants.fourWeeks) {\n lineWidth = 0.375\n }\n /*\n Calculate y1 position: 100 is default minus radius bottom\n width = 0.8 rem height = 12 rem'\n */\n\n /*\n * The max points that are showed are 1600, to make sure extremes dont obscure the view\n * */\n const limitedNumpoints = Math.min(dailyDose.numPoints, MAX_SCORE)\n const ratioOfMax = (limitedNumpoints / maxDailyDose)\n\n /*\n * 70 percent of the bar height is dependant of the score, 30 percent is default\n * */\n const percentageOfMaxDailyDoseOfPeriod = ratioOfMax * 70 + 30\n const yStart = 100 - ((lineWidth / 2) / 12) * 100 - 1 // -1 to make it fit\n const yDestination = 100 - (percentageOfMaxDailyDoseOfPeriod) + positionConfig.circleHeight * 2 + positionConfig.marginTop || 0\n\n return (\n <svg\n onClick={() => onClick(dailyDose.date)}\n onMouseOver={onMouseOver}\n onMouseOut={onMouseOut}\n viewBox={`0 0 1 ${8 * (1.6 / lineWidth)}`}\n className=\"daily-dose-activity__bar-line-container\"\n style={{\n width: `${lineWidth}rem`,\n margin: 'auto',\n height: '100%',\n }}\n data-date={dailyDose.date}\n >\n <motion.line\n animate={{\n y1: [`${100 - positionConfig.circleHeight / 2}%`,\n `${yDestination}%`],\n opacity: 1,\n }}\n initial={{\n opacity: 0,\n }}\n transition={{\n duration: 0.3,\n delay: index * transitionDelay,\n type: 'spring',\n }}\n y2={`${yStart}%`}\n style={{\n stroke: cssPostFix || dailyDose.numPoints === 0 ? null : '#f3a1c2',\n }}\n className={classNameLine}\n x1={0.5}\n x2={0.5}\n strokeLinecap=\"round\"\n />\n {dailyDose.numPoints > 0\n && (\n <motion.g\n animate={{\n scale: [1.2, 0.8, 1],\n opacity: [0.2, 1, 1],\n }}\n transition={{\n delay: 0.6,\n type: 'spring',\n }}\n initial={{\n opacity: 0,\n }}\n >\n {(DailyDosePeriodConstants.fourWeeks !== period && dailyDose.numPoints >= dailyDoseRequiredCirclePoints) && (\n <>\n {/* 5 is added as margin, otherwise the element gets shadowed by the svg container */}\n <circle\n className={classNameCircle}\n cx={0.5}\n cy={`${100 - percentageOfMaxDailyDoseOfPeriod + positionConfig.marginTop}%`}\n r=\"0.3\"\n />\n <IconCheckmark\n fill=\"#fff\"\n x={`${50 - positionConfig.circleWidth / 2}%`}\n y={`${100 - percentageOfMaxDailyDoseOfPeriod - positionConfig.checkMarkHeight / 2 + positionConfig.marginTop}%`}\n width={`${positionConfig.circleWidth}%`}\n height={`${positionConfig.circleHeight}%`}\n />\n </>\n )}\n </motion.g>\n )}\n </svg>\n )\n}\n\nexport default DailyDoseActivityBarComponent\n","import { StoreState } from 'client/store'\nimport { DailyDose, DailyDoseType } from 'client/types/DailyDose'\nimport { DailyDosePeriod } from 'client/types/DailyDosePeriod'\nimport { useMemo } from 'react'\nimport { useSelector } from 'react-redux'\nimport { DailyDosePeriodConstants } from 'pages/daily_dose/components/constants/DailyDosePeriod'\nimport { generateEmptyDaysForCurrentWeek, getDailyDoseDaysWithinPeriod } from './dailyDoseActivities'\n\n// Returns an object where DailyDose and DailyDoseType are merged of the highest achieved Daily dose\n// for given period and periodOffset.\nexport const useDailyDosesWithDoseType = (periodOffset: number, period: DailyDosePeriod): (DailyDose & DailyDoseType)[] => {\n const dailyDoseDays = useSelector<StoreState, DailyDose[]>((state) => state.puzzleData.dailyDoses)\n const dailyDoseTypes = useSelector<StoreState, DailyDoseType[]>((state) => state.puzzleData.dailyDoseTypes)\n\n // Only the four weeks view needs extra days to group and sum days for a full week\n let dailydoseDaysForPeriod = dailyDoseDays\n if (period === DailyDosePeriodConstants.fourWeeks) {\n dailydoseDaysForPeriod = [\n ...dailyDoseDays,\n ...generateEmptyDaysForCurrentWeek(dailyDoseDays[dailyDoseDays.length - 1])]\n }\n const dailyDosesWithDoseType = useMemo(() => {\n // Find the highest achieved daily dose in the range\n const dailyDoseDaysWithinPeriod = getDailyDoseDaysWithinPeriod(dailydoseDaysForPeriod, periodOffset, period)\n return dailyDoseDaysWithinPeriod.reduce<DailyDose[]>((acc, value) => {\n acc.push({\n ...value,\n ...findDailyDoseType(value, dailyDoseTypes),\n })\n return acc\n }, [])\n }, [dailyDoseTypes, dailydoseDaysForPeriod, period, periodOffset])\n\n return dailyDosesWithDoseType;\n}\n\n// Returns an object where DailyDose and DailyDoseType are merged of the highest achieved Daily dose\n// for given period and periodOffset.\nexport const useHighestAchievedDoseWithDoseType = (periodOffset: number, period: DailyDosePeriod): DailyDose & DailyDoseType => {\n const dailyDoseDays = useSelector<StoreState, DailyDose[]>((state) => state.puzzleData.dailyDoses)\n const dailyDoseTypes = useSelector<StoreState, DailyDoseType[]>((state) => state.puzzleData.dailyDoseTypes)\n const highestAchievedDoseWithDoseType = useMemo(() => {\n // Find the highest achieved daily dose in the range\n const dailyDoseDaysWithinPeriod = getDailyDoseDaysWithinPeriod(dailyDoseDays, periodOffset, period)\n const highestAchievedDose = dailyDoseDaysWithinPeriod.reduce((acc, value) => {\n if (!acc?.numPoints || value.numPoints > acc?.numPoints) {\n // eslint-disable-next-line no-param-reassign\n acc = value\n }\n return acc\n }, null)\n\n const doseType = dailyDoseTypes.reduce((acc, value) => {\n if (highestAchievedDose?.numPoints >= value.pointsRequired) {\n return value\n }\n return acc\n }, dailyDoseTypes?.[0])\n return {\n ...doseType,\n ...highestAchievedDose,\n }\n }, [dailyDoseDays, dailyDoseTypes, period, periodOffset])\n return highestAchievedDoseWithDoseType;\n}\n\n// Finds DailyDoseType belonging to given DailyDose\nconst findDailyDoseType = (dailyDose: DailyDose, dailyDoseTypes: DailyDoseType[]) => {\n return dailyDoseTypes.reduce((acc, value) => {\n if (dailyDose.numPoints > value.pointsRequired) {\n return value\n }\n return acc\n }, dailyDoseTypes?.[0])\n}\n","import translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { DailyDosePeriod } from 'client/types/DailyDosePeriod'\nimport React, { useContext, useMemo } from 'react'\nimport { useHighestAchievedDoseWithDoseType } from '../utilities/hooks'\nimport { DailyDosePositionConfig } from './DailyDoseActivityComponent'\n\ntype Props = {\n positionConfig: DailyDosePositionConfig,\n period: DailyDosePeriod,\n periodOffset: number,\n}\n\nconst DailyDoseActivityExtremeComponent = ({\n positionConfig,\n periodOffset,\n period,\n}: Props) => {\n const zeroPoint = (positionConfig.circleHeight + 1 + positionConfig.marginTop)\n const translation = useContext(TranslationContext)\n\n const highestAchievedDoseWithDoseType = useHighestAchievedDoseWithDoseType(periodOffset, period)\n\n const barHeight = useMemo(() => {\n return (1 - highestAchievedDoseWithDoseType.pointsRequired / highestAchievedDoseWithDoseType.numPoints) * (100 - (zeroPoint + 12))\n }, [highestAchievedDoseWithDoseType.numPoints, highestAchievedDoseWithDoseType.pointsRequired, zeroPoint])\n\n // this happens when you have < 100 points\n if (barHeight < 0) {\n return null\n }\n if (!highestAchievedDoseWithDoseType.nameLangKey) {\n return null\n }\n const title = `${translation.getTranslation(translationGroups.dailyDosePage, `dose-${highestAchievedDoseWithDoseType.nameLangKey}`)} \n ${highestAchievedDoseWithDoseType.pointsRequired} ${translation.getTranslation(translationGroups.dailyDosePage, 'points')}`\n\n return (\n <div\n className=\"daily-dose-activity__extreme\"\n style={{\n top: `${zeroPoint}%`,\n height: `${barHeight}%`,\n }}\n >\n <div className=\"daily-dose-activity__extreme__label\" title={title}>\n {translation.getTranslation(translationGroups.dailyDosePage, `dose-${highestAchievedDoseWithDoseType.nameLangKey}-short`)}\n </div>\n </div>\n )\n}\n\nexport default DailyDoseActivityExtremeComponent\n","import React from 'react'\nimport DailyDoseDateComponent from 'pages/daily_dose/components/DailyDoseDateComponent'\nimport { DailyDosePeriod } from '../../../types/DailyDosePeriod'\nimport CarouselBarArrowComponent from '../../common/components/carouselbar/CarouselBarArrowComponent'\n\ntype Props = {\n setPreviousPeriod: () => void\n setNextPeriod: () => void\n periodOffset: number\n period: DailyDosePeriod\n showPrevArrow:boolean\n}\n\nconst DailyDoseActivityHeaderComponent = ({\n setPreviousPeriod, setNextPeriod, periodOffset, period, showPrevArrow,\n}: Props) => (\n <div className=\"daily-dose-activity__header\">\n <CarouselBarArrowComponent arrowDirection=\"left\" disabled={!showPrevArrow} onClickHandler={setPreviousPeriod} />\n <span className=\"daily-dose-activity__header-title\">\n <DailyDoseDateComponent periodOffset={periodOffset} period={period} />\n </span>\n <CarouselBarArrowComponent arrowDirection=\"right\" disabled={periodOffset === 0} onClickHandler={setNextPeriod} />\n </div>\n)\n\nexport default DailyDoseActivityHeaderComponent\n","import React from 'react'\n\ntype Props = {\n periodSelected: boolean,\n hover?: boolean,\n width: number,\n periodCompleted: number,\n periodName: string | number,\n onClick: () => void\n onMouseOver: () => void\n onMouseOut: () => void\n}\n\nconst DailyDoseActivityLabelComponent = ({\n periodSelected,\n hover,\n width,\n periodCompleted,\n periodName,\n onClick,\n onMouseOver,\n onMouseOut,\n}: Props) => {\n let classNameLineLabel = 'daily-dose-activity__bar-label'\n if (periodSelected) {\n classNameLineLabel += ` ${classNameLineLabel}--selected`\n }\n\n return (\n <div\n style={{\n width: `${width}%`,\n bottom: 0,\n position: 'relative',\n }}\n onClick={onClick}\n onMouseOver={onMouseOver}\n onMouseOut={onMouseOut}\n role=\"button\"\n >\n <span className={classNameLineLabel}>\n {periodName}\n </span>\n <span className={classNameLineLabel}>{periodCompleted}</span>\n { periodSelected && <div className=\"daily-dose-activity__bar-label-underline\" /> }\n { hover && !periodSelected && <div className=\"daily-dose-activity__bar-label-hover\" /> }\n </div>\n )\n}\n\nexport default DailyDoseActivityLabelComponent\n","import React, { useContext, useMemo, useState } from 'react'\nimport { useSelector, useDispatch } from 'react-redux'\nimport DailyDoseActivityBarContainer from 'pages/daily_dose/containers/DailyDoseActivityBarContainer'\nimport { DailyDosePeriodConstants } from 'pages/daily_dose/components/constants/DailyDosePeriod'\nimport DailyDoseActivityExtremeComponent from 'pages/daily_dose/components/DailyDoseActivityExtremeComponent'\nimport { getDailyDoseDaysFourWeeks, getTimespanInDays } from 'pages/daily_dose/utilities/dailyDoseActivities'\nimport { StoreState } from 'klubble/app/client/store'\nimport { DailyDoseEnum } from 'client/enums/DailyDoseEnum'\nimport { getWeek } from 'client/utilities/date'\nimport breakpoints from 'common_packages/assets/js/constants/breakpoints'\nimport useWindowDimensions from 'common_packages/assets/js/hooks/useWindowDimensions'\nimport { DailyDosePeriod } from '../../../types/DailyDosePeriod'\nimport CardComponent from '../../common/components/cards/CardComponent'\nimport DailyDoseActivityHeaderComponent from './DailyDoseActivityHeaderComponent'\nimport DailyDoseActivityLabelComponent from './DailyDoseActivityLabelComponent'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\nimport { DailyDose } from '../../../types/DailyDose'\nimport { setDailyDoseSelectedDate } from '../../../actions/puzzleDataActions'\nimport { useDailyDosesWithDoseType, useHighestAchievedDoseWithDoseType } from '../utilities/hooks'\n\nexport const MAX_SCORE = 1600\nconst periodNames = {\n 7: 'day',\n 14: 'day',\n 28: 'week',\n}\n\nconst cssPostfixes = {\n [DailyDoseEnum.DAILY_DOSE]: 'daily-dose',\n [DailyDoseEnum.DOUBLE_DOSE]: 'double-dose',\n [DailyDoseEnum.MEGA_DOSE]: 'mega-dose',\n [DailyDoseEnum.ULTRA_DOSE]: 'ultra-dose',\n [DailyDoseEnum.EPIC_DOSE]: 'epic-dose',\n}\n\ntype Props = {\n period: DailyDosePeriod,\n setPeriod: (period: DailyDosePeriod) => void\n periodOffset: number,\n setPeriodOffset: (offset: number) => void,\n}\n\nexport interface DailyDosePositionConfig {\n circleWidth: number,\n circleHeight: number,\n checkMarkHeight: number,\n labelMargin: number,\n marginTop: number,\n}\n\ntype DailyDoseLabel = {\n weekNumber?: number;\n dates?: string[];\n date?: string;\n numPoints?: number;\n}\n\nconst DailyDoseActivityComponent = (props: Props) => {\n const {\n period,\n periodOffset,\n setPeriodOffset,\n setPeriod,\n } = props\n const translation = useContext(TranslationContext)\n const { width } = useWindowDimensions()\n const dispatch = useDispatch()\n const dailyDoseDays = useSelector<StoreState, DailyDose[]>((state) => state.puzzleData.dailyDoses)\n const dailyDoseSelectedDate = useSelector<StoreState, string>((state) => state.puzzleData.dailyDoseSelectedDate)\n const [hoveredLabel, setHoveredLabel] = useState<string>()\n\n const handleClickLabel = (date: string) => {\n dispatch(setDailyDoseSelectedDate(date))\n }\n\n const movePeriod = (direction: number): void => {\n const { to } = getTimespanInDays(dailyDoseDays, periodOffset + direction, period)\n if (to > 0 && ((periodOffset === 0 && direction === -1) || periodOffset < 0) && hasActivityFromStartTillPeriod(direction)) {\n setPeriodOffset(periodOffset + direction)\n }\n }\n\n const hasActivityFromStartTillPeriod = (direction: number): boolean => {\n const { to } = getTimespanInDays(dailyDoseDays, periodOffset + direction, period)\n return dailyDoseDays.slice(0, to).some((day) => day.numPoints > 0)\n }\n\n const togglePeriod = () => {\n if (period === DailyDosePeriodConstants.fourWeeks && width < breakpoints.MEDIUM) {\n setPeriod(DailyDosePeriodConstants.week)\n } else if (period === DailyDosePeriodConstants.fourWeeks && width >= breakpoints.MEDIUM) {\n setPeriod(DailyDosePeriodConstants.twoWeeks)\n } else {\n setPeriod(DailyDosePeriodConstants.fourWeeks)\n }\n /* Reset period offset when changing period type */\n setPeriodOffset(0)\n }\n\n /*\n * Setup animation timing\n * */\n const transitionDelay = period === DailyDosePeriodConstants.fourWeeks ? 0.0125 : 0.05\n\n /*\n * Setup positions and measures\n * */\n const positionConfig: DailyDosePositionConfig = {\n circleWidth: 45,\n circleHeight: period === DailyDosePeriodConstants.fourWeeks ? 2 : 7.2,\n checkMarkHeight: 7,\n labelMargin: 3,\n marginTop: 10,\n }\n\n // Compile list of all dailydose in store and combine with appropriate DailyDoseType\n const dailyDosesWithDailyDoseType = useDailyDosesWithDoseType(periodOffset, period)\n // In case of 28 days view, pad the results\n const dailyDoses = useMemo(() => {\n if (period === DailyDosePeriodConstants.fourWeeks) {\n return getDailyDoseDaysFourWeeks(dailyDosesWithDailyDoseType)\n }\n return dailyDosesWithDailyDoseType\n }, [dailyDosesWithDailyDoseType, period])\n\n // Create list of labels\n const dailyDoseLabels = useMemo<DailyDoseLabel[]>(() => {\n if (period === DailyDosePeriodConstants.fourWeeks) {\n if (dailyDoses.length !== DailyDosePeriodConstants.fourWeeks) {\n // eslint-disable-next-line no-console\n console.error('dailyDoseDaysWithMaxDose should contain 28 items')\n }\n /*\n * Take the dailyDoseDaysWithMaxDose and divides it between 4 weeks\n * result should cover 28 days, or 4 weeks\n * */\n return dailyDoses.reduce<DailyDoseLabel[]>((acc, value, index) => {\n if ((index) % 7 === 0) {\n acc.push({\n weekNumber: getWeek(new Date(value.date)),\n dates: [],\n numPoints: 0,\n })\n }\n acc[acc.length - 1].numPoints += value.numPoints\n acc[acc.length - 1].dates.push(value.date)\n return acc\n }, [])\n }\n return dailyDoses\n }, [dailyDoses, period])\n\n // Highest achieved dailydose for period\n const highestAchieved = useHighestAchievedDoseWithDoseType(periodOffset, period)\n // Cap at 1600\n const maxDailyDose = Math.min(highestAchieved.numPoints, MAX_SCORE)\n return (\n <div className=\"daily-dose-activity\">\n <h2 className=\"daily-dose-activity__section-header section-header\">\n {periodNames[period] && translation.getTranslation(translationGroups.dailyDosePage, `activity-period-${periodNames[period]}`)}\n <button className=\"daily-dose-activity__section-header-toggle\" onClick={togglePeriod} type=\"button\">\n {translation.getTranslation(translationGroups.dailyDosePage, `period-${period}`)}\n </button>\n </h2>\n <div className=\"daily-dose-activity__graph\">\n <CardComponent>\n <DailyDoseActivityHeaderComponent\n periodOffset={periodOffset}\n period={period}\n showPrevArrow={hasActivityFromStartTillPeriod(-1)}\n setNextPeriod={() => movePeriod(1)}\n setPreviousPeriod={() => movePeriod(-1)}\n />\n <div className=\"daily-dose-activity__bars\">\n <DailyDoseActivityExtremeComponent\n positionConfig={positionConfig}\n period={period}\n periodOffset={periodOffset}\n />\n { dailyDoses.map((dose, index) => (\n <DailyDoseActivityBarContainer\n key={`${period}${dose.date}`}\n dailyDose={dose}\n cssPostFix={dose.numPoints > 0 ? cssPostfixes[dose.nameLangKey] : null}\n index={index}\n period={period}\n transitionDelay={transitionDelay}\n positionConfig={positionConfig}\n maxDailyDose={maxDailyDose}\n onMouseOver={() => setHoveredLabel(dose.date)}\n onMouseOut={() => setHoveredLabel(undefined)}\n />\n ))}\n </div>\n\n <div className=\"daily-dose-activity__labels\">\n {period === DailyDosePeriodConstants.fourWeeks && dailyDoseLabels.map((dose) => (\n <DailyDoseActivityLabelComponent\n key={dose.dates[0]}\n periodSelected={dose.dates.includes(dailyDoseSelectedDate)}\n width={25 - positionConfig.labelMargin}\n periodName={`${translation.getTranslation(translationGroups.dailyDosePage, 'week')} ${dose.weekNumber}`}\n periodCompleted={dose.numPoints}\n hover={dose.dates.includes(hoveredLabel)}\n onClick={() => handleClickLabel(dose.dates[0])}\n onMouseOver={() => setHoveredLabel(dose.dates[0])}\n onMouseOut={() => setHoveredLabel(undefined)}\n />\n ))}\n\n {(period === DailyDosePeriodConstants.week || period === DailyDosePeriodConstants.twoWeeks) && dailyDoseLabels.map((dose) => (\n <DailyDoseActivityLabelComponent\n key={dose.date}\n periodSelected={dose.date === dailyDoseSelectedDate}\n width={100 / 7 - positionConfig.labelMargin}\n periodName={translation.getTranslation(translationGroups.weekDays, new Date(dose.date).getDay())}\n periodCompleted={dose.numPoints}\n hover={dose.date === hoveredLabel}\n onClick={() => handleClickLabel(dose.date)}\n onMouseOver={() => setHoveredLabel(dose.date)}\n onMouseOut={() => setHoveredLabel(undefined)}\n />\n ))}\n </div>\n </CardComponent>\n </div>\n </div>\n )\n}\n\nexport default DailyDoseActivityComponent\n","import { connect } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport DailyDoseComponent from '../components/DailyDoseComponent'\nimport * as puzzleDataActions from '../../../actions/puzzleDataActions'\n\nconst mapStateToProps = (state: StoreState) => ({\n continuePlayingPuzzleTypes: state?.puzzleData?.continuePlayingPuzzleTypes,\n})\n\nconst mapDispathToProps = (dispatch: any) => ({\n getDailyDoses: () => {\n dispatch(puzzleDataActions.getDailyDoses())\n },\n getDailyDoseTypes: () => {\n dispatch(puzzleDataActions.getDailyDoseTypes())\n },\n})\n\nexport default connect(mapStateToProps, mapDispathToProps)(DailyDoseComponent)\n","import React, { useContext, useEffect, useState } from 'react'\nimport { DailyDosePeriodConstants } from 'pages/daily_dose/components/constants/DailyDosePeriod'\nimport DailyDoseGameTypeSummaryComponent from 'pages/daily_dose/components/DailyDoseGameTypeSummaryComponent'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { ContinuePlayingPuzzleType } from 'client/types/ContinuePlayingPuzzleType'\nimport RecentPuzzlesBackgroundComponent from 'client/pages/common/components/RecentPuzzlesBackgroundComponent'\nimport NavigationPagesTabsComponent from 'client/pages/common/components/navigation/NavigationPagesTabsComponent'\nimport breakpoints from 'common_packages/assets/js/constants/breakpoints'\nimport useWindowDimensions from 'common_packages/assets/js/hooks/useWindowDimensions'\nimport { DailyDosePeriod } from '../../../types/DailyDosePeriod'\nimport HeaderTitleBarComponent from '../../common/components/HeaderTitleBarComponent'\nimport PageHeaderComponent from '../../common/components/page_header/PageHeaderComponent'\nimport DailyDoseTodayContainer from '../containers/DailyDoseTodayContainer'\nimport FeedbackCardComponent from '../../common/components/FeedbackCardComponent'\nimport RecentPuzzlesComponent from '../../common/components/RecentPuzzlesComponent'\nimport DailyDoseActivityComponent from './DailyDoseActivityComponent'\nimport translationGroups from '../../../constants/translationGroups'\n\ntype Props = {\n continuePlayingPuzzleTypes: ContinuePlayingPuzzleType[],\n getDailyDoses: () => void,\n getDailyDoseTypes: () => void,\n}\n\nconst DailyDoseComponent = ({\n continuePlayingPuzzleTypes,\n getDailyDoses,\n getDailyDoseTypes,\n}: Props) => {\n const translation = useContext(TranslationContext)\n const abilities = useAbilities()\n\n useEffect(() => {\n if (abilities.canUseDailyDose) {\n getDailyDoses()\n getDailyDoseTypes()\n }\n }, [getDailyDoses, getDailyDoseTypes, abilities.canUseDailyDose])\n\n /*\n * period is used for setting the current timespan view\n * periodOffset is used to go up and down in time\n * */\n const { width } = useWindowDimensions()\n const startPeriod = breakpoints.MEDIUM > width ? DailyDosePeriodConstants.week : DailyDosePeriodConstants.twoWeeks\n\n const [period, setPeriod] = useState<DailyDosePeriod>(startPeriod)\n const [periodOffset, setPeriodOffset] = useState(0)\n\n const shouldShowContinuePlaying = !!(continuePlayingPuzzleTypes?.length && abilities.canSeeRecentPuzzles)\n\n return (\n <>\n <PageHeaderComponent translationGroup={translationGroups.dailyDosePage}>\n <HeaderTitleBarComponent title={translation.getRawTranslation(translationGroups.dailyDosePage, 'header-title')} />\n <NavigationPagesTabsComponent pages={['daily_dose', 'stats']} />\n </PageHeaderComponent>\n <div className=\"container\">\n <DailyDoseTodayContainer />\n <DailyDoseActivityComponent\n setPeriod={setPeriod}\n period={period}\n periodOffset={periodOffset}\n setPeriodOffset={setPeriodOffset}\n />\n <DailyDoseGameTypeSummaryComponent\n period={period}\n periodOffset={periodOffset}\n />\n <FeedbackCardComponent />\n </div>\n { shouldShowContinuePlaying && (\n <div className=\"daily-dose__continue-playing\">\n <RecentPuzzlesBackgroundComponent />\n <div className=\"container\">\n <RecentPuzzlesComponent size={4} puzzleTypes={continuePlayingPuzzleTypes} />\n </div>\n </div>\n )}\n </>\n )\n}\n\nexport default DailyDoseComponent\n","import { DailyDose, DailyDosesWithTotal, DailyDoseType } from 'client/types/DailyDose'\nimport { DailyDoseEnum } from '../../../enums/DailyDoseEnum'\n\nconst cssPostfixes = {\n [DailyDoseEnum.DAILY_DOSE]: 'daily-dose',\n [DailyDoseEnum.DOUBLE_DOSE]: 'double-dose',\n [DailyDoseEnum.MEGA_DOSE]: 'mega-dose',\n [DailyDoseEnum.ULTRA_DOSE]: 'ultra-dose',\n [DailyDoseEnum.EPIC_DOSE]: 'epic-dose',\n}\n\n/**\n * This method helps styling the daily doses and calculates if a certain type for a certain day is finished.\n * Add percentage of required points and css modifiers to dailydosetypes.\n * The styling that's done through scss classes is injected per dose type.\n * @param dailyDoseTypes\n * @param dailyDoseOneDay\n */\nexport const getComposedDailyDoses = (dailyDoseTypes: DailyDoseType[], dailyDoseOneDay: DailyDose): DailyDosesWithTotal[] => {\n let composedDailyDoseTypes = []\n if (dailyDoseOneDay?.numPoints > 0 && dailyDoseTypes.length > 0) {\n const totalPointsToday = dailyDoseOneDay.numPoints\n\n let prevPointsRequired = 0\n composedDailyDoseTypes = composeWithCss([...dailyDoseTypes]).map((dailyDose) => {\n const {\n percentageOfRequired,\n percentageOfRequiredCircle,\n } = getPercentageOfRequired(dailyDose.pointsRequired, prevPointsRequired, totalPointsToday)\n prevPointsRequired = dailyDose.pointsRequired\n return {\n ...dailyDose,\n percentageOfRequired,\n percentageOfRequiredCircle,\n }\n })\n }\n /*\n * By default set composed daily dose types to dailyDoseTypes.\n * */\n if (composedDailyDoseTypes.length === 0) {\n composedDailyDoseTypes = composeWithCss(dailyDoseTypes)\n }\n\n return composedDailyDoseTypes\n}\n\n// returns the current daily dose treshold\nexport const getHighestDailyDose = (dailyDoseTypes: DailyDoseType[], dailyDoseOneDay?: DailyDose): DailyDoseType & { cssPostFix: string } | undefined => {\n if (!dailyDoseTypes.length) return undefined\n\n const goal = dailyDoseOneDay?.numPoints ?? 0\n let highest = dailyDoseTypes[0]\n if (goal > highest.pointsRequired) {\n const currentIndex = dailyDoseTypes.reduce((acc, value, index) => {\n return (value.pointsRequired < goal) ? index : acc\n }, 0)\n highest = dailyDoseTypes[currentIndex + 1] ?? dailyDoseTypes[dailyDoseTypes.length - 1]\n }\n return {\n ...highest,\n cssPostFix: cssPostfixes[highest.nameLangKey],\n }\n}\n\nfunction getPercentageOfRequired(pointsRequired, prevPointsRequired, totalPointsToday) {\n let percentageOfRequired = 0\n let percentageOfRequiredCircle = 0\n if (totalPointsToday < pointsRequired && totalPointsToday > prevPointsRequired) {\n percentageOfRequired = (totalPointsToday / pointsRequired) * 100\n percentageOfRequiredCircle = ((totalPointsToday - prevPointsRequired) / (pointsRequired - prevPointsRequired)) * 100\n } else if (totalPointsToday >= pointsRequired) {\n percentageOfRequired = 100\n percentageOfRequiredCircle = 100\n }\n return {\n percentageOfRequired,\n percentageOfRequiredCircle,\n }\n}\n\nfunction composeWithCss(doses: Array<DailyDose>) {\n return doses.map((dose) => ({\n ...dose,\n cssPostFix: cssPostfixes[dose.nameLangKey],\n }))\n}\n","import React, { useContext } from 'react'\nimport PillComponent from 'common_packages/assets/js/components/ui/pill/PillComponent'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { useDispatch } from 'react-redux'\nimport { showSubscribeDrawer } from 'client/actions/uiActions'\nimport { Link } from 'react-router-dom'\n\ntype Props = {\n title: string,\n subtitle: string,\n imageUrl: string,\n newPuzzle?: boolean,\n premiumOnly?: boolean,\n id: number\n}\n\nconst HomeFeaturedCardComponent = ({\n title,\n subtitle,\n imageUrl,\n newPuzzle,\n premiumOnly,\n id,\n}: Props) => {\n const translation = useContext(TranslationContext)\n const canPlay = useAbilities().canPlayDailyPuzzles\n const dispatch = useDispatch()\n\n const handleClick = () => {\n dispatch(showSubscribeDrawer())\n }\n\n const renderCard = () => {\n return (\n <>\n <div className=\"home-featured-card__text\">\n <h3 className=\"home-featured-card__title\">\n {title}\n </h3>\n <p className=\"home-featured-card__subtitle\">\n {subtitle}\n </p>\n {(newPuzzle || premiumOnly) && (\n <p className=\"home-featured-card__pill-container\">\n <PillComponent type={premiumOnly ? 'info' : 'new'}>\n {premiumOnly ? translation.getTranslation(translationGroups.common, 'subscription-type-premium') : translation.getTranslation(translationGroups.common, 'new')}\n </PillComponent>\n </p>\n )}\n </div>\n <img className=\"home-featured-card__image\" src={imageUrl} alt={title} />\n </>\n )\n }\n\n if (canPlay) {\n return (\n <Link to={`/calendar/${id}`} className=\"home-featured-card\">\n {renderCard()}\n </Link>\n )\n }\n return (\n <div className=\"home-featured-card\" onClick={handleClick} role=\"button\">\n {renderCard()}\n </div>\n )\n}\n\nexport default HomeFeaturedCardComponent\n","import React, { useContext } from 'react'\nimport { type FeaturedPuzzleType } from 'client/types/FeaturedPuzzleType'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { usePuzzleTypeImageUrls } from 'client/hooks/usePuzzleTypeImageUrls'\nimport useConfig from 'client/hooks/useConfig'\nimport { getPuzzleImageURL } from 'common_packages/assets/js/api/puzzleImageURLs'\nimport HomeFeaturedCardComponent from './HomeFeaturedCardComponent'\n\ntype Props = {\n puzzleTypes: FeaturedPuzzleType[]\n}\n\nconst HomeFeaturedComponent = ({ puzzleTypes = [] }: Props) => {\n const translation = useContext(TranslationContext)\n const { getBackgroundUrl } = usePuzzleTypeImageUrls()\n const config = useConfig()\n const puzzlesClientId = config.entity?.puzzlesClientId\n\n return (\n <section className=\"home-featured\">\n {puzzleTypes.map((puzzleType) => {\n const subtitle = translation.getTranslation(translationGroups.puzzleTags, puzzleType.format)\n const imageUrl = puzzleType.mostRecentId ? getPuzzleImageURL(puzzlesClientId, puzzleType.mostRecentId) : getBackgroundUrl(puzzleType.nameLangKey)\n\n return (\n <HomeFeaturedCardComponent\n key={puzzleType.puzzleTypeId}\n id={puzzleType.puzzleTypeId}\n title={translation.getTranslation(translationGroups.puzzle, puzzleType.nameLangKey)}\n subtitle={subtitle}\n imageUrl={imageUrl}\n newPuzzle={puzzleType.isNew}\n premiumOnly={puzzleType.isPremiumOnly}\n />\n )\n })}\n </section>\n )\n}\n\nexport default HomeFeaturedComponent\n","import React, { useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { useHistory } from 'react-router-dom'\nimport { PuzzleType } from 'client/types/PuzzleType'\nimport RoundedButtonComponent from 'client/pages/common/components/buttons/RoundedButtonComponent'\nimport GameCardRowComponent from '../../common/components/game_cards/GameCardRowComponent'\n\nimport * as puzzleFilters1 from '../../../constants/puzzleFilters1'\nimport * as puzzleFilters2 from '../../../constants/puzzleFilters2'\nimport { presetPuzzleFilters } from '../../../actions/puzzleFilterActions'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\n\ntype Props = {\n puzzleTypes: PuzzleType[]\n}\n\nconst HomeFavoritesComponent = ({ puzzleTypes }: Props) => {\n const translation = useContext(TranslationContext)\n const dispatch = useDispatch()\n const history = useHistory()\n\n const filterFavorites = (puzzle: PuzzleType) => puzzle.isFavorite\n\n const filteredPuzzleTypes: (type: PuzzleType) => boolean | number = filterFavorites\n const rowTitle = translation.getTranslation(translationGroups.homePage, 'favorites')\n\n const handleClickAllFavoritesLink = () => {\n dispatch(presetPuzzleFilters({\n filter1: puzzleFilters1.all,\n filter2: puzzleFilters2.FAVORITE,\n }))\n history.push('/puzzles')\n }\n\n if (puzzleTypes.filter(filterFavorites)?.length === 0) {\n return null\n }\n\n return (\n <section className=\"home-favorites\">\n <GameCardRowComponent\n puzzleTypes={puzzleTypes}\n rowFilter={filteredPuzzleTypes}\n rowTitle={rowTitle}\n moreItem={puzzleTypes.filter(filterFavorites)?.length > 3 && (\n <RoundedButtonComponent\n className=\"game-card-row__button-show-all\"\n buttonType=\"secondary\"\n text={translation.getTranslation(translationGroups.homePage, 'all-favorites-link')}\n onClickHandler={handleClickAllFavoritesLink}\n />\n )}\n />\n </section>\n )\n}\n\nexport default HomeFavoritesComponent\n","import React, { useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport { useHistory } from 'react-router-dom'\nimport { type PuzzleType } from 'client/types/PuzzleType'\nimport RoundedButtonComponent from 'client/pages/common/components/buttons/RoundedButtonComponent'\nimport { MINI } from 'client/constants/puzzleFormat'\nimport * as puzzleFilters1 from 'client/constants/puzzleFilters1'\nimport { presetPuzzleFilters } from 'client/actions/puzzleFilterActions'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport GameCardRowComponent from 'client/pages/common/components/game_cards/GameCardRowComponent'\n\ntype Props = {\n puzzleTypes: PuzzleType[]\n}\n\nconst HomeMinisComponent = ({ puzzleTypes }: Props) => {\n const translation = useContext(TranslationContext)\n const dispatch = useDispatch()\n const history = useHistory()\n\n const filterMinis = (puzzle: PuzzleType) => puzzle.format === MINI\n\n const onClickAllMinisLink = () => {\n dispatch(presetPuzzleFilters({\n filter1: puzzleFilters1.all,\n filter2: MINI,\n }))\n history.push('/puzzles')\n }\n\n return (\n <section className=\"home-minis\">\n <GameCardRowComponent\n puzzleTypes={puzzleTypes}\n rowFilter={filterMinis}\n rowTitle={translation.getTranslation(translationGroups.homePage, 'minis')}\n moreItem={puzzleTypes.filter(filterMinis)?.length > 5 && (\n <RoundedButtonComponent\n className=\"game-card-row__button-show-all\"\n buttonType=\"secondary\"\n text={`${translation.getTranslation(translationGroups.homePage, 'all-minis-link')} (${puzzleTypes.filter(filterMinis)?.length})`}\n onClickHandler={onClickAllMinisLink}\n />\n )}\n />\n </section>\n )\n}\n\nexport default HomeMinisComponent\n","import { connect } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport { games } from 'common_packages/assets/js/types/gameDataTypes'\nimport HomeHeroPuzzleSliderComponent from '../components/HomeHeroPuzzleSliderComponent'\nimport { getPuzzleCalendar } from '../../../actions/puzzleDataActions'\n\nconst MAX_PUZZLES = 8\n\nconst mapStateToProps = (state: StoreState) => {\n /* if there are recent puzzles, return early with those */\n if (state.puzzleData?.continuePlayingPuzzleTypes?.length) {\n return {\n cpPuzzleTypes: state.puzzleData.continuePlayingPuzzleTypes.slice(0, MAX_PUZZLES),\n }\n }\n\n /* else, get the recent days (if in store, if not, the component will call getCurrentPuzzleCalendar for the first puzzleType (first favorite or klubble mini)\n * and put it in store, which in turn will make this container run again and then the recent days will be in store)\n */\n const { daysPerLevel = {}, puzzleTypeId } = state?.puzzleData?.currentPuzzleCalendar\n const { levels = [] } = state?.puzzleData?.puzzleTypes?.find((puzzleType) => puzzleType.puzzleTypeId === puzzleTypeId) || {}\n const recentDays = daysPerLevel[levels[0]]?.slice(0, 3) || []\n\n /* if (first) favoritePuzzle is found, return early with that one (enhanced with recentDays object from store, if any) */\n const firstFavoritePuzzle = state.puzzleData.puzzleTypes?.find((puzzle) => puzzle.isFavorite)\n if (firstFavoritePuzzle) {\n return { cpPuzzleTypes: [{ ...firstFavoritePuzzle, recentDays }] }\n }\n\n /* if (first) klubbleMiniPuzzle is found, return early with that one (enhanced with recentDays object from store, if any) */\n const klubbleMiniPuzzle = state.puzzleData.puzzleTypes?.find((puzzle) => puzzle.nameLangKey.toUpperCase().replace(/-/g, '_') === games.ARROWWORD_PLUS_MINI)\n if (klubbleMiniPuzzle) {\n return { cpPuzzleTypes: [{ ...klubbleMiniPuzzle, recentDays }] }\n }\n\n return {\n cpPuzzleTypes: [],\n }\n}\n\nconst mapDispatchToProps = (dispatch: any) => ({\n getPuzzleCalendar: (id: number) => {\n dispatch(getPuzzleCalendar(id))\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(HomeHeroPuzzleSliderComponent)\n","import React, { useState, useEffect } from 'react'\nimport Slider from 'react-slick'\nimport IconArrowPrev from 'assets/icons/icon_chevron_back.svg'\nimport IconArrowNext from 'assets/icons/icon_chevron_next.svg'\nimport { ContinuePlayingPuzzleType } from 'client/types/ContinuePlayingPuzzleType'\nimport PuzzlePackCardContinueComponent from 'client/pages/common/components/puzzle_packs/PuzzlePackCardContinueComponent'\nimport breakpoints from 'common_packages/assets/js/constants/breakpoints'\nimport GameCardCalendarComponent from '../../common/components/game_cards/GameCardCalendarComponent'\nimport SliderButton from '../../common/components/buttons/SliderButtonComponent'\n\ntype Props = {\n cpPuzzleTypes: ContinuePlayingPuzzleType[],\n getPuzzleCalendar: (any) => void,\n}\n\nconst HomeHeroPuzzleSliderComponent = ({\n cpPuzzleTypes = [],\n getPuzzleCalendar,\n}: Props) => {\n const [currentSlide, setCurrentSlide] = useState(0)\n const [fetchedRecentDays, setFetchedRecentDays] = useState(false)\n\n useEffect(() => {\n /* In some edgecases currentSlide can be -1 (I saw it happening while switching between different accounts),\n * then we set it to 0\n */\n if (currentSlide < 0) {\n setCurrentSlide(0)\n }\n }, [currentSlide])\n\n useEffect(() => {\n const { recentDays, puzzleTypeId } = cpPuzzleTypes[0] || {}\n if (!recentDays?.length && !fetchedRecentDays && puzzleTypeId) {\n getPuzzleCalendar(puzzleTypeId)\n setFetchedRecentDays(true)\n }\n }, [cpPuzzleTypes, fetchedRecentDays, getPuzzleCalendar])\n\n /* Could be loaded dynamically, for now static */\n const renderSlides = () => cpPuzzleTypes\n .map((cpPuzzle: ContinuePlayingPuzzleType) => {\n if (cpPuzzle.puzzlePackId) {\n return <PuzzlePackCardContinueComponent key={cpPuzzle.puzzlePackId} puzzlePackId={cpPuzzle.puzzlePackId} isStacked />\n }\n return <GameCardCalendarComponent key={cpPuzzle.puzzleTypeId} puzzleTypeId={cpPuzzle.puzzleTypeId} recentDays={cpPuzzle.recentDays} stacked />\n })\n\n const settings = {\n dots: true,\n infinite: true,\n speed: 500,\n centerMode: true,\n marginBlockStart: 1,\n marginBlockEnd: 1,\n slidesToScroll: 1,\n centerPadding: 0,\n nextArrow: <SliderButton><IconArrowNext /></SliderButton>,\n prevArrow: <SliderButton><IconArrowPrev /></SliderButton>,\n responsive: [\n {\n breakpoint: breakpoints.MEDIUM - 1,\n settings: {\n infinite: false,\n centerPadding: '15px',\n },\n },\n ],\n beforeChange: (prev, next) => {\n setCurrentSlide(next)\n },\n customPaging: (i) => {\n let sliderPillClassName = 'slider-pill'\n if (currentSlide === i) {\n sliderPillClassName += ` ${sliderPillClassName}--active`\n }\n\n return (\n <div\n className={sliderPillClassName}\n />\n )\n },\n }\n return (\n <div className=\"home-hero-slider\">\n <Slider {...settings}>\n {renderSlides()}\n </Slider>\n </div>\n )\n}\n\nexport default HomeHeroPuzzleSliderComponent\n","import React from 'react'\n\nexport const HeroBackgroundDesktopComponent = () => (\n <svg className=\"page-header__background-svg--desktop\" width=\"100%\" height=\"470\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style={{ position: 'absolute', top: '0', left: '0)' }}>\n <g style={{ mixBlendMode: 'multiply' }}>\n <rect width=\"600\" height=\"600\" rx=\"35\" transform=\"matrix(1 1 -1 1 1030 -420)\" fill=\"var(--header-squircle-1-color)\" />\n </g>\n <g style={{ mixBlendMode: 'multiply' }}>\n <rect width=\"600\" height=\"600\" rx=\"35\" transform=\"matrix(1 1 -1 1 1170 -420)\" fill=\"var(--header-squircle-2-color)\" />\n </g>\n <g style={{ mixBlendMode: 'multiply' }}>\n <rect width=\"600\" height=\"600\" rx=\"35\" transform=\"matrix(1 1 -1 1 1310 -420)\" fill=\"var(--header-squircle-3-color)\" />\n </g>\n <rect width=\"150\" height=\"150\" rx=\"20\" transform=\"matrix(1 1 -1 1 1000 30)\" fill=\"var(--header-squircle-4-color)\" />\n </svg>\n)\n","import React, { useContext } from 'react'\nimport raw from 'rehype-raw'\nimport sanitize from 'rehype-sanitize'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport NotificationsBellComponent from 'client/pages/common/components/NotificationsBellComponent'\nimport { ReactMarkdown } from 'react-markdown/lib/react-markdown'\nimport HeaderTitleBarComponent from '../../common/components/HeaderTitleBarComponent'\nimport HomeHeroPuzzleSliderContainer from '../containers/HomeHeroPuzzleSliderContainer'\nimport { HeroBackgroundMobileComponent } from '../../common/components/page_header/HeroBackgroundMobileComponent'\nimport { HeroBackgroundDesktopComponent } from '../../common/components/page_header/HeroBackgroundDesktopComponent'\n\ntype Props = {\n firstName: string\n loadingContinuePlayingPuzzleTypes: boolean\n hasContinuePlayingPuzzleTypes: boolean\n hasPlayedBefore: boolean\n}\n\nconst HomeHeroComponent = ({\n firstName, loadingContinuePlayingPuzzleTypes, hasContinuePlayingPuzzleTypes, hasPlayedBefore,\n}: Props) => {\n const translation = useContext(TranslationContext)\n // If the user's first name is smaller than 15 chars, we can use it in the title.\n const canGreetFirstName = firstName?.length > 0 && firstName?.length < 15\n\n const homeHeroTitle = () => {\n if (hasContinuePlayingPuzzleTypes) {\n return (\n <h1 className=\"home-hero__title\">\n <ReactMarkdown rehypePlugins={[raw, sanitize]}>\n {translation.getRawTranslation(translationGroups.homePage, canGreetFirstName ? 'continue-playing-name' : 'continue-playing').replace('{firstName}', firstName)}\n </ReactMarkdown>\n </h1>\n )\n }\n\n if (!hasContinuePlayingPuzzleTypes && !hasPlayedBefore) {\n return (\n <>\n <h1 className=\"home-hero__title--small\">\n <ReactMarkdown rehypePlugins={[raw, sanitize]}>\n {translation.getRawTranslation(translationGroups.homePage, canGreetFirstName ? 'welcome-name' : 'welcome').replace('{firstName}', firstName)}\n </ReactMarkdown>\n </h1>\n <div className=\"home-hero__subtitle\">{translation.getTranslation(translationGroups.homePage, 'play-first-puzzle')}</div>\n </>\n )\n }\n\n return (\n <h1 className=\"home-hero__title--small\">\n <ReactMarkdown rehypePlugins={[raw, sanitize]}>\n {translation.getRawTranslation(translationGroups.homePage, canGreetFirstName ? 'welcome-back-name' : 'welcome-back').replace('{firstName}', firstName)}\n </ReactMarkdown>\n </h1>\n )\n }\n\n return (\n <section className=\"home-hero\">\n <HeaderTitleBarComponent title=\"\" showAccountButton>\n <NotificationsBellComponent />\n </HeaderTitleBarComponent>\n <div className=\"home-hero__content\">\n <HeroBackgroundMobileComponent />\n <HeroBackgroundDesktopComponent />\n <div className=\"home-hero__title-wrapper\">\n {(!loadingContinuePlayingPuzzleTypes || hasContinuePlayingPuzzleTypes) && homeHeroTitle()}\n </div>\n <HomeHeroPuzzleSliderContainer />\n </div>\n </section>\n )\n}\n\nexport default HomeHeroComponent\n","import React, { useContext, useEffect, useState } from 'react'\nimport { PuzzleType } from 'client/types/PuzzleType'\nimport GameCardRowComponent from '../../common/components/game_cards/GameCardRowComponent'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\n\ntype Props = {\n puzzleTypes: PuzzleType[]\n}\n\nconst HomeSuggestionsComponent = ({ puzzleTypes }: Props): JSX.Element => {\n const translation = useContext(TranslationContext)\n const filterSuggestions = (puzzle: PuzzleType) => puzzle.popularityScore\n const filterFavorites = (puzzle: PuzzleType) => puzzle.isFavorite\n const [suggestedPuzzleTypes, setSuggestedPuzzleTypes] = useState([])\n\n useEffect(() => {\n /**\n * On component load, filter out the favorite puzzles from this list. If user clicks the favorite button then\n * on one of the game cards, it remains in the list until the compontent gets mounted again */\n if (puzzleTypes.length > 0 && suggestedPuzzleTypes.length === 0) {\n const maxThreeFavoritedPuzzleTypes = puzzleTypes.filter(filterFavorites)?.slice(0, 3)\n\n if (maxThreeFavoritedPuzzleTypes?.length === 0) {\n setSuggestedPuzzleTypes(puzzleTypes.slice(3))\n } else {\n const notInFavorite = (p: PuzzleType) => !maxThreeFavoritedPuzzleTypes.some((f) => p.puzzleTypeId === f.puzzleTypeId)\n setSuggestedPuzzleTypes(puzzleTypes.filter(notInFavorite))\n }\n }\n }, [puzzleTypes, suggestedPuzzleTypes])\n\n return (\n <section className=\"home-suggestions\">\n <GameCardRowComponent\n puzzleTypes={suggestedPuzzleTypes}\n rowFilter={filterSuggestions}\n rowTitle={translation.getTranslation(translationGroups.homePage, 'suggested-for-you')}\n />\n </section>\n )\n}\n\nexport default HomeSuggestionsComponent\n","import React, { useContext } from 'react'\nimport AnimatedBackgroundSquircle from 'client/pages/common/components/AnimatedBackgroundSquircle'\nimport { isMobile } from 'react-device-detect'\nimport { ThemeContext } from 'client/pages/common/components/theme/ThemeContext'\n\nconst HomePuzzlePacksBackgroundComponent = () => {\n const { theme } = useContext(ThemeContext)\n\n return (\n <>\n {isMobile\n ? (\n <>\n <AnimatedBackgroundSquircle size={200} borderOnly border={2} borderRadius={5} top={-30} left={-80} gravity={0} />\n <AnimatedBackgroundSquircle size={40} top={-80} left={60} gravity={0} borderRadius={20} />\n </>\n ) : (\n <>\n <AnimatedBackgroundSquircle size={200} borderOnly top={-30} left={-70} gravity={0} />\n <AnimatedBackgroundSquircle size={70} top={-90} left={100} gravity={0} borderRadius={20} />\n </>\n )}\n <div className=\"home-puzzle-packs__bg-clipped\">\n <AnimatedBackgroundSquircle size={140} top={75} left={1050} borderOnly opacity={0.25} color=\"#FFFFFF\" gravity={0.3} borderRadius={15} border={5} />\n <AnimatedBackgroundSquircle size={90} top={550} left={-20} opacity={0.05} color=\"#FFFFFF\" gravity={0.4} borderRadius={15} />\n\n <AnimatedBackgroundSquircle size={285} top={500} left={900} borderOnly opacity={0.1} color=\"#FFFFFF\" gravity={0.1} borderRadius={10} />\n <AnimatedBackgroundSquircle size={150} top={490} left={860} opacity={0.05} color=\"#FFFFFF\" gravity={0.3} />\n <svg xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <clipPath id=\"clip-path\" clipPathUnits=\"objectBoundingBox\">\n <path\n transform=\"scale(0.001078748651564, 0.001742160278746)\"\n d={theme.sectionDividerDefinition}\n />\n </clipPath>\n </defs>\n </svg>\n </div>\n </>\n )\n}\n\nexport default HomePuzzlePacksBackgroundComponent\n","import React, { useContext } from 'react'\nimport { useHistory } from 'react-router'\nimport GameCardRowPuzzlePacksComponent from 'client/pages/common/components/game_cards/GameCardRowPuzzlePacksComponent'\nimport { usePuzzlePacks } from 'client/pages/puzzle_packs/hooks/usePuzzlePacks'\nimport RoundedButtonComponent from 'client/pages/common/components/buttons/RoundedButtonComponent'\nimport HomePuzzlePacksBackgroundComponent from 'client/pages/home/components/HomePuzzlePacksBackgroundComponent'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\n\nconst HomePuzzlePacksComponent = () => {\n const history = useHistory()\n const { getTranslation } = useContext(TranslationContext)\n const { puzzlePacks } = usePuzzlePacks()\n\n const handleClick = () => {\n history.push('/puzzle-packs')\n }\n\n const playablePacks = puzzlePacks\n .filter(({ isPurchased, isFree, isCompleted }) => (isPurchased || isFree) && !isCompleted)\n .sort((a, b) => new Date(b.publishDate).getTime() - new Date(a.publishDate).getTime())\n .sort((a, b) => (b.isNew ? 1 : 0) - (a.isNew ? 1 : 0))\n\n const unPurchasedPacks = puzzlePacks\n .filter(({ isPurchased, isFree }) => !isPurchased && !isFree)\n .sort((a, b) => new Date(b.publishDate).getTime() - new Date(a.publishDate).getTime())\n .sort((a, b) => (b.isNew ? 1 : 0) - (a.isNew ? 1 : 0))\n\n const completedPacks = puzzlePacks.filter(({ isCompleted }) => isCompleted)\n\n return (\n <section className=\"home-puzzle-packs\">\n <HomePuzzlePacksBackgroundComponent />\n <GameCardRowPuzzlePacksComponent\n puzzlePacks={[...playablePacks, ...unPurchasedPacks, ...completedPacks]}\n >\n <>\n {getTranslation(translationGroups.homePage, 'puzzle-packs')}\n <p className=\"home-puzzle-packs__body-text\">{getTranslation(translationGroups.homePage, 'puzzle-packs-intro')}</p>\n </>\n </GameCardRowPuzzlePacksComponent>\n {puzzlePacks.length > 4 && (\n <RoundedButtonComponent\n className=\"home-puzzle-packs__button-show-all\"\n text={getTranslation(translationGroups.homePage, 'all-puzzle-packs-link')}\n onClickHandler={handleClick}\n />\n )}\n </section>\n\n )\n}\n\nexport default HomePuzzlePacksComponent\n","import React from 'react'\nimport RecentPuzzlesComponent from 'client/pages/common/components/RecentPuzzlesComponent'\nimport { ContinuePlayingPuzzleType } from 'client/types/ContinuePlayingPuzzleType'\nimport RecentPuzzlesBackgroundComponent from 'client/pages/common/components/RecentPuzzlesBackgroundComponent'\n\ntype Props = {\n puzzleTypes: ContinuePlayingPuzzleType[]\n}\n\nconst HomeContinuePlayingComponent = ({ puzzleTypes = [] }: Props) => {\n return (\n <section className=\"home-continue-playing\">\n <RecentPuzzlesBackgroundComponent />\n <div className=\"container\">\n <RecentPuzzlesComponent size={4} puzzleTypes={puzzleTypes} />\n </div>\n </section>\n )\n}\n\nexport default HomeContinuePlayingComponent\n","import React, { useEffect, useState } from 'react'\nimport { PuzzleType } from 'client/types/PuzzleType'\nimport { FeaturedPuzzleType } from 'client/types/FeaturedPuzzleType'\nimport { ContinuePlayingPuzzleType } from 'client/types/ContinuePlayingPuzzleType'\nimport { klubbleAPI } from 'client/api/common'\nimport { UserStatsData } from 'common_packages/assets/js/types/UserStatsData'\nimport { useDispatch } from 'react-redux'\nimport { getPuzzlePacks } from 'client/actions/puzzleDataActions'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport { refreshToken } from 'client/api/authentication'\nimport HomeFeaturedComponent from './components/HomeFeaturedComponent'\nimport HomeFavoritesComponent from './components/HomeFavoritesComponent'\nimport HomeMinisComponent from './components/HomeMinisComponent'\nimport HomeHeroComponent from './components/HomeHeroComponent'\nimport HomeSuggestionsComponent from './components/HomeSuggestionsComponent'\nimport HomePuzzlePacksComponent from './components/HomePuzzlePacksComponent'\nimport HomeContinuePlayingComponent from './components/HomeContinuePlayingComponent'\n\ntype Props = {\n getContinuePlayingPuzzleTypes: () => void\n puzzleTypes: PuzzleType[],\n loadingFeaturedPuzzles: boolean\n featuredPuzzleTypes: FeaturedPuzzleType[],\n loadingContinuePlayingPuzzleTypes: boolean\n continuePlayingPuzzleTypes: ContinuePlayingPuzzleType[],\n firstName: string\n}\n\nconst HomeComponent = ({\n getContinuePlayingPuzzleTypes,\n puzzleTypes = [],\n loadingFeaturedPuzzles,\n featuredPuzzleTypes,\n loadingContinuePlayingPuzzleTypes,\n continuePlayingPuzzleTypes,\n firstName,\n}: Props) => {\n const [stats, setStats] = useState<UserStatsData>()\n const [isLoading, setIsLoading] = useState(true)\n const dispatch = useDispatch()\n const throwError = useAsyncError()\n\n useEffect(() => {\n const abortController = new AbortController()\n const getData = async () => {\n try {\n const { data } = await klubbleAPI.get<UserStatsData>('Auth/getuserstats')\n if (data?.mainTypes.length > 0 && data?.puzzleTypes.length > 0 && data?.variants.length > 0) {\n setStats(data)\n }\n dispatch(getPuzzlePacks(abortController))\n } catch (e) {\n // server error or no connection\n throwError(e)\n } finally {\n setIsLoading(false)\n }\n }\n\n const tryGetContinuePlayingPuzzleTypes = async () => {\n try {\n getContinuePlayingPuzzleTypes()\n } catch (e) {\n throwError(e, 'Error getting continue playing puzzles')\n }\n }\n\n // We want to refresh the user stats and data when the user returns to or refreshes the page.\n const getUserStatsAndData = async () => {\n await refreshToken()\n await tryGetContinuePlayingPuzzleTypes()\n await getData()\n }\n\n getUserStatsAndData()\n\n window.addEventListener('focus', getUserStatsAndData)\n\n return () => {\n window.removeEventListener('focus', getUserStatsAndData)\n abortController.abort()\n }\n }, [dispatch, getContinuePlayingPuzzleTypes, throwError])\n\n const hasContinuePlayingPuzzleTypes = continuePlayingPuzzleTypes?.length > 0\n const puzzleTypesSorted = [...puzzleTypes].sort((a, b) => b.popularityScore - a.popularityScore)\n return (\n <div>\n <HomeHeroComponent\n hasContinuePlayingPuzzleTypes={hasContinuePlayingPuzzleTypes}\n loadingContinuePlayingPuzzleTypes={loadingContinuePlayingPuzzleTypes && isLoading}\n firstName={firstName}\n hasPlayedBefore={!!stats?.puzzleTypes.length}\n />\n {!loadingFeaturedPuzzles && <HomeFeaturedComponent puzzleTypes={featuredPuzzleTypes} />}\n <HomeFavoritesComponent puzzleTypes={puzzleTypesSorted} />\n <HomeSuggestionsComponent puzzleTypes={puzzleTypesSorted} />\n <HomePuzzlePacksComponent />\n {/* {hasContinuePlayingPuzzleTypes && <HomePlayTogetherComponent puzzleTypes={puzzleTypes} />} */}\n <HomeMinisComponent puzzleTypes={puzzleTypes} />\n {hasContinuePlayingPuzzleTypes && <HomeContinuePlayingComponent puzzleTypes={continuePlayingPuzzleTypes} />}\n </div>\n )\n}\n\nexport default HomeComponent\n","import { StoreState } from 'client/store'\nimport { connect } from 'react-redux'\nimport { getContinuePlayingPuzzleTypes } from '../../../actions/puzzleDataActions'\nimport HomeComponent from '../HomeComponent'\n\nconst mapStateToProps = (state: StoreState) => ({\n puzzleTypes: state.puzzleData.puzzleTypes,\n loadingFeaturedPuzzles: state.puzzleData.loadingFeaturedPuzzles,\n featuredPuzzleTypes: state.puzzleData.featuredPuzzleTypes,\n loadingContinuePlayingPuzzleTypes: state.puzzleData.loadingContinuePlayingPuzzleTypes,\n continuePlayingPuzzleTypes: state.puzzleData.continuePlayingPuzzleTypes,\n firstName: state.user?.data?.firstName,\n})\n\nconst mapDispatchToProps = (dispatch: any) => ({\n getContinuePlayingPuzzleTypes: () => {\n dispatch(getContinuePlayingPuzzleTypes())\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(HomeComponent)\n","import React, { useContext } from 'react'\nimport { useHistory } from 'react-router-dom'\nimport { extendedTrial } from 'client/constants/paths'\nimport useConfig from 'client/hooks/useConfig'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport RoundedButtonComponent from 'client/pages/common/components/buttons/RoundedButtonComponent'\nimport LandingHeaderComponent from './LandingHeaderComponent'\n\nconst LandingPrintSubscriberComponent = () => {\n const { getRawTranslation } = useContext(TranslationContext)\n const { push } = useHistory()\n const { lightTrialDaysText, extendedTrialDaysText } = useConfig()\n const config = useConfig()\n const entityName = config?.entity?.name ?? 'klubble_nl'\n const url = `/entity/${entityName}/images/landing/landing-puzzle.png`\n\n const isExtendedTrial = window.location.pathname.indexOf(extendedTrial) > -1\n const freeDays = isExtendedTrial ? extendedTrialDaysText : lightTrialDaysText\n const uspList = getRawTranslation(translationGroups.landingPage, `usps${isExtendedTrial ? '-extended-trial' : ''}`)\n .replace(/{days}/g, freeDays)\n .split('\\n') ?? []\n const activateButtonText = getRawTranslation(translationGroups.landingPage, `activate-free-account${isExtendedTrial ? '-extended-trial' : ''}`)\n .replace(/{days}/g, freeDays)\n\n return (\n <div className=\"container\">\n <div className=\"landing-klubble landing-klubble--print-subscriber\">\n <LandingHeaderComponent />\n <img alt=\"Klubble puzzle\" src={url} className=\"landing-klubble__circle-image\" />\n <div className=\"landing-klubble__usps\">\n <ul className=\"landing-klubble__usp-list info-list\">\n {uspList.map((item) => (\n <li className=\"info-list__element\" key={item}>\n <span className=\"info-list__divider\">•</span>\n {item}\n </li>\n ))}\n </ul>\n <div className=\"landing-klubble__buttons\">\n <RoundedButtonComponent\n className=\"landing-klubble__activate-button\"\n text={activateButtonText}\n onClickHandler={() => push('/register')} // This will change once we can prefill user info in CIAM.\n />\n </div>\n </div>\n </div>\n </div>\n )\n}\n\nexport default LandingPrintSubscriberComponent\n","import React, { useEffect, useState } from 'react'\nimport { getParamsFromQueryString } from '../../../utilities/getParamsFromQueryString'\nimport { klubbleAPI } from '../../../api/common'\nimport LandingPrintSubscriberComponent from './LandingPrintSubscriberComponent'\nimport LandingRegularComponent from './LandingRegularComponent'\n\nconst LandingComponent = () => {\n const { userId, subscriberToken } = getParamsFromQueryString()\n const [loading, setLoading] = useState(Boolean(userId && subscriberToken))\n const [error, setError] = useState(false)\n const [emailPrefilled, setEmailPrefilled] = useState(null)\n\n useEffect(() => {\n async function fetchEmail() {\n try {\n const res = await klubbleAPI.get(`auth/getemail?userId=${userId}&token=${subscriberToken}`)\n if (!res.data.success) {\n throw new Error(`${res.config.url} did not return successfully`)\n }\n setEmailPrefilled(res.data.data)\n } catch (err) {\n setError(true)\n }\n setLoading(false)\n }\n\n if (userId && subscriberToken) {\n fetchEmail()\n }\n }, [userId, subscriberToken])\n\n if (loading) {\n /* Loading... this call takes quite some time (only in case of invalid userid/token combination), there is a delay set on the server to prevent attacks\n this is accepted, user will only see a white screen for a few seconds when he clicks on a invitation link in an email with an expired token */\n return null\n }\n\n if (emailPrefilled) {\n return (\n <LandingPrintSubscriberComponent />\n )\n }\n return <LandingRegularComponent message={error ? 'link-invalid-message' : null} />\n}\n\nexport default LandingComponent\n","import React from 'react'\nimport LogoComponent from 'pages/common/components/LogoComponent'\nimport LogoSubTitleComponent from 'client/pages/common/components/LogoSubTitleComponent'\n\nconst LandingHeaderComponent = () => {\n return (\n <div className=\"landing-klubble__header\">\n <LogoComponent className=\"landing-klubble__header-logo\" navigateTo=\"/\" />\n <LogoSubTitleComponent className=\"landing-klubble__header-subtitle\" />\n </div>\n )\n}\nexport default LandingHeaderComponent\n","import React, {\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from 'react'\nimport { useHistory, useLocation } from 'react-router'\nimport ReactMarkdown from 'react-markdown'\nimport useConfig from 'client/hooks/useConfig'\nimport RoundedButtonComponent from 'client/pages/common/components/buttons/RoundedButtonComponent'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useDispatch } from 'react-redux'\nimport { addToast } from 'common_packages/assets/js/actions/uiActions'\nimport { toastTypes } from 'common_packages/assets/js/types/toastTypes'\nimport { checkHasActiveSSOSession } from 'client/api/authentication'\nimport LandingHeaderComponent from './LandingHeaderComponent'\n\ntype LocationState = {\n errorMessage?:string\n}\ntype Props = {\n message?: string\n}\n\nconst SSO_REDIRECT_DELAY_MS = 150\n\nconst LandingRegularComponent = ({ message }: Props) => {\n const history = useHistory()\n const { lightTrialSuffix, lightTrialDaysText, entity } = useConfig()\n const { getTranslation, getRawTranslation, translationsSet } = useContext(TranslationContext)\n const dispatch = useDispatch()\n const location = useLocation() as { state: LocationState, pathname: string }\n const signInCheckTimer = useRef(null)\n const url = getRawTranslation(translationGroups.landingPage, 'image')\n const { errorMessage } = location.state ?? {}\n useEffect(() => {\n if (process.env.KLUBBLE_LOGIN_SSO_ENABLED === 'true') {\n if (signInCheckTimer.current) {\n clearTimeout(signInCheckTimer.current)\n }\n signInCheckTimer.current = setTimeout(() => {\n checkHasActiveSSOSession(entity.sso)\n .then((active) => {\n if (active === true) {\n // found active session at SSO provider, so we can redirect to the login flow straight away (it should complete instantly)\n window.location.href = `${process.env.KLUBBLE_API_BASE_PATH}/account/signin`\n }\n })\n }, SSO_REDIRECT_DELAY_MS)\n }\n return () => {\n clearTimeout(signInCheckTimer.current)\n }\n }, [entity])\n\n useEffect(() => {\n if (errorMessage && translationsSet) {\n dispatch(addToast({\n message: getRawTranslation(translationGroups.landingPage, errorMessage),\n type: toastTypes.ERROR,\n }))\n }\n }, [dispatch, errorMessage, getRawTranslation, translationsSet])\n\n const listItems = useMemo(() => {\n const list = getRawTranslation(translationGroups.landingPage, 'usps-regular')\n .split('\\n') ?? []\n\n return list.map((item) => (\n <li className=\"info-list__element\" key={item}>\n <span className=\"info-list__divider\">•</span>\n {item}\n </li>\n ))\n }, [getRawTranslation])\n\n return (\n <div className=\"container\">\n <div className=\"landing-klubble\">\n <LandingHeaderComponent />\n <div className=\"landing-klubble__image\" style={{ backgroundImage: `url(${url})` }} />\n <div className=\"landing-klubble__buttons\">\n {(message) && <div className=\"landing-klubble__message\">{getTranslation(translationGroups.landingPage, message)}</div>}\n <h2 className=\"landing-klubble__title\">{getTranslation(translationGroups.landingPage, 'klubble-tagline')}</h2>\n {/** USPs */}\n <ul className=\"info-list landing-klubble__usps\">\n {listItems}\n </ul>\n <RoundedButtonComponent\n data-test-id=\"login-button\"\n className=\"landing-klubble__login-button\"\n text={getTranslation(translationGroups.landingPage, 'login')}\n onClickHandler={() => history.push('/login')}\n />\n <div className=\"landing-klubble__not-a-member\">\n <ReactMarkdown>{getRawTranslation(translationGroups.loginPage, `join-klubble${lightTrialSuffix}`).replace(/{days}/g, lightTrialDaysText)}</ReactMarkdown>\n </div>\n </div>\n </div>\n </div>\n )\n}\n\nexport default LandingRegularComponent\n","import React, {\n useContext,\n useEffect,\n useRef,\n useState,\n} from 'react'\nimport { useHistory } from 'react-router'\nimport { useLogin } from 'client/hooks/useLogin'\nimport { getCookies } from 'client/utilities/getCookies'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport LandingHeaderComponent from './LandingHeaderComponent'\n\nconst LandingSSOLoginComponent = () => {\n const [SSOLoginInProgress, setSSOLoginInProgress] = useState<boolean>(false)\n const history = useHistory()\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const { playRedirectAfterLogin } = getCookies()\n const playLogin = useLogin()\n const initializedSSOLogin = useRef(false)\n const url = getRawTranslation(translationGroups.landingPage, 'image')\n\n useEffect(() => {\n if (!initializedSSOLogin.current) {\n initializedSSOLogin.current = true\n setSSOLoginInProgress(true)\n playLogin(null, null, true).then((res) => {\n setSSOLoginInProgress(false)\n if (res?.success && playRedirectAfterLogin) {\n window.location.replace(playRedirectAfterLogin)\n } else {\n history.replace('/')\n }\n }).catch(() => history.replace('/'))\n }\n }, [playLogin, history, playRedirectAfterLogin])\n\n return (\n <div className=\"container\">\n <div className=\"landing-klubble\">\n <LandingHeaderComponent />\n <div className=\"landing-klubble__image\" style={{ backgroundImage: `url(${url})` }} />\n\n <div className=\"landing-klubble__buttons\">\n {SSOLoginInProgress && <div className=\"landing-klubble__message\">{getTranslation(translationGroups.landingPage, 'login-in-progress')}</div>}\n\n <h2 className=\"landing-klubble__title\">{getTranslation(translationGroups.landingPage, 'klubble-tagline')}</h2>\n </div>\n </div>\n </div>\n )\n}\n\nexport default LandingSSOLoginComponent\n","export const getCookies = (): {[key: string]: string} => {\n return Object.fromEntries(document.cookie.split('; ').map((x) => x.split(/=(.*)$/, 2).map(decodeURIComponent)))\n}\n","import React, { useContext, useEffect } from 'react'\nimport { useHistory } from 'react-router'\nimport * as yup from 'yup'\nimport { SubmitHandler, useForm } from 'react-hook-form'\nimport ReactMarkdown from 'react-markdown'\nimport { yupResolver } from '@hookform/resolvers/yup'\nimport InputComponent from 'pages/common/components/form/InputComponent'\nimport SubmitButtonComponent from 'pages/common/components/form/SubmitButtonComponent'\nimport useConfig from 'client/hooks/useConfig'\nimport { useLogin } from 'client/hooks/useLogin'\nimport { getCurrentToken } from 'client/api/authentication'\nimport { UserState } from 'client/reducers/userReducer'\nimport { useSelector } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport TranslationContext from '../../../contexts/TranslationContext'\nimport translationGroups from '../../../constants/translationGroups'\nimport LoginHeaderComponent from './LoginHeaderComponent'\nimport useAbilities from '../../../hooks/useAbilities'\n\ntype Inputs = {\n email: string\n password: string\n}\n\nconst LoginComponent = () => {\n const translation = useContext(TranslationContext)\n const { getTranslation, getRawTranslation } = translation\n const { isAnonymous } = useAbilities()\n const history = useHistory()\n const login = useLogin()\n const { lightTrialDaysText, lightTrialSuffix } = useConfig()\n const { from } = (history?.location?.state) ?? {}\n const { data: userData } = useSelector<StoreState, UserState>((state) => state.user)\n\n useEffect(() => {\n if (getCurrentToken() && !isAnonymous && userData?.emailConfirmed) {\n // What are you doing here?\n history.replace('/')\n }\n }, [isAnonymous, userData?.emailConfirmed, history])\n\n const schema = yup.object().shape({\n email: yup\n .string()\n .trim()\n .email(getTranslation(translationGroups.error, 'email-invalid'))\n .required(getTranslation(translationGroups.error, 'required-field')),\n password: yup.string().required(getTranslation(translationGroups.error, 'required-field')),\n })\n const form = useForm<Inputs>({\n resolver: yupResolver(schema),\n })\n\n if (process.env.PLAYWRIGHT_ENV !== 'true' && process.env.KLUBBLE_LOGIN_SSO_ENABLED === 'true') {\n window.location.replace(`${process.env.KLUBBLE_API_BASE_PATH}/account/signin`)\n return null\n }\n\n const { handleSubmit } = form\n\n const onSubmit: SubmitHandler<Inputs> = async (data) => {\n login(data.email.toLowerCase().trim(), data.password)\n .then((res) => res?.success && history.push(from?.pathname ? `${from.pathname}${from.search}` : '/'))\n }\n\n return (\n <div className=\"container\">\n <div className=\"login\">\n <LoginHeaderComponent />\n <form onSubmit={handleSubmit(onSubmit)} className=\"form\">\n <h1 className=\"form__title\" data-test-id=\"login-title\">\n {getTranslation(translationGroups.loginPage, 'title')}\n </h1>\n <InputComponent\n className=\"form__field--lowercase\"\n name=\"email\"\n label={getTranslation(translationGroups.loginPage, 'email-placeholder')}\n type=\"email\"\n showValidatorError\n form={form}\n />\n <InputComponent\n name=\"password\"\n label={getTranslation(translationGroups.loginPage, 'password-placeholder')}\n type=\"password\"\n showValidatorError\n validatePassword={false}\n form={form}\n />\n <SubmitButtonComponent\n label={getTranslation(translationGroups.loginPage, 'login')}\n form={form}\n />\n </form>\n <div className=\"login__not-a-member\">\n <ReactMarkdown>{getRawTranslation(translationGroups.loginPage, `join-klubble${lightTrialSuffix}`).replace(/{days}/g, lightTrialDaysText)}</ReactMarkdown>\n </div>\n </div>\n </div>\n )\n}\n\nexport default LoginComponent\n","import React, { type ComponentProps } from 'react'\nimport { Link } from 'react-router-dom'\nimport LogoComponent from 'client/pages/common/components/LogoComponent'\nimport BrandIconComponent from 'client/pages/common/components/BrandIconComponent'\n\nconst OnboardingHeaderComponent = ({ children, className, ...otherProps }: ComponentProps<'header'>) => {\n return (\n <header {...otherProps} className={`header onboarding-header ${className ?? ''}`}>\n <div className=\"header__inner\">\n <LogoComponent className=\"header__logo\" navigateTo=\"/\" />\n <Link to=\"/\" className=\"header__logo-mobile\">\n <BrandIconComponent />\n </Link>\n {children}\n </div>\n </header>\n )\n}\n\nexport default OnboardingHeaderComponent\n","import React, { useContext, useRef } from 'react'\nimport HeartToggleContainer from 'pages/common/containers/HeartToggleContainer'\nimport { type PuzzleType } from 'client/types/PuzzleType'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport usePuzzleTypeFavorite from 'client/hooks/usePuzzleTypeFavorite'\nimport PuzzleIcon from '../puzzle_icon/PuzzleIcon'\n\ntype Props = {\n puzzleType: PuzzleType,\n miniPuzzleTypeId?: number,\n}\n\nconst GameCardAddFavoriteComponent = ({\n puzzleType,\n miniPuzzleTypeId,\n}: Props) => {\n const translation = useContext(TranslationContext)\n const heartToggleWrapperRef = useRef<HTMLDivElement>(null)\n const { puzzleTypeId, nameLangKey } = puzzleType\n const { toggleIsFavorite } = usePuzzleTypeFavorite(puzzleTypeId, miniPuzzleTypeId)\n\n const handleCardClick: React.MouseEventHandler<HTMLDivElement> = (e) => {\n e.stopPropagation()\n\n toggleIsFavorite()\n }\n\n return (\n <div className=\"game-card game-card--stacked game-card__add-favorite\" onClick={handleCardClick} role=\"button\">\n <div className=\"game-card__image\">\n <PuzzleIcon\n puzzleTypeId={puzzleTypeId}\n nameLangKey={nameLangKey}\n className=\"game-card__puzzle-icon\"\n />\n </div>\n <h3 className=\"game-card__title\">{translation.getTranslation(translationGroups.puzzle, nameLangKey)}</h3>\n <div ref={heartToggleWrapperRef} className=\"game-card__right\">\n <HeartToggleContainer\n puzzleTypeId={puzzleTypeId}\n miniPuzzleTypeId={miniPuzzleTypeId}\n isStacked\n />\n </div>\n </div>\n )\n}\n\nexport default GameCardAddFavoriteComponent\n","import React, { useContext, useState } from 'react'\nimport { PuzzleType } from 'client/types/PuzzleType'\nimport { Level } from 'client/interfaces/IPuzzleCalendar'\nimport TranslationContext from '../../../../contexts/TranslationContext'\nimport translationGroups from '../../../../constants/translationGroups'\nimport PuzzleIcon from '../puzzle_icon/PuzzleIcon'\nimport RoundedButtonComponent from '../buttons/RoundedButtonComponent'\n\ntype Props = {\n puzzleType: PuzzleType,\n onClickHandler: (value: Level) => void,\n}\n\nconst GameCardDifficultyComponent = ({\n puzzleType,\n onClickHandler,\n}: Props) => {\n const translation = useContext(TranslationContext)\n const {\n puzzleTypeId, nameLangKey, levels, selectedLevel,\n } = puzzleType\n const [selectedLevelKey, setSelectedLevelKey] = useState<Level>(selectedLevel || levels?.[0])\n\n return (\n <div className=\"game-card game-card--stacked game-card__set-difficulty\">\n <div className=\"game-card__image\">\n <PuzzleIcon\n puzzleTypeId={puzzleTypeId}\n nameLangKey={nameLangKey}\n className=\"game-card__puzzle-icon\"\n />\n </div>\n <h3 className=\"game-card__title\">{translation.getTranslation(translationGroups.puzzle, nameLangKey)}</h3>\n <div className=\"game-card__difficulties\">\n {levels?.map((level) => (\n <RoundedButtonComponent\n key={level}\n className={`game-card__difficulty ${selectedLevelKey === level ? 'game-card__difficulty--selected' : ''}`}\n onClickHandler={() => {\n setSelectedLevelKey(level)\n onClickHandler(level)\n }}\n text={translation.getTranslation(translationGroups.difficulty, level)}\n buttonType=\"secondary\"\n />\n ))}\n </div>\n </div>\n )\n}\n\nexport default GameCardDifficultyComponent\n","import React from 'react'\nimport DesktopFilledSquircle1 from 'client/assets/images/squircles/filled-clipped-312x309.svg'\nimport DesktopFilledSquircle2 from 'client/assets/images/squircles/filled-214x214.svg'\nimport DesktopOutlineSquircle from 'client/assets/images/squircles/outline-87x86.svg'\nimport MobileFilledSquircle1 from 'client/assets/images/squircles/filled-clipped-262x262.svg'\nimport MobileFilledSquircle2 from 'client/assets/images/squircles/filled-30x30.svg'\nimport MobileOutlineSquircle from 'client/assets/images/squircles/outline-clipped-83x83.svg'\n\nconst OnboardingPuzzlesBackgroundComponent = () => {\n return (\n <div className=\"onboarding-puzzles-background\">\n <DesktopFilledSquircle1 className=\"onboarding-puzzles-background__svg--desktop onboarding-puzzles-background__squircle-1\" />\n <DesktopFilledSquircle2 className=\"onboarding-puzzles-background__svg--desktop onboarding-puzzles-background__squircle-2\" />\n <DesktopOutlineSquircle className=\"onboarding-puzzles-background__svg--desktop onboarding-puzzles-background__squircle-3\" />\n <MobileFilledSquircle1 className=\"onboarding-puzzles-background__svg--mobile onboarding-puzzles-background__squircle-4\" />\n <MobileFilledSquircle2 className=\"onboarding-puzzles-background__svg--mobile onboarding-puzzles-background__squircle-5\" />\n <MobileOutlineSquircle className=\"onboarding-puzzles-background__svg--mobile onboarding-puzzles-background__squircle-6\" />\n </div>\n )\n}\n\nexport default OnboardingPuzzlesBackgroundComponent\n","import { useCallback, useRef } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { type StoreState } from 'client/store'\nimport { type PuzzleType } from 'client/types/PuzzleType'\nimport { savePuzzleSettingsBatch } from 'client/actions/puzzleDataActions'\n\ntype SettingsSlice = Pick<PuzzleType, 'puzzleTypeId' | 'selectedLevel'> | Pick<PuzzleType, 'puzzleTypeId' | 'isFavorite'>\n\n/**\n * This hook can be used to revert any changes done to the `puzzleData.puzzleTypes` store slice\n * It takes a snapshot of these settings (only the provided `setting`) during page load. Then the\n * returned function will call `savesettings/batch` endpoint with the original values\n */\nconst useRevertPuzzleSettings = (setting: 'selectedLevel' | 'isFavorite') => {\n const puzzleTypes = useSelector<StoreState, PuzzleType[]>((state) => state.puzzleData?.puzzleTypes)\n const dispatch = useDispatch()\n\n const originalSettings = useRef<SettingsSlice[]>(puzzleTypes.map((pT: PuzzleType) => ({\n puzzleTypeId: pT.puzzleTypeId,\n [setting]: pT[setting],\n })))\n\n const revertSettings = useCallback(() => {\n dispatch(savePuzzleSettingsBatch(originalSettings.current))\n }, [dispatch])\n\n return revertSettings\n}\n\nexport default useRevertPuzzleSettings\n","import React, { useContext, useEffect, useState } from 'react'\nimport { useSelector } from 'react-redux'\nimport { useHistory, useLocation } from 'react-router-dom'\nimport RoundedButtonComponent from 'pages/common/components/buttons/RoundedButtonComponent'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { type PuzzleType } from 'client/types/PuzzleType'\nimport GameCardAddFavoriteComponent from 'client/pages/common/components/game_cards/GameCardAddFavoriteComponent'\nimport { type StoreState } from 'client/store'\nimport GameCardDifficultyComponent from 'client/pages/common/components/game_cards/GameCardDifficultyComponent'\nimport IconChevronBack from 'assets/icons/icon_chevron_back.svg'\nimport { type Level } from 'client/interfaces/IPuzzleCalendar'\nimport { MINI } from 'client/constants/puzzleFormat'\nimport useSetSelectedPuzzleLevel from '../hooks/useSetSelectedPuzzleLevel'\nimport OnboardingPuzzlesBackgroundComponent from './OnboardingPuzzlesBackgroundComponent'\nimport OnboardingHeaderComponent from './OnboardingHeaderComponent'\nimport useRevertPuzzleSettings from '../hooks/useRevertPuzzleSettings'\n\nconst TOTAL_STEPS = 2\n\nconst OnboardingPuzzlesComponent = () => {\n const puzzleTypes = useSelector<StoreState, PuzzleType[]>((state) => state.puzzleData?.puzzleTypes)\n const [currentStep, setCurrentStep] = useState(1)\n const [isScrollable, setIsScrollable] = useState(false)\n const { state: stateFromLocation } = useLocation()\n const setSelectedPuzzleLevel = useSetSelectedPuzzleLevel()\n const translation = useContext(TranslationContext)\n const history = useHistory()\n\n // Save old/changed values in case user skips customization and we need to revert to the previous state\n const revertFavorites = useRevertPuzzleSettings('isFavorite')\n const revertDifficulties = useRevertPuzzleSettings('selectedLevel')\n const allFavorites = puzzleTypes?.filter((puzzleType) => puzzleType.isFavorite)\n\n useEffect(() => {\n const checkPageCanScroll = () => {\n const isPageScrollable = document.body.scrollHeight > window.innerHeight\n setIsScrollable(isPageScrollable)\n }\n\n checkPageCanScroll()\n window.addEventListener('resize', checkPageCanScroll)\n\n return () => {\n window.removeEventListener('resize', checkPageCanScroll)\n }\n }, [currentStep])\n\n if (stateFromLocation !== 'onboarding') {\n history.push('/')\n }\n\n const puzzlesAlphabetically = puzzleTypes.sort(\n (a, b) => { return a.sortOrder - b.sortOrder },\n ).filter((puzzle) => !(puzzle.format === MINI))\n\n const handleContinue = () => {\n if (currentStep < TOTAL_STEPS) {\n setCurrentStep(currentStep + 1)\n window.scrollTo(0, 0)\n } else {\n history.push('/')\n }\n }\n\n const handleSkipCustomization = async () => {\n if (currentStep === 1) {\n // Toggle all favorites back to their previous state\n revertFavorites()\n }\n if (currentStep === 2) {\n // Revert all changed difficulties back to their previous state\n revertDifficulties()\n }\n history.push('/')\n }\n\n const handleDifficultyChange = (puzzleType: PuzzleType, value: Level, puzzleTypeMini: PuzzleType) => {\n setSelectedPuzzleLevel(puzzleType.puzzleTypeId, value, puzzleTypeMini)\n }\n\n const previousStep = () => {\n revertDifficulties()\n setCurrentStep(currentStep - 1)\n }\n\n const getSubtitle = () => {\n switch (currentStep) {\n case 1:\n return translation.getTranslation(translationGroups.onboarding, 'puzzles-subtitle-add-favorite')\n case 2:\n return translation.getTranslation(translationGroups.onboarding, 'puzzles-subtitle-set-difficulty')\n default:\n return ''\n }\n }\n\n return (\n <>\n <OnboardingHeaderComponent>\n <RoundedButtonComponent\n className=\"onboarding-header__skip-customization-button\"\n text={translation.getTranslation(translationGroups.onboarding, 'skip-customization')}\n onClickHandler={handleSkipCustomization}\n inverted\n buttonType=\"secondary\"\n />\n </OnboardingHeaderComponent>\n <div className=\"onboarding-puzzles\">\n <OnboardingPuzzlesBackgroundComponent />\n <div className=\"onboarding-puzzles__header\">\n {currentStep > 1 && (\n // eslint-disable-next-line jsx-a11y/control-has-associated-label\n <button type=\"button\" className=\"onboarding-puzzles__back-button\" onClick={previousStep}>\n <IconChevronBack />\n {translation.getTranslation(translationGroups.onboarding, 'previous-step')}\n </button>\n )}\n <h1 className=\"onboarding-puzzles__title\">\n {translation.getTranslation(translationGroups.onboarding, 'puzzles-title')}\n </h1>\n <p className=\"onboarding-puzzles__subtitle\">\n {getSubtitle()}\n </p>\n </div>\n <div className={`onboarding-puzzles__puzzle-list${isScrollable ? ' onboarding-puzzles__puzzle-list--bottom-padding' : ''}`}>\n {(() => {\n switch (currentStep) {\n case 1:\n return puzzlesAlphabetically.map((puzzleType) => (\n <GameCardAddFavoriteComponent\n key={puzzleType.puzzleTypeId}\n puzzleType={puzzleType}\n miniPuzzleTypeId={puzzleTypes?.find((pt) => pt.nameLangKey === `${puzzleType.nameLangKey}-mini`)?.puzzleTypeId}\n />\n ))\n case 2:\n return allFavorites.filter((puzzle) => puzzle.format !== MINI).map((puzzleType) => (\n <GameCardDifficultyComponent\n key={puzzleType.puzzleTypeId}\n puzzleType={puzzleType}\n onClickHandler={(value) => handleDifficultyChange(puzzleType, value, puzzleTypes?.find((pt) => pt.nameLangKey === `${puzzleType.nameLangKey}-mini`))}\n />\n ))\n default:\n return null\n }\n })()}\n </div>\n <div className={`onboarding-puzzles__bottom-container${isScrollable ? ' onboarding-puzzles__bottom-container--fixed' : ''}`}>\n <RoundedButtonComponent\n className=\"onboarding-puzzles__continue-button\"\n text={translation.getTranslation(translationGroups.onboarding, 'next-step')}\n onClickHandler={handleContinue}\n buttonType=\"secondary\"\n disabled={!allFavorites?.length}\n />\n </div>\n </div>\n </>\n )\n}\n\nexport default OnboardingPuzzlesComponent\n","import { useDispatch } from 'react-redux'\nimport * as puzzleDataActions from 'klubble/app/client/actions/puzzleDataActions'\nimport { Level, levels as difficultyLevels } from 'client/interfaces/IPuzzleCalendar'\nimport { PuzzleType } from 'client/types/PuzzleType'\n\nconst useSetSelectedPuzzleLevel = () => {\n const dispatch = useDispatch()\n\n const setSelectedPuzzleLevel = (puzzleTypeId: number, value: Level, miniPuzzleType?: PuzzleType) => {\n const settings = [{ puzzleTypeId, selectedLevel: value }]\n\n if (miniPuzzleType) {\n let closestMiniPuzzleLevel = miniPuzzleType.levels[0]\n miniPuzzleType.levels.forEach((level) => {\n if (difficultyLevels.indexOf(level) <= difficultyLevels.indexOf(value)) {\n closestMiniPuzzleLevel = level\n }\n })\n settings.push({\n puzzleTypeId: miniPuzzleType.puzzleTypeId,\n selectedLevel: closestMiniPuzzleLevel,\n })\n }\n\n dispatch(puzzleDataActions.savePuzzleSettingsBatch(settings))\n }\n\n return setSelectedPuzzleLevel\n}\n\nexport default useSetSelectedPuzzleLevel\n","import React, {\n useEffect,\n} from 'react'\nimport { useHistory } from 'react-router-dom'\nimport { useDispatch } from 'react-redux'\nimport { refreshToken } from 'client/api/authentication'\nimport { type ApiResult, klubbleAPI } from 'client/api/common'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport PaymentStepHeaderComponent from 'client/pages/payment_input/PaymentStepHeaderComponent'\nimport getParameterByName from 'common_packages/assets/js/utilities/getParameterByName'\n\n// NOTE: this component is only used when activePaymentMethod is set to 'TWIKEY' in the admin. Can be removed when we finally support Twikey for QA in the FE.\nconst PaymentCompletePageComponent = () => {\n const paymentSuccess = getParameterByName('status') === 'ok'\n const dispatch = useDispatch()\n const history = useHistory()\n const abilities = useAbilities()\n const throwError = useAsyncError()\n\n if (abilities.hasPremiumSubscription && !paymentSuccess) {\n // What are you doing here?\n history.replace('/')\n }\n\n useEffect(() => {\n // For Adyen, not needed\n const cancelPendingMandates = async () => {\n if (!paymentSuccess) {\n try {\n // If failed, get new user data in order to fill out input form\n await refreshToken()\n\n // Inform backend to cancel pending mandates\n klubbleAPI.post('Auth/cancelpendingmandates', null, {\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n history.push('/payment-error')\n } catch (e) {\n throwError(e, 'Error cancelling pending mandates')\n }\n }\n }\n cancelPendingMandates()\n }, [history, paymentSuccess, throwError])\n\n useEffect(() => {\n const validatePendingMandates = async () => {\n try {\n const { data } = await klubbleAPI.post<ApiResult<void>>('Auth/validatependingmandates', null, {\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n if (data.success) {\n // Fetch new roles!\n await refreshToken()\n history.push('/payment-success')\n } else {\n history.push('/payment-error')\n }\n } catch {\n history.push('/payment-error')\n }\n }\n if (paymentSuccess && (!abilities.hasSubscription || abilities.hasLightSubscriptionOnly)) {\n validatePendingMandates()\n } else if (abilities.hasPremiumSubscription) {\n // In case a user refreshes the success page after payment, still show the success page.\n history.push('/payment-success')\n }\n }, [dispatch, paymentSuccess, abilities.hasSubscription, abilities.hasPremiumSubscription, abilities.hasLightSubscriptionOnly, history])\n\n return (\n <div className=\"payment-page-steps\">\n <PaymentStepHeaderComponent />\n <div className=\"container\">\n <div className=\"spinner\" />\n </div>\n </div>\n )\n}\n\nexport default PaymentCompletePageComponent\n","import React, { useContext, useEffect } from 'react'\nimport ErrorIcon from 'assets/images/misc/error.svg'\nimport { useHistory } from 'react-router-dom'\nimport useAbilities from 'client/hooks/useAbilities'\nimport TranslationContext from '../../contexts/TranslationContext'\nimport translationGroups from '../../constants/translationGroups'\nimport RoundedButtonComponent from '../common/components/buttons/RoundedButtonComponent'\nimport PaymentStepHeaderComponent from '../payment_input/PaymentStepHeaderComponent'\n\nconst PaymentPageErrorComponent = () => {\n const { getTranslation } = useContext(TranslationContext)\n const history = useHistory()\n const abilities = useAbilities()\n const purchaseIsPuzzlePack = localStorage.getItem('puzzle-pack-id')\n\n useEffect(() => {\n if (abilities.hasPremiumSubscription && !purchaseIsPuzzlePack) {\n // What are you doing here?\n history.replace('/')\n }\n }, [abilities.hasPremiumSubscription, purchaseIsPuzzlePack, history])\n\n const tryAgain = () => {\n if (purchaseIsPuzzlePack) {\n history.push('/buy-pack')\n } else if (abilities.hasLightSubscriptionOnly) {\n history.push('/upgrade')\n } else {\n history.push('/subscribe')\n }\n }\n\n return (\n <div className=\"payment-page-error payment-page-steps\">\n <PaymentStepHeaderComponent />\n <div className=\"container\">\n <div className=\"payment-page-error__icon-container\">\n <ErrorIcon />\n </div>\n <h2 className=\"payment-page-error__title\">\n {getTranslation(translationGroups.paymentInputPage, 'payment-page-error-title')}\n </h2>\n <div className=\"payment-page-error__explanation\">\n {getTranslation(translationGroups.paymentInputPage, 'payment-page-error-explanation')}\n </div>\n <RoundedButtonComponent\n text={getTranslation(translationGroups.paymentCompletePage, 'try-again')}\n buttonType=\"secondary\"\n className=\"payment-page-error__card-try-again\"\n onClickHandler={tryAgain}\n />\n </div>\n </div>\n )\n}\n\nexport default PaymentPageErrorComponent\n","import React, { useContext, useEffect } from 'react'\nimport PendingIcon from 'assets/images/misc/pending.svg'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { useHistory } from 'react-router'\nimport TranslationContext from '../../contexts/TranslationContext'\nimport translationGroups from '../../constants/translationGroups'\nimport PaymentStepHeaderComponent from '../payment_input/PaymentStepHeaderComponent'\nimport RoundedButtonComponent from '../common/components/buttons/RoundedButtonComponent'\n\nconst PaymentPagePendingComponent = () => {\n const { getTranslation } = useContext(TranslationContext)\n const history = useHistory()\n const abilities = useAbilities()\n const purchaseIsPuzzlePack = localStorage.getItem('puzzle-pack-id')\n\n useEffect(() => {\n if (abilities.hasPremiumSubscription && !purchaseIsPuzzlePack) {\n // What are you doing here?\n history.replace('/')\n }\n }, [abilities.hasPremiumSubscription, history, purchaseIsPuzzlePack])\n\n return (\n <div className=\"payment-page-pending payment-page-steps\">\n <PaymentStepHeaderComponent />\n <div className=\"container\">\n <div className=\"payment-page-pending__icon-container\">\n <PendingIcon />\n </div>\n <h2 className=\"payment-page-pending__title\">\n {getTranslation(translationGroups.paymentInputPage, 'payment-page-pending-title')}\n </h2>\n <div className=\"payment-page-pending__explanation\">\n {getTranslation(translationGroups.paymentInputPage, 'payment-page-pending-explanation')}\n </div>\n <RoundedButtonComponent\n text={getTranslation(translationGroups.paymentCompletePage, 'back')}\n buttonType=\"secondary\"\n className=\"payment-page-pending__back-button\"\n onClickHandler={() => { history.push('/') }}\n />\n </div>\n </div>\n )\n}\n\nexport default PaymentPagePendingComponent\n","import React from 'react'\nimport { motion } from 'framer-motion';\n\ninterface Props {\n className?: string\n}\n\nconst PaymentConfettiComponent = ({ className = 'endscreen-header__confetti' }: Props) => (\n <motion.div\n animate={{ y: [0, -40, 0], scale: [0.3, 1, 1.1], opacity: [1, 1, 0] }}\n transition={{\n repeat: Infinity,\n repeatType: 'loop',\n ease: ['easeOut', 'easeIn'],\n times: [0, 0.3, 1],\n duration: 2,\n }}\n >\n <svg\n className={className}\n width=\"155px\"\n height=\"91px\"\n viewBox=\"0 0 155 91\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g id=\"Player\" stroke=\"none\" strokeWidth=\"1\" fill=\"none\" fillRule=\"evenodd\">\n <g id=\"Congrats_Score_iPX_Klb\" transform=\"translate(-113.000000, -80.000000)\">\n <g id=\"Card-/-Summary\" transform=\"translate(20.000000, 80.000000)\">\n <g id=\"Confetti\" transform=\"translate(94.000000, 0.000000)\">\n <path\n className={`${className}-particle`}\n d=\"M15,68 L15,62.9705882 C15,60.7776929 13.2223071,59 11.0294118,59 C8.83651643,59 7.05882353,57.2223071 7.05882353,55.0294118 L7.05882353,54.5 C7.05882353,52.0147186 5.0441049,50 2.55882353,50 L0,50 L0,50\"\n id=\"Path-4\"\n stroke=\"#5FA378\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <path\n className={`${className}-particle`}\n d=\"M64,28 L64,24.6470588 C64,23.1851286 62.8148714,22 61.3529412,22 C59.891011,22 58.7058824,20.8148714 58.7058824,19.3529412 L58.7058824,19 C58.7058824,17.3431458 57.3627366,16 55.7058824,16 L54,16 L54,16\"\n id=\"Path-4\"\n stroke=\"#D2C45B\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n transform=\"translate(59.000000, 22.000000) rotate(10.000000) translate(-59.000000, -22.000000) \"\n />\n <path\n className={`${className}-particle`}\n d=\"M143,87 L143,81.9705882 C143,79.7776929 141.222307,78 139.029412,78 C136.836516,78 135.058824,76.2223071 135.058824,74.0294118 L135.058824,73.5 C135.058824,71.0147186 133.044105,69 130.558824,69 L128,69 L128,69\"\n id=\"Path-4\"\n stroke=\"#9999CC\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n transform=\"translate(135.500000, 78.000000) scale(-1, 1) translate(-135.500000, -78.000000) \"\n />\n <path\n className={`${className}-particle`}\n d=\"M138,37 L138,33.6470588 C138,32.1851286 136.814871,31 135.352941,31 C133.891011,31 132.705882,29.8148714 132.705882,28.3529412 L132.705882,28 C132.705882,26.3431458 131.362737,25 129.705882,25 L128,25 L128,25\"\n id=\"Path-4\"\n stroke=\"#D74141\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n transform=\"translate(133.000000, 31.000000) scale(-1, 1) rotate(30.000000) translate(-133.000000, -31.000000) \"\n />\n <circle\n className={`${className}-particle`}\n id=\"Oval\"\n fill=\"#000000\"\n cx=\"5.5\"\n cy=\"26.5\"\n r=\"1.5\"\n />\n <circle className={`${className}-particle`} id=\"Oval\" fill=\"#000000\" cx=\"10\" cy=\"87\" r=\"4\" />\n <circle\n className={`${className}-particle`}\n id=\"Oval-Copy\"\n fill=\"#000000\"\n cx=\"100\"\n cy=\"4\"\n r=\"4\"\n />\n <circle\n className={`${className}-particle`}\n id=\"Oval\"\n fill=\"#000000\"\n cx=\"151\"\n cy=\"47\"\n r=\"3\"\n />\n </g>\n </g>\n </g>\n </g>\n </svg>\n </motion.div>\n)\n\nexport default PaymentConfettiComponent\n","import React, { useContext } from 'react'\n\nimport CheckmarkImage from 'assets/images/misc/checkmark.svg'\n\nimport { Link } from 'react-router-dom'\nimport TranslationContext from '../../contexts/TranslationContext'\nimport translationGroups from '../../constants/translationGroups'\nimport PaymentConfettiComponent from './PaymentConfettiComponent'\nimport PaymentStepHeaderComponent from '../payment_input/PaymentStepHeaderComponent'\n\nconst PaymentPageSuccessComponent = () => {\n const { getTranslation } = useContext(TranslationContext)\n\n // remove possibly existing ls keys related to the payment, since payment has succeeded\n localStorage.removeItem('payment-period-id')\n localStorage.removeItem('puzzle-pack-id')\n localStorage.removeItem('adyen-checkout__session')\n\n return (\n <div className=\"payment-page-success payment-page-steps\">\n <PaymentStepHeaderComponent />\n <div className=\"container\">\n <div className=\"payment-page-success__animation-container\">\n <div className=\"payment-page-success__confetti-first\">\n <PaymentConfettiComponent className=\"payment-page-success__confetti\" />\n </div>\n <div className=\"payment-page-success__confetti-second\">\n <PaymentConfettiComponent className=\"payment-page-success__confetti\" />\n </div>\n <div className=\"payment-page-success__confetti-third\">\n <PaymentConfettiComponent className=\"payment-page-success__confetti\" />\n </div>\n <CheckmarkImage className=\"payment-page-success__checkmark\" />\n </div>\n <h1 className=\"payment-page-success__title\">\n {getTranslation(translationGroups.paymentInputPage, 'payment-page-success-title')}\n </h1>\n <div className=\"payment-page-success__explanation\">\n {getTranslation(translationGroups.paymentInputPage, 'payment-page-success-explanation')}\n </div>\n <Link to=\"/\">\n <button className=\"rounded-button payment-page-success__card-continue rounded-button--type-secondary\" type=\"button\">\n {getTranslation(translationGroups.paymentCompletePage, 'continue')}\n </button>\n </Link>\n </div>\n </div>\n )\n}\n\nexport default PaymentPageSuccessComponent\n","import React, {\n useContext, useMemo, PropsWithChildren, useEffect, useState,\n} from 'react'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport useConfig from 'client/hooks/useConfig'\nimport { SubscriptionType } from 'client/enums/SubscriptionType'\nimport { useCurrencyFormatters } from 'client/hooks/useCurrencyFormatters'\nimport { Currency, usePriceModels } from 'client/hooks/usePriceModels'\nimport PillComponent from 'common_packages/assets/js/components/ui/pill/PillComponent'\nimport { PAYMENT_PERIOD, PaymentPeriod } from '../PaymentStepsComponent'\n\ninterface Props {\n paymentPeriodId: PaymentPeriod\n subscriptionType: SubscriptionType\n isFree?: boolean\n showPrintDiscount?: boolean // show texts about the discount you receive due to having print subscription\n showDiscountPill?: boolean // show green pill that displays pct saved from choosing yearly over monthly\n showPremiumTrialTexts?: boolean\n showUSPs?:boolean\n}\n\ninterface PriceModel {\n discountPercentage?: number\n currency?: Currency\n amount?: number\n}\n\nconst PaymentSubscriptionCardComponent = ({\n subscriptionType,\n paymentPeriodId,\n isFree = false,\n showPrintDiscount = false,\n showDiscountPill = false,\n showPremiumTrialTexts = false,\n showUSPs = true,\n children,\n}: PropsWithChildren<Props>) => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const { lightTrialDaysText, extendedTrialDaysText } = useConfig()\n const { formatCurrency } = useCurrencyFormatters()\n const { getPriceModel } = usePriceModels()\n const [priceModel, setPriceModel] = useState<PriceModel>({})\n const freeDays = subscriptionType === SubscriptionType.extendedTrial ? extendedTrialDaysText : lightTrialDaysText\n\n useEffect(() => {\n const getModel = async () => {\n const model = await getPriceModel(subscriptionType, paymentPeriodId)\n if (model.amount) {\n setPriceModel(model)\n }\n }\n getModel()\n }, [subscriptionType, paymentPeriodId, getPriceModel])\n\n const listItems = useMemo(() => {\n const list = getRawTranslation(translationGroups.common, `subscription-type-usp-${subscriptionType}${showPrintDiscount ? '-print-discount' : ''}`)\n .replace(/{days}/g, freeDays)\n .split('\\n') ?? []\n return list.map((item) => (\n <li className=\"info-list__element\" key={item}>\n <span className=\"info-list__divider\">•</span>\n {item}\n </li>\n ))\n }, [getRawTranslation, subscriptionType, showPrintDiscount, freeDays])\n\n if (!subscriptionType) {\n return null\n }\n\n const classNames = ['payment-subscription-card', `payment-subscription-card--type-${subscriptionType.toLowerCase()}`]\n\n const amountClassBase = 'payment-subscription-card__price-amount'\n let amountClass = amountClassBase\n if (!showPremiumTrialTexts) amountClass += ` ${amountClassBase}--black`\n if (isFree) amountClass += ` ${amountClassBase}--big`\n\n return (\n <div className={classNames.join(' ')}>\n {showDiscountPill && (\n <PillComponent className=\"payment-page-steps__discount-pill\" type=\"success\">\n {getRawTranslation(translationGroups.paymentInputPage, 'discount-label').replace('{0}', `${priceModel.discountPercentage}`)}\n </PillComponent>\n )}\n <div className=\"payment-subscription-card__content\">\n <div className=\"payment-subscription-card__title\">\n {getRawTranslation(translationGroups.common, `subscription-type-${subscriptionType}`).replace(/{days}/g, freeDays)}\n </div>\n {showPremiumTrialTexts && (\n <div className=\"payment-subscription-card__sub-title\">\n {getTranslation(translationGroups.paymentInputPage, 'x-days-for-1-cent')}\n </div>\n )}\n <div className=\"payment-subscription-card__price\">\n {showPremiumTrialTexts && (\n <span className=\"payment-subscription-card__price-prefix\">\n {getTranslation(translationGroups.paymentInputPage, 'prefix-thereafter-you-pay')}\n {' '}\n </span>\n )}\n <span className={amountClass}>\n {isFree ? getTranslation(translationGroups.common, 'free') : formatCurrency(priceModel.amount)}\n </span>\n {!isFree && (\n <span className=\"payment-subscription-card__period-interval\">\n  /\n {getTranslation(translationGroups.common, `payment-interval-${PAYMENT_PERIOD[paymentPeriodId]}`)}\n </span>\n )}\n </div>\n {showUSPs && (\n <ul className=\"payment-subscription-card__usp info-list\">\n {listItems}\n </ul>\n )}\n {children}\n </div>\n </div>\n )\n}\n\nexport default PaymentSubscriptionCardComponent\n","import React, {\n useCallback,\n useContext, useEffect, useRef, useState,\n} from 'react'\nimport { SubscriptionType } from 'client/enums/SubscriptionType'\nimport { ApiResult, klubbleAPI } from 'client/api/common'\nimport { useHistory, useLocation } from 'react-router'\nimport { setItemSafely } from 'common_packages/assets/js/utilities/persistencyStorage'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { refreshToken } from 'client/api/authentication'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useSelector } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport { useTrackCheckout } from 'client/hooks/useTrackCheckout'\nimport getParameterByName from 'common_packages/assets/js/utilities/getParameterByName'\nimport PaymentPuzzlePackCardComponent from '../payment_input/product_cards/PaymentPuzzlePackCardComponent'\nimport PaymentSubscriptionCardComponent from '../payment_input/product_cards/PaymentSubscriptionCardComponent'\nimport { CheckoutType, PaymentPeriod } from '../payment_input/PaymentStepsComponent'\nimport PaymentStepHeaderComponent from '../payment_input/PaymentStepHeaderComponent'\n\ntype ProductTypeForPaymentResultResponse = {\n productType: string,\n puzzlePackId: number,\n paymentPeriodId: -1 | PaymentPeriod,\n}\n\nconst DELAY = 1000\nconst MAX_TRIES = 120\n\ntype PaymentResultResponse = {\n success: boolean\n}\n\ntype VerifyPaymentResponse = 'succeeded' | 'failed'\n\nconst PaymentRedirectComponent = () => {\n const location = useLocation()\n const history = useHistory()\n const throwError = useAsyncError()\n const redirectResult = getParameterByName('redirectResult')\n const sessionId = getParameterByName('sessionId')\n const { getTranslation } = useContext(TranslationContext)\n const userId = useSelector<StoreState, number>((state) => state.user?.data?.id)\n const { trackCheckoutEvent } = useTrackCheckout()\n const [puzzlePackId, setPuzzlePackId] = useState<number>(null)\n const [paymentPeriodId, setPaymentPeriodId] = useState<PaymentPeriod>(null)\n const [checkoutType, setCheckoutType] = useState<CheckoutType>(null)\n const [paymentSuccess, setPaymentSuccess] = useState(false)\n const triesRef = useRef(0)\n\n useEffect(() => {\n if (paymentSuccess && history.location.pathname !== '/payment-success') {\n trackCheckoutEvent({\n event: 'purchase',\n checkoutType,\n paymentPeriodId,\n puzzlePackId,\n sessionId,\n }).then(() => {\n history.push('/payment-success')\n })\n }\n }, [trackCheckoutEvent, checkoutType, paymentPeriodId, puzzlePackId, sessionId, history, paymentSuccess])\n\n useEffect(() => {\n const abortController = new AbortController()\n const getProduct = async () => {\n // we do not know what type of product (subscription / puzzle pack) is bought here, so we ask BE\n try {\n const { data: response } = await klubbleAPI.post<ApiResult<ProductTypeForPaymentResultResponse>>('Auth/getproducttypeforpayment', JSON.stringify({ details: { redirectResult }, paymentData: sessionId }), {\n headers: {\n 'Content-Type': 'application/json',\n },\n signal: abortController?.signal,\n })\n if (response.success) {\n const { productType, puzzlePackId: receivedPuzzlePackId, paymentPeriodId: receivedPaymentPeriod } = response.data\n if (receivedPuzzlePackId) {\n setItemSafely('puzzle-pack-id', receivedPuzzlePackId)\n setPuzzlePackId(receivedPuzzlePackId)\n }\n if (receivedPaymentPeriod === 0 || receivedPaymentPeriod === 1) {\n setItemSafely('payment-period-id', receivedPaymentPeriod)\n setPaymentPeriodId(receivedPaymentPeriod)\n }\n setCheckoutType(productType === 'Subscription' ? 'subscription' : 'puzzle-pack')\n }\n } catch (e) {\n throwError(e, 'Error getting product type for payment')\n }\n }\n\n if (sessionId && redirectResult) {\n getProduct()\n }\n }, [location.search, history, throwError, sessionId, redirectResult])\n\n useEffect(() => {\n let timeout\n const abortController = new AbortController()\n\n const forwardPaymentResult = async () => {\n // See: https://docs.adyen.com/online-payments/web-drop-in\n try {\n // There has been a case where an encoded redirectResult is send to Auth/paymentResult\n // Although the params.get('redirectResult') already decodes it, just to be sure, we\n // look to see if a '%' is found and if it is we decode it\n const decodedRedirectResult = redirectResult.indexOf('%') > -1 ? decodeURI(redirectResult) : redirectResult\n const { data: response } = await klubbleAPI.post<ApiResult<PaymentResultResponse>>('Auth/paymentResult', JSON.stringify({ details: { redirectResult: decodedRedirectResult }, paymentData: sessionId }), {\n headers: {\n 'Content-Type': 'application/json',\n },\n signal: abortController?.signal,\n })\n if (response.success) {\n verifyPayment()\n } else {\n history.push('/payment-error')\n }\n } catch {\n // We don't know the outcome of the payment, we just know the call to Auth/paymentResult went wrong.\n // There will be a general pending message.\n history.push('/payment-pending')\n }\n }\n\n const verifyPayment = () => {\n triesRef.current += 1\n clearTimeout(timeout)\n timeout = setTimeout(async () => {\n try {\n const { data: response } = await klubbleAPI.post<ApiResult<VerifyPaymentResponse>>('Auth/verifyPayment', JSON.stringify({ sessionId }), {\n headers: {\n 'Content-Type': 'application/json',\n },\n signal: abortController?.signal,\n })\n if (response.data === 'succeeded') {\n if (checkoutType === 'subscription') {\n window.dataLayer.push({\n event: 'regular_trial_converted',\n })\n }\n await refreshToken()\n setPaymentSuccess(true)\n } else if (response.data === 'failed') {\n history.push('/payment-error')\n } else if (triesRef.current < MAX_TRIES) {\n verifyPayment()\n } else {\n // If after MAX_TRIES*DELAY the BE was still not notified by a webhook from Adyen about the successful payment outcome,\n // then the user will not have a PREMIUM subscription yet.\n // In this case we show payment-pending, to inform the user.\n window.dataLayer.push({\n event: 'payment_pending',\n })\n history.push('/payment-pending')\n }\n } catch (e) {\n // We don't know the outcome of the payment, we just know the call to Auth/verifyPayment went wrong.\n // There will be a general pending message.\n history.push('/payment-pending')\n }\n }, DELAY)\n }\n\n if (checkoutType && redirectResult && sessionId && triesRef.current === 0) {\n forwardPaymentResult()\n }\n\n return () => {\n abortController.abort()\n clearTimeout(timeout)\n }\n }, [redirectResult, sessionId, checkoutType, history, userId, throwError])\n\n const renderProductInfo = useCallback(() => {\n if (puzzlePackId) {\n return <PaymentPuzzlePackCardComponent puzzlePackId={puzzlePackId} />\n }\n if (paymentPeriodId === 0 || paymentPeriodId === 1) {\n return <PaymentSubscriptionCardComponent paymentPeriodId={paymentPeriodId} subscriptionType={SubscriptionType.premium} showUSPs={false} />\n }\n return null\n }, [paymentPeriodId, puzzlePackId])\n\n if (!checkoutType) {\n return null\n }\n\n return (\n <div className=\"payment-adyen-redirect payment-page-steps\">\n <PaymentStepHeaderComponent />\n <div className=\"container\">\n {renderProductInfo()}\n <h1 className=\"payment-page-steps__title\">\n {getTranslation(translationGroups.paymentInputPage, 'header-title-adyen-checking-purchased')}\n </h1>\n <div className=\"payment-adyen-redirect__checking-purchased\">\n <div className=\"spinner\" />\n {getTranslation(translationGroups.paymentInputPage, 'adyen-checking-purchased')}\n </div>\n </div>\n </div>\n )\n}\n\nexport default PaymentRedirectComponent\n","import React from 'react'\nimport LogoComponent from '../common/components/LogoComponent'\n\nconst PaymentStepHeaderComponent = () => (\n <div className=\"payment-page-steps__header\">\n <LogoComponent className=\"header__logo payment-page-steps__header__logo\" navigateTo=\"/\" />\n </div>\n)\n\nexport default PaymentStepHeaderComponent\n","import React, {\n useContext, useEffect, useRef,\n useState,\n} from 'react'\nimport AdyenCheckout from '@adyen/adyen-web'\nimport Redirect from '@adyen/adyen-web/dist/types/components/Redirect'\nimport '@adyen/adyen-web/dist/adyen.css'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { refreshToken } from 'client/api/authentication'\nimport { useHistory } from 'react-router'\nimport { useSelector } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport { ErrorCodeObject } from '@adyen/adyen-web/dist/types/components/ThreeDS2/components/utils'\nimport { Role } from 'client/enums/Role'\nimport useConfig from 'client/hooks/useConfig'\nimport { ApiResult, klubbleAPI } from 'client/api/common'\nimport { PuzzlePack } from 'client/types/PuzzlePack'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport RedirectElement from '@adyen/adyen-web/dist/types/components/Redirect/Redirect'\nimport { useTrackCheckout } from 'client/hooks/useTrackCheckout'\nimport { AdyenPaymentInfo, CheckoutType, PaymentPeriod } from './PaymentStepsComponent'\n\ntype Props = {\n adyenPaymentInfo: AdyenPaymentInfo\n checkoutType: CheckoutType\n paymentPeriodId?: PaymentPeriod\n puzzlePackId?: number\n setIsCheckingItemPurchased: (value: boolean) => void\n setIsPayButtonPressed: (value: boolean) => void\n isCheckingItemPurchased: boolean\n}\n\ntype ResultCode = 'Authorised' | 'Cancelled' | 'Error' | 'Pending'\n\ntype PaymentResult = {\n resultCode: ResultCode\n}\n\nconst DELAY = 1000\nconst MAX_TRIES = 120\n\nconst PaymentStepAdyenComponent = ({\n adyenPaymentInfo, checkoutType, paymentPeriodId, puzzlePackId, setIsCheckingItemPurchased, isCheckingItemPurchased, setIsPayButtonPressed,\n}: Props) => {\n const { entity } = useConfig()\n const history = useHistory()\n const userId = useSelector<StoreState, number>((state) => state.user?.data?.id)\n const { getTranslation } = useContext(TranslationContext)\n const { trackCheckoutEvent } = useTrackCheckout()\n const [isLoadingCheckout, setIsLoadingCheckout] = useState(false)\n const [paymentSuccess, setPaymentSuccess] = useState(false)\n const containerRef = useRef<HTMLDivElement>()\n const dropinRef = useRef<RedirectElement>()\n const triesRef = useRef(0)\n const throwError = useAsyncError()\n\n useEffect(() => {\n if (paymentSuccess && history.location.pathname !== '/payment-success') {\n trackCheckoutEvent({\n event: 'purchase',\n checkoutType,\n paymentPeriodId,\n puzzlePackId,\n sessionId: adyenPaymentInfo.sessionId,\n }).then(() => {\n history.push('/payment-success')\n })\n }\n }, [trackCheckoutEvent, checkoutType, paymentPeriodId, puzzlePackId, paymentSuccess, adyenPaymentInfo, history])\n\n useEffect(() => {\n let timeout\n const abortController = new AbortController()\n const checkoutConfiguration = {\n environment: adyenPaymentInfo?.environment || 'test', // Change to 'live' for the live environment.\n clientKey: adyenPaymentInfo?.clientKey, // Public key used for client-side authentication: https://docs.adyen.com/development-resources/client-side-authentication\n analytics: {\n enabled: true, // Set to false to not send analytics data to Adyen.\n },\n session: {\n id: adyenPaymentInfo?.sessionId, // Unique identifier for the payment session.\n sessionData: adyenPaymentInfo?.sessionData, // The payment session data.\n },\n onPaymentCompleted: async (result: PaymentResult, component: Redirect) => {\n component?.unmount()\n if (result.resultCode === 'Authorised') {\n setIsCheckingItemPurchased(true)\n checkItemPurchased()\n } else {\n history.push('/payment-error')\n }\n },\n onError: (_error: ErrorCodeObject, component: Redirect) => {\n component?.unmount()\n history.push('/payment-error')\n },\n beforeSubmit: (data, component: Redirect, actions) => {\n setIsPayButtonPressed(true)\n actions.resolve(data)\n },\n }\n\n const checkItemPurchased = () => {\n triesRef.current += 1\n clearTimeout(timeout)\n timeout = setTimeout(async () => {\n let newToken\n let puzzlePackPurchased\n if (checkoutType === 'subscription') {\n try {\n newToken = await refreshToken()\n } catch (e) {\n throwError(e, 'Error refreshing token')\n }\n } else {\n try {\n const res = await klubbleAPI.get<ApiResult<PuzzlePack>>(`Puzzle/packs/${puzzlePackId}`, {\n signal: abortController?.signal,\n })\n puzzlePackPurchased = res?.data?.data.isPurchased\n } catch (e) {\n throwError(e, 'Error getting puzzle pack details')\n }\n }\n\n if (checkoutType === 'subscription' && newToken?.roles?.includes(Role.premium)) {\n window.dataLayer.push({\n event: 'regular_trial_converted',\n })\n setPaymentSuccess(true)\n } else if (puzzlePackPurchased) {\n // refresh token to get the possible new role puzzlePackOwner\n try {\n newToken = await refreshToken()\n setPaymentSuccess(true)\n } catch (e) {\n throwError('Error refreshing token after purchase puzzle pack')\n }\n } else if (triesRef.current < MAX_TRIES) {\n checkItemPurchased()\n } else {\n // If after MAX_TRIES*DELAY the BE was still not notified by a webhook from Adyen about the successful payment outcome,\n // then the user will not have a PREMIUM subscription yet.\n // In this case we show payment-pending, to inform the user.\n window.dataLayer.push({\n event: 'payment_pending',\n })\n history.push('/payment-pending')\n }\n }, DELAY)\n }\n\n const createDropin = async () => { \n try {\n // Create an instance of AdyenCheckout using the configuration object.\n setIsLoadingCheckout(true)\n\n // Unmount the previous instance of Drop-in if it exists.\n dropinRef.current?.unmount()\n\n const checkout = await AdyenCheckout(checkoutConfiguration)\n \n // We open the first payment method if there is only one.\n const dropinConfiguration = {\n openFirstPaymentMethod: checkout.paymentMethodsResponse.paymentMethods.length === 1,\n }\n\n // Create an instance of Drop-in and mount it to the container you created.\n const dropin = checkout.create('dropin', dropinConfiguration)\n dropin.mount(containerRef.current)\n\n dropinRef.current = dropin\n\n setIsLoadingCheckout(false)\n } catch {\n console.error('An error occurred while creating the Drop-in component.')\n }\n }\n\n if (adyenPaymentInfo?.sessionId) {\n createDropin()\n }\n\n return () => {\n abortController.abort()\n setIsLoadingCheckout(false)\n clearTimeout(timeout)\n }\n }, [adyenPaymentInfo, userId, entity, checkoutType, puzzlePackId, history, throwError, setIsCheckingItemPurchased, setIsPayButtonPressed])\n\n return (\n <div className=\"payment-adyen-checkout\">\n <h1 className={`payment-page-steps__title${isCheckingItemPurchased ? ' payment-page-steps__title--checking-purchased' : ''}`}>\n {getTranslation(translationGroups.paymentInputPage, isCheckingItemPurchased ? 'header-title-adyen-checking-purchased' : 'header-title-step-2')}\n </h1>\n <div className=\"payment-adyen-checkout__dropin\" ref={containerRef} />\n {isLoadingCheckout && (\n <div className=\"payment-adyen-checkout__loading-checkout\">\n <div className=\"spinner\" />\n </div>\n )}\n {isCheckingItemPurchased && (\n <div className=\"payment-adyen-checkout__checking-purchased\">\n <div className=\"spinner\" />\n {getTranslation(translationGroups.paymentInputPage, 'adyen-checking-purchased')}\n </div>\n )}\n </div>\n )\n}\n\nexport default PaymentStepAdyenComponent\n","import React, { useCallback } from 'react'\nimport { setItemSafely } from 'common_packages/assets/js/utilities/persistencyStorage'\nimport { type PaymentPeriod } from './PaymentStepsComponent'\nimport ChoosePaymentPeriodComponent from './choose_subscription/ChoosePaymentPeriodComponent'\n\ntype Props = {\n paymentPeriodId: PaymentPeriod\n headerTitle: string\n setPaymentPeriodId: (id: PaymentPeriod) => void\n canStartTrial: boolean\n}\n\nconst PaymentStepSubscriptionComponent = ({\n paymentPeriodId,\n headerTitle,\n setPaymentPeriodId,\n canStartTrial,\n}:Props) => {\n const handlePaymentPeriodIdChange = useCallback((id: PaymentPeriod) => {\n setItemSafely('payment-period-id', id) // We store this here in case payment fails, or in case of a page refresh.\n setPaymentPeriodId(id)\n }, [setPaymentPeriodId])\n\n return (\n <>\n <h1 className=\"payment-page-steps__title\">\n {headerTitle}\n </h1>\n <ChoosePaymentPeriodComponent\n selectedPaymentPeriodId={paymentPeriodId}\n canStartTrial={canStartTrial}\n onPaymentPeriodIdChange={handlePaymentPeriodIdChange}\n />\n </>\n )\n}\n\nexport default PaymentStepSubscriptionComponent\n","import React, { useContext } from 'react'\nimport { useSelector } from 'react-redux'\nimport SelectComponent from 'pages/common/components/form/SelectComponent'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport useCountryOptions from 'client/hooks/useCountryOptions'\nimport { ConfigState } from 'client/reducers/configReducer'\nimport { StoreState } from 'client/store'\n\nimport { SubmitHandler, UseFormReturn } from 'react-hook-form'\nimport InputComponent from '../common/components/form/InputComponent'\nimport SubmitButtonComponent from '../common/components/form/SubmitButtonComponent'\n\nexport type PaymentInputs = {\n firstName?: string,\n middleName?: string,\n lastName?: string,\n country?: string\n}\n\ntype Props = {\n form: UseFormReturn<PaymentInputs>,\n initializePayment: SubmitHandler<PaymentInputs>\n}\n\nconst PaymentStepPersonalInfoComponent = ({\n form, initializePayment,\n}:Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const { activePaymentPlatform } = useSelector<StoreState, ConfigState | null>((store) => store.config) || {}\n const countryOptions = useCountryOptions()\n const { handleSubmit } = form\n\n return (\n <>\n <h1 className=\"payment-page-steps__title\">\n {getTranslation(translationGroups.paymentInputPage, 'select-country') }\n </h1>\n <form\n onChange={activePaymentPlatform === 'ADYEN' ? handleSubmit(initializePayment) : null}\n onSubmit={activePaymentPlatform === 'TWIKEY' ? handleSubmit(initializePayment) : null}\n >\n <div className=\"payment-page-steps__form-wrapper\">\n <div className=\"payment-page-steps__form\">\n {activePaymentPlatform === 'TWIKEY' && (\n <>\n <div className=\"form__field-wrapper\">\n <InputComponent\n name=\"firstName\"\n label={getTranslation(translationGroups.paymentInputPage, 'first-name-label')}\n type=\"text\"\n showValidatorError\n form={form}\n />\n <InputComponent\n name=\"middleName\"\n label={getTranslation(translationGroups.paymentInputPage, 'middle-name-label')}\n type=\"text\"\n showValidatorError\n form={form}\n />\n </div>\n <InputComponent\n name=\"lastName\"\n label={getTranslation(translationGroups.paymentInputPage, 'last-name-label')}\n type=\"text\"\n showValidatorError\n form={form}\n />\n </>\n )}\n <SelectComponent\n name=\"country\"\n noEmptyOption\n label={getTranslation(translationGroups.paymentInputPage, 'country-label')}\n form={form}\n options={countryOptions.optionsSorted}\n translateItem={(_name: string, item: string) => countryOptions.translationMap.get(item)}\n />\n {activePaymentPlatform === 'TWIKEY' && (\n <SubmitButtonComponent\n label={getTranslation(translationGroups.paymentInputPage, 'next')}\n form={form}\n />\n )}\n </div>\n </div>\n </form>\n </>\n )\n}\n\nexport default PaymentStepPersonalInfoComponent\n","import React, {\n useContext, useMemo, useEffect, useState, useCallback, useRef,\n} from 'react'\nimport {\n useHistory, useLocation,\n} from 'react-router-dom'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { useForm, type SubmitHandler } from 'react-hook-form'\nimport { yupResolver } from '@hookform/resolvers/yup'\nimport * as yup from 'yup'\nimport { closeDrawer, addToast } from 'common_packages/assets/js/actions/uiActions'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { type StoreState } from 'client/store'\nimport { type UserData } from 'client/reducers/userReducer'\nimport useAbilities from 'client/hooks/useAbilities'\n\nimport { setItemSafely } from 'common_packages/assets/js/utilities/persistencyStorage'\nimport { useTrackCheckout } from 'client/hooks/useTrackCheckout'\n\nimport { type ConfigState } from 'client/reducers/configReducer'\nimport { type ApiResult, klubbleAPI } from 'client/api/common'\nimport { setUser } from 'client/actions/userActions'\nimport { refreshToken } from 'client/api/authentication'\nimport { toastTypes } from 'common_packages/assets/js/types/toastTypes'\nimport { alphanumeric } from 'client/utilities/userInput'\nimport useConfig from 'client/hooks/useConfig'\nimport usePrevious from 'common_packages/assets/js/hooks/usePrevious'\nimport PaymentStepAdyenComponent from './PaymentStepAdyenComponent'\nimport PaymentStepSubscriptionComponent from './PaymentStepSubscriptionComponent'\nimport PaymentStepPersonalInfoComponent, { type PaymentInputs } from './PaymentStepPersonalInfoComponent'\n\nimport PaymentPuzzlePackCardComponent from './product_cards/PaymentPuzzlePackCardComponent'\nimport PaymentStepHeaderComponent from './PaymentStepHeaderComponent'\n\n// This maps to the backend\nexport const PAYMENT_PERIOD = {\n 0: 'monthly',\n 1: 'yearly',\n}\n\nexport type PaymentPeriod = keyof typeof PAYMENT_PERIOD\n\nexport type AdyenPaymentInfo = {\n clientKey: string\n sessionData: string\n sessionId: string\n environment: 'test' | 'live'\n}\n\nexport interface LocationState {\n paymentPeriodId?: PaymentPeriod\n puzzlePackId?: number\n}\n\nexport type CheckoutType = 'subscription' | 'puzzle-pack'\n\ntype InitializePaymentResponses = ApiResult<{ paymentUrl?: string, success: boolean, adyenPaymentInfo: AdyenPaymentInfo }>\n\ntype Message = 'user-registration-user-already-loggedin-as-real-user' |\n'user-registration-user-already-registered-redirect-login' |\n'user-registration-user-is-unregistered-print-subscriber' |\n'user-registration-user-can-register' |\n'user-already-has-active-premium-subscription'\n\ntype Props = {\n checkoutType: CheckoutType\n}\n\nconst PaymentStepsComponent = ({ checkoutType }:Props) => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const history = useHistory()\n const location = useLocation() as { state: LocationState, search: string }\n const dispatch = useDispatch()\n const abilities = useAbilities()\n const initalizedRef = useRef(false)\n const { entity } = useConfig()\n const { trackCheckoutEvent } = useTrackCheckout()\n const { activePaymentPlatform } = useSelector<StoreState, ConfigState | null>((store) => store.config)\n\n const puzzlePackId = checkoutType === 'puzzle-pack' ? +(String(location?.state?.puzzlePackId ?? localStorage.getItem('puzzle-pack-id'))) : null\n const [paymentPeriodId, setPaymentPeriodId] = useState<PaymentPeriod>((location?.state?.paymentPeriodId ?? +(localStorage.getItem('payment-period-id') ?? 1)) as PaymentPeriod)\n const previousPaymentPeriodId = usePrevious(paymentPeriodId)\n\n const [adyenPaymentInfo, setAdyenPaymentInfo] = useState<AdyenPaymentInfo>(null)\n const [isCheckingItemPurchased, setIsCheckingItemPurchased] = useState(false)\n const [isPayButtonPressed, setIsPayButtonPressed] = useState(false)\n\n const {\n email, firstName, middleName, lastName, country: storedCountry,\n } = useSelector<StoreState, UserData>((state) => state.user?.data)\n\n useEffect(() => {\n // If pressing browser forward button after going back home, ensure modal is closed\n dispatch(closeDrawer())\n }, [dispatch])\n\n useEffect(() => {\n if (checkoutType === 'subscription') {\n setItemSafely('payment-period-id', paymentPeriodId)\n } else {\n setItemSafely('puzzle-pack-id', puzzlePackId)\n }\n }, [checkoutType, paymentPeriodId, puzzlePackId])\n\n useEffect(() => {\n if (abilities.hasPremiumSubscription && checkoutType === 'subscription' && !adyenPaymentInfo) {\n // What are you doing here?\n history.replace('/')\n }\n }, [abilities.hasPremiumSubscription, checkoutType, history, adyenPaymentInfo])\n\n const user = useSelector<StoreState, UserData>((state) => state.user?.data)\n const { canStartTrial } = user || {}\n\n const initializePaymentEndpoint = useMemo(() => {\n if (checkoutType === 'puzzle-pack') {\n return 'initializepaymentforpuzzlepack'\n } if (!canStartTrial || abilities.hasLightSubscriptionOnly) {\n return 'initializepaymentforsubscription'\n }\n return 'initializepaymentfortrial'\n }, [checkoutType, canStartTrial, abilities.hasLightSubscriptionOnly])\n\n const country = storedCountry?.length ? storedCountry : entity.defaultCountry?.code\n\n const schema = yup.object({}).shape({\n country: yup.string()\n .matches(alphanumeric, {\n message: getRawTranslation(translationGroups.error, 'invalid-input'),\n }),\n })\n\n const form = useForm<PaymentInputs>({\n resolver: yupResolver(schema),\n values: {\n firstName,\n middleName,\n lastName,\n country,\n },\n })\n\n const initializePayment: SubmitHandler<PaymentInputs> = useCallback(async (data: PaymentInputs) => {\n try {\n const payload = {\n firstName: data.firstName ?? firstName,\n middleName: data.middleName ?? middleName,\n lastName: data.lastName ?? lastName,\n country: data.country ?? country,\n email,\n paymentPeriodId,\n puzzlePackId,\n }\n\n const { data: response } = await klubbleAPI.post<InitializePaymentResponses>(`Auth/${initializePaymentEndpoint}`, JSON.stringify(payload), {\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n\n if (response.data?.success) {\n await setUser()(dispatch)\n const { paymentUrl, adyenPaymentInfo: adyenInfo } = response.data\n if (activePaymentPlatform === 'ADYEN' && adyenInfo?.sessionId) {\n // if the paymentProvider is set to Adyen, there will be adyenPaymentInfo in initializePaymentResponse\n setAdyenPaymentInfo(adyenInfo)\n\n trackCheckoutEvent({\n event: 'begin_checkout',\n checkoutType,\n paymentPeriodId: checkoutType === 'subscription' ? paymentPeriodId : null,\n puzzlePackId: checkoutType === 'subscription' ? null : puzzlePackId,\n sessionId: adyenInfo?.sessionId,\n })\n } else if (activePaymentPlatform === 'TWIKEY' && paymentUrl) {\n // otherwise, if the server setting for paymentProvider is set to Twikey, the initializePaymentResponse will have a paymentUrl\n window.location.href = paymentUrl\n }\n } else {\n let translationKey = `payment-${response.message}`\n let toastType = toastTypes.ERROR\n switch (response.message as Message) {\n case 'user-already-has-active-premium-subscription':\n toastType = toastTypes.SUCCESS\n await refreshToken()\n history.push('/')\n break\n default:\n translationKey = 'payment-personal-details-error'\n break\n }\n dispatch(addToast({\n message: getTranslation(translationGroups.form, translationKey),\n type: toastType,\n }))\n }\n } catch {\n dispatch(addToast({\n message: getTranslation(translationGroups.api, 'something-went-wrong'),\n type: toastTypes.ERROR,\n }))\n }\n }, [\n firstName,\n middleName,\n lastName,\n country,\n email,\n paymentPeriodId,\n puzzlePackId,\n initializePaymentEndpoint,\n dispatch,\n activePaymentPlatform,\n trackCheckoutEvent,\n checkoutType,\n getTranslation,\n history,\n ])\n\n useEffect(() => {\n // Call initializePayment automatically first time and in case paymentPeriodId changes and activePaymentPlatform is Adyen.\n // This way the Adyen payment form is shown immediately, or updated in case paymentPeriodId changes.\n const paymentPeriodChanged = paymentPeriodId !== previousPaymentPeriodId && (paymentPeriodId === 0 || paymentPeriodId === 1)\n if (activePaymentPlatform === 'ADYEN' && (!initalizedRef.current || paymentPeriodChanged)) {\n initalizedRef.current = true\n initializePayment({})\n }\n }, [paymentPeriodId, activePaymentPlatform, initializePayment, previousPaymentPeriodId])\n\n const headerTitle = useMemo(() => {\n const title = `header-title-step-0${checkoutType === 'puzzle-pack' ? '-puzzle-pack' : ''}`\n if (checkoutType === 'subscription' && abilities.hasLightSubscriptionOnly) {\n return `${title}-upgrade`\n }\n if (checkoutType === 'subscription' && canStartTrial) {\n return `${title}-trial`\n }\n return title\n }, [checkoutType, abilities.hasLightSubscriptionOnly, canStartTrial])\n\n return (\n <div className=\"payment-page-steps\">\n <PaymentStepHeaderComponent />\n <div className=\"container\">\n {!isCheckingItemPurchased && !isPayButtonPressed && (\n <>\n {checkoutType === 'subscription' ? (\n <PaymentStepSubscriptionComponent\n paymentPeriodId={paymentPeriodId}\n headerTitle={getTranslation(translationGroups.paymentInputPage, headerTitle)}\n setPaymentPeriodId={setPaymentPeriodId}\n canStartTrial={canStartTrial}\n />\n ) : (\n <>\n <h1 className=\"payment-page-steps__title\">{getTranslation(translationGroups.paymentInputPage, headerTitle)}</h1>\n <PaymentPuzzlePackCardComponent\n puzzlePackId={puzzlePackId}\n />\n </>\n )}\n <PaymentStepPersonalInfoComponent\n form={form}\n initializePayment={initializePayment}\n />\n </>\n )}\n {activePaymentPlatform === 'ADYEN'\n && (\n <PaymentStepAdyenComponent\n adyenPaymentInfo={adyenPaymentInfo}\n checkoutType={checkoutType}\n paymentPeriodId={paymentPeriodId}\n puzzlePackId={puzzlePackId}\n setIsCheckingItemPurchased={setIsCheckingItemPurchased}\n setIsPayButtonPressed={setIsPayButtonPressed}\n isCheckingItemPurchased={isCheckingItemPurchased}\n />\n )}\n </div>\n </div>\n )\n}\n\nexport default PaymentStepsComponent\n","import React, { useContext } from 'react'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { type PriceModelState } from 'client/hooks/usePriceModels'\nimport { useCurrencyFormatters } from 'client/hooks/useCurrencyFormatters'\nimport PillComponent from 'common_packages/assets/js/components/ui/pill/PillComponent'\nimport { PAYMENT_PERIOD, type PaymentPeriod } from '../PaymentStepsComponent'\n\ntype Props = {\n paymentPeriodId: PaymentPeriod\n onSelect?: () => void\n active: boolean\n priceModel: PriceModelState\n}\n\nconst PaymentPeriodComponent = ({\n paymentPeriodId,\n priceModel,\n onSelect,\n active,\n}: Props) => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const { formatCurrency } = useCurrencyFormatters()\n\n const className = [\n 'choose-payment-period__payment-period',\n ...(active ? ['choose-payment-period__payment-period--active'] : []),\n ].join(' ')\n\n const showDiscountPill = priceModel?.discountPercentage > 0\n\n return (\n <div className={className} onClick={onSelect} role=\"button\">\n {showDiscountPill && (\n <PillComponent className=\"choose-payment-period__payment-period-discount-pill\" type=\"success\">\n {getRawTranslation(translationGroups.paymentInputPage, 'discount-label')\n .replace('{0}', `${priceModel.discountPercentage}`)}\n </PillComponent>\n )}\n <div className=\"choose-payment-period__payment-period-description\">\n <span className={`choose-payment-period__payment-period-radio${active ? ' choose-payment-period__payment-period-radio--active' : ''}`} />\n {getTranslation(translationGroups.paymentInputPage, `interval-subscription-type-${PAYMENT_PERIOD[paymentPeriodId]}`)}\n </div>\n { !priceModel && (<>...</>) }\n { priceModel && (\n <div className=\"choose-payment-period__payment-period-amount\">\n { formatCurrency(priceModel.amount)}\n <span className=\"choose-payment-period__payment-period-interval\">\n {` / ${getRawTranslation(translationGroups.common, `payment-interval-${PAYMENT_PERIOD[paymentPeriodId]}`).toLowerCase()}`}\n </span>\n </div>\n )}\n </div>\n )\n}\n\nexport default PaymentPeriodComponent\n","import React, {\n useContext, useEffect, useMemo, useState,\n} from 'react'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { type PriceModelState, usePriceModels } from 'client/hooks/usePriceModels'\nimport { type PaymentPeriod } from '../PaymentStepsComponent'\nimport RoundedButtonComponent from '../../common/components/buttons/RoundedButtonComponent'\nimport PaymentPeriodComponent from './PaymentPeriodComponent'\n\ntype Props = {\n selectedPaymentPeriodId: PaymentPeriod\n onPaymentPeriodIdChange: (paymentPeriodId: PaymentPeriod) => void\n canStartTrial: boolean\n onNext?: () => void\n className?: string\n}\n\n// This is where the user chooses the payment period (monthly/yearly)\nconst ChoosePaymentPeriodComponent = ({\n selectedPaymentPeriodId,\n onPaymentPeriodIdChange,\n canStartTrial,\n onNext,\n className: propsClassName,\n}: Props) => {\n const abilities = useAbilities()\n const { getTranslation } = useContext(TranslationContext)\n\n const { getAllPriceModels } = usePriceModels()\n const [priceModels, setPriceModels] = useState<PriceModelState[]>([])\n\n useEffect(() => {\n const fetchModels = async () => {\n const models = await getAllPriceModels()\n setPriceModels(models)\n }\n if (!priceModels.length) {\n fetchModels()\n }\n }, [getAllPriceModels, priceModels])\n\n const continueTitle = useMemo(() => {\n if (abilities.hasLightSubscriptionOnly) {\n return 'continue-upgrade'\n }\n if (canStartTrial) {\n return 'continue-trial'\n }\n return 'continue-subscription'\n }, [abilities.hasLightSubscriptionOnly, canStartTrial])\n\n const className = [\n 'choose-payment-period',\n propsClassName,\n ].join(' ')\n\n const renderPaymentPeriodComponent = (paymentPeriod: PaymentPeriod) => (\n <PaymentPeriodComponent\n paymentPeriodId={paymentPeriod}\n active={selectedPaymentPeriodId === paymentPeriod}\n onSelect={() => { onPaymentPeriodIdChange(paymentPeriod) }}\n priceModel={priceModels.find((pM) => pM.paymentPeriodId === paymentPeriod)}\n />\n )\n\n return (\n <div className={className}>\n\n {renderPaymentPeriodComponent(1)}\n {renderPaymentPeriodComponent(0)}\n\n {onNext && (\n <RoundedButtonComponent\n className=\"choose-payment-period__continue-button\"\n text={getTranslation(translationGroups.paymentInputPage, continueTitle)}\n onClickHandler={onNext}\n />\n )}\n </div>\n )\n}\n\nexport default ChoosePaymentPeriodComponent\n","import React, { useContext } from 'react'\nimport raw from 'rehype-raw'\nimport sanitize from 'rehype-sanitize'\nimport ReactMarkdown from 'react-markdown'\n\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useCurrencyFormatters } from 'client/hooks/useCurrencyFormatters'\nimport { type Level } from 'client/interfaces/IPuzzleCalendar'\nimport { CustomListItemComponent } from 'client/pages/common/components/react_markdown/CustomListItemComponent'\nimport { usePuzzlePacks } from '../../puzzle_packs/hooks/usePuzzlePacks'\n\ntype Props = {\n puzzlePackId: number\n showDescription?: boolean\n}\n\nconst PaymentPuzzlePackCardComponent = ({ puzzlePackId, showDescription }: Props) => {\n const { getPuzzlePackById } = usePuzzlePacks()\n const puzzlePack = getPuzzlePackById(puzzlePackId)\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const { formatCurrency } = useCurrencyFormatters()\n\n if (!puzzlePack) {\n return null\n }\n return (\n <div className=\"payment-puzzle-pack-card\">\n <div className=\"payment-puzzle-pack-card__content\">\n <div className=\"payment-puzzle-pack-card__title\">\n {puzzlePack.displayName}\n </div>\n <div className=\"payment-puzzle-pack-card__tags\">\n {getTranslation(translationGroups.puzzleTags, puzzlePack.largestFormat)}\n <span className=\"payment-puzzle-pack-card__tag-divider\">•</span>\n {puzzlePack.levels.map((level: Level) => getTranslation(translationGroups.difficulty, level.toLocaleLowerCase())).join(' / ')}\n </div>\n <div className=\"payment-puzzle-pack-card__size\">\n {getRawTranslation(translationGroups.puzzlePack, 'content-size').replace(/{size}/g, puzzlePack.size?.toString())}\n </div>\n <div className=\"payment-puzzle-pack-card__price\">\n {formatCurrency(puzzlePack.price)}\n </div>\n {showDescription && (\n <div className=\"payment-puzzle-pack-card__description\">\n <ReactMarkdown rehypePlugins={[raw, sanitize]} components={{ li: CustomListItemComponent }}>{puzzlePack.description}</ReactMarkdown>\n </div>\n )}\n </div>\n </div>\n\n )\n}\n\nexport default PaymentPuzzlePackCardComponent\n","import React, { CSSProperties } from 'react'\nimport CheckmarkImage from 'assets/images/misc/checkmark.svg'\nimport { EndscreenAnimationConfig } from './types'\n\ntype Props = {\n animation: EndscreenAnimationConfig\n isEndscreenAnimationActive: boolean\n}\n\nconst EndscreenCheckmarkComponent = ({ animation, isEndscreenAnimationActive }: Props) => {\n const className = [\n 'endscreen-celebration-checkmark',\n ...(isEndscreenAnimationActive ? ['endscreen-celebration-checkmark--animate'] : ['endscreen-celebration-checkmark--hidden']),\n ].join(' ')\n const duration = isEndscreenAnimationActive ? `${animation.checkmark.duration}s` : '0s'\n\n return (\n <div\n className={className}\n style={{\n '--animation-duration': duration,\n '--animation-delay': `${animation.checkmark.delay}s`,\n } as CSSProperties}\n >\n <CheckmarkImage />\n </div>\n )\n}\n\nexport default EndscreenCheckmarkComponent\n","import IconBadgeCompleted from 'assets/icons/icon_badge_completed.svg'\nimport IconBadgeHints from 'assets/icons/icon_badge_hints.svg'\nimport IconBadgeTime from 'assets/icons/icon_badge_time.svg'\nimport IconBadgeStreak from 'assets/icons/icon_badge_streak.svg'\nimport IconBadgeSocial from 'assets/icons/icon_badge_social.svg'\nimport IconTrophy from 'assets/icons/icon_trophy.svg'\nimport { ScoringBadge } from 'client/types/ScoringBadge'\nimport { BrainpointBadge } from '../types/BrainpointBadge'\n\nconst templates: BrainpointBadge[] = [\n {\n scoreType: 'mini',\n subtitle: 'mini-subtitle',\n IconComponent: IconBadgeCompleted,\n score: '',\n iconUrl: '',\n },\n {\n scoreType: 'classic',\n subtitle: 'classic-subtitle',\n IconComponent: IconBadgeCompleted,\n score: '',\n iconUrl: '',\n },\n {\n scoreType: 'wordguess',\n subtitle: 'wordguess-subtitle',\n IconComponent: IconBadgeCompleted,\n score: '',\n iconUrl: '',\n },\n {\n scoreType: 'rebus',\n subtitle: 'rebus-subtitle',\n IconComponent: IconBadgeCompleted,\n score: '',\n iconUrl: '',\n },\n {\n scoreType: 'time',\n subtitle: 'time-subtitle',\n IconComponent: IconBadgeTime,\n score: '',\n iconUrl: '',\n },\n {\n scoreType: 'tries',\n subtitle: 'tries-subtitle',\n IconComponent: IconBadgeTime,\n score: '',\n iconUrl: '',\n },\n {\n scoreType: 'hint-usage',\n subtitle: 'hint-subtitle',\n IconComponent: IconBadgeHints,\n score: '',\n iconUrl: '',\n },\n {\n scoreType: 'streak',\n subtitle: 'streak-subtitle',\n IconComponent: IconBadgeStreak,\n score: '',\n iconUrl: '',\n },\n {\n scoreType: 'chats',\n subtitle: 'chats-subtitle',\n IconComponent: IconBadgeSocial,\n score: '',\n iconUrl: '',\n },\n {\n scoreType: 'badge',\n subtitle: 'badge-subtitle',\n IconComponent: IconTrophy,\n score: '',\n iconUrl: '',\n },\n]\n\nexport const getBrainPointBadgesList = (brainpoints: ScoringBadge[]): BrainpointBadge[] => {\n let gameType = 'unknown'\n if (brainpoints.some((brainPoint) => brainPoint.scoreType === 'mini')) {\n gameType = 'mini'\n } else if (brainpoints.some((brainPoint) => brainPoint.scoreType === 'classic')) {\n gameType = 'classic'\n } else if (brainpoints.some((brainPoint) => brainPoint.scoreType === 'wordguess')) {\n gameType = 'wordguess'\n } else if (brainpoints.some((brainPoint) => brainPoint.scoreType === 'rebus')) {\n gameType = 'rebus'\n }\n\n const orderedScoringCategories = ['mini', 'normal', 'wordguess', 'rebus', 'bonus', 'streak', 'badge', 'hint-usage', 'time', 'tries', 'total']\n return brainpoints.reduce((extendedBrainpoints, brainPointItem) => {\n const template = templates.find((brainPoint) => brainPoint.scoreType === brainPointItem.scoreType)\n const brainpointBadge: BrainpointBadge = {\n ...brainPointItem,\n score: null,\n subtitle: null,\n iconUrl: null,\n IconComponent: null,\n }\n if (template) {\n brainpointBadge.score = `${brainPointItem.score}`\n brainpointBadge.subtitle = (['tries', 'time', 'hint-usage'].includes(brainPointItem.scoreType))\n ? `subtitle-${template.subtitle}-${gameType}-${brainPointItem.score}`\n : `subtitle-${template.subtitle}`\n brainpointBadge.iconUrl = template.iconUrl\n brainpointBadge.IconComponent = template.IconComponent\n }\n\n /* Make sure only badges are listed */\n if (template?.IconComponent) {\n extendedBrainpoints.push(brainpointBadge)\n }\n return extendedBrainpoints\n }, [])\n .sort((x, y) => {\n if (orderedScoringCategories.indexOf(x.scoreType) < orderedScoringCategories.indexOf(y.scoreType)) {\n return -1\n }\n if (orderedScoringCategories.indexOf(x.scoreType) > orderedScoringCategories.indexOf(y.scoreType)) {\n return 1\n }\n return 0\n })\n}\n","import { StoreState } from 'client/store'\nimport { ScoringBadge } from 'client/types/ScoringBadge'\nimport { getBrainPointBadgesList } from 'client/utilities/brainpointsUtilities'\nimport { useMemo } from 'react'\nimport { useSelector } from 'react-redux'\n\nconst useBrainpointBadges = () => {\n const scoringBadges = useSelector<StoreState, ScoringBadge[]>((state) => state.puzzleData.finishedPuzzle.scoringBadges)\n return useMemo(() => {\n return getBrainPointBadgesList(scoringBadges)\n }, [scoringBadges])\n}\n\nexport default useBrainpointBadges\n","import React from 'react'\nimport IconDropdownComponent from 'assets/icons/icon_dropdown_down.svg'\n\ntype Props = {\n onClickHandler: () => void,\n active: boolean\n}\n\nconst ExpandToggleComponent = ({ onClickHandler, active }: Props) => {\n const baseToggleClass = 'expand-toggle'\n const toggleClass = active ? `${baseToggleClass} ${baseToggleClass}--active` : baseToggleClass\n\n return (\n <button className={toggleClass} onClick={onClickHandler}><IconDropdownComponent className=\"expand-toggle__icon\" /></button>\n )\n}\n\nexport default ExpandToggleComponent\n","import React, {\n useCallback, useContext, useState, useEffect,\n} from 'react'\nimport { AnimatePresence, motion } from 'framer-motion'\nimport { useSelector } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport { ScoringBadge } from 'client/types/ScoringBadge'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport ExpandToggleComponent from 'client/pages/common/components/toggles/ExpandToggleComponent'\nimport useBrainpointBadges from '../../hooks/useBrainpointBadges'\n\ntype Props = {\n collapseBrainpoints?: boolean\n}\n\nconst EndscreenBrainpointsComponent = ({ collapseBrainpoints = false }: Props) => {\n const translation = useContext(TranslationContext)\n const [autoCollapsed, setAutoCollapsed] = useState(false)\n const [open, setOpen] = useState(false)\n\n const scoringBadges = useSelector<StoreState, ScoringBadge[]>((state) => state.puzzleData.finishedPuzzle.scoringBadges)\n const brainPointBadgesList = useBrainpointBadges()\n\n const toggleOpen = useCallback(() => {\n setOpen(!open)\n }, [open])\n\n useEffect(() => {\n if (!open && collapseBrainpoints && !autoCollapsed) {\n setOpen(!open)\n setAutoCollapsed(true)\n }\n }, [collapseBrainpoints, autoCollapsed, open])\n\n const total = scoringBadges.find((brainPoint) => brainPoint.scoreType === 'total')?.score\n const baseHeaderClass = 'list-item-header'\n const headerClass = open ? `${baseHeaderClass} ${baseHeaderClass}--active` : baseHeaderClass\n\n return (\n <div className=\"endscreen-brainpoints\">\n <div className={`${headerClass} list-item`}>\n <span className=\"list-item-header__points\">{`+${total}`}</span>\n <span className=\"list-item-header__title\">{translation.getTranslation(translationGroups.endscreenPage, 'brainpoints')}</span>\n <div className=\"list-item__right\">\n <ExpandToggleComponent onClickHandler={toggleOpen} active={open} />\n </div>\n </div>\n <AnimatePresence initial={false}>\n {open && (\n <motion.section\n layout\n key=\"content\"\n initial=\"collapsed\"\n animate=\"open\"\n exit=\"collapsed\"\n variants={{\n open: { opacity: 1, x: '0%', height: 'auto' },\n collapsed: { opacity: 0, x: '-50%', height: 0 },\n }}\n transition={{ duration: 0.8, ease: [0.04, 0.62, 0.23, 0.98] }}\n >\n <>\n {brainPointBadgesList.map((brainPoint) => {\n const subtitle = translation.getRawTranslation(translationGroups.brainpoints, brainPoint.subtitle)\n return (\n <div key={brainPoint.scoreType} className=\"list-item\">\n <div className=\"list-item__icon\">\n <brainPoint.IconComponent className=\"endscreen-brainpoints__badge\" />\n </div>\n <span className=\"list-item__description\">\n {translation.getTranslation(translationGroups.brainpoints, `type-${brainPoint.scoreType}`)}\n {subtitle?.trim().length > 0 && <span className=\"list-item__subtext list-item__subtext--small\">{subtitle}</span>}\n </span>\n <span className=\"list-item__right\">\n {`+${brainPoint.score}`}\n </span>\n </div>\n )\n })}\n\n <div className=\"endscreen-brainpoints__list-footer list-item\">\n {translation.getTranslation(translationGroups.brainpoints, 'total')}\n <span className=\"endscreen-brainpoints__total\">{total}</span>\n </div>\n </>\n </motion.section>\n )}\n </AnimatePresence>\n </div>\n )\n}\nexport default EndscreenBrainpointsComponent\n","import React, { useLayoutEffect } from 'react'\nimport { motion, useMotionValue } from 'framer-motion'\nimport { EndscreenAnimationConfig } from 'client/pages/endscreen/components/types'\nimport breakpoints from 'common_packages/assets/js/constants/breakpoints'\nimport useWindowPosition from 'client/hooks/useWindowPosition'\nimport useWindowDimensions from 'common_packages/assets/js/hooks/useWindowDimensions'\nimport EndscreenBrainpointsComponent from './EndscreenBrainpointsComponent'\n\ntype Props = {\n animation: EndscreenAnimationConfig\n active: boolean\n}\nconst yBottomBrainpoints = 30\n\n// BrainpointsOne is the animating, 'fake' version\nconst EndscreenBrainpointsOneComponent = ({ animation, active: isEndscreenAnimationActive }: Props) => {\n const scrollPosition = useWindowPosition()\n const { width: windowWidth, height: windowHeight } = useWindowDimensions()\n const bottom = useMotionValue(scrollPosition)\n\n useLayoutEffect(() => {\n bottom.set(yBottomBrainpoints + scrollPosition)\n }, [scrollPosition, bottom])\n\n const { duration } = animation.endscreenBrainpoints\n const delay = animation.endscreenCelebration.duration + animation.endscreenBrainpoints.delay\n\n return (\n <motion.div\n layout\n key=\"endscreen-celebration-brainpoints\"\n animate={isEndscreenAnimationActive ? 'visible' : 'hidden'}\n variants={{\n visible: () => {\n const elem = document.getElementById('endscreen-brainpoints-two')\n const headerHeight = (windowWidth >= breakpoints.MEDIUM) ? 64 : 0\n const yDiff = windowHeight - yBottomBrainpoints - (elem.offsetTop + elem.clientHeight + headerHeight)\n\n return {\n y: [0, -yDiff],\n transitionEnd: {\n display: 'none',\n opacity: 0,\n },\n transition: {\n duration,\n delay,\n ease: 'easeOut',\n },\n }\n },\n hidden: { opacity: 0, display: 'none' },\n }}\n style={{\n position: 'fixed',\n bottom,\n }}\n className=\"endscreen-brainpoints-one\"\n >\n <EndscreenBrainpointsComponent />\n </motion.div>\n )\n}\n\nexport default EndscreenBrainpointsOneComponent\n","import React from 'react'\nimport { motion } from 'framer-motion'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { EndscreenAnimationConfig } from '../types'\nimport EndscreenBrainpointsComponent from './EndscreenBrainpointsComponent'\n\ntype Props = {\n animation: EndscreenAnimationConfig\n isEndscreenAnimationActive: boolean\n}\n\n// Player can open this component to see all brainpoints awarded\nconst EndscreenBrainpointsTwoComponent = ({ animation, isEndscreenAnimationActive }: Props) => {\n const { canSeeCollapsedDailyDoseEndscreen } = useAbilities()\n const endscreenBrainpointsVariants = {\n standard: {\n opacity: [0, 1],\n transition: {\n duration: 0,\n delay: animation.endscreenCelebration.duration + animation.endscreenBrainpoints.duration + animation.endscreenBrainpoints.delay,\n },\n },\n endscreenAnimationNotActive: {\n opacity: 1,\n transition: {\n ease: 'easeOut',\n duration: 0,\n },\n },\n }\n\n return (\n <motion.div\n layout\n id=\"endscreen-brainpoints-two\"\n key=\"endscreen-brainpoints\"\n variants={endscreenBrainpointsVariants}\n initial={{\n opacity: 0,\n }}\n animate={isEndscreenAnimationActive ? 'standard' : 'endscreenAnimationNotActive'}\n >\n <EndscreenBrainpointsComponent\n collapseBrainpoints={canSeeCollapsedDailyDoseEndscreen}\n />\n </motion.div>\n )\n}\n\nexport default EndscreenBrainpointsTwoComponent\n","import React, { useContext, useEffect, useState } from 'react'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { useHistory } from 'react-router'\nimport translationGroups from 'client/constants/translationGroups'\nimport { StoreState } from 'client/store'\nimport { FinishedPuzzle } from 'client/types/FinishedPuzzle'\nimport ProgressBarComponent from 'common_packages/assets/js/components/ui/progress-bar/ProgressBarComponent'\n\nconst NextQRPuzzleProgressBarComponent = () => {\n const { getRawTranslation } = useContext(TranslationContext)\n const dispatch = useDispatch()\n const history = useHistory()\n const { getTranslation } = useContext(TranslationContext)\n const frameRate = 1000 / 60\n const milliseconds = 15000\n const [progress, setProgress] = useState(0)\n const [countDown, setCountDown] = useState(milliseconds / 100)\n const { qrLocationGuid } = useSelector<StoreState, FinishedPuzzle>((state) => state.puzzleData?.finishedPuzzle) ?? {}\n\n useEffect(() => {\n // this useEffect is only used by the player of the QR host on a QR location\n let intervalId\n if (qrLocationGuid) {\n intervalId = setInterval(() => setProgress((p) => p + (100 / (milliseconds / frameRate))), frameRate)\n }\n return () => clearInterval(intervalId)\n }, [qrLocationGuid, frameRate])\n\n useEffect(() => {\n if (progress > 100) {\n history.replace(`/qrgame/${qrLocationGuid}`)\n }\n setCountDown(Math.ceil((100 - progress) / 100 * (milliseconds / 1000)))\n }, [qrLocationGuid, progress, getTranslation, dispatch, history])\n\n return (\n <div className=\"next-puzzle-progress-bar card\">\n {getRawTranslation(translationGroups.endscreenPage, 'qr-next-game-countdown').replace(/{seconds}/g, String(countDown))}\n <ProgressBarComponent percentage={progress} />\n </div>\n )\n}\n\nexport default NextQRPuzzleProgressBarComponent\n","export const getGiphy = (): string => {\n // Change the numberOfGifs if more gifs are added to img/endscreen/gifs\n const numberOfGifs = 28\n return `/images/endscreen/gifs/celebration${Math.round(Math.random() * (numberOfGifs - 1)) + 1}.gif`\n}\n","import React from 'react'\nimport { getGiphy } from '../../../../../../utilities/getImageUrls'\n\ninterface Props {\n className?: string\n}\n\nconst CelebrationGifComponent = React.memo(({ className = 'endscreen-celebration__gif' }: Props) => (\n <img className={className} src={getGiphy()} alt=\"Klubble endgame animation\" />\n))\n\nexport default CelebrationGifComponent\n","import React, { useContext } from 'react'\nimport { motion } from 'framer-motion'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport ToastComponent from 'client/pages/common/components/toasts/ToastComponent'\nimport useBrainpointBadges from '../../hooks/useBrainpointBadges'\n\nconst EndscreenCelebrationToastsComponent = () => {\n const translation = useContext(TranslationContext)\n\n const brainPointBadgesList = useBrainpointBadges()\n\n const numOfToasts = brainPointBadgesList.length\n\n const duration = 2.5\n\n const toastVariants = {\n animate: (custom) => {\n const offset = Math.min(3 + custom, 6)\n return {\n y: [30, 20, 10, 0, 0, -75].slice(-offset),\n scale: [0.85, 0.9, 0.95, 1, 1, 1].slice(-offset),\n opacity: [0, 0.8, 0.9, 1, 1, 0].slice(-offset),\n transition: { times: [0, 0.2, 0.4, 0.6, 0.8, 1].slice(-offset), duration, delay: custom * (duration / 3.2) },\n }\n },\n }\n\n return (\n <>\n {brainPointBadgesList.map(({ IconComponent, scoreType, score }, i) => (\n <motion.div\n className=\"endscreen-celebration__toast\"\n key={`endscreen-celebration__toast${i + 1}`}\n variants={toastVariants}\n animate=\"animate\"\n custom={i}\n style={{ zIndex: numOfToasts - i }}\n >\n <ToastComponent\n IconComponent={IconComponent}\n message={translation.getTranslation(translationGroups.brainpoints, `type-${scoreType}`)}\n textRight={`+${score}`}\n />\n </motion.div>\n ))}\n </>\n )\n}\n\nexport default EndscreenCelebrationToastsComponent\n","import React, { useContext, useMemo } from 'react'\nimport { motion } from 'framer-motion'\nimport { isMobile } from 'react-device-detect'\nimport CelebrationGifComponent from 'klubble_player/js/components/modals/game_status/endgame_modal/CelebrationGifComponent'\nimport { EndscreenAnimationConfig } from 'client/pages/endscreen/components/types'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport EndscreenCelebrationToastsComponent from './EndscreenCelebrationToastsComponent'\n\ntype Props = {\n animation: EndscreenAnimationConfig\n active: boolean\n}\n\n// Shows a animated gif that will slightly shrink when shown\n// as well as a celebratory text at the top\n// After `endscreenCelebration.duration` time, it will fade out and move up\nconst EndscreenCelebrationComponent = ({ animation, active: isEndscreenAnimationActive }: Props) => {\n const { getRawTranslation } = useContext(TranslationContext)\n\n let className = 'endscreen-celebration'\n\n // Desktop needs absolute positioning because of the scrollbar that is added after going to the endscreen. (second part of animation)\n if (!isMobile) {\n className += ' endscreen-celebration--absolute-positioned'\n }\n\n const endscreenCelebrationVariants = {\n animate: {\n opacity: [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],\n y: [0, 0, 0, 0, 0, -800],\n transition: {\n duration: animation.endscreenCelebration.duration,\n ease: 'easeOut',\n },\n },\n hidden: {\n opacity: 0,\n display: 'none',\n },\n }\n\n const celebrationGifTransition = useMemo(() => {\n return {\n ease: 'easeOut',\n duration: animation.endscreenCelebrationGif.duration,\n delay: animation.endscreenCelebrationGif.delay,\n }\n }, [animation.endscreenCelebrationGif])\n\n return (\n <motion.div\n className={className}\n key=\"endscreen-celebration\"\n variants={endscreenCelebrationVariants}\n animate={isEndscreenAnimationActive ? 'animate' : 'hidden'}\n >\n <div className=\"endscreen-celebration__title\">\n {getRawTranslation(translationGroups.endscreenPage, 'well-done')}\n </div>\n <motion.div\n layout\n key=\"endscreen-celebration-gif\"\n className=\"endscreen-celebration__gif-container\"\n animate={{ scale: [0.7, 1], opacity: [0, 1] }}\n exit={{ x: -100 }}\n transition={celebrationGifTransition}\n >\n <CelebrationGifComponent />\n </motion.div>\n <EndscreenCelebrationToastsComponent />\n </motion.div>\n )\n}\n\nexport default EndscreenCelebrationComponent\n","import React from 'react'\nimport IconClose from 'assets/icons/icon_close-white.svg'\nimport HeartToggleContainer from 'pages/common/containers/HeartToggleContainer'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { FinishedPuzzle } from 'client/types/FinishedPuzzle'\nimport HeartPuzzlePackTypeToggleContainer from 'client/pages/common/containers/HeartPuzzlePackTypeToggleContainer'\n\ntype Props = {\n finishedPuzzle: FinishedPuzzle,\n gotoOverview: () => void,\n puzzlePackTypeId?: number\n}\n\nconst EndscreenTopBarComponent = ({\n finishedPuzzle, gotoOverview, puzzlePackTypeId,\n}: Props) => {\n const abilities = useAbilities()\n const isPuzzlePackPuzzle = !!finishedPuzzle.puzzlePackId\n\n return (\n <div className=\"endscreen-top-bar top-bar\">\n <IconClose className=\"endscreen-top-bar__close\" onClick={gotoOverview} />\n {abilities.canFavoritePuzzles && (\n isPuzzlePackPuzzle ? (\n <HeartPuzzlePackTypeToggleContainer puzzlePackTypeId={puzzlePackTypeId} />\n ) : (\n <HeartToggleContainer puzzleTypeId={finishedPuzzle.puzzleTypeId} />\n )\n )}\n </div>\n )\n}\n\nexport default EndscreenTopBarComponent\n","import React from 'react'\nimport IconCalendar from 'assets/icons/icon_calendar.svg'\n\ntype Props = {\n onClick?: () => void,\n text?: string,\n className?: string\n active?: boolean,\n paused?: boolean,\n}\n\nconst OverviewButtonComponent = ({\n onClick,\n text = '',\n active = true,\n paused = false,\n className: propsClassName = '',\n}: Props) => {\n const className = [\n 'to-calendar-button',\n 'endscreen-header__button-group-button',\n 'endscreen-header__button-group-button--with-icon',\n propsClassName,\n ...(!active ? ['play-button--disabled'] : []),\n ...(paused ? ['play-button--paused'] : []),\n ].join(' ')\n\n return (\n <button\n type=\"button\"\n className={className}\n onClick={() => {\n if (active && onClick) {\n onClick()\n }\n }}\n data-test-id=\"button-to-calendar\"\n >\n <IconCalendar className=\"info-button-icon\" />\n <span>{text}</span>\n </button>\n )\n}\n\nexport default OverviewButtonComponent\n","import React from 'react'\nimport { motion } from 'framer-motion'\n\ntype Props = {\n className?: string\n}\n\nconst EndscreenConfettiComponent = ({ className = 'endscreen-header__confetti' }: Props) => (\n <motion.div\n animate={{ y: [0, -40, 0], scale: [0.3, 1, 1.1], opacity: [1, 1, 0] }}\n transition={{\n repeat: Infinity,\n repeatType: 'loop',\n ease: ['easeOut', 'easeIn'],\n times: [0, 0.3, 1],\n duration: 2,\n }}\n >\n <svg\n className={className}\n width=\"155px\"\n height=\"91px\"\n viewBox=\"0 0 155 91\"\n version=\"1.1\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g id=\"Player\" stroke=\"none\" strokeWidth=\"1\" fill=\"none\" fillRule=\"evenodd\">\n <g id=\"Congrats_Score_iPX_Klb\" transform=\"translate(-113.000000, -80.000000)\">\n <g id=\"Card-/-Summary\" transform=\"translate(20.000000, 80.000000)\">\n <g id=\"Confetti\" transform=\"translate(94.000000, 0.000000)\">\n <path\n className={`${className}-particle`}\n d=\"M15,68 L15,62.9705882 C15,60.7776929 13.2223071,59 11.0294118,59 C8.83651643,59 7.05882353,57.2223071 7.05882353,55.0294118 L7.05882353,54.5 C7.05882353,52.0147186 5.0441049,50 2.55882353,50 L0,50 L0,50\"\n id=\"Path-4\"\n stroke=\"#FFFFFF\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <path\n className={`${className}-particle`}\n d=\"M64,28 L64,24.6470588 C64,23.1851286 62.8148714,22 61.3529412,22 C59.891011,22 58.7058824,20.8148714 58.7058824,19.3529412 L58.7058824,19 C58.7058824,17.3431458 57.3627366,16 55.7058824,16 L54,16 L54,16\"\n id=\"Path-4\"\n stroke=\"#F3F3F3\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n transform=\"translate(59.000000, 22.000000) rotate(10.000000) translate(-59.000000, -22.000000) \"\n />\n <path\n className={`${className}-particle`}\n d=\"M143,87 L143,81.9705882 C143,79.7776929 141.222307,78 139.029412,78 C136.836516,78 135.058824,76.2223071 135.058824,74.0294118 L135.058824,73.5 C135.058824,71.0147186 133.044105,69 130.558824,69 L128,69 L128,69\"\n id=\"Path-4\"\n stroke=\"#FFFFFF\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n transform=\"translate(135.500000, 78.000000) scale(-1, 1) translate(-135.500000, -78.000000) \"\n />\n <path\n className={`${className}-particle`}\n d=\"M138,37 L138,33.6470588 C138,32.1851286 136.814871,31 135.352941,31 C133.891011,31 132.705882,29.8148714 132.705882,28.3529412 L132.705882,28 C132.705882,26.3431458 131.362737,25 129.705882,25 L128,25 L128,25\"\n id=\"Path-4\"\n stroke=\"#F3F3F3\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n transform=\"translate(133.000000, 31.000000) scale(-1, 1) rotate(30.000000) translate(-133.000000, -31.000000) \"\n />\n <circle\n className={`${className}-particle`}\n id=\"Oval\"\n fill=\"#000000\"\n cx=\"5.5\"\n cy=\"26.5\"\n r=\"1.5\"\n />\n <circle className={`${className}-particle`} id=\"Oval\" fill=\"#000000\" cx=\"10\" cy=\"87\" r=\"4\" />\n <circle\n className={`${className}-particle`}\n id=\"Oval-Copy\"\n fill=\"#000000\"\n cx=\"100\"\n cy=\"4\"\n r=\"4\"\n />\n <circle\n className={`${className}-particle`}\n id=\"Oval\"\n fill=\"#000000\"\n cx=\"151\"\n cy=\"47\"\n r=\"3\"\n />\n </g>\n </g>\n </g>\n </g>\n </svg>\n </motion.div>\n)\n\nexport default EndscreenConfettiComponent\n","import React, { useContext } from 'react'\nimport IconPresent from 'assets/icons/icon_present.svg'\nimport ButtonComponent, { Props } from 'common_packages/assets/js/components/ButtonComponent'\nimport { store } from 'client/store'\nimport { getAbilities } from 'client/hooks/useAbilities'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport useShareDialog from 'client/hooks/useShareDialog'\n\nconst EndscreenGiftPuzzleButtonComponent = (props: Props) => {\n const { roles } = store.getState().user\n const { canGiftPuzzle } = getAbilities(roles)\n const { openShareDialog } = useShareDialog()\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const className = `endscreen-header__button-group-button endscreen-header__button-group-button--with-icon gift-button ${props.className ?? ''}`\n\n const handleClick = async () => {\n openShareDialog('gift', getRawTranslation(translationGroups.drawer, 'gift-puzzle'), getRawTranslation(translationGroups.invite, 'gift-puzzle-share-text'))\n }\n\n if (!canGiftPuzzle) return null\n return (\n <ButtonComponent {...props} onClick={handleClick} className={className}>\n <IconPresent className=\"endscreen-header__button-group-button-icon\" />\n <span className=\"endscreen-header__button-group-button-title\">\n {getTranslation(translationGroups.endscreenPage, 'button-send-as-gift')}\n </span>\n </ButtonComponent>\n )\n}\n\nexport default EndscreenGiftPuzzleButtonComponent\n","import React, { useContext } from 'react'\nimport IconShare from 'assets/icons/icon_share.svg'\nimport ButtonComponent, { Props as ButtonProps } from 'common_packages/assets/js/components/ButtonComponent'\nimport useAbilities from 'client/hooks/useAbilities'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport useShareDialog from 'client/hooks/useShareDialog'\n\ntype Props = ButtonProps & {\n shouldShowLabel?: boolean;\n}\n\nconst EndscreenShareResultButtonComponent = (props: Props) => {\n const { canGiftPuzzle } = useAbilities()\n const { openShareDialog, shareResultText } = useShareDialog()\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n\n const className = [\n 'endscreen-header__button-group-button endscreen-header__button-group-button--with-icon share-button',\n props.className,\n ...(props.shouldShowLabel ? ['endscreen-header__button-group-button--with-label'] : []),\n ].join(' ')\n\n const handleClick = async () => {\n openShareDialog('share-result', getRawTranslation(translationGroups.shareResult, 'title'), shareResultText)\n }\n\n if (!canGiftPuzzle) return null\n return (\n <ButtonComponent {...props} onClick={handleClick} type=\"button\" className={className}>\n <IconShare className=\"endscreen-header__button-group-button-icon\" />\n <span className=\"endscreen-header__button-group-button-title\">\n {getTranslation(translationGroups.endscreenPage, 'button-share-result')}\n </span>\n </ButtonComponent>\n )\n}\n\nexport default EndscreenShareResultButtonComponent\n","import React, { useContext } from 'react'\nimport { useDispatch } from 'react-redux'\nimport IconEye from 'assets/icons/icon_eye.svg'\nimport ButtonComponent, { Props } from 'common_packages/assets/js/components/ButtonComponent'\nimport useAbilities from 'client/hooks/useAbilities'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { setDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\n\nconst EndscreenViewPuzzleButtonComponent = (props: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const abilities = useAbilities()\n const className = `endscreen-header__button-group-button endscreen-header__button-group-button--with-icon view-puzzle-button${abilities.hasSubscription ? '' : '--large'} ${props.className ?? ''}`\n const dispatch = useDispatch()\n\n const handleClick = async () => {\n dispatch(setDrawer({\n drawer: drawerTypes.VIEW_PUZZLE,\n }))\n }\n\n return (\n <ButtonComponent\n {...props}\n onClick={handleClick}\n className={className}\n data-test-id=\"view-puzzle\"\n >\n <IconEye className=\"endscreen-header__button-group-button-icon\" />\n <span className=\"endscreen-header__button-group-button-title\">\n {getTranslation(translationGroups.endscreenPage, 'button-view-puzzle')}\n </span>\n </ButtonComponent>\n )\n}\n\nexport default EndscreenViewPuzzleButtonComponent\n","import React, { useContext, useMemo } from 'react'\nimport { useSelector } from 'react-redux'\nimport ViewButtonComponent from 'client/pages/common/components/buttons/ViewButtonComponent'\nimport { StoreState } from 'client/store'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { FinishedPuzzle } from 'client/types/FinishedPuzzle'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport PlayButtonComponent from 'client/pages/common/components/buttons/PlayButtonComponent'\nimport ButtonGroupDaysComponent from 'client/pages/common/components/buttons/ButtonGroupDaysComponent'\nimport CardComponent from 'client/pages/common/components/cards/CardComponent'\nimport ProgressBarComponent from 'common_packages/assets/js/components/ui/progress-bar/ProgressBarComponent'\nimport OverviewButtonComponent from 'client/pages/common/components/buttons/OverviewButtonComponent'\nimport { usePuzzleTypeImageUrls } from 'client/hooks/usePuzzleTypeImageUrls'\nimport EndscreenConfettiComponent from './EndscreenConfettiComponent'\nimport EndscreenGiftPuzzleButtonComponent from './buttons/EndscreenGiftPuzzleButtonComponent'\nimport EndscreenShareResultButtonComponent from './buttons/EndscreenShareResultButtonComponent'\nimport EndscreenViewPuzzleButtonComponent from './buttons/EndscreenViewPuzzleButtonComponent'\n\ntype Props = {\n finishedPuzzle: FinishedPuzzle,\n nextPuzzleUrl: string\n gotoOverview: () => void,\n returnToPuzzlePackType?: string\n}\n\nconst EndscreenHeaderComponent = ({\n finishedPuzzle, nextPuzzleUrl, gotoOverview, returnToPuzzlePackType,\n}: Props) => {\n const { isMultiPlayerQR, nextPuzzle, puzzlePackPercentageProgress } = useSelector<StoreState, FinishedPuzzle>((state) => state.puzzleData?.finishedPuzzle) ?? {}\n const translation = useContext(TranslationContext)\n const abilities = useAbilities()\n const { getIconUrl } = usePuzzleTypeImageUrls()\n const isPuzzlePackPuzzle = !!finishedPuzzle.puzzlePackId\n const canPlayNext = nextPuzzle != null\n\n const recentDays = useMemo(() => {\n if (!abilities.hasSubscription && finishedPuzzle.playerContributions.length === 1) {\n // If you're playing the freebee puzzle, we show it as\n // 'today's puzzle\n return finishedPuzzle.recentDays\n .map((day, index) => (index === 0 ? { ...day, isPlayed: true } : day))\n }\n return finishedPuzzle.recentDays\n }, [abilities.hasSubscription, finishedPuzzle.recentDays, finishedPuzzle.playerContributions])\n\n // If finishPuzzle call tells us there's no next puzzle, we show the view button that shows the overview of the completed calendar / puzzle pack based on the conditions below\n // If the conditions are not met, we show the play next button. This button not always leads to the next puzzle, it can also lead to a overview page, or a join now modal.\n const showViewButtonCompleted = useMemo(() => {\n // Light user who has played the most recent two days\n if (abilities.hasLightSubscriptionOnly && recentDays[0]?.isPlayed && recentDays[1]?.isPlayed) {\n return true\n }\n // Premium user who has played all days\n if (abilities.hasPremiumSubscription && recentDays[0]?.isPlayed && recentDays[1]?.isPlayed && recentDays[2]?.isPlayed) {\n return true\n }\n // Puzzle pack is completed\n if (puzzlePackPercentageProgress === 100) {\n return true\n }\n return false\n }, [abilities.hasLightSubscriptionOnly, abilities.hasPremiumSubscription, recentDays, puzzlePackPercentageProgress])\n\n return (\n <CardComponent>\n <div className={`endscreen-header${isMultiPlayerQR ? ' endscreen-header--multiplayer-qr' : ''}`}>\n <EndscreenConfettiComponent />\n <img\n className=\"endscreen-header__puzzle-icon\"\n src={getIconUrl(finishedPuzzle.nameLangKey)}\n alt=\"puzzle icon\"\n />\n <h1 className=\"endscreen-header__title\">{translation.getTranslation(translationGroups.puzzle, finishedPuzzle.nameLangKey)}</h1>\n <div className=\"endscreen-header__subtitles\">\n <span className=\"endscreen-header__subtitle\">{translation.getTranslation(translationGroups.difficulty, finishedPuzzle.recentDays[0]?.level)}</span>\n <span className=\"endscreen-header__divider\">\n •\n </span>\n <span className=\"endscreen-header__subtitle\">\n {translation.getTranslation(translationGroups.puzzleTags, finishedPuzzle.format)}\n </span>\n </div>\n {!isMultiPlayerQR ? (\n <>\n {finishedPuzzle.puzzlePackPercentageProgress ? (\n <ProgressBarComponent percentage={finishedPuzzle.puzzlePackPercentageProgress} />\n ) : (\n <ButtonGroupDaysComponent\n onClick={gotoOverview}\n recentDays={recentDays}\n />\n\n )}\n <div className=\"endscreen-header__button-group\">\n <EndscreenViewPuzzleButtonComponent />\n <EndscreenShareResultButtonComponent shouldShowLabel={isPuzzlePackPuzzle} />\n {canPlayNext && (\n <OverviewButtonComponent\n className=\"endscreen-header__button-group-button\"\n onClick={gotoOverview}\n text={translation.getTranslation(translationGroups.endscreenPage, 'button-goto-calendar')}\n />\n )}\n {!canPlayNext && showViewButtonCompleted\n ? (\n <span className=\"endscreen-header__button-group-button view-available-puzzles-button\">\n <ViewButtonComponent onClick={gotoOverview}>\n {translation.getTranslation(translationGroups.endscreenPage, returnToPuzzlePackType ? 'button-view-available-puzzle-packs' : 'button-view-available-puzzles')}\n </ViewButtonComponent>\n </span>\n ) : (\n <PlayButtonComponent\n nextPuzzleUrl={nextPuzzleUrl}\n onClick={!nextPuzzleUrl ? gotoOverview : undefined}\n className=\"endscreen-header__button-group-button\"\n text={translation.getTranslation(translationGroups.endscreenPage, 'button-play-next')}\n />\n )}\n {!isPuzzlePackPuzzle && (\n <EndscreenGiftPuzzleButtonComponent />\n )}\n </div>\n\n </>\n ) : (\n <PlayButtonComponent\n onClick={gotoOverview}\n className=\"endscreen-header__continue-playing-button\"\n text={translation.getTranslation(translationGroups.endscreenPage, 'continue-playing')}\n />\n )}\n </div>\n </CardComponent>\n )\n}\n\nexport default EndscreenHeaderComponent\n","import React, { useContext, useEffect, useMemo } from 'react'\n\nimport { StoreState } from 'client/store'\nimport { useDispatch, useSelector } from 'react-redux'\nimport DailyDoseNoScoreComponent from 'client/pages/daily_dose/components/DailyDoseNoScoreComponent'\nimport DailyDoseCirclesContainer from 'client/pages/daily_dose/containers/DailyDoseCirclesContainer'\nimport { getDailyDoseTypes } from 'client/actions/puzzleDataActions'\nimport CardComponent from 'client/pages/common/components/cards/CardComponent'\nimport { DailyDose, DailyDoseType } from 'client/types/DailyDose'\nimport { getHighestDailyDose } from 'client/pages/daily_dose/utilities/dailyDoseComposer'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { useHistory } from 'react-router-dom'\nimport IconCheckmark from 'client/assets/icons/icon_checkmark.svg'\n\ntype Props = {\n delay?: number\n showHeader: boolean\n}\n\nconst EndscreenDailyDoseComponent = ({ delay = 0, showHeader = false }: Props) => {\n const dailyDoseToday = useSelector<StoreState, DailyDose>((state) => state.puzzleData?.dailyDoses?.[state.puzzleData?.dailyDoses.length - 1])\n const dailyDoseTypes = useSelector<StoreState, DailyDoseType[]>((state) => state.puzzleData?.dailyDoseTypes)\n\n const highestDailyDose = useMemo(() => getHighestDailyDose(dailyDoseTypes, dailyDoseToday), [dailyDoseToday, dailyDoseTypes])\n\n const dispatch = useDispatch()\n const { getTranslation } = useContext(TranslationContext)\n const history = useHistory()\n\n useEffect(() => {\n if (!dailyDoseTypes.length) {\n dispatch(getDailyDoseTypes())\n }\n }, [dailyDoseTypes.length, dispatch])\n\n const handleClick = () => {\n history.push('/daily_dose')\n }\n\n return (\n <div className=\"endscreen-daily-dose\" onClick={handleClick} role=\"button\">\n { showHeader && (\n <h2 className=\"section-header\">\n {getTranslation(translationGroups.endscreenPage, 'daily-dose')}\n </h2>\n )}\n {!dailyDoseToday?.numPoints && (\n <DailyDoseNoScoreComponent />\n )}\n <CardComponent>\n <DailyDoseCirclesContainer animateOffset={0} delay={delay} />\n { highestDailyDose && (\n <div className=\"endscreen-daily-dose__current\" key={`${highestDailyDose.nameLangKey}`}>\n <div className={`endscreen-daily-dose__current__icon endscreen-daily-dose__current__icon--${highestDailyDose.cssPostFix}`}>\n { dailyDoseToday?.numPoints >= highestDailyDose.pointsRequired && <IconCheckmark /> }\n </div>\n <span className=\"endscreen-daily-dose__current__description\">\n {getTranslation(translationGroups.dailyDosePage, `dose-${highestDailyDose.nameLangKey}`)}\n </span>\n <span className=\"endscreen-daily-dose__current__right\">\n {highestDailyDose.pointsRequired}\n {' '}\n {getTranslation(translationGroups.dailyDosePage, 'points')}\n </span>\n </div>\n )}\n </CardComponent>\n </div>\n )\n}\n\nexport default EndscreenDailyDoseComponent\n","import React, { useContext } from 'react'\nimport ProgressBarComponent from 'common_packages/assets/js/components/ui/progress-bar/ProgressBarComponent'\nimport PlayerAvatarComponent from 'client/player/js/components/gameroom/PlayerAvatarComponent'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { FinishedPuzzle } from 'client/types/FinishedPuzzle'\nimport { StoreState } from 'client/store'\nimport { useSelector } from 'react-redux'\nimport { Player } from 'client/types/Player'\n\ntype Props = {\n contributions: Player[]\n}\n\nconst EndscreenContributionComponent = ({ contributions }: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const { isMultiPlayerQR } = useSelector<StoreState, FinishedPuzzle>((state) => state.puzzleData?.finishedPuzzle) ?? {}\n\n // if this is a QR game, do not display the host (1st player in the list)\n const filteredContributions = isMultiPlayerQR ? contributions.filter(({ playerNumber }) => playerNumber !== 1) : contributions\n\n return (\n <div className=\"endscreen-contribution\">\n <h2 className=\"section-header\">{getTranslation(translationGroups.endscreenPage, 'contributions')}</h2>\n <ul className=\"card list endscreen-contribution__player-list\">\n {filteredContributions.map(({ playerNumber, displayName, contribution }) => (\n <li key={playerNumber} className=\"list-item\">\n <PlayerAvatarComponent player={{ playerNumber, displayName }} />\n <div className=\"list-item__description\">\n <span>{displayName}</span>\n <ProgressBarComponent percentage={contribution} />\n </div>\n <div className=\"list-item__right\" />\n </li>\n ))}\n </ul>\n </div>\n )\n}\n\nexport default EndscreenContributionComponent\n","import React, { useCallback, useEffect, useMemo } from 'react'\nimport { motion } from 'framer-motion'\nimport { useHistory } from 'react-router'\nimport EndscreenBrainpointsOneComponent from 'pages/endscreen/components/brainpoints/EndscreenBrainpointsOneComponent'\nimport EndscreenBrainpointsTwoComponent from 'pages/endscreen/components/brainpoints/EndscreenBrainpointsTwoComponent'\nimport { EndscreenAnimationConfig } from 'client/pages/endscreen/components/types'\nimport FeedbackCardComponent from 'pages/common/components/FeedbackCardComponent'\nimport RecentPuzzlesComponent from 'client/pages/common/components/RecentPuzzlesComponent'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { type DrawerType, drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { closeDrawer, setDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport { useDispatch, useSelector } from 'react-redux'\nimport { type ContinuePlayingPuzzleType } from 'client/types/ContinuePlayingPuzzleType'\nimport { type FinishedPuzzle } from 'client/types/FinishedPuzzle'\nimport { type StoreState } from 'client/store'\nimport NextQRPuzzleProgressBarComponent from 'client/pages/common/components/bars/NextQRPuzzleProgressBarComponent'\nimport useConfig from 'client/hooks/useConfig'\nimport usePuzzleType from 'client/hooks/usePuzzleType'\nimport { usePuzzlePacks } from 'client/pages/puzzle_packs/hooks/usePuzzlePacks'\nimport getParameterByName from 'common_packages/assets/js/utilities/getParameterByName'\nimport { getPuzzlePacks } from 'client/actions/puzzleDataActions'\nimport { getPlayerPageQueryString, getPuzzlePackPlayerPageQueryString } from 'client/utilities/player'\nimport EndscreenCelebrationComponent from './celebration/EndscreenCelebrationComponent'\nimport EndscreenTopBarComponent from './cards/EndscreenTopBarComponent'\nimport EndscreenHeaderComponent from './cards/EndscreenHeaderComponent'\nimport EndscreenDailyDoseComponent from './cards/EndscreenDailyDoseComponent'\nimport EndscreenContributionComponent from './cards/EndscreenContributionComponent'\n\ntype Props = {\n animation: EndscreenAnimationConfig\n continuePlayingPuzzleTypes: ContinuePlayingPuzzleType[]\n finishedPuzzle: FinishedPuzzle\n getContinuePlayingPuzzleTypes: () => void\n showNav: () => void\n isEndscreenAnimationActive: boolean\n}\n\nconst endscreenVariants = {\n open: { opacity: 1, y: '0%' },\n collapsed: { opacity: 0, y: '10%' },\n}\n\nconst EndscreenComponent = ({\n continuePlayingPuzzleTypes,\n animation,\n finishedPuzzle,\n getContinuePlayingPuzzleTypes,\n showNav,\n isEndscreenAnimationActive,\n}: Props) => {\n const history = useHistory()\n const abilities = useAbilities()\n const { entity } = useConfig()\n const dispatch = useDispatch()\n const puzzleType = usePuzzleType(finishedPuzzle.puzzleTypeId)\n\n const drawer = useSelector<StoreState, DrawerType>((store) => store.ui.drawer)\n const {\n puzzlePackTypes, getPuzzlePackById, showPuzzlePackContents,\n } = usePuzzlePacks()\n const puzzlePackId = finishedPuzzle?.puzzlePackId\n const puzzlePack = getPuzzlePackById(puzzlePackId)\n const puzzlePackTypeName = puzzlePackTypes?.find((p) => p.id === puzzlePack?.puzzlePackTypeId)?.name\n const returnToPuzzlePackType = puzzlePackTypeName || getParameterByName('puzzlePackType')\n const config = useConfig()\n\n // delay and duration of animating content cards\n const { duration } = animation.endscreen\n const delay = animation.endscreenCelebration.duration + animation.endscreen.delayContent\n\n const { isMultiPlayerQR } = finishedPuzzle ?? {}\n\n useEffect(() => {\n showNav()\n }, [showNav])\n\n useEffect(() => {\n // if finished puzzle is a puzzlePackPuzzle, fetch puzzlePacks,\n // since puzzlePacks might be outdated or not fetched at all for an anonymous user that opens a gift link for the first time for example\n const abortController = new AbortController()\n if (puzzlePackId) {\n dispatch(getPuzzlePacks(abortController))\n }\n return () => {\n abortController.abort()\n }\n }, [dispatch, puzzlePackId])\n\n useEffect(() => () => {\n // When the endscreen unmounts (possibly due to browser back button being used) and modal VIEW_PUZZLE is open, close it.\n if (drawer === drawerTypes.VIEW_PUZZLE) {\n dispatch(closeDrawer())\n }\n }, [drawer, dispatch])\n\n const showJoinNowModal = useCallback(() => {\n const contributions = finishedPuzzle?.playerContributions ?? []\n const inviterName = finishedPuzzle?.isMultiPlayerQR ? undefined : contributions.find((player) => player.playerNumber === 1)?.displayName\n const url = entity.publicUrl\n dispatch(setDrawer({\n drawer: drawerTypes.JOIN_NOW,\n drawerData: { inviterName },\n onClose: () => { window.location.href = url },\n forceModal: true,\n modalAutoGrow: true,\n hideHeader: true,\n bleedToEdge: true,\n }))\n }, [dispatch, entity.publicUrl, finishedPuzzle])\n\n const gotoCalendar = useCallback(() => {\n const { puzzleTypeId } = finishedPuzzle\n const lightUserAndPremiumPuzzle = abilities.hasLightSubscriptionOnly && puzzleType.isPremiumOnly\n if (abilities.canPlayDailyPuzzles && !lightUserAndPremiumPuzzle) {\n history.push(`/calendar/${puzzleTypeId}`)\n } else if (abilities.isAnonymous) {\n showJoinNowModal()\n } else {\n history.push('/puzzles')\n }\n }, [abilities, finishedPuzzle, history, showJoinNowModal, puzzleType.isPremiumOnly])\n\n const gotoPuzzlePacks = useCallback(async () => {\n if (puzzlePack) {\n const {\n id, isFree, isPurchased,\n } = puzzlePack\n if (!abilities.isAnonymous && (isFree || isPurchased)) {\n await showPuzzlePackContents(id)\n }\n }\n history.push(`/puzzle-packs/${returnToPuzzlePackType}`)\n }, [history, puzzlePack, returnToPuzzlePackType, showPuzzlePackContents, abilities.isAnonymous])\n\n const nextPuzzleUrl = useMemo(() => {\n if (!finishedPuzzle.nextPuzzle) {\n return undefined\n }\n const puzzlesClientId = config.entity?.puzzlesClientId\n const {\n externalPuzzleId,\n klubblePuzzleId,\n nameLangKey,\n puzzleTypeId,\n } = finishedPuzzle.nextPuzzle\n\n if (puzzlePack) {\n const queryString = getPuzzlePackPlayerPageQueryString(nameLangKey, externalPuzzleId, puzzlesClientId, klubblePuzzleId, puzzleTypeId, puzzlePackId, returnToPuzzlePackType)\n return `/player${queryString}`\n }\n\n const queryString = getPlayerPageQueryString(nameLangKey, externalPuzzleId, puzzlesClientId, klubblePuzzleId, puzzleTypeId)\n return `/player${queryString}`\n }, [config.entity?.puzzlesClientId, finishedPuzzle, puzzlePack, puzzlePackId, returnToPuzzlePackType])\n\n const handleGoToOverview = useCallback(() => {\n if (returnToPuzzlePackType) {\n gotoPuzzlePacks()\n } else {\n gotoCalendar()\n }\n }, [gotoCalendar, gotoPuzzlePacks, returnToPuzzlePackType])\n\n useEffect(() => {\n if (abilities.canSeeRecentPuzzles && !returnToPuzzlePackType) {\n getContinuePlayingPuzzleTypes()\n }\n }, [abilities.canSeeRecentPuzzles, returnToPuzzlePackType, getContinuePlayingPuzzleTypes])\n\n const showRecentPuzzles = abilities.canSeeRecentPuzzles && !isMultiPlayerQR && !returnToPuzzlePackType && continuePlayingPuzzleTypes?.length > 0\n\n return (\n <motion.div\n className=\"endscreen\"\n data-test-id=\"endscreen\"\n key=\"endscreen-wrapper\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ ease: 'easeOut', duration: 1 }}\n >\n <div className=\"squirkles squirkles__top\" />\n <div className=\"squirkles squirkles__bottom\" />\n <div className=\"endscreen-content\">\n <EndscreenCelebrationComponent\n animation={animation}\n active={isEndscreenAnimationActive && !animation.endscreenCelebration.hidden}\n />\n <motion.div\n layout\n key=\"endscreen\"\n initial=\"collapsed\"\n animate=\"open\"\n exit=\"collapsed\"\n variants={endscreenVariants}\n transition={{\n duration,\n delay,\n }}\n >\n {!isMultiPlayerQR && (\n <EndscreenTopBarComponent\n gotoOverview={handleGoToOverview}\n finishedPuzzle={finishedPuzzle}\n puzzlePackTypeId={puzzlePack?.puzzlePackTypeId}\n />\n )}\n {!abilities.isQRHost && (\n <EndscreenHeaderComponent\n nextPuzzleUrl={nextPuzzleUrl}\n gotoOverview={handleGoToOverview}\n finishedPuzzle={finishedPuzzle}\n returnToPuzzlePackType={returnToPuzzlePackType}\n />\n )}\n {!isMultiPlayerQR && (\n <EndscreenBrainpointsTwoComponent animation={animation} isEndscreenAnimationActive={isEndscreenAnimationActive} />\n )}\n {finishedPuzzle?.playerContributions?.length > 1 && (\n <EndscreenContributionComponent contributions={finishedPuzzle.playerContributions} />\n )}\n {abilities.isQRHost && (\n <NextQRPuzzleProgressBarComponent />\n )}\n {abilities.canUseDailyDose && !isMultiPlayerQR && (\n <EndscreenDailyDoseComponent\n // when playing in single-player, header is unnecessary\n showHeader={finishedPuzzle?.playerContributions?.length > 1}\n delay={animation.endscreen.delay}\n />\n )}\n {showRecentPuzzles && (\n <RecentPuzzlesComponent\n puzzleTypes={continuePlayingPuzzleTypes.filter(({ puzzleTypeId }) => puzzleTypeId !== finishedPuzzle.puzzleTypeId)}\n stacked\n fromLocation=\"endscreen\"\n />\n )}\n {abilities.canGiveFeedback && !isMultiPlayerQR && <FeedbackCardComponent />}\n </motion.div>\n { !isMultiPlayerQR && (\n <EndscreenBrainpointsOneComponent animation={animation} active={isEndscreenAnimationActive && !animation.endscreenBrainpoints.hidden} />\n )}\n </div>\n </motion.div>\n )\n}\n\nexport default EndscreenComponent\n","import { connect } from 'react-redux'\nimport { setShowNav } from 'common_packages/assets/js/actions/uiActions'\nimport { StoreState } from 'client/store'\nimport { getContinuePlayingPuzzleTypes } from '../../../actions/puzzleDataActions'\nimport EndscreenComponent from '../components/EndscreenComponent'\n\nconst mapStateToProps = (state: StoreState) => ({\n puzzleTypes: state?.puzzleData?.puzzleTypes,\n continuePlayingPuzzleTypes: state?.puzzleData?.continuePlayingPuzzleTypes,\n finishedPuzzle: state?.puzzleData?.finishedPuzzle,\n})\n\nconst mapDispatchToProps = (dispatch: any) => ({\n getContinuePlayingPuzzleTypes: () => {\n dispatch(getContinuePlayingPuzzleTypes())\n },\n showNav: () => {\n dispatch(setShowNav(true))\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(EndscreenComponent)\n","import React, {\n ReactNode,\n useEffect,\n useMemo,\n useState,\n} from 'react'\nimport { DrawerType, drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { useSelector } from 'react-redux'\nimport { StoreState } from 'client/store'\nimport { AnimateSharedLayout, motion } from 'framer-motion'\nimport EndscreenCheckmarkComponent from 'pages/endscreen/components/EndscreenCheckmarkComponent'\nimport { EndscreenAnimationConfig } from 'client/pages/endscreen/components/types'\nimport useBrainpointBadges from 'client/pages/endscreen/hooks/useBrainpointBadges'\nimport EndscreenContainer from '../../endscreen/containers/EndscreenContainer'\n\n/**\n * 1. After `checkmark.delay` time a checkmark appears, sliding in from the bottom and growing in size. This animation takes `checkmark.duration` time.\n * 2. After the end of this checkmark animation + `endscreen.delay` time (which can be negative to have the animations overlap) the endscreen orange\n * background appears, fading in over `endscreen.duration` time. Most of the content is not shown yet, however.\n * 3. The celebration appears, showing a a celebratory text at the top and an animated gif. this celebration will slide out to the top over\n * `endscreenCelebration.duration` time.\n * 4. After `endscreenCelebrationGif.delay` an animated gif is shown on the celebration component, becoming visible over `endscreenCelebrationGif.duration` time.\n * 5. The actual content of the endscreen (header, brainpoints summary, daily dose, recently played etc) is shown after\n * `endscreenCelebration.duration` + `endscreen.delayContent` time.\n * 6. BrainpointsOne is shown with a fixed position to the bottom of the screen. It animates to the correct posisition after `endscreenBrainpoints.delay`\n * over `endscreenBrainpoints.duration` time.\n * 7. After this time, BrainpointsOne is hidden and BrainpointsTwo takes its place. This component can be interacted with by the user.\n */\n\ntype Props = { children: ReactNode }\n\nconst toastDuration = 1\nconst PlayerEndscreenAnimationComponent = ({\n children,\n}: Props) => {\n const drawer = useSelector<StoreState, DrawerType>((state) => state.ui.drawer)\n const skipCelebration = useSelector<StoreState, boolean>((state) => state.settings.skipCelebration)\n const showEndscreen = useSelector<StoreState, boolean>((store) => store.ui.showEndscreen)\n const numScoringBadges = useBrainpointBadges().length\n\n const animation: EndscreenAnimationConfig = useMemo(() => {\n const config = {\n checkmark: {\n delay: 0,\n duration: 2.5,\n },\n endscreen: {\n delay: -0.5, // start during checkmark animation\n duration: 1,\n delayContent: -0.75, // start during celebration phase\n },\n endscreenCelebration: {\n duration: skipCelebration ? 0 : 2 + numScoringBadges * toastDuration,\n hidden: skipCelebration,\n },\n endscreenCelebrationGif: {\n delay: 0.1,\n duration: 1,\n },\n endscreenBrainpoints: {\n duration: skipCelebration ? 0 : 1,\n delay: -0.5, // start animating up during celebration phase\n hidden: skipCelebration,\n },\n }\n\n return config\n }, [numScoringBadges, skipCelebration])\n\n const [endscreenActive, setEndscreenActive] = useState(false)\n const [isEndscreenAnimationActive, setIsEndscreenAnimationActive] = useState(true)\n\n useEffect(() => {\n let timeoutEndscreen: NodeJS.Timeout\n if (showEndscreen) {\n timeoutEndscreen = setTimeout(() => {\n setEndscreenActive(true)\n }, (animation.checkmark.delay + animation.checkmark.duration + animation.endscreen.delay) * 1000)\n }\n\n return () => {\n clearTimeout(timeoutEndscreen)\n }\n }, [animation, showEndscreen])\n const isViewingPuzzle = drawer === drawerTypes.VIEW_PUZZLE\n\n useEffect(() => {\n let timeout: NodeJS.Timeout\n if (showEndscreen) {\n const scrollbarWidth = `${window.innerWidth - document.body.clientWidth}px`\n document.body.style.overflowY = 'hidden'\n document.body.style.paddingRight = scrollbarWidth\n\n if (!isEndscreenAnimationActive && !isViewingPuzzle) {\n document.body.style.overflowY = 'scroll'\n document.body.style.paddingRight = '0'\n } else {\n timeout = setTimeout(() => {\n if (!isViewingPuzzle) {\n document.body.style.overflowY = 'scroll'\n document.body.style.paddingRight = '0'\n setIsEndscreenAnimationActive(false)\n }\n }, (animation.checkmark.delay + animation.checkmark.duration + animation.endscreenCelebration.duration + animation.endscreenCelebrationGif.delay) * 1000)\n }\n }\n\n return () => {\n document.body.style.overflowY = 'scroll'\n document.body.style.paddingRight = '0'\n clearTimeout(timeout)\n }\n }, [animation, isEndscreenAnimationActive, isViewingPuzzle, showEndscreen])\n\n // If the tab is blurred then we disable the endscreen animation, if the window is focused again we enable this animation\n // unless if the endscreen animation is currently playing,\n // because otherwise the animation would collide with the endscreen (see ticket DD-1960)\n useEffect(() => {\n const onWindowBlur = () => {\n setIsEndscreenAnimationActive(false)\n }\n const onWindowFocus = () => {\n if (!endscreenActive) {\n setIsEndscreenAnimationActive(true)\n }\n }\n window.addEventListener('blur', onWindowBlur)\n window.addEventListener('focus', onWindowFocus)\n\n return () => {\n window.removeEventListener('blur', onWindowBlur)\n window.removeEventListener('focus', onWindowFocus)\n }\n }, [endscreenActive, setIsEndscreenAnimationActive])\n\n return (\n <>\n <AnimateSharedLayout>\n {/* Endscreen */}\n {endscreenActive && <EndscreenContainer animation={animation} isEndscreenAnimationActive={isEndscreenAnimationActive} />}\n\n {/* Player as children */}\n {!endscreenActive && (\n <motion.div layout className=\"player-motion-wrapper\" key=\"children\" transition={{ ease: 'easeIn' }}>\n {children}\n </motion.div>\n )}\n </AnimateSharedLayout>\n\n {/* Checkmark animation */}\n {showEndscreen && !isViewingPuzzle && <EndscreenCheckmarkComponent animation={animation} isEndscreenAnimationActive={isEndscreenAnimationActive} />}\n </>\n )\n}\n\nexport default PlayerEndscreenAnimationComponent\n","import React from 'react'\nimport { Redirect } from 'react-router'\nimport getIdentifiers from 'common_packages/assets/js/utilities/getIdentifiers'\nimport PlayerComponent2 from '../../../player/js/components/PlayerComponent'\nimport PlayerEndscreenAnimationComponent from './PlayerEndscreenAnimationComponent'\n\nconst PlayerComponent = () => {\n if (!getIdentifiers().gameType) {\n return <Redirect to=\"/\" />\n }\n return (\n <PlayerEndscreenAnimationComponent>\n <PlayerComponent2 />\n </PlayerEndscreenAnimationComponent>\n )\n}\n\nexport default PlayerComponent\n","import React from 'react'\nimport AnimatedBackgroundSquircle from 'client/pages/common/components/AnimatedBackgroundSquircle'\nimport { isMobile } from 'react-device-detect'\n\nconst SectionBackgroundComponent = () => {\n return (\n <>\n {isMobile\n ? (\n <>\n <AnimatedBackgroundSquircle size={200} borderOnly border={5} borderRadius={5} top={-30} left={-50} color=\"var(--tertiary-color)\" gravity={0} />\n <AnimatedBackgroundSquircle size={40} top={-80} left={-20} color=\"var(--tertiary-color)\" gravity={0} borderRadius={20} />\n <AnimatedBackgroundSquircle size={300} borderOnly top={-40} left={600} color=\"var(--tertiary-color)\" gravity={0} borderRadius={5} border={5} />\n </>\n ) : (\n <AnimatedBackgroundSquircle size={300} borderOnly top={-50} left={900} color=\"var(--tertiary-color)\" gravity={0} borderRadius={5} border={5} />\n )}\n <div className=\"section-background__clipped\">\n <AnimatedBackgroundSquircle size={110} top={180} left={-100} opacity={0.65} color=\"#FFFFFF\" gravity={0.4} borderRadius={25} />\n <AnimatedBackgroundSquircle size={185} top={150} left={1055} borderOnly opacity={0.7} color=\"#FFFFFF\" gravity={0.1} borderRadius={10} border={6} />\n <AnimatedBackgroundSquircle size={175} top={340} left={1050} opacity={0.55} color=\"#FFFFFF\" gravity={0.3} borderRadius={15} />\n <svg xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <clipPath id=\"clip-path\" clipPathUnits=\"objectBoundingBox\">\n <path\n transform=\"scale(0.001078748651564, 0.001742160278746)\"\n d=\"M 1472 0 L 0 0 V 797.603 H 1472 V 0 Z\"\n />\n </clipPath>\n </defs>\n </svg>\n </div>\n </>\n )\n}\n\nexport default SectionBackgroundComponent\n","import React, {\n useContext,\n useMemo,\n} from 'react'\nimport { useDispatch } from 'react-redux'\nimport { useHistory } from 'react-router'\nimport IconChevronBack from 'assets/icons/icon_chevron_back.svg'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport formatLabel from 'client/utilities/formatLabel'\nimport transformGameNameForTranslation from 'common_packages/assets/js/utilities/gameNameTransformer'\nimport HeartPuzzlePackTypeToggleContainer from 'client/pages/common/containers/HeartPuzzlePackTypeToggleContainer'\nimport { type PuzzlePackType } from 'client/types/PuzzlePackType'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { PageHeaderBackgroundMobileComponent } from 'client/pages/common/components/page_header/PageHeaderBackgroundMobileComponent'\nimport { PageHeaderBackgroundDesktopComponent } from 'client/pages/common/components/page_header/PageHeaderBackgroundDesktopComponent'\nimport IconChevronDown from 'assets/icons/icon_chevron_down.svg'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { type DrawerType, drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { usePuzzlePacks } from '../hooks/usePuzzlePacks'\n\ntype Props = {\n puzzlePackType: PuzzlePackType\n}\n\nconst PuzzlePackTypeHeaderComponent = ({ puzzlePackType }: Props) => {\n const translation = useContext(TranslationContext)\n const history = useHistory()\n const { canFavoritePuzzles } = useAbilities()\n const {\n id,\n name,\n isFavorite,\n formats,\n } = puzzlePackType\n const dispatch = useDispatch()\n const { getSelectedLevelForPuzzlePackType, getAvailableLevelsWithinPuzzlePackType } = usePuzzlePacks()\n const availableLevels = getAvailableLevelsWithinPuzzlePackType(id)\n const selectedLevel = getSelectedLevelForPuzzlePackType(id)\n\n const goBack = () => {\n history.push('/puzzle-packs')\n }\n\n const title = useMemo(() => {\n const text = translation.getRawTranslation(translationGroups.puzzle, transformGameNameForTranslation(name))\n return formatLabel(text, '®', 'puzzle-pack-type-header__title--superscript')\n }, [name, translation])\n\n const handleClickLevelSelector = (e) => {\n e.stopPropagation()\n dispatch(uiActions.setDrawer({ drawer: drawerTypes.PUZZLE_PACK_TYPE_LEVEL as DrawerType, drawerData: { id }, forceModal: true }))\n }\n\n return (\n <div className=\"puzzle-pack-type-header\">\n <div className=\"puzzle-pack-type-header__background\">\n <PageHeaderBackgroundMobileComponent />\n <PageHeaderBackgroundDesktopComponent />\n </div>\n <div className=\"puzzle-pack-type-header__content\">\n <div className=\"puzzle-pack-type-header__top-bar\">\n <IconChevronBack className=\"puzzle-pack-type-header__back\" onClick={goBack} />\n {canFavoritePuzzles && (\n <HeartPuzzlePackTypeToggleContainer\n className={`puzzle-pack-type-header__heart${isFavorite ? ' puzzle-pack-type-header__heart--favorited' : ''}`}\n puzzlePackTypeId={id}\n >\n <span className=\"puzzle-pack-type-header__heart-text\">\n {translation.getTranslation(translationGroups.calendarPage, isFavorite ? 'favorite-active' : 'favorite')}\n </span>\n </HeartPuzzlePackTypeToggleContainer>\n )}\n </div>\n\n <h1 className=\"puzzle-pack-type-header__title\">\n {title}\n </h1>\n <h3 className=\"puzzle-pack-type-header__subtitle\">\n {formats.map((tag) => translation.getTranslation(translationGroups.puzzleTags, tag)).join(' • ')}\n </h3>\n <button type=\"button\" className=\"calendar-header__level-selector\" onClick={handleClickLevelSelector}>\n {translation.getTranslation(translationGroups.drawer, 'puzzle-calendar-level')}\n :\n {' '}\n <span className=\"calendar-header__level-selected\">\n {translation.getTranslation(translationGroups.difficulty, selectedLevel)}\n </span>\n {availableLevels.length > 1 && (<IconChevronDown className=\"calendar-header__level-icon\" />)}\n </button>\n </div>\n </div>\n )\n}\n\nexport default PuzzlePackTypeHeaderComponent\n","import React, { useContext } from 'react'\nimport PillComponent from 'common_packages/assets/js/components/ui/pill/PillComponent'\nimport { translationGroups } from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\n\ntype Props = {\n nameLangKey: string,\n url:string\n}\n\nconst TryOutPuzzleTypeCardComponent = ({\n nameLangKey, url,\n}: Props) => {\n const { getRawTranslation } = useContext(TranslationContext)\n\n return (\n <a href={url} className=\"try-out-puzzle-type-card\">\n <h3 className=\"try-out-puzzle-type-card__title\">\n {getRawTranslation(translationGroups.puzzlePackTypePage, 'new-to-this-puzzle-type').replace('{puzzleType}', getRawTranslation(translationGroups.puzzle, nameLangKey))}\n </h3>\n <div className=\"try-out-puzzle-type-card__pill-container\">\n <PillComponent type=\"warning\" className=\"try-out-puzzle-type-card__pill\">\n {getRawTranslation(translationGroups.puzzlePackTypePage, 'try-out-puzzle-type').replace('{puzzleType}', getRawTranslation(translationGroups.puzzle, nameLangKey))}\n </PillComponent>\n </div>\n </a>\n )\n}\n\nexport default TryOutPuzzleTypeCardComponent\n","import React, { useContext, useMemo } from 'react'\nimport { useHistory, useParams } from 'react-router'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport GameCardRowPuzzlePacksComponent from 'client/pages/common/components/game_cards/GameCardRowPuzzlePacksComponent'\nimport Breadcrumbs from 'client/pages/common/components/breadcrumbs/BreadcrumbsComponent'\nimport translationGroups from 'client/constants/translationGroups'\nimport useWindowDimensions from 'common_packages/assets/js/hooks/useWindowDimensions'\nimport breakpoints from 'common_packages/assets/js/constants/breakpoints'\nimport SectionBackgroundComponent from 'client/pages/common/components/SectionBackgroundComponent'\nimport PuzzlePackTypeHeaderComponent from './PuzzlePackTypeHeaderComponent'\nimport { usePuzzlePackAuthentication } from '../hooks/usePuzzlePackAuthentication'\nimport { usePuzzlePacks } from '../hooks/usePuzzlePacks'\nimport { useShowPuzzlePackContents } from '../hooks/useShowPuzzlePackContents'\nimport TryOutPuzzleTypeCardComponent from './TryOutPuzzleTypeCardComponent'\n\nconst PuzzlePackTypeComponent = () => {\n const { getTranslation } = useContext(TranslationContext)\n const history = useHistory()\n const params = useParams<{name: string, id: string}>()\n const {\n puzzlePacks, getPuzzlePackTypeByName, getPuzzlePacksWithinPuzzlePackType, getSelectedLevelForPuzzlePackType,\n } = usePuzzlePacks()\n const puzzlePackType = getPuzzlePackTypeByName(params.name)\n const selectedLevel = getSelectedLevelForPuzzlePackType(puzzlePackType?.id)\n const puzzlePacksForTypeUnsorted = getPuzzlePacksWithinPuzzlePackType(puzzlePackType?.id)?.filter((puzzlePack) => selectedLevel === puzzlePack.levels[0].toLocaleLowerCase())\n\n const { width } = useWindowDimensions()\n usePuzzlePackAuthentication()\n useShowPuzzlePackContents()\n\n const playablePacks = useMemo(() => {\n return puzzlePacksForTypeUnsorted\n .filter(({ isPurchased, isFree, isCompleted }) => (isPurchased || isFree) && !isCompleted)\n .sort((a, b) => new Date(b.publishDate).getTime() - new Date(a.publishDate).getTime())\n .sort((a, b) => (b.isNew ? 1 : 0) - (a.isNew ? 1 : 0))\n .sort((a, b) => (new Date(b.lastPlayed ?? 0).getTime() - (new Date(a.lastPlayed ?? 0).getTime())))\n }, [puzzlePacksForTypeUnsorted])\n\n const unPurchasedPacks = useMemo(() => {\n return puzzlePacksForTypeUnsorted\n .filter(({ isPurchased, isFree }) => !isPurchased && !isFree)\n .sort((a, b) => new Date(b.publishDate).getTime() - new Date(a.publishDate).getTime())\n .sort((a, b) => (b.isNew ? 1 : 0) - (a.isNew ? 1 : 0))\n }, [puzzlePacksForTypeUnsorted])\n\n const completedPacks = useMemo(() => {\n return puzzlePacksForTypeUnsorted\n .filter(({ isCompleted }) => isCompleted)\n }, [puzzlePacksForTypeUnsorted])\n\n const showPerRow = useMemo(() => {\n if (width < breakpoints.MEDIUM) {\n return 0\n }\n if (width < breakpoints.LARGE) {\n return 4\n }\n return 5\n }, [width])\n\n if (!puzzlePackType) {\n if (puzzlePacks.length > 0) {\n // Puzzle packs have been fetched, but the requested puzzle pack type does not exist\n history.push('/puzzle-packs')\n }\n // Still in the process of logging in and fetching the puzzle packs\n return null\n }\n\n const { puzzleTypeName, freeBeeUrl } = puzzlePackType.puzzleTypeFreeBeeUrls?.[0] || {}\n\n return (\n <>\n <PuzzlePackTypeHeaderComponent puzzlePackType={puzzlePackType} />\n <Breadcrumbs />\n <div className=\"puzzle-list__wrapper\">\n <div className=\"puzzle-list\">\n <div className=\"container\">\n {freeBeeUrl && (<TryOutPuzzleTypeCardComponent nameLangKey={puzzleTypeName} url={`${freeBeeUrl}?puzzlePackType=${puzzlePackType.name}`} />)}\n {playablePacks.length > 0 && (\n <GameCardRowPuzzlePacksComponent puzzlePacks={playablePacks} showPerRow={showPerRow} showProgress>\n {getTranslation(translationGroups.puzzlePackTypePage, 'continue-section-title')}\n </GameCardRowPuzzlePacksComponent>\n )}\n </div>\n {unPurchasedPacks.length > 0 && (\n <div className=\"container\">\n <GameCardRowPuzzlePacksComponent puzzlePacks={unPurchasedPacks} showPerRow={showPerRow}>\n {getTranslation(translationGroups.puzzlePackTypePage, 'buy-section-title')}\n </GameCardRowPuzzlePacksComponent>\n </div>\n )}\n {completedPacks.length > 0 && (\n <div className=\"section__completed-packs\">\n <SectionBackgroundComponent />\n <div className=\"container\">\n <GameCardRowPuzzlePacksComponent puzzlePacks={completedPacks} showPerRow={showPerRow}>\n {getTranslation(translationGroups.puzzlePackTypePage, 'completed-section-title')}\n </GameCardRowPuzzlePacksComponent>\n </div>\n </div>\n )}\n </div>\n </div>\n </>\n )\n}\n\nexport default PuzzlePackTypeComponent\n","import { useMemo, useEffect } from 'react'\nimport { useLocation } from 'react-router'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { usePuzzlePacks } from './usePuzzlePacks'\n\ntype LocationState = {\n puzzlePackId?: number\n}\n\nexport const useShowPuzzlePackContents = () => {\n const location = useLocation() as { state: LocationState }\n const { showPuzzlePackContents } = usePuzzlePacks()\n const abilities = useAbilities()\n\n const puzzlePackId = useMemo(() => {\n if (location.state?.puzzlePackId) {\n return location.state.puzzlePackId ?? 0\n }\n return +localStorage.getItem('puzzle-pack-id')\n }, [location.state?.puzzlePackId])\n\n useEffect(() => {\n if (!abilities.isAnonymous && puzzlePackId) {\n showPuzzlePackContents(puzzlePackId)\n }\n\n localStorage.removeItem('puzzle-pack-id') // in case we didn't pass paymentSuccess\n }, [puzzlePackId, showPuzzlePackContents, abilities.isAnonymous])\n}\n","import { connect } from 'react-redux'\nimport { type PuzzleFilter1 } from 'client/constants/puzzleFilters1'\nimport { type PuzzleFilterAction } from 'client/actions/types'\nimport { type TDispatch } from 'common_packages/assets/js/types/TDispatch'\nimport { type StoreState } from 'client/store'\nimport PuzzleFilter1Component from '../../puzzles/components/PuzzleFilter1Component'\nimport { setPuzzlePackTypeFilter } from '../../../actions/puzzleFilterActions'\n\nconst mapStateToProps = (state: StoreState) => ({\n filter1: state.puzzleFilter.puzzlePackTypeFilter1,\n})\n\nconst mapDispatchToProps = (dispatch: TDispatch<PuzzleFilterAction>) => ({\n selectPuzzleFilter: (filter:PuzzleFilter1) => {\n dispatch(setPuzzlePackTypeFilter({\n puzzlePackTypeFilter1: filter,\n }))\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(PuzzleFilter1Component)\n","import React from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport {\n RECENT,\n type PuzzleFilter2,\n} from 'client/constants/puzzleFilters2'\nimport useConfig from 'client/hooks/useConfig'\nimport { type StoreState } from 'client/store'\nimport { setPuzzlePackTypeFilter } from 'client/actions/puzzleFilterActions'\nimport PuzzleFilter2Component from 'client/pages/puzzles/components/PuzzleFilter2Component'\nimport { CLASSIC, MINI } from 'client/constants/puzzleFormat'\n\nconst PuzzleFilter2Container = () => {\n const dispatch = useDispatch()\n const filter2 = useSelector<StoreState, PuzzleFilter2>((state) => state.puzzleFilter.puzzlePackTypeFilter2)\n const { entity } = useConfig()\n const { tags } = entity\n\n const textButtons = [\n CLASSIC,\n MINI,\n ...tags.map((tag) => tag.tagLangKey),\n RECENT,\n ]\n\n const selectPuzzleFilter = (filter: PuzzleFilter2) => {\n dispatch(setPuzzlePackTypeFilter({\n puzzlePackTypeFilter2: filter,\n }))\n }\n\n return (\n <PuzzleFilter2Component\n filter2={filter2}\n textButtons={textButtons}\n selectPuzzleFilter={selectPuzzleFilter}\n />\n )\n}\n\nexport default PuzzleFilter2Container\n","import React, { PropsWithChildren, ReactNode, useContext } from 'react'\nimport { Link } from 'react-router-dom'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport transformGameNameForTranslation from 'common_packages/assets/js/utilities/gameNameTransformer'\nimport { getPuzzlePackTypeColor } from 'client/utilities/getPuzzlePackTypeColor'\nimport { usePuzzleTypeImageUrls } from 'client/hooks/usePuzzleTypeImageUrls'\nimport PuzzlePackIcons from './PuzzlePackIcons'\n\ntype Props = {\n name: string\n puzzlePackTypeId: number\n subtitle?: ReactNode\n isStackedOnMobileView?: boolean\n showFavoriteToggle?: boolean\n}\n\n/*\n* The puzzlePackCard component with an optional icon or new button\n* */\nconst PuzzlePackTypeCardComponent = ({\n name,\n puzzlePackTypeId,\n subtitle,\n isStackedOnMobileView = false,\n showFavoriteToggle = false,\n children,\n}: PropsWithChildren<Props>) => {\n const { getTranslation } = useContext(TranslationContext)\n const { getIconUrl } = usePuzzleTypeImageUrls()\n\n const cardClassName = [\n `game-card puzzle-pack-type-card puzzle-pack-card puzzle-pack-card--${getPuzzlePackTypeColor(name)}`,\n ...(isStackedOnMobileView ? ['game-card--stacked-on-mobile-view'] : []),\n ].join(' ')\n const iconUrlIds = [0, 0, 0]\n const iconUrls = iconUrlIds.map(() => getIconUrl(transformGameNameForTranslation(name)))\n\n return (\n <Link\n to={{ pathname: `/puzzle-packs/${name.toLowerCase()}` }}\n className={cardClassName}\n data-test-id={`puzzle-pack-type-card-${name.toLowerCase()}`}\n >\n <div className=\"game-card__image\">\n <PuzzlePackIcons\n className=\"game-card__puzzle-icon\"\n puzzlePackTypeId={puzzlePackTypeId}\n showFavoriteToggle={showFavoriteToggle}\n iconUrls={iconUrls}\n />\n </div>\n <div className=\"game-card__body\">\n <h3 className=\"game-card__title\">{getTranslation(translationGroups.puzzlePack, name)}</h3>\n <span className=\"game-card__subtitle\">{subtitle}</span>\n {children}\n </div>\n </Link>\n )\n}\n\nexport default PuzzlePackTypeCardComponent\n","import React, {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport PuzzlePackTypeCardComponent from 'client/pages/common/components/puzzle_packs/PuzzlePackTypeCardComponent'\nimport { useSelector } from 'react-redux'\nimport { type StoreState } from 'client/store'\nimport { type PuzzlePackType } from 'client/types/PuzzlePackType'\nimport { type PuzzleFilterState } from 'client/reducers/puzzleFilterReducer'\nimport {\n RECENT,\n FAVORITE,\n} from 'client/constants/puzzleFilters2'\nimport HeartPuzzlePackTypeToggleContainer from 'client/pages/common/containers/HeartPuzzlePackTypeToggleContainer'\nimport { type ApiResult, klubbleAPI } from 'client/api/common'\nimport { type UserData } from 'client/reducers/userReducer'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport { type PuzzlePack } from 'client/types/PuzzlePack'\nimport { CLASSIC, MINI } from 'client/constants/puzzleFormat'\nimport { all } from 'client/constants/puzzleFilters1'\nimport { usePuzzlePacks } from '../hooks/usePuzzlePacks'\n\nconst PuzzlePackTypesDisplayComponent = () => {\n const { getTranslation, getRawTranslation } = useContext(TranslationContext)\n const { puzzlePackTypes, getPuzzlePacksWithinPuzzlePackType } = usePuzzlePacks()\n const { puzzlePackTypeFilter1 = all, puzzlePackTypeFilter2 } = useSelector<StoreState, PuzzleFilterState>((state) => state.puzzleFilter)\n const [recentPuzzlePackTypes, setRecentPuzzlePackTypes] = useState<PuzzlePackType[]>()\n const user = useSelector<StoreState, UserData>((state: StoreState) => state.user?.data)\n const throwError = useAsyncError()\n\n useEffect(() => {\n const abortController = new AbortController()\n\n async function fetchRecentPuzzlePacks() {\n try {\n const res = await klubbleAPI.get<ApiResult<[PuzzlePackType]>>('Puzzle/packs/recent', {\n signal: abortController?.signal,\n })\n if (res?.status === 200) {\n setRecentPuzzlePackTypes(res.data.data)\n } else {\n throw new Error(`${res.config.url} did not return succesfully`)\n }\n } catch (e) {\n throwError(e, 'Error fetching puzzle pack info')\n }\n }\n\n if (user) {\n fetchRecentPuzzlePacks()\n }\n return () => {\n abortController.abort()\n }\n }, [throwError, user])\n\n const matchesFilter1 = useCallback((packs: PuzzlePack[]) => {\n if (puzzlePackTypeFilter1 === 'all') {\n return true\n }\n return packs.some((pack) => (pack.mainTypes.includes(puzzlePackTypeFilter1)))\n }, [puzzlePackTypeFilter1])\n\n const matchesFilter2 = useCallback((puzzlePackType: PuzzlePackType, packs: PuzzlePack[]) => {\n switch (puzzlePackTypeFilter2) {\n case undefined:\n case '':\n // No filter2 set!\n return true\n case CLASSIC:\n return packs.some((pack) => (pack.formats.includes(CLASSIC)))\n case MINI:\n return packs.some((pack) => (pack.formats.includes(MINI)))\n case RECENT:\n return recentPuzzlePackTypes?.filter((rP) => rP.id === puzzlePackType.id)?.length > 0\n case FAVORITE:\n return puzzlePackType.isFavorite\n default:\n // A tag, configured in the admin\n return packs.some((pack) => (pack.tags.includes(puzzlePackTypeFilter2)))\n }\n }, [puzzlePackTypeFilter2, recentPuzzlePackTypes])\n\n const sortedPuzzlePacksTypes = useMemo(() => {\n if (!puzzlePackTypes) return []\n\n const selectByFilters = (puzzlePackType: PuzzlePackType) => {\n const packsWithinType = getPuzzlePacksWithinPuzzlePackType(puzzlePackType.id)\n\n return matchesFilter1(packsWithinType) && matchesFilter2(puzzlePackType, packsWithinType)\n }\n\n return puzzlePackTypes\n .filter(selectByFilters)\n .sort((a, b) => getRawTranslation(translationGroups.puzzlePack, a.name).localeCompare(getRawTranslation(translationGroups.puzzlePack, b.name)) || b.name.localeCompare(a.name))\n }, [puzzlePackTypes, getPuzzlePacksWithinPuzzlePackType, matchesFilter1, matchesFilter2, getRawTranslation])\n\n return (\n <div className=\"container\">\n <div className=\"puzzle-list__wrapper\">\n {(puzzlePackTypeFilter2 === FAVORITE && sortedPuzzlePacksTypes.length === 0) && (\n <div className=\"puzzle-list__empty\">\n {getTranslation(translationGroups.puzzlePackTypesPage, 'no-favorites-yet')}\n </div>\n )}\n {(puzzlePackTypeFilter2 === RECENT && sortedPuzzlePacksTypes.length === 0) && (\n <div className=\"puzzle-list__empty\">\n {getTranslation(translationGroups.puzzlePackTypesPage, 'no-recents-yet')}\n </div>\n )}\n <div className=\"puzzle-list\">\n {sortedPuzzlePacksTypes.map((puzzlePackType: PuzzlePackType) => {\n return (\n <PuzzlePackTypeCardComponent\n puzzlePackTypeId={puzzlePackType.id}\n key={puzzlePackType.id}\n subtitle={(\n <span>\n {getTranslation(translationGroups.puzzleTags, puzzlePackType.largestFormat)}\n </span>\n )}\n name={puzzlePackType.name}\n isStackedOnMobileView\n showFavoriteToggle\n >\n <div className=\"game-card__right\">\n <HeartPuzzlePackTypeToggleContainer isStacked puzzlePackTypeId={puzzlePackType.id} />\n </div>\n </PuzzlePackTypeCardComponent>\n )\n })}\n </div>\n </div>\n </div>\n )\n}\n\nexport default PuzzlePackTypesDisplayComponent\n","import React, { useContext } from 'react'\nimport PageHeaderComponent from 'client/pages/common/components/page_header/PageHeaderComponent'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport HeaderTitleBarComponent from '../../common/components/HeaderTitleBarComponent'\nimport PuzzlePackTypeFilter1Container from '../containers/PuzzlePackTypeFilter1Container'\nimport PuzzlePackTypeFilter2Container from '../containers/PuzzlePackTypeFilter2Container'\nimport PuzzlePackTypesDisplayComponent from './PuzzlePackTypesDisplayComponent'\nimport { usePuzzlePackAuthentication } from '../hooks/usePuzzlePackAuthentication'\n\nconst PuzzlePackTypesComponent = () => {\n const translation = useContext(TranslationContext)\n usePuzzlePackAuthentication()\n\n return (\n <>\n <PageHeaderComponent translationGroup={translationGroups.puzzlePackTypesPage}>\n <HeaderTitleBarComponent title={translation.getTranslation(translationGroups.puzzlePackTypesPage, 'header-title')} />\n <PuzzlePackTypeFilter1Container />\n <PuzzlePackTypeFilter2Container />\n </PageHeaderComponent>\n <PuzzlePackTypesDisplayComponent />\n </>\n )\n}\n\nexport default PuzzlePackTypesComponent\n","import { getPuzzlePacks } from 'client/actions/puzzleDataActions'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { useLogin } from 'client/hooks/useLogin'\nimport { UserData } from 'client/reducers/userReducer'\nimport { StoreState } from 'client/store'\nimport { useEffect, useRef } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\n\n// This hook will fetch the puzzle packs and store them in redux. If not authenticated, we will\n// login anonymously\nexport const usePuzzlePackAuthentication = () => {\n const dispatch = useDispatch()\n const loginAnonymous = useLogin()\n const loginCalled = useRef(false)\n const user = useSelector<StoreState, UserData>((state: StoreState) => state.user?.data)\n const abilities = useAbilities()\n\n useEffect(() => {\n const abortController = new AbortController()\n if (user === null && !abilities.isAnonymous) {\n // Not logged in as an anon user, attempt to do so now\n if (loginCalled.current === false) {\n loginCalled.current = true\n loginAnonymous()\n }\n }\n if (user) {\n dispatch(getPuzzlePacks(abortController))\n }\n return () => {\n abortController.abort()\n }\n }, [abilities.isAnonymous, loginAnonymous, user, dispatch])\n}\n","import { getPuzzlePacks } from 'client/actions/puzzleDataActions'\nimport { klubbleAPI } from 'client/api/common'\nimport { StoreState } from 'client/store'\nimport { PuzzlePack } from 'client/types/PuzzlePack'\nimport { PuzzlePackType } from 'client/types/PuzzlePackType'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { useCallback, useEffect, useRef } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { refreshToken } from 'client/api/authentication'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport { Level, levels } from 'client/interfaces/IPuzzleCalendar'\n\nexport const usePuzzlePacks = () => {\n const puzzlePacks = useSelector<StoreState, PuzzlePack[]>((state) => state.puzzleData?.puzzlePacks)\n const puzzlePackTypes = useSelector<StoreState, PuzzlePackType[]>((state) => state.puzzleData?.puzzlePackTypes)\n const dispatch = useDispatch()\n const throwError = useAsyncError()\n\n const abortController = useRef(null)\n\n useEffect(() => {\n abortController.current = new AbortController()\n return () => {\n abortController.current.abort()\n }\n }, [])\n\n const getPuzzlePackTypeById = useCallback((id: number) => {\n return puzzlePackTypes.find((ppt) => ppt.id === id)\n }, [puzzlePackTypes])\n\n const getPuzzlePackTypeByName = useCallback((name: string) => {\n return puzzlePackTypes.find((ppt) => ppt.name.toLowerCase() === name)\n }, [puzzlePackTypes])\n\n const getPuzzlePackById = useCallback((id: number) => {\n return puzzlePacks.find((pp) => pp.id === id)\n }, [puzzlePacks])\n\n const getPuzzlePacksWithinPuzzlePackType = useCallback((puzzlePackTypeId: number) => {\n return puzzlePacks.filter((pack) => pack.puzzlePackTypeId === puzzlePackTypeId)\n }, [puzzlePacks])\n\n const getAvailableLevelsWithinPuzzlePackType = useCallback((puzzlePackTypeId: number) => {\n const puzzlePacksWithinPuzzlePackType = puzzlePacks.filter((pack) => pack.puzzlePackTypeId === puzzlePackTypeId)\n const availableLevels = Array.from(new Set(puzzlePacksWithinPuzzlePackType.flatMap((puzzlePack) => puzzlePack.levels))).map((level) => level.toLocaleLowerCase() as Level)\n availableLevels.sort((a, b) => levels.indexOf(a) - levels.indexOf(b))\n return availableLevels\n }, [puzzlePacks])\n\n const getSelectedLevelForPuzzlePackType = useCallback((id: number) => {\n return puzzlePackTypes.find((ppt) => ppt.id === id)?.selectedLevel?.toLocaleLowerCase()\n }, [puzzlePackTypes])\n\n const obtainFreePuzzlePack = useCallback(async (puzzlePackId: number) => {\n try {\n const res = await klubbleAPI.get(`Puzzle/packs/${puzzlePackId}/buyfree`, {\n signal: abortController.current?.signal,\n })\n if (res?.status === 200) {\n // refresh token as you might just have gained new role PUZZLE_PACK_OWNER\n await refreshToken()\n // reload puzzlePacks for the updated isPurchased\n await getPuzzlePacks(abortController.current)(dispatch)\n } else {\n throw new Error(`${res.config.url} did not return succesfully`)\n }\n } catch (e) {\n throwError(e, 'Error buying puzzle pack puzzle')\n }\n }, [dispatch, throwError])\n\n const showPuzzlePackContents = useCallback(async (puzzlePackId: number) => {\n const { isFree, isPurchased } = getPuzzlePackById(puzzlePackId)\n // if this is a free puzzlePack and it has not been 'purchased'/'obtained' before, than first 'purchase'/'obtain' it, so user has the rights to play it.\n if (isFree && !isPurchased) {\n await obtainFreePuzzlePack(puzzlePackId)\n }\n dispatch(uiActions.setDrawer({\n drawer: drawerTypes.PUZZLE_PACK_CONTENT,\n drawerData: {\n puzzlePackId,\n },\n forceModal: true,\n modalAutoGrow: true,\n bleedToEdge: true,\n className: 'drawer--colored-header',\n }))\n }, [dispatch, getPuzzlePackById, obtainFreePuzzlePack])\n\n return {\n puzzlePacks,\n puzzlePackTypes,\n getPuzzlePackTypeById,\n getPuzzlePackTypeByName,\n getPuzzlePackById,\n getPuzzlePacksWithinPuzzlePackType,\n getAvailableLevelsWithinPuzzlePackType,\n getSelectedLevelForPuzzlePackType,\n showPuzzlePackContents,\n }\n}\n","import React, { useContext, useEffect } from 'react'\nimport { all, type PuzzleFilter1 } from 'client/constants/puzzleFilters1'\nimport TabNav from 'client/pages/common/components/TabNav'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport { LOGIC, WORDS } from 'client/constants/puzzleMainType'\nimport { type AcceptedFilterAndSortingValue, syncFilterAndSortingWithUrl } from './syncFilterAndSortingWithUrl'\n\ntype Props = {\n selectPuzzleFilter: (filter: PuzzleFilter1) => void\n filter1: PuzzleFilter1\n}\n\nconst filters: AcceptedFilterAndSortingValue[] = [\n all,\n LOGIC,\n WORDS,\n]\n\nconst PuzzleFilter1Component = ({ selectPuzzleFilter, filter1 }: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n\n useEffect(() => {\n syncFilterAndSortingWithUrl('filter1', filter1, filters, selectPuzzleFilter)\n }, [selectPuzzleFilter, filter1])\n\n const handleUpdateFilter = (filter: PuzzleFilter1) => {\n const searchParams = new URLSearchParams(window.location.search)\n searchParams.set('filter1', filter)\n window.history.pushState({}, '', `${window.location.pathname}?${searchParams.toString()}`)\n selectPuzzleFilter(filter)\n }\n\n return (\n <div className=\"puzzle-filter-1\">\n <TabNav\n active={filter1}\n buttons={filters.map((key) => ({ key, text: getTranslation(translationGroups.puzzlePage, `filter-${key}`) }))}\n onClickHandler={handleUpdateFilter}\n />\n </div>\n )\n}\n\nexport default PuzzleFilter1Component\n","import React, { useContext, useEffect } from 'react'\nimport IconHeartFull from 'assets/icons/icon_heart_full.svg'\nimport IconHeartEmpty from 'assets/icons/icon_heart_empty.svg'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport {\n FAVORITE,\n type PuzzleFilter2,\n} from 'client/constants/puzzleFilters2'\nimport { syncFilterAndSortingWithUrl } from './syncFilterAndSortingWithUrl'\n\ntype Props = {\n selectPuzzleFilter: (type: PuzzleFilter2) => void\n filter2: PuzzleFilter2\n textButtons: string[]\n}\n\nconst PuzzleFilter2Component = ({ selectPuzzleFilter, filter2, textButtons }: Props) => {\n const translation = useContext(TranslationContext)\n\n useEffect(() => {\n syncFilterAndSortingWithUrl('filter2', filter2, [FAVORITE, ...textButtons], selectPuzzleFilter)\n }, [selectPuzzleFilter, filter2, textButtons])\n\n const handleUpdateFilter = (value: PuzzleFilter2) => {\n const searchParams = new URLSearchParams(window.location.search)\n if (value === filter2) {\n searchParams.delete('filter2')\n } else {\n searchParams.set('filter2', value)\n }\n window.history.pushState({}, '', `${window.location.pathname}?${searchParams.toString()}`)\n selectPuzzleFilter(value)\n }\n const renderNavTextButtons = () => textButtons.map((filter) => {\n const className = [\n 'puzzle-filter-2__button',\n ...(filter === filter2 ? ['puzzle-filter-2__button--active'] : []),\n ].join(' ')\n\n return (\n <button\n key={filter}\n type=\"button\"\n className={className}\n onClick={() => handleUpdateFilter(filter)}\n >\n {translation.getTranslation(translationGroups.puzzleTags, filter)}\n </button>\n )\n })\n\n const favoriteButtonClass = [\n 'puzzle-filter-2__button',\n 'puzzle-filter-2__button-heart',\n ...(filter2 === FAVORITE ? ['puzzle-filter-2__button--active'] : []),\n ].join(' ')\n\n return (\n <div className=\"puzzle-filter-2\">\n <div className=\"puzzle-filter-2__content-box\">\n <button\n type=\"button\"\n className={favoriteButtonClass}\n onClick={() => handleUpdateFilter(FAVORITE)}\n >\n {filter2 === FAVORITE\n ? <IconHeartFull className=\"puzzle-filter-2__heart\" />\n : <IconHeartEmpty className=\"puzzle-filter-2__heart\" />}\n </button>\n {renderNavTextButtons()}\n </div>\n </div>\n )\n}\n\nexport default PuzzleFilter2Component\n","import { type PuzzleFilter1 } from 'client/constants/puzzleFilters1'\nimport { type PuzzleFilter2 } from 'client/constants/puzzleFilters2'\nimport { puzzleSortingEnum } from 'client/enums/puzzleData'\n\nexport type AcceptedFilterAndSortingValue = PuzzleFilter1 | PuzzleFilter2 | puzzleSortingEnum\n\nexport const syncFilterAndSortingWithUrl = (\n type: 'filter1' | 'filter2' | 'sort',\n value: AcceptedFilterAndSortingValue,\n acceptedFilterAndSortingValues: AcceptedFilterAndSortingValue[],\n setUrlValueInRedux: (value: AcceptedFilterAndSortingValue) => void,\n) => {\n const searchParams = new URLSearchParams(window.location.search)\n const urlValue = searchParams.get(type) ?? '' as AcceptedFilterAndSortingValue\n const foundFilter = acceptedFilterAndSortingValues.find((fsv) => fsv.toLowerCase() === urlValue.toLowerCase())\n\n if ((value !== foundFilter)) {\n setUrlValueInRedux(foundFilter)\n } if (!urlValue && value) {\n searchParams.set(type, value)\n window.history.pushState({}, '', `${window.location.pathname}?${searchParams.toString()}`)\n }\n}\n","import React, { useEffect } from 'react'\nimport IconKlubbleHamburger from 'assets/icons/icon_hamburger.svg'\nimport { puzzleSortingEnum } from 'client/enums/puzzleData'\nimport { syncFilterAndSortingWithUrl } from './syncFilterAndSortingWithUrl'\n\ntype Props = {\n puzzleSorting: puzzleSortingEnum;\n setPuzzleSorting: (value: puzzleSortingEnum) => void;\n onClickHandler: () => void;\n}\n\nconst PuzzleSortComponent = ({ puzzleSorting, setPuzzleSorting, onClickHandler }: Props) => {\n useEffect(() => {\n syncFilterAndSortingWithUrl('sort', puzzleSorting, Object.values(puzzleSortingEnum), setPuzzleSorting)\n }, [setPuzzleSorting, puzzleSorting])\n\n return (\n <button type=\"button\" className=\"header-title-bar__hamburger\" onClick={onClickHandler} aria-label=\"Sort Puzzles\">\n <IconKlubbleHamburger />\n </button>\n )\n}\n\nexport default PuzzleSortComponent\n","import { connect } from 'react-redux'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { puzzleSortingEnum } from 'client/enums/puzzleData'\nimport { setPuzzleSorting } from 'client/actions/puzzleDataActions'\nimport { StoreState } from 'client/store'\nimport { TDispatch } from 'common_packages/assets/js/types/TDispatch'\nimport { AnyAction } from 'redux'\nimport PuzzleSortComponent from '../components/PuzzleSortComponent'\n\nconst mapStateToProps = (state: StoreState) => ({\n puzzleSorting: state.puzzleData.puzzleSorting,\n})\n\nconst mapDispatchToProps = (dispatch: TDispatch<AnyAction>) => ({\n onClickHandler: () => {\n dispatch(uiActions.setDrawer({ drawer: drawerTypes.PUZZLES_SORTING }))\n },\n setPuzzleSorting: (puzzleSortType: puzzleSortingEnum) => {\n dispatch(setPuzzleSorting(puzzleSortType))\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(PuzzleSortComponent)\n","import { connect } from 'react-redux'\nimport { type PuzzleFilter1 } from 'client/constants/puzzleFilters1'\nimport { type PuzzleFilterAction } from 'client/actions/types'\nimport { type TDispatch } from 'common_packages/assets/js/types/TDispatch'\nimport { type StoreState } from 'client/store'\nimport PuzzleFilter1Component from '../components/PuzzleFilter1Component'\nimport { setPuzzleFilter } from '../../../actions/puzzleFilterActions'\n\nconst mapStateToProps = (state: StoreState) => ({\n filter1: state.puzzleFilter.filter1,\n})\n\nconst mapDispatchToProps = (dispatch: TDispatch<PuzzleFilterAction>) => ({\n selectPuzzleFilter: (filter:PuzzleFilter1) => {\n dispatch(setPuzzleFilter({\n filter1: filter,\n }))\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(PuzzleFilter1Component)\n","import React from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\nimport {\n PLAY_TOGETHER,\n RECENT,\n type PuzzleFilter2,\n} from 'client/constants/puzzleFilters2'\nimport { type StoreState } from 'client/store'\nimport useConfig from 'client/hooks/useConfig'\nimport { type PuzzleFilterState } from 'client/reducers/puzzleFilterReducer'\nimport { CLASSIC, MINI } from 'client/constants/puzzleFormat'\nimport { setPuzzleFilter } from '../../../actions/puzzleFilterActions'\nimport PuzzleFilter2Component from '../components/PuzzleFilter2Component'\n\nconst PuzzleFilter2Container = () => {\n const dispatch = useDispatch()\n const { filter2 } = useSelector<StoreState, PuzzleFilterState>((state) => state.puzzleFilter)\n const { entity } = useConfig()\n const { tags } = entity\n\n const textButtons = [\n CLASSIC,\n MINI,\n ...tags.map((tag) => tag.tagLangKey),\n RECENT,\n PLAY_TOGETHER,\n ]\n\n const selectPuzzleFilter = (filter: PuzzleFilter2) => {\n dispatch(setPuzzleFilter({\n filter2: filter,\n }))\n }\n\n return (\n <PuzzleFilter2Component\n filter2={filter2}\n textButtons={textButtons}\n selectPuzzleFilter={selectPuzzleFilter}\n />\n )\n}\n\nexport default PuzzleFilter2Container\n","import React, {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react'\nimport { type PuzzleType } from 'client/types/PuzzleType'\nimport { klubbleAPI } from 'client/api/common'\nimport HeartToggleContainer from 'pages/common/containers/HeartToggleContainer'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport PillComponent from 'common_packages/assets/js/components/ui/pill/PillComponent'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport IconPlay from 'client/assets/icons/icon_play.svg'\nimport GameCardComponent from 'client/pages/common/components/game_cards/GameCardComponent'\nimport {\n type PuzzleFilter2,\n RECENT,\n FAVORITE,\n PLAY_TOGETHER,\n} from 'client/constants/puzzleFilters2'\nimport { type PuzzleFilter1, all } from 'client/constants/puzzleFilters1'\nimport { puzzleSortingEnum } from 'client/enums/puzzleData'\nimport { CLASSIC, MINI } from 'client/constants/puzzleFormat'\n\ntype Props = {\n puzzleTypes: PuzzleType[]\n filter1: PuzzleFilter1\n filter2: PuzzleFilter2\n puzzleSorting: puzzleSortingEnum\n onClickSortHandler: () => void\n}\n\nconst PuzzleDisplayComponent = ({\n puzzleTypes,\n filter1 = all,\n filter2,\n puzzleSorting,\n onClickSortHandler,\n}: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n\n const [recentPuzzleTypes, setRecentPuzzleTypes] = useState<PuzzleType[]>()\n const throwError = useAsyncError()\n\n useEffect(() => {\n /* Here specifically getrecent is used instead of getcontinueplaying, because the latter only returns recently played puzzles that\n still have days left to play, whereas the first returns all recently played puzzles, regardless if there are any days left to play\n and that is exactly what we need here. */\n\n klubbleAPI.get<PuzzleType[]>('Puzzle/getrecent')\n .then((response) => {\n if (response?.status === 200) {\n setRecentPuzzleTypes(response.data)\n } else {\n throw new Error(`${response.config.url} did not return succesfully`)\n }\n // eslint-disable-next-line no-console\n }).catch((e) => {\n throwError(e, 'Error getting recent puzzles')\n })\n }, [throwError])\n\n const matchesFilter1 = useCallback((puzzle: PuzzleType) => {\n return puzzle.mainType.toLowerCase() === filter1.toLowerCase() || filter1 === all\n }, [filter1])\n\n const matchesFilter2 = useCallback((puzzle: PuzzleType) => {\n switch (filter2) {\n case undefined:\n case '':\n // No filter2 set!\n return true\n case CLASSIC:\n return puzzle.format.toLowerCase() === CLASSIC.toLowerCase()\n case MINI:\n return puzzle.format.toLowerCase() === MINI.toLowerCase()\n case RECENT:\n return recentPuzzleTypes?.filter((rP) => rP.puzzleTypeId === puzzle.puzzleTypeId)?.length > 0\n case FAVORITE:\n return puzzle.isFavorite\n case PLAY_TOGETHER:\n return puzzle.isPlayTogether\n default:\n // A tag, configured in the admin\n return puzzle.tags.includes(filter2)\n }\n }, [filter2, recentPuzzleTypes])\n\n const sortedPuzzles = useMemo(() => {\n if (!puzzleTypes) return []\n\n const selectByFilters = (puzzle: PuzzleType) => {\n return matchesFilter1(puzzle) && matchesFilter2(puzzle)\n }\n\n return puzzleTypes\n .filter(selectByFilters)\n .sort((a, b) => sortPuzzles(a, b, puzzleSorting))\n }, [matchesFilter1, matchesFilter2, puzzleSorting, puzzleTypes])\n\n return (\n <div className=\"container\">\n <div className=\"puzzle-list__wrapper\">\n <button type=\"button\" className=\"puzzle-list__sort-button\" tabIndex={0} onClick={onClickSortHandler}>\n {getTranslation(translationGroups.puzzlePage, 'sort-puzzle-list')}\n <IconPlay className=\"play-button-icon\" />\n </button>\n {(filter2 === FAVORITE && sortedPuzzles.length === 0) && (\n <div className=\"puzzle-list__empty\">\n {getTranslation(translationGroups.puzzlePage, 'no-favorites-yet')}\n </div>\n )}\n {(filter2 === RECENT && sortedPuzzles.length === 0) && (\n <div className=\"puzzle-list__empty\">\n {getTranslation(translationGroups.puzzlePage, 'no-recents-yet')}\n </div>\n )}\n <div className=\"puzzle-list\">\n {sortedPuzzles.map((puzzle: PuzzleType) => (\n <GameCardComponent\n key={puzzle.puzzleTypeId}\n puzzleTypeId={puzzle.puzzleTypeId}\n nameLangKey={puzzle.nameLangKey}\n subtitle={(\n <span className=\"puzzle-list__item-description-underline\">\n {getTranslation(translationGroups.puzzleTags, puzzle.format)}\n </span>\n )}\n isNew={puzzle.isNew}\n isPremiumOnly={puzzle.isPremiumOnly}\n isStackedOnMobileView\n showFavoriteToggle\n from=\"puzzles\"\n >\n <div className=\"game-card__right\">\n {puzzle.isPremiumOnly && (\n <PillComponent type=\"info\" className=\"puzzle-list__pill\">\n {getTranslation(translationGroups.common, 'subscription-type-premium')}\n </PillComponent>\n )}\n {(puzzle.isNew && !puzzle.isPremiumOnly) && (\n <PillComponent type=\"new\" className=\"puzzle-list__pill\">\n {getTranslation(translationGroups.common, 'new')}\n </PillComponent>\n )}\n <HeartToggleContainer isStacked puzzleTypeId={puzzle.puzzleTypeId} />\n </div>\n </GameCardComponent>\n ))}\n </div>\n </div>\n </div>\n )\n}\n\nexport default PuzzleDisplayComponent\n\nconst sortPuzzles = (a: PuzzleType, b: PuzzleType, puzzleSorting: puzzleSortingEnum) => {\n switch (puzzleSorting) {\n case puzzleSortingEnum.alphabetical: {\n return a.sortOrder - b.sortOrder\n }\n case puzzleSortingEnum.popularity: {\n return b.popularityScore - a.popularityScore\n }\n default: {\n return 0\n }\n }\n return 0\n}\n","import { connect } from 'react-redux'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { type StoreState } from 'client/store'\nimport { type TDispatch } from 'common_packages/assets/js/types/TDispatch'\nimport { type AnyAction } from 'redux'\nimport PuzzleDisplayComponent from '../components/PuzzleDisplayComponent'\n\nconst mapStateToProps = (state: StoreState) => ({\n puzzleTypes: state.puzzleData.puzzleTypes,\n puzzleSorting: state.puzzleData.puzzleSorting,\n ...state.puzzleFilter,\n})\n\nconst mapDispatchToProps = (dispatch: TDispatch<AnyAction>) => ({\n onClickSortHandler: () => {\n dispatch(uiActions.setDrawer({ drawer: drawerTypes.PUZZLES_SORTING }))\n },\n})\n\nexport default connect(mapStateToProps, mapDispatchToProps)(PuzzleDisplayComponent)\n","import { connect } from 'react-redux'\nimport { getContinuePlayingPuzzleTypes } from '../../../actions/puzzleDataActions'\nimport PuzzlesComponent from '../components/PuzzlesComponent'\n\nconst mapDispatchToProps = (dispatch: any) => ({\n getContinuePlayingPuzzleTypes: () => {\n dispatch(getContinuePlayingPuzzleTypes())\n },\n})\n\nexport default connect(null, mapDispatchToProps)(PuzzlesComponent)\n","import React, { useEffect, useContext } from 'react'\nimport PageHeaderComponent from 'client/pages/common/components/page_header/PageHeaderComponent'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport HeaderTitleBarComponent from '../../common/components/HeaderTitleBarComponent'\nimport PuzzleSortContainer from '../containers/PuzzleSortContainer'\nimport PuzzleFilter1Container from '../containers/PuzzleFilter1Container'\nimport PuzzleFilter2Container from '../containers/PuzzleFilter2Container'\nimport PuzzleDisplayContainer from '../containers/PuzzleDisplayContainer'\n\ntype Props = {\n getContinuePlayingPuzzleTypes: () => void\n}\n\nconst PuzzlesComponent = ({ getContinuePlayingPuzzleTypes }: Props) => {\n const translation = useContext(TranslationContext)\n\n useEffect(() => {\n getContinuePlayingPuzzleTypes()\n }, [getContinuePlayingPuzzleTypes])\n\n return (\n <>\n <PageHeaderComponent translationGroup={translationGroups.puzzlePage}>\n <HeaderTitleBarComponent title={translation.getTranslation(translationGroups.puzzlePage, 'header-title')}>\n <PuzzleSortContainer />\n </HeaderTitleBarComponent>\n <PuzzleFilter1Container />\n <PuzzleFilter2Container />\n </PageHeaderComponent>\n <PuzzleDisplayContainer />\n </>\n )\n}\n\nexport default PuzzlesComponent\n","import React, {\n useRef, useContext, useLayoutEffect, useState,\n} from 'react'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport { usePuzzleTypeImageUrls } from 'client/hooks/usePuzzleTypeImageUrls'\n\ntype Props = {\n index: number\n puzzleTypeNameKey: string\n variantNameKey: 'Mini' | 'Classic'\n numPlayed: number\n percentage: number\n maxLabelWidth: number\n setMaxLabelWidth: (number) => void\n animateDelay?: number\n}\n\nconst StatsTotalsItemComponent = (props: Props) => {\n const {\n index,\n puzzleTypeNameKey,\n numPlayed,\n variantNameKey,\n maxLabelWidth = 0,\n setMaxLabelWidth,\n animateDelay = 0,\n } = props\n const { getIconUrl } = usePuzzleTypeImageUrls()\n const { getTranslation } = useContext(TranslationContext)\n const isMini = variantNameKey === 'Mini'\n const [startAnim, setStartAnim] = useState(false)\n\n const ref = useRef(null)\n\n useLayoutEffect(() => {\n const timeout = setTimeout(() => {\n setStartAnim(true)\n if (index === 0) {\n /* If this is the first bar, get the label width (which is the maxLabelWidth for all the bars)\n and send it to the parent, so that it can be shared with all the other bars,\n and they can use it to properly calculate their width, taking the width of the top bar into account. */\n setMaxLabelWidth(ref.current ? ref.current.offsetWidth : 0)\n }\n }, animateDelay)\n return () => clearTimeout(timeout)\n }, [animateDelay, index, setMaxLabelWidth])\n\n return (\n <li className=\"stats-totals-item list-item\">\n <img className=\"stats-totals-item__icon\" src={getIconUrl(puzzleTypeNameKey)} alt={puzzleTypeNameKey} />\n <div className=\"stats-totals-item__info\">\n <div className=\"stats-totals-item__puzzle-name\">{getTranslation(translationGroups.puzzle, puzzleTypeNameKey)}</div>\n <div className=\"stats-totals-item__classification\">{getTranslation(translationGroups.puzzle, isMini ? 'mini' : 'classic')}</div>\n <div className=\"stats-totals-item__progress\">\n <div className=\"progress-bar\" style={startAnim ? { width: `calc(${props.percentage * 0.01} * (100% - ${maxLabelWidth}px)` } : {}} />\n {startAnim\n && (\n <div ref={ref} className=\"stats-totals-item__progress-number\">\n {numPlayed}\n </div>\n )}\n\n </div>\n </div>\n </li>\n )\n}\n\nexport default StatsTotalsItemComponent\n","import React, {\n useContext, useState,\n} from 'react'\nimport { UserStatsData } from 'common_packages/assets/js/types/UserStatsData'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport StatsTotalsItemComponent from './StatsTotalsItemComponent'\n\ntype Props = Partial<Pick<UserStatsData, 'puzzleTypes'>> & {\n animationDelay: number\n}\n\nconst StatsTotalsComponent = ({ puzzleTypes, animationDelay }: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const [seeingAll, setSeeingAll] = useState(false)\n const [maxLabelWidth, setMaxLabelWidth] = useState(0)\n const handleToggleSeeAll = () => {\n setSeeingAll(!seeingAll)\n }\n\n return (\n <div className={`stats-totals ${seeingAll ? 'stats-totals--see-all' : ''}`}>\n <div className=\"stats-totals__header\">\n <h2 className=\"stats-totals__title\">{getTranslation(translationGroups.statsPage, 'total-play')}</h2>\n {puzzleTypes\n && (\n <div className=\"stats-totals__see-all\" onClick={handleToggleSeeAll} role=\"button\">\n {getTranslation(translationGroups.statsPage, seeingAll ? 'see-less' : 'see-all')}\n </div>\n )}\n </div>\n <div className=\"card info-card\">\n {puzzleTypes ? (\n <ul className=\"stats-totals__list list\">\n {puzzleTypes?.map((pT, i) => (\n <StatsTotalsItemComponent\n key={pT.puzzleTypeNameKey}\n index={i}\n animateDelay={300 * i + (animationDelay * 1000)}\n maxLabelWidth={maxLabelWidth}\n setMaxLabelWidth={setMaxLabelWidth}\n {...pT}\n />\n ))}\n </ul>\n ) : (\n getTranslation(translationGroups.statsPage, 'no-puzzles-played')\n )}\n </div>\n </div>\n )\n}\n\nexport default StatsTotalsComponent\n","import React from 'react'\nimport { motion } from 'framer-motion'\n\ntype Props = {\n percentage?: number\n animationDelay: number\n}\n\nconst dCircle = 'M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831'\n\nconst StatsPieChartGraphComponent = ({ percentage, animationDelay: delay }: Props) => {\n const duration = 1.5\n return (\n <svg viewBox=\"0 0 36 36\" className=\"stats-pie-chart__circle\">\n <path\n className=\"stats-pie-chart__circle-path stats-pie-chart__circle-path--primary\"\n strokeDasharray={100}\n d={dCircle}\n />\n {percentage > 0 && (\n <>\n <motion.path\n strokeDasharray={`${percentage}px, 100px`}\n strokeDashoffset={`${percentage}px`}\n initial={{\n strokeDashoffset: `${percentage}px`,\n }}\n animate={{\n strokeDashoffset: [`${percentage}px`, '0px'],\n transition: { duration, ease: 'linear', delay },\n }}\n stroke-width=\"5\"\n stroke-linejoin=\"round\"\n className=\"stats-pie-chart__circle-path stats-pie-chart__circle-path--outline\"\n d={dCircle}\n />\n <motion.path\n strokeDasharray={`${percentage}px, 100px`}\n strokeDashoffset={`${percentage}px`}\n initial={{\n strokeDashoffset: `${percentage}px`,\n }}\n animate={{\n strokeDashoffset: [`${percentage}px`, '0px'],\n transition: { duration, ease: 'linear', delay },\n }}\n stroke-width=\"5\"\n stroke-linejoin=\"round\"\n className=\"stats-pie-chart__circle-path stats-pie-chart__circle-path--secondary\"\n d={dCircle}\n />\n </>\n )}\n </svg>\n )\n}\n\nexport default StatsPieChartGraphComponent\n","import React, { useContext, useMemo } from 'react'\nimport { type UserStatsData } from 'common_packages/assets/js/types/UserStatsData'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport StatsPieChartGraphComponent from './StatsPieChartGraphComponent'\n\ntype Props = {\n stats?: UserStatsData\n animationDelay: number\n}\n\nconst StatsSizesComponent = ({ stats, animationDelay }: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const [primaryData, secondaryData] = useMemo(() => {\n if (!stats) return []\n // sort descending\n return [...stats.variants].sort((a, b) => b.percentage - a.percentage)\n }, [stats])\n\n return (\n <div className=\"stats-pie-chart card info-card\">\n <div className=\"stats-pie-chart__circle-container\">\n <StatsPieChartGraphComponent percentage={secondaryData?.percentage} animationDelay={animationDelay} />\n <div className=\"stats-pie-chart__label\">\n {getTranslation(translationGroups.statsPage, 'data-variants')}\n </div>\n </div>\n <ul className=\"stats-pie-chart__legend\">\n <li className=\"stats-pie-chart__legend-item stats-pie-chart__legend-item--primary\">\n <div className=\"stats-pie-chart__legend-label\">\n {primaryData && getTranslation(translationGroups.statsPage, `data-variant-${primaryData.variantNameKey}`)}\n </div>\n <div className=\"stats-pie-chart__legend-percentage\">\n {`${Math.round(primaryData?.percentage ?? 0)}%`}\n </div>\n </li>\n <li className=\"stats-pie-chart__legend-item stats-pie-chart__legend-item--secondary\">\n <div className=\"stats-pie-chart__legend-label\">\n {secondaryData && getTranslation(translationGroups.statsPage, `data-variant-${secondaryData.variantNameKey}`)}\n </div>\n <div className=\"stats-pie-chart__legend-percentage\">\n {`${Math.round(secondaryData?.percentage ?? 0)}%`}\n </div>\n </li>\n </ul>\n </div>\n )\n}\n\nexport default StatsSizesComponent\n","import React, { useContext, useMemo } from 'react'\nimport { type UserStatsData } from 'common_packages/assets/js/types/UserStatsData'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\nimport StatsPieChartGraphComponent from './StatsPieChartGraphComponent'\n\ntype Props = {\n stats?: UserStatsData\n animationDelay: number\n}\n\nconst StatsTypesComponent = ({ stats, animationDelay }: Props) => {\n const { getTranslation } = useContext(TranslationContext)\n const [primaryData, secondaryData] = useMemo(() => {\n if (!stats) return []\n // sort descending\n return [...stats.mainTypes].sort((a, b) => b.percentage - a.percentage)\n }, [stats])\n\n return (\n <div className=\"stats-pie-chart card info-card\">\n <div className=\"stats-pie-chart__circle-container\">\n <StatsPieChartGraphComponent percentage={secondaryData?.percentage} animationDelay={animationDelay} />\n <div className=\"stats-pie-chart__label\">\n {getTranslation(translationGroups.statsPage, 'data-main-types')}\n </div>\n </div>\n <ul className=\"stats-pie-chart__legend\">\n <li className=\"stats-pie-chart__legend-item stats-pie-chart__legend-item--primary\">\n <div className=\"stats-pie-chart__legend-label\">\n {primaryData && getTranslation(translationGroups.statsPage, `data-main-type-${primaryData.mainTypeNameKey}`)}\n </div>\n <div className=\"stats-pie-chart__legend-percentage\">\n {`${Math.round(primaryData?.percentage ?? 0)}%`}\n </div>\n </li>\n <li className=\"stats-pie-chart__legend-item stats-pie-chart__legend-item--secondary\">\n <div className=\"stats-pie-chart__legend-label\">\n {secondaryData && getTranslation(translationGroups.statsPage, `data-main-type-${secondaryData.mainTypeNameKey}`)}\n </div>\n <div className=\"stats-pie-chart__legend-percentage\">\n {`${Math.round(secondaryData?.percentage ?? 0)}%`}\n </div>\n </li>\n </ul>\n </div>\n )\n}\n\nexport default StatsTypesComponent\n","import React, { useContext } from 'react'\nimport { useHistory } from 'react-router-dom'\nimport RoundedButtonComponent from 'pages/common/components/buttons/RoundedButtonComponent'\nimport CardComponent from 'pages/common/components/cards/CardComponent'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\n\nconst NoStatsComponent = () => {\n const translation = useContext(TranslationContext)\n const { push } = useHistory()\n return (\n <CardComponent className=\"no-stats info-card\">\n <h2 className=\"info-card__title\">{translation.getTranslation(translationGroups.statsPage, 'no-stats-header')}</h2>\n <div className=\"info-card__body\">{translation.getTranslation(translationGroups.statsPage, 'no-stats-body')}</div>\n <div className=\"info-card__buttons\">\n <RoundedButtonComponent text={translation.getTranslation(translationGroups.statsPage, 'no-stats-play-puzzle-packs')} onClickHandler={() => { push('/puzzle-packs') }} />\n <RoundedButtonComponent text={translation.getTranslation(translationGroups.statsPage, 'no-stats-play-puzzles')} onClickHandler={() => { push('/puzzles') }} />\n </div>\n </CardComponent>\n )\n}\n\nexport default NoStatsComponent\n","import React, { useContext, useEffect, useState } from 'react'\nimport { klubbleAPI } from 'client/api/common'\nimport { UserStatsData } from 'common_packages/assets/js/types/UserStatsData'\nimport { useAsyncError } from 'client/hooks/useAsyncError'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport StatsTotalsComponent from './StatsTotalsComponent'\nimport StatsSizesComponent from './StatsSizesComponent'\nimport StatsTypesComponent from './StatsTypesComponent'\nimport NoStatsComponent from './NoStatsComponent'\nimport HeaderTitleBarComponent from '../common/components/HeaderTitleBarComponent'\nimport PageHeaderComponent from '../common/components/page_header/PageHeaderComponent'\nimport NavigationPagesTabsComponent from '../common/components/navigation/NavigationPagesTabsComponent'\n\nconst StatsComponent = () => {\n const [stats, setStats] = useState<UserStatsData>()\n const [isLoading, setIsLoading] = useState(true)\n const translation = useContext(TranslationContext)\n const throwError = useAsyncError()\n\n useEffect(() => {\n const getData = async () => {\n try {\n const { data } = await klubbleAPI.get<UserStatsData>('Auth/getuserstats')\n if (data?.mainTypes.length > 0 && data?.puzzleTypes.length > 0 && data?.variants.length > 0) {\n setStats(data)\n }\n } catch (error) {\n // server error or no connection\n throwError(error, 'Error retrieving stats')\n } finally {\n setIsLoading(false)\n }\n }\n getData()\n }, [throwError])\n\n return (\n <>\n <PageHeaderComponent translationGroup={translationGroups.statsPage}>\n <HeaderTitleBarComponent title={translation.getRawTranslation(translationGroups.statsPage, 'header-title')} />\n <NavigationPagesTabsComponent pages={['daily_dose', 'stats']} />\n </PageHeaderComponent>\n {!isLoading && (\n <div className={`container stats ${!stats ? 'stats--empty' : ''}`}>\n {stats ? (\n <>\n <div className=\"stats-sizes\">\n <StatsSizesComponent stats={stats} animationDelay={0.15} />\n </div>\n\n <div className=\"stats-types\">\n <StatsTypesComponent stats={stats} animationDelay={0.5} />\n </div>\n </>\n ) : (\n <NoStatsComponent />\n )}\n <StatsTotalsComponent puzzleTypes={stats?.puzzleTypes} animationDelay={0.8} />\n </div>\n )}\n </>\n )\n}\n\nexport default StatsComponent\n","import { Dispatch } from 'redux'\nimport * as base from 'wordsearch/resources/assets/js/actions/clueActions'\nimport { MatchCluePayload, WordsearchAction } from 'wordsearch/resources/assets/js/actions/types'\nimport { WordsearchStoreState } from 'wordsearch/resources/assets/js/reducers'\nimport gameroomConnection from 'client/player/js/gameroom/gameroomConnection'\nimport { MATCH_CLUE } from 'wordsearch/resources/assets/js/actions/clueActions'\nimport { WordsearchCluesState } from 'wordsearch/resources/assets/js/reducers/cluesReducer'\n\nexport const { matchClue } = base\nexport const { revealPuzzle } = base\n\n// Reveals the next word. Is only available when environment var ALLOW_SOLVE is set\nexport const revealSelectedClue = () => (dispatch: Dispatch<WordsearchAction>, getState: () => WordsearchStoreState) => {\n if (process.env.ALLOW_SOLVE !== 'true') {\n return\n }\n const { clues } = getState()\n const clueIndex = getFirstUnmatchedClue(clues)\n\n if (clueIndex === undefined) {\n return\n }\n\n const playerNumber = gameroomConnection.getPlayerNumber() ?? -1\n\n const clueCells = clues.clueCells[clueIndex]\n const payload: MatchCluePayload = {\n originCell: clueCells[0],\n destinationCell: clueCells[clueCells.length - 1],\n playerNumber,\n }\n\n dispatch({\n type: MATCH_CLUE,\n payload,\n })\n}\n\n// returns the first clue index that's not matched (found) yet\nconst getFirstUnmatchedClue = (clues: WordsearchCluesState) => {\n const clueCount = clues.clues.length\n for (let i = 0; i < clueCount; i++) {\n if (!clues.solvedClues.some((sC) => sC.clueIndex === i)) {\n return i\n }\n }\n return undefined\n}\n","import * as base from 'common_packages/assets/js/actions/actionServices/cellActionServices'\nimport { games } from 'common_packages/assets/js/types/gameDataTypes'\nimport * as wordsearchActions from 'client/player/puzzles/wordsearch/js/actions/clueActions'\nimport { CommonKlubblePuzzleStoreState } from '../../types/store'\n\nexport const executeCellAction = (action: string, payload?: unknown) => (dispatch, getState: () => CommonKlubblePuzzleStoreState) => {\n const state = getState()\n const { gameType } = state.settings\n let cellActions\n switch (gameType) {\n case games.WORDSEARCH:\n case games.WORDSEARCH_MINI:\n cellActions = wordsearchActions\n break\n default:\n dispatch(base.executeCellAction(action, payload))\n return\n }\n\n if (cellActions?.[action]) {\n dispatch(cellActions[action](payload))\n } else {\n // eslint-disable-next-line no-console\n console.error(`Action dispatcher ${action} not specified for ${gameType}`)\n }\n}\n","import React, {\n type FC,\n createRef, lazy, useCallback, useEffect, useMemo, useState,\n} from 'react'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport { useDispatch } from 'react-redux'\nimport { PlayerContext } from 'common_packages/assets/js/contexts/PlayerContext'\nimport ClientContextComponent from 'common_packages/assets/js/components/ClientContextComponent'\nimport { type GameType } from 'common_packages/assets/js/types/gameDataTypes'\nimport getIdentifiers from 'common_packages/assets/js/utilities/getIdentifiers'\nimport { tryPreloadAssets } from 'client/utilities/tryPreloadAssets'\nimport useAbilities from 'client/hooks/useAbilities'\nimport { finishPuzzle } from 'client/api/gameEvents'\nimport { getDailyDoses, setFinishedPuzzle } from 'client/actions/puzzleDataActions'\nimport { setDrawer, setShowEndscreen, setShowNav } from 'common_packages/assets/js/actions/uiActions'\nimport { resetPuzzle } from 'common_packages/assets/js/actions/gameActions'\nimport { fullscreenArea } from 'common_packages/assets/js/config/idAttributes'\nimport { closeFullscreen } from 'common_packages/assets/js/utilities/fullscreen'\nimport getQueryParam, { queryParams } from 'common_packages/assets/js/utilities/getQueryParam'\nimport { type FinishedPuzzle } from 'client/types/FinishedPuzzle'\nimport LoadingComponent from 'client/pages/common/loading/LoadingComponent'\nimport { getGamesFolder } from 'common_packages/assets/js/utilities/gamesFolder'\nimport { getPuzzleSpecificShareDetails } from '../utilities/getPuzzleSpecificShareDetails'\nimport gameroomConnection from '../gameroom/gameroomConnection'\nimport { showCannotStartPuzzleDrawer } from '../store/utilities/error'\nimport { type CommonKlubblePuzzleStore } from '../types/store'\n\ntype AsyncAppProps = {\n showBreadcrumbs?: boolean\n}\n\ntype Props = {\n isInViewPuzzleMode?: boolean\n}\n\nexport type ProcessFinishedPuzzle = (puzzleStore: CommonKlubblePuzzleStore) => void\n\nconst PlayerComponent = ({ isInViewPuzzleMode = false }: Props) => {\n const playerRef = createRef<HTMLDivElement>()\n const [triedPreloadAssets, setTriedPreloadAssets] = useState(false)\n const { gameType, puzzleId } = getPuzzleInfo()\n const abilities = useAbilities()\n const dispatch = useDispatch()\n const folderName = getGamesFolder(gameType)\n\n useEffect(() => {\n if (gameType && folderName) {\n tryPreloadAssets().finally(() => { setTriedPreloadAssets(true) })\n } else {\n showCannotStartPuzzleDrawer()\n // eslint-disable-next-line no-console\n console.error(`${gameType} is not a valid or defined gameType.`)\n setTriedPreloadAssets(true)\n }\n\n if (playerRef.current && playerRef.current.offsetTop < window.pageYOffset) {\n window.scrollTo(0, playerRef.current.offsetTop)\n }\n }, [folderName, gameType, playerRef])\n\n useEffect(() => {\n return () => {\n gameroomConnection.closeConnection()\n }\n }, [])\n\n const processFinishPuzzle = useCallback<ProcessFinishedPuzzle>((puzzleStore) => {\n const klubblePuzzleId = getQueryParam(queryParams.KLUBBLE_PUZZLE_ID)\n const element = document.getElementById(fullscreenArea)\n if (element) {\n /* We go out of fullscreen when going to the endscreen: exiting the fullscreen API on android\n * or removing the touchmove event handler on iOS. However, we pass keepFullscreenClass = true\n * such that we don't remove the keyboard or other elements from the player and the layout doesn't\n * jump before going to the endscreen.\n */\n closeFullscreen(element, true)\n }\n const time = puzzleStore.getState().timer.counter\n const isMultiPlayerQR = gameroomConnection.getIsMultiPlayerQR()\n const { qrLocationGuid } = puzzleStore.getState().gameInfo\n\n const { date } = puzzleStore.getState().gameInfo\n\n finishPuzzle(klubblePuzzleId, time).then((data) => {\n /**\n * update daily doses data, for showing in endscreen\n */\n if (abilities.canUseDailyDose) {\n dispatch(getDailyDoses())\n }\n\n const payload: FinishedPuzzle = {\n ...data,\n klubblePuzzleId,\n date,\n time,\n ...getPuzzleSpecificShareDetails(puzzleStore),\n isMultiPlayerQR,\n qrLocationGuid,\n }\n dispatch(setFinishedPuzzle(payload))\n\n dispatch(setShowNav(false))\n dispatch(setShowEndscreen(true))\n }).catch((error) => {\n if (error?.message === 'no-contribution' || error?.message === 'current-user-not-part-of-that-puzzle') {\n closeFullscreen(element)\n puzzleStore.dispatch(resetPuzzle())\n dispatch(setDrawer({\n drawer: drawerTypes.PUZZLE_FINISHED_WITHOUT_CONTRIBUTION,\n drawerData: { blockPlayer: true },\n modalAutoGrow: true,\n forceModal: true,\n hideHeader: true,\n hideClose: true,\n }))\n gameroomConnection.closeConnection()\n }\n })\n }, [abilities.canUseDailyDose, dispatch])\n\n const playerContext = useMemo(() => ({\n gameType,\n puzzleId,\n playerRef,\n processFinishPuzzle,\n isInViewPuzzleMode,\n }), [gameType, isInViewPuzzleMode, playerRef, processFinishPuzzle, puzzleId])\n\n if (!folderName) {\n return null\n }\n const AppComponent = lazy<FC<AsyncAppProps>>(() => import(\n /* webpackChunkName: \"appcomponent-[request]\" */\n `../../puzzles/${folderName}/js/components/AppComponent`\n ))\n\n return (\n <div\n id=\"puzzle-player\"\n className={triedPreloadAssets ? 'player' : 'player--loading'}\n ref={playerRef}\n >\n {triedPreloadAssets && (\n <ClientContextComponent>\n <PlayerContext.Provider\n value={playerContext}\n >\n <AppComponent\n showBreadcrumbs={abilities.canSeePuzzlePlayerBreadcrumbs}\n />\n </PlayerContext.Provider>\n </ClientContextComponent>\n )}\n {(!triedPreloadAssets && !isInViewPuzzleMode) && (\n <LoadingComponent />\n )}\n </div>\n )\n}\n\nconst getPuzzleInfo = () => {\n const { gameType: gameTypeLowerCase, puzzleId } = getIdentifiers()\n const gameType = gameTypeLowerCase.toUpperCase().replace(/-/g, '_') as GameType\n\n return {\n gameType,\n puzzleId,\n }\n}\n\nexport default PlayerComponent\n","import getIdentifiers from 'common_packages/assets/js/utilities/getIdentifiers'\nimport { games, type GameType } from 'common_packages/assets/js/types/gameDataTypes'\nimport { getPuzzleImageURL } from 'common_packages/assets/js/api/puzzleImageURLs'\n\nconst tryPreloadArrowWordPlusImage = (game: GameType, src: string) => new Promise<void>((resolve) => {\n // Since we're only TRYING to preload, in the end we always resolve, no matter what the outcome\n if (game === games.ARROWWORD_PLUS || game === games.ARROWWORD_PLUS_MINI) {\n const img = new Image()\n img.onload = () => resolve()\n img.onerror = () => resolve()\n img.src = src\n } else {\n resolve()\n }\n})\n\nexport const tryPreloadAssets = async () => {\n const { gameType, puzzleId, customerId } = getIdentifiers()\n const game = gameType.toUpperCase().replace(/-/g, '_') as GameType\n return tryPreloadArrowWordPlusImage(game, getPuzzleImageURL(customerId, puzzleId))\n}\n","import { Store } from 'redux'\nimport cellStatuses from 'common_packages/assets/js/constants/statuses'\nimport { games } from 'common_packages/assets/js/types/gameDataTypes'\n\nexport const getPuzzleSpecificShareDetails = (store: Store<any>): { shareTemplateTranslationKey: string, visual?: string, tries?: number } => {\n const { gameType } = store.getState().settings\n const shareTemplateTranslationKey = 'share-template'\n\n if (gameType === games.WORDGUESS) {\n const {\n rows, columns, cellData,\n } = store.getState().cells || {}\n const squareArr = cellData.reduce((acc, item, index) => {\n const enter = (index % columns === columns - 1)\n if (item.status === cellStatuses.CORRECT || item.status === cellStatuses.REVEALED) {\n acc.push('🟩')\n } else if (item.status === cellStatuses.SEMICORRECT) {\n acc.push('🟧')\n } else if (item.status === cellStatuses.INCORRECT) {\n acc.push('⬜')\n }\n if (enter) {\n acc.push('\\n')\n }\n return acc\n }, [])\n\n return { shareTemplateTranslationKey: `${shareTemplateTranslationKey}-${gameType.replace(/_/g, '-').toLowerCase()}`, visual: squareArr.join(''), tries: rows }\n }\n\n return { shareTemplateTranslationKey }\n}\n","import React, { useContext } from 'react'\nimport translationGroups from 'client/constants/translationGroups'\nimport TranslationContext from 'client/contexts/TranslationContext'\n\nconst ClueBarSeeImageComponent = () => {\n const { getTranslation } = useContext(TranslationContext)\n return (\n <>\n { getTranslation(translationGroups.clueBar, 'see-image')}\n </>\n )\n}\n\nexport default ClueBarSeeImageComponent\n","import { Player } from 'client/types/Player'\nimport React from 'react'\n\ninterface Props {\n player: Player\n className?: string\n}\n\nconst PlayerAvatarComponent = ({ player, className }: Props) => {\n const username = player.displayName\n return (\n <div className={`avatar player-avatar player-avatar--player-${player.playerNumber} ${className ?? ''}`}>\n <div className=\"avatar__letter\">{Array.from(username ?? '')[0]?.toUpperCase()}</div>\n </div>\n )\n}\n\nexport default PlayerAvatarComponent\n","import React, { useContext } from 'react'\nimport IconAdd from 'assets/icons/icon_add.svg'\nimport ButtonComponent, { type Props } from 'common_packages/assets/js/components/ButtonComponent'\nimport { store } from 'client/store'\nimport { getAbilities } from 'client/hooks/useAbilities'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport * as timerActions from 'common_packages/assets/js/actions/timerActions'\nimport { useDispatch } from 'react-redux'\nimport useShareDialog from 'client/hooks/useShareDialog'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\n\nconst PuzzleInviteButtonComponent = (props: Props) => {\n const { roles } = store.getState().user\n const { canInvite } = getAbilities(roles)\n\n const dispatch = useDispatch()\n const className = `puzzle-header__invite-button ${props.className ?? ''}`\n const { openShareDialog } = useShareDialog()\n\n const { getRawTranslation, getTranslation } = useContext(TranslationContext)\n\n const handleInviteClick = async () => {\n dispatch(timerActions.pauseTimer())\n dispatch(uiActions.closeDrawer()) // close the 'player list' drawer, if needed\n openShareDialog('mp-invite', getRawTranslation(translationGroups.invite, 'share-this'), getRawTranslation(translationGroups.invite, 'click-here-to-join'))\n }\n\n if (!canInvite) return null\n return (\n <ButtonComponent {...props} onClick={handleInviteClick} type=\"button\" className={className}>\n <IconAdd className=\"puzzle-header__add-icon\" />\n { getTranslation(translationGroups.invite, 'invite-button') }\n </ButtonComponent>\n )\n}\n\nexport default PuzzleInviteButtonComponent\n","import React, { useContext } from 'react'\nimport { isDesktop } from 'react-device-detect'\nimport IconRotateDevice from 'client/assets/icons/icon_rotate_device.svg'\nimport TranslationContext from 'client/contexts/TranslationContext'\nimport translationGroups from 'client/constants/translationGroups'\n\nconst RotateScreenComponent = () => {\n const { getTranslation } = useContext(TranslationContext)\n if (isDesktop) {\n // media query should handle most cases, but when it doesnt...\n return null\n }\n\n return (\n <div className=\"overlay rotate-screen\">\n <div className=\"rotate-screen__icon\">\n <IconRotateDevice />\n </div>\n <div className=\"rotate-screen__title\">\n { getTranslation(translationGroups.rotateScreen, 'title')}\n </div>\n <div className=\"rotate-screen__instructions\">\n { getTranslation(translationGroups.rotateScreen, 'instructions')}\n </div>\n </div>\n )\n}\n\nexport default RotateScreenComponent\n","import { type Dispatch } from 'redux'\nimport { type ApiResult, klubbleAPI } from 'client/api/common'\nimport { type Player } from 'client/types/Player'\nimport { rethrowError } from 'client/utilities/error'\nimport { type GameroomMessageType, type Selection } from '../reducers/gameroomReducer'\n\nexport const SET_CONNECTION_DATA = 'SET_CONNECTION_DATA'\nexport const SET_SELECTION = 'SET_SELECTION'\nexport const RESET_SELECTION = 'RESET_SELECTION'\nexport const ADD_TO_UNSENT_GUESSES_QUEUE = 'ADD_TO_UNSENT_GUESSES_QUEUE'\nexport const CLEAR_UNSENT_GUESSES_QUEUE = 'CLEAR_UNSENT_GUESSES_QUEUE'\nexport const SET_PLAYER_CONTRIBUTIONS = 'SET_PLAYER_CONTRIBUTIONS'\nexport const SET_PLAYER_LIST = 'SET_PLAYER_LIST'\nexport const ADD_MESSAGE = 'ADD_MESSAGE'\nexport const DISMISS_MESSAGE = 'DISMISS_MESSAGE'\nexport const SEND_GAMEROOM_GUESSES = 'SEND_GAMEROOM_GUESSES'\n\nexport type DefaultSpecialCellIdentifiers = 'reset' | 'timer'\n\nexport type GameroomGuess<TGuess = unknown, TSpecialCellIdentifiers = DefaultSpecialCellIdentifiers> = ({\n cellIdentifier: string\n correctAnswer: boolean\n hintsUsed: number\n} & TGuess) | {\n cellIdentifier: TSpecialCellIdentifiers\n}\n\nexport type GameroomGuessPayload<TGuess = unknown, TSpecialCellIdentifiers = DefaultSpecialCellIdentifiers> = {\n guesses: GameroomGuess<TGuess, TSpecialCellIdentifiers>[]\n}\n\ntype AddGameroomMessagePayload = {\n type: GameroomMessageType\n content: string\n sender: Player\n}\n\ntype DismissGameroomMessagePayload = {\n id: string\n}\n\ntype GetPlayerListResponse = ApiResult<{\n players: Player[]\n}>\n\n// TGuess describes the guess data we're going to send (in addition to cellIdentifier)\nexport type GameroomAction<TGuess = unknown> = {\n type: typeof SET_SELECTION\n payload: Selection\n} | {\n type: typeof RESET_SELECTION\n} | {\n type: typeof INCREMENT_SENDING_GUESSSES_AMOUNT,\n} | {\n type: typeof DECREMENT_SENDING_GUESSSES_AMOUNT,\n} | {\n type: typeof ADD_TO_UNSENT_GUESSES_QUEUE,\n payload: GameroomGuessPayload<TGuess>[]\n} | {\n type: typeof CLEAR_UNSENT_GUESSES_QUEUE,\n} | {\n type: typeof SET_PLAYER_CONTRIBUTIONS,\n payload: Player[]\n} | {\n type: typeof SET_PLAYER_LIST,\n payload: Player[]\n} | {\n type: typeof ADD_MESSAGE,\n payload: AddGameroomMessagePayload\n} | {\n type: typeof DISMISS_MESSAGE,\n payload: DismissGameroomMessagePayload\n} | {\n type: typeof SEND_GAMEROOM_GUESSES\n payload: GameroomGuessPayload<TGuess>\n}\n\nexport const setSelection = (payload: Selection): GameroomAction => ({\n type: SET_SELECTION,\n payload,\n})\n\nexport const resetSelection = (): GameroomAction => ({\n type: RESET_SELECTION,\n})\n\nexport const addToUnsentGuessesQueue = <TGuess>(payload: GameroomGuessPayload<TGuess>[]): GameroomAction<TGuess> => ({\n type: ADD_TO_UNSENT_GUESSES_QUEUE,\n payload,\n})\n\nexport const clearUnsentGuessesQueue = (): GameroomAction => ({\n type: CLEAR_UNSENT_GUESSES_QUEUE,\n})\n\n/**\n * Fetches player list for puzzle and stores it in redux\n * @param puzzleInstanceId\n */\nexport const fetchPlayerList = (puzzleInstanceId: number) => async (dispatch: Dispatch<GameroomAction>) => {\n try {\n const { data: responseData } = await klubbleAPI.post<GetPlayerListResponse>('Puzzle/getplayerlist', { puzzleInstanceId }, {\n headers: {\n 'Content-Type': 'application/json',\n },\n })\n if (responseData?.success) {\n dispatch({\n type: SET_PLAYER_LIST,\n payload: responseData.data?.players ?? [],\n })\n }\n } catch (e) {\n rethrowError(e, 'Error getting playerlist')\n }\n}\n\nexport const addMessage = (content: string, sender: Player, type: GameroomMessageType = 'express') => (dispatch: Dispatch<GameroomAction>) => {\n dispatch({\n type: ADD_MESSAGE,\n payload: {\n content,\n sender,\n type,\n },\n })\n}\n\nexport const dismissMessage = (id: string) => (dispatch: Dispatch<GameroomAction>) => {\n dispatch({\n type: DISMISS_MESSAGE,\n payload: {\n id,\n },\n })\n}\n\nconst sendGameroomGuessesAction = <TGuess>(payload: GameroomGuessPayload<TGuess>): GameroomAction<TGuess> => ({\n type: SEND_GAMEROOM_GUESSES,\n payload,\n})\n\nexport const sendGameroomGuesses = <TGuess>(payload: GameroomGuessPayload<TGuess>) => (dispatch: Dispatch<GameroomAction<TGuess>>) => {\n dispatch(sendGameroomGuessesAction<TGuess>(payload))\n}\n","/* eslint-disable no-console */\nimport * as signalR from '@microsoft/signalr'\nimport { type Dispatch, type AnyAction, type Store } from 'redux'\nimport { executeCellAction } from 'client/player/js/actions/actionServices/cellActionServices'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\nimport * as uiActions from 'common_packages/assets/js/actions/uiActions'\nimport { type TStore } from 'common_packages/assets/js/types/TDispatch'\nimport { klubbleAPI } from 'client/api/common'\nimport { gameStatus } from 'common_packages/assets/js/types/gameStatusTypes'\nimport * as timerActions from 'common_packages/assets/js/actions/timerActions'\nimport { type Expression } from 'client/pages/common/components/drawer/express/DrawerContentExpressComponent'\nimport { type Player } from 'client/types/Player'\nimport uniqueid from 'uniqid'\nimport { type GameroomGuessCell, type GameroomGuessesPayload } from 'common_packages/assets/js/actions/types'\nimport { type KlubblePuzzleWithSelectionStoreState } from '../types/store'\nimport {\n type GameroomGuessPayload,\n addToUnsentGuessesQueue,\n fetchPlayerList,\n setSelection,\n SET_PLAYER_CONTRIBUTIONS,\n clearUnsentGuessesQueue,\n addMessage,\n} from './actions/gameroomActions'\nimport { ProcessFinishedPuzzle } from '../components/PlayerComponent'\n\nconst SAVE_TIMER_INTERVAL = 1000 * 30\n\nexport type GameroomActions = {\n gameroomGuessesAction: (payload: GameroomGuessesPayload, store: TStore<AnyAction, KlubblePuzzleWithSelectionStoreState>) => (dispatch: Dispatch<AnyAction>) => void\n}\n\ntype GuessesList = { stepId: string, cellIdentifier: string }[]\n\ntype ExpressionDto = {\n expression: Expression\n playerNumber: number\n puzzleInstanceId: number\n userName: string\n}\n\nclass GameroomConnection {\n // Public\n\n /** Creates the gameroom connection. Will resolve the promise once signlR connection is open and everything is set up */\n async create(\n puzzleInstanceId: number,\n userId: number,\n playerNumber: number,\n seenEndScreen: boolean,\n isMultiPlayerQR: boolean,\n justStarted: boolean,\n store: Store<KlubblePuzzleWithSelectionStoreState>,\n gameroomActions: GameroomActions,\n processFinishPuzzle: (puzzleStore: Store<KlubblePuzzleWithSelectionStoreState>) => void,\n ) {\n // kill a possible existing connection\n this.closeConnection()\n\n this.puzzleInstanceId = puzzleInstanceId\n this.userId = userId\n this.playerNumber = playerNumber\n this.seenEndScreen = seenEndScreen\n this.isMultiPlayerQR = isMultiPlayerQR\n this.justStarted = justStarted\n this.store = store\n this.gameroomActions = gameroomActions\n this.processFinishPuzzle = processFinishPuzzle\n\n this.createSignalRHubConnection()\n\n this.attachConnectionEventListeners()\n\n // Start the signalRHub connection\n try {\n await this.connection.start()\n await this.subscribeToRoom(true)\n\n /* Save timer to server every 30 seconds, just to keep the time sort of up to date on the server,\n in case someone leaves a puzzle open for a long time in one browser/device and opens the puzzle\n in another browser/device to solve it there (very hypothetical, but just in case).\n */\n\n this.saveServerTimerIntervalId = setInterval(this.saveTimerToServer, SAVE_TIMER_INTERVAL)\n } catch (err) {\n console.error(err.toString())\n throw err\n }\n }\n\n getPlayerNumber() {\n return this.playerNumber\n }\n\n getIsMultiPlayerQR() {\n return this.isMultiPlayerQR\n }\n\n getSeenEndScreen() {\n return this.seenEndScreen\n }\n\n getJustStarted() {\n return this.justStarted\n }\n\n async addGuesses(guesses: Array<GameroomGuessPayload>) {\n const { counter } = this.store.getState().timer\n const formattedGuesses = guesses.map((g) => this.formatGuess(g, counter))\n try {\n await klubbleAPI.post('/Puzzle/addGuesses', formattedGuesses)\n // Looks like we are connected here, good opportunity to send unsend guesses, if any.\n this.processUnsentGuesses()\n } catch (e) {\n this.store.dispatch(addToUnsentGuessesQueue(formattedGuesses))\n throw new Error()\n }\n }\n\n async syncPuzzleState(isFirstFetch?: boolean) {\n /* When we decide to sync the puzzle state we don't care about any incoming guesses anymore before we fetch the full\n * state, since they will be in the full state anyway. We unlock newGuesses after we have fetched the full state,\n * in getGuesses.\n */\n this.newGuessesLocked = true\n\n await this.processUnsentGuesses()\n\n // Possibly sending any unsent guesses above failed. In that case we won't process a finished puzzle or get guesses from the server.\n // TODO: what if processUnsentGuesses failed? show error modal?\n if (!this.store.getState().gameroom.unsentGuessesQueue.length) {\n if (this.store.getState().gameStatus.status === gameStatus.IS_SOLVED && !this.seenEndScreen) {\n // Scenario 3, 5 in https://keesingdigital.atlassian.net/wiki/spaces/K/pages/214204417/Showing+the+endscreen\n this.processFinishPuzzle(this.store)\n } else {\n await this.getGuesses(true, isFirstFetch)\n }\n }\n }\n\n async sendExpression(expression: Expression) {\n const players = this.store.getState().gameroom.players ?? []\n const userName = players.find((p) => p.playerNumber === this.playerNumber)?.displayName ?? '?'\n\n const expressionDto = {\n playerNumber: this.playerNumber,\n userName,\n puzzleinstanceId: +this.puzzleInstanceId,\n expression,\n }\n if (!this.connection || this.connection.state !== signalR.HubConnectionState.Connected) {\n return\n }\n await this.connection.invoke('SendExpression', expressionDto).catch((err) => {\n // eslint-disable-next-line no-console\n console.error(err.toString())\n })\n }\n\n async sendSelection(selectedCellIndex: number) {\n const selectionDto = {\n puzzleinstanceId: +this.puzzleInstanceId,\n selection: JSON.stringify(selectedCellIndex),\n playerNumber: this.playerNumber,\n }\n if (!this.connection || this.connection.state !== signalR.HubConnectionState.Connected) {\n return\n }\n await this.connection.invoke('SetSelection', selectionDto).catch((err) => {\n // eslint-disable-next-line no-console\n console.error(err.toString())\n })\n }\n\n saveTimerToServer = () => {\n if (!this.store) {\n return\n }\n\n if (this.store.getState().gameStatus.status === gameStatus.IS_SOLVED) {\n // Puzzle has been solved, stop saving the time to the server\n clearTimeout(this.saveServerTimerIntervalId)\n return\n }\n\n const { qrLocationGuid } = this.store.getState().gameInfo\n const { counter } = this.store.getState().timer\n // this is not added to the queue...\n if (!qrLocationGuid) {\n try {\n klubbleAPI.post('/Puzzle/addGuesses', [this.formatGuess({ cellIdentifier: 'timer' }, counter)])\n } catch (e) {\n console.error(`error saving time to server ${e}`)\n }\n }\n }\n\n async closeConnection() {\n clearTimeout(this.saveServerTimerIntervalId)\n this.connection?.stop()\n }\n\n // Private\n private connection: signalR.HubConnection\n\n private puzzleInstanceId: number\n\n private userId: number\n\n private playerNumber: number\n\n private seenEndScreen: boolean\n\n private isMultiPlayerQR: boolean\n\n private justStarted = false\n\n private store: TStore<AnyAction, KlubblePuzzleWithSelectionStoreState>\n\n private gameroomActions: GameroomActions\n\n private processFinishPuzzle: ProcessFinishedPuzzle\n\n private guessCount = 0\n\n private ownSentGuesses: GuessesList\n\n private newGuessesLocked = false\n\n private connectionLostTimeoutId: ReturnType<typeof setTimeout> = null\n\n private retryIntervalId: ReturnType<typeof setInterval> = null\n\n private saveServerTimerIntervalId: ReturnType<typeof setInterval> = null\n\n private selectionTimeoutIds: { [key: number]: ReturnType<typeof setTimeout> } = {}\n\n private createSignalRHubConnection() {\n this.connection = new signalR.HubConnectionBuilder()\n .withUrl(`${process.env.KLUBBLE_API_BASE_PATH}/guesshub`)\n .configureLogging(signalR.LogLevel.Information)\n .withAutomaticReconnect({\n nextRetryDelayInMilliseconds: (retryContext) => {\n switch (retryContext.previousRetryCount) {\n case 0:\n return 0\n case 1:\n return 2000\n default:\n return 5000\n }\n },\n })\n .build()\n }\n\n private async subscribeToRoom(isFirstFetch?: boolean) {\n /* After (re)connecting we might have newGuesses incoming before we fetch the full state. So we lock\n * newGuesses to prevent these guesses from being processed (and potentially calling getGuesses a second time).\n */\n this.newGuessesLocked = true\n\n // Just in case we're stuck in the 'connection lost' loop\n this.cleanupConnectionLost()\n\n try {\n await this.connection.invoke('SubscribeRoom', {\n gameroomId: this.puzzleInstanceId,\n playerNumber: this.playerNumber,\n userId: `${this.userId}`,\n connectionId: this.connection.connectionId,\n })\n } catch (err) {\n console.error(err.toString())\n }\n\n await this.syncPuzzleState(isFirstFetch)\n }\n\n private attachConnectionEventListeners() {\n if (!this.connection) {\n throw new Error('No connection found')\n }\n const offlineHandler = () => this.handleConnectionLost()\n window.addEventListener('offline', offlineHandler)\n\n const unloadHandler = () => {\n window.removeEventListener('beforeunload', unloadHandler)\n this.saveTimerToServer()\n }\n window.addEventListener('beforeunload', unloadHandler)\n\n this.connection.on('playercontributions', (playerContributions) => {\n this.store.dispatch({\n type: SET_PLAYER_CONTRIBUTIONS,\n payload: playerContributions,\n })\n })\n\n this.connection.on('newguess', (guess, count) => {\n if (!this.newGuessesLocked) {\n const parsedGuess = { ...JSON.parse(guess?.stepJson ?? '{}') }\n this.updateLocalTime(parsedGuess.time)\n const ownGuessIndex = this.ownSentGuesses.findIndex((item) => item.stepId === parsedGuess.stepId)\n\n if (this.guessCount < count - 1) {\n // would only come here if we missed newguess without the connection going offline\n this.syncPuzzleState()\n } else if (guess?.stepJson) {\n // Don't process own guesses. Don't process others' guesses that are already overwritten by your own guess on the server.\n if (ownGuessIndex === -1 && !this.ownSentGuesses.some((item) => item.cellIdentifier === guess.cellIdentifier)) {\n if (guess.cellIdentifier !== 'timer') {\n this.storeGuesses([{ ...parsedGuess, cellIdentifier: guess.cellIdentifier }], false)\n }\n // Own guess is received back so we don't have to pay attention for this guess anymore.\n } else if (ownGuessIndex !== -1) {\n this.ownSentGuesses.splice(ownGuessIndex, 1)\n }\n }\n\n this.guessCount = count\n }\n })\n this.connection.on('finishPuzzle', () => {\n if (this.store.getState().gameStatus.status !== gameStatus.IS_SOLVED && this.store.getState().gameStatus.status !== gameStatus.SHOW_RESULT) {\n this.syncPuzzleState()\n }\n })\n this.connection.on('roomChanged', (activePlayerList: number[]) => {\n activePlayerList.forEach((playerNum) => this.clearSelectionTimeoutId(playerNum))\n this.clearSelectionInactivePlayers(activePlayerList)\n this.store.dispatch(fetchPlayerList(this.puzzleInstanceId))\n\n // Send selection here so the new player immediately receives the selection of all players.\n if (this.store.getState()?.selection?.selectedCellIndex !== null) {\n this.sendSelection(this.store.getState()?.selection?.selectedCellIndex)\n }\n })\n this.connection.on('SetSelection', (selectionDto) => {\n const incomingPlayerNumber = selectionDto.playerNumber\n if (incomingPlayerNumber !== this.playerNumber && !(this.isMultiPlayerQR && incomingPlayerNumber === 1)) {\n this.store.dispatch(setSelection({\n playerNumber: incomingPlayerNumber,\n selectedCell: JSON.parse(selectionDto.selection) ?? undefined,\n }))\n }\n })\n this.connection.on('SendExpression', (expressionDto: ExpressionDto) => {\n // Received an expression\n const sender: Player = {\n playerNumber: expressionDto.playerNumber,\n displayName: expressionDto.userName,\n }\n this.store.dispatch(addMessage(expressionDto.expression, sender, 'express'))\n })\n this.connection.onreconnected(() => {\n this.subscribeToRoom()\n })\n this.connection.onreconnecting((_error) => {\n this.handleConnectionLost()\n })\n this.connection.onclose((_error) => {\n // clean up\n this.ownSentGuesses = []\n Object.keys(this.selectionTimeoutIds).forEach((key) => this.clearSelectionTimeoutId(+key))\n this.selectionTimeoutIds = {}\n this.cleanupConnectionLost()\n window.removeEventListener('offline', offlineHandler)\n window.removeEventListener('beforeunload', unloadHandler)\n })\n }\n\n storeGuesses(guesses: GameroomGuessCell[], isFirstFetch: boolean) {\n if (guesses.length && this.gameroomActions) {\n const payload: GameroomGuessesPayload = {\n cells: [...guesses],\n isFirstFetch,\n }\n this.store.dispatch(this.gameroomActions.gameroomGuessesAction(payload, this.store))\n }\n }\n\n private async getGuesses(updateTimer = false, isFirstFetch = false) {\n if (this.puzzleInstanceId) {\n try {\n const result = await this.connection.invoke('RequestFullState', this.puzzleInstanceId)\n this.newGuessesLocked = false\n this.ownSentGuesses = []\n\n // Save guesses to redux\n if (result) {\n // filter out the 'guess' with cellIdentifier 'timer' since this is a saved timer value, not a actual guess\n const parsedGuesses = result.guesses?.filter((guess) => guess.cellIdentifier !== 'timer').map((guess) => ({ ...JSON.parse(guess.stepJson), cellIdentifier: guess.cellIdentifier }))\n await this.storeGuesses(parsedGuesses, isFirstFetch)\n this.guessCount = result.count\n if (updateTimer) {\n // get the max time from all the 'guesses', so including the time from the guesses with cellIdentifier 'timer'\n const time = Math.max(...(result.guesses ?? []).map((guessVal) => JSON.parse(guessVal.stepJson).time), 0)\n this.updateLocalTime(time)\n }\n }\n\n if (this.store.getState().gameStatus.status === gameStatus.IS_SOLVED) {\n this.closeConnection()\n }\n } catch (err) {\n console.error(err.toString())\n }\n }\n }\n\n private formatGuess({\n cellIdentifier = null,\n cellIndex = null,\n value = null,\n notes = null,\n status = null,\n locked = null,\n codeNumber = null,\n originCell = null, // for hashi\n destinationCell = null, // for hashi\n blockId = null, // for blockpuzzle\n regionIndex = null, // for blockpuzzle\n correctAnswer = null,\n cellData = null,\n bridgeCount = null, // for hashi\n isCrossedOff = null, // for nonogram edge cells\n hintsUsed = 0,\n }, time: number) {\n const date = new Date()\n const stepId = uniqueid()\n const step = {\n cellIndex,\n value,\n notes,\n status,\n locked,\n codeNumber,\n originCell,\n destinationCell,\n blockId,\n regionIndex,\n cellData,\n bridgeCount,\n isCrossedOff,\n playerNumber: this.playerNumber,\n time,\n stepId,\n }\n const stepJson = JSON.stringify(\n Object.entries(step).reduce((acc, [key, v]) => {\n if (v === null) {\n return acc\n }\n return {\n ...acc,\n [key]: v,\n }\n }, {}),\n )\n this.ownSentGuesses.push({ stepId, cellIdentifier })\n\n // todo: type for this?\n const obj = {\n puzzleInstanceId: this.puzzleInstanceId,\n stepDateTime: date.toISOString(),\n cellIdentifier,\n stepJson,\n }\n\n if (cellIdentifier === 'timer') {\n return obj\n }\n\n return { ...obj, hintsUsed, checkSum: createCheckSum(correctAnswer) }\n }\n\n /* Since the timer.tick function is not executed at the exact same time for all players,\n * we allow small differences in the timer value. That's why we only update the timer if\n * it's more than one second behind another player.\n */\n private updateLocalTime = (time: number) => {\n const { counter } = this.store.getState().timer\n\n if (time > counter + 1) {\n this.store.dispatch(timerActions.setTimer(time))\n }\n }\n\n private async processUnsentGuesses() {\n const { unsentGuessesQueue } = this.store.getState().gameroom\n\n if (unsentGuessesQueue?.length > 0) {\n try {\n await klubbleAPI.post('/Puzzle/addGuesses', unsentGuessesQueue)\n // remove guesses from queue in redux\n this.store.dispatch(clearUnsentGuessesQueue())\n } catch {\n // optionally, show message to user here\n }\n }\n }\n\n private handleConnectionLost() {\n if (this.store.getState().gameroom.players?.length > 1) {\n clearTimeout(this.connectionLostTimeoutId)\n clearInterval(this.retryIntervalId)\n this.connectionLostTimeoutId = setTimeout(() => this.freezeGame(), 2000)\n this.retryIntervalId = setInterval(() => {\n if (this.connection.state === signalR.HubConnectionState.Connected && navigator.onLine) {\n this.cleanupConnectionLost()\n }\n }, 1000)\n }\n }\n\n private freezeGame() {\n // delete any guesses that are possibly inside unsent guesses array and remove them from the grid\n const { unsentGuessesQueue } = this.store.getState().gameroom ?? {}\n if (unsentGuessesQueue.length) {\n // remove unsentGuesses from grid and queue\n const cellIndices = unsentGuessesQueue.map((guess) => JSON.parse(guess?.stepJson)?.cellIndex)\n this.store.dispatch(executeCellAction('clearCells', { cellIndices, skipAddGuessToServer: true }))\n this.store.dispatch(clearUnsentGuessesQueue())\n this.ownSentGuesses = []\n }\n this.store.dispatch(uiActions.setDrawer({\n drawer: drawerTypes.GENERIC_ERROR,\n drawerData: {\n contentTranslationKey: 'error-message-connection-lost',\n hideButton: true,\n },\n forceModal: true,\n hideClose: true,\n hideHeader: true,\n }))\n }\n\n private cleanupConnectionLost() {\n clearTimeout(this.connectionLostTimeoutId)\n clearInterval(this.retryIntervalId)\n\n this.connectionLostTimeoutId = null\n this.store.dispatch(uiActions.closeDrawer())\n }\n\n private clearSelectionInactivePlayers(activePlayerList) {\n const selection = this.store.getState()?.gameroom.selection\n\n const nonActivePlayersWithSelection = selection.filter(({ playerNumber: num, selectedCell }) => selectedCell !== null && !activePlayerList.includes(num))\n nonActivePlayersWithSelection.forEach(({ playerNumber: playerNum }) => {\n this.clearSelectionTimeoutId(playerNum)\n this.selectionTimeoutIds[playerNum] = setTimeout(() => {\n this.store.dispatch(setSelection({\n playerNumber: playerNum,\n selectedCell: undefined,\n }))\n }, 10000)\n })\n }\n\n private clearSelectionTimeoutId(playerNum: number) {\n const timeoutId = this.selectionTimeoutIds[playerNum]\n if (timeoutId) {\n clearTimeout(timeoutId)\n }\n this.selectionTimeoutIds[playerNum] = null\n }\n}\n\nconst gameroomConnection = new GameroomConnection()\nexport default gameroomConnection\n\nfunction createCheckSum(correctAnswer: boolean) {\n // For a correct answer, return a number divisible by 7\n const checkSum = Math.round(Math.random() * 10000)\n const checkSumRemainder = checkSum % 7\n if (correctAnswer) {\n return checkSum - checkSumRemainder\n }\n // For an incorrect answer, make sure to return a number not divisible by 7\n return (checkSumRemainder === 0) ? checkSum + 1 : checkSum\n}\n","import { store as klubbleStore } from 'client/store'\nimport { setDrawer } from 'common_packages/assets/js/actions/uiActions'\nimport { drawerTypes } from 'common_packages/assets/js/types/drawerTypes'\n\n/*\n * General ui blocking 'puzzle cannot be started' modal, if starting puzzle fails,\n * clicking 'ok' -> history.push('/) prevents that the user can play the puzzle when startpuzzle call failed somehow.\n */\nexport const showCannotStartPuzzleDrawer = () => {\n klubbleStore.dispatch(setDrawer({\n drawer: drawerTypes.CANNOT_START_PUZZLE,\n drawerData: { blockPlayer: true },\n modalAutoGrow: true,\n forceModal: true,\n hideHeader: true,\n hideClose: true,\n }))\n}\n","import { type GameType } from 'common_packages/assets/js/types/gameDataTypes'\n\nexport const getPersistKey = (gameType: GameType, puzzleId: string, language: string, klubblePuzzleId: number, userId: number) => {\n return `${gameType},${puzzleId},${language}${klubblePuzzleId}-${userId}`\n}\n","import { type AnyAction } from 'redux'\n\nexport type NotificationsState = NotificationState[]\nexport type NotificationIconType = 'klubble' | 'smile' | 'puzzle'\n\nexport type NotificationState = {\n author: string\n langKey: string\n unread?: boolean\n date: number\n icon?: NotificationIconType\n image?: string\n}\n\nconst initialState = [{\n author: 'Daniel Sanchez',\n langKey: 'invited you to help solve a Crossword Classic',\n date: new Date('Fri, 30 Apr 2021 11:16:15 GMT').getTime(),\n unread: true,\n icon: 'klubble' as const,\n}, {\n author: 'Nikki Coleman',\n langKey: 'sent you a friend invite',\n date: new Date('Fri, 30 Apr 2021 11:00:15 GMT').getTime(),\n unread: true,\n icon: 'smile' as const,\n}, {\n author: 'Klubble Nederland',\n langKey: 'just released a new puzzle ',\n date: new Date('Fri, 28 Apr 2021 11:00:15 GMT').getTime(),\n icon: 'puzzle' as const,\n}]\n\n// eslint-disable-next-line default-param-last\nexport const notificationsReducer = (state: NotificationsState = initialState, actions: AnyAction): NotificationsState => {\n switch (actions.type) {\n default:\n return state\n }\n}\n","import { type Reducer } from 'redux'\nimport { type SettingsAction } from 'client/actions/types'\nimport * as settingTypes from 'client/actions/settingActions'\n\nexport type SettingsStoreState = {\n language?: string\n showTimer: boolean\n skipCompletedLetters: boolean\n skipCelebration: boolean\n}\n\nconst initialState = {\n language: 'nl',\n showTimer: true,\n skipCompletedLetters: true,\n skipCelebration: false,\n}\n\n// eslint-disable-next-line default-param-last\nexport const settingsReducer: Reducer<SettingsStoreState, SettingsAction> = (state = initialState, action) => {\n switch (action.type) {\n case settingTypes.SET_LANGUAGE:\n return {\n ...state,\n language: action.payload,\n }\n\n case settingTypes.SET_SETTINGS: {\n return {\n ...state,\n ...action.payload,\n }\n }\n\n default:\n return state\n }\n}\n","import { type Reducer } from 'redux'\nimport * as puzzleDataActions from 'client/actions/puzzleDataActions'\nimport { type IPuzzleCalendar } from 'client/interfaces/IPuzzleCalendar'\nimport { type FinishedPuzzle } from 'client/types/FinishedPuzzle'\nimport { type FeaturedPuzzleType } from 'client/types/FeaturedPuzzleType'\nimport { type PuzzleDataAction } from 'client/actions/types'\nimport { type ContinuePlayingPuzzleType } from 'client/types/ContinuePlayingPuzzleType'\nimport { type PuzzlePackType } from 'client/types/PuzzlePackType'\nimport { type PuzzlePack } from 'client/types/PuzzlePack'\nimport { puzzleSortingEnum } from '../enums/puzzleData'\nimport { type DailyDose, type DailyDoseType } from '../types/DailyDose'\nimport { type PuzzleType } from '../types/PuzzleType'\n\nexport type PuzzleDataState = {\n puzzleTypes: PuzzleType[]\n puzzlePackTypes: PuzzlePackType[]\n puzzlePacks: PuzzlePack[]\n loadingFeaturedPuzzles: boolean\n featuredPuzzleTypes: FeaturedPuzzleType[]\n loadingContinuePlayingPuzzleTypes: boolean\n continuePlayingPuzzleTypes: ContinuePlayingPuzzleType[]\n finishedPuzzle: FinishedPuzzle\n currentPuzzleCalendar: IPuzzleCalendar\n puzzleSorting: puzzleSortingEnum\n dailyDoses: DailyDose[]\n dailyDoseTypes: DailyDoseType[]\n dailyDoseSelectedDate: string\n}\n\nconst initialState: PuzzleDataState = {\n puzzleTypes: [],\n puzzlePackTypes: [],\n puzzlePacks: [],\n loadingFeaturedPuzzles: false,\n featuredPuzzleTypes: [],\n loadingContinuePlayingPuzzleTypes: false,\n continuePlayingPuzzleTypes: [],\n finishedPuzzle: {\n puzzleTypeId: undefined,\n klubblePuzzleId: undefined,\n nameLangKey: undefined,\n date: undefined,\n time: undefined,\n mainType: undefined,\n format: undefined,\n shareTemplateTranslationKey: undefined,\n tries: undefined,\n visual: undefined,\n isFreePuzzle: false,\n isMultiPlayerQR: false,\n qrLocationGuid: undefined,\n nextDay: undefined,\n recentDays: [],\n scoringBadges: [],\n playerContributions: [],\n },\n currentPuzzleCalendar: {\n puzzleTypeId: null,\n },\n puzzleSorting: puzzleSortingEnum.alphabetical,\n dailyDoses: [],\n dailyDoseTypes: [],\n dailyDoseSelectedDate: null,\n}\n\n// eslint-disable-next-line default-param-last\nexport const puzzleDataReducer: Reducer<PuzzleDataState, PuzzleDataAction> = (state = initialState, action) => {\n switch (action.type) {\n case puzzleDataActions.SET_PUZZLE_TYPES:\n\n return {\n ...state,\n puzzleTypes: action.payload,\n }\n\n case puzzleDataActions.SET_PUZZLE_PACKS:\n return {\n ...state,\n puzzlePackTypes: action.payload.puzzlePackTypes,\n puzzlePacks: action.payload.puzzlePacks,\n }\n\n case puzzleDataActions.SET_FAVORITE_PUZZLE_PACK_TYPE:\n return {\n ...state,\n puzzlePackTypes: state.puzzlePackTypes\n .map((puzzlePackType) => (puzzlePackType.id === action.payload.puzzlePackTypeId ? { ...puzzlePackType, isFavorite: action.payload.isFavorite } : puzzlePackType)),\n }\n\n case puzzleDataActions.SET_SELECTED_LEVEL_PUZZLE_PACK_TYPE:\n return {\n ...state,\n puzzlePackTypes: state.puzzlePackTypes\n .map((puzzlePackType) => (puzzlePackType.id === action.payload.puzzlePackTypeId ? { ...puzzlePackType, selectedLevel: action.payload.selectedLevel } : puzzlePackType)),\n }\n\n case puzzleDataActions.LOADING_FEATURED_PUZZLES:\n return {\n ...state,\n loadingFeaturedPuzzles: action.payload,\n }\n\n case puzzleDataActions.SET_FEATURED_PUZZLES:\n return {\n ...state,\n featuredPuzzleTypes: action.payload,\n }\n\n case puzzleDataActions.LOADING_CONTINUE_PLAYING_PUZZLE_TYPES:\n return {\n ...state,\n loadingContinuePlayingPuzzleTypes: action.payload,\n }\n\n case puzzleDataActions.SET_CONTINUE_PLAYING_PUZZLE_TYPES:\n return {\n ...state,\n continuePlayingPuzzleTypes: action.payload,\n }\n\n case puzzleDataActions.SET_PUZZLE_CALENDAR: {\n const {\n puzzleTypeId, daysPerLevel, iconUrl, nameLangKey,\n } = action.payload\n\n return {\n ...state,\n currentPuzzleCalendar: {\n puzzleTypeId, daysPerLevel, iconUrl, nameLangKey,\n },\n }\n }\n\n case puzzleDataActions.SET_FINISHED_PUZZLE: {\n const {\n puzzleTypeId,\n klubblePuzzleId,\n nameLangKey,\n date,\n time,\n format,\n shareTemplateTranslationKey,\n tries,\n visual,\n isFreePuzzle,\n isMultiPlayerQR,\n qrLocationGuid,\n nextDay,\n recentDays,\n scoringBadges,\n playerContributions,\n puzzlePackId,\n puzzlePackPercentageProgress,\n nextPuzzle,\n } = action.payload\n\n return {\n ...state,\n finishedPuzzle: {\n puzzleTypeId,\n klubblePuzzleId,\n nameLangKey,\n date,\n time,\n format,\n shareTemplateTranslationKey,\n tries,\n visual,\n isFreePuzzle,\n isMultiPlayerQR,\n qrLocationGuid,\n nextDay,\n recentDays,\n scoringBadges,\n playerContributions,\n puzzlePackId,\n puzzlePackPercentageProgress,\n nextPuzzle,\n },\n }\n }\n\n case puzzleDataActions.SET_PUZZLE_SORTING:\n return {\n ...state,\n puzzleSorting: action.payload,\n }\n\n case puzzleDataActions.SAVE_PUZZLE_SETTINGS: {\n /* Optimistically update puzzletypes */\n const newPuzzleTypes = state.puzzleTypes.reduce((array, puzzleItem) => {\n let puzzle = puzzleItem\n if (action.payload.puzzleTypeId === puzzle.puzzleTypeId) {\n puzzle = { ...puzzle, ...action.payload }\n }\n\n array.push(puzzle)\n return array\n }, [])\n\n return {\n ...state,\n puzzleTypes: newPuzzleTypes,\n }\n }\n\n case puzzleDataActions.SAVE_PUZZLE_SETTINGS_BATCH: {\n if (!action.payload.length) {\n return state\n }\n const puzzleTypes = state.puzzleTypes.reduce((acc, value) => {\n const update = action.payload.find((pT) => pT.puzzleTypeId === value.puzzleTypeId)\n if (update) {\n acc.push({\n ...value,\n ...update,\n })\n return acc\n }\n acc.push(value)\n return acc\n }, [])\n\n return {\n ...state,\n puzzleTypes,\n }\n }\n\n case puzzleDataActions.SET_DAILY_DOSES: {\n // By default select the current date when navigating to the brainpoints overview.\n return {\n ...state,\n dailyDoses: action.payload,\n dailyDoseSelectedDate: action.payload.slice(-1)[0].date,\n }\n }\n\n case puzzleDataActions.SET_DAILY_DOSE_TYPES: {\n return {\n ...state,\n dailyDoseTypes: action.payload,\n }\n }\n\n case puzzleDataActions.SET_DAILY_DOSE_SELECTED_DATE: {\n return {\n ...state,\n dailyDoseSelectedDate: action.payload,\n }\n }\n default:\n return state\n }\n}\n","import { type Reducer } from 'redux'\nimport { all, type PuzzleFilter1 } from 'client/constants/puzzleFilters1'\nimport { type PuzzleFilterAction } from 'client/actions/types'\nimport * as puzzleFilters from 'client/actions/puzzleFilterActions'\nimport { type PuzzleFilter2 } from 'client/constants/puzzleFilters2'\n\nconst initialState: PuzzleFilterState = {\n filter1: all,\n puzzlePackTypeFilter1: all,\n}\n\nexport type PuzzleTypeFilterState = {\n filter1?: PuzzleFilter1\n filter2?: PuzzleFilter2\n}\n\nexport type PuzzlePackTypeFilterState = {\n puzzlePackTypeFilter1?: PuzzleFilter1\n puzzlePackTypeFilter2?: PuzzleFilter2\n}\n\nexport type PuzzleFilterState = PuzzleTypeFilterState & PuzzlePackTypeFilterState\n\n// eslint-disable-next-line default-param-last\nexport const puzzleFilterReducer: Reducer<PuzzleFilterState, PuzzleFilterAction> = (state = initialState, action) => {\n switch (action.type) {\n case puzzleFilters.SET_PUZZLE_FILTER:\n /* Make filter deselectable */\n if (state.filter2 && state.filter2 === action.payload?.filter2) {\n return {\n ...state,\n filter2: '',\n }\n }\n return {\n ...state,\n ...action.payload,\n }\n case puzzleFilters.PRESET_PUZZLE_FILTERS:\n return {\n ...state,\n ...action.payload,\n }\n case puzzleFilters.SET_PUZZLE_PACK_TYPE_FILTER:\n /* Make filter deselectable */\n if (state.puzzlePackTypeFilter2 && state.puzzlePackTypeFilter2 === action.payload?.puzzlePackTypeFilter2) {\n return {\n ...state,\n puzzlePackTypeFilter2: '',\n }\n }\n return {\n ...state,\n ...action.payload,\n }\n case puzzleFilters.PRESET_PUZZLE_PACK_TYPE_FILTERS:\n return {\n ...state,\n ...action.payload,\n }\n default:\n return state\n }\n}\n","import { type Reducer } from 'redux'\nimport { type UserAction } from 'client/actions/types'\nimport { type PaymentPeriod } from 'client/pages/payment_input/PaymentStepsComponent'\nimport { type SubscriptionType } from 'client/enums/SubscriptionType'\nimport { arraysEqual } from 'common_packages/assets/js/utilities/array'\nimport { BrainpointBadge } from 'client/types/BrainpointBadge'\nimport * as userActions from '../actions/userActions'\nimport { type Role } from '../enums/Role'\n\nconst initialUserData = {\n data: null,\n roles: [],\n brainPoints: [],\n}\n\nexport type Subscription = {\n paidUntilDate: string\n terminationDate: string\n subscriptionTypeName: SubscriptionType\n isFree: boolean\n isInTrialPeriod: boolean\n paymentPeriodId: PaymentPeriod\n isActive: boolean\n bankAccountLastDigits: string\n amount: number\n currency: string\n amountExcludingVat: number\n amountVat: number\n isPrintDiscounted: boolean\n userNotified: boolean\n willAutoRenew: boolean\n canReEnable: boolean\n}\n\nexport type UserData = {\n language: string\n id: number\n userName: string\n subscriptions: Subscription[]\n hasNewsletterOptIn: boolean\n hasRunningPrint: boolean\n hasWeeklyStatisticsOptIn: boolean\n settingsJson: string\n firstName: string\n prefix: string\n middleName: string\n gender: string\n lastName: string\n email: string\n emailConfirmed: boolean\n accessFailedCount: number\n regionId: number\n country: string\n birthDate: string\n zipcode: string\n houseNumber: string\n street: string\n city: string\n numberOfPayments: number\n canStartTrial: boolean\n}\n\nexport type UserState = {\n data: UserData\n brainPoints: BrainpointBadge[]\n roles: Role[]\n}\n\n// eslint-disable-next-line default-param-last\nexport const userReducer: Reducer<UserState, UserAction> = (state = initialUserData, action) => {\n switch (action.type) {\n case userActions.SET_USER:\n return {\n ...state,\n data: action.payload,\n }\n case userActions.CLEAR_USER:\n return {\n ...state,\n data: null,\n }\n case userActions.SET_ROLES:\n if (arraysEqual(state.roles, action.payload)) {\n return state\n }\n return {\n ...state,\n roles: action.payload,\n }\n case userActions.SET_USER_NAME:\n return {\n ...state,\n data: {\n ...state.data,\n userName: action.payload,\n },\n }\n case userActions.SET_FIRST_NAME:\n return {\n ...state,\n data: {\n ...state.data,\n firstName: action.payload,\n },\n }\n case userActions.SET_OPT_IN_STATUSSES:\n return {\n ...state,\n data: {\n ...state.data,\n hasNewsletterOptIn: action.payload.subscribeNewsletter,\n hasWeeklyStatisticsOptIn: action.payload.subscribeWeeklyStatistics,\n },\n }\n default:\n return state\n }\n}\n","import {\n combineReducers, AnyAction,\n} from 'redux'\nimport {\n FLUSH, PAUSE, PERSIST, PURGE, REGISTER, REHYDRATE, persistReducer, persistStore,\n} from 'redux-persist'\nimport { configureStore } from '@reduxjs/toolkit'\nimport storage from 'redux-persist/lib/storage'\nimport uiReducer, { UIState } from 'common_packages/assets/js/reducers/uiReducer'\nimport { notificationsReducer, NotificationsState } from 'client/reducers/notificationsReducer'\nimport { klubbleApp } from 'common_packages/assets/js/utilities/persistency_storage/localStorageKeys'\nimport { type TStore } from 'common_packages/assets/js/types/TDispatch'\nimport { type ConfigState, configReducer } from 'client/reducers/configReducer'\nimport { settingsReducer, SettingsStoreState } from '../reducers/settingsReducer'\nimport { puzzleDataReducer, PuzzleDataState } from '../reducers/puzzleDataReducer'\nimport { puzzleFilterReducer, PuzzleFilterState } from '../reducers/puzzleFilterReducer'\nimport { userReducer, UserState } from '../reducers/userReducer'\nimport { CLEAR_USER } from '../actions/userActions'\n\nexport interface StoreState {\n settings: SettingsStoreState\n puzzleFilter: PuzzleFilterState\n puzzleData: PuzzleDataState\n user: UserState\n ui: UIState\n config: ConfigState | null\n notifications: NotificationsState\n}\n\nconst persistConfig = {\n key: `${klubbleApp}-${process.env.KLUBBLE_VERSION}`,\n storage,\n blacklist: ['ui'],\n}\n\nconst uiConfig = {\n key: 'ui',\n storage,\n blacklist: ['showEndscreen', 'drawer'],\n}\n\nconst combinedReducers = combineReducers<StoreState>({\n settings: settingsReducer,\n puzzleData: puzzleDataReducer,\n puzzleFilter: puzzleFilterReducer,\n user: userReducer,\n ui: persistReducer(uiConfig, uiReducer),\n config: configReducer,\n notifications: notificationsReducer,\n})\n\nconst rootReducer = (state: StoreState, action) => {\n // clear the redux store when user logs out, except for the config\n if (action.type === CLEAR_USER) {\n return combinedReducers({\n settings: undefined,\n puzzleData: undefined,\n puzzleFilter: undefined,\n user: undefined,\n ui: undefined,\n config: state.config,\n notifications: undefined,\n }, action)\n }\n\n return combinedReducers(state, action)\n}\n\nconst initStore = (): TStore<AnyAction, StoreState> => {\n const reducer = persistReducer(persistConfig, rootReducer)\n\n // Use devTools only when USE_REDUX_DEVTOOLS env var is set\n const devTools = process.env.USE_REDUX_DEVTOOLS === 'true' ? {\n name: 'Klubble',\n } : false\n\n const store: TStore<AnyAction, StoreState> = configureStore({\n reducer,\n devTools,\n middleware: (getDefaultMiddleware) => [\n ...getDefaultMiddleware({\n serializableCheck: {\n ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],\n },\n }),\n ],\n })\n return store\n}\n\nexport const store = initStore()\nexport const persistor = persistStore(store)\n","import { AnyAction } from 'redux'\nimport { SET_CONFIG } from 'client/actions/configActions'\nimport { EntitySettings } from '../hooks/useConfig'\n\ntype PaymentPlatformType = 'ADYEN' | 'TWIKEY'\n\nexport type ConfigState = {\n isFreeTrialMode: boolean\n freeTrialDays: number\n isLightTrialEnabled: boolean\n lightTrialDays: number\n isExtendedTrialMode: number\n extendedTrialDays: number\n entity?: EntitySettings\n activePaymentPlatform: PaymentPlatformType\n}\n\n// eslint-disable-next-line default-param-last\nexport const configReducer = (state: ConfigState = null, action: AnyAction): ConfigState => {\n switch (action.type) {\n case SET_CONFIG: {\n return action.payload\n }\n default:\n return state\n }\n}\n","import { isAxiosError } from 'axios'\n\n// Retrows given Error with given extra prefixed message\nexport const rethrowError = (e: Error, prefix: string) => {\n // Would prefer to use the `cause` option argument\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause\n // but is probably not supported for all our users' browsers\n if (!shouldSwallowException(e)) {\n prependWithMessage(e, prefix)\n throw e\n }\n}\n\n// Prepends given message to Error\nexport const prependWithMessage = (error: Error, prefix: string) => {\n // eslint-disable-next-line no-param-reassign\n error.message = `${prefix}\\n${error.message}`\n}\n\n// Determine whether a runtime exception should get caught by the ErrorBoundary\nexport const shouldSwallowException = (e: Error | string) => {\n if (isAxiosError(e)) {\n if (e.code === 'ERR_CANCELED') {\n return true\n }\n if (e.code === 'ERR_NETWORK') {\n return true\n }\n if (e.code === 'ERR_BAD_REQUEST' && e.request.status === 401) {\n return true\n }\n }\n return false\n}\n","import { ApiFormResult } from 'client/api/common'\nimport translationGroups from 'client/constants/translationGroups'\n\nexport const addServerErrors = <TInputs>(\n errors: { [P in keyof TInputs]?: string },\n setError: (\n fieldName: keyof TInputs,\n error: { type: string; message: string }\n ) => void,\n getRawTranslation: (group: string, name: string | number | string[]) => string,\n) => {\n Object.keys(errors)\n .forEach((key) => {\n setError(key as keyof TInputs, {\n type: 'server',\n message: getRawTranslation(translationGroups.form, errors[key as keyof TInputs]),\n })\n })\n}\n\nexport const processValidationErrors = <TInputs>(\n result: ApiFormResult<boolean, TInputs>,\n setError: (\n fieldName: keyof TInputs,\n error: { type: string; message: string }\n ) => void,\n getRawTranslation: (group: string, name: string | number | string[]) => string) => {\n if (!result.success) {\n addServerErrors<TInputs>(result.errors, setError, getRawTranslation)\n }\n}\n","import React, { ReactNode } from 'react'\n\n/**\n * Find and surround relevant keywords within a block of text with a span\n * @param {string} label - The text to parse\n * @param {string} value - The search keyword to highlight\n * @param {string} className - Classname to apply to the span\n * @return {object} A JSX object containing an array of alternating strings and JSX\n */\nconst formatLabel = (label: string, value: string, className: string) => {\n if (!value) {\n return label\n }\n\n const reducer = (prev, current, i) => {\n if (!i) {\n return [current]\n }\n return prev.concat((\n <span className={className} key={value + current}>\n {value}\n </span>\n ), current)\n }\n\n return (\n <>\n { label\n .split(value)\n .reduce<ReactNode[]>(reducer, [])}\n </>\n )\n}\n\nexport default formatLabel\n","import { Subscription } from 'client/reducers/userReducer'\nimport { SubscriptionType } from 'client/enums/SubscriptionType'\n\nexport const getActiveSubscription = (subscriptions: Subscription[]): Subscription => {\n let activeSubscription = subscriptions.find((subscription) => (\n subscription.isActive && subscription.subscriptionTypeName === SubscriptionType.premium\n ))\n\n if (!activeSubscription) {\n activeSubscription = subscriptions.find((subscription) => (\n subscription.isActive && (subscription.subscriptionTypeName === SubscriptionType.light)\n ))\n }\n\n if (!activeSubscription) {\n activeSubscription = subscriptions.find((subscription) => (\n subscription.isActive && (subscription.subscriptionTypeName === SubscriptionType.lightTrial)\n ))\n }\n if (!activeSubscription) {\n activeSubscription = subscriptions.find((subscription) => (\n subscription.isActive && (subscription.subscriptionTypeName === SubscriptionType.extendedTrial)\n ))\n }\n return activeSubscription\n}\n","import AppDisplayModes from '../constants/appDisplayModes'\n\nexport const getDisplayModeApp = () => {\n if ('standalone' in navigator && navigator.standalone) {\n return AppDisplayModes.standaloneIOS\n }\n if (window.matchMedia('(display-mode: standalone)').matches) {\n return AppDisplayModes.standaloneAndroid\n }\n return AppDisplayModes.browserTab\n}\n","export const getParamsFromQueryString = (): {[key: string]: string} => {\n const resultParams = {}\n const params = new URLSearchParams(window.location.search)\n\n params.forEach((value, key) => {\n resultParams[key] = Array.isArray(value) ? value[0] : value\n })\n return resultParams\n}\n","import { games } from 'common_packages/assets/js/types/gameDataTypes'\n\nexport const getPuzzlePackTypeColor = (puzzlePackTypeName: string) => {\n const colors = {\n blue: [games.SUDOKU, games.TECTONIC, games.BINERO, games.KDOKU],\n pink: [games.CAMPING, games.FLEETCOMMANDER, games.HASHI, games.REBUS],\n green: [games.ARROWWORD, games.CONTINUOUS, games.CROSSWORD, games.WORDSEARCH, games.FILIPPINE, games.CRYPTOGRAM],\n yellow: [games.CODEBREAKER, games.FITWORD, games.WORDGUESS, games.BLOCKPUZZLE],\n }\n\n return Object.keys(colors).find((color) => {\n const categorySubstrings = colors[color]\n return categorySubstrings.some((part) => puzzlePackTypeName.toUpperCase().includes(part))\n }) || 'purple'\n}\n","import { EntitySettings } from 'client/hooks/useConfig'\nimport { PuzzlePackType } from 'client/types/PuzzlePackType'\n\n// returns the querystring used by the player page for a 'daily puzzle'\nexport const getPlayerPageQueryString = (\n gameType: string,\n externalPuzzleId: string,\n puzzlesClientId: EntitySettings['puzzlesClientId'],\n klubblePuzzleId: number,\n puzzleTypeId: number,\n) => {\n return `?gametype=${gameType}&puzzleid=${externalPuzzleId}&customerid=${puzzlesClientId}&klubblePuzzleId=${klubblePuzzleId}&puzzleTypeId=${puzzleTypeId}`\n}\n\n// returns the querystring used by the player page for a puzzle pack puzzle\nexport const getPuzzlePackPlayerPageQueryString = (\n gametype: string,\n externalPuzzleId: string,\n portalid: EntitySettings['puzzlesClientId'],\n klubblePuzzleId: number,\n puzzleTypeId: number,\n puzzlePackId: number,\n puzzlePackType: PuzzlePackType | string,\n) => {\n const playerParams = {\n gametype,\n puzzleid: externalPuzzleId,\n // we are starting a puzzle pack puzzle here, so send along 'klubblepacks' for customerid\n customerid: 'klubblepacks',\n // we are starting a puzzle pack puzzle here, so send along config.entity?.puzzlesClientId for portalid,\n // so when the config is loaded this will be used rather than the 'klubblepacks' customerid (which does not have a config)\n ...(portalid && { portalid }),\n klubblePuzzleId: `${klubblePuzzleId}`,\n puzzleTypeId: `${puzzleTypeId}`,\n puzzlePackId: `${puzzlePackId}`,\n puzzlePackType: isPuzzlePackTypeObject(puzzlePackType) ? puzzlePackType.name.toLowerCase() : puzzlePackType,\n }\n return `?${new URLSearchParams(playerParams)}`\n}\n\nconst isPuzzlePackTypeObject = (puzzlePackType: PuzzlePackType | string): puzzlePackType is PuzzlePackType => {\n return typeof puzzlePackType === 'object' && puzzlePackType.name != null\n}\n","export const replaceAll = (str, find, replace) => str.replace(new RegExp(find, 'g'), replace)\n","import { useEffect } from 'react'\nimport { Path, PathValue, UseFormReturn } from 'react-hook-form'\n\n// Will sanitize user input such that Twikey doesnt break\nconst useTwikeySanitizer = <T> (form: UseFormReturn<T>, fields?: (keyof T)[]) => {\n const { watch, setValue } = form\n const watched = watch()\n\n useEffect(() => {\n const watchedFields = fields ?? Object.keys(watched)\n watchedFields.forEach((field) => {\n if (typeof watched[field] === 'string' && (<string>watched[field]).match(/[’`‘]/g)) {\n const asString = <string>(watched[field]).replace(/[’`‘]/g, \"'\")\n setValue(field as Path<T>, <PathValue<T, Path<T>>>asString)\n }\n }, [])\n }, [fields, setValue, watched])\n}\n\nexport default useTwikeySanitizer\n","// eslint-disable-next-line max-len, no-misleading-character-class, no-misleading-character-class\nexport const alphanumeric = /^[a-zA-Z 0-9\\u00C0-\\u00FF-ÀàÁáÂâÄäÃãĀāĄąĂăǍǎÇçĈĉČčĆćĐđĎďÈèÉéÊêËëĘęĒēĔĕĖėĚěĜĝĞğĠġĢģǦǧĤĥĦħÌìÍíÎîÏïĮįİıĨĩĪīĬĭǏǐĴĵĶķǨǩĹĺĻļĽľĿŀŁłM̂m̂ŃńN̂n̂ŅņÑñŇňṄṅÒòÓóÔôÖöÕõŐőǪǫŌōŎŏƠơŔŕŖŗŘřŚśŜŝŞşȘșŠšŤťŦŧŢţȚțÙùÚúÛûÜüŨũŪūŬŭŲųŮůŰűƯưŴŵÝýŶŷŸÿŹźŽžŻż'’‘`]*$/ // also include accented chars\nexport const MAX_PASSWORD_LENGTH = 64\nexport const MAX_USERNAME_LENGTH = 25\nexport const MAX_FIRST_NAME_LENGTH = 40\nexport const MAX_MIDDLE_NAME_LENGTH = 10\nexport const MAX_LAST_NAME_LENGTH = 50\nexport const MAX_REPORT_BUG_MESSAGE = 1200\nexport const MAX_FILE_SIZE_MB = 2\nexport const SUPPORTED_UPLOAD_FORMATS = ['image/jpg', 'image/jpeg', 'image/png', 'image/gif', 'application/pdf', 'video/mp4', 'video/x-m4v', 'video/webm', 'video/*']\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","__webpack_require__.amdO = {};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = (chunkId) => {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + ({\"272\":\"appcomponent-binero-js-components-AppComponent\",\"824\":\"appcomponent-kakuro-js-components-AppComponent\",\"836\":\"appcomponent-arrowword_plus-js-components-AppComponent\",\"928\":\"global_translation-en-global-json\",\"1024\":\"appcomponent-wordguess-js-components-AppComponent\",\"1528\":\"global_translation-sv-global-json\",\"2080\":\"appcomponent-codebreaker-js-components-AppComponent\",\"2496\":\"appcomponent-fleetcommander-js-components-AppComponent\",\"2672\":\"appcomponent-tectonic-js-components-AppComponent\",\"2898\":\"global_translation-nl-global-json\",\"3238\":\"appcomponent-crypto-js-components-AppComponent\",\"3760\":\"global_translation-it-global-json\",\"3778\":\"global_translation-no-global-json\",\"4020\":\"appcomponent-wordwheel-js-components-AppComponent\",\"4120\":\"appcomponent-kdoku-js-components-AppComponent\",\"4366\":\"appcomponent-frenchcrossword-js-components-AppComponent\",\"4840\":\"global_translation-fi-global-json\",\"5000\":\"appcomponent-camping-js-components-AppComponent\",\"5216\":\"global_translation-pt-global-json\",\"5584\":\"appcomponent-wordsearch-js-components-AppComponent\",\"5728\":\"appcomponent-sudoku_chaos-js-components-AppComponent\",\"5764\":\"appcomponent-fitword-js-components-AppComponent\",\"5832\":\"global_translation-es-global-json\",\"6154\":\"global_translation-da-global-json\",\"6244\":\"appcomponent-sudoku-js-components-AppComponent\",\"6584\":\"appcomponent-rebus-js-components-AppComponent\",\"6680\":\"appcomponent-sudoku_killer-js-components-AppComponent\",\"7488\":\"global_translation-fr-global-json\",\"7840\":\"appcomponent-ikura-js-components-AppComponent\",\"7972\":\"appcomponent-continuous-js-components-AppComponent\",\"8196\":\"appcomponent-crossword-js-components-AppComponent\",\"8292\":\"appcomponent-filippine-js-components-AppComponent\",\"8520\":\"appcomponent-hashi-js-components-AppComponent\",\"8544\":\"appcomponent-nonogram-js-components-AppComponent\",\"8704\":\"appcomponent-arrowword-js-components-AppComponent\",\"8754\":\"global_translation-be-global-json\",\"9172\":\"appcomponent-blockpuzzle-js-components-AppComponent\",\"9468\":\"global_translation-de-global-json\"}[chunkId] || chunkId) + \"-bundle.js?1738747637004\";\n};","// This function allow to reference async chunks\n__webpack_require__.miniCssF = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \"-bundle.css?1738747637004\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = (module) => {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","__webpack_require__.p = \"/\";","if (typeof document === \"undefined\") return;\nvar createStylesheet = (chunkId, fullhref, oldTag, resolve, reject) => {\n\tvar linkTag = document.createElement(\"link\");\n\n\tlinkTag.rel = \"stylesheet\";\n\tlinkTag.type = \"text/css\";\n\tvar onLinkComplete = (event) => {\n\t\t// avoid mem leaks.\n\t\tlinkTag.onerror = linkTag.onload = null;\n\t\tif (event.type === 'load') {\n\t\t\tresolve();\n\t\t} else {\n\t\t\tvar errorType = event && event.type;\n\t\t\tvar realHref = event && event.target && event.target.href || fullhref;\n\t\t\tvar err = new Error(\"Loading CSS chunk \" + chunkId + \" failed.\\n(\" + errorType + \": \" + realHref + \")\");\n\t\t\terr.name = \"ChunkLoadError\";\n\t\t\terr.code = \"CSS_CHUNK_LOAD_FAILED\";\n\t\t\terr.type = errorType;\n\t\t\terr.request = realHref;\n\t\t\tif (linkTag.parentNode) linkTag.parentNode.removeChild(linkTag)\n\t\t\treject(err);\n\t\t}\n\t}\n\tlinkTag.onerror = linkTag.onload = onLinkComplete;\n\tlinkTag.href = fullhref;\n\n\n\tif (oldTag) {\n\t\toldTag.parentNode.insertBefore(linkTag, oldTag.nextSibling);\n\t} else {\n\t\tdocument.head.appendChild(linkTag);\n\t}\n\treturn linkTag;\n};\nvar findStylesheet = (href, fullhref) => {\n\tvar existingLinkTags = document.getElementsByTagName(\"link\");\n\tfor(var i = 0; i < existingLinkTags.length; i++) {\n\t\tvar tag = existingLinkTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\") || tag.getAttribute(\"href\");\n\t\tif(tag.rel === \"stylesheet\" && (dataHref === href || dataHref === fullhref)) return tag;\n\t}\n\tvar existingStyleTags = document.getElementsByTagName(\"style\");\n\tfor(var i = 0; i < existingStyleTags.length; i++) {\n\t\tvar tag = existingStyleTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\");\n\t\tif(dataHref === href || dataHref === fullhref) return tag;\n\t}\n};\nvar loadStylesheet = (chunkId) => {\n\treturn new Promise((resolve, reject) => {\n\t\tvar href = __webpack_require__.miniCssF(chunkId);\n\t\tvar fullhref = __webpack_require__.p + href;\n\t\tif(findStylesheet(href, fullhref)) return resolve();\n\t\tcreateStylesheet(chunkId, fullhref, null, resolve, reject);\n\t});\n}\n// object to store loaded CSS chunks\nvar installedCssChunks = {\n\t8624: 0\n};\n\n__webpack_require__.f.miniCss = (chunkId, promises) => {\n\tvar cssChunks = {\"272\":1,\"824\":1,\"836\":1,\"1024\":1,\"2080\":1,\"2496\":1,\"2672\":1,\"3238\":1,\"4020\":1,\"4120\":1,\"4366\":1,\"5000\":1,\"5584\":1,\"5728\":1,\"5764\":1,\"6244\":1,\"6584\":1,\"6680\":1,\"7840\":1,\"7972\":1,\"8196\":1,\"8292\":1,\"8520\":1,\"8544\":1,\"8704\":1,\"9172\":1};\n\tif(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);\n\telse if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {\n\t\tpromises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(() => {\n\t\t\tinstalledCssChunks[chunkId] = 0;\n\t\t}, (e) => {\n\t\t\tdelete installedCssChunks[chunkId];\n\t\t\tthrow e;\n\t\t}));\n\t}\n};\n\n// no hmr","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t8624: 0\n};\n\n__webpack_require__.f.j = (chunkId, promises) => {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\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\tif(true) { // all chunks have JS\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise((resolve, reject) => (installedChunkData = installedChunks[chunkId] = [resolve, reject]));\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = (event) => {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0);\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = (parentChunkLoadingFunction, data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some((id) => (installedChunks[id] !== 0))) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkklubble_app_client\"] = self[\"webpackChunkklubble_app_client\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\n__webpack_require__.O(undefined, [8448,6768,6896,5503,4684,3428,4600,5744,6984,4833], () => (__webpack_require__(48016)))\nvar __webpack_exports__ = __webpack_require__.O(undefined, [8448,6768,6896,5503,4684,3428,4600,5744,6984,4833], () => (__webpack_require__(34636)))\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","leafPrototypes","getProto","inProgress","dataWebpackPrefix","map","webpackAsyncContext","req","__webpack_require__","o","Promise","resolve","then","e","Error","code","ids","id","all","slice","keys","Object","module","exports","getTranslation","useContext","TranslationContext","className","translationGroups","calendarPage","puzzleTypes","RecentPuzzlesBackgroundComponent","GameCardRowComponent","rowFilter","puzzle","rowTitle","dispatch","setDrawer","puzzleTypeId","uiActions","drawer","drawerTypes","PUZZLE_CALENDAR_LEVEL","drawerData","forceModal","showInstructions","GAME_INSTRUCTIONS","puzzleType","translation","history","nameLangKey","format","selectedLevel","usePuzzleSelectedLevel","title","useMemo","text","getRawTranslation","formatLabel","subtitle","puzzleTags","join","isFavorite","PageHeaderBackgroundMobileComponent","PageHeaderBackgroundDesktopComponent","onClick","from","location","state","push","HeartToggleContainer","type","stopPropagation","difficulty","levels","length","day","isActive","config","useConfig","formatDate","useDateFormatters","hasSubscription","useAbilities","gameType","externalPuzzleId","klubblePuzzleId","isPlayed","playAllowed","isStarted","useEffect","status","activeTitle","dayDelta","Date","dayDate","month","icons","start","paused","finished","locked","bodyText","String","dayNum","headerText","cardClassName","role","tabIndex","queryString","entity","puzzlesClientId","UPGRADE_SUBSCRIPTION","modalAutoGrow","hideHeader","currentPuzzleCalendar","puzzleData","activeDayIndex","setActiveDayIndex","useState","anyPuzzlesLeftToPlay","setAnyPuzzlesLeftToPlay","params","parseInt","currentPuzzleType","usePuzzleType","tryNowUrl","isPremiumOnlyPuzzle","isPremiumOnly","width","useWindowDimensions","isWeekPuzzle","ARROWWORD_PLUS","name","isLoading","setIsLoading","suggestedPuzzleTypes","puzzleTypeTryAlsos","suggestions","pTypeTryAlso","find","pType","canPlayPremiumOnlyPuzzles","backToHome","UPGRADE_SUBSCRIPTION_PREMIUM_ONLY","onClose","emptyCalendar","Array","fill","hasPuzzle","nextAchievement","level","index","levelCalendar","_a","daysPerLevel","calendarDays","firstNonPlayedDay","findIndex","gridColumns","activeDayNumber","breakpoints","LARGE","COLUMNS_LG","MEDIUM","COLUMNS_MD","onlyDesktop","style","gridTemplateColumns","filter","key","description","meta","theme","entityBrandName","pageTitle","pageDescription","htmlAttributes","lang","language","content","property","concat","size","borderOnly","color","opacity","top","left","border","borderRadius","gravity","rotateFrom","rotateTo","scrollYProgress","rotate","y","scale","div","height","borderStyle","borderColor","cssVariables","backgroundColor","position","zIndex","AvatarComponent","src","username","alt","toUpperCase","defaultProps","iconPath","endscreenPage","props","link","children","to","otherProps","open","setOpen","onMouseOver","onTouchStart","onMouseLeave","page","icon","navigation","showMenu","scrollPosition","useWindowPosition","canSeeMenu","isAnonymous","testId","cmp","getClassName","item","window","pathname","includes","LogoComponent","navigateTo","publicUrl","Component","handleClick","evt","preventDefault","scrollTo","NotificationsBellComponent","showBackButton","showAccountButton","canSeeAccount","pathParts","split","pop","showNav","ui","navigationBaseClassName","navigationClassName","screen","items","classNameIcon","classNameTitle","year","getFullYear","canSeePrivateFooterLinks","darkBg","LogoSubTitleComponent","footer","target","hideFooter","showEndscreen","contentClass","hideDesktopNavigation","HeaderComponent","hideMobileNavigation","NavigationMobileContainer","url","logoInvertedPath","logoPath","startsWith","href","showLogoSubTitle","common","notifications","unreadMessagesCount","navigator","setAppBadge","catch","ADD_TO_HOMESCREEN_INFO","skipSEO","themeColor","routeProps","abilities","login","loginCalled","useRef","puzzlePackId","afterRegistrationPath","paymentPeriodId","pack","isAnonRegisterForPuzzlePack","toLowerCase","user","data","current","replace","origin","document","querySelector","setAttribute","path","substring","xmlns","clipPathUnits","transform","d","sectionDividerDefinition","fromLocation","stacked","canSeeRecentPuzzles","homePage","cpPuzzle","isStackedOnMobileView","isStacked","recentDays","isEntirelyClickable","gameMode","error","setError","translationsSet","userData","queryParams","hasUserData","firstName","userName","endPoint","JSON","stringify","shareLinkShortUrl","guid","shareLink","response","post","headers","success","puzzleTypeNameKey","puzzlePackTypeName","isPuzzlePack","playerParams","gametype","puzzleid","customerid","portalid","puzzlePackType","multiplayer","mpqr","gift","free","shareresult","URLSearchParams","toString","message","translationKey","isMultiPlayerQR","GENERIC_ERROR","startGame","buttonText","err","SET_FIRST_NAME","hideClose","userId","isQRHost","locationGuid","qrLocationGuid","qrShareLink","active","buttons","onClickHandler","restProps","classNames","buttonClassName","SITEMAP","langKey","breadcrumbs","renderBreadcrumb","useCallback","bc","showLink","pt","isPuzzlePackPuzzle","getState","puzzlePacks","p","Number","displayName","viewBox","buttonEnum","innerButtonElement","Button","played","playing","spelled","reduceDuplicateDays","acc","value","some","s","getButtonEnum","default","reduce","nextPuzzleUrl","propsClassName","inside","forwardRef","ref","disabled","customClassName","iconBefore","IconBefore","iconAfter","IconAfter","inverted","buttonType","SliderButton","currentSlide","slideCount","arrowProps","CardComponent","arrowDirection","args","translations","setTranslations","abortController","AbortController","res","abort","group","shouldConvertToJSX","pattern","RegExp","match","p1","convertToJSX","translationContextProps","Provider","setCurrentSlide","usps","setUsps","throwError","useAsyncError","get","signal","customPaging","i","sliderPillClassName","settings","dots","infinite","speed","autoplay","autoplaySpeed","pauseHover","centerMode","marginBlockStart","marginBlockEnd","slidesToScroll","centerPadding","nextArrow","prevArrow","beforeChange","prev","next","sort","a","b","sortOrder","titleKey","descriptionKey","imageUrl","usp","inviterName","lightTrialSuffix","lightTrialDaysText","RoundedButtonComponent","expressions","yeah","eureka","welldone","loveit","hmm","stuck","haha","expression","rest","Icon","form","BASE_CLASS_NAME","label","secondaryLabel","customError","showValidatorError","validatePassword","radioValue","rows","register","watch","setValue","formState","isSubmitting","passwordVisible","setPasswordVisible","labelClassName","setLabelClassName","errors","inputClassName","test","newValue","trimStart","handleAutoFill","animationName","onAnimationStart","onScroll","_b","elem","scrollTop","classList","add","remove","autoCapitalize","defaultChecked","htmlFor","renderLabel","readOnly","options","noEmptyOption","translateItem","control","baseClassName","input","displayVal","hasDisplayValue","val","successMessage","disableWhileNotDirty","isDirty","isSubmitted","isValid","submitLabel","allPlayed","every","canPlay","canPlayDailyPuzzles","isNew","showFavoriteToggle","disableLink","gameCardClassName","gameCardSubtitle","innerGameCard","moreItem","showPerRow","showProgress","rowsShown","setRowsShown","getIconUrl","puzzlePacksToRender","puzzlePack","puzzlePackCardSubtitle","largestFormat","iconUrlIds","iconUrls","percentage","percentageProgress","puzzlePackTypePage","pages","activePage","HeroBackgroundMobileComponent","rx","stroke","strokeOpacity","strokeWidth","right","mixBlendMode","overflow","translationGroup","formatCurrency","showPuzzlePackContents","getPuzzlePackTypeById","puzzlePackTypeId","isPurchased","isFree","isCompleted","price","handleBuy","PUZZLE_PACK_INFO","bleedToEdge","handleClickCard","search","getPuzzlePackById","iconUrl","setDeferredPrompt","browserTab","dataLayer","event","source","handleBeforeInstallPrompt","addEventListener","removeEventListener","CustomListItemComponent","roles","isAuthenticated","token","ThemeContext","createContext","themes","klubble_nl","helpHomescreenPath","klubble_se","klubble_fr","setTheme","activeThemeEntity","setActiveThemeEntity","themeSettings","forEach","variable","documentElement","setProperty","handleSwitchTheme","ctrlKey","metaKey","themesArr","entityName","memoizedValue","IconComponent","disableAutoClose","duration","textRight","removeTimeout","setTimeout","clearTimeout","toggleIsFavorite","justFavorited","setJustFavorited","isMounted","toggleClassName","handleToggle","checked","onChange","subscription","isPuzzlePackOwner","eventSent","numberOfPayments","eventObj","subscriptionType","subscriptionTypeName","isTrial","isInTrialPeriod","entries","localStorage","removeItem","storage","estimate","usage","quota","mbConverter","extra","scroll","listen","onActivateSmartHint","clueIndex","onGameInstructionsClick","clueCells","clues","solvedClues","applePencilHelper","handleTouchStart","onTouchMove","handleTouchMove","onTouchEnd","handleTouchEnd","skipIntro","okButtonRef","onIntro","setOnIntro","setItem","focus","instructionText","osType","addHomescreenInfo","introImageSrc","rehypePlugins","useId","puzzleSorting","setPuzzleSorting","puzzleSortType","searchParams","set","pushState","alphabetical","puzzlePage","popularity","getCellValueOrSolution","cell","solution","c","INITIAL","cells","selection","guess","guessCell","cellData","selectedClue","clue","ClueBarSeeImageComponent","letter","onHintClick","word","hints","setHints","hintsFound","dictionary","getHints","singleHint","letters","languageUsesIJ","hint","GuessBarContainer","SmartHintsContainer","columns","solutionPathData","firstFoundMistake","hintCellIndex","hintCellEmpty","solutionPathDataForGameType","notes","solutionPath","action","x","selectCell","selectedCellIndex","drawerUseHighlightAnimation","setBodyText","useActiveSubscription","accountPage","toastTypes","SUCCESS","ERROR","gameroomConnection","sendExpression","ExpressionIcon","currentPuzzleCalendarNameLangKey","store","convertGameType","puzzleInstructions","translationKeyPart","handleOk","handleCancel","assist","contentTranslationKey","hideButton","onButtonClick","returnUrl","emailSubject","copied","setCopied","timeout","encodedText","encodeURIComponent","handleCopy","toCopyText","copyTextType","clipboard","writeText","sharePuzzle","invite","rel","reload","timerActions","miniPuzzleTypeId","miniPuzzleType","featuredPuzzleTypes","previousSelectedLevel","previousSelectedLevelCurrent","featuredPuzzleTypeChanged","fPT","puzzleDataActions","closestMiniPuzzleLevel","indexOf","nl","unread","author","date","n","players","playerCount","gameroom","isPlaying","puzzleStore","gameStatus","g","IS_PLAYING","canInviteMore","puzzleTypeDefinition","pT","maxPlayers","playerNumber","PlayerAvatarComponent","player","PuzzleInviteButtonComponent","schema","shape","trim","required","matches","max","resolver","yup","handleSubmit","onSubmit","InputComponent","SubmitButtonComponent","forceModeUserChoice","forceModes","mobile","extendedTrialDaysText","freeDays","SubscriptionType","extendedTrial","hasRunningPrint","listItems","selectedPaymentPeriodId","onPaymentPeriodIdChange","canStartTrial","onNext","premium","ChoosePaymentPeriodComponent","setPaymentPeriodId","onboarding","blockPlayer","PlayerComponent","isInViewPuzzleMode","shareResultText","useShareDialog","shareResult","fileToUpload","setFileToUpload","consent","oneOf","defaultValues","getDefaults","clearErrors","clearFileButton","handleClearFile","formData","FormData","storages","parse","append","getDisplayModeApp","Blob","values","indexedDbBytesUsage","console","autoComplete","accept","file","currentTarget","files","fileUploadErrorMessage","onFocus","onBlur","subText","components","li","activePuzzleIndex","baseClass","activePuzzle","usePuzzlePacks","puzzleUrl","closeDrawer","ViewButtonComponent","PlayButtonComponent","setActivePuzzle","setPuzzlePack","initialPuzzle","puzzles","fetchPuzzlePackContent","formats","fromCharCode","toLocaleLowerCase","Math","floor","ButtonComponent","subscriptions","isLightTrialEnabled","previousSubscriptionType","paidUntilDate","suffix","light","lightTrial","days","subtitleText","getAvailableLevelsWithinPuzzlePackType","getSelectedLevelForPuzzlePackType","availableLevels","storedValues","usernameEntered","usernameAvailable","useCheckUsernameAvailable","payload","fallback","childrenRef","renderFallback","setRenderFallback","useLayoutEffect","hasOverflow","parentNode","el","scrollHeight","clientHeight","scrollWidth","clientWidth","handleClose","onChooseOptIn","setShowConfetti","completedOptInStep","completeOptInStep","step","OnboardingHeaderComponent","platformUrl","confettiController","setConfettiController","shoot","onInit","conductor","decorateOptions","defaultOptions","colors","scalar","decay","particleCount","spread","ticks","drawerForceModal","drawerFullscreenOnMobile","drawerModalAutoGrow","drawerHideHeader","drawerHideClose","drawerBleedToEdge","drawerClassName","drawerSize","drawerOnClose","fullscreenOnMobile","pauseTimer","resumeTimer","close","extraClassName","windowHeight","setState","previousDrawer","currentDrawer","previousDrawerData","currentDrawerData","showConfetti","drawerRef","drawerContent","inFullscreen","getElementById","shouldClearLock","allowTouchMove","tagName","shouldClearPreventOverscroll","previousScrollY","scrollY","pageContentEl","drawerCurrent","drawerObserver","entry","modalHeight","contentRect","AUTO_GROW_MARGIN","pageContentHeight","innerHeight","getBoundingClientRect","body","observe","unobserve","requestAnimationFrame","addScrollbarBack","scrollbarWidth","innerWidth","overflowY","overflowX","paddingRight","touchAction","header","SUBSCRIBE","CANCEL_SUBSCRIPTION","CANNOT_START_PUZZLE","EXPRESS","FEATURE_IN_DEVELOPMENT","GENERIC_CONFIRM","GIFT_PUZZLE","INVITE_PUZZLE","JOIN_NOW","DrawerContentJoinNowComponent","NEED_TO_REGISTER","NOTIFICATIONS","ONBOARD_MODAL","ONSCREEN_KEYBOARD_HIDE","ONSCREEN_KEYBOARD_SHOW","PLAYER_LIST","PUZZLE_FINISHED_WITHOUT_CONTRIBUTION","PUZZLE_ONBOARDING_LEVEL","PUZZLE_PACK_CONTENT","PUZZLE_PACK_TYPE_LEVEL","PUZZLES_SORTING","DrawerContentSortingContainer","REPORT_BUG","SHARE_RESULT","SMART_HINT_LOGIC","DrawerContentSmartHintLogicContainer","SMART_HINT_WORDSEARCH","DrawerContentSmartHintWordsearchContainer","SMART_HINTS_DICTIONARY","TERMS_AND_CONDITIONS","VIEW_PUZZLE","RotateScreenComponent","overlayVariants","transition","closed","transparentVariants","transparentOverlay","show","clickable","setClickable","displayMode","timer","standaloneIOS","initial","animate","exit","variants","anonymousAllowed","skipSubscriptionCheck","showLandingWhenUnAuthenticatedOrAnon","renderLandingPage","LandingComponent","shouldCheckPendingMandates","emailConfirmed","onboardingInProgress","shouldShowTrialPresent","userNotified","customIcon","startLightTrial","api","hasLightSubscriptionOnly","isFreeOrGiftOrMP","getParameterByName","shouldShowOnboard","isIdentified","qrGame","getParamsFromQueryString","replaceAll","getTitle","setShowNav","setShowEndscreen","l","setUser","updateChannel","useBroadcastChannel","lastSSOCheckTimeStamp","now","sso","sessionIsActive","onmessage","toastIcons","INFO","enter","toasts","ToastComponent","resetError","textTitle","textDescription","textButton","backUrl","messageWithLinebreaks","dailyDosePage","nodeRef","node","prevVal","interval","controls","onUpdate","textContent","toFixed","stop","DailyDoseCirclesComponent","doses","numPointsDay","animateOffset","delay","lastThreeDoses","dose","percentageOfRequired","reverse","firstCompletedDoseIndex","getFirstStrokeDashArrayItem","strokeDashArrayFrom","lastCirclePoints","pointsRequired","completedDoseOffset","abs","strokeDasharray","cssPostFix","percentageOfRequiredCircle","ease","dailyDoseTypes","dailyDoses","numPoints","DailyDosePeriodConstants","freeze","fourWeeks","twoWeeks","week","datesEqual","date1","date2","getMonth","getDate","getWeek","setHours","setDate","getDay","week1","round","getTime","getDailyDoseDaysWithinPeriod","dailyDoseDays","periodOffset","period","getTimespanInDays","dailyDoseDaysPeriod","emptyDayFills","composedTypes","getDailyDoseDaysFourWeeks","weekNumber","generateEmptyDaysForCurrentWeek","lastDay","lastDate","daysToAdd","result","addDays","puzzelTypes","offset","toISOString","showSelectedDay","showWeekRange","dailyDoseSelectedDate","headerTitle","currentDate","isNaN","weekDays","months","fromDate","toDate","selectedWeekNumber","selectedYear","selectedWeekDays","rangeFromDate","rangeFromMonth","rangeToDate","selectedDate","today","monday","diff","getMonday","dailyDoseGameTypeSummary","setDailyDoseGameTypeSummary","getDailyDoseSummaryGameTypes","timespan","dailyDoseGameTypes","groupedGameTypes","gameTypeFound","points","totalPoints","accumulator","GameCardComponent","_index","DailyDoseTodayComponent","DailyDoseNoScoreComponent","DailyDoseCirclesContainer","DailyDoseTodayItemsContainer","dailyDoseRequiredCirclePoints","dailyDoseType","DailyDoseEnum","DAILY_DOSE","dailyDose","transitionDelay","positionConfig","maxDailyDose","onMouseOut","classNameLine","classNameCircle","lineWidth","percentageOfMaxDailyDoseOfPeriod","min","MAX_SCORE","yStart","yDestination","circleHeight","marginTop","margin","line","y1","y2","x1","x2","strokeLinecap","cx","cy","r","circleWidth","checkMarkHeight","useHighestAchievedDoseWithDoseType","highestAchievedDose","doseType","zeroPoint","highestAchievedDoseWithDoseType","barHeight","setPreviousPeriod","setNextPeriod","showPrevArrow","CarouselBarArrowComponent","periodSelected","hover","periodCompleted","periodName","classNameLineLabel","bottom","periodNames","cssPostfixes","DOUBLE_DOSE","MEGA_DOSE","ULTRA_DOSE","EPIC_DOSE","setPeriodOffset","setPeriod","hoveredLabel","setHoveredLabel","handleClickLabel","movePeriod","direction","hasActivityFromStartTillPeriod","labelMargin","dailyDosesWithDailyDoseType","dailydoseDaysForPeriod","findDailyDoseType","useDailyDosesWithDoseType","dailyDoseLabels","dates","highestAchieved","DailyDoseActivityBarContainer","continuePlayingPuzzleTypes","getDailyDoses","getDailyDoseTypes","canUseDailyDose","startPeriod","shouldShowContinuePlaying","PageHeaderComponent","HeaderTitleBarComponent","NavigationPagesTabsComponent","DailyDoseTodayContainer","FeedbackCardComponent","RecentPuzzlesComponent","getComposedDailyDoses","dailyDoseOneDay","composedDailyDoseTypes","totalPointsToday","prevPointsRequired","composeWithCss","getPercentageOfRequired","getHighestDailyDose","goal","highest","currentIndex","newPuzzle","premiumOnly","renderCard","PillComponent","getBackgroundUrl","usePuzzleTypeImageUrls","mostRecentId","filterFavorites","filteredPuzzleTypes","filter1","puzzleFilters1","filter2","puzzleFilters2","filterMinis","cpPuzzleTypes","firstFavoritePuzzle","klubbleMiniPuzzle","ARROWWORD_PLUS_MINI","getPuzzleCalendar","fetchedRecentDays","setFetchedRecentDays","responsive","breakpoint","PuzzlePackCardContinueComponent","GameCardCalendarComponent","HeroBackgroundDesktopComponent","loadingContinuePlayingPuzzleTypes","hasContinuePlayingPuzzleTypes","hasPlayedBefore","canGreetFirstName","HomeHeroPuzzleSliderContainer","setSuggestedPuzzleTypes","maxThreeFavoritedPuzzleTypes","notInFavorite","f","popularityScore","AnimatedBackgroundSquircle","playablePacks","publishDate","unPurchasedPacks","completedPacks","GameCardRowPuzzlePacksComponent","loadingFeaturedPuzzles","getContinuePlayingPuzzleTypes","stats","setStats","getUserStatsAndData","mainTypes","puzzleTypesSorted","isExtendedTrial","uspList","landingPage","activateButtonText","LandingHeaderComponent","subscriberToken","loading","setLoading","Boolean","emailPrefilled","setEmailPrefilled","fetchEmail","LandingRegularComponent","signInCheckTimer","errorMessage","backgroundImage","loginPage","SSOLoginInProgress","setSSOLoginInProgress","playRedirectAfterLogin","fromEntries","cookie","decodeURIComponent","playLogin","useLogin","initializedSSOLogin","email","password","heartToggleWrapperRef","usePuzzleTypeFavorite","PuzzleIcon","selectedLevelKey","setSelectedLevelKey","setting","originalSettings","currentStep","setCurrentStep","isScrollable","setIsScrollable","stateFromLocation","setSelectedPuzzleLevel","revertFavorites","revertDifficulties","allFavorites","checkPageCanScroll","isPageScrollable","puzzlesAlphabetically","getSubtitle","puzzleTypeMini","handleDifficultyChange","paymentSuccess","hasPremiumSubscription","purchaseIsPuzzlePack","getItem","paymentInputPage","paymentCompletePage","repeat","Infinity","repeatType","times","version","fillRule","PaymentStepHeaderComponent","showPrintDiscount","showDiscountPill","showPremiumTrialTexts","showUSPs","useCurrencyFormatters","getPriceModel","usePriceModels","priceModel","setPriceModel","model","amount","amountClassBase","amountClass","discountPercentage","redirectResult","sessionId","trackCheckoutEvent","useTrackCheckout","setPuzzlePackId","checkoutType","setCheckoutType","setPaymentSuccess","triesRef","details","paymentData","productType","receivedPuzzlePackId","receivedPaymentPeriod","verifyPayment","decodedRedirectResult","decodeURI","renderProductInfo","PaymentPuzzlePackCardComponent","adyenPaymentInfo","setIsCheckingItemPurchased","isCheckingItemPurchased","setIsPayButtonPressed","isLoadingCheckout","setIsLoadingCheckout","containerRef","dropinRef","checkoutConfiguration","environment","clientKey","analytics","enabled","session","sessionData","onPaymentCompleted","component","unmount","resultCode","checkItemPurchased","onError","_error","beforeSubmit","actions","newToken","puzzlePackPurchased","Role","checkout","dropinConfiguration","openFirstPaymentMethod","paymentMethodsResponse","paymentMethods","dropin","create","mount","handlePaymentPeriodIdChange","initializePayment","activePaymentPlatform","countryOptions","useCountryOptions","SelectComponent","optionsSorted","_name","translationMap","PAYMENT_PERIOD","initalizedRef","previousPaymentPeriodId","usePrevious","setAdyenPaymentInfo","isPayButtonPressed","middleName","lastName","country","storedCountry","initializePaymentEndpoint","defaultCountry","_c","_d","_e","paymentUrl","adyenInfo","toastType","paymentPeriodChanged","onSelect","getAllPriceModels","priceModels","setPriceModels","models","continueTitle","renderPaymentPeriodComponent","paymentPeriod","pM","showDescription","animation","isEndscreenAnimationActive","checkmark","templates","scoreType","score","scoringBadges","finishedPuzzle","brainpoints","brainPoint","orderedScoringCategories","extendedBrainpoints","brainPointItem","template","brainpointBadge","getBrainPointBadgesList","baseToggleClass","toggleClass","collapseBrainpoints","autoCollapsed","setAutoCollapsed","brainPointBadgesList","toggleOpen","total","baseHeaderClass","headerClass","section","layout","collapsed","windowWidth","endscreenBrainpoints","endscreenCelebration","visible","headerHeight","offsetTop","transitionEnd","display","hidden","canSeeCollapsedDailyDoseEndscreen","endscreenBrainpointsVariants","standard","endscreenAnimationNotActive","frameRate","progress","setProgress","countDown","setCountDown","milliseconds","intervalId","setInterval","clearInterval","ceil","ProgressBarComponent","random","numOfToasts","toastVariants","custom","endscreenCelebrationVariants","celebrationGifTransition","endscreenCelebrationGif","gotoOverview","canFavoritePuzzles","HeartPuzzlePackTypeToggleContainer","canGiftPuzzle","openShareDialog","shouldShowLabel","returnToPuzzlePackType","nextPuzzle","puzzlePackPercentageProgress","canPlayNext","playerContributions","showViewButtonCompleted","ButtonGroupDaysComponent","showHeader","dailyDoseToday","highestDailyDose","contributions","filteredContributions","contribution","endscreenVariants","puzzlePackTypes","endscreen","delayContent","showJoinNowModal","gotoCalendar","lightUserAndPremiumPuzzle","gotoPuzzlePacks","handleGoToOverview","showRecentPuzzles","canGiveFeedback","skipCelebration","numScoringBadges","endscreenActive","setEndscreenActive","setIsEndscreenAnimationActive","timeoutEndscreen","isViewingPuzzle","onWindowBlur","onWindowFocus","EndscreenContainer","getIdentifiers","tag","getPuzzlePackTypeByName","getPuzzlePacksWithinPuzzlePackType","puzzlePacksForTypeUnsorted","usePuzzlePackAuthentication","useShowPuzzlePackContents","lastPlayed","puzzleTypeName","freeBeeUrl","puzzleTypeFreeBeeUrls","puzzleFilter","puzzlePackTypeFilter1","selectPuzzleFilter","PuzzleFilter1Component","puzzlePackTypeFilter2","tags","textButtons","tagLangKey","PuzzleFilter2Component","getPuzzlePackTypeColor","PuzzlePackIcons","recentPuzzlePackTypes","setRecentPuzzlePackTypes","fetchRecentPuzzlePacks","matchesFilter1","packs","matchesFilter2","rP","sortedPuzzlePacksTypes","packsWithinType","localeCompare","puzzlePackTypesPage","PuzzlePackTypeFilter1Container","PuzzlePackTypeFilter2Container","loginAnonymous","ppt","pp","puzzlePacksWithinPuzzlePackType","Set","flatMap","obtainFreePuzzlePack","filters","handleUpdateFilter","delete","favoriteButtonClass","syncFilterAndSortingWithUrl","acceptedFilterAndSortingValues","setUrlValueInRedux","urlValue","foundFilter","fsv","sortPuzzles","onClickSortHandler","recentPuzzleTypes","setRecentPuzzleTypes","mainType","isPlayTogether","sortedPuzzles","PuzzleSortContainer","PuzzleFilter1Container","PuzzleDisplayContainer","numPlayed","variantNameKey","maxLabelWidth","setMaxLabelWidth","animateDelay","isMini","startAnim","setStartAnim","offsetWidth","animationDelay","seeingAll","setSeeingAll","statsPage","dCircle","strokeDashoffset","primaryData","secondaryData","mainTypeNameKey","matchClue","revealPuzzle","revealSelectedClue","executeCellAction","cellActions","WORDSEARCH","WORDSEARCH_MINI","playerRef","createRef","triedPreloadAssets","setTriedPreloadAssets","puzzleId","gameTypeLowerCase","getPuzzleInfo","folderName","customerId","game","img","Image","onload","onerror","finally","pageYOffset","closeConnection","processFinishPuzzle","getQueryParam","KLUBBLE_PUZZLE_ID","element","time","counter","getIsMultiPlayerQR","gameInfo","shareTemplateTranslationKey","WORDGUESS","squareArr","CORRECT","REVEALED","SEMICORRECT","INCORRECT","visual","tries","getPuzzleSpecificShareDetails","playerContext","AppComponent","lazy","ClientContextComponent","PlayerContext","showBreadcrumbs","canSeePuzzlePlayerBreadcrumbs","LoadingComponent","clueBar","canInvite","rotateScreen","SET_SELECTION","RESET_SELECTION","ADD_TO_UNSENT_GUESSES_QUEUE","CLEAR_UNSENT_GUESSES_QUEUE","SET_PLAYER_CONTRIBUTIONS","SET_PLAYER_LIST","ADD_MESSAGE","DISMISS_MESSAGE","SEND_GAMEROOM_GUESSES","setSelection","resetSelection","addToUnsentGuessesQueue","clearUnsentGuessesQueue","fetchPlayerList","puzzleInstanceId","responseData","addMessage","sender","dismissMessage","sendGameroomGuesses","sendGameroomGuessesAction","saveTimerToServer","this","IS_SOLVED","saveServerTimerIntervalId","formatGuess","cellIdentifier","justStarted","guessCount","newGuessesLocked","connectionLostTimeoutId","retryIntervalId","selectionTimeoutIds","updateLocalTime","seenEndScreen","gameroomActions","createSignalRHubConnection","attachConnectionEventListeners","connection","subscribeToRoom","getPlayerNumber","getSeenEndScreen","getJustStarted","addGuesses","guesses","formattedGuesses","processUnsentGuesses","syncPuzzleState","isFirstFetch","unsentGuessesQueue","getGuesses","expressionDto","puzzleinstanceId","Connected","invoke","sendSelection","selectionDto","withUrl","configureLogging","Information","withAutomaticReconnect","nextRetryDelayInMilliseconds","retryContext","previousRetryCount","build","cleanupConnectionLost","gameroomId","connectionId","offlineHandler","handleConnectionLost","unloadHandler","on","count","parsedGuess","stepJson","ownGuessIndex","ownSentGuesses","stepId","splice","storeGuesses","SHOW_RESULT","activePlayerList","playerNum","clearSelectionTimeoutId","clearSelectionInactivePlayers","incomingPlayerNumber","selectedCell","onreconnected","onreconnecting","onclose","gameroomGuessesAction","updateTimer","parsedGuesses","guessVal","cellIndex","codeNumber","originCell","destinationCell","blockId","regionIndex","correctAnswer","bridgeCount","isCrossedOff","hintsUsed","v","obj","stepDateTime","checkSum","createCheckSum","freezeGame","onLine","cellIndices","skipAddGuessToServer","num","timeoutId","checkSumRemainder","showCannotStartPuzzleDrawer","getPersistKey","initialState","showTimer","skipCompletedLetters","isFreePuzzle","nextDay","initialUserData","brainPoints","persistConfig","blacklist","uiConfig","combinedReducers","newPuzzleTypes","array","puzzleItem","update","userActions","hasNewsletterOptIn","subscribeNewsletter","hasWeeklyStatisticsOptIn","subscribeWeeklyStatistics","uiReducer","rootReducer","reducer","devTools","middleware","getDefaultMiddleware","serializableCheck","ignoredActions","initStore","persistor","rethrowError","prefix","shouldSwallowException","prependWithMessage","request","processValidationErrors","addServerErrors","getActiveSubscription","activeSubscription","standalone","matchMedia","standaloneAndroid","resultParams","isArray","blue","SUDOKU","TECTONIC","BINERO","KDOKU","pink","CAMPING","FLEETCOMMANDER","HASHI","REBUS","green","ARROWWORD","CONTINUOUS","CROSSWORD","FILIPPINE","CRYPTOGRAM","yellow","CODEBREAKER","FITWORD","BLOCKPUZZLE","part","getPlayerPageQueryString","getPuzzlePackPlayerPageQueryString","isPuzzlePackTypeObject","str","fields","watched","field","asString","alphanumeric","MAX_USERNAME_LENGTH","MAX_FIRST_NAME_LENGTH","MAX_MIDDLE_NAME_LENGTH","MAX_LAST_NAME_LENGTH","MAX_REPORT_BUG_MESSAGE","MAX_FILE_SIZE_MB","SUPPORTED_UPLOAD_FORMATS","__webpack_module_cache__","moduleId","cachedModule","undefined","loaded","__webpack_modules__","call","m","amdO","O","chunkIds","fn","priority","notFulfilled","fulfilled","j","getter","__esModule","getPrototypeOf","t","mode","ns","def","getOwnPropertyNames","definition","defineProperty","enumerable","chunkId","promises","u","miniCssF","globalThis","Function","prop","prototype","hasOwnProperty","done","script","needAttach","scripts","getElementsByTagName","getAttribute","createElement","charset","nc","onScriptComplete","doneFns","removeChild","bind","head","appendChild","Symbol","toStringTag","nmd","paths","installedCssChunks","miniCss","reject","fullhref","existingLinkTags","dataHref","existingStyleTags","findStylesheet","oldTag","linkTag","errorType","realHref","createStylesheet","loadStylesheet","installedChunks","installedChunkData","promise","realSrc","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","chunkLoadingGlobal","self","__webpack_exports__"],"sourceRoot":""}