{"version":3,"sources":["polyfill.js","models/PageInfo.ts","models/AppInfo.ts","models/Booster.ts","config.ts","utilities/analytics.ts","utilities/dateUtility.ts","utilities/pageUtility.ts","utilities/storageUtility.ts","models/Feedback.ts","models/GameVariant.ts","models/MapVariant.ts","models/Match.ts","models/MedalProgress.ts","models/PlayerSearch.ts","models/Rank.ts","models/ServiceRecord.ts","models/Spartan.ts","pages.ts","components/About/About.tsx","services/FeedbackService.ts","services/ImageService.ts","services/MatchService.ts","services/RankService.ts","services/SearchHistoryService.ts","services/SpartanService.ts","services/ToastService.ts","components/Feedback/FeedbackCheckbox/FeedbackCheckbox.tsx","components/Feedback/Feedback.tsx","components/Layout/FeedbackModal/FeedbackModal.tsx","components/Layout/Navigation/Navigation.tsx","components/Layout/ToastContainer/Toast/Toast.tsx","components/Layout/ToastContainer/ToastContainer.tsx","components/Layout/Tracking/Tracking.tsx","components/Layout/Layout.tsx","components/Legal/Legal.tsx","components/Loading/Loading.tsx","components/Ranks/Rank/Rank.tsx","components/Ranks/Ranks.tsx","components/Spartan/Player/LatestMatch/LatestMatch.tsx","components/Spartan/Player/PlayerName/PlayerName.tsx","components/Spartan/Player/Medals/Medal.tsx","components/Spartan/Player/Medals/MedalModal.tsx","components/Spartan/Player/Medals/Medals.tsx","components/Spartan/Player/PlayerStats/PlayerStat/PlayerStat.tsx","components/Spartan/Player/PlayerStats/StatDetailsModal/StatDetailsModal.tsx","components/Spartan/Player/PlayerStats/PlayerStats.tsx","components/Spartan/Player/ProgressBar/ProgressBar.tsx","components/Spartan/Player/Share/Share.tsx","components/Spartan/Player/SpartanImage/SpartanImage.tsx","components/Spartan/Player/Player.tsx","components/Spartan/PlayerNotFound/PlayerNotFound.tsx","components/Spartan/Spartan.tsx","components/TermsAndConditions/TermsAndConditions.tsx","components/Welcome/Welcome.tsx","components/App.tsx","reportWebVitals.js","index.tsx"],"names":["lastTime","vendors","x","length","window","requestAnimationFrame","cancelAnimationFrame","callback","element","currTime","Date","getTime","timeToCall","Math","max","id","setTimeout","clearTimeout","PageInfo","data","name","url","path","title","description","this","AppInfo","pageInfo","map","pi","Booster","rarity","image","config","amplitudeClientId","apiRootUrl","cacheTime","defaultPageTitle","isDevEnvironment","process","googleAnalyticsId","amp","amplitude","getInstance","init","analytics","trackPageView","pageTitle","pageURL","page_title","document","page_url","location","toString","trackEvent","event","gtag","logEvent","getDateParts","date","time","dateUtility","parseDate","d","formatDate","parts","days","hours","minutes","seconds","formatted","floor","formatDateReallyShort","hoursDecimal","toFixed","minutesDecimal","trim","formatDateShort","formatDateLong","pageUtility","titlePage","storageUtility","getFromLocalStorage","key","json","localStorage","getItem","JSON","parse","saveToLocalStorage","value","stringify","setItem","Feedback","userName","likesProgressionBar","likesProgressionBarComment","likesLastMatch","likesLastMatchComment","likesStatProjection","likesStatProjectionComment","likesRecentlySearched","likesRecentlySearchedComment","likesRankPage","likesRankPageComment","likesAdditionalComment","needsImprovementProgressionBar","needsImprovementProgressionBarComment","needsImprovementLastMatch","needsImprovementLastMatchComment","needsImprovementStatProjection","needsImprovementStatProjectionComment","needsImprovementRecentlySearched","needsImprovementRecentlySearchedComment","needsImprovementRankPage","needsImprovementRankPageComment","needsImprovementAdditionalComment","featureRequestMobileApp","featureRequestPredictionTool","featureRequestXpBreakdownPage","featureRequestComment","usesMobile","usesDesktop","generalComment","gamertag","GameVariant","MapVariant","Match","matchDate","team","rank","won","preGameSpartanRank","postGameSpartanRank","preGameTotalXp","postGameTotalXp","totalXpGained","boosterXp","booster","gameVariant","mapVariant","MedalProgress","currentCount","maxLevelRemainingCount","PlayerSearch","serviceTag","emblemBase64","isLegacy","Rank","rankNumber","startingXp","ServiceRecord","currentTimePlayed","currentGamesPlayed","currentGamesWon","currentGamesLost","currentTotalKills","currentSpartanKills","currentPveKills","currentDeaths","currentShotsFired","currentShotsLanded","currentVehiclesDestroyed","currentGrenadeKills","currentMeleeKills","currentAssassinations","currentShoulderBashKills","currentGroundPoundKills","maxRankTimeRemaining","maxRankGamesRemaining","maxRankGamesWonRemaining","maxRankGamesLostRemaining","maxRankTotalKillsRemaining","maxRankSpartanKillsRemaining","maxRankPveKillsRemaining","maxRankDeathsRemaining","maxRankShotsFiredRemaining","maxRankShotsLandedRemaining","maxRankVehiclesDestroyedRemaining","maxRankGrenadeKillsRemaining","maxRankMeleeKillsRemaining","maxRankAssassinationsRemaining","maxRankShoulderBashKillsRemaining","maxRankGroundPoundKillsRemaining","medalProgress","mp","Spartan","lastModified","companyId","companyName","currentRank","currentXp","maxRank","maxRankXp","maxRankOverallCompletion","allTime","arena","warzone","pages","About","props","className","FeedbackService","save","feedback","fetch","method","headers","body","then","r","ok","baseUrl","ImageService","medalIcon","medalId","spartanEmblem","defaultSpartanImage","spartanImage","MatchService","getLatestMatch","encodeURIComponent","resp","status","match","RankService","getAll","ranks","service","legacyLocalStorageKey","localStorageKey","localStorageLimit","subscriptions","Array","players","legacy","p","add","player","history","filter","toLowerCase","_h","idx","concat","subscribe","push","publish","sub","err","SearchHistoryService","SpartanService","getSpartan","spartan","toast","type","message","hideAfter","ToastService","fieldNum","FeedbackCheckbox","useState","isChecked","setIsChecked","comment","setComment","commentText","isLike","fieldName","checked","onChange","e","val","target","setValue","htmlFor","style","display","label","maxLength","setCommentState","isSubmitting","setIsSubmitting","FeedbackModel","setFeedback","setUserName","likesAdditionalComments","setLikesAdditionalComments","needsImprovementAdditionalComments","setNeedsImprovementAdditionalComments","featureRequest","setFeatureRequest","setGamertag","otherComments","setOtherComments","v","c","rows","onClick","Promise","resolve","items","scrollTo","catch","finally","disabled","FeedbackModal","Modal","show","onHide","dismiss","marginTop","Header","lineHeight","textDecoration","Body","Footer","showFeedback","sanatizeGamertag","replace","toLocaleLowerCase","Navigation","useHistory","urlParams","useParams","subPlayer","setSubPlayer","searchHistory","setSearchHistory","search","gt","preventDefault","search_term","useEffect","href","src","maxHeight","alt","onSubmit","list","autoComplete","placeholder","aria-label","Toast","marginBottom","autohide","delay","onClose","width","height","ToastContainer","subToast","setSubToast","toasts","setToasts","t","indexes","Object","keys","newIdx","parseInt","newToasts","aria-live","aria-atomic","position","top","right","index","closeToast","Tracking","useLocation","pathname","origin","defaultTitle","property","content","rel","usePageLayout","Component","options","Layout","promptForFeedback","setPromptForFeedback","navigate","visitsKey","dismissFeedbackKey","dismissFeedback","visits","toDateString","addVisit","listen","role","noPadding","getFullYear","Legal","Loading","setTime","margin","icon","faHelmetBattle","fill","ele","totalRemainingPercent","newXp","previousRank","newPercentage","previousPercentage","aria-valuenow","aria-valuemin","aria-valuemax","toLocaleString","Ranks","isLoading","setIsLoading","setRanks","reversedRanks","setReversedRanks","sortOrder","setSortOrder","previous","current","getRankInfo","reverse","error","faArrowCircleDown","size","faArrowCircleUp","LatestMatch","game","backgroundImage","backgroundColor","PlayerName","Medal","medal","MedalModal","showModal","closeModal","Button","variant","Medals","details","setDetails","medals","m","PlayerStat","currentLabel","statName","currentValue","remainingLabel","remainingValue","totalLabel","totalValue","showDetails","faInfoCircle","isLargeStat","StatDetailsModal","shortValueFormatter","longValueFormatter","getStatInfoFromServiceRecord","serviceRecord","isArena","stats","faClock","faGamepadAlt","faTrophyAlt","faChartLineDown","faCrosshairs","arenaExclude","arenaInclude","faUserAlien","faTombstoneAlt","faAlignLeft","faTasks","faAlignSlash","faCarCrash","faBomb","faHandRock","faKnifeKitchen","faBahai","faComet","filteredStats","s","PlayerStats","statType","setStatType","selectStatType","all","aria-current","stat","viewDetails","ProgressBar","maxXp","percentage","min","useMemo","nextRank","indexOf","currentLevel","nextLevel","maxLevel","percentageValue","aria-hidden","Share","text","windowSize","trackButtonClick","platform","open","faFacebook","faTwitter","faReddit","faEnvelope","SpartanImage","Player","completionPercentage","latestMatch","getElementsByClassName","scrollIntoView","PlayerNotFound","faUserLock","App","component","setSpartan","setLatestMatch","Privacy","Welcome","faMedal","faBullseye","appInfo","defaultPage","TermsAndConditions","reportWebVitals","onPerfEntry","Function","getCLS","getFID","getFCP","getLCP","getTTFB","render","getElementById"],"mappings":"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","file":"static/js/main.11af1cd5.chunk.js","sourcesContent":["// window.requestAnimationFrame\r\n(function() {\r\n var lastTime = 0;\r\n var vendors = ['ms', 'moz', 'webkit', 'o'];\r\n for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {\r\n window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];\r\n window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] \r\n || window[vendors[x]+'CancelRequestAnimationFrame'];\r\n }\r\n \r\n if (!window.requestAnimationFrame)\r\n window.requestAnimationFrame = function(callback, element) {\r\n var currTime = new Date().getTime();\r\n var timeToCall = Math.max(0, 16 - (currTime - lastTime));\r\n var id = window.setTimeout(function() { callback(currTime + timeToCall); }, \r\n timeToCall);\r\n lastTime = currTime + timeToCall;\r\n return id;\r\n };\r\n \r\n if (!window.cancelAnimationFrame)\r\n window.cancelAnimationFrame = function(id) {\r\n clearTimeout(id);\r\n };\r\n}());\r\n","/** Information about a page within the site. */\r\nexport class PageInfo {\r\n name: string;\r\n url: string;\r\n path: string;\r\n title: string;\r\n description: string;\r\n\r\n constructor();\r\n constructor(pageInfo: Partial);\r\n constructor(data?: Partial) {\r\n data = data || {};\r\n\r\n this.name = data.name || null;\r\n this.url = data.url || null;\r\n this.path = data.path || null;\r\n this.title = data.title || null;\r\n this.description = data.description || null;\r\n }\r\n}\r\n\r\nexport default PageInfo;\r\n","import PageInfo from \"./PageInfo\";\r\n\r\n/** Information required to initialize the application. */\r\nexport class AppInfo {\r\n pageInfo: PageInfo[];\r\n\r\n constructor();\r\n constructor(appInfo: Partial);\r\n constructor(data?: Partial) {\r\n data = data || {};\r\n\r\n this.pageInfo = (data.pageInfo || []).map(pi => new PageInfo(pi));\r\n }\r\n}\r\n\r\nexport default AppInfo;\r\n","export class Booster {\r\n name: string;\r\n description: string | null;\r\n rarity: string;\r\n image: string;\r\n\r\n constructor()\r\n constructor(booster: Partial)\r\n constructor(data?: Partial) {\r\n data = data || {};\r\n\r\n this.name = data.name || null;\r\n this.description = data.description || null;\r\n this.rarity = data.rarity || null;\r\n this.image = data.image || null;\r\n }\r\n}\r\n\r\nexport default Booster;\r\n","const isDevEnvironment: boolean = process.env.NODE_ENV !== \"production\";\r\n\r\n/** Constant configuration values. */\r\nexport const config = {\r\n\r\n /** The site's Amplitude client identifier. */\r\n amplitudeClientId: \"c8d311a9a65da4664205700f1884fc6b\",\r\n\r\n /** The root URL of the API. */\r\n apiRootUrl: isDevEnvironment ? \"https://localhost:44346\" : \"\",\r\n\r\n /** The default cache time for player data. */\r\n cacheTime: new Date(5 * 60 * 1000),\r\n\r\n /** The default page title. */\r\n defaultPageTitle: \"SR152 - Halo 5: Guardians Progress Tracker\",\r\n\r\n /** A flag indicating whether the build is running in a development environment. */\r\n isDevEnvironment: isDevEnvironment,\r\n\r\n /** The site's Google Analytics identifier. */\r\n googleAnalyticsId: \"G-LCC6810SJG\",\r\n}\r\n\r\nexport default config;\r\n","import amplitude, { AmplitudeClient } from \"amplitude-js\";\r\nimport config from \"../config\";\r\n\r\nconst amp: AmplitudeClient = amplitude.getInstance();\r\namp.init(config.amplitudeClientId);\r\n\r\nexport type AnalyticEvent = \"page_view\" | \"search\" | \"view_item\" | \"view_item_list\" | \"select_item\" | \"share-clicked\";\r\nexport type AnalyticData = { };\r\n\r\n/** A utility for working with analytical data. */\r\nexport const analytics = {\r\n\r\n /** Tracks a page view. */\r\n trackPageView: (pageTitle?: string, pageURL?: string): void => {\r\n const data = {\r\n page_title: pageTitle || document.title || config.defaultPageTitle,\r\n page_url: pageURL || document.location.toString(),\r\n };\r\n\r\n analytics.trackEvent(\"page_view\", data);\r\n },\r\n\r\n /** Tracks an event. */\r\n trackEvent: (event: AnalyticEvent, data: AnalyticData): void => {\r\n if (event && data && !config.isDevEnvironment) {\r\n if (event === \"page_view\") {\r\n gtag(\"config\", config.googleAnalyticsId, data);\r\n } else {\r\n gtag(\"event\", event, data);\r\n }\r\n\r\n amp.logEvent(event, data);\r\n }\r\n },\r\n};\r\n\r\nexport default analytics;\r\n","const getDateParts = (date: Date): [days: number, hours: number, minutes: number, seconds: number] => {\r\n if (typeof date === \"undefined\" || date === null) return null;\r\n\r\n const time = date.getTime();\r\n const days = time / (24 * 60 * 60 * 1000);\r\n const hours = time / (60 * 60 * 1000) % 24;\r\n const minutes = time / (60 * 1000) % 60;\r\n const seconds = time / 1000 % 60;\r\n const parts: [days: number, hours: number, minutes: number, seconds: number] = [ days, hours, minutes, seconds, ];\r\n\r\n return parts;\r\n}\r\n\r\n/** A utility which contains methods for working with dates. */\r\nexport const dateUtility = {\r\n\r\n /** Parses an existing string or date object returning a Date instance (or null if no data was input). */\r\n parseDate: (d: string | Date): Date => d ? (d instanceof Date ? d : new Date(d)) : null,\r\n\r\n /** Returns a date formatted as 00.00:00:00 where days are omitted if the value is less than a day. */\r\n formatDate: (date: Date): string => {\r\n const parts = getDateParts(date);\r\n const [days, hours, minutes, seconds] = parts;\r\n\r\n if (!parts) {\r\n return null;\r\n } else {\r\n let formatted: string = \"\";\r\n\r\n if (days >= 1) {\r\n formatted += `${Math.floor(days)}.`;\r\n }\r\n formatted += `${hours < 10 ? \"0\" : \"\"}${Math.floor(hours)}:`;\r\n formatted += `${minutes < 10 ? \"0\" : \"\"}${Math.floor(minutes)}:`;\r\n formatted += `${seconds < 10 ? \"0\" : \"\"}${Math.floor(seconds)}`;\r\n\r\n return formatted;\r\n }\r\n },\r\n\r\n /** Returns a date formatted as 0.0 Days or 0.0 Hours based on the size of the value. */\r\n formatDateReallyShort: (date: Date): string => {\r\n const parts = getDateParts(date);\r\n const [days, hours, minutes, seconds] = parts;\r\n\r\n if (!parts) {\r\n return null;\r\n } else {\r\n let formatted: string = \"\";\r\n\r\n if (days >= 1) {\r\n const hoursDecimal = hours / 24;\r\n formatted += `${(Math.floor(days) + hoursDecimal).toFixed(2)} Days`;\r\n } else {\r\n const minutesDecimal = minutes / 60;\r\n formatted += `${(Math.floor(days) + minutesDecimal).toFixed(2)} Hours`;\r\n }\r\n\r\n return formatted.trim();\r\n }\r\n },\r\n\r\n /** Returns a date formatted as 0 Days 0 Hours or 0 Hours 0 Minutes based on the size of the value. */\r\n formatDateShort: (date: Date): string => {\r\n const parts = getDateParts(date);\r\n const [days, hours, minutes, seconds] = parts;\r\n\r\n if (!parts) {\r\n return null;\r\n } else {\r\n let formatted: string = \"\";\r\n\r\n if (days >= 1) {\r\n formatted += `${Math.floor(days)} Days `;\r\n }\r\n formatted += `${Math.floor(hours)} Hours `;\r\n if (days < 1) {\r\n formatted += `${Math.floor(minutes)} Minutes`;\r\n }\r\n\r\n return formatted.trim();\r\n }\r\n },\r\n\r\n /** Returns a date formatted as 0 Days, 0 Hours, 0 Minutes, 0 Seconds where values are omitted if the date is not great enough to fulfill it. */\r\n formatDateLong: (date: Date): string => {\r\n const parts = getDateParts(date);\r\n const [days, hours, minutes, seconds] = parts;\r\n\r\n if (!parts) {\r\n return null;\r\n } else {\r\n let formatted: string = \"\";\r\n\r\n if (days >= 1) {\r\n formatted += `${Math.floor(days)} Days, `;\r\n }\r\n if (hours >= 1 || formatted) {\r\n formatted += `${Math.floor(hours)} Hours, `;\r\n }\r\n if (minutes >= 1 || formatted) {\r\n formatted += `${Math.floor(minutes)} Minutes, `;\r\n }\r\n formatted += `${Math.floor(seconds)} Seconds`;\r\n\r\n return formatted;\r\n }\r\n },\r\n}\r\n\r\nexport default dateUtility;\r\n","import config from \"../config\";\r\n\r\n/** A utility which exposes methods for working with the browser page and document. */\r\nexport const pageUtility = {\r\n\r\n /** Updates the title of the page. */\r\n titlePage: (title?: string): void => {\r\n if (typeof document !== \"undefined\") {\r\n document.title = title ? `${title} | ${config.defaultPageTitle}` : config.defaultPageTitle;\r\n }\r\n }\r\n}\r\n\r\nexport default pageUtility;\r\n","/** A utility class for working with storages. */\r\nexport const storageUtility = {\r\n\r\n /** Gets an object from local storage, returning null if it's not found. */\r\n getFromLocalStorage: (key: string): T => {\r\n const json = localStorage.getItem(key);\r\n const result = json ? JSON.parse(json) : null;\r\n\r\n return result;\r\n },\r\n\r\n /** Saves an object to local storage. */\r\n saveToLocalStorage: (key: string, value: T): void => {\r\n const json = JSON.stringify(value);\r\n\r\n localStorage.setItem(key, json);\r\n },\r\n};\r\n\r\nexport default storageUtility;\r\n","import { dateUtility } from \"../utilities\";\r\n\r\n/** User feedback regarding the application. */\r\nexport class Feedback {\r\n userName: string;\r\n likesProgressionBar: boolean;\r\n likesProgressionBarComment: string;\r\n likesLastMatch: boolean;\r\n likesLastMatchComment: string;\r\n likesStatProjection: boolean;\r\n likesStatProjectionComment: string;\r\n likesRecentlySearched: boolean;\r\n likesRecentlySearchedComment: string;\r\n likesRankPage: boolean;\r\n likesRankPageComment: string;\r\n likesAdditionalComment: string;\r\n\r\n needsImprovementProgressionBar: boolean;\r\n needsImprovementProgressionBarComment: string;\r\n needsImprovementLastMatch: boolean;\r\n needsImprovementLastMatchComment: string;\r\n needsImprovementStatProjection: boolean;\r\n needsImprovementStatProjectionComment: string;\r\n needsImprovementRecentlySearched: boolean;\r\n needsImprovementRecentlySearchedComment: string;\r\n needsImprovementRankPage: boolean;\r\n needsImprovementRankPageComment: string;\r\n needsImprovementAdditionalComment: string;\r\n\r\n featureRequestMobileApp: boolean;\r\n featureRequestPredictionTool: boolean;\r\n featureRequestXpBreakdownPage: boolean;\r\n featureRequestComment: string;\r\n\r\n usesMobile: boolean;\r\n usesDesktop: boolean;\r\n generalComment: string;\r\n gamertag: string;\r\n date: Date;\r\n\r\n constructor();\r\n constructor(feedback: Partial);\r\n constructor(data?: Partial) {\r\n data = data || {};\r\n\r\n this.userName = this.userName || null;\r\n this.likesProgressionBar = data.likesProgressionBar || null;\r\n this.likesProgressionBarComment = data.likesProgressionBarComment || null;\r\n this.likesLastMatch = data.likesLastMatch || null;\r\n this.likesLastMatchComment = data.likesLastMatchComment || null;\r\n this.likesStatProjection = data.likesStatProjection || null;\r\n this.likesStatProjectionComment = data.likesStatProjectionComment || null;\r\n this.likesRecentlySearched = data.likesRecentlySearched || null;\r\n this.likesRecentlySearchedComment = data.likesRecentlySearchedComment || null;\r\n this.likesRankPage = data.likesRankPage || null;\r\n this.likesRankPageComment = data.likesRankPageComment || null;\r\n this.likesAdditionalComment = data.likesAdditionalComment || null;\r\n this.needsImprovementProgressionBar = data.needsImprovementProgressionBar || null;\r\n this.needsImprovementProgressionBarComment = data.needsImprovementProgressionBarComment || null;\r\n this.needsImprovementLastMatch = data.needsImprovementLastMatch || null;\r\n this.needsImprovementLastMatchComment = data.needsImprovementLastMatchComment || null;\r\n this.needsImprovementStatProjection = data.needsImprovementStatProjection || null;\r\n this.needsImprovementStatProjectionComment = data.needsImprovementStatProjectionComment || null;\r\n this.needsImprovementRecentlySearched = data.needsImprovementRecentlySearched || null;\r\n this.needsImprovementRecentlySearchedComment = data.needsImprovementRecentlySearchedComment || null;\r\n this.needsImprovementRankPage = data.needsImprovementRankPage || null;\r\n this.needsImprovementRankPageComment = data.needsImprovementRankPageComment || null;\r\n this.needsImprovementAdditionalComment = data.needsImprovementAdditionalComment || null;\r\n this.featureRequestMobileApp = data.featureRequestMobileApp || null;\r\n this.featureRequestPredictionTool = data.featureRequestPredictionTool || null;\r\n this.featureRequestXpBreakdownPage = data.featureRequestXpBreakdownPage || null;\r\n this.featureRequestComment = data.featureRequestComment || null;\r\n this.usesMobile = data.usesMobile || null;\r\n this.usesDesktop = data.usesDesktop || null;\r\n this.generalComment = data.generalComment || null;\r\n this.gamertag = data.gamertag || null;\r\n this.date = dateUtility.parseDate(data.date) || null;\r\n }\r\n}\r\n\r\nexport default Feedback;\r\n","export class GameVariant {\r\n name: string;\r\n description: string | null;\r\n image: string;\r\n\r\n constructor()\r\n constructor(gameVariant: Partial)\r\n constructor(data?: Partial) {\r\n data = data || {};\r\n\r\n this.name = data.name || null;\r\n this.description = data.description || null;\r\n this.image = data.image || null;\r\n }\r\n}\r\n\r\nexport default GameVariant;\r\n","export class MapVariant {\r\n name: string;\r\n description: string | null;\r\n image: string;\r\n\r\n constructor()\r\n constructor(mapVariant: Partial)\r\n constructor(data?: Partial) {\r\n data = data || {};\r\n\r\n this.name = data.name || null;\r\n this.description = data.description || null;\r\n this.image = data.image || null;\r\n }\r\n}\r\n\r\nexport default MapVariant;\r\n","import dateUtility from \"../utilities/dateUtility\";\r\nimport Booster from \"./Booster\";\r\nimport GameVariant from \"./GameVariant\";\r\nimport MapVariant from \"./MapVariant\";\r\n\r\nexport class Match {\r\n gamertag: string;\r\n matchDate: Date;\r\n team: string;\r\n rank: number;\r\n won: boolean;\r\n preGameSpartanRank: number;\r\n postGameSpartanRank: number;\r\n preGameTotalXp: number;\r\n postGameTotalXp: number;\r\n totalXpGained: number;\r\n boosterXp: number;\r\n booster: Booster;\r\n gameVariant: GameVariant;\r\n mapVariant: MapVariant;\r\n\r\n constructor()\r\n constructor(match: Partial)\r\n constructor(data?: Partial) {\r\n data = data || {};\r\n\r\n this.gamertag = data.gamertag || null;\r\n this.matchDate = dateUtility.parseDate(data.matchDate) || null;\r\n this.team = data.team || null;\r\n this.rank = data.rank || 0;\r\n this.won = data.won || false;\r\n this.preGameSpartanRank = data.preGameSpartanRank || 0;\r\n this.postGameSpartanRank = data.postGameSpartanRank || 0;\r\n this.preGameTotalXp = data.preGameTotalXp || 0;\r\n this.postGameTotalXp = data.postGameTotalXp || 0;\r\n this.totalXpGained = data.totalXpGained || 0;\r\n this.boosterXp = data.boosterXp || 0;\r\n this.booster = data.booster ? new Booster(data.booster) : null;\r\n this.gameVariant = data.gameVariant ? new GameVariant(data.gameVariant) : null;\r\n this.mapVariant = data.mapVariant ? new MapVariant(data.mapVariant) : null;\r\n }\r\n}\r\n\r\nexport default Match;\r\n","/** Information about medals earned by a player. */\r\nexport class MedalProgress {\r\n id: number;\r\n name: string;\r\n description: string;\r\n currentCount: number;\r\n maxLevelRemainingCount: number;\r\n\r\n constructor();\r\n constructor(medalProgress: Partial);\r\n constructor(data?: Partial) {\r\n data = data || {};\r\n\r\n this.id = data.id || 0;\r\n this.name = data.name || null;\r\n this.description = data.description || null;\r\n this.currentCount = data.currentCount || 0;\r\n this.maxLevelRemainingCount = data.maxLevelRemainingCount || 0;\r\n }\r\n}\r\n\r\nexport default MedalProgress;\r\n","/** Information about a player whom was searched. */\r\nexport class PlayerSearch {\r\n\r\n /** The player's gamertag. */\r\n gamertag: string;\r\n\r\n /** The player's service tag. */\r\n serviceTag: string;\r\n\r\n /** The Base-64 encoded player emblem image. */\r\n emblemBase64 : string;\r\n\r\n /** A flag which indicates whether the record is a legacy record (from a previous non-compatible build) */\r\n isLegacy: boolean;\r\n\r\n constructor()\r\n constructor(playerSearch: Partial)\r\n constructor(data?: Partial) {\r\n data = data || {} as any;\r\n\r\n this.gamertag = data.gamertag || null;\r\n this.serviceTag = data.serviceTag || null;\r\n this.emblemBase64 = data.emblemBase64 || null;\r\n this.isLegacy = data.isLegacy || false;\r\n }\r\n}\r\n\r\nexport default PlayerSearch;\r\n","/** Information regarding a specific Spartan Rank (SR). */\r\nexport class Rank {\r\n rankNumber: number;\r\n startingXp: number;\r\n\r\n constructor()\r\n constructor(rank: Partial)\r\n constructor(data?: Partial) {\r\n data = data || {};\r\n\r\n this.rankNumber = data.rankNumber || 0;\r\n this.startingXp = data.startingXp || 0;\r\n }\r\n}\r\n\r\nexport default Rank;\r\n","import { dateUtility } from \"../utilities\";\r\nimport MedalProgress from \"./MedalProgress\";\r\n\r\n/** Information representing a service record of a Spartan. */\r\nexport class ServiceRecord {\r\n currentTimePlayed: Date;\r\n currentGamesPlayed: number;\r\n currentGamesWon: number;\r\n currentGamesLost: number;\r\n currentTotalKills: number;\r\n currentSpartanKills: number;\r\n currentPveKills: number;\r\n currentDeaths: number;\r\n currentShotsFired: number;\r\n currentShotsLanded: number;\r\n currentVehiclesDestroyed: number;\r\n currentGrenadeKills: number;\r\n currentMeleeKills: number;\r\n currentAssassinations: number;\r\n currentShoulderBashKills: number;\r\n currentGroundPoundKills: number;\r\n maxRankTimeRemaining: Date;\r\n maxRankGamesRemaining: number;\r\n maxRankGamesWonRemaining: number;\r\n maxRankGamesLostRemaining: number;\r\n maxRankTotalKillsRemaining: number;\r\n maxRankSpartanKillsRemaining: number;\r\n maxRankPveKillsRemaining: number;\r\n maxRankDeathsRemaining: number;\r\n maxRankShotsFiredRemaining: number;\r\n maxRankShotsLandedRemaining: number;\r\n maxRankVehiclesDestroyedRemaining: number;\r\n maxRankGrenadeKillsRemaining: number;\r\n maxRankMeleeKillsRemaining: number;\r\n maxRankAssassinationsRemaining: number;\r\n maxRankShoulderBashKillsRemaining: number;\r\n maxRankGroundPoundKillsRemaining: number;\r\n medalProgress: MedalProgress[];\r\n\r\n constructor()\r\n constructor(serviceRecord: Partial)\r\n constructor(data?: Partial) {\r\n data = data || {};\r\n\r\n this.currentTimePlayed = dateUtility.parseDate(data.currentTimePlayed);\r\n this.currentGamesPlayed = data.currentGamesPlayed || 0;\r\n this.currentGamesWon = data.currentGamesWon || 0;\r\n this.currentGamesLost = data.currentGamesLost || 0;\r\n this.currentTotalKills = data.currentTotalKills || 0;\r\n this.currentSpartanKills = data.currentSpartanKills || 0;\r\n this.currentPveKills = data.currentPveKills || 0;\r\n this.currentDeaths = data.currentDeaths || 0;\r\n this.currentShotsFired = data.currentShotsFired || 0;\r\n this.currentShotsLanded = data.currentShotsLanded || 0;\r\n this.currentVehiclesDestroyed = data.currentVehiclesDestroyed || 0;\r\n this.currentGrenadeKills = data.currentGrenadeKills || 0;\r\n this.currentMeleeKills = data.currentMeleeKills || 0;\r\n this.currentAssassinations = data.currentAssassinations || 0;\r\n this.currentShoulderBashKills = data.currentShoulderBashKills || 0;\r\n this.currentGroundPoundKills = data.currentGroundPoundKills || 0;\r\n this.maxRankTimeRemaining = dateUtility.parseDate(data.maxRankTimeRemaining);\r\n this.maxRankGamesRemaining = data.maxRankGamesRemaining || 0;\r\n this.maxRankGamesWonRemaining = data.maxRankGamesWonRemaining || 0;\r\n this.maxRankGamesLostRemaining = data.maxRankGamesLostRemaining || 0;\r\n this.maxRankTotalKillsRemaining = data.maxRankTotalKillsRemaining || 0;\r\n this.maxRankSpartanKillsRemaining = data.maxRankSpartanKillsRemaining || 0;\r\n this.maxRankPveKillsRemaining = data.maxRankPveKillsRemaining || 0;\r\n this.maxRankDeathsRemaining = data.maxRankDeathsRemaining || 0;\r\n this.maxRankShotsFiredRemaining = data.maxRankShotsFiredRemaining || 0;\r\n this.maxRankShotsLandedRemaining = data.maxRankShotsLandedRemaining || 0;\r\n this.maxRankVehiclesDestroyedRemaining = data.maxRankVehiclesDestroyedRemaining || 0;\r\n this.maxRankGrenadeKillsRemaining = data.maxRankGrenadeKillsRemaining || 0;\r\n this.maxRankMeleeKillsRemaining = data.maxRankMeleeKillsRemaining || 0;\r\n this.maxRankAssassinationsRemaining = data.maxRankAssassinationsRemaining || 0;\r\n this.maxRankShoulderBashKillsRemaining = data.maxRankShoulderBashKillsRemaining || 0;\r\n this.maxRankGroundPoundKillsRemaining = data.maxRankGroundPoundKillsRemaining || 0;\r\n this.medalProgress = (data.medalProgress || []).map(mp => new MedalProgress(mp));\r\n }\r\n}\r\n\r\nexport default ServiceRecord;\r\n","import { dateUtility } from \"../utilities\";\r\nimport ServiceRecord from \"./ServiceRecord\";\r\n\r\n/** Information representing a Spartan (player). */\r\nexport class Spartan {\r\n gamertag: string;\r\n lastModified: Date;\r\n serviceTag: string;\r\n companyId: string;\r\n companyName: string;\r\n currentRank: number;\r\n currentXp: number;\r\n maxRank: number;\r\n maxRankXp: number;\r\n maxRankOverallCompletion: number;\r\n allTime: ServiceRecord;\r\n arena: ServiceRecord;\r\n warzone: ServiceRecord;\r\n\r\n constructor()\r\n constructor(spartan: Partial)\r\n constructor(data?: Partial) {\r\n data = data || {};\r\n\r\n this.gamertag = data.gamertag || null;\r\n this.lastModified = dateUtility.parseDate(data.lastModified);\r\n this.serviceTag = data.serviceTag || null;\r\n this.companyId = data.companyId || null;\r\n this.companyName = data.companyName || null;\r\n this.currentRank = data.currentRank || 0;\r\n this.currentXp = data.currentXp || 0;\r\n this.maxRank = data.maxRank || 0;\r\n this.maxRankXp = data.maxRankXp || 0;\r\n this.maxRankOverallCompletion = data.maxRankOverallCompletion || 0;\r\n this.allTime = data.allTime ? new ServiceRecord(data.allTime) : null;\r\n this.arena = data.arena ? new ServiceRecord(data.arena) : null;\r\n this.warzone = data.warzone ? new ServiceRecord(data.warzone) : null;\r\n }\r\n}\r\n\r\nexport default Spartan;\r\n","import { PageInfo } from \"./models\";\r\n\r\nexport const pages: PageInfo[] = [\r\n {\r\n name: \"Home\",\r\n url: \"https://sr152.app\",\r\n path: \"/\",\r\n title: \"\",\r\n description: \"Halo 5: Guardians Spartan Rank 152 (SR 152) Progress Tracker & XP Tracker.\"\r\n },\r\n {\r\n name: \"Spartan\",\r\n url: \"https://sr152.app/spartan\",\r\n path: \"/spartan\",\r\n title: null,\r\n description: \"Player progression and statistics towards Spartan Rank 152.\"\r\n },\r\n {\r\n name: \"Ranks\",\r\n url: \"https://sr152.app/ranks\",\r\n path: \"/ranks\",\r\n title: \"Ranks\",\r\n description: \"All 152 Spartan Ranks in Halo 5: Guardians along with their XP requirement.\"\r\n },\r\n {\r\n name: \"Feedback\",\r\n url: \"https://sr152.app/feedback\",\r\n path: \"/feedback\",\r\n title: \"Feedback\",\r\n description: \"We'd love to hear what you think about SR152. Let us know what improvements you'd like to see or what we can improve.\"\r\n },\r\n {\r\n name: \"About\",\r\n url: \"https://sr152.app/about\",\r\n path: \"/about\",\r\n title: \"About\",\r\n description: \"SR152 is a small app designed to allow users to track their progress towards Spartan Rank 152 in Halo: 5 Guardians.\"\r\n },\r\n {\r\n name: \"Legal\",\r\n url: \"https://sr152.app/legal\",\r\n path: \"/legal\",\r\n title: \"Legal Disclaimers\",\r\n description: \"The legal stuff we have to provide.\"\r\n },\r\n {\r\n name: \"Terms & Conditions\",\r\n url: \"https://sr152.app/terms-and-conditions\",\r\n path: \"/terms-and-conditions\",\r\n title: \"Terms & Conditions\",\r\n description: \"Terms and conditions governing the use of the application.\"\r\n },\r\n];\r\n\r\nexport default pages;\r\n","import React from \"react\";\r\n\r\nexport interface AboutProps { }\r\n\r\nexport const About: React.FunctionComponent = (props) => {\r\n return (\r\n
\r\n

About

\r\n
\r\n

\r\n SR152 is an app which shows estimated progression data towards player's progress to Spartan Rank 152 in Halo: 5 Guardians.\r\n

\r\n\r\n

Game Progression

\r\n
\r\n

\r\n Halo 5: Guardians features a progression system where players earn experience points (XP) which contributes to their total Spartan Rank.\r\n

\r\n

\r\n The player begins the game at Spartan Rank 1 and can progress to the maximum rank of Spartan Rank 152 which requires 50,000,000 XP.\r\n

\r\n

\r\n Players gain experience points by competing in competitive match-made Arena or Warzone games or cooperative Warzone Firefight missions.\r\n

\r\n

\r\n The amount of XP required for each Spartan Rank increases between each rank, with the XP required for the final levels increasing drastically.\r\n

\r\n

\r\n Spartan Rank 125 is roughly 5% of the total XP required to reach Spartan Rank 152 at 4,935,000 XP.\r\n Spartan Rank 150 is just under 50% of the total XP required at 24,000,000 XP.\r\n

\r\n\r\n

App Purpose

\r\n
\r\n

\r\n This application provides linear progress estimates regarding games played, games won, kills, shots fired, and more until a player reaches Spartan Rank 152 based on past match data.\r\n

\r\n

\r\n These estimates are aimed at making progression a little more fun while showcasing the extreme requirements of Spartan Rank 152.\r\n

\r\n
\r\n );\r\n}\r\n\r\nexport default About;\r\n","import config from \"../config\";\r\nimport Feedback from \"../models/Feedback\";\r\n\r\n/** A service which exposes methods for working with user feedback. */\r\nexport const FeedbackService = {\r\n\r\n /** Returns a promise of a new user feedback. */\r\n save: (feedback: Feedback): Promise => fetch(`${config.apiRootUrl}/api/feedback`, {\r\n method: \"POST\",\r\n headers: {\r\n \"Accept\": \"application/json\",\r\n \"Content-Type\": \"application/json\",\r\n },\r\n body: JSON.stringify(feedback),\r\n }).then(r => {\r\n if (!r.ok) {\r\n throw r;\r\n }\r\n }),\r\n}\r\n\r\nexport default FeedbackService;\r\n","import config from \"../config\";\r\n\r\nconst baseUrl = `${config.apiRootUrl}/api/images`;\r\n\r\n/** Exposes methods for retrieving image data. */\r\nexport const ImageService = {\r\n /** Gets the URL of the identified medal image. */\r\n medalIcon: (medalId: number | string): string => `${baseUrl}/medals/${medalId}`,\r\n\r\n /** Gets the URL of the identified spartan emblem */\r\n spartanEmblem: (gamertag: string): string => `${baseUrl}/spartans/emblems/${gamertag}`,\r\n\r\n /** Gets the URL of the default spartan image */\r\n defaultSpartanImage: (): string => `${baseUrl}/spartans/image/default`,\r\n\r\n /** Gets the URL of the identified spartan image */\r\n spartanImage: (gamertag: string): string => `${baseUrl}/spartans/images/${gamertag}`,\r\n};\r\n\r\nexport default ImageService;\r\n","import config from \"../config\";\r\nimport Match from \"../models/Match\";\r\n\r\n/** A service which exposes methods for retrieving Match data. */\r\nexport const MatchService = {\r\n\r\n /**\r\n * Returns a promise of the latest Match data for the specified gamertag.\r\n * @param {string} gamertag The XBL gamertag of the latest match to lookup.\r\n */\r\n getLatestMatch: (gamertag: string): Promise => fetch(`${config.apiRootUrl}/api/matches/${encodeURIComponent(gamertag)}/latest`)\r\n .then(resp => resp.status !== 204 ? resp.json() : null)\r\n .then((match: Match) => match ? new Match(match) : null),\r\n}\r\n\r\nexport default MatchService;\r\n","import config from \"../config\";\r\nimport Rank from \"../models/Rank\";\r\n\r\n/** A service which exposes methods for working with Spartan Rank data. */\r\nexport const RankService = {\r\n\r\n /** Returns a promise of an array of all Spartan Ranks. */\r\n getAll: (): Promise => fetch(`${config.apiRootUrl}/api/ranks`)\r\n .then(resp => resp.status !== 204 ? resp.json() : null)\r\n .then((ranks: Rank[]) => ranks && ranks.length ? ranks.map(r => new Rank(r)) : []),\r\n}\r\n\r\nexport default RankService;\r\n","import { PlayerSearch } from \"../models\";\r\n\r\ninterface SearchHistoryDef {\r\n /** Returns all existing search history records. */\r\n getAll: () => PlayerSearch[];\r\n\r\n /** Subscribe to searches. */\r\n subscribe: (callback: (player: PlayerSearch) => void) => void;\r\n\r\n /** Publishes a new gamertag to the search history. */\r\n publish: (gamertag: string, serviceTag?: string) => void;\r\n}\r\n\r\nconst service = {\r\n legacyLocalStorageKey: \"gamertag-search-history\",\r\n localStorageKey: \"gamertag-serach-history-v2\",\r\n localStorageLimit: 15,\r\n subscriptions: Array<(player: PlayerSearch) => void>(0),\r\n\r\n getAll: (): PlayerSearch[] => {\r\n let players: PlayerSearch[] = [];\r\n\r\n const json: string = localStorage.getItem(service.localStorageKey);\r\n if (json) {\r\n players = JSON.parse(json) || [];\r\n } else {\r\n const legacy: string = localStorage.getItem(service.legacyLocalStorageKey);\r\n const history: string[] = legacy ? JSON.parse(legacy) || [] : [];\r\n\r\n players = history.map(p => new PlayerSearch({ gamertag: p, isLegacy: true, }))\r\n }\r\n\r\n return players;\r\n },\r\n\r\n add: (gamertag: string, serviceTag?: string, emblemBase64?: string): void => {\r\n if (gamertag) {\r\n const player: PlayerSearch = new PlayerSearch({ gamertag, serviceTag, emblemBase64, isLegacy: !serviceTag, });\r\n const json: string = localStorage.getItem(service.localStorageKey);\r\n const players: PlayerSearch[] = json ? JSON.parse(json) || [] : [];\r\n let history = players.filter(p => p?.gamertag?.toLowerCase() !== gamertag.toLowerCase()).filter((_h, idx) => idx < service.localStorageLimit - 1);\r\n history = [player].concat(history);\r\n\r\n localStorage.setItem(service.localStorageKey, JSON.stringify(history));\r\n }\r\n },\r\n\r\n subscribe: (callback: (player: PlayerSearch) => void): void => {\r\n if (callback) {\r\n service.subscriptions.push(callback);\r\n }\r\n },\r\n\r\n publish: (gamertag: string, serviceTag?: string, emblemBase64?: string): void => {\r\n if (gamertag) {\r\n service.add(gamertag, serviceTag, emblemBase64);\r\n\r\n for (let sub of service.subscriptions) {\r\n try {\r\n if (sub) {\r\n sub({ gamertag, serviceTag, emblemBase64, isLegacy: false, });\r\n }\r\n } catch (err) {\r\n // ignore\r\n }\r\n }\r\n }\r\n },\r\n};\r\n\r\nexport const SearchHistoryService = service as SearchHistoryDef;\r\n\r\nexport default SearchHistoryService;\r\n","import config from \"../config\";\r\nimport Spartan from \"../models/Spartan\";\r\n\r\n/** A service which exposes methods for retrieving Spartan data. */\r\nexport const SpartanService = {\r\n\r\n /**\r\n * Returns a promise of Spartan data for the specified gamertag.\r\n * @param {string} gamertag The XBL gamertag of the Spartan to lookup.\r\n */\r\n getSpartan: (gamertag: string): Promise => fetch(`${config.apiRootUrl}/api/spartans/${encodeURIComponent(gamertag)}`)\r\n .then(resp => resp.status !== 204 ? resp.json() : null)\r\n .then((spartan: Spartan) => spartan ? new Spartan(spartan) : null),\r\n}\r\n\r\nexport default SpartanService;\r\n","type ToastType = \"primary\" | \"secondary\" | \"success\" | \"info\" | \"warning\" | \"danger\";\r\ntype ToastInfo = {\r\n type: ToastType,\r\n title: string;\r\n message: string;\r\n hideAfter: number;\r\n}\r\n\r\ninterface ToastServiceDef {\r\n /** Subscribe to new toasts. */\r\n subscribe: (callback: (toastInfo: ToastInfo) => void) => void;\r\n\r\n /** Toast a new message to the UI. */\r\n toast: (type: ToastType, message: string, title?: string, hideAfter?: number) => void;\r\n}\r\n\r\nconst service = {\r\n subscriptions: Array<(toastInfo: ToastInfo) => void>(0),\r\n\r\n subscribe: (callback: (toastInfo: ToastInfo) => void): void => {\r\n if (callback) {\r\n service.subscriptions.push(callback);\r\n }\r\n },\r\n\r\n toast: (type: ToastType, message: string, title: string = \"\", hideAfter: number = null): void => {\r\n const toast: ToastInfo = {\r\n type,\r\n message,\r\n title,\r\n hideAfter,\r\n };\r\n\r\n for (let sub of service.subscriptions) {\r\n try {\r\n if (sub) {\r\n sub(toast);\r\n }\r\n } catch (err) {\r\n // ignore\r\n }\r\n }\r\n },\r\n};\r\n\r\nexport const ToastService: ToastServiceDef = service;\r\n\r\nexport default ToastService;\r\n","import { FunctionComponent, ReactElement, useState } from \"react\";\r\n\r\nlet fieldNum: number = 1;\r\n\r\nexport interface FeedbackCheckboxProps {\r\n fieldName: string;\r\n label: string;\r\n isLike?: boolean;\r\n setValue: (value: boolean) => void;\r\n setComment?: (comment: string) => void;\r\n}\r\n\r\nexport const FeedbackCheckbox: FunctionComponent = (props): ReactElement => {\r\n const [isChecked, setIsChecked] = useState(false);\r\n const [comment, setComment] = useState(\"\");\r\n const setCheckedState = (val: boolean) => {\r\n setIsChecked(val);\r\n props.setValue(val);\r\n };\r\n const setCommentState = (comment: string) => {\r\n setComment(comment);\r\n props.setComment(comment);\r\n };\r\n const commentText = props.isLike\r\n ? \"Let us know if you have any suggestions for this feature:\"\r\n : \"Let us know what changes or alternatives you'd like to see in this feature:\";\r\n fieldNum += 1;\r\n\r\n return (\r\n
\r\n setCheckedState(e.target.checked)}\r\n />\r\n \r\n
\r\n \r\n setCommentState(e.target.value)}\r\n />\r\n
\r\n
\r\n )\r\n}\r\n\r\nexport default FeedbackCheckbox;\r\n","import { FunctionComponent, ReactElement, useState } from \"react\";\r\nimport { Feedback as FeedbackModel } from \"../../models\";\r\nimport { FeedbackService, ToastService } from \"../../services\";\r\nimport { analytics } from \"../../utilities\";\r\nimport FeedbackCheckbox from \"./FeedbackCheckbox/FeedbackCheckbox\";\r\n\r\nlet fieldNum: number = 1;\r\n\r\nexport interface IFeedbackProps { }\r\n\r\nexport const Feedback: FunctionComponent = (props): ReactElement => {\r\n const [isSubmitting, setIsSubmitting] = useState();\r\n const [feedback, setFeedback] = useState(new FeedbackModel());\r\n const [userName, setUserName] = useState();\r\n const [likesAdditionalComments, setLikesAdditionalComments] = useState();\r\n const [needsImprovementAdditionalComments, setNeedsImprovementAdditionalComments] = useState();\r\n const [featureRequest, setFeatureRequest] = useState();\r\n const [gamertag, setGamertag] = useState();\r\n const [otherComments, setOtherComments] = useState();\r\n const submit = () => {\r\n feedback.userName = userName;\r\n feedback.likesAdditionalComment = likesAdditionalComments;\r\n feedback.needsImprovementAdditionalComment = needsImprovementAdditionalComments;\r\n feedback.featureRequestComment = featureRequest;\r\n feedback.gamertag = gamertag;\r\n feedback.generalComment = otherComments;\r\n\r\n Promise.resolve()\r\n .then(() => setIsSubmitting(true))\r\n .then(() => analytics.trackEvent(\"select_item\", {\r\n \"item_list_name\": \"Submit Feedback\",\r\n items: [\"Submit Feedback\"]\r\n }))\r\n .then(() => FeedbackService.save(feedback))\r\n .then(() => setFeedback(null))\r\n .then(() => {\r\n setFeedback(new FeedbackModel());\r\n setLikesAdditionalComments(\"\");\r\n setNeedsImprovementAdditionalComments(\"\");\r\n setFeatureRequest(\"\");\r\n setGamertag(\"\");\r\n setOtherComments(\"\");\r\n })\r\n .then(() => window.scrollTo(0, 1))\r\n .then(() => ToastService.toast(\"success\", \"Thank you for your feedback!\", \"Feedback Submitted\", 5000))\r\n .catch(err => ToastService.toast(\"danger\", \"An error occured saving your feedback. Please try again or contact us via email.\", \"Feedback Error\", 10000))\r\n .finally(() => setIsSubmitting(false))\r\n }\r\n fieldNum += 1;\r\n\r\n return feedback ? (\r\n
\r\n

