= {\n \"Buildbox 4 Free\": PlanIds.BB4Free,\n //\"Buildbox 4 Weekly\": PlanIds.BB4Weekly,\n \"Buildbox 4 Basic\": PlanIds.BB4Basic,\n \"Buildbox 4 Pro\": PlanIds.BB4Pro,\n \"Buildbox 4 Beginner\": PlanIds.BB4Beginner,\n \"Buildbox 3 Free\": PlanIds.BB3Free,\n \"Buildbox 3 Plus\": PlanIds.BB3Plus,\n \"Buildbox 3 Pro\": PlanIds.BB3Pro,\n \"Buildbox Classic Free\": PlanIds.BB2Free,\n \"Buildbox Classic Plus\": PlanIds.BB2Plus,\n \"Buildbox Classic Pro\": PlanIds.BB2Pro,\n \"Buildbox Classic Beginner\": PlanIds.BB2Beginner,\n \"Buildbox Bundle\": PlanIds.BBBundle,\n \"Soundbox Free\": PlanIds.SoundboxFree,\n \"Soundbox Pro\": PlanIds.SoundboxPro,\n}\n","export const bbaiUser = {\n id: \"1\",\n pic: \"https://frontend-assets.buildbox.com/web-gen-ai/boxy_avatar.svg\",\n};\n\nexport const defaultUser = {\n id: \"2\",\n pic: \"https://frontend-assets.buildbox.com/web-gen-ai/user_avatar.svg\",\n};\n\n\nexport enum bbaiStoryGamePromptStepStatus {\n INITIAL = \"INITIAL\",\n GENERATING_GAME_DATA = \"GENERATING_GAME_DATA\",\n GENERATING_GAME_ASSETS = \"GENERATING_GAME_ASSETS\",\n BUILD_BBDOC = \"BUILD_BBDOC\",\n DOWNLOAD_BBDOC = \"DOWNLOAD_BBDOC\",\n CLAIM_ACCOUNT = \"CLAIM_ACCOUNT\",\n COMPLETE = \"COMPLETE\",\n CLAIM_LOGIN_SKIP = \"CLAIM_LOGIN_SKIP\",\n LOGIN_ACCOUNT = \"LOGIN_ACCOUNT\",\n DONE = \"DONE\",\n GAME_DATA = \"GAME_DATA\",\n ERROR_RESTART_REGENERATE = \"ERROR_RESTART_REGENERATE\",\n}\n\n\nexport const bbaiStoryGamePromptOptions: Record<\n string,\n { prompt: string; errPrompt: string }\n> = {\n INITIAL: {\n prompt: \"Hello, I'm BBAI from Buildbox, and I'm here to help you make your first game! What story do you want to tell?\",\n errPrompt: \"I'm sorry, I didn't quite get that. Could you tell me more about your story?\",\n },\n GAME_DATA: {\n prompt: \"What story do you want to tell?\",\n errPrompt: \"I'm sorry, I was unable to generate your game (something went wrong). Please try again.\",\n }, \n GENERATING_GAME_DATA: {\n prompt: \"That's a great idea! I'm writing your Story Game now, this will take a minute or two...\",\n errPrompt: \"I'm sorry, I was unable to generate your game (something went wrong). Please try again.\",\n }, \n GENERATING_GAME_ASSETS: {\n prompt: \"I finished writing your Story Game! Now I'm working on adding graphics and sounds. This will take a minute or two...\",\n errPrompt: \"I'm sorry, I was unable to generate your game (something went wrong). Please try again.\",\n },\n BUILD_BBDOC: {\n prompt: \"Just one more moment, I'm putting the full game together!\",\n errPrompt: \"I'm sorry, I was unable to construct your game (something went wrong). Please try again.\"\n },\n CLAIM_LOGIN_SKIP: {\n prompt: \"\",\n errPrompt: \"Error: I'm sorry, I didn't quite get that. Please select CLAIM, LOGIN, or SKIP.\",\n },\n COMPLETE: {\n prompt: \"You can also download your game project as well as Buildbox to start modding it!\",\n errPrompt: \"Error while trying to download BBDoc\",\n },\n COMPLETE_MOBILE: {\n prompt: \"Play your bit now on Buildbox World!\",\n errPrompt: \"something went wrong when completing the game\",\n },\n DOWNLOAD_BBDOC: {\n prompt: \"I have finished uploading your game and it is now ready to play on the Buildbox World app!\",\n errPrompt: \"Error while trying to download BBDoc\",\n },\n CLAIM_ACCOUNT: {\n prompt: \"I have finished uploading your game and it is now ready to play on the Buildbox World app!\",\n errPrompt: \"We were unable to claim your account and bbdoc, try skipping and manually claiming your game!\",\n },\n};\n\nexport enum AssetType {\n CHARACTER = \"CHARACTER\",\n ENEMY = \"ENEMY\",\n BACKGROUND = \"BACKGROUND\",\n}\n\nexport type Display = {\n Component: React.ReactElement\n stage: number// maybe make this string avlue?\n nextStage: string\n}","import Env from \"../Env\";\n\nexport interface CreateTxt2ImgGenerationJobDTO{\n prompt: string ;\n costInVC:number ;\n disableSuggestedOptimizations: boolean ;\n jobId: string ;\n width: number ;\n height: number ;\n seed: number;\n removeBackground: boolean;\n webCYOASaveCopyToS3Filename?: string|undefined\n webCYOAProjectId?: string|undefined\n projectId?:string | undefined,\n\n // note that development has consistently been adding more potential params here, see bb-platform AssetGenerationDTO for the full list\n}\n\n\nexport interface Txt2ImgGenerationJobCreationResultDTO {\n job: Txt2ImgGenerationJobDTO\n buildbux: {\n newBalance: number;\n oldBalance: number;\n };\n uploadUrl?: string;\n}\n\nexport interface Txt2ImgGenerationJobDTO {\n jobId:string\n userId:string\n prompt:string\n userPrompt:string\n userNegativePrompt:string\n userDisableSuggestedOptimizations:boolean\n userRemoveBackground:boolean\n costInVC:number\n status: ImageGenerationJobStatus\n progress:number\n createdAt:string\n updatedAt:string\n hasInputImage:boolean\n originalRequest: object|null\n}\n\n\nexport enum ImageGenerationJobStatus {\n CREATED = \"CREATED\",\n IN_PROGRESS = \"IN_PROGRESS\",\n COMPLETE = \"COMPLETE\",\n ERROR = \"ERROR\",\n CANCELLED = \"CANCELLED\",\n}\n\nexport interface GenAssetsStateDTO {\n charAsset: Txt2ImgGenerationJobCreationResultDTO | null;\n enemyAsset: Txt2ImgGenerationJobCreationResultDTO | null;\n bgAsset: Txt2ImgGenerationJobCreationResultDTO | null;\n}\n\nexport interface ImageGenerationJobDTO {\n Id: string\n UserId: string;\n Status: ImageGenerationJobStatus;\n Progress: number;\n Prompt: string;\n CostInVC: number;\n Phase: string;\n ProgressInPhase: number;\n ErrorCode: string;\n Extra: string;\n TimeToComplete: number;\n UserMessage: string; \n Finalized: boolean\n CreatedAt: Date;\n UpdatedAt: Date;\n UserPrompt: string;\n UserNegativePrompt: string;\n UserRemoveBackground: boolean \n UserDisableSuggestedOptimizations: boolean\n JobRequestJson: string\n HasInputImage: boolean \n IsSoftDeleted: boolean \n}\n\nexport interface ImageGenerationJobCreationResultDTO {\n ETA: number;\n ImageGenerationJob: ImageGenerationJobDTO;\n Queue: number\n}\n\nexport enum templateType {\n SHOOTER = \"SHOOTER\",\n WORLD = \"WORLD\",\n PORTAL = \"PORTAL\",\n JETPACK = \"JETPACK\"\n}\n\n\nexport type NotificationType = 'success' | 'info' | 'warning' | 'error';\n\nexport enum BBDocBackButtonPosition {\n TOP_LEFT = \"TopLeft\",\n TOP_CENTER = \"TopCenter\",\n TOP_RIGHT = \"TopRight\",\n LEFT = \"Left\",\n CENTER = \"Center\",\n RIGHT = \"Right\",\n BOTTOM_LEFT = \"BottomLeft\",\n BOTTOM_CENTER = \"BottomCenter\",\n BOTTOM_RIGHT = \"BottomRight\",\n}\n\nexport enum BBDocRuntime {\n BBCLASSIC = \"BBClassic\",\n BB3 = \"BB3\",\n BB4 = \"BB4\",\n}\nexport interface UploadBBDocDTO {\n displayName: string\n bytes: number\n shareGlobally?: string\n shareAsPremiumBit?: string\n runtime?: BBDocRuntime | undefined\n backButtonPosition?: BBDocBackButtonPosition | undefined \n description?: string \n}\nexport enum DownloadPlatforms {\n WINDOWS = \"win\",\n MAC = \"mac\",\n UNKNOWN = \"unknown\",\n}\n\nexport interface BBDocResponseObj {\n id: string\n displayName: string\n bytes: number\n createdAt: number\n updatedAt: number\n}\n\nexport interface IBBDownloadVersions {\n BB4: {\n WIN: string | undefined;\n MAC: string | undefined;\n APP: string;\n };\n BB3: {\n WIN: string | undefined;\n MAC: string | undefined;\n APP: string;\n };\n BB2: {\n WIN: string | undefined;\n MAC: string | undefined;\n APP: string;\n };\n Soundbox: {\n WIN: string | undefined;\n MAC: string | undefined;\n APP: string;\n }\n}\n\nexport const BBDownloadVersion: IBBDownloadVersions = {\n BB4: {\n WIN: Env.BB4_DOWNLOAD_LINK_WIN,\n MAC: Env.BB4_DOWNLOAD_LINK_MAC,\n APP: \"buildbox4\",\n },\n BB3: {\n WIN: Env.BB3_DOWNLOAD_LINK_WIN,\n MAC: Env.BB3_DOWNLOAD_LINK_MAC,\n APP: \"buildbox3\",\n },\n BB2: {\n WIN: Env.BB2_DOWNLOAD_LINK_WIN,\n MAC: Env.BB2_DOWNLOAD_LINK_MAC,\n APP: \"buildbox2\",\n },\n Soundbox: {\n WIN: Env.SOUNDBOX_DOWNLOAD_LINK_WIN,\n MAC: Env.SOUNDBOX_DOWNLOAD_LINK_MAC,\n APP: \"soundbox\",\n }\n};\n\n export interface PostSSOTokensDTO {\n accessToken: string\n refreshToken: string\n clientId: string\n clientSecret: string\n}\n\nexport interface ChooseYourOwnAdventureChoiceData {\n choiceDescription: string\n coinsDelta: number\n healthDelta: number\n resultDescription: string\n}\n\nexport interface ChooseYourOwnAdventureChapterData {\n description: string\n imageFilename: string\n choices: ChooseYourOwnAdventureChoiceData[]\n}\n\nexport interface ChooseYourOwnAdventureCustomizationData {\n projectId: string\n badEndText: string\n goodEndText: string\n badEndImageFilename: string\n goodEndImageFilename: string\n title: string\n subtitle: string\n titleImageFilename: string\n backgroundMusicFilename: string\n iconFilename: string\n chapters: ChooseYourOwnAdventureChapterData[]\n}\n\nexport enum AuthOption {\n LOGIN,\n SIGNUP,\n}\n \n export enum bbaiStoryGamePromptStepStatus {\n INITIAL = \"INITIAL\",\n GENERATING_GAME_DATA = \"GENERATING_GAME_DATA\",\n GENERATING_GAME_ASSETS = \"GENERATING_GAME_ASSETS\",\n BUILD_BBDOC = \"BUILD_BBDOC\",\n DOWNLOAD_BBDOC = \"DOWNLOAD_BBDOC\",\n CLAIM_ACCOUNT = \"CLAIM_ACCOUNT\",\n COMPLETE = \"COMPLETE\",\n CLAIM_LOGIN_SKIP = \"CLAIM_LOGIN_SKIP\",\n LOGIN_ACCOUNT = \"LOGIN_ACCOUNT\",\n DONE = \"DONE\",\n GAME_DATA = \"GAME_DATA\",\n ERROR_RESTART_REGENERATE = \"ERROR_RESTART_REGENERATE\",\n }\n\nexport type AuthResult = {\n IdToken: string;\n AccessToken: string;\n RefreshToken: string;\n isGuest: boolean;\n}","export default (state: { auth: bb.state.IAuth }) => {\n return state.auth.gaClientId;\n};\n","export type SubMenu = {\n key: string,\n title: string,\n link: string,\n externalURL: string\n}\n\nexport type HeaderItem = {\n title: string,\n route: string,\n externalURL: string,\n subMenu?: SubMenu[]\n}\n\nexport const headerItems: HeaderItem[] = [\n {\n title: \"Plans\",\n route: \"/plans\",\n externalURL: \"\"\n },\n {\n \"title\": \"Downloads\",\n \"route\": \"\",\n \"externalURL\": \"\",\n \"subMenu\": [\n {\n \"key\": \"BB2\",\n \"title\": \"Buildbox Classic\",\n \"link\": \"/downloads/bb2\",\n \"externalURL\": \"\"\n },\n {\n \"key\": \"BB3\",\n \"title\": \"Buildbox 3\",\n \"link\": \"/downloads/bb3\",\n \"externalURL\": \"\"\n },\n {\n \"key\": \"BB4\",\n \"title\": \"Buildbox 4\",\n \"link\": \"/downloads/bb4\",\n \"externalURL\": \"\"\n }, \n {\n \"key\": \"Soundbox\",\n \"title\": \"Soundbox\",\n \"link\": \"/downloads/soundbox\",\n \"externalURL\": \"\"\n },\n {\n \"key\": \"Bundle\",\n \"title\": \"Bundle\",\n \"link\": \"/downloads/bbbundle\",\n \"externalURL\": \"\"\n },\n {\n \"key\": \"OtherTools\",\n \"title\": \"Other Tools\",\n \"link\": \"/downloads/tools\",\n \"externalURL\": \"\"\n }\n ]\n },\n {\n \"title\": \"Products\",\n \"route\": \"\",\n \"externalURL\": \"\",\n \"subMenu\": [\n {\n \"key\": \"BB2\",\n \"title\": \"Buildbox Classic\",\n \"link\": \"/product/bb2\",\n \"externalURL\": \"\"\n },\n {\n \"key\": \"BB3\",\n \"title\": \"Buildbox 3\",\n \"link\": \"/product/bb3\",\n \"externalURL\": \"\"\n },\n {\"key\": \"BB4\",\n \"title\": \"Buildbox 4\", \n \"link\": \"/product/bb4\", \n \"externalURL\": \"\" \n }, \n {\n \"key\": \"BBWorld\",\n \"title\": \"Buildbox World\",\n \"link\": \"/product/buildboxworld\",\n \"externalURL\": \"https://buildboxworld.com/\" \n }, \n {\n \"key\": \"Soundbox\",\n \"title\": \"Soundbox\",\n \"link\": \"/product/soundbox\",\n \"externalURL\": \"\"\n }\n ]\n },\n // {\n // \"title\": \"Learning Center\",\n // \"route\": \"\",\n // \"externalURL\": \"\",\n // \"subMenu\": [\n // {\n // \"key\": \"BB2Tutorials\",\n // \"title\": \"Buildbox Classic\",\n // \"link\": \"\",\n // \"externalURL\": \"https://www.buildbox.com/tutorials-buildbox-classic\"\n // },\n // {\n // \"key\": \"BB3Tutorials\",\n // \"title\": \"Buildbox 3\",\n // \"link\": \"\",\n // \"externalURL\": \"https://www.buildbox.com/tutorials-buildbox-3\"\n // } \n // ]\n // },\n {\n \"title\": \"Community\",\n \"route\": \"\",\n \"externalURL\": \"\",\n \"subMenu\": [\n {\n \"key\": \"productfeedback\",\n \"title\": \"Product Feedback\",\n \"link\": \"\",\n \"externalURL\": \"http://productboard.buildbox.com\"\n },\n {\n \"key\": \"gamejam\",\n \"title\": \"Game Jam\",\n \"link\": \"\",\n \"externalURL\": \"https://www.buildbox.com/gamejam\"\n },\n {\n \"key\": \"blog\",\n \"title\": \"Buildbox Blog\",\n \"link\": \"\",\n \"externalURL\": \"https://www.buildbox.com/blog/\"\n },\n {\n \"key\": \"forum\",\n \"title\": \"Buildbox Forum\",\n \"link\": \"\",\n \"externalURL\": \"https://www.buildbox.com/forum/index.php\"\n },\n {\n \"key\": \"discord\",\n \"title\": \"Buildbox Discord\",\n \"link\": \"\",\n \"externalURL\": \"https://discord.com/invite/buildbox\"\n }\n ]\n },\n // {\n // \"title\": \"Pricing\",\n // \"route\": \"/plans\",\n // \"externalURL\": \"\"\n // },\n {\n \"title\": \"Help\",\n \"route\": \"\",\n \"externalURL\": \"\",\n \"subMenu\": [\n {\n \"key\": \"reportissue\",\n \"title\": \"Report an Issue\",\n \"link\": \"/reportAnIssue\",\n \"externalURL\": \"\"\n },\n {\n \"key\": \"contact\",\n \"title\": \"Contact Support\",\n \"link\": \"/contactSupport\",\n \"externalURL\": \"\" \n },\n {\n \"key\": \"manual\",\n \"title\": \"Buildbox Manual\",\n \"link\": \"\",\n \"externalURL\": \"https://www.buildbox.com/help/buildbox-3-manual\"\n },\n {\n \"key\": \"api\",\n \"title\": \"API Reference\",\n \"link\": \"\",\n \"externalURL\": \"https://www.buildbox.com/help/buildbox-3-api-reference/\"\n },\n {\n \"key\": \"howto\",\n \"title\": \"How To/FAQs\",\n \"link\": \"\",\n \"externalURL\": \"https://www.buildbox.com/help/how-to-faqs/\"\n }\n ]\n }\n ]\n\nexport const profileHeaderItems: HeaderItem[] = [\n {\n \"title\": \"Profile\",\n \"route\": \"\",\n \"externalURL\": \"\",\n \"subMenu\": [\n {\n \"key\": \"profileInformation\",\n \"title\": \"Profile Information\",\n \"link\": \"/account/profile\",\n \"externalURL\": \"\"\n },\n {\n \"key\": \"subscription\",\n \"title\": \"Device Management\",\n \"link\": \"/account/subscription\",\n \"externalURL\": \"\"\n },\n {\n \"key\": \"monetization\",\n \"title\": \"Adbox\",\n \"link\": \"/account/ads/earnings\",\n \"externalURL\": \"\"\n },\n {\n \"key\": \"support\",\n \"title\": \"Profile Support\",\n \"link\": \"/account/support\",\n \"externalURL\": \"\"\n }\n ]\n }\n ]\n","import React, { useState, useEffect } from \"react\";\nimport styles from \"../styles/Header.module.scss\";\nimport { Link } from \"react-router-dom\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { faAngleDown } from \"@fortawesome/free-solid-svg-icons/faAngleDown\";\nimport { faAngleUp } from \"@fortawesome/free-solid-svg-icons/faAngleUp\";\nimport classnames from \"classnames\";\n\nexport const MenuItem = (props) => {\n const [menuOpenState, toggleMenuState] = useState(false);\n const [windowWidth, setWindowWidth] = useState(window.innerWidth);\n const isDesktop = windowWidth >= 650;\n const { menuItem } = props;\n\n useEffect(() => {\n const handleWindowResize = () => {\n setWindowWidth(window.innerWidth);\n };\n\n window.addEventListener(\"resize\", handleWindowResize);\n\n return () => {\n window.removeEventListener(\"resize\", handleWindowResize);\n };\n }, []);\n\n function toggleTab(path) {\n if (props.activeTab) {\n return props.activeTab === path ? styles.activeTab : \"\";\n }\n }\n\n const toggleMenu = (event) => {\n event.stopPropagation();\n toggleMenuState(!menuOpenState);\n };\n\n const renderSubMenuItems = (submenus) => {\n return (\n \n {submenus.map((submenu, i) => {\n return submenu.link !== \"\" ? (\n
\n {submenu.title}\n \n ) : (\n
\n {submenu.title}\n \n );\n })}\n
\n );\n };\n\n const { title } = menuItem;\n\n const renderParentMenu = () => {\n if (menuItem.route.length) {\n return (\n \n {title}
\n \n );\n } else if (menuItem.externalURL.length) {\n return (\n \n {title}
\n \n );\n } else {\n return (\n \n {title}\n
\n );\n }\n };\n\n return (\n \n
\n {renderParentMenu()}\n\n {menuItem.subMenu && (\n \n )}\n
\n\n {menuItem.subMenu && renderSubMenuItems(menuItem.subMenu)}\n
\n );\n};\n","import classnames from \"classnames\"\nimport React, { ReactElement } from \"react\"\n\nimport styles from \"../styles/SocialIcons.module.scss\"\n\nexport function SocialIcons(props:{className?:string}): ReactElement {\n return (\n \n )\n}\n\n\nexport function SocialText(props:{className?:string}): ReactElement {\n return (\n \n )\n}","import React, { useContext, useState, useEffect } from \"react\";\nimport { NavLink, useHistory } from \"react-router-dom\";\nimport { useSelector, useDispatch } from \"react-redux\";\nimport { UserContext } from \"../App\";\nimport { Link } from \"react-router-dom\";\nimport { useLocation } from \"react-router-dom\";\nimport Log from \"../utils/Log\";\nimport { logout } from \"../actions/auth\";\nimport { showError } from \"../actions/error\";\nimport currentUserInfo from \"../selectors/currentUserInfo\";\nimport styles from \"../styles/Header.module.scss\";\nimport imgBuildboxLogo from \"../img/LogoBB_Normal.png\";\nimport imgBuildbox4Logo from \"../img/BB4_Logo_Wordmark_Wht.png\";\nimport routes from \"../constants/routes.json\";\nimport classnames from \"classnames\"\n\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport { faBars } from \"@fortawesome/free-solid-svg-icons/faBars\";\nimport { faTimes } from \"@fortawesome/free-solid-svg-icons/faTimes\";\n\nimport {HeaderItem, headerItems, profileHeaderItems} from \"../constants/HeaderItems\";\nimport { MenuItem } from \"../components/MenuItem\";\nimport setCssVariables from \"../utils/setCssVariables\";\nimport { SocialIcons } from \"../components/SocialIcons\";\nimport useIsMobile from \"../hooks/useIsMobile\";\nimport { addPlanToCart } from \"../actions/cart\";\nimport { PlanIds } from \"../reducers/models\";\n\n// controls the \"Try Buildbox X\" button in upper right\nconst defaultHomepage = process.env.REACT_APP_MAIN_HOME_PAGE;\n\nexport default function Header() {\n const dispatch = useDispatch();\n const location = useLocation();\n const currentUser = useSelector(currentUserInfo);\n const { session } = useContext(UserContext);\n const {isMobile} = useIsMobile()\n const history = useHistory()\n \n const [menuOpenState, toggleMenuState] = useState(false);\n const [activeTab, setActiveTab] = useState(null);\n const [toggleDropdown, setToggleDropdown] = useState(false);\n\n const color1 = sessionStorage.getItem(\"profileColor1\");\n const color2 = sessionStorage.getItem(\"profileColor2\");\n\n async function onLoad() {\n try {\n if (currentUser) {\n // Log.trace(\"got current user!\", currentUser);\n }\n\n setActiveTab(location.pathname);\n } catch (e) {\n console.log(\"e\", e);\n }\n }\n\n useEffect(() => {\n onLoad(); //eslint-disable-next-line\n }, [location.pathname, currentUser, session]);\n\n function handleSignIn() {\n console.log(\"clicked\");\n\n try {\n // save path name to redirect after successful login\n sessionStorage.setItem(\"previousRoute\", location.pathname + location.search);\n\n // redirectToLoginPage(props);\n } catch (e) {\n Log.error(e, \"Header component: error signing in\");\n }\n }\n\n async function handleLogout() {\n try {\n await dispatch(logout());\n } catch (e: any) {\n Log.error(e, \"App Component: error caught logging out\");\n dispatch(showError(e.message));\n }\n }\n\n function renderAuthState() {\n // if (workState.loginState === LoginState.Loading) {\n // return (\n // \n //
\n //
SIGNING IN...
\n //
\n // );\n // }\n\n if (currentUser && currentUser.username) {\n const userNameLetter = currentUser.name.charAt(0).toUpperCase();\n const background = {\n \"background\": `linear-gradient(to bottom, ${color1}, ${color2})`,\n };\n setCssVariables(background);\n return (\n <>\n setToggleDropdown(!toggleDropdown)}\n >\n {userNameLetter}\n
\n {toggleDropdown && (\n \n
\n setToggleDropdown(!toggleDropdown)}\n >\n Profile \n \n setToggleDropdown(!toggleDropdown)}\n >\n Device Management \n \n setToggleDropdown(!toggleDropdown)}\n >\n Adbox \n \n setToggleDropdown(!toggleDropdown)}\n >\n Support \n \n \n Sign out
\n \n \n
\n )}\n >\n );\n } else {\n return (\n \n \n Sign In\n \n \n );\n }\n }\n\n function getMobileMenu() {\n const animStyle = {\n overflow: \"hidden\",\n transition: \"max-height 0.25s cubic-bezier(0.65, 0.05, 0.36, 1) 0s\",\n height: \"height: calc( 100vh - 100px )\",\n maxHeight: \"0px\",\n };\n\n const linkHeaderItems = {\n gridTemplateRows: `repeat( ${headerItems.length}, 35px )`,\n };\n\n if (menuOpenState) {\n animStyle.maxHeight = \"100vh\"; // Value doesn't seem to really matter, as long as its not auto and larger than content height\n }\n\n return (\n \n
\n {renderMenuItems(headerItems)}\n {renderMobileAuth()}\n
\n
\n );\n }\n\n function renderMenuItems(headerItemsArray: HeaderItem[]) {\n return headerItemsArray.map((headerItem) => {\n if(headerItem.title === \"Downloads\" && isMobile) return null\n return (\n \n )});\n }\n\n function renderMobileAuth() {\n if (currentUser && currentUser.username) {\n return (\n <>\n <>{renderMenuItems(profileHeaderItems)}>\n \n >\n );\n } else {\n return (\n \n \n \n );\n }\n }\n\n function toggleMenu() {\n toggleMenuState(!menuOpenState);\n }\n\n\n function handlePurchaseClick(): void {\n\n if(defaultHomepage === \"BBCLASSIC\") {\n dispatch(addPlanToCart(PlanIds.BB2Beginner));\n }\n else {\n dispatch(addPlanToCart(PlanIds.BB4Beginner));\n }\n\n const promoCode = sessionStorage.getItem(\"promoCode\");\n if (currentUser?.referralInfo?.Network?.toLowerCase() === \"xsolla\") {\n if (promoCode) {\n history.push(`/purchaseThroughXsolla?promo=${promoCode}`);\n } else {\n history.push(\"/purchaseThroughXsolla\");\n }\n } else {\n if (promoCode) {\n history.push(`/purchaseThroughStripeCheckout?promo=${promoCode}`);\n } else {\n history.push(\"/purchaseThroughStripeCheckout\");\n }\n }\n }\n\n function logoElement() {\n let logoUrl\n if(defaultHomepage === \"BBCLASSIC\") {\n logoUrl = imgBuildboxLogo\n }\n else {\n logoUrl = imgBuildbox4Logo\n }\n return (\n \n \n \n )\n }\n\n return (\n \n {logoElement()}\n
\n
\n {renderMenuItems(headerItems)}\n {renderAuthState()}\n {/* TODO: Double check if this is where we want to land */}\n Try Buildbox {defaultHomepage === \"BBCLASSIC\" ? \"Classic\" : 4} \n
\n
\n \n
\n {getMobileMenu()}\n
\n );\n}\n","export default function setCssVariables(variableObj) {\n Object.keys(variableObj).map((key) => {\n const value = variableObj[key];\n return document.documentElement.style.setProperty(key, value);\n });\n}\n","import React from \"react\";\nimport styles from \"../styles/Footer.module.scss\";\nimport classnames from \"classnames\"\nimport img from \"../img/LogoBB_Normal.png\";\n// import { SocialText } from \"../components/SocialIcons\"\n\nexport default function Footer() {\n\n return (\n \n
\n
\n
\n
\n
\n \n \n
STAY UP TO DATE \n
\n
\n
\n
\n
\n
\n
\n
\n );\n}\n","import React, { useEffect, Suspense } from \"react\";\nimport { Route } from \"react-router-dom\";\n\nexport default function AppliedRoute({ component: C, appProps, ...rest }) {\n useEffect(() => {\n //to bring to top of page since react-router remembers your scroll pos?\n window.scrollTo(0, 0);\n\n //TODO: this may need to include title ie below, pass informatin through the props\n // window.dataLayer.push({\n // event: \"pageview\",\n // page: {\n // url: location,\n // title: title,\n // },\n // });\n window.dataLayer.push({\n event: \"pageview\",\n });\n });\n return (\n (\n Loading...}>\n \n \n )}\n />\n );\n}\n","import React, { lazy } from \"react\";\nimport { Redirect, Switch } from \"react-router-dom\";\nimport AppliedRoute from \"./components/AppliedRoute\";\nimport routes from \"./constants/routes.json\";\n\nconst NewBB4Home = lazy(() => import(\"./containers/home/NewBB4Home\"));\nconst NewClassicStoryGamesHome = lazy(() => import(\"./containers/home/NewClassicStoryGamesHome\"));\nconst BB4Product = lazy(() => import(\"./containers/product/BB4Product.jsx\"));\nconst BB3Product = lazy(() => import(\"./containers/product/BB3Product.jsx\"));\nconst BB2Product = lazy(() => import(\"./containers/product/BB2Product.jsx\"));\nconst SoundboxProduct = lazy(() => import(\"./containers/product/SoundboxProduct.jsx\"));\nconst Plans = lazy(() => import(\"./containers/plans/Plans\"));\nconst NotFound = lazy(() => import(\"./containers/NotFound\"));\nconst Downloads = lazy(() => import(\"./containers/Downloads\"));\nconst BillingFormStripe = lazy(() => import(\"./containers/CheckoutStripe.tsx\"));\nconst StripeCheckout = lazy(() => import(\"./containers/StripeCheckout.tsx\"));\nconst StripeCheckoutReturn = lazy(() => import(\"./containers/StripeCheckoutReturn.tsx\"));\nconst BillingFormXsolla = lazy(() => import(\"./containers/CheckoutXsolla.tsx\"));\nconst XsollaCheckoutReturn = lazy(() => import(\"./containers/XsollaCheckoutReturn.tsx\"));\nconst AuthUI = lazy(() => import(\"./containers/AuthUI\"));\nconst ConfirmAccount = lazy(() => import(\"./containers/ConfirmAccount\"));\nconst ThankYou = lazy(() => import(\"./containers/ThankYou\"));\nconst Login = lazy(() => import(\"./containers/LoginPage\"));\nconst Loader = lazy(() => import(\"./containers/Loader\"));\nconst ClientUpgradeRedirect = lazy(() =>\n import(\"./containers/client/ClientUpgradeRedirect\")\n);\nconst ClientLoginRedirect = lazy(() =>\n import(\"./containers/client/ClientLoginRedirect\")\n);\nconst ClientLogoutRedirect = lazy(() =>\n import(\"./containers/client/ClientLogoutRedirect\")\n);\nconst ClientPostmessageConnection = lazy(() =>\n import(\"./containers/client/ClientPostmessageConnection\")\n);\nconst ClientGoogleLogin = lazy(() =>\n import(\"./containers/client/ClientGoogleLogin\")\n);\nconst ClientFacebookLogin = lazy(() =>\n import(\"./containers/client/ClientFacebookLogin\")\n);\nconst ClientAppleLogin = lazy(() =>\n import(\"./containers/client/ClientAppleLogin\")\n);\nconst ClientDeeplinkLogin = lazy(() =>\n import(\"./containers/client/ClientDeeplinkLogin\")\n);\nconst ClientAwaitingFacebookLogin = lazy(() =>\n import(\"./containers/client/ClientAwaitingFacebookLogin\")\n);\nconst ClientAwaitingAppleLogin = lazy(() =>\n import(\"./containers/client/ClientAwaitingAppleLogin\")\n);\nconst ClientAwaitingGoogleLogin = lazy(() =>\n import(\"./containers/client/ClientAwaitingGoogleLogin\")\n);\nconst ReportAnIssue = lazy(() => import(\"./containers/ReportAnIssue.jsx\"));\nconst ContactSupport = lazy(() => import(\"./containers/ContactSupport.jsx\"));\nconst NewFeature = lazy(() => import(\"./containers/NewFeature.jsx\"));\nconst FeatureThankYou = lazy(() => import(\"./containers/FeatureThankYou.jsx\"));\nconst FeaturePostMessage = lazy(() =>\n import(\"./containers/FeaturePostMessage.jsx\")\n);\nconst UserAccount = lazy(() => import(\"./containers/UserAccount.jsx\"));\nconst BuildBoxWorld = lazy(() => import(\"./containers/BuildBoxWorld.js\"));\nconst ReferralLandingPage = lazy(() =>\n import(\"./containers/ReferralLandingPage.jsx\")\n);\n\nconst GenAIPrompt = lazy(() => import(\"./containers/genai/GenAIPrompt.tsx\"));\nconst RenewalThankYou = lazy(() => import(\"./containers/RenewalThankYou\"))\nconst BB4AlphaPreviewNotes = lazy(() => import(\"./containers/BB4AlphaPreviewNotes\"));\nconst BB4CheckoutRedirect = lazy(() => import(\"./containers/BB4CheckoutRedirect\"));\nconst BB2CheckoutRedirect = lazy(() => import(\"./containers/BB2CheckoutRedirect\"));\n\nconst UpsellAfterTrial = lazy(() => import(\"./containers/trialUpsell/UpsellAfterTrial\"));\n\nconst BB2Campaign = lazy(() => import(\"./containers/landing/BB2Campaign\"));\n\nexport default function Routes({ appProps }) {\n const homePage = process.env.REACT_APP_MAIN_HOME_PAGE;\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {\n window.location.href = process.env.REACT_APP_STAGE === \"production\" ? \"https://storygames.buildbox.com/\": \"https://genai-fe.dev.8cell.com/\";\n return null;\n }}\n appProps={appProps}\n />\n {\n window.location.href = process.env.REACT_APP_STAGE === \"production\" ? \"https://buildboxworld.com/\": \"https://buildboxworld.com/\";\n return null;\n }}\n appProps={appProps}\n />\n \n \n \n \n {\n console.log('apple pay site verification route...');\n window.location.href = '/.well-known/apple-developer-merchantid-domain-association.dat';\n return null; \n }}\n appProps={appProps}\n />\n\n \n \n \n \n \n \n );\n}\n","import React, { useState, useEffect } from \"react\";\nimport styles from \"../styles/GenericLogoLander.module.scss\";\nimport { isUnsupportedBrowser } from \"../utils/browserUtils\";\n\nexport const RoadblockUI = (props) => {\n return (\n \n
\n
\n
\n Your browser is deprecated. Please use the latest version of Chrome,\n Firefox, Microsoft Edge, or Safari for an optimal experience.\n \n
\n
\n );\n};\n\nexport default function BrowserRoadblock({ children }) {\n const [isDeprecated, setRoadblock] = useState(false);\n\n const detectBrowser = () => {\n const isIE = isUnsupportedBrowser();\n\n if (isIE) {\n setRoadblock(true);\n sessionStorage.setItem(\"isDeprecated\", true);\n } else {\n setRoadblock(false);\n sessionStorage.setItem(\"isDeprecated\", false);\n }\n };\n\n useEffect(() => {\n detectBrowser();\n }, [isDeprecated]);\n\n return <>{isDeprecated ? : children}>;\n}\n","import React from 'react';\nimport { Helmet } from 'react-helmet';\n\nconst OneTrust = () => {\n return (\n <>\n {process.env.REACT_APP_STAGE === \"production\" ? \n null\n // (\n // \n // \n // \n // \n // \n // ) \n : \n (\n \n \n \n \n \n )\n }\n >\n );\n};\n\nexport default OneTrust;\n","import React, { useState, useEffect } from \"react\";\nimport Log from \"../src/utils/Log\";\nimport { push } from \"connected-react-router\";\nimport QueryString from \"query-string\";\nimport routes from \"./constants/routes.json\";\nimport { Hub } from \"@aws-amplify/core\";\nimport { withRouter } from \"react-router-dom\";\nimport { redirectToLoginPage } from \"./utils/routes\";\n\nimport Header from \"./containers/Header\";\nimport Footer from \"./containers/Footer\";\nimport Routes from \"./Routes\";\nimport styles from \"./styles/App.module.scss\";\n\nimport BrowserRoadblock from \"./containers/BrowserRoadblock\";\n//REDUX STUFF\nimport currentUserInfo from \"./selectors/currentUserInfo\";\nimport { login, logout } from \"./actions/auth\";\nimport { clientLoginRedirect, webLoginRedirect } from \"./actions/current\";\nimport { dispatchError } from \"./actions/error\";\nimport { showError } from \"./actions/error\";\nimport { setGAClientId } from \"./actions/analytics\";\nimport isLoggingInFromClient from \"./selectors/isLoggingInFromClient\";\n\nimport selectGAClientId from \"./selectors/selectGAClientId\";\nimport { waitForGAClientId } from \"./utils/analyticsUtils\";\nimport { setXsollaCookie } from \"./utils/referralUtils\";\n\nimport { useDispatch, useSelector } from \"react-redux\";\n\nimport { ToastContainer } from \"react-toastify\";\nimport OneTrust from \"./OneTrust\";\nimport \"react-toastify/dist/ReactToastify.css\";\n\n//use UserContext only for passing around methods:\nexport const UserContext = React.createContext();\n\nfunction App(props) {\n const dispatch = useDispatch();\n\n const currentUser = useSelector(currentUserInfo);\n\n const [authError, setAuthError] = useState(null);\n\n const [isAuthenticated, setIsAuthenticated] = useState(false);\n\n const errorState = useSelector((state) => state.error.error);\n const clientLoginState = useSelector(isLoggingInFromClient);\n const selectGoogleClientId = useSelector(selectGAClientId);\n\n useEffect(() => {\n onLoad();\n //eslint-disable-next-line\n }, []);\n\n useEffect(() => {\n if (errorState) {\n Log.error(errorState, \"App.js -- dispatching error\");\n dispatch(dispatchError(errorState));\n }\n //eslint-disable-next-line\n }, [errorState]);\n\n // Subscribe to auth events\n useEffect(() => {\n const handler = async ({ payload }) => {\n switch (payload.event) {\n case \"signIn\":\n Log.info(\"\", \"sign in heard\");\n try {\n await dispatch(login(props));\n const isFromBBClient = sessionStorage.getItem(\"fromBBClient\");\n\n if (isFromBBClient === \"true\") {\n await dispatch(clientLoginRedirect());\n } else {\n await dispatch(webLoginRedirect(props));\n }\n\n setIsAuthenticated(true);\n } catch (e) {\n Log.error(e, \"App.js: error caught signing in!!!\");\n setAuthError(e);\n dispatch(showError(e.message));\n }\n break;\n\n case \"signIn_failure\":\n Log.error(payload.data, \"App Component - error caught on signIn\");\n\n if (payload.data.message.includes(\"invalid_grant\") && !currentUser) {\n dispatch(\n showError(\"Something went wrong. Please sign out and log in.\")\n );\n redirectToLoginPage(props);\n } else {\n // redirectToAuthUI(props, payload.data);\n }\n\n break;\n case \"signOut\":\n dispatch(push(routes.CLIENT_LOGOUT_REDIRECT));\n break;\n\n default:\n break;\n }\n };\n\n Hub.listen(\"auth\", handler);\n \n //clean up any events\n return () => {\n Hub.remove(\"auth\", handler);\n };\n //eslint-disable-next-line\n }, []);\n\n async function onLoad() {\n try {\n const currentUrl = new URL(window.location);\n const urlQuery = QueryString.parse(currentUrl.search);\n const referralShortCode = urlQuery[\"tracking_id\"];\n\n if (referralShortCode) {\n setXsollaCookie(referralShortCode);\n }\n\n if (currentUser !== null) {\n Log.trace(\"user is already logged in\");\n }\n if (!selectGoogleClientId) {\n await waitForGAClientId((googleClientId) =>\n dispatch(setGAClientId(googleClientId))\n );\n }\n } catch (e) {\n if (e !== \"No current user\") {\n Log.error(e, \"App Component: error caught on load\");\n }\n }\n }\n\n // window.onload = function () {\n // console.log(\"hi\");\n // let sdk = document.getElementById(\"onetrust-consent-sdk\");\n // console.log(\"onetrust-consent-sdk\", sdk);\n // sdk.remove();\n // };\n\n async function handleLogout(url) {\n try {\n await dispatch(logout(url));\n } catch (e) {\n Log.error(e, \"App Component: error caught logging out\");\n dispatch(showError(e.message));\n }\n }\n\n const UserContextValue = {\n handleLogout: handleLogout,\n authError: authError,\n session: sessionStorage,\n };\n\n const hideHeaderAndFooter =\n props.location.pathname.includes(\"login\") ||\n props.location.pathname === \"/clientAwaitingGoogleLogin\" ||\n props.location.pathname === \"/clientAwaitingFacebookLogin\" ||\n props.location.pathname === \"/clientAwaitingAppleLogin\" ||\n props.location.pathname === \"/clientredirect\" ||\n props.location.pathname === \"/featurePostMessage\" ||\n props.location.pathname === \"/clientconnection\" ||\n (props.location.pathname.includes(\"/account/\") && clientLoginState) ||\n props.location.pathname === routes.REFERRAL_LANDING_PAGE;\n\n return (\n \n \n {!hideHeaderAndFooter && }\n \n \n\n \n {!hideHeaderAndFooter && (\n \n )}\n \n {!hideHeaderAndFooter && }\n \n \n
\n );\n}\n\nexport default withRouter(App);\n","import { AnyAction } from \"redux\";\nimport actions from \"../constants/actions.json\";\nimport { bbaiStoryGamePromptStepStatus, BBDocResponseObj } from \"../constants/GenPrompTypes\";\nimport { BBAI_STORE_VERSION, storeStorageVersion } from \"../utils/StorageVersion\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { mapPromptToDisplay } from \"../containers/genai/constants/mapPromptToDisplay\";\n\nexport const CYOAProjectType = \"cyoa\";\n\nconst BBAI_STORAGE_KEY = \"bbaiCyoa-Store\";\n\n\nstoreStorageVersion(BBAI_STORE_VERSION, BBAI_STORAGE_KEY);\n\n// localStorage.removeItem(BBAI_STORAGE_KEY);\n\nexport interface errorBody {\n title: string;\n message: string;\n}\n\nexport interface IStoryGameState {\n projectType: string;\n version: number;\n isLoading: boolean; \n completed?: boolean; \n error?: errorBody; \n promptStepStatus: bbaiStoryGamePromptStepStatus;\n userStoryPrompt: string;\n generatedCYOAGameData: any | null;\n projectId: string;\n allAssetsGenerated: boolean;\n bbworldBBDocId: string; \n isGuest: boolean;\n bbDocHistory: BBDocResponseObj[]|null\n // promptComponents: Display[] //React.ReactNode[]; //\n showAuthFrame: boolean;\n isAuthed: boolean;\n createAccountMode: boolean;\n userId: string | null;\n bbDocUrl: string | null;\n gameDataRestartID: string | null;\n titleImage: File | null;\n}\n\nexport const initialStoryGameState: IStoryGameState = {\n projectType: CYOAProjectType,\n version: BBAI_STORE_VERSION,\n isLoading: false,\n error: undefined,\n promptStepStatus: bbaiStoryGamePromptStepStatus.INITIAL,\n userStoryPrompt: \"\",\n generatedCYOAGameData: null,\n allAssetsGenerated: false,\n projectId: uuidv4(), // doesn't seeem to generate correctly\n bbworldBBDocId: \"\",\n completed: false,\n isGuest: false,\n bbDocHistory: null,\n // promptComponents: [mapPromptToDisplay[\"INITIAL\"]],\n showAuthFrame: false,\n isAuthed: false,\n createAccountMode: false,\n userId: null,\n bbDocUrl: null,\n gameDataRestartID: null,\n titleImage: null\n}; \n\n\nconst storyGameReducer = (\n state: IStoryGameState = initialStoryGameState,\n action: AnyAction\n):IStoryGameState => {\n switch (action.type) {\n case actions.storyGame.SET_LOADING: \n return {\n ...state,\n isLoading: action.loading\n }\n case actions.storyGame.INITIAL:\n return {\n ...initialStoryGameState\n }\n case actions.storyGame.SET_ERROR:\n return {\n ...state,\n error: action.error\n }\n case actions.storyGame.SET_PROMPT_STEP:\n return {\n ...state,\n promptStepStatus: action.stepStatus\n }\n case actions.storyGame.SET_USER_STORY_PROMPT:\n return {\n ...state,\n userStoryPrompt: action.prompt\n }\n case actions.storyGame.SET_GENERATED_STORY_GAME_DATA:\n return {\n ...state,\n generatedCYOAGameData: action.data\n }\n case actions.storyGame.SET_PROJECT_ID:\n return {\n ...state,\n projectId: action.id\n }\n case actions.storyGame.SET_ALL_ASSETS_GENERATED:\n return {\n ...state,\n allAssetsGenerated: action.allAssetsGenerated\n }\n case actions.storyGame.SET_BBWORLD_BBDOC_ID:\n return {\n ...state,\n bbworldBBDocId: action.id\n }\n case actions.storyGame.SET_BBDOC_HISTORY:\n return {\n ...state,\n bbDocHistory: action.history\n }\n case actions.storyGame.SET_GUEST: \n return { \n ...state,\n isGuest: action.isGuest\n }\n case actions.storyGame.NEXT_STAGE:\n const currentStage = state.promptStepStatus\n const nextStage = mapPromptToDisplay[bbaiStoryGamePromptStepStatus[currentStage]]?.nextStage\n return {\n ...state,\n promptStepStatus: bbaiStoryGamePromptStepStatus[nextStage as bbaiStoryGamePromptStepStatus],\n }\n case actions.storyGame.SET_STAGE: \n return {\n ...state,\n promptStepStatus: action.stage\n }\n case actions.storyGame.SET_SHOW_AUTH_FRAME:\n return {\n ...state,\n showAuthFrame: action.showAuthFrame\n }\n case actions.storyGame.SET_IS_AUTH: \n return {\n ...state,\n isAuthed: action.isAuthed\n }\n case actions.storyGame.SET_CREATE_ACCOUNT_MODE:\n return {\n ...state,\n createAccountMode: action.createAccountMode\n }\n case actions.storyGame.SET_USER_ID: \n return {\n ...state,\n userId: action.userId\n }\n case actions.storyGame.SET_BBDOC_URL:\n return {\n ...state,\n bbDocUrl: action.url\n }\n case actions.storyGame.START_OVER:\n return {\n ...initialStoryGameState,\n isAuthed: state.isAuthed,\n }\n case actions.storyGame.SET_RETRY_ID:\n return {\n ...state,\n gameDataRestartID: action.id\n }\n case actions.storyGame.SET_CONFIRM_COMPLETE:\n return {\n ...state,\n completed: true,\n }\n case actions.storyGame.GET_COMPONENTS_ARRAY: \n return {\n ...state,\n }\n case actions.storyGame.SET_TITLE_IMAGE:\n return {\n ...state,\n titleImage: action.titleImage\n }\n default:\n return state;\n }\n}\n\n\n\nexport default storyGameReducer;\n\n","\n\nexport const BBAI_STORE_VERSION = 6;\n\nexport const storeStorageVersion = (storeVersion: number, storageKey: string ) => {\n const BBAI_STORE_VERSION_KEY = `${storageKey}-version`;\n \n const storedVersionStr = localStorage.getItem(BBAI_STORE_VERSION_KEY);\n const storedVersion: number =\n storedVersionStr !== null ? parseInt(storedVersionStr) : 0;\n if (isNaN(storedVersion) || storedVersion < storeVersion) {\n console.warn(\n `[store.ts] Detected older version of prompt storage schema - clearing existing state`\n );\n localStorage.removeItem(storageKey);\n localStorage.setItem(BBAI_STORE_VERSION_KEY, storeVersion.toString(10));\n } else {\n console.debug(\n `[store.ts] bbai-storage-version is valid. found: ${storedVersion}, minimum: ${storeVersion}`\n );\n }\n\n}\n\n","module.exports = __webpack_public_path__ + \"static/media/BB4_Logo_Wordmark_Wht.e14e4e57.png\";","// extracted by mini-css-extract-plugin\nmodule.exports = {\"App\":\"App_App__2Fx1V\"};","// extracted by mini-css-extract-plugin\nmodule.exports = {\"animatedButton\":\"AnimatedButton_animatedButton__17jzF\",\"dance\":\"AnimatedButton_dance__3wA4q\"};","// import { showError } from \"./error\";\nimport { AnyAction } from \"redux\";\n// import { PlanType, WorkState } from \"../reducers/models\";\nimport actions from \"../constants/actions.json\";\n// import { getHouseAdCampaign, getSaleData } from \"../utils/saleUtils\";\nimport { errorBody } from \"../reducers/storyGameReducer\";\nimport { bbaiStoryGamePromptStepStatus, BBDocResponseObj } from \"../constants/GenPrompTypes\";\nimport { Display } from \"../containers/genai/constants/bbai.prompts\";\nimport { mapPromptToDisplay } from \"../containers/genai/constants/mapPromptToDisplay\";\n// import { getDiscountedPlanPricing } from \"../utils/saleUtils\";\n\n// export function resetSaleState(): DefaultThunkAction> {\n// return async (dispatch) => {\n// Log.trace(\"\", \"clearing sale state\");\n// sessionStorage.removeItem(\"promoCode\");\n// window.history.replaceState(null, window.location.pathname);\n\n// dispatch(clearSaleState());\n// };\n// }\n\nexport function loadingState(loading: boolean): AnyAction {\n return {\n type: actions.storyGame.SET_LOADING,\n loading,\n };\n}\n\nexport function setPolling(polling: boolean): AnyAction {\n return {\n type: actions.storyGame.SET_POLLING,\n polling,\n };\n}\n\nexport function initial(): AnyAction {\n return {\n type: actions.storyGame.INITIAL,\n // showSaleUI,\n };\n}\n\nexport function setErrorState(error: errorBody | undefined): AnyAction {\n return {\n type: actions.storyGame.SET_ERROR,\n error,\n };\n}\n\nexport function setPromptStepState(stepStatus: bbaiStoryGamePromptStepStatus): AnyAction {\n return {\n type: actions.storyGame.SET_PROMPT_STEP,\n stepStatus,\n };\n}\n\nexport function setUserStoryPrompt(prompt: string): AnyAction {\n return {\n type: actions.storyGame.SET_USER_STORY_PROMPT,\n prompt,\n };\n}\n\nexport function setGeneratedCYOAGameData(data: object | null): AnyAction {\n return {\n type: actions.storyGame.SET_GENERATED_STORY_GAME_DATA,\n data,\n };\n}\n\nexport function setProjectId(id: string): AnyAction {\n return {\n type: actions.storyGame.SET_PROJECT_ID,\n id\n };\n}\n\nexport function setAllAssetsGenerated(allAssetsGenerated: boolean): AnyAction {\n return {\n type: actions.storyGame.SET_ALL_ASSETS_GENERATED,\n allAssetsGenerated\n };\n}\n\nexport function setBBWorldBBDocId(id:string ): AnyAction {\n return {\n type: actions.storyGame.SET_BBWORLD_BBDOC_ID,\n id\n }\n}\n\nexport function setBBDocHistory(history:BBDocResponseObj[]|null): AnyAction {\n return {\n type: actions.storyGame.SET_BBDOC_HISTORY,\n history\n }\n}\n\nexport function setGuest(isGuest: boolean): AnyAction {\n return {\n type: actions.storyGame.SET_GUEST,\n isGuest\n }\n}\n\nexport function nextStage(): AnyAction {\n return {\n type: actions.storyGame.NEXT_STAGE,\n }\n}\n\nexport function setStage(stage: bbaiStoryGamePromptStepStatus): AnyAction {\n return {\n type: actions.storyGame.SET_STAGE,\n stage\n }\n}\n\nexport function setShowAuthFrame(showAuthFrame: boolean): AnyAction {\n return {\n type: actions.storyGame.SET_SHOW_AUTH_FRAME,\n showAuthFrame\n }\n}\n\nexport function setIsAuthed(isAuthed: boolean): AnyAction {\n return {\n type: actions.storyGame.SET_IS_AUTH,\n isAuthed\n }\n}\n\nexport function setCreateAccountMode(createAccountMode: boolean): AnyAction {\n return {\n type: actions.storyGame.SET_CREATE_ACCOUNT_MODE,\n createAccountMode\n }\n}\n\nexport function setUserId(userId: string): AnyAction {\n return {\n type: actions.storyGame.SET_USER_ID,\n userId\n }\n}\n\nexport function setBBDocUrl(url: string): AnyAction {\n return {\n type: actions.storyGame.SET_BBDOC_URL,\n url\n }\n}\n\nexport function startOver(): AnyAction {\n return {\n type: actions.storyGame.START_OVER,\n }\n}\n\nexport function setRetryID(id: string | null): AnyAction {\n\n // console.log(\"setRestartID\", id);\n let newComponentArray:Display[] = []\n\n for (const [key, value] of Object.entries(mapPromptToDisplay)) {\n newComponentArray.push(value)\n if(key === bbaiStoryGamePromptStepStatus.INITIAL) {\n break;\n } \n }\n \n return {\n type: actions.storyGame.SET_RETRY_ID,\n id\n }\n}\n\nexport function getComponentsArray(id: string | null): AnyAction {\n return {\n type: actions.storyGame.GET_COMPONENTS_ARRAY,\n id\n }\n}\n\nexport function setConfirmComplete(): AnyAction {\n return {\n type: actions.storyGame.SET_CONFIRM_COMPLETE,\n }\n}\n\nexport function setTitleImage(titleImage: File | null): AnyAction {\n return {\n type: actions.storyGame.SET_TITLE_IMAGE,\n titleImage\n }\n}","import { PlanType } from \"../reducers/models\";\n\nexport const BBDownloadVersion: bb.utility.IBBDownloadVersions = {\n BB4: {\n WIN: process.env.REACT_APP_BB4_DOWNLOAD_LINK_WIN,\n MAC: process.env.REACT_APP_BB4_DOWNLOAD_LINK_MAC,\n APP: \"buildbox4\",\n }, \n BB3: {\n WIN: process.env.REACT_APP_BB3_DOWNLOAD_LINK_WIN,\n MAC: process.env.REACT_APP_BB3_DOWNLOAD_LINK_MAC,\n APP: \"buildbox3\",\n },\n BB2: {\n WIN: process.env.REACT_APP_BB2_DOWNLOAD_LINK_WIN,\n MAC: process.env.REACT_APP_BB2_DOWNLOAD_LINK_MAC,\n APP: \"buildbox2\",\n },\n Soundbox: {\n WIN: process.env.REACT_APP_SOUNDBOX_DOWNLOAD_LINK_WIN,\n MAC: process.env.REACT_APP_SOUNDBOX_DOWNLOAD_LINK_MAC,\n APP: \"soundbox\",\n },\n Animationbox: {\n WIN: process.env.REACT_APP_ANIMATIONBOX_DOWNLOAD_LINK_WIN,\n MAC: process.env.REACT_APP_ANIMATIONBOX_DOWNLOAD_LINK_MAC,\n APP: \"animationbox\",\n },\n Pixelbox: {\n WIN: process.env.REACT_APP_PIXELBOX_DOWNLOAD_LINK_WIN,\n MAC: process.env.REACT_APP_PIXELBOX_DOWNLOAD_LINK_MAC,\n APP: \"pixelbox\",\n },\n Voxelbox: {\n WIN: process.env.REACT_APP_VOXELBOX_DOWNLOAD_LINK_WIN,\n MAC: process.env.REACT_APP_VOXELBOX_DOWNLOAD_LINK_MAC,\n APP: \"voxelbox\",\n }\n};\n\nexport const downloadPaths: bb.utility.DownloadPaths = {\n BB4: \"downloads/bb4\",\n BB3: \"downloads/bb3\",\n BB2: \"downloads/bb2\",\n BBBundle: \"downloads/bbbundle\",\n Soundbox: \"downloads/soundbox\",\n};\n\nexport const analyticProductTypes: bb.utility.BBProductTypes = {\n BB4: \"buildbox4\",\n BB3: \"buildbox3\",\n BB2: \"buildbox2\",\n BBBundle: \"buildboxbundle\",\n Soundbox: \"soundbox\",\n};\n\ntype AnalyticsProductTierNames = {\n [K in PlanType]: U;\n};\n\nexport const analyticProductTierNames: AnalyticsProductTierNames = {\n Monthly: \"Monthly\",\n Free: \"Free\",\n Plus: \"Plus\",\n Pro: \"Pro\",\n Bundle: \"Pro\",\n //Weekly: \"Weekly\",\n Beginner: \"Beginner\",\n Basic: \"Plus\",\n}\n\n","import API from \"@aws-amplify/api\";\nimport Log from \"../utils/Log\";\n\n//NK: We decided to keep this in case we want to implement Xsolla referral program in the future\n/**\n * fires a referral signup event\n *\n * @param {trackingId}: tracking id string from the referrer\n * @param {userId}: uuid of the signed up user in our server\n */\n\nexport const sendReferralTrackingId = (trackingId, userId) => {\n return new Promise((resolve, reject) => {\n API.post(\"assetsURL\", \"/assetmanagement/referralEvent\", {\n body: {\n trackingId: trackingId,\n userId: userId,\n },\n headers: {\n \"Content-Type\": \"application/json\",\n Token: \"\", //TODO: add access token here\n },\n response: true,\n })\n .then((res) => {\n console.log(\"res ======>\", res);\n Log.info(res.data, \"Referral Signup Credited:\");\n resolve(res);\n })\n .catch((e) => {\n Log.info(e.response?.data?.metadata?.message, \"Non-referral signup:\");\n if (e.response && e.response.status === 422) {\n resolve(e.response.data);\n } else {\n reject(e);\n }\n });\n });\n};\n","import Log from \"../utils/Log\";\nimport { push, replace } from \"connected-react-router\";\nimport Auth from \"@aws-amplify/auth\";\nimport { DefaultThunkAction } from \"./shared\";\nimport { AnyAction } from \"redux\";\nimport actions from \"../constants/actions.json\";\nimport routes from \"../constants/routes.json\";\nimport {\n createUser,\n fetchTokensforCode,\n fetchUserScreenName,\n updateUserScreenName,\n} from \"../api/auth\";\nimport { sendReferralTrackingId } from \"../api/referralprogram\";\nimport { addMailchimpAudienceTags } from \"../api/mailchimp\";\nimport { showError } from \"./error\";\nimport { LoginClientType, LoginState, WorkState } from \"../reducers/models\";\nimport {\n setFromSSORedirect,\n resetCurrentState,\n setLoginWorkState,\n setSignUpWorkState,\n setProductType,\n setLoggingInfromClient,\n} from \"./current\";\nimport {\n getCognitoUser,\n checkTokenExpiration,\n getRefreshedCognitoTokens,\n refreshWebAccessToken,\n getUserAttributes,\n} from \"../utils/CognitoUtils\";\nimport { setGAClientId, setAnalyticsRegistrationEvent } from \"./analytics\";\nimport { getGAClientId } from \"../utils/analyticsUtils\";\n// import { findCookieValue } from \"../utils/referralUtils\";\nimport { clearAccount } from \"./account\";\nimport { getDeviceType } from \"../utils/browserUtils\";\nimport { getRandomColor, getBBVersion } from \"../utils/helperUtils\";\nimport { validateEmail } from \"../utils/validationForm\";\n\n\nexport function login(props: any): DefaultThunkAction> {\n return async (dispatch) => {\n dispatch(setLoginWorkState(LoginState.Loading));\n try {\n const cognitoUserInfo:\n | bb.model.ICognitoUser\n | any = await getCognitoUser();\n const { accessToken, refreshToken, referralTrackingId } = cognitoUserInfo;\n // console.log(cognitoUserInfo);\n //if we detect a referral cookie on login include it for user creation\n const xsollaTrackingId = referralTrackingId;\n\n //console.log(\"login referral link\", referralTrackingId);\n let ReferralInfo = null;\n if (xsollaTrackingId) {\n ReferralInfo = {\n Network: \"Xsolla\",\n Info: xsollaTrackingId,\n };\n }\n\n const proposedBuildboxUserId = sessionStorage.getItem(\"proposedBuildboxUserId\");\n const oneTimeCode = sessionStorage.getItem(\"oneTimeCode\");\n const isGuest = sessionStorage.getItem(\"isGuest\") === \"1\";\n\n const userAttributes = await getUserAttributes(accessToken);\n const { email, name, username, locale } = userAttributes;\n\n const response = await createUser(accessToken, ReferralInfo, proposedBuildboxUserId, oneTimeCode, isGuest);\n const { user, userCreated } = response.payload;\n if(!user) {\n throw new Error(\"User creation failed\")\n }\n\n const userScreenName = await fetchUserScreenName(accessToken);\n dispatch(setUserScreenName(userScreenName));\n const userObject = {\n username: username,\n name: name,\n uuid: user.Id,\n email: email,\n // screenName: \"\",\n screenName: userScreenName || \"\",\n country: locale ? userAttributes.locale : \"United States of America\",\n isNewUser: userCreated,\n referralInfo: user.ReferralInfo,\n };\n\n const tokenObject = {\n refreshToken,\n accessToken,\n };\n const productType = sessionStorage.getItem(\"websocket-product\")\n ? sessionStorage.getItem(\"websocket-product\")\n : sessionStorage.getItem(\"productType\");\n\n sessionStorage.setItem(\"websocket-accessToken\", accessToken);\n sessionStorage.setItem(\"websocket-refreshToken\", refreshToken);\n sessionStorage.setItem(\"websocket-email\", email);\n sessionStorage.setItem(\"websocket-username\", username);\n\n sessionStorage.setItem(\"profileColor1\", getRandomColor());\n sessionStorage.setItem(\"profileColor2\", getRandomColor());\n\n dispatch(setUser(userObject));\n\n dispatch(setAuthTokens(tokenObject));\n\n const clientId = await getGAClientId();\n\n await dispatch(setGAClientId(clientId));\n\n //if we detect a cookie on login fire referral attribution\n // note this has to come after create user so we have the user id\n // maybe we could move it to platform side in the future.\n if (xsollaTrackingId) {\n await sendReferralTrackingId(xsollaTrackingId, user.Id);\n }\n\n if (userCreated) {\n await dispatch(handleNewUserRegistration(userObject, clientId));\n if (!email) return;\n await dispatch(setMailchimpMarketingTags(email, productType));\n } else {\n Log.info(email, \"not a new user\");\n }\n dispatch(setLoginWorkState(LoginState.None));\n\n // as we succeeded, clear out the checkout session info if there was any\n sessionStorage.removeItem(\"proposedBuildboxUserId\");\n sessionStorage.removeItem(\"oneTimeCode\");\n sessionStorage.removeItem(\"isGuest\");\n } \n catch (e:any) {\n Log.error(e, \"Error dispatching: login\");\n\n //show a global toast error for server errors on our end after Cognito signin\n dispatch(showError(e.message));\n\n if (e.response && e.response.status === 401) {\n dispatch(setLoginWorkState(LoginState.Unauthorized));\n } else {\n dispatch(setLoginWorkState(LoginState.ServerError));\n }\n }\n };\n}\n\nexport function logout(url?: string): DefaultThunkAction> {\n const previousRoute = sessionStorage.getItem(\"previousRoute\");\n\n return async (dispatch) => {\n try {\n await Auth.signOut();\n dispatch(clearUser());\n dispatch(resetCurrentState());\n dispatch(clearAccount());\n\n localStorage.clear();\n sessionStorage.clear();\n\n sessionStorage.setItem(\"previousRoute\", previousRoute || \"\");\n\n if (url && url.length) {\n window.location.href = url;\n }\n //else if (previousRoute) {\n // dispatch(push(previousRoute));\n // } else {\n // dispatch(push(routes.LOGIN));\n // }\n } catch (e:any) {\n Log.error(e, \"Error dispatching: logout\");\n let message = e.message\n dispatch(showError(message));\n }\n };\n}\n\nexport function ssoTokenLogin(\n token: string,\n goToPlansPage: boolean,\n planView?: string\n): DefaultThunkAction> {\n return async (dispatch) => {\n dispatch(setLoginWorkState(LoginState.Loading));\n try {\n const response = await fetchTokensforCode(token);\n\n Log.info(response, \"Response from fetchTokensforCode\");\n const {\n userId,\n email,\n accessToken,\n clientId,\n refreshToken,\n clientSecret,\n referralInfo,\n } = response;\n const userAttributes = await getUserAttributes(accessToken);\n Log.info(userAttributes, \"Response from userAttributes\");\n\n const userScreenName = await fetchUserScreenName(accessToken);\n\n const userObject = {\n username: userAttributes.username,\n name: userAttributes.name || email,\n uuid: userId,\n screenName: userScreenName || \"\",\n email: userAttributes.email || email,\n isNewUser: false,\n referralInfo: referralInfo,\n };\n\n const tokenObject = {\n refreshToken,\n accessToken,\n };\n\n Log.info(response, \"fetchTokensforCode response\");\n\n const gaClientId = await getGAClientId();\n\n dispatch(setGAClientId(gaClientId));\n\n //set the user object here\n dispatch(setUserScreenName(userScreenName));\n dispatch(setUser(userObject));\n\n dispatch(setCognitoClientInfo(clientId, clientSecret));\n dispatch(setAuthTokens(tokenObject));\n\n dispatch(setFromSSORedirect(true));\n dispatch(setLoggingInfromClient(LoginClientType.Client));\n dispatch(setLoginWorkState(LoginState.None));\n\n if (goToPlansPage) {\n if (planView && planView.length) {\n dispatch(setProductType(planView));\n dispatch(replace(`${routes.PURCHASE_PLANS}/${planView}`));\n } else {\n dispatch(push(routes.PURCHASE_PLANS));\n }\n }\n } catch (e:any) {\n Log.error(e, \"Error dispatching: ssoTokenLogin\");\n\n if (e.response && e.response.status === 401) {\n dispatch(setLoginWorkState(LoginState.Unauthorized));\n } else {\n dispatch(setLoginWorkState(LoginState.ServerError));\n }\n console.log(\"redirecting in sso token login!!\");\n\n //redirect user to web login\n dispatch(push(routes.LOGIN));\n }\n };\n}\n\nexport function handleNewUserRegistration(\n user: bb.model.IUser,\n clientId: string\n): DefaultThunkAction> {\n return async (dispatch) => {\n try {\n const { email, uuid } = user;\n let productName = sessionStorage.getItem(\"productType\")?.toLowerCase()\n let productType\n if(productName?.includes(\"bb2\")) {\n productType = \"buildbox2\"\n }\n else if(productName?.includes(\"bb3\")) {\n productType = \"buildbox3\"\n }\n else if(productName?.includes(\"bb4\")) {\n productType = \"buildbox4\"\n } \n else if(productName?.includes(\"soundbox\")) {\n productType = \"soundbox\"\n }\n else if(productName?.includes(\"bbbundle\") || productName?.includes(\"buildboxbundle\")) {\n productType = \"buildboxbundle\"\n }\n else {\n //console.error(\"unrecognized product: \", productName)\n //throw new Error(\"unrecognized product during user registration \" + productName)\n\n // TODO: should this be 'generic' or something?\n // throwing an error doesn't seem great\n console.log(\"no product selected on signup, defaulting to buildbox4\")\n productType = \"buildbox4\"\n }\n const deviceType = getDeviceType();\n\n Log.trace(deviceType, \"User is signing up on:\");\n await dispatch(\n setAnalyticsRegistrationEvent(\n email,\n uuid,\n clientId,\n productType,\n deviceType\n )\n );\n\n setSignUpWorkState(WorkState.None);\n } catch (error:any) {\n Log.error(error, \"Error dispatching: handleNewUserRegistration\");\n setSignUpWorkState(WorkState.Error);\n throw error;\n }\n };\n}\n\n//used to set mailchimp tags by product type for signed up user\nexport function setMailchimpMarketingTags(\n email: string,\n productType: string | null\n): DefaultThunkAction> {\n return async (dispatch) => {\n dispatch(setSignUpWorkState(WorkState.Loading));\n try {\n const product = getBBVersion(productType);\n const response = await addMailchimpAudienceTags(email, product);\n Log.info(\n response,\n `new user - adding Mailchimp Tags for product type: ${product}`\n );\n dispatch(setSignUpWorkState(WorkState.None));\n } catch (error:any) {\n //Log.error(error, \"error caught in setAnalyticsRegistrationEvent\");\n //dispatch(setSignUpWorkState(WorkState.Error));\n //throw error;\n\n // mailchimp gives too many unimportant errors, let's catch this and move on\n console.log(\"error adding mailchimp tags\", error);\n dispatch(setSignUpWorkState(WorkState.None));\n }\n };\n}\n\n//validates and refreshes cognito auth tokens\n\nexport function validateToken(): DefaultThunkAction> {\n return async (dispatch, getState) => {\n dispatch(setLoginWorkState(LoginState.Loading));\n\n try {\n const { auth } = getState();\n if(!auth || !auth.authTokens) {\n dispatch(setLoginWorkState(LoginState.Unauthorized));\n throw new Error(\"Please log in\")\n }\n\n const { accessToken, refreshToken } = auth.authTokens;\n if(!accessToken || !refreshToken) {\n dispatch(setLoginWorkState(LoginState.Unauthorized));\n throw new Error(\"Please log in\")\n }\n\n let tokenIsExpired = await checkTokenExpiration(accessToken);\n Log.trace(tokenIsExpired, \"Validate token: is token expired?\");\n\n if (tokenIsExpired || !accessToken) {\n const refreshedToken = await dispatch(refreshTokens(refreshToken));\n return refreshedToken;\n } else {\n dispatch(setLoginWorkState(LoginState.None));\n Log.info(\"\", \"access token is looking ok\");\n return accessToken;\n }\n } catch (error:any) {\n Log.error(error, \"Error dispatching: validateToken\");\n dispatch(setLoginWorkState(LoginState.Unauthorized));\n\n throw error;\n }\n };\n}\n\nexport function refreshTokens(\n refreshToken: string\n): DefaultThunkAction> {\n return async (dispatch, getState) => {\n dispatch(setLoginWorkState(LoginState.Loading));\n\n try {\n const { auth } = getState();\n const { cognitoClientId, clientSecret } = auth;\n let newToken = null;\n\n // refreshing with client tokens\n if (cognitoClientId && clientSecret) {\n newToken = await getRefreshedCognitoTokens(\n refreshToken,\n cognitoClientId,\n clientSecret\n );\n } else {\n newToken = await refreshWebAccessToken();\n }\n\n const tokenObject = {\n accessToken: newToken,\n refreshToken: refreshToken,\n };\n dispatch(setAuthTokens(tokenObject));\n dispatch(setLoginWorkState(LoginState.None));\n return newToken;\n } catch (error:any) {\n Log.error(error, \"Error dispatching: refreshTokens\");\n dispatch(setLoginWorkState(LoginState.Unauthorized));\n\n let message = error.message\n if (message) {\n throw new Error(message);\n } \n else {\n let newError = error;\n if (error === \"not authenticated\") {\n newError = new Error(\n `Your session has expired. Please sign in and try again`\n );\n // manual forced logout to prevent potential infinite loop\n await Auth.signOut();\n dispatch(clearUser());\n dispatch(resetCurrentState());\n dispatch(clearAccount());\n \n localStorage.clear();\n sessionStorage.clear(); \n }\n dispatch(push(routes.LOGIN));\n throw newError;\n }\n }\n };\n}\n\nexport function handleUpdateUserScreenName(\n screenName: string\n): DefaultThunkAction> {\n return async (dispatch) => {\n const accessToken = await dispatch>(validateToken());\n try {\n const newScreenName = await updateUserScreenName(accessToken, screenName);\n console.log(newScreenName);\n dispatch(setUserScreenName(newScreenName));\n\n return newScreenName;\n } catch (error:any) {\n console.log(\"error: \", error);\n // let err\n // if ( error.metadata.errorcode === 'ERROR_SCREEN_NAME_IN_USE'){\n // err = 'This Creator Name is already taken. Please choose a different one.'\n // }\n // if (error.metadata.errorcode === 'ERROR_SCREEN_NAME_INAPPROPRIATE' ){\n // err = error.metadata.message\n // }\n // if ( error.metadata.errorcode === 'ERROR_INVALID_SCREEN_NAME' ){\n // err = 'Creator Name must: be 3-25 characters long, only contain letters, numbers, dashes, periods, or underscores'\n // }\n\n let errorcode = error.metadata.errorcode\n throw errorcode;\n }\n };\n}\nexport function setCognitoClientInfo(\n cognitoClientId: string,\n clientSecret: string\n) {\n return {\n type: actions.auth.SET_COGNITO_CLIENT_INFO,\n cognitoClientId,\n clientSecret,\n };\n}\n\nexport function setUserScreenName(screenName: string): AnyAction {\n return {\n type: actions.auth.SET_SCREEN_NAME,\n screenName,\n };\n}\n\nexport function setAuthTokens(tokens: bb.model.ITokens): AnyAction {\n return {\n type: actions.auth.SET_AUTH_TOKENS,\n tokens,\n };\n}\n\nexport function setUser(user: bb.model.IUser): AnyAction {\n return {\n type: actions.auth.SET_USER,\n user,\n };\n}\n\nexport function clearUser(): AnyAction {\n return {\n type: actions.auth.CLEAR_USER,\n };\n}\n\nexport function setAccountlessPurchaseEmail(email: string | undefined): AnyAction {\n let actionBody: { \n type: string,\n email: string | undefined\n } = {\n type: actions.auth.SET_ACCOUNTLESS_PURCHASE_EMAIL,\n email: undefined\n }\n if(!email) return actionBody\n \n if(validateEmail(email)){\n console.debug(\"email is valid\")\n actionBody.email = email\n }\n return actionBody\n}","import API from \"@aws-amplify/api\";\nimport Log from \"../utils/Log\";\nimport {\n BBDocResponseObj,\n BBDownloadVersion,\n ChooseYourOwnAdventureChapterData,\n ChooseYourOwnAdventureChoiceData,\n ChooseYourOwnAdventureCustomizationData,\n CreateTxt2ImgGenerationJobDTO,\n DownloadPlatforms,\n ImageGenerationJobCreationResultDTO,\n PostSSOTokensDTO,\n templateType,\n Txt2ImgGenerationJobCreationResultDTO,\n} from \"../constants/GenPrompTypes\";\nimport Env from \"../Env\";\nimport { SharedBit } from \"../constants/BBPlatform.types\";\nconst UUID_REGEX = /^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$/\nexport class BBPlatformClientError extends Error {}\n\n\nfunction convertBBAICYOADataToPlatformFormat(projectId: string, input: any) : ChooseYourOwnAdventureCustomizationData {\n console.debug(\"convert to platform format for cyoa data: \", input)\n // AP: a little hacky but really this whole thing is \n let output: ChooseYourOwnAdventureCustomizationData = {} as ChooseYourOwnAdventureCustomizationData\n\n output.projectId = projectId;\n output.badEndText = input.lose.chapterContent;\n output.goodEndText = input.win.chapterContent;\n output.badEndImageFilename = \"lose.png\";\n output.goodEndImageFilename = \"win.png\";\n output.title = input.title.title;\n output.subtitle = input.title.mission;\n output.titleImageFilename = \"title.png\";\n output.iconFilename = \"icon.png\";\n output.backgroundMusicFilename = \"background_music.mp3\"; // TODO: figure this out, it's actually NYI\n\n // make some chapters...\n let chapters : ChooseYourOwnAdventureChapterData[] = []\n for(let ii = 0; ii < input.chapters.length; ii++) {\n let chapter = input.chapters[ii]\n // console.debug(\"chapter looks like: \", chapter)\n chapter.description = chapter.chapterContent;\n chapter.imageFilename = `chapter${ii}.png`\n let choicesData = chapter.choices\n let choices : ChooseYourOwnAdventureChoiceData[] = []\n for(let jj = 0; jj < choicesData.length; jj++) {\n let choiceData = choicesData[jj]\n let choice : ChooseYourOwnAdventureChoiceData = {\n choiceDescription: choiceData.choiceDescription,\n coinsDelta: choiceData.coinsDelta,\n healthDelta: choiceData.healthDelta,\n resultDescription: choiceData.resultDescription,\n }\n choices.push(choice)\n }\n chapter.choices = choices\n chapters.push(chapter)\n }\n output.chapters = chapters\n\n\n return output\n }\n\n// export const fancyTokenFunction = (): DefaultThunkAction> => {\n// return async (dispatch) => {\n// return await dispatch(validateToken());\n// }\n// }\n\nexport const getGenerateAsset = async (\n accessToken:any,\n body: CreateTxt2ImgGenerationJobDTO\n ): Promise => {\n try{ \n const res = await API.post(\"bb2URL\", \"/assetgeneration/txt2img\", {\n body: body,\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload;\n } catch (error) {\n Log.error(error, \"error caught in getGenerateAsset\");\n throw error;\n }\n}\n\nexport const getAssetGenerationProgress = async (\n accessToken:any,\n jobId: string\n ): Promise => {\n try{ \n \n const res = await API.get(\"bb2URL\", `/assetgeneration/job/${jobId}/progress`, {\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload;\n\n } catch(error) {\n Log.error(error, \"error caught in getAssetGenerationProgress\");\n throw error\n }\n}\n\nexport const generateClipdropAsset = async ( \n accessToken:any,\n body: CreateTxt2ImgGenerationJobDTO\n ): Promise => {\n\n try { \n const res = await API.post(\"bb2URL\", \"/assetgeneration/clipdrop/txt2img\", {\n body: body,\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload;\n } catch(error){ \n Log.error(error, \"error caught in generateClipdropAsset\"\n )\n throw error\n }\n}\n\nexport const emplaceCYOAResource = async ( \n accessToken:any,\n projectId: string,\n filename: string,\n url: string): Promise => {\n let data = {\n projectId: projectId,\n filename: filename,\n url: url,\n }\n\n try{\n const res = await API.post(\"bb2URL\", `/cyoa/emplace`, {\n body: data,\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload;\n\n }catch(error){\n Log.error(error, \"error caught in emplaceCYOAResource\")\n throw error\n }\n}\n\nexport const createCYOABBDoc = async (\n accessToken:any,\n projectId: string,\n gameData: any\n ): Promise => {\n let data = convertBBAICYOADataToPlatformFormat(projectId, gameData)\n\n try{ \n const res = await API.post(\"bb2URL\", `/cyoa/cyoa`, {\n body: data,\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload;\n } catch(error) {\n Log.error(error, \"error caught in createCYOABBDoc\")\n throw error\n }\n}\n\nexport const createBBDocRandomFile = async (body: {\n accessToken:any;\n characterImage: string;\n obstacleImage: string;\n backgroundImage: string;\n }): Promise => {\n const index = Math.floor(Math.random() * Object.keys(templateType).length);\n const randomTemplateType = Object.values(templateType)[index];\n\n try{\n const res = await API.post(\"bb2URL\", `/assetgeneration/createbbdoc`, {\n body: {\n ...body,\n templateType: templateType[randomTemplateType],\n //templateType: templateType[\"WORLD\"]\n },\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: body.accessToken\n },\n response: true\n })\n\n return res.data.payload;\n\n }catch(error) {\n Log.error(error, \"error caught in createBBDocRandomFile\")\n throw error\n }\n}\n\nexport const getAssetImages = async (\n accessToken:any,\n jobId: string\n ): Promise<{ jobId: string; presignedUrls: string[] }> => {\n try{\n const res = await API.get(\"bb2URL\", `/assetgeneration/job/${jobId}/result`, {\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload;\n } catch(error) {\n Log.error(error, \"error caught in getAssetImages\")\n throw error\n }\n }\n\nexport const downloadBuildboxClient = async ( \n accessToken:any,\n platformDesired: any,\n version: keyof typeof BBDownloadVersion\n ) => {\n\n try{ \n if (!platformDesired) {\n // try to auto detect platform from browser\n const platform = (window as any).navigator.platform;\n\n if (platform) {\n const macosPlatforms = [\"Macintosh\", \"MacIntel\", \"MacPPC\", \"Mac68K\"];\n const windowsPlatforms = [\"Win32\", \"Win64\", \"Windows\", \"WinCE\"];\n\n const foundMatch = (str: string) => str.includes(platform);\n if (windowsPlatforms.some(foundMatch)) {\n platformDesired = DownloadPlatforms.WINDOWS;\n } else if (macosPlatforms.some(foundMatch)) {\n platformDesired = DownloadPlatforms.MAC;\n } else {\n console.debug(\n \"unable to automatically determine download platform from \",\n platform\n );\n platformDesired = DownloadPlatforms.UNKNOWN;\n\n const dataLayer =\n ((window as any)[\"dataLayer\"] && (window as any)[\"dataLayer\"]) ||\n [];\n dataLayer.push({\n event: \"couldNotDeterminePlatformDownload\",\n payload: true,\n });\n }\n } else {\n console.debug(\"unable to automatically determine download platform\");\n platformDesired = DownloadPlatforms.UNKNOWN;\n\n const dataLayer = ((window as any).dataLayer =\n (window as any).dataLayer || []);\n dataLayer.push({\n event: \"platformInfoNotAvailableDownload\",\n payload: true,\n });\n }\n }\n\n // download!\n if (platformDesired === DownloadPlatforms.MAC) {\n\n //TODO: Update GTM tags to track BB2\n\n const downloadLink = BBDownloadVersion[version].MAC;\n // const downloadType = BBDownloadVersion[version].APP;\n\n (window as any).location.href = downloadLink;\n\n const dataLayer = ((window as any).dataLayer =\n (window as any).dataLayer || []);\n dataLayer.push({\n event: \"macDownload\",\n payload: true,\n });\n\n // const savedGoogleClientId = localStorage.getItem(\"googleClientId\");\n // BBPlatformClient.sendDownloadAnalytics(savedGoogleClientId, downloadType);\n\n return(downloadLink);\n } else if (platformDesired === DownloadPlatforms.WINDOWS) {\n\n //TODO: Update GTM tags to track BB2\n\n const downloadLink = BBDownloadVersion[version].WIN;\n // const downloadType = BBDownloadVersion[version].APP;\n\n (window as any).location.href = downloadLink;\n\n const dataLayer = ((window as any).dataLayer =\n (window as any).dataLayer || []);\n dataLayer.push({\n event: \"winDownload\",\n payload: true,\n });\n\n return (downloadLink);\n } else {\n console.debug(\"attempted download on non-mac/win platform\");\n\n const dataLayer = ((window as any).dataLayer =\n (window as any).dataLayer || []);\n dataLayer.push({\n event: \"unknownPlatformDownload\",\n payload: true,\n });\n\n return (false);\n }\n } catch( error) {\n Log.error(error, \"error caught in downloadBuildboxClient\")\n throw error\n } \n\n} \n \nexport const createUserDownloadsRequest = async (\n accessToken:any,\n clientId: any, version: string) => {\n let error;\n for (let ii = 0; ii < 5; ii++) {\n try {\n let resp = await sendUserDownloadRequestAnalytics(\n accessToken,\n clientId,\n version\n );\n return resp;\n } catch (err) {\n console.error(\"cudr error: \", err);\n error = err;\n }\n }\n\n console.debug(\"throw cudr error: \", error);\n throw error;\n }\n\nexport const sendUserDownloadRequestAnalytics = async(\n accessToken:any,\n clientId: any,\n version: string\n ): Promise => {\n try{\n const res = await API.post(\"userAccountManagementURL\", `/analytics/download`, {\n body: {\n clientId: clientId,\n app: version,\n },\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.data;\n \n }catch(error) {\n Log.error(error, \"error caught in sendUserDownloadRequestAnalytics\")\n throw error\n }\n}\n\n\nexport const sendDownloadAnalytics = async ( accesssToken:string, googleClientId: any, version: any) => {\n try {\n console.debug(googleClientId, \"Downloads Component: send client id\");\n console.debug(version, \"Downloads Component: app:\", version);\n\n const analyticsResponse =\n await createUserDownloadsRequest(\n accesssToken,\n googleClientId,\n version\n );\n console.debug(\n analyticsResponse,\n \"Downloads Component: Response from /createUserDownloadsRequest\"\n );\n } catch (error) {\n console.error(\n error,\n \"Downloads Component: Error caught from sendDownloadAnalytics\"\n );\n }\n }\n\nexport const getUserBBDocs = async (accessToken:any, limit:number=10,offset:number=0): Promise => {\n try{ \n const res = await API.get(\"bbworldUrl\", `/bbdoc/owned?runtime=BBClassic&limit=${limit}&offset=${offset}`, {\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload.bits;\n\n }catch(error) {\n Log.error(error, \"error caught in getUserBBDocs\")\n throw error\n }\n}\n\nexport const getBBDocDownloadLink = async (accessToken: any, bbdocId:string):Promise => {\n const validUUID = UUID_REGEX.test(bbdocId) // make sure it's a UUID and not some sill XSS attack\n if (!validUUID) {\n throw new BBPlatformClientError(\"Invalid BBDoc ID\")\n }\n try{ \n const res = await API.get(\"bb2URL\", `/assetgeneration/bbdoc/download/${bbdocId}`, {\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Tokoen: accessToken\n },\n response: true\n })\n\n return res.data.payload.url;\n\n } catch (error) {\n Log.error(error, \"error caught in getBBDocDownloadLink\")\n throw error\n }\n}\n\n\nexport const openBBWorld= (bbDocId:string=\"\"):void => {\n console.debug(\"play bit\", `${Env.BB_DEEP_LINK}${bbDocId}`)\n window.location.replace(`${Env.BB_DEEP_LINK}${bbDocId}`);\n}\n\nexport const getSSOToken = async ( accessToken:any, ssoTokenDTO:PostSSOTokensDTO ): Promise => {\n try{ \n const res = await API.post(\"userAccountManagementURL\", `/ssoTokens`, {\n body: {\n ...ssoTokenDTO\n },\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload.id;\n } catch(error){\n Log.error(error, \"error caught in getSSOToken\")\n throw error\n }\n}\n\n\nexport const cyoaNewId = async (accessToken:any): Promise =>\n{\n try{\n const res = await API.post(\"bb2URL\", `/cyoa/newId`, {\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload.projectId;\n\n } catch(error) {\n Log.error(error, \"error caught in cyoaNewId\")\n throw error\n }\n}\n\nexport const cyoaConfirmComplete = async (accessToken:any, projectId:string): Promise => {\n try{\n const res = await API.post(\"bb2URL\", `/cyoa/complete`, {\n body: {\n projectId\n },\n headers: {\n \"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload;\n\n } catch(error) {\n Log.error(error, \"error caught in cyoaConfirmation\")\n throw error\n }\n}\n\nexport const getCYOABBDocDownloadLink = async ( accessToken:any, projectId:string):Promise<{url:string, expiresIn:string}> => {\n const validUUID = UUID_REGEX.test(projectId) // make sure it's a UUID and not some sill XSS attack\n if (!validUUID) {\n throw new BBPlatformClientError(\"Invalid BBDoc ID\")\n }\n\n try{ \n const res = await API.get(\"bb2URL\", `/cyoa/bbdoc/download/${projectId}`, {\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return { url: res.data.payload.url, expiresIn: res.data.payload.expiresIn };\n\n } catch(error) {\n Log.error(error, \"error caught in getCYOABBDocDownloadLink\")\n throw error\n }\n}\n\nexport const getUserData = async (accessToken:any ): Promise => {\n\n try{ \n const res = await API.post(\"userAccountManagementURL\", `/webclientLogin`, {\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload;\n\n } catch(error) {\n Log.error(error, \"error caught in getUserData\")\n throw error\n }\n}\nexport const getBalance = async (accessToken:any): Promise<{ balance: number, creditsUsed: number}> => {\n try{ \n\n const res = await API.get(\"bb2URL\", `/cyoa/balance`, {\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload;\n\n } catch(error) {\n console.error(error, \"error caught in getBalance\")\n throw error\n }\n}\n \nexport const getFirebaseShortenDeepLink = async ( accessToken:any, bitId:string): Promise => {\n try{ \n const res = await API.get(\"bbworldUrl\", `/firebaseShortLink/${bitId}`, {\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data.payload.url;\n } catch(error) {\n // Log.error(error, \"error caught in getFirebaseShortenDeepLink\")\n throw error\n\n }\n}\n\nexport const cyoaGameAsJson = async (accessToken: any, userInput: string, numberOfChapters: number = 10): Promise => {\n\n try{ \n const res = await API.post(\"bbaiURL\", `/cyoa/game_as_json`, {\n body: {\n \"openai_configs\": {\n \"model_name\": Env.CYOA_OPENAI_MODEL,\n \"temperature\": Env.CYOA_OPENAI_TEMPERATURE,\n },\n \"user_input\": userInput,\n \"number_of_chapters\": numberOfChapters\n },\n headers: {\n\"webgenai-client-version\": true,\n \"Content-Type\": \"application/json\",\n Token: accessToken\n },\n response: true\n })\n\n return res.data;\n\n }catch(error) {\n Log.error(error, \"error caught in cyoaGameAsJson\")\n throw error\n }\n}\n\nexport const getAllSharedBits = async ( offset: number = 0):Promise => {\n try {\n const res = await API.get(\"bbworldUrl\", `/globalBits?offset=${offset}&limit=100`, {\n headers: {\n \"Content-Type\": \"application/json\"\n }\n })\n // console.log(res.payload)\n return res.payload.bits\n }catch(error) {\n Log.error(error, \"error caught in getAllSharedBits\")\n throw error\n }\n}","import actions from \"../constants/actions.json\";\nimport { toast } from \"react-toastify\";\nimport { v4 } from \"uuid\";\nimport { DefaultThunkAction } from \"./shared\";\n\n//for global toast errors\nexport function dispatchError(\n error: string\n): DefaultThunkAction> {\n return async (dispatch, getState) => {\n setTimeout(() => {\n toast.error(error, {\n toastId: v4(),\n onClose: () => dispatch(clearError()),\n });\n }, 100);\n\n await dispatch(clearError());\n };\n}\n\nexport function clearError() {\n toast.dismiss();\n return {\n type: actions.error.HIDE_ERROR,\n };\n}\n//for global errors\nexport function showError(error: string) {\n return {\n type: actions.error.SHOW_ERROR,\n error,\n };\n}\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"promptMessage\":\"PromptMessage_promptMessage__3fses\",\"senderImg\":\"PromptMessage_senderImg__2M8Bg\",\"promptImgContainer\":\"PromptMessage_promptImgContainer__2N-zq\",\"promptImg\":\"PromptMessage_promptImg__3SdU0\",\"promptImgActive\":\"PromptMessage_promptImgActive__31nPq\",\"promptDownload\":\"PromptMessage_promptDownload__XWiwr\",\"promptFeedbackUser\":\"PromptMessage_promptFeedbackUser__WRoag\",\"promptFeedbackBBAI\":\"PromptMessage_promptFeedbackBBAI__16hC9\",\"fancyText\":\"PromptMessage_fancyText__1hl0e\",\"promptImgLandscape\":\"PromptMessage_promptImgLandscape__1aGet\",\"qrContainer\":\"PromptMessage_qrContainer__1Lmcc\"};","import debug from \"debug\";\n\n// we use this to be able to see logs only for dev in the dev tools console\n//Format Log.info(response object/\"my message\", \"some general info about where it came from\")\n//Format Log.error(error object/\"my message\", \"registration error event:\")\n\nconst BASE = \"bb-frontend-dev\";\nconst COLOURS = {\n trace: \"lightblue\",\n info: \"blue\",\n warn: \"pink\",\n error: \"red\",\n}; // choose better colours :)\n\nclass Log {\n generateMessage(level, message, source) {\n // Set the prefix which will cause debug to enable the message\n const namespace = `${BASE}:${level}`;\n const createDebug = debug(namespace);\n\n createDebug.enabled = true;\n\n // Set the colour of the message based on the level\n createDebug.color = COLOURS[level];\n\n //only show logs in dev environment\n\n if (\n process.env.REACT_APP_STAGE !== \"production\" &&\n process.env.NODE_ENV !== \"test\"\n ) {\n if (source) {\n createDebug(source, message);\n } else {\n createDebug(message);\n }\n }\n }\n\n trace(message, source) {\n return this.generateMessage(\"trace\", message, source);\n }\n\n info(message, source) {\n return this.generateMessage(\"info\", message, source);\n }\n\n warn(message, source) {\n return this.generateMessage(\"warn\", message, source);\n }\n\n error(message, source) {\n return this.generateMessage(\"error\", message, source);\n }\n}\n\nexport default new Log();\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === \"localhost\" ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === \"[::1]\" ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\nexport function register(config) {\n if (process.env.NODE_ENV === \"production\" && \"serviceWorker\" in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener(\"load\", () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n \"This web app is being served cache-first by a service \" +\n \"worker. To learn more, visit https://bit.ly/CRA-PWA\"\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then((registration) => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker==null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === \"installed\") {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n \"New content is available and will be used when all \" +\n \"tabs for this page are closed. See https://bit.ly/CRA-PWA.\"\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log(\"Content is cached for offline use.\");\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch((error) => {\n console.error(\"Error during service worker registration:\", error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { \"Service-Worker\": \"script\" },\n })\n .then((response) => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get(\"content-type\");\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf(\"javascript\") === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then((registration) => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n \"No internet connection found. App is running in offline mode.\"\n );\n });\n}\n\nexport function unregister() {\n if (\"serviceWorker\" in navigator) {\n navigator.serviceWorker.ready\n .then((registration) => {\n registration.unregister();\n })\n .catch((error) => {\n console.error(error.message);\n });\n }\n}\n","import React, { ReactNode } from 'react';\n\ninterface ChunkErrorBoundaryProps {\n children: ReactNode;\n}\n\ninterface ChunkErrorBoundaryState {\n hasChunkError: boolean;\n hasOtherError: boolean;\n}\n\nclass ChunkErrorBoundary extends React.Component {\n constructor(props: ChunkErrorBoundaryProps) {\n super(props);\n this.state = { \n hasChunkError: false,\n hasOtherError: false,\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial | null {\n if (error.name === \"ChunkLoadError\" || error.message.includes(\"MIME type\")) {\n return { hasChunkError: true, hasOtherError: false };\n }\n else {\n return { hasChunkError: false, hasOtherError: true };\n }\n }\n\n componentDidCatch(error: Error, info: React.ErrorInfo) {\n if (error.name === \"ChunkLoadError\" || error.message.includes(\"MIME type\")) {\n console.error(\"Chunk or MIME type error caught in ChunkErrorBoundary:\", error, info);\n }\n else {\n console.error(\"Other error caught in ChunkErrorBoundary:\", error, info);\n }\n }\n\n render() {\n if (this.state.hasChunkError) {\n return (\n \n
This page has been updated! \n
\n Please refresh to get the latest version.\n
\n
window.location.reload()}>\n Refresh Page\n \n
\n );\n }\n else if (this.state.hasOtherError) {\n return (\n \n
Something unexpected happened. \n
\n You can try refreshing the page to try again. If you need more assistance please contact support@buildbox.com\n
\n
window.location.reload()}>\n Refresh Page\n \n
\n );\n\n }\n\n return this.props.children;\n }\n}\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column' as const,\n justifyContent: 'center',\n alignItems: 'center',\n height: '100vh',\n backgroundColor: '#f8f9fa',\n textAlign: 'center' as const,\n padding: '20px',\n },\n title: {\n fontSize: '24px',\n color: '#333',\n marginBottom: '16px',\n },\n message: {\n fontSize: '16px',\n color: '#555',\n marginBottom: '20px',\n },\n button: {\n padding: '10px 20px',\n fontSize: '16px',\n color: '#fff',\n backgroundColor: '#007bff',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n },\n};\n\nexport default ChunkErrorBoundary;\n","//add keys for dev and prod environments here:\n//adding just dev keys for now:\nimport Env from \"../Env\";\n\nexport const aws_config = {\n s3: {\n REGION: process.env.REACT_APP_REGION,\n },\n apiGateway: {\n REGION: process.env.REACT_APP_REGION,\n URL: process.env.REACT_APP_API_GATEWAY_URL,\n },\n analyticsGateway: {\n URL: process.env.REACT_APP_API_ANALYTICS_URL,\n },\n plansGateway: {\n URL: process.env.REACT_APP_API_PLAN_MANAGEMENT_URL,\n // URL: process.env.REACT_APP_LOCAL_PLANMGT_URL\n },\n adManagerGateway: {\n URL: process.env.REACT_APP_API_AD_MANAGER_URL,\n },\n assetManagementGateway: {\n URL: process.env.REACT_APP_ASSET_MANAGEMENT_GATEWAY_URL,\n },\n bbworldGetway: {\n URL: process.env.REACT_APP_BUILD_BOX_WORLD_GATEWAY_URL,\n },\n pseudo: {\n URL: process.env.REACT_APP_PSEUDO_URL,\n },\n bb2Gateway: {\n URL: Env.BB2D_BASE_URL,\n },\n bbaiGateway: {\n URL: Env.BBAI_BASE_URL,\n },\n assetMangerGateway: {\n URL: Env.ASSET_MANAGER_BASE_URL,\n },\n cognito: {\n REGION: process.env.REACT_APP_REGION,\n USER_POOL_ID: process.env.REACT_APP_USER_POOL_ID,\n APP_CLIENT_ID: process.env.REACT_APP_COGNITO_APP_CLIENT_ID,\n COOKIE_DOMAIN: process.env.REACT_APP_COGNITO_COOKIE_DOMAIN || \"localhost\",\n },\n oauth: {\n domain: process.env.REACT_APP_COGNITO_DOMAIN_URL,\n scope: [\"email\", \"profile\", \"openid\", \"aws.cognito.signin.user.admin\"],\n redirectSignIn: process.env.REACT_APP_REDIRECT_SIGN_IN_URL,\n redirectSignOut: process.env.REACT_APP_REDIRECT_SIGN_OUT_URL,\n responseType: \"code\",\n },\n};\n","import { AnyAction } from \"redux\";\nimport actions from \"../constants/actions.json\";\n\nconst initialState: bb.state.IAuth = {\n user: null,\n gaClientId: null,\n fromBBClient: false,\n cognitoClientId: null,\n clientSecret: null,\n authTokens: null,\n screenName: null,\n};\n\nconst authReducer = (\n state: bb.state.IAuth = initialState,\n action: AnyAction\n): bb.state.IAuth => {\n switch (action.type) {\n case actions.auth.SET_USER:\n return {\n ...state,\n user: action.user,\n };\n case actions.auth.SET_SCREEN_NAME: \n return {\n ...state,\n screenName: action.screenName\n };\n case actions.auth.SET_GA_CLIENT_ID:\n return {\n ...state,\n gaClientId: action.gaClientId,\n };\n case actions.auth.SET_AUTH_TOKENS:\n return {\n ...state,\n authTokens: action.tokens,\n };\n case actions.auth.SET_COGNITO_CLIENT_INFO:\n return {\n ...state,\n cognitoClientId: action.cognitoClientId,\n clientSecret: action.clientSecret,\n };\n case actions.auth.CLEAR_USER:\n return initialState;\n case actions.auth.SET_ACCOUNTLESS_PURCHASE_EMAIL: \n return {\n ...state,\n accountlessPurchaseEmail: action.email\n }\n default:\n return state;\n }\n};\n\nexport default authReducer;\n","import { AnyAction } from \"redux\";\nimport actions from \"../constants/actions.json\";\n\n\nconst initialState: bb.state.IAccount = {\n subscriptions: [],\n invoices: [],\n planInfo: [],\n upcomingInvoice: null,\n bundleSubscription: false,\n eligibleRenewal: {\n bb2: false,\n bb3: false,\n bb4: false,\n bbbundle: false,\n soundbox: false,\n },\n planProviders: {\n bb2: null,\n bb3: null,\n bb4: null,\n bbbundle: null,\n soundbox: null,\n },\n plans: {\n bb2: null,\n bb3: null,\n bb4: null,\n bbbundle: null,\n soundbox: null,\n },\n};\n\nconst accountReducer = (\n state: bb.state.IAccount = initialState,\n action: AnyAction\n): bb.state.IAccount => {\n switch (action.type) {\n case actions.account.SET_CURRENT_PLANS:\n return {\n ...state,\n subscriptions: [...action.plans],\n };\n case actions.account.SET_INVOICES:\n return {\n ...state,\n invoices: [...action.invoices],\n };\n case actions.account.SET_UPCOMING_INVOICE:\n return {\n ...state,\n upcomingInvoice: action.upcomingInvoice\n };\n case actions.account.SET_BUNDLE_SUBSCRIPTION:\n return {\n ...state,\n bundleSubscription: action.bundleSubscription\n };\n case actions.account.SET_ELIGIBLE_RENEWAL:\n return {\n ...state,\n eligibleRenewal: action.eligibleRenewal\n }\n case actions.account.CLEAR_ACCOUNT:\n return initialState;\n case actions.account.SET_PLAN_PROVIDERS:\n return {\n ...state,\n planProviders: action.planProviders\n }\n case actions.account.SET_USER_PLANS:\n return {\n ...state,\n plans: action.plans\n }\n default:\n return state;\n }\n};\n\nexport default accountReducer;\n","import { WorkState } from \"../reducers/models\";\nimport { AnyAction } from \"redux\";\nimport actions from \"../constants/actions.json\";\nimport PLANS_JSON from \"../constants/planMetadata\";\n\nconst initialState: bb.state.ISale = {\n houseAdCampaign: {\n website_homepage: null,\n website_pricing: null,\n website_stripe: null\n },\n saleData: {},\n saleContext: {\n showSaleUI: false,\n showSalesLoader: false,\n discountedCost: PLANS_JSON, //discounted copy of plans json\n totalCost: null,\n saleJustEnded: false,\n },\n workState: {\n saleState: WorkState.None,\n },\n};\n\nconst saleReducer = (\n state: bb.state.ISale = initialState,\n action: AnyAction\n): bb.state.ISale => {\n switch (action.type) {\n case actions.sale.SET_SALE_STATE:\n return {\n ...state,\n workState: {\n ...state.workState,\n saleState: action.saleState,\n },\n };\n case actions.sale.SET_SALE_DATA:\n return {\n ...state,\n saleData: Object.assign({}, { ...action.saleData }),\n };\n case actions.sale.SET_SALE_UI:\n return {\n ...state,\n saleContext: {\n ...state.saleContext,\n showSaleUI: action.showSaleUI,\n },\n };\n case actions.sale.SET_SALE_LOADER:\n return {\n ...state,\n saleContext: {\n ...state.saleContext,\n showSalesLoader: action.showSalesLoader,\n },\n };\n case actions.sale.SET_DISCOUNTED_COST:\n return {\n ...state,\n saleContext: {\n ...state.saleContext,\n discountedCost: action.discountedCost,\n },\n };\n case actions.sale.SET_TOTAL_COST:\n return {\n ...state,\n saleContext: {\n ...state.saleContext,\n totalCost: action.totalCost,\n },\n };\n case actions.sale.RESET_SALE_STATE:\n return {\n ...state,\n saleData: {},\n saleContext: {\n ...state.saleContext,\n showSaleUI: false,\n showSalesLoader: false,\n },\n };\n case actions.sale.SET_SALE_JUST_ENDED:\n return {\n ...state,\n saleContext: {\n ...state.saleContext,\n saleJustEnded: action.saleJustEnded,\n },\n };\n case actions.sale.CLEAR_SALE_DATA:\n return initialState;\n case actions.sale.SET_HOUSE_AD_CAMPAIGN_HOMEPAGE:\n const houseAdCampaignForHomepage = action.houseAdCampaign !== null? {...action.houseAdCampaign} : null\n return {\n ...state,\n houseAdCampaign: {\n ...state.houseAdCampaign,\n website_homepage: houseAdCampaignForHomepage\n }\n }\n case actions.sale.SET_HOUSE_AD_CAMPAIGN_PRICING:\n const houseAdCampaignForPricing = action.houseAdCampaign !== null? {...action.houseAdCampaign} : null\n return {\n ...state,\n houseAdCampaign: {\n ...state.houseAdCampaign,\n website_pricing: houseAdCampaignForPricing\n }\n }\n case actions.sale.SET_HOUSE_AD_CAMPAIGN_STRIPE:\n const houseAdCampaignForStripe = action.houseAdCampaign !== null? {...action.houseAdCampaign} : null\n return {\n ...state,\n houseAdCampaign: {\n ...state.houseAdCampaign,\n website_stripe: houseAdCampaignForStripe\n }\n }\n default:\n return state;\n }\n};\n\nexport default saleReducer;\n","import { AnyAction } from \"redux\";\nimport actions from \"../constants/actions.json\";\n\nconst initialState: bb.state.IError = {\n error: null,\n};\n\nconst errorReducer = (\n state: bb.state.IError = initialState,\n action: AnyAction\n) => {\n switch (action.type) {\n case actions.error.SHOW_ERROR:\n return {\n error: action.error,\n };\n case actions.error.HIDE_ERROR:\n return {\n error: null,\n };\n default:\n return state;\n }\n};\n\nexport default errorReducer;\n","import { AnyAction } from \"redux\";\nimport actions from \"../constants/actions.json\";\n\nconst initialState: bb.state.ICart = {\n quantity: 0,\n items: [],\n};\nconst cartReducer = (\n state: bb.state.ICart = initialState,\n action: AnyAction\n): bb.state.ICart => {\n switch (action.type) {\n case actions.cart.ADD_TO_CART:\n return {\n quantity: action.items.length,\n items: action.items,\n };\n case actions.cart.REMOVE_FROM_CART:\n const filteredCart = state.items.filter(\n (item) => item.cartId !== action.cartId\n );\n return {\n ...state,\n items: filteredCart,\n quantity: filteredCart.length,\n };\n case actions.cart.UPDATE_SEAT_QUANTITY:\n let plan = state.items.find((item) => item.cartId === action.cartId);\n let updatedCart = state.items.filter(\n (item) => item.cartId !== action.cartId\n );\n\n if (plan) {\n let seats = action.quantity;\n if (seats < 1 || seats === \"\") {\n seats = 1;\n }\n plan.seatQuantity = seats;\n updatedCart.push(plan);\n }\n\n return {\n ...state,\n items: updatedCart,\n };\n case actions.cart.CLEAR_CART:\n return initialState;\n default:\n return state;\n }\n};\n\nexport default cartReducer;\n","import { LoginClientType, LoginState, WorkState, ProductType } from \"./models\";\nimport { AnyAction } from \"redux\";\nimport actions from \"../constants/actions.json\";\n\nconst initialState: bb.state.ICurrent = {\n fromSSORedirect: false,\n workState: {\n client: LoginClientType.Web,\n loginState: LoginState.None,\n analytics: WorkState.None,\n signup: WorkState.None,\n purchase: WorkState.None,\n planFetch: WorkState.None,\n billingInfoFetch: WorkState.None,\n invoicesFetch: WorkState.None,\n transactionsFetch: WorkState.None,\n projectsFetch: WorkState.None,\n adSettings: WorkState.None,\n },\n userState: {\n productType: ProductType.BB4,\n },\n};\n\nconst currentReducer = (\n state: bb.state.ICurrent = initialState,\n action: AnyAction\n): bb.state.ICurrent => {\n switch (action.type) {\n case actions.current.SET_LOGIN_STATE:\n return {\n ...state,\n workState: {\n ...state.workState,\n loginState: action.loginState,\n },\n };\n case actions.current.SET_SIGNUP_STATE:\n return {\n ...state,\n workState: {\n ...state.workState,\n signup: action.workState,\n },\n };\n case actions.current.SET_ANALYTICS_WORKSTATE:\n return {\n ...state,\n workState: {\n ...state.workState,\n analytics: action.workState,\n },\n };\n case actions.current.SET_PURCHASE_STATE:\n return {\n ...state,\n workState: {\n ...state.workState,\n purchase: action.workState,\n },\n };\n case actions.current.SET_PLAN_FETCH_STATE:\n return {\n ...state,\n workState: {\n ...state.workState,\n planFetch: action.workState,\n },\n };\n case actions.current.SET_BILLING_INFO_FETCH_STATE:\n return {\n ...state,\n workState: {\n ...state.workState,\n billingInfoFetch: action.workState,\n },\n };\n case actions.current.SET_INVOICES_FETCH_STATE:\n return {\n ...state,\n workState: {\n ...state.workState,\n invoicesFetch: action.workState,\n },\n };\n case actions.current.SET_TRANSACTIONS_FETCH_WORKSTATE:\n return {\n ...state,\n workState: {\n ...state.workState,\n transactionsFetch: action.workState,\n },\n };\n case actions.current.SET_PROJECTS_FETCH_WORKSTATE:\n return {\n ...state,\n workState: {\n ...state.workState,\n projectsFetch: action.workState,\n },\n };\n case actions.current.SET_AD_SETTINGS_WORKSTATE:\n return {\n ...state,\n workState: {\n ...state.workState,\n adSettings: action.adSettingsWorkState,\n },\n };\n case actions.current.SET_LOGIN_TYPE:\n return {\n ...state,\n workState: {\n ...state.workState,\n client: action.client,\n },\n };\n case actions.current.SET_FROM_SSO_REDIRECT:\n return {\n ...state,\n fromSSORedirect: action.fromSSORedirect,\n };\n case actions.current.SET_PRODUCT_TYPE:\n const productType = action.productType.toUpperCase();\n sessionStorage.setItem(\"productType\", productType);\n sessionStorage.setItem(\"websocket-product\", productType);\n\n return {\n ...state,\n userState: {\n ...state.userState,\n productType: productType,\n },\n };\n case actions.current.RESET_CURRENT_STATE:\n return initialState;\n default:\n return state;\n }\n};\n\nexport default currentReducer;\n","import { AnyAction } from \"redux\";\nimport { HWAccountStatus, HWVerificationStatus, WorkState } from \"../reducers/models\";\nimport actions from \"../constants/actions.json\";\nimport { filterReducerAdboxReportItem } from \"../utils/reducerHelperUtils\";\n\nconst initialState: bb.state.IMonetization = {\n workState: {\n status: HWAccountStatus.UNREGISTERED,\n verificationStatus: HWVerificationStatus.REQUIRED,\n },\n accountInfo: {\n firstName: \"\",\n lastName: \"\",\n dateOfBirth: \"\",\n country: \"\",\n email: \"\",\n },\n paymentHistory: {\n transactions: [],\n },\n projects: {\n games: [],\n },\n adboxReport: {\n workState: WorkState.None,\n networkReports: undefined \n },\n monthToDateEarnings: {\n workState: WorkState.None,\n earnings: NaN,\n },\n filters: {\n networks: {\n appLovin: true,\n vungle: true\n },\n word: \"\",\n os: { ios: true, \n android: true},\n networkReports: [] \n },\n adboxDailyMetrics: {\n workState: WorkState.None,\n dailyMetrics: undefined,\n },\n};\nconst monetizationReducer = (\n state: bb.state.IMonetization = initialState,\n action: AnyAction\n): bb.state.IMonetization => {\n switch (action.type) {\n case actions.monetization.SET_HW_ACCOUNT_STATE:\n return {\n ...state,\n workState: action.accountState,\n };\n case actions.monetization.SET_HW_ACCOUNT_INFO:\n return {\n ...state,\n accountInfo: action.accountInfo,\n };\n case actions.monetization.SET_PAYMENT_TRANSACTIONS:\n return {\n ...state,\n paymentHistory: {\n ...state.paymentHistory,\n transactions: [...action.transactions],\n },\n };\n case actions.monetization.SET_PROJECTS:\n return {\n ...state,\n projects: {\n ...state.projects,\n games: [...action.projects],\n },\n };\n case actions.monetization.SET_MONTH_TO_DATE_EARNINGS:\n return{\n ...state,\n monthToDateEarnings: action.monthToDateEarnings\n }\n case actions.account.CLEAR_ACCOUNT:\n return initialState;\n case actions.monetization.SET_ADBOX_REPORT:\n return {\n ...state,\n adboxReport: action.adboxReport,\n filters: {\n ...state.filters,\n networkReports: filterReducerAdboxReportItem(action.adboxReport.networkReports, state.filters.os, state.filters.networks, state.filters.word),\n }\n }\n case actions.monetization.SET_NETWORK_FILTER:\n return {\n ...state,\n filters:{\n ...state.filters,\n networks: action.filters,\n networkReports: filterReducerAdboxReportItem(state.adboxReport.networkReports, state.filters.os, action.filters, state.filters.word),\n }\n }\n case actions.monetization.SET_BUNDLE_FILTER_WORD:\n return {\n ...state,\n filters: {\n ...state.filters,\n word: action.bundleFilterWord,\n networkReports: filterReducerAdboxReportItem(state.adboxReport.networkReports, state.filters.os, state.filters.networks, action.bundleFilterWord),\n } \n }\n case actions.monetization.SET_PLATFORM_OS_FILTER:\n return {\n ...state,\n filters:{\n ...state.filters,\n os: action.filters,\n networkReports: filterReducerAdboxReportItem(state.adboxReport.networkReports, action.filters, state.filters.networks, state.filters.word),\n }\n }\n case actions.monetization.SET_FILTERED_TABLE:{ \n return {\n ...state,\n filters:{\n ...state.filters,\n networkReports: filterReducerAdboxReportItem(state.adboxReport.networkReports, state.filters.os, state.filters.networks, state.filters.word),\n }\n }\n }\n case actions.monetization.SET_DAILY_METRICS:\n return {\n ...state,\n adboxDailyMetrics: action.adboxDailyMetrics,\n }\n default:\n return state;\n }\n};\n\nexport default monetizationReducer;\n","import { connectRouter } from \"connected-react-router\";\nimport { combineReducers } from \"redux\";\n\nimport auth from \"./authReducer\";\nimport account from \"./accountReducer\";\nimport sale from \"./saleReducer\";\nimport error from \"./errorReducer\";\nimport cart from \"./cartReducer\";\nimport current from \"./currentReducer\";\nimport monetization from \"./monetizationReducer\";\nimport storyGame from \"./storyGameReducer\";\nimport { persistReducer } from \"redux-persist\";\nimport sessionStorage from 'redux-persist/lib/storage/session'\n\nconst sessionStorageStoryGamePersistConfig = {\n key: 'storygame',\n storage: sessionStorage,\n}\n\nexport default function createRootReducer(history: History) {\n return combineReducers({\n auth: auth,\n account: account,\n cart: cart,\n sale: sale,\n error: error,\n current: current,\n monetization: monetization,\n router: connectRouter(history),\n storyGame: persistReducer(sessionStorageStoryGamePersistConfig, storyGame),\n // storyGame: storyGame,\n });\n}\n","import { createBrowserHistory, History } from \"history\";\nimport { applyMiddleware, compose, createStore } from \"redux\";\nimport { routerMiddleware } from \"connected-react-router\";\nimport createRootReducer from \"./reducers/\";\nimport thunk from \"redux-thunk\";\nimport storage from \"redux-persist/lib/storage\";\nimport storageSession from \"redux-persist/lib/storage/session\";\nimport { getBrowser } from \"./utils/browserUtils\";\nimport { persistStore, persistReducer } from \"redux-persist\";\n\nexport const history: History = createBrowserHistory();\n\nconst currentBrowser = getBrowser();\n\nlet persistConfig = {\n key: \"root\",\n storage,\n whitelist: [\"auth\", \"account\", \"cart\", \"current\", \"error\"],\n blacklist: [\"sale\", \"router\"],\n};\n\nif (currentBrowser === \"Safari\") {\n persistConfig = {\n key: \"root\",\n storage: storageSession,\n whitelist: [\"auth\", \"account\", \"cart\", \"current\", \"error\"],\n blacklist: [\"sale\", \"router\", ],\n };\n}\n\nexport default function configureStore(initialState?: bb.state.IRedux) {\n const middlewares = [routerMiddleware(history), thunk];\n\n const enhancers = [applyMiddleware(...middlewares)];\n\n let composeEnhancer = compose;\n\n if (process.env.REACT_APP_STAGE === \"dev\") {\n composeEnhancer =\n (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;\n }\n\n const reducers = createRootReducer(history);\n\n // Middleware: Redux Persist Persisted Reducer\n const persistedReducer = persistReducer(persistConfig, reducers);\n\n const store = createStore(\n persistedReducer,\n initialState,\n composeEnhancer(...enhancers) as any \n );\n\n // Middleware: Redux Persist Persisted Store\n const persistor = persistStore(store);\n\n // Hot reloading\n if (module.hot) {\n // Enable Webpack hot module replacement for reducers\n module.hot.accept(\"./reducers\", () => {\n store.replaceReducer(require(\"./reducers\").default);\n });\n }\n\n return { store, persistor };\n}\n","import \"react-app-polyfill/ie11\";\nimport \"react-app-polyfill/stable\";\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport \"./styles/index.scss\";\nimport App from \"./App\";\nimport { Provider } from \"react-redux\";\nimport * as serviceWorker from \"./serviceWorker\";\nimport { ConnectedRouter } from \"connected-react-router\";\nimport Amplify from \"@aws-amplify/core\";\nimport ChunkErrorBoundary from \"./containers/ChunkErrorBoundary\";\n\nimport { aws_config } from \"./constants/amplify_config\";\n// import TagManager from \"react-gtm-module\";\n\nimport { Elements } from \"@stripe/react-stripe-js\";\nimport { loadStripe } from \"@stripe/stripe-js\";\nimport { PersistGate } from \"redux-persist/integration/react\";\n\nimport configureStore, { history } from \"./configureStore\";\n\nconst stripePromise = loadStripe(process.env.REACT_APP_STRIPE_KEY);\n\n// const tagManagerArgs = {\n// gtmId: \"GTM-K8KCBNX\", // Google Tag Manager ID gets injected into react pages\n// };\n\n// TagManager.initialize(tagManagerArgs);\n\nAmplify.configure({\n Auth: {\n mandatorySignIn: false,\n region: aws_config.cognito.REGION,\n userPoolId: aws_config.cognito.USER_POOL_ID,\n userPoolWebClientId: aws_config.cognito.APP_CLIENT_ID,\n },\n Storage: {\n region: aws_config.s3.REGION,\n bucket: aws_config.s3.BUCKET,\n },\n API: {\n endpoints: [\n {\n name: \"userAccountManagementURL\",\n endpoint: aws_config.apiGateway.URL,\n region: aws_config.apiGateway.REGION,\n },\n {\n name: \"plansURL\",\n endpoint: aws_config.plansGateway.URL,\n },\n {\n name: \"adsURL\",\n endpoint: aws_config.adManagerGateway.URL,\n },\n {\n name: \"assetsURL\",\n endpoint: aws_config.assetManagementGateway.URL,\n },\n {\n name: \"bbworldUrl\",\n endpoint: aws_config.bbworldGetway.URL,\n region: aws_config.apiGateway.REGION,\n },\n {\n name: \"pseudoURL\",\n endpoint: aws_config.pseudo.URL,\n },\n {\n name: \"bb2URL\",\n endpoint: aws_config.bb2Gateway.URL,\n },\n {\n name: \"bbaiURL\",\n endpoint: aws_config.bbaiGateway.URL,\n },\n {\n name: \"assetManagerURL\",\n endpoint: aws_config.assetMangerGateway.URL,\n }\n ],\n },\n oauth: {\n domain: aws_config.oauth.domain,\n scope: aws_config.oauth.scope,\n redirectSignIn: aws_config.oauth.redirectSignIn,\n redirectSignOut: aws_config.oauth.redirectSignOut,\n responseType: aws_config.oauth.responseType,\n },\n});\n\nconst { store, persistor } = configureStore();\n\nReactDOM.render(\n \n \n \n \n \n \n \n \n \n \n ,\n document.getElementById(\"root\")\n);\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n","// extracted by mini-css-extract-plugin\nmodule.exports = {\"linkRegular\":\"Footer_linkRegular__2e5ki\",\"footer\":\"Footer_footer__2SqrG\",\"clientDefaultText\":\"Footer_clientDefaultText__KOuoe\",\"wrapper\":\"Footer_wrapper__3idgI\",\"linksContainer\":\"Footer_linksContainer__YwJnh\",\"linksWrapper\":\"Footer_linksWrapper__siqd9\",\"socialText\":\"Footer_socialText__2QZs2\",\"linkItems\":\"Footer_linkItems__19I1z\",\"privacyTerms\":\"Footer_privacyTerms__T3hG8\",\"linkTitle\":\"Footer_linkTitle__3LtkK\",\"ot-sdk-btn\":\"Footer_ot-sdk-btn__2JQV5\",\"blogLinks\":\"Footer_blogLinks__1tQtv\",\"interestsList\":\"Footer_interestsList__KTqNx\",\"termsContainer\":\"Footer_termsContainer__2ejWa\",\"formInputs\":\"Footer_formInputs__RQPt0\",\"socialIcons\":\"Footer_socialIcons__1xJqE\",\"socialLinkVertical\":\"Footer_socialLinkVertical__34BTn\",\"textSection\":\"Footer_textSection__3dRUU\",\"linkItemsSocial\":\"Footer_linkItemsSocial__2T95o\"};","export default (state: { auth: { user: bb.model.IUser } }) => {\n return state.auth.user;\n};\n"],"sourceRoot":""}