ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
Learn all 213 countries and territories, their capitals, and where they are on the map. Free, with four study modes, and Geo Classroom for teachers.
EducationJavaScript · CSSGitHub @cosmiccatmainOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗LearnGeo is a geography study app for learning the world's countries, their capitals and where they are on the map. It's a static site with no build step, and it's deployed on Vercel.
| Group | Count |
|---|---|
| UN member states | 193 |
| UN observer states (Vatican City, Palestine) | 2 |
| Territories and other places (Taiwan, Kosovo, Greenland, Puerto Rico, Hong Kong, ...) | 18 |
| Total | 213 |
Each place has a capital, the capital's coordinates and a region. A few capitals are tricky because there's more than one reasonable answer (Bolivia, South Africa, the Netherlands, Sri Lanka, Eswatini and some others). Those show a short note explaining why, and the other answers are accepted too.
Learn: practice for as long as you want and find out right away if you got it. The countries you're worst at come up first. There are six question types: country to capital, capital to country, find the country on the map, name the shaded country, name the country a flag belongs to, and pick a country's flag out of four.
Practice test: a fixed set of questions with a navigator, flags, an optional timer and an exam mode. At the end you get a report split up by region and question type.
Class quiz: works like the paper map quizzes from school. A country is shaded gold, you click it, then type its name and its capital from memory. Each question is worth two marks, there's no multiple choice, and you get a marked paper at the end.
Flashcards: country on one side, capital on the other, or a flag on the front with the country and its capital on the back. Rate each card Again, Hard, Good or Easy, and the ones you struggled with come back before the deck is over.
Flags: a section of its own in the top bar, with no map. Practice names the flag, finds
the flag or mixes both, by choice or typed, weakest first, and filters by region. "Pick
countries" narrows it to your own set instead: type names like in Learn or click flags on and
off, and the set is kept in flagPick in the save until you pick a region again. "All flags"
shows every flag with its name and capital, with a search and a "Hide names" self-test. A flag
counts as learned once it has been answered right twice more often than wrong, kept in
flagMastery in the save.
Games: 2D games in a section of their own. The first is Geo Dash, a one-button
runner like Geometry Dash: the cube runs by itself, and you jump over spikes, onto blocks,
off yellow pads and through yellow rings. Every 10, 20, 30 or 45 seconds a capital gate comes
down the track. Name the capital and the run speeds up and the cube wears that country's
flag; get it wrong and the run is over. The capitals use the same filters dialog as Learn
(regions, UN members or your own countries, multiple choice or typed, weakest first), and the
answers count toward mastery, XP and gems. Best distance is kept in games.dash in the save.
The second is Globe Defender, an orbit shooter: your ship circles a real globe and fires
outward on its own while you steer it (arrow keys, A / D, or the mouse) to meet the meteors.
A meteor that gets through costs one of three shields and lights up the country it landed on.
After every wave a supply drop arrives with four satellites showing flags, capitals or a mix;
shoot the right one (Space, or click / tap it) for a power-up (a shield back, triple shot,
rapid fire or slow motion), and a wrong answer or running out of time brings a meteor shower.
The questions use the Learn filters too, and the best score is kept in games.orbit.
The third is Capital Snake: classic Snake on a grid, steered with the arrow keys, WASD or a
swipe, where the food is the answer. The banner names a country and four capitals (or flags,
or a mix) lie on the board; eating the right one grows the snake, speeds it up and puts that
country's flag on its head, with more points for quick answers and streaks. A wrong one costs
three pieces of tail. Speed (relaxed, normal, fast) and walls (solid or wrap round) are set on
its setup screen, and the best score is kept in games.snake.
The fourth is Geo Golf: top-down golf on the flat world map, where the course is the part
of the map the filtered countries cover. Each hole names a country, or a capital whose country
you have to find (or a mix), and there is no pin to aim at. You drag back like a slingshot, or
aim with the arrow keys, and putt to where you think it is. Stopping in the wrong country names
it; stopping in the sea is a water hazard, +1 stroke and back to where you were. After three
misses the pin comes out, and after six the hole is picked up and the country shown. A hole
only counts as right for mastery if it was holed before the pin came out. Rounds are 6, 9 or
18 holes, par is 2 or 3 by distance, and the best score to par for each round length is kept
in games.golf.
All the modes save to the same mastery record, so the app knows what you keep getting wrong.
The 213 flags in assets/flags/ are the 4:3 SVGs from
flag-icons 7.6.0 (MIT, licence alongside them), named
by ISO 3166-1 alpha-2 code. Kosovo uses xk. The code for each place is in FLAG_CODES in
assets/js/data.js. Each flag is loaded only when it is shown; the whole set is about 1.4 MB.
Chad and Romania, and Indonesia and Monaco, have flags that look the same, so neither is ever offered as the wrong answer for the other.
OpenStreetMap tiles have every country and capital name printed on them, which would give away a lot of answers. So while a question is on screen, the map is clear at the world view but the tiles get blurred once you zoom in. Borders are drawn on top from our own country shapes, so you can still see them. After you answer, the blur goes away. If the question already tells you the country (country to capital), that country is shaded and labeled.
Countries are shaded as whole shapes instead of being marked with pins. The outlines come from
Natural Earth 1:50m through world-atlas, converted
to GeoJSON and rounded to 2 decimal places. They're in assets/data/countries.geo.json
(about 1.3 MB, around 400 KB gzipped). 211 of the 213 places have a polygon. Tuvalu and
Gibraltar are too small to show up at this scale, so they get a circle on the capital instead.
The same outlines are reused away from Leaflet. assets/js/worldmap.js projects them once
into a flat equirectangular SVG and snaps the result to a coarse grid, which takes about
900 KB of path data down to about 190 KB. That is the map on the home screen, coloured by
what you have mastered, and the map in the two landing-page screenshots.
The landing page has a quick demo with three sample questions: one country to capital, one
capital to country, and one where you name a country from its outline. It doesn't touch your
saved progress. When you finish, it asks if you want to sign up as a student or a teacher.
The outlines it uses are in demo-shapes.js, which was generated from countries.geo.json
so the landing page doesn't have to load the whole file.
You earn XP, level up and collect diamonds. Getting answers right in a row gives you a multiplier that goes up to ×3. There's a daily goal, and your day streak only counts days where you actually hit it. There are also ten achievements. You can spend diamonds in the shop on profile cosmetics: avatars, avatar decorations, profile effects, nameplates, banners and color themes.
A teacher gets one class with one class code. The teacher view has Stream, Classwork, People and Analytics tabs, plus a gradebook. Students get a Classroom tab where their assigned work shows up.
The class code is issued by the server when the class is created, so the classroom is the one part of the app that needs accounts: a teacher signs in to get a code, and students sign in to join with it. There are no long codes to copy and paste any more. After the join, assignments reach the class the moment they're saved and finished scores come back on their own. A teacher can still type a score straight into the gradebook for anyone who did the work on paper.
Stream is the teacher writing to the class: a reminder, a date for a quiz, a well done. Posts can be pinned to the top and go out the same way assignments do, turning up in every student's own Stream tab with an unread badge that clears once they have been read. It only runs one way — students read it, they can't post back.
The gradebook exports as a real CSV file. Names come from students, so a name starting with
=, +, - or @ is written out quoted — otherwise it would be a live formula the moment
the file opened in Excel.
You don't need an account. As a guest, everything is saved in your browser's localStorage.
If you make an account (email and password through Supabase Auth), your whole save gets
synced to Supabase: progress, mastery, diamonds, purchases, settings and classes. That way it
follows you to other devices. A new account starts with whatever you already played as a guest.
Accounts also make the classroom live:
All of this is in assets/js/cloud.js.
Email and password work everywhere. On a device that supports passkeys you can also set one
up and sign in with your face, fingerprint or screen lock instead, with no password to
remember. Supabase Auth runs that, and assets/js/passkey.js adds the button. That file also
puts an eye on every password box so you can check what you typed. It watches for the dialogs
to appear rather than being called by ui.js, so the two don't get in each other's way.
Adding ?admin to the URL opens a number pad. The four-digit codes live in Supabase and are
checked there (assets/js/admin-pin.js), so the page never holds one, and if it can't reach
the server it refuses rather than falling back to anything. Unlocking it lets you hand out the
two things the app won't award on its own: the verified seal and diamonds. It only changes
this browser's save. Four digits is a speed bump to keep students out, not real security.
| Table | Holds | Who can see it |
|---|---|---|
profiles | display name, role, the full save (jsonb) | only its owner |
classes | class code, name, teacher | the teacher and the class's students |
class_members | who joined which class, under what name | the student and the teacher |
assignments | title, mode, config | the teacher (read/write) and students (read) |
results | score, correct/total, countries missed | the student who sent it and the teacher |
announcements | the class stream: body, pinned | the teacher (read/write) and students (read) |
Row-level security is on for every table. Students join through the join_class(code, name)
function and hand in work through submit_result(...), so nobody can add themselves to a
class or post a score as someone else. A trigger creates the profile row when someone signs up.
The publishable key in cloud.js is supposed to be public. What people can read or write is
controlled by the policies above.
There are two schemas described in this repo and only one of them is real.
supabase/deployed/ is the live one — the tables above, the ones cloud.js talks to.
supabase/migrations/ describes a different design that has never been applied: classes keyed
on owner_id, seats with four states, submissions instead of results, and three Edge
Functions. Apply deployed/; supabase/deployed/README.md explains the split.
http://localhost:8765 for local testing. That way the
confirmation and password reset emails link back to the app.The map uses Leaflet with OpenStreetMap tiles. OpenStreetMap's tile server is free and doesn't need an API key, so the app works without any setup. If you want higher rate limits, Settings > Map lets you pick CARTO, MapTiler, Thunderforest or Stadia and paste in your key. If you pick one of those without a key, it goes back to plain OpenStreetMap.
Map data © OpenStreetMap contributors.
motion.css and motion.js handle the animations: button feedback, click ripples, views
sliding in, modals fading out and the scroll reveals on the landing page. motion.js only
watches the page and never calls into the other scripts, so you can delete both files and
everything still works. Most of it is skipped if your system has reduced motion turned on.
There's no build step. From the repo folder, run:
python3 -m http.server 8765
Then open http://localhost:8765. Use a local server instead of opening index.html
directly, because the country outlines are loaded with fetch and won't load from the
filesystem (every country would fall back to a circle).
Leaflet and supabase-js are loaded from CDNs in index.html, so there's nothing to install.
index.html is the student page and carries the app shell too, so every button on it opens
the app. teachers.html is marketing only: no app shell, and its buttons are plain links into
index.html?role=teacher. It loads one script and nothing else, globe.js, for the hero.
?role= and ?view= are read once on load and then wiped off the address bar. A role in the
URL only settles things for a guest; if the save belongs to an account, the account's own role
wins, so the link can open a view but never change who you are.
index.html student landing page and app shell
teachers.html teacher landing page (marketing only, no app shell)
assets/css/app.css main styles
assets/css/motion.css button feedback and transitions
assets/css/demo.css landing page demo
assets/css/auth.css sign in, create account and password dialogs
assets/css/brand.css the LearnGeo mark
assets/js/data.js the 213 places: capitals, coordinates, notes, aliases, flag codes
assets/flags/ one 4:3 SVG flag per place, named by ISO alpha-2 code
assets/js/cosmetics.js avatars, decorations, effects, nameplates, banners, themes, achievements
assets/js/avatars.js inline SVG artwork for avatars (no emoji fonts needed)
assets/js/core.js icons, state, storage, economy, sound, reward effects
assets/js/map.js Leaflet setup, country shapes, the map blur
assets/js/worldmap.js the outlines as one flat inline SVG, no Leaflet
assets/js/globe.js the globe behind the hero headline, drawn to a canvas
assets/js/relief.js the ridgeline relief behind the Geo Classroom headline
assets/js/quiz.js question generation
assets/js/assignments.js suggestions, share codes, handing in work
assets/js/cloud.js Supabase accounts, save sync, online classes
assets/js/ui.js shell, profile menu, sign in, settings, customization, shop
assets/js/passkey.js passkey sign-in and the eye on password boxes
assets/js/portal.js study center home screen, built around the map
assets/js/admin.js ?admin panel: grants and removes the verified seal and diamonds
assets/js/admin-pin.js checks the admin code against Supabase
assets/js/teacher.js teacher view: stream, classwork, people, analytics
assets/js/classroom.js student Classroom tab
assets/js/mode-learn.js Learn
assets/js/mode-test.js Practice test
assets/js/mode-quiz.js Class quiz
assets/js/mode-cards.js Flashcards
assets/js/mode-flags.js Flags: practice and the all-flags gallery
assets/js/study-filters.js the filters dialog, shared by Learn and the games
assets/js/games.js Games: the hub and each game's setup screen
assets/js/game-dash.js Geo Dash: the runner, its track pieces and capital gates
assets/js/game-orbit.js Globe Defender: the orbit shooter, its globe and supply drops
assets/js/game-snake.js Capital Snake: the board, the snake and the answers it eats
assets/js/game-golf.js Geo Golf: the course drawn from the map, the putting and the holes
assets/js/main.js startup and routing
assets/js/demo.js the three-question demo on the landing page
assets/js/demo-shapes.js country outlines for the demo
assets/js/motion.js ripples, entrances and scroll reveals
assets/data/countries.geo.json country outlines (GeoJSON)
It's hosted on Vercel as a static site. You don't need a build command or an output directory.