Sergei Argutin commited on
Commit
b9f2bbe
·
verified ·
1 Parent(s): 5671a81

Publish RepDB free dataset explorer

Browse files
Files changed (2) hide show
  1. README.md +17 -4
  2. index.html +191 -17
README.md CHANGED
@@ -1,10 +1,23 @@
1
  ---
2
- title: Repdb Exercise Dataset Explorer
3
- emoji: 🌖
4
- colorFrom: yellow
5
  colorTo: gray
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: RepDB Exercise Dataset Explorer
3
+ emoji: 💪
4
+ colorFrom: green
5
  colorTo: gray
6
  sdk: static
7
  pinned: false
8
+ license: other
9
+ short_description: Browse 400 multilingual exercises with WebP images.
10
  ---
11
 
12
+ # RepDB Exercise Dataset Explorer
13
+
14
+ Interactive browser for the [RepDB free exercise dataset](https://huggingface.co/datasets/sargutin/exercise-dataset).
15
+
16
+ The free tier contains 400 exercises with English, German, and Spanish instructions,
17
+ muscles, equipment, MET values, tags, and flat 512×512 WebP images. Commercial
18
+ in-app use is allowed with attribution; see the dataset card for the full license.
19
+
20
+ [Free dataset and documentation](https://repdb.co/free-exercise-dataset) ·
21
+ [Paid bundles](https://repdb.co/pricing)
22
+
23
+ Disclosure: this Space is maintained by the creator of RepDB.
index.html CHANGED
@@ -1,19 +1,193 @@
1
  <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
  <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Free Exercise Dataset — 400 Exercises, JSON + Images (EN/DE/ES) · RepDB</title>
7
+ <meta name="description" content="Browse RepDB's free exercise dataset: 400 exercises in JSON with flat illustrations, target muscles, equipment, MET, and EN/DE/ES instructions. Free for commercial in-app use with attribution. Full paid dataset at repdb.co." />
8
+ <link rel="canonical" href="https://repdb.co/free-exercise-dataset" />
9
+ <meta property="og:title" content="Free Exercise Dataset — 400 Exercises (RepDB)" />
10
+ <meta property="og:description" content="400 fitness exercises in JSON with illustrations, muscles, equipment and EN/DE/ES instructions. Free with attribution. The full paid dataset keeps growing at repdb.co." />
11
+ <meta property="og:type" content="website" />
12
+ <meta property="og:image" content="https://sergei-argutin.github.io/exercise-dataset/images/flat/squat-peak.webp" />
13
+ <script type="application/ld+json">
14
+ {
15
+ "@context": "https://schema.org",
16
+ "@type": "Dataset",
17
+ "name": "RepDB Exercise Dataset (free tier)",
18
+ "description": "Free multilingual fitness exercise dataset: exercises in JSON with flat WebP illustrations, target muscles, equipment, MET values, and step-by-step instructions in English, German and Spanish. Free for personal and commercial in-app use with attribution.",
19
+ "url": "https://sergei-argutin.github.io/exercise-dataset/",
20
+ "license": "https://github.com/sergei-argutin/exercise-dataset/blob/main/LICENSE-DATA.md",
21
+ "isAccessibleForFree": true,
22
+ "inLanguage": ["en", "de", "es"],
23
+ "creator": {
24
+ "@type": "Organization",
25
+ "name": "RepDB",
26
+ "url": "https://repdb.co"
27
+ },
28
+ "distribution": {
29
+ "@type": "DataDownload",
30
+ "encodingFormat": "application/json",
31
+ "contentUrl": "https://raw.githubusercontent.com/sergei-argutin/exercise-dataset/main/exercises.json"
32
+ }
33
+ }
34
+ </script>
35
+ <style>
36
+ :root{--bg:#0b0c0f;--card:#15171c;--mut:#9aa3af;--fg:#f3f4f6;--acc:#22c55e;--line:#252830}
37
+ *{box-sizing:border-box}
38
+ body{margin:0;font:15px/1.5 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;background:var(--bg);color:var(--fg)}
39
+ a{color:var(--acc)}
40
+ header{padding:28px 20px 14px;max-width:1100px;margin:0 auto}
41
+ h1{font-size:1.7rem;margin:0 0 6px}
42
+ .sub{color:var(--mut);margin:0 0 14px}
43
+ .cta{display:inline-block;background:var(--acc);color:#06210f;font-weight:700;text-decoration:none;padding:9px 16px;border-radius:9px}
44
+ .bar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;max-width:1100px;margin:8px auto 0;padding:0 20px}
45
+ input,select{background:var(--card);border:1px solid var(--line);color:var(--fg);padding:9px 11px;border-radius:8px;font-size:14px}
46
+ input{flex:1;min-width:180px}
47
+ main{max-width:1100px;margin:18px auto 60px;padding:0 20px}
48
+ .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:14px}
49
+ .card{position:relative;background:var(--card);border:1px solid var(--line);border-radius:12px;overflow:hidden;cursor:pointer;transition:.12s}
50
+ .card:hover,.card:focus-visible{border-color:var(--acc);transform:translateY(-2px)}
51
+ .card:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
52
+ .card .img{display:block;width:100%;aspect-ratio:1;object-fit:cover;background:#0f1115}
53
+ .card .meta{padding:9px 11px}
54
+ .card .meta b{display:block;font-size:.92rem}
55
+ .card .meta span{color:var(--mut);font-size:.78rem;text-transform:capitalize}
56
+ .count{color:var(--mut);font-size:.85rem;margin:14px 2px}
57
+ dialog{background:var(--card);color:var(--fg);border:1px solid var(--line);border-radius:14px;max-width:680px;width:92%;padding:0}
58
+ dialog::backdrop{background:rgba(0,0,0,.6)}
59
+ .modal{padding:20px}
60
+ .modal h2{margin:0 0 2px}
61
+ .poses{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:14px 0}
62
+ .poses.single{grid-template-columns:minmax(0,340px)}
63
+ .poses figure{margin:0;background:#0f1115;border-radius:10px;padding:8px;text-align:center}
64
+ .poses img{width:100%;aspect-ratio:1;object-fit:contain}
65
+ .poses figcaption{color:var(--mut);font-size:.75rem;margin-top:4px}
66
+ .chips{display:flex;gap:6px;flex-wrap:wrap;margin:8px 0}
67
+ .chip{background:#0f1115;border:1px solid var(--line);border-radius:999px;padding:3px 10px;font-size:.75rem;color:var(--mut);text-transform:capitalize}
68
+ ol{padding-left:18px}
69
+ .foot{border-top:1px solid var(--line);margin-top:16px;padding-top:12px;color:var(--mut);font-size:.85rem}
70
+ .x{position:absolute;top:10px;right:14px;background:0;border:0;color:var(--mut);font-size:1.4rem;cursor:pointer}
71
+ .promo{background:linear-gradient(90deg,#0f2417,#14171c);border:1px solid var(--line);border-radius:12px;padding:14px 16px;margin:0 0 18px;display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap}
72
+ .upgrade{margin:48px 0 0;border-top:1px solid var(--line);padding-top:28px}
73
+ .upgrade h2{font-size:1.25rem;margin:0 0 4px}
74
+ .upgrade .note{color:var(--mut);font-size:.88rem;margin:0 0 16px}
75
+ .upgrade .note b{color:var(--fg)}
76
+ .samples{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:14px}
77
+ .samples figure{margin:0;border:1px solid var(--line);border-radius:12px;padding:8px;text-align:center;
78
+ background-image:conic-gradient(#1b1e25 90deg,#0f1217 0 180deg,#1b1e25 0 270deg,#0f1217 0);background-size:16px 16px}
79
+ .samples img{width:100%;aspect-ratio:1;object-fit:contain}
80
+ .samples figcaption{color:var(--mut);font-size:.75rem;margin-top:4px;background:var(--bg);border-radius:6px;padding:2px 4px}
81
+ .samples .tag{color:var(--acc);font-weight:700}
82
+ </style>
83
+ </head>
84
+ <body>
85
+ <header>
86
+ <h1>Free Exercise Dataset — JSON + Images</h1>
87
+ <p class="sub">The free tier of <b>RepDB</b>: <b class="jscount">400</b> fitness exercises with flat illustrations, target muscles, equipment, MET, and instructions in English, German &amp; Spanish. Free for personal and commercial in-app use with attribution — see <a href="https://github.com/sergei-argutin/exercise-dataset/blob/main/LICENSE-DATA.md">LICENSE-DATA.md</a>. The full paid dataset keeps growing and adds high-res classic images, transparency and animations.</p>
88
+ <a class="cta" href="https://repdb.co/pricing">Get the full dataset →</a>
89
+ </header>
90
+
91
+ <div class="bar">
92
+ <input id="q" placeholder="Search exercises, muscles, equipment…" aria-label="Search exercises, muscles, equipment" />
93
+ <select id="body" aria-label="Filter by body part"><option value="">All body parts</option></select>
94
+ <select id="equip" aria-label="Filter by equipment"><option value="">All equipment</option></select>
95
+ </div>
96
+
97
+ <main>
98
+ <div class="promo">
99
+ <span>This is the <b>free tier</b> — <b><span class="jscount">400</span> exercises</b>, flat style, 512&nbsp;px, EN/DE/ES, attribution license. The full paid dataset keeps growing and ships classic white-background 1024&nbsp;px images, transparent backgrounds and looping animations.</span>
100
+ <a class="cta" href="https://repdb.co/pricing">See pricing →</a>
101
+ </div>
102
+ <div class="count" id="count"></div>
103
+ <div class="grid" id="grid"></div>
104
+
105
+ <section class="upgrade">
106
+ <h2>Upgrade samples — Standard tier preview</h2>
107
+ <p class="note"><b>Standard tier quality — evaluation only, see <a href="https://github.com/sergei-argutin/exercise-dataset/blob/main/LICENSE-DATA.md">LICENSE-DATA.md</a>.</b>
108
+ Looping, transparent-background exercise animations — the same clips shown on <a href="https://repdb.co">repdb.co</a> (checkerboard shows the transparency). The Standard tier adds looping animations like these for most exercises → <a href="https://repdb.co/pricing">repdb.co/pricing</a>.</p>
109
+ <div class="samples">
110
+ <figure><img src="https://huggingface.co/datasets/sargutin/exercise-dataset/resolve/main/upgrade-samples/bench-leg-pull-in.webp" alt="Bench Leg Pull-in — looping transparent animation" loading="lazy"><figcaption>Bench Leg Pull-in · <span class="tag">animation</span></figcaption></figure>
111
+ <figure><img src="https://huggingface.co/datasets/sargutin/exercise-dataset/resolve/main/upgrade-samples/cossack-squat.webp" alt="Cossack Squat — looping transparent animation" loading="lazy"><figcaption>Cossack Squat · <span class="tag">animation</span></figcaption></figure>
112
+ <figure><img src="https://huggingface.co/datasets/sargutin/exercise-dataset/resolve/main/upgrade-samples/bent-arm-barbell-pullover.webp" alt="Bent-arm Barbell Pullover — looping transparent animation" loading="lazy"><figcaption>Bent-arm Barbell Pullover · <span class="tag">animation</span></figcaption></figure>
113
+ <figure><img src="https://huggingface.co/datasets/sargutin/exercise-dataset/resolve/main/upgrade-samples/incline-db-curl.webp" alt="Incline Dumbbell Curl — looping transparent animation" loading="lazy"><figcaption>Incline Dumbbell Curl · <span class="tag">animation</span></figcaption></figure>
114
+ <figure><img src="https://huggingface.co/datasets/sargutin/exercise-dataset/resolve/main/upgrade-samples/mountain-climbers.webp" alt="Mountain Climbers — looping transparent animation" loading="lazy"><figcaption>Mountain Climbers · <span class="tag">animation</span></figcaption></figure>
115
+ </div>
116
+ </section>
117
+ </main>
118
+
119
+ <dialog id="dlg"><button class="x" aria-label="Close" onclick="dlg.close()">×</button><div class="modal" id="modal"></div></dialog>
120
+
121
+ <script>
122
+ let DATA=[];
123
+ const ASSET_BASE='https://huggingface.co/datasets/sargutin/exercise-dataset/resolve/main/';
124
+ const grid=document.getElementById('grid'), q=document.getElementById('q'),
125
+ bodySel=document.getElementById('body'), equipSel=document.getElementById('equip'),
126
+ countEl=document.getElementById('count'), dlg=document.getElementById('dlg'), modal=document.getElementById('modal');
127
+ const cap=s=>(s||'').replace(/[-_]/g,' ');
128
+
129
+ fetch(ASSET_BASE+'exercises.json').then(r=>r.json()).then(d=>{
130
+ DATA=d.exercises;
131
+ document.querySelectorAll('.jscount').forEach(el=>el.textContent=DATA.length);
132
+ [...new Set(DATA.map(e=>e.body_part).filter(Boolean))].sort().forEach(v=>bodySel.add(new Option(cap(v),v)));
133
+ [...new Set(DATA.map(e=>e.equipment).filter(Boolean))].sort().forEach(v=>equipSel.add(new Option(cap(v),v)));
134
+ render();
135
+ }).catch(()=>{
136
+ grid.innerHTML='<p class="count">Could not load exercises.json — try reloading, or browse the <a href="https://github.com/sergei-argutin/exercise-dataset">repository files</a> directly.</p>';
137
+ });
138
+ dlg.onclick=ev=>{ if(ev.target===dlg) dlg.close(); };
139
+
140
+ function filtered(){
141
+ const t=q.value.toLowerCase(), b=bodySel.value, eq=equipSel.value;
142
+ return DATA.filter(e=>{
143
+ if(b&&e.body_part!==b) return false;
144
+ if(eq&&e.equipment!==eq) return false;
145
+ if(!t) return true;
146
+ return (e.name_en+' '+(e.body_part||'')+' '+(e.equipment||'')+' '+(e.primary_muscles||[]).join(' ')).toLowerCase().includes(t);
147
+ });
148
+ }
149
+ function flat(e){ return (e.images||{}).flat||{}; }
150
+ function asset(path){ return path ? ASSET_BASE+path : ''; }
151
+ function cardImg(e){ const f=flat(e); return asset(f.peak||f.main||f.start||''); }
152
+ function render(){
153
+ const list=filtered();
154
+ countEl.textContent=list.length+' of '+DATA.length+' exercises';
155
+ grid.innerHTML='';
156
+ list.forEach(e=>{
157
+ const c=document.createElement('div'); c.className='card';
158
+ c.tabIndex=0; c.setAttribute('role','button');
159
+ c.setAttribute('aria-label','Show details for '+e.name_en);
160
+ c.innerHTML=`<img class="img" loading="lazy" src="${cardImg(e)}" alt="">
161
+ <div class="meta"><b>${e.name_en}</b><span>${[e.body_part,e.equipment].filter(Boolean).map(cap).join(' · ')}</span></div>`;
162
+ c.onclick=()=>open_(e);
163
+ c.onkeydown=ev=>{ if(ev.key==='Enter'||ev.key===' '){ ev.preventDefault(); open_(e); } };
164
+ grid.appendChild(c);
165
+ });
166
+ }
167
+ function poses(e){
168
+ const f=flat(e);
169
+ if(f.start&&f.peak) return `<div class="poses">
170
+ <figure><img src="${asset(f.start)}" alt="${e.name_en} start"><figcaption>Start</figcaption></figure>
171
+ <figure><img src="${asset(f.peak)}" alt="${e.name_en} peak"><figcaption>Peak</figcaption></figure>
172
+ </div>`;
173
+ const u=f.main||f.start||f.peak;
174
+ return u?`<div class="poses single">
175
+ <figure><img src="${asset(u)}" alt="${e.name_en}"></figure>
176
+ </div>`:'';
177
+ }
178
+ function open_(e){
179
+ const chips=[...(e.primary_muscles||[]),...(e.tags||[])].map(m=>`<span class="chip">${cap(m)}</span>`).join('');
180
+ const steps=(e.instructions_en||[]).map(s=>`<li>${s}</li>`).join('');
181
+ modal.innerHTML=`<h2>${e.name_en}</h2>
182
+ <div style="color:var(--mut)">${cap(e.difficulty)} · ${cap(e.mechanic)} · ${cap(e.category)}${e.met?' · MET '+e.met:''}</div>
183
+ ${poses(e)}
184
+ <p>${e.description_en||''}</p>
185
+ <div class="chips">${chips}</div>
186
+ ${steps?`<ol>${steps}</ol>`:''}
187
+ <div class="foot">German &amp; Spanish translations are in the JSON. The full paid dataset keeps growing — classic 1024&nbsp;px images, transparency &amp; animations at <a href="https://repdb.co">repdb.co →</a></div>`;
188
+ dlg.showModal();
189
+ }
190
+ q.oninput=bodySel.onchange=equipSel.onchange=render;
191
+ </script>
192
+ </body>
193
  </html>