ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
A Duolingo-style quiz experience for CAPS-aligned school learning.
Next.js 14 · TypeScript · Tailwind CSS · Supabase
The quiz system expects these tables. Create them if they don't exist.檢視完整 README ↗A Duolingo-style quiz experience for CAPS-aligned school learning.
Next.js 14 · TypeScript · Tailwind CSS · Supabase
# 1. Install dependencies
npm install
# 2. Set up environment variables
cp .env.example .env.local
# Fill in NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY
# 3. Run locally
npm run dev
# → http://localhost:3000/quiz
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | ✅ | Your Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY | ✅ | Supabase anon/public key |
ANTHROPIC_API_KEY | For Bloom | Powers Bloom, the Deep Learn tutor (/bloom). Locally it goes in the git-ignored .env.local; never commit it |
BLOOM_ACCESS | Optional | Who can use Bloom: off, testers or everyone. Unset means off, except under npm run dev (testers) |
BLOOM_TESTERS | Optional | Extra Bloom testers by email, comma-separated. Admin accounts are always testers |
The quiz system expects these tables. Create them if they don't exist.
quiz_levelscreate table quiz_levels (
id uuid primary key default gen_random_uuid(),
broad_topic text not null,
subject text not null,
grade int not null,
subtopic_id text,
level_number int default 1,
title text not null,
description text,
section_type text not null, -- 'level' | 'subtopic_mastery' | 'broad_topic_mastery' | 'general_practice'
question_count int default 10,
xp_reward int default 50,
pass_threshold float default 0.6,
is_premium boolean default false,
-- Learning zone fields
intro text,
concepts jsonb, -- array of LearningConcept objects
tested text[], -- array of strings
difficulty text -- 'easy' | 'medium' | 'hard'
);
questionscreate table questions (
id uuid primary key default gen_random_uuid(),
grade int not null,
subject text not null,
broad_topic text not null,
subtopic_id text,
level_id uuid references quiz_levels(id),
section_type text not null,
question_text text not null,
option_a text not null,
option_b text not null,
option_c text not null,
option_d text not null,
correct_option text not null, -- 'a' | 'b' | 'c' | 'd'
explanation text,
is_premium boolean default false
);
user_progresscreate table user_progress (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users(id) on delete cascade,
level_id uuid references quiz_levels(id),
subtopic_id text,
completed boolean default false,
passed boolean default false,
best_score int default 0,
attempts int default 0,
xp_earned int default 0,
completed_at timestamptz,
unique (user_id, level_id)
);
profilescreate table profiles (
id uuid primary key references auth.users(id) on delete cascade,
display_name text,
total_xp int default 0,
streak int default 0,
is_premium boolean default false,
is_founder boolean default false,
grade int
);
create or replace function award_quiz_xp(p_user_id uuid, p_xp int)
returns void as $$
begin
update profiles
set total_xp = total_xp + p_xp
where id = p_user_id;
end;
$$ language plpgsql security definer;
-- user_progress: users can only read/write their own rows
alter table user_progress enable row level security;
create policy "users own progress" on user_progress
using (auth.uid() = user_id) with check (auth.uid() = user_id);
-- quiz_levels: public read
alter table quiz_levels enable row level security;
create policy "public read levels" on quiz_levels for select using (true);
-- questions: public read for free, premium gated by app logic
alter table questions enable row level security;
create policy "public read questions" on questions for select using (true);
-- profiles: users read/write own
alter table profiles enable row level security;
create policy "users own profile" on profiles
using (auth.uid() = id) with check (auth.uid() = id);
/quiz Browse all topics (grade filter)
/quiz/[broadTopic] Broad topic overview + subtopics
/quiz/[broadTopic]/[subtopic] Subtopic level path
/quiz/[broadTopic]/[subtopic]/[level]/learn Learning zone (pre-quiz)
/quiz/[broadTopic]/[subtopic]/[level]/play Quiz runner
/quiz/[broadTopic]/practice General practice entry
broadTopic and subtopic in URLs are URI-encoded versions of the actual string values stored in Supabase.
For example: Parts of Speech → Parts%20of%20Speech
Two-layer mastery — both layers are required:
Normal levels (Level 1, Level 2, Level 3...)
↓ all passed
Subtopic Mastery (e.g. "Nouns Mastery")
↓ all subtopic masteries passed
Broad Topic Mastery (e.g. "Parts of Speech Mastery") ← final boss
In quiz_levels:
section_type = 'level'section_type = 'subtopic_mastery' + same subtopic_idsection_type = 'broad_topic_mastery' + same broad_topicEvery quiz attempt:
Implemented in lib/questions.ts → shuffleQuestion() and fetchLevelQuestions().
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYThis quiz system integrates cleanly alongside the existing static HTML pages (index.html, papers.html, admin.html) — they are separate and unaffected.
| Token | Value |
|---|---|
| Plum | #2B1E3F |
| Cyan | #6DD3CE |
| Coral | #FF5E5B |
| Amber | #F5C842 |
| Font Heading | Poppins 800/900 |
| Font Body | DM Sans |