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 ↗A daily GitHub Action pulls box scores with hoopR, builds every team's stats by window (YTD, L3, Home, Away, Prior) plus league averages, writes them to web/public/data/, and commits. The commit triggers a Vercel redeploy of the Next.js site.
The pipeline does no model math. Projections come from the Model sheet in web/model.json: a spreadsheet laid out like Sam's Team v Team tab, edited on the site's Model page and run for every game.
Full spec: docs/NBA_MODEL_SPEC.md.
pipeline/
config.R season types, league-average and rate methods
stats.R the 41 stat definitions (numerator / denominator per team-game)
fetch.R hoopR box scores + schedule, ESPN fallback for games missing from the bulk file
team_games.R one row per team per game with opponent stats joined, possessions
windows.R YTD / L3 / H/A / Prior team values and league averages as of a date
export.R per-date slate JSON (games + stat inputs)
stats_export.R raw stat tables (CSV + JSON)
run.R entry point
tests/ unit tests (run_tests.R)
web/ Next.js site (reads web/public/data and web/model.json at build time)
.github/workflows/daily.yml
Every run writes the model's inputs to web/public/data/stats/ (overwritten daily, history in git):
| File | Contents |
|---|---|
team_stats.csv | One row per team per window (YTD, L3, Home, Away, Prior) with games played and all 41 stats |
league_averages.csv | League average per window (mean of the 30 teams) |
team_games.csv | Every team-game this season and last: box score, opponent box, possessions, per-game stats |
slate.csv | Today's games and tip times (UTC) |
On the live site they're at /data/stats/<file>. The Team stats page lists them with a ready-made
=IMPORTDATA("…") formula for Google Sheets. Rates are decimals (0.523 = 52.3%).
Requires R 4.4+ with hoopR dplyr tibble jsonlite testthat, and Node 20+.
Rscript pipeline/tests/run_tests.R # unit tests
Rscript pipeline/run.R # today's slate (Eastern date)
Rscript pipeline/run.R --date=2026-10-23 # one date
Rscript pipeline/run.R --backfill # every slate this season through today
cd web && npm install && npm run dev # http://localhost:3000
run.R skips (with a warning) any slate where a team has no stats.
web, and keep the default Next.js settings. Every push to main redeploys.The Model page is a spreadsheet laid out like the Team v Team tab: score and stat line at the top, then YTD / L3 / H/A / Prior / Weighted rows for each stat, with Home, Away, Weight, League Average, Difference, Adjusted and Expected columns. Pick the home and away teams and every stat cell fills in.
=[Home YTD Points/Game], =[Away H/A EFG%], =[League Home Points/Game], =[Home Team].
H/A = the home team's home games / the away team's away games. -- = no games in that window.A1, $D$8, ranges B13:B16, + - * / ^ &, comparisons,
SUMPRODUCT, SUM, AVERAGE, MIN, MAX, ROUND, ROUNDUP, ROUNDDOWN, MROUND, ABS, IF, IFERROR.-- is 0 inside SUMPRODUCT/SUM and #VALUE! in plain arithmetic.Edits are kept in your browser as a draft. To publish: Download model.json, then upload it to the
web/ folder on GitHub and commit. Vercel redeploys and every visitor sees the new projections.
npx tsx scripts/build-model-template.ts (in web/) rebuilds the starting template, overwriting model.json.
Possessions use 0.475 x FTA and seasons include play-in and playoff games, both to match TeamRankings.
Still open: whether rate stats within a window should be
ratio of totals (current) or average of game rates (pipeline/config.R).
web/scripts/tune-weights.ts picks each stage's weights by backtest over the last three seasons (every
YTD/L3/H/A/Prior combination, scored on margin + total error, checked leave-one-season-out). The daily
workflow re-tunes on Mondays. Weighted rows skip windows with no games instead of counting them as 0.web/scripts/confidence.ts re-projects every game since 2023-24 through the published sheet with
point-in-time stats, joins sportsbook lines (pipeline/cache/lines.csv, via ESPN), and fits three models,
each validated leave-one-season-out (a model that doesn't beat a flat guess shows its base rate):
public/data/confidence_games.json (every slate game) and the report behind the Confidence page.
Research scripts: research*.ts (what was tested and rejected)./tracking): every finished game by team, home/away, model favourite/underdog and spread size
(ML W-L, covers vs the model or the sportsbook); precedents for each matchup on game pages, slate cards and the
Model page. Tested as a confidence feature (research6.ts): situational records do not predict future covers
(they slightly reverse), so they are shown but not used in the confidence %.pipeline/cache/inputs_<season>.ndjson.gz; rebuild them with
Rscript pipeline/backtest_inputs.R 2024 2025 2026 after changing stat definitions.pipeline/injuries.R): BPM-style, from Hollinger Game Score per 100 possessions scaled to
team net rating, shrunk toward replacement (-2), point-in-time.pipeline/injury_reports.py, the last report
at least an hour before tip, Out/Doubtful); today uses ESPN's injury report. Sheet references:
[Home Injury Value | BPM | Minutes | Count | List | DTD]. The Injuries section's adjustment (method 1, value lost
x 0.4; method 2 = BPM/2 each way; 0 = off) feeds the score cells.[Home Lineup Strength] = available players' ratings x projected minutes. The
section blends the sheet's margin 30% toward the player-based margin.pipeline/darko.py archives DARKO's free daily board to pipeline/cache/darko/ (no history is
published), so DARKO can be backtested once snapshots accumulate. EPM's terms prohibit copying its data.docs/SHEET_FORMULAS.md has the spreadsheet's formulas (reverse-engineered from docs/sheet_export_lal_bkn.csv) for reference when rebuilding them on the Model page.