NBA Feed
팀 뉴스와 경기 정보를 제공, 점수는 직접 확인할 때까지 숨겨져 있습니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A no-build web app for figure-skating dryland training, in the "Skate with
Grace" design system (rose/gold palette, Quicksand + Dancing Script) and
loaded with the Jenn Skating Dryland 2026.2 plan. It runs on the same
engine as the sibling Swimming Dryland Timer — the same files, shared as a
subtree — so a rule is one rule for both athletes, and only the plan, the
ranks, the prizes and the artwork are this app's own.README 전문 보기 ↗A no-build web app for figure-skating dryland training, in the "Skate with Grace" design system (rose/gold palette, Quicksand + Dancing Script) and loaded with the Jenn Skating Dryland 2026.2 plan. It runs on the same engine as the sibling Swimming Dryland Timer — the same files, checked identical by CI — so a rule is one rule for both athletes, and only the plan, the ranks, the prizes and the artwork are this app's own.
Everything that does not name the sport lives under core/: the session
engine, the store, the XP and prize rules, the grown-up gate, the cloud sync,
the screens, the service worker and the test harness. It is byte-identical in
both repositories. What makes this app this app is three things it owns:
js/sport.js — its identity: names, storage keys (unchanged, so history
carries over), the Firestore collection, the mascot and body-map images,
the twenty lines of copy that mention ice, and FEATURES.landingCheck.js/data.js — its content: the plan, the ranks and lore, the prizes, the
readiness copy, the Coach's Quiz. Built with the mechanism in core/plan.js.css/tokens/*, css/fonts.css, assets/, index.html,
manifest.webmanifest and the two-line sw.js that configures the shared
worker — the design system and the shell.A change to the rules is made once, in core/, and the same core/ folder is
copied to the sibling app in the same change: one pull request in each repo,
on a branch with the same name. CI checks it: the "Shared core is the same in
both apps" step compares this repo's core/ with the sibling's branch of the
same name (or its main) and fails on any difference.
6 training days + Sunday recovery, each run as up to 5 blocks:
① Warm-up → ② Coordination → ③ Main (traffic-light rounds) → ④ Finisher → ⑤ Skate-Skill (Axis Micro + Spin Board), with a Prep Pair inserted after Main on the days that carry one.
The light decides the whole session, not just the round count: green runs every block with 3 main rounds, yellow drops the prep pair and finisher and runs 2, red keeps warm-up, main and skate-skill with 1, recovery runs the recovery circuit only. Same policy as the swim app, block for block.
Timed vs rep moves. A timed move carries work seconds and runs a
countdown. A rep move is counted by the coach from its structured
prescription — sets × reps × sides × directions, tempo, hold — parsed once
from the dose text at load, or written out explicitly beside a dose the
parser cannot read ("3 × 4s ecc + max clean"). A dose the parser cannot
read fails at load, never quietly counts to ten.
Quality gates. The valgus gate is a ceiling on jump progressions: locked, every jump stays at Box Jump → Stick; unlocked, the bounds, rotational and single-leg landings run. It unlocks after clean weeks on the gate move and a parent-verified form check can close it again. Spin-dizziness stop and the never-to-failure pull series are in the plan's cues.
Landing check + jump-fatigue tier-drop. After every valgus-gated jump the
athlete grades the landing clean & frozen vs a bit wobbly before the rest
starts. Two wobbly landings in a row remove the highest remaining main round
(🟢→🟡→🔴, never the round in progress) with a spoken "quality over quantity"
cue, and the day's plan is lowered with it — so XP, the finish screen and a
same-day resume all agree on what the day asked for. Grades are recorded per
move for the grown-up watch-list. The rule lives in the core behind
FEATURES.landingCheck; this app turns it on, the swim app leaves it off.
Landings pay nothing extra: a session is priced on the rounds it trained,
exactly as in the swim app.
Identical to the swim app's, from the same file (core/store.js,
core/outcome.js):
dayComplete): every move attempted, nothing
skipped, none under half its dose, every planned main round counted — the
same door that earns the streak and pays the full day, so the week strip, the
day card, the log, the Grown-up boards and the finish screen cannot disagree.
A move counts (✓) at 80 % of its time or all of its reps, reads ½ when short,
⏭ when skipped or under 3 s; the day card and the finish screen show that
verdict per move with the reason, under a one-line legend.500 + (n−1)×30 to level 8, 1000 + (n−9)×45 to 17,
after — frozen, running to level 50 (Winter Sovereign).No build step — serve statically (ES modules need http, not file://):
python3 -m http.server 8000 # then open http://localhost:8000
npm test # every suite, in two timezones
npm test runs core/test/run.mjs, which runs every suite in its own
process under the default timezone and America/New_York and reports every
failure: the core's action-layer, invariants, integrity, landing-rule and
offline-shell suites against this app's content, the day-record suite, and
test/smoke.mjs, which
checks what only this app can get wrong — its plan, ranks, prizes, demo links
and readiness copy. On a pull request CI also runs
core/tools/release-check.mjs: a precached shell file that changed without a
bump of version in sw.js fails the build.
dayRecords() in
core/outcome.js settles each training day once: its sittings are grouped by
the weekday the day was for and the date it began (a session across midnight,
or a Monday caught up on Wednesday, is one day everywhere), never by a
device-local id, so a morning on the iPad and an afternoon on the phone are
one workout. Its rows are the merged log plus work banked live but never
saved; its ask is what the day was started under, lowered only by a
jump-landing tier drop; its minutes are summed in seconds and rounded once;
movements are reported in both units, distinct moves and performances; a pain
stop is a sitting's fact, not the day's verdict when she comes back and
finishes; the override flag is set only when an adult changed the light. The
finish screen, Today, Progress, the Grown-up Zone, the Body Check result and
the CSV read that record and nothing else — core/test/invariants.mjs
asserts no screen computes a day-level fact on its own, and
core/test/dayrecords.mjs drives fourteen days through the real engine.bankedRows, bankedSecs) — so a sitting
the iPad lost mid-way still counts by name. "I need to start over" clears it.localStorage, namespaced skate* / skate_*. Keys are unchanged
from the previous version, so existing history and progress carry over; a
journey written by the earlier draw ledger carries its high-water level
across on first boot.jenn_skating_sessions (session
rows, one journey-<athlete> doc, one readiness-<athlete> doc of abnormal
checks). The sync is both ways on every boot and only ever additive; the
journey is merged before it is written, so one device cannot erase the
other's prizes. The previous global journey-state document is still read.firestore.rules,
byte-identical in both repositories, naming both collections. Deploy from
either repo with
npx firebase-tools deploy --only firestore:rules --project chore-tracker-a461b.
The mirror has no sign-in; the rules confine a misbehaving client, not a
hostile one, and the app renders every stored string as text.core/sw-core.js, configured by sw.js)
precaches the shell, so an Add-to-Home-Screen launch with no network boots
and can run a whole workout — bump version in on every release.index.html # shell: loads css/ + core/main.js, registers sw.js
core/ # the shared engine (same in both repos; CI checks it)
js/sport.js # this app's identity: names, keys, images, copy, features
js/data.js # this app's content: DAYS, ranks/lore, quiz, readiness
css/tokens/*.css # Skate with Grace design tokens
css/fonts.css # self-hosted Quicksand + Dancing Script
css/app.css # shell/nav/buttons/keyframes
sw.js # cache prefix + version + the app's own shell files
manifest.webmanifest # Add to Home Screen
firestore.rules # shared with the swim app
test/smoke.mjs # this app's content tests
assets/skate/*.png # mascot illustrations + body maps
assets/exercises/ # optional per-move photos: "<Name> - Timer Image.png"
1500 + (n−18)×50sw.js