diff --git a/.eslintrc b/.eslintrc index df6f2def08..2fdaa5901f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -73,6 +73,7 @@ "prefer-const": ["error", { "destructuring": "all" }], + "radix": ["error", "as-needed"], "react/display-name": "off", "react/jsx-key": "off", "react/no-unescaped-entities": "off", diff --git a/TODO b/TODO index a8ae04fb41..28e4874837 100644 --- a/TODO +++ b/TODO @@ -1,21 +1,75 @@ -family tree https://mail.google.com/mail/u/0/#inbox/FMfcgzGllVlFGjtRhqBSxzzZsfpFXwpl +add way to play without salary cap +- https://old.reddit.com/r/BasketballGM/comments/rlbbby/creating_a_league_with_high_salary_cap_makes_the/hpfp3zb/?context=3 +- unify setting with hardCap? +add option to disable salary cap @hrmantovani#2284 +- historical leagues +- merge with hard cap setting +- salary cap value is still inflation + +minors +- add "type" property to stats row, could be playoffs, minors, or undefind (regular season) + - or, add a "minors" flag? + - same idea for regularSeason and playoffs flags in playersPlus +- configurable # of slots. default 0 +- at the end of every day, assemble random teams of players in the minors and sim minors games + - always keep same (pro) team together? + - position balance needed for hockey/football? +- should minors lead to improvement? make it configurable, but default no +- need anything special with contracts? + +sticky first column in most tables +- https://github.com/twbs/bootstrap/issues/31458 +- -on mobile, padding not being added to bottom of page when ad is shown? +TR doesn’t switch to playoffs TR when switching to it on the roster screen https://discord.com/channels/290013534023057409/290015591216054273/930604919973609523 -have "watch" as action in schedule page for playoff games too https://discord.com/channels/290013534023057409/331882115119448065/904946069727748106 +no awards if 0 games in regular season? https://discord.com/channels/290013534023057409/331882115119448065/930867153878544454 -way to tell getCopy we are not going to mutate, so don't need deepcopy -- noCopyCache -- in progress - - benchmark +more goalie injuries? https://discord.com/channels/@me/926178075614523402/930545643578081320 -half the distance to the goal should also happen for offensive penalties, except pass interference https://mail.google.com/mail/u/0/#inbox/FMfcgzGllMLKdrcDDZTrvJDDlgkNBFTl +dramatic reveal of awards and award voting results, similar to draft lottery -performance on FA page https://discord.com/channels/290013534023057409/290013534023057409/919493773224972348 +offsetting penalties broken on kickoff https://discord.com/channels/290013534023057409/290015591216054273/929998618331590667 -mobile zoom issue -- https://discord.com/channels/290013534023057409/290015591216054273/918908074251653202 -- The white space thing only shows up (atleast I'm pretty sure) on the roster page, for me whenever I click on the three bar things that shows the people's stats, zoom out, or releasing players it shows up. https://discord.com/channels/290013534023057409/569726303926878219/918742921736519710 +on team history, graph of team ovr / winp / mov over time, star for championship +- maybe better on league history, to show for whole league? + +manually specify draft order in god mode +- make draft page drag-and-drop, with purple handles + +new achievements +- force challenge mode to remain on + +hockey ovr revamp +- ovrs for skater and goalie. determine skater positions like BBGM, including possibility of hybrid positions like F. cause there's really a fair amount of overlap in what players do + +more season preview stuff +- top rookies +- top free agent signings +- ...1 more needed + - top young players? kind of redundant + +for some fbgm penalties, don't allow the ball carrier to be called + +soccer-style team names +- implementation + - add two field allongside abbrev/region/name - customMedium and customLong + - customMedium is a medium length name. if undefined, Region is used. could be defined to disambiguate two teams in the same reason, like "LA Earthquakes" and "LA Lowriders" + - customLong is a long name. if undefined, Region Name is used. could be defined to have european-style team names + - ...this still results in weird situations, like not knowing how to use the medium name in a sentence since it might be the city or it might be the team name, like is it plural or not? +- usually process in UI. maybe will need some in worker, like for notifications +- add to teamsPlus? +- @Ra98 + +getCopy/getCopies dry +- rename to idb.get/idb.getAll +- share code +- any place that uses this conditionally vs cache.get/getAll, use just getCopy and make sure it's no slower + - lookup of single primary key (such as season or xid) should look in cache first and short circuit if found there + +fbgm edge cases +- half the distance to the goal should also happen for offensive penalties, except pass interference https://mail.google.com/mail/u/0/#inbox/FMfcgzGllMLKdrcDDZTrvJDDlgkNBFTl +- defensive penalty on last possession of half/OT - should have one untimed down https://mail.google.com/mail/u/0/#inbox/FMfcgzGllVnWKrWXjxwNNXWTqsncqjNq QB throw a Interception but their were two offsetting penalties so the down was replayed but it still counted the INT to the Stats. So the Safety still got credit for a pick https://discord.com/channels/290013534023057409/290015591216054273/917134502336270396 @@ -50,8 +104,6 @@ add some way to auto find team colors based on logo use ovrStart/ovrEnd on power rankings page? - show change from beginning of season or last season? -on team history, graph of team ovr and winp over time, star for championship - fix applying penalties on xp/2pt - store scrimmage of 2pt, then xp is offset from that - wouldn't work for defensive penalties @@ -85,10 +137,6 @@ all-star snubs https://old.reddit.com/r/BasketballGM/comments/q53xkk/a_lil_featu better handle case where cannot play a game (like during contract negotiation) and player tries to live sim https://mail.google.com/mail/u/0/#all/FMfcgzGlkXrSgFVLkrnbVTGLQRjCHPDr -get rid of iterate() now that we don't need to support firefox 60. or at least refactor some of it - -other firefox comments - refactor FBGM play by play logging - move text generation client side, like hockey - typescript for log function @@ -134,8 +182,6 @@ nicidob improve value formula - https://discord.com/channels/290013534023057409/290015591216054273/891394602207174656 - https://discord.com/channels/290013534023057409/290015468939640832/893115141015625779 -"May have found a small bug (Chrome), when you update a players rating, then attempt to update him to a retired jersey number, it throws the retired jersey error. after you change the jersey number, the rating change shows, but the listed OVR doesn't change to what's reflected in the edit page" https://discord.com/channels/290013534023057409/290015591216054273/893175557410406440 - more dramatic play-by-play - pass attempt and description before result - fg attempt before result @@ -153,10 +199,6 @@ improve table column filtering - how to handle mixing with OR? - parentheses to group operations -More specific achievements, that are really more like challenges -- https://mail.google.com/mail/u/0/?pli=1#inbox/FMfcgzGkZsqLfGwBbsHhbdJVDcVTSgbX -- Win a championship as a play-in team https://discord.com/channels/290013534023057409/331882115119448065/889311847977730089 - better adjustment for real draft prospects don't use positions in substitution, or be less rigid about it https://discord.com/channels/@me/667557235479674880 @@ -208,16 +250,6 @@ schedule customization - how to define when a set of matchups is as good as we can do? generate a bunch and keep the best scoring one? - option to make the settings like "# games vs each division opponent" if someone wants that behavior for a league where divisions are not equal size -minors -- add "type" property to stats row, could be playoffs, minors, or undefind (regular season) - - or, add a "minors" flag? - - same idea for regularSeason and playoffs flags in playersPlus -- configurable # of slots. default 0 -- at the end of every day, assemble random teams of players in the minors and sim minors games - - always keep same (pro) team together? -- should minors lead to improvement? make it configurable, but default no -- need anything special with contracts? - frivolities - players - Best/Worst MVP, DPOY, ROY, 6MOY, MIP https://old.reddit.com/r/BasketballGM/comments/ovhv1i/monthly_suggestions_thread/h7iovrv/ @@ -250,14 +282,6 @@ all advanced stats have always disregarded the previous team's stats for traded Fix hardcoded 90000 in attendance.ts and writeTeamStats.ts -ability to specify default settings -- on global settings page -- ability to select individual settings from a dropdown to add -- ability to delete individual setting (go back to default) -- includes goat formula -- explain that it doens't override when a custom league file or historical league includes a value for a setting -- import/export default settings - injuries - make more representative of football: https://footballplayershealth.harvard.edu/wp-content/uploads/2017/05/06_Ch2_Injuries.pdf - https://discord.com/channels/290013534023057409/290015468939640832/859264726247800832 @@ -334,8 +358,6 @@ fbgm trade rate the better way to make FA more detailed but still simple would be to replace the "Sign" button with a "bid" button. And have FAs only take deals after you simulate forward a day. Allow teams to make deals that are +5 or +10 or +15% larger or smaller in the negotiate page, to make their chances of the FA signing with them better/worse. The get rid of the "player won't sign with you" thing. Just show a "chance of signing" given a certain size of deal https://discord.com/channels/290013534023057409/331882115119448065/846534950101843969 -teams shouldn't offer nothing on trading block - bundle size - defer - react-select @@ -485,8 +507,6 @@ head to head records - list statisitical feats between teams - link here from head2head and head2head_all -auto adjust ticket price for playoffs https://old.reddit.com/r/BasketballGM/comments/ko1zy7/monthly_suggestions_thread/ghykfvs/ - free agents should be more willing to sign with teams that overpay - https://old.reddit.com/r/BasketballGM/comments/lccu22/observation_from_an_intermittent_player_free/ @@ -702,12 +722,6 @@ trade balancing - FBGM should not demand as much in 2 for 1 trades? https://discord.com/channels/@me/696164463312764949/776342790586105877 - https://old.reddit.com/r/BasketballGM/comments/k3339l/the_cpus_lack_of_value_for_draft_picks_is/ -soccer-style team names -- instead of region and name, it's short name and long name -- abstract any display of team name/region to handle this - - maybe in teamsPlus, have longName and shortName which check some option to see how to generate them -- @Ra98 - profit for extreme caps needs to be fixed first, its not possible to make money above $400m cap space during re-signing phase, should still show % everywhere except re-signing table. same with free agency, i think? @@ -861,8 +875,6 @@ rebuilding/contending in the old days https://old.reddit.com/r/BasketballGM/comm option to lock ratings for all players, including future players -FBGM make ratings improvements less correlated - built-in UI to load custom user files - UI in BBGM to create league - api to list league files @@ -1002,15 +1014,6 @@ way to save/load leagues on server - ideally would send data from IndexedDB to WritableStream to some HTTP API, but that doesn't seem supported - https://github.com/whatwg/fetch/issues/378 for the HTTP request, but also it's a problem with IDB auto closing transactions - so would need to read entire league file into memory first -god mode stuff -- more stuff on player editor -- edit list of deaths - -add option to disable salary cap @hrmantovani#2284 -- historical leagues -- merge with hard cap setting -- salary cap value is still inflation - FBGM - in FBGM, tags aren't generated for custom roster's draft classes until the end of the season. - rosters https://raw.githubusercontent.com/nicidob/bbgm/master/fbgm_roster_2019_sss.json @@ -1070,9 +1073,6 @@ eventually - what happens to scheduled event if the user changes something relevant to it prior to the event happening? does this matter? - show draft prospects separately when creating a new custom league, to allow creating one without them -manually specify draft order in god mode -- make draft page drag-and-drop, with purple handles - redo trade system - make it so that teams are less likely to trade for players when there is a better/ slightly worse player in FA for around the same price. people exploit that all the time - some factor based on # of recent trades (similar to player mood revamp?) @@ -1229,7 +1229,7 @@ Game list redesign - show ovr in box score too - show player with highest game score under completed game -nicidob - Something like "Team Hall of Fame" based on wins/MOV/playoff. And some way to see in-season MOV graphs, and multi-season MOV/Win%/PowerRanking +nicidob - Something like "Team Hall of Fame" based on wins/MOV/playoff probGoForIt should account for being down by a FG or less late in the game @@ -1316,7 +1316,6 @@ https://react-hook-form.com/ for forms more customize player options - fixed position -- hof - awards football roster balance issues https://imgur.com/HmK00EF @Eddy @@ -1337,10 +1336,6 @@ load file from url https://old.reddit.com/r/BasketballGM/comments/c54rov/automat - file sharing platforms are sources, but not destinations? - requires server side integration -in basketball gamesim -- if all ratings are 0, why does one player dominate? -- player with assist can be same as player who shoots - # football some gamesim issues @@ -1430,10 +1425,6 @@ how to get types working, options: - pass around overrides manually everywhere, not making it a module - move everything inside deion -how will deionUI(overrides) work with types? -- can pass them as generics, then apply them to factory functions -- Import modules from deion. Add things like extra views. Apply factories/generics. - type better - skills/compositeRatings - should be RatingsKey, not string for components. And PlayerRatings - PlayerStatType should be sport specific @@ -1446,8 +1437,6 @@ split more from deion - processInputs for views only in one sport (depth, shot locations) - worker API functions only in one sport (depth) -show game stats in player page - contract demands and position assignments should be based on which position maximizes p.value, not which position maximizes ovr. would you rather have an 80 ovr qb or a 100 ovr kicker? RatingsOverview - could put in deion, with config to specify categories and names from getCols @@ -1496,16 +1485,10 @@ BoxScoreRow Difficulty fudge factor should only be for user team (finances, trades) - for trades this is hard because valueChange does not know if it's the user's team or not, need to accept another parameter -re-evaluate contracts -- somehow market based - make AI smarter about contracts - then do cool shit, like a tunable "randomness" factor or something that lets you tune player development, and also overall talent level, and also distribution of different ratings (to sim different eras) - https://www.google.com/search?q=OOTP+player+generator+modifiers&client=ubuntu&hs=nzO&channel=fs&sxsrf=ALeKk03DAwxNZl2Io6A0PwDmnR3InA95_w:1612847896152&source=lnms&tbm=isch&sa=X&ved=2ahUKEwjc07TPhtzuAhXlUd8KHdfaB9kQ_AUoAnoECA8QBA&biw=1920&bih=869#imgrc=qKcVVE7ByPY6xM -increase PG cutoff -- https://www.reddit.com/r/BasketballGM/comments/8lfyuh/7_center_turns_into_pg_when_the_season_starts/ - index updating - currenty: check if the indexed property has changed, and only update a specific index then - would be better: make _dirtyIndexes per index, not per store @@ -1571,14 +1554,9 @@ add franchise leaders (stats) to team history page marker for feats from the playoffs/finals https://www.reddit.com/r/BasketballGM/comments/6gpf1f/suggestion_a_marker_of_some_sort_next_to_game/ -some way to see draft picks by team, now that there are AI trades - AI trades - notification? only for big trades. quantify! maybe show that info in transactions page too -AI propose trade to user -- need way to show popup with link to trade page - colors - color ratings on ratings page (and tables), just like ratings popup - color stats in ratings popover @@ -1619,7 +1597,6 @@ document cache data format and API! - all modifications go into cache - cache mutations are dangerous, see getCopy - read from just the cache if you're sure everything is there (like an active player). otherwise, read from db and augment with cache (because anything could be in cache, even if it's not normally.. like retired player added to watch list). getCopy variables do this -- promise microtask worker crap - for firefox support, if you start a backboard tx manually, you can't do any promise/asyncawait stuff inside the callback ---- @@ -1644,8 +1621,6 @@ REACT later Draft button on player pages https://www.reddit.com/r/BasketballGM/comments/53op85/feature_request/ Trade Away button on your own players -keep showing splash screen until first view hydrated - Draft make it cooler fantasy draft is hacky and glitchy - do better! @@ -1660,11 +1635,6 @@ filters on event log make positions edited in god mode sticky, like custom roster -different height distributions by country https://www.reddit.com/message/messages/644he7 - even global setting would be nice, for country specific leagues - -newScheduleCrappy should be better - substitutions fucked up in long games https://www.reddit.com/r/BasketballGM/comments/44nv0s/100000_minute_quarters/ more detailed negotiation screen https://www.reddit.com/r/BasketballGM/comments/416o5g/well_this_is_new/cz11w9v?context=3 @@ -1687,11 +1657,6 @@ fantasy draft summary https://www.reddit.com/r/BasketballGM/comments/3g4p5a/issu crime https://www.reddit.com/r/BasketballGM/comments/3g1ngn/its_2015/ctudznu -different jump to menus for season and team specific pages? - or unify - add gamelog, roster, team finances - get rid of "More:" links - minutes directly, not by +/- use positions for roster building and rotations @@ -1709,14 +1674,6 @@ use positions for roster building and rotations Make AI smarter when constructing teams. Then, if that works, make synergy more impactful -Too many 8 seeds winning over 1 seeds - http://www.reddit.com/r/BasketballGM/comments/39j6gy/this_happens_way_too_often/cs4lor3 - http://www.reddit.com/r/BasketballGM/comments/391et4/1v8_seed_theory_100_years_of_simulation/ - point differential stuff - BBGM teams seem better than NBA teams, but still lose in 8-1 (and have worse records) - some of this could be running up the score against bad teams - -playoff and regular season playing time and injury differences http://www.reddit.com/r/BasketballGM/comments/38f7dj/playoff_variance_seems_a_little_high/crxh643 - when retired, player page (and other career-level things) should display most common pos, or maybe composite that us union of all positions (like GF for someone who was both SG and SF) draftHistory, hallOfFame, player, playerStats (careerTotals), teamHistory, anything else? @@ -1731,15 +1688,6 @@ DEATH reset owner mood, new owner message https://old.reddit.com/r/BasketballGM/comments/m087u6/could_we_get_something_like_this_as_an_extremely/ -screenshot - what do i link to? Imgur landing page? or include social links directly? - include social links directly. actually that should be the first-level UI - you don't click "Screenshot" you click "Share to X" where X is Twitter, FB, Reddit, etc - probably still save to imgur first - autocomplete wording: "Draft players, manage teams, go for the championship. How good a Basketball GM are you? Find out at http://basketball-gm.com" - also autocomplete hashtag - add prompts to take screenshots at various points - things can get cut off right, like wide tables in player pages - composite ratings / scouting report "Shooting", "PG Skills", "Paint Scoring", rebounding are these ones really complicated enough to warrant display? @@ -1761,13 +1709,6 @@ transaction log player.updateValues.getStats doesn't really make sense. Should get all from past 2 seasons, sort by PSID, and take stats up to 2000 minutes -new achievements -- gold -- 100 year championship drought before winning another (cubs) -- win title without any 1st round picks @AtomicDelirium#1413 -- "On the edge" – Play 28 games in playoffs and win finals (4-3 in each series) -- Have more than 100 players who played most of their career on your team be HOF @Happy_McSmileyface#1538 - PLAYER DEVELOPMENT REVAMP ------------------------- @@ -1780,7 +1721,6 @@ TEAM.VALUECHANGE REVAMP https://www.reddit.com/r/BasketballGM/comments/585af3/the_trade_ai_is_too_easy_to_abuse/ http://www.reddit.com/r/BasketballGM/comments/2v26p1/how_are_you_exploiting_the_trade_ai/ -http://www.reddit.com/r/BasketballGM/comments/255sta/i_think_we_need_longer_dynasty_achievements/che050a?context=3 IMPORTANT http://www.reddit.com/r/BasketballGM/comments/20i6v3/still_too_easy_to_trade_for_drafted_players/ just drafted players are undervalued, possibly related to the following issue second round draft picks are undervalued. also, giving away a pick should never make a trade worse, but sometimes it does now. http://www.reddit.com/r/BasketballGM/comments/2bg3zx/simple_feature_mark_players_as_offlimits_when_we/cj5ap89 @@ -1805,8 +1745,6 @@ Eventually: CURRENT ------- -game log for individual player - in each box score, include an array of players in the game. index on that. great ideas: http://www.reddit.com/r/BasketballGM/comments/2q9yn8/ideas_questions_and_feedback_feel_free_to_add/ career ending "injuries" http://www.reddit.com/r/BasketballGM/comments/2oo32x/are_there_career_ending_injuries/ "My Career" page with GM stats across teams http://www.reddit.com/r/BasketballGM/comments/2gc4sf/gm_page/ @@ -1832,8 +1770,6 @@ show prospects before draft movement between draft classes allow promising to draft a player at certain position to influence decision career stats - "All Seasons" option - add each unique player/season combo as a row, include column for year - column/table widths? EWA in averages should be average same with per36 per36, totals, playoffs options elsewhere @@ -1862,7 +1798,6 @@ BIG NEW FEATURES ---------------- player stat summaries http://www.reddit.com/r/BasketballGM/comments/2bf4z0/functionality_of_the_game_vs_2k/cj5ir16 -trading block should allow for multiple (different) offers from the same team display of relative ratings like https://mail.google.com/mail/u/0/#inbox/144a4a04330edf3d trade improvements refactor trade module with all the below in mind @@ -1922,32 +1857,22 @@ MINOR FIXES documentation http://www.reddit.com/r/BasketballGM/comments/2agxoe/questions_and_suggestions_from_a_new_player/ Add MVP and Titles columns to HoF table -Make good young players much less likely to become FAs -don't need to store abbrev with awards, just tids - fix display in season summary (correct in historyAll) -show team records in playoffs page on team history, show counts of conf/league championships, hall of fame players, etc if a player refuses to resign, that decision should also be reflected in free agency (don't recalculate mood) add "drb" to usage so that good ball handlers shoot more (favor guards over bigs more) in player page, show red/green for ratings changes from the previous year, maybe as heatmap in ratings tables, show dpot and dovr columns? maybe? -league leaders glitch http://www.reddit.com/r/BasketballGM/comments/1r20x5/league_leaders_bug/ -merge game.play and freeAgents.play replace random.gauss with random.realGauss don't need to check every team's roster limits every time games are played - could auto keep AI teams in line after any trade (with user or between AI teams), and then only the user's team needs to be checked -schedule page (and dashboard and maybe gamelog) should show opponent records LOW PRIORITY ------------ track longest W/L streaks team chemistry http://www.reddit.com/r/BasketballGM/comments/2oco2a/simple_suggestion_team_chemistry/cmrpap6?context=3 -upcoming free agents page should show at least some information about signings (or non-signings) during re-sign phase box plots / distributions "it'd be great to overlay your roster to see where you stand. Maybe click on a name in a list to add or remove it from the display. Do I have a fast team? Do I have a three point shooting team? Are we big and bruising and slow?" compare players http://www.reddit.com/r/BasketballGM/comments/1saclf/suggestion_compare_players/ -awards - show awards count in hall of fame fantasy draft when fantasy draft is over, go to summary of the draft do this in core.draft.untilUserOrEnd @@ -1964,11 +1889,7 @@ mobile UI, bootstrap 3 table headers others? some kind of playoff series overview page, including box scores for easy access -luxury tax money should be redistributed to non-taxpaying teams (or teams under the cap?) A year-to-date comparison of team finances with the previous year. -more detailed player moods - http://www.reddit.com/r/BasketballGM/comments/1k4val/players_refusing_to_sign_bug/cbln1oo?context=3 - player personality, team chemistry - http://www.reddit.com/r/BasketballGM/comments/1tkw3e/idea_player_traits/ dashboard info should be on a widget accessible from any screen player search page show stats, ratings, contract, etc. (customizable); allow filters to be applied. also filter by skill icon @@ -2120,11 +2041,6 @@ live play-by-play simulation allow the user to make substitutions in realtime multi team trades -# Pre-JavaScript TODO - -csrf protection - even for ajax https://docs.djangoproject.com/en/1.2/releases/1.2.5/#csrf-exception-for-ajax-requests - # BELOW IS OLD STUFF AI (NON-GAMESIM) diff --git a/babel.config.js b/babel.config.js index beacc4f6a4..9528ee7cb3 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,61 +1,3 @@ -// Need this rather than .babelrc to run on d3 inside node_modules (see also rollup-plugin-babel config) +const babelConfig = require("./tools/lib/babelConfig"); -module.exports = api => { - // Make sure config gets updated when process.env.LEGACY changes - api.cache.invalidate(() => - JSON.stringify([process.env.LEGACY, process.env.NODE_ENV]), - ); - - const plugins = [ - require("./tools/babel-plugin-sport-functions"), - [ - "transform-react-remove-prop-types", - { - removeImport: true, - }, - ], - ]; - - if (process.env.LEGACY) { - plugins.push( - [ - "@babel/plugin-proposal-optional-chaining", - { - loose: true, - }, - ], // Chrome 80, Safari 13.1 - [ - "@babel/plugin-proposal-nullish-coalescing-operator", - { - loose: true, - }, - ], // Chrome 80, Safari 13.1 - "@babel/plugin-proposal-object-rest-spread", // Chrome 60, Safari 11.1 - "@babel/plugin-transform-for-of", // Chrome 51 - "@babel/plugin-transform-destructuring", // Chrome 51 - "@babel/plugin-transform-exponentiation-operator", // Chrome 52 - "@babel/plugin-transform-async-to-generator", // Chrome 55 - ); - } - - return { - presets: [ - [ - "@babel/preset-react", - { - runtime: "automatic", - - // Results in a ton of warnings from Rollup during watch - // development: process.env.NODE_ENV !== "production", - }, - ], - "@babel/preset-typescript", - ], - plugins, - env: { - test: { - plugins: ["@babel/plugin-transform-modules-commonjs"], - }, - }, - }; -}; +module.exports = babelConfig(false); diff --git a/babel.config.legacy.js b/babel.config.legacy.js new file mode 100644 index 0000000000..f618092308 --- /dev/null +++ b/babel.config.legacy.js @@ -0,0 +1,3 @@ +const babelConfig = require("./tools/lib/babelConfig"); + +module.exports = babelConfig(true); diff --git a/data/names.json b/data/names.json index 7600701329..79a860b513 100644 --- a/data/names.json +++ b/data/names.json @@ -12259,121 +12259,273 @@ "Italy": { "first": { "Achille": 1, - "Agostino": 1, - "Alessandro": 13, + "Adolfo": 1, + "Adriano": 6, + "Agostino": 5, + "Alberto": 18, + "Aldo": 11, + "Alessandro": 39, + "Alessio": 3, "Alex": 2, - "Amedeo": 2, - "Andrea": 18, - "Antonio": 1, + "Alfio": 2, + "Alfonso": 5, + "Alfredo": 6, + "Amedeo": 4, + "Andrea": 62, + "Angelo": 35, + "Aniello": 2, + "Antonello": 2, + "Antonino": 13, + "Antonio": 12, "Ariel": 1, - "Augusto": 1, + "Armando": 6, + "Arnaldo": 1, + "Arturo": 2, + "Attilio": 3, + "Augusto": 4, + "Aurelio": 1, "Awudu": 1, + "Bartolomeo": 1, "Basile": 1, + "Battista": 1, + "Benedetto": 2, + "Benito": 2, "Bereket": 1, + "Biagio": 3, "Brandon": 1, "Brennan": 1, "Brian": 1, - "Bruno": 1, - "Christian": 1, - "Claudio": 2, - "Cristiano": 2, + "Bruno": 21, + "Calogero": 3, + "Camillo": 1, + "Carlo": 26, + "Carmelo": 7, + "Carmine": 7, + "Cesare": 5, + "Christian": 2, + "Ciro": 5, + "Claudio": 7, + "Corrado": 4, + "Cosimo": 6, + "Costantino": 1, + "Cristian": 2, + "Cristiano": 3, + "Damiano": 1, "Daniel": 1, - "Daniele": 4, - "Danilo": 1, - "Dario": 1, - "David": 1, - "Davide": 5, + "Daniele": 16, + "Danilo": 5, + "Dante": 2, + "Dario": 7, + "David": 2, + "Davide": 15, "Denis": 1, - "Diego": 1, - "Domenico": 1, - "Elio": 1, + "Diego": 4, + "Dino": 4, + "Domenico": 31, + "Donato": 5, + "Edoardo": 2, + "Egidio": 2, + "Elio": 5, + "Emanuele": 5, + "Emilio": 5, + "Ennio": 2, + "Enrico": 14, + "Enzo": 7, "Eric": 1, - "Fabio": 4, - "Fabrizio": 1, - "Federico": 3, - "Ferdinando": 1, - "Filippo": 2, - "Francesco": 6, - "Gabriele": 2, - "Giacomo": 3, - "Gian": 2, - "Giancarlo": 1, - "Gianluca": 2, + "Ermanno": 1, + "Ernesto": 4, + "Ettore": 3, + "Eugenio": 3, + "Ezio": 3, + "Fabio": 20, + "Fabrizio": 11, + "Fausto": 3, + "Federico": 9, + "Felice": 4, + "Ferdinando": 4, + "Fernando": 4, + "Ferruccio": 1, + "Filippo": 10, + "Flavio": 3, + "Francesco": 78, + "Franco": 28, + "Fulvio": 2, + "Gabriele": 10, + "Gaetano": 11, + "Gaspare": 1, + "Gennaro": 6, + "Gerardo": 3, + "Giacomo": 11, + "Giampaolo": 2, + "Giampiero": 2, + "Gian": 8, + "Giancarlo": 14, + "Gianfranco": 10, + "Gianluca": 8, + "Gianluigi": 1, "Gianmarco": 2, - "Gino": 1, - "Giorgio": 1, - "Giovanni": 4, - "Giuliano": 1, - "Giulio": 1, - "Giuseppe": 1, - "Guido": 1, + "Gianni": 8, + "Gilberto": 1, + "Gino": 8, + "Gioacchino": 1, + "Giordano": 1, + "Giorgio": 21, + "Giovanni": 81, + "Girolamo": 1, + "Giuliano": 8, + "Giulio": 7, + "Giuseppe": 118, + "Graziano": 3, + "Guglielmo": 2, + "Guido": 9, "Habakkuk": 1, + "Ignazio": 3, "Isacco": 1, - "Ivan": 1, + "Italo": 2, + "Ivan": 3, + "Ivano": 2, + "Ivo": 2, "Jacopo": 1, "Joel": 1, "Joshua": 1, - "Leonardo": 1, - "Lorenzo": 7, - "Luca": 11, - "Luigi": 2, + "Leonardo": 8, + "Lino": 3, + "Livio": 2, + "Lorenzo": 18, + "Loris": 2, + "Luca": 29, + "Luciano": 19, + "Lucio": 2, + "Luigi": 53, + "Luigino": 1, "Manuel": 5, - "Marco": 15, - "Mario": 1, - "Martino": 2, - "Massimo": 1, - "Matteo": 5, - "Mattia": 2, - "Michele": 8, + "Marcello": 7, + "Marco": 50, + "Mariano": 2, + "Marino": 3, + "Mario": 52, + "Martino": 3, + "Massimiliano": 6, + "Massimo": 24, + "Matteo": 14, + "Mattia": 3, + "Maurizio": 19, + "Mauro": 17, + "Michelangelo": 1, + "Michele": 37, "Miguel": 1, + "Mirco": 1, + "Mirko": 2, + "Monica": 11, + "Moreno": 1, + "Natale": 2, + "Nazzareno": 1, + "Nello": 1, "Niccolo": 1, "Nicholas": 1, - "Nicola": 1, - "Nicolo": 2, - "Paolo": 1, + "Nicola": 22, + "Nicolo": 4, + "Nino": 1, + "Nunzio": 2, + "Orazio": 2, + "Orlando": 1, + "Osvaldo": 1, + "Ottavio": 1, + "Paolo": 39, + "Pasquale": 17, "Paul": 1, + "Pier": 4, "Pierfrancesco": 1, - "Pietro": 1, + "Pierino": 1, + "Pierluigi": 3, + "Piero": 6, + "Pietro": 31, + "Primo": 1, + "Raffaele": 13, "Raphael": 1, "Reggie": 1, - "Riccardo": 7, - "Roberto": 4, - "Rodolfo": 1, + "Remo": 3, + "Renato": 11, + "Renzo": 6, + "Riccardo": 16, + "Rinaldo": 1, + "Rino": 2, + "Roberto": 42, + "Rocco": 7, + "Rodolfo": 3, + "Romano": 3, + "Romeo": 1, + "Rosario": 6, "Ruben": 2, - "Salvatore": 3, + "Ruggero": 1, + "Salvatore": 44, "Samuele": 1, - "Simone": 9, - "Stefano": 5, + "Sandro": 5, + "Sante": 1, + "Santo": 3, + "Saverio": 3, + "Sebastiano": 5, + "Sergio": 3, + "Silvano": 6, + "Silvio": 3, + "Simone": 18, + "Stefano": 30, + "Tiziano": 2, "Tomas": 1, - "Tommaso": 4, - "Umberto": 1, - "Valerio": 3, + "Tommaso": 9, + "Tonino": 1, + "Ugo": 4, + "Umberto": 8, + "Valentino": 2, + "Valerio": 4, + "Valter": 1, "Victor": 1, "Vincent": 1, - "Vincenzo": 1, - "Walter": 1 + "Vincenzo": 39, + "Vito": 9, + "Vittorio": 11, + "Walter": 6 }, "last": { "Abass": 1, "Abbio": 1, + "Agostini": 1, + "Aiello": 1, "Akele": 1, "Allegretti": 1, - "Amato": 1, + "Amato": 3, "Ambrassa": 1, "Ambrosin": 1, "Amoroso": 1, + "Angelini": 1, "Antelli": 1, + "Antonelli": 1, "Antonutti": 1, "Aradori": 1, + "Arena": 1, "Attruia": 1, - "Baldi": 1, + "Baldi": 2, "Baldo": 1, "Baldonado": 1, + "Barbieri": 3, "Bargnani": 1, - "Basile": 2, + "Barone": 2, + "Bartolini": 1, + "Basile": 4, + "Bassi": 1, + "Basso": 1, + "Battaglia": 1, "Belinelli": 1, "Bellan": 1, + "Bellini": 1, + "Benedetti": 2, + "Beretta": 1, "Bergamo": 1, + "Bernardi": 2, + "Bernardini": 1, + "Berti": 1, + "Bianchi": 6, + "Bianco": 2, "Biligha": 1, "Binelli": 1, "Blotto": 1, @@ -12384,9 +12536,13 @@ "Boni": 1, "Bonora": 1, "Boscagin": 1, + "Brambilla": 2, "Brkic": 1, + "Bruni": 1, + "Bruno": 4, "Bulleri": 1, "Buttiglieri": 1, + "Calabrese": 1, "Calamo": 1, "Calo": 1, "Camata": 1, @@ -12394,29 +12550,52 @@ "Candussi": 1, "Cantoni": 1, "Cappelletti": 1, + "Caputo": 2, + "Carbone": 2, "Cardillo": 1, "Carra": 1, "Carraretto": 1, + "Carta": 1, + "Caruso": 3, + "Castelli": 1, "Castori": 1, + "Catalano": 1, + "Cattaneo": 2, "Cavaliero": 1, + "Cavallo": 1, "Cazzaniga": 1, "Cazzolato": 1, + "Ceccarelli": 1, "Ceron": 1, "Cervi": 1, "Cesana": 1, "Chiacig": 1, "Cinciarini": 2, + "Cirillo": 1, "Cittadini": 1, "Coldebella": 1, - "Conti": 1, + "Colombo": 6, + "Conte": 2, + "Conti": 4, + "Coppola": 2, + "Corti": 1, + "Costa": 3, + "Costantini": 1, + "Costanzo": 1, "Cotani": 1, "Crespi": 1, "Criconia": 1, "Crosariol": 1, "Cuccarolo": 1, "Cusin": 1, - "D'Angelo": 1, + "D'Agostino": 1, + "D'Alessandro": 1, + "D'Ambrosio": 1, + "D'Amico": 2, + "D'Angelo": 3, "D'Ercole": 1, + "Dal": 4, + "Dalla": 2, "Datome": 1, "Davolio": 1, "De Gennaro": 1, @@ -12433,40 +12612,71 @@ "Di Meco": 1, "Di Napoli": 1, "Di Pizzo": 1, + "Donati": 1, "Donzelli": 1, - "Esposito": 2, + "Esposito": 9, + "Fabbri": 2, "Fabiani": 1, "Fantoni": 1, + "Farina": 2, "Fazzi": 1, - "Ferrero": 1, + "Ferrante": 1, + "Ferrara": 3, + "Ferrari": 8, + "Ferraro": 2, + "Ferrero": 2, + "Ferretti": 1, + "Ferri": 2, + "Ferro": 1, "Filloy": 1, + "Fiore": 2, "Fiusco": 1, "Flaccadori": 1, "Flamini": 1, "Foiera": 1, + "Fontana": 3, "Fontecchio": 1, "Formenti": 1, "Formisano": 1, "Fortes": 1, + "Franco": 2, "Frosini": 1, + "Fumagalli": 1, + "Fusco": 1, "Galanda": 1, - "Galli": 1, + "Galli": 4, "Gallinari": 1, + "Gallo": 4, + "Garofalo": 1, "Garri": 1, "Gaspardo": 1, + "Gatti": 2, "Gatto": 1, "Gazzotti": 1, "Gennarelli": 1, - "Gentile": 3, + "Gentile": 5, "Ghiacci": 1, "Giachetti": 1, + "Giannini": 1, "Gioia": 1, + "Giordano": 3, + "Giorgi": 1, + "Giuliani": 2, "Giuri": 1, "Goodnature": 1, + "Gori": 1, + "Grassi": 2, + "Grasso": 2, "Gravina": 1, "Graziani": 1, + "Greco": 4, + "Grillo": 1, + "Grimaldi": 1, "Groppi": 1, + "Grossi": 1, + "Guerra": 1, "Guglielmi": 1, + "Guidi": 1, "Imbro": 1, "Infante": 1, "Ingrosso": 1, @@ -12476,108 +12686,213 @@ "La Torre": 1, "Lagana": 1, "Lamma": 1, + "Landi": 1, "Laquintana": 1, "Lazzari": 1, "Lechthaler": 1, "Leggio": 1, + "Leonardi": 1, + "Leone": 2, + "Leoni": 1, "Lever": 1, "Li Vecchi": 1, - "Lombardi": 1, + "Locatelli": 2, + "Lombardi": 4, + "Lombardo": 2, + "Longo": 2, "Lulli": 1, "Lusvarghi": 1, + "Maggi": 1, "Maggioli": 1, + "Magnani": 1, "Magro": 1, "Malaventura": 1, + "Manca": 1, "Mancinelli": 1, + "Mancini": 3, + "Mancuso": 1, + "Mantovani": 1, + "Marchese": 1, + "Marchetti": 2, + "Marchi": 1, "Marconato": 1, "Maresca": 1, + "Mariani": 3, + "Marinelli": 1, + "Marini": 2, + "Marino": 4, + "Martinelli": 2, + "Martini": 2, + "Martino": 2, "Marzaioli": 1, "Mascolo": 1, "Mastellari": 1, + "Mauro": 1, + "Mazza": 2, "Mazzola": 1, + "Mele": 1, + "Melis": 1, "Melli": 1, + "Meloni": 1, "Meneghin": 1, + "Messina": 2, "Mian": 2, "Michelori": 1, + "Milani": 1, + "Molinari": 1, "Molinaro": 1, + "Monaco": 1, + "Montanari": 1, + "Monti": 2, "Morandotti": 1, "Moraschini": 1, "Mordente": 1, + "Morelli": 2, + "Moretti": 3, + "Moro": 1, + "Mosca": 1, + "Motta": 1, "Mussini": 1, + "Napolitano": 1, + "Nardi": 1, "Ndoye": 1, + "Negri": 1, "Nicolo": 1, "Norcino": 1, "Oliva": 1, + "Olivieri": 1, + "Orlandi": 1, + "Orlando": 2, "Orsini": 1, "Oxilia": 1, + "Pace": 1, "Pacifico": 1, + "Pagano": 1, "Paiola": 1, "Pajola": 1, + "Palmieri": 2, + "Palumbo": 2, "Parente": 1, + "Parisi": 2, "Parlato": 1, "Parrillo": 1, "Pascolo": 1, "Passera": 1, + "Pastore": 1, "Pastori": 1, "Pecchia": 1, "Pecile": 1, - "Pellegrino": 1, + "Pellegrini": 2, + "Pellegrino": 3, "Pena": 1, "Penna": 1, + "Pepe": 1, + "Perrone": 1, "Petteno": 1, + "Piazza": 1, + "Piccolo": 1, "Pietrini": 1, "Pilotti": 1, "Pilutti": 1, "Pini": 1, + "Pinna": 1, + "Piras": 2, "Pittis": 1, "Podesta": 1, "Poeta": 1, + "Poli": 1, "Polonara": 1, "Pompianu": 1, "Pozzecco": 1, + "Pozzi": 1, + "Proietti": 1, + "Pugliese": 1, "Ragonesi": 1, "Ranocchi": 1, "Ress": 1, "Restelli": 1, + "Ricci": 4, "Righetti": 1, + "Rinaldi": 2, + "Riva": 2, + "Rizzi": 2, + "Rizzo": 3, + "Romano": 5, "Rombaldoni": 1, - "Rosa": 1, + "Romeo": 1, + "Rosa": 2, "Rosselli": 1, - "Rossetti": 1, - "Rossi": 1, + "Rossetti": 3, + "Rossi": 16, + "Rosso": 1, + "Rota": 1, + "Ruggeri": 1, + "Ruggiero": 1, "Rullo": 1, "Rusconi": 1, + "Russo": 9, "Ruzzier": 1, "Sacchetti": 1, + "Sacco": 1, + "Sala": 2, "Salvi": 1, + "Sanna": 2, "Santarossa": 1, + "Santini": 1, + "Santoro": 2, + "Sartori": 1, + "Serafini": 1, "Serpilli": 1, + "Serra": 2, "Severini": 2, + "Silvestri": 2, "Simioni": 1, "Solazzi": 1, "Soragna": 1, + "Sorrentino": 1, "Sovera": 1, - "Spinelli": 1, + "Spina": 1, + "Spinelli": 2, "Stefanini": 1, + "Stella": 1, "Tessitori": 1, - "Testa": 1, + "Testa": 3, "Toffali": 1, "Tonolli": 1, "Tonut": 1, + "Tosi": 1, "Tote": 1, + "Trevisan": 1, + "Valenti": 1, + "Valentini": 2, "Vanuzzo": 1, "Vecerina": 1, "Ventrone": 1, + "Ventura": 1, + "Venturi": 1, + "Venturini": 1, "Vercellino": 1, "Vercesi": 1, - "Villa": 1, + "Villa": 3, + "Viola": 1, "Visconti": 1, - "Vitali": 2, + "Vitale": 2, + "Vitali": 3, + "Volpe": 1, "Zacchetti": 1, "Zanelli": 1, + "Zanetti": 1, "Zerini": 1, "Zilli": 1, - "Zugno": 1 + "Zugno": 1, + "de Angelis": 2, + "de Luca": 3, + "de Marco": 1, + "de Rosa": 2, + "de Santis": 2, + "de Simone": 1, + "di Marco": 1, + "di Stefano": 1 } }, "Ivory Coast": { diff --git a/data/real-player-data.basketball.json b/data/real-player-data.basketball.json index ef6eaaf60b..ce4ad88705 100644 --- a/data/real-player-data.basketball.json +++ b/data/real-player-data.basketball.json @@ -241188,6 +241188,18 @@ "draftYear": 2018, "draftRound": 0, "draftPick": 0 + }, + "dp_2023_gabe_wiznitzer": { + "name": "Gabe Wiznitzer", + "bornYear": 2001, + "country": "Walhalla, SC", + "weight": 240, + "pos": "C", + "height": 83, + "college": "Louisville", + "draftYear": 2023, + "draftRound": 0, + "draftPick": 0 } }, "ratings": [ @@ -700142,6 +700154,26 @@ "pss": 34, "reb": 63, "fuzz": 0 + }, + { + "slug": "dp_2023_gabe_wiznitzer", + "season": 2023, + "hgt": 65, + "stre": 13, + "spd": 9, + "jmp": 5, + "endu": 15, + "ins": 19, + "dnk": 8, + "ft": 31, + "fg": 16, + "tp": 0, + "diq": 13, + "oiq": 10, + "drb": 7, + "pss": 7, + "reb": 14, + "fuzz": 0 } ], "relatives": [ diff --git a/package.json b/package.json index ceaf44b32a..59645d018d 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "deploy": "yarn run lint && yarn test && node tools/deploy.mjs", "deploy-all": "yarn run lint && yarn test && node tools/deploy-all.mjs", "start-watch": "concurrently --kill-others \"yarn run start\" \"yarn run watch\"", - "watch": "yarn run ajv-hack && node --openssl-legacy-provider tools/watch.js", + "watch": "yarn run ajv-hack && node tools/watch.js", "lint": "concurrently --raw \"yarn run lint-js\" \"yarn run lint-ts\"", "lint-js": "eslint \"*.{mjs,js,ts,tsx}\" \"public/*.js\" \"src/**/*.{mjs,js,ts,tsx}\" \"tools/**/*.{mjs,js,ts,tsx}\"", "lint-ts": "node tools/pre-test.mjs && yarn run tsc", @@ -44,7 +44,7 @@ "@visx/scale": "^2.2.2", "@visx/shape": "^2.4.0", "@visx/text": "^2.3.0", - "ajv": "^8.8.2", + "ajv": "^8.9.0", "array-move": "^4.0.0", "bootstrap": "^5.1.3", "classnames": "^2.3.1", @@ -53,18 +53,18 @@ "dompurify": "^2.3.4", "dropbox": "^10.23.0", "facesjs": "^3.6.0", - "framer-motion": "^5.5.3", - "html2canvas": "^1.3.3", - "idb": "dumbmatter/idb#bbgm2", + "framer-motion": "^5.6.0", + "html2canvas": "^1.4.0", + "idb": "dumbmatter/idb#autoIncrementKeyPath2-build", "lodash-es": "^4.17.21", "nanoevents": "^6.0.2", "promise-worker-bi": "^4.0.2", "react": "^17.0.2", "react-addons-text-content": "^0.0.4", - "react-bootstrap": "^2.0.3", + "react-bootstrap": "^2.1.1", "react-confirm": "^0.1.24", "react-dom": "^17.0.2", - "react-select": "^5.2.1", + "react-select": "^5.2.2", "react-sortable-hoc": "^2.0.0", "roman-numerals": "^0.3.2", "s-ago": "^2.2.0", @@ -76,34 +76,34 @@ "workbox-precaching": "^6.4.2", "workbox-routing": "^6.4.2", "workbox-window": "^6.4.2", - "zustand": "^3.6.7" + "zustand": "^3.6.9" }, "devDependencies": { - "@babel/core": "^7.16.5", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.5", - "@babel/plugin-proposal-object-rest-spread": "^7.16.5", - "@babel/plugin-proposal-optional-chaining": "^7.16.5", - "@babel/plugin-syntax-typescript": "^7.16.5", - "@babel/plugin-transform-async-to-generator": "^7.16.5", - "@babel/plugin-transform-destructuring": "^7.16.5", - "@babel/plugin-transform-exponentiation-operator": "^7.16.5", - "@babel/plugin-transform-for-of": "^7.16.5", - "@babel/plugin-transform-modules-commonjs": "^7.16.5", - "@babel/preset-react": "^7.16.5", - "@babel/preset-typescript": "^7.16.5", - "@rollup/plugin-alias": "^3.1.8", + "@babel/core": "^7.16.7", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", + "@babel/plugin-proposal-object-rest-spread": "^7.16.7", + "@babel/plugin-proposal-optional-chaining": "^7.16.7", + "@babel/plugin-syntax-typescript": "^7.16.7", + "@babel/plugin-transform-async-to-generator": "^7.16.8", + "@babel/plugin-transform-destructuring": "^7.16.7", + "@babel/plugin-transform-exponentiation-operator": "^7.16.7", + "@babel/plugin-transform-for-of": "^7.16.7", + "@babel/plugin-transform-modules-commonjs": "^7.16.8", + "@babel/preset-react": "^7.16.7", + "@babel/preset-typescript": "^7.16.7", + "@rollup/plugin-alias": "^3.1.9", "@rollup/plugin-babel": "^5.3.0", "@rollup/plugin-commonjs": "21.0.1", "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.6", - "@rollup/plugin-replace": "^3.0.0", + "@rollup/plugin-node-resolve": "^13.1.3", + "@rollup/plugin-replace": "^3.0.1", "@types/d3-dsv": "^3.0.0", "@types/d3-scale": "^4.0.2", - "@types/dompurify": "^2.3.2", + "@types/dompurify": "^2.3.3", "@types/gtag.js": "^0.0.8", - "@types/jest": "^27.0.3", + "@types/jest": "^27.4.0", "@types/lodash-es": "^4.17.5", - "@types/react": "^17.0.37", + "@types/react": "^17.0.38", "@types/react-confirm": "^0.1.4", "@types/react-dom": "^17.0.11", "@types/roman-numerals": "^0.3.0", @@ -111,54 +111,54 @@ "@types/stripe-checkout": "^1.0.4", "@types/stripe-v2": "^2.0.2", "@types/wicg-file-system-access": "^2020.9.4", - "@typescript-eslint/eslint-plugin": "^5.6.0", - "@typescript-eslint/parser": "^5.6.0", + "@typescript-eslint/eslint-plugin": "^5.9.1", + "@typescript-eslint/parser": "^5.9.1", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "cheerio": "^1.0.0-rc.10", "chokidar": "^3.5.1", "clean-css": "^5.2.2", "cloudflare": "^2.9.1", - "concurrently": "^6.4.0", + "concurrently": "^7.0.0", "conditional-type-checks": "^1.0.5", "cross-env": "^7.0.3", - "esbuild": "^0.14.5", - "eslint": "^8.4.1", + "esbuild": "^0.14.11", + "eslint": "^8.6.0", "eslint-config-airbnb-typescript": "^16.0.0", "eslint-config-prettier": "^8.3.0", - "eslint-plugin-import": "^2.25.3", + "eslint-plugin-import": "^2.25.4", "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react": "^7.28.0", "eslint-plugin-react-hooks": "^4.3.0", "fake-indexeddb": "4.0.0-beta.2", "flag-icon-css": "^4.1.7", "fs-extra": "^10.0.0", "html-minifier-terser": "^6.1.0", "husky": "^7.0.4", - "import-jsx": "^4.0.0", + "import-jsx": "^4.0.1", "ink": "^3.2.0", "ink-spinner": "^4.0.3", - "jest": "^27.4.5", - "karma": "^6.3.9", + "jest": "^27.4.7", + "karma": "^6.3.11", "karma-browserstack-launcher": "^1.6.0", "karma-chrome-launcher": "^3.1.0", "karma-firefox-launcher": "^2.1.2", "karma-mocha": "^2.0.1", "karma-rollup-preprocessor": "^7.0.7", "karma-source-map-support": "^1.4.0", - "lint-staged": "^12.1.2", - "log-symbols": "^4.1.0", - "mocha": "^9.1.3", + "lint-staged": "^12.1.7", + "log-symbols": "^5.1.0", + "mocha": "^9.1.4", "patch-package": "^6.4.7", "postinstall-postinstall": "^2.1.0", "prettier": "^2.5.0", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "purgecss": "^4.1.3", "replace": "^1.2.1", - "rollup": "^2.61.1", + "rollup": "^2.64.0", "rollup-plugin-blacklist": "^1.0.1", "rollup-plugin-terser": "^7.0.2", - "rollup-plugin-visualizer": "^5.5.2", - "sass": "1.45.0", + "rollup-plugin-visualizer": "^5.5.4", + "sass": "1.48.0", "typescript": "^4.5.4", "workbox-build": "^6.4.2" }, diff --git a/public/.htaccess b/public/.htaccess index 9c48735d2d..baaa415545 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -1,4 +1,4 @@ - + Header set Access-Control-Allow-Origin "*" Header set Cache-Control "public,max-age=31536000" @@ -49,6 +49,6 @@ RewriteCond %{REQUEST_URI} !^/leagues RewriteCond %{REQUEST_URI} !^/manifest RewriteCond %{REQUEST_URI} !^/robots.txt RewriteCond %{REQUEST_URI} !^/sw.js -RewriteCond %{REQUEST_URI} !^/upgrade-39 +RewriteCond %{REQUEST_URI} !^/upgrade-50 RewriteCond %{REQUEST_URI} !^/(.well-known)(/|$) RewriteRule ^.*$ index.html \ No newline at end of file diff --git a/public/css/bbgm-notifications.scss b/public/css/bbgm-notifications.scss index f51a65b1cf..5825ff4e37 100644 --- a/public/css/bbgm-notifications.scss +++ b/public/css/bbgm-notifications.scss @@ -91,9 +91,10 @@ color: rgba(255, 255, 255, 0.7); cursor: pointer; padding: 0 7px; - position: absolute; - top: 0; - right: 0; + float: right; + margin-top: -6px; + margin-right: -12px; + margin-left: 12px; &:hover, &:focus { diff --git a/public/css/dark.scss b/public/css/dark.scss index d365e4e5d5..3a4ac59cbb 100644 --- a/public/css/dark.scss +++ b/public/css/dark.scss @@ -33,7 +33,7 @@ $table-bg-scale: 70%; $alert-bg-scale: 70%; $alert-border-scale: 60%; -$list-group-item-bg-scale: 50%; +$list-group-item-bg-scale: 70%; // Otherwise, it complains about contrast for buttons $min-contrast-ratio: 3; @@ -208,6 +208,12 @@ a.god-mode.active { .btn-outline-god-mode { @include button-variant(darken($purple, 20), $gray-400); + + &:active, + &:focus, + &:not(:disabled):hover { + color: $black !important; + } } .alert-god-mode { @@ -321,7 +327,6 @@ table.table thead .sorting::after { } } -.sorting_asc, -.sorting_desc { +.sorted { background-color: #5f583c !important; } diff --git a/public/css/glyphicons.scss b/public/css/glyphicons.scss index 6ff089152b..3b9a5b10f0 100644 --- a/public/css/glyphicons.scss +++ b/public/css/glyphicons.scss @@ -1,7 +1,6 @@ @font-face { font-family: "Glyphicons Halflings"; - src: url("../fonts/glyphicons-halflings-regular.woff2") format("woff2"), - url("../fonts/glyphicons-halflings-regular.woff") format("woff"); + src: url("../fonts/glyphicons-halflings-regular.woff2") format("woff2"); } .glyphicon { position: relative; diff --git a/public/css/light.scss b/public/css/light.scss index f11dd216a2..55a57ecf60 100644 --- a/public/css/light.scss +++ b/public/css/light.scss @@ -12,6 +12,9 @@ $badge-padding-y: 0.25em; $badge-padding-x: 0.4em; $popover-body-padding-y: 0.5rem; $popover-body-padding-x: 0.75rem; +$form-select-indicator-padding: 1.1rem; +$form-select-bg-position: right 0.15rem center; + .form-check-inline { margin-right: 0.75rem !important; } @@ -75,7 +78,7 @@ $flag-icon-css-path: "/img/flags"; height: auto; } -// Taken from bootstrap.scss, but with unused things deleted +// Taken from bootstrap.scss, but with unused things deleted. PurgeCSS would do the same thing from just importing the main bootstrap.scss file, but it has some false positives (such as offcanvas placeholder). @import "node_modules/bootstrap/scss/functions"; @import "node_modules/bootstrap/scss/variables"; @import "node_modules/bootstrap/scss/mixins"; @@ -503,6 +506,8 @@ table { margin: 0; padding: 0 0.25rem; height: 20px; + padding-right: 0.1rem; + background-position: right 0.1em center; } // These colors are duplicated from Roster.js @@ -589,6 +594,8 @@ table { padding-right: 1em; text-align: right; width: 85px; + white-space: nowrap; + overflow: hidden; } .finances-settings-text { @@ -939,13 +946,9 @@ tr.table-warning:hover > td { } .title-bar { - margin-left: -17px; h1 { - margin-left: 17px; - } - min-height: 52px; - select { - font-size: 14px; + font-size: 20px; + margin: 7px 0; // Needed in addition to .title-bar min-height when it wraps onto multiple lines } option { font-size: 12px; @@ -953,6 +956,11 @@ tr.table-warning:hover > td { .dropdown-links .dropdown.show.nav-item { background-color: $gray-100; } + gap: 0 10px; + min-height: 39px; +} +.dropdown-select-wrapper { + margin: 7px 0; // Needed in addition to .title-bar min-height when it wraps onto multiple lines } .dropdown-select { display: block; @@ -960,8 +968,7 @@ tr.table-warning:hover > td { -moz-appearance: none; -webkit-appearance: none; appearance: none; - padding-left: 2px; - padding-right: 13px; + padding: 1px 13px 0 2px; background-color: inherit; border: 0; color: inherit; @@ -971,11 +978,23 @@ tr.table-warning:hover > td { background-repeat: no-repeat, repeat; background-position: right 0 top 45%, 0 0; background-size: 0.62em auto, 100%; + font-size: 13px; option { color: #000; } } +@include media-breakpoint-up(md) { + .dropdown-select { + font-size: 14px; + } + .title-bar { + h1 { + font-size: 24px; + } + min-height: 45px; + } +} $league-top-bar-toggle-width: 15px; $league-top-bar-scrollbar-track-color: $gray-300; @@ -1001,6 +1020,9 @@ $league-top-bar-scrollbar-thumb-color: $gray-500; border-radius: 50px; } } +.league-top-bar-safari { + margin-right: $league-top-bar-toggle-width + 8px; +} .league-top-bar-toggle { border-top-right-radius: 0 !important; border-bottom-right-radius: 0 !important; @@ -1316,11 +1338,12 @@ a.anchor { } // https://www.codeply.com/go/NiFzSCukVl/bootstrap-4-open-modal-from-another-modal +// Increased z-index for Bootstrap 5 https://getbootstrap.com/docs/5.1/layout/z-index/ .highest-modal { - z-index: 1052 !important; + z-index: 1057 !important; } .highest-modal-backdrop.show { - z-index: 1051 !important; + z-index: 1056 !important; } .border-top-light { @@ -1340,8 +1363,7 @@ code { transition: none !important; } -.sorting_asc, -.sorting_desc { +.sorted { background-color: #ffeeba !important; } @@ -1363,3 +1385,27 @@ hr { .input-group-xs > .form-select { padding-right: $form-select-padding-x + $form-select-indicator-padding; } + +// Add !important to bg color so they can be used in table on achievements page +@each $state, $value in $theme-colors { + $list-group-variant-bg: shift-color($value, $list-group-item-bg-scale); + .list-group-item-#{$state} { + background-color: $list-group-variant-bg !important; + } +} + +.default-settings-select { + max-width: 400px; + + .dark-select__placeholder { + color: $black; + } + + .dark-select__group-heading { + font-size: 90%; + } + + .dark-select__menu { + z-index: 3; // Above .settings-buttons + } +} diff --git a/public/css/sidebar.scss b/public/css/sidebar.scss index 00ca41219a..d82525c56f 100644 --- a/public/css/sidebar.scss +++ b/public/css/sidebar.scss @@ -1,5 +1,7 @@ // https://getbootstrap.com/docs/4.1/examples/dashboard/ +$sidebar-width: 161px; // Line up with Play button + .sidebar { display: none; position: fixed; @@ -8,7 +10,7 @@ left: 0; z-index: 1040; border-right: 1px solid $gray-200; - width: 161px; // Line up with Play button + width: $sidebar-width; } .sidebar-sticky { @@ -57,23 +59,22 @@ } #actual-content, #main-footer { - margin-left: 161px; + margin-left: $sidebar-width; } #basketball-gm_leaderboard_atf, #football-gm_leaderboard_atf, #zen-gm_leaderboard_atf { - margin-left: 161px; + margin-left: $sidebar-width; } .league-top-bar { - margin-left: 161px; + margin-left: $sidebar-width; } .title-bar { - // -17 for left margin in .title-bar - margin-left: 144px !important; + margin-left: $sidebar-width !important; } } -@include media-breakpoint-down(lg) { +@include media-breakpoint-down(xl) { .sidebar { display: block; font-size: 1rem; @@ -90,7 +91,6 @@ } .navbar.fixed-top .navbar-toggler { - color: orange; display: block; } } diff --git a/public/fonts/glyphicons-halflings-regular.woff b/public/fonts/glyphicons-halflings-regular.woff deleted file mode 100644 index 8c54182aa5..0000000000 Binary files a/public/fonts/glyphicons-halflings-regular.woff and /dev/null differ diff --git a/public/hockey/.htaccess b/public/hockey/.htaccess index 104f9aa92f..1fbed35b0c 100644 --- a/public/hockey/.htaccess +++ b/public/hockey/.htaccess @@ -1,4 +1,4 @@ - + Header set Access-Control-Allow-Origin "*" Header set Cache-Control "max-age=31536000" @@ -67,6 +67,6 @@ RewriteCond %{REQUEST_URI} !^/leagues RewriteCond %{REQUEST_URI} !^/manifest RewriteCond %{REQUEST_URI} !^/robots.txt RewriteCond %{REQUEST_URI} !^/sw.js -RewriteCond %{REQUEST_URI} !^/upgrade-39 +RewriteCond %{REQUEST_URI} !^/upgrade-50 RewriteCond %{REQUEST_URI} !^/(.well-known)(/|$) RewriteRule ^.*$ index.html diff --git a/public/sw.js b/public/sw.js index f57e071d7c..6da842fe94 100644 --- a/public/sw.js +++ b/public/sw.js @@ -62,6 +62,7 @@ const navigationRoute = new NavigationRoute(handler, { new RegExp("^/manifest"), new RegExp("^/robots.txt"), new RegExp("^/sw.js"), + new RegExp("^/upgrade-"), ], }); registerRoute(navigationRoute); diff --git a/public/upgrade-39/index.html b/public/upgrade-50/index.html similarity index 78% rename from public/upgrade-39/index.html rename to public/upgrade-50/index.html index e3890f102f..9af75fe48c 100644 --- a/public/upgrade-39/index.html +++ b/public/upgrade-50/index.html @@ -4,7 +4,7 @@ Basketball GM Upgrade Fallback -

