BikeControl (SwiftControl)
使用 Zwift Click、Zwift Play、Shimano Di2,或任何藍牙控制器搭配 MyWhoosh、Rouvy、Zwift 等。可於 iOS、Android、Windows 與 macOS 免費試用。
AI 翻譯
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗Live site: https://rhyman7.github.io/nfl/
A static GitHub Pages site. Sister site: the CFB Matchup Dashboard.
index.html) — a board with one row per game in the current
week, grouped by kickoff time. Each row has both teams (a block in the team's color,
record and points per game), the spread, the total, implied team totals and the venue,
in fixed columns so the lines read straight down. A spread or total that has moved
shows what it opened at underneath. The venue line carries the kickoff forecast
("Indoors" for domes and closed roofs). Once a game starts, scores join the teams and
the implied column shows the game's status. Click a row to open the game. "Print all"
prints every matchup, two landscape pages each.matchup.html?game=<id>) — one game: kickoff, venue, roof, kickoff
forecast, current spread and O/U; a Head to Head table (each
offense against the other defense, with league ranks and edges); then both teams'
full stat cards. Prints on two landscape pages.print.html) — opened by the "Print all" button: every game this week,
two landscape pages per matchup, and brings up the print dialog. Each team card still
has its own Print button (one team per portrait page).scripts/build_pdfs.py writes pdf/matchups.pdf, pdf/games/<game id>.pdf,
pdf/epa.pdf (the EPA page's Print all) and pdf/manifest.json; the Build matchup PDFs workflow reruns it whenever
data/data.json or the print layout changes. The links only show when the PDFs are
for the week on the page. print.html?game=<id> prints a single game.scripts/build_report.py), the printed matchup, the EPA matchup page and the
value board's matchup (rhyman7/fb-value-board). scripts/build_packets.py builds the source
PDFs and pdf/packets.json in the Build matchup PDFs workflow; packets.js stitches the pages
together in the browser (pdf-lib, vendor/). The buttons show once the packets are for the
week on the page; a game the value board doesn't model gets a three-part packet.epa.html, epa.js) — opponent-adjusted EPA, linked left of Weekly Edges.
Pick a game for Head to Head panels (adjusted EPA / play, pass and rush EPA, early-down
pass EPA, success rate, with the same rank bars as the matchup page) and both teams'
cards (raw vs. adjusted rank, QB EPA / dropback and CPOE, pace, neutral pass rate and
regression flags such as turnover margin or one-score record). Below that: the EPA
line and total against the current market for every game, a sortable 32-team ratings
table, and a walk-forward check of how the ratings have done against closing lines.
Print all prints every game (one landscape page each), then the board and the
ratings; Download PDF is the same as pdf/epa.pdf. The ratings are
data/epa.json, which scripts/build_from_nflverse.py writes next to data.json
using scripts/epa_ratings.py (garbage time dropped at 10–90% win probability, a ridge
regression on offense, defense and home field, projections pulled toward a pick'em);
the page works out each game's projection from those ratings and the current line.epa-explained.html) — linked right of EPA: what expected points and EPA
are, why EPA beats yards and points, what "adjusted" means here, how to read every part of the
EPA page, a routine for any game and the limits. Its example uses the current #1 team in net
EPA from data/epa.json; the rest of the page is static.edges.html) — a game board for the week (current spread and O/U,
implied team totals, line move since the week's first update, net EPA edge, referee
and his over/under record) and prop matchup tables by position (QB pass yds, RB rush
yds, WR/TE/RB rec yds) listing players whose opponent allows more than the league
average at their position, with a matchup factor and an adjusted average.compare.html) — the original dashboard: pick any two teams
and compare them side by side. Links like compare.html?t1=Buffalo%20Bills&t2=Miami%20Dolphins preselect teams.ratings.html) — plain-language definitions of SoS, OSRS,
DSRS and SRS and how to use them in a matchup. Its example uses the current top-SRS
team from data/data.json; the rest of the page is static.All pages read one file, data/data.json, and share common.js, teamcolors.js and
style.css.
Look. Graphite background, with team colors carrying the color: teamcolors.js holds
each team's primary and secondary color and derives readable versions for the dark page
and for print. The matchup header is a scorebug (each team's name on its color, lettered
in its secondary color, with the current line between them); the secondary is used as
listed when it can be read on the primary (3:1 for the big lettering, 4.5:1 for the small
lines). A lighter secondary that falls short is nudged lighter in the same hue; a black
secondary, or one too dark to read on the primary, is set in white. Lettering is never
black. Below 900px wide the scorebug stacks. The bar
under it lists kickoff, venue, and either the roof ("Dome") for indoor games or the kickoff forecast for
outdoor ones. Head to Head draws a bar for each side's league rank, and the side with the
edge shows in its team color. Type is Archivo, loaded from Google Fonts.
Player game logs. On every team card, each player name in the Passing, Rushing and
Receiving tables is clickable. Hovering (on a computer) shows a tooltip with that
player's week-by-week stats for the table, the opponent, and full-PPR fantasy points;
clicking or tapping opens a panel with the full game log (result, passing, rushing,
receiving, fumbles lost, fantasy points). The logs live in gameLogs in
data/data.json, keyed ABBR|player_id, and each player row carries a log key that
points to its entry. Fantasy points are nflverse's fantasy_points_ppr.
Team games and box scores. Team names in the matchup header and on every team card
are clickable. Hovering (on a computer) shows the team's games this season: week,
opponent, result, and the team's high passer, rusher and receiver by yards. Clicking or
tapping opens a panel with the same list; pick a game to see its box score (scoring by
quarter, team stats, every passer, rusher and receiver, scoring plays), which the
browser fetches from ESPN using the game's espnId. If ESPN can't be reached the panel
says so and links to the game on ESPN. The list is games on each team in
data/data.json.
Defense by game. Hovering the Defense Pass Yds/G dial on a team card (tap on a
phone) shows every game this season: the quarterbacks the defense faced, their
completions/attempts and passing yards, and the team total. The Rush Yds/G dial shows
the rushing yards allowed in each game; hover or tap a game for a second popup with the
opponent's running backs (carries and yards) and any other rushers. The data is allowed
on each entry in games ({pass, rush, passers: [{n, pos, yds, cmp, att}], rushers: [{n,
pos, yds, car}]}), built from nflverse's player and team stats, so the totals match the dials.
The Passing table's Avg/C column is passing yards per completion (ypc).
Prop check. The game log panel has a prop tool: pick a stat (pass/rush/rec yards,
receptions, TDs, combos, fantasy points), type a line, and it shows how many games he
went over, the average, the last 3 results, each game marked O/U, and what next week's
opponent allows for that stat (from the defense and defense-vs-position numbers).
Each player row carries pos for this.
Injury tags. Player names carry a tag from ESPN's injury report: O, D, Q, IR (injured
reserve), PUP or SUSP; hover it for the injury. The Fetch injuries Action
(.github/workflows/fetch-injuries.yml, every 3 hours in season, or by hand) runs
scripts/fetch_espn_injuries.py, which reads ESPN's per-team injury lists (core API), keeps
each player's latest entry and writes data/injuries.json in the same shape as ESPN's
league feed. The pages read that file; if it is missing or more than 2 days old they try
ESPN's league feed (site.api.espn.com/.../nfl/injuries) in the browser instead. That league
feed went stale in October 2026 (one team, a week old), which is why the file exists. If
neither loads, the tables show no tags. The daily build doesn't download the nflverse injury file.
Player search. The search box in the top bar finds any player in the team tables and opens his game log and prop check.
Week strip. Just left of the search box, the top bar lists every week of the season
(1 to 18), right-aligned so the last week sits beside the search. The current week is
outlined and the week on screen is filled in. A finished week (index.html?week=N) shows
that week's games with final scores and each team's record going into it; a row opens
matchup.html?game=<id> with the game header and the full box score from ESPN, and
nothing else. A later week shows the schedule so far (kickoff, venue, records and any
line) as plain rows that don't open anything. The stats, Head to Head, Weekly Edges,
Print all and the PDFs stay on the current week. When the bar is too narrow for one row
the page names shorten, then the strip and search drop to a second row; on phones the
strip scrolls sideways. The weeks come from data/season.json and each week's games from
data/weeks/<N>.json (same shape as schedule in data.json, plus awayRecord /
homeRecord); the site decides what is past or upcoming from the week in data.json.
Implied totals and line movement. The matchup header, the week board and Weekly Edges
show implied team totals from the current spread and O/U. lineOpen on each schedule
game is the line from the week's first update; the build keeps it when it reruns for the
same week, and the pages show how far the line has moved since.
EPA and success rate. Head to Head adds EPA per play and success rate for each
offense and defense, from nflverse play-by-play (eff on each team).
Yards per rush. Head to Head also has a Rush Yds / Att row: rushing yards divided by
rush attempts for the offense, and the same for what the defense has allowed
(rushYdsAtt on each team's offense and defense, from nflverse team stats). For a
defense, lower is better.
Referee. When nflverse has the week's referee assignment, the matchup header and
Weekly Edges show the referee with his over/under record and points per game. These
are the only multi-season numbers on the site (refereeSeasons, e.g. 2023–2026),
because one season gives a crew just a few games.
Betting Trends. The matchup and Compare Any Two Teams pages show each team's record against
the spread (overall, as favorite/underdog, home/away) and over/under record, plus a
game-by-game list, from nflverse's closing spread_line and total_line. The data is
betting on each team in data/data.json. It's left out of printouts.
Live scores. On game days the slate and matchup pages fetch live scores straight
from ESPN's public site API in the viewer's browser (live.js): the slate shows
scores, quarter/clock, possession and a "Live now" group; the matchup page adds a box
score (line score, team stats, player stats, scoring plays) under the game header. Both
refresh every 30 seconds while a game is live and do nothing before the pre-game window.
The box score is left out of the printout. The feed is unofficial, so if it fails the
pages fall back to the weekly data and show a short note.
Lines and forecast. On page load the slate and matchup pages ask ESPN's scoreboard
for each game's current spread and O/U; games without ESPN odds keep the weekly
nflverse line. The forecast comes from Open-Meteo (free, no
key) in the viewer's browser (weather.js), using each stadium's coordinates from
data/data.json: temperature, chance of rain and wind for the hour nearest kickoff.
Forecasts only reach 16 days out, and if either service is down the page simply leaves
that part out.
Stadium locations and roof types live in STADIUMS at the top of
scripts/build_from_nflverse.py (keyed by nflverse stadium_id). If a new stadium or
international site shows up, add a row; until then that game just has no forecast.
After changing any CSS or JS file, bump the ?v= number on the <link>/<script>
tags in every HTML page so browsers pick up the new version.
A Claude scheduled task runs every Wednesday morning during the season. It downloads the current season's nflverse data, gets standings/SRS from Pro-Football-Reference, runs:
python scripts/build_from_nflverse.py --season 2026 --src <download folder>
A second scheduled task reruns the same build Friday at about 5 PM ET to pick up the
final injury report, referee assignments and line moves. The download folder also needs
play_by_play_2026.csv.gz from the nflverse-data releases (pbp); without it the
build leaves EPA out. Injury tags come from data/injuries.json (Fetch injuries Action), so injuries_2026.csv
is left out on purpose (the build then notes that injury tags are left out).
and pushes the new data/data.json along with data/season.json and data/weeks/,
which the same build rewrites for the week strip (only the weeks that changed; a week
whose scores are missing there is filled in from ESPN in the browser). Besides team and player stats, the file
holds schedule (the current week's games and byes), season and throughWeek.
Each schedule game also carries espnId (for live scores), start (kickoff in UTC),
neutral, and the venue's city, lat, lon and indoor flag.
The sections below describe the original Excel-based workflow. It's no longer used but still works if you ever want to go back to it.
nfl).https://<username>.github.io/nfl/
— that's your live site.That's it. The site is now live and will re-deploy automatically any time
data/data.json changes.
Every week, replace the 14 Excel files in data/raw/ with your fresh
exports (same file names — just overwrite them) and push. A GitHub Action
(.github/workflows/rebuild-data.yml) automatically regenerates
data/data.json and commits it, which triggers Pages to redeploy. Usually
live within a minute or two.
The 14 expected files (case-sensitive names):
data/raw/NFL Records.xlsx
data/raw/NFL Offense.xlsx
data/raw/NFL Offense Rush.xlsx
data/raw/NFL Offense Pass.xlsx
data/raw/NFL Defense.xlsx
data/raw/NFL Defense Rush.xlsx
data/raw/NFL Defense Pass.xlsx
data/raw/NFL Passing.xlsx
data/raw/NFL Rushing.xlsx
data/raw/NFL Receiving1.xlsx
data/raw/NFL DEF v RB.xlsx
data/raw/NFL v RecRB.xlsx
data/raw/NFL DEF v TE.xlsx
data/raw/NFL DEF v WR.xlsx
You can update these either by:
data/raw/ on github.com,
click the pencil/upload icon, and upload the new version. No git needed.data/raw/ locally, then
git add data/raw && git commit -m "Week N update" && git push.If you want to preview changes before pushing:
pip install -r requirements.txt
python scripts/build_data.py
python -m http.server 8000
# open http://localhost:8000
From inside this folder:
git init
git add .
git commit -m "Initial NFL dashboard"
git branch -M main
git remote add origin https://github.com/<your-username>/nfl.git
git push -u origin main
(Create the empty repo on github.com first, without a README, so there's nothing to conflict with.)
Offense/Defense Rush/Pass rank tables (rank 1 = best).NFL Records.xlsx.DEF v RB/TE/WR/RecRB files (i.e., how that team's defense performs
against the position, not an opponent-specific matchup).NFL Offense.xlsx.Note: the old Looker Studio report had a broken "Offense Pass Yds/G" gauge (it showed a static, non-updating number). This site fixes that — the offense column now has a real, working Pass Yds/G gauge and rank alongside the Rush Yds/G one.
Built by scripts/situational.py (called from build_from_nflverse.py) into each team's
situ, pace and usage keys, plus ts/ts3 on receiving rows and cs on rushing rows.
It downloads snap_counts_<season>.csv and advstats_week_pass/def_<season>.csv from the
nflverse-data releases into --src when they aren't there.
pass_oe).Printouts and the matchup PDFs include them: each matchup prints on two landscape pages (header, Head to Head and pace on the first; both team cards with usage on the second). Betting trends stay screen-only, as before.
how-to-read.html)Linked left of EPA. Walks through every section of a matchup page (game header, Head to Head,
pace, betting trends, team card, player tables and game logs, usage, defense vs position) using
one game from this week, with numbered markers on the real components and notes written from
that game's numbers (how-to-read.js, built on the same render functions as the matchup page).
It opens on a random game; the Game picker and "Pick another game" switch games, and
?game=<id> opens a given one. Nothing extra to build: it reads data/data.json.
data/props.json)The Fetch player props workflow (.github/workflows/fetch-props.yml, Thursdays at 15:07 UTC
and by hand from the Actions tab) runs scripts/fetch_props.py, which pulls seven markets for this
week's games from The Odds API at DraftKings and FanDuel only: pass yds, pass TD, rush yds, rush
attempts, rec yds, receptions and anytime TD. The key is the ODDS_API_KEY repository secret. Each
game costs 7 credits (about 105 a week, roughly 450 a month against the free plan's 500); games
already under way are skipped (and kept from the week's earlier pull), and the run stops before
using the last 25 credits. The file keeps each book's own line and prices per player (dk, fd),
and a teams map putting each player on one of the game's two teams from nflverse's weekly
rosters (team defenses left out). python scripts/fetch_props.py --tag-teams redoes that map
without the API key or any credits.
Where it's used. The sportsbook lines aren't shown anywhere on the site (the DraftKings /
FanDuel buttons and prop-line columns were removed in Oct 2026). The file is only used for the
matchup header's quarterback before kickoff: the team's player with the highest passing-yards
prop (heroQb() in common.js). Without the file it falls back to nflverse's starter.