Feedback

\r\n
\r\n

\r\n Thank you for using SR152!\r\n
\r\n We'd love to hear your feedback on the app and get input on future features and improvements.\r\n

\r\n\r\n
\r\n \r\n setUserName(e.target.value)}\r\n />\r\n
\r\n\r\n

What features do you like:

\r\n
\r\n feedback.likesProgressionBar = v}\r\n setComment={c => feedback.likesProgressionBarComment = c}\r\n />\r\n feedback.likesLastMatch = v}\r\n setComment={c => feedback.likesLastMatchComment = c}\r\n />\r\n feedback.likesStatProjection = v}\r\n setComment={c => feedback.likesStatProjectionComment = c}\r\n />\r\n feedback.likesRecentlySearched = v}\r\n setComment={c => feedback.likesRecentlySearchedComment = c}\r\n />\r\n feedback.likesRankPage = v}\r\n setComment={c => feedback.likesRankPageComment = c}\r\n />\r\n
\r\n \r\n setLikesAdditionalComments(e.target.value)}\r\n />\r\n
\r\n\r\n

What features need improvement:

\r\n
\r\n feedback.needsImprovementProgressionBar = v}\r\n setComment={c => feedback.needsImprovementProgressionBarComment = c}\r\n />\r\n feedback.needsImprovementLastMatch = v}\r\n setComment={c => feedback.needsImprovementLastMatchComment = c}\r\n />\r\n feedback.needsImprovementStatProjection = v}\r\n setComment={c => feedback.needsImprovementStatProjectionComment = c}\r\n />\r\n feedback.needsImprovementRecentlySearched = v}\r\n setComment={c => feedback.needsImprovementRecentlySearchedComment = c}\r\n />\r\n feedback.needsImprovementRankPage = v}\r\n setComment={c => feedback.needsImprovementRankPageComment = c}\r\n />\r\n
\r\n \r\n setNeedsImprovementAdditionalComments(e.target.value)}\r\n />\r\n
\r\n\r\n

