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 ↗Same stack and philosophy as nflprob: Vercel serverless functions + optional Supabase Postgres +
a single-file vanilla-JS frontend (app.html), free data only, every model output shipped with
its "why".
The core idea: one Monte Carlo tournament simulator feeds every market, so finishing odds, top-N, make-cut, 2-balls and 3-balls can never contradict each other.
| Tab | What it shows |
|---|---|
| Finishing odds | Win / top 5 / top 10 / top 20 / make cut, fair odds, avg finish, draw (AM/PM) with weather cost, signals, confidence. Once the event starts, a Pos column shows leaderboard position, total to par and holes completed (sortable). Click a player for the finish distribution, recent rounds, tee times and reasoning. Upload book odds for an Edge column. |
| Best plays | Top bet targets in three sections, each with per-play reasons and a summary of what separates them from the rest of the slate: matchup targets (one per group), finishing position (Win / Top 5 / 10 / 20 / Make cut) and the best 3-, 4- and 5-leg finishing-position parlays (Top 10 / Top 20 / Make cut, priced inside the simulation). With uploaded book prices a section ranks by expected profit and only keeps plays at 3%+ EV with a realistic chance to hit; without prices it ranks by model strength and says so. |
| Matchups | Every 3-ball / 2-ball from the real tee sheet (R2 projected from R1 until posted), dead-heat-adjusted. Upload a CSV of book prices → de-vigged edges and a "best prices" list ranked by EV. Parlay builder: tap players to add legs; legs are priced together inside the simulation (shared wave, same player both rounds), with fair odds and EV vs your book. Auto-build finds the best 2/3/4-leg parlays (by EV with book prices, else most likely). |
| DFS Optimizer | DK Classic projections (mean, floor, ceiling) from the same sims. Upload DKSalaries.csv → exact optimizer (6 golfers, $50k): Projection / Balanced / Ceiling, 1–150 lineups, exposure cap, min unique players, draw (wave) stacking, locks/excludes, exposure table, and a CSV in DK's upload format. |
| Weather | Draw verdict with ensemble agreement, day cards, hourly wind/gust chart with ensemble band and wave ribbons, direction strip, wind-by-wave compass, rain and temperature, a wave comparison table, and a full generated briefing. |
| Model & backtest | History data status, the live track record (each week's locked pre-tournament projection graded when final: market skill, winner rank, 3-ball favorites vs expected) and a leak-free backtest: Brier / log loss vs no-skill, calibration chart + table, per-event results. |
lib/store.js) — every completed round from ESPN (PGA + LIV + DP World by default,
TOURS env to change), stored in golf_rounds. Without a database it falls back to fetching
the most recent ~40 events live.lib/ratings.js) — two-way fixed effects
strokes = round difficulty + player ability, solved by alternating least squares, so a 68
against a weak field isn't worth a 68 at a major. Players who cross tours link the scales.lib/simulator.js) — 15,000 tournaments: a per-week form draw (plus skill
uncertainty), per-round noise, shared wave shocks, the cut (rule from ESPN → event name → field
size), integer scores so ties/dead heats/pushes happen naturally, playoffs. Completed rounds use
real scores; a round in progress uses strokes so far + only the remaining holes.lib/dk.js, lib/dk-optimizer.js) — each simulated round score becomes expected
DK hole points via tour-average par-3/4/5 outcome rates tilted to match the score (exact bogey-free
and birdie-streak probabilities over the real hole pars), plus finish points and the under-70 bonus
from the same sims. The optimizer is nflprob's exact knapsack (full prefix table), brute-force
verified; multiple lineups are each the exact best under exposure/uniqueness rules (branch and
bound), with exact dominance pruning. Runs in a Web Worker.lib/parlay.js) — legs settled per simulated tournament (3-ball dead heats, 2-ball
pushes), so the joint probability is counted, not multiplied.lib/grading.js) — the pre-tournament projection is re-saved on every visit until the
first tee time; finished events are graded on visit and by the weekly cron.lib/weather.js) — Open-Meteo hourly forecast + GFS 31-member ensemble. Each tee
time's cost averages ~5 hours of conditions (wind², gusts > 25 mph, heavy rain). Each sim draws
one ensemble member, so forecast uncertainty flows into the odds. Weekend tee order follows the
simulated leaderboard. lib/weather-writeup.js writes the briefing from the same numbers.npm test) on synthetic data with known ground truth: fixed effects recover
true skill across strong/weak fields, no leakage, probabilities sum correctly (one winner, top-10
dead-heat shares sum to 10), 3-ball prices match brute force, wave costs move the right players,
and an end-to-end run of every route with mocked ESPN/Open-Meteo./api/health, Oct 23 2026).
Findings applied: the leaderboard has per-round strokes / to-par / nine totals but no
hole-by-hole detail; the competition's round number lags the players' own; only the current
round carries a start hole. Rounds in progress are rebuilt from the course's hole pars + today's
to-par. Hole-by-hole (needed for DK scoring) will come from ESPN's core API in the DFS step.DATABASE_URL (or POSTGRES_URL, which Vercel's Supabase integration sets) to a Postgres connection string. In Supabase: Project Settings → Database → Connection string → URI, transaction pooler (port 6543). Tables create
themselves on first use./api/health to confirm ESPN + Open-Meteo shapes./api/sync?tour=pga&season=2025 (then 2026, and tour=liv,
tour=eur) repeatedly until each returns remaining: 0. A weekly cron keeps it current.Without a database everything still works — the model just runs on a shorter live history.
| Route | Purpose |
|---|---|
/api/tournament?tour=pga&event={id}&sims=15000 | Field, ratings, simulated odds, matchups |
/api/weather?tour=pga&event={id} | Forecast, waves, draw verdict, briefing |
/api/events?tour=pga&season=2026 | Season calendar for the event picker |
/api/backtest?tour=pga&events=8 | Leak-free backtest |
/api/sync?tour=pga&season=2025 | Backfill completed events into Postgres |
POST /api/parlay | Price a parlay {legs:[{round,id,dec}]} or auto-build {auto:{round,size}} |
POST /api/plays | Best plays {book:[{market,round,id,dec}]} |
/api/grades | Grade finished snapshots, return the live track record |
/api/status | History data status |
/api/health | Upstream checks + ESPN shape report |
lat/lon query params override the course location if the lookup is wrong.
market,round,player,odds
3ball,1,Scottie Scheffler,+150
3ball,1,"Aberg, Ludvig",+220
2ball,3,Xander Schauffele,-115
top10,,Rory McIlroy,+275
Markets: 3ball, 2ball, win, top5, top10, top20, make_cut. American or decimal odds.
Names match through accents, "Last, First", initials and Jr./III suffixes (an ambiguous name is never
guessed). Uploaded files stay in the browser (localStorage), per event.