Bygga
제품명을 박스에 입력하면 Bygga가 3D로 모든 조립 단계와 부품·스크류·도구를 보여주고 음성으로 안내합니다
공공 데이터 기반 식당 앱, 공식 검사 결과와 자체 평점을 제공, 21개 주에서 이용 가능
Restaurant apps from public records and open data: official inspection results or our own grades where available, hand-checked local picks. Now in 21 states.
라이프스타일Python · JavaScriptGitHub @nickstrom5온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Eats Ranked: landing page for a family of free state restaurant apps built from public inspection records. Static site, generated by Python.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗The landing page for Eats Ranked: free restaurant apps, one state at a time, built from public records.
It links each state's app and website (the live states are the "status": "live" entries in tools/site-data.json),
shows a hex-tile U.S. map of where we're live, explains how the apps work, answers common questions, and has a short
"Eating out, by the numbers" section from the Bureau of Labor Statistics.
The site is one static page served by GitHub Pages from docs/ at https://eatsranked.com/.
It makes no requests to other hosts (no fonts, CDNs or analytics), sets no cookies and needs no build
step on the server: styles, script, map and chart are inline in docs/index.html.
docs/ what GitHub Pages serves
index.html generated by tools/build.py (don't edit by hand)
404.html, sitemap.xml, robots.txt, CNAME, site.webmanifest, .nojekyll, .well-known/security.txt also written by build.py
icons/ each state app's icon (256x256 PNG) and the WebP copy of it that the page loads (make_images.py)
favicon.svg, favicon.ico, favicon-32.png, apple-touch-icon.png, icon-192.png, icon-512.png, og.png from make_images.py
tools/
site-data.json the single source of truth: states, taglines, links, App Store status, colours, icons, BLS prices
us-states-paths.json state names and codes (the map itself is a hex-tile layout, HEX_ROWS in build.py)
template.html, app.js, template-404.html the page template and its script
build.py site-data.json + template -> docs/
update_prices.py refreshes the BLS series in site-data.json, then rebuilds
make_images.py favicons, the 1200x630 share image and the WebP icons
verify.py recomputes every number from site-data.json and checks the page
browser_check.mjs headless-Chrome checks (layout 360-1600 px, map keyboard/hover/tap, no outside requests)
tools/site-data.json is the canonical copy of the site data from now on. It started as a copy of the
hub's site-data.json (the two were identical at hand-off, including Illinois' "region": "Chicago + Illinois");
edit this one, not the old hub file.
python3 tools/build.py # Python 3.9+, standard library only
python3 tools/build.py --data some.json --dry-run # does the page build from this data? writes nothing
python3 tools/verify.py # static checks, then serves docs/ locally and fetches every link
python3 tools/verify.py --browser # also runs tools/browser_check.mjs (Node 22+ and Google Chrome)
build.py only moves the sitemap's lastmod when index.html actually changes. Every number on the page
(the three stats, the $20 comparison, the chart, its table and hover readout) is computed from the BLS
series in site-data.json; verify.py recomputes them independently and fails if any number on the page
isn't one of them, a year, or a number that is in site-data.json itself.
To look at it locally: python3 -m http.server 8741 --directory docs and open http://127.0.0.1:8741/.
Put the app icon in docs/icons/ (256x256 PNG, e.g. docs/icons/texas.png).
Add an entry to states in tools/site-data.json:
| field | used for |
|---|---|
abbr | two-letter code; must match tools/us-states-paths.json |
status | "live" puts it on the page and fills it on the map; anything else counts as coming soon |
app, tagline | card title and text |
tagline_short | optional shorter text for the map's pop-up card |
region | optional eyebrow label (e.g. "Chicago + Illinois"); defaults to the state name |
site, how | website button; "How it works" link (left out when it's the same URL as site) |
web_app, web_app_label | optional web app link (e.g. "Search on the web") |
guides | optional list of {"label", "url"}: the state's best guide pages (e.g. a fish fry guide), shown as links on its card so the hub links deeper than each home page; plain https:// like every link |
app_store | App Store URL once the app is approved; null shows "Coming soon to the App Store" (not a link) |
app_store_note | hover text on the coming-soon badge; keep it true (e.g. add "(in review)" only once the build has actually been submitted to App Review) |
platforms | e.g. "iPhone & iPad, free" (shown as "iPhone & iPad · Free") |
colors.bg, colors.accent, colors.text | card colours; bg fills the state on the map, accent fills it in dark mode. If accent reads below 4.5:1 on bg, the card's label, button and focus ring use the nearest same-hue shade that passes (build.py prints a note); verify.py fails if text doesn't pass |
The map's icon position, the "Now in …" lines, the legend swatch, the meta description and the
JSON-LD all follow from the data; nothing else needs editing. If a card names MICHELIN (or Bib Gourmand) or
James Beard, the footer adds the trademark line for it by itself (and drops it when none does); verify.py checks.
Each page carries a Content-Security-Policy <meta> that allows only its own inline scripts and <style> blocks, by
hash: no script files, no 'unsafe-inline'. build.py turns every style="…" attribute into a generated class
(zs0, zs1, …) whose rule goes in one more hashed <style> block (hoist_styles), so templates may still use style
attributes; app.js sets positions through element.style, which the policy allows. build.py recomputes the hashes on
every build, so never edit docs/index.html by hand: a stale hash stops the script or the styles (verify.py checks
them, and that no style attribute is left in the markup). docs/.well-known/security.txt expires on the date in build.py
(SECURITY_TXT_EXPIRES); verify.py fails once it has passed, so move it on a year and rebuild.
While any live app still has app_store: null, the page says On the web now (section label, map legend,
map labels) and "Now in Illinois and Wisconsin". Once every live app has its App Store URL it switches to
Live now by itself. The meta description never claims the apps can be installed.
python3 tools/update_prices.py
Pulls every series listed under prices.series from the BLS public API v1
(https://api.bls.gov/publicAPI/v1/timeseries/data/, one POST, the last 10 years, no key), writes them
into site-data.json, regenerates the source line ("through . BLS did not publish data.")
and rebuilds. Months BLS didn't publish (value -, e.g. October 2025) are kept as null and drawn as a
gap. It writes nothing if a series comes back empty, short, or older than what's already there, or if
the page wouldn't build from the new data (it runs build.py --data <new file> --dry-run first), so
site-data.json and docs/index.html never disagree.
The Chicago/Midwest/U.S. 12-month stat needs the same month a year earlier. BLS skipped October 2025, so when
the latest month is October 2026 that stat uses September 2026 (the stat names its month; build.py prints a
note). Everything else uses the latest month.
The keyless API allows 25 queries a day, so run it once after each monthly CPI release (around mid-month),
then python3 tools/verify.py and commit. --out some.json fetches without touching site-data.json.
If the copy's claims stop being true (for example restaurants no longer outpacing overall prices, or groceries falling), the wording switches automatically ("outpacing" -> "compared with", "rose" -> "fell", chart title) rather than stating something false.
../chi-eats/.venv/bin/python tools/make_images.py # needs Pillow and Google Chrome
Draws the Eats Ranked mark (three bars, the last in the accent colour) into the favicons and renders
og.png (wordmark, "Restaurants, ranked state by state.", each live app's icon) with headless Chrome.
It also saves each state's icon PNG as a WebP of the same 256x256 size (quality 85, about a fifth of the bytes:
the 9 icons went from 121 KB to 26 KB), named after the PNG's SHA-256: icons/texas.<first 10 hex digits>.webp.
build.py (standard library only) works out the same name and loads the WebP when it's there for that exact PNG,
otherwise the PNG, so a replaced PNG never shows its old WebP; run build.py after make_images.py. The PNGs stay:
they're what og.png and the README's add-a-state step use. make_images.py --icons writes only the WebP icons.
verify.py warns when a live state's icon still loads as its PNG, and fails if a state's icon loads as a WebP made from another version of its PNG, or as a WebP that isn't on disk.
nickstrom5/eatsranked and push main.main, folder /docs. Custom domain eatsranked.com
(already in docs/CNAME); once the DNS check passes, tick Enforce HTTPS.https://eatsranked.com/ loads, https://eatsranked.com/nope shows the 404 page, www redirects,
and a link preview (iMessage, Slack) shows og.png.https://eatsranked.com/sitemap.xml in Google Search Console and Bing Webmaster Tools.When an app is approved on the App Store: set its app_store to the listing URL
(https://apps.apple.com/app/id<APP_ID>; Chicago Restaurants: Ranked is app_store_id 6816931379), run
build.py and verify.py, commit. The badge becomes a "Download on the App Store" link, on the state's card and on
its map pop-up; verify.py checks each of them (so the page has two App Store links per app). To use Apple's
official badge artwork instead, download it from Apple's marketing tools and commit it under docs/
(never hotlink it). When chicago.eatsranked.com is live, point Illinois's site and how at it
(future_site).
states-albers-10m, ISC License,
Copyright 2013-2019 Mike Bostock (full text in tools/us-atlas-LICENSE.txt), derived from U.S. Census
Bureau cartographic boundary files.Not affiliated with any government agency. Official inspection results are shown as published; grades of our own are labeled as ours. Contact: [email protected]
iconpath under docs/, e.g. "icons/texas.png"; keep pointing it at the PNG. The page loads make_images.py's WebP of it (icons/texas.<hash>.webp) once that exists |
pin | optional [x, y] for the state's map icon and label, in the units of tools/us-states-paths.json (viewBox 0 0 975 610; Connecticut's icon sits at about [888, 189]); it must lie inside the state. Leave it out and the icon goes to the point deepest inside the state. Set it when that point puts the icon over a neighbour's: verify.py --browser fails if two map icons overlap at 320-1600 px |
Every link (site, how, web_app, app_store) must be a plain https:// URL: build.py stops on any
other scheme or on spaces, backslashes and control characters, and verify.py checks every link on the built pages.
Run …/python tools/make_images.py (so the share image shows the new icon and the icon gets its WebP), then
python3 tools/build.py, then python3 tools/verify.py --browser, and look at the page at phone and desktop width.