Let us know what features you'd like to see added:

\r\n
\r\n feedback.featureRequestMobileApp = v}\r\n />\r\n feedback.featureRequestPredictionTool = v}\r\n />\r\n feedback.featureRequestXpBreakdownPage = v}\r\n />\r\n
\r\n \r\n setFeatureRequest(e.target.value)}\r\n />\r\n
\r\n\r\n

Tell use a little more:

\r\n
\r\n feedback.usesDesktop = v}\r\n />\r\n feedback.usesMobile = v}\r\n />\r\n
\r\n \r\n setGamertag(e.target.value)}\r\n />\r\n
\r\n
\r\n \r\n setOtherComments(e.target.value)}\r\n />\r\n
\r\n\r\n
\r\n submit()}\r\n disabled={isSubmitting || false}\r\n >\r\n {isSubmitting ? \"Sending Feedback\" : \"Send Feedback\"}\r\n \r\n
\r\n
\r\n ) : null;\r\n};\r\n\r\nexport default Feedback;\r\n","import { FunctionComponent, ReactElement } from \"react\";\r\nimport { Modal } from \"react-bootstrap\";\r\n\r\nexport interface FeedbackModalProps {\r\n show: boolean;\r\n showFeedback: () => void;\r\n dismiss: () => void;\r\n}\r\n\r\nexport const FeedbackModal: FunctionComponent = (props): ReactElement => {\r\n return (\r\n props.dismiss()} style={{ marginTop: \"100px\"}}>\r\n \r\n
\r\n