Use this if you're having trouble upgrading from version 38 to 39 (the player mood update) like described here.

+

Use this if you're having trouble upgrading from version 48/49 to 50.

It's okay if this gets interrupted in the middle, just start it again. And running it on an already-upgraded league will not break anything.

@@ -17,5 +17,5 @@
- + diff --git a/public/upgrade-39/upgrade-39.js b/public/upgrade-50/upgrade-50.js similarity index 64% rename from public/upgrade-39/upgrade-39.js rename to public/upgrade-50/upgrade-50.js index 092e577e84..2b356b989e 100644 --- a/public/upgrade-39/upgrade-39.js +++ b/public/upgrade-50/upgrade-50.js @@ -1,21 +1,3 @@ -const choice = x => { - return x[Math.floor(Math.random() * x.length)]; -}; - -const MOOD_TRAIT_KEYS = ["F", "L", "$", "W"]; - -const genMoodTraits = () => { - const moodTraits = [choice(MOOD_TRAIT_KEYS)]; - if (Math.random() < 0.5) { - moodTraits.push( - choice(MOOD_TRAIT_KEYS.filter(trait => trait !== moodTraits[0])), - ); - } - moodTraits.sort(); - - return moodTraits; -}; - const logDiv = document.getElementById("status"); const log = text => { logDiv.innerHTML += `${text}
`; @@ -42,17 +24,26 @@ const upgrade1000 = async (db, lastPidInput, lastDraftYearInput) => { let lastDraftYear = undefined; while (cursor) { const p = cursor.value; - if (!p.moodTraits) { - delete p.freeAgentMood; - p.moodTraits = genMoodTraits(); - p.numDaysFreeAgent = 0; - cursor.update(p); - numDone += 1; - - lastPid = p.pid; - lastDraftYear = p.draft.year; + + for (const key of ["hof", "watch"]) { + if (p[key]) { + p[key] = 1; + } else { + delete p[key]; + } + } + + if (p.note) { + p.noteBool = 1; + } else { + delete p.note; } + cursor.update(p); + numDone += 1; + lastPid = p.pid; + lastDraftYear = p.draft.year; + if (numDone >= 1000) { doneAllPlayers = false; break; @@ -70,23 +61,6 @@ const upgrade1000 = async (db, lastPidInput, lastDraftYearInput) => { }; }; -const upgradeTeamSeasons = async db => { - log("Upgrading teamSeasons..."); - const tx = db.transaction("teamSeasons", "readwrite"); - - let cursor = await tx.store.openCursor(); - while (cursor) { - const teamSeason = cursor.value; - if (typeof teamSeason.numPlayersTradedAway !== "number") { - teamSeason.numPlayersTradedAway = 0; - cursor.update(teamSeason); - } - cursor = await cursor.continue(); - } - - await tx.done; -}; - const initForm = async () => { const dbMeta = await idb.openDB("meta", 8); @@ -109,7 +83,24 @@ const initForm = async () => { const lid = parseInt(leagueSelect.value); log(`Attempting to connect to league ${lid}`); - const db = await idb.openDB(`league${lid}`, 39); + const db = await idb.openDB(`league${lid}`, 50, { + async upgrade(db, oldVersion, newVerison, transaction) { + log("Creating new indexes..."); + const playerStore = transaction.objectStore("players"); + + if (oldVersion <= 48) { + playerStore.createIndex("hof", "hof", { + unique: false, + }); + } + playerStore.createIndex("noteBool", "noteBool", { + unique: false, + }); + playerStore.createIndex("watch", "watch", { + unique: false, + }); + }, + }); log("Connected!"); log("Upgrading players..."); @@ -124,8 +115,6 @@ const initForm = async () => { } log("Done!"); - await upgradeTeamSeasons(db); - log("Done!"); log( "You should now be able to play your league like normal. Sorry for the trouble!", ); diff --git a/src/common/constants.ts b/src/common/constants.ts index 627556c86a..bc90b23a50 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -27,7 +27,7 @@ const DRAFT_BY_TEAM_OVR = bySport({ hockey: true, }); -const MAX_SUPPORTED_LEAGUE_VERSION = 48; +const MAX_SUPPORTED_LEAGUE_VERSION = 50; const NO_LOTTERY_DRAFT_TYPES: DraftType[] = [ "freeAgents", diff --git a/src/common/defaultGameAttributes.ts b/src/common/defaultGameAttributes.ts index d329cbec38..5e68328340 100644 --- a/src/common/defaultGameAttributes.ts +++ b/src/common/defaultGameAttributes.ts @@ -47,6 +47,7 @@ const defaultGameAttributes: GameAttributesLeagueWithHistory = { nextPhase: undefined, // Used only for fantasy draft playerBioInfo: undefined, injuries: undefined, + tragicDeaths: undefined, daysLeft: 0, // Used only for free agency gameOver: false, godMode: false, diff --git a/src/common/helpers.ts b/src/common/helpers.ts index 5c5d3557d2..387a99cdc6 100644 --- a/src/common/helpers.ts +++ b/src/common/helpers.ts @@ -751,6 +751,7 @@ function formatCurrency( return "$0"; } + // Keep in sync with getSortVal if (append === "M" && abs > 1000) { abs /= 1000; append = "B"; diff --git a/src/common/index.ts b/src/common/index.ts index 717a821a3b..863baf464f 100644 --- a/src/common/index.ts +++ b/src/common/index.ts @@ -8,7 +8,7 @@ export { default as gameAttributeHasHistory } from "./gameAttributeHasHistory"; export { default as gameAttributesArrayToObject } from "./gameAttributesArrayToObject"; export { default as getAdjustedTicketPrice } from "./getAdjustedTicketPrice"; export { default as getDraftLotteryProbs } from "./getDraftLotteryProbs"; -export { default as getCols } from "./getCols"; +export { default as getCols } from "../ui/util/columns/getCols"; export { default as getPeriodName } from "./getPeriodName"; export { default as helpers } from "./helpers"; export { default as isSport } from "./isSport"; diff --git a/src/common/polyfill-streams.ts b/src/common/polyfill-streams.ts index 31a362b8f5..4913d7d91e 100644 --- a/src/common/polyfill-streams.ts +++ b/src/common/polyfill-streams.ts @@ -17,7 +17,7 @@ if (POLYFILL_STREAMS) { self.WritableStream = PolyfillWritableStream; } -// Chrome 58 +// Chrome 59 if (self.CountQueuingStrategy === undefined) { self.CountQueuingStrategy = PolyfillCountQueuingStrategy; } diff --git a/src/common/types.basketball.ts b/src/common/types.basketball.ts index 94c57440b9..2bc37ae442 100644 --- a/src/common/types.basketball.ts +++ b/src/common/types.basketball.ts @@ -71,7 +71,7 @@ export type AwardPlayerDefense = { export type Awards< PlayerOverride = AwardPlayer, - PlayerDefenseOverride = AwardPlayerDefense + PlayerDefenseOverride = AwardPlayerDefense, > = { season: number; bestRecord: AwardTeam; diff --git a/src/common/types.ts b/src/common/types.ts index 7df0cd9b5e..80d79962b2 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -1,6 +1,5 @@ import type { Face } from "facesjs"; import type { MouseEvent, ReactNode } from "react"; -import type { Context } from "../ui/router"; import type processInputs from "../worker/api/processInputs"; import type views from "../worker/views"; @@ -440,6 +439,11 @@ export type InjuriesSetting = { games: number; }[]; +export type TragicDeaths = { + reason: string; + frequency: number; +}[]; + export type GameAttributesLeague = { aiJerseyRetirement: boolean; aiTradesFactor: number; @@ -565,6 +569,7 @@ export type GameAttributesLeague = { ties: boolean; tradeDeadline: number; tragicDeathRate: number; + tragicDeaths?: TragicDeaths; userTid: number; userTids: number[]; @@ -666,7 +671,7 @@ export type GameProcessedCompleted = { }; export type League = { - lid?: number; + lid: number; name: string; tid: number; phaseText: string; @@ -909,13 +914,6 @@ export type LocalStateUI = { userTid: number; userTids: number[]; username?: string; - viewInfo?: { - Component: any; - id: string; - inLeague: boolean; - context: Context; - cb: (a?: Error) => void; - }; title?: string; hideNewWindow: boolean; jumpTo: boolean; @@ -937,7 +935,6 @@ export type LocalStateUI = { moreInfoTid?: number; stickyFooterAd: boolean; stickyFormButtons: boolean; - stickyMultiTeamMenu: boolean; }; export type PartialTopMenu = { @@ -1053,7 +1050,7 @@ export type PlayerWithoutKey = { firstName: string; gamesUntilTradable: number; hgt: number; - hof: boolean; + hof?: 1; // Would rather be boolean, but can't index boolean imgURL: string; injury: PlayerInjury; injuries: { @@ -1067,6 +1064,7 @@ export type PlayerWithoutKey = { lastName: string; moodTraits: MoodTrait[]; note?: string; + noteBool?: 1; // Keep in sync with note - for indexing numDaysFreeAgent: number; pid?: number; pos?: string; // Only in players from custom league files @@ -1120,7 +1118,7 @@ export type PlayerWithoutKey = { valueNoPot: number; valueFuzz: number; valueNoPotFuzz: number; - watch: boolean; + watch?: 1; // Would rather be boolean, but can't index boolean weight: number; yearsFreeAgent: number; @@ -1629,6 +1627,7 @@ export type UpdateEvents = ( | "team" | "teamFinances" | "watchList" + | "customizeTable" )[]; export type RealPlayerPhotos = Record; diff --git a/src/ui/api/index.ts b/src/ui/api/index.ts index e98c56d08f..48c9511f96 100644 --- a/src/ui/api/index.ts +++ b/src/ui/api/index.ts @@ -116,7 +116,7 @@ const initAds = (goldUntil: number | undefined) => { // Add margin to footer - do this manually rather than using stickyFooterAd so