\r\n We could use your feedback!\r\n

\r\n props.dismiss()}\r\n >\r\n ×\r\n \r\n
\r\n
\r\n \r\n

\r\n Your feedback is important to us! It helps us decide what features to add, what adjustments to make, and more!\r\n

\r\n

\r\n Please consider taking a few minutes to let us know what we're doing right and where we can improve.\r\n

\r\n
\r\n \r\n
\r\n props.showFeedback()}\r\n >\r\n Give Feedback\r\n \r\n props.dismiss()}\r\n >\r\n No Thanks\r\n \r\n
\r\n
\r\n
\r\n );\r\n};\r\n\r\nexport default FeedbackModal;\r\n","import React, { FormEvent, FormEventHandler, useEffect, useState } from \"react\";\r\nimport { useHistory, useParams } from \"react-router-dom\";\r\nimport config from \"../../../config\";\r\nimport { PlayerSearch } from \"../../../models\";\r\nimport { ImageService, SearchHistoryService } from \"../../../services\";\r\nimport { analytics } from \"../../../utilities\";\r\nimport \"./Navigation.scss\";\r\n\r\nconst sanatizeGamertag = (gamertag: string): string => gamertag?.replace(\"#\", \"\").toLocaleLowerCase();\r\n\r\nexport interface NavigationProps { }\r\n\r\n/** Primary navigation menu. */\r\nexport const Navigation: React.FunctionComponent = (props) => {\r\n const history = useHistory();\r\n const urlParams = useParams>();\r\n const [gamertag, setGamertag] = useState(config.isDevEnvironment ? \"Link of Darknes\" : \"\");\r\n const [subPlayer, setSubPlayer] = useState();\r\n const [searchHistory, setSearchHistory] = useState([]);\r\n const goHome: FormEventHandler = (e) => {\r\n e.preventDefault();\r\n\r\n history.push('/');\r\n };\r\n const search = (e: FormEvent, gt?: string) => {\r\n e.preventDefault();\r\n\r\n if (gt || gamertag) {\r\n analytics.trackEvent(\"search\", {\r\n search_term: gt || gamertag,\r\n });\r\n\r\n history.push(`/spartan/${sanatizeGamertag(gt || gamertag)}`);\r\n }\r\n };\r\n const players = searchHistory.filter(p => !p.isLegacy && sanatizeGamertag(p.gamertag) !== urlParams.gamertag);\r\n\r\n useEffect(() => {\r\n const searchHistory = SearchHistoryService.getAll();\r\n SearchHistoryService.subscribe(gt => setSubPlayer(gt));\r\n setSearchHistory(searchHistory || []);\r\n }, [])\r\n\r\n useEffect(() => {\r\n if (subPlayer) {\r\n const history = SearchHistoryService.getAll();\r\n setSearchHistory(history || []);\r\n }\r\n }, [subPlayer])\r\n\r\n return (\r\n
\r\n
\r\n
\r\n \r\n \"SR152\r\n \r\n
\r\n { e.preventDefault(); history.push(\"/ranks\") }}\r\n className=\"btn btn-secondary me-3\"\r\n >\r\n Ranks\r\n \r\n setGamertag(e.target.value)}\r\n value={gamertag}\r\n />\r\n \r\n {searchHistory.map((p, idx) => (\r\n \r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n {players.map((p, idx) => (\r\n
4 ? \"d-none\" : null}`}>\r\n \r\n
\r\n ))}\r\n
\r\n
\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default Navigation;\r\n","import \"./Toast.scss\";\r\nimport React from \"react\";\r\nimport { Toast as BootstrapToast } from \"react-bootstrap\";\r\n\r\nexport interface ToastProps {\r\n\r\n /** The classification of the toast. */\r\n type: \"primary\" | \"secondary\" | \"success\" | \"info\" | \"warning\" | \"danger\";\r\n\r\n /** The title of the toast. */\r\n title: string;\r\n\r\n /** The body content of the toast. */\r\n message: string;\r\n\r\n /** The optional number of milliseconds to auto-hide the toast after. */\r\n hideAfter?: number;\r\n\r\n /** A call back to the parent component indicating the toast should be closed. */\r\n onClose: () => void;\r\n}\r\n\r\nexport const Toast: React.FunctionComponent = (props) => {\r\n return (\r\n 0}\r\n delay={props?.hideAfter}\r\n onClose={() => props.onClose()}\r\n >\r\n \r\n \r\n {props.title || \"\"}\r\n {/*just now*/}\r\n \r\n \r\n {props.message}\r\n \r\n \r\n )\r\n}\r\n\r\nexport default Toast;\r\n","import React, { useEffect, useState } from \"react\";\r\nimport { ToastService } from \"../../../services\";\r\nimport { Toast, ToastProps } from \"./Toast/Toast\";\r\n\r\ntype ToastInfo = Omit;\r\ntype Toasts = {\r\n [index: string]: ToastInfo;\r\n}\r\n\r\nexport interface ToastContainerProps { }\r\n\r\nexport const ToastContainer: React.FunctionComponent = (props) => {\r\n const [subToast, setSubToast] = useState();\r\n const [toasts, setToasts] = useState({});\r\n const closeToast = (index: string) => {\r\n const newToasts = { ...toasts };\r\n delete newToasts[index];\r\n setToasts(newToasts);\r\n };\r\n\r\n useEffect(() => {\r\n ToastService.subscribe(t => setSubToast(t));\r\n }, [])\r\n\r\n useEffect(() => {\r\n if (subToast) {\r\n const indexes = toasts ? Object.keys(toasts) : [];\r\n const newIdx = indexes.length ? parseInt(indexes[indexes.length - 1]) + 1 : 0;\r\n const newToasts = { ...toasts, }\r\n newToasts[newIdx] = subToast;\r\n setToasts(newToasts);\r\n }\r\n }, [subToast])\r\n\r\n return (\r\n \r\n {Object.keys(toasts).map(key => (\r\n closeToast(key)} />\r\n ))}\r\n \r\n )\r\n}\r\n\r\nexport default ToastContainer;\r\n","import { FunctionComponent, useEffect } from \"react\";\r\nimport { Helmet } from \"react-helmet-async\";\r\nimport { useLocation } from \"react-router\";\r\nimport config from \"../../../config\";\r\nimport { PageInfo } from \"../../../models\";\r\nimport { analytics } from \"../../../utilities\";\r\nimport \"./Tracking.scss\";\r\n\r\nexport interface TrackingProps {\r\n /** Information about the current page. */\r\n pageInfo: PageInfo;\r\n};\r\n\r\nexport const Tracking: FunctionComponent = (props) => {\r\n const location = useLocation();\r\n\r\n // SPA page changes\r\n useEffect(() => {\r\n const url = location.pathname && location.pathname.length > 1 ? `${window.location.origin}${location.pathname}` : window.location.origin;\r\n\r\n analytics.trackPageView(null, url);\r\n }, [location]);\r\n\r\n return (\r\n
\r\n {props.pageInfo ? (\r\n \r\n { /* Title */ }\r\n {props.pageInfo.title ? (\r\n \r\n {props.pageInfo.title ? `${props.pageInfo.title} | ${config.defaultPageTitle}` : config.defaultPageTitle}\r\n \r\n ) : null}\r\n {props.pageInfo.title ? (\r\n \r\n ) : null}\r\n\r\n { /* Description */ }\r\n {props.pageInfo.description ? (\r\n \r\n ): null}\r\n {props.pageInfo.description ? (\r\n \r\n ): null}\r\n\r\n { /* Canonical URL */ }\r\n {props.pageInfo.url ? (\r\n \r\n ): null}\r\n {props.pageInfo.url ? (\r\n \r\n ): null}\r\n \r\n ) : null}\r\n
\r\n );\r\n};\r\n\r\nexport default Tracking;\r\n","import React, { useEffect, useState } from \"react\";\r\nimport { useHistory } from \"react-router-dom\";\r\nimport { PageInfo } from \"../../models\";\r\nimport { storageUtility } from \"../../utilities\";\r\nimport FeedbackModal from \"./FeedbackModal/FeedbackModal\";\r\nimport \"./Layout.scss\";\r\nimport Navigation from \"./Navigation/Navigation\";\r\nimport ToastContainer from \"./ToastContainer/ToastContainer\";\r\nimport Tracking from \"./Tracking/Tracking\";\r\n\r\ntype Visits = {\r\n [key: string]: boolean;\r\n}\r\n\r\n/** Configuration options for usePageLayout. */\r\nexport interface PageLayoutOptions {\r\n\r\n /** Information about the current page. */\r\n pageInfo: PageInfo;\r\n\r\n /** An optional flag which when true disables the default padding in the layout's body. */\r\n noPadding?: boolean;\r\n}\r\n\r\n/** A HOC which renders the page layout around any component. */\r\nexport const usePageLayout = (Component: React.JSXElementConstructor, options: PageLayoutOptions): React.ReactElement => {\r\n const Layout: React.FunctionComponent = (props) => {\r\n const [promptForFeedback, setPromptForFeedback] = useState(false);\r\n const history = useHistory();\r\n const navigate = (e: React.UIEvent, path: string) => {\r\n e.preventDefault();\r\n\r\n history.push(path);\r\n };\r\n const visitsKey = \"layout.visits\";\r\n const dismissFeedbackKey = \"layout.dismiss-feedback\";\r\n const addVisit = (): void => {\r\n const visits = storageUtility.getFromLocalStorage(visitsKey) || {};\r\n visits[new Date().toDateString()] = true;\r\n\r\n storageUtility.saveToLocalStorage(visitsKey, visits);\r\n };\r\n const dismissFeedback = () => {\r\n storageUtility.saveToLocalStorage(dismissFeedbackKey, 1);\r\n setPromptForFeedback(false);\r\n }\r\n const showFeedback = () => {\r\n dismissFeedback();\r\n history.push(\"/feedback\");\r\n };\r\n\r\n useEffect(() => {\r\n addVisit();\r\n\r\n history.listen(() => window.scrollTo(0, 1));\r\n\r\n // show feedback prompt?\r\n const visits = storageUtility.getFromLocalStorage(visitsKey) || {};\r\n const dismissed = storageUtility.getFromLocalStorage(dismissFeedbackKey);\r\n if (!dismissed && Object.keys(visits).length > 3 && Component.name !== \"Feedback\") {\r\n setPromptForFeedback(true);\r\n }\r\n }, []);\r\n\r\n return (\r\n
\r\n \r\n
\r\n \r\n
\r\n
\r\n \r\n showFeedback()}\r\n dismiss={() => dismissFeedback()}\r\n />\r\n
\r\n
\r\n { /*\r\n
\r\n Sidebar\r\n
\r\n */ }\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n );\r\n }\r\n\r\n return ();\r\n};\r\n\r\nexport default usePageLayout;\r\n","import { FunctionComponent } from \"react\";\r\n\r\nexport interface LegalProps { }\r\n\r\nexport const Legal: FunctionComponent = (props) => {\r\n return (\r\n
\r\n

Legal Notices

\r\n\r\n

\r\n SR152

\r\n
\r\n

\r\n The application and SR152 logo are Copyright © Lod Softworks LLC, All Rights Reserved.\r\n

\r\n

\r\n This application is provided as-is and may be modified, suspended, or discontinued at any time without notice or liability.\r\n

\r\n

\r\n Use of the application is subject to Lod Softwork LLC's \r\n \r\n Privacy Policy\r\n .\r\n

\r\n\r\n

Halo

\r\n
\r\n

\r\n This application is offered by Lod Softworks LLC, which is solely responsible for its content.\r\n It is not sponsored or endorsed by Microsoft.\r\n This application uses the Halo® Game Data API.\r\n

\r\n

\r\n Halo © Microsoft Corporation. All rights reserved. Microsoft, Halo, and the Halo Logo are trademarks of the Microsoft group of companies.\r\n

\r\n

\r\n Image assets excluding the SR152 logo and Lod Softworks logo are owned and copyrighted by Microsoft Corporation.\r\n

\r\n\r\n

Iconography

\r\n
\r\n

\r\n Icons are provided under license by Font Awesome.\r\n

\r\n
\r\n );\r\n}\r\n\r\nexport default Legal;\r\n","import React, { useEffect, useState } from \"react\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { faHelmetBattle } from \"@fortawesome/pro-duotone-svg-icons\";\r\n\r\nexport interface LoadingProps {\r\n message?: string;\r\n}\r\n\r\nexport const Loading: React.FunctionComponent = (props) => {\r\n const [time, setTime] = useState(0);\r\n useEffect(() => {\r\n setTimeout(() => setTime(time + 1), 500)\r\n }, [time])\r\n\r\n return (\r\n
\r\n
\r\n \r\n

\r\n { props.message || \"Loading\" }{ Array((time % 3) + 1).fill(null).map((ele, idx) => (.)) }\r\n

\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default Loading;\r\n","import React from \"react\";\r\nimport { Rank as RankModel } from \"../../../models\";\r\n\r\nexport interface RankProps {\r\n previousRank: RankModel;\r\n currentRank: RankModel;\r\n maxRank: RankModel;\r\n}\r\n\r\nexport const Rank: React.FunctionComponent = (props) => {\r\n const totalRemainingXp = props.maxRank.startingXp - props.currentRank.startingXp;\r\n const totalRemainingPercent = totalRemainingXp / props.maxRank.startingXp;\r\n const newXp = props.currentRank.startingXp - props.previousRank.startingXp;\r\n const newPercentage = ((props.currentRank.startingXp - props.previousRank.startingXp) / props.maxRank.startingXp);\r\n const previousPercentage = newPercentage < 1 ? 1 - totalRemainingPercent - newPercentage : 0;\r\n\r\n return (\r\n
\r\n
\r\n
\r\n
\r\n

\r\n Spartan Rank {props.currentRank.rankNumber}\r\n

\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n\r\n
\r\n \r\n\r\n
\r\n
\r\n
\r\n
\r\n Rank XP: { newXp.toLocaleString() } ({ (newPercentage * 100).toFixed(3) }%)\r\n
\r\n
\r\n Total XP: { props.currentRank.startingXp.toLocaleString() } ({ ((1 - totalRemainingPercent) * 100).toFixed(3) }%)\r\n
\r\n
\r\n
\r\n \r\n \r\n );\r\n}\r\n\r\nexport default Rank;\r\n","import { faArrowCircleDown, faArrowCircleUp } from \"@fortawesome/pro-duotone-svg-icons\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport React, { useEffect, useState } from \"react\";\r\nimport { Rank as RankModel } from \"../../models\";\r\nimport { RankService, ToastService } from \"../../services\";\r\nimport Loading from \"../Loading/Loading\";\r\nimport Rank from \"./Rank/Rank\";\r\n\r\ntype RankInfo = {\r\n previous: RankModel;\r\n current: RankModel;\r\n max: RankModel;\r\n}\r\n\r\nexport interface RanksProps { }\r\n\r\nexport const Ranks: React.FunctionComponent = (props) => {\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [ranks, setRanks] = useState();\r\n const [reversedRanks, setReversedRanks] = useState();\r\n const [sortOrder, setSortOrder] = useState<\"asc\" | \"desc\">(\"asc\");\r\n\r\n const getRankInfo = (rank: RankModel, index: number, ranks: RankModel[]): RankInfo => {\r\n const previous: RankModel = index > 0 ? ranks[index - 1] : rank;\r\n const max: RankModel = ranks[ranks.length - 1];\r\n const rankInfo: RankInfo = {\r\n previous: previous,\r\n current: rank,\r\n max: max,\r\n };\r\n\r\n return rankInfo;\r\n };\r\n\r\n useEffect(() => {\r\n Promise.resolve()\r\n .then(() => RankService.getAll())\r\n .then(ranks => ranks.map((rank, idx) => getRankInfo(rank, idx, ranks)))\r\n .then(ranks => {\r\n setRanks(ranks);\r\n setReversedRanks(ranks.map(r => r).reverse());\r\n })\r\n .catch(error => ToastService.toast(\"danger\", \"An error occured retrieving rank information.\", \"Rank Lookup Error\", 10000))\r\n .finally(() => setIsLoading(false));\r\n }, []);\r\n\r\n return (\r\n
\r\n {isLoading ? (\r\n \r\n ) : (\r\n
\r\n

Spartan Ranks

\r\n
\r\n

\r\n There are 152 Spartan Ranks in Halo: 5 Guardians, each with an increasing experience point (XP) requirement.\r\n

\r\n

\r\n The below table shows each rank's XP requirement and it's total progression towards Spartan Rank 152.\r\n

\r\n
\r\n setSortOrder(\"asc\")}\r\n title=\"Sort Ascending\"\r\n >\r\n \r\n \r\n Ascending\r\n \r\n \r\n setSortOrder(\"desc\")}\r\n title=\"Sort Descending\"\r\n >\r\n \r\n \r\n Descending\r\n \r\n \r\n
\r\n
\r\n {(sortOrder !== \"desc\" ? ranks : reversedRanks).map((rank, idx) => (\r\n \r\n ))}\r\n
\r\n
\r\n )}\r\n
\r\n );\r\n}\r\n\r\nexport default Ranks;\r\n","import \"./LatestMatch.scss\";\r\nimport { FunctionComponent } from \"react\";\r\nimport { Match } from \"../../../../models\";\r\nimport { match } from \"node:assert\";\r\n\r\nexport interface LatestMatchProps {\r\n match: Match;\r\n}\r\n\r\nexport const LatestMatch: FunctionComponent = (props) => {\r\n const booster = props.match?.booster;\r\n const game = props.match?.gameVariant;\r\n const map = props.match?.mapVariant;\r\n\r\n return props.match ? (\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n

\r\n {game.name}\r\n

\r\n
\r\n \r\n Map: {map.name}\r\n \r\n
\r\n
\r\n \r\n  \r\n { props.match.team } Team\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n XP Earned: {props.match.totalXpGained.toLocaleString()}\r\n {/* \r\n Booster XP: {props.match.boosterXp.toLocaleString()}\r\n */}\r\n
\r\n
\r\n XP Earned: {props.match.totalXpGained.toLocaleString()}\r\n
\r\n
\r\n Placement: {props.match.rank.toLocaleString()}\r\n
\r\n
\r\n Placement: {props.match.rank.toLocaleString()}\r\n
\r\n
\r\n {booster ? (\r\n
\r\n \r\n
\r\n ) : null}\r\n
\r\n
\r\n
\r\n
\r\n ) : (
)\r\n}\r\n\r\nexport default LatestMatch;\r\n","import React from \"react\";\r\nimport { ImageService } from \"../../../../services\";\r\nimport \"./PlayerName.scss\";\r\n\r\nexport interface PlayerNameProps {\r\n gamertag: string;\r\n serviceTag: string;\r\n}\r\n\r\nexport const PlayerName: React.FunctionComponent = (props) => {\r\n return (\r\n
\r\n
\r\n \r\n

\r\n {props.gamertag}\r\n {props.serviceTag ? (\r\n \r\n [{props.serviceTag}]\r\n \r\n ) : null}\r\n

\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default PlayerName;\r\n","import { FunctionComponent } from \"react\";\r\nimport { MedalProgress } from \"../../../../models\";\r\nimport { ImageService } from \"../../../../services\";\r\nimport \"./Medal.scss\";\r\n\r\nexport interface MedalProps { \r\n medal: MedalProgress; \r\n onClick: (id: number) => void;\r\n}\r\n\r\nexport const Medal: FunctionComponent = (props) => {\r\n return (\r\n
props?.onClick(props.medal.id)}>\r\n \r\n

\r\n {props.medal.name}\r\n

\r\n
\r\n
\r\n Current: {props.medal.currentCount}\r\n
\r\n
\r\n Remaining: {props.medal.maxLevelRemainingCount}\r\n
\r\n
\r\n
\r\n {props.medal.currentCount}/{props.medal.maxLevelRemainingCount + props.medal.currentCount}\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default Medal;\r\n","import React from \"react\";\r\nimport { Button, Modal } from \"react-bootstrap\";\r\nimport config from \"../../../../config\";\r\nimport { MedalProgress } from \"../../../../models\";\r\n\r\nexport interface MedalModalProps {\r\n medal: MedalProgress;\r\n showModal: boolean;\r\n closeModal: () => void;\r\n}\r\n\r\nexport const MedalModal: React.FunctionComponent = (props) => {\r\n return (\r\n props.closeModal()} style={{ marginTop: \"100px\"}}>\r\n \r\n
\r\n \r\n

\r\n { props.medal.name }\r\n

\r\n

\r\n { props.medal.description }\r\n

\r\n
\r\n
\r\n \r\n

\r\n \r\n Current:\r\n \r\n { props.medal.currentCount }\r\n

\r\n

\r\n \r\n Remaining:\r\n \r\n { props.medal.maxLevelRemainingCount }\r\n

\r\n

\r\n \r\n Estimated Total:\r\n \r\n { props.medal.currentCount + props.medal.maxLevelRemainingCount }\r\n

\r\n
\r\n \r\n props.closeModal()}\r\n >\r\n Close\r\n \r\n \r\n
\r\n );\r\n}\r\n\r\nexport default MedalModal;\r\n","import { FunctionComponent, useState } from \"react\";\r\nimport { MedalProgress } from \"../../../../models\";\r\nimport Medal from \"./Medal\";\r\nimport MedalModal from \"./MedalModal\";\r\nimport \"./Medals.scss\";\r\n\r\nexport interface MedalsProps {\r\n medals: MedalProgress[];\r\n}\r\n\r\nexport const Medals: FunctionComponent = (props) => {\r\n const [details, setDetails] = useState();\r\n\r\n return (\r\n
\r\n

\r\n Medals\r\n

\r\n
\r\n {props.medals ? props.medals.map((m, idx) => (\r\n
\r\n setDetails(m)}\r\n />\r\n
\r\n )) : null}\r\n
\r\n {details ? (\r\n setDetails(null)}\r\n />\r\n ) : null}\r\n
\r\n );\r\n}\r\n\r\nexport default Medals;\r\n","import \"./PlayerStat.scss\";\r\nimport React from \"react\";\r\nimport { IconDefinition } from \"@fortawesome/fontawesome-common-types\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { faInfoCircle } from \"@fortawesome/pro-duotone-svg-icons\";\r\n\r\nexport interface PlayerStatProps {\r\n icon: IconDefinition;\r\n statName: string;\r\n isLargeStat?: boolean;\r\n currentLabel?: string;\r\n currentValue: string;\r\n remainingLabel?: string;\r\n remainingValue: string;\r\n totalLabel?: string;\r\n totalValue: string;\r\n showDetails: () => void;\r\n}\r\n\r\nexport const PlayerStat: React.FunctionComponent = (props) => {\r\n const details = `${props.currentLabel || `Current ${props.statName}`}: ${props.currentValue || \"\"}\\r\\n`\r\n + `${props.remainingLabel || `Est. Remaining ${props.statName}`}: ${props.remainingValue || \"\"}\\r\\n`\r\n + `${props.totalLabel || `Est. Total ${props.statName}`}: ${props.totalValue || \"\"}`;\r\n\r\n return (\r\n
\r\n
\r\n
\r\n

\r\n
\r\n \r\n
\r\n { props.statName}\r\n

\r\n
\r\n
\r\n \r\n { props.currentValue } / { props.totalValue }\r\n \r\n \r\n
\r\n
\r\n
\r\n
\r\n Current: { props.currentValue }\r\n
\r\n
\r\n Remaining: { props.remainingValue }\r\n
\r\n
\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default PlayerStat;\r\n","import React from \"react\";\r\nimport { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { Button, Modal } from \"react-bootstrap\";\r\n\r\nexport interface StatDetailsModalProps {\r\n statName: string;\r\n icon: IconDefinition;\r\n currentLabel?: string;\r\n currentValue: string;\r\n remainingLabel?: string;\r\n remainingValue: string;\r\n totalLabel?: string;\r\n totalValue: string;\r\n showModal: boolean;\r\n closeModal: () => void;\r\n}\r\n\r\nexport const StatDetailsModal: React.FunctionComponent = (props) => {\r\n return (\r\n props.closeModal()} style={{ marginTop: \"100px\"}}>\r\n \r\n
\r\n \r\n

\r\n { props.statName }\r\n

\r\n
\r\n
\r\n \r\n

\r\n \r\n { props.currentLabel || \"Current\" }:\r\n \r\n { props.currentValue }\r\n

\r\n

\r\n \r\n { props.remainingLabel || \"Remaining\" }:\r\n \r\n { props.remainingValue }\r\n

\r\n

\r\n \r\n { props.totalLabel || \"Estimated Total\" }:\r\n \r\n { props.totalValue }\r\n

\r\n
\r\n \r\n props.closeModal()}\r\n >\r\n Close\r\n \r\n \r\n
\r\n );\r\n}\r\n\r\nexport default StatDetailsModal;\r\n","import { IconDefinition } from \"@fortawesome/fontawesome-svg-core\";\r\nimport {\r\n faAlignLeft, faAlignSlash, faBahai, faBomb, faCarCrash, faChartLineDown, faClock, faComet, faCrosshairs, faGamepadAlt, faHandRock, faHelmetBattle, faKnifeKitchen, faTasks, faTombstoneAlt, faTrophyAlt, faUserAlien\r\n} from \"@fortawesome/pro-duotone-svg-icons\";\r\nimport React, { useEffect, useState } from \"react\";\r\nimport { MedalProgress, ServiceRecord, Spartan } from \"../../../../models\";\r\nimport { analytics, dateUtility } from \"../../../../utilities\";\r\nimport Medals from \"../Medals/Medals\";\r\nimport PlayerStat from \"./PlayerStat/PlayerStat\";\r\nimport \"./PlayerStats.scss\";\r\nimport StatDetailsModal from \"./StatDetailsModal/StatDetailsModal\";\r\n\r\ntype StatType = \"all\" | \"arena\" | \"warzone\";\r\ntype StatValue = number | Date;\r\ntype StatInfo = {\r\n statName: string;\r\n icon: IconDefinition;\r\n isLargeStat?: boolean;\r\n currentLabel?: string;\r\n currentValue: StatValue;\r\n remainingLabel?: string;\r\n remainingValue: StatValue;\r\n totalLabel?: string;\r\n totalValue: StatValue;\r\n}\r\ntype StatInfos = {\r\n all: StatInfo[];\r\n arena: StatInfo[];\r\n warzone: StatInfo[];\r\n}\r\ntype MedalInfos = {\r\n all: MedalProgress[];\r\n arena: MedalProgress[];\r\n warzone: MedalProgress[];\r\n}\r\n\r\nconst shortValueFormatter = (value: StatValue): string => {\r\n let formatted: string = \"\";\r\n\r\n if (typeof value === \"number\") {\r\n formatted = value.toLocaleString();\r\n } else if (value instanceof Date) {\r\n formatted = dateUtility.formatDateShort(value);\r\n } else if (typeof value === \"string\") {\r\n formatted = value;\r\n }\r\n\r\n return formatted;\r\n}\r\n\r\nconst longValueFormatter = (value: StatValue): string => {\r\n let formatted: string = \"\";\r\n\r\n if (typeof value === \"number\") {\r\n formatted = value.toLocaleString();\r\n } else if (value instanceof Date) {\r\n formatted = dateUtility.formatDateLong(value);\r\n } else if (typeof value === \"string\") {\r\n formatted = value;\r\n }\r\n\r\n return formatted;\r\n}\r\n\r\nconst getStatInfoFromServiceRecord = (serviceRecord: ServiceRecord, isArena: boolean = false): StatInfo[] => {\r\n const stats: Array = [\r\n {\r\n statName: \"Time Played\",\r\n icon: faClock,\r\n isLargeStat: true,\r\n currentLabel: \"Current Time\",\r\n currentValue: serviceRecord?.currentTimePlayed || new Date(0),\r\n remainingLabel: \"Est. Time Remaining\",\r\n remainingValue: serviceRecord?.maxRankTimeRemaining || new Date(0),\r\n totalLabel: \"Est. Total Time\",\r\n totalValue: serviceRecord ? new Date(serviceRecord?.currentTimePlayed.getTime() + serviceRecord?.maxRankTimeRemaining.getTime()) : new Date(0),\r\n },\r\n {\r\n statName: \"Games Played\",\r\n icon: faGamepadAlt,\r\n currentLabel: \"Current Games Played\",\r\n currentValue: serviceRecord?.currentGamesPlayed || 0,\r\n remainingLabel: \"Est. Games Remaining\",\r\n remainingValue: serviceRecord?.maxRankGamesRemaining || 0,\r\n totalLabel: \"Est. Total Games\",\r\n totalValue: (serviceRecord?.currentGamesPlayed + serviceRecord?.maxRankGamesRemaining) || 0,\r\n },\r\n {\r\n statName: \"Games Won\",\r\n icon: faTrophyAlt,\r\n currentLabel: \"Current Wins\",\r\n currentValue: serviceRecord?.currentGamesWon || 0,\r\n remainingLabel: \"Est. Wins Remaining\",\r\n remainingValue: serviceRecord?.maxRankGamesWonRemaining || 0,\r\n totalLabel: \"Est. Total Wins\",\r\n totalValue: (serviceRecord?.currentGamesWon + serviceRecord?.maxRankGamesWonRemaining) || 0,\r\n },\r\n {\r\n statName: \"Games Lost\",\r\n icon: faChartLineDown,\r\n currentLabel: \"Current Losses\",\r\n currentValue: serviceRecord?.currentGamesLost || 0,\r\n remainingLabel: \"Est. Losses Remaining\",\r\n remainingValue: serviceRecord?.maxRankGamesLostRemaining || 0,\r\n totalLabel: \"Est. Total Losses\",\r\n totalValue: (serviceRecord?.currentGamesLost + serviceRecord?.maxRankGamesLostRemaining) || 0,\r\n },\r\n {\r\n statName: \"Kills\",\r\n icon: faCrosshairs,\r\n currentLabel: \"Current Kills\",\r\n currentValue: serviceRecord?.currentSpartanKills || 0,\r\n remainingLabel: \"Est. Kills Remaining\",\r\n remainingValue: serviceRecord?.maxRankSpartanKillsRemaining || 0,\r\n totalLabel: \"Est. Total Kills\",\r\n totalValue: (serviceRecord?.currentSpartanKills + serviceRecord?.maxRankSpartanKillsRemaining) || 0,\r\n arenaExclude: true,\r\n },\r\n {\r\n statName: \"Total Kills\",\r\n icon: faCrosshairs,\r\n currentLabel: \"Current Kills\",\r\n currentValue: serviceRecord?.currentTotalKills || 0,\r\n remainingLabel: \"Est. Kills Remaining\",\r\n remainingValue: serviceRecord?.maxRankTotalKillsRemaining || 0,\r\n totalLabel: \"Est. Total Kills\",\r\n totalValue: (serviceRecord?.currentTotalKills + serviceRecord?.maxRankTotalKillsRemaining) || 0,\r\n arenaInclude: true,\r\n },\r\n {\r\n statName: \"Spartan Kills\",\r\n icon: faHelmetBattle,\r\n currentLabel: \"Current Spartan Kills\",\r\n currentValue: serviceRecord?.currentSpartanKills || 0,\r\n remainingLabel: \"Est. Spartan Kills Remaining\",\r\n remainingValue: serviceRecord?.maxRankSpartanKillsRemaining || 0,\r\n totalLabel: \"Est. Spartan Total Kills\",\r\n totalValue: (serviceRecord?.currentSpartanKills + serviceRecord?.maxRankSpartanKillsRemaining) || 0,\r\n arenaInclude: true,\r\n },\r\n {\r\n statName: \"NPC Kills\",\r\n icon: faUserAlien,\r\n currentLabel: \"Current NPC Kills\",\r\n currentValue: serviceRecord?.currentPveKills || 0,\r\n remainingLabel: \"Est. NPC Kills Remaining\",\r\n remainingValue: serviceRecord?.maxRankPveKillsRemaining || 0,\r\n totalLabel: \"Est. NPC Total Kills\",\r\n totalValue: (serviceRecord?.currentPveKills + serviceRecord?.maxRankPveKillsRemaining) || 0,\r\n arenaInclude: true,\r\n },\r\n {\r\n statName: \"Deaths\",\r\n icon: faTombstoneAlt,\r\n currentLabel: \"Current Deaths\",\r\n currentValue: serviceRecord?.currentDeaths || 0,\r\n remainingLabel: \"Est. Deaths Remaining\",\r\n remainingValue: serviceRecord?.maxRankDeathsRemaining || 0,\r\n totalLabel: \"Est. Total Deaths\",\r\n totalValue: (serviceRecord?.currentDeaths + serviceRecord?.maxRankDeathsRemaining) || 0,\r\n },\r\n {\r\n statName: \"Shots Fired\",\r\n icon: faAlignLeft,\r\n currentLabel: \"Current Shots Fired\",\r\n currentValue: serviceRecord?.currentShotsFired || 0,\r\n remainingLabel: \"Est. Remaining Shots\",\r\n remainingValue: serviceRecord?.maxRankShotsFiredRemaining || 0,\r\n totalLabel: \"Est. Total Shots\",\r\n totalValue: (serviceRecord?.currentShotsFired + serviceRecord?.maxRankShotsFiredRemaining) || 0,\r\n },\r\n {\r\n statName: \"Shots Hit\",\r\n icon: faTasks,\r\n currentLabel: \"Current Hits\",\r\n currentValue: serviceRecord?.currentShotsLanded || 0,\r\n remainingLabel: \"Est. Remaining Hits\",\r\n remainingValue: serviceRecord?.maxRankShotsLandedRemaining || 0,\r\n totalLabel: \"Est. Total Hits\",\r\n totalValue: (serviceRecord?.currentShotsLanded + serviceRecord?.maxRankShotsLandedRemaining) || 0,\r\n },\r\n {\r\n statName: \"Shots Missed\",\r\n icon: faAlignSlash,\r\n currentLabel: \"Current Misses\",\r\n currentValue: (serviceRecord?.currentShotsFired - serviceRecord?.currentShotsLanded) || 0,\r\n remainingLabel: \"Est. Remaining Misses\",\r\n remainingValue: (serviceRecord?.maxRankShotsFiredRemaining - serviceRecord?.maxRankShotsLandedRemaining) || 0,\r\n totalLabel: \"Est. Total Misses\",\r\n totalValue: ((serviceRecord?.currentShotsFired - serviceRecord?.currentShotsLanded) + (serviceRecord?.maxRankShotsFiredRemaining - serviceRecord?.maxRankShotsLandedRemaining)) || 0,\r\n },\r\n {\r\n statName: \"Vehicles Destroyed\",\r\n icon: faCarCrash,\r\n currentLabel: \"Current Vehicles Destroyed\",\r\n currentValue: serviceRecord?.currentVehiclesDestroyed || 0,\r\n remainingLabel: \"Est. Remaining Vehicle Destroys\",\r\n remainingValue: serviceRecord?.maxRankVehiclesDestroyedRemaining || 0,\r\n totalLabel: \"Est. Total Vehicle Destroys\",\r\n totalValue: (serviceRecord?.currentVehiclesDestroyed + serviceRecord?.maxRankVehiclesDestroyedRemaining) || 0,\r\n },\r\n {\r\n statName: \"Grenade Kills\",\r\n icon: faBomb,\r\n currentLabel: \"Current Grenade Kills\",\r\n currentValue: serviceRecord?.currentGrenadeKills || 0,\r\n remainingLabel: \"Est. Remaining Grenade Kills\",\r\n remainingValue: serviceRecord?.maxRankGrenadeKillsRemaining || 0,\r\n totalLabel: \"Est. Total Grenade Kills\",\r\n totalValue: (serviceRecord?.currentGrenadeKills + serviceRecord?.maxRankGrenadeKillsRemaining) || 0,\r\n },\r\n {\r\n statName: \"Melee Kills\",\r\n icon: faHandRock,\r\n currentLabel: \"Current Melee Kills\",\r\n currentValue: serviceRecord?.currentMeleeKills || 0,\r\n remainingLabel: \"Est. Remaining Melee Kills\",\r\n remainingValue: serviceRecord?.maxRankMeleeKillsRemaining || 0,\r\n totalLabel: \"Est. Total Melee Kills\",\r\n totalValue: (serviceRecord?.currentMeleeKills + serviceRecord?.maxRankMeleeKillsRemaining) || 0,\r\n },\r\n {\r\n statName: \"Assassinations\",\r\n icon: faKnifeKitchen,\r\n currentLabel: \"Current Assassinations\",\r\n currentValue: serviceRecord?.currentAssassinations || 0,\r\n remainingLabel: \"Est. Remaining Assassinations\",\r\n remainingValue: serviceRecord?.maxRankAssassinationsRemaining || 0,\r\n totalLabel: \"Est. Total Assassinations\",\r\n totalValue: (serviceRecord?.currentAssassinations + serviceRecord?.maxRankAssassinationsRemaining) || 0,\r\n },\r\n {\r\n statName: \"Shoulder Bash Kills\",\r\n icon: faBahai,\r\n currentLabel: \"Current Shoulder Bash Kills\",\r\n currentValue: serviceRecord?.currentShoulderBashKills || 0,\r\n remainingLabel: \"Est. Remaining Shoulder Bash Kills\",\r\n remainingValue: serviceRecord?.maxRankShoulderBashKillsRemaining || 0,\r\n totalLabel: \"Est. Total Shoulder Bash Kills\",\r\n totalValue: (serviceRecord?.currentShoulderBashKills + serviceRecord?.maxRankShoulderBashKillsRemaining) || 0,\r\n },\r\n {\r\n statName: \"Ground Pound Kills\",\r\n icon: faComet,\r\n currentLabel: \"Current Ground Pound Kills\",\r\n currentValue: serviceRecord?.currentGroundPoundKills || 0,\r\n remainingLabel: \"Est. Remaining Ground Pound Kills\",\r\n remainingValue: serviceRecord?.maxRankGroundPoundKillsRemaining || 0,\r\n totalLabel: \"Est. Total Ground Pound Kills\",\r\n totalValue: (serviceRecord?.currentGroundPoundKills + serviceRecord?.maxRankGroundPoundKillsRemaining) || 0,\r\n },\r\n ];\r\n const filteredStats = stats.filter(s => typeof (s.arenaExclude || s.arenaInclude) === \"undefined\" || (s.arenaExclude == isArena || s.arenaInclude == !isArena));\r\n\r\n return filteredStats;\r\n}\r\n\r\nexport interface PlayerStatsProps {\r\n spartan: Spartan;\r\n}\r\n\r\nexport const PlayerStats: React.FunctionComponent = (props) => {\r\n const [statType, setStatType] = useState(\"all\");\r\n const [details, setDetails] = useState();\r\n const selectStatType = (type: StatType) => {\r\n analytics.trackEvent(\"view_item_list\", {\r\n items: [{\r\n name: type,\r\n }],\r\n });\r\n\r\n setStatType(type);\r\n }\r\n const viewDetails = (stat: StatInfo) => {\r\n if (stat) {\r\n analytics.trackEvent(\"view_item\", {\r\n items: [{\r\n name: stat.statName,\r\n statType: statType,\r\n }],\r\n });\r\n }\r\n\r\n setDetails(stat);\r\n };\r\n const stats: StatInfos = {\r\n all: getStatInfoFromServiceRecord(props.spartan?.allTime),\r\n arena: getStatInfoFromServiceRecord(props?.spartan?.arena, true),\r\n warzone: getStatInfoFromServiceRecord(props?.spartan?.warzone),\r\n };\r\n const medals: MedalInfos = {\r\n all: props.spartan?.allTime?.medalProgress || [],\r\n arena: props.spartan?.arena?.medalProgress || [],\r\n warzone: props.spartan?.warzone?.medalProgress || [],\r\n };\r\n\r\n useEffect(() => selectStatType(\"all\"), []);\r\n\r\n return (\r\n
\r\n
    \r\n
  • \r\n selectStatType(\"all\")}\r\n >\r\n All Stats\r\n \r\n
  • \r\n
  • \r\n selectStatType(\"arena\")}\r\n >\r\n Arena Stats\r\n \r\n
  • \r\n
  • \r\n selectStatType(\"warzone\")}\r\n >\r\n Warzone Stats\r\n \r\n
  • \r\n
\r\n
\r\n {stats[statType].map((stat, idx) => (\r\n
\r\n viewDetails(stats[statType][idx])}\r\n />\r\n
\r\n ))}\r\n
\r\n
\r\n \r\n
\r\n {details ? (\r\n setDetails(null)}\r\n />\r\n ) : (
)}\r\n
\r\n );\r\n}\r\n\r\nexport default PlayerStats;\r\n","import React, { useMemo } from \"react\";\r\nimport { Rank } from \"../../../../models\";\r\n\r\nexport interface ProgressBarProps {\r\n completionPercentage: number;\r\n currentXp: number;\r\n ranks: Rank[];\r\n}\r\n\r\n// TODO: need to expand or modal an XP table showing each level's XP and the progress towards it (and how insignificant it is to 152)\r\n\r\nexport const ProgressBar: React.FunctionComponent = (props) => {\r\n const minXp = 0;\r\n const maxXp = props.ranks ? props.ranks[props.ranks.length - 1].startingXp : 0;\r\n const percentage = Math.min(1, props?.currentXp / maxXp) || 0;\r\n\r\n const [currentLevel, nextLevel, maxLevel] = useMemo((): [currentRank: Rank, nextRank: Rank, maxLevel: Rank] => {\r\n const currentXp = props?.currentXp || 0;\r\n const maxRank: Rank = props.ranks[props.ranks.length - 1];\r\n let currentRank: Rank;\r\n let nextRank: Rank;\r\n\r\n if (currentXp <= 0) {\r\n currentRank = props.ranks[0];\r\n nextRank = props.ranks[1];\r\n } else if (currentXp >= maxXp) {\r\n currentRank = nextRank = maxRank;\r\n } else {\r\n const remainingRanks = props.ranks.filter(r => r.startingXp > currentXp);\r\n nextRank = remainingRanks[0];\r\n currentRank = props.ranks[props.ranks.indexOf(nextRank) - 1];\r\n }\r\n\r\n return [ currentRank, nextRank, maxRank, ];\r\n }, [props.ranks, props.currentXp]);\r\n\r\n const percentageValue: React.ReactElement = (\r\n \r\n { (percentage * 100).toFixed(2) }%\r\n \r\n { props.currentXp.toLocaleString() } XP / { maxLevel.startingXp.toLocaleString() } XP\r\n \r\n \r\n );\r\n\r\n return (\r\n
\r\n
\r\n \r\n { percentage >= .5 ? percentageValue : null }\r\n
\r\n \r\n { percentage < .5 ? percentageValue : null }\r\n
\r\n
\r\n
\r\n
\r\n Current Rank: { currentLevel.rankNumber } ({ currentLevel.startingXp.toLocaleString() } XP)\r\n
\r\n
\r\n Next Rank: { nextLevel.rankNumber } ({ nextLevel.startingXp.toLocaleString() } XP)\r\n
\r\n
\r\n Max Rank: { maxLevel.rankNumber } ({ maxLevel.startingXp.toLocaleString() } XP)\r\n
\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default ProgressBar;\r\n","import { faFacebook, faReddit, faTwitter } from \"@fortawesome/free-brands-svg-icons\";\r\nimport { faEnvelope } from \"@fortawesome/pro-solid-svg-icons\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport { FunctionComponent } from \"react\";\r\nimport { analytics } from \"../../../../utilities\";\r\n\r\nexport interface ShareProps { }\r\n\r\nexport const Share: FunctionComponent = (props) => {\r\n const url = document.location.toString();\r\n const text = \"Follow my progress towards Spartan Rank 152 in Halo 5: Guardians.\";\r\n const windowSize = \"width=550,height=420\";\r\n const trackButtonClick = (platform: string) => analytics.trackEvent(\"share-clicked\", { platform, })\r\n const shareToFacebook = () => {\r\n trackButtonClick(\"facebook\");\r\n window.open(`https://facebook.com/sharer.php?u=${encodeURIComponent(url)}&p=${encodeURIComponent(text)}`, \"_blank\", windowSize);\r\n };\r\n const shareToTwitter = () => {\r\n trackButtonClick(\"twitter\");\r\n window.open(`https://twitter.com/share?method=share&url=${encodeURIComponent(url)}&text=${encodeURIComponent(text)}`, \"_blank\", windowSize);\r\n };\r\n const shareToReddit = () => {\r\n trackButtonClick(\"reddit\");\r\n window.open(`https://reddit.com/submit?url=${encodeURIComponent(url)}&title=${encodeURIComponent(text)}`);\r\n };\r\n const shareToEmail = () => {\r\n trackButtonClick(\"email\");\r\n window.open(`mailto:?subject=<${text}&body=${url}`, \"_blank\", windowSize);\r\n };\r\n\r\n return (\r\n
\r\n \r\n Share\r\n \r\n
\r\n
\r\n shareToFacebook()}\r\n className=\"btn btn-sm btn-outline-secondary\"\r\n title=\"Share to Facebook\"\r\n >\r\n \r\n \r\n shareToTwitter()}\r\n className=\"btn btn-sm btn-outline-secondary\"\r\n title=\"Share to Twitter\"\r\n >\r\n \r\n \r\n shareToReddit()}\r\n className=\"btn btn-sm btn-outline-secondary\"\r\n title=\"Share to Reddit\"\r\n >\r\n \r\n \r\n shareToEmail()}\r\n className=\"btn btn-sm btn-outline-secondary\"\r\n title=\"Share to Email\"\r\n >\r\n \r\n \r\n
\r\n
\r\n )\r\n}\r\n\r\nexport default Share;\r\n","import React from \"react\";\r\nimport { ImageService } from \"../../../../services\";\r\n\r\nexport interface SpartanImageProps {\r\n gamertag: string;\r\n}\r\n\r\nexport const SpartanImage: React.FunctionComponent = (props) => {\r\n return (\r\n \r\n );\r\n}\r\n\r\nexport default SpartanImage;\r\n","import React, { useEffect } from \"react\";\r\nimport config from \"../../../config\";\r\nimport { Match, Rank, Spartan } from \"../../../models\";\r\nimport { SearchHistoryService } from \"../../../services\";\r\nimport { dateUtility, pageUtility } from \"../../../utilities\";\r\nimport LatestMatch from \"./LatestMatch/LatestMatch\";\r\nimport PlayerName from \"./PlayerName/PlayerName\";\r\nimport PlayerStats from \"./PlayerStats/PlayerStats\";\r\nimport ProgressBar from \"./ProgressBar/ProgressBar\";\r\nimport Share from \"./Share/Share\";\r\nimport SpartanImage from \"./SpartanImage/SpartanImage\";\r\n\r\nexport interface PlayerProps {\r\n ranks: Rank[];\r\n spartan: Spartan;\r\n latestMatch: Match;\r\n}\r\n\r\nexport const Player: React.FunctionComponent = (props) => {\r\n useEffect(() => {\r\n pageUtility.titlePage(`Spartan ${props.spartan?.gamertag}`);\r\n SearchHistoryService.publish(props.spartan?.gamertag, props.spartan?.serviceTag);\r\n }, []);\r\n\r\n return (\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n Quick Stats\r\n \r\n
\r\n window.document.getElementsByClassName(\"medals-component\")[0].scrollIntoView() }\r\n >\r\n View Medals\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n Last Updated: {props.spartan.lastModified.toLocaleString()}\r\n \r\n \r\n Stats are updated every {dateUtility.formatDateLong(config.cacheTime)}\r\n \r\n
\r\n
\r\n
\r\n

\r\n *Stats are linear estimations based on previous match data; they represent no guarantee and may be impacted by changes to the players preformance, the current player population, and use of XP boosters.\r\n

\r\n
\r\n
\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default Player;","import { faUserLock } from \"@fortawesome/pro-duotone-svg-icons\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport React, { useEffect } from \"react\";\r\nimport { pageUtility } from \"../../../utilities\";\r\n\r\nexport interface PlayerNotFoundProps {\r\n gamertag: string;\r\n}\r\n\r\nexport const PlayerNotFound: React.FunctionComponent = (props) => {\r\n useEffect(() => {\r\n pageUtility.titlePage(\"Player Not Found\");\r\n }, []);\r\n\r\n return (\r\n
\r\n
\r\n
\r\n
\r\n \r\n

\r\n Record Not Found\r\n

\r\n

\r\n \r\n The specified Spartan was not found.\r\n \r\n

\r\n

\r\n “Spartans never die. They're just missing in action.”\r\n

\r\n
\r\n
\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default PlayerNotFound;","import React, { useEffect, useState } from \"react\";\r\nimport { useParams } from \"react-router-dom\";\r\nimport { Match, Rank, Spartan } from \"../../models\";\r\nimport { MatchService, RankService, SpartanService, ToastService } from \"../../services\";\r\nimport Loading from \"../Loading/Loading\";\r\nimport Player from \"./Player/Player\";\r\nimport PlayerNotFound from \"./PlayerNotFound/PlayerNotFound\";\r\n\r\nexport interface SpartanProps { }\r\n\r\nexport const App: React.FunctionComponent = (props) => {\r\n const { gamertag } = useParams<{ gamertag: string; }>();\r\n const [isLoading, setIsLoading] = useState(true);\r\n const [ranks, setRanks] = useState();\r\n const [spartan, setSpartan] = useState();\r\n const [latestMatch, setLatestMatch] = useState();\r\n\r\n useEffect(() => {\r\n const latestMatch = Promise.resolve()\r\n .then(() => gamertag ? MatchService.getLatestMatch(gamertag) : null)\r\n .then(match => setLatestMatch(match))\r\n .catch(error => ToastService.toast(\"danger\", \"An error occured retrieving previous match data from the server.\", \"Match Lookup Error\", 10000))\r\n\r\n Promise.resolve()\r\n .then(() => setIsLoading(true))\r\n .then(() => {\r\n setSpartan(null);\r\n setLatestMatch(null);\r\n })\r\n .then(() => !ranks ? RankService.getAll() : null)\r\n .then(ranks => ranks ? setRanks(ranks) : null)\r\n .then(() => gamertag ? SpartanService.getSpartan(gamertag) : null)\r\n .then(spartan => setSpartan(spartan))\r\n .then(() => latestMatch)\r\n .catch(error => ToastService.toast(\"danger\", \"An error occured retrieving spartan information from the server.\", \"Spartan Lookup Error\", 10000))\r\n .finally(() => setIsLoading(false));\r\n }, [gamertag]);\r\n\r\n let component: React.ReactElement;\r\n if (isLoading) {\r\n component = ();\r\n } else if (spartan) {\r\n component = (\r\n \r\n );\r\n } else {\r\n component = (\r\n \r\n );\r\n }\r\n\r\n return (\r\n
\r\n { component }\r\n
\r\n );\r\n}\r\n\r\nexport default App;\r\n","import { FunctionComponent } from \"react\";\r\nimport \"./TermsAndConditions.scss\";\r\n\r\nexport interface PrivacyProps { }\r\n\r\nexport const Privacy: FunctionComponent = (props) => {\r\n return (\r\n
\r\n

Terms and Conditions

\r\n

\r\n Effective November 2021\r\n

\r\n\r\n

\r\n Agreement between User and Lod Softworks LLC\r\n

\r\n

\r\n Welcome to SR152. The SR152 website (the \"Site\") is comprised of various web pages operated by Lod Softworks LLC.\r\n SR152 is offered to you conditioned on your acceptance without modification of the terms, conditions, and notices contained herein (the \"Terms\").\r\n Your use of SR152 constitutes your agreement to all such Terms. Please read these terms carefully, and keep a copy of them for your reference.\r\n

\r\n\r\n

SR152 is an Gaming Assistant.

\r\n

\r\n We provide the client with online tools for tracking progress within Halo 5: Guardians.\r\n Services provided come without any guarantee or warranty.\r\n Statistical information is estimated and does not provide any form of guarantee.\r\n

\r\n\r\n

Privacy

\r\n

\r\n Your use of SR152 is subject to Lod Softworks LLC's Privacy Policy.\r\n Please review our Privacy Policy, which also governs the Site and informs users of our data collection practices.\r\n

\r\n\r\n

Electronic Communications

\r\n

\r\n Visiting SR152 or sending emails to Lod Softworks LLC constitutes electronic communications.\r\n You consent to receive electronic communications and you agree that all agreements, notices, disclosures and other communications\r\n that we provide to you electronically, via email and on the Site, satisfy any legal requirement that such communications be in writing.\r\n

\r\n\r\n

Children Under Thirteen

\r\n

\r\n Lod Softworks LLC does not knowingly collect, either online or offline, personal information from persons under the age of thirteen.\r\n If you are under 18, you may use SR152 only with permission of a parent or guardian.\r\n

\r\n\r\n

Links to Third Party Sites/Third Party Services

\r\n

\r\n SR152 may contain links to other websites (\"Linked Sites\").\r\n The Linked Sites are not under the control of Lod Softworks LLC and Lod Softworks LLC is not responsible for the contents of any Linked Site,\r\n including without limitation any link contained in a Linked Site, or any changes or updates to a Linked Site.\r\n Lod Softworks LLC is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement by\r\n Lod Softworks LLC of the site or any association with its operators.\r\n

\r\n

\r\n Certain services made available via SR152 are delivered by third party sites and organizations.\r\n By using any product, service or functionality originating from the SR152 domain, you hereby acknowledge and consent\r\n that Lod Softworks LLC may share such information and data with any third party with whom Lod Softworks LLC has a contractual\r\n relationship to provide the requested product, service or functionality on behalf of SR152 users and customers.\r\n

\r\n\r\n

No Unlawful or Prohibited Use/Intellectual Property

\r\n

\r\n You are granted a non-exclusive, non-transferable, revocable license to access and use SR152 strictly in accordance with these terms of use.\r\n As a condition of your use of the Site, you warrant to Lod Softworks LLC that you will not use the Site for any purpose that is unlawful\r\n or prohibited by these Terms. You may not use the Site in any manner which could damage, disable, overburden, or impair the Site or interfere\r\n with any other party's use and enjoyment of the Site. You may not obtain or attempt to obtain any materials or information through any means not\r\n intentionally made available or provided for through the Site.\r\n

\r\n

\r\n All content included as part of the Service, such as text, graphics, logos, images, as well as the compilation thereof, and any software used on the Site,\r\n is the property of Lod Softworks LLC or its suppliers and protected by copyright and other laws that protect intellectual property and proprietary rights.\r\n You agree to observe and abide by all copyright and other proprietary notices, legends, or other restrictions contained in any such content and will not\r\n make any changes thereto.\r\n

\r\n

\r\n You will not modify, publish, transmit, reverse engineer, participate in the transfer or sale, create derivative works,\r\n or in any way exploit any of the content, in whole or in part, found on the Site. Lod Softworks LLC content is not for resale.\r\n Your use of the Site does not entitle you to make any unauthorized use of any protected content, and in particular, you will not delete or\r\n alter any proprietary rights or attribution notices in any content. You will use protected content solely for your personal use and will\r\n make no other use of the content without the express written permission of Lod Softworks LLC and the copyright owner.\r\n You agree that you do not acquire any ownership rights in any protected content.\r\n We do not grant you any licenses, express or implied, to the intellectual property of Lod Softworks LLC or our licensors except as expressly\r\n authorized by these Terms.\r\n

\r\n\r\n

Third-Party Accounts

\r\n

\r\n You will be able to connect your Lod Softworks LLC account to third party accounts.\r\n By connecting your Lod Softworks LLC account to your third party account, you acknowledge and agree that you are consenting\r\n to the continuous release of information about you to others (in accordance with your privacy settings on those third party sites).\r\n If you do not want information about yourself to be shared in this manner, do not use this feature.\r\n

\r\n\r\n

International Users

\r\n

\r\n The Service is controlled, operated and administered by Lod Softworks LLC from our offices within the USA.\r\n If you access the Service from a location outside the USA, you are responsible for compliance with all local laws.\r\n You agree that you will not use the Lod Softworks LLC Content accessed through SR152 in any country or in any manner\r\n prohibited by any applicable laws, restrictions or regulations.\r\n

\r\n\r\n

Indemnification

\r\n

\r\n You agree to indemnify, defend and hold harmless Lod Softworks LLC, its officers, directors, employees, agents and third parties,\r\n for any losses, costs, liabilities and expenses (including reasonable attorney's fees) relating to or arising out of your use of or inability\r\n to use the Site or services, any user postings made by you, your violation of any terms of this Agreement or your violation of any rights of\r\n a third party, or your violation of any applicable laws, rules or regulations. Lod Softworks LLC reserves the right, at its own cost, to\r\n assume the exclusive defense and control of any matter otherwise subject to indemnification by you, in which event you will fully cooperate\r\n with Lod Softworks LLC in asserting any available defenses.\r\n

\r\n\r\n

Arbitration

\r\n

\r\n In the event the parties are not able to resolve any dispute between them arising out of or concerning these Terms and Conditions,\r\n or any provisions hereof, whether in contract, tort, or otherwise at law or in equity for damages or any other relief, then such dispute\r\n shall be resolved only by final and binding arbitration pursuant to the Federal Arbitration Act, conducted by a single neutral arbitrator\r\n and administered by the American Arbitration Association, or a similar arbitration service selected by the parties, in a location mutually\r\n agreed upon by the parties. The arbitrator's award shall be final, and judgment may be entered upon it in any court having jurisdiction.\r\n In the event that any legal or equitable action, proceeding, or arbitration arises out of or concerns these Terms and Conditions, the\r\n prevailing party shall be entitled to recover its costs and reasonable attorney's fees. The parties agree to arbitrate all disputes and\r\n claims in regards to these Terms and Conditions or any disputes arising as a result of these Terms and Conditions, whether directly or\r\n indirectly, including Tort claims that are a result of these Terms and Conditions. The parties agree that the Federal Arbitration Act governs\r\n the interpretation and enforcement of this provision. The entire dispute, including the scope and enforceability of this arbitration provision,\r\n shall be determined by the Arbitrator. This arbitration provision shall survive the termination of these Terms and Conditions.\r\n

\r\n\r\n

Class Action Waiver

\r\n

\r\n Any arbitration under these Terms and Conditions will take place on an individual basis; class arbitrations and class/representative/collective actions are not permitted. THE PARTIES AGREE THAT A PARTY MAY BRING CLAIMS AGAINST THE OTHER ONLY IN EACH'S INDIVIDUAL CAPACITY, AND NOT AS A PLAINTIFF OR CLASS MEMBER IN ANY PUTATIVE CLASS, COLLECTIVE AND/ OR REPRESENTATIVE PROCEEDING, SUCH AS IN THE FORM OF A PRIVATE ATTORNEY GENERAL ACTION AGAINST THE OTHER. Further, unless both you and Lod Softworks LLC agree otherwise, the arbitrator may not consolidate more than one person's claims, and may not otherwise preside over any form of a representative or class proceeding.\r\n

\r\n\r\n

Liability Disclaimer

\r\n

\r\n THE INFORMATION, SOFTWARE, PRODUCTS, AND SERVICES INCLUDED IN OR AVAILABLE THROUGH THE SITE MAY INCLUDE INACCURACIES OR TYPOGRAPHICAL ERRORS.\r\n CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION HEREIN. LOD SOFTWORKS LLC AND/OR ITS SUPPLIERS MAY MAKE IMPROVEMENTS AND/OR CHANGES IN THE SITE AT ANY TIME.\r\n

\r\n

\r\n LOD SOFTWORKS LLC AND/OR ITS SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY, RELIABILITY, AVAILABILITY, TIMELINESS, AND ACCURACY OF THE INFORMATION,\r\n SOFTWARE, PRODUCTS, SERVICES AND RELATED GRAPHICS CONTAINED ON THE SITE FOR ANY PURPOSE. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, ALL SUCH INFORMATION,\r\n SOFTWARE, PRODUCTS, SERVICES AND RELATED GRAPHICS ARE PROVIDED \"AS IS\" WITHOUT WARRANTY OR CONDITION OF ANY KIND. LOD SOFTWORKS LLC AND/OR ITS SUPPLIERS HEREBY\r\n DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THIS INFORMATION, SOFTWARE, PRODUCTS, SERVICES AND RELATED GRAPHICS, INCLUDING ALL IMPLIED WARRANTIES OR\r\n CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT.\r\n

\r\n

\r\n TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL LOD SOFTWORKS LLC AND/OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, PUNITIVE,\r\n INCIDENTAL, SPECIAL, CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF USE, DATA OR PROFITS, ARISING OUT\r\n OF OR IN ANY WAY CONNECTED WITH THE USE OR PERFORMANCE OF THE SITE, WITH THE DELAY OR INABILITY TO USE THE SITE OR RELATED SERVICES, THE PROVISION OF OR\r\n FAILURE TO PROVIDE SERVICES, OR FOR ANY INFORMATION, SOFTWARE, PRODUCTS, SERVICES AND RELATED GRAPHICS OBTAINED THROUGH THE SITE, OR OTHERWISE ARISING OUT\r\n OF THE USE OF THE SITE, WHETHER BASED ON CONTRACT, TORT, NEGLIGENCE, STRICT LIABILITY OR OTHERWISE, EVEN IF LOD SOFTWORKS LLC OR ANY OF ITS SUPPLIERS HAS\r\n BEEN ADVISED OF THE POSSIBILITY OF DAMAGES. BECAUSE SOME STATES/JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR\r\n INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU. IF YOU ARE DISSATISFIED WITH ANY PORTION OF THE SITE, OR WITH ANY OF THESE TERMS OF USE,\r\n YOUR SOLE AND EXCLUSIVE REMEDY IS TO DISCONTINUE USING THE SITE.\r\n

\r\n\r\n

Termination/Access Restriction

\r\n

\r\n Lod Softworks LLC reserves the right, in its sole discretion, to terminate your access to the Site and the related services or any portion thereof at any time,\r\n without notice. To the maximum extent permitted by law, this agreement is governed by the laws of the State of Utah and you hereby consent to the exclusive\r\n jurisdiction and venue of courts in Utah in all disputes arising out of or relating to the use of the Site. Use of the Site is unauthorized in any jurisdiction\r\n that does not give effect to all provisions of these Terms, including, without limitation, this section.\r\n

\r\n

\r\n You agree that no joint venture, partnership, employment, or agency relationship exists between you and Lod Softworks LLC as a result of this agreement or use\r\n of the Site. Lod Softworks LLC's performance of this agreement is subject to existing laws and legal processes, and nothing contained in this agreement is in\r\n derogation of Lod Softworks LLC's right to comply with governmental, court, and law enforcement requests or requirements relating to your use of the Site or\r\n information provided to or gathered by Lod Softworks LLC with respect to such use. If any part of this agreement is determined to be invalid or unenforceable\r\n pursuant to applicable law including, but not limited to, the warranty disclaimers and liability limitations set forth above, then the invalid or unenforceable provision will be deemed superseded by a valid, enforceable provision that most closely matches the intent of the original provision and the remainder of the agreement shall continue in effect.\r\n

\r\n

\r\n Unless otherwise specified herein, this agreement constitutes the entire agreement between the user and Lod Softworks LLC with respect to the Site and it\r\n supersedes all prior or contemporaneous communications and proposals, whether electronic, oral or written, between the user and Lod Softworks LLC with\r\n respect to the Site. A printed version of this agreement and of any notice given in electronic form shall be admissible in judicial or administrative\r\n proceedings based upon or relating to this agreement to the same extent and subject to the same conditions as other business documents and records originally\r\n generated and maintained in printed form. It is the express wish to the parties that this agreement and all related documents be written in English.\r\n

\r\n\r\n

Changes to Terms

\r\n

\r\n Lod Softworks LLC reserves the right, in its sole discretion, to change the Terms under which SR152 is offered.\r\n The most current version of the Terms will supersede all previous versions. Lod Softworks LLC encourages you to periodically review the Terms to stay\r\n informed of our updates.\r\n

\r\n\r\n

Contact Us

\r\n

\r\n Lod Softworks LLC welcomes your questions or comments regarding the Terms via email to support@sr152.app.\r\n

\r\n
\r\n );\r\n}\r\n\r\nexport default Privacy;\r\n","import { faBullseye, faClock, faMedal } from \"@fortawesome/pro-duotone-svg-icons\";\r\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\r\nimport React from \"react\";\r\nimport { ImageService } from \"../../services\";\r\n\r\nexport interface WelcomeProps { }\r\n\r\nexport const Welcome: React.FunctionComponent = (props) => {\r\n return (\r\n
\r\n
\r\n
\r\n
\r\n
\r\n

\r\n It's time to rank up Spartan!\r\n

\r\n
\r\n Spartan Rank 152 is a long grind.\r\n Get estimates on how long you'll have to play, how many wins you'll need, how much damage you'll have to deal, and more until you reach max rank in Halo 5: Guardians.\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n

\r\n Rank Up Easier\r\n

\r\n
\r\n Get fun metric estimates on your progression towards Spartan Rank 152.\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
Time
\r\n
\r\n How many weeks, days, hours, and minutes you'll have to play.\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
Wins
\r\n
\r\n How many remaining games you'll have to play, and how many wins and losses you'll likely see.\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
Kills
\r\n
\r\n How many kills, deaths, and assists and more until SR152.\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n

\r\n Carry your prestige into Halo Infinite\r\n

\r\n

\r\n While reaching Spartan Rank 152 rewards you with the Inheritor Requisition Pack and the exclusive Mantle emblem in Halo 5,\r\n your prestige can carry forward to Halo Infinite with the Watchdog armor and weapon coatings, exclusive to players who\r\n reach Spartan Rank 152 in Halo 5: Guardians!\r\n

\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n );\r\n}\r\n\r\nexport default Welcome;\r\n","import { FunctionComponent, useMemo } from \"react\";\r\nimport { HelmetProvider } from \"react-helmet-async\";\r\nimport { BrowserRouter as Router, Route, Switch } from \"react-router-dom\";\r\nimport { AppInfo, PageInfo } from \"../models\";\r\nimport pageInfo from \"../pages\";\r\nimport About from \"./About/About\";\r\nimport Feedback from \"./Feedback/Feedback\";\r\nimport usePageLayout from \"./Layout/Layout\";\r\nimport Legal from \"./Legal/Legal\";\r\nimport Ranks from \"./Ranks/Ranks\";\r\nimport Spartan from \"./Spartan/Spartan\";\r\nimport TermsAndConditions from \"./TermsAndConditions/TermsAndConditions\";\r\nimport Welcome from \"./Welcome/Welcome\";\r\n\r\ntype Pages = {\r\n [key: string]: PageInfo;\r\n}\r\n\r\nexport interface AppProps { }\r\n\r\nexport const App: FunctionComponent = (props) => {\r\n const appInfo: AppInfo = new AppInfo({pageInfo});\r\n const pages: Pages = useMemo(() => {\r\n const pages: Pages = {};\r\n for (let pageInfo of appInfo.pageInfo) {\r\n pages[pageInfo.path] = pageInfo;\r\n }\r\n return pages;\r\n }, []);\r\n const defaultPage = pages[\"/\"];\r\n \r\n return (\r\n
\r\n \r\n \r\n \r\n \r\n {usePageLayout(About, {\r\n pageInfo: pages[\"/about\"] || defaultPage,\r\n })}\r\n \r\n \r\n {usePageLayout(Feedback, {\r\n pageInfo: pages[\"/feedback\"] || defaultPage,\r\n })}\r\n \r\n \r\n {usePageLayout(Legal, {\r\n pageInfo: pages[\"/legal\"] || defaultPage,\r\n })}\r\n \r\n \r\n {usePageLayout(TermsAndConditions, {\r\n pageInfo: pages[\"/terms-and-conditions\"] || defaultPage,\r\n })}\r\n \r\n \r\n {usePageLayout(Ranks, {\r\n pageInfo: pages[\"/ranks\"] || defaultPage,\r\n })}\r\n \r\n \r\n {usePageLayout(Spartan, {\r\n pageInfo: pages[\"/spartan\"] || defaultPage,\r\n })}\r\n \r\n \r\n {usePageLayout(Welcome, {\r\n pageInfo: pages[\"/\"] || defaultPage,\r\n noPadding: true,\r\n })}\r\n \r\n \r\n \r\n \r\n
\r\n );\r\n}\r\n\r\nexport default App;\r\n","const reportWebVitals = onPerfEntry => {\r\n if (onPerfEntry && onPerfEntry instanceof Function) {\r\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\r\n getCLS(onPerfEntry);\r\n getFID(onPerfEntry);\r\n getFCP(onPerfEntry);\r\n getLCP(onPerfEntry);\r\n getTTFB(onPerfEntry);\r\n });\r\n }\r\n};\r\n\r\nexport default reportWebVitals;\r\n","import \"bootstrap/dist/css/bootstrap.min.css\";\r\nimport { StrictMode } from \"react\";\r\nimport { render } from \"react-snapshot\";\r\nimport App from \"./components/App\";\r\nimport \"./index.scss\";\r\nimport \"./polyfill\";\r\nimport reportWebVitals from \"./reportWebVitals\";\r\n\r\nrender(\r\n \r\n \r\n ,\r\n document.getElementById(\"root\")\r\n);\r\n\r\n// If you want to start measuring performance in your app, pass a function\r\n// to log results (for example: reportWebVitals(console.log))\r\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\r\nreportWebVitals();\r\n"],"sourceRoot":""}